From 1678aaa5550ebf8d89b83a762fa03c2613b30916 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 13 Jun 2020 22:19:34 +0200 Subject: [PATCH] ProtocolServer+LibProtocol: Propagate HTTP status codes to clients Clients now receive HTTP status codes like 200, 404, etc. Note that a 404 with content is still considered a "successful" download from ProtocolServer's perspective. It's up to the client to interpret the status code. I'm not sure if this is the best API, but it'll work for now. --- Applications/Browser/DownloadWidget.cpp | 2 +- Libraries/LibProtocol/Client.cpp | 2 +- Libraries/LibProtocol/Download.cpp | 4 ++-- Libraries/LibProtocol/Download.h | 4 ++-- Libraries/LibWeb/Loader/ResourceLoader.cpp | 7 ++++++- Services/ProtocolServer/ClientConnection.cpp | 2 +- Services/ProtocolServer/Download.h | 3 +++ Services/ProtocolServer/HttpDownload.cpp | 1 + Services/ProtocolServer/HttpsDownload.cpp | 1 + Services/ProtocolServer/ProtocolClient.ipc | 2 +- Userland/pro.cpp | 2 +- 11 files changed, 20 insertions(+), 10 deletions(-) diff --git a/Applications/Browser/DownloadWidget.cpp b/Applications/Browser/DownloadWidget.cpp index b03cd332bb6..69d53f9c7d0 100644 --- a/Applications/Browser/DownloadWidget.cpp +++ b/Applications/Browser/DownloadWidget.cpp @@ -60,7 +60,7 @@ DownloadWidget::DownloadWidget(const URL& url) m_download->on_progress = [this](Optional total_size, u32 downloaded_size) { did_progress(total_size.value(), downloaded_size); }; - m_download->on_finish = [this](bool success, auto& payload, auto payload_storage, auto& response_headers) { + m_download->on_finish = [this](bool success, auto& payload, auto payload_storage, auto& response_headers, auto) { did_finish(success, payload, payload_storage, response_headers); }; diff --git a/Libraries/LibProtocol/Client.cpp b/Libraries/LibProtocol/Client.cpp index 303910dce25..f5e22979e42 100644 --- a/Libraries/LibProtocol/Client.cpp +++ b/Libraries/LibProtocol/Client.cpp @@ -72,7 +72,7 @@ void Client::handle(const Messages::ProtocolClient::DownloadFinished& message) { RefPtr download; if ((download = m_downloads.get(message.download_id()).value_or(nullptr))) { - download->did_finish({}, message.success(), message.total_size(), message.shbuf_id(), message.response_headers()); + download->did_finish({}, message.success(), message.status_code(), message.total_size(), message.shbuf_id(), message.response_headers()); } send_sync(message.shbuf_id()); m_downloads.remove(message.download_id()); diff --git a/Libraries/LibProtocol/Download.cpp b/Libraries/LibProtocol/Download.cpp index 616321df920..0a2a29ed687 100644 --- a/Libraries/LibProtocol/Download.cpp +++ b/Libraries/LibProtocol/Download.cpp @@ -41,7 +41,7 @@ bool Download::stop() return m_client->stop_download({}, *this); } -void Download::did_finish(Badge, bool success, u32 total_size, i32 shbuf_id, const IPC::Dictionary& response_headers) +void Download::did_finish(Badge, bool success, Optional status_code, u32 total_size, i32 shbuf_id, const IPC::Dictionary& response_headers) { if (!on_finish) return; @@ -59,7 +59,7 @@ void Download::did_finish(Badge, bool success, u32 total_size, i32 shbuf caseless_response_headers.set(name, value); }); - on_finish(success, payload, move(shared_buffer), caseless_response_headers); + on_finish(success, payload, move(shared_buffer), caseless_response_headers, status_code); } void Download::did_progress(Badge, Optional total_size, u32 downloaded_size) diff --git a/Libraries/LibProtocol/Download.h b/Libraries/LibProtocol/Download.h index 4934e54fb9e..12f7ce90528 100644 --- a/Libraries/LibProtocol/Download.h +++ b/Libraries/LibProtocol/Download.h @@ -48,10 +48,10 @@ public: int id() const { return m_download_id; } bool stop(); - Function payload_storage, const HashMap& response_headers)> on_finish; + Function payload_storage, const HashMap& response_headers, Optional status_code)> on_finish; Function total_size, u32 downloaded_size)> on_progress; - void did_finish(Badge, bool success, u32 total_size, i32 shbuf_id, const IPC::Dictionary& response_headers); + void did_finish(Badge, bool success, Optional status_code, u32 total_size, i32 shbuf_id, const IPC::Dictionary& response_headers); void did_progress(Badge, Optional total_size, u32 downloaded_size); private: diff --git a/Libraries/LibWeb/Loader/ResourceLoader.cpp b/Libraries/LibWeb/Loader/ResourceLoader.cpp index f8c4d5a3ee5..20c12e452b5 100644 --- a/Libraries/LibWeb/Loader/ResourceLoader.cpp +++ b/Libraries/LibWeb/Loader/ResourceLoader.cpp @@ -163,7 +163,7 @@ void ResourceLoader::load(const URL& url, Functionon_finish = [this, success_callback = move(success_callback), error_callback = move(error_callback)](bool success, const ByteBuffer& payload, auto, auto& response_headers) { + download->on_finish = [this, success_callback = move(success_callback), error_callback = move(error_callback)](bool success, const ByteBuffer& payload, auto, auto& response_headers, auto status_code) { --m_pending_loads; if (on_load_counter_change) on_load_counter_change(); @@ -172,6 +172,11 @@ void ResourceLoader::load(const URL& url, Function, Download& download, IPC::Dictionary response_headers; for (auto& it : download.response_headers()) response_headers.add(it.key, it.value); - post_message(Messages::ProtocolClient::DownloadFinished(download.id(), success, download.total_size().value(), buffer ? buffer->shbuf_id() : -1, response_headers)); + post_message(Messages::ProtocolClient::DownloadFinished(download.id(), success, download.status_code(), download.total_size().value(), buffer ? buffer->shbuf_id() : -1, response_headers)); m_downloads.remove(download.id()); } diff --git a/Services/ProtocolServer/Download.h b/Services/ProtocolServer/Download.h index 9bc3c7a5f7f..2cc0487a6d5 100644 --- a/Services/ProtocolServer/Download.h +++ b/Services/ProtocolServer/Download.h @@ -42,6 +42,7 @@ public: i32 id() const { return m_id; } URL url() const { return m_url; } + Optional status_code() const { return m_status_code; } Optional total_size() const { return m_total_size; } size_t downloaded_size() const { return m_downloaded_size; } const ByteBuffer& payload() const { return m_payload; } @@ -54,6 +55,7 @@ protected: void did_finish(bool success); void did_progress(Optional total_size, u32 downloaded_size); + void set_status_code(u32 status_code) { m_status_code = status_code; } void set_payload(const ByteBuffer&); void set_response_headers(const HashMap&); @@ -61,6 +63,7 @@ private: ClientConnection& m_client; i32 m_id { 0 }; URL m_url; + Optional m_status_code; Optional m_total_size {}; size_t m_downloaded_size { 0 }; ByteBuffer m_payload; diff --git a/Services/ProtocolServer/HttpDownload.cpp b/Services/ProtocolServer/HttpDownload.cpp index fd0a9862cf3..bfa22351d3d 100644 --- a/Services/ProtocolServer/HttpDownload.cpp +++ b/Services/ProtocolServer/HttpDownload.cpp @@ -36,6 +36,7 @@ HttpDownload::HttpDownload(ClientConnection& client, NonnullRefPtron_finish = [this](bool success) { if (auto* response = m_job->response()) { + set_status_code(response->code()); set_payload(response->payload()); set_response_headers(response->headers()); } diff --git a/Services/ProtocolServer/HttpsDownload.cpp b/Services/ProtocolServer/HttpsDownload.cpp index 6a578b80ab1..899c204019a 100644 --- a/Services/ProtocolServer/HttpsDownload.cpp +++ b/Services/ProtocolServer/HttpsDownload.cpp @@ -36,6 +36,7 @@ HttpsDownload::HttpsDownload(ClientConnection& client, NonnullRefPtron_finish = [this](bool success) { if (auto* response = m_job->response()) { + set_status_code(response->code()); set_payload(response->payload()); set_response_headers(response->headers()); } diff --git a/Services/ProtocolServer/ProtocolClient.ipc b/Services/ProtocolServer/ProtocolClient.ipc index 575b3ddd2b7..e4f7ab7a5b3 100644 --- a/Services/ProtocolServer/ProtocolClient.ipc +++ b/Services/ProtocolServer/ProtocolClient.ipc @@ -2,5 +2,5 @@ endpoint ProtocolClient = 13 { // Download notifications DownloadProgress(i32 download_id, Optional total_size, u32 downloaded_size) =| - DownloadFinished(i32 download_id, bool success, u32 total_size, i32 shbuf_id, IPC::Dictionary response_headers) =| + DownloadFinished(i32 download_id, bool success, Optional status_code, u32 total_size, i32 shbuf_id, IPC::Dictionary response_headers) =| } diff --git a/Userland/pro.cpp b/Userland/pro.cpp index 3ab6590cb8a..fcad52f95af 100644 --- a/Userland/pro.cpp +++ b/Userland/pro.cpp @@ -78,7 +78,7 @@ int main(int argc, char** argv) previous_downloaded_size = downloaded_size; prev_time = current_time; }; - download->on_finish = [&](bool success, auto& payload, auto, auto&) { + download->on_finish = [&](bool success, auto& payload, auto, auto&, auto) { fprintf(stderr, "\033]9;-1;\033\\"); fprintf(stderr, "\n"); if (success)