wreq 1.2.5 → 1.2.6

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +20 -13
  3. data/Cargo.toml +10 -2
  4. data/crates/wreq-util/src/emulate/macros.rs +12 -10
  5. data/crates/wreq-util/src/emulate/profile/chrome/header.rs +18 -3
  6. data/crates/wreq-util/src/emulate/profile/firefox/header.rs +16 -0
  7. data/crates/wreq-util/src/emulate/profile/opera/header.rs +6 -7
  8. data/crates/wreq-util/tests/client.rs +103 -1
  9. data/lib/wreq.rb +70 -45
  10. data/lib/wreq_ruby/body.rb +29 -11
  11. data/lib/wreq_ruby/client.rb +88 -55
  12. data/lib/wreq_ruby/cookie.rb +79 -19
  13. data/lib/wreq_ruby/emulate.rb +74 -6
  14. data/lib/wreq_ruby/error.rb +5 -7
  15. data/lib/wreq_ruby/http.rb +74 -0
  16. data/lib/wreq_ruby/response.rb +3 -0
  17. data/script/build_windows_gnu.ps1 +6 -0
  18. data/src/arch.rs +22 -0
  19. data/src/client/body/form.rs +2 -0
  20. data/src/client/body/json.rs +47 -14
  21. data/src/client/body/stream.rs +147 -43
  22. data/src/client/body.rs +11 -15
  23. data/src/client/param.rs +7 -7
  24. data/src/client/req.rs +87 -47
  25. data/src/client/resp.rs +23 -24
  26. data/src/client.rs +310 -230
  27. data/src/cookie.rs +280 -87
  28. data/src/emulate.rs +85 -50
  29. data/src/error.rs +198 -41
  30. data/src/extractor.rs +16 -76
  31. data/src/header.rs +146 -23
  32. data/src/http.rs +62 -33
  33. data/src/lib.rs +26 -20
  34. data/src/macros.rs +71 -46
  35. data/src/options.rs +284 -0
  36. data/src/rt.rs +22 -11
  37. data/src/serde/de/array_deserializer.rs +48 -0
  38. data/src/serde/de/array_enumerator.rs +59 -0
  39. data/src/serde/de/deserializer.rs +307 -0
  40. data/src/serde/de/enum_deserializer.rs +47 -0
  41. data/src/serde/de/hash_deserializer.rs +89 -0
  42. data/src/serde/de/number_deserializer.rs +51 -0
  43. data/src/serde/de/variant_deserializer.rs +101 -0
  44. data/src/serde/de.rs +33 -0
  45. data/src/serde/error.rs +146 -0
  46. data/src/serde/ser/enums.rs +14 -0
  47. data/src/serde/ser/map_serializer.rs +56 -0
  48. data/src/serde/ser/seq_serializer.rs +71 -0
  49. data/src/serde/ser/serializer.rs +194 -0
  50. data/src/serde/ser/struct_serializer.rs +106 -0
  51. data/src/serde/ser/struct_variant_serializer.rs +44 -0
  52. data/src/serde/ser/tuple_variant_serializer.rs +41 -0
  53. data/src/serde/ser.rs +18 -0
  54. data/src/serde/tests.rs +237 -0
  55. data/src/serde.rs +202 -0
  56. data/test/body_sender_test.rb +246 -0
  57. data/test/cookie_test.rb +211 -10
  58. data/test/json_precision_test.rb +209 -0
  59. data/test/option_validation_test.rb +311 -0
  60. data/test/value_semantics_test.rb +238 -0
  61. metadata +25 -2
  62. data/src/header/helper.rs +0 -112
data/src/client.rs CHANGED
@@ -6,38 +6,38 @@ pub mod resp;
6
6
 
7
7
  use std::{net::IpAddr, time::Duration};
8
8
 
9
- use magnus::{
10
- Module, Object, RHash, RModule, Ruby, TryConvert, Value, function, method, typed_data::Obj,
11
- };
12
- use serde::Deserialize;
9
+ use ::serde::Deserialize;
10
+ use magnus::{Module, Object, RModule, Ruby, TryConvert, Value, function, method, typed_data::Obj};
13
11
  use wreq::Proxy;
14
12
 
