Node.js CONNECT Handlers Must Preserve the head Buffer
Handle Node's CONNECT socket and head buffer at the HTTP-to-tunnel boundary, preserving bytes already read beyond the headers.
A Node HTTP server handles an ordinary proxy request through its request callback. CONNECT takes another path: the server emits connect with the request, the client socket and a head buffer.
That event is the handoff between HTTP parsing and a tunnel. There is no ordinary ServerResponse object to keep using for the tunneled traffic.
| Argument | What it carries |
|---|---|
req | The CONNECT request, including its destination authority and headers |
clientSocket | The connection back to the client |
head | Tunnel data Node has already read beyond the HTTP headers, possibly empty |
Finish the HTTP decision before relaying bytes
Validate the requested host and port, apply the proxy's access and authentication policy, and establish the upstream connection. CONNECT identifies an authority such as service.example:443; parse that form with IPv6 authorities in mind rather than splitting blindly on every colon.
When the tunnel is accepted, send the successful HTTP response followed by its terminating blank line. Then forward any head bytes upstream before continuing with later bytes from the client socket. Attaching a new data listener cannot recover a buffer already delivered separately to the handler.
Node's official tunneling example performs that handoff with serverSocket.write(head) before connecting the two stream directions. Its small example illustrates the transition; a deployed proxy also needs bounded connection attempts, access controls and lifecycle handling.
After success, the bytes belong to the service protocol
A successful CONNECT response changes the connection into a byte stream. If the target is an HTTPS site, its TLS exchange travels inside that stream. Merely tunneling it does not require the proxy to issue a replacement website certificate.
Before accepting CONNECT, an HTTP error can explain why it was refused. After acceptance, writing an HTTP 500 into the stream would inject bytes into the tunneled protocol. End or destroy the appropriate connections on later failures instead.
Connect both directions with backpressure-aware stream handling, and decide how end, error and close events terminate the peer. Preserve the initial head buffer as part of that same ownership model; it is application data, not spare HTTP headers to discard.