Hacker DirectoryHacker Directory

WEB / WEB-08.01

HTTP/1.x connections and framing

Track message boundaries and response order separately on one TCP byte stream. Persistence permits another exchange; pipelining does not interleave responses.

CORE · RED · BLUE · ARTIFACT · PRACTICE

1. Core · Mechanism

Read every scenario without motion

Pipeline order

  1. Two GETs ready

    The client chooses two safe GETs on one open connection without awaiting the first response.

    Client / Duru
    GET A /atlas-notes and B /tea ready; awaiting responses
    Atlas server
    No requests
    Local connection state
    conn-h1 open
  2. Request A arrived

    The server receives the first complete GET as A; no response or status has reached the client.

    Client / Duru
    GET A /atlas-notes and B /tea ready; awaiting responses
    Atlas server
    A received
    Local connection state
    conn-h1 open
  3. Request B arrived

    B arrives without waiting for A’s response, establishing receive order A followed by B.

    Client / Duru
    GET A /atlas-notes and B /tea ready; awaiting responses
    Atlas server
    A/B received
    Local connection state
    conn-h1 open
  4. B ready, A pending

    Local scheduling prepares B first, but response-order rules keep it queued behind A.

    Client / Duru
    No response yet
    Atlas server
    B ready; A pending
    Local connection state
    Prepared order: B
  5. A also ready

    A is also prepared. The server must follow received-request order, not preparation order: A with ten content bytes precedes B with four.

    Client / Duru
    No response yet
    Atlas server
    A CL10 and B CL4 ready; A first
    Local connection state
    Prepared order: B,A
  6. Response A arrived

    The first complete response contains 10 content bytes, completing A before parsing B’s boundary.

    Client / Duru
    A complete: Atlas note
    Atlas server
    A delivered; B ready
    Local connection state
    conn-h1 open
  7. Response B arrived

    The second complete response carries four UTF-8 bytes for Çay, preserving arrival order A then B.

    Client / Duru
    A/B complete; B: Çay
    Atlas server
    A/B delivered
    Local connection state
    conn-h1 open
  8. Ready for reuse

    Both self-delimited bodies have been consumed; absent closure the connection can carry another exchange.

    Client / Duru
    Both complete
    Atlas server
    No pending response
    Local connection state
    conn-h1 reusable

HTTP/1.0 EOF

  1. Historical GET

    The historical branch starts with one GET on a new HTTP/1.0 connection without persistence extensions.

    Client / Duru
    GET /tea ready; awaiting response
    Atlas server
    No request
    Local connection state
    conn-10 open
  2. GET arrived

    The server receives the complete HTTP/1.0 request; its response body needs a separate boundary rule.

    Client / Duru
    GET /tea ready; awaiting response
    Atlas server
    GET /tea received
    Local connection state
    conn-10 open
  3. Close-delimited ready

    The server prepares a valid response without Content-Length, relying on closure to delimit its body.

    Client / Duru
    Awaiting response
    Atlas server
    200 ready; no CL
    Local connection state
    conn-10 open
  4. Bytes arrived

    Status and four content bytes arrive, but without EOF the client cannot yet mark the message complete.

    Client / Duru
    200; 4 bytes; incomplete
    Atlas server
    Response bytes delivered
    Local connection state
    conn-10 open
  5. Close event

    A supplied transport closure updates local state without inventing logout traffic or another HTTP response.

    Client / Duru
    200; 4 bytes; incomplete
    Atlas server
    Response bytes delivered
    Local connection state
    conn-10 closed; EOF
  6. EOF boundary

    The client uses EOF to end the body: Çay is complete, while this connection can no longer be reused.

    Client / Duru
    Complete: Çay
    Atlas server
    Exchange finished
    Local connection state
    conn-10 not reusable

ACTORS · STATE · DATA FLOW

HTTP/1.0 as a historical baseline

When Duru’s Atlas client retrieves a note, HTTP/1.0 still carries a method, target, status, and representation metadata. RFC 1945 is an Informational document from May 1996, used here to explain historical behavior rather than define current HTTP/1.1 parser requirements.

Its ordinary operation opens a connection for each request and closes it after the response. Later keep-alive extensions are distinct from that baseline; equal persistence support cannot be assumed across HTTP/1.0 clients.

