diff --git a/Userland/Libraries/LibHTTP/HttpRequest.cpp b/Userland/Libraries/LibHTTP/HttpRequest.cpp index 32e1c3fbc9..2bf198290b 100644 --- a/Userland/Libraries/LibHTTP/HttpRequest.cpp +++ b/Userland/Libraries/LibHTTP/HttpRequest.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -57,7 +58,7 @@ ByteBuffer HttpRequest::to_raw_request() const builder.append("Connection: close\r\n"); if (!m_body.is_empty()) { builder.appendff("Content-Length: {}\r\n\r\n", m_body.size()); - builder.append((const char*)m_body.data(), m_body.size()); + builder.append((char const*)m_body.data(), m_body.size()); } builder.append("\r\n"); return builder.to_byte_buffer(); @@ -169,10 +170,41 @@ Optional HttpRequest::from_raw_request(ReadonlyBytes raw_request) return request; } -void HttpRequest::set_headers(const HashMap& headers) +void HttpRequest::set_headers(HashMap const& headers) { for (auto& it : headers) m_headers.append({ it.key, it.value }); } +Optional HttpRequest::get_http_basic_authentication_header(URL const& url) +{ + if (!url.includes_credentials()) + return {}; + StringBuilder builder; + builder.append(url.username()); + builder.append(':'); + builder.append(url.password()); + auto token = encode_base64(builder.to_string().bytes()); + builder.clear(); + builder.append("Basic "); + builder.append(token); + return Header { "Authorization", builder.to_string() }; +} + +Optional HttpRequest::parse_http_basic_authentication_header(String const& value) +{ + if (!value.starts_with("Basic ", AK::CaseSensitivity::CaseInsensitive)) + return {}; + auto token = value.substring_view(6); + if (token.is_empty()) + return {}; + auto decoded_token = String::copy(decode_base64(token)); + auto colon_index = decoded_token.find(':'); + if (!colon_index.has_value()) + return {}; + auto username = decoded_token.substring_view(0, colon_index.value()); + auto password = decoded_token.substring_view(colon_index.value() + 1); + return BasicAuthenticationCredentials { username, password }; +} + } diff --git a/Userland/Libraries/LibHTTP/HttpRequest.h b/Userland/Libraries/LibHTTP/HttpRequest.h index a3b28d61b6..0c0a3f4a42 100644 --- a/Userland/Libraries/LibHTTP/HttpRequest.h +++ b/Userland/Libraries/LibHTTP/HttpRequest.h @@ -29,28 +29,35 @@ public: String value; }; + struct BasicAuthenticationCredentials { + String username; + String password; + }; + HttpRequest(); ~HttpRequest(); - const String& resource() const { return m_resource; } - const Vector
& headers() const { return m_headers; } + String const& resource() const { return m_resource; } + Vector
const& headers() const { return m_headers; } - const URL& url() const { return m_url; } - void set_url(const URL& url) { m_url = url; } + URL const& url() const { return m_url; } + void set_url(URL const& url) { m_url = url; } Method method() const { return m_method; } void set_method(Method method) { m_method = method; } - const ByteBuffer& body() const { return m_body; } + ByteBuffer const& body() const { return m_body; } void set_body(ReadonlyBytes body) { m_body = ByteBuffer::copy(body); } void set_body(ByteBuffer&& body) { m_body = move(body); } String method_name() const; ByteBuffer to_raw_request() const; - void set_headers(const HashMap&); + void set_headers(HashMap const&); static Optional from_raw_request(ReadonlyBytes); + static Optional
get_http_basic_authentication_header(URL const&); + static Optional parse_http_basic_authentication_header(String const&); private: URL m_url;