Repository navigation
fix(tcp): repoint TCP:80/8080 at the HTTP version proxy (#682) - #821
Conversation
|
These 10 red legs are not this PR's fault — they are Verified rather than assumed, because "the same test fails on the baseline" is exactly the claim a broken PR would also make:
#821 is simply the first PR whose branch was cut after #814 merged, which is why #817 and #820 — both based on pre-#814 One correction to my own earlier note here: I flagged the Cross-review is running; verdict to follow. |
|
Cross-review verdict: GOOD TO GO (sonnet; author was opus). All seven load-bearing claims confirmed by independent derivation, not by restating the author — including one probe the reviewer caught failing on itself ( Highlights it re-derived rather than accepted: the 9 changed frames are 35-43 1-indexed (the author's "34-42" is 0-indexed, same frames); 23 captures / 1604 frames enumerated with The nuance worth your attention, which I verified myself on So the one behavioural consequence of this PR: TCP:80/8080 traffic that is neither valid HTTP/1 nor preface-carrying is now exposed to that fall-through, where The 10 red legs are #822's, inherited from |
`TCP.__proto__` bound `httpv1.HTTP` directly for ports 80 and 8080, so a segment on either port was HTTP/1 by assertion of the port number: an HTTP/2 payload there was refused by the HTTP/1 parser and reported as `Raw`. Both versions share those ports on the wire, so the port cannot decide the version and the payload has to. * `pcapkit/protocols/transport/tcp.py` — ports 80 and 8080 now resolve to `pcapkit.protocols.application.http.HTTP`, which identifies the version before parsing (#800, landed via #814) rather than trial-parsing. * `examples/generators/dispatch.py` — `PINNED_TARGETS` for `tcp/80` and `tcp/8080` follow the repoint. * `pcapkit/protocols/transport/udp.py`, `docs/source/pep.rst` — the prose documenting the TCP/UDP asymmetry is now stale; both tables agree. * `tests/protocols/transport/test_tcp_http_dispatch_unit.py` — new; pins the descriptor, the TCP/UDP parity, and that HTTP/2 on port 80/8080 decodes as HTTP/2 while HTTP/1.1 still decodes as HTTP/1.1. All 231 HTTP/1.1 frames in the 23-capture corpus keep their chain; 9 frames in `options-transport.pcap` change `TCP:Raw` -> `TCP:HTTP/2`, which is the defect being fixed. `_guess_version` entry count over the corpus goes 0 -> 252.
67b88a4 to
555c4fc
Compare
|
Rebased onto
The Heads-up on a latent collision: this PR and #826 both touch |
|
CI is complete and clean — The 10 red legs here were #822's, inherited from Ordering note, because it decides which of two PRs needs a rebase: this PR and #826 both touch The behavioural caveat from the cross-review still stands and is on the record above: TCP:80/8080 traffic that is neither valid HTTP/1 nor preface-carrying is now exposed to |
…s in #817 and #821 Two bullets, both non-breaking, appended after the #800 entry in merge order. Bullet count 128 to 130 (`grep -cE '^\* \*\*'`). - #804 (PR #817) -- the three `__repr__` methods #798 left `%`-formatted are f-strings now, dropping `consider-using-f-string` from both const modules and both vendor templates; the other bespoke templates in `{const,vendor}/{ftp,http}/` still carry the disable, so #804's claim holds for this pair only, not for those directories. - #682 (PR #821) -- `TCP.__proto__` no longer binds `httpv1.HTTP` directly for ports 80/8080; both repoint to the generic HTTP proxy `_guess_version` identifies through, which only became reliable once #800/#814 landed. `udp.py` already pointed there, so that side of the PR is prose-only (its port rows and docstring), not a code change, and the entry says so. Protochain over the 23 sample captures is *not* byte-identical: 9 frames in `options-transport.pcap` go `Raw` to `HTTP/2`, all 231 HTTP/1.1 frames are unaffected, and `_guess_version`'s entry count goes 0 to 252. Not marked `**a breaking change to**`: PR #821's own labels are `bug,fix,docs,test`, no `breaking`, unlike #759/#783 and #805/#811 last round, whose crediting PRs did carry it. The entry does say what a `breaking`-blind reader would still want to know -- TCP:80/8080 traffic that is neither valid HTTP/1 nor preface-carrying now reaches `_guess_version`'s fall-through arm instead of the direct `httpv1` bind's unconditional `Raw`, which is where the 12 (of 252) fall-throughs the PR measured come from. `util/changelog_md.py` regenerated `CHANGELOG.md`, first pass, no line-spanning literal this round; `--check` exit 0. `test_changelog_md.py` 47 passed.
…s in #817 and #821 Two bullets, both non-breaking, appended after the #800 entry in merge order. Bullet count 128 to 130 (`grep -cE '^\* \*\*'`). - #804 (PR #817) -- the three `__repr__` methods #798 left `%`-formatted are f-strings now, dropping `consider-using-f-string` from both const modules and both vendor templates; the other bespoke templates in `{const,vendor}/{ftp,http}/` still carry the disable, so #804's claim holds for this pair only, not for those directories. - #682 (PR #821) -- `TCP.__proto__` no longer binds `httpv1.HTTP` directly for ports 80/8080; both repoint to the generic HTTP proxy `_guess_version` identifies through, which only became reliable once #800/#814 landed. `udp.py` already pointed there, so that side of the PR is prose-only (its port rows and docstring), not a code change, and the entry says so. Protochain over the 23 sample captures is *not* byte-identical: 9 frames in `options-transport.pcap` go `Raw` to `HTTP/2`, all 231 HTTP/1.1 frames are unaffected, and `_guess_version`'s entry count goes 0 to 252. Not marked `**a breaking change to**`: PR #821's own labels are `bug,fix,docs,test`, no `breaking`, unlike #759/#783 and #805/#811 last round, whose crediting PRs did carry it. The entry does say what a `breaking`-blind reader would still want to know -- TCP:80/8080 traffic that is neither valid HTTP/1 nor preface-carrying now reaches `_guess_version`'s fall-through arm instead of the direct `httpv1` bind's unconditional `Raw`, which is where the 12 (of 252) fall-throughs the PR measured come from. `util/changelog_md.py` regenerated `CHANGELOG.md`, first pass, no line-spanning literal this round; `--check` exit 0. `test_changelog_md.py` 47 passed.
make pylint,make mypy,make isort) — not runmake testpasses, and a test case covers the change — a test case covers it (tests/protocols/transport/test_tcp_http_dispatch_unit.py), but the fullmake testwas not run; scope run wastests/protocols/What is the purpose of your pull request?
fix— corrects a defectDescription of your pull request and other information
Closes #682.
TCP.__proto__boundhttpv1.HTTPdirectly for ports 80 and 8080 (tcp.py:330-331on3cbdf8999), so a segment on either port was HTTP/1 by assertion of the port number. Both versions share those ports on the wire, so the port cannot decide the version and the payload has to. Repointed topcapkit.protocols.application.http.HTTP, whose identification became positive in #800/#814 — which is why this waited.udp.pyalready bound the proxy for both ports, so this removes the asymmetry its docstring anddocs/source/pep.rstdocumented as an open request; both are updated.Protochain over all 23 captures / 1604 frames is not byte-identical, and that is the fix. All 231 HTTP/1.1 frames keep their chain (0 lost an HTTP layer). Nine frames in
options-transport.pcapchangeEthernet:IPv4:TCP:Raw->Ethernet:IPv4:TCP:HTTP/2: genuine HTTP/2 frames (self-consistent 9-octet headers, types 0-9,sid=0) built by this library's ownhttpv2.HTTP.make, previously refused by the HTTP/1 parser.Instrumented
_guess_versionentry count over the corpus: 0 -> 252 (231 HTTP/1.1 + 9 HTTP/2 + 12 fall-throughs that stayRaw).examples/generators/dispatch.py'sPINNED_TARGETSfollows the repoint, which is whattests/protocols/test_dispatch_registry_unit.pychecks against.One pre-existing failure, unrelated and out of scope:
test_http_unit.py::test_guess_version_reports_a_preface_with_no_frame_as_suchfails identically on stock3cbdf8999.