curb 0.9.11 → 1.0.5

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.
@@ -1,4 +1,5 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
+ require 'set'
2
3
 
3
4
  class TestCurbCurlMulti < Test::Unit::TestCase
4
5
  def teardown
@@ -9,20 +10,58 @@ class TestCurbCurlMulti < Test::Unit::TestCase
9
10
  # for https://github.com/taf2/curb/issues/277
10
11
  # must connect to an external
11
12
  def test_connection_keepalive
12
- # 0123456 default & reserved RubyVM. It will probably include 7 from Dir.glob
13
- lsof=`/usr/bin/which lsof`.strip
14
- open_fds = lambda do
15
- `#{lsof} -p #{Process.pid} | egrep "TCP|UDP" | wc -l`.strip.to_i
13
+ # this test fails with libcurl 7.22.0. I didn't investigate, but it may be related
14
+ # to CURLOPT_MAXCONNECTS bug fixed in 7.30.0:
15
+ # https://github.com/curl/curl/commit/e87e76e2dc108efb1cae87df496416f49c55fca0
16
+ omit("Skip, libcurl too old (< 7.22.0)") if Curl::CURL_VERSION.split('.')[1].to_i <= 22
17
+
18
+ @server.shutdown if @server
19
+ @test_thread.kill if @test_thread
20
+ @server = nil
21
+ File.unlink(locked_file)
22
+ Curl::Multi.autoclose = true
23
+ assert Curl::Multi.autoclose
24
+ # XXX: thought maybe we can clean house here to have the full suite pass in osx... but for now running this test in isolate does pass
25
+ # additionally, if ss allows this to pass on linux without requesting google i think this is a good trade off... leaving some of the thoughts below
26
+ # in hopes that coming back to this later will find it and remember how to fix it
27
+ # types = Set.new
28
+ # close_types = Set.new([TCPServer,TCPSocket,Socket,Curl::Multi, Curl::Easy,WEBrick::Log])
29
+ # ObjectSpace.each_object {|o|
30
+ # if o.respond_to?(:close)
31
+ # types << o.class
32
+ # end
33
+ # if close_types.include?(o.class)
34
+ # o.close
35
+ # end
36
+ # }
37
+ #puts "unique types: #{types.to_a.join("\n")}"
38
+ GC.start # cleanup FDs left over from other tests
39
+ server_setup
40
+ GC.start # cleanup FDs left over from other tests
41
+
42
+ if `which ss`.strip.size == 0
43
+ # osx need lsof still :(
44
+ open_fds = lambda do
45
+ out = `/usr/sbin/lsof -p #{Process.pid} | egrep "TCP|UDP"`# | egrep ':#{TestServlet.port} ' | egrep ESTABLISHED`# | wc -l`.strip.to_i
46
+ #puts out.lines.join("\n")
47
+ out.lines.size
48
+ end
49
+ else
50
+ ss = `which ss`.strip
51
+ open_fds = lambda do
52
+ `#{ss} -n4 state established dport = :#{TestServlet.port} | wc -l`.strip.to_i
53
+ end
16
54
  end
55
+ Curl::Multi.autoclose = false
17
56
  before_open = open_fds.call
57
+ #puts "before_open: #{before_open.inspect}"
18
58
  assert !Curl::Multi.autoclose
19
59
  multi = Curl::Multi.new
20
60
  multi.max_connects = 1 # limit to 1 connection within the multi handle
21
61
 
22
62
  did_complete = false
23
63
  5.times do |n|
24
- # NOTE: we use google here because connecting to our TEST_URL as a local host address appears to not register correctly with lsof as a socket... if anyone knows a better way would be great to not have an external dependency here in the test
25
- easy = Curl::Easy.new("http://google.com/") do |curl|
64
+ easy = Curl::Easy.new(TestServlet.url) do |curl|
26
65
  curl.timeout = 5 # ensure we don't hang for ever connecting to an external host