The historical fixture retrieves /tea using a 200 response without Content-Length. Çay occupies four UTF-8 bytes, but receipt of those bytes alone cannot establish that no more will follow. Supplied connection closure establishes the response-body boundary. Closing a request body is different because the server still needs to send its response.

A byte stream is not a message boundary

TCP delivers ordered bytes, but a socket read need not equal an HTTP message. One read can contain half a header, one message, or several messages together. HTTP/1.1 determines framing from the start-line, CRLF-delimited fields, blank separator, and method/status context.

The normal fixture concatenates two GET requests and two Content-Length responses. Atlas note occupies 10 content bytes and Çay occupies 4. After the first header section, a parser consumes exactly 10 content bytes; the next response start is not part of that content. Readable headers do not turn byte lengths into character counts.

HEAD/204 content restrictions, valid chunked framing, and close-delimited responses have distinct rules. This fixture uses only ordinary GET with one Content-Length per response. Current HTTP favors self-delimited responses because close delimiting makes normal completion harder to distinguish from transport failure.

Persistence permits reuse after completion

HTTP/1.1 can keep a connection persistent by default. The normal branch carries two exchanges on conn-h1 and leaves it open after both responses complete. Adding Keep-Alive is not a prerequisite for this default. Explicit close, peer policy, or transport events can end reuse.

The prior body must be consumed before reuse so its bytes are not mistaken for another message. A self-defined length supports an open connection. In contrast, a response whose body ends only at EOF consumes that connection’s ability to serve a later exchange.

An open connection proves neither an active application session nor a verified subject. Conn-h1 denotes a transport resource rather than an authentication record. The session/connection distinction from WEB-07.05 now connects to message completion and reuse, while policy decisions remain independent.

Pipelining retains response order

A client can send its second request without waiting for the first response: pipelining. Responses on that byte stream must follow received-request order. Safe requests can be processed in parallel, but their content cannot be arbitrarily interleaved without stream identifiers.

The scene receives A=/atlas-notes before B=/tea. B’s four-byte response is prepared first, but it waits while A is still preparing. Once A is ready, A’s response arrives before B’s. Prepared at the server and complete at the client are separate states: this is application-level head-of-line blocking.

Both requests are safe GETs, and the server delay is a supplied condition rather than a measured duration. Real clients need not use pipelining. Retry decisions depend on unanswered exchanges, method semantics, and partial failures; waiting or losing a connection does not prove a non-idempotent action never ran.

2. Red · Trust & Impact

Read every scenario without motion

Pipeline order

  1. Request order was marked with aliases

    A names GET /atlas-notes and B names GET /tea. Their request order on the same HTTP/1.1 connection is A, B. The aliases provide teaching correlation, not actual HTTP/1.1 stream-identifier fields.

    Request/response ledger
    Requests: A, B
    Order/completion gate
    Completion gate pending
    Application boundary
    Delivery outcome unknown
  2. Preparation order was separated from delivery order

    The server may prepare response B before A; preparedOrder is B, A. Pipeline response order remains A, B. Being ready does not allow B to move ahead of A for delivery to the client.

    Request/response ledger
    Requests: A, B
    Order/completion gate
    Prepared B,A / required delivery A,B
    Application boundary
    Delivery outcome unknown
  3. Waiting was not promoted to a forbidden result

    B waits because of response ordering in this ledger. No authorization denial for B was observed. Two safe GETs on one connection likewise do not grant permission to both resources; application policy is another boundary.

    Request/response ledger
    Requests: A, B
    Order/completion gate
    Prepared B,A / required delivery A,B
    Application boundary
    B waits for order / permission unknown
  4. A socket read was not treated as a message boundary

    The response stream carries A and B messages consecutively. TCP read groupings need not preserve those message boundaries. A’s Content-Length 10 identifies its content boundary; subsequent bytes may belong to the separate B message.

    Request/response ledger
    A content 10 / next bytes may be B
    Order/completion gate
    Prepared B,A / required delivery A,B
    Application boundary
    B waits for order / permission unknown
  5. Parser completion and bounded work were kept separate

    A maintained parser completes each message under its framing rule instead of treating a read() return as a complete HTTP response. Pending work and timeouts are bounded separately. Here B waits for order; this is not a production-performance diagnosis.

    Request/response ledger
    A content 10 / next bytes may be B
    Order/completion gate
    Framing per message / bounded pending work
    Application boundary
    B waits for order / permission unknown
  6. The boundary result retained its evidence scope

    deliveredOrder is supplied as A, B; the connection remains open after both contents complete. This record explains transport/message scheduling. It does not establish browser-pool, proxy, TLS or business-commit behavior.

    Request/response ledger
    A content 10 / next bytes may be B
    Order/completion gate
    Framing per message / bounded pending work
    Application boundary
    Order A,B / connection open / app unknown

