curb 0.9.8 → 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.
- checksums.yaml +4 -4
- data/README.markdown +69 -7
- data/Rakefile +18 -19
- data/ext/banned.h +32 -0
- data/ext/curb.c +164 -8
- data/ext/curb.h +18 -5
- data/ext/curb_easy.c +134 -44
- data/ext/curb_easy.h +3 -0
- data/ext/curb_macros.h +12 -0
- data/ext/curb_multi.c +50 -24
- data/ext/curb_postfield.c +9 -7
- data/ext/curb_upload.c +1 -0
- data/ext/extconf.rb +45 -0
- data/lib/curb.rb +1 -0
- data/lib/curl/easy.rb +14 -7
- data/lib/curl/multi.rb +11 -3
- data/lib/curl.rb +12 -3
- data/tests/bug_crash_on_debug.rb +14 -28
- data/tests/bug_crash_on_progress.rb +7 -31
- data/tests/bug_curb_easy_blocks_ruby_threads.rb +8 -13
- data/tests/bug_curb_easy_post_with_string_no_content_length_header.rb +6 -30
- data/tests/bug_follow_redirect_288.rb +83 -0
- data/tests/bug_instance_post_differs_from_class_post.rb +3 -5
- data/tests/bug_issue277.rb +32 -0
- data/tests/bug_multi_segfault.rb +1 -0
- data/tests/bug_raise_on_callback.rb +29 -0
- data/tests/helper.rb +27 -1
- data/tests/tc_curl_easy.rb +72 -4
- data/tests/tc_curl_maxfilesize.rb +12 -0
- data/tests/tc_curl_multi.rb +98 -16
- data/tests/tc_curl_postfield.rb +29 -29
- data/tests/tc_curl_protocols.rb +37 -0
- data/tests/timeout.rb +21 -5
- metadata +37 -27
@@ -0,0 +1,83 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
2
|
+
|
3
|
+
class BugFollowRedirect288 < Test::Unit::TestCase
|
4
|
+
include BugTestServerSetupTeardown
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@port = 9999
|
8
|
+
super
|
9
|
+
@server.mount_proc("/redirect_to_test") do|req,res|
|
10
|
+
res.set_redirect(WEBrick::HTTPStatus::TemporaryRedirect, "/test")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_follow_redirect_with_no_redirect
|
15
|
+
|
16
|
+
c = Curl::Easy.new('http://127.0.0.1:9999/test')
|
17
|
+
did_call_redirect = false
|
18
|
+
c.on_redirect do|x|
|
19
|
+
did_call_redirect = true
|
20
|
+
end
|
21
|
+
c.perform
|
22
|
+
|
23
|
+
assert !did_call_redirect, "should reach this point redirect should not have been called"
|
24
|
+
|
25
|
+
c = Curl::Easy.new('http://127.0.0.1:9999/test')
|
26
|
+
did_call_redirect = false
|
27
|
+
c.on_redirect do|x|
|
28
|
+
did_call_redirect = true
|
29
|
+
end
|
30
|
+
c.follow_location = true
|
31
|
+
c.perform
|
32
|
+
|
33
|
+
assert_equal 0, c.redirect_count
|
34
|
+
assert !did_call_redirect, "should reach this point redirect should not have been called"
|
35
|
+
|
36
|
+
c = Curl::Easy.new('http://127.0.0.1:9999/redirect_to_test')
|
37
|
+
did_call_redirect = false
|
38
|
+
c.on_redirect do|x|
|
39
|
+
did_call_redirect = true
|
40
|
+
end
|
41
|
+
c.perform
|
42
|
+
assert_equal 307, c.response_code
|
43
|
+
|
44
|
+
assert did_call_redirect, "we should have called on_redirect"
|
45
|
+
|
46
|
+
c = Curl::Easy.new('http://127.0.0.1:9999/redirect_to_test')
|
47
|
+
did_call_redirect = false
|
48
|
+
c.follow_location = true
|
49
|
+
# NOTE: while this API is not supported by libcurl e.g. there is no redirect function callback in libcurl we could
|
50
|
+
# add support in ruby for this by executing this callback if redirect_count is greater than 0 at the end of a request in curb_multi.c
|
51
|
+
c.on_redirect do|x|
|
52
|
+
did_call_redirect = true
|
53
|
+
end
|
54
|
+
c.perform
|
55
|
+
assert_equal 1, c.redirect_count
|
56
|
+
assert_equal 200, c.response_code
|
57
|
+
|
58
|
+
assert did_call_redirect, "we should have called on_redirect"
|
59
|
+
|
60
|
+
c.url = 'http://127.0.0.1:9999/test'
|
61
|
+
c.perform
|
62
|
+
assert_equal 0, c.redirect_count
|
63
|
+
assert_equal 200, c.response_code
|
64
|
+
|
65
|
+
puts "checking for raise support"
|
66
|
+
did_raise = false
|
67
|
+
begin
|
68
|
+
c = Curl::Easy.new('http://127.0.0.1:9999/redirect_to_test')
|
69
|
+
did_call_redirect = false
|
70
|
+
c.on_redirect do|x|
|
71
|
+
raise "raise"
|
72
|
+
did_call_redirect = true
|
73
|
+
end
|
74
|
+
c.perform
|
75
|
+
rescue => e
|
76
|
+
did_raise = true
|
77
|
+
end
|
78
|
+
assert_equal 307, c.response_code
|
79
|
+
assert did_raise
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
@@ -35,15 +35,13 @@ class BugTestInstancePostDiffersFromClassPost < Test::Unit::TestCase
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def do_test
|
38
|
-
c = Curl::Easy.http_post('https://www.google.com/accounts/ServiceLoginAuth',
|
39
|
-
Curl::PostField.content('ltmpl','m_blanco'))
|
38
|
+
c = Curl::Easy.http_post('https://www.google.com/accounts/ServiceLoginAuth', Curl::PostField.content('ltmpl','m_blanco'))
|
40
39
|
body_c, header_c = c.body_str, c.header_str
|
41
40
|
|
42
41
|
sleep 2
|
43
42
|
|
44
|
-
c.http_post('https://www.google.com/accounts/ServiceLoginAuth',
|
45
|
-
|
46
|
-
body_i, header_i = c.body_str, c.header_str
|
43
|
+
c.http_post('https://www.google.com/accounts/ServiceLoginAuth', Curl::PostField.content('ltmpl','m_blanco'))
|
44
|
+
body_i, header_i = c.body, c.head
|
47
45
|
|
48
46
|
# timestamps will differ, just check first bit. We wont get here if
|
49
47
|
# the bug bites anyway...
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
2
|
+
|
3
|
+
|
4
|
+
require 'curb'
|
5
|
+
|
6
|
+
class BugIssue102 < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def test_gc_closewait
|
9
|
+
100.times do
|
10
|
+
responses = {}
|
11
|
+
requests = ["http://www.google.co.uk/", "http://www.ruby-lang.org/"]
|
12
|
+
m = Curl::Multi.new
|
13
|
+
# add a few easy handles
|
14
|
+
requests.each do |url|
|
15
|
+
responses[url] = ""
|
16
|
+
c = Curl::Easy.new(url) do|curl|
|
17
|
+
curl.follow_location = true
|
18
|
+
curl.on_body{|data| responses[url] << data; data.size }
|
19
|
+
curl.on_success {|easy| #puts "success, add more easy handles"
|
20
|
+
}
|
21
|
+
end
|
22
|
+
m.add(c)
|
23
|
+
end
|
24
|
+
|
25
|
+
m.perform do
|
26
|
+
#puts "idling... can do some work here"
|
27
|
+
end
|
28
|
+
GC.start
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
data/tests/bug_multi_segfault.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
# irb: multi = Curl::Multi.new
|
4
4
|
# irb: exit
|
5
5
|
# <main>:47140: [BUG] Bus Error
|
6
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
6
7
|
$:.unshift File.expand_path(File.join(File.dirname(__FILE__),'..','ext'))
|
7
8
|
$:.unshift File.expand_path(File.join(File.dirname(__FILE__),'..','lib'))
|
8
9
|
require 'curb'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
2
|
+
|
3
|
+
class BugRaiseOnCallback < Test::Unit::TestCase
|
4
|
+
include BugTestServerSetupTeardown
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@port = 9999
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_on_complte
|
12
|
+
c = Curl::Easy.new('http://127.0.0.1:9999/test')
|
13
|
+
did_raise = false
|
14
|
+
begin
|
15
|
+
c.on_complete do|x|
|
16
|
+
assert_equal 'http://127.0.0.1:9999/test', x.url
|
17
|
+
raise "error complete" # this will get swallowed
|
18
|
+
end
|
19
|
+
c.perform
|
20
|
+
rescue => e
|
21
|
+
did_raise = true
|
22
|
+
end
|
23
|
+
assert did_raise, "we want to raise an exception if the ruby callbacks raise"
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
#test_on_debug
|
data/tests/helper.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
# Copyright (c)2006 Ross Bamford. See LICENSE.
|
3
3
|
$CURB_TESTING = true
|
4
4
|
require 'uri'
|
5
|
+
require 'stringio'
|
5
6
|
|
6
7
|
$TOPDIR = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
7
8
|
$EXTDIR = File.join($TOPDIR, 'ext')
|
@@ -134,6 +135,32 @@ class TestServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
134
135
|
|
135
136
|
end
|
136
137
|
|
138
|
+
module BugTestServerSetupTeardown
|
139
|
+
def setup
|
140
|
+
@port ||= 9992
|
141
|
+
@server = WEBrick::HTTPServer.new( :Port => @port )
|
142
|
+
@server.mount_proc("/test") do|req,res|
|
143
|
+
if @response_proc
|
144
|
+
@response_proc.call(res)
|
145
|
+
else
|
146
|
+
res.body = "hi"
|
147
|
+
res['Content-Type'] = "text/html"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
@thread = Thread.new(@server) do|srv|
|
152
|
+
srv.start
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def teardown
|
157
|
+
while @server.status != :Shutdown
|
158
|
+
@server.shutdown
|
159
|
+
end
|
160
|
+
@thread.join
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
137
164
|
module TestServerMethods
|
138
165
|
def locked_file
|
139
166
|
File.join(File.dirname(__FILE__),"server_lock-#{@__port}")
|
@@ -142,7 +169,6 @@ module TestServerMethods
|
|
142
169
|
def server_setup(port=9129,servlet=TestServlet)
|
143
170
|
@__port = port
|
144
171
|
if (@server ||= nil).nil? and !File.exist?(locked_file)
|
145
|
-
|
146
172
|
File.open(locked_file,'w') {|f| f << 'locked' }
|
147
173
|
if TEST_SINGLE_THREADED
|
148
174
|
rd, wr = IO.pipe
|
data/tests/tc_curl_easy.rb
CHANGED
@@ -10,6 +10,74 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
10
10
|
Curl.reset
|
11
11
|
end
|
12
12
|
|
13
|
+
def test_nested_easy_methods
|
14
|
+
easy = Curl.get(TestServlet.url) {|http|
|
15
|
+
res = Curl.get(TestServlet.url + '/not_here')
|
16
|
+
assert_equal 404, res.code
|
17
|
+
}
|
18
|
+
assert_equal 200, easy.code
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_curlopt_stderr_with_file
|
22
|
+
# does not work with Tempfile directly
|
23
|
+
path = Tempfile.new('curb_test_curlopt_stderr').path
|
24
|
+
File.open(path, 'w') do |file|
|
25
|
+
easy = Curl::Easy.new(TestServlet.url)
|
26
|
+
easy.verbose = true
|
27
|
+
easy.setopt(Curl::CURLOPT_STDERR, file)
|
28
|
+
easy.perform
|
29
|
+
end
|
30
|
+
output = File.read(path)
|
31
|
+
|
32
|
+
assert_match(/HTTP\/1\.1\ 200\ OK(?:\ )?/, output)
|
33
|
+
assert_match('Host: 127.0.0.1:9129', output)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_curlopt_stderr_with_io
|
37
|
+
path = Tempfile.new('curb_test_curlopt_stderr').path
|
38
|
+
fd = IO.sysopen(path, 'w')
|
39
|
+
io = IO.for_fd(fd)
|
40
|
+
|
41
|
+
easy = Curl::Easy.new(TestServlet.url)
|
42
|
+
easy.verbose = true
|
43
|
+
easy.setopt(Curl::CURLOPT_STDERR, io)
|
44
|
+
easy.perform
|
45
|
+
|
46
|
+
|
47
|
+
output = File.read(path)
|
48
|
+
|
49
|
+
assert_match(output, 'HTTP/1.1 200 OK')
|
50
|
+
assert_match(output, 'Host: 127.0.0.1:9129')
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_curlopt_stderr_fails_with_tempdir
|
54
|
+
Tempfile.open('curb_test_curlopt_stderr') do |tempfile|
|
55
|
+
easy = Curl::Easy.new(TestServlet.url)
|
56
|
+
|
57
|
+
assert_raise(TypeError) do
|
58
|
+
easy.setopt(Curl::CURLOPT_STDERR, tempfile)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_curlopt_stderr_fails_with_stringio
|
64
|
+
stringio = StringIO.new
|
65
|
+
easy = Curl::Easy.new(TestServlet.url)
|
66
|
+
|
67
|
+
assert_raise(TypeError) do
|
68
|
+
easy.setopt(Curl::CURLOPT_STDERR, stringio)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_curlopt_stderr_fails_with_string
|
73
|
+
string = String.new
|
74
|
+
easy = Curl::Easy.new(TestServlet.url)
|
75
|
+
|
76
|
+
assert_raise(TypeError) do
|
77
|
+
easy.setopt(Curl::CURLOPT_STDERR, string)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
13
81
|
def test_exception
|
14
82
|
begin
|
15
83
|
Curl.get('NOT_FOUND_URL')
|
@@ -653,9 +721,9 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
653
721
|
on_success_called = false
|
654
722
|
curl.on_success {|c|
|
655
723
|
on_success_called = true
|
656
|
-
assert_not_nil c.
|
657
|
-
|
658
|
-
assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.
|
724
|
+
assert_not_nil c.body
|
725
|
+
assert_match(/Content-Length: /, c.head)
|
726
|
+
assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body)
|
659
727
|
}
|
660
728
|
curl.perform
|
661
729
|
assert on_success_called, "Success handler not called"
|
@@ -1079,7 +1147,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
1079
1147
|
c = Curl::Easy.new($TEST_URL)
|
1080
1148
|
c.on_success {|x| raise "error" }
|
1081
1149
|
c.perform
|
1082
|
-
rescue => e
|
1150
|
+
rescue Curl::Err::AbortedByCallbackError => e
|
1083
1151
|
assert_equal 'Curl::Err::AbortedByCallbackError', e.class.to_s
|
1084
1152
|
c.close
|
1085
1153
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
2
|
+
|
3
|
+
class TestCurbCurlMaxFileSize < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@easy = Curl::Easy.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_maxfilesize
|
9
|
+
@easy.set(Curl::CURLOPT_MAXFILESIZE, 5000000)
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
data/tests/tc_curl_multi.rb
CHANGED
@@ -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,19 +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
|
-
#
|
13
|
-
|
14
|
-
|
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
|
15
54
|
end
|
55
|
+
Curl::Multi.autoclose = false
|
16
56
|
before_open = open_fds.call
|
57
|
+
#puts "before_open: #{before_open.inspect}"
|
17
58
|
assert !Curl::Multi.autoclose
|
18
59
|
multi = Curl::Multi.new
|
19
60
|
multi.max_connects = 1 # limit to 1 connection within the multi handle
|
20
61
|
|
21
62
|
did_complete = false
|
22
63
|
5.times do |n|
|
23
|
-
|
24
|
-
easy = Curl::Easy.new("http://google.com/") do |curl|
|
64
|
+
easy = Curl::Easy.new(TestServlet.url) do |curl|
|
25
65
|
curl.timeout = 5 # ensure we don't hang for ever connecting to an external host
|
26
66
|
curl.on_complete {
|
27
67
|
did_complete = true
|
@@ -33,18 +73,21 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
33
73
|
multi.perform
|
34
74
|
assert did_complete
|
35
75
|
after_open = open_fds.call
|
36
|
-
|
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"
|
37
80
|
multi.close
|
38
81
|
|
39
82
|
after_open = open_fds.call
|
40
|
-
|
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"
|
41
85
|
|
42
86
|
Curl::Multi.autoclose = true
|
43
87
|
multi = Curl::Multi.new
|
44
88
|
did_complete = false
|
45
89
|
5.times do |n|
|
46
|
-
|
47
|
-
easy = Curl::Easy.new("http://google.com/") do |curl|
|
90
|
+
easy = Curl::Easy.new(TestServlet.url) do |curl|
|
48
91
|
curl.timeout = 5 # ensure we don't hang for ever connecting to an external host
|
49
92
|
curl.on_complete {
|
50
93
|
did_complete = true
|
@@ -56,7 +99,8 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
56
99
|
multi.perform
|
57
100
|
assert did_complete
|
58
101
|
after_open = open_fds.call
|
59
|
-
|
102
|
+
#puts "after_open: #{after_open} before_open: #{before_open.inspect}"
|
103
|
+
assert_equal 0, (after_open - before_open), "auto close the connections"
|
60
104
|
ensure
|
61
105
|
Curl::Multi.autoclose = false # restore default
|
62
106
|
end
|
@@ -117,6 +161,44 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
117
161
|
|
118
162
|
end
|
119
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
|
+
|
120
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
|
121
203
|
# on my MacBook, this causes curl_easy_init to take nearly 0.01 seconds / * 100 below is 1 second too many!
|
122
204
|
def test_n_requests
|
@@ -438,7 +520,7 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
438
520
|
{ :url => TestServlet.url, :method => :get }
|
439
521
|
]
|
440
522
|
Curl::Multi.http(urls, {:pipeline => true}) do|easy, code, method|
|
441
|
-
assert_equal
|
523
|
+
assert_equal 200, code
|
442
524
|
case method
|
443
525
|
when :post
|
444
526
|
assert_match(/POST/, easy.body_str)
|
@@ -452,20 +534,20 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
452
534
|
end
|
453
535
|
|
454
536
|
def test_multi_easy_http_with_max_connects
|
455
|
-
|
537
|
+
urls = [
|
456
538
|
{ :url => TestServlet.url + '?q=1', :method => :get },
|
457
539
|
{ :url => TestServlet.url + '?q=2', :method => :get },
|
458
540
|
{ :url => TestServlet.url + '?q=3', :method => :get }
|
459
541
|
]
|
460
542
|
Curl::Multi.http(urls, {:pipeline => true, :max_connects => 1}) do|easy, code, method|
|
461
|
-
assert_equal
|
543
|
+
assert_equal 200, code
|
462
544
|
case method
|
463
545
|
when :post
|
464
|
-
assert_match(/POST/, easy.
|
546
|
+
assert_match(/POST/, easy.body)
|
465
547
|
when :get
|
466
|
-
assert_match(/GET/, easy.
|
548
|
+
assert_match(/GET/, easy.body)
|
467
549
|
when :put
|
468
|
-
assert_match(/PUT/, easy.
|
550
|
+
assert_match(/PUT/, easy.body)
|
469
551
|
end
|
470
552
|
end
|
471
553
|
end
|
data/tests/tc_curl_postfield.rb
CHANGED
@@ -2,63 +2,63 @@ require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
|
2
2
|
|
3
3
|
class TestCurbCurlPostfield < Test::Unit::TestCase
|
4
4
|
def test_private_new
|
5
|
-
assert_raise(NoMethodError) { Curl::PostField.new }
|
5
|
+
assert_raise(NoMethodError) { Curl::PostField.new }
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
def test_new_content_01
|
9
9
|
pf = Curl::PostField.content('foo', 'bar')
|
10
|
-
|
10
|
+
|
11
11
|
assert_equal 'foo', pf.name
|
12
12
|
assert_equal 'bar', pf.content
|
13
13
|
assert_nil pf.content_type
|
14
14
|
assert_nil pf.local_file
|
15
|
-
assert_nil pf.remote_file
|
15
|
+
assert_nil pf.remote_file
|
16
16
|
assert_nil pf.set_content_proc
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
def test_new_content_02
|
20
20
|
pf = Curl::PostField.content('foo', 'bar', 'text/html')
|
21
|
-
|
21
|
+
|
22
22
|
assert_equal 'foo', pf.name
|
23
23
|
assert_equal 'bar', pf.content
|
24
24
|
assert_equal 'text/html', pf.content_type
|
25
25
|
assert_nil pf.local_file
|
26
26
|
assert_nil pf.remote_file
|
27
|
-
assert_nil pf.set_content_proc
|
28
|
-
end
|
29
|
-
|
27
|
+
assert_nil pf.set_content_proc
|
28
|
+
end
|
29
|
+
|
30
30
|
def test_new_content_03
|
31
31
|
l = lambda { |field| "never gets run" }
|
32
32
|
pf = Curl::PostField.content('foo', &l)
|
33
|
-
|
33
|
+
|
34
34
|
assert_equal 'foo', pf.name
|
35
35
|
assert_nil pf.content
|
36
36
|
assert_nil pf.content_type
|
37
37
|
assert_nil pf.local_file
|
38
38
|
assert_nil pf.remote_file
|
39
|
-
|
39
|
+
|
40
40
|
# N.B. This doesn't just get the proc, but also removes it.
|
41
41
|
assert_equal l, pf.set_content_proc
|
42
|
-
end
|
42
|
+
end
|
43
43
|
|
44
44
|
def test_new_content_04
|
45
45
|
l = lambda { |field| "never gets run" }
|
46
46
|
pf = Curl::PostField.content('foo', 'text/html', &l)
|
47
|
-
|
47
|
+
|
48
48
|
assert_equal 'foo', pf.name
|
49
49
|
assert_nil pf.content
|
50
50
|
assert_equal 'text/html', pf.content_type
|
51
51
|
assert_nil pf.local_file
|
52
52
|
assert_nil pf.remote_file
|
53
|
-
|
53
|
+
|
54
54
|
# N.B. This doesn't just get the proc, but also removes it.
|
55
55
|
assert_equal l, pf.set_content_proc
|
56
|
-
end
|
56
|
+
end
|
57
57
|
|
58
58
|
|
59
59
|
def test_new_file_01
|
60
60
|
pf = Curl::PostField.file('foo', 'localname')
|
61
|
-
|
61
|
+
|
62
62
|
assert_equal 'foo', pf.name
|
63
63
|
assert_equal 'localname', pf.local_file
|
64
64
|
assert_equal 'localname', pf.remote_file
|
@@ -67,44 +67,44 @@ class TestCurbCurlPostfield < Test::Unit::TestCase
|
|
67
67
|
assert_nil pf.content
|
68
68
|
assert_nil pf.set_content_proc
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
def test_new_file_02
|
72
72
|
pf = Curl::PostField.file('foo', 'localname', 'remotename')
|
73
|
-
|
73
|
+
|
74
74
|
assert_equal 'foo', pf.name
|
75
75
|
assert_equal 'localname', pf.local_file
|
76
76
|
assert_equal 'remotename', pf.remote_file
|
77
77
|
assert_nil pf.content_type
|
78
78
|
assert_nil pf.content
|
79
79
|
assert_nil pf.set_content_proc
|
80
|
-
end
|
81
|
-
|
80
|
+
end
|
81
|
+
|
82
82
|
def test_new_file_03
|
83
83
|
l = lambda { |field| "never gets run" }
|
84
84
|
pf = Curl::PostField.file('foo', 'remotename', &l)
|
85
|
-
|
85
|
+
|
86
86
|
assert_equal 'foo', pf.name
|
87
87
|
assert_equal 'remotename', pf.remote_file
|
88
88
|
assert_nil pf.local_file
|
89
89
|
assert_nil pf.content_type
|
90
90
|
assert_nil pf.content
|
91
|
-
|
91
|
+
|
92
92
|
# N.B. This doesn't just get the proc, but also removes it.
|
93
93
|
assert_equal l, pf.set_content_proc
|
94
|
-
end
|
94
|
+
end
|
95
95
|
|
96
96
|
def test_new_file_04
|
97
97
|
assert_raise(ArgumentError) do
|
98
98
|
# no local name, no block
|
99
99
|
Curl::PostField.file('foo')
|
100
100
|
end
|
101
|
-
|
101
|
+
|
102
102
|
assert_raise(ArgumentError) do
|
103
103
|
# no remote name with block
|
104
104
|
Curl::PostField.file('foo') { |field| "never runs" }
|
105
105
|
end
|
106
106
|
end
|
107
|
-
|
107
|
+
|
108
108
|
def test_new_file_05
|
109
109
|
# local gets ignored when supplying a block, but remote
|
110
110
|
# is still set up properly.
|
@@ -118,15 +118,15 @@ class TestCurbCurlPostfield < Test::Unit::TestCase
|
|
118
118
|
assert_nil pf.content
|
119
119
|
|
120
120
|
assert_equal l, pf.set_content_proc
|
121
|
-
end
|
122
|
-
|
121
|
+
end
|
122
|
+
|
123
123
|
def test_to_s_01
|
124
|
-
pf = Curl::PostField.content('foo', 'bar')
|
124
|
+
pf = Curl::PostField.content('foo', 'bar')
|
125
125
|
assert_equal "foo=bar", pf.to_s
|
126
126
|
end
|
127
127
|
|
128
128
|
def test_to_s_02
|
129
|
-
pf = Curl::PostField.content('foo', 'bar ton')
|
129
|
+
pf = Curl::PostField.content('foo', 'bar ton')
|
130
130
|
assert_equal "foo=bar%20ton", pf.to_s
|
131
131
|
end
|
132
132
|
|