From dc8be499e6e55404a329fac93c663a00961e81bf Mon Sep 17 00:00:00 2001 From: Thomas Keppler Date: Tue, 20 Dec 2022 16:46:30 +0100 Subject: [PATCH] WebServer: Use new String type internally as much as possible Here, we try to use the new String type for everything internal, keeping the public interface and the interface to other code the same. --- Userland/Services/WebServer/Client.cpp | 31 ++++++++++++++++---------- Userland/Services/WebServer/Client.h | 8 ++++--- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/Userland/Services/WebServer/Client.cpp b/Userland/Services/WebServer/Client.cpp index 2291d22851..f9dd8ec2ba 100644 --- a/Userland/Services/WebServer/Client.cpp +++ b/Userland/Services/WebServer/Client.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2020, Andreas Kling * Copyright (c) 2021, Max Wipfli + * Copyright (c) 2022, Thomas Keppler * * SPDX-License-Identifier: BSD-2-Clause */ @@ -116,21 +117,23 @@ ErrorOr Client::handle_request(ReadonlyBytes raw_request) if (Configuration::the().credentials().has_value()) { bool has_authenticated = verify_credentials(request.headers()); if (!has_authenticated) { - TRY(send_error_response(401, request, { "WWW-Authenticate: Basic realm=\"WebServer\", charset=\"UTF-8\"" })); + auto const basic_auth_header = TRY(String::from_utf8("WWW-Authenticate: Basic realm=\"WebServer\", charset=\"UTF-8\""sv)); + Vector headers {}; + TRY(headers.try_append(basic_auth_header)); + TRY(send_error_response(401, request, move(headers))); return false; } } - auto requested_path = LexicalPath::join("/"sv, resource_decoded).string(); + auto requested_path = TRY(String::from_deprecated_string(LexicalPath::join("/"sv, resource_decoded).string())); dbgln_if(WEBSERVER_DEBUG, "Canonical requested path: '{}'", requested_path); StringBuilder path_builder; path_builder.append(Configuration::the().document_root_path()); path_builder.append(requested_path); - auto real_path = path_builder.to_deprecated_string(); - - if (Core::File::is_directory(real_path)) { + auto real_path = TRY(path_builder.to_string()); + if (Core::File::is_directory(real_path.bytes_as_string_view())) { if (!resource_decoded.ends_with('/')) { StringBuilder red; @@ -144,7 +147,7 @@ ErrorOr Client::handle_request(ReadonlyBytes raw_request) StringBuilder index_html_path_builder; index_html_path_builder.append(real_path); index_html_path_builder.append("/index.html"sv); - auto index_html_path = index_html_path_builder.to_deprecated_string(); + auto index_html_path = TRY(index_html_path_builder.to_string()); if (!Core::File::exists(index_html_path)) { TRY(handle_directory_listing(requested_path, real_path, request)); return true; @@ -152,7 +155,7 @@ ErrorOr Client::handle_request(ReadonlyBytes raw_request) real_path = index_html_path; } - auto file = Core::File::construct(real_path); + auto file = Core::File::construct(real_path.bytes_as_string_view()); if (!file->open(Core::OpenMode::ReadOnly)) { TRY(send_error_response(404, request)); return false; @@ -165,7 +168,11 @@ ErrorOr Client::handle_request(ReadonlyBytes raw_request) Core::InputFileStream stream { file }; - TRY(send_response(stream, request, { .type = Core::guess_mime_type_based_on_filename(real_path), .length = TRY(Core::File::size(real_path)) })); + auto const info = ContentInfo { + .type = TRY(String::from_deprecated_string(Core::guess_mime_type_based_on_filename(real_path.bytes_as_string_view()))), + .length = TRY(Core::File::size(real_path.bytes_as_string_view())) + }; + TRY(send_response(stream, request, move(info))); return true; } @@ -255,7 +262,7 @@ static DeprecatedString file_image_data() return cache; } -ErrorOr Client::handle_directory_listing(DeprecatedString const& requested_path, DeprecatedString const& real_path, HTTP::HttpRequest const& request) +ErrorOr Client::handle_directory_listing(String const& requested_path, String const& real_path, HTTP::HttpRequest const& request) { StringBuilder builder; @@ -278,7 +285,7 @@ ErrorOr Client::handle_directory_listing(DeprecatedString const& requested builder.append("
\n"sv); builder.append("\n"sv); - Core::DirIterator dt(real_path); + Core::DirIterator dt(real_path.bytes_as_string_view()); Vector names; while (dt.has_next()) names.append(dt.next_path()); @@ -331,10 +338,10 @@ ErrorOr Client::handle_directory_listing(DeprecatedString const& requested auto response = builder.to_deprecated_string(); InputMemoryStream stream { response.bytes() }; - return send_response(stream, request, { .type = "text/html", .length = response.length() }); + return send_response(stream, request, { .type = TRY(String::from_utf8("text/html"sv)), .length = response.length() }); } -ErrorOr Client::send_error_response(unsigned code, HTTP::HttpRequest const& request, Vector const& headers) +ErrorOr Client::send_error_response(unsigned code, HTTP::HttpRequest const& request, Vector const& headers) { auto reason_phrase = HTTP::HttpResponse::reason_phrase_for_code(code); diff --git a/Userland/Services/WebServer/Client.h b/Userland/Services/WebServer/Client.h index 4e23bf563a..c93176ed11 100644 --- a/Userland/Services/WebServer/Client.h +++ b/Userland/Services/WebServer/Client.h @@ -1,11 +1,13 @@ /* * Copyright (c) 2020, Andreas Kling + * Copyright (c) 2022, Thomas Keppler * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once +#include #include #include #include @@ -23,17 +25,17 @@ private: Client(NonnullOwnPtr, Core::Object* parent); struct ContentInfo { - DeprecatedString type; + String type; size_t length {}; }; ErrorOr handle_request(ReadonlyBytes); 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 = {}); + ErrorOr send_error_response(unsigned code, HTTP::HttpRequest const&, Vector const& headers = {}); void die(); void log_response(unsigned code, HTTP::HttpRequest const&); - ErrorOr handle_directory_listing(DeprecatedString const& requested_path, DeprecatedString const& real_path, HTTP::HttpRequest const&); + ErrorOr handle_directory_listing(String const& requested_path, String const& real_path, HTTP::HttpRequest const&); bool verify_credentials(Vector const&); NonnullOwnPtr m_socket;