wreq 1.2.2-x86_64-linux → 1.2.4-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.
data/test/stream_test.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "test_helper"
2
+ require "socket"
2
3
 
3
4
  class StreamTest < Minitest::Test
4
5
  def test_simple_push_stream
@@ -9,7 +10,7 @@ class StreamTest < Minitest::Test
9
10
  sender.close
10
11
  end
11
12
 
12
- resp = client.post("http://localhost:8080/post", body: sender, headers: {"Content-Type" => "text/plain"})
13
+ resp = client.post("#{HTTPBIN_URL}/post", body: sender, headers: {"Content-Type" => "text/plain"})
13
14
 
14
15
  assert_equal 200, resp.code
15
16
 
@@ -23,7 +24,7 @@ class StreamTest < Minitest::Test
23
24
 
24
25
  def test_response_body_chunks_stream
25
26
  client = Wreq::Client.new
26
- resp = client.get("http://localhost:8080/stream/5")
27
+ resp = client.get("#{HTTPBIN_URL}/stream/5")
27
28
  chunks = []
28
29
 
29
30
  resp.chunks do |chunk|
@@ -37,7 +38,7 @@ class StreamTest < Minitest::Test
37
38
 
38
39
  def test_chunks_yields_binary_encoding
39
40
  client = Wreq::Client.new
40
- resp = client.get("http://localhost:8080/stream/3")
41
+ resp = client.get("#{HTTPBIN_URL}/stream/3")
41
42
 
42
43
  resp.chunks do |chunk|
43
44
  assert chunk.encoding == Encoding::BINARY || chunk.encoding == Encoding::ASCII_8BIT,
@@ -47,7 +48,7 @@ class StreamTest < Minitest::Test
47
48
 
48
49
  def test_chunks_with_single_chunk_body
49
50
  client = Wreq::Client.new
50
- resp = client.get("http://localhost:8080/bytes/1024")
51
+ resp = client.get("#{HTTPBIN_URL}/bytes/1024")
51
52
  chunk_count = 0
52
53
  total_bytes = 0
53
54
 
@@ -62,7 +63,7 @@ class StreamTest < Minitest::Test
62
63
 
63
64
  def test_chunks_returns_nil
64
65
  client = Wreq::Client.new
65
- resp = client.get("http://localhost:8080/stream/3")
66
+ resp = client.get("#{HTTPBIN_URL}/stream/3")
66
67
 
67
68
  result = resp.chunks { |_chunk| :processing }
68
69
 
@@ -71,7 +72,7 @@ class StreamTest < Minitest::Test
71
72
 
72
73
  def test_chunks_with_empty_body
73
74
  client = Wreq::Client.new
74
- resp = client.get("http://localhost:8080/status/204")
75
+ resp = client.get("#{HTTPBIN_URL}/status/204")
75
76
  chunk_count = 0
76
77
 
77
78
  resp.chunks do |_chunk|
@@ -83,7 +84,7 @@ class StreamTest < Minitest::Test
83
84
 
84
85
  def test_chunks_without_block_raises_error
85
86
  client = Wreq::Client.new
86
- resp = client.get("http://localhost:8080/stream/3")
87
+ resp = client.get("#{HTTPBIN_URL}/stream/3")
87
88
 
88
89
  assert_raises(LocalJumpError) do
89
90
  resp.chunks
@@ -92,7 +93,7 @@ class StreamTest < Minitest::Test
92
93
 
93
94
  def test_other_threads_run_during_streaming
94
95
  client = Wreq::Client.new
95
- resp = client.get("http://localhost:8080/drip?duration=3&numbytes=3&delay=1")
96
+ resp = client.get("#{HTTPBIN_URL}/drip?duration=3&numbytes=3&delay=1")
96
97
 
97
98
  counter = 0
98
99
  tick_thread = Thread.new do
@@ -121,7 +122,7 @@ class StreamTest < Minitest::Test
121
122
  done = {}
122
123
 
123
124
  t1 = Thread.new do
124
- resp = client.get("http://localhost:8080/stream/3")
125
+ resp = client.get("#{HTTPBIN_URL}/stream/3")
125
126
  chunks = []
