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_;