rnet 3.0.0rc1__cp311-abi3-musllinux_1_2_aarch64.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/__init__.py +19 -0
- rnet/__init__.pyi +1174 -0
- rnet/blocking.py +511 -0
- rnet/cookie.py +130 -0
- rnet/emulation.py +185 -0
- rnet/exceptions.py +214 -0
- rnet/header.py +431 -0
- rnet/py.typed +0 -0
- rnet/rnet.abi3.so +0 -0
- rnet/tls.py +161 -0
- rnet-3.0.0rc1.dist-info/METADATA +188 -0
- rnet-3.0.0rc1.dist-info/RECORD +15 -0
- rnet-3.0.0rc1.dist-info/WHEEL +4 -0
- rnet-3.0.0rc1.dist-info/licenses/LICENSE +674 -0
- rnet.libs/libgcc_s-3aecca4c.so.1 +0 -0
rnet/header.py
ADDED
|
@@ -0,0 +1,431 @@
|
|
|
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 List, Optional, Tuple
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class HeaderMap:
|
|
18
|
+
r"""
|
|
19
|
+
A case-insensitive HTTP header map supporting multiple values per header.
|
|
20
|
+
|
|
21
|
+
This class provides efficient storage and retrieval of HTTP headers,
|
|
22
|
+
automatically handling case-insensitive header names and supporting
|
|
23
|
+
headers with multiple values (such as Set-Cookie or Accept-Encoding).
|
|
24
|
+
|
|
25
|
+
The implementation follows HTTP/1.1 specifications for header handling
|
|
26
|
+
and provides both dictionary-like access and specialized methods for
|
|
27
|
+
HTTP header manipulation.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __getitem__(self, key: str) -> Optional[bytes]:
|
|
31
|
+
"""Get the first value for a header name (case-insensitive)."""
|
|
32
|
+
...
|
|
33
|
+
|
|
34
|
+
def __setitem__(self, key: str, value: str) -> None:
|
|
35
|
+
"""Set a header to a single value, replacing any existing values."""
|
|
36
|
+
...
|
|
37
|
+
|
|
38
|
+
def __delitem__(self, key: str) -> None:
|
|
39
|
+
"""Remove all values for a header name."""
|
|
40
|
+
...
|
|
41
|
+
|
|
42
|
+
def __contains__(self, key: str) -> bool:
|
|
43
|
+
"""Check if a header name exists (case-insensitive)."""
|
|
44
|
+
...
|
|
45
|
+
|
|
46
|
+
def __len__(self) -> int:
|
|
47
|
+
"""Return the total number of header values (not unique names)."""
|
|
48
|
+
...
|
|
49
|
+
|
|
50
|
+
def __iter__(self) -> "HeaderMapKeysIter":
|
|
51
|
+
"""Iterate over unique header names."""
|
|
52
|
+
...
|
|
53
|
+
|
|
54
|
+
def __str__(self) -> str:
|
|
55
|
+
"""Return a string representation of all headers."""
|
|
56
|
+
...
|
|
57
|
+
|
|
58
|
+
def __new__(
|
|
59
|
+
cls, init: Optional[dict] = None, capacity: Optional[int] = None
|
|
60
|
+
) -> "HeaderMap":
|
|
61
|
+
"""
|
|
62
|
+
Create a new HeaderMap.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
init: Optional dictionary to initialize headers from
|
|
66
|
+
capacity: Optional initial capacity hint for performance
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
A new HeaderMap instance
|
|
70
|
+
|
|
71
|
+
Example:
|
|
72
|
+
```python
|
|
73
|
+
# Empty header map
|
|
74
|
+
headers = HeaderMap()
|
|
75
|
+
|
|
76
|
+
# Initialize from dictionary
|
|
77
|
+
headers = HeaderMap({
|
|
78
|
+
'Content-Type': 'text/html',
|
|
79
|
+
'Cache-Control': 'no-cache'
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
# Pre-allocate capacity for performance
|
|
83
|
+
headers = HeaderMap(capacity=50)
|
|
84
|
+
```
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
def contains_key(self, key: str) -> bool:
|
|
88
|
+
r"""
|
|
89
|
+
Check if the header map contains the given key.
|
|
90
|
+
|
|
91
|
+
This is equivalent to using the 'in' operator but provides
|
|
92
|
+
an explicit method name. Header name comparison is case-insensitive.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
key: The header name to check
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
True if the header exists, False otherwise
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
def insert(self, key: str, value: str) -> None:
|
|
102
|
+
r"""
|
|
103
|
+
Insert a header, replacing any existing values.
|
|
104
|
+
|
|
105
|
+
This method replaces all existing values for the given header name
|
|
106
|
+
with the new value. For adding additional values, use append() instead.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
key: The header name (case-insensitive)
|
|
110
|
+
value: The header value to set
|
|
111
|
+
|
|
112
|
+
Example:
|
|
113
|
+
```python
|
|
114
|
+
headers.insert('Content-Type', 'application/json')
|
|
115
|
+
# Replaces any existing Content-Type header
|
|
116
|
+
```
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
def append(self, key: str, value: str) -> None:
|
|
120
|
+
r"""
|
|
121
|
+
Append a value to an existing header or create a new one.
|
|
122
|
+
|
|
123
|
+
If the header already exists, this adds an additional value.
|
|
124
|
+
If the header doesn't exist, it creates a new header with this value.
|
|
125
|
+
This is useful for headers that can have multiple values.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
key: The header name (case-insensitive)
|
|
129
|
+
value: The header value to append
|
|
130
|
+
|
|
131
|
+
Example:
|
|
132
|
+
```python
|
|
133
|
+
headers.append('Accept-Encoding', 'gzip')
|
|
134
|
+
headers.append('Accept-Encoding', 'deflate')
|
|
135
|
+
# Results in: Accept-Encoding: gzip, deflate
|
|
136
|
+
```
|
|
137
|
+
"""
|
|
138
|
+
|
|
139
|
+
def remove(self, key: str) -> None:
|
|
140
|
+
r"""
|
|
141
|
+
Remove all values for a header name.
|
|
142
|
+
|
|
143
|
+
This removes the header entirely from the map. If the header
|
|
144
|
+
doesn't exist, this method does nothing.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
key: The header name to remove (case-insensitive)
|
|
148
|
+
"""
|
|
149
|
+
|
|
150
|
+
def get(self, key: str, default: Optional[bytes] = None) -> Optional[bytes]:
|
|
151
|
+
r"""
|
|
152
|
+
Get the first value for a header name with optional default.
|
|
153
|
+
|
|
154
|
+
Returns the first value associated with the header name, or the
|
|
155
|
+
default value if the header doesn't exist. For headers with multiple
|
|
156
|
+
values, use get_all() to retrieve all values.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
key: The header name (case-insensitive)
|
|
160
|
+
default: Value to return if header doesn't exist
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
The first header value as bytes, or the default value
|
|
164
|
+
|
|
165
|
+
Example:
|
|
166
|
+
```python
|
|
167
|
+
content_type = headers.get('Content-Type', b'text/plain')
|
|
168
|
+
auth = headers.get('Authorization') # Returns None if missing
|
|
169
|
+
```
|
|
170
|
+
"""
|
|
171
|
+
|
|
172
|
+
def get_all(self, key: str) -> "HeaderMapValuesIter":
|
|
173
|
+
r"""
|
|
174
|
+
Get all values for a header name.
|
|
175
|
+
|
|
176
|
+
Returns an iterator over all values associated with the header name.
|
|
177
|
+
This is useful for headers that can have multiple values, such as
|
|
178
|
+
Set-Cookie, Accept-Encoding, or custom headers.
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
key: The header name (case-insensitive)
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
An iterator over all header values
|
|
185
|
+
|
|
186
|
+
Example:
|
|
187
|
+
```python
|
|
188
|
+
# Get all Set-Cookie headers
|
|
189
|
+
cookies = list(headers.get_all('Set-Cookie'))
|
|
190
|
+
|
|
191
|
+
# Process multiple Accept-Encoding values
|
|
192
|
+
for encoding in headers.get_all('Accept-Encoding'):
|
|
193
|
+
print(f"Accepts: {encoding.decode()}")
|
|
194
|
+
```
|
|
195
|
+
"""
|
|
196
|
+
|
|
197
|
+
def len(self) -> int:
|
|
198
|
+
"""
|
|
199
|
+
Get the total number of header values.
|
|
200
|
+
|
|
201
|
+
This returns the total count of header values, which can be greater
|
|
202
|
+
than the number of unique header names if some headers have multiple
|
|
203
|
+
values.
|
|
204
|
+
|
|
205
|
+
Returns:
|
|
206
|
+
Total number of header values stored
|
|
207
|
+
"""
|
|
208
|
+
|
|
209
|
+
def keys_len(self) -> int:
|
|
210
|
+
"""
|
|
211
|
+
Get the number of unique header names.
|
|
212
|
+
|
|
213
|
+
This returns the count of unique header names, regardless of how
|
|
214
|
+
many values each header has.
|
|
215
|
+
|
|
216
|
+
Returns:
|
|
217
|
+
Number of unique header names
|
|
218
|
+
"""
|
|
219
|
+
|
|
220
|
+
def is_empty(self) -> bool:
|
|
221
|
+
"""
|
|
222
|
+
Check if the header map is empty.
|
|
223
|
+
|
|
224
|
+
Returns:
|
|
225
|
+
True if no headers are stored, False otherwise
|
|
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
|
+
def items(self) -> "HeaderMapItemsIter":
|
|
237
|
+
r"""
|
|
238
|
+
Get an iterator over all header name-value pairs.
|
|
239
|
+
|
|
240
|
+
Returns an iterator that yields tuples of (name, value) for each
|
|
241
|
+
header value. Headers with multiple values will appear multiple
|
|
242
|
+
times with different values.
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
Iterator over (name, value) tuples
|
|
246
|
+
|
|
247
|
+
Example:
|
|
248
|
+
```python
|
|
249
|
+
for name, value in headers.items():
|
|
250
|
+
print(f"{name.decode()}: {value.decode()}")
|
|
251
|
+
```
|
|
252
|
+
"""
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
class OrigHeaderMap:
|
|
256
|
+
"""
|
|
257
|
+
A map from header names to their original casing as received in an HTTP message.
|
|
258
|
+
|
|
259
|
+
OrigHeaderMap not only preserves the original case of each header name as it appeared
|
|
260
|
+
in the HTTP message, but also maintains the insertion order of headers. This makes
|
|
261
|
+
it suitable for use cases where the order of headers matters, such as HTTP/1.x message
|
|
262
|
+
serialization, proxying, or reproducing requests/responses exactly as received.
|
|
263
|
+
|
|
264
|
+
The map stores a mapping between the case-insensitive (standard) header name and the
|
|
265
|
+
original case-sensitive header name as it appeared in the HTTP message.
|
|
266
|
+
|
|
267
|
+
Example:
|
|
268
|
+
If an HTTP message included the following headers:
|
|
269
|
+
|
|
270
|
+
x-Bread: Baguette
|
|
271
|
+
X-BREAD: Pain
|
|
272
|
+
x-bread: Ficelle
|
|
273
|
+
|
|
274
|
+
Then the OrigHeaderMap would preserve both the exact casing and order of these headers:
|
|
275
|
+
- Standard name "x-bread" maps to original "x-Bread"
|
|
276
|
+
- Standard name "x-bread" maps to original "X-BREAD"
|
|
277
|
+
- Standard name "x-bread" maps to original "x-bread"
|
|
278
|
+
|
|
279
|
+
This allows the client to reproduce the exact header casing when forwarding or
|
|
280
|
+
reconstructing the HTTP message.
|
|
281
|
+
"""
|
|
282
|
+
|
|
283
|
+
def __init__(
|
|
284
|
+
self,
|
|
285
|
+
init: Optional[List[str]] = None,
|
|
286
|
+
capacity: Optional[int] = None,
|
|
287
|
+
) -> None:
|
|
288
|
+
"""
|
|
289
|
+
Creates a new OrigHeaderMap from an optional list of header names.
|
|
290
|
+
|
|
291
|
+
Args:
|
|
292
|
+
init: Optional list of header names to initialize with.
|
|
293
|
+
capacity: Optional initial capacity for the map.
|
|
294
|
+
"""
|
|
295
|
+
...
|
|
296
|
+
|
|
297
|
+
def insert(self, value: str) -> bool:
|
|
298
|
+
"""
|
|
299
|
+
Insert a new header name into the collection.
|
|
300
|
+
|
|
301
|
+
If the map did not previously have this key present, then False is returned.
|
|
302
|
+
If the map did have this key present, the new value is pushed to the end
|
|
303
|
+
of the list of values currently associated with the key. The key is not
|
|
304
|
+
updated, though; this matters for types that can be == without being identical.
|
|
305
|
+
|
|
306
|
+
Args:
|
|
307
|
+
value: The header name to insert.
|
|
308
|
+
|
|
309
|
+
Returns:
|
|
310
|
+
True if the key was newly inserted, False if it already existed.
|
|
311
|
+
"""
|
|
312
|
+
...
|
|
313
|
+
|
|
314
|
+
def extend(self, other: "OrigHeaderMap") -> None:
|
|
315
|
+
"""
|
|
316
|
+
Extends the map with all entries from another OrigHeaderMap, preserving order.
|
|
317
|
+
|
|
318
|
+
Args:
|
|
319
|
+
other: Another OrigHeaderMap to extend from.
|
|
320
|
+
"""
|
|
321
|
+
...
|
|
322
|
+
|
|
323
|
+
def items(self) -> "OrigHeaderMapIter":
|
|
324
|
+
"""
|
|
325
|
+
Returns an iterator over the (standard_name, original_name) pairs.
|
|
326
|
+
|
|
327
|
+
Returns:
|
|
328
|
+
An iterator over header name pairs.
|
|
329
|
+
"""
|
|
330
|
+
...
|
|
331
|
+
|
|
332
|
+
def __len__(self) -> int:
|
|
333
|
+
"""
|
|
334
|
+
Returns the number of header names stored in the map.
|
|
335
|
+
"""
|
|
336
|
+
...
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
class HeaderMapItemsIter:
|
|
340
|
+
r"""
|
|
341
|
+
Iterator over header name-value pairs in a HeaderMap.
|
|
342
|
+
|
|
343
|
+
Yields tuples of (header_name, header_value) where both are bytes.
|
|
344
|
+
Headers with multiple values will appear as separate tuples.
|
|
345
|
+
"""
|
|
346
|
+
|
|
347
|
+
def __iter__(self) -> "HeaderMapItemsIter":
|
|
348
|
+
"""Return self as iterator."""
|
|
349
|
+
...
|
|
350
|
+
|
|
351
|
+
def __next__(self) -> Optional[Tuple[bytes, bytes]]:
|
|
352
|
+
"""
|
|
353
|
+
Get the next header name-value pair.
|
|
354
|
+
|
|
355
|
+
Returns:
|
|
356
|
+
Tuple of (header_name, header_value) or None when exhausted
|
|
357
|
+
"""
|
|
358
|
+
...
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
class HeaderMapKeysIter:
|
|
362
|
+
r"""
|
|
363
|
+
Iterator over unique header names in a HeaderMap.
|
|
364
|
+
|
|
365
|
+
Yields each unique header name as bytes, regardless of how many
|
|
366
|
+
values each header has.
|
|
367
|
+
"""
|
|
368
|
+
|
|
369
|
+
def __iter__(self) -> "HeaderMapKeysIter":
|
|
370
|
+
"""Return self as iterator."""
|
|
371
|
+
...
|
|
372
|
+
|
|
373
|
+
def __next__(self) -> Optional[bytes]:
|
|
374
|
+
"""
|
|
375
|
+
Get the next unique header name.
|
|
376
|
+
|
|
377
|
+
Returns:
|
|
378
|
+
Header name as bytes, or None when exhausted
|
|
379
|
+
"""
|
|
380
|
+
...
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
class HeaderMapValuesIter:
|
|
384
|
+
r"""
|
|
385
|
+
Iterator over header values in a HeaderMap.
|
|
386
|
+
|
|
387
|
+
Yields header values as bytes. When used with get_all(), yields
|
|
388
|
+
all values for a specific header name. When used independently,
|
|
389
|
+
yields all values in the entire map.
|
|
390
|
+
"""
|
|
391
|
+
|
|
392
|
+
def __iter__(self) -> "HeaderMapValuesIter":
|
|
393
|
+
"""Return self as iterator."""
|
|
394
|
+
...
|
|
395
|
+
|
|
396
|
+
def __next__(self) -> Optional[bytes]:
|
|
397
|
+
"""
|
|
398
|
+
Get the next header value.
|
|
399
|
+
|
|
400
|
+
Returns:
|
|
401
|
+
Header value as bytes, or None when exhausted
|
|
402
|
+
"""
|
|
403
|
+
...
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
class OrigHeaderMapIter:
|
|
407
|
+
"""
|
|
408
|
+
An iterator over the items in an OrigHeaderMap.
|
|
409
|
+
|
|
410
|
+
Yields tuples of (standard_header_name, original_header_name) where:
|
|
411
|
+
- standard_header_name is the normalized header name
|
|
412
|
+
- original_header_name is the header name as originally received/specified
|
|
413
|
+
"""
|
|
414
|
+
|
|
415
|
+
def __iter__(self) -> "OrigHeaderMapIter":
|
|
416
|
+
"""
|
|
417
|
+
Returns the iterator itself.
|
|
418
|
+
"""
|
|
419
|
+
...
|
|
420
|
+
|
|
421
|
+
def __next__(self) -> Tuple[bytes, bytes]:
|
|
422
|
+
"""
|
|
423
|
+
Returns the next (standard_name, original_name) pair.
|
|
424
|
+
|
|
425
|
+
Returns:
|
|
426
|
+
A tuple of (standard_header_name, original_header_name) as bytes.
|
|
427
|
+
|
|
428
|
+
Raises:
|
|
429
|
+
StopIteration: When there are no more items.
|
|
430
|
+
"""
|
|
431
|
+
...
|
rnet/py.typed
ADDED
|
File without changes
|
rnet/rnet.abi3.so
ADDED
|
Binary file
|
rnet/tls.py
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TLS Utilities and Types
|
|
3
|
+
|
|
4
|
+
This module provides types and utilities for configuring TLS (Transport Layer Security) in HTTP clients.
|
|
5
|
+
|
|
6
|
+
These types are typically used to configure client-side TLS authentication and certificate verification in HTTP requests.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from enum import Enum, auto
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import List, Optional
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class TlsVersion(Enum):
|
|
15
|
+
r"""
|
|
16
|
+
The TLS version.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
TLS_1_0 = auto()
|
|
20
|
+
TLS_1_1 = auto()
|
|
21
|
+
TLS_1_2 = auto()
|
|
22
|
+
TLS_1_3 = auto()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class Identity:
|
|
26
|
+
"""
|
|
27
|
+
Represents a private key and X509 cert as a client certificate.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
@staticmethod
|
|
31
|
+
def from_pkcs12_der(buf: bytes, pass_: str) -> "Identity":
|
|
32
|
+
"""
|
|
33
|
+
Parses a DER-formatted PKCS #12 archive, using the specified password to decrypt the key.
|
|
34
|
+
|
|
35
|
+
The archive should contain a leaf certificate and its private key, as well any intermediate
|
|
36
|
+
certificates that allow clients to build a chain to a trusted root.
|
|
37
|
+
The chain certificates should be in order from the leaf certificate towards the root.
|
|
38
|
+
|
|
39
|
+
PKCS #12 archives typically have the file extension `.p12` or `.pfx`, and can be created
|
|
40
|
+
with the OpenSSL `pkcs12` tool:
|
|
41
|
+
|
|
42
|
+
openssl pkcs12 -export -out identity.pfx -inkey key.pem -in cert.pem -certfile chain_certs.pem
|
|
43
|
+
"""
|
|
44
|
+
...
|
|
45
|
+
|
|
46
|
+
@staticmethod
|
|
47
|
+
def from_pkcs8_pem(buf: bytes, key: bytes) -> "CertStore":
|
|
48
|
+
"""
|
|
49
|
+
Parses a chain of PEM encoded X509 certificates, with the leaf certificate first.
|
|
50
|
+
`key` is a PEM encoded PKCS #8 formatted private key for the leaf certificate.
|
|
51
|
+
|
|
52
|
+
The certificate chain should contain any intermediate certificates that should be sent to
|
|
53
|
+
clients to allow them to build a chain to a trusted root.
|
|
54
|
+
|
|
55
|
+
A certificate chain here means a series of PEM encoded certificates concatenated together.
|
|
56
|
+
"""
|
|
57
|
+
...
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class CertStore:
|
|
61
|
+
"""
|
|
62
|
+
Represents a certificate store for verifying TLS connections.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
def __new__(
|
|
66
|
+
cls,
|
|
67
|
+
der_certs: Optional[List[bytes]] = None,
|
|
68
|
+
pem_certs: Optional[List[str]] = None,
|
|
69
|
+
default_paths: Optional[bool] = None,
|
|
70
|
+
) -> "CertStore":
|
|
71
|
+
"""
|
|
72
|
+
Creates a new CertStore.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
der_certs: Optional list of DER-encoded certificates (as bytes).
|
|
76
|
+
pem_certs: Optional list of PEM-encoded certificates (as str).
|
|
77
|
+
default_paths: If True, use system default certificate paths.
|
|
78
|
+
"""
|
|
79
|
+
...
|
|
80
|
+
|
|
81
|
+
@staticmethod
|
|
82
|
+
def from_der_certs(certs: List[bytes]) -> "CertStore":
|
|
83
|
+
"""
|
|
84
|
+
Creates a CertStore from a collection of DER-encoded certificates.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
certs: List of DER-encoded certificates (as bytes).
|
|
88
|
+
"""
|
|
89
|
+
...
|
|
90
|
+
|
|
91
|
+
@staticmethod
|
|
92
|
+
def from_pem_certs(certs: List[str]) -> "CertStore":
|
|
93
|
+
"""
|
|
94
|
+
Creates a CertStore from a collection of PEM-encoded certificates.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
certs: List of PEM-encoded certificates (as str).
|
|
98
|
+
"""
|
|
99
|
+
...
|
|
100
|
+
|
|
101
|
+
@staticmethod
|
|
102
|
+
def from_pem_stack(certs: bytes) -> "CertStore":
|
|
103
|
+
"""
|
|
104
|
+
Creates a CertStore from a PEM-encoded certificate stack.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
certs: PEM-encoded certificate stack (as bytes).
|
|
108
|
+
"""
|
|
109
|
+
...
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class KeyLogPolicy:
|
|
113
|
+
"""
|
|
114
|
+
Specifies the intent for a (TLS) keylogger to be used in a client or server configuration.
|
|
115
|
+
|
|
116
|
+
This type allows you to control how TLS session keys are logged for debugging or analysis.
|
|
117
|
+
You can either use the default environment variable (SSLKEYLOGFILE) or specify a file path
|
|
118
|
+
directly. This is useful for tools like Wireshark that can decrypt TLS traffic if provided
|
|
119
|
+
with the correct session keys.
|
|
120
|
+
|
|
121
|
+
Static Methods:
|
|
122
|
+
environment() -> KeyLogPolicy
|
|
123
|
+
Use the SSLKEYLOGFILE environment variable for key logging.
|
|
124
|
+
file(path: Path) -> KeyLogPolicy
|
|
125
|
+
Log keys to the specified file path.
|
|
126
|
+
|
|
127
|
+
Methods:
|
|
128
|
+
is_environment() -> bool
|
|
129
|
+
Returns True if this policy uses the environment variable.
|
|
130
|
+
is_file() -> bool
|
|
131
|
+
Returns True if this policy logs to a specific file.
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
@staticmethod
|
|
135
|
+
def environment() -> "KeyLogPolicy":
|
|
136
|
+
"""
|
|
137
|
+
Use the SSLKEYLOGFILE environment variable for key logging.
|
|
138
|
+
"""
|
|
139
|
+
...
|
|
140
|
+
|
|
141
|
+
@staticmethod
|
|
142
|
+
def file(path: Path) -> "KeyLogPolicy":
|
|
143
|
+
"""
|
|
144
|
+
Log keys to the specified file path.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
path: The file path to log TLS keys to.
|
|
148
|
+
"""
|
|
149
|
+
...
|
|
150
|
+
|
|
151
|
+
def is_environment(self) -> bool:
|
|
152
|
+
"""
|
|
153
|
+
Returns True if this policy uses the environment variable.
|
|
154
|
+
"""
|
|
155
|
+
...
|
|
156
|
+
|
|
157
|
+
def is_file(self) -> bool:
|
|
158
|
+
"""
|
|
159
|
+
Returns True if this policy logs to a specific file.
|
|
160
|
+
"""
|
|
161
|
+
...
|