vey-proxy: add http_guard public-edge HTTP reverse proxy - #104
Merged
Merged
Conversation
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
zh-jq
force-pushed
the
http-guard
branch
2 times, most recently
from
September 8, 2026 00:31
70bab93 to
76cea04
Compare
Inspect the first client bytes and only serve HTTP/1.x, auto-detect TLS, and match SNI against TLS-capable sites while plaintext Host uses a separate HTTP table. Tenant identity goes to ICAP as X-Tenant-Username. Co-authored-by: Cursor <cursoragent@cursor.com>
Origin H2 is multiplexed from a site pool without 1:1 client binding; config splits shared HTTP from H1/H2, with optional H2C and H2 Websocket. Co-authored-by: Cursor <cursoragent@cursor.com>
Reuse is per-origin: http_expose and http_guard read http.h1.upstream_keepalive (enabled by default) instead of a server key. Co-authored-by: Cursor <cursoragent@cursor.com>
Parse and reload checks for the always-on site H2 pool, plus a TLS origin coverage path so http_guard HTTP/2 does not share the H1 plaintext site. Co-authored-by: Cursor <cursoragent@cursor.com>
Share one TLS client per site. HTTP/2 origin sets h2 on the connection Ssl instead of a second SslCtx. Co-authored-by: Cursor <cursoragent@cursor.com>
Reuse one client connection in the existing pycurl and requests suites instead of extra curl invocations in coverage shells. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
zh-jq
force-pushed
the
http-guard
branch
4 times, most recently
from
September 13, 2026 14:20
8ca4f85 to
a5453a5
Compare
Co-authored-by: Cursor <cursoragent@cursor.com>
…raffic Co-authored-by: Cursor <cursoragent@cursor.com>
Count payload after transfer-coding is removed so H1 chunked framing is not included, and record each side independently. On failure record the size completed on that hop so far. An H1 chunked body is forwarded as on-wire bytes, so the payload written is not counted as it goes out; report a lower bound there that excludes data still held in the copy buffer. Restore the pending chunk on H2 write errors, so the size received is not undercounted by a whole chunk on the paths that report it. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
add_invalid_param() was incrementing user_blocked, so username-parameter rejections never appeared on server.forbidden.invalid_param. Co-authored-by: Cursor <cursoragent@cursor.com>
H2 tasks only enabled local error replies after the origin was ready, so checkout_or_connect failures left the client with no response. Co-authored-by: Cursor <cursoragent@cursor.com>
RFC 9113 requires Host to identify the same entity as :authority after scheme-based normalization. Mismatches return 409, matching HTTP/1. Co-authored-by: Cursor <cursoragent@cursor.com>
H1 and H2 checkout on the same worker, TLS, and the server's configured escaper so different escapers do not mix, while servers sharing that escaper can still reuse connections. Move the pools under site/pool/. Co-authored-by: Cursor <cursoragent@cursor.com>
H1 Upgrade and H2 CONNECT with :protocol=websocket share task_type Websocket and CONNECT-style tunnel logs. Other CONNECT or Upgrade is rejected; H1 WebSocket always opens a new origin connection. Co-authored-by: Cursor <cursoragent@cursor.com>
Site tenants are not visitors, so they no longer share UserContext. Forbidden stats and ACL stay on TenantContext; request and traffic stats stay on the site. Co-authored-by: Cursor <cursoragent@cursor.com>
Origin TLS still follows site tls_client. Client https:// absolute-form is accepted without becoming https_forward or requiring a TLS client hop. Co-authored-by: Cursor <cursoragent@cursor.com>
Buffer the origin reader only while parsing the Upgrade response, take leftover bytes with into_parts after 101, and reject unexpected 1xx instead of looping for a final status. Co-authored-by: Cursor <cursoragent@cursor.com>
Read the origin response once like H1: 1xx is a protocol error, 2xx starts relaying, and other statuses are forwarded to the client. Checkout of the origin H2 sender is now a task method. Co-authored-by: Cursor <cursoragent@cursor.com>
…tered inspect H2 is covered via the intercept acceptor (select callback). http_guard uses OpensslServerConfigBuilder, which called the client set_alpn_protos API; a handshake test shows selected ALPN was None, so H2 clients fell back to 1.1 and serve/http_guard/task/h2 stayed at 0%. Co-authored-by: Cursor <cursoragent@cursor.com>
Sites without tls_server were dropped from the TLS host table, so Host matching after the default-cert handshake always 400'd. H2 still requires the site's own certificate. Co-authored-by: Cursor <cursoragent@cursor.com>
Unmatched SNI and Host are rejected locally instead of falling through to set_default. H2 always carries the pinned site; global_tls_server remains the H1 certificate fallback. Co-authored-by: Cursor <cursoragent@cursor.com>
Move origin checkout and early H2 errors onto H2TaskContext. H2Forward and Websocket logs record client and upstream stream ids. Co-authored-by: Cursor <cursoragent@cursor.com>
H1 forward and websocket already have the site at construction, so keep SiteContext on the task instead of Arc<Site> and a duplicated keepalive field. SNI pin is that same context, so drop pinned_host from H1TaskContext. Socket speed limits shrink site and tenant in one place. Co-authored-by: Cursor <cursoragent@cursor.com>
A site pool is all TLS or all cleartext; reload with a different tls_client replaces the pool. Keep matching on the server escaper only. Co-authored-by: Cursor <cursoragent@cursor.com>
A blocked tenant is forbidden when a new reverse-proxy request starts. Idle checks still cancel a blocked visitor. Document the split in Sphinx. Co-authored-by: Cursor <cursoragent@cursor.com>
Match http_guard: the pipeline writer extracts check_run, and the forward task reads site and tenant from SiteContext instead of Arc<Site>. Co-authored-by: Cursor <cursoragent@cursor.com>
Take site-pool connections with if-let and `?` instead of an intermediate Option, and drop an unnecessary Host clone in http_expose lookup. Co-authored-by: Cursor <cursoragent@cursor.com>
Acquire user and site alive-request permits through notes so they drop with the task, and drop the started/post_stop Drop impls that only existed to release them. Co-authored-by: Cursor <cursoragent@cursor.com>
Honor tenant user block_and_delay at site entry before sending 403, matching visitor blocked-user auth. Co-authored-by: Cursor <cursoragent@cursor.com>
Fold http_guard H1 adaptation.rs back into the task so send_response stays with the common path, and extract run_without_adaptation like http_proxy. Align expose/proxy body dispatch to the same early-return shape. Co-authored-by: Cursor <cursoragent@cursor.com>
Untrusted drain now runs under the matched site's rate, alive, speed, and idle limits, and counts request-header plus body bytes on site traffic. Co-authored-by: Cursor <cursoragent@cursor.com>
Give H2 connection/forward/websocket their own directories and H2Connection logs. Record connection_id, origin TCP keys, and site/tenant on reverse-proxy tasks. Co-authored-by: Cursor <cursoragent@cursor.com>
Give each accepted stream its own dispatch task that logs only the error or the spawned H2Forward/Websocket. Fold origin ping into H2TaskContext and treat ping failure as a closed origin connection. Co-authored-by: Cursor <cursoragent@cursor.com>
Drop WebSocketTaskStats on the H2 websocket task and record received vs copied sizes from H2BodyTransfer instead. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.