wreq 1.2.2 → 1.2.4
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.
- checksums.yaml +4 -4
- data/Cargo.lock +45 -67
- data/Cargo.toml +2 -2
- data/Gemfile +1 -0
- data/README.md +7 -4
- data/build.rs +7 -0
- data/docs/windows-gnu-tokio-crash.md +70 -0
- data/examples/emulate_request.rb +1 -1
- data/lib/wreq_ruby/emulate.rb +1 -0
- data/script/build_windows_gnu.ps1 +264 -0
- data/src/arch.rs +33 -0
- data/src/client/body/stream.rs +12 -9
- data/src/client/req.rs +122 -110
- data/src/client/resp.rs +9 -17
- data/src/client.rs +13 -0
- data/src/cookie.rs +1 -3
- data/src/emulate.rs +3 -142
- data/src/http.rs +2 -13
- data/src/lib.rs +1 -0
- data/src/macros.rs +10 -0
- data/src/rt.rs +26 -9
- data/test/client_cookie_test.rb +6 -6
- data/test/client_test.rb +16 -16
- data/test/cookie_test.rb +8 -6
- data/test/error_handling_test.rb +4 -4
- data/test/header_test.rb +1 -1
- data/test/inspect_test.rb +4 -4
- data/test/module_methods_test.rb +11 -11
- data/test/request_parameters_test.rb +30 -30
- data/test/request_test.rb +22 -22
- data/test/response_test.rb +6 -6
- data/test/stream_test.rb +61 -35
- data/test/test_helper.rb +46 -3
- metadata +4 -1
data/src/emulate.rs
CHANGED
|
@@ -49,6 +49,7 @@ define_ruby_enum!(
|
|
|
49
49
|
Chrome146,
|
|
50
50
|
Chrome147,
|
|
51
51
|
Chrome148,
|
|
52
|
+
Chrome149,
|
|
52
53
|
|
|
53
54
|
Edge101,
|
|
54
55
|
Edge122,
|
|
@@ -221,152 +222,12 @@ pub fn include(ruby: &Ruby, gem_module: &RModule) -> Result<(), Error> {
|
|
|
221
222
|
// Profile enum binding
|
|
222
223
|
let profile = gem_module.define_class("Profile", ruby.class_object())?;
|
|
223
224
|
profile.define_method("to_s", method!(Profile::to_s, 0))?;
|
|
224
|
-
|
|
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)?;
|
|
225
|
+
Profile::define_constants(profile)?;
|
|
361
226
|
|
|
362
227
|
// Platform enum binding
|
|
363
228
|
let platform = gem_module.define_class("Platform", ruby.class_object())?;
|
|
364
229
|
platform.define_method("to_s", method!(Platform::to_s, 0))?;
|
|
365
|
-
|
|
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)?;
|
|
230
|
+
Platform::define_constants(platform)?;
|
|
370
231
|
|
|
371
232
|
// Emulation class binding
|
|
372
233
|
let emulation = gem_module.define_class("Emulation", ruby.class_object())?;
|
data/src/http.rs
CHANGED
|
@@ -111,21 +111,10 @@ impl From<wreq::StatusCode> for StatusCode {
|
|
|
111
111
|
|
|
112
112
|
pub fn include(ruby: &Ruby, gem_module: &RModule) -> Result<(), Error> {
|
|
113
113
|
let method_class = gem_module.define_class("Method", ruby.class_object())?;
|
|
114
|
-
|
|
115
|
-
method_class.const_set("POST", Method::POST)?;
|
|
116
|
-
method_class.const_set("PUT", Method::PUT)?;
|
|
117
|
-
method_class.const_set("DELETE", Method::DELETE)?;
|
|
118
|
-
method_class.const_set("PATCH", Method::PATCH)?;
|
|
119
|
-
method_class.const_set("HEAD", Method::HEAD)?;
|
|
120
|
-
method_class.const_set("TRACE", Method::TRACE)?;
|
|
121
|
-
method_class.const_set("OPTIONS", Method::OPTIONS)?;
|
|
114
|
+
Method::define_constants(method_class)?;
|
|
122
115
|
|
|
123
116
|
let version_class = gem_module.define_class("Version", ruby.class_object())?;
|
|
124
|
-
|
|
125
|
-
version_class.const_set("HTTP_10", Version::HTTP_10)?;
|
|
126
|
-
version_class.const_set("HTTP_11", Version::HTTP_11)?;
|
|
127
|
-
version_class.const_set("HTTP_2", Version::HTTP_2)?;
|
|
128
|
-
version_class.const_set("HTTP_3", Version::HTTP_3)?;
|
|
117
|
+
Version::define_constants(version_class)?;
|
|
129
118
|
version_class.define_method("to_s", method!(Version::to_s, 0))?;
|
|
130
119
|
version_class.define_method("==", method!(Version::equals, 1))?;
|
|
131
120
|
|
data/src/lib.rs
CHANGED
data/src/macros.rs
CHANGED
|
@@ -75,6 +75,11 @@ macro_rules! define_ruby_enum {
|
|
|
75
75
|
_ => unreachable!(),
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
+
|
|
79
|
+
pub fn define_constants(class: magnus::RClass) -> Result<(), magnus::Error> {
|
|
80
|
+
$(class.const_set(stringify!($rust_variant), <$enum_type>::$rust_variant)?;)*
|
|
81
|
+
Ok(())
|
|
82
|
+
}
|
|
78
83
|
}
|
|
79
84
|
};
|
|
80
85
|
|
|
@@ -103,6 +108,11 @@ macro_rules! define_ruby_enum {
|
|
|
103
108
|
_ => unreachable!(),
|
|
104
109
|
}
|
|
105
110
|
}
|
|
111
|
+
|
|
112
|
+
pub fn define_constants(class: magnus::RClass) -> Result<(), magnus::Error> {
|
|
113
|
+
$(class.const_set(stringify!($rust_variant), <$enum_type>::$rust_variant)?;)*
|
|
114
|
+
Ok(())
|
|
115
|
+
}
|
|
106
116
|
}
|
|
107
117
|
};
|
|
108
118
|
}
|
data/src/rt.rs
CHANGED
|
@@ -5,25 +5,42 @@ use tokio::runtime::{Builder, Runtime};
|
|
|
5
5
|
use crate::{error::interrupt_error, gvl};
|
|
6
6
|
|
|
7
7
|
static RUNTIME: LazyLock<Runtime> = LazyLock::new(|| {
|
|
8
|
-
Builder::new_multi_thread()
|
|
8
|
+
let mut builder = Builder::new_multi_thread();
|
|
9
|
+
|
|
10
|
+
builder
|
|
9
11
|
.enable_all()
|
|
10
12
|
.build()
|
|
11
13
|
.expect("Failed to initialize Tokio runtime")
|
|
12
14
|
});
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
enum BlockOnError<E> {
|
|
17
|
+
Interrupted,
|
|
18
|
+
Future(E),
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/// Block on a future to completion on the global Tokio runtime.
|
|
22
|
+
///
|
|
23
|
+
/// The future runs without Ruby's GVL, so it must not construct Ruby objects or
|
|
24
|
+
/// Ruby exceptions. Convert Rust errors back into Ruby errors after the GVL has
|
|
25
|
+
/// been reacquired.
|
|
26
|
+
pub fn try_block_on<F, T, E, M>(future: F, map_err: M) -> Result<T, magnus::Error>
|
|
17
27
|
where
|
|
18
|
-
F: Future<Output = Result<T,
|
|
28
|
+
F: Future<Output = Result<T, E>>,
|
|
29
|
+
M: FnOnce(E) -> magnus::Error,
|
|
19
30
|
{
|
|
20
|
-
gvl::nogvl_cancellable(|flag| {
|
|
31
|
+
let result = gvl::nogvl_cancellable(|flag| {
|
|
21
32
|
RUNTIME.block_on(async move {
|
|
22
33
|
tokio::select! {
|
|
23
34
|
biased;
|
|
24
|
-
_ = flag.cancelled() => Err(
|
|
25
|
-
result = future => result,
|
|
35
|
+
_ = flag.cancelled() => Err(BlockOnError::Interrupted),
|
|
36
|
+
result = future => result.map_err(BlockOnError::Future),
|
|
26
37
|
}
|
|
27
38
|
})
|
|
28
|
-
})
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
match result {
|
|
42
|
+
Ok(value) => Ok(value),
|
|
43
|
+
Err(BlockOnError::Interrupted) => Err(interrupt_error()),
|
|
44
|
+
Err(BlockOnError::Future(err)) => Err(map_err(err)),
|
|
45
|
+
}
|
|
29
46
|
}
|
data/test/client_cookie_test.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
require "test_helper"
|
|
4
4
|
|
|
5
5
|
class ClientCookieProviderTest < Minitest::Test
|
|
6
|
-
HOST =
|
|
6
|
+
HOST = HTTPBIN_URL
|
|
7
7
|
|
|
8
8
|
def setup
|
|
9
9
|
@jar = Wreq::Jar.new
|
|
@@ -29,9 +29,9 @@ class ClientCookieProviderTest < Minitest::Test
|
|
|
29
29
|
# subsequent request should send the stored cookie automatically
|
|
30
30
|
res2 = @client.get("#{HOST}/cookies")
|
|
31
31
|
assert_equal 200, res2.code
|
|
32
|
-
|
|
33
|
-
assert_kind_of Hash,
|
|
34
|
-
assert_equal "bar",
|
|
32
|
+
cookies = httpbin_cookies(res2.json)
|
|
33
|
+
assert_kind_of Hash, cookies
|
|
34
|
+
assert_equal "bar", httpbin_fetch(cookies, "foo")
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def test_prepopulated_jar_is_used_by_client
|
|
@@ -40,7 +40,7 @@ class ClientCookieProviderTest < Minitest::Test
|
|
|
40
40
|
|
|
41
41
|
res = @client.get("#{HOST}/cookies")
|
|
42
42
|
assert_equal 200, res.code
|
|
43
|
-
cookies = res.json
|
|
44
|
-
assert_equal "1", cookies
|
|
43
|
+
cookies = httpbin_cookies(res.json)
|
|
44
|
+
assert_equal "1", httpbin_fetch(cookies, "pref")
|
|
45
45
|
end
|
|
46
46
|
end
|
data/test/client_test.rb
CHANGED
|
@@ -20,40 +20,40 @@ class ClientTest < Minitest::Test
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def test_get_request
|
|
23
|
-
response = @client.get("
|
|
23
|
+
response = @client.get("#{HTTPBIN_URL}/get")
|
|
24
24
|
refute_nil response
|
|
25
25
|
assert_equal 200, response.code
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def test_post_request
|
|
29
|
-
response = @client.post("
|
|
29
|
+
response = @client.post("#{HTTPBIN_URL}/post",
|
|
30
30
|
json: {test: "wreq-ruby"})
|
|
31
31
|
refute_nil response
|
|
32
32
|
assert_equal 200, response.code
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def test_put_request
|
|
36
|
-
response = @client.put("
|
|
36
|
+
response = @client.put("#{HTTPBIN_URL}/put",
|
|
37
37
|
json: {data: "test"})
|
|
38
38
|
refute_nil response
|
|
39
39
|
assert_equal 200, response.code
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def test_delete_request
|
|
43
|
-
response = @client.delete("
|
|
43
|
+
response = @client.delete("#{HTTPBIN_URL}/delete")
|
|
44
44
|
refute_nil response
|
|
45
45
|
assert_equal 200, response.code
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def test_patch_request
|
|
49
|
-
response = @client.patch("
|
|
49
|
+
response = @client.patch("#{HTTPBIN_URL}/patch",
|
|
50
50
|
json: {update: "field"})
|
|
51
51
|
refute_nil response
|
|
52
52
|
assert_equal 200, response.code
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def test_request_with_query_params
|
|
56
|
-
response = @client.get("
|
|
56
|
+
response = @client.get("#{HTTPBIN_URL}/get",
|
|
57
57
|
query: {"param" => "value"})
|
|
58
58
|
refute_nil response
|
|
59
59
|
assert_equal 200, response.code
|
|
@@ -61,7 +61,7 @@ class ClientTest < Minitest::Test
|
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
def test_request_with_form_data
|
|
64
|
-
response = @client.post("
|
|
64
|
+
response = @client.post("#{HTTPBIN_URL}/post",
|
|
65
65
|
form: {"field" => "value"})
|
|
66
66
|
refute_nil response
|
|
67
67
|
assert_equal 200, response.code
|
|
@@ -69,7 +69,7 @@ class ClientTest < Minitest::Test
|
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
def test_request_with_raw_body
|
|
72
|
-
response = @client.post("
|
|
72
|
+
response = @client.post("#{HTTPBIN_URL}/post",
|
|
73
73
|
body: "raw content",
|
|
74
74
|
headers: {"Content-Type" => "text/plain"})
|
|
75
75
|
refute_nil response
|
|
@@ -78,14 +78,14 @@ class ClientTest < Minitest::Test
|
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
def test_basic_authentication
|
|
81
|
-
response = @client.get("
|
|
81
|
+
response = @client.get("#{HTTPBIN_URL}/basic-auth/user/pass",
|
|
82
82
|
basic_auth: ["user", "pass"])
|
|
83
83
|
refute_nil response
|
|
84
84
|
assert_equal 200, response.code
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
def test_bearer_authentication
|
|
88
|
-
response = @client.get("
|
|
88
|
+
response = @client.get("#{HTTPBIN_URL}/bearer",
|
|
89
89
|
bearer_auth: "test-token")
|
|
90
90
|
refute_nil response
|
|
91
91
|
assert_equal 200, response.code
|
|
@@ -93,21 +93,21 @@ class ClientTest < Minitest::Test
|
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
def test_redirect_following
|
|
96
|
-
response = @client.get("
|
|
96
|
+
response = @client.get("#{HTTPBIN_URL}/redirect/1",
|
|
97
97
|
allow_redirects: true)
|
|
98
98
|
refute_nil response
|
|
99
99
|
assert_equal 200, response.code
|
|
100
100
|
end
|
|
101
101
|
|
|
102
102
|
def test_redirect_blocking
|
|
103
|
-
response = @client.get("
|
|
103
|
+
response = @client.get("#{HTTPBIN_URL}/redirect/1",
|
|
104
104
|
allow_redirects: false)
|
|
105
105
|
refute_nil response
|
|
106
106
|
assert_equal 302, response.code
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
def test_gzip_compression
|
|
110
|
-
response = @client.get("
|
|
110
|
+
response = @client.get("#{HTTPBIN_URL}/gzip", gzip: true)
|
|
111
111
|
refute_nil response
|
|
112
112
|
assert_equal 200, response.code
|
|
113
113
|
end
|
|
@@ -115,12 +115,12 @@ class ClientTest < Minitest::Test
|
|
|
115
115
|
def test_timeout_handling
|
|
116
116
|
# Test that short timeouts properly raise exceptions
|
|
117
117
|
assert_raises(Wreq::TimeoutError) do
|
|
118
|
-
@client.get("
|
|
118
|
+
@client.get("#{HTTPBIN_URL}/delay/10", timeout: 1)
|
|
119
119
|
end
|
|
120
120
|
|
|
121
121
|
# Test that reasonable timeouts work normally
|
|
122
122
|
start_time = Time.now
|
|
123
|
-
response = @client.get("
|
|
123
|
+
response = @client.get("#{HTTPBIN_URL}/delay/1", timeout: 5)
|
|
124
124
|
elapsed = Time.now - start_time
|
|
125
125
|
|
|
126
126
|
refute_nil response
|
|
@@ -129,7 +129,7 @@ class ClientTest < Minitest::Test
|
|
|
129
129
|
end
|
|
130
130
|
|
|
131
131
|
def test_status_codes
|
|
132
|
-
response = @client.get("
|
|
132
|
+
response = @client.get("#{HTTPBIN_URL}/status/404")
|
|
133
133
|
refute_nil response
|
|
134
134
|
assert_equal 404, response.code
|
|
135
135
|
end
|
data/test/cookie_test.rb
CHANGED
|
@@ -157,24 +157,26 @@ class CookieTest < Minitest::Test
|
|
|
157
157
|
def test_request_uncompressed_cookies
|
|
158
158
|
client = Wreq::Client.new
|
|
159
159
|
resp = client.get(
|
|
160
|
-
"
|
|
160
|
+
"#{HTTPBIN_URL}/cookies",
|
|
161
161
|
cookies: {"foo" => "bar", "baz" => "qux"}
|
|
162
162
|
)
|
|
163
163
|
json = resp.json
|
|
164
164
|
assert_instance_of Hash, json
|
|
165
|
-
|
|
166
|
-
assert_equal "
|
|
165
|
+
cookies = json.fetch("cookies", json)
|
|
166
|
+
assert_equal "bar", cookies["foo"]
|
|
167
|
+
assert_equal "qux", cookies["baz"]
|
|
167
168
|
end
|
|
168
169
|
|
|
169
170
|
def test_request_compressed_cookies
|
|
170
171
|
client = Wreq::Client.new
|
|
171
172
|
resp = client.get(
|
|
172
|
-
"
|
|
173
|
+
"#{HTTPBIN_URL}/cookies",
|
|
173
174
|
cookies: "foo=bar; baz=qux"
|
|
174
175
|
)
|
|
175
176
|
json = resp.json
|
|
176
177
|
assert_instance_of Hash, json
|
|
177
|
-
|
|
178
|
-
assert_equal "
|
|
178
|
+
cookies = json.fetch("cookies", json)
|
|
179
|
+
assert_equal "bar", cookies["foo"]
|
|
180
|
+
assert_equal "qux", cookies["baz"]
|
|
179
181
|
end
|
|
180
182
|
end
|
data/test/error_handling_test.rb
CHANGED
|
@@ -21,7 +21,7 @@ class ErrorHandlingTest < Minitest::Test
|
|
|
21
21
|
def test_http_error_status_codes
|
|
22
22
|
# These should not raise errors, just return responses with error codes
|
|
23
23
|
[400, 401, 403, 404, 500, 502, 503].each do |status_code|
|
|
24
|
-
response = Wreq.get("
|
|
24
|
+
response = Wreq.get("#{HTTPBIN_URL}/status/#{status_code}")
|
|
25
25
|
assert_equal status_code, response.code
|
|
26
26
|
# Should not raise an exception for HTTP error codes
|
|
27
27
|
end
|
|
@@ -31,7 +31,7 @@ class ErrorHandlingTest < Minitest::Test
|
|
|
31
31
|
# Test timeout with a delay that should definitely cause timeout
|
|
32
32
|
|
|
33
33
|
# Request with a very short timeout that should fail
|
|
34
|
-
response = Wreq.get("
|
|
34
|
+
response = Wreq.get("#{HTTPBIN_URL}/delay/10", timeout: 1)
|
|
35
35
|
# If we get here, the request didn't timeout (unexpected)
|
|
36
36
|
flunk "Expected timeout error but got response: #{response.code}"
|
|
37
37
|
rescue => e
|
|
@@ -42,7 +42,7 @@ class ErrorHandlingTest < Minitest::Test
|
|
|
42
42
|
|
|
43
43
|
def test_invalid_json_response
|
|
44
44
|
# Get a non-JSON response and try to parse as JSON
|
|
45
|
-
response = Wreq.get("
|
|
45
|
+
response = Wreq.get("#{HTTPBIN_URL}/html")
|
|
46
46
|
assert_equal 200, response.code
|
|
47
47
|
|
|
48
48
|
# Should raise an error when trying to parse HTML as JSON
|
|
@@ -54,7 +54,7 @@ class ErrorHandlingTest < Minitest::Test
|
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
def test_empty_response_json
|
|
57
|
-
response = Wreq.get("
|
|
57
|
+
response = Wreq.get("#{HTTPBIN_URL}/status/204")
|
|
58
58
|
assert_equal 204, response.code
|
|
59
59
|
assert_equal "", response.text
|
|
60
60
|
|
data/test/header_test.rb
CHANGED
|
@@ -2,7 +2,7 @@ require "test_helper"
|
|
|
2
2
|
|
|
3
3
|
class HeadersTest < Minitest::Test
|
|
4
4
|
def setup
|
|
5
|
-
@response = Wreq.get("
|
|
5
|
+
@response = Wreq.get("#{HTTPBIN_URL}/response-headers",
|
|
6
6
|
query: {
|
|
7
7
|
"X-Custom-Header" => "custom-value",
|
|
8
8
|
"X-Multi-Header" => "value1"
|
data/test/inspect_test.rb
CHANGED
|
@@ -84,12 +84,12 @@ class InspectTest < Minitest::Test
|
|
|
84
84
|
# ---- Response ----
|
|
85
85
|
|
|
86
86
|
def test_response_to_s_returns_body
|
|
87
|
-
response = Wreq.get("
|
|
87
|
+
response = Wreq.get("#{HTTPBIN_URL}/json")
|
|
88
88
|
assert_equal response.text, response.to_s
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
def test_response_inspect_format
|
|
92
|
-
response = Wreq.get("
|
|
92
|
+
response = Wreq.get("#{HTTPBIN_URL}/json")
|
|
93
93
|
result = response.inspect
|
|
94
94
|
assert result.start_with?("#<Wreq::Response")
|
|
95
95
|
assert_includes result, "200"
|
|
@@ -99,7 +99,7 @@ class InspectTest < Minitest::Test
|
|
|
99
99
|
# ---- StatusCode ----
|
|
100
100
|
|
|
101
101
|
def test_status_code_inspect
|
|
102
|
-
response = Wreq.get("
|
|
102
|
+
response = Wreq.get("#{HTTPBIN_URL}/status/200")
|
|
103
103
|
result = response.status.inspect
|
|
104
104
|
assert result.start_with?("#<Wreq::StatusCode")
|
|
105
105
|
assert_includes result, response.status.to_s
|
|
@@ -117,7 +117,7 @@ class InspectTest < Minitest::Test
|
|
|
117
117
|
end
|
|
118
118
|
|
|
119
119
|
def test_version_inspect_from_response
|
|
120
|
-
response = Wreq.get("
|
|
120
|
+
response = Wreq.get("#{HTTPBIN_URL}/get")
|
|
121
121
|
result = response.version.inspect
|
|
122
122
|
assert result.start_with?("#<Wreq::Version")
|
|
123
123
|
assert result.end_with?(">")
|
data/test/module_methods_test.rb
CHANGED
|
@@ -2,33 +2,33 @@ require "test_helper"
|
|
|
2
2
|
|
|
3
3
|
class ModuleMethodsTest < Minitest::Test
|
|
4
4
|
def test_module_get
|
|
5
|
-
response = Wreq.get("
|
|
5
|
+
response = Wreq.get("#{HTTPBIN_URL}/get")
|
|
6
6
|
refute_nil response
|
|
7
7
|
assert_equal 200, response.code
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def test_module_post
|
|
11
|
-
response = Wreq.post("
|
|
11
|
+
response = Wreq.post("#{HTTPBIN_URL}/post",
|
|
12
12
|
json: {module: "test"})
|
|
13
13
|
refute_nil response
|
|
14
14
|
assert_equal 200, response.code
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def test_module_put
|
|
18
|
-
response = Wreq.put("
|
|
18
|
+
response = Wreq.put("#{HTTPBIN_URL}/put",
|
|
19
19
|
json: {data: "test"})
|
|
20
20
|
refute_nil response
|
|
21
21
|
assert_equal 200, response.code
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def test_module_delete
|
|
25
|
-
response = Wreq.delete("
|
|
25
|
+
response = Wreq.delete("#{HTTPBIN_URL}/delete")
|
|
26
26
|
refute_nil response
|
|
27
27
|
assert_equal 200, response.code
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def test_module_patch
|
|
31
|
-
response = Wreq.patch("
|
|
31
|
+
response = Wreq.patch("#{HTTPBIN_URL}/patch",
|
|
32
32
|
json: {update: "field"})
|
|
33
33
|
refute_nil response
|
|
34
34
|
assert_equal 200, response.code
|
|
@@ -37,23 +37,23 @@ class ModuleMethodsTest < Minitest::Test
|
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def test_module_request_method
|
|
40
|
-
response = Wreq.request(Wreq::Method::GET, "
|
|
40
|
+
response = Wreq.request(Wreq::Method::GET, "#{HTTPBIN_URL}/get")
|
|
41
41
|
refute_nil response
|
|
42
42
|
assert_equal 200, response.code
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def test_module_methods_with_parameters
|
|
46
|
-
response = Wreq.get("
|
|
46
|
+
response = Wreq.get("#{HTTPBIN_URL}/get",
|
|
47
47
|
headers: {"Accept" => "application/json"},
|
|
48
48
|
query: {"test" => "module"})
|
|
49
49
|
refute_nil response
|
|
50
|
-
assert_equal
|
|
51
|
-
|
|
50
|
+
assert_equal "#{HTTPBIN_URL}/get?test=module", response.url
|
|
51
|
+
assert_equal "module", httpbin_fetch(response.json["args"], "test")
|
|
52
52
|
assert_equal 200, response.code
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def test_module_post_with_json
|
|
56
|
-
response = Wreq.post("
|
|
56
|
+
response = Wreq.post("#{HTTPBIN_URL}/post",
|
|
57
57
|
json: {
|
|
58
58
|
string: "test",
|
|
59
59
|
number: 123,
|
|
@@ -65,7 +65,7 @@ class ModuleMethodsTest < Minitest::Test
|
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
def test_module_post_with_form
|
|
68
|
-
response = Wreq.post("
|
|
68
|
+
response = Wreq.post("#{HTTPBIN_URL}/post",
|
|
69
69
|
form: {"field1" => "value1", "field2" => "value2"})
|
|
70
70
|
refute_nil response
|
|
71
71
|
assert_equal 200, response.code
|