wreq 1.2.1-aarch64-linux → 1.2.3-aarch64-linux

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a4fe6a278e93c2752ad962e6463bb9815640b95f1c529bfa8dcc699cc198be2a
4
- data.tar.gz: a4390325af71d1a5b0377cc7e8412ee83f7b630a16a34c7df6e3e256e6a7ab19
3
+ metadata.gz: a47ab39ac373c828bb5dfe512749ece2faa56629c8db42e38bf18a22ce15d515
4
+ data.tar.gz: fb70422e9029953e2a53974f03bb398eac6f9b3a1453f47cd8d4bc6aec6ba40f
5
5
  SHA512:
6
- metadata.gz: 6ccdfd91b1f58b450bdb5fed549e53be41ee98e0294304c402b2804271fa1abe9449beef9cdbf241dd1024d6ad5f48c3294d2b0f9b4dd494e85eb1945350dc0a
7
- data.tar.gz: 9faca13e2e89958a6f185fb78a45643768842d291abeb02a16be46cc65872b94697452add56623db9a66b37134a3bfe3446cfa1dd5e46b5346a70313c516915e
6
+ metadata.gz: ccba25e28e305ce675f56dc8c3cf86e7433905e4029780cbe604e7e7ccfc129160ae6ab0955704a764f54dd2604efd29bfb88fcd067b7ff28fc3af3240edcdc5
7
+ data.tar.gz: 3d38f4979c3d2f761a287a3f64a69efbcc19256e825093d4ba59080966c540d7cf096a5b4af2e49920dce2e103ff4570b0db80e82d42d192e7e6abffa9548f73
data/Gemfile CHANGED
@@ -8,6 +8,7 @@ group :development, :test do
8
8
  gem "rb_sys", "~> 0.9.110" # for Makefile generation in extconf.rb
9
9
  gem "rake-compiler", "~> 1.2.9" # to build a debug build
10
10
  gem "minitest", "~> 6.0" # test library
11
+ gem "minitest-retry", "~> 0.3", require: false # retry flaky network tests
11
12
  gem "activesupport", "~> 8.0.1" # testing support
12
13
  gem "standard", "~> 1.52" # linter with pre-specified rules
13
14
  gem "redcarpet", "~> 3.6" # for documentation markdown parsing
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # wreq-ruby
2
2
 
