wreq 1.0.0 → 1.2.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.
data/src/emulate.rs ADDED
@@ -0,0 +1,375 @@
1
+ use magnus::{
2
+ Error, Module, Object, RHash, RModule, Ruby, TryConvert, Value, function, method,
3
+ typed_data::{Inspect, Obj},
4
+ };
5
+
6
+ define_ruby_enum!(
7
+ /// An emulation profile.
8
+ const,
9
+ Profile,
10
+ "Wreq::Profile",
11
+ wreq_util::Profile,
12
+ Chrome100,
13
+ Chrome101,
14
+ Chrome104,
15
+ Chrome105,
16
+ Chrome106,
17
+ Chrome107,
18
+ Chrome108,
19
+ Chrome109,
20
+ Chrome110,
21
+ Chrome114,
22
+ Chrome116,
23
+ Chrome117,
24
+ Chrome118,
25
+ Chrome119,
26
+ Chrome120,
27
+ Chrome123,
28
+ Chrome124,
29
+ Chrome126,
30
+ Chrome127,
31
+ Chrome128,
32
+ Chrome129,
33
+ Chrome130,
34
+ Chrome131,
35
+ Chrome132,
36
+ Chrome133,
37
+ Chrome134,
38
+ Chrome135,
39
+ Chrome136,
40
+ Chrome137,
41
+ Chrome138,
42
+ Chrome139,
43
+ Chrome140,
44
+ Chrome141,
45
+ Chrome142,
46
+ Chrome143,
47
+ Chrome144,
48
+ Chrome145,
49
+ Chrome146,
50
+ Chrome147,
51
+ Chrome148,
52
+
53
+ Edge101,
54
+ Edge122,
55
+ Edge127,
56
+ Edge131,
57
+ Edge134,
58
+ Edge135,
59
+ Edge136,
60
+ Edge137,
61
+ Edge138,
62
+ Edge139,
63
+ Edge140,
64
+ Edge141,
65
+ Edge142,
66
+ Edge143,
67
+ Edge144,
68
+ Edge145,
69
+ Edge146,
70
+ Edge147,
71
+ Edge148,
72
+
73
+ Firefox109,
74
+ Firefox117,
75
+ Firefox128,
76
+ Firefox133,
77
+ Firefox135,
78
+ FirefoxPrivate135,
79
+ FirefoxAndroid135,
80
+ Firefox136,
81
+ FirefoxPrivate136,
82
+ Firefox139,
83
+ Firefox142,
84
+ Firefox143,
85
+ Firefox144,
86
+ Firefox145,
87
+ Firefox146,
88
+ Firefox147,
89
+ Firefox148,
90
+ Firefox149,
91
+ Firefox150,
92
+ Firefox151,
93
+
94
+ SafariIos17_2,
95
+ SafariIos17_4_1,
96
+ SafariIos16_5,
97
+ Safari15_3,
98
+ Safari15_5,
99
+ Safari15_6_1,
100
+ Safari16,
101
+ Safari16_5,
102
+ Safari17_0,
103
+ Safari17_2_1,
104
+ Safari17_4_1,
105
+ Safari17_5,
106
+ Safari17_6,
107
+ Safari18,
108
+ SafariIPad18,
109
+ Safari18_2,
110
+ Safari18_3,
111
+ Safari18_3_1,
112
+ SafariIos18_1_1,
113
+ Safari18_5,
114
+ Safari26,
115
+ Safari26_1,
116
+ Safari26_2,
117
+ Safari26_3,
118
+ Safari26_4,
119
+ SafariIos26,
120
+ SafariIos26_2,
121
+ SafariIPad26,
122
+ SafariIpad26_2,
123
+
124
+ OkHttp3_9,
125
+ OkHttp3_11,
126
+ OkHttp3_13,
127
+ OkHttp3_14,
128
+ OkHttp4_9,
129
+ OkHttp4_10,
130
+ OkHttp4_12,
131
+ OkHttp5,
132
+
133
+ Opera116,
134
+ Opera117,
135
+ Opera118,
136
+ Opera119,
137
+ Opera120,
138
+ Opera121,
139
+ Opera122,
140
+ Opera123,
141
+ Opera124,
142
+ Opera125,
143
+ Opera126,
144
+ Opera127,
145
+ Opera128,
146
+ Opera129,
147
+ Opera130,
148
+ Opera131,
149
+ );
150
+
151
+ define_ruby_enum!(
152
+ /// An emulation profile for OS.
153
+ const,
154
+ Platform,
155
+ "Wreq::Platform",
156
+ wreq_util::Platform,
157
+ Windows,
158
+ MacOS,
159
+ Linux,
160
+ Android,
161
+ IOS,
162
+ );
163
+
164
+ /// A struct to represent the `EmulationOption` class.
165
+ #[derive(Clone)]
166
+ #[magnus::wrap(class = "Wreq::Emulation", free_immediately, size)]
167
+ pub struct Emulation(pub wreq_util::Emulation);
168
+
169
+ // ===== impl Profile =====
170
+
171
+ impl Profile {
172
+ pub fn to_s(&self) -> String {
173
+ self.into_ffi().inspect()
174
+ }
175
+ }
176
+
177
+ // ===== impl Platform =====
178
+
179
+ impl Platform {
180
+ pub fn to_s(&self) -> String {
181
+ self.into_ffi().inspect()
182
+ }
183
+ }
184
+
185
+ // ===== impl Emulation =====
186
+
187
+ impl Emulation {
188
+ fn new(ruby: &Ruby, args: &[Value]) -> Result<Self, Error> {
189
+ let mut profile = None;
190
+ let mut platform = None;
191
+ let mut http2 = None;
192
+ let mut headers = None;
193
+
194
+ if let Some(hash) = args.first().and_then(|v| RHash::from_value(*v)) {
195
+ if let Some(v) = hash.get(ruby.to_symbol(stringify!(profile))) {
196
+ profile = Some(Obj::<Profile>::try_convert(v)?);
197
+ }
198
+ if let Some(v) = hash.get(ruby.to_symbol(stringify!(platform))) {
199
+ platform = Some(Obj::<Platform>::try_convert(v)?);
200
+ }
201
+ if let Some(v) = hash.get(ruby.to_symbol(stringify!(http2))) {
202
+ http2 = Some(bool::try_convert(v)?);
203
+ }
204
+ if let Some(v) = hash.get(ruby.to_symbol(stringify!(headers))) {
205
+ headers = Some(bool::try_convert(v)?);
206
+ }
207
+ }
208
+
209
+ let emulation = wreq_util::Emulation::builder()
210
+ .profile(profile.map(|obj| obj.into_ffi()).unwrap_or_default())
211
+ .platform(platform.map(|os| os.into_ffi()).unwrap_or_default())
212
+ .http2(http2.unwrap_or(true))
213
+ .headers(headers.unwrap_or(true))
214
+ .build();
215
+
216
+ Ok(Self(emulation))
217
+ }
218
+ }
219
+
220
+ pub fn include(ruby: &Ruby, gem_module: &RModule) -> Result<(), Error> {
221
+ // Profile enum binding
222
+ let profile = gem_module.define_class("Profile", ruby.class_object())?;
223
+ profile.define_method("to_s", method!(Profile::to_s, 0))?;
224
+ profile.const_set("Chrome100", Profile::Chrome100)?;
225
+ profile.const_set("Chrome101", Profile::Chrome101)?;
226
+ profile.const_set("Chrome104", Profile::Chrome104)?;
227
+ profile.const_set("Chrome105", Profile::Chrome105)?;
228
+ profile.const_set("Chrome106", Profile::Chrome106)?;
229
+ profile.const_set("Chrome107", Profile::Chrome107)?;
230
+ profile.const_set("Chrome108", Profile::Chrome108)?;
231
+ profile.const_set("Chrome109", Profile::Chrome109)?;
232
+ profile.const_set("Chrome110", Profile::Chrome110)?;
233
+ profile.const_set("Chrome114", Profile::Chrome114)?;
234
+ profile.const_set("Chrome116", Profile::Chrome116)?;
235
+ profile.const_set("Chrome117", Profile::Chrome117)?;
236
+ profile.const_set("Chrome118", Profile::Chrome118)?;
237
+ profile.const_set("Chrome119", Profile::Chrome119)?;
238
+ profile.const_set("Chrome120", Profile::Chrome120)?;
239
+ profile.const_set("Chrome123", Profile::Chrome123)?;
240
+ profile.const_set("Chrome124", Profile::Chrome124)?;
241
+ profile.const_set("Chrome126", Profile::Chrome126)?;
242
+ profile.const_set("Chrome127", Profile::Chrome127)?;
243
+ profile.const_set("Chrome128", Profile::Chrome128)?;
244
+ profile.const_set("Chrome129", Profile::Chrome129)?;
245
+ profile.const_set("Chrome130", Profile::Chrome130)?;
246
+ profile.const_set("Chrome131", Profile::Chrome131)?;
247
+ profile.const_set("Chrome132", Profile::Chrome132)?;
248
+ profile.const_set("Chrome133", Profile::Chrome133)?;
249
+ profile.const_set("Chrome134", Profile::Chrome134)?;
250
+ profile.const_set("Chrome135", Profile::Chrome135)?;
251
+ profile.const_set("Chrome136", Profile::Chrome136)?;
252
+ profile.const_set("Chrome137", Profile::Chrome137)?;
253
+ profile.const_set("Chrome138", Profile::Chrome138)?;
254
+ profile.const_set("Chrome139", Profile::Chrome139)?;
255
+ profile.const_set("Chrome140", Profile::Chrome140)?;
256
+ profile.const_set("Chrome141", Profile::Chrome141)?;
257
+ profile.const_set("Chrome142", Profile::Chrome142)?;
258
+ profile.const_set("Chrome143", Profile::Chrome143)?;
259
+ profile.const_set("Chrome144", Profile::Chrome144)?;
260
+ profile.const_set("Chrome145", Profile::Chrome145)?;
261
+ profile.const_set("Chrome146", Profile::Chrome146)?;
262
+ profile.const_set("Chrome147", Profile::Chrome147)?;
263
+ profile.const_set("Chrome148", Profile::Chrome148)?;
264
+
265
+ profile.const_set("Edge101", Profile::Edge101)?;
266
+ profile.const_set("Edge122", Profile::Edge122)?;
267
+ profile.const_set("Edge127", Profile::Edge127)?;
268
+ profile.const_set("Edge131", Profile::Edge131)?;
269
+ profile.const_set("Edge134", Profile::Edge134)?;
270
+ profile.const_set("Edge135", Profile::Edge135)?;
271
+ profile.const_set("Edge136", Profile::Edge136)?;
272
+ profile.const_set("Edge137", Profile::Edge137)?;
273
+ profile.const_set("Edge138", Profile::Edge138)?;
274
+ profile.const_set("Edge139", Profile::Edge139)?;
275
+ profile.const_set("Edge140", Profile::Edge140)?;
276
+ profile.const_set("Edge141", Profile::Edge141)?;
277
+ profile.const_set("Edge142", Profile::Edge142)?;
278
+ profile.const_set("Edge143", Profile::Edge143)?;
279
+ profile.const_set("Edge144", Profile::Edge144)?;
280
+ profile.const_set("Edge145", Profile::Edge145)?;
281
+ profile.const_set("Edge146", Profile::Edge146)?;
282
+ profile.const_set("Edge147", Profile::Edge147)?;
283
+ profile.const_set("Edge148", Profile::Edge148)?;
284
+
285
+ profile.const_set("Firefox109", Profile::Firefox109)?;
286
+ profile.const_set("Firefox117", Profile::Firefox117)?;
287
+ profile.const_set("Firefox128", Profile::Firefox128)?;
288
+ profile.const_set("Firefox133", Profile::Firefox133)?;
289
+ profile.const_set("Firefox135", Profile::Firefox135)?;
290
+ profile.const_set("FirefoxPrivate135", Profile::FirefoxPrivate135)?;
291
+ profile.const_set("FirefoxAndroid135", Profile::FirefoxAndroid135)?;
292
+ profile.const_set("Firefox136", Profile::Firefox136)?;
293
+ profile.const_set("FirefoxPrivate136", Profile::FirefoxPrivate136)?;
294
+ profile.const_set("Firefox139", Profile::Firefox139)?;
295
+ profile.const_set("Firefox142", Profile::Firefox142)?;
296
+ profile.const_set("Firefox143", Profile::Firefox143)?;
297
+ profile.const_set("Firefox144", Profile::Firefox144)?;
298
+ profile.const_set("Firefox145", Profile::Firefox145)?;
299
+ profile.const_set("Firefox146", Profile::Firefox146)?;
300
+ profile.const_set("Firefox147", Profile::Firefox147)?;
301
+ profile.const_set("Firefox148", Profile::Firefox148)?;
302
+ profile.const_set("Firefox149", Profile::Firefox149)?;
303
+ profile.const_set("Firefox150", Profile::Firefox150)?;
304
+ profile.const_set("Firefox151", Profile::Firefox151)?;
305
+
306
+ profile.const_set("SafariIos17_2", Profile::SafariIos17_2)?;
307
+ profile.const_set("SafariIos17_4_1", Profile::SafariIos17_4_1)?;
308
+ profile.const_set("SafariIos16_5", Profile::SafariIos16_5)?;
309
+ profile.const_set("Safari15_3", Profile::Safari15_3)?;
310
+ profile.const_set("Safari15_5", Profile::Safari15_5)?;
311
+ profile.const_set("Safari15_6_1", Profile::Safari15_6_1)?;
312
+ profile.const_set("Safari16", Profile::Safari16)?;
313
+ profile.const_set("Safari16_5", Profile::Safari16_5)?;
314
+ profile.const_set("Safari17_0", Profile::Safari17_0)?;
315
+ profile.const_set("Safari17_2_1", Profile::Safari17_2_1)?;
316
+ profile.const_set("Safari17_4_1", Profile::Safari17_4_1)?;
317
+ profile.const_set("Safari17_5", Profile::Safari17_5)?;
318
+ profile.const_set("Safari17_6", Profile::Safari17_6)?;
319
+ profile.const_set("Safari18", Profile::Safari18)?;
320
+ profile.const_set("SafariIPad18", Profile::SafariIPad18)?;
321
+ profile.const_set("Safari18_2", Profile::Safari18_2)?;
322
+ profile.const_set("Safari18_3", Profile::Safari18_3)?;
323
+ profile.const_set("Safari18_3_1", Profile::Safari18_3_1)?;
324
+ profile.const_set("SafariIos18_1_1", Profile::SafariIos18_1_1)?;
325
+ profile.const_set("Safari18_5", Profile::Safari18_5)?;
326
+ profile.const_set("Safari26", Profile::Safari26)?;
327
+ profile.const_set("Safari26_1", Profile::Safari26_1)?;
328
+ profile.const_set("Safari26_2", Profile::Safari26_2)?;
329
+ profile.const_set("Safari26_3", Profile::Safari26_3)?;
330
+ profile.const_set("Safari26_4", Profile::Safari26_4)?;
331
+ profile.const_set("SafariIos26", Profile::SafariIos26)?;
332
+ profile.const_set("SafariIos26_2", Profile::SafariIos26_2)?;
333
+ profile.const_set("SafariIPad26", Profile::SafariIPad26)?;
334
+ profile.const_set("SafariIpad26_2", Profile::SafariIpad26_2)?;
335
+
336
+ profile.const_set("OkHttp3_9", Profile::OkHttp3_9)?;
337
+ profile.const_set("OkHttp3_11", Profile::OkHttp3_11)?;
338
+ profile.const_set("OkHttp3_13", Profile::OkHttp3_13)?;
339
+ profile.const_set("OkHttp3_14", Profile::OkHttp3_14)?;
340
+ profile.const_set("OkHttp4_9", Profile::OkHttp4_9)?;
341
+ profile.const_set("OkHttp4_10", Profile::OkHttp4_10)?;
342
+ profile.const_set("OkHttp4_12", Profile::OkHttp4_12)?;
343
+ profile.const_set("OkHttp5", Profile::OkHttp5)?;
344
+
345
+ profile.const_set("Opera116", Profile::Opera116)?;
346
+ profile.const_set("Opera117", Profile::Opera117)?;
347
+ profile.const_set("Opera118", Profile::Opera118)?;
348
+ profile.const_set("Opera119", Profile::Opera119)?;
349
+ profile.const_set("Opera120", Profile::Opera120)?;
350
+ profile.const_set("Opera121", Profile::Opera121)?;
351
+ profile.const_set("Opera122", Profile::Opera122)?;
352
+ profile.const_set("Opera123", Profile::Opera123)?;
353
+ profile.const_set("Opera124", Profile::Opera124)?;
354
+ profile.const_set("Opera125", Profile::Opera125)?;
355
+ profile.const_set("Opera126", Profile::Opera126)?;
356
+ profile.const_set("Opera127", Profile::Opera127)?;
357
+ profile.const_set("Opera128", Profile::Opera128)?;
358
+ profile.const_set("Opera129", Profile::Opera129)?;
359
+ profile.const_set("Opera130", Profile::Opera130)?;
360
+ profile.const_set("Opera131", Profile::Opera131)?;
361
+
362
+ // Platform enum binding
363
+ let platform = gem_module.define_class("Platform", ruby.class_object())?;
364
+ platform.define_method("to_s", method!(Platform::to_s, 0))?;
365
+ platform.const_set("Windows", Platform::Windows)?;
366
+ platform.const_set("MacOS", Platform::MacOS)?;
367
+ platform.const_set("Linux", Platform::Linux)?;
368
+ platform.const_set("Android", Platform::Android)?;
369
+ platform.const_set("IOS", Platform::IOS)?;
370
+
371
+ // Emulation class binding
372
+ let emulation = gem_module.define_class("Emulation", ruby.class_object())?;
373
+ emulation.define_singleton_method("new", function!(Emulation::new, -1))?;
374
+ Ok(())
375
+ }
data/src/error.rs CHANGED
@@ -85,6 +85,14 @@ pub fn interrupt_error() -> MagnusError {
85
85
  MagnusError::new(ruby!().get_inner(&INTERRUPT_ERROR), "request interrupted")
86
86
  }
