wreq-rb 0.4.0 → 0.5.1

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 (150) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +1922 -397
  3. data/LICENSE +203 -0
  4. data/README.md +47 -16
  5. data/exe/wreq +211 -0
  6. data/ext/wreq_rb/Cargo.toml +4 -6
  7. data/ext/wreq_rb/src/client.rs +145 -41
  8. data/lib/wreq-rb/version.rb +1 -1
  9. data/patches/0001-add-transfer-size-tracking.patch +76 -67
  10. data/vendor/wreq/Cargo.toml +119 -71
  11. data/vendor/wreq/README.md +25 -20
  12. data/vendor/wreq/bench/http1.rs +25 -0
  13. data/vendor/wreq/bench/http1_over_tls.rs +25 -0
  14. data/vendor/wreq/bench/http2.rs +25 -0
  15. data/vendor/wreq/bench/http2_over_tls.rs +25 -0
  16. data/vendor/wreq/bench/support/bench.rs +91 -0
  17. data/vendor/wreq/bench/support/client.rs +217 -0
  18. data/vendor/wreq/bench/support/server.rs +188 -0
  19. data/vendor/wreq/bench/support.rs +56 -0
  20. data/vendor/wreq/examples/cert_store.rs +4 -4
  21. data/vendor/wreq/examples/{emulation.rs → emulate.rs} +2 -2
  22. data/vendor/wreq/examples/http2_websocket.rs +2 -2
  23. data/vendor/wreq/examples/keylog.rs +3 -3
  24. data/vendor/wreq/examples/{request_with_emulation.rs → request_with_emulate.rs} +2 -2
  25. data/vendor/wreq/examples/rt.rs +23 -0
  26. data/vendor/wreq/src/client/body.rs +23 -61
  27. data/vendor/wreq/src/client/emulate.rs +119 -0
  28. data/vendor/wreq/src/client/{http/future.rs → future.rs} +11 -32
  29. data/vendor/wreq/src/client/{http → layer}/client/pool.rs +66 -61
  30. data/vendor/wreq/src/client/{http → layer}/client.rs +416 -270
  31. data/vendor/wreq/src/client/layer/config.rs +27 -6
  32. data/vendor/wreq/src/client/layer/decoder.rs +9 -4
  33. data/vendor/wreq/src/client/layer/redirect/future.rs +6 -3
  34. data/vendor/wreq/src/client/layer/redirect.rs +4 -5
  35. data/vendor/wreq/src/client/layer/retry.rs +8 -5
  36. data/vendor/wreq/src/client/layer/timeout/body.rs +15 -6
  37. data/vendor/wreq/src/client/layer/timeout/future.rs +23 -18
  38. data/vendor/wreq/src/client/layer/timeout.rs +24 -74
  39. data/vendor/wreq/src/client/layer.rs +1 -2
  40. data/vendor/wreq/src/client/multipart.rs +137 -154
  41. data/vendor/wreq/src/client/request.rs +202 -118
  42. data/vendor/wreq/src/client/response.rs +46 -45
  43. data/vendor/wreq/src/client/upgrade.rs +15 -0
  44. data/vendor/wreq/src/client/ws.rs +73 -25
  45. data/vendor/wreq/src/client.rs +1655 -17
  46. data/vendor/wreq/src/config.rs +11 -11
  47. data/vendor/wreq/src/{client/conn → conn}/connector.rs +139 -137
  48. data/vendor/wreq/src/conn/descriptor.rs +143 -0
  49. data/vendor/wreq/src/conn/http.rs +484 -0
  50. data/vendor/wreq/src/conn/net/io.rs +75 -0
  51. data/vendor/wreq/src/conn/net/tcp/compio.rs +71 -0
  52. data/vendor/wreq/src/conn/net/tcp/tokio.rs +57 -0
  53. data/vendor/wreq/src/conn/net/tcp.rs +561 -0
  54. data/vendor/wreq/src/conn/net/uds/compio.rs +60 -0
  55. data/vendor/wreq/src/{client/conn/uds.rs → conn/net/uds/tokio.rs} +18 -12
  56. data/vendor/wreq/src/conn/net/uds.rs +11 -0
  57. data/vendor/wreq/src/conn/net.rs +130 -0
  58. data/vendor/wreq/src/{client/conn → conn}/proxy/socks.rs +2 -9
  59. data/vendor/wreq/src/{client/conn → conn}/proxy/tunnel.rs +21 -56
  60. data/vendor/wreq/src/conn/tls_info.rs +47 -0
  61. data/vendor/wreq/src/{client/conn.rs → conn.rs} +202 -54
  62. data/vendor/wreq/src/cookie.rs +302 -142
  63. data/vendor/wreq/src/dns/gai/compio.rs +77 -0
  64. data/vendor/wreq/src/dns/gai/tokio.rs +90 -0
  65. data/vendor/wreq/src/dns/gai.rs +14 -164
  66. data/vendor/wreq/src/dns/hickory.rs +16 -23
  67. data/vendor/wreq/src/dns/resolve.rs +7 -41
  68. data/vendor/wreq/src/dns.rs +90 -7
  69. data/vendor/wreq/src/error.rs +57 -31
  70. data/vendor/wreq/src/ext.rs +25 -0
  71. data/vendor/wreq/src/group.rs +211 -0
  72. data/vendor/wreq/src/header.rs +100 -112
  73. data/vendor/wreq/src/lib.rs +124 -73
  74. data/vendor/wreq/src/proxy.rs +6 -20
  75. data/vendor/wreq/src/redirect.rs +1 -1
  76. data/vendor/wreq/src/rt.rs +208 -0
  77. data/vendor/wreq/src/sync.rs +97 -98
  78. data/vendor/wreq/src/tls/compress.rs +124 -0
  79. data/vendor/wreq/src/tls/conn/ext.rs +54 -45
  80. data/vendor/wreq/src/tls/conn/service.rs +14 -18
  81. data/vendor/wreq/src/tls/conn.rs +169 -241
  82. data/vendor/wreq/src/tls/keylog.rs +68 -5
  83. data/vendor/wreq/src/tls/session.rs +205 -0
  84. data/vendor/wreq/src/tls/{x509 → trust}/identity.rs +4 -21
  85. data/vendor/wreq/src/tls/{x509/parser.rs → trust/parse.rs} +1 -1
  86. data/vendor/wreq/src/tls/{x509 → trust}/store.rs +42 -81
  87. data/vendor/wreq/src/tls/{x509.rs → trust.rs} +8 -2
  88. data/vendor/wreq/src/tls.rs +489 -25
  89. data/vendor/wreq/src/trace.rs +0 -12
  90. data/vendor/wreq/src/util.rs +1 -1
  91. data/vendor/wreq/tests/badssl.rs +10 -10
  92. data/vendor/wreq/tests/client.rs +3 -9
  93. data/vendor/wreq/tests/cookie.rs +6 -8
  94. data/vendor/wreq/tests/{emulation.rs → emulate.rs} +130 -22
  95. data/vendor/wreq/tests/multipart.rs +43 -1
  96. data/vendor/wreq/tests/proxy.rs +1 -1
  97. data/vendor/wreq/tests/support/layer.rs +1 -0
  98. metadata +53 -72
  99. data/vendor/wreq/src/client/conn/conn.rs +0 -231
  100. data/vendor/wreq/src/client/conn/http.rs +0 -1023
  101. data/vendor/wreq/src/client/conn/tls_info.rs +0 -98
  102. data/vendor/wreq/src/client/core/body/incoming.rs +0 -485
  103. data/vendor/wreq/src/client/core/body/length.rs +0 -118
  104. data/vendor/wreq/src/client/core/body.rs +0 -34
  105. data/vendor/wreq/src/client/core/common/buf.rs +0 -149
  106. data/vendor/wreq/src/client/core/common/rewind.rs +0 -141
  107. data/vendor/wreq/src/client/core/common/watch.rs +0 -76
  108. data/vendor/wreq/src/client/core/common.rs +0 -3
  109. data/vendor/wreq/src/client/core/conn/http1.rs +0 -342
  110. data/vendor/wreq/src/client/core/conn/http2.rs +0 -307
  111. data/vendor/wreq/src/client/core/conn.rs +0 -11
  112. data/vendor/wreq/src/client/core/dispatch.rs +0 -299
  113. data/vendor/wreq/src/client/core/error.rs +0 -435
  114. data/vendor/wreq/src/client/core/ext.rs +0 -201
  115. data/vendor/wreq/src/client/core/http1.rs +0 -178
  116. data/vendor/wreq/src/client/core/http2.rs +0 -483
  117. data/vendor/wreq/src/client/core/proto/h1/conn.rs +0 -988
  118. data/vendor/wreq/src/client/core/proto/h1/decode.rs +0 -1170
  119. data/vendor/wreq/src/client/core/proto/h1/dispatch.rs +0 -684
  120. data/vendor/wreq/src/client/core/proto/h1/encode.rs +0 -580
  121. data/vendor/wreq/src/client/core/proto/h1/io.rs +0 -879
  122. data/vendor/wreq/src/client/core/proto/h1/role.rs +0 -694
  123. data/vendor/wreq/src/client/core/proto/h1.rs +0 -104
  124. data/vendor/wreq/src/client/core/proto/h2/client.rs +0 -650
  125. data/vendor/wreq/src/client/core/proto/h2/ping.rs +0 -539
  126. data/vendor/wreq/src/client/core/proto/h2.rs +0 -379
  127. data/vendor/wreq/src/client/core/proto/headers.rs +0 -138
  128. data/vendor/wreq/src/client/core/proto.rs +0 -58
  129. data/vendor/wreq/src/client/core/rt/bounds.rs +0 -57
  130. data/vendor/wreq/src/client/core/rt/timer.rs +0 -150
  131. data/vendor/wreq/src/client/core/rt/tokio.rs +0 -99
  132. data/vendor/wreq/src/client/core/rt.rs +0 -25
  133. data/vendor/wreq/src/client/core/upgrade.rs +0 -267
  134. data/vendor/wreq/src/client/core.rs +0 -16
  135. data/vendor/wreq/src/client/emulation.rs +0 -161
  136. data/vendor/wreq/src/client/http/client/error.rs +0 -142
  137. data/vendor/wreq/src/client/http/client/exec.rs +0 -29
  138. data/vendor/wreq/src/client/http/client/extra.rs +0 -77
  139. data/vendor/wreq/src/client/http/client/util.rs +0 -104
  140. data/vendor/wreq/src/client/http.rs +0 -1629
  141. data/vendor/wreq/src/client/layer/config/options.rs +0 -156
  142. data/vendor/wreq/src/client/layer/cookie.rs +0 -161
  143. data/vendor/wreq/src/hash.rs +0 -143
  144. data/vendor/wreq/src/tls/conn/cache.rs +0 -123
  145. data/vendor/wreq/src/tls/conn/cert_compression.rs +0 -125
  146. data/vendor/wreq/src/tls/keylog/handle.rs +0 -64
  147. data/vendor/wreq/src/tls/options.rs +0 -464
  148. /data/vendor/wreq/src/client/{http → layer}/client/lazy.rs +0 -0
  149. /data/vendor/wreq/src/{client/conn → conn}/proxy.rs +0 -0
  150. /data/vendor/wreq/src/{client/conn → conn}/verbose.rs +0 -0
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "wreq"
3
- version = "6.0.0-rc.28"
3
+ version = "6.0.0-rc.29"
4
4
  description = "An ergonomic Rust HTTP Client with TLS fingerprint"
