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/or X-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.)