wreq 1.2.11 → 1.2.13
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 +88 -146
- data/Cargo.toml +10 -7
- data/crates/wreq-util/src/emulate/profile/chrome/http2.rs +1 -1
- data/crates/wreq-util/src/emulate/profile/firefox/http2.rs +2 -2
- data/crates/wreq-util/src/emulate/profile/opera/http2.rs +1 -1
- data/docs/fork-safety.md +51 -0
- data/docs/interrupt-handling.md +134 -0
- data/examples/tls_info.rb +27 -0
- data/lib/wreq.rb +37 -0
- data/lib/wreq_ruby/body.rb +9 -0
- data/lib/wreq_ruby/client.rb +24 -1
- data/lib/wreq_ruby/cookie.rb +9 -0
- data/lib/wreq_ruby/error.rb +15 -0
- data/lib/wreq_ruby/response.rb +44 -0
- data/lib/wreq_ruby/tls.rb +73 -0
- data/src/arch.rs +174 -0
- data/src/client/body/stream.rs +28 -22
- data/src/client/req.rs +119 -122
- data/src/client/resp.rs +120 -47
- data/src/client.rs +103 -44
- data/src/cookie.rs +47 -11
- data/src/error.rs +28 -0
- data/src/lib.rs +3 -1
- data/src/macros.rs +2 -3
- data/src/rt.rs +46 -25
- data/src/tls.rs +51 -0
- data/test/fork_test.rb +106 -0
- data/test/scripts/fork_safety.rb +133 -0
- data/test/scripts/prefork_runtime.rb +95 -0
- data/test/support/tls_server.rb +95 -0
- data/test/tls_info_test.rb +59 -0
- metadata +11 -1
data/src/client/req.rs
CHANGED
|
@@ -184,131 +184,128 @@ pub fn execute_request<U: AsRef<str>>(
|
|
|
184
184
|
url: U,
|
|
185
185
|
mut request: Request,
|
|
186
186
|
) -> Result<Response, magnus::Error> {
|
|
187
|
-
rt::
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
Duration::from_secs
|
|
218
|
-
);
|
|
219
|
-
|
|
220
|
-
// Network options.
|
|
221
|
-
apply_option!(set_if_some, builder, request.proxy, proxy);
|
|
222
|
-
apply_option!(set_if_some, builder, request.local_address, local_address);
|
|
223
|
-
#[cfg(any(
|
|
224
|
-
target_os = "android",
|
|
225
|
-
target_os = "fuchsia",
|
|
226
|
-
target_os = "illumos",
|
|
227
|
-
target_os = "ios",
|
|
228
|
-
target_os = "linux",
|
|
229
|
-
target_os = "macos",
|
|
230
|
-
target_os = "solaris",
|
|
231
|
-
target_os = "tvos",
|
|
232
|
-
target_os = "visionos",
|
|
233
|
-
target_os = "watchos",
|
|
234
|
-
))]
|
|
235
|
-
apply_option!(set_if_some, builder, request.interface, interface);
|
|
236
|
-
|
|
237
|
-
// Headers options.
|
|
238
|
-
apply_option!(set_if_some_into_inner, builder, request.headers, headers);
|
|
239
|
-
apply_option!(
|
|
240
|
-
set_if_some_inner,
|
|
241
|
-
builder,
|
|
242
|
-
request.orig_headers,
|
|
243
|
-
orig_headers
|
|
244
|
-
);
|
|
245
|
-
apply_option!(
|
|
246
|
-
set_if_some,
|
|
247
|
-
builder,
|
|
248
|
-
request.default_headers,
|
|
249
|
-
default_headers
|
|
250
|
-
);
|
|
251
|
-
|
|
252
|
-
// Cookies options.
|
|
253
|
-
if let Some(cookies) = request.cookies.take() {
|
|
254
|
-
for cookie in cookies.0 {
|
|
255
|
-
builder = builder.header(header::COOKIE, cookie);
|
|
256
|
-
}
|
|
257
|
-
}
|
|
187
|
+
rt::block_on(ruby, async move {
|
|
188
|
+
let mut builder = client.request(method.into_ffi(), url.as_ref());
|
|
189
|
+
|
|
190
|
+
// Emulation options.
|
|
191
|
+
apply_option!(set_if_some_inner, builder, request.emulation, emulation);
|
|
192
|
+
|
|
193
|
+
// Version options.
|
|
194
|
+
apply_option!(
|
|
195
|
+
set_if_some_map,
|
|
196
|
+
builder,
|
|
197
|
+
request.version,
|
|
198
|
+
version,
|
|
199
|
+
Version::into_ffi
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
// Timeout options.
|
|
203
|
+
apply_option!(
|
|
204
|
+
set_if_some_map,
|
|
205
|
+
builder,
|
|
206
|
+
request.timeout,
|
|
207
|
+
timeout,
|
|
208
|
+
Duration::from_secs
|
|
209
|
+
);
|
|
210
|
+
apply_option!(
|
|
211
|
+
set_if_some_map,
|
|
212
|
+
builder,
|
|
213
|
+
request.read_timeout,
|
|
214
|
+
read_timeout,
|
|
215
|
+
Duration::from_secs
|
|
216
|
+
);
|
|
258
217
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
218
|
+
// Network options.
|
|
219
|
+
apply_option!(set_if_some, builder, request.proxy, proxy);
|
|
220
|
+
apply_option!(set_if_some, builder, request.local_address, local_address);
|
|
221
|
+
#[cfg(any(
|
|
222
|
+
target_os = "android",
|
|
223
|
+
target_os = "fuchsia",
|
|
224
|
+
target_os = "illumos",
|
|
225
|
+
target_os = "ios",
|
|
226
|
+
target_os = "linux",
|
|
227
|
+
target_os = "macos",
|
|
228
|
+
target_os = "solaris",
|
|
229
|
+
target_os = "tvos",
|
|
230
|
+
target_os = "visionos",
|
|
231
|
+
target_os = "watchos",
|
|
232
|
+
))]
|
|
233
|
+
apply_option!(set_if_some, builder, request.interface, interface);
|
|
234
|
+
|
|
235
|
+
// Headers options.
|
|
236
|
+
apply_option!(set_if_some_into_inner, builder, request.headers, headers);
|
|
237
|
+
apply_option!(
|
|
238
|
+
set_if_some_inner,
|
|
239
|
+
builder,
|
|
240
|
+
request.orig_headers,
|
|
241
|
+
orig_headers
|
|
242
|
+
);
|
|
243
|
+
apply_option!(
|
|
244
|
+
set_if_some,
|
|
245
|
+
builder,
|
|
246
|
+
request.default_headers,
|
|
247
|
+
default_headers
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
// Cookies options.
|
|
251
|
+
if let Some(cookies) = request.cookies.take() {
|
|
252
|
+
for cookie in cookies.0 {
|
|
253
|
+
builder = builder.header(header::COOKIE, cookie);
|
|
270
254
|
}
|
|
255
|
+
}
|
|
271
256
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
// Form options.
|
|
299
|
-
apply_option!(set_if_some_ref, builder, request.form, form);
|
|
300
|
-
|
|
301
|
-
// JSON options.
|
|
302
|
-
apply_option!(set_if_some_ref, builder, request.json, json);
|
|
303
|
-
|
|
304
|
-
// Body options.
|
|
305
|
-
if let Some(body) = request.body.take() {
|
|
306
|
-
builder = builder.body(wreq::Body::from(body));
|
|
257
|
+
// Authentication options.
|
|
258
|
+
apply_option!(
|
|
259
|
+
set_if_some_map_ref,
|
|
260
|
+
builder,
|
|
261
|
+
request.auth,
|
|
262
|
+
auth,
|
|
263
|
+
AsRef::<str>::as_ref
|
|
264
|
+
);
|
|
265
|
+
apply_option!(set_if_some, builder, request.bearer_auth, bearer_auth);
|
|
266
|
+
if let Some(basic_auth) = request.basic_auth.take() {
|
|
267
|
+
builder = builder.basic_auth(basic_auth.0, basic_auth.1);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Allow redirects options.
|
|
271
|
+
match request.allow_redirects {
|
|
272
|
+
Some(false) => {
|
|
273
|
+
builder = builder.redirect(wreq::redirect::Policy::none());
|
|
274
|
+
}
|
|
275
|
+
Some(true) => {
|
|
276
|
+
builder = builder.redirect(
|
|
277
|
+
request
|
|
278
|
+
.max_redirects
|
|
279
|
+
.take()
|
|
280
|
+
.map(wreq::redirect::Policy::limited)
|
|
281
|
+
.unwrap_or_default(),
|
|
282
|
+
);
|
|
307
283
|
}
|
|
284
|
+
None => {}
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
// Compression options.
|
|
288
|
+
apply_option!(set_if_some, builder, request.gzip, gzip);
|
|
289
|
+
apply_option!(set_if_some, builder, request.brotli, brotli);
|
|
290
|
+
apply_option!(set_if_some, builder, request.deflate, deflate);
|
|
291
|
+
apply_option!(set_if_some, builder, request.zstd, zstd);
|
|
292
|
+
|
|
293
|
+
// Query options.
|
|
294
|
+
apply_option!(set_if_some_ref, builder, request.query, query);
|
|
295
|
+
|
|
296
|
+
// Form options.
|
|
297
|
+
apply_option!(set_if_some_ref, builder, request.form, form);
|
|
298
|
+
|
|
299
|
+
// JSON options.
|
|
300
|
+
apply_option!(set_if_some_ref, builder, request.json, json);
|
|
301
|
+
|
|
302
|
+
// Body options.
|
|
303
|
+
if let Some(body) = request.body.take() {
|
|
304
|
+
builder = builder.body(wreq::Body::from(body));
|
|
305
|
+
}
|
|
308
306
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
)
|
|
307
|
+
// Send request.
|
|
308
|
+
builder.send().await.map(Response::new)
|
|
309
|
+
})?
|
|
310
|
+
.map_err(|err| wreq_error(ruby, err))
|
|
314
311
|
}
|
data/src/client/resp.rs
CHANGED
|
@@ -9,6 +9,7 @@ use magnus::{Error, Module, RArray, RModule, Ruby, Value, scan_args::scan_args};
|
|
|
9
9
|
use wreq::Uri;
|
|
10
10
|
|
|
11
11
|
use crate::{
|
|
12
|
+
arch::ProcessLocal,
|
|
12
13
|
client::body::{json::Json, stream::BodyReceiver},
|
|
13
14
|
cookie::Cookie,
|
|
14
15
|
error::{memory_error, no_block_given_error, wreq_error},
|
|
@@ -16,11 +17,15 @@ use crate::{
|
|
|
16
17
|
header::Headers,
|
|
17
18
|
http::{StatusCode, Version},
|
|
18
19
|
rt,
|
|
20
|
+
tls::TlsInfo,
|
|
19
21
|
};
|
|
20
22
|
|
|
21
23
|
/// A response from a request.
|
|
22
24
|
#[magnus::wrap(class = "Wreq::Response", free_immediately, size)]
|
|
23
|
-
pub struct Response
|
|
25
|
+
pub struct Response(ProcessLocal<ResponseInner>);
|
|
26
|
+
|
|
27
|
+
/// Inner response state owned by the process that received it.
|
|
28
|
+
struct ResponseInner {
|
|
24
29
|
uri: Uri,
|
|
25
30
|
version: Version,
|
|
26
31
|
status: StatusCode,
|
|
@@ -50,50 +55,54 @@ impl Response {
|
|
|
50
55
|
let response = HttpResponse::from(response);
|
|
51
56
|
let (parts, body) = response.into_parts();
|
|
52
57
|
|
|
53
|
-
Response {
|
|
58
|
+
Response(ProcessLocal::new(ResponseInner {
|
|
54
59
|
uri,
|
|
55
60
|
local_addr,
|
|
56
61
|
remote_addr,
|
|
57
62
|
content_length,
|
|
58
|
-
extensions: parts.extensions,
|
|
59
63
|
version: Version::from_ffi(parts.version),
|
|
60
64
|
status: StatusCode::from(parts.status),
|
|
61
65
|
headers: parts.headers,
|
|
62
66
|
body: ArcSwapOption::from_pointee(Body::Streamable(body)),
|
|
63
|
-
|
|
67
|
+
extensions: parts.extensions,
|
|
68
|
+
}))
|
|
64
69
|
}
|
|
65
70
|
|
|
66
71
|
/// Internal method to get the wreq::Response, optionally streaming the body.
|
|
67
72
|
fn response(&self, ruby: &Ruby, stream: bool) -> Result<wreq::Response, Error> {
|
|
73
|
+
let state = self.0.get(ruby)?;
|
|
74
|
+
|
|
68
75
|
let build_response = |body: wreq::Body| -> wreq::Response {
|
|
69
76
|
let mut response = HttpResponse::new(body);
|
|
70
|
-
*response.version_mut() =
|
|
71
|
-
*response.status_mut() =
|
|
72
|
-
*response.headers_mut() =
|
|
73
|
-
*response.extensions_mut() =
|
|
77
|
+
*response.version_mut() = state.version.into_ffi();
|
|
78
|
+
*response.status_mut() = state.status.0;
|
|
79
|
+
*response.headers_mut() = state.headers.clone();
|
|
80
|
+
*response.extensions_mut() = state.extensions.clone();
|
|
74
81
|
wreq::Response::from(response)
|
|
75
82
|
};
|
|
76
83
|
|
|
77
|
-
if let Some(arc) =
|
|
84
|
+
if let Some(arc) = state.body.swap(None) {
|
|
78
85
|
match Arc::try_unwrap(arc) {
|
|
79
86
|
Ok(Body::Streamable(body)) => {
|
|
80
87
|
return if stream {
|
|
81
88
|
Ok(build_response(body))
|
|
82
89
|
} else {
|
|
83
|
-
let bytes = rt::
|
|
90
|
+
let bytes = rt::block_on(
|
|
84
91
|
ruby,
|
|
85
92
|
BodyExt::collect(body).map_ok(|buf| buf.to_bytes()),
|
|
86
|
-
|
|
87
|
-
)?;
|
|
93
|
+
)?
|
|
94
|
+
.map_err(|err| wreq_error(ruby, err))?;
|
|
88
95
|
|
|
89
|
-
|
|
96
|
+
state
|
|
97
|
+
.body
|
|
90
98
|
.store(Some(Arc::new(Body::Reusable(bytes.clone()))));
|
|
91
99
|
|
|
92
100
|
Ok(build_response(wreq::Body::from(bytes)))
|
|
93
101
|
};
|
|
94
102
|
}
|
|
95
103
|
Ok(Body::Reusable(bytes)) => {
|
|
96
|
-
|
|
104
|
+
state
|
|
105
|
+
.body
|
|
97
106
|
.store(Some(Arc::new(Body::Reusable(bytes.clone()))));
|
|
98
107
|
|
|
99
108
|
if !stream {
|
|
@@ -110,38 +119,66 @@ impl Response {
|
|
|
110
119
|
|
|
111
120
|
impl Response {
|
|
112
121
|
/// Get the response status code as a u16.
|
|
122
|
+
///
|
|
123
|
+
/// # Errors
|
|
124
|
+
///
|
|
125
|
+
/// Returns `Wreq::ForkError` when the response belongs to a parent process.
|
|
113
126
|
#[inline]
|
|
114
|
-
pub fn code(&
|
|
115
|
-
|
|
127
|
+
pub fn code(ruby: &Ruby, rb_self: &Self) -> Result<u16, Error> {
|
|
128
|
+
rb_self
|
|
129
|
+
.0
|
|
130
|
+
.get(ruby)
|
|
131
|
+
.map(|response| response.status.0.as_u16())
|
|
116
132
|
}
|
|
117
133
|
|
|
118
134
|
/// Get the response status code.
|
|
135
|
+
///
|
|
136
|
+
/// # Errors
|
|
137
|
+
///
|
|
138
|
+
/// Returns `Wreq::ForkError` when the response belongs to a parent process.
|
|
119
139
|
#[inline]
|
|
120
|
-
pub fn status(&
|
|
121
|
-
|
|
140
|
+
pub fn status(ruby: &Ruby, rb_self: &Self) -> Result<StatusCode, Error> {
|
|
141
|
+
rb_self.0.get(ruby).map(|response| response.status)
|
|
122
142
|
}
|
|
123
143
|
|
|
124
144
|
/// Get the response HTTP version.
|
|
145
|
+
///
|
|
146
|
+
/// # Errors
|
|
147
|
+
///
|
|
148
|
+
/// Returns `Wreq::ForkError` when the response belongs to a parent process.
|
|
125
149
|
#[inline]
|
|
126
|
-
pub fn version(&
|
|
127
|
-
|
|
150
|
+
pub fn version(ruby: &Ruby, rb_self: &Self) -> Result<Version, Error> {
|
|
151
|
+
rb_self.0.get(ruby).map(|response| response.version)
|
|
128
152
|
}
|
|
129
153
|
|
|
130
154
|
/// Get the response URL.
|
|
155
|
+
///
|
|
156
|
+
/// # Errors
|
|
157
|
+
///
|
|
158
|
+
/// Returns `Wreq::ForkError` when the response belongs to a parent process.
|
|
131
159
|
#[inline]
|
|
132
|
-
pub fn url(&
|
|
133
|
-
|
|
160
|
+
pub fn url(ruby: &Ruby, rb_self: &Self) -> Result<String, Error> {
|
|
161
|
+
rb_self.0.get(ruby).map(|response| response.uri.to_string())
|
|
134
162
|
}
|
|
135
163
|
|
|
136
164
|
/// Get the content length of the response, if known.
|
|
165
|
+
///
|
|
166
|
+
/// # Errors
|
|
167
|
+
///
|
|
168
|
+
/// Returns `Wreq::ForkError` when the response belongs to a parent process.
|
|
137
169
|
#[inline]
|
|
138
|
-
pub fn content_length(&
|
|
139
|
-
|
|
170
|
+
pub fn content_length(ruby: &Ruby, rb_self: &Self) -> Result<Option<u64>, Error> {
|
|
171
|
+
rb_self.0.get(ruby).map(|response| response.content_length)
|
|
140
172
|
}
|
|
141
173
|
|
|
142
174
|
/// Get the response cookies.
|
|
175
|
+
///
|
|
176
|
+
/// # Errors
|
|
177
|
+
///
|
|
178
|
+
/// Returns `Wreq::ForkError` when the response belongs to a parent process.
|
|
143
179
|
pub fn cookies(ruby: &Ruby, rb_self: &Self) -> Result<RArray, Error> {
|
|
144
|
-
let
|
|
180
|
+
let response = rb_self.0.get(ruby)?;
|
|
181
|
+
let cookies = Cookie::extract_headers_cookies(&response.headers);
|
|
145
182
|
let ary = ruby.ary_new_capa(cookies.len());
|
|
146
183
|
for cookie in cookies {
|
|
147
184
|
ary.push(cookie)?;
|
|
@@ -150,27 +187,63 @@ impl Response {
|
|
|
150
187
|
}
|
|
151
188
|
|
|
152
189
|
/// Get the response headers.
|
|
190
|
+
///
|
|
191
|
+
/// # Errors
|
|
192
|
+
///
|
|
193
|
+
/// Returns `Wreq::ForkError` when the response belongs to a parent process.
|
|
153
194
|
#[inline]
|
|
154
|
-
pub fn headers(&
|
|
155
|
-
|
|
195
|
+
pub fn headers(ruby: &Ruby, rb_self: &Self) -> Result<Headers, Error> {
|
|
196
|
+
rb_self
|
|
197
|
+
.0
|
|
198
|
+
.get(ruby)
|
|
199
|
+
.map(|response| Headers::from(response.headers.clone()))
|
|
156
200
|
}
|
|
157
201
|
|
|
158
202
|
/// Get the local socket address, if available.
|
|
203
|
+
///
|
|
204
|
+
/// # Errors
|
|
205
|
+
///
|
|
206
|
+
/// Returns `Wreq::ForkError` when the response belongs to a parent process.
|
|
159
207
|
#[inline]
|
|
160
|
-
pub fn local_addr(&
|
|
161
|
-
|
|
208
|
+
pub fn local_addr(ruby: &Ruby, rb_self: &Self) -> Result<Option<String>, Error> {
|
|
209
|
+
rb_self
|
|
210
|
+
.0
|
|
211
|
+
.get(ruby)
|
|
212
|
+
.map(|response| response.local_addr.map(|addr| addr.to_string()))
|
|
162
213
|
}
|
|
163
214
|
|
|
164
215
|
/// Get the remote socket address, if available.
|
|
216
|
+
///
|
|
217
|
+
/// # Errors
|
|
218
|
+
///
|
|
219
|
+
/// Returns `Wreq::ForkError` when the response belongs to a parent process.
|
|
165
220
|
#[inline]
|
|
166
|
-
pub fn remote_addr(&
|
|
167
|
-
|
|
221
|
+
pub fn remote_addr(ruby: &Ruby, rb_self: &Self) -> Result<Option<String>, Error> {
|
|
222
|
+
rb_self
|
|
223
|
+
.0
|
|
224
|
+
.get(ruby)
|
|
225
|
+
.map(|response| response.remote_addr.map(|addr| addr.to_string()))
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/// Return peer certificate data retained for this response.
|
|
229
|
+
///
|
|
230
|
+
/// # Errors
|
|
231
|
+
///
|
|
232
|
+
/// Returns `Wreq::ForkError` when the response belongs to a parent process.
|
|
233
|
+
fn tls_info(ruby: &Ruby, rb_self: &Self) -> Result<Option<TlsInfo>, Error> {
|
|
234
|
+
Ok(rb_self
|
|
235
|
+
.0
|
|
236
|
+
.get(ruby)?
|
|
237
|
+
.extensions
|
|
238
|
+
.get::<wreq::tls::TlsInfo>()
|
|
239
|
+
.cloned()
|
|
240
|
+
.map(TlsInfo))
|
|
168
241
|
}
|
|
169
242
|
|
|
170
243
|
/// Get the response body as bytes.
|
|
171
244
|
pub fn bytes(ruby: &Ruby, rb_self: &Self) -> Result<Bytes, Error> {
|
|
172
245
|
let response = rb_self.response(ruby, false)?;
|
|
173
|
-
rt::
|
|
246
|
+
rt::block_on(ruby, response.bytes())?.map_err(|err| wreq_error(ruby, err))
|
|
174
247
|
}
|
|
175
248
|
|
|
176
249
|
/// Get the full response text given a specific encoding.
|
|
@@ -178,17 +251,17 @@ impl Response {
|
|
|
178
251
|
let args = scan_args::<(), (Option<String>,), (), (), (), ()>(args)?;
|
|
179
252
|
let response = rb_self.response(ruby, false)?;
|
|
180
253
|
match args.optional.0 {
|
|
181
|
-
Some(encoding) =>
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
None => rt::try_block_on(ruby, response.text(), wreq_error),
|
|
254
|
+
Some(encoding) => rt::block_on(ruby, response.text_with_charset(encoding))?
|
|
255
|
+
.map_err(|err| wreq_error(ruby, err)),
|
|
256
|
+
None => rt::block_on(ruby, response.text())?.map_err(|err| wreq_error(ruby, err)),
|
|
185
257
|
}
|
|
186
258
|
}
|
|
187
259
|
|
|
188
260
|
/// Get the response body as JSON.
|
|
189
261
|
pub fn json(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
|
|
190
262
|
let response = rb_self.response(ruby, false)?;
|
|
191
|
-
let json =
|
|
263
|
+
let json =
|
|
264
|
+
rt::block_on(ruby, response.json::<Json>())?.map_err(|err| wreq_error(ruby, err))?;
|
|
192
265
|
crate::serde::serialize(ruby, &json)
|
|
193
266
|
}
|
|
194
267
|
|
|
@@ -211,16 +284,15 @@ impl Response {
|
|
|
211
284
|
}
|
|
212
285
|
|
|
213
286
|
/// Close the response body, dropping any resources.
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
self.body.swap(None);
|
|
287
|
+
///
|
|
288
|
+
/// # Errors
|
|
289
|
+
///
|
|
290
|
+
/// Returns `Wreq::ForkError` before touching a response inherited from the
|
|
291
|
+
/// parent process.
|
|
292
|
+
pub fn close(ruby: &Ruby, rb_self: &Self) -> Result<(), Error> {
|
|
293
|
+
let response = rb_self.0.get(ruby)?;
|
|
294
|
+
gvl::nogvl(|| response.body.swap(None));
|
|
295
|
+
Ok(())
|
|
224
296
|
}
|
|
225
297
|
}
|
|
226
298
|
|
|
@@ -243,5 +315,6 @@ pub fn include(ruby: &Ruby, gem_module: &RModule) -> Result<(), Error> {
|
|
|
243
315
|
response.define_method("json", magnus::method!(Response::json, 0))?;
|
|
244
316
|
response.define_method("chunks", magnus::method!(Response::chunks, 0))?;
|
|
245
317
|
response.define_method("close", magnus::method!(Response::close, 0))?;
|
|
318
|
+
response.define_method("tls_info", magnus::method!(Response::tls_info, 0))?;
|
|
246
319
|
Ok(())
|
|
247
320
|
}
|