5
5
  keywords = ["http", "client", "websocket", "ja3", "ja4"]
6
6
  categories = ["web-programming::http-client"]
@@ -19,7 +19,13 @@ rustdoc-args = ["--cfg", "docsrs"]
19
19
  targets = ["x86_64-unknown-linux-gnu"]
20
20
 
21
21
  [features]
22
- default = ["webpki-roots"]
22
+ default = ["webpki-roots", "tokio-rt"]
23
+
24
+ # Enable tokio as the async runtime (default).
25
+ tokio-rt = ["tokio/rt", "tokio/net", "tokio/fs", "wreq-rt/tokio-rt"]
26
+
27
+ # Enable compio as the async runtime (completion-based, io_uring/IOCP).
28
+ compio-rt = ["dep:compio", "compio?/runtime", "compio?/net", "wreq-rt/compio-rt"]
23
29
 
24
30
  # Enable support for decoding text.
25
31
  charset = ["dep:encoding_rs", "dep:mime"]
@@ -27,41 +33,41 @@ charset = ["dep:encoding_rs", "dep:mime"]
27
33
  # Enable cookies store support.
28
34
  cookies = ["dep:cookie"]
29
35
 
30
- # Enable gzip compression support.
31
- gzip = ["tower-http/decompression-gzip"]
36
+ # Enable gzip decompression support.
37
+ gzip = ["dep:tower-http", "tower-http?/decompression-gzip"]
32
38
 
