wreq 1.2.2 → 1.2.3

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.
@@ -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
+ }
data/src/arch.rs ADDED
@@ -0,0 +1,33 @@
1
+ //! Platform-specific support code.
2
+ //!
3
+ //! Keep this module small and focused on platform quirks that affect linking,
4
+ //! ABI boundaries, or OS APIs used by the Rust extension. Normal HTTP client
5
+ //! behavior should stay in the client/runtime modules so platform workarounds
6
+ //! do not leak into the rest of the binding.
7
+
8
+ #[cfg(all(target_os = "windows", target_env = "gnu"))]
9
+ mod windows_gnu {
10
+ //! Windows GNU support.
11
+ //!
12
+ //! RubyInstaller's GNU/UCRT Ruby exports some symbols with the same names as
13
+ //! Win32 APIs. When GNU ld links this extension against Ruby, those symbols
14
+ //! can shadow the real Windows APIs unless we pin the calls we care about.
15
+
16
+ #[link(name = "kernel32")]
17
+ unsafe extern "system" {
18
+ fn SleepEx(milliseconds: u32, alertable: i32) -> u32;
19
+ }
20
+
21
+ // RubyInstaller's GNU/UCRT Ruby exports a Ruby-aware Sleep symbol. GNU ld can
22
+ // bind extension calls to that symbol instead of KERNEL32!Sleep, which crashes
23
+ // on native worker threads that have no Ruby TLS. The linker wrapper keeps those
24
+ // calls on the Windows API path.
25
+ #[unsafe(no_mangle)]
26
+ pub extern "system" fn __wrap_Sleep(milliseconds: u32) {
27
+ // SAFETY: SleepEx is a Win32 API. Passing alertable=false matches Sleep's
28
+ // behavior, and any u32 duration is accepted by the API.
29
+ unsafe {
30
+ SleepEx(milliseconds, 0);
31
+ }
32
+ }
33
+ }
@@ -5,7 +5,7 @@ use std::{
5
5
  };
6
6
 
7
7
  use bytes::Bytes;
8
- use futures_util::{Stream, StreamExt, TryFutureExt};
8
+ use futures_util::{Stream, StreamExt};
9
9
  use magnus::{Error, RString, TryConvert, Value};