3
3
  [![CI](https://github.com/SearchApi/wreq-ruby/actions/workflows/ci.yml/badge.svg)](https://github.com/SearchApi/wreq-ruby/actions/workflows/ci.yml)
4
+ ![GitHub License](https://img.shields.io/github/license/SearchApi/wreq-ruby)
4
5
  [![Gem Version](https://badge.fury.io/rb/wreq.svg)](https://rubygems.org/gems/wreq)
5
6
 
6
7
  An easy and powerful Ruby HTTP client with advanced browser fingerprinting that accurately emulates **Chrome**, **Edge**, **Firefox**, **Safari**, **Opera**, and **OkHttp**, with precise **TLS/HTTP2** signatures, and powered by [wreq](https://github.com/0x676e67/wreq).
@@ -31,8 +32,10 @@ gem "wreq"
31
32
  ```
32
33
 
33
34
  Pre-compiled native gems are available for:
35
+
34
36
  - Linux (x86_64, aarch64)
35
37
  - macOS (arm64)
38
+ - Windows (x86_64)
36
39
 
37
40
  ## Example
38
41
 
@@ -88,11 +91,11 @@ Most browser device models share identical TLS and HTTP/2 configurations, differ
88
91
 
89
92
  | **Browser** | **Versions** |
90
93
  | ----------- | ------------ |
91
- | **Chrome** | `Chrome100`, `Chrome101`, `Chrome104`, `Chrome105`, `Chrome106`, `Chrome107`, `Chrome108`, `Chrome109`, `Chrome110`, `Chrome114`, `Chrome116`, `Chrome117`, `Chrome118`, `Chrome119`, `Chrome120`, `Chrome123`, `Chrome124`, `Chrome126`, `Chrome127`, `Chrome128`, `Chrome129`, `Chrome130`, `Chrome131`, `Chrome132`, `Chrome133`, `Chrome134`, `Chrome135`, `Chrome136`, `Chrome137`, `Chrome138`, `Chrome139`, `Chrome140`, `Chrome141`, `Chrome142`, `Chrome143`, `Chrome144`, `Chrome145`, `Chrome146`, `Chrome147` |
92
- | **Edge** | `Edge101`, `Edge122`, `Edge127`, `Edge131`, `Edge134`, `Edge135`, `Edge136`, `Edge137`, `Edge138`, `Edge139`, `Edge140`, `Edge141`, `Edge142`, `Edge143`, `Edge144`, `Edge145`, `Edge146`, `Edge147` |
93
- | **Firefox** | `Firefox109`, `Firefox117`, `Firefox128`, `Firefox133`, `Firefox135`, `FirefoxPrivate135`, `FirefoxAndroid135`, `Firefox136`, `FirefoxPrivate136`, `Firefox139`, `Firefox142`, `Firefox143`, `Firefox144`, `Firefox145`, `Firefox146`, `Firefox147`, `Firefox148`, `Firefox149` |
94
+ | **Chrome** | `Chrome100`, `Chrome101`, `Chrome104`, `Chrome105`, `Chrome106`, `Chrome107`, `Chrome108`, `Chrome109`, `Chrome110`, `Chrome114`, `Chrome116`, `Chrome117`, `Chrome118`, `Chrome119`, `Chrome120`, `Chrome123`, `Chrome124`, `Chrome126`, `Chrome127`, `Chrome128`, `Chrome129`, `Chrome130`, `Chrome131`, `Chrome132`, `Chrome133`, `Chrome134`, `Chrome135`, `Chrome136`, `Chrome137`, `Chrome138`, `Chrome139`, `Chrome140`, `Chrome141`, `Chrome142`, `Chrome143`, `Chrome144`, `Chrome145`, `Chrome146`, `Chrome147`, `Chrome148`, `Chrome149` |
95
+ | **Edge** | `Edge101`, `Edge122`, `Edge127`, `Edge131`, `Edge134`, `Edge135`, `Edge136`, `Edge137`, `Edge138`, `Edge139`, `Edge140`, `Edge141`, `Edge142`, `Edge143`, `Edge144`, `Edge145`, `Edge146`, `Edge147`, `Edge148` |
96
+ | **Firefox** | `Firefox109`, `Firefox117`, `Firefox128`, `Firefox133`, `Firefox135`, `FirefoxPrivate135`, `FirefoxAndroid135`, `Firefox136`, `FirefoxPrivate136`, `Firefox139`, `Firefox142`, `Firefox143`, `Firefox144`, `Firefox145`, `Firefox146`, `Firefox147`, `Firefox148`, `Firefox149`, `Firefox150`, `Firefox151` |
94
97
  | **Safari** | `Safari15_3`, `Safari15_5`, `Safari15_6_1`, `Safari16`, `Safari16_5`, `Safari17_0`, `Safari17_2_1`, `Safari17_4_1`, `Safari17_5`, `Safari17_6`, `Safari18`, `Safari18_2`, `Safari18_3`, `Safari18_3_1`, `Safari18_5`, `Safari26`, `Safari26_1`, `Safari26_2`, `SafariIos16_5`, `SafariIos17_2`, `SafariIos17_4_1`, `SafariIos18_1_1`, `SafariIos26`, `SafariIos26_2`, `SafariIPad18`, `SafariIPad26`, `SafariIpad26_2` |
95
- | **OkHttp** | `OkHttp3_9`, `OkHttp3_11`, `OkHttp3_13`, `OkHttp3_14`, `OkHttp4_9`, `OkHttp4_10`, `OkHttp4_12`, `OkHttp5` |
98
+ | **OkHttp** | `Opera116`, `Opera117`, `Opera118`, `Opera119`, `Opera120`, `Opera121`, `Opera122`, `Opera123`, `Opera124`, `Opera125`, `Opera126`, `Opera127`, `Opera128`, `Opera129`, `Opera130` |
96
99
  | **Opera** | `Opera116`, `Opera117`, `Opera118`, `Opera119` |
97
100
 
98
101
  </details>
@@ -0,0 +1,70 @@
1
+ # Windows GNU Tokio multi-thread crash
2
+
3
+ ## Summary
4
+
5
+ On RubyInstaller GNU/UCRT, Tokio's multi-thread runtime could crash when the
6
+ native extension was loaded by Ruby. The issue was not Tokio's scheduler logic
7
+ itself. It came from Windows symbol resolution while linking the Ruby extension.
8
+
9
+ ## Root cause
10
+
11
+ RubyInstaller GNU/UCRT exports a Ruby-aware `Sleep` symbol from
12
+ `x64-ucrt-ruby400.dll`.
13
+
14
+ When the extension is linked with GNU ld, an unqualified `Sleep` reference can
15
+ bind to Ruby's `Sleep` instead of `KERNEL32!Sleep`. Tokio's multi-thread runtime
16
+ creates native worker threads that are not Ruby-managed threads. If one of those
17
+ threads calls Ruby's `Sleep`, Ruby expects Ruby thread-local state to exist, but
18
+ that TLS slot is empty on the Tokio worker thread. This can crash with an access
19
+ violation or Ruby VM bug report.
20
+
21
+ The local investigation found the fault inside:
22
+
23
+ ```text
24
+ x64-ucrt-ruby400.dll!Sleep + 0x40
25
+ ```
26
+
27
+ The import table also showed the bad binding:
28
+
29
+ ```text
30
+ DLL Name: x64-ucrt-ruby400.dll
31
+ Sleep
32
+ ```
33
+
34
+ ## Fix
35
+
36
+ For `x86_64-pc-windows-gnu`, the build now wraps `Sleep` at link time:
37
+
38
+ ```text
39
+ -Wl,--wrap=Sleep
40
+ ```
41
+
42
+ The wrapper lives in `src/arch.rs` and forwards calls to `KERNEL32!SleepEx`.
43
+ This keeps Tokio's worker threads on the real Windows API path while preserving
44
+ Tokio's multi-thread runtime and Ruby GVL release behavior.
45
+
46
+ After the fix, the import table shows:
47
+
48
+ ```text
49
+ DLL Name: KERNEL32.dll
50
+ Sleep
51
+ SleepEx
52
+ ```
53
+
54
+ ## Notes
55
+
56
+ `windows-sys` raw-dylib was also tested. It is not enough on its own because the
57
+ problematic `Sleep` reference can come from Rust std, MinGW, or pthread-related
58
+ linking paths, not only from `windows-sys`.
59
+
60
+ Verified with:
61
+
62
+ ```powershell
63
+ .\script\build_windows_gnu.ps1 -SkipBundleInstall -SkipToolInstall -RunTests
64
+ ```
65
+
66
+ Result:
67
+
68
+ ```text
69
+ 160 runs, 775 assertions, 0 failures, 0 errors
70
+ ```
Binary file
Binary file
Binary file
@@ -57,6 +57,7 @@ module Wreq
57
57
  Chrome146 = nil
58
58
  Chrome147 = nil
59
59
  Chrome148 = nil
60
+ Chrome149 = nil
60
61
 
61
62
  Edge101 = nil
62
63
  Edge122 = nil
@@ -0,0 +1,257 @@
1
+ param(
2
+ [switch]$SkipBundleInstall,
3
+ [switch]$SkipToolInstall,
4
+ [switch]$BuildGem,
5
+ [switch]$TestGem,
6
+ [switch]$RunTests,
7
+ [string]$SmokeUrl = $env:WREQ_SMOKE_URL
8
+ )
9
+
10
+ $ErrorActionPreference = "Stop"
11
+
12
+ $target = "x86_64-pc-windows-gnu"
13
+ $platform = "x64-mingw-ucrt"
14
+ $gemPattern = "pkg\wreq-*-$platform.gem"
15
+ if ([string]::IsNullOrWhiteSpace($SmokeUrl)) {
16
+ $SmokeUrl = "https://httpbin.io/get"
17
+ }
18
+ $rubyRoot = Split-Path (Split-Path (Get-Command ruby).Source -Parent) -Parent
19
+ $ucrt = Join-Path $rubyRoot "msys64\ucrt64"
20
+ $ucrtBin = Join-Path $ucrt "bin"
21
+ $msysPackages = @(
22
+ "mingw-w64-ucrt-x86_64-gcc",
23
+ "mingw-w64-ucrt-x86_64-clang",
24
+ "mingw-w64-ucrt-x86_64-cmake",
25
+ "mingw-w64-ucrt-x86_64-pkgconf"
26
+ )
27
+
28
+ function Invoke-Step {
29
+ param(
30
+ [string]$Name,
31
+ [scriptblock]$Command
32
+ )
33
+
34
+ Write-Host "==> $Name"
35
+ & $Command
36
+ }
37
+
38
+ function Get-MissingUcrtTools {
39
+ $missing = @()
40
+
41
+ if (-not (Test-Path (Join-Path $ucrtBin "gcc.exe")) -or -not (Test-Path (Join-Path $ucrtBin "g++.exe"))) {
42
+ $missing += "gcc/g++"
43
+ }
44
+
45
+ if (-not (Test-Path (Join-Path $ucrtBin "clang.exe")) -or -not (Test-Path (Join-Path $ucrtBin "libclang.dll"))) {
46
+ $missing += "clang/libclang"
47
+ }
48
+
49
+ if (-not (Test-Path (Join-Path $ucrtBin "cmake.exe"))) {
50
+ $missing += "cmake"
51
+ }
52
+
53
+ if (-not (Test-Path (Join-Path $ucrtBin "pkgconf.exe")) -and -not (Test-Path (Join-Path $ucrtBin "pkg-config.exe"))) {
54
+ $missing += "pkgconf"
55
+ }
56
+
57
+ $missing
58
+ }
59
+
60
+ function Get-LatestPlatformGem {
61
+ $gem = Get-ChildItem -Path $gemPattern -ErrorAction SilentlyContinue |
62
+ Sort-Object LastWriteTime -Descending |
63
+ Select-Object -First 1
64
+
65
+ if (-not $gem) {
66
+ throw "No Windows GNU platform gem found at '$gemPattern'. Re-run with -BuildGem first."
67
+ }
68
+
69
+ $gem
70
+ }
71
+
72
+ function Invoke-RubySmoke {
73
+ param(
74
+ [string]$Name,
75
+ [string]$Code
76
+ )
77
+
78
+ Write-Host "Smoke: $Name"
79
+ ruby -e $Code
80
+ if ($LASTEXITCODE -ne 0) {
81
+ throw "$Name failed with exit code $LASTEXITCODE."
82
+ }
83
+ }
84
+
85
+ Invoke-Step "Check Ruby platform" {
86
+ $rubyArch = & ruby -rrbconfig -e "print RbConfig::CONFIG['arch']"
87
+ if ($rubyArch -ne $platform) {
88
+ throw "Expected Ruby platform '$platform', got '$rubyArch'. Use RubyInstaller UCRT for this build."
89
+ }
90
+
91
+ ruby -v
92
+ ruby -rrbconfig -rrubygems -e "puts RbConfig::CONFIG.values_at('arch', 'host', 'CC').join(%q{ }); puts Gem::Platform.local"
93
+ }
94
+
95
+ Invoke-Step "Install Rust target" {
96
+ $installedTargets = @(rustup target list --installed)
97
+ if ($installedTargets -contains $target) {
98
+ Write-Host "Rust target $target already installed; skipping rustup."
99
+ return
100
+ }
101
+
102
+ rustup target add $target
103
+ if ($LASTEXITCODE -ne 0) {
104
+ throw "Failed to install Rust target $target."
105
+ }
106
+ }
107
+
108
+ Invoke-Step "Check MSYS2 UCRT build tools" {
109
+ $missing = @(Get-MissingUcrtTools)
110
+ if ($missing.Count -eq 0) {
111
+ Write-Host "MSYS2 UCRT build tools already present; skipping pacman."
112
+ return
113
+ }
114
+
115
+ if ($SkipToolInstall) {
116
+ throw "Missing MSYS2 UCRT build tools: $($missing -join ', '). Re-run without -SkipToolInstall or install them with ridk."
117
+ }
118
+
119
+ Write-Host "Missing MSYS2 UCRT build tools: $($missing -join ', ')"
120
+ ridk exec pacman -S --needed --noconfirm @msysPackages
121
+ if ($LASTEXITCODE -ne 0) {
122
+ $stillMissing = @(Get-MissingUcrtTools)
123
+ if ($stillMissing.Count -eq 0) {
124
+ Write-Warning "pacman returned exit code $LASTEXITCODE, but all required tools are present; continuing."
125
+ return
126
+ }
127
+
128
+ throw "Failed to install MSYS2 UCRT build tools. Missing: $($stillMissing -join ', '). If pacman cannot lock its database, close other pacman/ridk shells, run PowerShell as Administrator, or install RubyInstaller in a user-writable directory."
129
+ }
130
+ }
131
+
132
+ Invoke-Step "Configure Windows GNU toolchain" {
133
+ $env:CARGO_BUILD_TARGET = $target
134
+ $env:LIBCLANG_PATH = $ucrtBin
135
+ $env:CC_x86_64_pc_windows_gnu = Join-Path $ucrtBin "gcc.exe"
136
+ $env:CXX_x86_64_pc_windows_gnu = Join-Path $ucrtBin "g++.exe"
137
+ $env:CMAKE = Join-Path $ucrtBin "cmake.exe"
138
+ Remove-Item Env:\CMAKE_GENERATOR -ErrorAction SilentlyContinue
139
+
140
+ rustc -Vv
141
+ Write-Host "LIBCLANG_PATH=$env:LIBCLANG_PATH"
142
+ Write-Host "CC_x86_64_pc_windows_gnu=$env:CC_x86_64_pc_windows_gnu"
143
+ Write-Host "CXX_x86_64_pc_windows_gnu=$env:CXX_x86_64_pc_windows_gnu"
144
+ Write-Host "CMAKE=$env:CMAKE"
145
+ }
146
+
147
+ if (-not $SkipBundleInstall) {
148
+ Invoke-Step "Install Ruby dependencies" {
149
+ bundle install
150
+ }
151
+ }
152
+
153
+ Invoke-Step "Compile native extension" {
154
+ ridk exec ruby -S bundle exec rake compile
155
+ }
156
+
157
+ Invoke-Step "Verify extension loads" {
158
+ ruby -Ilib -rwreq -e "puts Wreq::VERSION; puts Wreq::Client.new.class"
159
+ }
160
+
161
+ if ($RunTests) {
162
+ Invoke-Step "Run tests" {
163
+ ridk exec ruby -S bundle exec rake test
164
+ }
165
+ }
166
+
167
+ if ($BuildGem) {
168
+ Invoke-Step "Build local platform gem" {
169
+ $rubyMinor = & ruby -e "print RUBY_VERSION[/\A\d+\.\d+/]"
170
+ $dest = "lib\wreq_ruby\$rubyMinor"
171
+ New-Item -ItemType Directory -Force $dest | Out-Null
172
+ Copy-Item "lib\wreq_ruby\wreq_ruby.so" (Join-Path $dest "wreq_ruby.so") -Force
173
+
174
+ ruby script/build_platform_gem.rb $platform
175
+ }
176
+ }
177
+
178
+ if ($TestGem) {
179
+ Invoke-Step "Install and smoke test platform gem" {
180
+ $gem = Get-LatestPlatformGem
181
+ $gemHome = Join-Path ([System.IO.Path]::GetTempPath()) "wreq-gem-test-$PID"
182
+ $gemBin = Join-Path $gemHome "bin"
183
+ $testDir = Join-Path ([System.IO.Path]::GetTempPath()) "wreq-gem-test-cwd-$PID"
184
+
185
+ Remove-Item -Recurse -Force $gemHome, $testDir -ErrorAction SilentlyContinue
186
+ New-Item -ItemType Directory -Force $gemHome, $gemBin, $testDir | Out-Null
187
+
188
+ $oldGemHome = $env:GEM_HOME
189
+ $oldGemPath = $env:GEM_PATH
190
+ $oldGemrc = $env:GEMRC
191
+ $oldRubyopt = $env:RUBYOPT
192
+ $oldRubylib = $env:RUBYLIB
193
+ $oldBundleGemfile = $env:BUNDLE_GEMFILE
194
+ $oldBundleBinPath = $env:BUNDLE_BIN_PATH
195
+ $oldBundlerVersion = $env:BUNDLER_VERSION
196
+ $oldSmokeUrl = $env:WREQ_SMOKE_URL
197
+ $oldWreqGemHome = $env:WREQ_GEM_HOME
198
+
199
+ try {
200
+ $env:GEM_HOME = $gemHome
201
+ $env:GEM_PATH = $gemHome
202
+ $env:GEMRC = ""
203
+ $env:RUBYOPT = ""
204
+ $env:RUBYLIB = ""
205
+ $env:BUNDLE_GEMFILE = ""
206
+ $env:BUNDLE_BIN_PATH = ""
207
+ $env:BUNDLER_VERSION = ""
208
+ $env:WREQ_SMOKE_URL = $SmokeUrl
209
+ $env:WREQ_GEM_HOME = $gemHome
210
+
211
+ gem install --norc --local --install-dir $gemHome --bindir $gemBin --no-document --force --no-user-install $gem.FullName
212
+ if ($LASTEXITCODE -ne 0) {
213
+ throw "Failed to install $($gem.FullName)."
214
+ }
215
+
216
+ Push-Location $testDir
217
+ try {
218
+ Invoke-RubySmoke "Load installed platform gem" @'
219
+ STDOUT.sync = true
220
+ STDERR.sync = true
221
+ require "wreq"
222
+ spec = Gem.loaded_specs.fetch("wreq")
223
+ expected = File.expand_path(ENV.fetch("WREQ_GEM_HOME"))
224
+ actual = File.expand_path(spec.full_gem_path)
225
+ raise "loaded #{actual}, expected under #{expected}" unless actual.start_with?(expected)
226
+ puts "loaded #{spec.full_name}"
227
+ puts actual
228
+ puts "wreq #{Wreq::VERSION}"
229
+ '@
230
+
231
+ Invoke-RubySmoke "Request through installed platform gem" @'
232
+ STDOUT.sync = true
233
+ STDERR.sync = true
234
+ require "wreq"
235
+ client = Wreq::Client.new
236
+ resp = client.get(ENV.fetch("WREQ_SMOKE_URL"), timeout: 20)
237
+ puts "HTTP #{resp.code}"
238
+ raise "unexpected status #{resp.code}" unless resp.code == 200
239
+ '@
240
+ } finally {
241
+ Pop-Location
242
+ }
243
+ } finally {
244
+ $env:GEM_HOME = $oldGemHome
245
+ $env:GEM_PATH = $oldGemPath
246
+ $env:GEMRC = $oldGemrc
247
+ $env:RUBYOPT = $oldRubyopt
248
+ $env:RUBYLIB = $oldRubylib
249
+ $env:BUNDLE_GEMFILE = $oldBundleGemfile
250
+ $env:BUNDLE_BIN_PATH = $oldBundleBinPath
251
+ $env:BUNDLER_VERSION = $oldBundlerVersion
252
+ $env:WREQ_SMOKE_URL = $oldSmokeUrl
253
+ $env:WREQ_GEM_HOME = $oldWreqGemHome
254
+ Remove-Item -Recurse -Force $gemHome, $testDir -ErrorAction SilentlyContinue
255
+ }
256
+ }
257
+ }
@@ -3,7 +3,7 @@
3
3
  require "test_helper"
4
4
 
5
5
  class ClientCookieProviderTest < Minitest::Test
6
- HOST = "http://localhost:8080"
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
- body = res2.json
33
- assert_kind_of Hash, body
34
- assert_equal "bar", body.dig("cookies", "foo")
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["cookies"]
44
- assert_equal "1", cookies["pref"]
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("http://localhost:8080/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("http://localhost:8080/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("http://localhost:8080/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("http://localhost:8080/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("http://localhost:8080/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("http://localhost:8080/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("http://localhost:8080/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("http://localhost:8080/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("http://localhost:8080/basic-auth/user/pass",
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("http://localhost:8080/bearer",
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("http://localhost:8080/redirect/1",
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("http://localhost:8080/redirect/1",
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("http://localhost:8080/gzip", gzip: true)
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("http://localhost:8080/delay/10", timeout: 1)
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("http://localhost:8080/delay/1", timeout: 5)
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("http://localhost:8080/status/404")
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
- "https://httpbin.io/cookies",
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
- assert_equal "bar", json["foo"]
166
- assert_equal "qux", json["baz"]
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
- "https://httpbin.io/cookies",
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
- assert_equal "bar", json["foo"]
178
- assert_equal "qux", json["baz"]
178
+ cookies = json.fetch("cookies", json)
179
+ assert_equal "bar", cookies["foo"]
180
+ assert_equal "qux", cookies["baz"]
179
181
  end
180
182
  end
@@ -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("http://localhost:8080/status/#{status_code}")
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("http://localhost:8080/delay/10", timeout: 1)
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("http://localhost:8080/html")
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("http://localhost:8080/status/204")
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("http://localhost:8080/response-headers",
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("http://localhost:8080/json")
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("http://localhost:8080/json")
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("http://localhost:8080/status/200")
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("http://localhost:8080/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?(">")