33
- # Enable Brotli compression support.
34
- brotli = ["tower-http/decompression-br"]
39
+ # Enable brotli decompression support.
40
+ brotli = ["dep:tower-http", "tower-http?/decompression-br"]
35
41
 
36
- # Enable Zstandard compression support.
37
- zstd = ["tower-http/decompression-zstd"]
42
+ # Enable zstd decompression support.
43
+ zstd = ["dep:tower-http", "tower-http?/decompression-zstd"]
38
44
 
39
- # Enable deflate compression support.
40
- deflate = ["tower-http/decompression-deflate"]
45
+ # Enable deflate decompression support.
46
+ deflate = ["dep:tower-http", "tower-http?/decompression-deflate"]
41
47
 
42
48
  # Enable URL query string serialization support.
43
- query = ["dep:serde", "dep:serde_urlencoded"]
49
+ query = ["dep:serde", "dep:serde_html_form"]
44
50
 
45
51
  # Enable x-www-form-urlencoded form support.
46
- form = ["dep:serde", "dep:serde_urlencoded"]
52
+ form = ["dep:serde", "dep:serde_html_form"]
47
53
 
48
54
  # Enable JSON support.
49
55
  json = ["dep:serde", "dep:serde_json"]
50
56
 
51
57
  # Enable multipart/form-data support.
52
- multipart = ["dep:mime_guess", "dep:sync_wrapper"]
58
+ multipart = ["dep:mime_guess", "dep:sync_wrapper", "sync_wrapper?/futures"]
53
59
 
54
60
  # Enable hickory DNS resolver.
55
61
  hickory-dns = ["dep:hickory-resolver"]
56
62
 
57
63
  # Enable streaming support.
58
- stream = ["tokio/fs", "dep:tokio-util", "dep:sync_wrapper"]
64
+ stream = ["dep:tokio-util", "dep:sync_wrapper", "sync_wrapper?/futures"]
59
65
 
60
- # Enable SOCKS proxy support.
66
+ # Enable SOCKS/4/5 proxy support.
61
67
  socks = ["dep:tokio-socks"]
62
68
 
63
69
  # Enable WebSocket support.
64
- ws = ["dep:tokio-tungstenite"]
70
+ ws = ["dep:tokio-tungstenite", "tokio-tungstenite?/handshake"]
65
71
 
66
72
  # Enable webpki-roots for TLS certificate validation.
67
73
  webpki-roots = ["dep:webpki-root-certs"]
@@ -70,52 +76,48 @@ webpki-roots = ["dep:webpki-root-certs"]
70
76
  system-proxy = ["dep:system-configuration", "dep:windows-registry"]
71
77
 
72
78
  # Enable tracing logging.
