nodejs/node
HTTP, HTTP/2, HTTP/3, and QUIC
Owners: @nodejs/http, @nodejs/http2, @nodejs/quic.
Purpose
Provide built-in HTTP servers and clients for HTTP/1.1 (http), HTTP/2 (http2), HTTP/3 (over QUIC, experimental), and the underlying QUIC transport (quic, experimental). The fetch API at globalThis.fetch ships through the vendored undici library.
Directory layout
lib/
http.js // public HTTP/1.1 module
https.js // HTTPS = HTTP/1.1 over TLS
http2.js // public HTTP/2 module
quic.js // public QUIC (experimental)
_http_agent.js // ClientRequest / Agent connection pool
_http_client.js // ClientRequest implementation
_http_common.js // shared parser glue
_http_incoming.js // IncomingMessage (Readable)
_http_outgoing.js // OutgoingMessage (Writable)
_http_server.js // Server, ServerResponse
internal/http2/ // http2 internals (compat, util, core)
internal/quic/ // QUIC JS shims (experimental)
src/
node_http_parser.cc // llhttp wrapper
node_http_common.{cc,h} // shared HEADERS table for h1/h2/h3
node_http2.{cc,h} // HTTP/2 binding (on nghttp2)
node_http2_state.h // HTTP/2 session state
quic/ // QUIC implementation
application.cc/.h // base ApplicationLayer
http3.cc/.h // HTTP/3 ApplicationLayer
session.{cc,h} // QuicSession
endpoint.{cc,h} // QuicEndpoint (UDP socket binding)
streams.{cc,h} // QuicStream (StreamBase)
tlscontext.{cc,h} // QUIC TLS handshake glue
bindingdata.{cc,h} // per-realm binding storage
transportparams.{cc,h} // RFC 9000 transport params
tokens.{cc,h} // retry / new tokens
cid.{cc,h} // connection IDs
data.{cc,h} // packet/data primitives
arena.h // pooled memory arena
deps/
llhttp/ // HTTP/1 parser
nghttp2/ // HTTP/2
ngtcp2/ // QUIC + nghttp3 for HTTP/3HTTP/1.1
sequenceDiagram
participant Client as http.ClientRequest
participant Sock as net.Socket
participant Parser as HTTPParser (llhttp)
participant Server as http.Server
participant Resp as ServerResponse / IncomingMessage
Client->>Sock: write request bytes
Sock->>Server: bytes via TCP
Server->>Parser: feed onread bytes
Parser-->>Server: onHeadersComplete -> emit 'request'
Server->>Resp: build IncomingMessage + ServerResponse
Resp-->>Sock: writeHead + body
Sock-->>Client: response bytes
Client->>Parser: response bytes -> emit 'response'node_http_parser.ccwrapsdeps/llhttp/. EachSocketlazily attaches anHTTPParserinstance that fires JS callbacks (onHeadersComplete,onBody,onMessageComplete).Agent(_http_agent.js) maintains a per-host connection pool and keepalive policy.getAgentis overridable from user code;httpsswaps in a TLS-aware Agent.IncomingMessageis aReadable;OutgoingMessage/ServerResponse/ClientRequestareWritablewithchunkedencoding logic baked in._http_server.jshandleskeepAlive,Expect: 100-continue,Upgrade, and Connection-header cleanup.
https.js is http.js with tls.connect/tls.createServer swapped for the underlying socket creation. The https.Agent reuses TLS sessions across keepalive connections.
HTTP/2
graph TD
Sock[TLS or TCP socket] --> NHttp2[Http2Session : nghttp2]
NHttp2 --> Streams[Http2Stream*]
Streams --> Compat["Http2Stream → ServerHttp2Stream / Compat"]
Compat --> ServerResp[Compat ServerResponse]
Compat --> ClientReq[Compat ClientHttp2Stream]src/node_http2.ccis one of the largest files in the tree (~131 K LOC).Http2Sessionwraps annghttp2_session. Frames in/out flow through callbacksOnFrameSend,OnDataChunkRecv,OnHeader,OnStreamClose.Http2Streamis aStreamBase, so HTTP/2 server pushes get the same backpressure/pipestory as TCP.- The compat layer in
lib/internal/http2/compat.jsletshttp2.createServeraccept HTTP/1-style request handlers ((req, res) => …). - HPACK header tables are managed by nghttp2; Node imposes additional limits via
--max-http-header-sizeand the security-conscious settings inlib/internal/http2/util.js.
QUIC and HTTP/3
src/quic/ is a from-scratch binding over deps/ngtcp2/ (QUIC) and deps/nghttp3/ (HTTP/3). It is gated by the build-time node_use_quic GYP variable and the --experimental-quic flag (see the features.quic getter in lib/internal/bootstrap/node.js).
QuicEndpoint(src/quic/endpoint.cc) binds a UDP socket viaUDPWrap.QuicSession(src/quic/session.cc, ~104K) drives the ngtcp2 conn, manages keys, paths, and streams.QuicStream(src/quic/streams.cc) is aStreamBasewired into the session's outbound queues.Http3Application(src/quic/http3.cc) plugs into nghttp3 for header compression and stream management.- TLS handshake state lives in
tlscontext.cc; certificate validation reusescrypto_x509.
Fetch (globalThis.fetch)
globalThis.fetch, Request, Response, Headers, FormData, WebSocket, Blob, and the URL/URLPattern integration come from deps/undici/. The undici source is bundled by tools/js2c.cc along with Node's own lib/. The integration glue lives in lib/internal/bootstrap/web/ and adds a small set of Node-specific tweaks (proxy support via NODE_USE_ENV_PROXY, telemetry hooks via diagnostics_channel).
undici uses net/tls for transport so HTTP/2 fetch and HTTP/1 fetch share the same socket layer documented above.
Integration points
- Streams: every body is a
Readable/Writable(or a WHATWGReadableStreamfor fetch). - TLS:
https.Serverand HTTP/2 reusetls.Server; HTTP/3 reusescrypto/crypto_tls-style key extraction. - Permission model: net domain restrictions apply to all client connections and listeners.
- Diagnostics channel:
lib/_http_*.jsand thenode:httpclients publish events todiagnostics_channelchannels (http.client.request.start,http.server.request.start, etc.). undici similarly publishes toundici:request:create,undici:request:headers, …
Entry points for modification
- HTTP/1 parser bug? Fixes go upstream at
nodejs/llhttp; the Node side just regeneratesdeps/llhttp/. - HTTP/2 frame handling? Most logic is in
src/node_http2.cc; small surface inlib/internal/http2/core.js. - QUIC:
src/quic/session.cc(state machine),src/quic/streams.cc(data plane),src/quic/http3.cc(HTTP/3). New PRs should also touchdoc/api/quic.mdand the@nodejs/quicteam. - Fetch behaviour: usually fixes go upstream to undici; sometimes
lib/internal/bootstrap/web/for environment plumbing.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.