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