73
- tracing = ["http2/tracing", "dep:tracing"]
79
+ tracing = ["dep:tracing", "wreq-proto/tracing"]
74
80
 
75
- # Symbol prefixing for BoringSSL's libcrypto and libssl to avoid linker conflicts
76
- # when other OpenSSL/BoringSSL versions are present in the same process space.
77
- prefix-symbols = ["boring2/prefix-symbols"]
81
+ # Enables the `parking_lot` crate for synchronization primitives.
82
+ parking_lot = ["dep:parking_lot", "http2/parking_lot"]
83
+
84
+ # Prefix BoringSSL symbols in libcrypto/libssl to avoid linker conflicts
85
+ # when multiple OpenSSL versions coexist in the same process.
86
+ prefix-symbols = ["btls/prefix-symbols"]
78
87
 
79
88
  [dependencies]
80
- percent-encoding = "2.3.2"
81
89
  url = "2.5.8"
82
- bytes = "1.10.1"
83
- http = "1.3.1"
84
- http2 = { version = "0.5.11", features = ["unstable", "parking_lot"] }
90
+ bytes = "1.11.1"
91
+ http = "1.4.0"
92
+ http2 = "0.5.17"
85
93
  httparse = "1.10.1"
86
94
  http-body = "1.0.1"
87
95
  http-body-util = "0.1.3"
88
- futures-channel = "0.3.31"
89
- futures-util = { version = "0.3.31", default-features = false }
90
- pin-project-lite = "0.2.16"
91
- smallvec = { version = "1.15.1", features = ["const_generics", "const_new"] }
92
- want = "0.3.1"
93
- socket2 = { version = "0.6.1", features = ["all"] }
94
- ipnet = "2.11.0"
95
- schnellru = { version = "0.2.4", default-features = false }
96
- ahash = { version = "0.8.12", default-features = false }
97
- boring2 = "5.0.0-alpha.12"
98
- tokio-boring2 = { version = "5.0.0-alpha.12", features = ["read_uninit"]}
99
- brotli = "8.0.2"
100
- flate2 = "1.1.2"
101
- zstd = "0.13.3"
96
+ percent-encoding = "2.3.2"
97
+ pin-project-lite = "0.2.17"
98
+ futures-util = { version = "0.3.32", default-features = false }
99
+ socket2 = { version = "0.6.3", features = ["all"] }
100
+ ipnet = "2.12.0"
101
+ lru = "0.18.0"
102
+ btls = "0.5.6"
103
+ btls-sys = "0.5.6"
104
+ tokio-btls = "0.5.6"
105
+ tokio = { version = "1.52.3", default-features = false }
106
+ compio = { version = "0.19.0-rc.1", features = ["io", "io-compat"], optional = true }
107
+ wreq-rt = { version = "0.2.2-rc.2", default-features = false }
108
+ wreq-proto = { version = "0.2.3", default-features = false }
102
109
  tower = { version = "0.5.3", default-features = false, features = [
103
110
  "timeout",
104
111
  "util",
105
112
  "retry",
106
113
  ] }
107
- tokio = { version = "1.48.0", default-features = false, features = [
108
- "net",
109
- "time",
110
- "rt",
111
- ] }
112
114
 
113
115
  # Optional deps...
114
116
 
115
117
  ## serde
116
118
  serde = { version = "1.0", optional = true }
117
119
  serde_json = { version = "1.0", optional = true }
118
- serde_urlencoded = { version = "0.7.1", optional = true }
120
+ serde_html_form = { version = "0.4.0", optional = true }
119
121
 
120
122
  ## multipart
121
123
  mime_guess = { version = "2.0", default-features = false, optional = true }
@@ -125,10 +127,10 @@ encoding_rs = { version = "0.8", optional = true }
125
127
  mime = { version = "0.3.17", optional = true }
126
128
 
127
129
  ## sync wrapper
128
- sync_wrapper = { version = "1.0.2", features = ["futures"], optional = true }
130
+ sync_wrapper = { version = "1.0.2", optional = true }
129
131
 
130
132
  ## webpki root certs
131
- webpki-root-certs = { version = "1.0.2", optional = true }
133
+ webpki-root-certs = { version = "1.0.7", optional = true }
132
134
 
133
135
  ## cookies
134
136
  cookie = { version = "0.18", optional = true }
@@ -136,44 +138,49 @@ cookie = { version = "0.18", optional = true }
136
138
  ## tower http
137
139
  tower-http = { version = "0.6.8", default-features = false, optional = true }
138
140
 
139
- ## tokio util
140
- tokio-util = { version = "0.7.17", default-features = false, optional = true }
141
-
142
- ## socks
141
+ ## tokio socks
143
142
  tokio-socks = { version = "0.5.2", optional = true }
144
143
 
145
- ## websocket
146
- tokio-tungstenite = { version = "0.28.0", default-features = false, features = [
147
- "handshake",
148
- ], optional = true }
144
+ ## tokio websocket
145
+ tokio-tungstenite = { version = "0.29.0", default-features = false, optional = true }
146
+
147
+ ## tokio util
148
+ tokio-util = { version = "0.7.18", default-features = false, optional = true }
149
149
 
150
150
  ## hickory-dns
151
- hickory-resolver = { version = "0.25.2", optional = true }
151
+ hickory-resolver = { version = "0.26.0", optional = true }
152
+
153
+ ## parking_lot
154
+ parking_lot = { version = "0.12.5", optional = true }
152
155
 