15
13
  use crate::{
14
+ arch::{SUPPORTS_INTERFACE, SUPPORTS_TCP_USER_TIMEOUT},
16
15
  client::{req::execute_request, resp::Response},
17
16
  cookie::Jar,
18
17
  emulate::Emulation,
19
- error::wreq_error_to_magnus,
18
+ error::wreq_error,
20
19
  extractor::Extractor,
21
20
  gvl,
22
21
  header::{Headers, OrigHeaders, UserAgent},
23
22
  http::Method,
23
+ options::{NativeOption, Options},
24
24
  };
25
25
 
26
26
  /// A builder for `Client`.
27
27
  #[derive(Default, Deserialize)]
28
28
  struct Builder {
29
29
  // The emulation option for the client.
30
- #[serde(skip)]
31
- emulation: Option<Emulation>,
30
+ #[serde(default)]
31
+ emulation: NativeOption<Emulation>,
32
32
  /// The user agent to use for the client.
33
- #[serde(skip)]
34
- user_agent: Option<UserAgent>,
33
+ #[serde(default)]
34
+ user_agent: NativeOption<UserAgent>,
35
35
  /// The headers to use for the client.
36
- #[serde(skip)]
37
- headers: Option<Headers>,
36
+ #[serde(default)]
37
+ headers: NativeOption<Headers>,
38
38
  /// The original headers to use for the client.
39
- #[serde(skip)]
40
- orig_headers: Option<OrigHeaders>,
39
+ #[serde(default)]
40
+ orig_headers: NativeOption<OrigHeaders>,
41
41
  /// Whether to use referer.
42
42
  referer: Option<bool>,
43
43
  /// Whether to allow redirects.
@@ -49,8 +49,8 @@ struct Builder {
49
49
  /// Whether to use cookie store.
50
50
  cookie_store: Option<bool>,
51
51
  /// Whether to use cookie store provider.
52
- #[serde(skip)]
53
- cookie_provider: Option<Jar>,
52
+ #[serde(default)]
53
+ cookie_provider: NativeOption<Jar>,
54
54
 
55
55
  // ========= Timeout options =========
56
56
  /// The timeout to use for the client. (in seconds)
@@ -68,7 +68,7 @@ struct Builder {
68
68
  /// Set the number of retries for TCP keepalive.
69
69
  tcp_keepalive_retries: Option<u32>,
70
70
  /// Set an optional user timeout for TCP sockets. (in seconds)
71
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
71
+ #[allow(dead_code)]
72
72
  tcp_user_timeout: Option<u64>,
73
73
  /// Set that all sockets have `NO_DELAY` set.
74
74
  tcp_nodelay: Option<bool>,
@@ -92,15 +92,15 @@ struct Builder {
92
92
  https_only: Option<bool>,
93
93
 
94
94
  // ========= TLS options =========
95
- /// Whether to verify the SSL certificate or root certificate file path.
95
+ /// Whether to verify TLS certificates.
96
96
  verify: Option<bool>,
97
97
 
98
98
  // ========= Network options =========
99
99
  /// Whether to disable the proxy for the client.
100
100
  no_proxy: Option<bool>,
101
101
  /// The proxy to use for the client.
102
- #[serde(skip)]
103
- proxy: Option<Proxy>,
102
+ #[serde(default)]
103
+ proxy: NativeOption<Proxy>,
104
104
  /// Bind to a local IP Address.
105
105
  local_address: Option<IpAddr>,
106
106
  /// Bind to an interface by `SO_BINDTODEVICE`.
@@ -118,42 +118,65 @@ struct Builder {
118
118
  zstd: Option<bool>,
119
119
  }
120
120
 
121
- #[derive(Clone, Default)]
121
+ #[derive(Clone)]
122
122
  #[magnus::wrap(class = "Wreq::Client", free_immediately, size)]
123
123
  pub struct Client(wreq::Client);
124
124
 
125
125
  // ===== impl Builder =====
126
126
 
127
127
  impl Builder {
128
- /// Create a new [`Builder`] from Ruby keyword arguments.
129
- fn new(ruby: &magnus::Ruby, keyword: &Value) -> Result<Self, magnus::Error> {
130
- let Ok(hash) = RHash::try_convert(*keyword) else {
131
- return Ok(Default::default());
132
- };
133
-
134
- let mut builder: Self = serde_magnus::deserialize(ruby, hash)?;
135
-
136
- if let Some(v) = hash.get(ruby.to_symbol(stringify!(emulation))) {
137
- builder.emulation = Some((*Obj::<Emulation>::try_convert(v)?).clone());
138
- }
139
-
140
- if let Some(v) = hash.get(ruby.to_symbol(stringify!(user_agent))) {
141
- builder.user_agent = Some(UserAgent::try_convert(v)?);
142
- }
143
-
144
- if let Some(v) = hash.get(ruby.to_symbol(stringify!(headers))) {
145
- builder.headers = Some(Headers::try_convert(v)?);
146
- }
147
-
148
- if let Some(v) = hash.get(ruby.to_symbol(stringify!(orig_headers))) {
149
- builder.orig_headers = Some(OrigHeaders::try_convert(v)?);
150
- }
151
-
152
- if let Some(v) = hash.get(ruby.to_symbol(stringify!(cookie_provider))) {
153
- builder.cookie_provider = Some((*Obj::<Jar>::try_convert(v)?).clone());
154
- }
155
-
156
- builder.proxy = Extractor::<Proxy>::try_convert(*keyword)?.into_inner();
128
+ /// Create a new [`Builder`] from a Ruby options Hash.
129
+ ///
130
+ /// # Errors
131
+ ///
132
+ /// Returns `ArgumentError` for unknown, duplicate, conflicting,
133
+ /// ineffective, or platform-specific options. Known values retain their
134
+ /// Ruby conversion error class and include the option name.
135
+ fn from_options(options: Options<'_>) -> Result<Self, magnus::Error> {
136
+ let options = options.validate_keys::<Self>()?;
137
+ let mut builder = options
138
+ .validator()
139
+ .reject_unsupported(stringify!(tcp_user_timeout), SUPPORTS_TCP_USER_TIMEOUT)
140
+ .reject_unsupported(stringify!(interface), SUPPORTS_INTERFACE)
141
+ .finish()?
142
+ .deserialize::<Self>()?;
143
+
144
+ options
145
+ .validator()
146
+ .reject_conflicts([
147
+ (stringify!(http1_only), builder.http1_only == Some(true)),
148
+ (stringify!(http2_only), builder.http2_only == Some(true)),
149
+ ])
150
+ .reject_conflicts([
151
+ (stringify!(proxy), options.is_non_nil(stringify!(proxy))),
152
+ (stringify!(no_proxy), builder.no_proxy == Some(true)),
153
+ ])
154
+ .require_when_present(
155
+ stringify!(max_redirects),
156
+ builder.max_redirects.is_some(),
157
+ builder.allow_redirects == Some(true),
158
+ ":allow_redirects to be true",
159
+ )
160
+ .finish()?;
161
+
162
+ extract_native_option!(
163
+ options,
164
+ builder,
165
+ emulation,
166
+ Obj<Emulation> => |value| (*value).clone()
167
+ );
168
+ extract_native_option!(options, builder, user_agent);
169
+ extract_native_option!(options, builder, headers);
170
+ extract_native_option!(options, builder, orig_headers);
171
+ extract_native_option!(
172
+ options,
173
+ builder,
174
+ cookie_provider,
175
+ Obj<Jar> => |value| (*value).clone()
176
+ );
177
+ builder
178
+ .proxy
179
+ .set(Extractor::<Proxy>::try_convert(options.as_value())?.into_inner());
157
180
 
158
181
  Ok(builder)
159
182
  }
@@ -163,234 +186,291 @@ impl Builder {
163
186
 
164
187
  impl Client {
165
188
  /// Create a new [`Client`] with the given keyword arguments.
166
- pub fn new(ruby: &Ruby, keyword: &[Value]) -> Result<Self, magnus::Error> {
167
- if let Some(keyword) = keyword.first() {
168
- let mut params = Builder::new(ruby, keyword)?;
169
- gvl::nogvl(|| {
170
- let mut builder = wreq::Client::builder();
171
-
172
- // Emulation options.
173
- apply_option!(set_if_some_inner, builder, params.emulation, emulation);
174
-
175
- // User agent options.
176
- apply_option!(set_if_some_inner, builder, params.user_agent, user_agent);
177
-
178
- // Headers options.
179
- apply_option!(
180
- set_if_some_into_inner,
181
- builder,
182
- params.headers,
183
- default_headers
184
- );
185
- apply_option!(
186
- set_if_some_inner,
187
- builder,
188
- params.orig_headers,
189
- orig_headers
190
- );
191
-
192
- // Allow redirects options.
193
- apply_option!(set_if_some, builder, params.referer, referer);
194
- apply_option!(
195
- set_if_true_with,
196
- builder,
197
- params.allow_redirects,
198
- redirect,
199
- false,
200
- params
201
- .max_redirects
202
- .take()
203
- .map(wreq::redirect::Policy::limited)
204
- .unwrap_or_default()
205
- );
206
-
207
- // Cookie options.
208
- apply_option!(set_if_some, builder, params.cookie_store, cookie_store);
209
- apply_option!(
210
- set_if_some_inner,
211
- builder,
212
- params.cookie_provider,
213
- cookie_provider
214
- );
215
-
216
- // TCP options.
217
- apply_option!(
218
- set_if_some_map,
219
- builder,
220
- params.tcp_keepalive,
221
- tcp_keepalive,
222
- Duration::from_secs
223
- );
224
- apply_option!(
225
- set_if_some_map,
226
- builder,
227
- params.tcp_keepalive_interval,
228
- tcp_keepalive_interval,
229
- Duration::from_secs
230
- );
231
- apply_option!(
232
- set_if_some,
233
- builder,
234
- params.tcp_keepalive_retries,
235
- tcp_keepalive_retries
236
- );
237
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
238
- apply_option!(
239
- set_if_some_map,
240
- builder,
241
- params.tcp_user_timeout,
242
- tcp_user_timeout,
243
- Duration::from_secs
244
- );
245
- apply_option!(set_if_some, builder, params.tcp_nodelay, tcp_nodelay);
246
- apply_option!(
247
- set_if_some,
248
- builder,
249
- params.tcp_reuse_address,
250
- tcp_reuse_address
251
- );
252
-
253
- // Timeout options.
254
- apply_option!(
255
- set_if_some_map,
256
- builder,
257
- params.timeout,
258
- timeout,
259
- Duration::from_secs
260
- );
261
- apply_option!(
262
- set_if_some_map,
263
- builder,
264
- params.connect_timeout,
265
- connect_timeout,
266
- Duration::from_secs
267
- );
268
- apply_option!(
269
- set_if_some_map,
270
- builder,
271
- params.read_timeout,
272
- read_timeout,
273
- Duration::from_secs
274
- );
275
-
276
- // Pool options.
277
- apply_option!(
278
- set_if_some_map,
279
- builder,
280
- params.pool_idle_timeout,
281
- pool_idle_timeout,
282
- Duration::from_secs
283
- );
284
- apply_option!(
285
- set_if_some,
286
- builder,
287
- params.pool_max_idle_per_host,
288
- pool_max_idle_per_host
289
- );
290
- apply_option!(set_if_some, builder, params.pool_max_size, pool_max_size);
291
-
292
- // Protocol options.
293
- apply_option!(set_if_true, builder, params.http1_only, http1_only, false);
294
- apply_option!(set_if_true, builder, params.http2_only, http2_only, false);
295
- apply_option!(set_if_some, builder, params.https_only, https_only);
296
-
297
- // TLS options.
298
- apply_option!(set_if_some, builder, params.verify, tls_cert_verification);
299
-
300
- // Network options.
301
- apply_option!(set_if_some, builder, params.proxy, proxy);
302
- apply_option!(set_if_true, builder, params.no_proxy, no_proxy, false);
303
- apply_option!(set_if_some, builder, params.local_address, local_address);
304
- #[cfg(any(
305
- target_os = "android",
306
- target_os = "fuchsia",
307
- target_os = "illumos",
308
- target_os = "ios",
309
- target_os = "linux",
310
- target_os = "macos",
311
- target_os = "solaris",
312
- target_os = "tvos",
313
- target_os = "visionos",
314
- target_os = "watchos",
315
- ))]
316
- apply_option!(set_if_some, builder, params.interface, interface);
317
-
318
- // Compression options.
319
- apply_option!(set_if_some, builder, params.gzip, gzip);
320
- apply_option!(set_if_some, builder, params.brotli, brotli);
321
- apply_option!(set_if_some, builder, params.deflate, deflate);
322
- apply_option!(set_if_some, builder, params.zstd, zstd);
323
-
324
- builder.build().map(Client).map_err(wreq_error_to_magnus)
325
- })
326
- } else {
327
- gvl::nogvl(|| Ok(Self(wreq::Client::new())))
328
- }
189
+ ///
190
+ /// # Errors
191
+ ///
192
+ /// Returns Ruby configuration errors from [`Builder::from_options`] or the
193
+ /// native fallible client builder. Extra positional arguments return
194
+ /// `ArgumentError`.
195
+ pub fn new(ruby: &Ruby, args: &[Value]) -> Result<Self, magnus::Error> {
196
+ Options::from_args(ruby, args, "client")?
197
+ .map(Builder::from_options)
198
+ .transpose()
199
+ .map(Option::unwrap_or_default)
200
+ .and_then(|params| Self::build(ruby, params))
201
+ }
202
+
203
+ /// Build the default client through the same fallible path as `new`.
204
+ ///
205
+ /// # Errors
206
+ ///
207
+ /// Returns `Wreq::BuilderError`, `Wreq::TlsError`, or another mapped native
208
+ /// initialization error without unwinding through Ruby.
209
+ pub(crate) fn default_client(ruby: &Ruby) -> Result<Self, magnus::Error> {
210
+ Self::build(ruby, Builder::default())
211
+ }
212
+
213
+ /// Apply validated parameters and build the native client without the GVL.
214
+ ///
215
+ /// # Errors
216
+ ///
217
+ /// Maps native build failures only after the GVL has been reacquired.
218
+ fn build(ruby: &Ruby, mut params: Builder) -> Result<Self, magnus::Error> {
219
+ let result = gvl::nogvl(|| {
220
+ let mut builder = wreq::Client::builder();
221
+
222
+ // Emulation options.
223
+ apply_option!(set_if_some_inner, builder, params.emulation, emulation);
224
+
225
+ // User agent options.
226
+ apply_option!(set_if_some_inner, builder, params.user_agent, user_agent);
227
+
228
+ // Headers options.
229
+ apply_option!(
230
+ set_if_some_into_inner,
231
+ builder,
232
+ params.headers,
233
+ default_headers
234
+ );
235
+ apply_option!(
236
+ set_if_some_inner,
237
+ builder,
238
+ params.orig_headers,
239
+ orig_headers
240
+ );
241
+
242
+ // Allow redirects options.
243
+ apply_option!(set_if_some, builder, params.referer, referer);
244
+ match params.allow_redirects {
245
+ Some(false) => {
246
+ builder = builder.redirect(wreq::redirect::Policy::none());
247
+ }
248
+ Some(true) => {
249
+ builder = builder.redirect(
250
+ params
251
+ .max_redirects
252
+ .take()
253
+ .map(wreq::redirect::Policy::limited)
254
+ .unwrap_or_default(),
255
+ );
256
+ }
257
+ None => {}
258
+ }
259
+
260
+ // Cookie options.
261
+ apply_option!(set_if_some, builder, params.cookie_store, cookie_store);
262
+ apply_option!(
263
+ set_if_some_inner,
264
+ builder,
265
+ params.cookie_provider,
266
+ cookie_provider
267
+ );
268
+
269
+ // TCP options.
270
+ apply_option!(
271
+ set_if_some_map,
272
+ builder,
273
+ params.tcp_keepalive,
274
+ tcp_keepalive,
275
+ Duration::from_secs
276
+ );
277
+ apply_option!(
278
+ set_if_some_map,
279
+ builder,
280
+ params.tcp_keepalive_interval,
281
+ tcp_keepalive_interval,
282
+ Duration::from_secs
283
+ );
284
+ apply_option!(
285
+ set_if_some,
286
+ builder,
287
+ params.tcp_keepalive_retries,
288
+ tcp_keepalive_retries
289
+ );
290
+ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
291
+ apply_option!(
292
+ set_if_some_map,
293
+ builder,
294
+ params.tcp_user_timeout,
295
+ tcp_user_timeout,
296
+ Duration::from_secs
297
+ );
298
+ apply_option!(set_if_some, builder, params.tcp_nodelay, tcp_nodelay);
299
+ apply_option!(
300
+ set_if_some,
301
+ builder,
302
+ params.tcp_reuse_address,
303
+ tcp_reuse_address
304
+ );
305
+
306
+ // Timeout options.
307
+ apply_option!(
308
+ set_if_some_map,
309
+ builder,
310
+ params.timeout,
311
+ timeout,
312
+ Duration::from_secs
313
+ );
314
+ apply_option!(
315
+ set_if_some_map,
316
+ builder,
317
+ params.connect_timeout,
318
+ connect_timeout,
319
+ Duration::from_secs
320
+ );
321
+ apply_option!(
322
+ set_if_some_map,
323
+ builder,
324
+ params.read_timeout,
325
+ read_timeout,
326
+ Duration::from_secs
327
+ );
328
+
329
+ // Pool options.
330
+ apply_option!(
331
+ set_if_some_map,
332
+ builder,
333
+ params.pool_idle_timeout,
334
+ pool_idle_timeout,
335
+ Duration::from_secs
336
+ );
337
+ apply_option!(
338
+ set_if_some,
339
+ builder,
340
+ params.pool_max_idle_per_host,
341
+ pool_max_idle_per_host
342
+ );
343
+ apply_option!(set_if_some, builder, params.pool_max_size, pool_max_size);
344
+
345
+ // Protocol options.
346
+ apply_option!(set_if_true, builder, params.http1_only, http1_only, false);
347
+ apply_option!(set_if_true, builder, params.http2_only, http2_only, false);
348
+ apply_option!(set_if_some, builder, params.https_only, https_only);
349
+
350
+ // TLS options.
351
+ apply_option!(set_if_some, builder, params.verify, tls_cert_verification);
352
+
353
+ // Network options.
354
+ apply_option!(set_if_some, builder, params.proxy, proxy);
355
+ apply_option!(set_if_true, builder, params.no_proxy, no_proxy, false);
356
+ apply_option!(set_if_some, builder, params.local_address, local_address);
357
+ #[cfg(any(
358
+ target_os = "android",
359
+ target_os = "fuchsia",
360
+ target_os = "illumos",
361
+ target_os = "ios",
362
+ target_os = "linux",
363
+ target_os = "macos",
364
+ target_os = "solaris",
365
+ target_os = "tvos",
366
+ target_os = "visionos",
367
+ target_os = "watchos",
368
+ ))]
369
+ apply_option!(set_if_some, builder, params.interface, interface);
370
+
371
+ // Compression options.
372
+ apply_option!(set_if_some, builder, params.gzip, gzip);
373
+ apply_option!(set_if_some, builder, params.brotli, brotli);
374
+ apply_option!(set_if_some, builder, params.deflate, deflate);
375
+ apply_option!(set_if_some, builder, params.zstd, zstd);
376
+
377
+ builder.build().map(Client)
378
+ });
379
+
380
+ // Ruby exceptions must be created after the GVL has been reacquired.
381
+ result.map_err(|err| wreq_error(ruby, err))
329
382
  }
330
383
  }
331
384
 
332
385
  impl Client {
386
+ /// Send a request through a newly built default client.
387
+ ///
388
+ /// Request arguments are validated before the native client is built, so
389
+ /// invalid options fail without initializing a connection pool.
390
+ pub(crate) fn request_with_default_client(
391
+ ruby: &Ruby,
392
+ args: &[Value],
393
+ ) -> Result<Response, magnus::Error> {
394
+ let ((method, url), request) = extract_request!(args, (Obj<Method>, String));
395
+ let client = Self::default_client(ruby)?;
396
+ execute_request(ruby, client.0, *method, url, request)
397
+ }
398
+
399
+ /// Send a request with `method` through a newly built default client.
400
+ ///
401
+ /// Request arguments are validated before the native client is built, so
402
+ /// invalid options fail without initializing a connection pool.
403
+ pub(crate) fn execute_with_default_client(
404
+ ruby: &Ruby,
405
+ method: Method,
406
+ args: &[Value],
407
+ ) -> Result<Response, magnus::Error> {
408
+ let ((url,), request) = extract_request!(args, (String,));
409
+ let client = Self::default_client(ruby)?;
410
+ execute_request(ruby, client.0, method, url, request)
411
+ }
412
+
333
413
  /// Send a HTTP request.
334
414
  #[inline]
335
- pub fn request(rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
415
+ pub fn request(ruby: &Ruby, rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
336
416
  let ((method, url), request) = extract_request!(args, (Obj<Method>, String));
337
- execute_request(rb_self.0.clone(), *method, url, request)
417
+ execute_request(ruby, rb_self.0.clone(), *method, url, request)
338
418
  }
339
419
 
340
420
  /// Send a GET request.
341
421
  #[inline]
342
- pub fn get(rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
422
+ pub fn get(ruby: &Ruby, rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
343
423
  let ((url,), request) = extract_request!(args, (String,));
344
- execute_request(rb_self.0.clone(), Method::GET, url, request)
424
+ execute_request(ruby, rb_self.0.clone(), Method::GET, url, request)
345
425
  }
346
426
 
347
427
  /// Send a POST request.
348
428
  #[inline]
349
- pub fn post(rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
429
+ pub fn post(ruby: &Ruby, rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
350
430
  let ((url,), request) = extract_request!(args, (String,));
351
- execute_request(rb_self.0.clone(), Method::POST, url, request)
431
+ execute_request(ruby, rb_self.0.clone(), Method::POST, url, request)
352
432
  }
353
433
 
354
434
  /// Send a PUT request.
355
435
  #[inline]
356
- pub fn put(rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
436
+ pub fn put(ruby: &Ruby, rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
357
437
  let ((url,), request) = extract_request!(args, (String,));
358
- execute_request(rb_self.0.clone(), Method::PUT, url, request)
438
+ execute_request(ruby, rb_self.0.clone(), Method::PUT, url, request)
359
439
  }
360
440
 
361
441
  /// Send a DELETE request.
362
442
  #[inline]
363
- pub fn delete(rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
443
+ pub fn delete(ruby: &Ruby, rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
364
444
  let ((url,), request) = extract_request!(args, (String,));
365
- execute_request(rb_self.0.clone(), Method::DELETE, url, request)
445
+ execute_request(ruby, rb_self.0.clone(), Method::DELETE, url, request)
366
446
  }
367
447
 
368
448
  /// Send a HEAD request.
369
449
  #[inline]
370
- pub fn head(rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
450
+ pub fn head(ruby: &Ruby, rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
371
451
  let ((url,), request) = extract_request!(args, (String,));
372
- execute_request(rb_self.0.clone(), Method::HEAD, url, request)
452
+ execute_request(ruby, rb_self.0.clone(), Method::HEAD, url, request)
373
453
  }
374
454
 
375
455
  /// Send an OPTIONS request.
376
456
  #[inline]
377
- pub fn options(rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
457
+ pub fn options(ruby: &Ruby, rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
378
458
  let ((url,), request) = extract_request!(args, (String,));
379
- execute_request(rb_self.0.clone(), Method::OPTIONS, url, request)
459
+ execute_request(ruby, rb_self.0.clone(), Method::OPTIONS, url, request)
380
460
  }
381
461
 
382
462
  /// Send a TRACE request.
383
463
  #[inline]
384
- pub fn trace(rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
464
+ pub fn trace(ruby: &Ruby, rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
385
465
  let ((url,), request) = extract_request!(args, (String,));
386
- execute_request(rb_self.0.clone(), Method::TRACE, url, request)
466
+ execute_request(ruby, rb_self.0.clone(), Method::TRACE, url, request)
387
467
  }
388
468
 
389
469
  /// Send a PATCH request.
390
470
  #[inline]
391
- pub fn patch(rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
471
+ pub fn patch(ruby: &Ruby, rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
392
472
  let ((url,), request) = extract_request!(args, (String,));
393
- execute_request(rb_self.0.clone(), Method::PATCH, url, request)
473
+ execute_request(ruby, rb_self.0.clone(), Method::PATCH, url, request)
394
474
  }
395
475
  }
396
476