EOF boundary

  1. Historical response framing was selected

    The HTTP/1.0 /tea response has neither Content-Length nor Transfer-Encoding. Its Çay body occupies 4 bytes. This valid historical example completes at response connection close; seeing the body text alone does not identify the boundary.

    Request/response ledger
    H1.0 / CL absent / TE absent / body 4
    Order/completion gate
    Completion gate pending
    Application boundary
    Delivery outcome unknown
  2. Completion was not declared merely after body bytes

    With four bytes present, completeBeforeClose is false. Close-delimited framing learns that no more body bytes follow from the close event. Starting to display the text does not establish HTTP-message completion.

    Request/response ledger
    H1.0 / CL absent / TE absent / body 4
    Order/completion gate
    Before close: complete=false
    Application boundary
    Delivery outcome unknown
  3. Incomplete state was not labeled application failure

    At this stage parser completion is pending. No HTTP failure, authorization denial or session logout is added; those mechanisms need separate evidence. Partial content and a final outcome are not the same state.

    Request/response ledger
    H1.0 / CL absent / TE absent / body 4
    Order/completion gate
    Before close: complete=false
    Application boundary
    Completion pending / application unknown
  4. The supplied nature of the close event was retained

    The historical ledger supplies a close event. It is not a native HTTP/1.0 socket measurement. After that event the parser knows the EOF boundary; the model invents neither another network packet nor a user logout.

    Request/response ledger
    Supplied close / not a socket measurement
    Order/completion gate
    Before close: complete=false
    Application boundary
    Completion pending / application unknown
  5. Completion and connection reuse reached different outcomes

    completeAfterSuppliedClose becomes true and reusableAfterClose is false. The body is complete, but a new exchange cannot use the same closed connection. Copying the self-delimited HTTP/1.1 branch’s open result into this case would be incorrect.

    Request/response ledger
    Supplied close / not a socket measurement
    Order/completion gate
    After close: complete=true / reusable=false
    Application boundary
    Completion pending / application unknown
  6. Transport closure produced no session verdict

    This EOF determines the HTTP body boundary and ends connection reuse. It supplies no evidence about a business operation, resource lifetime or session termination. Reaching the same Çay text does not make all protocol branches equivalent.

    Request/response ledger
    Supplied close / not a socket measurement
    Order/completion gate
    After close: complete=true / reusable=false
    Application boundary
    Message complete / session outcome unknown

ASSUMPTION · BOUNDARY · CONTROL

A wrong boundary produces a wrong exchange interpretation

Treating a socket read as a complete message can fail under normal fragmentation or coalescing. The condition is conflating TCP delivery units with HTTP framing; impact can include associating a response with the wrong resource.

Use maintained protocol parsers, version-aware completeness, and bounded buffering. Keep declared message length, received content bytes, and remaining bytes distinct. These two valid responses demonstrate that distinction without proving a parser safe for every input or deployment.

Starting to display content does not by itself establish a final business outcome or complete response. Separating partial observations from the completed exchange ledger gives security and incident analysis the correct boundary.

Queues and authorization consume different resources

B waits here because A must precede it, not because B is forbidden. Connections and pending responses consume resources, but every delay is not hostile: upstream delay, application work, and ordinary scheduling can expose similar wait states.

Bound pending work and apply explicit timeout/reuse policies separately from resource authorization. More connections can sometimes reduce response-order delays, but unlimited connections are not a general solution because server and network resources are shared.

Duru’s two GETs on one connection do not automatically permit both resources. A safe method is not an access-control result. This fixture teaches message scheduling while subject and resource policies belong at the real application boundary.

3. Blue · Secure development & defense

Read every scenario without motion

