Kaynağa Gözat

Everywhere: Correctly report progress of downloads larger than 4GiB

This commit changes the variables used to represent the size and
progress of downloads from u32 to u64. This allows `pro` and
`Browser` to report the total size and progress of a download
correctly for downloads larger than 4GiB.
Tim Ledbetter 2 yıl önce
ebeveyn
işleme
1a17e08f87

+ 7 - 9
Userland/Applications/Browser/DownloadWidget.cpp

@@ -43,7 +43,7 @@ DownloadWidget::DownloadWidget(const URL& url)
     m_elapsed_timer.start();
     m_download = Web::ResourceLoader::the().connector().start_request("GET", url);
     VERIFY(m_download);
-    m_download->on_progress = [this](Optional<u32> total_size, u32 downloaded_size) {
+    m_download->on_progress = [this](Optional<u64> total_size, u64 downloaded_size) {
         did_progress(total_size.value(), downloaded_size);
     };
 
@@ -78,6 +78,8 @@ DownloadWidget::DownloadWidget(const URL& url)
 
     m_progressbar = add<GUI::Progressbar>();
     m_progressbar->set_fixed_height(20);
+    m_progressbar->set_max(0);
+    m_progressbar->set_max(100);
 
     m_progress_label = add<GUI::Label>();
     m_progress_label->set_text_alignment(Gfx::TextAlignment::CenterLeft);
@@ -117,17 +119,14 @@ DownloadWidget::DownloadWidget(const URL& url)
     };
 }
 