126
127
  resp.chunks { |chunk| chunks << chunk }
127
128
  results[:t1] = chunks.size
@@ -129,7 +130,7 @@ class StreamTest < Minitest::Test
129
130
  end
130
131
 
131
132
  t2 = Thread.new do
132
- resp = client.get("http://localhost:8080/stream/3")
133
+ resp = client.get("#{HTTPBIN_URL}/stream/3")
133
134
  chunks = []
134
135
  resp.chunks { |chunk| chunks << chunk }
135
136
  results[:t2] = chunks.size
@@ -174,7 +175,7 @@ class StreamTest < Minitest::Test
174
175
  end
175
176
 
176
177
  def test_thread_interrupt_body_reading
177
- url = "http://localhost:8080/drip?duration=5&numbytes=5"
178
+ url = "#{HTTPBIN_URL}/drip?duration=5&numbytes=5"
178
179
  thread = Thread.new do
179
180
  resp = Wreq.get(url)
180
181
  resp.text
@@ -189,7 +190,7 @@ class StreamTest < Minitest::Test
189
190
  end
190
191
 
191
192
  def test_thread_interrupt_body_streaming
192
- url = "http://localhost:8080/drip?duration=5&numbytes=5"
193
+ url = "#{HTTPBIN_URL}/drip?duration=5&numbytes=5"
193
194
  thread = Thread.new do
194
195
  resp = Wreq.get(url)
195
196
  resp.chunks { |chunk| chunk }
@@ -204,7 +205,7 @@ class StreamTest < Minitest::Test
204
205
  end
205
206
 
206
207
  def test_thread_interrupt_during_slow_stream_with_block_processing
207
- url = "http://localhost:8080/drip?duration=5&numbytes=5&delay=1"
208
+ url = "#{HTTPBIN_URL}/drip?duration=5&numbytes=5&delay=1"
208
209
  thread = Thread.new do
209
210
  resp = Wreq.get(url)
210
211
  resp.chunks do |_chunk|
@@ -222,26 +223,21 @@ class StreamTest < Minitest::Test
222
223
 
223
224
  def test_chunks_propagates_streaming_errors
224
225
  client = Wreq::Client.new
225
- resp = client.get("http://localhost:8080/drip?duration=10&numbytes=10", timeout: 1)
226
- error_raised = false
227
226
 
228
- begin
229
- resp.chunks do |_chunk|
227
+ with_truncated_chunked_response do |url|
228
+ resp = client.get(url)
229
+ error = assert_raises(Wreq::BodyError, Wreq::ConnectionResetError, Wreq::DecodingError) do
230
+ resp.chunks do |_chunk|
231
+ end
230
232
  end
231
- rescue => e
232
- error_raised = true
233
- assert(
234
- e.is_a?(Wreq::TimeoutError) || e.is_a?(Wreq::BodyError) || e.is_a?(Wreq::ConnectionResetError),
235
- "Expected a streaming error (TimeoutError/BodyError/ConnectionResetError), got #{e.class}: #{e.message}"
236
- )
237
- end
238
233
 
239
- assert error_raised, "A streaming error should have been raised for a timed-out drip response"
234
+ assert_match(/body|connection|decode|incomplete|closed|unexpected/i, error.message)
235
+ end
240
236
  end
241
237
 
242
238
  def test_exception_in_block_propagates
243
239
  client = Wreq::Client.new
244
- resp = client.get("http://localhost:8080/stream/5")
240
+ resp = client.get("#{HTTPBIN_URL}/stream/5")
245
241
  error_raised = false
246
242
  chunks_before_error = 0
247
243
 
@@ -261,7 +257,7 @@ class StreamTest < Minitest::Test
261
257
 
262
258
  def test_chunks_called_twice_raises_error
263
259
  client = Wreq::Client.new
264
- resp = client.get("http://localhost:8080/stream/3")
260
+ resp = client.get("#{HTTPBIN_URL}/stream/3")
265
261
  resp.chunks { |_chunk| }
266
262
  error_raised = false
