wreq 1.0.0-aarch64-linux

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,208 @@
1
+ # frozen_string_literal: true
2
+
3
+ unless defined?(Wreq)
4
+ module Wreq
5
+ # HTTP response object containing status, headers, and body.
6
+ #
7
+ # This class wraps a native Rust implementation providing efficient
8
+ # access to HTTP response data including status codes, headers, body
9
+ # content, and streaming capabilities.
10
+ #
11
+ # @example Basic response handling
12
+ # response = client.get("https://api.example.com")
13
+ # puts response.status.as_int # => 200
14
+ # puts response.text
15
+ #
16
+ # @example JSON response
17
+ # response = client.get("https://api.example.com/data")
18
+ # data = response.json
19
+ #
20
+ # @example Streaming response
21
+ # response = client.get("https://example.com/large-file")
22
+ # response.stream.each do |chunk|
23
+ # # Process chunk
24
+ # end
25
+ class Response
26
+ # Get the HTTP status code as an integer.
27
+ #
28
+ # @return [Integer] Status code (e.g., 200, 404, 500)
29
+ # @example
30
+ # response.code # => 200
31
+ def code
32
+ end
33
+
34
+ # Get the HTTP status code object.
35
+ #
36
+ # @return [Wreq::StatusCode] Status code wrapper with helper methods
37
+ # @example
38
+ # status = response.status
39
+ # status.success? # => true
40
+ def status
41
+ end
42
+
43
+ # Get the HTTP protocol version used.
44
+ #
45
+ # @return [Wreq::Version] HTTP version (HTTP/1.1, HTTP/2, etc.)
46
+ # @example
47
+ # response.version # => Wreq::Version::HTTP_11
48
+ def version
49
+ end
50
+
51
+ # Get the final URL after redirects.
52
+ #
53
+ # @return [String] The final URL
54
+ # @example
55
+ # response.url # => "https://example.com/final-page"
56
+ def url
57
+ end
58
+
59
+ # Get the content length if known.
60
+ #
61
+ # @return [Integer, nil] Content length in bytes, or nil if unknown
62
+ # @example
63
+ # response.content_length # => 1024
64
+ def content_length
65
+ end
66
+
67
+ # Get the local socket address.
68
+ #
69
+ # @return [String, nil] Local address (e.g., "127.0.0.1:54321"), or nil
70
+ # @example
71
+ # response.local_addr # => "192.168.1.100:54321"
72
+ def local_addr
73
+ end
74
+
75
+ # Get the remote socket address.
76
+ #
77
+ # @return [String, nil] Remote address (e.g., "93.184.216.34:443"), or nil
78
+ # @example
79
+ # response.remote_addr # => "93.184.216.34:443"
80
+ def remote_addr
81
+ end
82
+
83
+ # Get the response bytes as a binary string.
84
+ # @return [String] Response body as binary data
85
+ # @example
86
+ # binary_data = response.bytes
87
+ # puts binary_data.size # => 1024
88
+ def bytes
89
+ end
90
+
91
+ # Get the response body as text.
92
+ #
93
+ # @return [String] Response body decoded as UTF-8 text
94
+ # @example
95
+ # html = response.text
96
+ # puts html
97
+ # @raise [Wreq::DecodingError] if body cannot be decoded as binary
98
+ def text
99
+ end
100
+
101
+ # Get the response body as text with a specific charset.
102
+ # This method allows you to specify a default encoding
103
+ # to use when decoding the response body.
104
+ # # @param default_encoding [String] Default encoding to use (e.g., "UTF-8")
105
+ # # @return [String] Response body decoded as text using the specified encoding
106
+ # @example
107
+ # html = response.text_with_charset("ISO-8859-1")
108
+ # puts html
109
+ # @raise [Wreq::DecodingError] if body cannot be decoded with the specified encoding
110
+ def text_with_charset(default_encoding)
111
+ end
112
+
113
+ # Parse the response body as JSON.
114
+ #
115
+ # @return [Object] Parsed JSON (Hash, Array, String, Integer, Float, Boolean, nil)
116
+ # @raise [Wreq::DecodingError] if body is not valid JSON
117
+ # @example
118
+ # data = response.json
119
+ # puts data["key"]
120
+ def json
121
+ end
122
+
123
+ # Get a streaming iterator for the response body, yielding each chunk.
124
+ #
125
+ # This method allows you to process large HTTP responses efficiently,
126
+ # by yielding each chunk of the body as it arrives, without loading
127
+ # the entire response into memory.
128
+ #
129
+ # @return An iterator over response body chunks (binary String)
130
+ # @yield [chunk] Each chunk of the response body as a binary String
131
+ # @example Save response to file
132
+ # File.open("output.bin", "wb") do |f|
133
+ # response.chunks { |chunk| f.write(chunk) }
134
+ # end
135
+ # @example Count total bytes streamed
136
+ # total = 0
137
+ # response.chunks { |chunk| total += chunk.bytesize }
138
+ # puts "Downloaded #{total} bytes"
139
+ #
140
+ # Note: The returned Receiver is only for reading response bodies, not for uploads.
141
+ def chunks
142
+ end
143
+
144
+ # Close the response and free associated resources.
145
+ #
146
+ # @return [void]
147
+ # @example
148
+ # response.close
149
+ def close
150
+ end
151
+ end
152
+ end
153
+ end
154
+
155
+ # ======================== Ruby API Extensions ========================
156
+
157
+ module Wreq
158
+ class Response
159
+ # Returns a compact string representation of the response.
160
+ #
161
+ # Format: #<Wreq::Response STATUS content-type="..." body=SIZE>
162
+ #
163
+ # @return [String] Compact formatted response information
164
+ # @example
165
+ # puts response.to_s
166
+ # # => #<Wreq::Response 200 content-type="application/json" body=456B>
167
+ def to_s
168
+ parts = ["#<Wreq::Response"]
169
+
170
+ # Status code
171
+ parts << code.to_s
172
+
173
+ # Content-Type header if present
174
+ if headers.respond_to?(:get)
175
+ content_type = headers.get("content-type")
176
+ parts << "content-type=#{content_type.inspect}" if content_type
177
+ end
178
+
179
+ # Body size
180
+ if content_length
181
+ parts << "body=#{format_bytes(content_length)}"
182
+ end
183
+
184
+ parts.join(" ") + ">"
185
+ end
186
+
187
+ private
188
+
189
+ def format_bytes(bytes)
190
+ return "0B" if bytes.zero?
191
+
192
+ units = ["B", "KB", "MB", "GB"]
193
+ size = bytes.to_f
194
+ unit_index = 0
195
+
196
+ while size >= 1024 && unit_index < units.length - 1
197
+ size /= 1024.0
198
+ unit_index += 1
199
+ end
200
+
201
+ if unit_index == 0
202
+ "#{size.to_i}#{units[unit_index]}"
203
+ else
204
+ "#{size.round(1)}#{units[unit_index]}"
205
+ end
206
+ end
207
+ end
208
+ end
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Build a platform-specific gem with pre-compiled native extensions.
5
+ #
6
+ # Usage: ruby script/build_platform_gem.rb PLATFORM
7
+ # Example: ruby script/build_platform_gem.rb arm64-darwin
8
+ #
9
+ # Expects compiled .bundle/.so files in version-specific directories:
10
+ # lib/wreq_ruby/3.3/wreq_ruby.bundle
11
+ # lib/wreq_ruby/3.4/wreq_ruby.bundle
12
+ # lib/wreq_ruby/4.0/wreq_ruby.bundle
13
+
14
+ require "rubygems/package"
15
+ require "fileutils"
16
+
17
+ platform = ARGV.fetch(0) { abort "Usage: #{$0} PLATFORM" }
18
+
19
+ spec = Gem::Specification.load("wreq.gemspec")
20
+ spec.platform = Gem::Platform.new(platform)
21
+ spec.extensions = []
22
+ # Keep in sync with Rakefile cross_compiling block
23
+ spec.required_ruby_version = Gem::Requirement.new(">= 3.3", "< 4.1.dev")
24
+
25
+ # Add version-specific compiled extensions
26
+ binaries = Dir.glob("lib/wreq_ruby/[0-9]*/*.{bundle,so}")
27
+ abort "No compiled binaries found in lib/wreq_ruby/*/. Did compilation succeed?" if binaries.empty?
28
+ spec.files += binaries
29
+
30
+ FileUtils.mkdir_p("pkg")
31
+ gem_file = Gem::Package.build(spec)
32
+ FileUtils.mv(gem_file, "pkg/")
33
+
34
+ puts "Built: pkg/#{File.basename(gem_file)}"
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class ClientCookieProviderTest < Minitest::Test
6
+ HOST = "http://localhost:8080"
7
+
8
+ def setup
9
+ @jar = Wreq::Jar.new
10
+ @client = Wreq::Client.new(
11
+ cookie_store: true,
12
+ cookie_provider: @jar,
13
+ allow_redirects: true
14
+ )
15
+ end
16
+
17
+ def test_custom_jar_captures_set_cookie_and_sends_back
18
+ # starts empty
19
+ assert_kind_of Array, @jar.get_all
20
+ assert_equal 0, @jar.get_all.length
21
+
22
+ # server sets cookie; client follows redirect; jar should store it
23
+ res1 = @client.get("#{HOST}/cookies/set?foo=bar")
24
+ assert_equal 200, res1.code
25
+
26
+ names = @jar.get_all.map(&:name)
27
+ assert_includes names, "foo"
28
+
29
+ # subsequent request should send the stored cookie automatically
30
+ res2 = @client.get("#{HOST}/cookies")
31
+ assert_equal 200, res2.code
32
+ body = res2.json
33
+ assert_kind_of Hash, body
34
+ assert_equal "bar", body.dig("cookies", "foo")
35
+ end
36
+
37
+ def test_prepopulated_jar_is_used_by_client
38
+ # pre-populate jar
39
+ @jar.add_cookie_str("pref=1; Path=/", "#{HOST}/")
40
+
41
+ res = @client.get("#{HOST}/cookies")
42
+ assert_equal 200, res.code
43
+ cookies = res.json["cookies"]
44
+ assert_equal "1", cookies["pref"]
45
+ end
46
+ end
@@ -0,0 +1,136 @@
1
+ require "test_helper"
2
+
3
+ class ClientTest < Minitest::Test
4
+ def setup
5
+ @client = Wreq::Client.new
6
+ end
7
+
8
+ def test_client_creation
9
+ refute_nil @client
10
+ assert_instance_of Wreq::Client, @client
11
+ end
12
+
13
+ def test_client_with_configuration
14
+ client = Wreq::Client.new(
15
+ timeout: 30,
16
+ headers: {"User-Agent" => "wreq-ruby/test"}
17
+ )
18
+ refute_nil client
19
+ assert_instance_of Wreq::Client, client
20
+ end
21
+
22
+ def test_get_request
23
+ response = @client.get("http://localhost:8080/get")
24
+ refute_nil response
25
+ assert_equal 200, response.code
26
+ end
27
+
28
+ def test_post_request
29
+ response = @client.post("http://localhost:8080/post",
30
+ json: {test: "wreq-ruby"})
31
+ refute_nil response
32
+ assert_equal 200, response.code
33
+ end
34
+
35
+ def test_put_request
36
+ response = @client.put("http://localhost:8080/put",
37
+ json: {data: "test"})
38
+ refute_nil response
39
+ assert_equal 200, response.code
40
+ end
41
+
42
+ def test_delete_request
43
+ response = @client.delete("http://localhost:8080/delete")
44
+ refute_nil response
45
+ assert_equal 200, response.code
46
+ end
47
+
48
+ def test_patch_request
49
+ response = @client.patch("http://localhost:8080/patch",
50
+ json: {update: "field"})
51
+ refute_nil response
52
+ assert_equal 200, response.code
53
+ end
54
+
55
+ def test_request_with_query_params
56
+ response = @client.get("http://localhost:8080/get",
57
+ query: {"param" => "value"})
58
+ refute_nil response
59
+ assert_equal 200, response.code
60
+ assert_includes response.text, "param"
61
+ end
62
+
63
+ def test_request_with_form_data
64
+ response = @client.post("http://localhost:8080/post",
65
+ form: {"field" => "value"})
66
+ refute_nil response
67
+ assert_equal 200, response.code
68
+ assert_includes response.text, "field"
69
+ end
70
+
71
+ def test_request_with_raw_body
72
+ response = @client.post("http://localhost:8080/post",
73
+ body: "raw content",
74
+ headers: {"Content-Type" => "text/plain"})
75
+ refute_nil response
76
+ assert_equal 200, response.code
77
+ assert_includes response.text, "raw content"
78
+ end
79
+
80
+ def test_basic_authentication
81
+ response = @client.get("http://localhost:8080/basic-auth/user/pass",
82
+ basic_auth: ["user", "pass"])
83
+ refute_nil response
84
+ assert_equal 200, response.code
85
+ end
86
+
87
+ def test_bearer_authentication
88
+ response = @client.get("http://localhost:8080/bearer",
89
+ bearer_auth: "test-token")
90
+ refute_nil response
91
+ assert_equal 200, response.code
92
+ assert_includes response.text, "test-token"
93
+ end
94
+
95
+ def test_redirect_following
96
+ response = @client.get("http://localhost:8080/redirect/1",
97
+ allow_redirects: true)
98
+ refute_nil response
99
+ assert_equal 200, response.code
100
+ end
101
+
102
+ def test_redirect_blocking
103
+ response = @client.get("http://localhost:8080/redirect/1",
104
+ allow_redirects: false)
105
+ refute_nil response
106
+ assert_equal 302, response.code
107
+ end
108
+
109
+ def test_gzip_compression
110
+ response = @client.get("http://localhost:8080/gzip", gzip: true)
111
+ refute_nil response
112
+ assert_equal 200, response.code
113
+ end
114
+
115
+ def test_timeout_handling
116
+ # Test that short timeouts properly raise exceptions
117
+ assert_raises(Wreq::TimeoutError) do
118
+ @client.get("http://localhost:8080/delay/10", timeout: 1)
119
+ end
120
+
121
+ # Test that reasonable timeouts work normally
122
+ start_time = Time.now
123
+ response = @client.get("http://localhost:8080/delay/1", timeout: 5)
124
+ elapsed = Time.now - start_time
125
+
126
+ refute_nil response
127
+ assert_equal 200, response.code
128
+ assert elapsed < 5, "Request should complete within timeout"
129
+ end
130
+
131
+ def test_status_codes
132
+ response = @client.get("http://localhost:8080/status/404")
133
+ refute_nil response
134
+ assert_equal 404, response.code
135
+ end
136
+ end
@@ -0,0 +1,166 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class CookieTest < Minitest::Test
6
+ def setup
7
+ @jar = Wreq::Jar.new
8
+ @base_url = "https://example.com"
9
+ end
10
+
11
+ def test_jar_initially_empty
12
+ assert_instance_of Wreq::Jar, @jar
13
+ cookies = begin
14
+ Wreq::Jar.get_all(@jar)
15
+ rescue
16
+ @jar.get_all
17
+ end # support either binding style
18
+ assert_kind_of Array, cookies
19
+ assert_equal 0, cookies.length
20
+ end
21
+
22
+ def test_add_cookie_str_and_get_all
23
+ set_cookie = "sid=abc123; Path=/; Domain=example.com; HttpOnly; Secure"
24
+ @jar.add_cookie_str(set_cookie, @base_url)
25
+
26
+ cookies = @jar.get_all
27
+ assert_kind_of Array, cookies
28
+ assert_equal 1, cookies.length
29
+
30
+ c = cookies.first
31
+ assert_instance_of Wreq::Cookie, c
32
+ assert_equal "sid", c.name
33
+ assert_equal "abc123", c.value
34
+
35
+ # attributes parsed from Set-Cookie
36
+ assert_equal "/", c.path
37
+ assert_equal "example.com", c.domain
38
+
39
+ # predicate-ish flags
40
+ assert_equal true, (c.http_only || c.http_only?)
41
+ assert_equal true, (c.secure || c.secure?)
42
+ end
43
+
44
+ def test_add_multiple_and_remove
45
+ @jar.add_cookie_str("a=1; Path=/", @base_url)
46
+ @jar.add_cookie_str("b=2; Path=/", @base_url)
47
+ @jar.add_cookie_str("c=3; Path=/", @base_url)
48
+
49
+ cookies = @jar.get_all
50
+ assert_equal 3, cookies.length
51
+
52
+ # remove one by name
53
+ @jar.remove("b", @base_url)
54
+ names = @jar.get_all.map(&:name)
55
+ refute_includes names, "b"
56
+ assert_includes names, "a"
57
+ assert_includes names, "c"
58
+ end
59
+
60
+ def test_clear
61
+ @jar.add_cookie_str("x=1; Path=/", @base_url)
62
+ @jar.add_cookie_str("y=2; Path=/", @base_url)
63
+ refute_empty @jar.get_all
64
+
65
+ @jar.clear
66
+ assert_empty @jar.get_all
67
+ end
68
+
69
+ def test_max_age_and_expires_optional
70
+ # Max-Age only
71
+ @jar.clear
72
+ @jar.add_cookie_str("ma=1; Max-Age=3600; Path=/", @base_url)
73
+ c1 = @jar.get_all.find { |c| c.name == "ma" }
74
+ assert c1
75
+ # can be nil or Integer; just ensure responds and is truthy integer
76
+ if (v = c1.max_age)
77
+ assert_kind_of Integer, v
78
+ assert_operator v, :>=, 0
79
+ end
80
+
81
+ # Expires only
82
+ @jar.clear
83
+ t = Time.now + 3600
84
+ @jar.add_cookie_str("exp=1; Expires=#{t.gmtime.strftime("%a, %d %b %Y %H:%M:%S GMT")}; Path=/", @base_url)
85
+ c2 = @jar.get_all.find { |c| c.name == "exp" }
86
+ assert c2
87
+ # expires returns Float (unix seconds) or nil
88
+ if (e = c2.expires)
89
+ assert_kind_of Float, e
90
+ assert_operator e, :>, Time.now.to_f - 1_000_000 # sanity bound
91
+ end
92
+ end
93
+
94
+ # -------- Wreq::Cookie unit tests --------
95
+
96
+ def test_cookie_new_minimal
97
+ c = Wreq::Cookie.new("sid", "abc")
98
+
99
+ assert_instance_of Wreq::Cookie, c
100
+ assert_equal "sid", c.name
101
+ assert_equal "abc", c.value
102
+
103
+ assert_nil c.path
104
+ assert_nil c.domain
105
+ assert_nil c.max_age
106
+ assert_nil c.expires
107
+
108
+ assert_equal false, (c.http_only || c.http_only?)
109
+ assert_equal false, (c.secure || c.secure?)
110
+ assert_equal false, c.same_site_lax?
111
+ assert_equal false, c.same_site_strict?
112
+ end
113
+
114
+ def test_cookie_new_full_attributes
115
+ exp = Time.now.to_f + 7200.0
116
+ c = Wreq::Cookie.new("sess", "v",
117
+ domain: "example.com",
118
+ path: "/",
119
+ max_age: 3600,
120
+ expires: exp,
121
+ http_only: true,
122
+ secure: true,
123
+ same_site: Wreq::SameSite::Lax)
124
+
125
+ assert_equal "sess", c.name
126
+ assert_equal "v", c.value
127
+ assert_equal "example.com", c.domain
128
+ assert_equal "/", c.path
129
+
130
+ # Max-Age returns seconds as Integer
131
+ assert_equal 3600, c.max_age
132
+
133
+ # Expires returns Float seconds-since-epoch (with small tolerance)
134
+ assert c.expires
135
+ assert_kind_of Float, c.expires
136
+ assert_in_delta exp, c.expires, 2.0
137
+
138
+ assert_equal true, (c.http_only || c.http_only?)
139
+ assert_equal true, (c.secure || c.secure?)
140
+ # constructor currently sets SameSite to none
141
+ assert_equal true, c.same_site_lax?
142
+ assert_equal false, c.same_site_strict?
143
+ end
144
+
145
+ def test_same_site_flags_from_parsed_header
146
+ @jar.clear
147
+ @jar.add_cookie_str("s1=1; Path=/; SameSite=Strict", @base_url)
148
+ @jar.add_cookie_str("s2=1; Path=/; SameSite=Lax", @base_url)
149
+
150
+ cookies = @jar.get_all
151
+ h = cookies.to_h { |ck| [ck.name, [ck.same_site_strict?, ck.same_site_lax?]] }
152
+
153
+ assert_equal [true, false], h["s1"]
154
+ assert_equal [false, true], h["s2"]
155
+ end
156
+
157
+ def test_request_cookie_value_percent_encoding
158
+ raw_value = "hello world?"
159
+ client = Wreq::Client.new
160
+ resp = client.get(
161
+ "http://localhost:8080/cookies",
162
+ cookies: {"mykey" => raw_value}
163
+ )
164
+ assert_includes resp.text, "hello%20world%3F"
165
+ end
166
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class EmulationTest < Minitest::Test
6
+ def test_all_emulation_device_constants_are_non_nil
7
+ Wreq::EmulationDevice.constants.each do |name|
8
+ const = Wreq::EmulationDevice.const_get(name)
9
+ assert_instance_of Wreq::EmulationDevice, const,
10
+ "#{name} should be EmulationDevice, got #{const.inspect}"
11
+ end
12
+ end
13
+
14
+ def test_all_emulation_os_constants_are_non_nil
15
+ Wreq::EmulationOS.constants.each do |name|
16
+ const = Wreq::EmulationOS.const_get(name)
17
+ assert_instance_of Wreq::EmulationOS, const,
18
+ "#{name} should be EmulationOS, got #{const.inspect}"
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,89 @@
1
+ require "test_helper"
2
+
3
+ class ErrorHandlingTest < Minitest::Test
4
+ def test_network_error_handling
5
+ # Try to connect to a non-existent domain
6
+ response = Wreq.get("https://definitely-not-a-real-domain-12345.com")
7
+ flunk "Expected network error but got response: #{response.code}"
8
+ rescue => e
9
+ assert_instance_of Wreq::ConnectionError, e
10
+ # Network errors should be caught and wrapped appropriately
11
+ end
12
+
13
+ def test_invalid_url_handling
14
+ # Invalid URL format
15
+ response = Wreq.get("not-a-valid-url")
16
+ flunk "Expected URL error but got response: #{response.code}"
17
+ rescue => e
18
+ assert_instance_of Wreq::BuilderError, e
19
+ end
20
+
21
+ def test_http_error_status_codes
22
+ # These should not raise errors, just return responses with error codes
23
+ [400, 401, 403, 404, 500, 502, 503].each do |status_code|
24
+ response = Wreq.get("http://localhost:8080/status/#{status_code}")
25
+ assert_equal status_code, response.code
26
+ # Should not raise an exception for HTTP error codes
27
+ end
28
+ end
29
+
30
+ def test_timeout_handling
31
+ # Test timeout with a delay that should definitely cause timeout
32
+
33
+ # Request with a very short timeout that should fail
34
+ response = Wreq.get("http://localhost:8080/delay/10", timeout: 1)
35
+ # If we get here, the request didn't timeout (unexpected)
36
+ flunk "Expected timeout error but got response: #{response.code}"
37
+ rescue => e
38
+ # Timeout error is expected
39
+ assert_instance_of Wreq::TimeoutError, e
40
+ # Could also check error message contains timeout-related keywords
41
+ end
42
+
43
+ def test_invalid_json_response
44
+ # Get a non-JSON response and try to parse as JSON
45
+ response = Wreq.get("http://localhost:8080/html")
46
+ assert_equal 200, response.code
47
+
48
+ # Should raise an error when trying to parse HTML as JSON
49
+ begin
50
+ response.json
51
+ rescue => e
52
+ assert_instance_of Wreq::DecodingError, e
53
+ end
54
+ end
55
+
56
+ def test_empty_response_json
57
+ response = Wreq.get("http://localhost:8080/status/204")
58
+ assert_equal 204, response.code
59
+ assert_equal "", response.text
60
+
61
+ # Empty body should raise error when parsing as JSON
62
+ begin
63
+ response.json
64
+ rescue => e
65
+ assert_instance_of Wreq::DecodingError, e
66
+ end
67
+ end
68
+
69
+ def test_proxy_error_handling
70
+ invalid_proxies = [
71
+ "http://invalid.proxy:8080",
72
+ "https://invalid.proxy:8080",
73
+ "socks4://invalid.proxy:8080",
74
+ "socks4a://invalid.proxy:8080",
75
+ "socks5://invalid.proxy:8080",
76
+ "socks5h://invalid.proxy:8080"
77
+ ]
78
+ target_urls = ["https://example.com", "http://example.com"]
79
+
80
+ invalid_proxies.each do |proxy|
81
+ target_urls.each do |url|
82
+ Wreq.get(url, proxy: proxy, timeout: 5)
83
+ flunk "Expected proxy connection error but got response"
84
+ rescue => e
85
+ assert_instance_of Wreq::ProxyConnectionError, e
86
+ end
87
+ end
88
+ end
89
+ end