Case study 05 / HTTP and TLS

Concurrent Clear-to-
Secure Proxy

A concurrent forward proxy that accepts clear-text HTTP, establishes verified TLS upstream, applies reloadable access controls, and relays framed HTTP/1.1 responses.

Role
Architecture and implementation
Stack
C++17 · OpenSSL · POSIX sockets
Concurrency
Isolated worker threads
Status
Integration tested · Public

A proxy sits between two independently framed connections and has to remain correct when clients, origins, DNS, TLS, or policy fail.

The downstream side accepts ordinary HTTP proxy requests. The upstream side resolves the requested host, establishes TLS, verifies the certificate and hostname, rewrites the request, and streams the response back without losing message boundaries.

At the same time, the process must isolate concurrent clients, enforce hostname and resolved-IP rules, and produce useful HTTP errors rather than leaking socket failures to the browser.

  1. AcceptParse the client request

    GET and HEAD are accepted in absolute proxy form or origin form with a Host header.

  2. AuthorizeCheck host and addresses

    The requested hostname and every resolved address are compared with the current forbidden-sites snapshot.

  3. SecureOpen verified TLS

    The proxy connects upstream with OpenSSL, validates the certificate chain, and verifies the requested hostname.

  4. RelayPreserve HTTP framing

    Content-Length, chunked, HEAD, and connection-close responses are streamed using their actual termination rules.

A

Verification by default

TLS certificate and hostname checks remain enabled unless an explicit development-only environment override is set.

B

Policy after resolution

Checking both the hostname and resolved addresses prevents a permitted name from silently reaching a forbidden destination address.

C

Framing-aware persistence

Downstream keep-alive is used only when the response boundary is known; close-delimited responses end the client connection.

D

Explicit HTTP failure mapping

Malformed requests, blocked sites, unsupported methods, DNS failures, upstream errors, capacity limits, and timeouts become distinct responses.

Policy changes should not require stopping the service or leaving newly forbidden connections active.

Sending SIGINT reloads the forbidden-sites file into a new immutable snapshot while the proxy remains running. New requests immediately use the replacement rule set.

The proxy also reevaluates active upstream destinations. Connections covered by a newly loaded hostname or IP rule are shut down so the policy change applies to existing work as well as future requests.

50client capacity
2forwarded methods
6mapped HTTP errors
TLS 1.2+verified upstream

The integration suite creates a locally trusted TLS origin and exercises GET, HEAD, X-Forwarded-For, unsupported methods, concurrent requests, ACL reload, blocked responses, persistent requests, chunked responses, malformed input, and structured access logging.

A forwarding service needs enough evidence to explain what happened without retaining response bodies.

Each completed request produces an RFC 3339 access-log entry with the client address, request line, returned status, and relayed byte count. X-Forwarded-For is created or extended so the origin receives the downstream address chain.

Worker cleanup is centralized so client sockets, upstream sockets, and TLS objects are released consistently across success, parse errors, access-control rejection, and connection failure.

The proxy demonstrates HTTP, TLS, concurrency, and policy mechanics; it is not intended as an anonymous or production security gateway.

It supports GET and HEAD rather than tunneling arbitrary HTTPS with CONNECT, uses a fixed worker capacity, and does not provide caching, authentication, content inspection, or distributed policy management.

The project originated in CSE 156/L at UC Santa Cruz in Winter 2025. After the original university-hosted source was lost, the published implementation was reconstructed from the surviving specification and expanded with stronger TLS verification, broader framing coverage, automated tests, and detailed cleanup documentation.

Selected work

More systems,
built to be examined.

Back to all projects