Allow sending additional headers with masque_client This CL adds the ability to send custom headers on MASQUE requests from the command line. PiperOrigin-RevId: 593797450
diff --git a/quiche/quic/masque/masque_client_bin.cc b/quiche/quic/masque/masque_client_bin.cc index 99e93d2..5ee715f 100644 --- a/quiche/quic/masque/masque_client_bin.cc +++ b/quiche/quic/masque/masque_client_bin.cc
@@ -41,6 +41,12 @@ "Allows setting MASQUE mode, currently only valid value is \"open\"."); DEFINE_QUICHE_COMMAND_LINE_FLAG( + std::string, proxy_headers, "", + "A list of HTTP headers to add to request to the MASQUE proxy. " + "Separated with colons and semicolons. " + "For example: \"name1:value1;name2:value2\"."); + +DEFINE_QUICHE_COMMAND_LINE_FLAG( bool, bring_up_tun, false, "If set to true, no URLs need to be specified and instead a TUN device " "is brought up with the assigned IP from the MASQUE CONNECT-IP server."); @@ -306,6 +312,9 @@ QUIC_LOG(INFO) << "MASQUE is connected " << masque_client->connection_id() << " in " << masque_mode << " mode"; + masque_client->masque_client_session()->set_additional_headers( + quiche::GetQuicheCommandLineFlag(FLAGS_proxy_headers)); + if (bring_up_tun) { QUIC_LOG(INFO) << "Bringing up tun"; MasqueTunSession tun_session(event_loop.get(),
diff --git a/quiche/quic/masque/masque_client_session.cc b/quiche/quic/masque/masque_client_session.cc index 57f26d1..14cf58a 100644 --- a/quiche/quic/masque/masque_client_session.cc +++ b/quiche/quic/masque/masque_client_session.cc
@@ -6,11 +6,13 @@ #include <cstring> #include <string> +#include <vector> #include "absl/algorithm/container.h" #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/strings/str_cat.h" +#include "absl/strings/str_split.h" #include "absl/strings/string_view.h" #include "quiche/quic/core/http/spdy_utils.h" #include "quiche/quic/core/quic_data_reader.h" @@ -21,6 +23,7 @@ #include "quiche/quic/tools/quic_url.h" #include "quiche/common/platform/api/quiche_googleurl.h" #include "quiche/common/platform/api/quiche_url_utils.h" +#include "quiche/common/quiche_text_utils.h" #include "quiche/spdy/core/http2_header_block.h" namespace quic { @@ -146,6 +149,7 @@ headers[":authority"] = authority; headers[":path"] = canonicalized_path; headers["connect-udp-version"] = "12"; + AddAdditionalHeaders(headers); size_t bytes_sent = stream->SendRequest(std::move(headers), /*body=*/"", /*fin=*/false); if (bytes_sent == 0) { @@ -192,6 +196,7 @@ headers[":authority"] = authority; headers[":path"] = path; headers["connect-ip-version"] = "3"; + AddAdditionalHeaders(headers); size_t bytes_sent = stream->SendRequest(std::move(headers), /*body=*/"", /*fin=*/false); if (bytes_sent == 0) { @@ -240,6 +245,7 @@ headers[":scheme"] = scheme; headers[":authority"] = authority; headers[":path"] = path; + AddAdditionalHeaders(headers); size_t bytes_sent = stream->SendRequest(std::move(headers), /*body=*/"", /*fin=*/false); if (bytes_sent == 0) { @@ -679,4 +685,22 @@ fake_addresses_.erase(fake_address.ToPackedString()); } +void MasqueClientSession::AddAdditionalHeaders( + spdy::Http2HeaderBlock& headers) const { + if (additional_headers_.empty()) { + return; + } + for (absl::string_view sp : absl::StrSplit(additional_headers_, ';')) { + quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&sp); + if (sp.empty()) { + continue; + } + std::vector<absl::string_view> kv = + absl::StrSplit(sp, absl::MaxSplits(':', 1)); + quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&kv[0]); + quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&kv[1]); + headers[kv[0]] = kv[1]; + } +} + } // namespace quic
diff --git a/quiche/quic/masque/masque_client_session.h b/quiche/quic/masque/masque_client_session.h index 9307f74..8b8331e 100644 --- a/quiche/quic/masque/masque_client_session.h +++ b/quiche/quic/masque/masque_client_session.h
@@ -93,8 +93,7 @@ const QuicConfig& config, const ParsedQuicVersionVector& supported_versions, QuicConnection* connection, const QuicServerId& server_id, - QuicCryptoClientConfig* crypto_config, - Owner* owner); + QuicCryptoClientConfig* crypto_config, Owner* owner); // Disallow copy and assign. MasqueClientSession(const MasqueClientSession&) = delete; @@ -145,6 +144,13 @@ // Removes a fake address that was previously created by GetFakeAddress(). void RemoveFakeAddress(const quiche::QuicheIpAddress& fake_address); + // Set additional HTTP headers that will be sent on all requests to the MASQUE + // proxy. Separated with colons and semicolons. + // For example: "name1:value1;name2:value2". + void set_additional_headers(absl::string_view additional_headers) { + additional_headers_ = additional_headers; + } + private: // State that the MasqueClientSession keeps for each CONNECT-UDP request. class QUIC_NO_EXPORT ConnectUdpClientState @@ -284,8 +290,11 @@ const ConnectEthernetClientState* GetOrCreateConnectEthernetClientState( EncapsulatedEthernetSession* encapsulated_ethernet_session); + void AddAdditionalHeaders(spdy::Http2HeaderBlock& headers) const; + MasqueMode masque_mode_; std::string uri_template_; + std::string additional_headers_; std::list<ConnectUdpClientState> connect_udp_client_states_; std::list<ConnectIpClientState> connect_ip_client_states_; std::list<ConnectEthernetClientState> connect_ethernet_client_states_;