tigrcorn-protocols 0.3.16.dev5__py3-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.
Files changed (80) hide show
  1. tigrcorn_protocols/__init__.py +1 -0
  2. tigrcorn_protocols/_compression.py +219 -0
  3. tigrcorn_protocols/connect.py +107 -0
  4. tigrcorn_protocols/content_coding.py +179 -0
  5. tigrcorn_protocols/custom/__init__.py +3 -0
  6. tigrcorn_protocols/custom/adapters.py +18 -0
  7. tigrcorn_protocols/custom/registry.py +15 -0
  8. tigrcorn_protocols/flow/__init__.py +1 -0
  9. tigrcorn_protocols/flow/backpressure.py +17 -0
  10. tigrcorn_protocols/flow/buffers.py +29 -0
  11. tigrcorn_protocols/flow/credits.py +21 -0
  12. tigrcorn_protocols/flow/keepalive.py +85 -0
  13. tigrcorn_protocols/flow/timeouts.py +17 -0
  14. tigrcorn_protocols/flow/watermarks.py +16 -0
  15. tigrcorn_protocols/http1/__init__.py +16 -0
  16. tigrcorn_protocols/http1/keepalive.py +21 -0
  17. tigrcorn_protocols/http1/parser.py +481 -0
  18. tigrcorn_protocols/http1/serializer.py +198 -0
  19. tigrcorn_protocols/http1/state.py +9 -0
  20. tigrcorn_protocols/http2/__init__.py +16 -0
  21. tigrcorn_protocols/http2/codec.py +266 -0
  22. tigrcorn_protocols/http2/flow.py +35 -0
  23. tigrcorn_protocols/http2/handler.py +1303 -0
  24. tigrcorn_protocols/http2/hpack.py +393 -0
  25. tigrcorn_protocols/http2/state.py +226 -0
  26. tigrcorn_protocols/http2/streams.py +76 -0
  27. tigrcorn_protocols/http2/websocket.py +360 -0
  28. tigrcorn_protocols/http3/__init__.py +82 -0
  29. tigrcorn_protocols/http3/codec.py +148 -0
  30. tigrcorn_protocols/http3/handler/__init__.py +3 -0
  31. tigrcorn_protocols/http3/handler/core.py +1823 -0
  32. tigrcorn_protocols/http3/handler/webtransport.py +184 -0
  33. tigrcorn_protocols/http3/handler.py +3 -0
  34. tigrcorn_protocols/http3/qpack.py +843 -0
  35. tigrcorn_protocols/http3/state.py +129 -0
  36. tigrcorn_protocols/http3/streams.py +657 -0
  37. tigrcorn_protocols/http3/websocket.py +360 -0
  38. tigrcorn_protocols/lifespan/__init__.py +3 -0
  39. tigrcorn_protocols/lifespan/driver.py +83 -0
  40. tigrcorn_protocols/py.typed +1 -0
  41. tigrcorn_protocols/rawframed/__init__.py +5 -0
  42. tigrcorn_protocols/rawframed/codec.py +18 -0
  43. tigrcorn_protocols/rawframed/frames.py +28 -0
  44. tigrcorn_protocols/rawframed/handler.py +72 -0
  45. tigrcorn_protocols/rawframed/state.py +9 -0
  46. tigrcorn_protocols/registry.py +22 -0
  47. tigrcorn_protocols/scheduler/__init__.py +17 -0
  48. tigrcorn_protocols/scheduler/cancellation.py +40 -0
  49. tigrcorn_protocols/scheduler/dispatch.py +27 -0
  50. tigrcorn_protocols/scheduler/fairness.py +21 -0
  51. tigrcorn_protocols/scheduler/policy.py +12 -0
  52. tigrcorn_protocols/scheduler/priorities.py +8 -0
  53. tigrcorn_protocols/scheduler/quotas.py +19 -0
  54. tigrcorn_protocols/scheduler/runtime.py +156 -0
  55. tigrcorn_protocols/scheduler/tasks.py +31 -0
  56. tigrcorn_protocols/sessions/__init__.py +1 -0
  57. tigrcorn_protocols/sessions/base.py +16 -0
  58. tigrcorn_protocols/sessions/connection.py +12 -0
  59. tigrcorn_protocols/sessions/limits.py +12 -0
  60. tigrcorn_protocols/sessions/manager.py +31 -0
  61. tigrcorn_protocols/sessions/metadata.py +10 -0
  62. tigrcorn_protocols/sessions/quic.py +14 -0
  63. tigrcorn_protocols/streams/__init__.py +1 -0
  64. tigrcorn_protocols/streams/base.py +13 -0
  65. tigrcorn_protocols/streams/ids.py +5 -0
  66. tigrcorn_protocols/streams/multiplex.py +6 -0
  67. tigrcorn_protocols/streams/registry.py +22 -0
  68. tigrcorn_protocols/streams/singleplex.py +6 -0
  69. tigrcorn_protocols/websocket/__init__.py +1 -0
  70. tigrcorn_protocols/websocket/codec.py +31 -0
  71. tigrcorn_protocols/websocket/extensions.py +324 -0
  72. tigrcorn_protocols/websocket/frames.py +174 -0
  73. tigrcorn_protocols/websocket/handler.py +462 -0
  74. tigrcorn_protocols/websocket/handshake.py +66 -0
  75. tigrcorn_protocols/websocket/state.py +10 -0
  76. tigrcorn_protocols-0.3.16.dev5.dist-info/METADATA +240 -0
  77. tigrcorn_protocols-0.3.16.dev5.dist-info/RECORD +80 -0
  78. tigrcorn_protocols-0.3.16.dev5.dist-info/WHEEL +5 -0
  79. tigrcorn_protocols-0.3.16.dev5.dist-info/licenses/LICENSE +163 -0
  80. tigrcorn_protocols-0.3.16.dev5.dist-info/top_level.txt +1 -0
