curb 0.9.11 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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