http: add native single-shot response builder

AN
19d ago
+1839-135

Summary

Add a C++ buildHttpMessage helper used by the HTTP/1.1 outgoing path so the common cases avoid repeated JavaScript string concatenation and multi-write overhead:

  • _storeHeader: builds the status/request line + header block natively (with JS fallback for special cases such as content-disposition latin1 / unique cookie joining).
  • ServerResponse.end() fast paths:
    • Headers not yet rendered: full message (headers + body) built in C++ and written once.
    • After writeHead(): tryFastFlushEnd flushes the prebuilt header + body without the full write_() / extra empty-write path (this is the benchmark/http/simple.js case).
  • Server-side native headers stay as Buffers until write time (no latin1 string copy on the hot path). ClientRequest still materializes a string for _header compatibility.
  • Complex encodings (hex, utf16le, ...), trailers, and fake/standalone sockets keep the existing JS path.

Public API and on-the-wire format are unchanged.

Benchmarks

Machine-local out/Release on the same host. Baseline measured before this change.

benchmark/http/simple.js (primary)

type=bytes len=4 chunks=1 c=50 chunkedEnc=0 duration=5
RPS
Baseline~80,236
This PR (5 runs, latest tip)120,087 / 122,461 / 116,360 / 122,196 / 123,654
Delta~+45% to +54% (typical ~+50% around 120–123k)

Other simple.js variants (same tip):

ConfigRPS (3 runs)
chunkedEnc=1 (TE: chunked)121k / 120k / 116k
len=1024 content-length103k / 106k / 96k

Other microbenches

WorkloadRPS
end-vs-write-end method=end asc/64 c=50 duration=5~104–129k (run-to-run variance)
end-vs-write-end method=write asc/64 c=50 duration=5~106k
Custom keep-alive res.end('ok') only (50 clients, 3s)~47–49k

Review feedback (document flags, no incidental C++ reformat, no Buffer.concat) is included; the common ASCII path still shows the large win vs baseline.

Tests

Full test/parallel/test-http* suite: 751/751 passed (pre-push on an earlier tip); targeted suite re-run after the latest speed-ups.

Test plan

  • tools/test.py test/parallel/test-http* --mode=release (751 passed)
  • Targeted cases: write-head, non-utf8 content-disposition, chunked 204/304, CONNECT, client default headers, outgoing-end-types, hex/utf16le first-chunk encodings, standalone ServerResponse
  • benchmark/http/simple.js before/after (and after review + further speed-ups)
  • CI on this PR