curb 0.9.3 → 1.0.2
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 +5 -5
- data/README.markdown +78 -22
- data/Rakefile +26 -20
- data/ext/banned.h +32 -0
- data/ext/curb.c +190 -14
- data/ext/curb.h +18 -5
- data/ext/curb_easy.c +499 -84
- data/ext/curb_easy.h +7 -0
- data/ext/curb_errors.c +86 -0
- data/ext/curb_macros.h +6 -0
- data/ext/curb_multi.c +172 -233
- data/ext/curb_multi.h +0 -1
- data/ext/curb_postfield.c +9 -7
- data/ext/curb_upload.c +1 -0
- data/ext/extconf.rb +76 -6
- data/lib/curb.rb +1 -0
- data/lib/curl/easy.rb +16 -9
- data/lib/curl/multi.rb +52 -13
- data/lib/curl.rb +20 -12
- data/tests/bug_crash_on_debug.rb +14 -4
- data/tests/bug_crash_on_progress.rb +4 -2
- data/tests/bug_follow_redirect_288.rb +91 -0
- data/tests/bug_issue277.rb +32 -0
- data/tests/bug_raise_on_callback.rb +40 -0
- data/tests/helper.rb +96 -13
- data/tests/tc_curl.rb +31 -1
- data/tests/tc_curl_download.rb +3 -3
- data/tests/tc_curl_easy.rb +167 -46
- data/tests/tc_curl_easy_resolve.rb +16 -0
- data/tests/tc_curl_maxfilesize.rb +12 -0
- data/tests/tc_curl_multi.rb +123 -18
- data/tests/tc_curl_postfield.rb +29 -29
- data/tests/tc_curl_protocols.rb +37 -0
- data/tests/timeout.rb +21 -5
- metadata +20 -8
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
2
|
+
|
3
|
+
require 'webrick'
|
4
|
+
class ::WEBrick::HTTPServer ; def access_log(config, req, res) ; end ; end
|
5
|
+
class ::WEBrick::BasicLog ; def log(level, data) ; end ; end
|
6
|
+
|
7
|
+
require 'curl'
|
8
|
+
|
9
|
+
class BugRaiseOnCallback < Test::Unit::TestCase
|
10
|
+
|
11
|
+
def test_on_complte
|
12
|
+
server = WEBrick::HTTPServer.new( :Port => 9999 )
|
13
|
+
server.mount_proc("/test") do|req,res|
|
14
|
+
res.body = "hi"
|
15
|
+
res['Content-Type'] = "text/html"
|
16
|
+
end
|
17
|
+
thread = Thread.new(server) do|srv|
|
18
|
+
srv.start
|
19
|
+
end
|
20
|
+
c = Curl::Easy.new('http://127.0.0.1:9999/test')
|
21
|
+
did_raise = false
|
22
|
+
begin
|
23
|
+
c.on_complete do|x|
|
24
|
+
assert_equal 'http://127.0.0.1:9999/test', x.url
|
25
|
+
raise "error complete" # this will get swallowed
|
26
|
+
end
|
27
|
+
c.perform
|
28
|
+
rescue => e
|
29
|
+
did_raise = true
|
30
|
+
end
|
31
|
+
assert did_raise, "we want to raise an exception if the ruby callbacks raise"
|
32
|
+
|
33
|
+
ensure
|
34
|
+
server.shutdown
|
35
|
+
thread.exit
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
#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')
|
@@ -18,7 +19,7 @@ rescue LoadError
|
|
18
19
|
end
|
19
20
|
require 'fileutils'
|
20
21
|
|
21
|
-
$TEST_URL = "file://#{
|
22
|
+
$TEST_URL = "file://#{'/' if RUBY_DESCRIPTION =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/}#{File.expand_path(__FILE__).tr('\\','/')}"
|
22
23
|
|
23
24
|
require 'thread'
|
24
25
|
require 'webrick'
|
@@ -30,19 +31,22 @@ require 'webrick'
|
|
30
31
|
TEST_SINGLE_THREADED=false
|
31
32
|
|
32
33
|
# keep webrick quiet
|
33
|
-
|
34
|
+
::WEBrick::HTTPServer.send(:remove_method,:access_log) if ::WEBrick::HTTPServer.instance_methods.include?(:access_log)
|
35
|
+
::WEBrick::BasicLog.send(:remove_method,:log) if ::WEBrick::BasicLog.instance_methods.include?(:log)
|
36
|
+
|
37
|
+
::WEBrick::HTTPServer.class_eval do
|
34
38
|
def access_log(config, req, res)
|
35
39
|
# nop
|
36
40
|
end
|
37
41
|
end
|
38
|
-
|
42
|
+
::WEBrick::BasicLog.class_eval do
|
39
43
|
def log(level, data)
|
40
44
|
# nop
|
41
45
|
end
|
42
46
|
end
|
43
47
|
|
44
48
|
#
|
45
|
-
# Simple test server to record number of times a request is sent/recieved of a specific
|
49
|
+
# Simple test server to record number of times a request is sent/recieved of a specific
|
46
50
|
# request type, e.g. GET,POST,PUT,DELETE
|
47
51
|
#
|
48
52
|
class TestServlet < WEBrick::HTTPServlet::AbstractServlet
|
@@ -52,13 +56,12 @@ class TestServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
52
56
|
end
|
53
57
|
|
54
58
|
def self.port
|
55
|
-
|
59
|
+
@port ||= 9129
|
56
60
|
end
|
57
61
|
|
58
62
|
def self.path
|
59
63
|
'/methods'
|
60
64
|
end
|
61
|
-
|
62
65
|
def self.url
|
63
66
|
"http://127.0.0.1:#{port}#{path}"
|
64
67
|
end
|
@@ -70,12 +73,12 @@ class TestServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
70
73
|
end
|
71
74
|
|
72
75
|
def do_GET(req,res)
|
73
|
-
if req.path.match
|
76
|
+
if req.path.match(/redirect$/)
|
74
77
|
res.status = 302
|
75
78
|
res['Location'] = '/foo'
|
76
|
-
elsif req.path.match
|
79
|
+
elsif req.path.match(/not_here$/)
|
77
80
|
res.status = 404
|
78
|
-
elsif req.path.match
|
81
|
+
elsif req.path.match(/error$/)
|
79
82
|
res.status = 500
|
80
83
|
end
|
81
84
|
respond_with("GET#{req.query_string}",req,res)
|
@@ -94,6 +97,9 @@ class TestServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
94
97
|
end
|
95
98
|
if params and params['s'] == '500'
|
96
99
|
res.status = 500
|
100
|
+
elsif params and params['c']
|
101
|
+
cookie = URI.decode_www_form_component(params['c']).split('=')
|
102
|
+
res.cookies << WEBrick::Cookie.new(*cookie)
|
97
103
|
else
|
98
104
|
respond_with("POST\n#{req.body}",req,res)
|
99
105
|
end
|
@@ -136,8 +142,7 @@ module TestServerMethods
|
|
136
142
|
|
137
143
|
def server_setup(port=9129,servlet=TestServlet)
|
138
144
|
@__port = port
|
139
|
-
if @server.nil? and !File.exist?(locked_file)
|
140
|
-
|
145
|
+
if (@server ||= nil).nil? and !File.exist?(locked_file)
|
141
146
|
File.open(locked_file,'w') {|f| f << 'locked' }
|
142
147
|
if TEST_SINGLE_THREADED
|
143
148
|
rd, wr = IO.pipe
|
@@ -145,7 +150,7 @@ module TestServerMethods
|
|
145
150
|
rd.close
|
146
151
|
rd = nil
|
147
152
|
|
148
|
-
# start up a webrick server for testing delete
|
153
|
+
# start up a webrick server for testing delete
|
149
154
|
server = WEBrick::HTTPServer.new :Port => port, :DocumentRoot => File.expand_path(File.dirname(__FILE__))
|
150
155
|
|
151
156
|
server.mount(servlet.path, servlet)
|
@@ -161,7 +166,7 @@ module TestServerMethods
|
|
161
166
|
rd.read
|
162
167
|
rd.close
|
163
168
|
else
|
164
|
-
# start up a webrick server for testing delete
|
169
|
+
# start up a webrick server for testing delete
|
165
170
|
@server = WEBrick::HTTPServer.new :Port => port, :DocumentRoot => File.expand_path(File.dirname(__FILE__))
|
166
171
|
|
167
172
|
@server.mount(servlet.path, servlet)
|
@@ -202,3 +207,81 @@ module TestServerMethods
|
|
202
207
|
rescue Errno::EADDRINUSE
|
203
208
|
end
|
204
209
|
end
|
210
|
+
|
211
|
+
|
212
|
+
|
213
|
+
# Backport for Ruby 1.8
|
214
|
+
module Backports
|
215
|
+
module Ruby18
|
216
|
+
module URIFormEncoding
|
217
|
+
TBLENCWWWCOMP_ = {}
|
218
|
+
TBLDECWWWCOMP_ = {}
|
219
|
+
|
220
|
+
def encode_www_form_component(str)
|
221
|
+
if TBLENCWWWCOMP_.empty?
|
222
|
+
256.times do |i|
|
223
|
+
TBLENCWWWCOMP_[i.chr] = '%%%02X' % i
|
224
|
+
end
|
225
|
+
TBLENCWWWCOMP_[' '] = '+'
|
226
|
+
TBLENCWWWCOMP_.freeze
|
227
|
+
end
|
228
|
+
str.to_s.gsub( /([^*\-.0-9A-Z_a-z])/ ) {|*| TBLENCWWWCOMP_[$1] }
|
229
|
+
end
|
230
|
+
|
231
|
+
def decode_www_form_component(str)
|
232
|
+
if TBLDECWWWCOMP_.empty?
|
233
|
+
256.times do |i|
|
234
|
+
h, l = i>>4, i&15
|
235
|
+
TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
|
236
|
+
TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
|
237
|
+
TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
|
238
|
+
TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
|
239
|
+
end
|
240
|
+
TBLDECWWWCOMP_['+'] = ' '
|
241
|
+
TBLDECWWWCOMP_.freeze
|
242
|
+
end
|
243
|
+
|
244
|
+
raise ArgumentError, "invalid %-encoding (#{str.dump})" unless /\A(?:%[[:xdigit:]]{2}|[^%]+)*\z/ =~ str
|
245
|
+
str.gsub( /(\+|%[[:xdigit:]]{2})/ ) {|*| TBLDECWWWCOMP_[$1] }
|
246
|
+
end
|
247
|
+
|
248
|
+
def encode_www_form( enum )
|
249
|
+
enum.map do |k,v|
|
250
|
+
if v.nil?
|
251
|
+
encode_www_form_component(k)
|
252
|
+
elsif v.respond_to?(:to_ary)
|
253
|
+
v.to_ary.map do |w|
|
254
|
+
str = encode_www_form_component(k)
|
255
|
+
unless w.nil?
|
256
|
+
str << '='
|
257
|
+
str << encode_www_form_component(w)
|
258
|
+
end
|
259
|
+
end.join('&')
|
260
|
+
else
|
261
|
+
str = encode_www_form_component(k)
|
262
|
+
str << '='
|
263
|
+
str << encode_www_form_component(v)
|
264
|
+
end
|
265
|
+
end.join('&')
|
266
|
+
end
|
267
|
+
|
268
|
+
WFKV_ = '(?:%\h\h|[^%#=;&])'
|
269
|
+
def decode_www_form(str, _)
|
270
|
+
return [] if str.to_s == ''
|
271
|
+
|
272
|
+
unless /\A#{WFKV_}=#{WFKV_}(?:[;&]#{WFKV_}=#{WFKV_})*\z/ =~ str
|
273
|
+
raise ArgumentError, "invalid data of application/x-www-form-urlencoded (#{str})"
|
274
|
+
end
|
275
|
+
ary = []
|
276
|
+
$&.scan(/([^=;&]+)=([^;&]*)/) do
|
277
|
+
ary << [decode_www_form_component($1, enc), decode_www_form_component($2, enc)]
|
278
|
+
end
|
279
|
+
ary
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
unless URI.methods.include?(:encode_www_form)
|
286
|
+
URI.extend(Backports::Ruby18::URIFormEncoding)
|
287
|
+
end
|
data/tests/tc_curl.rb
CHANGED
@@ -31,7 +31,37 @@ class TestCurl < Test::Unit::TestCase
|
|
31
31
|
assert_equal "OPTIONSfoo=bar", curl.body_str
|
32
32
|
end
|
33
33
|
|
34
|
-
|
34
|
+
def test_urlalize_without_extra_params
|
35
|
+
url_no_params = 'http://localhost/test'
|
36
|
+
url_with_params = 'http://localhost/test?a=1'
|
37
|
+
|
38
|
+
assert_equal(url_no_params, Curl.urlalize(url_no_params))
|
39
|
+
assert_equal(url_with_params, Curl.urlalize(url_with_params))
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_urlalize_with_nil_as_params
|
43
|
+
url = 'http://localhost/test'
|
44
|
+
assert_equal(url, Curl.urlalize(url, nil))
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_urlalize_with_extra_params
|
48
|
+
url_no_params = 'http://localhost/test'
|
49
|
+
url_with_params = 'http://localhost/test?a=1'
|
50
|
+
extra_params = { :b => 2 }
|
51
|
+
|
52
|
+
expected_url_no_params = 'http://localhost/test?b=2'
|
53
|
+
expected_url_with_params = 'http://localhost/test?a=1&b=2'
|
54
|
+
|
55
|
+
assert_equal(expected_url_no_params, Curl.urlalize(url_no_params, extra_params))
|
56
|
+
assert_equal(expected_url_with_params, Curl.urlalize(url_with_params, extra_params))
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_urlalize_does_not_strip_trailing_?
|
60
|
+
url_empty_params = 'http://localhost/test?'
|
61
|
+
assert_equal(url_empty_params, Curl.urlalize(url_empty_params))
|
62
|
+
end
|
63
|
+
|
64
|
+
include TestServerMethods
|
35
65
|
|
36
66
|
def setup
|
37
67
|
server_setup
|
data/tests/tc_curl_download.rb
CHANGED
@@ -11,7 +11,7 @@ class TestCurbCurlDownload < Test::Unit::TestCase
|
|
11
11
|
dl_url = "http://127.0.0.1:9129/ext/curb_easy.c"
|
12
12
|
dl_path = File.join(Dir::tmpdir, "dl_url_test.file")
|
13
13
|
|
14
|
-
|
14
|
+
Curl::Easy.download(dl_url, dl_path)
|
15
15
|
assert File.exist?(dl_path)
|
16
16
|
assert_equal File.read(File.join(File.dirname(__FILE__), '..','ext','curb_easy.c')), File.read(dl_path)
|
17
17
|
ensure
|
@@ -23,7 +23,7 @@ class TestCurbCurlDownload < Test::Unit::TestCase
|
|
23
23
|
dl_path = File.join(Dir::tmpdir, "dl_url_test.file")
|
24
24
|
io = File.open(dl_path, 'wb')
|
25
25
|
|
26
|
-
|
26
|
+
Curl::Easy.download(dl_url, io)
|
27
27
|
assert io.closed?
|
28
28
|
assert File.exist?(dl_path)
|
29
29
|
assert_equal File.read(File.join(File.dirname(__FILE__), '..','ext','curb_easy.c')), File.read(dl_path)
|
@@ -49,7 +49,7 @@ class TestCurbCurlDownload < Test::Unit::TestCase
|
|
49
49
|
# Download remote source
|
50
50
|
begin
|
51
51
|
reader.close
|
52
|
-
|
52
|
+
Curl::Easy.download(dl_url, writer)
|
53
53
|
Process.wait
|
54
54
|
ensure
|
55
55
|
writer.close rescue IOError # if the stream has already been closed, which occurs in Easy::download
|
data/tests/tc_curl_easy.rb
CHANGED
@@ -5,11 +5,89 @@ end
|
|
5
5
|
|
6
6
|
class TestCurbCurlEasy < Test::Unit::TestCase
|
7
7
|
def test_global_reset
|
8
|
-
|
8
|
+
Curl.get($TEST_URL)
|
9
9
|
# in a Timeout block you should reset the thread current handle
|
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.response_code
|
17
|
+
}
|
18
|
+
assert_equal 200, easy.response_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
|
+
|
81
|
+
def test_exception
|
82
|
+
begin
|
83
|
+
Curl.get('NOT_FOUND_URL')
|
84
|
+
rescue
|
85
|
+
assert true
|
86
|
+
rescue Exception
|
87
|
+
assert false, "We should raise StandardError"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
13
91
|
def test_threads
|
14
92
|
t = []
|
15
93
|
5.times do
|
@@ -18,20 +96,17 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
18
96
|
c = Curl.get($TEST_URL)
|
19
97
|
assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body_str)
|
20
98
|
assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body)
|
21
|
-
assert_equal "", c.header_str
|
22
|
-
assert_equal "", c.head
|
23
99
|
end
|
24
100
|
end
|
25
101
|
end
|
26
102
|
|
27
|
-
t.each {|
|
103
|
+
t.each {|x| x.join }
|
28
104
|
end
|
29
105
|
|
30
106
|
def test_class_perform_01
|
31
107
|
assert_instance_of Curl::Easy, c = Curl::Easy.perform($TEST_URL)
|
32
108
|
assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body_str)
|
33
109
|
assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body)
|
34
|
-
assert_equal "", c.header_str
|
35
110
|
end
|
36
111
|
|
37
112
|
def test_class_perform_02
|
@@ -39,12 +114,11 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
39
114
|
assert_instance_of Curl::Easy, c = Curl::Easy.perform($TEST_URL) { |curl| curl.on_body { |d| data << d; d.length } }
|
40
115
|
|
41
116
|
assert_nil c.body_str
|
42
|
-
assert_equal "", c.header_str
|
43
117
|
assert_match(/^# DO NOT REMOVE THIS COMMENT/, data)
|
44
118
|
end
|
45
119
|
|
46
120
|
def test_class_perform_03
|
47
|
-
assert_raise(Curl::Err::CouldntReadError) {
|
121
|
+
assert_raise(Curl::Err::CouldntReadError) { Curl::Easy.perform($TEST_URL + "nonexistent") }
|
48
122
|
end
|
49
123
|
|
50
124
|
def test_new_01
|
@@ -134,7 +208,6 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
134
208
|
c = Curl::Easy.new($TEST_URL)
|
135
209
|
assert_equal true, c.http_get
|
136
210
|
assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body_str)
|
137
|
-
assert_equal "", c.header_str
|
138
211
|
end
|
139
212
|
|
140
213
|
def test_get_02
|
@@ -146,7 +219,6 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
146
219
|
assert_equal true, c.http_get
|
147
220
|
|
148
221
|
assert_nil c.body_str
|
149
|
-
assert_equal "", c.header_str
|
150
222
|
assert_match(/^# DO NOT REMOVE THIS COMMENT/, data)
|
151
223
|
end
|
152
224
|
|
@@ -329,29 +401,69 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
329
401
|
c.max_redirects = nil
|
330
402
|
assert_nil c.max_redirects
|
331
403
|
end
|
332
|
-
|
404
|
+
|
405
|
+
def test_timeout_with_floats
|
406
|
+
c = Curl::Easy.new($TEST_URL)
|
407
|
+
|
408
|
+
c.timeout = 1.5
|
409
|
+
assert_equal 1500, c.timeout_ms
|
410
|
+
assert_equal 1.5, c.timeout
|
411
|
+
end
|
412
|
+
|
413
|
+
def test_timeout_with_negative
|
414
|
+
c = Curl::Easy.new($TEST_URL)
|
415
|
+
|
416
|
+
c.timeout = -1.5
|
417
|
+
assert_equal 0, c.timeout
|
418
|
+
assert_equal 0, c.timeout_ms
|
419
|
+
|
420
|
+
c.timeout = -4.8
|
421
|
+
assert_equal 0, c.timeout
|
422
|
+
assert_equal 0, c.timeout_ms
|
423
|
+
end
|
424
|
+
|
333
425
|
def test_timeout_01
|
334
426
|
c = Curl::Easy.new($TEST_URL)
|
335
|
-
|
336
|
-
|
337
|
-
|
427
|
+
|
428
|
+
assert_equal 0, c.timeout
|
429
|
+
|
338
430
|
c.timeout = 3
|
339
431
|
assert_equal 3, c.timeout
|
340
|
-
|
341
|
-
c.timeout =
|
342
|
-
|
432
|
+
|
433
|
+
c.timeout = 0
|
434
|
+
assert_equal 0, c.timeout
|
343
435
|
end
|
344
436
|
|
345
437
|
def test_timeout_ms_01
|
346
438
|
c = Curl::Easy.new($TEST_URL)
|
347
439
|
|
348
|
-
|
440
|
+
assert_equal 0, c.timeout_ms
|
349
441
|
|
350
442
|
c.timeout_ms = 100
|
351
443
|
assert_equal 100, c.timeout_ms
|
352
444
|
|
353
445
|
c.timeout_ms = nil
|
354
|
-
|
446
|
+
assert_equal 0, c.timeout_ms
|
447
|
+
end
|
448
|
+
|
449
|
+
def test_timeout_ms_with_floats
|
450
|
+
c = Curl::Easy.new($TEST_URL)
|
451
|
+
|
452
|
+
c.timeout_ms = 55.5
|
453
|
+
assert_equal 55, c.timeout_ms
|
454
|
+
assert_equal 0.055, c.timeout
|
455
|
+
end
|
456
|
+
|
457
|
+
def test_timeout_ms_with_negative
|
458
|
+
c = Curl::Easy.new($TEST_URL)
|
459
|
+
|
460
|
+
c.timeout_ms = -1.5
|
461
|
+
assert_equal 0, c.timeout
|
462
|
+
assert_equal 0, c.timeout_ms
|
463
|
+
|
464
|
+
c.timeout_ms = -4.8
|
465
|
+
assert_equal 0, c.timeout
|
466
|
+
assert_equal 0, c.timeout_ms
|
355
467
|
end
|
356
468
|
|
357
469
|
def test_connect_timeout_01
|
@@ -595,14 +707,23 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
595
707
|
assert_equal "some.file", c.cookiejar
|
596
708
|
end
|
597
709
|
|
710
|
+
def test_cookielist
|
711
|
+
c = Curl::Easy.new TestServlet.url
|
712
|
+
c.enable_cookies = true
|
713
|
+
c.post_body = URI.encode_www_form('c' => 'somename=somevalue')
|
714
|
+
assert_nil c.cookielist
|
715
|
+
c.perform
|
716
|
+
assert_match(/somevalue/, c.cookielist.join(''))
|
717
|
+
end
|
718
|
+
|
598
719
|
def test_on_success
|
599
720
|
curl = Curl::Easy.new($TEST_URL)
|
600
721
|
on_success_called = false
|
601
722
|
curl.on_success {|c|
|
602
723
|
on_success_called = true
|
603
|
-
assert_not_nil c.
|
604
|
-
|
605
|
-
assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.
|
724
|
+
assert_not_nil c.body
|
725
|
+
assert_match /Content-Length: 7714/, c.head
|
726
|
+
assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body)
|
606
727
|
}
|
607
728
|
curl.perform
|
608
729
|
assert on_success_called, "Success handler not called"
|
@@ -657,7 +778,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
657
778
|
retries = 0
|
658
779
|
begin
|
659
780
|
count = 0
|
660
|
-
|
781
|
+
Curl::Easy.send("http_#{method}", TestServlet.url) do|c|
|
661
782
|
count += 1
|
662
783
|
assert_equal Curl::Easy, c.class
|
663
784
|
end
|
@@ -679,8 +800,8 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
679
800
|
Curl::PostField.file('bar', File.expand_path(File.join(File.dirname(__FILE__),'..','README.markdown')))
|
680
801
|
]
|
681
802
|
curl.http_post(fields)
|
682
|
-
assert_match
|
683
|
-
assert_match
|
803
|
+
assert_match(/HTTP POST file upload/, curl.body_str)
|
804
|
+
assert_match(/Content-Disposition: form-data/, curl.body_str)
|
684
805
|
end
|
685
806
|
|
686
807
|
def test_post_with_body_remote
|
@@ -706,8 +827,8 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
706
827
|
curl.multipart_form_post = true
|
707
828
|
pf = Curl::PostField.file('readme', File.expand_path(File.join(File.dirname(__FILE__),'..','README.markdown')))
|
708
829
|
curl.http_post(pf)
|
709
|
-
assert_match
|
710
|
-
assert_match
|
830
|
+
assert_match(/HTTP POST file upload/, curl.body_str)
|
831
|
+
assert_match(/Content-Disposition: form-data/, curl.body_str)
|
711
832
|
end
|
712
833
|
|
713
834
|
def test_delete_remote
|
@@ -729,7 +850,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
729
850
|
redirect = curl.header_str.match(/Location: (.*)/)
|
730
851
|
|
731
852
|
assert_equal '', curl.body_str
|
732
|
-
assert_match
|
853
|
+
assert_match('/nonexistent', redirect[1])
|
733
854
|
end
|
734
855
|
|
735
856
|
def test_head_accessor
|
@@ -740,7 +861,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
740
861
|
redirect = curl.header_str.match(/Location: (.*)/)
|
741
862
|
|
742
863
|
assert_equal '', curl.body_str
|
743
|
-
assert_match
|
864
|
+
assert_match('/nonexistent', redirect[1])
|
744
865
|
curl.head = false
|
745
866
|
curl.perform
|
746
867
|
assert_equal 'GET', curl.body_str
|
@@ -750,11 +871,11 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
750
871
|
curl = Curl::Easy.new(TestServlet.url)
|
751
872
|
curl.headers['Content-Type'] = 'application/json'
|
752
873
|
assert curl.http_put("message")
|
753
|
-
assert_match
|
754
|
-
assert_match
|
755
|
-
assert_match
|
756
|
-
assert_match
|
757
|
-
assert_match
|
874
|
+
assert_match(/^PUT/, curl.body_str)
|
875
|
+
assert_match(/message$/, curl.body_str)
|
876
|
+
assert_match(/message$/, curl.body)
|
877
|
+
assert_match(/application\/json/, curl.header_str)
|
878
|
+
assert_match(/application\/json/, curl.head)
|
758
879
|
end
|
759
880
|
|
760
881
|
def test_put_data
|
@@ -763,8 +884,8 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
763
884
|
|
764
885
|
curl.perform
|
765
886
|
|
766
|
-
assert_match
|
767
|
-
assert_match
|
887
|
+
assert_match(/^PUT/, curl.body_str)
|
888
|
+
assert_match(/message$/, curl.body_str)
|
768
889
|
end
|
769
890
|
|
770
891
|
# https://github.com/taf2/curb/issues/101
|
@@ -774,8 +895,8 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
774
895
|
|
775
896
|
curl.perform
|
776
897
|
|
777
|
-
assert_match
|
778
|
-
assert_match
|
898
|
+
assert_match(/^PUT/, curl.body_str)
|
899
|
+
assert_match("a\0b", curl.body_str)
|
779
900
|
end
|
780
901
|
|
781
902
|
def test_put_nil_data_no_crash
|
@@ -790,7 +911,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
790
911
|
File.open(__FILE__,'rb') do|f|
|
791
912
|
assert curl.http_put(f)
|
792
913
|
end
|
793
|
-
assert_equal "PUT\n#{File.read(__FILE__)}", curl.body_str
|
914
|
+
assert_equal "PUT\n#{File.read(__FILE__)}", curl.body_str.tr("\r", '')
|
794
915
|
end
|
795
916
|
|
796
917
|
def test_put_class_method
|
@@ -800,7 +921,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
800
921
|
assert_equal Curl::Easy, c.class
|
801
922
|
end
|
802
923
|
assert_equal 1, count
|
803
|
-
assert_equal "PUT\n#{File.read(__FILE__)}", curl.body_str
|
924
|
+
assert_equal "PUT\n#{File.read(__FILE__)}", curl.body_str.tr("\r", '')
|
804
925
|
end
|
805
926
|
|
806
927
|
# Generate a self-signed cert with
|
@@ -809,7 +930,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
809
930
|
def test_cert
|
810
931
|
curl = Curl::Easy.new(TestServlet.url)
|
811
932
|
curl.cert= File.join(File.dirname(__FILE__),"cert.pem")
|
812
|
-
assert_match
|
933
|
+
assert_match(/cert.pem$/,curl.cert)
|
813
934
|
end
|
814
935
|
|
815
936
|
def test_cert_with_password
|
@@ -817,7 +938,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
817
938
|
path = File.join(File.dirname(__FILE__),"cert.pem")
|
818
939
|
curl.certpassword = 'password'
|
819
940
|
curl.cert = path
|
820
|
-
assert_match
|
941
|
+
assert_match(/cert.pem$/,curl.cert)
|
821
942
|
end
|
822
943
|
|
823
944
|
def test_cert_type
|
@@ -838,7 +959,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
838
959
|
def test_ca_cert
|
839
960
|
curl = Curl::Easy.new(TestServlet.url)
|
840
961
|
curl.cacert= File.join(File.dirname(__FILE__),"cacert.pem")
|
841
|
-
assert_match
|
962
|
+
assert_match(/cacert.pem$/, curl.cacert)
|
842
963
|
end
|
843
964
|
|
844
965
|
def test_user_agent
|
@@ -896,7 +1017,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
896
1017
|
easy.http_post(pf)
|
897
1018
|
|
898
1019
|
assert_not_equal(0,easy.body_str.size)
|
899
|
-
assert_equal(easy.body_str,File.read(readme))
|
1020
|
+
assert_equal(easy.body_str.tr("\r", ''), File.read(readme))
|
900
1021
|
end
|
901
1022
|
|
902
1023
|
|
@@ -992,8 +1113,8 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
992
1113
|
curl.headers['Accept'] = '*/*'
|
993
1114
|
curl.headers['Authorization'] = 'Foo Bar Biz Baz'
|
994
1115
|
curl.http_put(rd)
|
995
|
-
assert_match
|
996
|
-
assert_match
|
1116
|
+
assert_match(/^PUT/, curl.body_str)
|
1117
|
+
assert_match(/hello$/, curl.body_str)
|
997
1118
|
curl.header_str
|
998
1119
|
curl.body_str
|
999
1120
|
end
|
@@ -1026,7 +1147,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
1026
1147
|
c = Curl::Easy.new($TEST_URL)
|
1027
1148
|
c.on_success {|x| raise "error" }
|
1028
1149
|
c.perform
|
1029
|
-
rescue => e
|
1150
|
+
rescue Curl::Err::AbortedByCallbackError => e
|
1030
1151
|
assert_equal 'Curl::Err::AbortedByCallbackError', e.class.to_s
|
1031
1152
|
c.close
|
1032
1153
|
end
|