27
66
  curl.on_complete {
28
67
  did_complete = true
@@ -34,18 +73,21 @@ class TestCurbCurlMulti < Test::Unit::TestCase
34
73
  multi.perform
35
74
  assert did_complete
36
75
  after_open = open_fds.call
37
- assert_equal (after_open - before_open), 1, "with max connections set to 1 at this point the connection to google should still be open"
76
+ #puts "after_open: #{after_open} before_open: #{before_open.inspect}"
77
+ # ruby process may keep a connection alive
78
+ assert (after_open - before_open) < 3, "with max connections set to 1 at this point the connection to google should still be open"
79
+ assert (after_open - before_open) > 0, "with max connections set to 1 at this point the connection to google should still be open"
38
80
  multi.close
39
81
 
40
82
  after_open = open_fds.call
41
- assert_equal (after_open - before_open), 0, "after closing the multi handle all connections should be closed"
83
+ #puts "after_open: #{after_open} before_open: #{before_open.inspect}"
84
+ assert_equal 0, (after_open - before_open), "after closing the multi handle all connections should be closed"
42
85
 
43
86
  Curl::Multi.autoclose = true
44
87
  multi = Curl::Multi.new
45
88
  did_complete = false
46
89
  5.times do |n|
47
- # NOTE: we use google here because connecting to our TEST_URL as a local host address appears to not register correctly with lsof as a socket... if anyone knows a better way would be great to not have an external dependency here in the test
48
- easy = Curl::Easy.new("http://google.com/") do |curl|
90
+ easy = Curl::Easy.new(TestServlet.url) do |curl|
49
91
  curl.timeout = 5 # ensure we don't hang for ever connecting to an external host
50
92
  curl.on_complete {
51
93
  did_complete = true
@@ -57,7 +99,8 @@ class TestCurbCurlMulti < Test::Unit::TestCase
57
99
  multi.perform
58
100
  assert did_complete
59
101
  after_open = open_fds.call
60
- assert_equal (after_open - before_open), 0, "auto close the connections"
102
+ #puts "after_open: #{after_open} before_open: #{before_open.inspect}"
103
+ assert_equal 0, (after_open - before_open), "auto close the connections"
61
104
  ensure
62
105
  Curl::Multi.autoclose = false # restore default
63
106
  end
@@ -118,6 +161,44 @@ class TestCurbCurlMulti < Test::Unit::TestCase
118
161
 
119
162
  end
120
163
 
164
+ def test_multi_easy_get
165
+ n = 1
166
+ urls = []
167
+ n.times { urls << $TEST_URL }
168
+ Curl::Multi.get(urls, {timeout: 5}) {|easy|
169
+ assert_match(/file:/, easy.last_effective_url)
170
+ }
171
+ end
172
+
173
+ def test_multi_easy_get_with_error
174
+ begin
175
+ did_raise = false
176
+ n = 3
177
+ urls = []
178
+ n.times { urls << $TEST_URL }
179
+ error_line_number_should_be = nil
180
+ Curl::Multi.get(urls, {timeout: 5}) {|easy|
181
+ # if we got this right the error will be reported to be on the line below our error_line_number_should_be
182
+ error_line_number_should_be = __LINE__
183
+ raise
184
+ }
185
+
186
+ rescue Curl::Err::AbortedByCallbackError => e
187
+ did_raise = true
188
+ in_file = e.backtrace.detect {|err| err.match?(File.basename(__FILE__)) }
189
+ in_file_stack = e.backtrace.select {|err| err.match?(File.basename(__FILE__)) }
190
+ assert_match(__FILE__, in_file)
191
+ in_file.gsub!(__FILE__)
192
+ parts = in_file.split(':')
193
+ parts.shift
194
+ line_no = parts.shift.to_i
195
+ assert_equal error_line_number_should_be+1, line_no.to_i
196
+ end
197
+
198
+ assert did_raise, "we should have raised an exception"
199
+
200
+ end
201
+
121
202
  # NOTE: if this test runs slowly on Mac OSX, it is probably due to the use of a port install curl+ssl+ares install
122
203
  # on my MacBook, this causes curl_easy_init to take nearly 0.01 seconds / * 100 below is 1 second too many!
123
204
  def test_n_requests
@@ -439,7 +520,7 @@ class TestCurbCurlMulti < Test::Unit::TestCase
439
520
  { :url => TestServlet.url, :method => :get }
440
521
  ]
441
522
  Curl::Multi.http(urls, {:pipeline => true}) do|easy, code, method|
442
- assert_equal nil, code
523
+ assert_equal 200, code
443
524
  case method
444
525
  when :post
445
526
  assert_match(/POST/, easy.body_str)
@@ -453,20 +534,20 @@ class TestCurbCurlMulti < Test::Unit::TestCase
453
534
  end
454
535
 
455
536
  def test_multi_easy_http_with_max_connects
456
- urls = [
537
+ urls = [
457
538
  { :url => TestServlet.url + '?q=1', :method => :get },
458
539
  { :url => TestServlet.url + '?q=2', :method => :get },
459
540
  { :url => TestServlet.url + '?q=3', :method => :get }
460
541
  ]
461
542
  Curl::Multi.http(urls, {:pipeline => true, :max_connects => 1}) do|easy, code, method|
462
- assert_equal nil, code
543
+ assert_equal 200, code
463
544
  case method
464
545
  when :post
465
- assert_match(/POST/, easy.body_str)
546
+ assert_match(/POST/, easy.body)
466
547
  when :get
467
- assert_match(/GET/, easy.body_str)
548
+ assert_match(/GET/, easy.body)
468
549
  when :put
469
- assert_match(/PUT/, easy.body_str)
550
+ assert_match(/PUT/, easy.body)
470
551
  end
471
552
  end
472
553
  end
@@ -0,0 +1,37 @@
1
+ class TestCurbCurlProtocols < Test::Unit::TestCase
2
+ include TestServerMethods
3
+
4
+ def setup
5
+ @easy = Curl::Easy.new
6
+ @easy.set :protocols, Curl::CURLPROTO_HTTP | Curl::CURLPROTO_HTTPS
7
+ @easy.follow_location = true
8
+ server_setup
9
+ end
10
+
11
+ def test_protocol_allowed
12
+ @easy.set :url, "http://127.0.0.1:9129/this_file_does_not_exist.html"
13
+ @easy.perform
14
+ assert_equal 404, @easy.response_code
15
+ end
16
+
17
+ def test_protocol_denied
18
+ @easy.set :url, "gopher://google.com/"
19
+ assert_raises Curl::Err::UnsupportedProtocolError do
20
+ @easy.perform
21
+ end
22
+ end
23
+
24
+ def test_redir_protocol_allowed
25
+ @easy.set :url, TestServlet.url + "/redirect"
26
+ @easy.set :redir_protocols, Curl::CURLPROTO_HTTP
27
+ @easy.perform
28
+ end
29
+
30
+ def test_redir_protocol_denied
31
+ @easy.set :url, TestServlet.url + "/redirect"
32
+ @easy.set :redir_protocols, Curl::CURLPROTO_HTTPS
33
+ assert_raises Curl::Err::UnsupportedProtocolError do
34
+ @easy.perform
35
+ end
36
+ end
37
+ end
data/tests/timeout.rb CHANGED
@@ -17,9 +17,13 @@ class TestCurbTimeouts < Test::Unit::TestCase
17
17
  def test_overall_timeout_on_dead_transfer
18
18
  curl = Curl::Easy.new(wait_url(2))
19
19
  curl.timeout = 1
20
- assert_raise(Curl::Err::TimeoutError) do
20
+ exception = assert_raise(Curl::Err::TimeoutError) do
21
21
  curl.http_get
22
22
  end
23
+ assert_match(
24
+ /^Timeout was reached: Operation timed out after/,
25
+ exception.message
26
+ )
23
27
  end
24
28
 
25
29
  def test_overall_timeout_ms_on_dead_transfer
@@ -44,16 +48,20 @@ class TestCurbTimeouts < Test::Unit::TestCase
44
48
  curl = Curl::Easy.new(serve_url(100, 2, 3))
45
49
  curl.timeout = 1
46
50
  # transfer is aborted despite data being exchanged
47
- assert_raise(Curl::Err::TimeoutError) do
51
+ exception = assert_raise(Curl::Err::TimeoutError) do
48
52
  curl.http_get
49
53
  end
54
+ assert_match(
55
+ /^Timeout was reached: Operation timed out after/,
56
+ exception.message
57
+ )
50
58
  end
51
59
 
52
60
  def test_low_speed_time_on_slow_transfer
53
61
  curl = Curl::Easy.new(serve_url(100, 1, 3))
54
62
  curl.low_speed_time = 2
55
63
  # use default low_speed_limit of 1
56
- assert true, curl.http_get
64
+ assert_equal true, curl.http_get
57
65
  end
58
66
 
59
67
  def test_low_speed_time_on_very_slow_transfer
@@ -63,18 +71,26 @@ class TestCurbTimeouts < Test::Unit::TestCase
63
71
  # XXX for some reason this test fails if low speed limit is not specified
64
72
  curl.low_speed_limit = 1
65
73
  # use default low_speed_limit of 1
66
- assert_raise(Curl::Err::TimeoutError) do
74
+ exception = assert_raise(Curl::Err::TimeoutError) do
67
75
  curl.http_get
68
76
  end
77
+ assert_match(
78
+ /^Timeout was reached: Operation too slow/,
79
+ exception.message
80
+ )
69
81
  end
70
82
 
71
83
  def test_low_speed_limit_on_slow_transfer
72
84
  curl = Curl::Easy.new(serve_url(10, 1, 3))
73
85
  curl.low_speed_time = 2
74
86
  curl.low_speed_limit = 1000
75
- assert_raise(Curl::Err::TimeoutError) do
87
+ exception = assert_raise(Curl::Err::TimeoutError) do
76
88
  curl.http_get
77
89
  end
90
+ assert_match(
91
+ /^Timeout was reached: Operation too slow/,
92
+ exception.message
93
+ )
78
94
  end
79
95
 
80
96
  def test_clearing_low_speed_time
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: curb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.11
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ross Bamford
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-11-02 00:00:00.000000000 Z
12
+ date: 2023-01-04 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Curb (probably CUrl-RuBy or something) provides Ruby-language bindings
15
15
  for the libcurl(3), a fully-featured client-side URL transfer library. cURL and
@@ -50,12 +50,14 @@ files:
50
50
  - tests/bug_crash_on_progress.rb
51
51
  - tests/bug_curb_easy_blocks_ruby_threads.rb
52
52
  - tests/bug_curb_easy_post_with_string_no_content_length_header.rb
53
+ - tests/bug_follow_redirect_288.rb
53
54
  - tests/bug_instance_post_differs_from_class_post.rb
54
55
  - tests/bug_issue102.rb
55
56
  - tests/bug_issue277.rb
56
57
  - tests/bug_multi_segfault.rb
57
58
  - tests/bug_postfields_crash.rb
58
59
  - tests/bug_postfields_crash2.rb
60
+ - tests/bug_raise_on_callback.rb
59
61
  - tests/bug_require_last_or_segfault.rb
60
62
  - tests/bugtests.rb
61
63
  - tests/helper.rb
@@ -70,6 +72,7 @@ files:
70
72
  - tests/tc_curl_maxfilesize.rb
71
73
  - tests/tc_curl_multi.rb
72
74
  - tests/tc_curl_postfield.rb
75
+ - tests/tc_curl_protocols.rb
73
76
  - tests/timeout.rb
74
77
  - tests/timeout_server.rb
75
78
  - tests/unittests.rb
@@ -95,36 +98,39 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
98
  - !ruby/object:Gem::Version
96
99
  version: '0'
97
100
  requirements: []
98
- rubygems_version: 3.0.8
101
+ rubygems_version: 3.2.33
99
102
  signing_key:
100
103
  specification_version: 4
101
104
  summary: Ruby libcurl bindings
102
105
  test_files:
103
- - tests/tc_curl_multi.rb
104
106
  - tests/alltests.rb
105
- - tests/tc_curl_easy_setopt.rb
106
- - tests/tc_curl.rb
107
- - tests/bug_postfields_crash.rb
107
+ - tests/bug_crash_on_debug.rb
108
108
  - tests/bug_crash_on_progress.rb
109
- - tests/helper.rb
109
+ - tests/bug_curb_easy_blocks_ruby_threads.rb
110
+ - tests/bug_curb_easy_post_with_string_no_content_length_header.rb
111
+ - tests/bug_follow_redirect_288.rb
112
+ - tests/bug_instance_post_differs_from_class_post.rb
113
+ - tests/bug_issue102.rb
110
114
  - tests/bug_issue277.rb
115
+ - tests/bug_multi_segfault.rb
116
+ - tests/bug_postfields_crash.rb
111
117
  - tests/bug_postfields_crash2.rb
118
+ - tests/bug_raise_on_callback.rb
112
119
  - tests/bug_require_last_or_segfault.rb
113
- - tests/timeout.rb
114
- - tests/bug_crash_on_debug.rb
115
- - tests/unittests.rb
116
- - tests/bug_issue102.rb
117
- - tests/bug_curb_easy_blocks_ruby_threads.rb
118
- - tests/bug_multi_segfault.rb
119
- - tests/bug_instance_post_differs_from_class_post.rb
120
+ - tests/bugtests.rb
121
+ - tests/helper.rb
122
+ - tests/mem_check.rb
120
123
  - tests/require_last_or_segfault_script.rb
121
- - tests/timeout_server.rb
124
+ - tests/signals.rb
125
+ - tests/tc_curl.rb
122
126
  - tests/tc_curl_download.rb
123
127
  - tests/tc_curl_easy.rb
124
- - tests/mem_check.rb
125
- - tests/tc_curl_postfield.rb
126
- - tests/tc_curl_maxfilesize.rb
127
- - tests/bugtests.rb
128
128
  - tests/tc_curl_easy_resolve.rb
129
- - tests/signals.rb
130
- - tests/bug_curb_easy_post_with_string_no_content_length_header.rb
129
+ - tests/tc_curl_easy_setopt.rb
130
+ - tests/tc_curl_maxfilesize.rb
131
+ - tests/tc_curl_multi.rb
132
+ - tests/tc_curl_postfield.rb
133
+ - tests/tc_curl_protocols.rb
134
+ - tests/timeout.rb
135
+ - tests/timeout_server.rb
136
+ - tests/unittests.rb