Skip to content

refactor(application): use the RFC names HTTP/1 and HTTP/2 in HTTP's id()? #2524

Open

Description

@JarryShaw

The owner asked in session whether HTTP's id() should use the RFC canonical names, by the same reasoning as the ICMPv4 and IGMPv1 rulings in protocol-family-grouping.rst's Canonical Names section.

Today, unchanged since 1.5.1: HTTP.id() is ('HTTP', 'HTTPv1', 'HTTPv2'), HTTPv1.id() is ('HTTP', 'HTTPv1') and HTTPv2.id() is ('HTTP', 'HTTPv2'). The per-message alias already carries the exact version: HTTP/0.9, HTTP/1.0, HTTP/1.1 or HTTP/2.

Decision needed: what names go in the version slots of id()?

  1. HTTP/1 and HTTP/2, keeping the family-inclusive shape: ('HTTP', 'HTTP/1', 'HTTP/2'), ('HTTP', 'HTTP/1') and ('HTTP', 'HTTP/2').
  2. HTTP/1.1 and HTTP/2, the RFC 9112 and RFC 9113 titles.
  3. Keep HTTPv1 and HTTPv2.

Recommendation: 1. RFC 9113 names HTTP/2 exactly that. No RFC is titled HTTP/1, but the v1 class parses 0.9, 1.0 and 1.1, so HTTP/1.1 would misname 1.0 traffic, and the alias already gives the exact version. Either 1 or 2 is breaking: layer == 'HTTPv1' stops matching, because string == checks only id(). The HTTPv1/HTTPv2 registry keys keep selecting through the class. 'HTTP/2' in frame and frame['HTTP/2'] start matching, which brings Protocol selectors in line with ProtoChain's alias match. The doc's Selector Matching examples and Member Shapes table change with it, and the change gets versionchanged:: 1.6.0.

Activity

  1. added
    refactorRestructuring for its own sake — neither a fix nor a new capability (refactor: prefix)
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Nov 1, 2026
  2. JarryShaw commented on Nov 1, 2026

    @JarryShaw
    OwnerAuthor

    i think it should be

    HTTP.id() -> (HTTP/1, HTTP/2)
    HTTPv1.id() -> (HTTP/1,)
    HTTPv2.id() -> (HTTP/2,)

    we've got convention in action from ICMP and IGMP.

  3. moved this to Needs decision in PyPCAPKiton Nov 1, 2026
  4. JarryShaw commented on Nov 1, 2026

    @JarryShaw
    OwnerAuthor

    Owner ruling, paraphrased: HTTP follows the ICMP/IGMP canonical-name convention fully. The members narrow to their RFC names, and the base lists only the members:

    • HTTP.id() → ('HTTP/1', 'HTTP/2'), members only, in the shape of IP.id() (('IPv4', 'IPv6')).
    • HTTPv1.id() → ('HTTP/1',) and HTTPv2.id() → ('HTTP/2',), each narrowed to itself.

    Reconciled against the options above: this takes option 1's names, with the narrow-to-self shape rather than the family-inclusive one. It is breaking, because string == checks only id(), so layer == 'HTTPv1' and layer == 'HTTP' stop matching. The HTTP/HTTPv1/HTTPv2 registry keys still select through their classes. The change carries versionchanged:: 1.6.0 and updates protocol-family-grouping.rst's Member Shapes, Canonical Names and Selector Matching to match. Dispatched.

  5. added
    wipWork in flight - a covering PR is open or an agent is actively on it
    breakingBreaks public-facing behaviour or API (apply alongside the type label)
    and removed
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Nov 1, 2026
  6. moved this from Needs decision to WIP in PyPCAPKiton Nov 1, 2026
  7. JarryShaw commented on Nov 1, 2026

    @JarryShaw
    OwnerAuthor

    The ruled id() tuples are done locally (9cc9d5110). Its review says the code is correct, and asks for text fixes: five stale cross-references and a fuller breaking note. The #2529 class renames (httpv1.HTTPv1, httpv2.HTTPv2, with their schema/data classes per Q2) join that fix round. Decision needed: version selectors on a parsed layer. A parsed HTTP/1.1 or HTTP/2 layer is always the base HTTP class, and HTTP.id() lists both members, so 'HTTP/1' in, 'HTTP/2' in and layer == 'HTTP/2' are all True on either frame. That breaks Selector Matching's rule that each version name selects its own (#2443). Part of it already held on main ('HTTPv2' in an HTTP/1.1 frame), and part is new (the protochain's 'HTTP/2' used to be False on HTTP/1.1).

    1. Accept it as HTTP's documented exception: the per-message alias/version tell the versions apart, and nothing else changes.
    2. Make a parsed layer narrow to its version, by dispatching to HTTPv1/HTTPv2 as IGMP does or with an instance-aware id(). That moves the data key from http to httpv1/httpv2, which shipped, so it is breaking.

    Recommendation: 1. It keeps the shipped info key, and alias already carries the exact version. The page states the exception.

  8. added
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Nov 1, 2026
  9. moved this from WIP to Needs decision in PyPCAPKiton Nov 1, 2026
  10. JarryShaw commented on Nov 1, 2026

    @JarryShaw
    OwnerAuthor

    Take 2

  11. JarryShaw commented on Nov 1, 2026

    @JarryShaw
    OwnerAuthor

    Owner chose 2: a parsed HTTP layer narrows to its own version. A frame is dispatched to HTTPv1/HTTPv2, as IGMP is, so 'HTTP/1' in, 'HTTP/2' in and layer == 'HTTP/2' match only their own version. That restores Selector Matching's rule from #2443, with no HTTP exception.
    It is breaking: the data key moves from http to httpv1/httpv2, matching IGMP's info_name ruling (a). It goes into the running #2524 fix round on the same branch, after that round reports back.

  12. removed
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Nov 1, 2026
  13. moved this from Needs decision to WIP in PyPCAPKiton Nov 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    breakingBreaks public-facing behaviour or API (apply alongside the type label)refactorRestructuring for its own sake — neither a fix nor a new capability (refactor: prefix)wipWork in flight - a covering PR is open or an agent is actively on it

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions