wreq-rb 0.3.0

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 (167) hide show
  1. checksums.yaml +7 -0
  2. data/Cargo.lock +2688 -0
  3. data/Cargo.toml +6 -0
  4. data/README.md +179 -0
  5. data/ext/wreq_rb/Cargo.toml +39 -0
  6. data/ext/wreq_rb/extconf.rb +22 -0
  7. data/ext/wreq_rb/src/client.rs +565 -0
  8. data/ext/wreq_rb/src/error.rs +25 -0
  9. data/ext/wreq_rb/src/lib.rs +20 -0
  10. data/ext/wreq_rb/src/response.rs +132 -0
  11. data/lib/wreq-rb/version.rb +5 -0
  12. data/lib/wreq-rb.rb +17 -0
  13. data/patches/0001-add-transfer-size-tracking.patch +292 -0
  14. data/vendor/wreq/Cargo.toml +306 -0
  15. data/vendor/wreq/LICENSE +202 -0
  16. data/vendor/wreq/README.md +122 -0
  17. data/vendor/wreq/examples/cert_store.rs +77 -0
  18. data/vendor/wreq/examples/connect_via_lower_priority_tokio_runtime.rs +258 -0
  19. data/vendor/wreq/examples/emulation.rs +118 -0
  20. data/vendor/wreq/examples/form.rs +14 -0
  21. data/vendor/wreq/examples/http1_websocket.rs +37 -0
  22. data/vendor/wreq/examples/http2_websocket.rs +45 -0
  23. data/vendor/wreq/examples/json_dynamic.rs +41 -0
  24. data/vendor/wreq/examples/json_typed.rs +47 -0
  25. data/vendor/wreq/examples/keylog.rs +16 -0
  26. data/vendor/wreq/examples/request_with_emulation.rs +115 -0
  27. data/vendor/wreq/examples/request_with_interface.rs +37 -0
  28. data/vendor/wreq/examples/request_with_local_address.rs +16 -0
  29. data/vendor/wreq/examples/request_with_proxy.rs +13 -0
  30. data/vendor/wreq/examples/request_with_redirect.rs +22 -0
  31. data/vendor/wreq/examples/request_with_version.rs +15 -0
  32. data/vendor/wreq/examples/tor_socks.rs +24 -0
  33. data/vendor/wreq/examples/unix_socket.rs +33 -0
  34. data/vendor/wreq/src/client/body.rs +304 -0
  35. data/vendor/wreq/src/client/conn/conn.rs +231 -0
  36. data/vendor/wreq/src/client/conn/connector.rs +549 -0
  37. data/vendor/wreq/src/client/conn/http.rs +1023 -0
  38. data/vendor/wreq/src/client/conn/proxy/socks.rs +233 -0
  39. data/vendor/wreq/src/client/conn/proxy/tunnel.rs +260 -0
  40. data/vendor/wreq/src/client/conn/proxy.rs +39 -0
  41. data/vendor/wreq/src/client/conn/tls_info.rs +98 -0
  42. data/vendor/wreq/src/client/conn/uds.rs +44 -0
  43. data/vendor/wreq/src/client/conn/verbose.rs +149 -0
  44. data/vendor/wreq/src/client/conn.rs +323 -0
  45. data/vendor/wreq/src/client/core/body/incoming.rs +485 -0
  46. data/vendor/wreq/src/client/core/body/length.rs +118 -0
  47. data/vendor/wreq/src/client/core/body.rs +34 -0
  48. data/vendor/wreq/src/client/core/common/buf.rs +149 -0
  49. data/vendor/wreq/src/client/core/common/rewind.rs +141 -0
  50. data/vendor/wreq/src/client/core/common/watch.rs +76 -0
  51. data/vendor/wreq/src/client/core/common.rs +3 -0
  52. data/vendor/wreq/src/client/core/conn/http1.rs +342 -0
  53. data/vendor/wreq/src/client/core/conn/http2.rs +307 -0
  54. data/vendor/wreq/src/client/core/conn.rs +11 -0
  55. data/vendor/wreq/src/client/core/dispatch.rs +299 -0
  56. data/vendor/wreq/src/client/core/error.rs +435 -0
  57. data/vendor/wreq/src/client/core/ext.rs +201 -0
  58. data/vendor/wreq/src/client/core/http1.rs +178 -0
  59. data/vendor/wreq/src/client/core/http2.rs +483 -0
  60. data/vendor/wreq/src/client/core/proto/h1/conn.rs +988 -0
  61. data/vendor/wreq/src/client/core/proto/h1/decode.rs +1170 -0
  62. data/vendor/wreq/src/client/core/proto/h1/dispatch.rs +684 -0
  63. data/vendor/wreq/src/client/core/proto/h1/encode.rs +580 -0
  64. data/vendor/wreq/src/client/core/proto/h1/io.rs +879 -0
  65. data/vendor/wreq/src/client/core/proto/h1/role.rs +694 -0
  66. data/vendor/wreq/src/client/core/proto/h1.rs +104 -0
  67. data/vendor/wreq/src/client/core/proto/h2/client.rs +650 -0
  68. data/vendor/wreq/src/client/core/proto/h2/ping.rs +539 -0
  69. data/vendor/wreq/src/client/core/proto/h2.rs +379 -0
  70. data/vendor/wreq/src/client/core/proto/headers.rs +138 -0
  71. data/vendor/wreq/src/client/core/proto.rs +58 -0
  72. data/vendor/wreq/src/client/core/rt/bounds.rs +57 -0
  73. data/vendor/wreq/src/client/core/rt/timer.rs +150 -0
  74. data/vendor/wreq/src/client/core/rt/tokio.rs +99 -0
  75. data/vendor/wreq/src/client/core/rt.rs +25 -0
  76. data/vendor/wreq/src/client/core/upgrade.rs +267 -0
  77. data/vendor/wreq/src/client/core.rs +16 -0
  78. data/vendor/wreq/src/client/emulation.rs +161 -0
  79. data/vendor/wreq/src/client/http/client/error.rs +142 -0
  80. data/vendor/wreq/src/client/http/client/exec.rs +29 -0
  81. data/vendor/wreq/src/client/http/client/extra.rs +77 -0
  82. data/vendor/wreq/src/client/http/client/lazy.rs +79 -0
  83. data/vendor/wreq/src/client/http/client/pool.rs +1105 -0
  84. data/vendor/wreq/src/client/http/client/util.rs +104 -0
  85. data/vendor/wreq/src/client/http/client.rs +1003 -0
  86. data/vendor/wreq/src/client/http/future.rs +99 -0
  87. data/vendor/wreq/src/client/http.rs +1629 -0
  88. data/vendor/wreq/src/client/layer/config/options.rs +156 -0
  89. data/vendor/wreq/src/client/layer/config.rs +116 -0
  90. data/vendor/wreq/src/client/layer/cookie.rs +161 -0
  91. data/vendor/wreq/src/client/layer/decoder.rs +139 -0
  92. data/vendor/wreq/src/client/layer/redirect/future.rs +270 -0
  93. data/vendor/wreq/src/client/layer/redirect/policy.rs +63 -0
  94. data/vendor/wreq/src/client/layer/redirect.rs +145 -0
  95. data/vendor/wreq/src/client/layer/retry/classify.rs +105 -0
  96. data/vendor/wreq/src/client/layer/retry/scope.rs +51 -0
  97. data/vendor/wreq/src/client/layer/retry.rs +151 -0
  98. data/vendor/wreq/src/client/layer/timeout/body.rs +233 -0
  99. data/vendor/wreq/src/client/layer/timeout/future.rs +90 -0
  100. data/vendor/wreq/src/client/layer/timeout.rs +177 -0
  101. data/vendor/wreq/src/client/layer.rs +15 -0
  102. data/vendor/wreq/src/client/multipart.rs +717 -0
  103. data/vendor/wreq/src/client/request.rs +818 -0
  104. data/vendor/wreq/src/client/response.rs +534 -0
  105. data/vendor/wreq/src/client/ws/json.rs +99 -0
  106. data/vendor/wreq/src/client/ws/message.rs +453 -0
  107. data/vendor/wreq/src/client/ws.rs +714 -0
  108. data/vendor/wreq/src/client.rs +27 -0
  109. data/vendor/wreq/src/config.rs +140 -0
  110. data/vendor/wreq/src/cookie.rs +579 -0
  111. data/vendor/wreq/src/dns/gai.rs +249 -0
  112. data/vendor/wreq/src/dns/hickory.rs +78 -0
  113. data/vendor/wreq/src/dns/resolve.rs +180 -0
  114. data/vendor/wreq/src/dns.rs +69 -0
  115. data/vendor/wreq/src/error.rs +502 -0
  116. data/vendor/wreq/src/ext.rs +398 -0
  117. data/vendor/wreq/src/hash.rs +143 -0
  118. data/vendor/wreq/src/header.rs +506 -0
  119. data/vendor/wreq/src/into_uri.rs +187 -0
  120. data/vendor/wreq/src/lib.rs +586 -0
  121. data/vendor/wreq/src/proxy/mac.rs +82 -0
  122. data/vendor/wreq/src/proxy/matcher.rs +806 -0
  123. data/vendor/wreq/src/proxy/uds.rs +66 -0
  124. data/vendor/wreq/src/proxy/win.rs +31 -0
  125. data/vendor/wreq/src/proxy.rs +569 -0
  126. data/vendor/wreq/src/redirect.rs +575 -0
  127. data/vendor/wreq/src/retry.rs +198 -0
  128. data/vendor/wreq/src/sync.rs +129 -0
  129. data/vendor/wreq/src/tls/conn/cache.rs +123 -0
  130. data/vendor/wreq/src/tls/conn/cert_compression.rs +125 -0
  131. data/vendor/wreq/src/tls/conn/ext.rs +82 -0
  132. data/vendor/wreq/src/tls/conn/macros.rs +34 -0
  133. data/vendor/wreq/src/tls/conn/service.rs +138 -0
  134. data/vendor/wreq/src/tls/conn.rs +681 -0
  135. data/vendor/wreq/src/tls/keylog/handle.rs +64 -0
  136. data/vendor/wreq/src/tls/keylog.rs +99 -0
  137. data/vendor/wreq/src/tls/options.rs +464 -0
  138. data/vendor/wreq/src/tls/x509/identity.rs +122 -0
  139. data/vendor/wreq/src/tls/x509/parser.rs +71 -0
  140. data/vendor/wreq/src/tls/x509/store.rs +228 -0
  141. data/vendor/wreq/src/tls/x509.rs +68 -0
  142. data/vendor/wreq/src/tls.rs +154 -0
  143. data/vendor/wreq/src/trace.rs +55 -0
  144. data/vendor/wreq/src/util.rs +122 -0
  145. data/vendor/wreq/tests/badssl.rs +228 -0
  146. data/vendor/wreq/tests/brotli.rs +350 -0
  147. data/vendor/wreq/tests/client.rs +1098 -0
  148. data/vendor/wreq/tests/connector_layers.rs +227 -0
  149. data/vendor/wreq/tests/cookie.rs +306 -0
  150. data/vendor/wreq/tests/deflate.rs +347 -0
  151. data/vendor/wreq/tests/emulation.rs +260 -0
  152. data/vendor/wreq/tests/gzip.rs +347 -0
  153. data/vendor/wreq/tests/layers.rs +261 -0
  154. data/vendor/wreq/tests/multipart.rs +165 -0
  155. data/vendor/wreq/tests/proxy.rs +438 -0
  156. data/vendor/wreq/tests/redirect.rs +629 -0
  157. data/vendor/wreq/tests/retry.rs +135 -0
  158. data/vendor/wreq/tests/support/delay_server.rs +117 -0
  159. data/vendor/wreq/tests/support/error.rs +16 -0
  160. data/vendor/wreq/tests/support/layer.rs +183 -0
  161. data/vendor/wreq/tests/support/mod.rs +9 -0
  162. data/vendor/wreq/tests/support/server.rs +232 -0
  163. data/vendor/wreq/tests/timeouts.rs +281 -0
  164. data/vendor/wreq/tests/unix_socket.rs +135 -0
  165. data/vendor/wreq/tests/upgrade.rs +98 -0
  166. data/vendor/wreq/tests/zstd.rs +559 -0
  167. metadata +225 -0
