Properly handle query parameters in MASQUE/OHTTP test code

In HTTP/2 and HTTP/3, the ":path" pseudo-header is poorly named in that it carries not only the path but also the query parameters. That confusion led to bugs in this codebase where only the path was sent or acted upon. This CL fixes that by sending both and making sure to ignore the query upon receipt when relevant.

PiperOrigin-RevId: 847141777
diff --git a/quiche/quic/masque/masque_ohttp_client.cc b/quiche/quic/masque/masque_ohttp_client.cc
index 003ef84..8461afb 100644
--- a/quiche/quic/masque/masque_ohttp_client.cc
+++ b/quiche/quic/masque/masque_ohttp_client.cc
@@ -100,7 +100,7 @@
   request.headers[":method"] = "GET";
   request.headers[":scheme"] = url.scheme();
   request.headers[":authority"] = url.HostPort();
-  request.headers[":path"] = url.path();
+  request.headers[":path"] = url.PathParamsQuery();
   request.headers["accept"] = "application/ohttp-keys";
 
   QUICHE_ASSIGN_OR_RETURN(key_fetch_request_id_,
@@ -209,7 +209,7 @@
   control_data.method = post_data_.empty() ? "GET" : "POST";
   control_data.scheme = url.scheme();
   control_data.authority = url.HostPort();
-  control_data.path = url.path();
+  control_data.path = url.PathParamsQuery();
   BinaryHttpRequest binary_request(control_data);
   binary_request.set_body(post_data_);
   absl::StatusOr<std::string> encoded_request = binary_request.Serialize();
@@ -232,7 +232,7 @@
   request.headers[":method"] = "POST";
   request.headers[":scheme"] = relay_url_.scheme();
   request.headers[":authority"] = relay_url_.HostPort();
-  request.headers[":path"] = relay_url_.path();
+  request.headers[":path"] = relay_url_.PathParamsQuery();
   request.headers["content-type"] = "message/ohttp-req";
   request.body = ohttp_request->EncapsulateAndSerialize();
   absl::StatusOr<RequestId> request_id =
diff --git a/quiche/quic/masque/masque_tcp_client_bin.cc b/quiche/quic/masque/masque_tcp_client_bin.cc
index 1779999..cf86302 100644
--- a/quiche/quic/masque/masque_tcp_client_bin.cc
+++ b/quiche/quic/masque/masque_tcp_client_bin.cc
@@ -454,7 +454,7 @@
   }
 
   void SendH1Request() {
-    std::string request = absl::StrCat("GET ", url_.path(),
+    std::string request = absl::StrCat("GET ", url_.PathParamsQuery(),
                                        " HTTP/1.1\r\nHost: ", url_.HostPort(),
                                        "\r\nConnection: close\r\n\r\n");
     QUICHE_DVLOG(1) << "Sending h1 request of length " << request.size()
@@ -481,7 +481,7 @@
     headers[":method"] = "GET";
     headers[":scheme"] = url_.scheme();
     headers[":authority"] = url_.HostPort();
-    headers[":path"] = url_.path();
+    headers[":path"] = url_.PathParamsQuery();
     stream_id_ = h2_connection_->SendRequest(headers, std::string());
     h2_connection_->AttemptToSend();
     if (stream_id_ >= 0) {
diff --git a/quiche/quic/masque/masque_tcp_server_bin.cc b/quiche/quic/masque/masque_tcp_server_bin.cc
index b373462..9abc234 100644
--- a/quiche/quic/masque/masque_tcp_server_bin.cc
+++ b/quiche/quic/masque/masque_tcp_server_bin.cc
@@ -540,7 +540,7 @@
     request.headers[":method"] = "POST";
     request.headers[":scheme"] = relay_gateway_url.scheme();
     request.headers[":authority"] = relay_gateway_url.HostPort();
-    request.headers[":path"] = relay_gateway_url.path();
+    request.headers[":path"] = relay_gateway_url.PathParamsQuery();
     request.headers["content-type"] = "message/ohttp-req";
     request.body = encapsulated_request;
     absl::StatusOr<RequestId> request_id =
@@ -561,7 +561,7 @@
     request.headers[":method"] = "GET";
     request.headers[":scheme"] = key_proxy_url.scheme();
     request.headers[":authority"] = key_proxy_url.HostPort();
-    request.headers[":path"] = key_proxy_url.path();
+    request.headers[":path"] = key_proxy_url.PathParamsQuery();
     request.headers["accept"] = "application/ohttp-keys";
     absl::StatusOr<RequestId> request_id =
         connection_pool_.SendRequest(request);
@@ -581,21 +581,27 @@
     std::string response_body;
     auto path_pair = headers.find(":path");
     auto method_pair = headers.find(":method");
-    auto content_type_pair = headers.find("content-type");
-    auto accept_pair = headers.find("accept");
     if (path_pair == headers.end() || method_pair == headers.end()) {
       // This should never happen because the h2 adapter should have rejected
       // the request, but handle it gracefully just in case.
       response_headers[":status"] = "400";
       response_body = "Request missing pseudo-headers";
-    } else if (!gateway_path_.empty() && path_pair->second == gateway_path_ &&
-               masque_ohttp_gateway_ && method_pair->second == "GET" &&
-               accept_pair != headers.end() &&
-               accept_pair->second == "application/ohttp-keys") {
+      connection->SendResponse(stream_id, response_headers, response_body);
+      return;
+    }
+    std::vector<absl::string_view> path_parts =
+        absl::StrSplit(path_pair->second, absl::MaxSplits('?', 1));
+    absl::string_view path = path_parts[0];
+    auto content_type_pair = headers.find("content-type");
+    auto accept_pair = headers.find("accept");
+    if (!gateway_path_.empty() && path == gateway_path_ &&
+        masque_ohttp_gateway_ && method_pair->second == "GET" &&
+        accept_pair != headers.end() &&
+        accept_pair->second == "application/ohttp-keys") {
       response_headers[":status"] = "200";
       response_headers["content-type"] = "application/ohttp-keys";
       response_body = masque_ohttp_gateway_->concatenated_keys();
-    } else if (auto key_proxy_pair = key_proxy_urls_.find(path_pair->second);
+    } else if (auto key_proxy_pair = key_proxy_urls_.find(path);
                key_proxy_pair != key_proxy_urls_.end() &&
                method_pair->second == "GET" && accept_pair != headers.end() &&
                accept_pair->second == "application/ohttp-keys" &&
@@ -606,11 +612,11 @@
         return;
       } else {
         QUICHE_LOG(ERROR) << "Failed to handle OHTTP key proxy request for "
-                          << path_pair->second << ": " << status;
+                          << path << ": " << status;
         response_headers[":status"] = "500";
         response_body = status.message();
       }
-    } else if (auto relay_pair = relay_gateway_urls_.find(path_pair->second);
+    } else if (auto relay_pair = relay_gateway_urls_.find(path);
                relay_pair != relay_gateway_urls_.end() &&
                method_pair->second == "POST" &&
                content_type_pair != headers.end() &&
@@ -620,12 +626,12 @@
       if (status.ok()) {
         return;
       } else {
-        QUICHE_LOG(ERROR) << "Failed to handle OHTTP relay request for "
-                          << path_pair->second << ": " << status;
+        QUICHE_LOG(ERROR) << "Failed to handle OHTTP relay request for " << path
+                          << ": " << status;
         response_headers[":status"] = "500";
         response_body = status.message();
       }
-    } else if (!gateway_path_.empty() && path_pair->second == gateway_path_ &&
+    } else if (!gateway_path_.empty() && path == gateway_path_ &&
                method_pair->second == "POST" &&
                content_type_pair != headers.end() &&
                content_type_pair->second == "message/ohttp-req") {
@@ -639,7 +645,7 @@
                           << status;
         response_body = status.message();
       }
-    } else if (method_pair->second == "GET" && path_pair->second == "/") {
+    } else if (method_pair->second == "GET" && path == "/") {
       response_headers[":status"] = "200";
       response_body = "<h1>This is a response body</h1>";
     } else {