267
263
 
@@ -278,7 +274,7 @@ class StreamTest < Minitest::Test
278
274
 
279
275
  def test_text_after_chunks_raises_error
280
276
  client = Wreq::Client.new
281
- resp = client.get("http://localhost:8080/stream/3")
277
+ resp = client.get("#{HTTPBIN_URL}/stream/3")
282
278
  resp.chunks { |_chunk| }
283
279
  error_raised = false
284
280
 
@@ -295,10 +291,10 @@ class StreamTest < Minitest::Test
295
291
 
296
292
  def test_chunks_content_matches_full_body
297
293
  client = Wreq::Client.new
298
- resp_full = client.get("http://localhost:8080/bytes/4096")
294
+ resp_full = client.get("#{HTTPBIN_URL}/bytes/4096")
299
295
  full_bytes = resp_full.bytes
300
296
 
301
- resp_stream = client.get("http://localhost:8080/bytes/4096")
297
+ resp_stream = client.get("#{HTTPBIN_URL}/bytes/4096")
302
298
  streamed_bytes = "".b
303
299
  resp_stream.chunks do |chunk|
304
300
  streamed_bytes << chunk
@@ -310,7 +306,7 @@ class StreamTest < Minitest::Test
310
306
 
311
307
  def test_chunks_json_stream_content
312
308
  client = Wreq::Client.new
313
- resp = client.get("http://localhost:8080/stream/5")
309
+ resp = client.get("#{HTTPBIN_URL}/stream/5")
314
310
  chunks = []
315
311
 
316
312
  resp.chunks do |chunk|
@@ -325,7 +321,7 @@ class StreamTest < Minitest::Test
325
321
 
326
322
  def test_block_not_garbage_collected_during_streaming
327
323
  client = Wreq::Client.new
328
- resp = client.get("http://localhost:8080/drip?duration=3&numbytes=3&delay=1")
324
+ resp = client.get("#{HTTPBIN_URL}/stream/3")
329
325
  chunks_received = 0
330
326
 
331
327
  resp.chunks do |_chunk|
@@ -340,14 +336,14 @@ class StreamTest < Minitest::Test
340
336
 
341
337
  def test_close_after_streaming
342
338
  client = Wreq::Client.new
343
- resp = client.get("http://localhost:8080/stream/3")
339
+ resp = client.get("#{HTTPBIN_URL}/stream/3")
344
340
 
345
341
  resp.chunks { |_chunk| }
346
342
  resp.close
347
343
  end
348
344
 
349
345
  def test_chunks_via_module_method
350
- resp = Wreq.get("http://localhost:8080/stream/3")
346
+ resp = Wreq.get("#{HTTPBIN_URL}/stream/3")
351
347
  chunks = []
352
348
 
353
349
  resp.chunks do |chunk|
@@ -359,7 +355,7 @@ class StreamTest < Minitest::Test
359
355
 
360
356
  def test_chunks_via_client_instance
361
357
  client = Wreq::Client.new
362
- resp = client.get("http://localhost:8080/stream/3")
358
+ resp = client.get("#{HTTPBIN_URL}/stream/3")
363
359
  chunks = []
364
360
 
365
361
  resp.chunks do |chunk|
@@ -368,4 +364,34 @@ class StreamTest < Minitest::Test
368
364
 
369
365
  assert_equal 3, chunks.size, "Client instance get + chunks should work"
370
366
  end
367
+
368
+ private
369
+
370
+ def with_truncated_chunked_response
371
+ server = TCPServer.new("127.0.0.1", 0)
372
+ port = server.addr[1]
373
+ thread = Thread.new do
374
+ socket = server.accept
375
+ begin
376
+ socket.readpartial(4096) if IO.select([socket], nil, nil, 5)
377
+ socket.write "HTTP/1.1 200 OK\r\n"
378
+ socket.write "Content-Type: text/plain\r\n"
379
+ socket.write "Transfer-Encoding: chunked\r\n"
380
+ socket.write "\r\n"
381
+ socket.write "5\r\nhello\r\n"
382
+ socket.write "A\r\nshort"
383
+ ensure
384
+ socket.close unless socket.closed?
385
+ end
386
+ rescue IOError, SystemCallError
387
+ ensure
388
+ server.close unless server.closed?
389
+ end
390
+ thread.report_on_exception = false
391
+
392
+ yield "http://127.0.0.1:#{port}/"
393
+ ensure
394
+ server&.close unless server&.closed?
395
+ thread&.join(5)
396
+ end
371
397
  end
