◐ Off-By-One · answer catalog

js-http11-pipelining-chunked-slowloris

2 answer(s)jsnode20jsnode20

js-http11-pipelining-chunked-slowloris

📦 Source in repository (JSON)

Answer 1

All checks green. The solution is complete and verified.

Summary

Deliverables (in ~/http11-server/): - server.js — the raw HTTP/1.1 server (plain net.Socket, no http module/frameworks) - test.js — verification harness: 14 tests incl. the 500-concurrent stress mix - extra-checks.js — 6 extra edge checks (LF-only messages, 2000-request single-write burst, 431 on oversized headers, 200 KB chunked body + trailers, RST survival) - solution.md — the requested markdown: title, root-cause analysis, exact fix (full code inline, byte-identical to server.js), and verification section

Root causes addressed: - data events are never message-aligned → incremental state machine; every parse step consumes only complete tokens and returns 'wait' otherwise - Pipelining → strictly sequential per-connection pump: full body consumed before next request, responses in request order - Chunked bodies → hand-rolled decoder validating hex sizes, CRLF framing, trailers; an 'end' state rejects bytes after the final chunk unless they begin a valid next request — 400'd before the current response is emitted (single-400 semantics) - Smuggling vectors → duplicate Content-Length (even identical), Transfer-Encoding + Content-Length, TE ≠ chunked, obs-fold, malformed request line → 400 + close; eager first-line check catches chunk-looking garbage immediately - Slowloris → socket idle timeout plus per-stage stall clocks (trickle clients never go idle, so idle alone is insufficient), max-requests-per-connection cap (Nth response sends Connection: close), and pause/resume backpressure with a hard pending-buffer cap - Half-close → pipelined-then-FIN clients still get all responses; leftover unparseable bytes at FIN → 400

Verification: 14 passed, 0 failed across 4 consecutive runs (no flakiness), including the stress test: 500 concurrent keep-alive pipelines × 10 mixed requests each (single-segment pipelines) + 30 byte-trickling slowloris clients — 5,000 responses verified for status/body/order in ~2.7 s, all tricklers terminated. Extra checks: 6/6, including a 2000-request in-order burst and server survival of a mid-request RST.

Evidence & signatures

# Evidence
- Problem class: js-http11-pipelining-chunked-slowloris
- Model: openrouter/deepseek/deepseek-v4-flash-0731
- Solved: 2026-08-31T00:51:47.334Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Write a raw Node.js HTTP/1.1 server (no frameworks) that handles pipelined requests on one socket, chunked transfer-encoding with trailers, and partial/fragmented reads, while enforcing a per-connection idle timeout and a max-requests-per-connection cap to survive slowloris clients. Responses must be serialized in request order, and protocol violations (malformed chunk size, bytes after final chunk, duplicate Content-Length) must 400 the connection and close it to prevent request smuggling. Must pass a stress test mixing 500 concurrent keep-alive pipelines with deliberately slow trickle clients.", "environment": "node20", "language": "js", "model": "openrouter/deepseek/deepseek-v4-flash-0731", "problem_class": "js-http11-pipelining-chunked-slowloris", "provider": "openrouter", "solved_at": "2026-08-31T00:51:47.335Z", "version": "20"}

Answer 2

All checks green. The solution is complete and verified.

Summary

Deliverables (in ~/http11-server/): - server.js — the raw HTTP/1.1 server (plain net.Socket, no http module/frameworks) - test.js — verification harness: 14 tests incl. the 500-concurrent stress mix - extra-checks.js — 6 extra edge checks (LF-only messages, 2000-request single-write burst, 431 on oversized headers, 200 KB chunked body + trailers, RST survival) - solution.md — the requested markdown: title, root-cause analysis, exact fix (full code inline, byte-identical to server.js), and verification section

Root causes addressed: - data events are never message-aligned → incremental state machine; every parse step consumes only complete tokens and returns 'wait' otherwise - Pipelining → strictly sequential per-connection pump: full body consumed before next request, responses in request order - Chunked bodies → hand-rolled decoder validating hex sizes, CRLF framing, trailers; an 'end' state rejects bytes after the final chunk unless they begin a valid next request — 400'd before the current response is emitted (single-400 semantics) - Smuggling vectors → duplicate Content-Length (even identical), Transfer-Encoding + Content-Length, TE ≠ chunked, obs-fold, malformed request line → 400 + close; eager first-line check catches chunk-looking garbage immediately - Slowloris → socket idle timeout plus per-stage stall clocks (trickle clients never go idle, so idle alone is insufficient), max-requests-per-connection cap (Nth response sends Connection: close), and pause/resume backpressure with a hard pending-buffer cap - Half-close → pipelined-then-FIN clients still get all responses; leftover unparseable bytes at FIN → 400

Verification: 14 passed, 0 failed across 4 consecutive runs (no flakiness), including the stress test: 500 concurrent keep-alive pipelines × 10 mixed requests each (single-segment pipelines) + 30 byte-trickling slowloris clients — 5,000 responses verified for status/body/order in ~2.7 s, all tricklers terminated. Extra checks: 6/6, including a 2000-request in-order burst and server survival of a mid-request RST.

Evidence & signatures

# Evidence
- Problem class: js-http11-pipelining-chunked-slowloris
- Model: openrouter/deepseek/deepseek-v4-flash-0731
- Solved: 2026-08-31T00:51:47.334Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Write a raw Node.js HTTP/1.1 server (no frameworks) that handles pipelined requests on one socket, chunked transfer-encoding with trailers, and partial/fragmented reads, while enforcing a per-connection idle timeout and a max-requests-per-connection cap to survive slowloris clients. Responses must be serialized in request order, and protocol violations (malformed chunk size, bytes after final chunk, duplicate Content-Length) must 400 the connection and close it to prevent request smuggling. Must pass a stress test mixing 500 concurrent keep-alive pipelines with deliberately slow trickle clients.", "environment": "node20", "language": "js", "model": "openrouter/deepseek/deepseek-v4-flash-0731", "problem_class": "js-http11-pipelining-chunked-slowloris", "provider": "openrouter", "solved_at": "2026-08-31T00:51:47.335Z", "version": "20"}
Generated from the verified corpus · MIT licensedBack to the catalog