diff --git a/proxygen/lib/http/coro/client/HTTPClient.cpp b/proxygen/lib/http/coro/client/HTTPClient.cpp index 3b43c59073..f4d16fbb25 100644 --- a/proxygen/lib/http/coro/client/HTTPClient.cpp +++ b/proxygen/lib/http/coro/client/HTTPClient.cpp @@ -292,7 +292,8 @@ folly::coro::Task HTTPClient::getHTTPSessionViaProxy( std::chrono::milliseconds connectTimeout, std::chrono::milliseconds readTimeout, std::string clientCertPath, - std::string clientKeyPath) { + std::string clientKeyPath, + HTTPCoroConnector::ConnectHeaderMap connectHeaders) { HTTPCoroConnector::ConnectionParams connParams; auto tlsParams = makeTLSParams(clientCertPath, clientKeyPath, kDefaultNextProtocols); @@ -308,7 +309,8 @@ folly::coro::Task HTTPClient::getHTTPSessionViaProxy( connectUnique, connectTimeout, connParams, - getSessionParams(readTimeout))); + getSessionParams(readTimeout), + std::move(connectHeaders))); co_return res; } diff --git a/proxygen/lib/http/coro/client/HTTPClient.h b/proxygen/lib/http/coro/client/HTTPClient.h index e5e5575338..0b369360f8 100644 --- a/proxygen/lib/http/coro/client/HTTPClient.h +++ b/proxygen/lib/http/coro/client/HTTPClient.h @@ -265,7 +265,9 @@ class HTTPClient { std::chrono::milliseconds connectTimeout, std::chrono::milliseconds readTimeout, std::string clientCertPath = "", - std::string clientKeyPath = ""); + std::string clientKeyPath = "", + HTTPCoroConnector::ConnectHeaderMap connectHeaders = + HTTPCoroConnector::ConnectHeaderMap()); private: static std::vector& defaultCAPaths(); diff --git a/proxygen/lib/http/coro/client/HTTPCoroConnector.cpp b/proxygen/lib/http/coro/client/HTTPCoroConnector.cpp index 3d3704f63b..d4238c6561 100644 --- a/proxygen/lib/http/coro/client/HTTPCoroConnector.cpp +++ b/proxygen/lib/http/coro/client/HTTPCoroConnector.cpp @@ -654,17 +654,26 @@ folly::coro::Task HTTPCoroConnector::proxyConnect( bool connectUnique, std::chrono::milliseconds timeout, const ConnectionParams& connParams, - const SessionParams& sessionParams) { + const SessionParams& sessionParams, + ConnectHeaderMap connectHeaders) { // egress bufer option? XLOG(DBG2) << "Sending CONNECT to " << authority; std::unique_ptr connectStream; if (connectUnique) { connectStream = co_await co_nothrow(HTTPConnectStream::connectUnique( - proxySession, std::move(reservation), authority, timeout)); + proxySession, + std::move(reservation), + authority, + timeout, + std::move(connectHeaders))); } else { connectStream = co_await co_nothrow(HTTPConnectStream::connect( - proxySession, std::move(reservation), authority, timeout)); + proxySession, + std::move(reservation), + authority, + timeout, + std::move(connectHeaders))); } auto peerAddr = connectStream->peerAddr_; co_return co_await co_nothrow(connectImpl(proxySession->getEventBase(), diff --git a/proxygen/lib/http/coro/client/HTTPCoroConnector.h b/proxygen/lib/http/coro/client/HTTPCoroConnector.h index 7d11a65c5a..1007c7c050 100644 --- a/proxygen/lib/http/coro/client/HTTPCoroConnector.h +++ b/proxygen/lib/http/coro/client/HTTPCoroConnector.h @@ -24,6 +24,7 @@ #include #include "proxygen/lib/http/coro/HTTPCoroSession.h" +#include "proxygen/lib/http/coro/transport/HTTPConnectStream.h" #include #include #include @@ -177,7 +178,10 @@ class HTTPCoroConnector { const SessionParams& sessionParams = defaultSessionParams(), std::chrono::milliseconds happyEyeballsTimeout = kHappyEyeballsDelay); - // For HTTP connections over HTTP CONNECT + // For HTTP connections over HTTP CONNECT. `connectHeaders` is forwarded + // to `HTTPConnectStream::connect[Unique]` so callers can inject + // `Proxy-Authorization` and similar. + using ConnectHeaderMap = HTTPConnectStream::RequestHeaderMap; static folly::coro::Task proxyConnect( HTTPCoroSession* proxySession, HTTPCoroSession::RequestReservation reservation, @@ -185,7 +189,8 @@ class HTTPCoroConnector { bool connectUnique, std::chrono::milliseconds timeout, const ConnectionParams& connParams = defaultConnectionParams(), - const SessionParams& sessionParams = defaultSessionParams()); + const SessionParams& sessionParams = defaultSessionParams(), + ConnectHeaderMap connectHeaders = ConnectHeaderMap()); static folly::coro::Task connect( folly::EventBase* evb, diff --git a/proxygen/lib/http/coro/client/test/HTTPClientTests.cpp b/proxygen/lib/http/coro/client/test/HTTPClientTests.cpp index 0bb2ea9969..dffdc64353 100644 --- a/proxygen/lib/http/coro/client/test/HTTPClientTests.cpp +++ b/proxygen/lib/http/coro/client/test/HTTPClientTests.cpp @@ -669,6 +669,10 @@ CO_TEST_P_X(HTTPClientTests, Connect) { timeout)); EXPECT_FALSE(sess.hasException()); + HTTPCoroConnector::ConnectHeaderMap connectHeaders = { + {"Proxy-Authorization", "Basic dGVzdA=="}, + {"X-Proxy-Trace", "trace-id"}}; + testHandler_->expectedConnectHeaders_ = connectHeaders; auto sessViaProxy = co_await co_awaitTry( HTTPClient::getHTTPSessionViaProxy(*sess, "example.com", @@ -676,7 +680,10 @@ CO_TEST_P_X(HTTPClientTests, Connect) { true, transportImpl(TransportType::TCP), timeout, - timeout)); + timeout, + /*clientCertPath=*/"", + /*clientKeyPath=*/"", + std::move(connectHeaders))); EXPECT_FALSE(sessViaProxy.hasException()); (*sessViaProxy)->initiateDrain(); diff --git a/proxygen/lib/http/coro/client/test/HTTPClientTestsCommon.cpp b/proxygen/lib/http/coro/client/test/HTTPClientTestsCommon.cpp index e3e9e3c3bf..342f93b2d7 100644 --- a/proxygen/lib/http/coro/client/test/HTTPClientTestsCommon.cpp +++ b/proxygen/lib/http/coro/client/test/HTTPClientTestsCommon.cpp @@ -94,6 +94,10 @@ folly::coro::Task TestHandler::handleRequest( EXPECT_EQ(request->isSecure(), ctx->getSetupTransportInfo().secure); if (request->getMethod() == HTTPMethod::CONNECT) { + for (const auto& expectedHeader : expectedConnectHeaders_) { + EXPECT_EQ(request->getHeaders().getSingleOrEmpty(expectedHeader.first), + expectedHeader.second); + } // Hack to silence the expect in connectHandler request->getHeaders().add("Foo", "Bar"); auto hybridSource = new HTTPHybridSource(std::move(headerEvent.headers), diff --git a/proxygen/lib/http/coro/client/test/HTTPClientTestsCommon.h b/proxygen/lib/http/coro/client/test/HTTPClientTestsCommon.h index f3b69197e8..ebce767750 100644 --- a/proxygen/lib/http/coro/client/test/HTTPClientTestsCommon.h +++ b/proxygen/lib/http/coro/client/test/HTTPClientTestsCommon.h @@ -55,6 +55,7 @@ class TestHandler : public HTTPHandler { HTTPSourceHolder requestSource) override; ConnectHandler connectHandler_; + HTTPCoroConnector::ConnectHeaderMap expectedConnectHeaders_; }; class HTTPClientTests : public TestWithParam {