@@ -0,0 +1,586 @@
1
+ #![deny(unused)]
2
+ #![deny(unsafe_code)]
3
+ #![deny(missing_docs)]
4
+ #![cfg_attr(docsrs, feature(doc_cfg))]
5
+ #![cfg_attr(test, deny(warnings))]
6
+ #![cfg_attr(not(test), warn(unused_crate_dependencies))]
7
+
8
+ //! # wreq
9
+ //!
10
+ //! An ergonomic all-in-one HTTP client for browser emulation with TLS, JA3/JA4, and HTTP/2
11
+ //! fingerprints.
12
+ //!
13
+ //! - Plain bodies, [JSON](#json), [urlencoded](#forms), [multipart]
14
+ //! - Cookies Store
15
+ //! - [Redirect Policy](#redirect-policies)
16
+ //! - Original Header
17
+ //! - Rotating [Proxies](#proxies)
18
+ //! - [Certificate Store](#certificate-store)
19
+ //! - [Tower](https://docs.rs/tower/latest/tower) Middleware
20
+ //! - [WebSocket](#websocket) Upgrade
21
+ //! - HTTPS via [BoringSSL](#tls)
22
+ //! - HTTP/2 over TLS [Emulation](#emulation)
23
+ //!
24
+ //! Additional learning resources include:
25
+ //!
26
+ //! - [The Rust Cookbook](https://doc.rust-lang.org/stable/book/ch00-00-introduction.html)
27
+ //! - [Repository Examples](https://github.com/0x676e67/wreq/tree/main/examples)
28
+ //!
29
+ //! ## Emulation
30
+ //!
31
+ //! The `emulation` module provides a way to simulate various browser TLS/HTTP2 fingerprints.
32
+ //!
33
+ //! ```rust,no_run
34
+ //! use wreq_util::Emulation;
35
+ //!
36
+ //! #[tokio::main]
37
+ //! async fn main() -> wreq::Result<()> {
38
+ //! // Use the API you're already familiar with
39
+ //! let resp = wreq::get("https://tls.peet.ws/api/all")
40
+ //! .emulation(Emulation::Firefox136)
41
+ //! .send().await?;
42
+ //! println!("{}", resp.text().await?);
43
+ //!
44
+ //! Ok(())
45
+ //! }
46
+ //! ```
47
+ //!
48
+ //! ## Websocket
49
+ //!
50
+ //! The `websocket` module provides a way to upgrade a connection to a websocket.
51
+ //!
52
+ //! ```rust,no_run
53
+ //! use futures_util::{SinkExt, StreamExt, TryStreamExt};
54
+ //! use wreq::{header, ws::message::Message};
55
+ //!
56
+ //! #[tokio::main]
57
+ //! async fn main() -> wreq::Result<()> {
58
+ //! // Use the API you're already familiar with
59
+ //! let websocket = wreq::websocket("wss://echo.websocket.org")
60
+ //! .header(header::USER_AGENT, env!("CARGO_PKG_NAME"))
61
+ //! .send()
62
+ //! .await?;
63
+ //!
64
+ //! assert_eq!(websocket.version(), http::Version::HTTP_11);
65
+ //!
66
+ //! let (mut tx, mut rx) = websocket.into_websocket().await?.split();
67
+ //!
68
+ //! tokio::spawn(async move {
69
+ //! for i in 1..11 {
70
+ //! if let Err(err) = tx.send(Message::text(format!("Hello, World! {i}"))).await {
71
+ //! eprintln!("failed to send message: {err}");
72
+ //! }
73
+ //! }
74
+ //! });
75
+ //!
76
+ //! while let Some(message) = rx.try_next().await? {
77
+ //! if let Message::Text(text) = message {
78
+ //! println!("received: {text}");
79
+ //! }
80
+ //! }
81
+ //!
82
+ //! Ok(())
83
+ //! }
84
+ //! ```
85
+ //!
86
+ //! ## Making a GET request
87
+ //!
88
+ //! Making a GET request is simple.
89
+ //!
90
+ //! ```rust
91
+ //! # async fn run() -> wreq::Result<()> {
92
+ //! let body = wreq::get("https://www.rust-lang.org")
93
+ //! .send()
94
+ //! .await?
95
+ //! .text()
96
+ //! .await?;
97
+ //!
98
+ //! println!("body = {:?}", body);
99
+ //! # Ok(())
100
+ //! # }
101
+ //! ```
102
+ //!
103
+ //! **NOTE**: If you plan to perform multiple requests, it is best to create a
104
+ //! [`Client`][client] and reuse it, taking advantage of keep-alive connection
105
+ //! pooling.
106
+ //!
107
+ //! ## Making POST requests (or setting request bodies)
108
+ //!
109
+ //! There are several ways you can set the body of a request. The basic one is
110
+ //! by using the `body()` method of a [`RequestBuilder`][builder]. This lets you set the
111
+ //! exact raw bytes of what the body should be. It accepts various types,
112
+ //! including `String` and `Vec<u8>`. If you wish to pass a custom
113
+ //! type, you can use the `wreq::Body` constructors.
114
+ //!
115
+ //! ```rust
116
+ //! # use wreq::Error;
117
+ //! #
118
+ //! # async fn run() -> Result<(), Error> {
119
+ //! let client = wreq::Client::new();
120
+ //! let res = client
121
+ //! .post("http://httpbin.org/post")
122
+ //! .body("the exact body that is sent")
123
+ //! .send()
124
+ //! .await?;
125
+ //! # Ok(())
126
+ //! # }
127
+ //! ```
128
+ //!
129
+ //! ### Forms
130
+ //!
131
+ //! It's very common to want to send form data in a request body. This can be
132
+ //! done with any type that can be serialized into form data.
133
+ //!
134
+ //! This can be an array of tuples, or a `HashMap`, or a custom type that
135
+ //! implements [`Serialize`][serde].
136
+ //!
137
+ //! The feature `form` is required.
138
+ //!
139
+ //! ```rust
140
+ //! # use wreq::Error;
141
+ //! # #[cfg(feature = "form")]
142
+ //! # async fn run() -> Result<(), Error> {
143
+ //! // This will POST a body of `foo=bar&baz=quux`
144
+ //! let params = [("foo", "bar"), ("baz", "quux")];
145
+ //! let client = wreq::Client::new();
146
+ //! let res = client
147
+ //! .post("http://httpbin.org/post")
148
+ //! .form(&params)
149
+ //! .send()
150
+ //! .await?;
151
+ //! # Ok(())
152
+ //! # }
153
+ //! ```
154
+ //!
155
+ //! ### JSON
156
+ //!
157
+ //! There is also a `json` method helper on the [`RequestBuilder`][builder] that works in
158
+ //! a similar fashion the `form` method. It can take any value that can be
159
+ //! serialized into JSON. The feature `json` is required.
160
+ //!
161
+ //! ```rust
162
+ //! # use wreq::Error;
163
+ //! # use std::collections::HashMap;
164
+ //! #
165
+ //! # #[cfg(feature = "json")]
166
+ //! # async fn run() -> Result<(), Error> {
167
+ //! // This will POST a body of `{"lang":"rust","body":"json"}`
168
+ //! let mut map = HashMap::new();
169
+ //! map.insert("lang", "rust");
170
+ //! map.insert("body", "json");
171
+ //!
172
+ //! let client = wreq::Client::new();
173
+ //! let res = client
174
+ //! .post("http://httpbin.org/post")
175
+ //! .json(&map)
176
+ //! .send()
177
+ //! .await?;
178
+ //! # Ok(())
179
+ //! # }
180
+ //! ```
181
+ //!
182
+ //! ## Redirect Policies
183
+ //!
184
+ //! By default, the client does not handle HTTP redirects.
185
+ //! To customize this behavior, you can use [`redirect::Policy`][redirect] with ClientBuilder.
186
+ //!
187
+ //! ## Cookies
188
+ //!
189
+ //! The automatic storing and sending of session cookies can be enabled with
190
+ //! the [`cookie_store`][ClientBuilder::cookie_store] method on `ClientBuilder`.
191
+ //!
192
+ //! ## Proxies
193
+ //!
194
+ //! **NOTE**: System proxies are enabled by default.
195
+ //!
196
+ //! System proxies look in environment variables to set HTTP or HTTPS proxies.
197
+ //!
198
+ //! `HTTP_PROXY` or `http_proxy` provide HTTP proxies for HTTP connections while
199
+ //! `HTTPS_PROXY` or `https_proxy` provide HTTPS proxies for HTTPS connections.
200
+ //! `ALL_PROXY` or `all_proxy` provide proxies for both HTTP and HTTPS connections.
201
+ //! If both the all proxy and HTTP or HTTPS proxy variables are set the more specific
202
+ //! HTTP or HTTPS proxies take precedence.
203
+ //!
204
+ //! These can be overwritten by adding a [`Proxy`] to `ClientBuilder`
205
+ //! i.e. `let proxy = wreq::Proxy::http("https://secure.example")?;`
206
+ //! or disabled by calling `ClientBuilder::no_proxy()`.
207
+ //!
208
+ //! `socks` feature is required if you have configured socks proxy like this:
209
+ //!
210
+ //! ```bash
211
+ //! export https_proxy=socks5://127.0.0.1:1086
212
+ //! ```
213
+ //!
214
+ //! * `http://` is the scheme for http proxy
215
+ //! * `https://` is the scheme for https proxy
216
+ //! * `socks4://` is the scheme for socks4 proxy
217
+ //! * `socks4a://` is the scheme for socks4a proxy
218
+ //! * `socks5://` is the scheme for socks5 proxy
219
+ //! * `socks5h://` is the scheme for socks5h proxy
220
+ //!
221
+ //! ## TLS
222
+ //!
223
+ //! By default, clients will utilize BoringSSL transport layer security to connect to HTTPS targets.
224
+ //!
225
+ //! - Various parts of TLS can also be configured or even disabled on the `ClientBuilder`.
226
+ //!
227
+ //! ## Certificate Store
228
+ //!
229
+ //! By default, wreq uses Mozilla's root certificates through the webpki-roots crate.
230
+ //! This static root certificate bundle is not automatically updated and ignores any root
231
+ //! certificates installed on the host. You can disable default-features to use the system's default
232
+ //! certificate path. Additionally, wreq provides a certificate store for users to customize and
233
+ //! update certificates.
234
+ //!
235
+ //! Custom Certificate Store verification supports Root CA certificates, peer certificates, and
236
+ //! self-signed certificate SSL pinning.
237
+ //!
238
+ //! ## Optional Features
239
+ //!
240
+ //! The following are a list of [Cargo features][cargo-features] that can be
241
+ //! enabled or disabled:
242
+ //!
243
+ //! - **cookies**: Provides cookie session support.
244
+ //! - **gzip**: Provides response body gzip decompression.
245
+ //! - **brotli**: Provides response body brotli decompression.
246
+ //! - **zstd**: Provides response body zstd decompression.
247
+ //! - **deflate**: Provides response body deflate decompression.
248
+ //! - **query**: Provides query parameter serialization.
249
+ //! - **form**: Provides form data serialization.
250
+ //! - **json**: Provides serialization and deserialization for JSON bodies.
251
+ //! - **multipart**: Provides functionality for multipart forms.
252
+ //! - **charset**: Improved support for decoding text.
253
+ //! - **stream**: Adds support for `futures::Stream`.
254
+ //! - **socks**: Provides SOCKS5 and SOCKS4 proxy support.
255
+ //! - **ws**: Provides websocket support.
256
+ //! - **hickory-dns**: Enables a hickory-dns async resolver instead of default threadpool using
257
+ //! `getaddrinfo`.
258
+ //! - **webpki-roots** *(enabled by default)*: Use the webpki-roots crate for root certificates.
259
+ //! - **system-proxy**: Enable system proxy support.
260
+ //! - **tracing**: Enable tracing logging support.
261
+ //! - **prefix-symbols**: Prefix BoringSSL symbols to avoid linker conflicts.
262
+ //!
263
+ //! [client]: ./struct.Client.html
264
+ //! [response]: ./struct.Response.html
265
+ //! [get]: ./fn.get.html
266
+ //! [builder]: ./struct.RequestBuilder.html
267
+ //! [serde]: http://serde.rs
268
+ //! [redirect]: crate::redirect
269
+ //! [Proxy]: ./struct.Proxy.html
270
+ //! [cargo-features]: https://doc.rust-lang.org/stable/cargo/reference/manifest.html#the-features-section
271
+
272
+ #[macro_use]
273
+ mod trace;
274
+ #[macro_use]
275
+ mod config;
276
+ mod client;
277
+ mod error;
278
+ mod ext;
279
+ mod hash;
280
+ mod into_uri;
281
+ mod proxy;
282
+ mod sync;
283
+ mod util;
284
+
285
+ #[cfg(feature = "cookies")]
286
+ pub mod cookie;
287
+ pub mod dns;
288
+ pub mod header;
289
+ pub mod redirect;
290
+ pub mod retry;
291
+ pub mod tls;
292
+
293
+ pub use http::{Method, StatusCode, Uri, Version};
294
+ #[cfg(unix)]
295
+ use libc as _;
296
+
297
+ #[cfg(feature = "multipart")]
298
+ pub use self::client::multipart;
299
+ #[cfg(feature = "ws")]
300
+ pub use self::client::ws;
301
+ pub use self::{
302
+ client::{
303
+ Body, Client, ClientBuilder, Emulation, EmulationBuilder, EmulationFactory, Request,
304
+ RequestBuilder, Response, Upgraded, http1, http2,
305
+ },
306
+ error::{Error, Result},
307
+ ext::{ResponseBuilderExt, ResponseExt},
308
+ into_uri::IntoUri,
309
+ proxy::{NoProxy, Proxy},
310
+ };
311
+
312
+ fn _assert_impls() {
313
+ fn assert_send<T: Send>() {}
314
+ fn assert_sync<T: Sync>() {}
315
+ fn assert_clone<T: Clone>() {}
316
+
317
+ assert_send::<Client>();
318
+ assert_sync::<Client>();
319
+ assert_clone::<Client>();
320
+
321
+ assert_send::<Request>();
322
+ assert_send::<RequestBuilder>();
323
+ #[cfg(feature = "ws")]
324
+ assert_send::<ws::WebSocketRequestBuilder>();
325
+
326
+ assert_send::<Response>();
327
+ #[cfg(feature = "ws")]
328
+ assert_send::<ws::WebSocketResponse>();
329
+ #[cfg(feature = "ws")]
330
+ assert_send::<ws::WebSocket>();
331
+
332
+ assert_send::<Error>();
333
+ assert_sync::<Error>();
334
+ }
335
+
336
+ /// Shortcut method to quickly make a `GET` request.
337
+ ///
338
+ /// See also the methods on the [`wreq::RequestBuilder`](./struct.RequestBuilder.html)
339
+ /// type.
340
+ ///
341
+ /// **NOTE**: This function creates a new internal `Client` on each call,
342
+ /// and so should not be used if making many requests. Create a
343
+ /// [`Client`](./struct.Client.html) instead.
344
+ ///
345
+ /// # Examples
346
+ ///
347
+ /// ```rust
348
+ /// # async fn run() -> wreq::Result<()> {
349
+ /// let body = wreq::get("https://www.rust-lang.org")
350
+ /// .send()
351
+ /// .await?
352
+ /// .text()
353
+ /// .await?;
354
+ /// # Ok(())
355
+ /// # }
356
+ /// ```
357
+ #[inline]
358
+ pub fn get<T: IntoUri>(uri: T) -> RequestBuilder {
359
+ Client::new().get(uri)
360
+ }
361
+
362
+ /// Shortcut method to quickly make a `POST` request.
363
+ ///
364
+ /// See also the methods on the [`wreq::RequestBuilder`](./struct.RequestBuilder.html)
365
+ /// type.
366
+ ///
367
+ /// **NOTE**: This function creates a new internal `Client` on each call,
368
+ /// and so should not be used if making many requests. Create a
369
+ /// [`Client`](./struct.Client.html) instead.
370
+ ///
371
+ /// # Examples
372
+ ///
373
+ /// ```rust
374
+ /// # async fn run() -> wreq::Result<()> {
375
+ /// let res = wreq::post("https://httpbin.org/post")
376
+ /// .body("example body")
377
+ /// .send()
378
+ /// .await?;
379
+ /// # Ok(())
380
+ /// # }
381
+ /// ```
382
+ #[inline]
383
+ pub fn post<T: IntoUri>(uri: T) -> RequestBuilder {
384
+ Client::new().post(uri)
385
+ }
386
+
387
+ /// Shortcut method to quickly make a `PUT` request.
388
+ ///
389
+ /// See also the methods on the [`wreq::RequestBuilder`](./struct.RequestBuilder.html)
390
+ /// type.
391
+ ///
392
+ /// **NOTE**: This function creates a new internal `Client` on each call,
393
+ /// and so should not be used if making many requests. Create a
394
+ /// [`Client`](./struct.Client.html) instead.
395
+ ///
396
+ /// # Examples
397
+ ///
398
+ /// ```rust
399
+ /// # async fn run() -> wreq::Result<()> {
400
+ /// let res = wreq::put("https://httpbin.org/put")
401
+ /// .body("update content")
402
+ /// .send()
403
+ /// .await?;
404
+ /// # Ok(())
405
+ /// # }
406
+ /// ```
407
+ #[inline]
408
+ pub fn put<T: IntoUri>(uri: T) -> RequestBuilder {
409
+ Client::new().put(uri)
410
+ }
411
+
412
+ /// Shortcut method to quickly make a `DELETE` request.
413
+ ///
414
+ /// See also the methods on the [`wreq::RequestBuilder`](./struct.RequestBuilder.html)
415
+ /// type.
416
+ ///
417
+ /// **NOTE**: This function creates a new internal `Client` on each call,
418
+ /// and so should not be used if making many requests. Create a
419
+ /// [`Client`](./struct.Client.html) instead.
420
+ ///
421
+ /// # Examples
422
+ ///
423
+ /// ```rust
424
+ /// # async fn run() -> wreq::Result<()> {
425
+ /// let res = wreq::delete("https://httpbin.org/delete")
426
+ /// .send()
427
+ /// .await?;
428
+ /// # Ok(())
429
+ /// # }
430
+ /// ```
431
+ #[inline]
432
+ pub fn delete<T: IntoUri>(uri: T) -> RequestBuilder {
433
+ Client::new().delete(uri)
434
+ }
435
+
436
+ /// Shortcut method to quickly make a `HEAD` request.
437
+ ///
438
+ /// See also the methods on the [`wreq::RequestBuilder`](./struct.RequestBuilder.html)
439
+ /// type.
440
+ ///
441
+ /// **NOTE**: This function creates a new internal `Client` on each call,
442
+ /// and so should not be used if making many requests. Create a
443
+ /// [`Client`](./struct.Client.html) instead.
444
+ ///
445
+ /// # Examples
446
+ ///
447
+ /// ```rust
448
+ /// # async fn run() -> wreq::Result<()> {
449
+ /// let res = wreq::head("https://httpbin.org/get")
450
+ /// .send()
451
+ /// .await?;
452
+ /// # Ok(())
453
+ /// # }
454
+ /// ```
455
+ #[inline]
456
+ pub fn head<T: IntoUri>(uri: T) -> RequestBuilder {
457
+ Client::new().head(uri)
458
+ }
459
+
460
+ /// Shortcut method to quickly make a `PATCH` request.
461
+ ///
462
+ /// See also the methods on the [`wreq::RequestBuilder`](./struct.RequestBuilder.html)
463
+ /// type.
464
+ ///
465
+ /// **NOTE**: This function creates a new internal `Client` on each call,
466
+ /// and so should not be used if making many requests. Create a
467
+ /// [`Client`](./struct.Client.html) instead.
468
+ ///
469
+ /// # Examples
470
+ ///
471
+ /// ```rust
472
+ /// # async fn run() -> wreq::Result<()> {
473
+ /// let res = wreq::patch("https://httpbin.org/patch")
474
+ /// .body("patch content")
475
+ /// .send()
476
+ /// .await?;
477
+ /// # Ok(())
478
+ /// # }
479
+ /// ```
480
+ #[inline]
481
+ pub fn patch<T: IntoUri>(uri: T) -> RequestBuilder {
482
+ Client::new().patch(uri)
483
+ }
484
+
485
+ /// Shortcut method to quickly make an `OPTIONS` request.
486
+ ///
487
+ /// See also the methods on the [`wreq::RequestBuilder`](./struct.RequestBuilder.html)
488
+ /// type.
489
+ ///
490
+ /// **NOTE**: This function creates a new internal `Client` on each call,
491
+ /// and so should not be used if making many requests. Create a
492
+ /// [`Client`](./struct.Client.html) instead.
493
+ ///
494
+ /// # Examples
495
+ ///
496
+ /// ```rust
497
+ /// # async fn run() -> wreq::Result<()> {
498
+ /// let res = wreq::options("https://httpbin.org/get")
499
+ /// .send()
500
+ /// .await?;
501
+ /// # Ok(())
502
+ /// # }
503
+ /// ```
504
+ #[inline]
505
+ pub fn options<T: IntoUri>(uri: T) -> RequestBuilder {
506
+ Client::new().options(uri)
507
+ }
508
+
509
+ /// Shortcut method to quickly make a request with a custom HTTP method.
510
+ ///
511
+ /// See also the methods on the [`wreq::RequestBuilder`](./struct.RequestBuilder.html)
512
+ /// type.
513
+ ///
514
+ /// **NOTE**: This function creates a new internal `Client` on each call,
515
+ /// and so should not be used if making many requests. Create a
516
+ /// [`Client`](./struct.Client.html) instead.
517
+ ///
518
+ /// # Examples
519
+ ///
520
+ /// ```rust
521
+ /// # async fn run() -> wreq::Result<()> {
522
+ /// use http::Method;
523
+ /// let res = wreq::request(Method::TRACE, "https://httpbin.org/trace")
524
+ /// .send()
525
+ /// .await?;
526
+ /// # Ok(())
527
+ /// # }
528
+ /// ```
529
+ #[inline]
530
+ pub fn request<T: IntoUri>(method: Method, uri: T) -> RequestBuilder {
531
+ Client::new().request(method, uri)
532
+ }
533
+
534
+ /// Shortcut method to quickly make a WebSocket request.
535
+ ///
536
+ /// See also the methods on the
537
+ /// [`wreq::ws::WebSocketRequestBuilder`](./ws/struct.WebSocketRequestBuilder.html) type.
538
+ ///
539
+ /// **NOTE**: This function creates a new internal `Client` on each call,
540
+ /// and so should not be used if making many requests. Create a
541
+ /// [`Client`](./struct.Client.html) instead.
542
+ ///
543
+ /// # Examples
544
+ ///
545
+ /// ```rust
546
+ /// # async fn run() -> wreq::Result<()> {
547
+ /// use futures_util::{SinkExt, StreamExt, TryStreamExt};
548
+ /// use wreq::{header, ws::message::Message};
549
+ ///
550
+ /// let resp = wreq::websocket("wss://echo.websocket.org")
551
+ /// .header(header::USER_AGENT, env!("CARGO_PKG_NAME"))
552
+ /// .read_buffer_size(1024 * 1024)
553
+ /// .send()
554
+ /// .await?;
555
+ ///
556
+ /// assert_eq!(resp.version(), http::Version::HTTP_11);
557
+ ///
558
+ /// let websocket = resp.into_websocket().await?;
559
+ /// if let Some(protocol) = websocket.protocol() {
560
+ /// println!("WebSocket subprotocol: {:?}", protocol);
561
+ /// }
562
+ ///
563
+ /// let (mut tx, mut rx) = websocket.split();
564
+ ///
565
+ /// tokio::spawn(async move {
566
+ /// for i in 1..11 {
567
+ /// if let Err(err) = tx.send(Message::text(format!("Hello, World! {i}"))).await {
568
+ /// eprintln!("failed to send message: {err}");
569
+ /// }
570
+ /// }
571
+ /// });
572
+ ///
573
+ /// while let Some(message) = rx.try_next().await? {
574
+ /// if let Message::Text(text) = message {
575
+ /// println!("received: {text}");
576
+ /// }
577
+ /// }
578
+ /// # Ok(())
579
+ /// # }
580
+ /// ```
581
+ #[inline]
582
+ #[cfg(feature = "ws")]
583
+ #[cfg_attr(docsrs, doc(cfg(feature = "ws")))]
584
+ pub fn websocket<T: IntoUri>(uri: T) -> ws::WebSocketRequestBuilder {
585
+ Client::new().websocket(uri)
586
+ }
@@ -0,0 +1,82 @@
1
+ use system_configuration::{
2
+ core_foundation::{
3
+ base::CFType,
4
+ dictionary::CFDictionary,
5
+ number::CFNumber,
6
+ string::{CFString, CFStringRef},
7
+ },
8
+ dynamic_store::SCDynamicStoreBuilder,
9
+ sys::schema_definitions::{
10
+ kSCPropNetProxiesHTTPEnable, kSCPropNetProxiesHTTPPort, kSCPropNetProxiesHTTPProxy,
11
+ kSCPropNetProxiesHTTPSEnable, kSCPropNetProxiesHTTPSPort, kSCPropNetProxiesHTTPSProxy,
12
+ },
13
+ };
14
+
15
+ #[allow(unsafe_code)]
16
+ pub(super) fn with_system(builder: &mut super::matcher::Builder) {
17
+ let Some(proxies_map) = SCDynamicStoreBuilder::new("")
18
+ .build()
19
+ .and_then(|store| store.get_proxies())
20
+ else {
21
+ return;
22
+ };
23
+
24
+ if builder.http.is_empty() {
25
+ let http_proxy_config = parse_setting_from_dynamic_store(
26
+ &proxies_map,
27
+ unsafe { kSCPropNetProxiesHTTPEnable },
28
+ unsafe { kSCPropNetProxiesHTTPProxy },
29
+ unsafe { kSCPropNetProxiesHTTPPort },
30
+ );
31
+ if let Some(http) = http_proxy_config {
32
+ builder.http = http;
33
+ }
34
+ }
35
+
36
+ if builder.https.is_empty() {
37
+ let https_proxy_config = parse_setting_from_dynamic_store(
38
+ &proxies_map,
39
+ unsafe { kSCPropNetProxiesHTTPSEnable },
40
+ unsafe { kSCPropNetProxiesHTTPSProxy },
41
+ unsafe { kSCPropNetProxiesHTTPSPort },
42
+ );
43
+
44
+ if let Some(https) = https_proxy_config {
45
+ builder.https = https;
46
+ }
47
+ }
48
+ }
49
+
50
+ fn parse_setting_from_dynamic_store(
51
+ proxies_map: &CFDictionary<CFString, CFType>,
52
+ enabled_key: CFStringRef,
53
+ host_key: CFStringRef,
54
+ port_key: CFStringRef,
55
+ ) -> Option<String> {
56
+ let proxy_enabled = proxies_map
57
+ .find(enabled_key)
58
+ .and_then(|flag| flag.downcast::<CFNumber>())
59
+ .and_then(|flag| flag.to_i32())
60
+ .unwrap_or(0)
61
+ == 1;
62
+
63
+ if proxy_enabled {
64
+ let proxy_host = proxies_map
65
+ .find(host_key)
66
+ .and_then(|host| host.downcast::<CFString>())
67
+ .map(|host| host.to_string());
68
+ let proxy_port = proxies_map
69
+ .find(port_key)
70
+ .and_then(|port| port.downcast::<CFNumber>())
71
+ .and_then(|port| port.to_i32());
72
+
73
+ return match (proxy_host, proxy_port) {
74
+ (Some(proxy_host), Some(proxy_port)) => Some(format!("{proxy_host}:{proxy_port}")),
75
+ (Some(proxy_host), None) => Some(proxy_host),
76
+ (None, Some(_)) => None,
77
+ (None, None) => None,
78
+ };
79
+ }
80
+
81
+ None
82
+ }