Message ledger

  1. Content count was separated from complete-message count

    A’s Atlas note content is 10 bytes and its full response message is 127. B’s Çay content is 4 bytes and its full message is 120. Adding header and delimiter overhead to Content-Length would make the comparison incorrect.

    Message record
    A: 10/127 bytes / B: 4/120 bytes
    Correlation review
    Count/order review pending
    Evidence conclusion
    No coverage verdict
  2. UTF-8 accounting preserved the message boundary

    Çay contains three code points but four UTF-8 bytes. B’s Content-Length 4 matches that content. Substituting character count for octet count would end the boundary at the wrong point in A/B correlation.

    Message record
    A: 10/127 bytes / B: 4/120 bytes
    Correlation review
    A CL 10 / B CL 4 consistent
    Evidence conclusion
    No coverage verdict
  3. Preparation and arrival arrays were read separately

    preparedOrder is B, A while deliveredOrder is A, B. B-ready is not B-arrived. Keeping these measures separate for the same request order prevents ordinary pipeline waiting from being misclassified as wrong response order.

    Message record
    Prepared B,A / delivered A,B
    Correlation review
    A CL 10 / B CL 4 consistent
    Evidence conclusion
    No coverage verdict
  4. The order oracle used normal and positive controls

    Normal selector XML has requestOrder A,B and deliveredOrder A,B, yielding zero mismatches. The positive XML reports deliveredOrder B,A and yields one. The positive control is an authored observation, not a recorded real protocol failure.

    Message record
    Prepared B,A / delivered A,B
    Correlation review
    Normal mismatch 0 / positive mismatch 1
    Evidence conclusion
    No coverage verdict
  5. Normal completion was not treated as a session event

    After both self-delimited responses complete, connectionAfterComplete remains open. That is a connection-reuse condition. The message ledger contains no login, logout, user-role or private-resource-policy event.

    Message record
    Prepared B,A / delivered A,B
    Correlation review
    Normal mismatch 0 / positive mismatch 1
    Evidence conclusion
    Messages complete / connection open
  6. Regression was tied to byte and order predicates

    Server preparation records can supply preparedOrder=B,A; the client HTTP parser can supply deliveredOrder=A,B and complete-message boundaries correlated with request order on the same connection. A/B are not stream IDs. Header serialization changes require recalculating message counts 127 and 120.

    Message record
    Prepared B,A / delivered A,B
    Correlation review
    Normal mismatch 0 / positive mismatch 1
    Evidence conclusion
    Recheck content bytes, message bytes and order

Arrival gap

  1. The observation scope was identified for review

    In the alternative review, request order A,B and server preparation order are known, but client-delivery observations are missing. The normal artifact contains deliveredOrder; that value cannot be treated as evidence from the incomplete trace.

    Message record
    Request/preparation known / arrival unobserved
    Correlation review
    Count/order review pending
    Evidence conclusion
    No coverage verdict
  2. Preparation records did not close the arrival gap

    B being ready first does not mean it arrived first. A’s ready record is not client receipt either. The correlation gate checks observer location and complete-message boundaries rather than replacing client measurements with server state.

    Message record
    Request/preparation known / arrival unobserved
    Correlation review
    Ready ≠ arrival / receiver coverage needed
    Evidence conclusion
    No coverage verdict
  3. A missing trace can produce zero matches

    The order selector operates only on available pipeline observations. If delivered-order records are absent, the inconsistency count may remain zero. That does not establish trace completeness or preservation of protocol order.

    Message record
    Zero mismatch possible with missing evidence
    Correlation review
    Ready ≠ arrival / receiver coverage needed
    Evidence conclusion
    No coverage verdict
  4. The negative control was evaluated within scope

    The complete normal XML and positive mismatch XML test oracle behavior together. Missing client observation is a different condition from either control. Substituting the fixture’s expected array for a missing observation would remove the coverage requirement.

    Message record
    Zero mismatch possible with missing evidence
    Correlation review
    Controls known / actual arrival evidence absent
    Evidence conclusion
    No coverage verdict
  5. The delivery verdict was left unknown

    Delivery order remains UNKNOWN in this review. No network-loss, authorization-denial or session-termination conclusion is added. Missing evidence alone establishes neither success nor failure of the boundary.

    Message record
    Zero mismatch possible with missing evidence
    Correlation review
    Controls known / actual arrival evidence absent
    Evidence conclusion
    UNKNOWN: client delivery order
  6. New observation was scoped to the minimum need

    A changed verdict requires client-observer records of message completion and correlation. Storing all private content is unnecessary; request order, declared length, completion and observer scope may suffice. The normal fixture’s result is not transferred without new evidence.

    Message record
    Zero mismatch possible with missing evidence
    Correlation review
    Controls known / actual arrival evidence absent
    Evidence conclusion
    Needed: receiver completion + correlation

