Skip to content

Commit

Permalink
Fix host header for connect proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
algesten committed Jan 6, 2025
1 parent 423aa8f commit a9dcbbc
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 15 deletions.
15 changes: 8 additions & 7 deletions src/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,16 +211,17 @@ impl<In: Transport> Connector<In> for ConnectProxyConnector {

let mut w = TransportAdapter::new(transport);

let uri = &details.uri;
uri.ensure_valid_url()?;
// unwrap is ok because run.rs will construct the ConnectionDetails
// such that CONNECT proxy _must_ have the `proxied` field set.
let proxied = details.proxied.unwrap();
proxied.ensure_valid_url()?;

// All these unwrap() are ok because ensure_valid_uri() above checks them.
let host = uri.host().unwrap();
let port = uri
let proxied_host = proxied.host().unwrap();
let proxied_port = proxied
.port_u16()
.unwrap_or(uri.scheme().unwrap().default_port().unwrap());
.unwrap_or(proxied.scheme().unwrap().default_port().unwrap());

write!(w, "CONNECT {}:{} HTTP/1.1\r\n", host, port)?;
write!(w, "CONNECT {}:{} HTTP/1.1\r\n", proxied_host, proxied_port)?;
write!(w, "Host: {}:{}\r\n", proxy.host(), proxy.port())?;
if let Some(v) = details.config.user_agent().as_str(DEFAULT_USER_AGENT) {
write!(w, "User-Agent: {}\r\n", v)?;
Expand Down
19 changes: 11 additions & 8 deletions src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,23 +315,25 @@ fn add_headers(
fn connect(
agent: &Agent,
config: &Config,
uri: &Uri,
wanted_uri: &Uri,
timings: &mut CallTimings,
) -> Result<Connection, Error> {
// If we're using a CONNECT proxy, we need to resolve that hostname.
let maybe_connect_uri = config.connect_proxy_uri();

let effective_uri = maybe_connect_uri.unwrap_or(uri);
let (uri, proxied) = if let Some(connect_uri) = maybe_connect_uri {
(connect_uri, Some(wanted_uri))
} else {
(wanted_uri, None)
};

// Before resolving the URI we need to ensure it is a full URI. We
// cannot make requests with partial uri like "/path".
effective_uri.ensure_valid_url()?;
uri.ensure_valid_url()?;

let addrs = agent.resolver.resolve(
effective_uri,
config,
timings.next_timeout(Timeout::Resolve),
)?;
let addrs = agent
.resolver
.resolve(uri, config, timings.next_timeout(Timeout::Resolve))?;

timings.record_time(Timeout::Resolve);

Expand All @@ -342,6 +344,7 @@ fn connect(
config,
now: timings.now(),
timeout: timings.next_timeout(Timeout::Connect),
proxied,
};

let connection = agent.pool.connect(&details, config.max_idle_age().into())?;
Expand Down
11 changes: 11 additions & 0 deletions src/unversioned/transport/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ where
/// The parameters needed to create a [`Transport`].
pub struct ConnectionDetails<'a> {
/// Full uri that is being requested.
///
/// In the case of CONNECT (HTTP) proxy, this is the URI of the
/// proxy, and the actual URI is in the `proxied` field.
pub uri: &'a Uri,

/// The resolved IP address + port for the uri being requested. See [`Resolver`].
Expand All @@ -196,6 +199,14 @@ pub struct ConnectionDetails<'a> {
/// The next timeout for making the connection.
// TODO(martin): Make mechanism to lower duration for each step in the connector chain.
pub timeout: NextTimeout,

/// In case of CONNECT (HTTP) proxy, this is the actual requested
/// uri that will go through the proxy.
///
/// This ends up in the connect line like `CONNECT host:port HTTP/1.1`.
///
/// For socks proxy it is `None`.
pub proxied: Option<&'a Uri>,
}

impl<'a> ConnectionDetails<'a> {
Expand Down

0 comments on commit a9dcbbc

Please sign in to comment.