153
156
  ## tracing
154
- tracing = { version = "0.1", default-features = false, features = [
155
- "std",
156
- ], optional = true }
157
+ tracing = { version = "0.1", default-features = false, optional = true }
157
158
 
158
- ## windows system proxy
159
+ ## windows
159
160
  [target.'cfg(windows)'.dependencies]
160
161
  windows-registry = { version = "0.6.0", optional = true }
161
162
 
162
- ## macOS system proxy
163
+ ## macOS
163
164
  [target.'cfg(target_os = "macos")'.dependencies]
164
165
  system-configuration = { version = "0.7.0", optional = true }
165
166
 
166
167
  ## interface binding
167
168
  [target.'cfg(unix)'.dependencies]
168
- libc = "0.2.173"
169
+ libc = "0.2.186"
169
170
 
170
171
  [dev-dependencies]
172
+ wreq-rt = { version = "0.2.2-rc.1", features = ["tokio-rt", "compio-rt"] }
173
+ tokio = { version = "1.0", default-features = false, features = [
174
+ "macros",
175
+ "rt-multi-thread",
176
+ ] }
177
+ compio = { version = "0.19.0-rc.1", features = ["macros", "net", "runtime", "time", "io", "io-compat"] }
171
178
  hyper = { version = "1.7.0", default-features = false, features = [
172
179
  "http1",
173
180
  "http2",
174
181
  "server",
175
182
  ] }
