rnet 2.4.2__cp313-cp313t-win_amd64.whl → 3.0.0rc10__cp313-cp313t-win_amd64.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.

Potentially problematic release.


This version of rnet might be problematic. Click here for more details.

rnet/header.py CHANGED
@@ -1 +1,319 @@
1
- # type: ignore
1
+ """
2
+ HTTP Header Management
3
+
4
+ This module provides efficient storage and manipulation of HTTP headers with
5
+ support for multiple values per header name. The HeaderMap class is designed
6
+ to handle the complexities of HTTP header processing, including case-insensitive
7
+ header names and multiple header values.
8
+
9
+ The implementation follows HTTP specifications (RFC 7230) for header handling,
10
+ including proper support for headers that can have multiple values (like
11
+ Set-Cookie, Accept-Encoding, etc.).
12
+ """
13
+
14
+ from typing import Dict, Iterator, List, Optional, Tuple
15
+
16
+ __all__ = ["HeaderMap", "OrigHeaderMap"]
17
+
18
+
19
+ class HeaderMap:
20
+ r"""
21
+ A case-insensitive HTTP header map supporting multiple values per header.
22
+
23
+ This class provides efficient storage and retrieval of HTTP headers,
24
+ automatically handling case-insensitive header names and supporting
25
+ headers with multiple values (such as Set-Cookie or Accept-Encoding).
26
+
27
+ The implementation follows HTTP/1.1 specifications for header handling
28
+ and provides both dictionary-like access and specialized methods for
29
+ HTTP header manipulation.
30
+ """
31
+
32
+ def __getitem__(self, key: str) -> Optional[bytes]:
33
+ """Get the first value for a header name (case-insensitive)."""
34
+ ...
35
+
36
+ def __setitem__(self, key: str, value: str) -> None:
37
+ """Set a header to a single value, replacing any existing values."""
38
+ ...
39
+
40
+ def __delitem__(self, key: str) -> None:
41
+ """Remove all values for a header name."""
42
+ ...
43
+
44
+ def __contains__(self, key: str) -> bool:
45
+ """Check if a header name exists (case-insensitive)."""
46
+ ...
47
+
48
+ def __len__(self) -> int:
49
+ """Return the total number of header values (not unique names)."""
50
+ ...
51
+
52
+ def __iter__(self) -> Iterator[Tuple[bytes, bytes]]:
53
+ """Iterate all header(name, value) pairs, including duplicates for multiple values."""
54
+ ...
55
+
56
+ def __str__(self) -> str:
57
+ """Return a string representation of all headers."""
58
+ ...
59
+
60
+ def __init__(
61
+ self, init: Dict[str, str] | None = None, capacity: int | None = None
62
+ ) -> None:
63
+ """
64
+ Create a new HeaderMap.
65
+
66
+ Args:
67
+ init: Optional dictionary to initialize headers from
68
+ capacity: Optional initial capacity hint for performance
69
+
70
+ Returns:
71
+ A new HeaderMap instance
72
+
73
+ Example:
74
+ ```python
75
+ # Empty header map
76
+ headers = HeaderMap()
77
+
78
+ # Initialize from dictionary
79
+ headers = HeaderMap({
80
+ 'Content-Type': 'text/html',
81
+ 'Cache-Control': 'no-cache'
82
+ })
83
+
84
+ # Pre-allocate capacity for performance
85
+ headers = HeaderMap(capacity=50)
86
+ ```
87
+ """
88
+
89
+ def contains_key(self, key: str) -> bool:
90
+ r"""
91
+ Check if the header map contains the given key.
92
+
93
+ This is equivalent to using the 'in' operator but provides
94
+ an explicit method name. Header name comparison is case-insensitive.
95
+
96
+ Args:
97
+ key: The header name to check
98
+
99
+ Returns:
100
+ True if the header exists, False otherwise
101
+ """
102
+ ...
103
+
104
+ def insert(self, key: str, value: str) -> None:
105
+ r"""
106
+ Insert a header, replacing any existing values.
107
+
108
+ This method replaces all existing values for the given header name
109
+ with the new value. For adding additional values, use append() instead.
110
+
111
+ Args:
112
+ key: The header name (case-insensitive)
113
+ value: The header value to set
114
+ """
115
+ ...
116
+
117
+ def append(self, key: str, value: str) -> None:
118
+ r"""
119
+ Append a value to an existing header or create a new one.
120
+
121
+ If the header already exists, this adds an additional value.
122
+ If the header doesn't exist, it creates a new header with this value.
123
+ This is useful for headers that can have multiple values.
124
+
125
+ Args:
126
+ key: The header name (case-insensitive)
127
+ value: The header value to append
128
+ """
129
+ ...
130
+
131
+ def remove(self, key: str) -> None:
132
+ r"""
133
+ Remove all values for a header name.
134
+
135
+ This removes the header entirely from the map. If the header
136
+ doesn't exist, this method does nothing.
137
+
138
+ Args:
139
+ key: The header name to remove (case-insensitive)
140
+ """
141
+ ...
142
+
143
+ def get(self, key: str, default: Optional[bytes] = None) -> Optional[bytes]:
144
+ r"""
145
+ Get the first value for a header name with optional default.
146
+
147
+ Returns the first value associated with the header name, or the
148
+ default value if the header doesn't exist. For headers with multiple
149
+ values, use get_all() to retrieve all values.
150
+
151
+ Args:
152
+ key: The header name (case-insensitive)
153
+ default: Value to return if header doesn't exist
154
+
155
+ Returns:
156
+ The first header value as bytes, or the default value
157
+ """
158
+ ...
159
+
160
+ def get_all(self, key: str) -> Iterator[bytes]:
161
+ r"""
162
+ Get all values for a header name.
163
+
164
+ Returns an iterator over all values associated with the header name.
165
+ This is useful for headers that can have multiple values, such as
166
+ Set-Cookie, Accept-Encoding, or custom headers.
167
+
168
+ Args:
169
+ key: The header name (case-insensitive)
170
+
171
+ Returns:
172
+ An iterator over all header values
173
+ """
174
+ ...
175
+
176
+ def values(self) -> Iterator[bytes]:
177
+ """
178
+ Iterate over all header values.
179
+
180
+ Returns:
181
+ An iterator over all header values as bytes.
182
+ """
183
+ ...
184
+
185
+ def keys(self) -> Iterator[bytes]:
186
+ """
187
+ Iterate over unique header names.
188
+
189
+ Returns:
190
+ An iterator over unique header names as bytes.
191
+ """
192
+ ...
193
+
194
+ def len(self) -> int:
195
+ """
196
+ Get the total number of header values.
197
+
198
+ This returns the total count of header values, which can be greater
199
+ than the number of unique header names if some headers have multiple
200
+ values.
201
+
202
+ Returns:
203
+ Total number of header values stored
204
+ """
205
+ ...
206
+
207
+ def keys_len(self) -> int:
208
+ """
209
+ Get the number of unique header names.
210
+
211
+ This returns the count of unique header names, regardless of how
212
+ many values each header has.
213
+
214
+ Returns:
215
+ Number of unique header names
216
+ """
217
+ ...
218
+
219
+ def is_empty(self) -> bool:
220
+ """
221
+ Check if the header map is empty.
222
+
223
+ Returns:
224
+ True if no headers are stored, False otherwise
225
+ """
226
+ ...
227
+
228
+ def clear(self) -> None:
229
+ """
230
+ Remove all headers from the map.
231
+
232
+ After calling this method, the header map will be empty and
233
+ is_empty() will return True.
234
+ """
235
+ ...
236
+
237
+
238
+ class OrigHeaderMap:
239
+ """
240
+ A map from header names to their original casing as received in an HTTP message.
241
+
242
+ OrigHeaderMap not only preserves the original case of each header name as it appeared
243
+ in the HTTP message, but also maintains the insertion order of headers. This makes
244
+ it suitable for use cases where the order of headers matters, such as HTTP/1.x message
245
+ serialization, proxying, or reproducing requests/responses exactly as received.
246
+
247
+ The map stores a mapping between the case-insensitive (standard) header name and the
248
+ original case-sensitive header name as it appeared in the HTTP message.
249
+
250
+ Example:
251
+ If an HTTP message included the following headers:
252
+
253
+ x-Bread: Baguette
254
+ X-BREAD: Pain
255
+ x-bread: Ficelle
256
+
257
+ Then the OrigHeaderMap would preserve both the exact casing and order of these headers:
258
+ - Standard name "x-bread" maps to original "x-Bread"
259
+ - Standard name "x-bread" maps to original "X-BREAD"
260
+ - Standard name "x-bread" maps to original "x-bread"
261
+
262
+ This allows the client to reproduce the exact header casing when forwarding or
263
+ reconstructing the HTTP message.
264
+ """
265
+
266
+ def __init__(
267
+ self,
268
+ init: Optional[List[str]] = None,
269
+ capacity: Optional[int] = None,
270
+ ) -> None:
271
+ """
272
+ Creates a new OrigHeaderMap from an optional list of header names.
273
+
274
+ Args:
275
+ init: Optional list of header names to initialize with.
276
+ capacity: Optional initial capacity for the map.
277
+ """
278
+ ...
279
+
280
+ def __iter__(self) -> Iterator[Tuple[bytes, bytes]]:
281
+ """
282
+ Returns an iterator over the (standard_name, original_name) pairs.
283
+
284
+ Returns:
285
+ An iterator over header name pairs.
286
+ """
287
+ ...
288
+
289
+ def __len__(self) -> int:
290
+ """
291
+ Returns the number of header names stored in the map.
292
+ """
293
+ ...
294
+
295
+ def insert(self, value: str) -> bool:
296
+ """
297
+ Insert a new header name into the collection.
298
+
299
+ If the map did not previously have this key present, then False is returned.
300
+ If the map did have this key present, the new value is pushed to the end
301
+ of the list of values currently associated with the key. The key is not
302
+ updated, though; this matters for types that can be == without being identical.
303
+
304
+ Args:
305
+ value: The header name to insert.
306
+
307
+ Returns:
308
+ True if the key was newly inserted, False if it already existed.
309
+ """
310
+ ...
311
+
312
+ def extend(self, other: "OrigHeaderMap") -> None:
313
+ """
314
+ Extends the map with all entries from another OrigHeaderMap, preserving order.
315
+
316
+ Args:
317
+ other: Another OrigHeaderMap to extend from.
318
+ """
319
+ ...
rnet/http1.py ADDED
@@ -0,0 +1,68 @@
1
+ """
2
+ HTTP/1 connection configuration.
3
+ """
4
+
5
+ from typing import TypedDict, Unpack, NotRequired, final
6
+
7
+ __all__ = ["Http1Options", "Params"]
8
+
9
+
10
+ class Params(TypedDict):
11
+ """
12
+ All parameters for HTTP/1 connections.
13
+ """
14
+
15
+ http09_responses: NotRequired[bool]
16
+ """
17
+ Enable support for HTTP/0.9 responses.
18
+ """
19
+
20
+ writev: NotRequired[bool]
21
+ """
22
+ Whether to use vectored writes for HTTP/1 connections.
23
+ """
24
+
25
+ max_headers: NotRequired[int]
26
+ """
27
+ Maximum number of headers allowed in HTTP/1 responses.
28
+ """
29
+
30
+ read_buf_exact_size: NotRequired[int]
31
+ """
32
+ Exact size of the read buffer to use.
33
+ """
34
+
35
+ max_buf_size: NotRequired[int]
36
+ """
37
+ Maximum buffer size for HTTP/1 connections.
38
+ """
39
+
40
+ allow_spaces_after_header_name_in_responses: NotRequired[bool]
41
+ """
42
+ Allow spaces after header names.
43
+ """
44
+
45
+ ignore_invalid_headers_in_responses: NotRequired[bool]
46
+ """
47
+ Ignore invalid headers in responses.
48
+ """
49
+
50
+ allow_obsolete_multiline_headers_in_responses: NotRequired[bool]
51
+ """
52
+ Allow obsolete multiline headers.
53
+ """
54
+
55
+
56
+ @final
57
+ class Http1Options:
58
+ """
59
+ HTTP/1 protocol options for customizing connection behavior.
60
+ These options allow you to customize the behavior of HTTP/1 connections,
61
+ such as enabling support for HTTP/0.9 responses, header case preservation, etc.
62
+ """
63
+
64
+ def __init__(self, **kwargs: Unpack[Params]) -> None:
65
+ """
66
+ Crate a new Http1Options instance.
67
+ """
68
+ ...