10
10
  use tokio::sync::{
11
11
  Mutex,
@@ -40,13 +40,16 @@ impl BodyReceiver {
40
40
 
41
41
  /// Read the next body chunk, converting stream errors into Ruby errors.
42
42
  pub fn next(&self) -> Result<Option<Bytes>, Error> {
43
- rt::try_block_on(async {
44
- match self.0.lock().await.as_mut().next().await {
45
- Some(Ok(data)) => Ok(Some(data)),
46
- Some(Err(err)) => Err(wreq_error_to_magnus(err)),
47
- None => Ok(None),
48
- }
49
- })
43
+ rt::try_block_on(
44
+ async {
45
+ match self.0.lock().await.as_mut().next().await {
46
+ Some(Ok(data)) => Ok(Some(data)),
47
+ Some(Err(err)) => Err(err),
48
+ None => Ok(None),
49
+ }
50
+ },
51
+ wreq_error_to_magnus,
52
+ )
50
53
  }
51
54
  }
52
55
 
@@ -73,7 +76,7 @@ impl BodySender {
73
76
  let bytes = data.to_bytes();
74
77
  let inner = rb_self.0.read().unwrap();
75
78
  if let Some(ref tx) = inner.tx {
76
- rt::try_block_on(tx.send(bytes).map_err(mpsc_send_error_to_magnus))?;
79
+ rt::try_block_on(tx.send(bytes), mpsc_send_error_to_magnus)?;
77
80
  }
78
81
  Ok(())
79
82
  }
data/src/client/req.rs CHANGED
@@ -33,6 +33,7 @@ pub struct Request {
33
33
  local_address: Option<IpAddr>,
34
34
 
35
35
  /// Bind to an interface by `SO_BINDTODEVICE`.
36
+ #[allow(dead_code)]
36
37
  interface: Option<String>,
37
38
 
38
39
  /// The timeout to use for the request.
@@ -144,119 +145,130 @@ pub fn execute_request<U: AsRef<str>>(
144
145
  url: U,
145
146
  mut request: Request,
146
147
  ) -> Result<Response, magnus::Error> {
147
- rt::try_block_on(async move {
148
- let mut builder = client.request(method.into_ffi(), url.as_ref());
149
-
150
- // Emulation options.
151
- apply_option!(set_if_some_inner, builder, request.emulation, emulation);
152
-
153
- // Version options.
154
- apply_option!(
155
- set_if_some_map,
156
- builder,
157
- request.version,
158
- version,
159
- Version::into_ffi
160
- );
161
-
162
- // Timeout options.
163
- apply_option!(
164
- set_if_some_map,
165
- builder,
166
- request.timeout,
167
- timeout,
168
- Duration::from_secs
169
- );
170
- apply_option!(
171
- set_if_some_map,
172
- builder,
173
- request.read_timeout,
174
- read_timeout,
175
- Duration::from_secs
176
- );
177
-
178
- // Network options.
179
- apply_option!(set_if_some, builder, request.proxy, proxy);
180
- apply_option!(set_if_some, builder, request.local_address, local_address);
181
- apply_option!(set_if_some, builder, request.interface, interface);
182
-
183
- // Headers options.
184
- apply_option!(set_if_some_into_inner, builder, request.headers, headers);
185
- apply_option!(
186
- set_if_some_inner,
187
- builder,
188
- request.orig_headers,
189
- orig_headers
190
- );
191
- apply_option!(
192
- set_if_some,
193
- builder,
194
- request.default_headers,
195
- default_headers
196
- );
197
-
198
- // Cookies options.
199
- if let Some(cookies) = request.cookies.take() {
200
- for cookie in cookies.0 {
201
- builder = builder.header(header::COOKIE, cookie);
148
+ rt::try_block_on(
149
+ async move {
150
+ let mut builder = client.request(method.into_ffi(), url.as_ref());
151
+
152
+ // Emulation options.
153
+ apply_option!(set_if_some_inner, builder, request.emulation, emulation);
154
+
155
+ // Version options.
156
+ apply_option!(
157
+ set_if_some_map,
158
+ builder,
159
+ request.version,
160
+ version,
161
+ Version::into_ffi
162
+ );
163
+
164
+ // Timeout options.
165
+ apply_option!(
166
+ set_if_some_map,
167
+ builder,
168
+ request.timeout,
169
+ timeout,
170
+ Duration::from_secs
171
+ );
172
+ apply_option!(
173
+ set_if_some_map,
174
+ builder,
175
+ request.read_timeout,
176
+ read_timeout,
177
+ Duration::from_secs
178
+ );
179
+
180
+ // Network options.
181
+ apply_option!(set_if_some, builder, request.proxy, proxy);
182
+ apply_option!(set_if_some, builder, request.local_address, local_address);
183
+ #[cfg(any(
184
+ target_os = "android",
185
+ target_os = "fuchsia",
186
+ target_os = "illumos",
187
+ target_os = "ios",
188
+ target_os = "linux",
189
+ target_os = "macos",
190
+ target_os = "solaris",
191
+ target_os = "tvos",
192
+ target_os = "visionos",
193
+ target_os = "watchos",
194
+ ))]
195
+ apply_option!(set_if_some, builder, request.interface, interface);
196
+
197
+ // Headers options.
198
+ apply_option!(set_if_some_into_inner, builder, request.headers, headers);
199
+ apply_option!(
200
+ set_if_some_inner,
201
+ builder,
202
+ request.orig_headers,
203
+ orig_headers
204
+ );
205
+ apply_option!(
206
+ set_if_some,
207
+ builder,
208
+ request.default_headers,
209
+ default_headers
210
+ );
211
+
212
+ // Cookies options.
213
+ if let Some(cookies) = request.cookies.take() {
214
+ for cookie in cookies.0 {
215
+ builder = builder.header(header::COOKIE, cookie);
216
+ }
202
217
  }
203
- }
204
-
205
- // Authentication options.
206
- apply_option!(
207
- set_if_some_map_ref,
208
- builder,
209
- request.auth,
210
- auth,
211
- AsRef::<str>::as_ref
212
- );
213
- apply_option!(set_if_some, builder, request.bearer_auth, bearer_auth);
214
- if let Some(basic_auth) = request.basic_auth.take() {
215
- builder = builder.basic_auth(basic_auth.0, basic_auth.1);
216
- }
217
218
 
218
- // Allow redirects options.
219
- match request.allow_redirects {
220
- Some(false) => {
221
- builder = builder.redirect(wreq::redirect::Policy::none());
219
+ // Authentication options.
220
+ apply_option!(
221
+ set_if_some_map_ref,
222
+ builder,
223
+ request.auth,
224
+ auth,
225
+ AsRef::<str>::as_ref
226
+ );
227
+ apply_option!(set_if_some, builder, request.bearer_auth, bearer_auth);
228
+ if let Some(basic_auth) = request.basic_auth.take() {
229
+ builder = builder.basic_auth(basic_auth.0, basic_auth.1);
222
230
  }
223
- Some(true) => {
224
- builder = builder.redirect(
225
- request
226
- .max_redirects
227
- .take()
228
- .map(wreq::redirect::Policy::limited)
229
- .unwrap_or_default(),
230
- );
231
- }
232
- None => {}
233
- };
234
-
235
- // Compression options.
236
- apply_option!(set_if_some, builder, request.gzip, gzip);
237
- apply_option!(set_if_some, builder, request.brotli, brotli);
238
- apply_option!(set_if_some, builder, request.deflate, deflate);
239
- apply_option!(set_if_some, builder, request.zstd, zstd);
240
231
 
241
- // Query options.
242
- apply_option!(set_if_some_ref, builder, request.query, query);
243
-
244
- // Form options.
245
- apply_option!(set_if_some_ref, builder, request.form, form);
246
-
247
- // JSON options.
248
- apply_option!(set_if_some_ref, builder, request.json, json);
249
-
250
- // Body options.
251
- if let Some(body) = request.body.take() {
252
- builder = builder.body(wreq::Body::from(body));
253
- }
232
+ // Allow redirects options.
233
+ match request.allow_redirects {
234
+ Some(false) => {
235
+ builder = builder.redirect(wreq::redirect::Policy::none());
236
+ }
237
+ Some(true) => {
238
+ builder = builder.redirect(
239
+ request
240
+ .max_redirects
241
+ .take()
242
+ .map(wreq::redirect::Policy::limited)
243
+ .unwrap_or_default(),
244
+ );
245
+ }
246
+ None => {}
247
+ };
248
+
249
+ // Compression options.
250
+ apply_option!(set_if_some, builder, request.gzip, gzip);
251
+ apply_option!(set_if_some, builder, request.brotli, brotli);
252
+ apply_option!(set_if_some, builder, request.deflate, deflate);
253
+ apply_option!(set_if_some, builder, request.zstd, zstd);
254
+
255
+ // Query options.
256
+ apply_option!(set_if_some_ref, builder, request.query, query);
257
+
258
+ // Form options.
259
+ apply_option!(set_if_some_ref, builder, request.form, form);
260
+
261
+ // JSON options.
262
+ apply_option!(set_if_some_ref, builder, request.json, json);
263
+
264
+ // Body options.
265
+ if let Some(body) = request.body.take() {
266
+ builder = builder.body(wreq::Body::from(body));
267
+ }
254
268
 
255
- // Send request.
256
- builder
257
- .send()
258
- .await
259
- .map(Response::new)
260
- .map_err(wreq_error_to_magnus)
261
- })
269
+ // Send request.
270
+ builder.send().await.map(Response::new)
271
+ },
272
+ wreq_error_to_magnus,
273
+ )
262
274
  }
data/src/client/resp.rs CHANGED
@@ -81,9 +81,8 @@ impl Response {
81
81
  Ok(build_response(body))
82
82
  } else {
83
83
  let bytes = rt::try_block_on(
84
- BodyExt::collect(body)
85
- .map_ok(|buf| buf.to_bytes())
86
- .map_err(wreq_error_to_magnus),
84
+ BodyExt::collect(body).map_ok(|buf| buf.to_bytes()),
85
+ wreq_error_to_magnus,
87
86
  )?;
88
87
 
89
88
  self.body
@@ -170,7 +169,7 @@ impl Response {
170
169
  /// Get the response body as bytes.
171
170
  pub fn bytes(&self) -> Result<Bytes, Error> {
172
171
  let response = self.response(false)?;
173
- rt::try_block_on(response.bytes().map_err(wreq_error_to_magnus))
172
+ rt::try_block_on(response.bytes(), wreq_error_to_magnus)
174
173
  }
175
174
 
176
175
  /// Get the full response text given a specific encoding.
@@ -178,25 +177,18 @@ impl Response {
178
177
  let args = scan_args::<(), (Option<String>,), (), (), (), ()>(args)?;
179
178
  let response = self.response(false)?;
180
179
  match args.optional.0 {
181
- Some(encoding) => rt::try_block_on(
182
- response
183
- .text_with_charset(encoding)
184
- .map_err(wreq_error_to_magnus),
185
- ),
186
- None => rt::try_block_on(response.text().map_err(wreq_error_to_magnus)),
180
+ Some(encoding) => {
181
+ rt::try_block_on(response.text_with_charset(encoding), wreq_error_to_magnus)
182
+ }
183
+ None => rt::try_block_on(response.text(), wreq_error_to_magnus),
187
184
  }
188
185
  }
189
186
 
190
187
  /// Get the response body as JSON.
191
188
  pub fn json(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
192
189
  let response = rb_self.response(false)?;
193
- rt::try_block_on(async move {
194
- let json = response
195
- .json::<Json>()
196
- .await
197
- .map_err(wreq_error_to_magnus)?;
198
- serde_magnus::serialize(ruby, &json)
199
- })
190
+ let json = rt::try_block_on(response.json::<Json>(), wreq_error_to_magnus)?;
191
+ serde_magnus::serialize(ruby, &json)
200
192
  }
201
193
 
202
194
  /// Yield response body chunks to the given Ruby block.
data/src/client.rs CHANGED
@@ -104,6 +104,7 @@ struct Builder {
104
104
  /// Bind to a local IP Address.
105
105
  local_address: Option<IpAddr>,
106
106
  /// Bind to an interface by `SO_BINDTODEVICE`.
107
+ #[allow(dead_code)]
107
108
  interface: Option<String>,
108
109
 
109
110
  // ========= Compression options =========
@@ -300,6 +301,18 @@ impl Client {
300
301
  apply_option!(set_if_some, builder, params.proxy, proxy);
301
302
  apply_option!(set_if_true, builder, params.no_proxy, no_proxy, false);
302
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
+ ))]
303
316
  apply_option!(set_if_some, builder, params.interface, interface);
304
317
 
305
318
  // Compression options.
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,
data/src/lib.rs CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  #[macro_use]
4
4
  mod macros;
5
+ mod arch;
5
6
  mod client;
6
7
  mod cookie;
7
8
  mod emulate;