Quellcode durchsuchen

LibHTTP+WebServer: Add querystring support

Split the path from querystring when determining the requested resource.
0xbigshaq vor 3 Jahren
Ursprung
Commit
af46734497

+ 11 - 1
Userland/Libraries/LibHTTP/HttpRequest.cpp

@@ -182,8 +182,18 @@ Optional<HttpRequest> HttpRequest::from_raw_request(ReadonlyBytes raw_request)
     else
         return {};
 
-    request.m_resource = URL::percent_decode(resource);
     request.m_headers = move(headers);
+    auto url_parts = resource.split_limit('?', 2, true);
+
+    request.m_url.set_cannot_be_a_base_url(true);
+    if (url_parts.size() == 2) {
+        request.m_resource = url_parts[0];
+        request.m_url.set_paths({ url_parts[0] });
+        request.m_url.set_query(url_parts[1]);
+    } else {
+        request.m_resource = resource;
+        request.m_url.set_paths({ resource });
+    }
 
     return request;
 }

+ 4 - 3
Userland/Services/WebServer/Client.cpp

@@ -98,6 +98,7 @@ ErrorOr<bool> Client::handle_request(ReadonlyBytes raw_request)
     if (!request_or_error.has_value())
         return false;
     auto& request = request_or_error.value();
+    auto resource_decoded = URL::percent_decode(request.resource());
 
     if constexpr (WEBSERVER_DEBUG) {
         dbgln("Got HTTP request: {} {}", request.method_name(), request.resource());
@@ -120,7 +121,7 @@ ErrorOr<bool> Client::handle_request(ReadonlyBytes raw_request)
         }
     }
 
-    auto requested_path = LexicalPath::join("/"sv, request.resource()).string();
+    auto requested_path = LexicalPath::join("/"sv, resource_decoded).string();
     dbgln_if(WEBSERVER_DEBUG, "Canonical requested path: '{}'", requested_path);
 
     StringBuilder path_builder;
@@ -130,7 +131,7 @@ ErrorOr<bool> Client::handle_request(ReadonlyBytes raw_request)
 
     if (Core::File::is_directory(real_path)) {
 
-        if (!request.resource().ends_with('/')) {
+        if (!resource_decoded.ends_with('/')) {
             StringBuilder red;
 
             red.append(requested_path);
@@ -362,7 +363,7 @@ ErrorOr<void> Client::send_error_response(unsigned code, HTTP::HttpRequest const
 
 void Client::log_response(unsigned code, HTTP::HttpRequest const& request)
 {
-    outln("{} :: {:03d} :: {} {}", Core::DateTime::now().to_string(), code, request.method_name(), request.resource());
+    outln("{} :: {:03d} :: {} {}", Core::DateTime::now().to_string(), code, request.method_name(), request.url().serialize().substring(1));
 }
 
 bool Client::verify_credentials(Vector<HTTP::HttpRequest::Header> const& headers)