@@ -0,0 +1,129 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+
5
+
6
+ HTTP3_REQUEST_PHASE_INITIAL = 'initial'
7
+ HTTP3_REQUEST_PHASE_DATA = 'data'
8
+ HTTP3_REQUEST_PHASE_TRAILERS = 'trailers'
9
+
10
+ HTTP3RequestPhase_INITIAL = HTTP3_REQUEST_PHASE_INITIAL
11
+ HTTP3RequestPhase_DATA = HTTP3_REQUEST_PHASE_DATA
12
+ HTTP3RequestPhase_TRAILERS = HTTP3_REQUEST_PHASE_TRAILERS
13
+
14
+ HTTP3_REQUEST_TRANSITION_TABLE: tuple[dict[str, object], ...] = (
15
+ {'from': 'initial', 'event': 'HEADERS', 'to': 'data', 'notes': 'initial request header section decoded successfully'},
16
+ {'from': 'initial', 'event': 'HEADERS (QPACK blocked)', 'to': 'initial', 'notes': 'blocked section is preserved until encoder instructions arrive'},
17
+ {'from': 'initial', 'event': 'DATA', 'to': 'error', 'notes': 'DATA before initial HEADERS is forbidden'},
18
+ {'from': 'data', 'event': 'DATA', 'to': 'data', 'notes': 'body payload accumulates and content-length accounting advances'},
19
+ {'from': 'data', 'event': 'HEADERS', 'to': 'trailers', 'notes': 'trailing header section closes the data phase'},
20
+ {'from': 'trailers', 'event': 'DATA', 'to': 'error', 'notes': 'DATA after trailers is forbidden'},
21
+ {'from': 'initial|data|trailers', 'event': 'FIN + complete parse + validators satisfied', 'to': 'ready', 'notes': 'request is ready only when fin is seen, initial headers exist, no blocked sections remain, and content-length matches'},
22
+ )
23
+
24
+ HTTP3_CONTROL_STREAM_RULES: tuple[dict[str, object], ...] = (
25
+ {'rule': 'single-control-stream', 'error_code': 'H3_STREAM_CREATION_ERROR', 'notes': 'peer must not open more than one control stream'},
26
+ {'rule': 'control-stream-begins-with-settings', 'error_code': 'H3_MISSING_SETTINGS', 'notes': 'first frame on control stream must be SETTINGS'},
27
+ {'rule': 'duplicate-settings-forbidden', 'error_code': 'H3_FRAME_UNEXPECTED', 'notes': 'second SETTINGS frame is rejected'},
28
+ {'rule': 'control-stream-close-is-fatal', 'error_code': 'H3_CLOSED_CRITICAL_STREAM', 'notes': 'control stream cannot be closed'},
29
+ {'rule': 'request-frames-forbidden-on-control-stream', 'error_code': 'H3_FRAME_UNEXPECTED', 'notes': 'HEADERS, DATA, and PUSH_PROMISE are not valid control-stream frames'},
30
+ {'rule': 'goaway-id-must-not-increase', 'error_code': 'H3_ID_ERROR', 'notes': 'successive GOAWAY identifiers are monotonic non-increasing'},
31
+ {'rule': 'server-goaway-id-must-name-client-bidi-stream', 'error_code': 'H3_ID_ERROR', 'notes': 'server GOAWAY identifier must reference a client-initiated bidirectional stream id'},
32
+ {'rule': 'server-cannot-send-max-push-id', 'error_code': 'H3_FRAME_UNEXPECTED', 'notes': 'MAX_PUSH_ID is only valid from the client'},
33
+ )
34
+
35
+ HTTP3_QPACK_ACCOUNTING_RULES: tuple[dict[str, object], ...] = (
36
+ {'rule': 'blocked-header-sections-are-retained', 'notes': 'request body and partial parse state are preserved until QPACK unblocks'},
37
+ {'rule': 'encoder-stream-errors-map-to-encoder-stream-error', 'notes': 'invalid encoder stream payload is surfaced as QPACK_ENCODER_STREAM_ERROR'},
38
+ {'rule': 'decoder-stream-errors-map-to-decoder-stream-error', 'notes': 'invalid decoder stream payload is surfaced as QPACK_DECODER_STREAM_ERROR'},
39
+ {'rule': 'field-section-errors-map-to-decompression-failed', 'notes': 'bad field sections surface as QPACK_DECOMPRESSION_FAILED'},
40
+ )
41
+
42
+
43
+ def http3_request_transition_table() -> tuple[dict[str, object], ...]:
44
+ return tuple(dict(entry) for entry in HTTP3_REQUEST_TRANSITION_TABLE)
45
+
46
+
47
+ def http3_control_stream_rule_table() -> tuple[dict[str, object], ...]:
48
+ return tuple(dict(entry) for entry in HTTP3_CONTROL_STREAM_RULES)
49
+
50
+
51
+ def http3_qpack_accounting_rule_table() -> tuple[dict[str, object], ...]:
52
+ return tuple(dict(entry) for entry in HTTP3_QPACK_ACCOUNTING_RULES)
53
+
54
+
55
+ @dataclass(slots=True)
56
+ class HTTP3BlockedSection:
57
+ kind: str
58
+ payload: bytes
59
+ push_id: int | None = None
60
+
61
+
62
+ @dataclass(slots=True)
63
+ class HTTP3PushPromiseState:
64
+ push_id: int
65
+ headers: list[tuple[bytes, bytes]]
66
+ request_stream_ids: set[int] = field(default_factory=set)
67
+
68
+
69
+ @dataclass(slots=True)
70
+ class HTTP3RequestState:
71
+ stream_id: int
72
+ headers: list[tuple[bytes, bytes]] = field(default_factory=list)
73
+ informational_headers: list[list[tuple[bytes, bytes]]] = field(default_factory=list)
74
+ trailers: list[tuple[bytes, bytes]] = field(default_factory=list)
75
+ body_parts: list[bytes] = field(default_factory=list)
76
+ ended: bool = False
77
+ parse_buffer: bytearray = field(default_factory=bytearray)
78
+ blocked_header_sections: list[HTTP3BlockedSection] = field(default_factory=list)
79
+ phase: str = HTTP3_REQUEST_PHASE_INITIAL
80
+ received_initial_headers: bool = False
81
+ received_trailers: bool = False
82
+ expected_content_length: int | None = None
83
+ received_content_length: int = 0
84
+ push_promises: dict[int, HTTP3PushPromiseState] = field(default_factory=dict)
85
+ abandoned: bool = False
86
+
87
+ @property
88
+ def body(self) -> bytes:
89
+ return b''.join(self.body_parts)
90
+
91
+ @property
92
+ def ready(self) -> bool:
93
+ return (
94
+ not self.abandoned
95
+ and self.ended
96
+ and self.received_initial_headers
97
+ and not self.blocked_header_sections
98
+ and not self.parse_buffer
99
+ )
100
+
101
+
102
+ @dataclass(slots=True)
103
+ class HTTP3UniStreamState:
104
+ stream_id: int
105
+ stream_type: int | None = None
106
+ parse_buffer: bytearray = field(default_factory=bytearray)
107
+ settings_received: bool = False
108
+ discard_stream: bool = False
109
+ push_id: int | None = None
110
+
111
+
112
+ @dataclass(slots=True)
113
+ class HTTP3ConnectionState:
114
+ local_settings: dict[int, int] = field(default_factory=dict)
115
+ remote_settings: dict[int, int] = field(default_factory=dict)
116
+ goaway_stream_id: int | None = field(default=None)
117
+ local_goaway_id: int | None = None
118
+ peer_goaway_id: int | None = None
119
+ peer_goaway_direction: str | None = None
120
+ control_stream_opened: bool = False
121
+ remote_control_stream_id: int | None = None
122
+ remote_qpack_encoder_stream_id: int | None = None
123
+ remote_qpack_decoder_stream_id: int | None = None
124
+ remote_push_stream_ids: set[int] = field(default_factory=set)
125
+ uni_streams: dict[int, HTTP3UniStreamState] = field(default_factory=dict)
126
+ promised_pushes: dict[int, HTTP3PushPromiseState] = field(default_factory=dict)
127
+ cancelled_push_ids: set[int] = field(default_factory=set)
128
+ local_max_push_id: int | None = None
129
+ peer_max_push_id: int | None = None