MASQUE 2020-03-01 changes
diff --git a/quic/masque/masque_client_session.cc b/quic/masque/masque_client_session.cc index 79ab509..1a9fc9b 100644 --- a/quic/masque/masque_client_session.cc +++ b/quic/masque/masque_client_session.cc
@@ -6,6 +6,7 @@ #include "absl/algorithm/container.h" #include "quic/core/http/spdy_utils.h" #include "quic/core/quic_data_reader.h" +#include "quic/core/quic_utils.h" #include "common/platform/api/quiche_text_utils.h" namespace quic { @@ -198,6 +199,16 @@ } void MasqueClientSession::OnStreamClosed(QuicStreamId stream_id) { + if (QuicUtils::IsBidirectionalStreamId(stream_id, version()) && + QuicUtils::IsClientInitiatedStreamId(transport_version(), stream_id)) { + QuicSpdyClientStream* stream = + reinterpret_cast<QuicSpdyClientStream*>(GetActiveStream(stream_id)); + if (stream != nullptr) { + QUIC_DLOG(INFO) << "Stream " << stream_id + << " closed, got response headers:" + << stream->response_headers().DebugString(); + } + } for (auto it = connect_udp_client_states_.begin(); it != connect_udp_client_states_.end();) { if (it->stream()->id() == stream_id) {
diff --git a/quic/masque/masque_server_backend.cc b/quic/masque/masque_server_backend.cc index 64c36e1..6c7f7e1 100644 --- a/quic/masque/masque_server_backend.cc +++ b/quic/masque/masque_server_backend.cc
@@ -21,20 +21,20 @@ const spdy::Http2HeaderBlock& request_headers, const std::string& request_body, QuicSimpleServerBackend::RequestHandler* request_handler) { - auto path_pair = request_headers.find(":path"); - auto method_pair = request_headers.find(":method"); - auto scheme_pair = request_headers.find(":scheme"); - if (path_pair == request_headers.end() || - method_pair == request_headers.end() || - scheme_pair == request_headers.end()) { - // This request is missing required headers. - return false; - } - absl::string_view path = path_pair->second; - absl::string_view scheme = scheme_pair->second; - absl::string_view method = method_pair->second; std::string masque_path = ""; if (masque_mode_ == MasqueMode::kLegacy) { + auto path_pair = request_headers.find(":path"); + auto method_pair = request_headers.find(":method"); + auto scheme_pair = request_headers.find(":scheme"); + if (path_pair == request_headers.end() || + method_pair == request_headers.end() || + scheme_pair == request_headers.end()) { + // This request is missing required headers. + return false; + } + absl::string_view path = path_pair->second; + absl::string_view scheme = scheme_pair->second; + absl::string_view method = method_pair->second; if (scheme != "https" || method != "POST" || request_body.empty()) { // MASQUE requests MUST be a non-empty https POST. return false; @@ -45,11 +45,6 @@ return false; } masque_path = std::string(path.substr(sizeof("/.well-known/masque/") - 1)); - } else { - if (method != "CONNECT-UDP") { - // Unexpected method. - return false; - } } if (!server_authority_.empty()) {
diff --git a/quic/masque/masque_server_session.cc b/quic/masque/masque_server_session.cc index 4f065ee..78cbbf4 100644 --- a/quic/masque/masque_server_session.cc +++ b/quic/masque/masque_server_session.cc
@@ -60,13 +60,13 @@ std::unique_ptr<QuicBackendResponse> CreateBackendErrorResponse( absl::string_view status, - absl::string_view body) { + absl::string_view error_details) { spdy::Http2HeaderBlock response_headers; response_headers[":status"] = status; + response_headers["masque-debug-info"] = error_details; auto response = std::make_unique<QuicBackendResponse>(); response->set_response_type(QuicBackendResponse::REGULAR_RESPONSE); response->set_headers(std::move(response_headers)); - response->set_body(body); return response; } @@ -177,12 +177,21 @@ auto scheme_pair = request_headers.find(":scheme"); auto method_pair = request_headers.find(":method"); auto authority_pair = request_headers.find(":authority"); - if (path_pair == request_headers.end() || - scheme_pair == request_headers.end() || - method_pair == request_headers.end() || - authority_pair == request_headers.end()) { - QUIC_DLOG(ERROR) << "MASQUE request is missing required headers"; - return CreateBackendErrorResponse("400", "Missing required headers"); + if (path_pair == request_headers.end()) { + QUIC_DLOG(ERROR) << "MASQUE request is missing :path"; + return CreateBackendErrorResponse("400", "Missing :path"); + } + if (scheme_pair == request_headers.end()) { + QUIC_DLOG(ERROR) << "MASQUE request is missing :scheme"; + return CreateBackendErrorResponse("400", "Missing :scheme"); + } + if (method_pair == request_headers.end()) { + QUIC_DLOG(ERROR) << "MASQUE request is missing :method"; + return CreateBackendErrorResponse("400", "Missing :method"); + } + if (authority_pair == request_headers.end()) { + QUIC_DLOG(ERROR) << "MASQUE request is missing :authority"; + return CreateBackendErrorResponse("400", "Missing :authority"); } absl::string_view path = path_pair->second; absl::string_view scheme = scheme_pair->second;
diff --git a/quic/tools/quic_memory_cache_backend.cc b/quic/tools/quic_memory_cache_backend.cc index c67e5b3..c030732 100644 --- a/quic/tools/quic_memory_cache_backend.cc +++ b/quic/tools/quic_memory_cache_backend.cc
@@ -316,8 +316,13 @@ quic_response = GetResponse(authority->second, path->second); } - std::string request_url = - std::string(authority->second) + std::string(path->second); + std::string request_url; + if (authority != request_headers.end()) { + request_url = std::string(authority->second); + } + if (path != request_headers.end()) { + request_url += std::string(path->second); + } std::list<ServerPushInfo> resources = GetServerPushResources(request_url); QUIC_DVLOG(1) << "Fetching QUIC response from backend in-memory cache for url "
diff --git a/quic/tools/quic_simple_server_stream.cc b/quic/tools/quic_simple_server_stream.cc index 800608b..4377b56 100644 --- a/quic/tools/quic_simple_server_stream.cc +++ b/quic/tools/quic_simple_server_stream.cc
@@ -153,13 +153,24 @@ return; } - if (!QuicContainsKey(request_headers_, ":authority") || - !QuicContainsKey(request_headers_, ":path")) { - QUIC_DVLOG(1) << "Request headers do not contain :authority or :path."; + if (!QuicContainsKey(request_headers_, ":authority")) { + QUIC_DVLOG(1) << "Request headers do not contain :authority."; SendErrorResponse(); return; } + if (!QuicContainsKey(request_headers_, ":path")) { + // CONNECT and other CONNECT-like methods (such as CONNECT-UDP) do not all + // require :path to be present. + auto it = request_headers_.find(":method"); + if (it == request_headers_.end() || + !absl::StartsWith(it->second, "CONNECT")) { + QUIC_DVLOG(1) << "Request headers do not contain :path."; + SendErrorResponse(); + return; + } + } + if (quic_simple_server_backend_ == nullptr) { QUIC_DVLOG(1) << "Backend is missing."; SendErrorResponse();
diff --git a/quic/tools/quic_simple_server_stream_test.cc b/quic/tools/quic_simple_server_stream_test.cc index 5806ad7..541316a 100644 --- a/quic/tools/quic_simple_server_stream_test.cc +++ b/quic/tools/quic_simple_server_stream_test.cc
@@ -77,6 +77,9 @@ const std::string& body() const { return body_; } int content_length() const { return content_length_; } bool send_response_was_called() const { return send_response_was_called_; } + bool send_error_response_was_called() const { + return send_error_response_was_called_; + } absl::string_view GetHeader(absl::string_view key) const { auto it = request_headers_.find(key); @@ -90,8 +93,14 @@ QuicSimpleServerStream::SendResponse(); } + void SendErrorResponse() override { + send_error_response_was_called_ = true; + QuicSimpleServerStream::SendErrorResponse(); + } + private: bool send_response_was_called_ = false; + bool send_error_response_was_called_ = false; }; namespace { @@ -778,6 +787,7 @@ EXPECT_EQ("CONNECT-SILLY", StreamHeadersValue(":method")); EXPECT_EQ(body_, StreamBody()); EXPECT_TRUE(stream_->send_response_was_called()); + EXPECT_FALSE(stream_->send_error_response_was_called()); } } // namespace