diff --git a/Userland/Services/WebServer/Client.cpp b/Userland/Services/WebServer/Client.cpp index 95dc899560b..d8675f25474 100644 --- a/Userland/Services/WebServer/Client.cpp +++ b/Userland/Services/WebServer/Client.cpp @@ -164,11 +164,11 @@ ErrorOr Client::handle_request(ReadonlyBytes raw_request) Core::InputFileStream stream { file }; - TRY(send_response(stream, request, Core::guess_mime_type_based_on_filename(real_path))); + TRY(send_response(stream, request, { .type = Core::guess_mime_type_based_on_filename(real_path), .length = TRY(Core::File::size(real_path)) })); return true; } -ErrorOr Client::send_response(InputStream& response, HTTP::HttpRequest const& request, String const& content_type) +ErrorOr Client::send_response(InputStream& response, HTTP::HttpRequest const& request, ContentInfo content_info) { StringBuilder builder; builder.append("HTTP/1.0 200 OK\r\n"); @@ -176,9 +176,8 @@ ErrorOr Client::send_response(InputStream& response, HTTP::HttpRequest con builder.append("X-Frame-Options: SAMEORIGIN\r\n"); builder.append("X-Content-Type-Options: nosniff\r\n"); builder.append("Pragma: no-cache\r\n"); - builder.append("Content-Type: "); - builder.append(content_type); - builder.append("\r\n"); + builder.appendff("Content-Type: {}\r\n", content_info.type); + builder.appendff("Content-Length: {}\r\n", content_info.length); builder.append("\r\n"); auto builder_contents = builder.to_byte_buffer(); @@ -326,31 +325,33 @@ ErrorOr Client::handle_directory_listing(String const& requested_path, Str auto response = builder.to_string(); InputMemoryStream stream { response.bytes() }; - return send_response(stream, request, "text/html"); + return send_response(stream, request, { .type = "text/html", .length = response.length() }); } ErrorOr Client::send_error_response(unsigned code, HTTP::HttpRequest const& request, Vector const& headers) { auto reason_phrase = HTTP::HttpResponse::reason_phrase_for_code(code); - StringBuilder builder; - builder.appendff("HTTP/1.0 {} ", code); - builder.append(reason_phrase); - builder.append("\r\n"); + + StringBuilder content_builder; + content_builder.append("

"); + content_builder.appendff("{} ", code); + content_builder.append(reason_phrase); + content_builder.append("

"); + + StringBuilder header_builder; + header_builder.appendff("HTTP/1.0 {} ", code); + header_builder.append(reason_phrase); + header_builder.append("\r\n"); for (auto& header : headers) { - builder.append(header); - builder.append("\r\n"); + header_builder.append(header); + header_builder.append("\r\n"); } - builder.append("Content-Type: text/html; charset=UTF-8\r\n"); - - builder.append("\r\n"); - builder.append("

"); - builder.appendff("{} ", code); - builder.append(reason_phrase); - builder.append("

"); - - auto builder_contents = builder.to_byte_buffer(); - TRY(m_socket->write(builder_contents)); + header_builder.append("Content-Type: text/html; charset=UTF-8\r\n"); + header_builder.appendff("Content-Length: {}\r\n", content_builder.length()); + header_builder.append("\r\n"); + TRY(m_socket->write(header_builder.to_byte_buffer())); + TRY(m_socket->write(content_builder.to_byte_buffer())); log_response(code, request); return {}; diff --git a/Userland/Services/WebServer/Client.h b/Userland/Services/WebServer/Client.h index 98ddfdc654a..b817c357388 100644 --- a/Userland/Services/WebServer/Client.h +++ b/Userland/Services/WebServer/Client.h @@ -22,8 +22,13 @@ public: private: Client(NonnullOwnPtr, Core::Object* parent); + struct ContentInfo { + String type; + size_t length {}; + }; + ErrorOr handle_request(ReadonlyBytes); - ErrorOr send_response(InputStream&, HTTP::HttpRequest const&, String const& content_type); + ErrorOr send_response(InputStream&, HTTP::HttpRequest const&, ContentInfo); ErrorOr send_redirect(StringView redirect, HTTP::HttpRequest const&); ErrorOr send_error_response(unsigned code, HTTP::HttpRequest const&, Vector const& headers = {}); void die();