-void DownloadWidget::did_progress(Optional<u32> total_size, u32 downloaded_size)
+void DownloadWidget::did_progress(Optional<u64> total_size, u64 downloaded_size)
 {
-    m_progressbar->set_min(0);
+    int percent = 0;
     if (total_size.has_value()) {
-        int percent = roundf(((float)downloaded_size / (float)total_size.value()) * 100.0f);
+        percent = downloaded_size * 100 / total_size.value();
         window()->set_progress(percent);
-        m_progressbar->set_max(total_size.value());
-    } else {
-        m_progressbar->set_max(0);
+        m_progressbar->set_value(percent);
     }
-    m_progressbar->set_value(downloaded_size);
 
     {
         StringBuilder builder;
@@ -140,7 +139,6 @@ void DownloadWidget::did_progress(Optional<u32> total_size, u32 downloaded_size)
     {
         StringBuilder builder;
         if (total_size.has_value()) {
-            int percent = roundf(((float)downloaded_size / (float)total_size.value()) * 100);
             builder.appendff("{}%", percent);
         } else {
             builder.append(human_readable_size(downloaded_size));

+ 1 - 1
Userland/Applications/Browser/DownloadWidget.h

@@ -25,7 +25,7 @@ public:
 private:
     explicit DownloadWidget(const URL&);
 
-    void did_progress(Optional<u32> total_size, u32 downloaded_size);
+    void did_progress(Optional<u64> total_size, u64 downloaded_size);
     void did_finish(bool success);
 
     URL m_url;

+ 1 - 1
Userland/Libraries/LibCore/NetworkJob.cpp

@@ -56,7 +56,7 @@ void NetworkJob::did_fail(Error error)
     shutdown(ShutdownMode::DetachFromSocket);
 }
 
-void NetworkJob::did_progress(Optional<u32> total_size, u32 downloaded)
+void NetworkJob::did_progress(Optional<u64> total_size, u64 downloaded)
 {
     if (is_cancelled())
         return;

+ 2 - 2
Userland/Libraries/LibCore/NetworkJob.h

@@ -29,7 +29,7 @@ public:
     // Could fire twice, after Headers and after Trailers!
     Function<void(HashMap<DeprecatedString, DeprecatedString, CaseInsensitiveStringTraits> const& response_headers, Optional<u32> response_code)> on_headers_received;
     Function<void(bool success)> on_finish;
-    Function<void(Optional<u32>, u32)> on_progress;
+    Function<void(Optional<u64>, u64)> on_progress;
 
     bool is_cancelled() const { return m_error == Error::Cancelled; }
     bool has_error() const { return m_error != Error::None; }
@@ -55,7 +55,7 @@ protected:
     NetworkJob(Stream&);
     void did_finish(NonnullRefPtr<NetworkResponse>&&);
     void did_fail(Error);
-    void did_progress(Optional<u32> total_size, u32 downloaded);
+    void did_progress(Optional<u64> total_size, u64 downloaded);
 
     ErrorOr<size_t> do_write(ReadonlyBytes bytes) { return m_output_stream.write_some(bytes); }
 

+ 1 - 1
Userland/Libraries/LibHTTP/Job.cpp

@@ -380,7 +380,7 @@ void Job::on_socket_connected()
                 dbgln_if(JOB_DEBUG, "Content-Encoding {} detected, cannot stream output :(", value);
                 m_can_stream_response = false;
             } else if (name.equals_ignoring_ascii_case("Content-Length"sv)) {
-                auto length = value.to_uint();
+                auto length = value.to_uint<u64>();
                 if (length.has_value())
                     m_content_length = length.value();
             }

+ 1 - 1
Userland/Libraries/LibHTTP/Job.h

@@ -74,7 +74,7 @@ protected:
 
     size_t m_buffered_size { 0 };
     size_t m_received_size { 0 };
-    Optional<u32> m_content_length;
+    Optional<u64> m_content_length;
     Optional<ssize_t> m_current_chunk_remaining_size;
     Optional<size_t> m_current_chunk_total_size;
     bool m_can_stream_response { true };

+ 3 - 3
Userland/Libraries/LibProtocol/Request.cpp

@@ -88,7 +88,7 @@ void Request::set_should_buffer_all_input(bool value)
         m_internal_buffered_data->response_code = move(response_code);
     };
 
-    on_finish = [this](auto success, u32 total_size) {
+    on_finish = [this](auto success, auto total_size) {
         auto output_buffer = ByteBuffer::create_uninitialized(m_internal_buffered_data->payload_stream.used_buffer_size()).release_value_but_fixme_should_propagate_errors();
         m_internal_buffered_data->payload_stream.read_until_filled(output_buffer).release_value_but_fixme_should_propagate_errors();
         on_buffered_request_finish(
@@ -102,7 +102,7 @@ void Request::set_should_buffer_all_input(bool value)
     stream_into(m_internal_buffered_data->payload_stream);
 }
 
-void Request::did_finish(Badge<RequestClient>, bool success, u32 total_size)
+void Request::did_finish(Badge<RequestClient>, bool success, u64 total_size)
 {
     if (!on_finish)
         return;
@@ -110,7 +110,7 @@ void Request::did_finish(Badge<RequestClient>, bool success, u32 total_size)
     on_finish(success, total_size);
 }
 
-void Request::did_progress(Badge<RequestClient>, Optional<u32> total_size, u32 downloaded_size)
+void Request::did_progress(Badge<RequestClient>, Optional<u64> total_size, u64 downloaded_size)
 {
     if (on_progress)
         on_progress(total_size, downloaded_size);

+ 5 - 5
Userland/Libraries/LibProtocol/Request.h

@@ -43,14 +43,14 @@ public:
     void set_should_buffer_all_input(bool);
 
     /// Note: Must be set before `set_should_buffer_all_input(true)`.
-    Function<void(bool success, u32 total_size, HashMap<DeprecatedString, DeprecatedString, CaseInsensitiveStringTraits> const& response_headers, Optional<u32> response_code, ReadonlyBytes payload)> on_buffered_request_finish;
-    Function<void(bool success, u32 total_size)> on_finish;
-    Function<void(Optional<u32> total_size, u32 downloaded_size)> on_progress;
+    Function<void(bool success, u64 total_size, HashMap<DeprecatedString, DeprecatedString, CaseInsensitiveStringTraits> const& response_headers, Optional<u32> response_code, ReadonlyBytes payload)> on_buffered_request_finish;
+    Function<void(bool success, u64 total_size)> on_finish;
+    Function<void(Optional<u64> total_size, u64 downloaded_size)> on_progress;
     Function<void(HashMap<DeprecatedString, DeprecatedString, CaseInsensitiveStringTraits> const& response_headers, Optional<u32> response_code)> on_headers_received;
     Function<CertificateAndKey()> on_certificate_requested;
 
-    void did_finish(Badge<RequestClient>, bool success, u32 total_size);
-    void did_progress(Badge<RequestClient>, Optional<u32> total_size, u32 downloaded_size);
+    void did_finish(Badge<RequestClient>, bool success, u64 total_size);
+    void did_progress(Badge<RequestClient>, Optional<u64> total_size, u64 downloaded_size);
     void did_receive_headers(Badge<RequestClient>, HashMap<DeprecatedString, DeprecatedString, CaseInsensitiveStringTraits> const& response_headers, Optional<u32> response_code);
     void did_request_certificates(Badge<RequestClient>);
 

+ 2 - 2
Userland/Libraries/LibProtocol/RequestClient.cpp

@@ -54,7 +54,7 @@ bool RequestClient::set_certificate(Badge<Request>, Request& request, Deprecated
     return IPCProxy::set_certificate(request.id(), move(certificate), move(key));
 }
 
-void RequestClient::request_finished(i32 request_id, bool success, u32 total_size)
+void RequestClient::request_finished(i32 request_id, bool success, u64 total_size)
 {
     RefPtr<Request> request;
     if ((request = m_requests.get(request_id).value_or(nullptr))) {
@@ -63,7 +63,7 @@ void RequestClient::request_finished(i32 request_id, bool success, u32 total_siz
     m_requests.remove(request_id);
 }
 
-void RequestClient::request_progress(i32 request_id, Optional<u32> const& total_size, u32 downloaded_size)
+void RequestClient::request_progress(i32 request_id, Optional<u64> const& total_size, u64 downloaded_size)
 {
     if (auto request = const_cast<Request*>(m_requests.get(request_id).value_or(nullptr))) {
         request->did_progress({}, total_size, downloaded_size);

+ 2 - 2
Userland/Libraries/LibProtocol/RequestClient.h

@@ -32,8 +32,8 @@ public:
 private:
     RequestClient(NonnullOwnPtr<Core::LocalSocket>);
 
-    virtual void request_progress(i32, Optional<u32> const&, u32) override;
-    virtual void request_finished(i32, bool, u32) override;
+    virtual void request_progress(i32, Optional<u64> const&, u64) override;
+    virtual void request_finished(i32, bool, u64) override;
     virtual void certificate_requested(i32) override;
     virtual void headers_became_available(i32, HashMap<DeprecatedString, DeprecatedString, CaseInsensitiveStringTraits> const&, Optional<u32> const&) override;
 

+ 3 - 3
Userland/Libraries/LibWeb/Loader/ResourceLoader.h

@@ -65,9 +65,9 @@ public:
 
     virtual void stream_into(Stream&) = 0;
 
-    Function<void(bool success, u32 total_size, HashMap<DeprecatedString, DeprecatedString, CaseInsensitiveStringTraits> const& response_headers, Optional<u32> response_code, ReadonlyBytes payload)> on_buffered_request_finish;
-    Function<void(bool success, u32 total_size)> on_finish;
-    Function<void(Optional<u32> total_size, u32 downloaded_size)> on_progress;
+    Function<void(bool success, u64 total_size, HashMap<DeprecatedString, DeprecatedString, CaseInsensitiveStringTraits> const& response_headers, Optional<u32> response_code, ReadonlyBytes payload)> on_buffered_request_finish;
+    Function<void(bool success, u64 total_size)> on_finish;
+    Function<void(Optional<u64> total_size, u64 downloaded_size)> on_progress;
     Function<CertificateAndKey()> on_certificate_requested;
 
 protected:

+ 2 - 2
Userland/Libraries/LibWebView/RequestServerAdapter.cpp

@@ -24,13 +24,13 @@ RequestServerRequestAdapter::RequestServerRequestAdapter(NonnullRefPtr<Protocol:
                 strong_this->on_buffered_request_finish(success, total_size, response_headers, response_code, move(payload));
     };
 
-    request->on_finish = [weak_this = make_weak_ptr()](bool success, u32 total_size) {
+    request->on_finish = [weak_this = make_weak_ptr()](bool success, u64 total_size) {
         if (auto strong_this = weak_this.strong_ref())
             if (strong_this->on_finish)
                 strong_this->on_finish(success, total_size);
     };
 
-    request->on_progress = [weak_this = make_weak_ptr()](Optional<u32> total_size, u32 downloaded_size) {
+    request->on_progress = [weak_this = make_weak_ptr()](Optional<u64> total_size, u64 downloaded_size) {
         if (auto strong_this = weak_this.strong_ref())
             if (strong_this->on_progress)
                 strong_this->on_progress(total_size, downloaded_size);

+ 1 - 1
Userland/Services/RequestServer/GeminiRequest.cpp

@@ -41,7 +41,7 @@ GeminiRequest::GeminiRequest(ConnectionFromClient& client, NonnullRefPtr<Gemini:
 
         did_finish(success);
     };
-    m_job->on_progress = [this](Optional<u32> total, u32 current) {
+    m_job->on_progress = [this](Optional<u64> total, u64 current) {
         did_progress(move(total), current);
     };
 }

+ 1 - 1
Userland/Services/RequestServer/HttpCommon.h

@@ -46,7 +46,7 @@ void init(TSelf* self, TJob job)
 
         self->did_finish(success);
     };
-    job->on_progress = [self](Optional<u32> total, u32 current) {
+    job->on_progress = [self](Optional<u64> total, u64 current) {
         self->did_progress(total, current);
     };
     if constexpr (requires { job->on_certificate_requested; }) {

+ 1 - 1
Userland/Services/RequestServer/Request.cpp

@@ -39,7 +39,7 @@ void Request::did_finish(bool success)
     m_client.did_finish_request({}, *this, success);
 }
 
-void Request::did_progress(Optional<u32> total_size, u32 downloaded_size)
+void Request::did_progress(Optional<u64> total_size, u64 downloaded_size)
 {
     m_total_size = total_size;
     m_downloaded_size = downloaded_size;

+ 3 - 3
Userland/Services/RequestServer/Request.h

@@ -23,7 +23,7 @@ public:
     virtual URL url() const = 0;
 
     Optional<u32> status_code() const { return m_status_code; }
-    Optional<u32> total_size() const { return m_total_size; }
+    Optional<u64> total_size() const { return m_total_size; }
     size_t downloaded_size() const { return m_downloaded_size; }
     HashMap<DeprecatedString, DeprecatedString, CaseInsensitiveStringTraits> const& response_headers() const { return m_response_headers; }
 
@@ -35,7 +35,7 @@ public:
     int request_fd() const { return m_request_fd; }
 
     void did_finish(bool success);
-    void did_progress(Optional<u32> total_size, u32 downloaded_size);
+    void did_progress(Optional<u64> total_size, u64 downloaded_size);
     void set_status_code(u32 status_code) { m_status_code = status_code; }
     void did_request_certificates();
     void set_response_headers(HashMap<DeprecatedString, DeprecatedString, CaseInsensitiveStringTraits> const&);
@@ -50,7 +50,7 @@ private:
     i32 m_id { 0 };
     int m_request_fd { -1 }; // Passed to client.
     Optional<u32> m_status_code;
-    Optional<u32> m_total_size {};
+    Optional<u64> m_total_size {};
     size_t m_downloaded_size { 0 };
     NonnullOwnPtr<Core::File> m_output_stream;
     HashMap<DeprecatedString, DeprecatedString, CaseInsensitiveStringTraits> m_response_headers;

+ 2 - 2
Userland/Services/RequestServer/RequestClient.ipc

@@ -2,8 +2,8 @@
 
 endpoint RequestClient
 {
-    request_progress(i32 request_id, Optional<u32> total_size, u32 downloaded_size) =|
-    request_finished(i32 request_id, bool success, u32 total_size) =|
+    request_progress(i32 request_id, Optional<u64> total_size, u64 downloaded_size) =|
+    request_finished(i32 request_id, bool success, u64 total_size) =|
     headers_became_available(i32 request_id, HashMap<DeprecatedString,DeprecatedString,CaseInsensitiveStringTraits> response_headers, Optional<u32> status_code) =|
 
     // Certificate requests

+ 2 - 2
Userland/Utilities/pro.cpp

@@ -232,7 +232,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
     bool should_save_stream_data = false;
     bool following_url = false;
 
-    u32 previous_downloaded_size = 0;
+    u64 previous_downloaded_size = 0;
     u32 const report_time_in_ms = 100;
     u32 const speed_update_time_in_ms = 4000;
 
@@ -274,7 +274,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
             }
         }
 
-        request->on_progress = [&](Optional<u32> maybe_total_size, u32 downloaded_size) {
+        request->on_progress = [&](Optional<u64> maybe_total_size, u64 downloaded_size) {
             gettimeofday(&current_time, nullptr);
             timersub(&current_time, &previous_time, &time_diff);
             auto time_diff_ms = time_diff.tv_sec * 1000 + time_diff.tv_usec / 1000;