87
87
 
88
+ /// LocalJumpError for methods that require a Ruby block.
89
+ pub fn no_block_given_error() -> MagnusError {
90
+ MagnusError::new(
91
+ ruby!().exception_local_jump_error(),
92
+ "no block given (yield)",
93
+ )
94
+ }
95
+
88
96
  /// Map [`tokio::sync::mpsc::error::SendError`] to corresponding [`magnus::Error`]
89
97
  pub fn mpsc_send_error_to_magnus<T>(err: SendError<T>) -> MagnusError {
90
98
  MagnusError::new(
data/src/extractor.rs CHANGED
@@ -1,4 +1,3 @@
1
- use bytes::Bytes;
2
1
  use magnus::{RArray, RHash, RString, Ruby, TryConvert, r_hash::ForEach};
3
2
  use wreq::{
4
3
  Proxy, Version,
@@ -138,41 +137,6 @@ impl TryConvert for Extractor<OrigHeaderMap> {
138
137
  }
139
138
  }
140
139
 
141
- // ===== impl Extractor<Vec<HeaderValue>> =====
142
-
143
- impl ExtractorName for Vec<HeaderValue> {
144
- const NAME: &str = "cookies";
145
- }
146
-
147
- impl TryConvert for Extractor<Vec<HeaderValue>> {
148
- fn try_convert(value: magnus::Value) -> Result<Self, magnus::Error> {
149
- use percent_encoding::{NON_ALPHANUMERIC, percent_encode};
150
-
151
- let ruby = Ruby::get_with(value);
152
- let keyword = RHash::try_convert(value)?;
153
-
154
- if let Some(hash) = keyword
155
- .get(ruby.to_symbol(Vec::<HeaderValue>::NAME))
156
- .and_then(RHash::from_value)
157
- {
158
- let mut cookies = Vec::new();
159
- hash.foreach(|name: RString, value: RString| {
160
- let value = value.to_bytes();
161
- let encoded_value = percent_encode(&value, NON_ALPHANUMERIC);
162
- let cookie = format!("{name}={encoded_value}");
163
- let header_value = HeaderValue::from_maybe_shared(Bytes::from(cookie))
164
- .map_err(header_value_error_to_magnus)?;
165
- cookies.push(header_value);
166
- Ok(ForEach::Continue)
167
- })?;
168
-
169
- return Ok(Extractor(Some(cookies)));
170
- }
171
-
172
- Ok(Extractor(None))
173
- }
174
- }
175
-
176
140
  // ===== impl Extractor<Proxy> =====
177
141
 
178
142
  impl ExtractorName for Proxy {
@@ -182,9 +146,9 @@ impl ExtractorName for Proxy {
182
146
  impl TryConvert for Extractor<Proxy> {
183
147
  fn try_convert(value: magnus::Value) -> Result<Self, magnus::Error> {
184
148
  let ruby = Ruby::get_with(value);
185
- let keyword = RHash::try_convert(value)?;
149
+ let rhash = RHash::try_convert(value)?;
186
150
 
187
- if let Some(proxy) = keyword
151
+ if let Some(proxy) = rhash
188
152
  .get(ruby.to_symbol(Proxy::NAME))
189
153
  .and_then(RString::from_value)
190
154
  {
data/src/header.rs CHANGED
@@ -3,8 +3,11 @@ use std::cell::RefCell;
3
3
  use bytes::Bytes;
4
4
  use http::{HeaderMap, HeaderName, HeaderValue};
5
5
  use magnus::{
6
- Error, Module, Object, RArray, RModule, Ruby, block::Yield, function, method,
7
- typed_data::Inspect,
6
+ Error, Module, Object, RArray, RHash, RModule, RString, Ruby, TryConvert, Value,
7
+ block::Yield,
8
+ function, method,
9
+ r_hash::ForEach,
10
+ typed_data::{Inspect, Obj},
8
11
  };
9
12
 
10
13
  use crate::error::{header_name_error_to_magnus, header_value_error_to_magnus};
@@ -15,7 +18,14 @@ use crate::error::{header_name_error_to_magnus, header_value_error_to_magnus};
15
18
  /// accessing, modifying, and iterating over header name-value pairs.
16
19
  #[derive(Clone, Default)]
17
20
  #[magnus::wrap(class = "Wreq::Headers", free_immediately, size)]
18
- pub struct Headers(RefCell<HeaderMap>);
21
+ pub struct Headers(pub RefCell<HeaderMap>);
22
+
23
+ struct HeaderIter {
24
+ inner: http::header::IntoIter<HeaderValue>,
25
+ next_name: Option<HeaderName>,
26
+ }
27
+
28
+ // ===== impl Headers =====
19
29
 
20
30
  impl Headers {
21
31
  /// Create a new empty Headers instance.
@@ -132,11 +142,32 @@ impl From<HeaderMap> for Headers {
132
142
  }
133
143
  }
134
144
 
135
- struct HeaderIter {
136
- inner: http::header::IntoIter<HeaderValue>,
137
- next_name: Option<HeaderName>,
145
+ impl TryConvert for Headers {
146
+ fn try_convert(value: Value) -> Result<Self, Error> {
147
+ if let Some(rhash) = RHash::from_value(value) {
148
+ let mut headers = HeaderMap::new();
149
+
150
+ rhash.foreach(|name: RString, value: RString| {
151
+ let name = HeaderName::from_bytes(&name.to_bytes())
152
+ .map_err(header_name_error_to_magnus)?;
153
+ let value = HeaderValue::from_maybe_shared(value.to_bytes())
154
+ .map_err(header_value_error_to_magnus)?;
155
+ headers.insert(name, value);
156
+
157
+ Ok(ForEach::Continue)
158
+ })?;
159
+
160
+ return Ok(Self::from(headers));
161
+ }
162
+
163
+ Obj::<Headers>::try_convert(value)
164
+ .map(|headers| headers.0.clone())
165
+ .map(Self)
166
+ }
138
167
  }
139
168
 
169
+ // ===== impl HeaderIter =====
170
+
140
171
  impl Iterator for HeaderIter {
141
172
  type Item = (Bytes, Bytes);
142
173
  fn next(&mut self) -> Option<Self::Item> {
data/src/lib.rs CHANGED
@@ -4,7 +4,7 @@
4
4
  mod macros;
5
5
  mod client;
6
6
  mod cookie;
7
- mod emulation;
7
+ mod emulate;
8
8
  mod error;
9
9
  mod extractor;
10
10
  mod gvl;
@@ -91,7 +91,7 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
91
91
  header::include(ruby, &gem_module)?;
92
92
  cookie::include(ruby, &gem_module)?;
93
93
  client::include(ruby, &gem_module)?;
94
- emulation::include(ruby, &gem_module)?;
94
+ emulate::include(ruby, &gem_module)?;
95
95
  error::include(ruby);
96
96
  Ok(())
97
97
  }
data/src/macros.rs CHANGED
@@ -14,6 +14,11 @@ macro_rules! apply_option {
14
14
  $builder = $builder.$method(value.0);
15
15
  }
16
16
  };
17
+ (set_if_some_into_inner, $builder:expr, $option:expr, $method:ident) => {
18
+ if let Some(value) = $option.take() {
19
+ $builder = $builder.$method(value.0.into_inner());
20
+ }
21
+ };
17
22
  (set_if_some_map, $builder:expr, $option:expr, $method:ident, $transform:expr) => {
18
23
  if let Some(value) = $option.take() {
19
24
  $builder = $builder.$method($transform(value));
data/src/rt.rs CHANGED
@@ -27,21 +27,3 @@ where
27
27
  })
28
28
  })
29
29
  }
30
-
31
- /// Block on a future to completion on the global Tokio runtime,
32
- /// returning `None` if cancelled via the provided `CancelFlag`.
33
- #[inline]
34
- pub fn maybe_block_on<F, T>(future: F) -> F::Output
35
- where
36
- F: Future<Output = Option<T>>,
37
- {
38
- gvl::nogvl_cancellable(|flag| {
39
- RUNTIME.block_on(async move {
40
- tokio::select! {
41
- biased;
42
- _ = flag.cancelled() => None,
43
- result = future => result,
44
- }
45
- })
46
- })
47
- }
@@ -36,7 +36,7 @@ class ClientCookieProviderTest < Minitest::Test
36
36
 
37
37
  def test_prepopulated_jar_is_used_by_client
38
38
  # pre-populate jar
39
- @jar.add_cookie_str("pref=1; Path=/", "#{HOST}/")
39
+ @jar.add("pref=1; Path=/", "#{HOST}/")
40
40
 
41
41
  res = @client.get("#{HOST}/cookies")
42
42
  assert_equal 200, res.code
data/test/cookie_test.rb CHANGED
@@ -19,9 +19,9 @@ class CookieTest < Minitest::Test
19
19
  assert_equal 0, cookies.length
20
20
  end
21
21
 
22
- def test_add_cookie_str_and_get_all
22
+ def test_add_and_get_all
23
23
  set_cookie = "sid=abc123; Path=/; Domain=example.com; HttpOnly; Secure"
24
- @jar.add_cookie_str(set_cookie, @base_url)
24
+ @jar.add(set_cookie, @base_url)
25
25
 
26
26
  cookies = @jar.get_all
27
27
  assert_kind_of Array, cookies
@@ -42,9 +42,9 @@ class CookieTest < Minitest::Test
42
42
  end
43
43
 
44
44
  def test_add_multiple_and_remove
45
- @jar.add_cookie_str("a=1; Path=/", @base_url)
46
- @jar.add_cookie_str("b=2; Path=/", @base_url)
47
- @jar.add_cookie_str("c=3; Path=/", @base_url)
45
+ @jar.add("a=1; Path=/", @base_url)
46
+ @jar.add("b=2; Path=/", @base_url)
47
+ @jar.add("c=3; Path=/", @base_url)
48
48
 
49
49
  cookies = @jar.get_all
50
50
  assert_equal 3, cookies.length
@@ -58,8 +58,8 @@ class CookieTest < Minitest::Test
58
58
  end
59
59
 
60
60
  def test_clear
61
- @jar.add_cookie_str("x=1; Path=/", @base_url)
62
- @jar.add_cookie_str("y=2; Path=/", @base_url)
61
+ @jar.add("x=1; Path=/", @base_url)
62
+ @jar.add("y=2; Path=/", @base_url)
63
63
  refute_empty @jar.get_all
64
64
 
65
65
  @jar.clear
@@ -69,7 +69,7 @@ class CookieTest < Minitest::Test
69
69
  def test_max_age_and_expires_optional
70
70
  # Max-Age only
71
71
  @jar.clear
72
- @jar.add_cookie_str("ma=1; Max-Age=3600; Path=/", @base_url)
72
+ @jar.add("ma=1; Max-Age=3600; Path=/", @base_url)
73
73
  c1 = @jar.get_all.find { |c| c.name == "ma" }
74
74
  assert c1
75
75
  # can be nil or Integer; just ensure responds and is truthy integer
@@ -81,7 +81,7 @@ class CookieTest < Minitest::Test
81
81
  # Expires only
82
82
  @jar.clear
83
83
  t = Time.now + 3600
84
- @jar.add_cookie_str("exp=1; Expires=#{t.gmtime.strftime("%a, %d %b %Y %H:%M:%S GMT")}; Path=/", @base_url)
84
+ @jar.add("exp=1; Expires=#{t.gmtime.strftime("%a, %d %b %Y %H:%M:%S GMT")}; Path=/", @base_url)
85
85
  c2 = @jar.get_all.find { |c| c.name == "exp" }
86
86
  assert c2
87
87
  # expires returns Float (unix seconds) or nil
@@ -144,8 +144,8 @@ class CookieTest < Minitest::Test
144
144
 
145
145
  def test_same_site_flags_from_parsed_header
146
146
  @jar.clear
147
- @jar.add_cookie_str("s1=1; Path=/; SameSite=Strict", @base_url)
148
- @jar.add_cookie_str("s2=1; Path=/; SameSite=Lax", @base_url)
147
+ @jar.add("s1=1; Path=/; SameSite=Strict", @base_url)
148
+ @jar.add("s2=1; Path=/; SameSite=Lax", @base_url)
149
149
 
150
150
  cookies = @jar.get_all
151
151
  h = cookies.to_h { |ck| [ck.name, [ck.same_site_strict?, ck.same_site_lax?]] }
@@ -154,13 +154,27 @@ class CookieTest < Minitest::Test
154
154
  assert_equal [false, true], h["s2"]
155
155
  end
156
156
 
157
- def test_request_cookie_value_percent_encoding
158
- raw_value = "hello world?"
157
+ def test_request_uncompressed_cookies
159
158
  client = Wreq::Client.new
160
159
  resp = client.get(
161
- "http://localhost:8080/cookies",
162
- cookies: {"mykey" => raw_value}
160
+ "https://httpbin.io/cookies",
161
+ cookies: {"foo" => "bar", "baz" => "qux"}
163
162
  )
164
- assert_includes resp.text, "hello%20world%3F"
163
+ json = resp.json
164
+ assert_instance_of Hash, json
165
+ assert_equal "bar", json["foo"]
166
+ assert_equal "qux", json["baz"]
167
+ end
168
+
169
+ def test_request_compressed_cookies
170
+ client = Wreq::Client.new
171
+ resp = client.get(
172
+ "https://httpbin.io/cookies",
173
+ cookies: "foo=bar; baz=qux"
174
+ )
175
+ json = resp.json
176
+ assert_instance_of Hash, json
177
+ assert_equal "bar", json["foo"]
178
+ assert_equal "qux", json["baz"]
165
179
  end
166
180
  end