diff --git a/Cargo.toml b/Cargo.toml index 5b396ed..f4526ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ name = "wreq_ruby" magnus = { version = "0.8", features = ["bytes"] } rb-sys = { version = "0.9.110", default-features = false } tokio = { version = "1", features = ["full"] } -wreq = { version = "6.0.0-rc.24", features = [ +wreq = { version = "6.0.0-rc.23", features = [ "json", "socks", "stream", @@ -49,5 +49,7 @@ debug = false incremental = false lto = "fat" opt-level = 3 -panic = "abort" strip = true + +[patch.crates-io] +wreq = { git = "https://github.com/0x676e67/wreq" } diff --git a/lib/wreq.rb b/lib/wreq.rb index ae0779f..25be38f 100644 --- a/lib/wreq.rb +++ b/lib/wreq.rb @@ -37,8 +37,6 @@ module Wreq # @param cookies [Array, nil] Cookies to send # @param allow_redirects [Boolean, nil] Whether to follow redirects # @param max_redirects [Integer, nil] Maximum number of redirects to follow - # @param referer [Boolean, nil] Whether to send Referer header on redirects - # @param history [Boolean, nil] Track full redirect chain # @param gzip [Boolean, nil] Enable gzip compression # @param brotli [Boolean, nil] Enable Brotli compression # @param deflate [Boolean, nil] Enable deflate compression @@ -71,8 +69,6 @@ def self.request(method, url, **options) # @param cookies [Array, nil] Cookies to send # @param allow_redirects [Boolean, nil] Whether to follow redirects # @param max_redirects [Integer, nil] Maximum number of redirects to follow - # @param referer [Boolean, nil] Whether to send Referer header on redirects - # @param history [Boolean, nil] Track full redirect chain # @param gzip [Boolean, nil] Enable gzip compression # @param brotli [Boolean, nil] Enable Brotli compression # @param deflate [Boolean, nil] Enable deflate compression @@ -105,8 +101,7 @@ def self.get(url, **options) # @param cookies [Array, nil] Cookies to send # @param allow_redirects [Boolean, nil] Whether to follow redirects # @param max_redirects [Integer, nil] Maximum number of redirects to follow - # @param referer [Boolean, nil] Whether to send Referer header on redirects - # @param history [Boolean, nil] Track full redirect chain + # @param gzip [Boolean, nil] Enable gzip compression # @param brotli [Boolean, nil] Enable Brotli compression # @param deflate [Boolean, nil] Enable deflate compression @@ -139,8 +134,6 @@ def self.head(url, **options) # @param cookies [Array, nil] Cookies to send # @param allow_redirects [Boolean, nil] Whether to follow redirects # @param max_redirects [Integer, nil] Maximum number of redirects to follow - # @param referer [Boolean, nil] Whether to send Referer header on redirects - # @param history [Boolean, nil] Track full redirect chain # @param gzip [Boolean, nil] Enable gzip compression # @param brotli [Boolean, nil] Enable Brotli compression # @param deflate [Boolean, nil] Enable deflate compression @@ -173,8 +166,6 @@ def self.post(url, **options) # @param cookies [Array, nil] Cookies to send # @param allow_redirects [Boolean, nil] Whether to follow redirects # @param max_redirects [Integer, nil] Maximum number of redirects to follow - # @param referer [Boolean, nil] Whether to send Referer header on redirects - # @param history [Boolean, nil] Track full redirect chain # @param gzip [Boolean, nil] Enable gzip compression # @param brotli [Boolean, nil] Enable Brotli compression # @param deflate [Boolean, nil] Enable deflate compression @@ -207,8 +198,6 @@ def self.put(url, **options) # @param cookies [Array, nil] Cookies to send # @param allow_redirects [Boolean, nil] Whether to follow redirects # @param max_redirects [Integer, nil] Maximum number of redirects to follow - # @param referer [Boolean, nil] Whether to send Referer header on redirects - # @param history [Boolean, nil] Track full redirect chain # @param gzip [Boolean, nil] Enable gzip compression # @param brotli [Boolean, nil] Enable Brotli compression # @param deflate [Boolean, nil] Enable deflate compression @@ -241,8 +230,6 @@ def self.delete(url, **options) # @param cookies [Array, nil] Cookies to send # @param allow_redirects [Boolean, nil] Whether to follow redirects # @param max_redirects [Integer, nil] Maximum number of redirects to follow - # @param referer [Boolean, nil] Whether to send Referer header on redirects - # @param history [Boolean, nil] Track full redirect chain # @param gzip [Boolean, nil] Enable gzip compression # @param brotli [Boolean, nil] Enable Brotli compression # @param deflate [Boolean, nil] Enable deflate compression @@ -275,8 +262,6 @@ def self.options(url, **options) # @param cookies [Array, nil] Cookies to send # @param allow_redirects [Boolean, nil] Whether to follow redirects # @param max_redirects [Integer, nil] Maximum number of redirects to follow - # @param referer [Boolean, nil] Whether to send Referer header on redirects - # @param history [Boolean, nil] Track full redirect chain # @param gzip [Boolean, nil] Enable gzip compression # @param brotli [Boolean, nil] Enable Brotli compression # @param deflate [Boolean, nil] Enable deflate compression @@ -309,8 +294,6 @@ def self.trace(url, **options) # @param cookies [Array, nil] Cookies to send # @param allow_redirects [Boolean, nil] Whether to follow redirects # @param max_redirects [Integer, nil] Maximum number of redirects to follow - # @param referer [Boolean, nil] Whether to send Referer header on redirects - # @param history [Boolean, nil] Track full redirect chain # @param gzip [Boolean, nil] Enable gzip compression # @param brotli [Boolean, nil] Enable Brotli compression # @param deflate [Boolean, nil] Enable deflate compression diff --git a/lib/wreq_ruby/client.rb b/lib/wreq_ruby/client.rb index 7c093c9..cbf56b1 100644 --- a/lib/wreq_ruby/client.rb +++ b/lib/wreq_ruby/client.rb @@ -43,9 +43,6 @@ class Client # headers when following redirects. When true, the previous URL will # be sent as the Referer header. # - # @param history [Boolean, nil] Whether to track the full redirect chain - # for each request. Useful for debugging redirect issues. - # # @param allow_redirects [Boolean, nil] Enable automatic following of # HTTP redirects (3xx status codes). When false, redirect responses # will be returned directly to the caller. @@ -252,8 +249,6 @@ def self.new(**options) # @param cookies [Array, nil] Cookies to send # @param allow_redirects [Boolean, nil] Whether to follow redirects # @param max_redirects [Integer, nil] Maximum number of redirects to follow - # @param referer [Boolean, nil] Whether to send Referer header on redirects - # @param history [Boolean, nil] Track full redirect chain # @param gzip [Boolean, nil] Enable gzip compression # @param brotli [Boolean, nil] Enable Brotli compression # @param deflate [Boolean, nil] Enable deflate compression @@ -285,8 +280,6 @@ def request(method, url, **options) # @param cookies [Array, nil] Cookies to send # @param allow_redirects [Boolean, nil] Whether to follow redirects # @param max_redirects [Integer, nil] Maximum number of redirects to follow - # @param referer [Boolean, nil] Whether to send Referer header on redirects - # @param history [Boolean, nil] Track full redirect chain # @param gzip [Boolean, nil] Enable gzip compression # @param brotli [Boolean, nil] Enable Brotli compression # @param deflate [Boolean, nil] Enable deflate compression @@ -318,8 +311,6 @@ def get(url, **options) # @param cookies [Array, nil] Cookies to send # @param allow_redirects [Boolean, nil] Whether to follow redirects # @param max_redirects [Integer, nil] Maximum number of redirects to follow - # @param referer [Boolean, nil] Whether to send Referer header on redirects - # @param history [Boolean, nil] Track full redirect chain # @param gzip [Boolean, nil] Enable gzip compression # @param brotli [Boolean, nil] Enable Brotli compression # @param deflate [Boolean, nil] Enable deflate compression @@ -351,8 +342,6 @@ def head(url, **options) # @param cookies [Array, nil] Cookies to send # @param allow_redirects [Boolean, nil] Whether to follow redirects # @param max_redirects [Integer, nil] Maximum number of redirects to follow - # @param referer [Boolean, nil] Whether to send Referer header on redirects - # @param history [Boolean, nil] Track full redirect chain # @param gzip [Boolean, nil] Enable gzip compression # @param brotli [Boolean, nil] Enable Brotli compression # @param deflate [Boolean, nil] Enable deflate compression @@ -384,8 +373,6 @@ def post(url, **options) # @param cookies [Array, nil] Cookies to send # @param allow_redirects [Boolean, nil] Whether to follow redirects # @param max_redirects [Integer, nil] Maximum number of redirects to follow - # @param referer [Boolean, nil] Whether to send Referer header on redirects - # @param history [Boolean, nil] Track full redirect chain # @param gzip [Boolean, nil] Enable gzip compression # @param brotli [Boolean, nil] Enable Brotli compression # @param deflate [Boolean, nil] Enable deflate compression @@ -417,8 +404,6 @@ def put(url, **options) # @param cookies [Array, nil] Cookies to send # @param allow_redirects [Boolean, nil] Whether to follow redirects # @param max_redirects [Integer, nil] Maximum number of redirects to follow - # @param referer [Boolean, nil] Whether to send Referer header on redirects - # @param history [Boolean, nil] Track full redirect chain # @param gzip [Boolean, nil] Enable gzip compression # @param brotli [Boolean, nil] Enable Brotli compression # @param deflate [Boolean, nil] Enable deflate compression @@ -450,8 +435,6 @@ def delete(url, **options) # @param cookies [Array, nil] Cookies to send # @param allow_redirects [Boolean, nil] Whether to follow redirects # @param max_redirects [Integer, nil] Maximum number of redirects to follow - # @param referer [Boolean, nil] Whether to send Referer header on redirects - # @param history [Boolean, nil] Track full redirect chain # @param gzip [Boolean, nil] Enable gzip compression # @param brotli [Boolean, nil] Enable Brotli compression # @param deflate [Boolean, nil] Enable deflate compression @@ -483,8 +466,6 @@ def options(url, **options) # @param cookies [Array, nil] Cookies to send # @param allow_redirects [Boolean, nil] Whether to follow redirects # @param max_redirects [Integer, nil] Maximum number of redirects to follow - # @param referer [Boolean, nil] Whether to send Referer header on redirects - # @param history [Boolean, nil] Track full redirect chain # @param gzip [Boolean, nil] Enable gzip compression # @param brotli [Boolean, nil] Enable Brotli compression # @param deflate [Boolean, nil] Enable deflate compression @@ -516,8 +497,6 @@ def trace(url, **options) # @param cookies [Array, nil] Cookies to send # @param allow_redirects [Boolean, nil] Whether to follow redirects # @param max_redirects [Integer, nil] Maximum number of redirects to follow - # @param referer [Boolean, nil] Whether to send Referer header on redirects - # @param history [Boolean, nil] Track full redirect chain # @param gzip [Boolean, nil] Enable gzip compression # @param brotli [Boolean, nil] Enable Brotli compression # @param deflate [Boolean, nil] Enable deflate compression diff --git a/lib/wreq_ruby/error.rb b/lib/wreq_ruby/error.rb index 8843b4a..f32cc0f 100644 --- a/lib/wreq_ruby/error.rb +++ b/lib/wreq_ruby/error.rb @@ -22,6 +22,18 @@ class MemoryError < StandardError; end # end class ConnectionError < StandardError; end + # Proxy Connection to the server failed. + # + # Raised when the client cannot establish a connection to the proxy server. + # @example + # begin + # client.get("http://example.com", proxy: "http://invalid-proxy:8080") + # rescue Wreq::ProxyConnectionError => e + # puts "Proxy connection failed: #{e.message}" + # retry_with_different_proxy + # end + class ProxyConnectionError < StandardError; end + # Connection was reset by the server. # # Raised when the server closes the connection unexpectedly. diff --git a/src/client.rs b/src/client.rs index 668139f..b128874 100644 --- a/src/client.rs +++ b/src/client.rs @@ -42,8 +42,6 @@ struct Builder { orig_headers: Option, /// Whether to use referer. referer: Option, - /// Whether to keep track of request history. - history: Option, /// Whether to allow redirects. allow_redirects: Option, /// The maximum number of redirects to follow. @@ -184,7 +182,6 @@ impl Client { // Allow redirects options. apply_option!(set_if_some, builder, params.referer, referer); - apply_option!(set_if_some, builder, params.history, history); apply_option!( set_if_true_with, builder, @@ -201,7 +198,7 @@ impl Client { // Cookie options. apply_option!(set_if_some, builder, params.cookie_store, cookie_store); apply_option!( - set_if_some, + set_if_some_inner, builder, params.cookie_provider, cookie_provider diff --git a/src/client/req.rs b/src/client/req.rs index 7441e7f..6de2abd 100644 --- a/src/client/req.rs +++ b/src/client/req.rs @@ -200,7 +200,7 @@ pub fn execute_request>( // Cookies options. if let Some(cookies) = request.cookies.take() { for cookie in cookies { - builder = builder.header_append(header::COOKIE, cookie); + builder = builder.header(header::COOKIE, cookie); } } diff --git a/src/cookie.rs b/src/cookie.rs index 36d0b0a..88e39cd 100644 --- a/src/cookie.rs +++ b/src/cookie.rs @@ -5,11 +5,7 @@ use magnus::{ Error, Module, Object, RModule, Ruby, Value, function, method, typed_data::Obj, value::ReprValue, }; -use wreq::{ - Uri, - cookie::CookieStore, - header::{self, HeaderMap, HeaderValue}, -}; +use wreq::header::{self, HeaderMap, HeaderValue}; use crate::gvl; @@ -36,7 +32,7 @@ pub struct Cookie(RawCookie<'static>); /// existing cookies more easily, before creating a `Client`. #[derive(Clone, Default)] #[magnus::wrap(class = "Wreq::Jar", free_immediately, size)] -pub struct Jar(Arc); +pub struct Jar(pub Arc); // ===== impl Cookie ===== @@ -203,18 +199,6 @@ impl fmt::Display for Cookie { // ===== impl Jar ===== -impl CookieStore for Jar { - #[inline] - fn set_cookies(&self, cookie_headers: &mut dyn Iterator, uri: &Uri) { - self.0.set_cookies(cookie_headers, uri); - } - - #[inline] - fn cookies(&self, uri: &Uri) -> Vec { - self.0.cookies(uri) - } -} - impl Jar { /// Create a new [`Jar`] with an empty cookie store. pub fn new() -> Self { diff --git a/src/error.rs b/src/error.rs index 42f1744..edb6932 100644 --- a/src/error.rs +++ b/src/error.rs @@ -47,6 +47,11 @@ define_exception!(MEMORY, "MemoryError", exception_runtime_error); // Network connection errors define_exception!(CONNECTION_ERROR, "ConnectionError", exception_runtime_error); +define_exception!( + PROXY_CONNECTION_ERROR, + "ProxyConnectionError", + exception_runtime_error +); define_exception!( CONNECTION_RESET_ERROR, "ConnectionResetError", @@ -116,6 +121,7 @@ pub fn wreq_error_to_magnus(err: wreq::Error) -> MagnusError { is_tls => TLS_ERROR, is_connection_reset => CONNECTION_RESET_ERROR, is_connect => CONNECTION_ERROR, + is_proxy_connect => PROXY_CONNECTION_ERROR, is_decode => DECODING_ERROR, is_redirect => REDIRECT_ERROR, is_timeout => TIMEOUT_ERROR, @@ -127,6 +133,7 @@ pub fn wreq_error_to_magnus(err: wreq::Error) -> MagnusError { pub fn include(ruby: &Ruby) { Lazy::force(&MEMORY, ruby); Lazy::force(&CONNECTION_ERROR, ruby); + Lazy::force(&PROXY_CONNECTION_ERROR, ruby); Lazy::force(&CONNECTION_RESET_ERROR, ruby); Lazy::force(&TLS_ERROR, ruby); Lazy::force(&REQUEST_ERROR, ruby); diff --git a/test/error_handling_test.rb b/test/error_handling_test.rb index 0e902bb..d4377e6 100644 --- a/test/error_handling_test.rb +++ b/test/error_handling_test.rb @@ -65,4 +65,25 @@ def test_empty_response_json assert_instance_of Wreq::DecodingError, e end end + + def test_proxy_error_handling + invalid_proxies = [ + "http://invalid.proxy:8080", + "https://invalid.proxy:8080", + "socks4://invalid.proxy:8080", + "socks4a://invalid.proxy:8080", + "socks5://invalid.proxy:8080", + "socks5h://invalid.proxy:8080" + ] + target_urls = ["https://example.com", "http://example.com"] + + invalid_proxies.each do |proxy| + target_urls.each do |url| + Wreq.get(url, proxy: proxy, timeout: 5) + flunk "Expected proxy connection error but got response" + rescue => e + assert_instance_of Wreq::ProxyConnectionError, e + end + end + end end