data/test/test_helper.rb CHANGED
@@ -1,9 +1,52 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- #
4
- # Run httpbin server: `docker run -d -p 8080:80 --name httpbin kennethreitz/httpbin`
5
-
6
3
  $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
7
4
  require "wreq"
8
5
 
6
+ HTTPBIN_URL = ENV.fetch("HTTPBIN_URL", "https://httpbin.io").delete_suffix("/")
7
+ MINITEST_RETRY_COUNT = Integer(ENV.fetch("MINITEST_RETRY_COUNT", "3"))
8
+ MINITEST_RETRY_DISPLAY_FAILURE_MESSAGES =
9
+ ENV.fetch("MINITEST_RETRY_DISPLAY_FAILURE_MESSAGES", "true") != "false"
10
+ MINITEST_RETRY_SLEEP_INTERVAL = Float(ENV.fetch("MINITEST_RETRY_SLEEP_INTERVAL", "1"))
11
+
9
12
  require "minitest/autorun"
13
+ require "minitest/retry"
14
+
15
+ # httpbin.io is a shared external service, so the integration tests can see
16
+ # occasional network failures even when the client behavior is correct.
17
+ Minitest::Retry.use!(
18
+ retry_count: MINITEST_RETRY_COUNT,
19
+ verbose: false,
20
+ io: $stderr
21
+ )
22
+
23
+ Minitest::Retry.on_retry do |klass, test_name, attempt, result|
24
+ $stderr.puts "[MinitestRetry] retry #{klass}##{test_name} (#{attempt}/#{MINITEST_RETRY_COUNT})"
25
+
26
+ if MINITEST_RETRY_DISPLAY_FAILURE_MESSAGES
27
+ result.failures.each do |failure|
28
+ message = failure.message.to_s.strip
29
+ $stderr.puts message unless message.empty?
30
+ end
31
+ end
32
+
33
+ sleep MINITEST_RETRY_SLEEP_INTERVAL if MINITEST_RETRY_SLEEP_INTERVAL.positive?
34
+ end
35
+
36
+ module HttpbinHelpers
37
+ def httpbin_value(value)
38
+ (value.is_a?(Array) && value.length == 1) ? value.first : value
39
+ end
40
+
41
+ def httpbin_fetch(hash, key)
42
+ httpbin_value(hash.fetch(key))
43
+ end
44
+
45
+ def httpbin_cookies(json)
46
+ json.fetch("cookies", json)
47
+ end
48
+ end
49
+
50
+ class Minitest::Test
51
+ include HttpbinHelpers
52
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wreq
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.2.4
5
5
  platform: x86_64-linux
6
6
  authors:
7
7
  - SearchApi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-06-11 00:00:00.000000000 Z
11
+ date: 2026-07-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: An easy and powerful Ruby HTTP client with advanced browser fingerprinting
14
14
  that accurately emulates Chrome, Edge, Firefox, Safari, Opera, and OkHttp with precise
@@ -24,6 +24,7 @@ files:
24
24
  - LICENSE
25
25
  - README.md
26
26
  - Rakefile
27
+ - docs/windows-gnu-tokio-crash.md
27
28
  - examples/body.rb
28
29
  - examples/client.rb
29
30
  - examples/cookie.rb
@@ -46,6 +47,7 @@ files:
46
47
  - lib/wreq_ruby/http.rb
47
48
  - lib/wreq_ruby/response.rb
48
49
  - script/build_platform_gem.rb
50
+ - script/build_windows_gnu.ps1
49
51
  - test/client_cookie_test.rb
50
52
  - test/client_test.rb
51
53
  - test/cookie_test.rb