rnet 3.0.0rc11__cp314-cp314t-manylinux_2_34_armv7l.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/tls.py ADDED
@@ -0,0 +1,428 @@
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, NotRequired, TypedDict, Unpack, final
12
+
13
+ __all__ = [
14
+ "TlsVersion",
15
+ "Identity",
16
+ "CertStore",
17
+ "KeyLog",
18
+ "AlpnProtocol",
19
+ "AlpsProtocol",
20
+ "CertificateCompressionAlgorithm",
21
+ "ExtensionType",
22
+ "TlsOptions",
23
+ "Params",
24
+ ]
25
+
26
+
27
+ @final
28
+ class TlsVersion(Enum):
29
+ r"""
30
+ The TLS version.
31
+ """
32
+
33
+ TLS_1_0 = auto()
34
+ TLS_1_1 = auto()
35
+ TLS_1_2 = auto()
36
+ TLS_1_3 = auto()
37
+
38
+
39
+ @final
40
+ class AlpnProtocol(Enum):
41
+ """
42
+ A TLS ALPN protocol.
43
+ """
44
+
45
+ HTTP1 = auto()
46
+ HTTP2 = auto()
47
+ HTTP3 = auto()
48
+
49
+
50
+ @final
51
+ class AlpsProtocol(Enum):
52
+ """
53
+ Application-layer protocol settings for HTTP/1.1 and HTTP/2.
54
+ """
55
+
56
+ HTTP1 = auto()
57
+ HTTP2 = auto()
58
+ HTTP3 = auto()
59
+
60
+
61
+ @final
62
+ class CertificateCompressionAlgorithm(Enum):
63
+ """
64
+ IANA assigned identifier of compression algorithm.
65
+ See https://www.rfc-editor.org/rfc/rfc8879.html#name-compression-algorithms
66
+ """
67
+
68
+ ZLIB = auto()
69
+ BROTLI = auto()
70
+ ZSTD = auto()
71
+
72
+
73
+ @final
74
+ class ExtensionType(Enum):
75
+ """
76
+ A TLS extension type.
77
+ """
78
+
79
+ SERVER_NAME = auto()
80
+ STATUS_REQUEST = auto()
81
+ EC_POINT_FORMATS = auto()
82
+ SIGNATURE_ALGORITHMS = auto()
83
+ SRTP = auto()
84
+ APPLICATION_LAYER_PROTOCOL_NEGOTIATION = auto()
85
+ PADDING = auto()
86
+ EXTENDED_MASTER_SECRET = auto()
87
+ QUIC_TRANSPORT_PARAMETERS_LEGACY = auto()
88
+ QUIC_TRANSPORT_PARAMETERS_STANDARD = auto()
89
+ CERT_COMPRESSION = auto()
90
+ SESSION_TICKET = auto()
91
+ SUPPORTED_GROUPS = auto()
92
+ PRE_SHARED_KEY = auto()
93
+ EARLY_DATA = auto()
94
+ SUPPORTED_VERSIONS = auto()
95
+ COOKIE = auto()
96
+ PSK_KEY_EXCHANGE_MODES = auto()
97
+ CERTIFICATE_AUTHORITIES = auto()
98
+ SIGNATURE_ALGORITHMS_CERT = auto()
99
+ KEY_SHARE = auto()
100
+ RENEGOTIATE = auto()
101
+ DELEGATED_CREDENTIAL = auto()
102
+ APPLICATION_SETTINGS = auto()
103
+ APPLICATION_SETTINGS_NEW = auto()
104
+ ENCRYPTED_CLIENT_HELLO = auto()
105
+ CERTIFICATE_TIMESTAMP = auto()
106
+ NEXT_PROTO_NEG = auto()
107
+ CHANNEL_ID = auto()
108
+ RECORD_SIZE_LIMIT = auto()
109
+
110
+
111
+ @final
112
+ class Identity:
113
+ """
114
+ Represents a private key and X509 cert as a client certificate.
115
+ """
116
+
117
+ @staticmethod
118
+ def from_pkcs12_der(buf: bytes, pass_: str) -> "Identity":
119
+ """
120
+ Parses a DER-formatted PKCS #12 archive, using the specified password to decrypt the key.
121
+
122
+ The archive should contain a leaf certificate and its private key, as well any intermediate
123
+ certificates that allow clients to build a chain to a trusted root.
124
+ The chain certificates should be in order from the leaf certificate towards the root.
125
+
126
+ PKCS #12 archives typically have the file extension `.p12` or `.pfx`, and can be created
127
+ with the OpenSSL `pkcs12` tool:
128
+
129
+ openssl pkcs12 -export -out identity.pfx -inkey key.pem -in cert.pem -certfile chain_certs.pem
130
+ """
131
+ ...
132
+
133
+ @staticmethod
134
+ def from_pkcs8_pem(buf: bytes, key: bytes) -> "Identity":
135
+ """
136
+ Parses a chain of PEM encoded X509 certificates, with the leaf certificate first.
137
+ `key` is a PEM encoded PKCS #8 formatted private key for the leaf certificate.
138
+
139
+ The certificate chain should contain any intermediate certificates that should be sent to
140
+ clients to allow them to build a chain to a trusted root.
141
+
142
+ A certificate chain here means a series of PEM encoded certificates concatenated together.
143
+ """
144
+ ...
145
+
146
+
147
+ @final
148
+ class CertStore:
149
+ """
150
+ Represents a certificate store for verifying TLS connections.
151
+ """
152
+
153
+ def __init__(
154
+ self,
155
+ der_certs: List[bytes] | None = None,
156
+ pem_certs: List[str] | None = None,
157
+ default_paths: bool | None = None,
158
+ ) -> None:
159
+ """
160
+ Creates a new CertStore.
161
+
162
+ Args:
163
+ der_certs: Optional list of DER-encoded certificates (as bytes).
164
+ pem_certs: Optional list of PEM-encoded certificates (as str).
165
+ default_paths: If True, use system default certificate paths.
166
+ """
167
+ ...
168
+
169
+ @staticmethod
170
+ def from_der_certs(certs: List[bytes]) -> "CertStore":
171
+ """
172
+ Creates a CertStore from a collection of DER-encoded certificates.
173
+
174
+ Args:
175
+ certs: List of DER-encoded certificates (as bytes).
176
+ """
177
+ ...
178
+
179
+ @staticmethod
180
+ def from_pem_certs(certs: List[str]) -> "CertStore":
181
+ """
182
+ Creates a CertStore from a collection of PEM-encoded certificates.
183
+
184
+ Args:
185
+ certs: List of PEM-encoded certificates (as str).
186
+ """
187
+ ...
188
+
189
+ @staticmethod
190
+ def from_pem_stack(certs: bytes) -> "CertStore":
191
+ """
192
+ Creates a CertStore from a PEM-encoded certificate stack.
193
+
194
+ Args:
195
+ certs: PEM-encoded certificate stack (as bytes).
196
+ """
197
+ ...
198
+
199
+
200
+ @final
201
+ class KeyLog:
202
+ """
203
+ Specifies the intent for a (TLS) keylogger to be used in a client or server configuration.
204
+
205
+ This type allows you to control how TLS session keys are logged for debugging or analysis.
206
+ You can either use the default environment variable (SSLKEYLOGFILE) or specify a file path
207
+ directly. This is useful for tools like Wireshark that can decrypt TLS traffic if provided
208
+ with the correct session keys.
209
+
210
+ Static Methods:
211
+ environment() -> KeyLog
212
+ Use the SSLKEYLOGFILE environment variable for key logging.
213
+ file(path: Path) -> KeyLog
214
+ Log keys to the specified file path.
215
+
216
+ Methods:
217
+ is_environment() -> bool
218
+ Returns True if this policy uses the environment variable.
219
+ is_file() -> bool
220
+ Returns True if this policy logs to a specific file.
221
+ """
222
+
223
+ @staticmethod
224
+ def environment() -> "KeyLog":
225
+ """
226
+ Use the SSLKEYLOGFILE environment variable for key logging.
227
+ """
228
+ ...
229
+
230
+ @staticmethod
231
+ def file(path: Path) -> "KeyLog":
232
+ """
233
+ Log keys to the specified file path.
234
+
235
+ Args:
236
+ path: The file path to log TLS keys to.
237
+ """
238
+ ...
239
+
240
+
241
+ class Params(TypedDict):
242
+ """
243
+ All parameters for TLS connections.
244
+ """
245
+
246
+ alpn_protocols: NotRequired[List[AlpnProtocol]]
247
+ """
248
+ Application-Layer Protocol Negotiation (RFC 7301).
249
+
250
+ Specifies which application protocols (e.g., HTTP/2, HTTP/1.1) may be negotiated
251
+ over a single TLS connection.
252
+ """
253
+
254
+ alps_protocols: NotRequired[List[AlpsProtocol]]
255
+ """
256
+ Application-Layer Protocol Settings (ALPS).
257
+
258
+ Enables exchanging application-layer settings during the handshake
259
+ for protocols negotiated via ALPN.
260
+ """
261
+
262
+ alps_use_new_codepoint: NotRequired[bool]
263
+ """
264
+ Whether to use an alternative ALPS codepoint for compatibility.
265
+
266
+ Useful when larger ALPS payloads are required.
267
+ """
268
+
269
+ session_ticket: NotRequired[bool]
270
+ """
271
+ Enables TLS Session Tickets (RFC 5077).
272
+
273
+ Allows session resumption without requiring server-side state.
274
+ """
275
+
276
+ min_tls_version: NotRequired[TlsVersion]
277
+ """
278
+ Minimum TLS version allowed for the connection.
279
+ """
280
+
281
+ max_tls_version: NotRequired[TlsVersion]
282
+ """
283
+ Maximum TLS version allowed for the connection.
284
+ """
285
+
286
+ pre_shared_key: NotRequired[bool]
287
+ """
288
+ Enables Pre-Shared Key (PSK) cipher suites (RFC 4279).
289
+
290
+ Authentication relies on out-of-band pre-shared keys instead of certificates.
291
+ """
292
+
293
+ enable_ech_grease: NotRequired[bool]
294
+ """
295
+ Controls whether to send a GREASE Encrypted ClientHello (ECH) extension
296
+ when no supported ECH configuration is available.
297
+
298
+ GREASE prevents protocol ossification by sending unknown extensions.
299
+ """
300
+
301
+ permute_extensions: NotRequired[bool]
302
+ """
303
+ Controls whether ClientHello extensions should be permuted.
304
+ """
305
+
306
+ grease_enabled: NotRequired[bool]
307
+ """
308
+ Controls whether GREASE extensions (RFC 8701) are enabled in general.
309
+ """
310
+
311
+ enable_ocsp_stapling: NotRequired[bool]
312
+ """
313
+ Enables OCSP stapling for the connection.
314
+ """
315
+
316
+ enable_signed_cert_timestamps: NotRequired[bool]
317
+ """
318
+ Enables Signed Certificate Timestamps (SCT).
319
+ """
320
+
321
+ record_size_limit: NotRequired[int]
322
+ """
323
+ Sets the maximum TLS record size.
324
+ """
325
+
326
+ psk_skip_session_ticket: NotRequired[bool]
327
+ """
328
+ Whether to skip session tickets when using PSK.
329
+ """
330
+
331
+ key_shares_limit: NotRequired[int]
332
+ """
333
+ Maximum number of key shares to include in ClientHello.
334
+ """
335
+
336
+ psk_dhe_ke: NotRequired[bool]
337
+ """
338
+ Enables PSK with (EC)DHE key establishment (`psk_dhe_ke`).
339
+ """
340
+
341
+ renegotiation: NotRequired[bool]
342
+ """
343
+ Enables TLS renegotiation by sending the `renegotiation_info` extension.
344
+ """
345
+
346
+ delegated_credentials: NotRequired[str]
347
+ """
348
+ Delegated Credentials (RFC 9345).
349
+
350
+ Allows TLS 1.3 endpoints to use temporary delegated credentials
351
+ for authentication with reduced long-term key exposure.
352
+ """
353
+
354
+ curves_list: NotRequired[str]
355
+ """
356
+ List of supported elliptic curves.
357
+ """
358
+
359
+ cipher_list: NotRequired[str]
360
+ """
361
+ Cipher suite configuration string.
362
+
363
+ Uses BoringSSL's mini-language to select, enable, and prioritize ciphers.
364
+ """
365
+
366
+ sigalgs_list: NotRequired[str]
367
+ """
368
+ List of supported signature algorithms.
369
+ """
370
+
371
+ certificate_compression_algorithms: NotRequired[
372
+ List[CertificateCompressionAlgorithm]
373
+ ]
374
+ """
375
+ Supported certificate compression algorithms (RFC 8879).
376
+ """
377
+
378
+ extension_permutation: NotRequired[List[ExtensionType]]
379
+ """
380
+ Supported TLS extensions, used for extension ordering/permutation.
381
+ """
382
+
383
+ aes_hw_override: NotRequired[bool]
384
+ """
385
+ Overrides AES hardware acceleration.
386
+ """
387
+
388
+ preserve_tls13_cipher_list: NotRequired[bool]
389
+ """
390
+ Sets whether to preserve the TLS 1.3 cipher list as configured by cipher_list.
391
+
392
+ By default, BoringSSL does not preserve the TLS 1.3 cipher list. When this option is disabled
393
+ (the default), BoringSSL uses its internal default TLS 1.3 cipher suites in its default order,
394
+ regardless of what is set via cipher_list.
395
+
396
+ When enabled, this option ensures that the TLS 1.3 cipher suites explicitly set via
397
+ cipher_list are retained in their original order, without being reordered or
398
+ modified by BoringSSL's internal logic. This is useful for maintaining specific cipher suite
399
+ priorities for TLS 1.3. Note that if cipher_list does not include any TLS 1.3
400
+ cipher suites, BoringSSL will still fall back to its default TLS 1.3 cipher suites and order.
401
+ """
402
+
403
+ random_aes_hw_override: NotRequired[bool]
404
+ """
405
+ Overrides the random AES hardware acceleration.
406
+ """
407
+
408
+
409
+ @final
410
+ class TlsOptions:
411
+ """
412
+ TLS connection configuration options.
413
+
414
+ This struct provides fine-grained control over the behavior of TLS
415
+ connections, including:
416
+ - **Protocol negotiation** (ALPN, ALPS, TLS versions)
417
+ - **Session management** (tickets, PSK, key shares)
418
+ - **Security & privacy** (OCSP, GREASE, ECH, delegated credentials)
419
+ - **Performance tuning** (record size, cipher preferences, hardware overrides)
420
+
421
+ All fields are optional or have defaults. See each field for details.
422
+ """
423
+
424
+ def __init__(self, **kwargs: Unpack[Params]) -> None:
425
+ """
426
+ Creates a new TlsOptions.
427
+ """
428
+ ...
@@ -0,0 +1,205 @@
1
+ Metadata-Version: 2.4
2
+ Name: rnet
3
+ Version: 3.0.0rc11
4
+ Classifier: Programming Language :: Rust
5
+ Classifier: Programming Language :: Python :: Implementation :: CPython
6
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
7
+ Classifier: Programming Language :: Python :: 3.11
8
+ Classifier: Programming Language :: Python :: 3.12
9
+ Classifier: Programming Language :: Python :: 3.13
10
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
14
+ Classifier: Operating System :: Microsoft :: Windows
15
+ Classifier: Operating System :: POSIX
16
+ Classifier: Operating System :: Unix
17
+ Classifier: Operating System :: MacOS
18
+ License-File: LICENSE
19
+ Summary: An ergonomic Python HTTP client with TLS fingerprint
20
+ Keywords: http,client,websocket,ja3,ja4
21
+ Author-email: 0x676e67 <gngppz@gmail.com>
22
+ License: Apache-2.0
23
+ Requires-Python: >=3.11
24
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
25
+ Project-URL: Documentation, https://github.com/0x676e67/rnet/blob/main/rnet.pyi
26
+ Project-URL: Homepage, https://github.com/0x676e67/rnet
27
+ Project-URL: Repository, https://github.com/0x676e67/rnet
28
+
29
+ # rnet
30
+
31
+ [![CI](https://github.com/0x676e67/rnet/actions/workflows/ci.yml/badge.svg)](https://github.com/0x676e67/rnet/actions/workflows/ci.yml)
32
+ [![PyPI - License](https://img.shields.io/pypi/l/rnet)](https://github.com/0x676e67/rnet/blob/main/LICENSE)
33
+ ![Python Version from PEP 621 TOML](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2F0x676e67%2Frnet%2Fmain%2Fpyproject.toml&logo=python)
34
+ [![PyPI](https://img.shields.io/pypi/v/rnet?logo=python)](https://pypi.org/project/rnet/)
35
+ [![PyPI Downloads](https://static.pepy.tech/badge/rnet)](https://pepy.tech/projects/rnet)
36
+
37
+ > 🚀 Help me work seamlessly with open source sharing by [sponsoring me on GitHub](https://github.com/0x676e67/0x676e67/blob/main/SPONSOR.md)
38
+
39
+ An ergonomic and modular Python HTTP client for advanced and low-level emulation, featuring customizable TLS, JA3/JA4, and HTTP/2 fingerprinting capabilities, powered by [wreq](https://github.com/0x676e67/wreq).
40
+
41
+ ## Features
42
+
43
+ - Async and Blocking `Client`s
44
+ - Plain bodies, JSON, urlencoded, multipart
45
+ - Cookie Store
46
+ - Redirect Policy
47
+ - Original Headers
48
+ - Rotating Proxies
49
+ - Connection Pooling
50
+ - Streaming Transfers
51
+ - Zero-Copy Transfers
52
+ - WebSocket Upgrade
53
+ - HTTPS via BoringSSL
54
+ - Free-Threaded Safety
55
+ - Automatic Decompression
56
+
57
+ ## Example
58
+
59
+ The following example uses the `asyncio` runtime with `rnet` installed via pip:
60
+
61
+ ```bash
62
+ pip install asyncio rnet==3.0.0rc11
63
+ ```
64
+
65
+ And then the code:
66
+
67
+ ```python
68
+ import asyncio
69
+ from rnet import Client, Emulation
70
+
71
+
72
+ async def main():
73
+ # Build a client
74
+ client = Client(emulation=Emulation.Safari26)
75
+
76
+ # Use the API you're already familiar with
77
+ resp = await client.get("https://tls.peet.ws/api/all")
78
+
79
+ # Print the response
80
+ print(await resp.text())
81
+
82
+
83
+ if __name__ == "__main__":
84
+ asyncio.run(main())
85
+
86
+ ```
87
+
88
+ Additional learning resources include:
89
+
90
+ - [DeepWiki](https://deepwiki.com/0x676e67/rnet)
91
+ - [API Documentation](https://github.com/0x676e67/rnet/blob/main/python/rnet)
92
+ - [Repository Tests](https://github.com/0x676e67/rnet/tree/main/tests)
93
+ - [Synchronous Examples](https://github.com/0x676e67/rnet/tree/main/python/examples/blocking)
94
+ - [Asynchronous Examples](https://github.com/0x676e67/rnet/tree/main/python/examples)
95
+
96
+ ## Behavior
97
+
98
+ 1. **HTTP/2 over TLS**
99
+
100
+ Due to the complexity of TLS encryption and the widespread adoption of HTTP/2, browser fingerprints such as **JA3**, **JA4**, and **Akamai** cannot be reliably emulated using simple fingerprint strings. Instead of parsing and emulating these string-based fingerprints, `rnet` provides fine-grained control over TLS and HTTP/2 extensions and settings for precise browser behavior emulation.
101
+
102
+ 2. **Device Emulation**
103
+
104
+ Most browser device models share identical TLS and HTTP/2 configurations, differing only in the `User-Agent` string.
105
+
106
+ - <details>
107
+ <summary>Available OS emulations</summary>
108
+
109
+ | **OS** | **Description** |
110
+ | ----------- | ------------------------------ |
111
+ | **Windows** | Windows (any version) |
112
+ | **MacOS** | macOS (any version) |
113
+ | **Linux** | Linux (any distribution) |
114
+ | **Android** | Android (mobile) |
115
+ | **iOS** | iOS (iPhone/iPad) |
116
+
117
+ </details>
118
+ - <details>
119
+ <summary>Available browser emulations</summary>
120
+
121
+ | **Browser** | **Versions** |
122
+ | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
123
+ | **Chrome** | `Chrome100`, `Chrome101`, `Chrome104`, `Chrome105`, `Chrome106`, `Chrome107`, `Chrome108`, `Chrome109`, `Chrome110`, `Chrome114`, `Chrome116`, `Chrome117`, `Chrome118`, `Chrome119`, `Chrome120`, `Chrome123`, `Chrome124`, `Chrome126`, `Chrome127`, `Chrome128`, `Chrome129`, `Chrome130`, `Chrome131`, `Chrome132`, `Chrome133`, `Chrome134`, `Chrome135`, `Chrome136`, `Chrome137`, `Chrome138`, `Chrome139`, `Chrome140`, `Chrome141`, `Chrome142` |
124
+ | **Safari** | `SafariIos17_2`, `SafariIos17_4_1`, `SafariIos16_5`, `Safari15_3`, `Safari15_5`, `Safari15_6_1`, `Safari16`, `Safari16_5`, `Safari17_0`, `Safari17_2_1`, `Safari17_4_1`, `Safari17_5`, `Safari18`, `SafariIPad18`, `Safari18_2`, `SafariIos18_1_1`, `Safari18_3`, `Safari18_3_1`, `Safari18_5`, `Safari26`, `SafariIos26`, `SafariIPad26` |
125
+ | **Firefox** | `Firefox109`, `Firefox117`, `Firefox128`, `Firefox133`, `Firefox135`, `FirefoxPrivate135`, `FirefoxAndroid135`, `Firefox136`, `FirefoxPrivate136`, `Firefox139`, `Firefox142`, `Firefox143` |
126
+ | **OkHttp** | `OkHttp3_9`, `OkHttp3_11`, `OkHttp3_13`, `OkHttp3_14`, `OkHttp4_9`, `OkHttp4_10`, `OkHttp4_12`, `OkHttp5` |
127
+ | **Edge** | `Edge101`, `Edge122`, `Edge127`, `Edge131`, `Edge134` |
128
+ | **Opera** | `Opera116`, `Opera117`, `Opera118`, `Opera119` |
129
+
130
+ </details>
131
+
132
+ ## Building
133
+
134
+ 1. Platforms
135
+
136
+ - Linux(**glibc**/**musl**): `x86_64`, `aarch64`, `armv7`, `i686`
137
+ - macOS: `x86_64`,`aarch64`
138
+ - Windows: `x86_64`,`i686`,`aarch64`
139
+ - Android: `aarch64`, `x86_64`
140
+
141
+ 2. Manylinux
142
+
143
+ Install the BoringSSL build environment by referring to [boring](https://github.com/cloudflare/boring/blob/master/.github/workflows/ci.yml) and [boringssl](https://github.com/google/boringssl/blob/master/BUILDING.md#build-prerequisites).
144
+
145
+ ```bash
146
+ # on ubuntu or debian
147
+ sudo apt install -y build-essential cmake perl pkg-config libclang-dev musl-tools git
148
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
149
+ pip install uv maturin
150
+
151
+ uv venv
152
+ source .venv/bin/activate
153
+
154
+ # Development
155
+ maturin develop --uv
156
+
157
+ # Build wheels
158
+ maturin build --release
159
+ ```
160
+
161
+ 3. Musllinux
162
+
163
+ Make sure you have Docker installed. The provided image may be outdated, so you might need to build it yourself. See [rust-cross-musl](https://github.com/0x676e67/toolchain/blob/master/rust-musl-cross/Dockerfile) and the upstream [rust-cross/rust-musl-cross](https://github.com/rust-cross/rust-musl-cross) for reference.
164
+
165
+ ```bash
166
+ bash .github/musl_build.sh i686-unknown-linux-musl
167
+ bash .github/musl_build.sh x86_64-unknown-linux-musl
168
+ bash .github/musl_build.sh aarch64-unknown-linux-musl
169
+ bash .github/musl_build.sh armv7-unknown-linux-musleabihf
170
+ ```
171
+
172
+ ## Benchmark
173
+
174
+ Outperforms `requests`, `httpx`, `Python-TLS-Client`, and `curl_cffi`. See the [benchmark](https://github.com/0x676e67/rnet/tree/main/python/benchmark) for details. Benchmark data is for reference only—actual performance may vary based on your environment and use case.
175
+
176
+ ## Services
177
+
178
+ Help sustain the ongoing development of this open-source project by reaching out for [commercial support](mailto:gngppz@gmail.com). Receive private guidance, expert reviews, or direct access to the maintainer, with personalized technical assistance tailored to your needs.
179
+
180
+ ## License
181
+
182
+ Licensed under either of Apache License, Version 2.0 ([LICENSE](./LICENSE) or http://www.apache.org/licenses/LICENSE-2.0).
183
+
184
+ ## Contribution
185
+
186
+ Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the [Apache-2.0](./LICENSE) license, shall be licensed as above, without any additional terms or conditions.
187
+
188
+ ## Sponsors
189
+
190
+ <a href="https://hypersolutions.co/?utm_source=github&utm_medium=readme&utm_campaign=rnet" target="_blank"><img src="https://raw.githubusercontent.com/0x676e67/rnet/main/.github/assets/hypersolutions.jpg" height="47" width="149"></a>
191
+
192
+ TLS fingerprinting alone isn't enough for modern bot protection. **[Hyper Solutions](https://hypersolutions.co?utm_source=github&utm_medium=readme&utm_campaign=rnet)** provides the missing piece - API endpoints that generate valid antibot tokens for:
193
+
194
+ **Akamai** • **DataDome** • **Kasada** • **Incapsula**
195
+
196
+ No browser automation. Just simple API calls that return the exact cookies and headers these systems require.
197
+
198
+ 🚀 **[Get Your API Key](https://hypersolutions.co?utm_source=github&utm_medium=readme&utm_campaign=rnet)** | 📖 **[Docs](https://docs.justhyped.dev)** | 💬 **[Discord](https://discord.gg/akamai)**
199
+
200
+ ---
201
+
202
+ <a href="https://dashboard.capsolver.com/passport/register?inviteCode=y7CtB_a-3X6d" target="_blank"><img src="https://raw.githubusercontent.com/0x676e67/rnet/main/.github/assets/capsolver.jpg" height="47" width="149"></a>
203
+
204
+ [CapSolver](https://www.capsolver.com/?utm_source=github&utm_medium=banner_repo&utm_campaign=rnet) leverages AI-powered Auto Web Unblock to bypass Captchas effortlessly, providing fast, reliable, and cost-effective data access with seamless integration into Colly, Puppeteer, and Playwright—use code **`RNET`** for a 6% bonus!
205
+
@@ -0,0 +1,17 @@
1
+ rnet-3.0.0rc11.dist-info/METADATA,sha256=bw2a_bJYfPbnUEVRCZ1Q8xrKvWgyxcIPR1YGKfGJFHI,11641
2
+ rnet-3.0.0rc11.dist-info/WHEEL,sha256=obeb5SYskmeOLywlTYFkZk1pDINUGa1hD4FxEDURyIg,109
3
+ rnet-3.0.0rc11.dist-info/licenses/LICENSE,sha256=ld2UNRYADDwfLyJ9Q34VP3bWRfS53mvK1tixHd57kN0,11357
4
+ rnet/__init__.py,sha256=WGkIeJdp402itYDq9uUXGA5UKHnRXYGPqsahE1FoTGQ,438
5
+ rnet/__init__.pyi,sha256=yXO-fcqw8HNuJGtph85YBmNbqf8UGY6EGNF5Uo6H_lI,33947
6
+ rnet/blocking.py,sha256=W2tTSUH1y8MVNKnFY1Zdran36hMT8Qj9rosWVyGIgBE,8747
7
+ rnet/cookie.py,sha256=ngIcyM162h96f5XYDO35vcPg0W0GyyvRIh_gfdF-qEQ,3037
8
+ rnet/dns.py,sha256=iIlsAQpiSPZQSbsdB2TU8w3zr5SJ9fSlfoqJCVQeiOE,2270
9
+ rnet/emulation.py,sha256=SpAEH-u2tHVRByU1PIifqCNyiJ7PYwmQ-JAoh8YTeUQ,5316
10
+ rnet/exceptions.py,sha256=Rpwo1GVE2eJhFVAGJWAlsY4XypZ-i0j9Th-pnm7l_yY,5951
11
+ rnet/header.py,sha256=K_bp5F_4D21UjMaBp7aM-aGVYI162IsX-vn2fjExEF4,9749
12
+ rnet/http1.py,sha256=AoUepwDFa0Wzeqooej49ofaycamvpEjUN4MgJGMpkMo,1511
13
+ rnet/http2.py,sha256=NDq_7zHADpS0VfpKkGlPVdeQiqgBIFSFxp6bNkIWH9Y,9197
14
+ rnet/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ rnet/rnet.cpython-314t-arm-linux-gnueabihf.so,sha256=rhnKoJM8gDg0LfOseO-3BAI5GSaBHg6wGB75I7E9yPI,7314368
16
+ rnet/tls.py,sha256=jcVvzt4W1cjDc2nBEVnpuxXLGWL4Hp6W9MoFPIpuQ0Y,11635
17
+ rnet-3.0.0rc11.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: maturin (1.9.6)
3
+ Root-Is-Purelib: false
4
+ Tag: cp314-cp314t-manylinux_2_34_armv7l