176
- hyper-util = { version = "0.1.16", features = [
183
+ hyper-util = { version = "0.1.20", features = [
177
184
  "http1",
178
185
  "http2",
179
186
  "server-auto",
@@ -181,16 +188,52 @@ hyper-util = { version = "0.1.16", features = [
181
188
  "tokio",
182
189
  ] }
183
190
  serde = { version = "1.0", features = ["derive"] }
184
- tokio = { version = "1.0", default-features = false, features = [
185
- "macros",
186
- "rt-multi-thread",
187
- ] }
188
191
  futures = { version = "0.3.0", default-features = false, features = ["std"] }
189
192
  tower = { version = "0.5.2", default-features = false, features = ["limit"] }
190
- tokio-test = "0.4"
193
+ tokio-test = "0.4.5"
191
194
  tracing = "0.1"
192
195
  tracing-subscriber = "0.3.20"
193
196
  pretty_env_logger = "0.5"
197
+ brotli = "8.0.2"
198
+ flate2 = "1.1.9"
199
+ zstd = "0.13.3"
200
+
201
+ # for benchmarks
202
+ sysinfo = { version = "0.39.1", default-features = false, features = ["system"] }
203
+ criterion = { version = "0.8.2", features = ["async_tokio"] }
204
+ reqwest = { version = "0.13.3", default-features = false, features = ["rustls", "stream", "http2"] }
205
+
206
+ [profile.release]
207
+ codegen-units = 1
208
+ incremental = false
209
+
210
+ [profile.bench]
211
+ codegen-units = 1
212
+ incremental = false
213
+
214
+ [[bench]]
215
+ name = "http1"
216
+ path = "bench/http1.rs"
217
+ harness = false
218
+ required-features = ["stream"]
219
+
220
+ [[bench]]
221
+ name = "http2"
222
+ path = "bench/http2.rs"
223
+ harness = false
224
+ required-features = ["stream"]
225
+
226
+ [[bench]]
227
+ name = "http1_over_tls"
228
+ path = "bench/http1_over_tls.rs"
229
+ harness = false
230
+ required-features = ["stream"]
231
+
232
+ [[bench]]
233
+ name = "http2_over_tls"
234
+ path = "bench/http2_over_tls.rs"
235
+ harness = false
236
+ required-features = ["stream"]
194
237
 
195
238
  [[test]]
196
239
  name = "cookie"
@@ -252,8 +295,8 @@ path = "examples/connect_via_lower_priority_tokio_runtime.rs"
252
295
  required-features = ["tracing"]
253
296
 
254
297
  [[example]]
255
- name = "emulation"
256
- path = "examples/emulation.rs"
298
+ name = "emulate"
299
+ path = "examples/emulate.rs"
257
300
  required-features = ["gzip", "brotli", "zstd", "deflate", "tracing"]
258
301
 
259
302
  [[example]]
@@ -275,8 +318,8 @@ path = "examples/request_with_proxy.rs"
275
318
  required-features = ["socks"]
276
319
 
277
320
  [[example]]
278
- name = "request_with_emulation"
279
- path = "examples/request_with_emulation.rs"
321
+ name = "request_with_emulate"
322
+ path = "examples/request_with_emulate.rs"
280
323
  required-features = ["gzip", "brotli", "zstd", "deflate", "tracing"]
281
324
 
282
325
  [[example]]
@@ -304,3 +347,8 @@ path = "examples/keylog.rs"
304
347
  [[example]]
305
348
  name = "unix_socket"
306
349
  path = "examples/unix_socket.rs"
350
+
351
+ [[example]]
352
+ name = "rt"
353
+ path = "examples/rt.rs"
354
+ required-features = ["compio-rt"]
@@ -4,11 +4,14 @@
4
4
  [![Crates.io License](https://img.shields.io/crates/l/wreq)](https://github.com/0x676e67/wreq/blob/main/LICENSE)
5
5
  [![Crates.io MSRV](https://img.shields.io/crates/msrv/wreq?logo=rust)](https://crates.io/crates/wreq)
6
6
  [![crates.io](https://img.shields.io/crates/v/wreq.svg?logo=rust)](https://crates.io/crates/wreq)
7
- [![docs.rs](https://img.shields.io/docsrs/wreq?logo=rust)](https://docs.rs/wreq)
7
+ [![Discord chat][discord-badge]][discord-url]
8
+
9
+ [discord-badge]: https://img.shields.io/discord/1486741856397164788.svg?logo=discord
10
+ [discord-url]: https://discord.gg/rfbvyFkgq3
8
11
 
9
12
  > 🚀 Help me work seamlessly with open source sharing by [sponsoring me on GitHub](https://github.com/0x676e67/0x676e67/blob/main/SPONSOR.md)
10
13
 
11
- An ergonomic and modular Rust HTTP client for advanced and low-level emulation, with customizable TLS, JA3/JA4, and HTTP/2 fingerprinting capabilities.
14
+ An ergonomic and modular Rust HTTP Client for high-fidelity protocol matching, featuring customizable TLS, JA3/JA4, and HTTP/2 signature capabilities.
12
15
 
13
16
  ## Features
14
17
 
@@ -21,8 +24,9 @@ An ergonomic and modular Rust HTTP client for advanced and low-level emulation,
21
24
  - Tower Middleware
22
25
  - WebSocket Upgrade
23
26
  - HTTPS via BoringSSL
24
- - HTTP/2 over TLS Emulation
27
+ - HTTP/2 over TLS Parity
25
28
  - Certificate Store (CAs & mTLS)
29
+ - Multiple Runtime (Tokio, Compio)
26
30
 
27
31
  ## Example
28
32
 
@@ -31,8 +35,8 @@ The following example uses the [Tokio](https://tokio.rs) runtime with optional f
31
35
  ```toml
32
36
  [dependencies]
33
37
  tokio = { version = "1", features = ["full"] }
34
- wreq = "6.0.0-rc.28"
35
- wreq-util = "3.0.0-rc.10"
38
+ wreq = "6.0.0-rc"
39
+ wreq-util = "3.0.0-rc"
36
40
  ```
37
41
 
38
42
  And then the code:
@@ -67,18 +71,13 @@ Due to the complexity of **TLS** encryption and the widespread adoption of **HTT
67
71
 
68
72
  - **Device Emulation**
69
73
 
70
- Most browser device models share identical **TLS** and **HTTP/2** configurations, differing only in the **User-Agent** string. Common browser device emulation templates are maintained in [wreq-util](https://github.com/0x676e67/wreq-util), a companion utility crate.
74
+ **TLS** and **HTTP/2** fingerprints are often identical across various browser models because these underlying protocols evolve slower than browser release cycles. **100+ browser device emulation profiles** are maintained in [wreq-util](https://github.com/0x676e67/wreq-util).
71
75
 
72
76
  ## Building
73
77
 
74
- Compiling alongside **openssl-sys** can cause symbol conflicts with **boring-sys** that lead to [link failures](https://github.com/cloudflare/boring/issues/197), and on **Linux** and **Android** this can be avoided by enabling the **prefix-symbols** feature.
75
-
76
- ```toml
77
- [dependencies]
78
- wreq = { version = "6.0.0-rc.27", features = ["prefix-symbols"] }
79
- ```
78
+ Compiling alongside **openssl-sys** can cause symbol conflicts with **boringssl** that lead to [link failures](https://github.com/cloudflare/boring/issues/197), and on **Linux** and **Android** this can be avoided by enabling the **`prefix-symbols`** feature.
80
79
 
81
- Install the dependencies required to build [BoringSSL](https://github.com/google/boringssl/blob/master/BUILDING.md#build-prerequisites)
80
+ Install [BoringSSL build dependencies](https://github.com/google/boringssl/blob/master/BUILDING.md#build-prerequisites) and build with:
82
81
 
83
82
  ```bash
84
83
  sudo apt-get install build-essential cmake perl pkg-config libclang-dev musl-tools git -y
@@ -101,21 +100,27 @@ Unless you explicitly state otherwise, any contribution intentionally submitted
101
100
 
102
101
  ## Sponsors
103
102
 
104
- <a href="https://hypersolutions.co/?utm_source=github&utm_medium=readme&utm_campaign=wreq" target="_blank"><img src="https://raw.githubusercontent.com/0x676e67/wreq/main/.github/assets/hypersolutions.jpg" height="47" width="149"></a>
103
+ <a href="https://captcha.fun/?utm_source=github&utm_medium=readme&utm_campaign=wreq" target="_blank"><img src="https://www.captcha.fun/banner.jpg" height="47" width="149"></a>
105
104
 
106
- TLS fingerprinting alone isn't enough for modern bot protection. **[Hyper Solutions](https://hypersolutions.co?utm_source=github&utm_medium=readme&utm_campaign=wreq)** provides the missing piece - API endpoints that generate valid antibot tokens for:
105
+ **Solve reCAPTCHA in less than 2 seconds**
107
106
 
108
- **Akamai** **DataDome** **Kasada** **Incapsula**
107
+ **[Captcha.fun](https://captcha.fun/?utm_source=github&utm_medium=readme&utm_campaign=wreq)** delivers fast, reliable CAPTCHA solving built for automation at scale.
109
108
 
110
- No browser automation. Just simple API calls that return the exact cookies and headers these systems require.
109
+ With simple API integration, consistent performance, and competitive pricing, it's an easy way to keep your workflows moving without delays—use code **`WREQ`** for **10% bonus credits**.
111
110
 
112
- 🚀 **[Get Your API Key](https://hypersolutions.co?utm_source=github&utm_medium=readme&utm_campaign=wreq)** | 📖 **[Docs](https://docs.justhyped.dev)** | 💬 **[Discord](https://discord.gg/akamai)**
111
+ **[Dashboard](https://dash.captcha.fun/)** | **[Docs](http://docs.captcha.fun/)** | **[Discord](https://discord.gg/captchafun)**
113
112
 
114
113
  ---
115
114
 
116
- <a href="https://dashboard.capsolver.com/passport/register?inviteCode=y7CtB_a-3X6d" target="_blank"><img src="https://raw.githubusercontent.com/0x676e67/wreq/main/.github/assets/capsolver.jpg" height="47" width="149"></a>
115
+ <a href="https://hypersolutions.co/?utm_source=github&utm_medium=readme&utm_campaign=wreq" target="_blank"><img src="https://raw.githubusercontent.com/0x676e67/wreq/main/.github/assets/hypersolutions.jpg" height="47" width="149"></a>
116
+
117
+ TLS fingerprinting alone isn't enough for modern bot protection. **[Hyper Solutions](https://hypersolutions.co?utm_source=github&utm_medium=readme&utm_campaign=wreq)** provides the missing piece - API endpoints that generate valid antibot tokens for:
118
+
119
+ **Akamai** • **DataDome** • **Kasada** • **Incapsula**
120
+
121
+ No browser automation. Just simple API calls that return the exact cookies and headers these systems require.
117
122
 
118
- [CapSolver](https://www.capsolver.com/?utm_source=github&utm_medium=banner_repo&utm_campaign=wreq) 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 **`RQUEST`** for a 6% bonus!
123
+ **[Dashboard](https://hypersolutions.co?utm_source=github&utm_medium=readme&utm_campaign=wreq)** | **[Docs](https://docs.justhyped.dev)** | **[Discord](https://discord.gg/akamai)**
119
124
 
120
125
  ## Accolades
121
126
 
@@ -0,0 +1,25 @@
1
+ //! HTTP/1.1 benchmark
2
+
3
+ mod support;
4
+
5
+ use std::time::Duration;
6
+
7
+ use criterion::{Criterion, criterion_group, criterion_main};
8
+ use support::{HttpVersion, Tls, bench};
9
+
10
+ const NUM_REQUESTS_TO_SEND: usize = 500;
11
+
12
+ #[inline]
13
+ fn bench(c: &mut Criterion) {
14
+ bench::bench(c, Tls::Disabled, HttpVersion::Http1, NUM_REQUESTS_TO_SEND)
15
+ .expect("Failed to run HTTP/1 benchmark server")
16
+ }
17
+
18
+ criterion_group!(
19
+ name = benches;
20
+ config = Criterion::default()
21
+ .sample_size(10)
22
+ .warm_up_time(Duration::from_secs(3));
23
+ targets = bench
24
+ );
25
+ criterion_main!(benches);
@@ -0,0 +1,25 @@
1
+ //! HTTP/1.1 over TLS benchmark
2
+
3
+ mod support;
4
+
5
+ use std::time::Duration;
6
+
7
+ use criterion::{Criterion, criterion_group, criterion_main};
8
+ use support::{HttpVersion, Tls, bench};
9
+
10
+ const NUM_REQUESTS_TO_SEND: usize = 500;
11
+
12
+ #[inline]
13
+ fn bench(c: &mut Criterion) {
14
+ bench::bench(c, Tls::Enabled, HttpVersion::Http1, NUM_REQUESTS_TO_SEND)
15
+ .expect("Failed to run HTTP/1 over TLS benchmark server")
16
+ }
17
+
18
+ criterion_group!(
19
+ name = benches;
20
+ config = Criterion::default()
21
+ .sample_size(10)
22
+ .warm_up_time(Duration::from_secs(3));
23
+ targets = bench
24
+ );
25
+ criterion_main!(benches);
@@ -0,0 +1,25 @@
1
+ //! HTTP/2 benchmark
2
+
3
+ mod support;
4
+
5
+ use std::time::Duration;
6
+
7
+ use criterion::{Criterion, criterion_group, criterion_main};
8
+ use support::{HttpVersion, Tls, bench};
9
+
10
+ const NUM_REQUESTS_TO_SEND: usize = 500;
11
+
12
+ #[inline]
13
+ fn bench(c: &mut Criterion) {
14
+ bench::bench(c, Tls::Disabled, HttpVersion::Http2, NUM_REQUESTS_TO_SEND)
15
+ .expect("Failed to run HTTP/2 benchmark server")
16
+ }
17
+
18
+ criterion_group!(
19
+ name = benches;
20
+ config = Criterion::default()
21
+ .sample_size(10)
22
+ .warm_up_time(Duration::from_secs(3));
23
+ targets = bench
24
+ );
25
+ criterion_main!(benches);
@@ -0,0 +1,25 @@
1
+ //! HTTP/2 over TLS benchmark
2
+
3
+ mod support;
4
+
5
+ use std::time::Duration;
6
+
7
+ use criterion::{Criterion, criterion_group, criterion_main};
8
+ use support::{HttpVersion, Tls, bench};
9
+
10
+ const NUM_REQUESTS_TO_SEND: usize = 500;
11
+
12
+ #[inline]
13
+ fn bench(c: &mut Criterion) {
14
+ bench::bench(c, Tls::Enabled, HttpVersion::Http2, NUM_REQUESTS_TO_SEND)
15
+ .expect("Failed to run HTTP/2 over TLS benchmark server")
16
+ }
17
+
18
+ criterion_group!(
19
+ name = benches;
20
+ config = Criterion::default()
21
+ .sample_size(10)
22
+ .warm_up_time(Duration::from_secs(3));
23
+ targets = bench
24
+ );
25
+ criterion_main!(benches);
@@ -0,0 +1,91 @@
1
+ use criterion::Criterion;
2
+
3
+ use crate::support::{
4
+ BoxError, HttpVersion, Tls, client::bench_clients, current_thread_runtime,
5
+ multi_thread_runtime, server::with_server,
6
+ };
7
+
8
+ pub const CURRENT_THREAD_LABEL: &str = "current_thread";
9
+ pub const MULTI_THREAD_LABEL: &str = "multi_thread";
10
+ pub const CONCURRENT_CASES: &[usize] = &[10, 50, 100, 150];
11
+
12
+ /// Recommended chunk sizes for real-world network scenarios:
13
+ /// - 16 KB: Matches standard TCP buffers, ideal for HTTP/2 frames.
14
+ /// - 32 KB: For large HTTP payloads, fits modern socket buffers.
15
+ /// - 64 KB: Default Linux buffer size, optimized for large uploads.
16
+ /// - 128 KB: For high-throughput, large-scale transfers.
17
+ /// - 256 KB: Bulk data, maximum throughput on fast networks.
18
+ ///
19
+ /// For benchmarking latency-sensitive and high-throughput transfers.
20
+ pub const BODY_CASES: [(&[u8], usize); 7] = [
21
+ (&[b'a'; 1024], 1024), // 1 KB, chunk 1 KB
22
+ (&[b'a'; 10 * 1024], 10 * 1024), // 10 KB, chunk 10 KB
23
+ (&[b'a'; 64 * 1024], 16 * 1024), // 64 KB, chunk 16 KB
24
+ (&[b'a'; 128 * 1024], 32 * 1024), // 128 KB, chunk 32 KB
25
+ (&[b'a'; 1024 * 1024], 64 * 1024), // 1 MB, chunk 64 KB
26
+ (&[b'a'; 2 * 1024 * 1024], 128 * 1024), // 2 MB, chunk 128 KB
27
+ (&[b'a'; 4 * 1024 * 1024], 256 * 1024), // 4 MB, chunk 256 KB
28
+ ];
29
+
30
+ pub fn bench(
31
+ c: &mut Criterion,
32
+ tls: Tls,
33
+ http_version: HttpVersion,
34
+ num_requests: usize,
35
+ ) -> Result<(), BoxError> {
36
+ const OS: &str = std::env::consts::OS;
37
+ const ARCH: &str = std::env::consts::ARCH;
38
+
39
+ let system = sysinfo::System::new_all();
40
+ let cpu_model = system
41
+ .cpus()
42
+ .first()
43
+ .map_or("n/a", |cpu| cpu.brand().trim_start().trim_end());
44
+
45
+ for &concurrent_limit in CONCURRENT_CASES {
46
+ for body in BODY_CASES {
47
+ with_server(tls, |addr| {
48
+ // single-threaded client
49
+ let mut group = c.benchmark_group(format!(
50
+ "{cpu_model}/{OS}_{ARCH}/{CURRENT_THREAD_LABEL}/{tls}/{http_version}/{concurrent_limit}/{}KB",
51
+ body.0.len() / 1024,
52
+ ));
53
+
54
+ bench_clients(
55
+ &mut group,
56
+ current_thread_runtime,
57
+ addr,
58
+ tls,
59
+ http_version,
60
+ num_requests,
61
+ concurrent_limit,
62
+ body,
63
+ )?;
64
+ group.finish();
65
+ Ok(())
66
+ })?;
67
+
68
+ with_server(tls, |addr| {
69
+ // multi-threaded client
70
+ let mut group = c.benchmark_group(format!(
71
+ "{cpu_model}/{OS}_{ARCH}/{MULTI_THREAD_LABEL}/{tls}/{http_version}/{concurrent_limit}/{}KB",
72
+ body.0.len() / 1024,
73
+ ));
74
+ bench_clients(
75
+ &mut group,
76
+ multi_thread_runtime,
77
+ addr,
78
+ tls,
79
+ http_version,
80
+ num_requests,
81
+ concurrent_limit,
82
+ body,
83
+ )?;
84
+ group.finish();
85
+ Ok(())
86
+ })?;
87
+ }
88
+ }
89
+
90
+ Ok(())
91
+ }