IMPLEMENTATION · SECURITY CONTROL · VERIFICATION

Record order and completeness in one ledger

Assign instructional A/B order aliases to requests and count response content bytes against declared lengths. These aliases are not HTTP/1.1 stream identifiers; correlation uses request order. Mark the next message starting after each response’s final byte.

B-ready can precede A-ready while B-arrived must follow A-arrived. Separate artifact arrays record preparation and delivery orders. The XPath selects an authored observation claiming reversed response delivery; normal and inconsistent fixtures return 0 and 1.

Missing observations can also return 0 without verifying ordering. Defer speed/success conclusions until trace scope, correlation, and completeness are established. Diagnostics need not retain entire bodies or personal notes.

Interpret closure in framing context

In the historical branch, receiving four content bytes does not yet end an EOF-delimited response. The supplied closure establishes its boundary and removes connection reuse. Drawing closure as application logout or resource deletion would invent another mechanism.

The current self-delimited branch completes CL=10 and CL=4 while leaving its connection open. Equal visible text does not imply equal completeness or reuse rules. Manual analysis proceeds from version/method/status through framing to transport closure.

A native local fixture can exercise in-order delivery for two safe GETs, while the authored scene as a whole remains a teaching model. Browser pooling, TLS, proxy conversion, production timeouts, and session policy require separate evidence.

An HTTP/1.1 client must consume the complete response body before reusing its connection for another request. A server must likewise consume the request body or close after responding. Leave framing to a standard HTTP implementation instead of treating an application read chunk as a whole message. For these two normal GETs, B must not be emitted before A even when ready earlier; ordered responses and completed body boundaries are distinct requirements to preserve together.

NOW APPLY IT TO THE CASE

What separate evidence do preparation, message completion and client arrival require?

A names the Atlas note response and B the Çay response. Even when the server prepares B first, HTTP/1.1 pipeline response order stays A, B. In the historical HTTP/1.0 example, four body bytes are insufficient; a close event identifies completion.

Which application conditions would remain if the case used another HTTP transport? Do not equate stream or packet completion with successful note parsing.

Open the related case file ↗

READ THE EXAMPLE TOGETHER

A/B pipeline and EOF ledger

Select a field and examine what it supports and where the evidence ends.

Read the raw artifact and field explanations
{
  "requests": [
    {
      "alias": "A",
      "path": "/atlas-notes",
      "wire": "GET /atlas-notes HTTP/1.1\r\nHost: library.atlas.example\r\n\r\n"
    },
    {
      "alias": "B",
      "path": "/tea",
      "wire": "GET /tea HTTP/1.1\r\nHost: library.atlas.example\r\n\r\n"
    }
  ],
  "responses": [
    {
      "alias": "A",
      "body": "Atlas note",
      "contentOctets": 10,
      "wire": "HTTP/1.1 200 OK\r\nDate: Thu, 08 Oct 2026 00:00:00 GMT\r\nContent-Type: text/plain; charset=utf-8\r\nContent-Length: 10\r\n\r\nAtlas note",
      "messageOctets": 127
    },
    {
      "alias": "B",
      "body": "Çay",
      "contentOctets": 4,
      "wire": "HTTP/1.1 200 OK\r\nDate: Thu, 08 Oct 2026 00:00:00 GMT\r\nContent-Type: text/plain; charset=utf-8\r\nContent-Length: 4\r\n\r\nÇay",
      "messageOctets": 120
    }
  ],
  "requestStream": "GET /atlas-notes HTTP/1.1\r\nHost: library.atlas.example\r\n\r\nGET /tea HTTP/1.1\r\nHost: library.atlas.example\r\n\r\n",
  "responseStream": "HTTP/1.1 200 OK\r\nDate: Thu, 08 Oct 2026 00:00:00 GMT\r\nContent-Type: text/plain; charset=utf-8\r\nContent-Length: 10\r\n\r\nAtlas noteHTTP/1.1 200 OK\r\nDate: Thu, 08 Oct 2026 00:00:00 GMT\r\nContent-Type: text/plain; charset=utf-8\r\nContent-Length: 4\r\n\r\nÇay",
  "preparedOrder": [
    "B",
    "A"
  ],
  "deliveredOrder": [
    "A",
    "B"
  ],
  "connectionAfterComplete": "open",
  "http10": {
    "request": "GET /tea HTTP/1.0\r\n\r\n",
    "responseBytesBeforeClose": "HTTP/1.0 200 OK\r\nDate: Thu, 08 Oct 2026 00:00:00 GMT\r\nContent-Type: text/plain; charset=utf-8\r\n\r\nÇay",
    "body": "Çay",
    "bodyOctets": 4,
    "contentLengthField": null,
    "transferEncodingField": null,
    "completionRule": "response connection close",
    "completeBeforeClose": false,
    "completeAfterSuppliedClose": true,
    "reusableAfterClose": false,
    "scope": "Historical valid close-delimited response; EOF event supplied, not a native HTTP1.0 measurement."
  },
  "selector": {
    "language": "XPath",
    "xml": "<observations><pipeline requestOrder=\"A,B\" deliveredOrder=\"A,B\"/></observations>",
    "xpath": "count(/observations/pipeline[@requestOrder=\"A,B\" and @deliveredOrder!=\"A,B\"])",
    "expected": 0,
    "positiveFixtureXml": "<observations><pipeline requestOrder=\"A,B\" deliveredOrder=\"B,A\"/></observations>",
    "positiveExpected": 1,
    "scope": "Only authored protocol-decision observations, not product log field names or a live HTTP capture.",
    "missingFieldBehavior": "Missing observation is insufficient evidence; zero matches is not proof of correct runtime behavior."
  }
}
preparedOrder / deliveredOrder
Server preparation and client arrival are distinct orders.
contentOctets / messageOctets
Content-Length counts content; the full message also contains headers.
http10.completeBeforeClose
EOF-delimited completeness is false before the supplied close.

Valid safe GET fixtures; A/B are not protocol fields. Historical close is supplied; native local pipeline evidence has a separate scope. Browser/TLS/proxy/session behavior is not measured.

Two reality checks

Pipelining interleaves the second response as soon as it is ready.

HTTP/1.1 response order follows request order. B waits for A even when prepared first; stream multiplexing is different.

An HTTP message ends whenever a TCP read ends.

Socket-delivery boundaries are not message boundaries. Self-delimited length or the correct EOF context supplies framing; four received bytes alone do not prove completion.

YOUR TURN

Work through this story.

Predict the outcome, find the evidence boundary, and explain it in your own words.

A pipeline receives A then B, but response B is ready first. What is the selected HTTP/1.1 delivery order?

  1. A, B; ready B waits behind the first response.
  2. B, A; the first completed handler always writes first to the wire.
Read the explained answer

A, B; ready B waits behind the first response. — Pipelined responses match request order. PreparedOrder B, A does not make delivery B, A.

When is this historical HTTP/1.0 response considered complete?

Selected lesson artifact fields; teaching example

http10.contentLengthField
null
http10.completeBeforeClose
false
http10.completeAfterSuppliedClose
true
  1. As soon as Çay appears; the body length is guessed.
  2. After the supplied connection close.
Read the explained answer

After the supplied connection close. — The selected close-delimited content ends at EOF; that connection is no longer reusable.

How does HTTP/1.1 separate two Content-Length responses in one byte stream? Why is a read-call boundary insufficient?

Read the explained answer

The parser finds the CRLF header boundary, consumes ten content octets for the first response, then the second start-line/headers and four octets. TCP reads need not align with message boundaries. Searching for another response by adding arbitrary whitespace after the body is not this fixture’s length framing.

□ I used content octets for framing.

□ I did not treat TCP-read boundaries as HTTP boundaries.

Open the application console · request / response / browser
Also open request, URL, cookie and DOM examples

Sources and scope