Filename: 365-http-connect-ext.md
Title: Extensions for HTTP CONNECT support
Author: Nick Mathewson
Created: 10 June 2025
Status: Open
Introduction and scope
The C tor implementation supports HTTP CONNECT as an alternative to SOCKS for applications to use when negotiating connections. As of this writing, we have a draft specification for C tor's current behavior
There are a few reasons to prefer HTTP CONNECT over SOCKS:
- It is more readily extensible, and supports named headers in requests and responses.
- It is supported by many applications by which SOCKS is not.
For these reasons, we'd like to add support in Arti as well. But before we do so, it would be a good idea to bring HTTP CONNECT up to par with SOCKS in terms of the features we support with it.
This proposal describes changes and extensions to our HTTP CONNECT behavior.
Changes to current HTTP CONNECT behavior
These are changes to the behavior implemented in C tor, and described in the draft specification. They should be implemented in C tor as well as Arti.
Improved error codes
END_REASON_RESOLVEFAILED
should produce 503; currently it produces 404.END_REASON_NOROUTE
should produce 503; currently it produces 404.
Limited use of Proxy-Authorization or stream isolation
Currently we look at the Proxy-Authorization
header
as a possible source of stream isolation.
This is by analogy to our use of SOCKS usernames and passwords
for stream isolation.
Ordinarily, we prefer that applications should use
the X-Tor-Stream-Isolation
header for this purpose instead:
we only allow Proxy-Authorization
in order to support
applications with janky HTTP libraries
that do not support adding arbitrary headers.
We will retain our current Proxy-Authorization
behavior,
for backward compatibility;
however, we will specify that applications wishing to use this behavior
in the future SHOULD set the auth-scheme to "Basic",
with a username of x-tor
, and an arbitrary password,
all encoded as specified in RFC 7617.
We will also specify that proxies SHOULD warn if a Proxy-Authorization
in any other format is provided.
Additional features
The features in this section are meant to be proposed independently. We anticipate that, after discussion, some will be approved and some will not.
For each feature, we'll describe whether it should be implemented in Arti only, or in both Arti and C Tor.
X-Tor-RPC-Target
: Arti RPC support
We reserve the header "X-Tor-RPC-Target" to contain an RPC Object ID, to be used as a target for an RPC request.
Implementations SHOULD reject such requests if the target RPC object does not exist.
Implementations that do not support Arti RPC should reject requests containing this header.
(Arti should implement RPC behavior; C tor should implement "reject" behavior.)
X-Tor-Request-Failed
Extended error codes
When a connection closes before it can be established, we currently communicate the failure reason in the HTTP status code.
We will also include a X-Tor-Request-Failed
header indicating
one or more reasons why the connection could not be completed.
This will be a space-separated list of tokens.
The specified members of this list will at
minimum correspond to all the current END reasons,
and all the onion-service-specific SOCKS failure codes.
(Arti only.)
X-Tor-Proxy
: Indication for Tor proxy protocol support
We should specify that all implementations that support these extensions
should include a non-empty X-Tor-Proxy
header in their responses.
The header may include the name of the software, and its version.
Proxies MUST NOT include this header unless they forward user traffic over anonymous Tor connections.
Clients MAY check for the presence or absence of this header.
Clients SHOULD NOT inspect the contents of this header to determine whether a given feature is supported or not.
(Arti and C tor.)
OPTIONS
method support
We should implement the "OPTIONS" method to check the capabilities of a proxy
without making a request.
It should return an Allow
header indicating the permitted methods
(CONNECT and OPTIONS).
This feature is only useful if we also implement the
X-Tor-Proxy
and/orX-Tor-Capabilities
response headers.
(Arti and C tor.)
X-Tor-Optimistic
: Optimistic connections
We propose a X-Tor-Optimistic:
header.
Recognized values are "on" and "off".
Proxies should treat unrecognized values as "off".
When the value of this header is "on", the proxy SHOULD return a 200 OK (CONNECTED) response immediately, before the connection has been established, and begin relaying data from the client immediately.
Using this extension makes it easier for clients to benefit from optimistic data.
Regardless of whether this extension is on or off, clients MAY still send data after their CONNECT request; proxies MUST retain and deliver that data if the connection is successful, and SHOULD send that data optimistically (after the BEGIN cell, before any CONNECTED is received).
(Header support in arti only; optimistic data behavior everywhere.)
X-Tor-Family-Preference
: IP version preferences
Tor allows the client to transmit its preferences for IP versions as part of its BEGIN message.
We allow these to be encoded in an HTTP CONNECT header,
X-Tor-Family-Preference
.
Permitted values are:
ipv4-preferred
(any family allowed; ipv4 preferred)ipv6-preferred
(any family allowed; ipv6 preferred)ipv4-only
(only ipv4 is allowed)ipv6-only
(only ipv6 is allowed)
The default is "ipv4-preferred".
Any unrecognized value SHOULD be treated as "ipv4-preferred".
(Arti only.)
X-Tor-Capabilities
: Determining specific extensions
In responses,
proxies SHOULD include an X-Tor-Capabilities
header
containing a space-separated list of capabilities.
Clients MAY use this header to decide
whether a required capability is present.
All new features that we add will have a corresponding capability. Clients SHOULD use check for these capabilities whenever they are using a feature which, if absent, would be insecure.
Every request header has a capability of the same name, to indicate that the header will be recognized and processed if sent.
As an alternative, we might use something like
X-Tor-Require-Capabilities
for the client to say "don't even talk to me unless you support X." I'm not taking this alternative, though, since the default behavior of a non-tor HTTP CONNECT proxy would be exactly what we don't want here.
If we're worried about overhead from a list that will grow longer and longer over time, we could say that it MUST be sent in response to OPTIONS only.
(Arti and C Tor.)
"Bilingual" proxies: HTTP CONNECT and SOCKS on one port.
A SOCKS handshake always begins with a byte of value 4 or five. An HTTP handshake always begins with an ASCII character. Currently, in the C tor implementation, we use this property to distinguish SOCKS from HTTP connections, and we reject each kind with an appropriate error message if it arrives on the wrong port.
Instead, we could specify that there is a single "proxy port" which accepts both SOCKS and HTTP requests. This port could accept both SOCKS and "HTTP CONNECT".
Before implementing this, we should make sure it is safe.
(For what it's worth, a TLS handshake always begins with the byte 22 followed by two bytes to indicate record protocol version, so we could add support for TLS in the future if we wanted.)
(Arti only. Maybe C tor if lack of HTTP-by-default becomes a deployment issue.)