Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
    npro  
 Modern all-safe Rust Network Protocol library supporting h1, h2, h3, ws, wt sans-IO and with socket IO + tls
git clone https://npro.rs/repo/npro
 
root / crates / npro-test / h1 / requests / headers-bare-cr.http
Author[]Andy Green <andy@warmcat.com> 2026-10-03 09:24 UTC
Committer[]Andy Green <andy@warmcat.com> 2026-10-05 06:32 UTC
Treede0d6c6fd75dcd39f6c67883d0fd0d1e21480ebc   Raw Patch
 
npro-test: sync the transcripts with C lws main-dev 1ba2879
npro-test: sync the transcripts with C lws main-dev 1ba2879

C main-dev moved from 75b415f4 by 43 commits.  Two of them add
api-test-sansio cases, and their README rows come with them:
- 393de4b, h1-short-answer: an answer completed short of its framing
  closes the connection;
- a7003b3, ws-server-not-get: an h1 ws upgrade that is not a GET is
  refused.

The 48 transcripts already here are unchanged.  Others in the range fix
what the port plan listed as wanted before the state tables are
translated:
- bbe4261: an h1 answer now arms and renews the response watchdog;
- b9dd466: a body left unread by a file abandoned on a worker read is
  discarded.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019kg5Eemy68ZaqDBcUJQG6J
