pypcapkit 1.3.3.post1__cp313-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pcapkit/__init__.py +126 -0
- pcapkit/__main__.py +138 -0
- pcapkit/all.py +136 -0
- pcapkit/const/__init__.py +81 -0
- pcapkit/const/arp/__init__.py +25 -0
- pcapkit/const/arp/hardware.py +181 -0
- pcapkit/const/arp/operation.py +131 -0
- pcapkit/const/ftp/__init__.py +25 -0
- pcapkit/const/ftp/command.py +309 -0
- pcapkit/const/ftp/return_code.py +304 -0
- pcapkit/const/hip/__init__.py +94 -0
- pcapkit/const/hip/certificate.py +77 -0
- pcapkit/const/hip/cipher.py +65 -0
- pcapkit/const/hip/di.py +59 -0
- pcapkit/const/hip/ecdsa_curve.py +59 -0
- pcapkit/const/hip/ecdsa_low_curve.py +56 -0
- pcapkit/const/hip/eddsa_curve.py +65 -0
- pcapkit/const/hip/esp_transform_suite.py +98 -0
- pcapkit/const/hip/group.py +86 -0
- pcapkit/const/hip/hi_algorithm.py +86 -0
- pcapkit/const/hip/hit_suite.py +68 -0
- pcapkit/const/hip/nat_traversal.py +62 -0
- pcapkit/const/hip/notify_message.py +200 -0
- pcapkit/const/hip/packet.py +89 -0
- pcapkit/const/hip/parameter.py +377 -0
- pcapkit/const/hip/registration.py +68 -0
- pcapkit/const/hip/registration_failure.py +84 -0
- pcapkit/const/hip/suite.py +71 -0
- pcapkit/const/hip/transport.py +59 -0
- pcapkit/const/http/__init__.py +39 -0
- pcapkit/const/http/error_code.py +95 -0
- pcapkit/const/http/frame.py +95 -0
- pcapkit/const/http/method.py +184 -0
- pcapkit/const/http/setting.py +96 -0
- pcapkit/const/http/status_code.py +294 -0
- pcapkit/const/ipv4/__init__.py +57 -0
- pcapkit/const/ipv4/classification_level.py +64 -0
- pcapkit/const/ipv4/option_class.py +55 -0
- pcapkit/const/ipv4/option_number.py +137 -0
- pcapkit/const/ipv4/protection_authority.py +63 -0
- pcapkit/const/ipv4/qs_function.py +51 -0
- pcapkit/const/ipv4/router_alert.py +251 -0
- pcapkit/const/ipv4/tos_del.py +51 -0
- pcapkit/const/ipv4/tos_ecn.py +55 -0
- pcapkit/const/ipv4/tos_pre.py +63 -0
- pcapkit/const/ipv4/tos_rel.py +51 -0
- pcapkit/const/ipv4/tos_thr.py +51 -0
- pcapkit/const/ipv4/ts_flag.py +53 -0
- pcapkit/const/ipv6/__init__.py +53 -0
- pcapkit/const/ipv6/extension_header.py +66 -0
- pcapkit/const/ipv6/option.py +137 -0
- pcapkit/const/ipv6/option_action.py +55 -0
- pcapkit/const/ipv6/qs_function.py +51 -0
- pcapkit/const/ipv6/router_alert.py +266 -0
- pcapkit/const/ipv6/routing.py +80 -0
- pcapkit/const/ipv6/seed_id.py +55 -0
- pcapkit/const/ipv6/smf_dpd_mode.py +51 -0
- pcapkit/const/ipv6/tagger_id.py +62 -0
- pcapkit/const/ipx/__init__.py +27 -0
- pcapkit/const/ipx/packet.py +72 -0
- pcapkit/const/ipx/socket.py +104 -0
- pcapkit/const/l2tp/__init__.py +21 -0
- pcapkit/const/l2tp/type.py +51 -0
- pcapkit/const/mh/__init__.py +204 -0
- pcapkit/const/mh/access_type.py +92 -0
- pcapkit/const/mh/ack_status_code.py +71 -0
- pcapkit/const/mh/ani_suboption.py +74 -0
- pcapkit/const/mh/auth_subtype.py +53 -0
- pcapkit/const/mh/binding_ack_flag.py +66 -0
- pcapkit/const/mh/binding_error.py +51 -0
- pcapkit/const/mh/binding_revocation.py +59 -0
- pcapkit/const/mh/binding_update_flag.py +81 -0
- pcapkit/const/mh/cga_extension.py +66 -0
- pcapkit/const/mh/cga_sec.py +57 -0
- pcapkit/const/mh/cga_type.py +68 -0
- pcapkit/const/mh/dhcp_support_mode.py +53 -0
- pcapkit/const/mh/dns_status_code.py +65 -0
- pcapkit/const/mh/dsmip6_tls_packet.py +62 -0
- pcapkit/const/mh/dsmipv6_home_address.py +74 -0
- pcapkit/const/mh/enumerating_algorithm.py +56 -0
- pcapkit/const/mh/fb_ack_status.py +62 -0
- pcapkit/const/mh/fb_action.py +71 -0
- pcapkit/const/mh/fb_indication_trigger.py +65 -0
- pcapkit/const/mh/fb_type.py +59 -0
- pcapkit/const/mh/flow_id_status.py +77 -0
- pcapkit/const/mh/flow_id_suboption.py +71 -0
- pcapkit/const/mh/handoff_type.py +71 -0
- pcapkit/const/mh/handover_ack_flag.py +54 -0
- pcapkit/const/mh/handover_ack_status.py +92 -0
- pcapkit/const/mh/handover_initiate_flag.py +57 -0
- pcapkit/const/mh/handover_initiate_status.py +62 -0
- pcapkit/const/mh/home_address_reply.py +71 -0
- pcapkit/const/mh/lla_code.py +63 -0
- pcapkit/const/mh/lma_mag_suboption.py +59 -0
- pcapkit/const/mh/mn_group_id.py +59 -0
- pcapkit/const/mh/mn_id_subtype.py +77 -0
- pcapkit/const/mh/operator_id.py +63 -0
- pcapkit/const/mh/option.py +260 -0
- pcapkit/const/mh/packet.py +119 -0
- pcapkit/const/mh/qos_attribute.py +89 -0
- pcapkit/const/mh/revocation_status_code.py +83 -0
- pcapkit/const/mh/revocation_trigger.py +86 -0
- pcapkit/const/mh/status_code.py +232 -0
- pcapkit/const/mh/traffic_selector.py +62 -0
- pcapkit/const/mh/upa_status.py +71 -0
- pcapkit/const/mh/upn_reason.py +80 -0
- pcapkit/const/ospf/__init__.py +27 -0
- pcapkit/const/ospf/authentication.py +65 -0
- pcapkit/const/ospf/packet.py +71 -0
- pcapkit/const/pcapng/__init__.py +51 -0
- pcapkit/const/pcapng/block_type.py +152 -0
- pcapkit/const/pcapng/filter_type.py +48 -0
- pcapkit/const/pcapng/hash_algorithm.py +59 -0
- pcapkit/const/pcapng/option_type.py +233 -0
- pcapkit/const/pcapng/record_type.py +57 -0
- pcapkit/const/pcapng/secrets_type.py +56 -0
- pcapkit/const/pcapng/verdict_type.py +53 -0
- pcapkit/const/reg/__init__.py +34 -0
- pcapkit/const/reg/apptype.py +32702 -0
- pcapkit/const/reg/ethertype.py +714 -0
- pcapkit/const/reg/linktype.py +902 -0
- pcapkit/const/reg/transtype.py +523 -0
- pcapkit/const/tcp/__init__.py +35 -0
- pcapkit/const/tcp/checksum.py +55 -0
- pcapkit/const/tcp/flags.py +73 -0
- pcapkit/const/tcp/mp_tcp_option.py +80 -0
- pcapkit/const/tcp/option.py +198 -0
- pcapkit/const/vlan/__init__.py +23 -0
- pcapkit/const/vlan/priority_level.py +71 -0
- pcapkit/corekit/__init__.py +59 -0
- pcapkit/corekit/fields/__init__.py +45 -0
- pcapkit/corekit/fields/collections.py +282 -0
- pcapkit/corekit/fields/field.py +269 -0
- pcapkit/corekit/fields/ipaddress.py +274 -0
- pcapkit/corekit/fields/misc.py +722 -0
- pcapkit/corekit/fields/numbers.py +375 -0
- pcapkit/corekit/fields/strings.py +245 -0
- pcapkit/corekit/infoclass.py +394 -0
- pcapkit/corekit/io.py +506 -0
- pcapkit/corekit/module.py +39 -0
- pcapkit/corekit/multidict.py +626 -0
- pcapkit/corekit/protochain.py +263 -0
- pcapkit/corekit/version.py +33 -0
- pcapkit/dumpkit/__init__.py +15 -0
- pcapkit/dumpkit/common.py +199 -0
- pcapkit/dumpkit/null.py +77 -0
- pcapkit/dumpkit/pcap.py +144 -0
- pcapkit/foundation/__init__.py +45 -0
- pcapkit/foundation/engines/__init__.py +36 -0
- pcapkit/foundation/engines/dpkt.py +230 -0
- pcapkit/foundation/engines/engine.py +194 -0
- pcapkit/foundation/engines/pcap.py +188 -0
- pcapkit/foundation/engines/pcapng.py +310 -0
- pcapkit/foundation/engines/pyshark.py +166 -0
- pcapkit/foundation/engines/scapy.py +161 -0
- pcapkit/foundation/extraction.py +915 -0
- pcapkit/foundation/reassembly/__init__.py +49 -0
- pcapkit/foundation/reassembly/data/__init__.py +48 -0
- pcapkit/foundation/reassembly/data/ip.py +117 -0
- pcapkit/foundation/reassembly/data/tcp.py +145 -0
- pcapkit/foundation/reassembly/ip.py +192 -0
- pcapkit/foundation/reassembly/ipv4.py +50 -0
- pcapkit/foundation/reassembly/ipv6.py +50 -0
- pcapkit/foundation/reassembly/reassembly.py +389 -0
- pcapkit/foundation/reassembly/tcp.py +249 -0
- pcapkit/foundation/registry/__init__.py +41 -0
- pcapkit/foundation/registry/foundation.py +327 -0
- pcapkit/foundation/registry/protocols.py +885 -0
- pcapkit/foundation/traceflow/__init__.py +44 -0
- pcapkit/foundation/traceflow/data/__init__.py +30 -0
- pcapkit/foundation/traceflow/data/tcp.py +105 -0
- pcapkit/foundation/traceflow/tcp.py +159 -0
- pcapkit/foundation/traceflow/traceflow.py +390 -0
- pcapkit/interface/__init__.py +22 -0
- pcapkit/interface/core.py +185 -0
- pcapkit/interface/misc.py +120 -0
- pcapkit/protocols/__init__.py +85 -0
- pcapkit/protocols/application/NotImplemented/bgp.py +0 -0
- pcapkit/protocols/application/NotImplemented/dhcp.py +0 -0
- pcapkit/protocols/application/NotImplemented/dhcpv6.py +0 -0
- pcapkit/protocols/application/NotImplemented/dns.py +0 -0
- pcapkit/protocols/application/NotImplemented/imap.py +0 -0
- pcapkit/protocols/application/NotImplemented/ldap.py +0 -0
- pcapkit/protocols/application/NotImplemented/mqtt.py +0 -0
- pcapkit/protocols/application/NotImplemented/nntp.py +0 -0
- pcapkit/protocols/application/NotImplemented/ntp.py +0 -0
- pcapkit/protocols/application/NotImplemented/onc_rpc.py +0 -0
- pcapkit/protocols/application/NotImplemented/pop.py +0 -0
- pcapkit/protocols/application/NotImplemented/rip.py +0 -0
- pcapkit/protocols/application/NotImplemented/rtp.py +0 -0
- pcapkit/protocols/application/NotImplemented/sip.py +0 -0
- pcapkit/protocols/application/NotImplemented/smtp.py +0 -0
- pcapkit/protocols/application/NotImplemented/snmp.py +0 -0
- pcapkit/protocols/application/NotImplemented/ssh.py +0 -0
- pcapkit/protocols/application/NotImplemented/telnet.py +0 -0
- pcapkit/protocols/application/NotImplemented/tls.py +0 -0
- pcapkit/protocols/application/NotImplemented/xmpp.py +0 -0
- pcapkit/protocols/application/__init__.py +34 -0
- pcapkit/protocols/application/application.py +114 -0
- pcapkit/protocols/application/ftp.py +206 -0
- pcapkit/protocols/application/http.py +176 -0
- pcapkit/protocols/application/httpv1.py +320 -0
- pcapkit/protocols/application/httpv2.py +1255 -0
- pcapkit/protocols/data/__init__.py +192 -0
- pcapkit/protocols/data/application/__init__.py +57 -0
- pcapkit/protocols/data/application/ftp.py +59 -0
- pcapkit/protocols/data/application/httpv1.py +79 -0
- pcapkit/protocols/data/application/httpv2.py +293 -0
- pcapkit/protocols/data/data.py +25 -0
- pcapkit/protocols/data/internet/__init__.py +298 -0
- pcapkit/protocols/data/internet/ah.py +31 -0
- pcapkit/protocols/data/internet/hip.py +804 -0
- pcapkit/protocols/data/internet/hopopt.py +351 -0
- pcapkit/protocols/data/internet/ipv4.py +369 -0
- pcapkit/protocols/data/internet/ipv6.py +67 -0
- pcapkit/protocols/data/internet/ipv6_frag.py +29 -0
- pcapkit/protocols/data/internet/ipv6_opts.py +368 -0
- pcapkit/protocols/data/internet/ipv6_route.py +86 -0
- pcapkit/protocols/data/internet/ipx.py +56 -0
- pcapkit/protocols/data/internet/mh.py +509 -0
- pcapkit/protocols/data/link/__init__.py +33 -0
- pcapkit/protocols/data/link/arp.py +74 -0
- pcapkit/protocols/data/link/ethernet.py +28 -0
- pcapkit/protocols/data/link/l2tp.py +63 -0
- pcapkit/protocols/data/link/ospf.py +58 -0
- pcapkit/protocols/data/link/vlan.py +42 -0
- pcapkit/protocols/data/misc/__init__.py +109 -0
- pcapkit/protocols/data/misc/null.py +18 -0
- pcapkit/protocols/data/misc/pcap/__init__.py +18 -0
- pcapkit/protocols/data/misc/pcap/frame.py +56 -0
- pcapkit/protocols/data/misc/pcap/header.py +53 -0
- pcapkit/protocols/data/misc/pcapng.py +925 -0
- pcapkit/protocols/data/misc/raw.py +25 -0
- pcapkit/protocols/data/protocol.py +32 -0
- pcapkit/protocols/data/transport/__init__.py +71 -0
- pcapkit/protocols/data/transport/tcp.py +555 -0
- pcapkit/protocols/data/transport/udp.py +29 -0
- pcapkit/protocols/internet/NotImplemented/ecn.py +0 -0
- pcapkit/protocols/internet/NotImplemented/esp.py +97 -0
- pcapkit/protocols/internet/NotImplemented/icmp.py +0 -0
- pcapkit/protocols/internet/NotImplemented/icmpv6.py +0 -0
- pcapkit/protocols/internet/NotImplemented/igmp.py +0 -0
- pcapkit/protocols/internet/NotImplemented/shim6.py +0 -0
- pcapkit/protocols/internet/__init__.py +43 -0
- pcapkit/protocols/internet/ah.py +275 -0
- pcapkit/protocols/internet/hip.py +4727 -0
- pcapkit/protocols/internet/hopopt.py +1879 -0
- pcapkit/protocols/internet/internet.py +240 -0
- pcapkit/protocols/internet/ip.py +51 -0
- pcapkit/protocols/internet/ipsec.py +50 -0
- pcapkit/protocols/internet/ipv4.py +1782 -0
- pcapkit/protocols/internet/ipv6.py +361 -0
- pcapkit/protocols/internet/ipv6_frag.py +258 -0
- pcapkit/protocols/internet/ipv6_opts.py +1890 -0
- pcapkit/protocols/internet/ipv6_route.py +710 -0
- pcapkit/protocols/internet/ipx.py +230 -0
- pcapkit/protocols/internet/mh.py +2764 -0
- pcapkit/protocols/link/NotImplemented/dsl.py +0 -0
- pcapkit/protocols/link/NotImplemented/eapol.py +1 -0
- pcapkit/protocols/link/NotImplemented/fddi.py +0 -0
- pcapkit/protocols/link/NotImplemented/isdn.py +0 -0
- pcapkit/protocols/link/NotImplemented/ndp.py +0 -0
- pcapkit/protocols/link/NotImplemented/ppp.py +0 -0
- pcapkit/protocols/link/__init__.py +35 -0
- pcapkit/protocols/link/arp.py +421 -0
- pcapkit/protocols/link/ethernet.py +248 -0
- pcapkit/protocols/link/l2tp.py +267 -0
- pcapkit/protocols/link/link.py +140 -0
- pcapkit/protocols/link/ospf.py +342 -0
- pcapkit/protocols/link/rarp.py +82 -0
- pcapkit/protocols/link/vlan.py +225 -0
- pcapkit/protocols/misc/__init__.py +37 -0
- pcapkit/protocols/misc/null.py +129 -0
- pcapkit/protocols/misc/pcap/__init__.py +17 -0
- pcapkit/protocols/misc/pcap/frame.py +478 -0
- pcapkit/protocols/misc/pcap/header.py +358 -0
- pcapkit/protocols/misc/pcapng.py +5520 -0
- pcapkit/protocols/misc/raw.py +180 -0
- pcapkit/protocols/protocol.py +1216 -0
- pcapkit/protocols/schema/__init__.py +140 -0
- pcapkit/protocols/schema/application/__init__.py +40 -0
- pcapkit/protocols/schema/application/ftp.py +21 -0
- pcapkit/protocols/schema/application/httpv1.py +21 -0
- pcapkit/protocols/schema/application/httpv2.py +384 -0
- pcapkit/protocols/schema/internet/__init__.py +294 -0
- pcapkit/protocols/schema/internet/ah.py +40 -0
- pcapkit/protocols/schema/internet/hip.py +1184 -0
- pcapkit/protocols/schema/internet/hopopt.py +679 -0
- pcapkit/protocols/schema/internet/ipv4.py +576 -0
- pcapkit/protocols/schema/internet/ipv6.py +63 -0
- pcapkit/protocols/schema/internet/ipv6_frag.py +48 -0
- pcapkit/protocols/schema/internet/ipv6_opts.py +680 -0
- pcapkit/protocols/schema/internet/ipv6_route.py +198 -0
- pcapkit/protocols/schema/internet/ipx.py +40 -0
- pcapkit/protocols/schema/internet/mh.py +718 -0
- pcapkit/protocols/schema/link/__init__.py +19 -0
- pcapkit/protocols/schema/link/arp.py +39 -0
- pcapkit/protocols/schema/link/ethernet.py +51 -0
- pcapkit/protocols/schema/link/l2tp.py +88 -0
- pcapkit/protocols/schema/link/ospf.py +90 -0
- pcapkit/protocols/schema/link/vlan.py +69 -0
- pcapkit/protocols/schema/misc/__init__.py +108 -0
- pcapkit/protocols/schema/misc/null.py +18 -0
- pcapkit/protocols/schema/misc/pcap/__init__.py +10 -0
- pcapkit/protocols/schema/misc/pcap/frame.py +51 -0
- pcapkit/protocols/schema/misc/pcap/header.py +63 -0
- pcapkit/protocols/schema/misc/pcapng.py +1689 -0
- pcapkit/protocols/schema/misc/raw.py +24 -0
- pcapkit/protocols/schema/schema.py +809 -0
- pcapkit/protocols/schema/transport/__init__.py +69 -0
- pcapkit/protocols/schema/transport/tcp.py +928 -0
- pcapkit/protocols/schema/transport/udp.py +90 -0
- pcapkit/protocols/transport/NotImplemented/dccp.py +0 -0
- pcapkit/protocols/transport/NotImplemented/rsvp.py +0 -0
- pcapkit/protocols/transport/NotImplemented/sctp.py +0 -0
- pcapkit/protocols/transport/__init__.py +27 -0
- pcapkit/protocols/transport/tcp.py +3025 -0
- pcapkit/protocols/transport/transport.py +158 -0
- pcapkit/protocols/transport/udp.py +214 -0
- pcapkit/py.typed +0 -0
- pcapkit/toolkit/__init__.py +57 -0
- pcapkit/toolkit/dpkt.py +306 -0
- pcapkit/toolkit/pcap.py +212 -0
- pcapkit/toolkit/pcapng.py +251 -0
- pcapkit/toolkit/pyshark.py +99 -0
- pcapkit/toolkit/scapy.py +297 -0
- pcapkit/utilities/__init__.py +20 -0
- pcapkit/utilities/compat.py +196 -0
- pcapkit/utilities/decorators.py +192 -0
- pcapkit/utilities/exceptions.py +365 -0
- pcapkit/utilities/logging.py +55 -0
- pcapkit/utilities/warnings.py +185 -0
- pcapkit/vendor/__init__.py +105 -0
- pcapkit/vendor/__main__.py +92 -0
- pcapkit/vendor/arp/__init__.py +27 -0
- pcapkit/vendor/arp/hardware.py +29 -0
- pcapkit/vendor/arp/operation.py +29 -0
- pcapkit/vendor/default.py +474 -0
- pcapkit/vendor/ftp/__init__.py +27 -0
- pcapkit/vendor/ftp/command.py +244 -0
- pcapkit/vendor/ftp/return_code.py +256 -0
- pcapkit/vendor/hip/__init__.py +94 -0
- pcapkit/vendor/hip/certificate.py +29 -0
- pcapkit/vendor/hip/cipher.py +29 -0
- pcapkit/vendor/hip/di.py +29 -0
- pcapkit/vendor/hip/ecdsa_curve.py +29 -0
- pcapkit/vendor/hip/ecdsa_low_curve.py +29 -0
- pcapkit/vendor/hip/eddsa_curve.py +85 -0
- pcapkit/vendor/hip/esp_transform_suite.py +29 -0
- pcapkit/vendor/hip/group.py +87 -0
- pcapkit/vendor/hip/hi_algorithm.py +29 -0
- pcapkit/vendor/hip/hit_suite.py +29 -0
- pcapkit/vendor/hip/nat_traversal.py +29 -0
- pcapkit/vendor/hip/notify_message.py +29 -0
- pcapkit/vendor/hip/packet.py +88 -0
- pcapkit/vendor/hip/parameter.py +88 -0
- pcapkit/vendor/hip/registration.py +29 -0
- pcapkit/vendor/hip/registration_failure.py +29 -0
- pcapkit/vendor/hip/suite.py +29 -0
- pcapkit/vendor/hip/transport.py +29 -0
- pcapkit/vendor/http/__init__.py +39 -0
- pcapkit/vendor/http/error_code.py +95 -0
- pcapkit/vendor/http/frame.py +91 -0
- pcapkit/vendor/http/method.py +167 -0
- pcapkit/vendor/http/setting.py +93 -0
- pcapkit/vendor/http/status_code.py +185 -0
- pcapkit/vendor/ipv4/__init__.py +57 -0
- pcapkit/vendor/ipv4/classification_level.py +91 -0
- pcapkit/vendor/ipv4/option_class.py +80 -0
- pcapkit/vendor/ipv4/option_number.py +105 -0
- pcapkit/vendor/ipv4/protection_authority.py +84 -0
- pcapkit/vendor/ipv4/qs_function.py +78 -0
- pcapkit/vendor/ipv4/router_alert.py +93 -0
- pcapkit/vendor/ipv4/tos_del.py +78 -0
- pcapkit/vendor/ipv4/tos_ecn.py +95 -0
- pcapkit/vendor/ipv4/tos_pre.py +84 -0
- pcapkit/vendor/ipv4/tos_rel.py +78 -0
- pcapkit/vendor/ipv4/tos_thr.py +77 -0
- pcapkit/vendor/ipv4/ts_flag.py +79 -0
- pcapkit/vendor/ipv6/__init__.py +53 -0
- pcapkit/vendor/ipv6/extension_header.py +171 -0
- pcapkit/vendor/ipv6/option.py +104 -0
- pcapkit/vendor/ipv6/option_action.py +90 -0
- pcapkit/vendor/ipv6/qs_function.py +78 -0
- pcapkit/vendor/ipv6/router_alert.py +93 -0
- pcapkit/vendor/ipv6/routing.py +87 -0
- pcapkit/vendor/ipv6/seed_id.py +81 -0
- pcapkit/vendor/ipv6/smf_dpd_mode.py +78 -0
- pcapkit/vendor/ipv6/tagger_id.py +81 -0
- pcapkit/vendor/ipx/__init__.py +37 -0
- pcapkit/vendor/ipx/packet.py +123 -0
- pcapkit/vendor/ipx/socket.py +125 -0
- pcapkit/vendor/l2tp/__init__.py +21 -0
- pcapkit/vendor/l2tp/type.py +78 -0
- pcapkit/vendor/mh/__init__.py +204 -0
- pcapkit/vendor/mh/access_type.py +87 -0
- pcapkit/vendor/mh/ack_status_code.py +88 -0
- pcapkit/vendor/mh/ani_suboption.py +88 -0
- pcapkit/vendor/mh/auth_subtype.py +83 -0
- pcapkit/vendor/mh/binding_ack_flag.py +148 -0
- pcapkit/vendor/mh/binding_error.py +78 -0
- pcapkit/vendor/mh/binding_revocation.py +87 -0
- pcapkit/vendor/mh/binding_update_flag.py +147 -0
- pcapkit/vendor/mh/cga_extension.py +91 -0
- pcapkit/vendor/mh/cga_sec.py +91 -0
- pcapkit/vendor/mh/cga_type.py +74 -0
- pcapkit/vendor/mh/dhcp_support_mode.py +77 -0
- pcapkit/vendor/mh/dns_status_code.py +87 -0
- pcapkit/vendor/mh/dsmip6_tls_packet.py +87 -0
- pcapkit/vendor/mh/dsmipv6_home_address.py +87 -0
- pcapkit/vendor/mh/enumerating_algorithm.py +82 -0
- pcapkit/vendor/mh/fb_ack_status.py +87 -0
- pcapkit/vendor/mh/fb_action.py +88 -0
- pcapkit/vendor/mh/fb_indication_trigger.py +87 -0
- pcapkit/vendor/mh/fb_type.py +88 -0
- pcapkit/vendor/mh/flow_id_status.py +87 -0
- pcapkit/vendor/mh/flow_id_suboption.py +87 -0
- pcapkit/vendor/mh/handoff_type.py +87 -0
- pcapkit/vendor/mh/handover_ack_flag.py +143 -0
- pcapkit/vendor/mh/handover_ack_status.py +87 -0
- pcapkit/vendor/mh/handover_initiate_flag.py +143 -0
- pcapkit/vendor/mh/handover_initiate_status.py +87 -0
- pcapkit/vendor/mh/home_address_reply.py +87 -0
- pcapkit/vendor/mh/lla_code.py +97 -0
- pcapkit/vendor/mh/lma_mag_suboption.py +88 -0
- pcapkit/vendor/mh/mn_group_id.py +87 -0
- pcapkit/vendor/mh/mn_id_subtype.py +87 -0
- pcapkit/vendor/mh/operator_id.py +87 -0
- pcapkit/vendor/mh/option.py +83 -0
- pcapkit/vendor/mh/packet.py +82 -0
- pcapkit/vendor/mh/qos_attribute.py +87 -0
- pcapkit/vendor/mh/revocation_status_code.py +87 -0
- pcapkit/vendor/mh/revocation_trigger.py +87 -0
- pcapkit/vendor/mh/status_code.py +91 -0
- pcapkit/vendor/mh/traffic_selector.py +87 -0
- pcapkit/vendor/mh/upa_status.py +87 -0
- pcapkit/vendor/mh/upn_reason.py +87 -0
- pcapkit/vendor/ospf/__init__.py +27 -0
- pcapkit/vendor/ospf/authentication.py +29 -0
- pcapkit/vendor/ospf/packet.py +29 -0
- pcapkit/vendor/pcapng/__init__.py +51 -0
- pcapkit/vendor/pcapng/block_type.py +94 -0
- pcapkit/vendor/pcapng/filter_type.py +77 -0
- pcapkit/vendor/pcapng/hash_algorithm.py +82 -0
- pcapkit/vendor/pcapng/option_type.py +287 -0
- pcapkit/vendor/pcapng/record_type.py +81 -0
- pcapkit/vendor/pcapng/secrets_type.py +81 -0
- pcapkit/vendor/pcapng/verdict_type.py +79 -0
- pcapkit/vendor/reg/__init__.py +34 -0
- pcapkit/vendor/reg/apptype.py +338 -0
- pcapkit/vendor/reg/ethertype.py +121 -0
- pcapkit/vendor/reg/linktype.py +110 -0
- pcapkit/vendor/reg/transtype.py +111 -0
- pcapkit/vendor/tcp/__init__.py +35 -0
- pcapkit/vendor/tcp/checksum.py +80 -0
- pcapkit/vendor/tcp/flags.py +149 -0
- pcapkit/vendor/tcp/mp_tcp_option.py +90 -0
- pcapkit/vendor/tcp/option.py +103 -0
- pcapkit/vendor/vlan/__init__.py +23 -0
- pcapkit/vendor/vlan/priority_level.py +97 -0
- pypcapkit-1.3.3.post1.dist-info/LICENSE +29 -0
- pypcapkit-1.3.3.post1.dist-info/METADATA +236 -0
- pypcapkit-1.3.3.post1.dist-info/RECORD +466 -0
- pypcapkit-1.3.3.post1.dist-info/WHEEL +5 -0
- pypcapkit-1.3.3.post1.dist-info/entry_points.txt +3 -0
- pypcapkit-1.3.3.post1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1255 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
"""HTTP/2 - Hypertext Transfer Protocol
|
3
|
+
==========================================
|
4
|
+
|
5
|
+
.. module:: pcapkit.protocols.application.httpv2
|
6
|
+
|
7
|
+
:mod:`pcapkit.protocols.application.httpv2` contains
|
8
|
+
:class:`~pcapkit.protocols.application.httpv2.HTTP`
|
9
|
+
only, which implements extractor for Hypertext Transfer
|
10
|
+
Protocol (HTTP/2) [*]_, whose structure is described as
|
11
|
+
below:
|
12
|
+
|
13
|
+
======= ========= ===================== ==========================
|
14
|
+
Octets Bits Name Description
|
15
|
+
======= ========= ===================== ==========================
|
16
|
+
0 0 ``http.length`` Length
|
17
|
+
3 24 ``http.type`` Type
|
18
|
+
4 32 ``http.flags`` Flags
|
19
|
+
5 40 Reserved
|
20
|
+
5 41 ``http.sid`` Stream Identifier
|
21
|
+
9 72 ``http.payload`` Frame Payload
|
22
|
+
======= ========= ===================== ==========================
|
23
|
+
|
24
|
+
.. [*] https://en.wikipedia.org/wiki/HTTP/2
|
25
|
+
|
26
|
+
"""
|
27
|
+
import collections
|
28
|
+
from typing import TYPE_CHECKING, cast
|
29
|
+
|
30
|
+
from pcapkit.const.http.error_code import ErrorCode as Enum_ErrorCode
|
31
|
+
from pcapkit.const.http.frame import Frame as Enum_Frame
|
32
|
+
from pcapkit.const.http.setting import Setting as Enum_Setting
|
33
|
+
from pcapkit.corekit.multidict import OrderedMultiDict
|
34
|
+
from pcapkit.protocols.application.http import HTTP as HTTPBase
|
35
|
+
from pcapkit.protocols.data.application.httpv2 import HTTP as Data_HTTP
|
36
|
+
from pcapkit.protocols.data.application.httpv2 import ContinuationFrame as Data_ContinuationFrame
|
37
|
+
from pcapkit.protocols.data.application.httpv2 import \
|
38
|
+
ContinuationFrameFlags as Data_ContinuationFrameFlags
|
39
|
+
from pcapkit.protocols.data.application.httpv2 import DataFrame as Data_DataFrame
|
40
|
+
from pcapkit.protocols.data.application.httpv2 import DataFrameFlags as Data_DataFrameFlags
|
41
|
+
from pcapkit.protocols.data.application.httpv2 import GoawayFrame as Data_GoawayFrame
|
42
|
+
from pcapkit.protocols.data.application.httpv2 import HeadersFrame as Data_HeadersFrame
|
43
|
+
from pcapkit.protocols.data.application.httpv2 import HeadersFrameFlags as Data_HeadersFrameFlags
|
44
|
+
from pcapkit.protocols.data.application.httpv2 import PingFrame as Data_PingFrame
|
45
|
+
from pcapkit.protocols.data.application.httpv2 import PingFrameFlags as Data_PingFrameFlags
|
46
|
+
from pcapkit.protocols.data.application.httpv2 import PriorityFrame as Data_PriorityFrame
|
47
|
+
from pcapkit.protocols.data.application.httpv2 import PushPromiseFrame as Data_PushPromiseFrame
|
48
|
+
from pcapkit.protocols.data.application.httpv2 import \
|
49
|
+
PushPromiseFrameFlags as Data_PushPromiseFrameFlags
|
50
|
+
from pcapkit.protocols.data.application.httpv2 import RSTStreamFrame as Data_RSTStreamFrame
|
51
|
+
from pcapkit.protocols.data.application.httpv2 import SettingsFrame as Data_SettingsFrame
|
52
|
+
from pcapkit.protocols.data.application.httpv2 import SettingsFrameFlags as Data_SettingsFrameFlags
|
53
|
+
from pcapkit.protocols.data.application.httpv2 import UnassignedFrame as Data_UnassignedFrame
|
54
|
+
from pcapkit.protocols.data.application.httpv2 import WindowUpdateFrame as Data_WindowUpdateFrame
|
55
|
+
from pcapkit.protocols.schema.application.httpv2 import HTTP as Schema_HTTP
|
56
|
+
from pcapkit.protocols.schema.application.httpv2 import \
|
57
|
+
ContinuationFrame as Schema_ContinuationFrame
|
58
|
+
from pcapkit.protocols.schema.application.httpv2 import DataFrame as Schema_DataFrame
|
59
|
+
from pcapkit.protocols.schema.application.httpv2 import FrameType as Schema_FrameType
|
60
|
+
from pcapkit.protocols.schema.application.httpv2 import GoawayFrame as Schema_GoawayFrame
|
61
|
+
from pcapkit.protocols.schema.application.httpv2 import HeadersFrame as Schema_HeadersFrame
|
62
|
+
from pcapkit.protocols.schema.application.httpv2 import PingFrame as Schema_PingFrame
|
63
|
+
from pcapkit.protocols.schema.application.httpv2 import PriorityFrame as Schema_PriorityFrame
|
64
|
+
from pcapkit.protocols.schema.application.httpv2 import PushPromiseFrame as Schema_PushPromiseFrame
|
65
|
+
from pcapkit.protocols.schema.application.httpv2 import RSTStreamFrame as Schema_RSTStreamFrame
|
66
|
+
from pcapkit.protocols.schema.application.httpv2 import SettingPair as Schema_SettingPair
|
67
|
+
from pcapkit.protocols.schema.application.httpv2 import SettingsFrame as Schema_SettingsFrame
|
68
|
+
from pcapkit.protocols.schema.application.httpv2 import UnassignedFrame as Schema_UnassignedFrame
|
69
|
+
from pcapkit.protocols.schema.application.httpv2 import \
|
70
|
+
WindowUpdateFrame as Schema_WindowUpdateFrame
|
71
|
+
from pcapkit.protocols.schema.schema import Schema
|
72
|
+
from pcapkit.utilities.exceptions import ProtocolError
|
73
|
+
from pcapkit.utilities.warnings import ProtocolWarning, RegistryWarning, warn
|
74
|
+
|
75
|
+
if TYPE_CHECKING:
|
76
|
+
from enum import IntEnum as StdlibEnum
|
77
|
+
from typing import Any, Callable, DefaultDict, Optional, Tuple, Type
|
78
|
+
|
79
|
+
from aenum import IntEnum as AenumEnum
|
80
|
+
from mypy_extensions import DefaultArg, KwArg, NamedArg
|
81
|
+
from typing_extensions import Literal
|
82
|
+
|
83
|
+
Flags = Schema_FrameType.Flags
|
84
|
+
|
85
|
+
FrameParser = Callable[[Schema_FrameType, NamedArg(Schema_HTTP, 'header')], Data_HTTP]
|
86
|
+
FrameConstructor = Callable[[Enum_Frame, DefaultArg(Optional[Data_HTTP]),
|
87
|
+
KwArg(Any)], Tuple[Schema_FrameType, 'Flags']]
|
88
|
+
|
89
|
+
__all__ = ['HTTP']
|
90
|
+
|
91
|
+
|
92
|
+
class HTTP(HTTPBase[Data_HTTP, Schema_HTTP],
|
93
|
+
schema=Schema_HTTP, data=Data_HTTP):
|
94
|
+
"""This class implements Hypertext Transfer Protocol (HTTP/2).
|
95
|
+
|
96
|
+
This class currently supports parsing of the following HTTP/2 frames,
|
97
|
+
which are directly mapped to the :class:`pcapkit.const.http.frame.Frame`
|
98
|
+
enumeration:
|
99
|
+
|
100
|
+
.. list-table::
|
101
|
+
:header-rows: 1
|
102
|
+
|
103
|
+
* - Frame Code
|
104
|
+
- Frame Parser
|
105
|
+
- Frame Constructor
|
106
|
+
* - :attr:`~pcapkit.const.http.frame.Frame.DATA`
|
107
|
+
- :meth:`~pcapkit.protocols.application.httpv2.HTTP._read_http_data`
|
108
|
+
- :meth:`~pcapkit.protocols.application.httpv2.HTTP._make_http_data`
|
109
|
+
* - :attr:`~pcapkit.const.http.frame.Frame.HEADERS`
|
110
|
+
- :meth:`~pcapkit.protocols.application.httpv2.HTTP._read_http_headers`
|
111
|
+
- :meth:`~pcapkit.protocols.application.httpv2.HTTP._make_http_headers`
|
112
|
+
* - :attr:`~pcapkit.const.http.frame.Frame.PRIORITY`
|
113
|
+
- :meth:`~pcapkit.protocols.application.httpv2.HTTP._read_http_priority`
|
114
|
+
- :meth:`~pcapkit.protocols.application.httpv2.HTTP._make_http_priority`
|
115
|
+
* - :attr:`~pcapkit.const.http.frame.Frame.RST_STREAM`
|
116
|
+
- :meth:`~pcapkit.protocols.application.httpv2.HTTP._read_http_rst_stream`
|
117
|
+
- :meth:`~pcapkit.protocols.application.httpv2.HTTP._make_http_rst_stream`
|
118
|
+
* - :attr:`~pcapkit.const.http.frame.Frame.SETTINGS`
|
119
|
+
- :meth:`~pcapkit.protocols.application.httpv2.HTTP._read_http_settings`
|
120
|
+
- :meth:`~pcapkit.protocols.application.httpv2.HTTP._make_http_settings`
|
121
|
+
* - :attr:`~pcapkit.const.http.frame.Frame.PUSH_PROMISE`
|
122
|
+
- :meth:`~pcapkit.protocols.application.httpv2.HTTP._read_http_push_promise`
|
123
|
+
- :meth:`~pcapkit.protocols.application.httpv2.HTTP._make_http_push_promise`
|
124
|
+
* - :attr:`~pcapkit.const.http.frame.Frame.PING`
|
125
|
+
- :meth:`~pcapkit.protocols.application.httpv2.HTTP._read_http_ping`
|
126
|
+
- :meth:`~pcapkit.protocols.application.httpv2.HTTP._make_http_ping`
|
127
|
+
* - :attr:`~pcapkit.const.http.frame.Frame.GOAWAY`
|
128
|
+
- :meth:`~pcapkit.protocols.application.httpv2.HTTP._read_http_goaway`
|
129
|
+
- :meth:`~pcapkit.protocols.application.httpv2.HTTP._make_http_goaway`
|
130
|
+
* - :attr:`~pcapkit.const.http.frame.Frame.WINDOW_UPDATE`
|
131
|
+
- :meth:`~pcapkit.protocols.application.httpv2.HTTP._read_http_window_update`
|
132
|
+
- :meth:`~pcapkit.protocols.application.httpv2.HTTP._make_http_window_update`
|
133
|
+
* - :attr:`~pcapkit.const.http.frame.Frame.CONTINUATION`
|
134
|
+
- :meth:`~pcapkit.protocols.application.httpv2.HTTP._read_http_continuation`
|
135
|
+
- :meth:`~pcapkit.protocols.application.httpv2.HTTP._make_http_continuation`
|
136
|
+
|
137
|
+
"""
|
138
|
+
|
139
|
+
##########################################################################
|
140
|
+
# Defaults.
|
141
|
+
##########################################################################
|
142
|
+
|
143
|
+
#: DefaultDict[Enum_Frame, str | tuple[FrameParser, FrameConstructor]]: Frame
|
144
|
+
#: code to method mapping. Method names are expected to be referred to
|
145
|
+
#: the class by ``_read_http_${name}`` and/or ``_make_http_${name}``, and if
|
146
|
+
#: such name not found, the value should then be a method that can parse the
|
147
|
+
#: frame by itself.
|
148
|
+
__frame__ = collections.defaultdict(
|
149
|
+
lambda: 'none',
|
150
|
+
{
|
151
|
+
Enum_Frame.DATA: 'data', # DATA
|
152
|
+
Enum_Frame.HEADERS: 'headers', # HEADERS
|
153
|
+
Enum_Frame.PRIORITY: 'priority', # PRIORITY
|
154
|
+
Enum_Frame.RST_STREAM: 'rst_stream', # RST_STREAM
|
155
|
+
Enum_Frame.SETTINGS: 'settings', # SETTINGS
|
156
|
+
Enum_Frame.PUSH_PROMISE: 'push_promise', # PUSH_PROMISE
|
157
|
+
Enum_Frame.PING: 'ping', # PING
|
158
|
+
Enum_Frame.GOAWAY: 'goaway', # GOAWAY
|
159
|
+
Enum_Frame.WINDOW_UPDATE: 'window_update', # WINDOW_UPDATE
|
160
|
+
Enum_Frame.CONTINUATION: 'continuation', # CONTINUATION
|
161
|
+
},
|
162
|
+
) # type: DefaultDict[Enum_Frame | int, str | tuple[FrameParser, FrameConstructor]]
|
163
|
+
|
164
|
+
##########################################################################
|
165
|
+
# Properties.
|
166
|
+
##########################################################################
|
167
|
+
|
168
|
+
@property
|
169
|
+
def alias(self) -> 'Literal["HTTP/2"]':
|
170
|
+
"""Acronym of current protocol."""
|
171
|
+
return 'HTTP/2'
|
172
|
+
|
173
|
+
@property
|
174
|
+
def length(self) -> 'Literal[9]':
|
175
|
+
"""Header length of current protocol."""
|
176
|
+
return 9
|
177
|
+
|
178
|
+
@property
|
179
|
+
def version(self) -> 'Literal["2"]':
|
180
|
+
"""Version of current protocol."""
|
181
|
+
return '2'
|
182
|
+
|
183
|
+
##########################################################################
|
184
|
+
# Methods.
|
185
|
+
##########################################################################
|
186
|
+
|
187
|
+
def read(self, length: 'Optional[int]' = None, **kwargs: 'Any') -> 'Data_HTTP':
|
188
|
+
"""Read Hypertext Transfer Protocol (HTTP/2).
|
189
|
+
|
190
|
+
Structure of HTTP/2 packet [:rfc:`7540`]:
|
191
|
+
|
192
|
+
.. code-block:: text
|
193
|
+
|
194
|
+
+-----------------------------------------------+
|
195
|
+
| Length (24) |
|
196
|
+
+---------------+---------------+---------------+
|
197
|
+
| Type (8) | Flags (8) |
|
198
|
+
+-+-------------+---------------+-------------------------------+
|
199
|
+
|R| Stream Identifier (31) |
|
200
|
+
+=+=============================================================+
|
201
|
+
| Frame Payload (0...) ...
|
202
|
+
+---------------------------------------------------------------+
|
203
|
+
|
204
|
+
Args:
|
205
|
+
length: Length of packet data.
|
206
|
+
**kwargs: Arbitrary keyword arguments.
|
207
|
+
|
208
|
+
Returns:
|
209
|
+
Parsed packet data.
|
210
|
+
|
211
|
+
Raises:
|
212
|
+
ProtocolError: If the packet is malformed.
|
213
|
+
|
214
|
+
"""
|
215
|
+
if length is None:
|
216
|
+
length = len(self)
|
217
|
+
schema = self.__header__
|
218
|
+
|
219
|
+
if schema.length < 9:
|
220
|
+
raise ProtocolError(f'HTTP/2: [Type {schema.type}] invalid format')
|
221
|
+
if schema.type in (Enum_Frame.SETTINGS, Enum_Frame.PING) and schema.stream['sid'] != 0:
|
222
|
+
raise ProtocolError(f'HTTP/2: [Type {schema.type}] invalid format')
|
223
|
+
|
224
|
+
name = self.__frame__[schema.type]
|
225
|
+
if isinstance(name, str):
|
226
|
+
meth_name = f'_read_http_{name}'
|
227
|
+
meth = cast('FrameParser',
|
228
|
+
getattr(self, meth_name, self._read_http_none))
|
229
|
+
else:
|
230
|
+
meth = name[0]
|
231
|
+
http = meth(schema.frame, header=schema)
|
232
|
+
|
233
|
+
return http
|
234
|
+
|
235
|
+
def make(self, # type: ignore[override]
|
236
|
+
type: 'Enum_Frame | StdlibEnum | AenumEnum | str | int' = Enum_Frame.DATA,
|
237
|
+
type_default: 'Optional[int]' = None,
|
238
|
+
type_namespace: 'Optional[dict[str, int] | dict[int, str] | Type[StdlibEnum] | Type[AenumEnum]]' = None, # pylint: disable=line-too-long
|
239
|
+
type_reversed: 'bool' = False,
|
240
|
+
flags: 'Flags' = 0, # type: ignore[assignment]
|
241
|
+
sid: 'int' = 0,
|
242
|
+
frame: 'bytes | Data_HTTP | Schema_FrameType | dict[str, Any]' = b'',
|
243
|
+
**kwargs: 'Any') -> 'Schema_HTTP':
|
244
|
+
"""Make (construct) packet data.
|
245
|
+
|
246
|
+
Args:
|
247
|
+
type: Type of HTTP/2 frame.
|
248
|
+
type_default: Default frame type.
|
249
|
+
type_namespace: Namespace of frame type.
|
250
|
+
type_reversed: Whether to reverse the namespace.
|
251
|
+
flags: Flags of HTTP/2 frame.
|
252
|
+
sid: Stream ID of HTTP/2 frame.
|
253
|
+
frame: Frame data of HTTP/2 frame.
|
254
|
+
**kwargs: Arbitrary keyword arguments.
|
255
|
+
|
256
|
+
Returns:
|
257
|
+
Constructed packet data.
|
258
|
+
|
259
|
+
"""
|
260
|
+
type_val = cast('Enum_Frame',
|
261
|
+
self._make_index(type, type_default, namespace=type_namespace,
|
262
|
+
reversed=type_reversed, pack=False))
|
263
|
+
|
264
|
+
if isinstance(frame, bytes):
|
265
|
+
length = len(frame) + 9
|
266
|
+
frame_val = frame # type: bytes | Schema_FrameType
|
267
|
+
elif isinstance(frame, (dict, Data_HTTP)):
|
268
|
+
name = self.__frame__[type_val]
|
269
|
+
if isinstance(name, str):
|
270
|
+
meth_name = f'_make_http_{name}'
|
271
|
+
meth = cast('FrameConstructor',
|
272
|
+
getattr(self, meth_name, self._make_http_none))
|
273
|
+
else:
|
274
|
+
meth = name[1]
|
275
|
+
|
276
|
+
if isinstance(frame, dict):
|
277
|
+
frame_val, flags = meth(type_val, **frame)
|
278
|
+
else:
|
279
|
+
frame_val, flags = meth(type_val, frame)
|
280
|
+
length = len(frame_val.pack()) + 9
|
281
|
+
elif isinstance(frame, Schema):
|
282
|
+
length = len(frame.pack()) + 9
|
283
|
+
frame_val = frame
|
284
|
+
else:
|
285
|
+
raise ProtocolError(f'HTTP/2: [Type {type_val}] invalid format')
|
286
|
+
|
287
|
+
flags_val = {} # type: dict[str, int]
|
288
|
+
for bit in range(8):
|
289
|
+
flags_val[f'bit_{bit}'] = (flags & (1 << bit)) >> bit
|
290
|
+
|
291
|
+
return Schema_HTTP(
|
292
|
+
length=length,
|
293
|
+
type=type_val,
|
294
|
+
flags=flags_val, # type: ignore[arg-type]
|
295
|
+
stream={
|
296
|
+
'sid': sid,
|
297
|
+
},
|
298
|
+
frame=frame_val,
|
299
|
+
)
|
300
|
+
|
301
|
+
@classmethod
|
302
|
+
def id(cls) -> 'tuple[Literal["HTTP"], Literal["HTTPv2"]]': # type: ignore[override]
|
303
|
+
"""Index ID of the protocol.
|
304
|
+
|
305
|
+
Returns:
|
306
|
+
Index ID of the protocol.
|
307
|
+
|
308
|
+
"""
|
309
|
+
return (cls.__name__, 'HTTPv2') # type: ignore[return-value]
|
310
|
+
|
311
|
+
@classmethod
|
312
|
+
def register_frame(cls, code: 'Enum_Frame', meth: 'str | tuple[FrameParser, FrameConstructor]') -> 'None':
|
313
|
+
"""Register a frame parser.
|
314
|
+
|
315
|
+
Args:
|
316
|
+
code: HTTP frame type code.
|
317
|
+
meth: Method name or callable to parse and/or construct the frame.
|
318
|
+
|
319
|
+
"""
|
320
|
+
if code in cls.__frame__:
|
321
|
+
warn(f'HTTP/2: [Type {code}] frame already registered', RegistryWarning)
|
322
|
+
cls.__frame__[code] = meth
|
323
|
+
|
324
|
+
##########################################################################
|
325
|
+
# Data models.
|
326
|
+
##########################################################################
|
327
|
+
|
328
|
+
def __length_hint__(self) -> 'Literal[9]':
|
329
|
+
"""Total length of corresponding protocol."""
|
330
|
+
return 9
|
331
|
+
|
332
|
+
##########################################################################
|
333
|
+
# Utilities.
|
334
|
+
##########################################################################
|
335
|
+
|
336
|
+
@classmethod
|
337
|
+
def _make_data(cls, data: 'Data_HTTP') -> 'dict[str, Any]': # type: ignore[override]
|
338
|
+
"""Create key-value pairs from ``data`` for protocol construction.
|
339
|
+
|
340
|
+
Args:
|
341
|
+
data: protocol data
|
342
|
+
|
343
|
+
Returns:
|
344
|
+
Key-value pairs for protocol construction.
|
345
|
+
|
346
|
+
"""
|
347
|
+
return {
|
348
|
+
'length': data.length,
|
349
|
+
'type': data.type,
|
350
|
+
'flags': data.flags.__value__ if data.flags is not None else 0,
|
351
|
+
'sid': data.sid,
|
352
|
+
'frame': data,
|
353
|
+
}
|
354
|
+
|
355
|
+
def _read_http_none(self, schema: 'Schema_UnassignedFrame', *,
|
356
|
+
header: 'Schema_HTTP') -> 'Data_UnassignedFrame':
|
357
|
+
"""Read HTTP packet with unassigned type.
|
358
|
+
|
359
|
+
Args:
|
360
|
+
schema: Parsed frame schema.
|
361
|
+
header: Parsed HTTP/2 header schema.
|
362
|
+
|
363
|
+
Returns:
|
364
|
+
Parsed packet data.
|
365
|
+
|
366
|
+
Raises:
|
367
|
+
ProtocolError: If the packet is malformed.
|
368
|
+
|
369
|
+
"""
|
370
|
+
if any(header.flags):
|
371
|
+
#raise ProtocolError(f'HTTP/2: [Type {frame}] invalid format')
|
372
|
+
warn(f'HTTP/2: [Type {header.type}] invalid format', ProtocolWarning)
|
373
|
+
|
374
|
+
data = Data_UnassignedFrame(
|
375
|
+
length=header.length,
|
376
|
+
type=header.type,
|
377
|
+
flags=None,
|
378
|
+
sid=header.stream['sid'],
|
379
|
+
data=schema.data,
|
380
|
+
)
|
381
|
+
return data
|
382
|
+
|
383
|
+
def _read_http_data(self, schema: 'Schema_DataFrame', *,
|
384
|
+
header: 'Schema_HTTP') -> 'Data_DataFrame':
|
385
|
+
"""Read HTTP/2 ``DATA`` frames.
|
386
|
+
|
387
|
+
Structure of HTTP/2 ``DATA`` frame [:rfc:`7540`]:
|
388
|
+
|
389
|
+
.. code-block:: text
|
390
|
+
|
391
|
+
+-----------------------------------------------+
|
392
|
+
| Length (24) |
|
393
|
+
+---------------+---------------+---------------+
|
394
|
+
| Type (8) | Flags (8) |
|
395
|
+
+-+-------------+---------------+-------------------------------+
|
396
|
+
|R| Stream Identifier (31) |
|
397
|
+
+---------------+-----------------------------------------------+
|
398
|
+
|Pad Length? (8)|
|
399
|
+
+---------------+-----------------------------------------------+
|
400
|
+
| Data (*) ...
|
401
|
+
+---------------------------------------------------------------+
|
402
|
+
| Padding (*) ...
|
403
|
+
+---------------------------------------------------------------+
|
404
|
+
|
405
|
+
Args:
|
406
|
+
schema: Parsed frame schema.
|
407
|
+
header: Parsed HTTP/2 header schema.
|
408
|
+
|
409
|
+
Returns:
|
410
|
+
Parsed packet data.
|
411
|
+
|
412
|
+
Raises:
|
413
|
+
ProtocolError: If the packet is malformed.
|
414
|
+
|
415
|
+
"""
|
416
|
+
flag = Data_DataFrameFlags(
|
417
|
+
END_STREAM=bool(header.flags['bit_0']), # bit 0
|
418
|
+
PADDED=bool(header.flags['bit_3']), # bit 3
|
419
|
+
)
|
420
|
+
flag.__update__({
|
421
|
+
'__value__': schema.__flags__,
|
422
|
+
})
|
423
|
+
|
424
|
+
data = Data_DataFrame(
|
425
|
+
length=header.length,
|
426
|
+
type=header.type,
|
427
|
+
flags=flag,
|
428
|
+
pad_len=schema.pad_len if flag.PADDED else 0,
|
429
|
+
sid=header.stream['sid'],
|
430
|
+
data=schema.data,
|
431
|
+
)
|
432
|
+
return data
|
433
|
+
|
434
|
+
def _read_http_headers(self, schema: 'Schema_HeadersFrame', *,
|
435
|
+
header: 'Schema_HTTP') -> 'Data_HeadersFrame':
|
436
|
+
"""Read HTTP/2 ``HEADERS`` frames.
|
437
|
+
|
438
|
+
Structure of HTTP/2 ``HEADERS`` frame [:rfc:`7540`]:
|
439
|
+
|
440
|
+
.. code-block:: text
|
441
|
+
|
442
|
+
+-----------------------------------------------+
|
443
|
+
| Length (24) |
|
444
|
+
+---------------+---------------+---------------+
|
445
|
+
| Type (8) | Flags (8) |
|
446
|
+
+-+-------------+---------------+-------------------------------+
|
447
|
+
|R| Stream Identifier (31) |
|
448
|
+
+---------------+-----------------------------------------------+
|
449
|
+
|Pad Length? (8)|
|
450
|
+
+-+-------------+-----------------------------------------------+
|
451
|
+
|E| Stream Dependency? (31) |
|
452
|
+
+-+-------------+-----------------------------------------------+
|
453
|
+
| Weight? (8) |
|
454
|
+
+-+-------------+-----------------------------------------------+
|
455
|
+
| Header Block Fragment (*) ...
|
456
|
+
+---------------------------------------------------------------+
|
457
|
+
| Padding (*) ...
|
458
|
+
+---------------------------------------------------------------+
|
459
|
+
|
460
|
+
Args:
|
461
|
+
schema: Parsed frame schema.
|
462
|
+
header: Parsed HTTP/2 header schema.
|
463
|
+
|
464
|
+
Returns:
|
465
|
+
Parsed packet data.
|
466
|
+
|
467
|
+
Raises:
|
468
|
+
ProtocolError: If the packet is malformed.
|
469
|
+
|
470
|
+
"""
|
471
|
+
flag = Data_HeadersFrameFlags(
|
472
|
+
END_STREAM=bool(header.flags['bit_0']), # bit 0
|
473
|
+
END_HEADERS=bool(header.flags['bit_2']), # bit 2
|
474
|
+
PADDED=bool(header.flags['bit_3']), # bit 3
|
475
|
+
PRIORITY=bool(header.flags['bit_5']), # bit 5
|
476
|
+
)
|
477
|
+
flag.__update__({
|
478
|
+
'__value__': schema.__flags__,
|
479
|
+
})
|
480
|
+
|
481
|
+
data = Data_HeadersFrame(
|
482
|
+
length=header.length,
|
483
|
+
type=header.type,
|
484
|
+
flags=flag,
|
485
|
+
pad_len=schema.pad_len if flag.PADDED else 0,
|
486
|
+
sid=header.stream['sid'],
|
487
|
+
excl_dependency=bool(schema.stream_dep['exclusive']) if flag.PRIORITY else False,
|
488
|
+
stream_dependency=schema.stream_dep['sid'] if flag.PRIORITY else 0,
|
489
|
+
weight=(schema.weight + 1) if flag.PRIORITY else 0,
|
490
|
+
fragment=schema.fragment,
|
491
|
+
)
|
492
|
+
return data
|
493
|
+
|
494
|
+
def _read_http_priority(self, schema: 'Schema_PriorityFrame', *,
|
495
|
+
header: 'Schema_HTTP') -> 'Data_PriorityFrame': # pylint: disable=unused-argument
|
496
|
+
"""Read HTTP/2 ``PRIORITY`` frames.
|
497
|
+
|
498
|
+
Structure of HTTP/2 ``PRIORITY`` frame [:rfc:`7540`]:
|
499
|
+
|
500
|
+
.. code-block:: text
|
501
|
+
|
502
|
+
+-----------------------------------------------+
|
503
|
+
| Length (24) |
|
504
|
+
+---------------+---------------+---------------+
|
505
|
+
| Type (8) | Flags (8) |
|
506
|
+
+-+-------------+---------------+-------------------------------+
|
507
|
+
|R| Stream Identifier (31) |
|
508
|
+
+-+-------------------------------------------------------------+
|
509
|
+
|E| Stream Dependency (31) |
|
510
|
+
+-+-------------+-----------------------------------------------+
|
511
|
+
| Weight (8) |
|
512
|
+
+-+-------------+
|
513
|
+
|
514
|
+
Args:
|
515
|
+
schema: Parsed frame schema.
|
516
|
+
header: Parsed HTTP/2 header schema.
|
517
|
+
|
518
|
+
Returns:
|
519
|
+
Parsed packet data.
|
520
|
+
|
521
|
+
Raises:
|
522
|
+
ProtocolError: If the packet is malformed.
|
523
|
+
|
524
|
+
"""
|
525
|
+
if header.length != 9:
|
526
|
+
raise ProtocolError(f'HTTP/2: [Type {header.type}] invalid format')
|
527
|
+
|
528
|
+
data = Data_PriorityFrame(
|
529
|
+
length=header.length,
|
530
|
+
type=header.type,
|
531
|
+
flags=None,
|
532
|
+
sid=header.stream['sid'],
|
533
|
+
excl_dependency=bool(schema.stream['exclusive']),
|
534
|
+
stream_dependency=schema.stream['sid'],
|
535
|
+
weight=schema.weight + 1,
|
536
|
+
)
|
537
|
+
return data
|
538
|
+
|
539
|
+
def _read_http_rst_stream(self, schema: 'Schema_RSTStreamFrame', *,
|
540
|
+
header: 'Schema_HTTP') -> 'Data_RSTStreamFrame': # pylint: disable=unused-argument
|
541
|
+
"""Read HTTP/2 ``RST_STREAM`` frames.
|
542
|
+
|
543
|
+
Structure of HTTP/2 ``RST_STREAM`` frame [:rfc:`7540`]:
|
544
|
+
|
545
|
+
.. code-block:: text
|
546
|
+
|
547
|
+
+-----------------------------------------------+
|
548
|
+
| Length (24) |
|
549
|
+
+---------------+---------------+---------------+
|
550
|
+
| Type (8) | Flags (8) |
|
551
|
+
+-+-------------+---------------+-------------------------------+
|
552
|
+
|R| Stream Identifier (31) |
|
553
|
+
+---------------------------------------------------------------+
|
554
|
+
| Error Code (32) |
|
555
|
+
+---------------------------------------------------------------+
|
556
|
+
|
557
|
+
Args:
|
558
|
+
schema: Parsed frame schema.
|
559
|
+
header: Parsed HTTP/2 header schema.
|
560
|
+
|
561
|
+
Returns:
|
562
|
+
Parsed packet data.
|
563
|
+
|
564
|
+
Raises:
|
565
|
+
ProtocolError: If the packet is malformed.
|
566
|
+
|
567
|
+
"""
|
568
|
+
if header.length != 13:
|
569
|
+
raise ProtocolError(f'HTTP/2: [Type {header.type}] invalid format')
|
570
|
+
|
571
|
+
data = Data_RSTStreamFrame(
|
572
|
+
length=header.length,
|
573
|
+
type=header.type,
|
574
|
+
flags=None,
|
575
|
+
sid=header.stream['sid'],
|
576
|
+
error=schema.error,
|
577
|
+
)
|
578
|
+
return data
|
579
|
+
|
580
|
+
def _read_http_settings(self, schema: 'Schema_SettingsFrame', *,
|
581
|
+
header: 'Schema_HTTP') -> 'Data_SettingsFrame':
|
582
|
+
"""Read HTTP/2 ``SETTINGS`` frames.
|
583
|
+
|
584
|
+
Structure of HTTP/2 ``SETTINGS`` frame [:rfc:`7540`]:
|
585
|
+
|
586
|
+
.. code-block:: text
|
587
|
+
|
588
|
+
+-----------------------------------------------+
|
589
|
+
| Length (24) |
|
590
|
+
+---------------+---------------+---------------+
|
591
|
+
| Type (8) | Flags (8) |
|
592
|
+
+-+-------------+---------------+-------------------------------+
|
593
|
+
|R| Stream Identifier (31) |
|
594
|
+
+---------------------------------------------------------------+
|
595
|
+
| Identifier (16) |
|
596
|
+
+-------------------------------+-------------------------------+
|
597
|
+
| Value (32) |
|
598
|
+
+---------------------------------------------------------------+
|
599
|
+
| ...... |
|
600
|
+
|
601
|
+
Args:
|
602
|
+
schema: Parsed frame schema.
|
603
|
+
header: Parsed HTTP/2 header schema.
|
604
|
+
|
605
|
+
Returns:
|
606
|
+
Parsed packet data.
|
607
|
+
|
608
|
+
Raises:
|
609
|
+
ProtocolError: If the packet is malformed.
|
610
|
+
|
611
|
+
"""
|
612
|
+
if (header.length - 9) % 6 != 0 or header.stream['sid'] != 0:
|
613
|
+
raise ProtocolError(f'HTTP/2: [Type {header.type}] invalid format')
|
614
|
+
|
615
|
+
flag = Data_SettingsFrameFlags(
|
616
|
+
ACK=bool(header.flags['bit_0']), # bit 0
|
617
|
+
)
|
618
|
+
flag.__update__({
|
619
|
+
'__value__': schema.__flags__,
|
620
|
+
})
|
621
|
+
|
622
|
+
if flag.ACK and header.length - 9 != 0:
|
623
|
+
raise ProtocolError(f'HTTP/2: [Type {header.type}] invalid format')
|
624
|
+
|
625
|
+
sets = OrderedMultiDict() # type: OrderedMultiDict[Enum_Setting, int]
|
626
|
+
for setting in schema.settings:
|
627
|
+
sets[setting.id] = setting.value
|
628
|
+
|
629
|
+
data = Data_SettingsFrame(
|
630
|
+
length=header.length,
|
631
|
+
type=header.type,
|
632
|
+
flags=flag,
|
633
|
+
sid=header.stream['sid'],
|
634
|
+
settings=sets,
|
635
|
+
)
|
636
|
+
return data
|
637
|
+
|
638
|
+
def _read_http_push_promise(self, schema: 'Schema_PushPromiseFrame', *,
|
639
|
+
header: 'Schema_HTTP') -> 'Data_PushPromiseFrame':
|
640
|
+
"""Read HTTP/2 ``PUSH_PROMISE`` frames.
|
641
|
+
|
642
|
+
Structure of HTTP/2 ``PUSH_PROMISE`` frame [:rfc:`7540`]:
|
643
|
+
|
644
|
+
.. code-block:: text
|
645
|
+
|
646
|
+
+-----------------------------------------------+
|
647
|
+
| Length (24) |
|
648
|
+
+---------------+---------------+---------------+
|
649
|
+
| Type (8) | Flags (8) |
|
650
|
+
+-+-------------+---------------+-------------------------------+
|
651
|
+
|R| Stream Identifier (31) |
|
652
|
+
+---------------+-----------------------------------------------+
|
653
|
+
|Pad Length? (8)|
|
654
|
+
+-+-------------+-----------------------------------------------+
|
655
|
+
|R| Promised Stream ID (31) |
|
656
|
+
+-+-----------------------------+-------------------------------+
|
657
|
+
| Header Block Fragment (*) ...
|
658
|
+
+---------------------------------------------------------------+
|
659
|
+
| Padding (*) ...
|
660
|
+
+---------------------------------------------------------------+
|
661
|
+
|
662
|
+
Args:
|
663
|
+
schema: Parsed frame schema.
|
664
|
+
header: Parsed HTTP/2 header schema.
|
665
|
+
|
666
|
+
Returns:
|
667
|
+
Parsed packet data.
|
668
|
+
|
669
|
+
Raises:
|
670
|
+
ProtocolError: If the packet is malformed.
|
671
|
+
|
672
|
+
"""
|
673
|
+
if header.length < 13:
|
674
|
+
raise ProtocolError(f'HTTP/2: [Type {header.type}] invalid format')
|
675
|
+
|
676
|
+
flag = Data_PushPromiseFrameFlags(
|
677
|
+
END_HEADERS=bool(header.flags['bit_2']), # bit 2
|
678
|
+
PADDED=bool(header.flags['bit_3']), # bit 3
|
679
|
+
)
|
680
|
+
flag.__update__({
|
681
|
+
'__value__': schema.__flags__,
|
682
|
+
})
|
683
|
+
|
684
|
+
data = Data_PushPromiseFrame(
|
685
|
+
length=header.length,
|
686
|
+
type=header.type,
|
687
|
+
flags=flag,
|
688
|
+
sid=header.stream['sid'],
|
689
|
+
pad_len=schema.pad_len if flag.PADDED else 0,
|
690
|
+
promised_sid=schema.stream['sid'],
|
691
|
+
fragment=schema.fragment,
|
692
|
+
)
|
693
|
+
|
694
|
+
return data
|
695
|
+
|
696
|
+
def _read_http_ping(self, schema: 'Schema_PingFrame', *,
|
697
|
+
header: 'Schema_HTTP') -> 'Data_PingFrame':
|
698
|
+
"""Read HTTP/2 ``PING`` frames.
|
699
|
+
|
700
|
+
Structure of HTTP/2 ``PING`` frame [:rfc:`7540`]:
|
701
|
+
|
702
|
+
.. code-block:: text
|
703
|
+
|
704
|
+
+-----------------------------------------------+
|
705
|
+
| Length (24) |
|
706
|
+
+---------------+---------------+---------------+
|
707
|
+
| Type (8) | Flags (8) |
|
708
|
+
+-+-------------+---------------+-------------------------------+
|
709
|
+
|R| Stream Identifier (31) |
|
710
|
+
+---------------------------------------------------------------+
|
711
|
+
| |
|
712
|
+
| Opaque Data (64) |
|
713
|
+
| |
|
714
|
+
+---------------------------------------------------------------+
|
715
|
+
|
716
|
+
Args:
|
717
|
+
schema: Parsed frame schema.
|
718
|
+
header: Parsed HTTP/2 header schema.
|
719
|
+
|
720
|
+
Returns:
|
721
|
+
Parsed packet data.
|
722
|
+
|
723
|
+
Raises:
|
724
|
+
ProtocolError: If the packet is malformed.
|
725
|
+
|
726
|
+
"""
|
727
|
+
if header.length != 17:
|
728
|
+
raise ProtocolError(f'HTTP/2: [Type {header.type}] invalid format')
|
729
|
+
|
730
|
+
flag = Data_PingFrameFlags(
|
731
|
+
ACK=bool(header.flags['bit_0']), # bit 0
|
732
|
+
)
|
733
|
+
flag.__update__({
|
734
|
+
'__value__': schema.__flags__,
|
735
|
+
})
|
736
|
+
|
737
|
+
data = Data_PingFrame(
|
738
|
+
length=header.length,
|
739
|
+
type=header.type,
|
740
|
+
flags=flag,
|
741
|
+
sid=header.stream['sid'],
|
742
|
+
data=schema.data,
|
743
|
+
)
|
744
|
+
return data
|
745
|
+
|
746
|
+
def _read_http_goaway(self, schema: 'Schema_GoawayFrame', *,
|
747
|
+
header: 'Schema_HTTP') -> 'Data_GoawayFrame': # pylint: disable=unused-argument
|
748
|
+
"""Read HTTP/2 ``GOAWAY`` frames.
|
749
|
+
|
750
|
+
Structure of HTTP/2 ``GOAWAY`` frame [:rfc:`7540`]:
|
751
|
+
|
752
|
+
.. code-block:: text
|
753
|
+
|
754
|
+
+-----------------------------------------------+
|
755
|
+
| Length (24) |
|
756
|
+
+---------------+---------------+---------------+
|
757
|
+
| Type (8) | Flags (8) |
|
758
|
+
+-+-------------+---------------+-------------------------------+
|
759
|
+
|R| Stream Identifier (31) |
|
760
|
+
+-+-------------+---------------+-------------------------------+
|
761
|
+
|R| Last-Stream-ID (31) |
|
762
|
+
+-+-------------------------------------------------------------+
|
763
|
+
| Error Code (32) |
|
764
|
+
+---------------------------------------------------------------+
|
765
|
+
| Additional Debug Data (*) |
|
766
|
+
+---------------------------------------------------------------+
|
767
|
+
|
768
|
+
Args:
|
769
|
+
schema: Parsed frame schema.
|
770
|
+
header: Parsed HTTP/2 header schema.
|
771
|
+
|
772
|
+
Returns:
|
773
|
+
Parsed packet data.
|
774
|
+
|
775
|
+
Raises:
|
776
|
+
ProtocolError: If the packet is malformed.
|
777
|
+
|
778
|
+
"""
|
779
|
+
data = Data_GoawayFrame(
|
780
|
+
length=header.length,
|
781
|
+
type=header.type,
|
782
|
+
flags=None,
|
783
|
+
sid=header.stream['sid'],
|
784
|
+
last_sid=schema.stream['sid'],
|
785
|
+
error=schema.error,
|
786
|
+
debug_data=schema.debug,
|
787
|
+
)
|
788
|
+
return data
|
789
|
+
|
790
|
+
def _read_http_window_update(self, schema: 'Schema_WindowUpdateFrame', *,
|
791
|
+
header: 'Schema_HTTP') -> 'Data_WindowUpdateFrame': # pylint: disable=unused-argument
|
792
|
+
"""Read HTTP/2 ``WINDOW_UPDATE`` frames.
|
793
|
+
|
794
|
+
Structure of HTTP/2 ``WINDOW_UPDATE`` frame [:rfc:`7540`]:
|
795
|
+
|
796
|
+
.. code-block:: text
|
797
|
+
|
798
|
+
+-----------------------------------------------+
|
799
|
+
| Length (24) |
|
800
|
+
+---------------+---------------+---------------+
|
801
|
+
| Type (8) | Flags (8) |
|
802
|
+
+-+-------------+---------------+-------------------------------+
|
803
|
+
|R| Stream Identifier (31) |
|
804
|
+
+-+-------------+---------------+-------------------------------+
|
805
|
+
|R| Window Size Increment (31) |
|
806
|
+
+-+-------------------------------------------------------------+
|
807
|
+
|
808
|
+
Args:
|
809
|
+
schema: Parsed frame schema.
|
810
|
+
header: Parsed HTTP/2 header schema.
|
811
|
+
|
812
|
+
Returns:
|
813
|
+
Parsed packet data.
|
814
|
+
|
815
|
+
Raises:
|
816
|
+
ProtocolError: If the packet is malformed.
|
817
|
+
|
818
|
+
"""
|
819
|
+
if header.length != 13:
|
820
|
+
raise ProtocolError(f'HTTP/2: [Type {header.type}] invalid format')
|
821
|
+
|
822
|
+
data = Data_WindowUpdateFrame(
|
823
|
+
length=header.length,
|
824
|
+
type=header.type,
|
825
|
+
flags=None,
|
826
|
+
sid=header.stream['sid'],
|
827
|
+
increment=schema.size['incr'],
|
828
|
+
)
|
829
|
+
return data
|
830
|
+
|
831
|
+
def _read_http_continuation(self, schema: 'Schema_ContinuationFrame', *,
|
832
|
+
header: 'Schema_HTTP') -> 'Data_ContinuationFrame':
|
833
|
+
"""Read HTTP/2 ``CONTINUATION`` frames.
|
834
|
+
|
835
|
+
Structure of HTTP/2 ``CONTINUATION`` frame [:rfc:`7540`]:
|
836
|
+
|
837
|
+
.. code-block:: text
|
838
|
+
|
839
|
+
+-----------------------------------------------+
|
840
|
+
| Length (24) |
|
841
|
+
+---------------+---------------+---------------+
|
842
|
+
| Type (8) | Flags (8) |
|
843
|
+
+-+-------------+---------------+-------------------------------+
|
844
|
+
|R| Stream Identifier (31) |
|
845
|
+
+---------------------------------------------------------------+
|
846
|
+
| Header Block Fragment (*) ...
|
847
|
+
+---------------------------------------------------------------+
|
848
|
+
|
849
|
+
Args:
|
850
|
+
schema: Parsed frame schema.
|
851
|
+
header: Parsed HTTP/2 header schema.
|
852
|
+
|
853
|
+
Returns:
|
854
|
+
Parsed packet data.
|
855
|
+
|
856
|
+
Raises:
|
857
|
+
ProtocolError: If the packet is malformed.
|
858
|
+
|
859
|
+
"""
|
860
|
+
flag = Data_ContinuationFrameFlags(
|
861
|
+
END_HEADERS=bool(header.flags['bit_2']), # bit 2
|
862
|
+
)
|
863
|
+
flag.__update__({
|
864
|
+
'__value__': schema.__flags__,
|
865
|
+
})
|
866
|
+
|
867
|
+
data = Data_ContinuationFrame(
|
868
|
+
length=header.length,
|
869
|
+
type=header.type,
|
870
|
+
flags=flag,
|
871
|
+
sid=header.stream['sid'],
|
872
|
+
fragment=schema.fragment,
|
873
|
+
)
|
874
|
+
return data
|
875
|
+
|
876
|
+
def _make_http_none(self, frame: 'Optional[Data_UnassignedFrame]' = None, *,
|
877
|
+
data: 'bytes' = b'',
|
878
|
+
**kwargs: 'Any') -> 'tuple[Schema_UnassignedFrame, Flags]':
|
879
|
+
"""Make HTTP/2 unassigned frame type.
|
880
|
+
|
881
|
+
Args:
|
882
|
+
frame: Frame data model.
|
883
|
+
data: Unspecified frame data.
|
884
|
+
**kwargs: Arbitrary keyword arguments.
|
885
|
+
|
886
|
+
Returns:
|
887
|
+
Constructed frame schema and updated flags.
|
888
|
+
|
889
|
+
"""
|
890
|
+
if frame is not None:
|
891
|
+
data = frame.data
|
892
|
+
|
893
|
+
return Schema_UnassignedFrame(
|
894
|
+
data=data,
|
895
|
+
), Schema_UnassignedFrame.Flags(0)
|
896
|
+
|
897
|
+
def _make_http_data(self, frame: 'Optional[Data_DataFrame]' = None, *,
|
898
|
+
end_stream: 'bool' = False,
|
899
|
+
pad_len: 'int' = 0,
|
900
|
+
data: 'bytes' = b'',
|
901
|
+
**kwargs: 'Any') -> 'tuple[Schema_DataFrame, Flags]':
|
902
|
+
"""Make HTTP/2 ``DATA`` frame.
|
903
|
+
|
904
|
+
Args:
|
905
|
+
frame: Frame data model.
|
906
|
+
end_stream: End of stream flag.
|
907
|
+
data: Frame data.
|
908
|
+
**kwargs: Arbitrary keyword arguments.
|
909
|
+
|
910
|
+
Returns:
|
911
|
+
Constructed frame schema and updated flags.
|
912
|
+
|
913
|
+
"""
|
914
|
+
if frame is not None:
|
915
|
+
pad_len = frame.pad_len
|
916
|
+
data = frame.data
|
917
|
+
|
918
|
+
flags = Schema_DataFrame.Flags(0)
|
919
|
+
if end_stream:
|
920
|
+
flags |= Schema_DataFrame.Flags.END_STREAM
|
921
|
+
if pad_len:
|
922
|
+
flags |= Schema_DataFrame.Flags.PADDED
|
923
|
+
|
924
|
+
return Schema_DataFrame(
|
925
|
+
pad_len=pad_len,
|
926
|
+
data=data,
|
927
|
+
), flags
|
928
|
+
|
929
|
+
def _make_http_headers(self, frame: 'Optional[Data_HeadersFrame]' = None, *,
|
930
|
+
end_stream: 'bool' = False,
|
931
|
+
end_headers: 'bool' = False,
|
932
|
+
pad_len: 'int' = 0,
|
933
|
+
excl_dep: 'bool' = False,
|
934
|
+
sid_dep: 'Optional[int]' = None,
|
935
|
+
weight: 'int' = 0,
|
936
|
+
fragment: 'bytes' = b'',
|
937
|
+
**kwargs: 'Any') -> 'tuple[Schema_HeadersFrame, Flags]':
|
938
|
+
"""Make HTTP/2 ``HEADERS`` frame.
|
939
|
+
|
940
|
+
Args:
|
941
|
+
frame: Frame data model.
|
942
|
+
end_stream: End of stream flag.
|
943
|
+
end_headers: End of headers flag.
|
944
|
+
excl_dep: Exclusive dependency flag.
|
945
|
+
sid_dep: Dependency stream identifier.
|
946
|
+
weight: Priority weight value.
|
947
|
+
fragment: Header block fragment.
|
948
|
+
**kwargs: Arbitrary keyword arguments.
|
949
|
+
|
950
|
+
Returns:
|
951
|
+
Constructed frame schema and updated flags.
|
952
|
+
|
953
|
+
"""
|
954
|
+
if frame is not None:
|
955
|
+
priority = frame.flags.PRIORITY
|
956
|
+
end_headers = frame.flags.END_HEADERS
|
957
|
+
end_stream = frame.flags.END_STREAM
|
958
|
+
|
959
|
+
pad_len = frame.pad_len
|
960
|
+
excl_dep = frame.excl_dependency
|
961
|
+
sid_dep = frame.stream_dependency
|
962
|
+
weight = frame.weight
|
963
|
+
fragment = frame.fragment
|
964
|
+
else:
|
965
|
+
priority = sid_dep is not None
|
966
|
+
sid_dep = sid_dep or 0
|
967
|
+
|
968
|
+
flags = Schema_HeadersFrame.Flags(0)
|
969
|
+
if end_stream:
|
970
|
+
flags |= Schema_HeadersFrame.Flags.END_STREAM
|
971
|
+
if end_headers:
|
972
|
+
flags |= Schema_HeadersFrame.Flags.END_HEADERS
|
973
|
+
if pad_len:
|
974
|
+
flags |= Schema_HeadersFrame.Flags.PADDED
|
975
|
+
if priority:
|
976
|
+
flags |= Schema_HeadersFrame.Flags.PRIORITY
|
977
|
+
|
978
|
+
return Schema_HeadersFrame(
|
979
|
+
pad_len=pad_len,
|
980
|
+
stream_dep={
|
981
|
+
'exclusive': excl_dep,
|
982
|
+
'sid': sid_dep,
|
983
|
+
},
|
984
|
+
weight=weight - 1 if weight else 0,
|
985
|
+
fragment=fragment,
|
986
|
+
), flags
|
987
|
+
|
988
|
+
def _make_http_priority(self, frame: 'Optional[Data_PriorityFrame]' = None, *,
|
989
|
+
sid_dep: 'int' = 0,
|
990
|
+
excl_dep: 'bool' = False,
|
991
|
+
weight: 'int' = 0,
|
992
|
+
**kwargs: 'Any') -> 'tuple[Schema_PriorityFrame, Flags]':
|
993
|
+
"""Make HTTP/2 ``PRIORITY`` frame.
|
994
|
+
|
995
|
+
Args:
|
996
|
+
frame: Frame data model.
|
997
|
+
excl_dep: Exclusive dependency flag.
|
998
|
+
sid_dep: Dependency stream identifier.
|
999
|
+
weight: Priority weight value.
|
1000
|
+
**kwargs: Arbitrary keyword arguments.
|
1001
|
+
|
1002
|
+
Returns:
|
1003
|
+
Constructed frame schema and updated flags.
|
1004
|
+
|
1005
|
+
"""
|
1006
|
+
if frame is not None:
|
1007
|
+
excl_dep = frame.excl_dependency
|
1008
|
+
sid_dep = frame.stream_dependency
|
1009
|
+
weight = frame.weight
|
1010
|
+
|
1011
|
+
return Schema_PriorityFrame(
|
1012
|
+
stream={
|
1013
|
+
'exclusive': excl_dep,
|
1014
|
+
'sid': sid_dep,
|
1015
|
+
},
|
1016
|
+
weight=weight - 1 if weight else 0,
|
1017
|
+
), Schema_PriorityFrame.Flags(0)
|
1018
|
+
|
1019
|
+
def _make_http_rst_stream(self, frame: 'Optional[Data_RSTStreamFrame]' = None, *,
|
1020
|
+
error: 'Enum_ErrorCode | str | int | StdlibEnum | AenumEnum' = Enum_ErrorCode.HTTP_1_1_REQUIRED,
|
1021
|
+
error_default: 'Optional[int]' = None,
|
1022
|
+
error_namespace: 'Optional[dict[str, int] | dict[int, str] | Type[StdlibEnum] | Type[AenumEnum]]' = None, # pylint: disable=line-too-long
|
1023
|
+
error_reversed: 'bool' = False,
|
1024
|
+
**kwargs: 'Any') -> 'tuple[Schema_RSTStreamFrame, Flags]':
|
1025
|
+
"""Make HTTP/2 ``RST_STREAM`` frame.
|
1026
|
+
|
1027
|
+
Args:
|
1028
|
+
frame: Frame data model.
|
1029
|
+
error: Error code.
|
1030
|
+
**kwargs: Arbitrary keyword arguments.
|
1031
|
+
|
1032
|
+
Returns:
|
1033
|
+
Constructed frame schema and updated flags.
|
1034
|
+
|
1035
|
+
"""
|
1036
|
+
if frame is not None:
|
1037
|
+
error_val = frame.error
|
1038
|
+
else:
|
1039
|
+
error_val = self._make_index(error, error_default, namespace=error_namespace, # type: ignore[assignment]
|
1040
|
+
reversed=error_reversed, pack=False)
|
1041
|
+
|
1042
|
+
return Schema_RSTStreamFrame(
|
1043
|
+
error=error_val,
|
1044
|
+
), Schema_RSTStreamFrame.Flags(0)
|
1045
|
+
|
1046
|
+
def _make_http_settings(self, frame: 'Optional[Data_SettingsFrame]' = None, *,
|
1047
|
+
ack: 'bool' = False,
|
1048
|
+
settings: 'Optional[OrderedMultiDict[Enum_Setting, int] | bytes | list[Schema_SettingPair | tuple[Enum_Setting, int]]]' = None, # pylint: disable=line-too-long
|
1049
|
+
**kwargs: 'Any') -> 'tuple[Schema_SettingsFrame, Flags]':
|
1050
|
+
"""Make HTTP/2 ``SETTINGS`` frame.
|
1051
|
+
|
1052
|
+
Args:
|
1053
|
+
frame: Frame data model.
|
1054
|
+
ack: Acknowledge flag.
|
1055
|
+
settings: Settings.
|
1056
|
+
**kwargs: Arbitrary keyword arguments.
|
1057
|
+
|
1058
|
+
Returns:
|
1059
|
+
Constructed frame schema and updated flags.
|
1060
|
+
|
1061
|
+
"""
|
1062
|
+
if frame is not None:
|
1063
|
+
ack = frame.flags.ACK
|
1064
|
+
settings = frame.settings
|
1065
|
+
|
1066
|
+
flags = Schema_SettingsFrame.Flags(0)
|
1067
|
+
if ack:
|
1068
|
+
flags |= Schema_SettingsFrame.Flags.ACK
|
1069
|
+
|
1070
|
+
if isinstance(settings, bytes):
|
1071
|
+
settings_val = settings # type: bytes | list[Schema_SettingPair]
|
1072
|
+
elif isinstance(settings, dict):
|
1073
|
+
settings_val = []
|
1074
|
+
for key, val in settings.items(multi=True):
|
1075
|
+
settings_val.append(Schema_SettingPair(
|
1076
|
+
id=key,
|
1077
|
+
value=val,
|
1078
|
+
))
|
1079
|
+
elif isinstance(settings, list):
|
1080
|
+
settings_val = []
|
1081
|
+
for item in settings:
|
1082
|
+
if isinstance(item, Schema_SettingPair):
|
1083
|
+
temp = item
|
1084
|
+
else:
|
1085
|
+
id, value = item
|
1086
|
+
temp = Schema_SettingPair(
|
1087
|
+
id=id,
|
1088
|
+
value=value,
|
1089
|
+
)
|
1090
|
+
settings_val.append(temp)
|
1091
|
+
else:
|
1092
|
+
raise ProtocolError(f'HTTP/2 : [Type {Enum_Frame.SETTINGS}] invalid settings')
|
1093
|
+
|
1094
|
+
return Schema_SettingsFrame(
|
1095
|
+
settings=settings_val,
|
1096
|
+
), flags
|
1097
|
+
|
1098
|
+
def _make_http_push_promise(self, frame: 'Optional[Data_PushPromiseFrame]' = None, *,
|
1099
|
+
end_headers: 'bool' = False,
|
1100
|
+
pad_len: 'int' = 0,
|
1101
|
+
promised_sid: 'int' = 0,
|
1102
|
+
fragment: 'bytes' = b'',
|
1103
|
+
**kwargs: 'Any') -> 'tuple[Schema_PushPromiseFrame, Flags]':
|
1104
|
+
"""Make HTTP/2 ``PUSH_PROMISE`` frame.
|
1105
|
+
|
1106
|
+
Args:
|
1107
|
+
frame: Frame data model.
|
1108
|
+
end_headers: End of headers flag.
|
1109
|
+
pad_len: Padding length.
|
1110
|
+
promised_sid: Promised stream identifier.
|
1111
|
+
fragment: Header block fragment.
|
1112
|
+
**kwargs: Arbitrary keyword arguments.
|
1113
|
+
|
1114
|
+
Returns:
|
1115
|
+
Constructed frame schema and updated flags.
|
1116
|
+
|
1117
|
+
"""
|
1118
|
+
if frame is not None:
|
1119
|
+
end_headers = frame.flags.END_HEADERS
|
1120
|
+
pad_len = frame.pad_len
|
1121
|
+
promised_sid = frame.promised_sid
|
1122
|
+
fragment = frame.fragment
|
1123
|
+
|
1124
|
+
flags = Schema_PushPromiseFrame.Flags(0)
|
1125
|
+
if end_headers:
|
1126
|
+
flags |= Schema_PushPromiseFrame.Flags.END_HEADERS
|
1127
|
+
if pad_len:
|
1128
|
+
flags |= Schema_PushPromiseFrame.Flags.PADDED
|
1129
|
+
|
1130
|
+
return Schema_PushPromiseFrame(
|
1131
|
+
pad_len=pad_len,
|
1132
|
+
stream={
|
1133
|
+
'sid': promised_sid,
|
1134
|
+
},
|
1135
|
+
fragment=fragment,
|
1136
|
+
), flags
|
1137
|
+
|
1138
|
+
def _make_http_ping(self, frame: 'Optional[Data_PingFrame]' = None, *,
|
1139
|
+
ack: 'bool' = False,
|
1140
|
+
opaque_data: 'bytes' = b'',
|
1141
|
+
**kwargs: 'Any') -> 'tuple[Schema_PingFrame, Flags]':
|
1142
|
+
"""Make HTTP/2 ``PING`` frame.
|
1143
|
+
|
1144
|
+
Args:
|
1145
|
+
frame: Frame data model.
|
1146
|
+
ack: Acknowledge flag.
|
1147
|
+
opaque_data: Opaque data.
|
1148
|
+
**kwargs: Arbitrary keyword arguments.
|
1149
|
+
|
1150
|
+
Returns:
|
1151
|
+
Constructed frame schema and updated flags.
|
1152
|
+
|
1153
|
+
"""
|
1154
|
+
if frame is not None:
|
1155
|
+
ack = frame.flags.ACK
|
1156
|
+
opaque_data = frame.data
|
1157
|
+
|
1158
|
+
flags = Schema_PingFrame.Flags(0)
|
1159
|
+
if ack:
|
1160
|
+
flags |= Schema_PingFrame.Flags.ACK
|
1161
|
+
|
1162
|
+
return Schema_PingFrame(
|
1163
|
+
data=opaque_data,
|
1164
|
+
), flags
|
1165
|
+
|
1166
|
+
def _make_http_goaway(self, frame: 'Optional[Data_GoawayFrame]' = None, *,
|
1167
|
+
last_sid: 'int' = 0,
|
1168
|
+
error: 'Enum_ErrorCode | str | int | StdlibEnum | AenumEnum' = Enum_ErrorCode.HTTP_1_1_REQUIRED,
|
1169
|
+
error_default: 'Optional[int]' = None,
|
1170
|
+
error_namespace: 'Optional[dict[str, int] | dict[int, str] | Type[StdlibEnum] | Type[AenumEnum]]' = None, # pylint: disable=line-too-long
|
1171
|
+
error_reversed: 'bool' = False,
|
1172
|
+
debug_data: 'bytes' = b'',
|
1173
|
+
**kwargs: 'Any') -> 'tuple[Schema_GoawayFrame, Flags]':
|
1174
|
+
"""Make HTTP/2 ``GOAWAY`` frame.
|
1175
|
+
|
1176
|
+
Args:
|
1177
|
+
frame: Frame data model.
|
1178
|
+
last_sid: Last stream identifier.
|
1179
|
+
error: Error code.
|
1180
|
+
error_default: Default value of error code.
|
1181
|
+
error_namespace: Namespace of error code.
|
1182
|
+
error_reversed: Reversed namespace of error code.
|
1183
|
+
debug_data: Additional debug data.
|
1184
|
+
**kwargs: Arbitrary keyword arguments.
|
1185
|
+
|
1186
|
+
Returns:
|
1187
|
+
Constructed frame schema and updated flags.
|
1188
|
+
|
1189
|
+
"""
|
1190
|
+
if frame is not None:
|
1191
|
+
last_sid = frame.last_sid
|
1192
|
+
error_val = frame.error
|
1193
|
+
debug = frame.debug_data
|
1194
|
+
else:
|
1195
|
+
error_val = self._make_index(error, error_default, namespace=error_namespace, # type: ignore[assignment]
|
1196
|
+
reversed=error_reversed, pack=False)
|
1197
|
+
|
1198
|
+
return Schema_GoawayFrame(
|
1199
|
+
stream={
|
1200
|
+
'sid': last_sid,
|
1201
|
+
},
|
1202
|
+
error=error_val,
|
1203
|
+
debug=debug,
|
1204
|
+
), Schema_GoawayFrame.Flags(0)
|
1205
|
+
|
1206
|
+
def _make_http_window_update(self, frame: 'Optional[Data_WindowUpdateFrame]' = None, *,
|
1207
|
+
incr: 'int' = 0,
|
1208
|
+
**kwargs: 'Any') -> 'tuple[Schema_WindowUpdateFrame, Flags]':
|
1209
|
+
"""Make HTTP/2 ``WINDOW_UPDATE`` frame.
|
1210
|
+
|
1211
|
+
Args:
|
1212
|
+
frame: Frame data model.
|
1213
|
+
incr: Window size increment.
|
1214
|
+
**kwargs: Arbitrary keyword arguments.
|
1215
|
+
|
1216
|
+
Returns:
|
1217
|
+
Constructed frame schema and updated flags.
|
1218
|
+
|
1219
|
+
"""
|
1220
|
+
if frame is not None:
|
1221
|
+
incr = frame.increment
|
1222
|
+
|
1223
|
+
return Schema_WindowUpdateFrame(
|
1224
|
+
size={
|
1225
|
+
'incr': incr,
|
1226
|
+
}
|
1227
|
+
), Schema_WindowUpdateFrame.Flags(0)
|
1228
|
+
|
1229
|
+
def _make_http_continuation(self, frame: 'Optional[Data_ContinuationFrame]' = None, *,
|
1230
|
+
end_headers: 'bool' = False,
|
1231
|
+
fragment: 'bytes' = b'',
|
1232
|
+
**kwargs: 'Any') -> 'tuple[Schema_ContinuationFrame, Flags]':
|
1233
|
+
"""Make HTTP/2 ``CONTINUATION`` frame.
|
1234
|
+
|
1235
|
+
Args:
|
1236
|
+
frame: Frame data model.
|
1237
|
+
end_headers: End of headers flag.
|
1238
|
+
fragment: Header block fragment.
|
1239
|
+
**kwargs: Arbitrary keyword arguments.
|
1240
|
+
|
1241
|
+
Returns:
|
1242
|
+
Constructed frame schema and updated flags.
|
1243
|
+
|
1244
|
+
"""
|
1245
|
+
if frame is not None:
|
1246
|
+
end_headers = frame.flags.END_HEADERS
|
1247
|
+
fragment = frame.fragment
|
1248
|
+
|
1249
|
+
flags = Schema_ContinuationFrame.Flags(0)
|
1250
|
+
if end_headers:
|
1251
|
+
flags |= Schema_ContinuationFrame.Flags.END_HEADERS
|
1252
|
+
|
1253
|
+
return Schema_ContinuationFrame(
|
1254
|
+
fragment=fragment,
|
1255
|
+
), flags
|