Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions lib/wreq_ruby/http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,20 @@ class Version
def to_s
end
end

# Compares HTTP versions by semantic value, not object identity.
#
# This method is implemented by the native extension.
# When comparing with non-{Wreq::Version} objects, it returns false.
#
# @param other [Object] object to compare against
# @return [Boolean] true when both represent the same HTTP version
# @example
# Wreq::Version::HTTP_11 == response.version
unless method_defined?(:==)
def ==(other)
end
end
end

# HTTP status code wrapper.
Expand Down
17 changes: 13 additions & 4 deletions src/client/req.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{net::IpAddr, time::Duration};
use http::header;
use magnus::{RHash, TryConvert, typed_data::Obj, value::ReprValue};
use serde::Deserialize;
use wreq::{Client, Proxy, Version, header::OrigHeaderMap};
use wreq::{Client, Proxy, header::OrigHeaderMap};

use super::body::{Body, Form, Json};
use crate::{
Expand All @@ -13,7 +13,7 @@ use crate::{
error::wreq_error_to_magnus,
extractor::Extractor,
header::Headers,
http::Method,
http::{Method, Version},
rt,
};

Expand Down Expand Up @@ -112,6 +112,10 @@ impl Request {
builder.emulation = Some((*obj).clone());
}

if let Some(v) = hash.get(ruby.to_symbol(stringify!(version))) {
builder.version = Some(Version::try_convert(v)?);
}

if let Some(v) = hash.get(ruby.to_symbol(stringify!(headers))) {
builder.headers = Some(Headers::try_convert(v)?);
}
Expand All @@ -125,7 +129,6 @@ impl Request {
}

builder.proxy = Extractor::<Proxy>::try_convert(keyword)?.into_inner();
builder.version = Extractor::<Version>::try_convert(keyword)?.into_inner();
builder.orig_headers = Extractor::<OrigHeaderMap>::try_convert(keyword)?.into_inner();

Ok(builder)
Expand All @@ -145,7 +148,13 @@ pub fn execute_request<U: AsRef<str>>(
apply_option!(set_if_some_inner, builder, request.emulation, emulation);

// Version options.
apply_option!(set_if_some, builder, request.version, version);
apply_option!(
set_if_some_map,
builder,
request.version,
version,
Version::into_ffi
);

// Timeout options.
apply_option!(
Expand Down
17 changes: 16 additions & 1 deletion src/http.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use magnus::{Error, Module, RModule, Ruby, method, typed_data::Inspect};
use magnus::{Error, Module, RModule, Ruby, TryConvert, Value, method, typed_data::Inspect};

define_ruby_enum!(
/// An HTTP version.
Expand Down Expand Up @@ -41,6 +41,20 @@ impl Version {
pub fn to_s(&self) -> String {
self.into_ffi().inspect()
}

/// Value-based equality for Ruby (`==`).
#[inline]
pub fn equals(&self, other: Value) -> bool {
<&Version>::try_convert(other)
.map(|other| *self == *other)
.unwrap_or(false)
}
}

impl TryConvert for Version {
fn try_convert(value: magnus::Value) -> Result<Self, magnus::Error> {
<&Version>::try_convert(value).cloned()
}
}

// ===== impl StatusCode =====
Expand Down Expand Up @@ -113,6 +127,7 @@ pub fn include(ruby: &Ruby, gem_module: &RModule) -> Result<(), Error> {
version_class.const_set("HTTP_2", Version::HTTP_2)?;
version_class.const_set("HTTP_3", Version::HTTP_3)?;
version_class.define_method("to_s", method!(Version::to_s, 0))?;
version_class.define_method("==", method!(Version::equals, 1))?;

let status_code_class = gem_module.define_class("StatusCode", ruby.class_object())?;
status_code_class.define_method("as_int", method!(StatusCode::as_int, 0))?;
Expand Down
10 changes: 10 additions & 0 deletions test/request_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ def setup
@client = Wreq::Client.new(timeout: 30)
end

def test_spec_http1_version
response = Wreq.get("https://tls.browserleaks.com", version: Wreq::Version::HTTP_11)
assert_equal response.version, Wreq::Version::HTTP_11
end

def test_spec_http2_version
response = Wreq.get("https://tls.browserleaks.com", version: Wreq::Version::HTTP_2)
assert_equal response.version, Wreq::Version::HTTP_2
end

def test_module_get_method
response = Wreq.get("http://localhost:8080/get")
assert_equal 200, response.code
Expand Down