Commit b240749
authored
RFC Conformance: Fix HTTP/1.0 streaming response framing
I had Claude help validate the code against various RFC spec for conformance, and it flagged below. Claude helped with the desc.
## Nonconformance
`Bandit.HTTP1.Socket.send_headers/4` added `Transfer-Encoding: chunked` for every streamed response without a `Content-Length`, including responses to HTTP/1.0 requests.
[RFC 9112 Section 6.1](https://www.rfc-editor.org/rfc/rfc9112.html#section-6.1) says that a server **MUST NOT** send a response containing `Transfer-Encoding` unless the corresponding request indicates HTTP/1.1 or later. [RFC 9112 Section 6.3, rule 8](https://www.rfc-editor.org/rfc/rfc9112.html#section-6.3-8) defines a response without `Transfer-Encoding` or `Content-Length` as close-delimited.
## Change
For an HTTP/1.0 streamed response whose length is not known in advance, Bandit now:
- sends the body bytes without HTTP/1.1 chunk framing;
- omits `Transfer-Encoding`, including a field supplied by the application;
- sends `Connection: close`; and
- disables connection reuse so that connection closure delimits the body.
HTTP/1.1 streaming and content-length-delimited streaming are unchanged.
## Regression test
The new protocol test sends an HTTP/1.0 request with `Connection: keep-alive` to a chunked Plug response. It reads through connection closure and verifies that:
- the decoded body is complete;
- no `Transfer-Encoding` field is present; and
- `Connection: close` is present.
A companion test verifies that Bandit removes an application-supplied `Transfer-Encoding` field from an HTTP/1.0 streamed response.
Run:
```console
mix test test/bandit/http1/protocol_test.exs
```
Verified against Bandit `main` at `b084b37` with Erlang/OTP 27.3 and Elixir 1.18.4:
- `mix format --check-formatted`
- `MIX_ENV=test mix compile --warnings-as-errors`
- Full non-slow suite: 816 tests pass (the suite's one IPv6 server binding test needs an IPv6-capable host)
- `mix credo --strict` and `mix dialyzer` pass on the combined tree of all nineteen prepared Bandit changes1 parent b084b37 commit b240749
2 files changed
Lines changed: 69 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
455 | 455 | | |
456 | 456 | | |
457 | 457 | | |
| 458 | + | |
458 | 459 | | |
459 | 460 | | |
460 | 461 | | |
| |||
465 | 466 | | |
466 | 467 | | |
467 | 468 | | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
468 | 478 | | |
469 | 479 | | |
470 | 480 | | |
| |||
484 | 494 | | |
485 | 495 | | |
486 | 496 | | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
487 | 505 | | |
488 | 506 | | |
489 | 507 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1551 | 1551 | | |
1552 | 1552 | | |
1553 | 1553 | | |
| 1554 | + | |
| 1555 | + | |
| 1556 | + | |
| 1557 | + | |
| 1558 | + | |
| 1559 | + | |
| 1560 | + | |
| 1561 | + | |
| 1562 | + | |
| 1563 | + | |
| 1564 | + | |
| 1565 | + | |
| 1566 | + | |
| 1567 | + | |
| 1568 | + | |
| 1569 | + | |
| 1570 | + | |
| 1571 | + | |
| 1572 | + | |
| 1573 | + | |
| 1574 | + | |
| 1575 | + | |
| 1576 | + | |
| 1577 | + | |
| 1578 | + | |
| 1579 | + | |
| 1580 | + | |
| 1581 | + | |
| 1582 | + | |
| 1583 | + | |
| 1584 | + | |
| 1585 | + | |
| 1586 | + | |
| 1587 | + | |
| 1588 | + | |
| 1589 | + | |
| 1590 | + | |
| 1591 | + | |
| 1592 | + | |
| 1593 | + | |
| 1594 | + | |
| 1595 | + | |
| 1596 | + | |
| 1597 | + | |
| 1598 | + | |
| 1599 | + | |
| 1600 | + | |
| 1601 | + | |
| 1602 | + | |
| 1603 | + | |
| 1604 | + | |
1554 | 1605 | | |
1555 | 1606 | | |
1556 | 1607 | | |
| |||
0 commit comments