Skip to content

Commit a837dde

Browse files
committed
feat(emulate): parse tls/http2
1 parent 7755340 commit a837dde

10 files changed

Lines changed: 882 additions & 190 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ wreq = { version = "6.0.0-rc.28", features = [
3333
wreq-util = "3.0.0-rc.10"
3434
serde = { version = "1.0", features = ["derive"] }
3535
serde_magnus = "0.10.0"
36+
serde_json = "1.0"
3637
indexmap = { version = "2.12.1", features = ["serde"] }
3738
cookie = "0.18"
3839
bytes = "1.11.1"

lib/wreq_ruby/emulation.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,5 +182,13 @@ class Emulation
182182
def self.new(device: nil, os: nil, skip_http2: false, skip_headers: false)
183183
end
184184
end
185+
186+
unless method_defined?(:parse)
187+
# Parses a string representation of an emulation option.
188+
# @param str [String] String to parse into an emulation option
189+
# @return [Wreq::Emulation] Parsed emulation option
190+
def self.parse(json, permute_extensions: false, psk_skip_session_ticket: false)
191+
end
192+
end
185193
end
186194
end

src/client.rs

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ use crate::{
2525
http::Method,
2626
};
2727

28+
macro_rules! request {
29+
($args:expr, $required:ty) => {{
30+
let args = magnus::scan_args::scan_args::<$required, (), (), (), magnus::RHash, ()>($args)?;
31+
let required = args.required;
32+
let request = crate::client::req::Request::new(&ruby!(), args.keywords)?;
33+
(required, request)
34+
}};
35+
}
36+
2837
/// A builder for `Client`.
2938
#[derive(Default, Deserialize)]
3039
struct Builder {
@@ -127,31 +136,32 @@ pub struct Client(wreq::Client);
127136

128137
impl Builder {
129138
/// Create a new [`Builder`] from Ruby keyword arguments.
130-
fn new(ruby: &magnus::Ruby, keyword: &Value) -> Result<Self, magnus::Error> {
131-
if let Ok(hash) = RHash::try_convert(*keyword) {
139+
fn new(ruby: &magnus::Ruby, keyword: Value) -> Result<Self, magnus::Error> {
140+
if let Ok(hash) = RHash::try_convert(keyword) {
132141
let mut builder: Self = serde_magnus::deserialize(ruby, hash)?;
133142
// extra emulation handling
134-
if let Some(v) = hash.get(ruby.to_symbol("emulation")) {
135-
let emulation_obj = Obj::<Emulation>::try_convert(v)?;
136-
builder.emulation = Some((*emulation_obj).clone());
143+
if let Some(v) = hash.get(ruby.to_symbol(stringify!(emulation))) {
144+
let obj = Obj::<Emulation>::try_convert(v)?;
145+
builder.emulation = Some((*obj).clone());
146+
}
147+
148+
// extra cookie store handling
149+
if let Some(jar) = hash.get(ruby.to_symbol(stringify!(cookie_provider))) {
150+
let obj = Obj::<Jar>::try_convert(jar)?;
151+
builder.cookie_provider = Some((*obj).clone());
137152
}
138153

139154
// extra user agent handling
140-
builder.user_agent = Extractor::<HeaderValue>::try_convert(*keyword)?.into_inner();
155+
builder.user_agent = Extractor::<HeaderValue>::try_convert(keyword)?.into_inner();
141156

142157
// extra headers handling
143-
builder.headers = Extractor::<HeaderMap>::try_convert(*keyword)?.into_inner();
158+
builder.headers = Extractor::<HeaderMap>::try_convert(keyword)?.into_inner();
144159

145160
// extra original headers handling
146-
builder.orig_headers = Extractor::<OrigHeaderMap>::try_convert(*keyword)?.into_inner();
161+
builder.orig_headers = Extractor::<OrigHeaderMap>::try_convert(keyword)?.into_inner();
147162

148163
// extra proxy handling
149-
builder.proxy = Extractor::<Proxy>::try_convert(*keyword)?.into_inner();
150-
151-
// extra cookie store handling
152-
if let Some(jar) = hash.get(ruby.to_symbol("cookie_provider")) {
153-
builder.cookie_provider = Some((*Obj::<Jar>::try_convert(jar)?).clone());
154-
}
164+
builder.proxy = Extractor::<Proxy>::try_convert(keyword)?.into_inner();
155165

156166
return Ok(builder);
157167
}
@@ -166,12 +176,12 @@ impl Client {
166176
/// Create a new [`Client`] with the given keyword arguments.
167177
pub fn new(ruby: &Ruby, kwargs: &[Value]) -> Result<Self, magnus::Error> {
168178
if let Some(kwargs) = kwargs.first() {
169-
let mut params = Builder::new(ruby, kwargs)?;
179+
let mut params = Builder::new(ruby, *kwargs)?;
170180
gvl::nogvl(|| {
171181
let mut builder = wreq::Client::builder();
172182

173183
// Emulation options.
174-
apply_option!(set_if_some_inner, builder, params.emulation, emulation);
184+
apply_option!(set_if_some, builder, params.emulation, emulation);
175185

176186
// User agent options.
177187
apply_option!(set_if_some, builder, params.user_agent, user_agent);
@@ -312,63 +322,63 @@ impl Client {
312322
/// Send a HTTP request.
313323
#[inline]
314324
pub fn request(rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
315-
let ((method, url), request) = extract_request!(args, (Obj<Method>, String));
325+
let ((method, url), request) = request!(args, (Obj<Method>, String));
316326
execute_request(rb_self.0.clone(), *method, url, request)
317327
}
318328

319329
/// Send a GET request.
320330
#[inline]
321331
pub fn get(rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
322-
let ((url,), request) = extract_request!(args, (String,));
332+
let ((url,), request) = request!(args, (String,));
323333
execute_request(rb_self.0.clone(), Method::GET, url, request)
324334
}
325335

326336
/// Send a POST request.
327337
#[inline]
328338
pub fn post(rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
329-
let ((url,), request) = extract_request!(args, (String,));
339+
let ((url,), request) = request!(args, (String,));
330340
execute_request(rb_self.0.clone(), Method::POST, url, request)
331341
}
332342

333343
/// Send a PUT request.
334344
#[inline]
335345
pub fn put(rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
336-
let ((url,), request) = extract_request!(args, (String,));
346+
let ((url,), request) = request!(args, (String,));
337347
execute_request(rb_self.0.clone(), Method::PUT, url, request)
338348
}
339349

340350
/// Send a DELETE request.
341351
#[inline]
342352
pub fn delete(rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
343-
let ((url,), request) = extract_request!(args, (String,));
353+
let ((url,), request) = request!(args, (String,));
344354
execute_request(rb_self.0.clone(), Method::DELETE, url, request)
345355
}
346356

347357
/// Send a HEAD request.
348358
#[inline]
349359
pub fn head(rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
350-
let ((url,), request) = extract_request!(args, (String,));
360+
let ((url,), request) = request!(args, (String,));
351361
execute_request(rb_self.0.clone(), Method::HEAD, url, request)
352362
}
353363

354364
/// Send an OPTIONS request.
355365
#[inline]
356366
pub fn options(rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
357-
let ((url,), request) = extract_request!(args, (String,));
367+
let ((url,), request) = request!(args, (String,));
358368
execute_request(rb_self.0.clone(), Method::OPTIONS, url, request)
359369
}
360370

361371
/// Send a TRACE request.
362372
#[inline]
363373
pub fn trace(rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
364-
let ((url,), request) = extract_request!(args, (String,));
374+
let ((url,), request) = request!(args, (String,));
365375
execute_request(rb_self.0.clone(), Method::TRACE, url, request)
366376
}
367377

368378
/// Send a PATCH request.
369379
#[inline]
370380
pub fn patch(rb_self: &Self, args: &[Value]) -> Result<Response, magnus::Error> {
371-
let ((url,), request) = extract_request!(args, (String,));
381+
let ((url,), request) = request!(args, (String,));
372382
execute_request(rb_self.0.clone(), Method::PATCH, url, request)
373383
}
374384
}

src/client/req.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,14 @@ impl Request {
109109
let mut builder: Self = serde_magnus::deserialize(ruby, kwargs)?;
110110

111111
// extra emulation handling
112-
if let Some(v) = hash.get(ruby.to_symbol("emulation")) {
113-
let emulation_obj = Obj::<Emulation>::try_convert(v)?;
114-
builder.emulation = Some((*emulation_obj).clone());
112+
if let Some(v) = hash.get(ruby.to_symbol(stringify!(emulation))) {
113+
let obj = Obj::<Emulation>::try_convert(v)?;
114+
builder.emulation = Some((*obj).clone());
115+
}
116+
117+
// extra body handling
118+
if let Some(body) = hash.get(ruby.to_symbol(stringify!(body))) {
119+
builder.body = Some(Body::try_convert(body)?);
115120
}
116121

117122
// extra version handling
@@ -129,11 +134,6 @@ impl Request {
129134
// extra proxy handling
130135
builder.proxy = Extractor::<Proxy>::try_convert(kwargs)?.into_inner();
131136

132-
// extra body handling
133-
if let Some(body) = hash.get(ruby.to_symbol("body")) {
134-
builder.body = Some(Body::try_convert(body)?);
135-
}
136-
137137
Ok(builder)
138138
}
139139
}
@@ -148,7 +148,7 @@ pub fn execute_request<U: AsRef<str>>(
148148
let mut builder = client.request(method.into_ffi(), url.as_ref());
149149

150150
// Emulation options.
151-
apply_option!(set_if_some_inner, builder, request.emulation, emulation);
151+
apply_option!(set_if_some, builder, request.emulation, emulation);
152152

153153
// Version options.
154154
apply_option!(set_if_some, builder, request.version, version);

0 commit comments

Comments
 (0)