Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions docs/WEB_COVER.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ HTTP/2 CONNECT presented to the public origin is always treated as cover,
including when it carries an otherwise valid ticket: the handler removes
`Proxy-Authorization` before delegation and never dials its authority.

Public physical-connection limits are separate from authenticated tunnel-stream
limits, and the combined TCP/UDP server shares its global and per-source
connection allowance. Source builds after v1.0.1 reject an excess H3 connection
with `H3_EXCESSIVE_LOAD` (`0x107`), rather than reusing the native relay's code,
which means `H3_INTERNAL_ERROR` in [HTTP/3](https://www.rfc-editor.org/rfc/rfc9114.html#section-8.1).
Rejection happens before HTTP dispatch;
the existing admitted connection remains usable and closing it releases capacity.
This is overload handling, not a tunnel authentication response.

### Website WebSocket support in source builds

Source builds after v1.0.1 also forward valid HTTP/1.1 WebSocket upgrades to
Expand Down Expand Up @@ -202,6 +211,17 @@ the upstream cannot be reached. Consequently, an upstream that requires an
`Authorization` request header is not suitable without a separate authorized
front end.

Source builds after v1.0.1 disable automatic compression negotiation and response
decompression on the proxy's private default upstream transport. The visitor's
`Accept-Encoding` remains unchanged: explicitly requested gzip still works, and
the origin's encoded bytes, `Content-Encoding`, length, digest and ETag remain
together. This avoids rewriting `no-transform` content while retaining metadata
for the old bytes; see [HTTP message transformations](https://www.rfc-editor.org/rfc/rfc9110.html#section-7.7).
It does not verify the website's digest or establish browser-like fingerprints.
Applications supplying a custom RoundTripper retain their own negotiation/decoding
policy and must configure transparent forwarding themselves. Static cover,
authenticated tunnel payloads and the published v1.0.1 binary are unchanged.

#### Optional fixed public origin in source builds

Source builds after v1.0.1 can separate the website's public HTTP identity
Expand Down
5 changes: 5 additions & 0 deletions internal/cover/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ var hopByHopHeaders = [...]string{
// NewReverseProxyHandler returns a reverse proxy that can dial only origin.
// The requester controls the path, query, and ordinary end-to-end headers, but
// never the upstream scheme, authority, or Host header.
// A nil transport does not add compression negotiation or decode responses.
// Supplied transports retain their own compression policy.
func NewReverseProxyHandler(origin *url.URL, transport http.RoundTripper) (http.Handler, error) {
target, err := normalizeOrigin(origin)
if err != nil {
Expand All @@ -43,6 +45,9 @@ func newReverseProxyHandler(target *url.URL, transport http.RoundTripper, public
if transport == nil {
defaultTransport := http.DefaultTransport.(*http.Transport).Clone()
defaultTransport.Proxy = nil
// Forward the visitor's encoding preferences and the origin's encoded
// bytes together with their metadata, including no-transform/digests.
defaultTransport.DisableCompression = true
transport = defaultTransport
}

Expand Down
3 changes: 2 additions & 1 deletion internal/cover/public_origin.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import (
// and TLS still use upstream; public supplies only the outbound Host and the
// trusted X-Forwarded-Host/Proto values. Both URLs must be root origins.
//
// Origin, Referer, cookies, redirects, and content are never rewritten. The
// Origin, Referer, cookies, redirects, and content are not rewritten by the
// handler. Supplied transports retain their own compression policy. The
// upstream must generate its own public URLs and retain its CSRF/Origin checks;
// an absent Origin is not evidence that a request is safe. Its trusted-header
// whitelist must use only the proxy-owned forwarding fields, not arbitrary
Expand Down
Loading
Loading