wreq 1.0.0-x86_64-linux → 1.2.0-x86_64-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.
- checksums.yaml +4 -4
- data/README.md +8 -8
- data/examples/cookie.rb +24 -0
- data/examples/{emulation_request.rb → emulate_request.rb} +8 -8
- data/lib/wreq.rb +45 -55
- data/lib/wreq_ruby/3.3/wreq_ruby.so +0 -0
- data/lib/wreq_ruby/3.4/wreq_ruby.so +0 -0
- data/lib/wreq_ruby/4.0/wreq_ruby.so +0 -0
- data/lib/wreq_ruby/client.rb +71 -63
- data/lib/wreq_ruby/cookie.rb +21 -9
- data/lib/wreq_ruby/{emulation.rb → emulate.rb} +74 -29
- data/lib/wreq_ruby/error.rb +1 -3
- data/lib/wreq_ruby/header.rb +8 -0
- data/lib/wreq_ruby/http.rb +14 -0
- data/lib/wreq_ruby/response.rb +22 -21
- data/test/client_cookie_test.rb +1 -1
- data/test/cookie_test.rb +30 -16
- data/test/emulation_test.rb +8 -8
- data/test/error_handling_test.rb +4 -1
- data/test/inspect_test.rb +125 -0
- data/test/stream_test.rb +292 -2
- metadata +6 -4
data/lib/wreq_ruby/response.rb
CHANGED
|
@@ -88,26 +88,16 @@ unless defined?(Wreq)
|
|
|
88
88
|
def bytes
|
|
89
89
|
end
|
|
90
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
91
|
# Get the response body as text with a specific charset.
|
|
102
92
|
# This method allows you to specify a default encoding
|
|
103
93
|
# to use when decoding the response body.
|
|
104
94
|
# # @param default_encoding [String] Default encoding to use (e.g., "UTF-8")
|
|
105
95
|
# # @return [String] Response body decoded as text using the specified encoding
|
|
106
96
|
# @example
|
|
107
|
-
# html = response.
|
|
97
|
+
# html = response.text("ISO-8859-1")
|
|
108
98
|
# puts html
|
|
109
99
|
# @raise [Wreq::DecodingError] if body cannot be decoded with the specified encoding
|
|
110
|
-
def
|
|
100
|
+
def text(default_encoding: "UTF-8")
|
|
111
101
|
end
|
|
112
102
|
|
|
113
103
|
# Parse the response body as JSON.
|
|
@@ -120,14 +110,17 @@ unless defined?(Wreq)
|
|
|
120
110
|
def json
|
|
121
111
|
end
|
|
122
112
|
|
|
123
|
-
#
|
|
113
|
+
# Stream the response body, yielding each chunk to the given block.
|
|
124
114
|
#
|
|
125
115
|
# This method allows you to process large HTTP responses efficiently,
|
|
126
116
|
# by yielding each chunk of the body as it arrives, without loading
|
|
127
117
|
# the entire response into memory.
|
|
128
118
|
#
|
|
129
|
-
# @return
|
|
119
|
+
# @return [nil]
|
|
130
120
|
# @yield [chunk] Each chunk of the response body as a binary String
|
|
121
|
+
# @raise [LocalJumpError] if called without a block
|
|
122
|
+
# @raise [Wreq::TimeoutError, Wreq::BodyError, Wreq::ConnectionResetError, Wreq::RequestError]
|
|
123
|
+
# if streaming fails while reading the response body
|
|
131
124
|
# @example Save response to file
|
|
132
125
|
# File.open("output.bin", "wb") do |f|
|
|
133
126
|
# response.chunks { |chunk| f.write(chunk) }
|
|
@@ -137,7 +130,7 @@ unless defined?(Wreq)
|
|
|
137
130
|
# response.chunks { |chunk| total += chunk.bytesize }
|
|
138
131
|
# puts "Downloaded #{total} bytes"
|
|
139
132
|
#
|
|
140
|
-
#
|
|
133
|
+
# Exceptions raised inside the block are propagated to the caller.
|
|
141
134
|
def chunks
|
|
142
135
|
end
|
|
143
136
|
|
|
@@ -156,27 +149,35 @@ end
|
|
|
156
149
|
|
|
157
150
|
module Wreq
|
|
158
151
|
class Response
|
|
159
|
-
# Returns
|
|
152
|
+
# Returns the response body as a string.
|
|
153
|
+
#
|
|
154
|
+
# @return [String] Response body text
|
|
155
|
+
# @example
|
|
156
|
+
# puts response.to_s
|
|
157
|
+
# puts response
|
|
158
|
+
# File.write("page.html", response)
|
|
159
|
+
def to_s
|
|
160
|
+
text
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Returns a compact string representation for debugging.
|
|
160
164
|
#
|
|
161
165
|
# Format: #<Wreq::Response STATUS content-type="..." body=SIZE>
|
|
162
166
|
#
|
|
163
167
|
# @return [String] Compact formatted response information
|
|
164
168
|
# @example
|
|
165
|
-
#
|
|
169
|
+
# p response
|
|
166
170
|
# # => #<Wreq::Response 200 content-type="application/json" body=456B>
|
|
167
|
-
def
|
|
171
|
+
def inspect
|
|
168
172
|
parts = ["#<Wreq::Response"]
|
|
169
173
|
|
|
170
|
-
# Status code
|
|
171
174
|
parts << code.to_s
|
|
172
175
|
|
|
173
|
-
# Content-Type header if present
|
|
174
176
|
if headers.respond_to?(:get)
|
|
175
177
|
content_type = headers.get("content-type")
|
|
176
178
|
parts << "content-type=#{content_type.inspect}" if content_type
|
|
177
179
|
end
|
|
178
180
|
|
|
179
|
-
# Body size
|
|
180
181
|
if content_length
|
|
181
182
|
parts << "body=#{format_bytes(content_length)}"
|
|
182
183
|
end
|
data/test/client_cookie_test.rb
CHANGED
|
@@ -36,7 +36,7 @@ class ClientCookieProviderTest < Minitest::Test
|
|
|
36
36
|
|
|
37
37
|
def test_prepopulated_jar_is_used_by_client
|
|
38
38
|
# pre-populate jar
|
|
39
|
-
@jar.
|
|
39
|
+
@jar.add("pref=1; Path=/", "#{HOST}/")
|
|
40
40
|
|
|
41
41
|
res = @client.get("#{HOST}/cookies")
|
|
42
42
|
assert_equal 200, res.code
|
data/test/cookie_test.rb
CHANGED
|
@@ -19,9 +19,9 @@ class CookieTest < Minitest::Test
|
|
|
19
19
|
assert_equal 0, cookies.length
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
def
|
|
22
|
+
def test_add_and_get_all
|
|
23
23
|
set_cookie = "sid=abc123; Path=/; Domain=example.com; HttpOnly; Secure"
|
|
24
|
-
@jar.
|
|
24
|
+
@jar.add(set_cookie, @base_url)
|
|
25
25
|
|
|
26
26
|
cookies = @jar.get_all
|
|
27
27
|
assert_kind_of Array, cookies
|
|
@@ -42,9 +42,9 @@ class CookieTest < Minitest::Test
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
def test_add_multiple_and_remove
|
|
45
|
-
@jar.
|
|
46
|
-
@jar.
|
|
47
|
-
@jar.
|
|
45
|
+
@jar.add("a=1; Path=/", @base_url)
|
|
46
|
+
@jar.add("b=2; Path=/", @base_url)
|
|
47
|
+
@jar.add("c=3; Path=/", @base_url)
|
|
48
48
|
|
|
49
49
|
cookies = @jar.get_all
|
|
50
50
|
assert_equal 3, cookies.length
|
|
@@ -58,8 +58,8 @@ class CookieTest < Minitest::Test
|
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
def test_clear
|
|
61
|
-
@jar.
|
|
62
|
-
@jar.
|
|
61
|
+
@jar.add("x=1; Path=/", @base_url)
|
|
62
|
+
@jar.add("y=2; Path=/", @base_url)
|
|
63
63
|
refute_empty @jar.get_all
|
|
64
64
|
|
|
65
65
|
@jar.clear
|
|
@@ -69,7 +69,7 @@ class CookieTest < Minitest::Test
|
|
|
69
69
|
def test_max_age_and_expires_optional
|
|
70
70
|
# Max-Age only
|
|
71
71
|
@jar.clear
|
|
72
|
-
@jar.
|
|
72
|
+
@jar.add("ma=1; Max-Age=3600; Path=/", @base_url)
|
|
73
73
|
c1 = @jar.get_all.find { |c| c.name == "ma" }
|
|
74
74
|
assert c1
|
|
75
75
|
# can be nil or Integer; just ensure responds and is truthy integer
|
|
@@ -81,7 +81,7 @@ class CookieTest < Minitest::Test
|
|
|
81
81
|
# Expires only
|
|
82
82
|
@jar.clear
|
|
83
83
|
t = Time.now + 3600
|
|
84
|
-
@jar.
|
|
84
|
+
@jar.add("exp=1; Expires=#{t.gmtime.strftime("%a, %d %b %Y %H:%M:%S GMT")}; Path=/", @base_url)
|
|
85
85
|
c2 = @jar.get_all.find { |c| c.name == "exp" }
|
|
86
86
|
assert c2
|
|
87
87
|
# expires returns Float (unix seconds) or nil
|
|
@@ -144,8 +144,8 @@ class CookieTest < Minitest::Test
|
|
|
144
144
|
|
|
145
145
|
def test_same_site_flags_from_parsed_header
|
|
146
146
|
@jar.clear
|
|
147
|
-
@jar.
|
|
148
|
-
@jar.
|
|
147
|
+
@jar.add("s1=1; Path=/; SameSite=Strict", @base_url)
|
|
148
|
+
@jar.add("s2=1; Path=/; SameSite=Lax", @base_url)
|
|
149
149
|
|
|
150
150
|
cookies = @jar.get_all
|
|
151
151
|
h = cookies.to_h { |ck| [ck.name, [ck.same_site_strict?, ck.same_site_lax?]] }
|
|
@@ -154,13 +154,27 @@ class CookieTest < Minitest::Test
|
|
|
154
154
|
assert_equal [false, true], h["s2"]
|
|
155
155
|
end
|
|
156
156
|
|
|
157
|
-
def
|
|
158
|
-
raw_value = "hello world?"
|
|
157
|
+
def test_request_uncompressed_cookies
|
|
159
158
|
client = Wreq::Client.new
|
|
160
159
|
resp = client.get(
|
|
161
|
-
"
|
|
162
|
-
cookies: {"
|
|
160
|
+
"https://httpbin.io/cookies",
|
|
161
|
+
cookies: {"foo" => "bar", "baz" => "qux"}
|
|
163
162
|
)
|
|
164
|
-
|
|
163
|
+
json = resp.json
|
|
164
|
+
assert_instance_of Hash, json
|
|
165
|
+
assert_equal "bar", json["foo"]
|
|
166
|
+
assert_equal "qux", json["baz"]
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def test_request_compressed_cookies
|
|
170
|
+
client = Wreq::Client.new
|
|
171
|
+
resp = client.get(
|
|
172
|
+
"https://httpbin.io/cookies",
|
|
173
|
+
cookies: "foo=bar; baz=qux"
|
|
174
|
+
)
|
|
175
|
+
json = resp.json
|
|
176
|
+
assert_instance_of Hash, json
|
|
177
|
+
assert_equal "bar", json["foo"]
|
|
178
|
+
assert_equal "qux", json["baz"]
|
|
165
179
|
end
|
|
166
180
|
end
|
data/test/emulation_test.rb
CHANGED
|
@@ -4,18 +4,18 @@ require "test_helper"
|
|
|
4
4
|
|
|
5
5
|
class EmulationTest < Minitest::Test
|
|
6
6
|
def test_all_emulation_device_constants_are_non_nil
|
|
7
|
-
Wreq::
|
|
8
|
-
const = Wreq::
|
|
9
|
-
assert_instance_of Wreq::
|
|
10
|
-
"#{name} should be
|
|
7
|
+
Wreq::Profile.constants.each do |name|
|
|
8
|
+
const = Wreq::Profile.const_get(name)
|
|
9
|
+
assert_instance_of Wreq::Profile, const,
|
|
10
|
+
"#{name} should be Profile, got #{const.inspect}"
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def test_all_emulation_os_constants_are_non_nil
|
|
15
|
-
Wreq::
|
|
16
|
-
const = Wreq::
|
|
17
|
-
assert_instance_of Wreq::
|
|
18
|
-
"#{name} should be
|
|
15
|
+
Wreq::Platform.constants.each do |name|
|
|
16
|
+
const = Wreq::Platform.const_get(name)
|
|
17
|
+
assert_instance_of Wreq::Platform, const,
|
|
18
|
+
"#{name} should be Platform, got #{const.inspect}"
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
end
|
data/test/error_handling_test.rb
CHANGED
|
@@ -82,7 +82,10 @@ class ErrorHandlingTest < Minitest::Test
|
|
|
82
82
|
Wreq.get(url, proxy: proxy, timeout: 5)
|
|
83
83
|
flunk "Expected proxy connection error but got response"
|
|
84
84
|
rescue => e
|
|
85
|
-
|
|
85
|
+
assert(
|
|
86
|
+
e.is_a?(Wreq::ProxyConnectionError) || e.is_a?(Wreq::RequestError),
|
|
87
|
+
"Expected ProxyConnectionError or RequestError, got #{e.class}: #{e.message}"
|
|
88
|
+
)
|
|
86
89
|
end
|
|
87
90
|
end
|
|
88
91
|
end
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
class InspectTest < Minitest::Test
|
|
6
|
+
# ---- Headers ----
|
|
7
|
+
|
|
8
|
+
def test_headers_inspect_empty
|
|
9
|
+
headers = Wreq::Headers.new
|
|
10
|
+
assert_equal "#<Wreq::Headers [0 headers]>", headers.inspect
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def test_headers_inspect_with_entries
|
|
14
|
+
headers = Wreq::Headers.new
|
|
15
|
+
headers.set("Content-Type", "text/html")
|
|
16
|
+
headers.set("Accept", "application/json")
|
|
17
|
+
assert_equal "#<Wreq::Headers [2 headers]>", headers.inspect
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# ---- Cookie ----
|
|
21
|
+
|
|
22
|
+
def test_cookie_inspect_minimal
|
|
23
|
+
c = Wreq::Cookie.new("sid", "secret123")
|
|
24
|
+
result = c.inspect
|
|
25
|
+
assert_includes result, "#<Wreq::Cookie"
|
|
26
|
+
assert_includes result, "sid"
|
|
27
|
+
refute_includes result, "secret123"
|
|
28
|
+
assert result.end_with?(">")
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_cookie_inspect_with_domain_and_path
|
|
32
|
+
c = Wreq::Cookie.new("sid", "val",
|
|
33
|
+
domain: "example.com",
|
|
34
|
+
path: "/app")
|
|
35
|
+
result = c.inspect
|
|
36
|
+
assert_includes result, "domain=example.com"
|
|
37
|
+
assert_includes result, "path=/app"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_cookie_inspect_with_flags
|
|
41
|
+
c = Wreq::Cookie.new("sid", "val",
|
|
42
|
+
secure: true,
|
|
43
|
+
http_only: true)
|
|
44
|
+
result = c.inspect
|
|
45
|
+
assert_includes result, "secure"
|
|
46
|
+
assert_includes result, "http_only"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def test_cookie_inspect_omits_nil_attributes
|
|
50
|
+
c = Wreq::Cookie.new("sid", "val")
|
|
51
|
+
result = c.inspect
|
|
52
|
+
refute_includes result, "domain="
|
|
53
|
+
refute_includes result, "path="
|
|
54
|
+
refute_includes result, "secure"
|
|
55
|
+
refute_includes result, "http_only"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# ---- Jar ----
|
|
59
|
+
|
|
60
|
+
def test_jar_inspect_empty
|
|
61
|
+
jar = Wreq::Jar.new
|
|
62
|
+
assert_equal "#<Wreq::Jar [0 cookies]>", jar.inspect
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def test_jar_inspect_with_cookies
|
|
66
|
+
jar = Wreq::Jar.new
|
|
67
|
+
jar.add("a=1; Path=/", "https://example.com")
|
|
68
|
+
jar.add("b=2; Path=/", "https://example.com")
|
|
69
|
+
assert_equal "#<Wreq::Jar [2 cookies]>", jar.inspect
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# ---- Client ----
|
|
73
|
+
|
|
74
|
+
def test_client_inspect
|
|
75
|
+
client = Wreq::Client.new
|
|
76
|
+
assert_equal "#<Wreq::Client>", client.inspect
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def test_client_inspect_with_options
|
|
80
|
+
client = Wreq::Client.new(timeout: 30, gzip: true)
|
|
81
|
+
assert_equal "#<Wreq::Client>", client.inspect
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# ---- Response ----
|
|
85
|
+
|
|
86
|
+
def test_response_to_s_returns_body
|
|
87
|
+
response = Wreq.get("http://localhost:8080/json")
|
|
88
|
+
assert_equal response.text, response.to_s
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def test_response_inspect_format
|
|
92
|
+
response = Wreq.get("http://localhost:8080/json")
|
|
93
|
+
result = response.inspect
|
|
94
|
+
assert result.start_with?("#<Wreq::Response")
|
|
95
|
+
assert_includes result, "200"
|
|
96
|
+
assert result.end_with?(">")
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# ---- StatusCode ----
|
|
100
|
+
|
|
101
|
+
def test_status_code_inspect
|
|
102
|
+
response = Wreq.get("http://localhost:8080/status/200")
|
|
103
|
+
result = response.status.inspect
|
|
104
|
+
assert result.start_with?("#<Wreq::StatusCode")
|
|
105
|
+
assert_includes result, response.status.to_s
|
|
106
|
+
assert result.end_with?(">")
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# ---- Version ----
|
|
110
|
+
|
|
111
|
+
def test_version_inspect_from_constant
|
|
112
|
+
v = Wreq::Version::HTTP_11
|
|
113
|
+
result = v.inspect
|
|
114
|
+
assert result.start_with?("#<Wreq::Version")
|
|
115
|
+
assert_includes result, v.to_s
|
|
116
|
+
assert result.end_with?(">")
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def test_version_inspect_from_response
|
|
120
|
+
response = Wreq.get("http://localhost:8080/get")
|
|
121
|
+
result = response.version.inspect
|
|
122
|
+
assert result.start_with?("#<Wreq::Version")
|
|
123
|
+
assert result.end_with?(">")
|
|
124
|
+
end
|
|
125
|
+
end
|