diff --git a/crates/npro-test/transcripts/C-COMMIT b/crates/npro-test/transcripts/C-COMMIT index 27ce8ae..9bb4339 100644 --- a/crates/npro-test/transcripts/C-COMMIT +++ b/crates/npro-test/transcripts/C-COMMIT @@ -1 +1 @@ -75b415f4afd5b542badbbf87b6ffec56f3cf3cfc api-test-ws-pmd-takeover: xorshift masks what each left shift would discard +1ba28796b2db62a255720c308498eff0325b3e83 metrics: release tags a close adds to the wsi after its caliper report diff --git a/crates/npro-test/transcripts/README.lws.md b/crates/npro-test/transcripts/README.lws.md index b5da82b..4e91a31 100644 --- a/crates/npro-test/transcripts/README.lws.md +++ b/crates/npro-test/transcripts/README.lws.md @@ -86,7 +86,7 @@ does only this: |`h1-client-cl-junk`, `h1-client-cl-twice`, `h1-client-te-list`|client|as `h1-client-get`. The peer answers 200 with `Content-Length: 10abc`; with `Content-Length: 10` and a second `Content-Length: 5`; or with `Transfer-Encoding: chunked` and a second `Transfer-Encoding: gzip`, which makes the codings a list. lws cannot know where such a body ends: it gives the app none of it, fails the connection and releases it| |`h1-client-head-chunked`, `h1-client-head-cl`, `h1-client-304-cl`|client|as `h1-client-get`, asking with `HEAD` for the first two. The peer answers 200 with `Transfer-Encoding: chunked`; 200 with `Content-Length: 10`; or, to the `GET`, 304 with `Content-Length: 10`. None of these has a body (RFC 9112 6.3): lws completes the transaction at the end of the headers and gives the app nothing| |`ws-client`|client|connects to `sansio`, port 80, `GET /echo`, ws subprotocol `echo`; once established, sends one text message `Hello`, and takes the messages it receives| -|`ws-server-version-8`, `ws-server-no-version`, `ws-server-conn-no-upgrade`, `ws-server-no-subprotocol`|server|as `h1-ws-server`. The peer asks for a ws upgrade saying `Sec-WebSocket-Version: 8`; or no version at all; or `Connection: up`, which is not the `upgrade` token; or only the subprotocol `chat`, which the vhost does not have. lws answers the first with 426 and `sec-websocket-version: 13`, the others with 400, each with the usual status page, then shuts the connection down (a half-close, waiting for the peer's; no `close` step follows)| +|`ws-server-version-8`, `ws-server-no-version`, `ws-server-conn-no-upgrade`, `ws-server-no-subprotocol`, `ws-server-not-get`|server|as `h1-ws-server`. The peer asks for a ws upgrade saying `Sec-WebSocket-Version: 8`; or no version at all; or `Connection: up`, which is not the `upgrade` token; or only the subprotocol `chat`, which the vhost does not have; or, otherwise acceptably, with a POST, where an h1 upgrade must be a GET (RFC 6455 4.1). lws answers the first with 426 and `sec-websocket-version: 13`, the others with 400, each with the usual status page, then shuts the connection down (a half-close, waiting for the peer's; no `close` step follows)| |`ws-client-rsv1-no-ext`, `ws-client-rsv2`, `ws-client-huge-frame`|client|as `ws-client`, no extension offered. After the 101, the peer sends a frame with RSV1, with RSV2, or whose length is 256MiB + 1: lws gives the app nothing of it and sends a close, status 1002 `rsv bits` for the RSV ones and 1009 `huge frame` for the length; the peer answers the close and lws releases the connection| |`ws-client-ping-close`|client|as `ws-client`, sending nothing once established. The peer sends a ping `p` and then a close with status 1000 in one read: lws sends the masked pong, then the masked answer to the close with the peer's 1000, and releases the connection| |`ws-client-interim`|client|as `ws-client`. The peer answers the upgrade with an interim `100 Continue`, then in the same read the 101: lws skips the interim response, goes on waiting, and is established by the 101| @@ -105,6 +105,7 @@ does only this: |`h2-ws-peer-close`|server|a sixth vhost, `sansio-h2ws`, taking h2 with prior knowledge, with the ws protocols of `sansio`. The peer sends the preface and SETTINGS, then an extended CONNECT (RFC 8441) for a ws stream on sid 1 speaking `echo`, which is accepted with 200; then one DATA frame holding, masked, a close with status 1000 and after it a ping `p`. lws answers the close with the peer's own 1000 and END_STREAM, reads nothing after it, so the ping gets no pong, and resets the stream with NO_ERROR, since the peer has not ended its side: not REFUSED_STREAM, which is only for a refused upgrade| |`h1-post-no-length`|server|as `h1-uri-*`, on `sansio-uri`. The peer sends, in one read, `POST /x?a=1` with neither `Content-Length` nor `Transfer-Encoding`, and behind its head `GET /y?b=2`. The POST has no body (RFC 9112 6.3): lws answers it (path `/x`, args `a=1`), then serves the GET as the next request on the kept-alive connection, rather than taking it as the POST's body and reading until the close| |`h1-connect-rejected-ua`|server|as `h1-reqline-*`, on `sansio-uri`, in a context that turns away a user agent containing `badbot` with `403 Go away`. The peer sends a CONNECT for `example.com:443` saying it is `badbot/1`: it is refused like any other request of its, 403 with the status page, and the connection shut down, rather than handed to the fallback role first| +|`h1-short-answer`|server|as `h1-uri-*`, on `sansio-uri`, whose app answers `/short` with a head giving `content-length: 10`, sends `abc` (nothing to a HEAD) and completes the transaction. The peer sends `HEAD /short`: the answer is whole without a body, and the connection is kept alive. Then `GET /short`: the answer is 7 bytes short of its length, and kept alive, the peer would read the next answer as the rest of it, so the connection is shut down| ## Recording diff --git a/crates/npro-test/transcripts/h1-short-answer.json b/crates/npro-test/transcripts/h1-short-answer.json new file mode 100644 index 0000000..d334d20 --- /dev/null +++ b/crates/npro-test/transcripts/h1-short-answer.json @@ -0,0 +1,14 @@ +{ + "format": "lws-transcript/1", + "case": "h1-short-answer", + "side": "server", + "t0_us": 1000000000, + "t0_wall": 1767225600, + "seed": 0, + "steps": [ + {"t": 205001000, "rx": "48454144202f73686f727420485454502f312e310d0a486f73743a2073616e73696f2d7572690d0a0d0a"}, + {"t": 205001000, "tx": "485454502f312e3120323030204f4b0d0a636f6e74656e742d747970653a20746578742f706c61696e0d0a636f6e74656e742d6c656e6774683a2031300d0a0d0a"}, + {"t": 205002000, "rx": "474554202f73686f727420485454502f312e310d0a486f73743a2073616e73696f2d7572690d0a0d0a"}, + {"t": 205002000, "tx": "485454502f312e3120323030204f4b0d0a636f6e74656e742d747970653a20746578742f706c61696e0d0a636f6e74656e742d6c656e6774683a2031300d0a0d0a616263"} + ] +} diff --git a/crates/npro-test/transcripts/ws-server-not-get.json b/crates/npro-test/transcripts/ws-server-not-get.json new file mode 100644 index 0000000..7672ca7 --- /dev/null +++ b/crates/npro-test/transcripts/ws-server-not-get.json @@ -0,0 +1,12 @@ +{ + "format": "lws-transcript/1", + "case": "ws-server-not-get", + "side": "server", + "t0_us": 1000000000, + "t0_wall": 1767225600, + "seed": 0, + "steps": [ + {"t": 3005000, "rx": "504f5354202f6563686f20485454502f312e310d0a486f73743a2073616e73696f0d0a557067726164653a20776562736f636b65740d0a436f6e6e656374696f6e3a20557067726164650d0a5365632d576562536f636b65742d56657273696f6e3a2031330d0a5365632d576562536f636b65742d50726f746f636f6c3a206563686f0d0a5365632d576562536f636b65742d4b65793a206447686c49484e68625842735a5342756232356a5a513d3d0d0a0d0a"}, + {"t": 3005000, "tx": "485454502f312e31203430302042616420526571756573740d0a636f6e74656e742d747970653a20746578742f68746d6c0d0a636f6e74656e742d6c656e6774683a203137330d0a0d0a3c68746d6c3e3c686561643e3c6d65746120636861727365743d7574662d3820687474702d65717569763d22436f6e74656e742d4c616e67756167652220636f6e74656e743d22656e222f3e3c6c696e6b2072656c3d227374796c6573686565742220747970653d22746578742f6373732220687265663d222f6572726f722e637373222f3e3c2f686561643e3c626f64793e3c68313e3430303c2f68313e3c2f626f64793e3c2f68746d6c3e"} + ] +}
Page fetched 0s ago, creation time: 2ms (vhost etag hits: 0%, cache hits: 0%)