curb 0.6.5.0 → 0.8.4
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/README +42 -5
- data/Rakefile +27 -4
- data/ext/curb.c +638 -0
- data/ext/curb.h +6 -4
- data/ext/curb_easy.c +954 -573
- data/ext/curb_easy.h +31 -2
- data/ext/curb_errors.c +16 -2
- data/ext/curb_errors.h +1 -0
- data/ext/curb_macros.h +4 -0
- data/ext/curb_multi.c +229 -67
- data/ext/curb_postfield.c +61 -49
- data/ext/curb_upload.c +2 -2
- data/ext/extconf.rb +232 -4
- data/lib/curb.rb +1 -186
- data/lib/curl/easy.rb +468 -0
- data/lib/curl/multi.rb +248 -0
- data/lib/curl.rb +61 -1
- data/tests/bug_crash_on_debug.rb +39 -0
- data/tests/bug_crash_on_progress.rb +33 -0
- data/tests/bug_curb_easy_blocks_ruby_threads.rb +2 -2
- data/tests/bug_issue102.rb +17 -0
- data/tests/bug_multi_segfault.rb +6 -2
- data/tests/bug_postfields_crash2.rb +57 -0
- data/tests/bug_require_last_or_segfault.rb +1 -1
- data/tests/bugtests.rb +9 -0
- data/tests/helper.rb +40 -10
- data/tests/signals.rb +33 -0
- data/tests/tc_curl.rb +39 -0
- data/tests/tc_curl_download.rb +44 -1
- data/tests/tc_curl_easy.rb +355 -22
- data/tests/tc_curl_easy_setopt.rb +31 -0
- data/tests/tc_curl_multi.rb +57 -5
- data/tests/tc_curl_postfield.rb +3 -1
- data/tests/timeout.rb +100 -0
- data/tests/timeout_server.rb +33 -0
- metadata +87 -48
data/lib/curl.rb
CHANGED
|
@@ -1,2 +1,62 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'curb_core'
|
|
2
|
+
require 'curl/easy'
|
|
3
|
+
require 'curl/multi'
|
|
4
|
+
require 'uri'
|
|
2
5
|
|
|
6
|
+
# expose shortcut methods
|
|
7
|
+
module Curl
|
|
8
|
+
|
|
9
|
+
def self.http(verb, url, post_body=nil, put_data=nil, &block)
|
|
10
|
+
handle = Thread.current[:curb_curl] ||= Curl::Easy.new
|
|
11
|
+
handle.url = url
|
|
12
|
+
handle.post_body = post_body if post_body
|
|
13
|
+
handle.put_data = put_data if put_data
|
|
14
|
+
yield handle if block_given?
|
|
15
|
+
handle.http(verb)
|
|
16
|
+
handle
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.get(url, params={}, &block)
|
|
20
|
+
http :GET, urlalize(url, params), nil, nil, &block
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.post(url, params={}, &block)
|
|
24
|
+
http :POST, url, postalize(params), nil, &block
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.put(url, params={}, &block)
|
|
28
|
+
http :PUT, url, nil, postalize(params), &block
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.delete(url, params={}, &block)
|
|
32
|
+
http :DELETE, url, postalize(params), nil, &block
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.patch(url, params={}, &block)
|
|
36
|
+
http :PATCH, url, postalize(params), nil, &block
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.head(url, params={}, &block)
|
|
40
|
+
http :HEAD, urlalize(url, params), nil, nil, &block
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.options(url, params={}, &block)
|
|
44
|
+
http :OPTIONS, urlalize(url, params), nil, nil, &block
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def self.urlalize(url, params={})
|
|
48
|
+
query_str = params.map {|k,v| "#{URI.escape(k.to_s)}=#{URI.escape(v.to_s)}" }.join('&')
|
|
49
|
+
if url.match(/\?/)
|
|
50
|
+
"#{url}&#{query_str}"
|
|
51
|
+
elsif query_str.size > 0
|
|
52
|
+
"#{url}?#{query_str}"
|
|
53
|
+
else
|
|
54
|
+
url
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self.postalize(params={})
|
|
59
|
+
params.respond_to?(:map) ? URI.encode_www_form(params) : (params.respond_to?(:to_s) ? params.to_s : params)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
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 BugCrashOnDebug < Test::Unit::TestCase
|
|
10
|
+
|
|
11
|
+
def test_on_debug
|
|
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
|
+
puts 'a'
|
|
18
|
+
thread = Thread.new(server) do|srv|
|
|
19
|
+
srv.start
|
|
20
|
+
end
|
|
21
|
+
puts 'b'
|
|
22
|
+
c = Curl::Easy.new('http://127.0.0.1:9999/test')
|
|
23
|
+
c.on_debug do|x|
|
|
24
|
+
puts x.inspect
|
|
25
|
+
raise "error" # this will get swallowed
|
|
26
|
+
end
|
|
27
|
+
c.perform
|
|
28
|
+
puts 'c'
|
|
29
|
+
ensure
|
|
30
|
+
puts 'd'
|
|
31
|
+
server.shutdown
|
|
32
|
+
puts 'e'
|
|
33
|
+
puts thread.exit
|
|
34
|
+
puts 'f'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
#test_on_debug
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
|
2
|
+
require 'webrick'
|
|
3
|
+
class ::WEBrick::HTTPServer ; def access_log(config, req, res) ; end ; end
|
|
4
|
+
class ::WEBrick::BasicLog ; def log(level, data) ; end ; end
|
|
5
|
+
|
|
6
|
+
class BugCrashOnDebug < Test::Unit::TestCase
|
|
7
|
+
|
|
8
|
+
def test_on_debug
|
|
9
|
+
server = WEBrick::HTTPServer.new( :Port => 9999 )
|
|
10
|
+
server.mount_proc("/test") do|req,res|
|
|
11
|
+
res.body = "hi"
|
|
12
|
+
res['Content-Type'] = "text/html"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
thread = Thread.new(server) do|srv|
|
|
16
|
+
srv.start
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
c = Curl::Easy.new('http://127.0.0.1:9999/test')
|
|
20
|
+
c.on_progress do|x|
|
|
21
|
+
raise "error"
|
|
22
|
+
end
|
|
23
|
+
c.perform
|
|
24
|
+
|
|
25
|
+
assert false, "should not reach this point"
|
|
26
|
+
|
|
27
|
+
rescue => e
|
|
28
|
+
assert_equal 'Curl::Err::AbortedByCallbackError', e.class.to_s
|
|
29
|
+
c.close
|
|
30
|
+
ensure
|
|
31
|
+
server.shutdown
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -21,7 +21,7 @@ class BugTestInstancePostDiffersFromClassPost < Test::Unit::TestCase
|
|
|
21
21
|
|
|
22
22
|
5.times do |i|
|
|
23
23
|
t = Thread.new do
|
|
24
|
-
c = Curl::Easy.perform('http://
|
|
24
|
+
c = Curl::Easy.perform('http://127.0.0.1:9999/test')
|
|
25
25
|
c.header_str
|
|
26
26
|
end
|
|
27
27
|
threads << t
|
|
@@ -37,7 +37,7 @@ class BugTestInstancePostDiffersFromClassPost < Test::Unit::TestCase
|
|
|
37
37
|
timer = Time.now
|
|
38
38
|
single_responses = []
|
|
39
39
|
5.times do |i|
|
|
40
|
-
c = Curl::Easy.perform('http://
|
|
40
|
+
c = Curl::Easy.perform('http://127.0.0.1:9999/test')
|
|
41
41
|
single_responses << c.header_str
|
|
42
42
|
end
|
|
43
43
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
|
2
|
+
|
|
3
|
+
class BugIssue102 < Test::Unit::TestCase
|
|
4
|
+
|
|
5
|
+
def test_interface
|
|
6
|
+
test = "https://api.twitter.com/1/users/show.json?screen_name=TwitterAPI&include_entities=true"
|
|
7
|
+
ip = "192.168.1.61"
|
|
8
|
+
|
|
9
|
+
c = Curl::Easy.new do |curl|
|
|
10
|
+
curl.url = test
|
|
11
|
+
curl.interface = ip
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
c.perform
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
data/tests/bug_multi_segfault.rb
CHANGED
|
@@ -6,5 +6,9 @@
|
|
|
6
6
|
$:.unshift File.expand_path(File.join(File.dirname(__FILE__),'..','ext'))
|
|
7
7
|
$:.unshift File.expand_path(File.join(File.dirname(__FILE__),'..','lib'))
|
|
8
8
|
require 'curb'
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
|
|
10
|
+
class BugMultiSegfault < Test::Unit::TestCase
|
|
11
|
+
def test_bug
|
|
12
|
+
multi = Curl::Multi.new
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Not sure if this is an IRB bug, but thought you guys should know.
|
|
2
|
+
#
|
|
3
|
+
# ** My Ruby version: ruby 1.8.7 (2009-06-12 patchlevel 174) [x86_64-linux]
|
|
4
|
+
# ** Version of Rubygems: 1.3.5
|
|
5
|
+
# ** Version of the Curb gem: 0.6.6.0
|
|
6
|
+
#
|
|
7
|
+
#
|
|
8
|
+
# Transcript of IRB session:
|
|
9
|
+
# ------------------------------------------------------------------------------------------------------------------
|
|
10
|
+
# irb(main):001:0> a = {
|
|
11
|
+
# irb(main):002:1* :type => :pie,
|
|
12
|
+
# irb(main):003:1* :series => {
|
|
13
|
+
# irb(main):004:2* :names => [:a,:b],
|
|
14
|
+
# irb(main):005:2* :values => [70,30],
|
|
15
|
+
# irb(main):006:2* :colors => [:red,:green]
|
|
16
|
+
# irb(main):007:2> },
|
|
17
|
+
# irb(main):008:1* :output_format => :png
|
|
18
|
+
# irb(main):009:1> }
|
|
19
|
+
# => {:type=>:pie, :output_format=>:png, :series=>{:names=>[:a, :b], :values=>[70, 30], :colors=>[:red, :green]}}
|
|
20
|
+
# irb(main):010:0> post = []
|
|
21
|
+
# => []
|
|
22
|
+
# irb(main):011:0> require 'rubygems'
|
|
23
|
+
# => true
|
|
24
|
+
# irb(main):012:0> require 'curb'
|
|
25
|
+
# => true
|
|
26
|
+
# irb(main):013:0> include Curl
|
|
27
|
+
# => Object
|
|
28
|
+
# irb(main):014:0> a.each_pair do |k,v|
|
|
29
|
+
# irb(main):015:1* post << PostField.content(k,v)
|
|
30
|
+
# irb(main):016:1> end
|
|
31
|
+
# => {:type=>:pie, :output_format=>:png, :series=>{:names=>[:a, :b], :values=>[70, 30], :colors=>[:red, :green]}}
|
|
32
|
+
# irb(main):017:0> post
|
|
33
|
+
# /usr/lib/ruby/1.8/irb.rb:302: [BUG] Segmentation fault
|
|
34
|
+
# ruby 1.8.7 (2009-06-12 patchlevel 174) [x86_64-linux]
|
|
35
|
+
#
|
|
36
|
+
# Aborted
|
|
37
|
+
# ------------------------------------------------------------------------------------------------------------------
|
|
38
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
|
39
|
+
|
|
40
|
+
class BugPostFieldsCrash2 < Test::Unit::TestCase
|
|
41
|
+
def test_crash
|
|
42
|
+
a = {
|
|
43
|
+
:type => :pie,
|
|
44
|
+
:series => {
|
|
45
|
+
:names => [:a,:b],
|
|
46
|
+
:values => [70,30],
|
|
47
|
+
:colors => [:red,:green]
|
|
48
|
+
},
|
|
49
|
+
:output_format => :png
|
|
50
|
+
}
|
|
51
|
+
post = []
|
|
52
|
+
a.each_pair do |k,v|
|
|
53
|
+
post << Curl::PostField.content(k,v)
|
|
54
|
+
end
|
|
55
|
+
post.inspect
|
|
56
|
+
end
|
|
57
|
+
end
|
data/tests/bugtests.rb
ADDED
data/tests/helper.rb
CHANGED
|
@@ -11,6 +11,7 @@ $:.unshift($EXTDIR)
|
|
|
11
11
|
|
|
12
12
|
require 'curb'
|
|
13
13
|
require 'test/unit'
|
|
14
|
+
require 'fileutils'
|
|
14
15
|
|
|
15
16
|
$TEST_URL = "file://#{URI.escape(File.expand_path(__FILE__).tr('\\','/').tr(':','|'))}"
|
|
16
17
|
|
|
@@ -64,23 +65,35 @@ class TestServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
|
64
65
|
end
|
|
65
66
|
|
|
66
67
|
def do_GET(req,res)
|
|
67
|
-
|
|
68
|
+
if req.path.match /redirect$/
|
|
69
|
+
res.status = 302
|
|
70
|
+
res['Location'] = '/foo'
|
|
71
|
+
elsif req.path.match /not_here$/
|
|
72
|
+
res.status = 404
|
|
73
|
+
elsif req.path.match /error$/
|
|
74
|
+
res.status = 500
|
|
75
|
+
end
|
|
76
|
+
respond_with("GET#{req.query_string}",req,res)
|
|
68
77
|
end
|
|
69
78
|
|
|
70
79
|
def do_HEAD(req,res)
|
|
71
80
|
res['Location'] = "/nonexistent"
|
|
72
|
-
respond_with(
|
|
81
|
+
respond_with("HEAD#{req.query_string}",req,res)
|
|
73
82
|
end
|
|
74
83
|
|
|
75
84
|
def do_POST(req,res)
|
|
76
|
-
if req.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
85
|
+
if req.query['filename'].nil?
|
|
86
|
+
if req.body
|
|
87
|
+
params = {}
|
|
88
|
+
req.body.split('&').map{|s| k,v=s.split('='); params[k] = v }
|
|
89
|
+
end
|
|
90
|
+
if params and params['s'] == '500'
|
|
91
|
+
res.status = 500
|
|
92
|
+
else
|
|
93
|
+
respond_with("POST\n#{req.body}",req,res)
|
|
94
|
+
end
|
|
82
95
|
else
|
|
83
|
-
respond_with(
|
|
96
|
+
respond_with(req.query['filename'],req,res)
|
|
84
97
|
end
|
|
85
98
|
end
|
|
86
99
|
|
|
@@ -90,7 +103,23 @@ class TestServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
|
90
103
|
end
|
|
91
104
|
|
|
92
105
|
def do_DELETE(req,res)
|
|
93
|
-
respond_with(
|
|
106
|
+
respond_with("DELETE#{req.query_string}",req,res)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def do_PURGE(req,res)
|
|
110
|
+
respond_with("PURGE#{req.query_string}",req,res)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def do_COPY(req,res)
|
|
114
|
+
respond_with("COPY#{req.query_string}",req,res)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def do_PATCH(req,res)
|
|
118
|
+
respond_with("PATCH\n#{req.body}",req,res)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def do_OPTIONS(req,res)
|
|
122
|
+
respond_with("OPTIONS#{req.query_string}",req,res)
|
|
94
123
|
end
|
|
95
124
|
|
|
96
125
|
end
|
|
@@ -165,5 +194,6 @@ module TestServerMethods
|
|
|
165
194
|
at_exit{exit_code.call}
|
|
166
195
|
|
|
167
196
|
end
|
|
197
|
+
rescue Errno::EADDRINUSE
|
|
168
198
|
end
|
|
169
199
|
end
|
data/tests/signals.rb
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
|
2
|
+
|
|
3
|
+
# This test suite requires the timeout server to be running
|
|
4
|
+
# See tests/timeout.rb for more info about the timeout server
|
|
5
|
+
class TestCurbSignals < Test::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
# Testcase for https://github.com/taf2/curb/issues/117
|
|
8
|
+
def test_continue_after_signal
|
|
9
|
+
trap("SIGUSR1") { }
|
|
10
|
+
|
|
11
|
+
curl = Curl::Easy.new(wait_url(2))
|
|
12
|
+
pid = $$
|
|
13
|
+
Thread.new do
|
|
14
|
+
sleep 1
|
|
15
|
+
Process.kill("SIGUSR1", pid)
|
|
16
|
+
end
|
|
17
|
+
assert_equal true, curl.http_get
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def wait_url(time)
|
|
23
|
+
"#{server_base}/wait/#{time}"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def serve_url(chunk_size, time, count)
|
|
27
|
+
"#{server_base}/serve/#{chunk_size}/every/#{time}/for/#{count}"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def server_base
|
|
31
|
+
'http://127.0.0.1:9128'
|
|
32
|
+
end
|
|
33
|
+
end
|
data/tests/tc_curl.rb
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
|
2
|
+
|
|
3
|
+
class TestCurl < Test::Unit::TestCase
|
|
4
|
+
def test_get
|
|
5
|
+
curl = Curl.get(TestServlet.url, {:foo => "bar"})
|
|
6
|
+
assert_equal "GETfoo=bar", curl.body_str
|
|
7
|
+
|
|
8
|
+
curl = Curl.options(TestServlet.url, {:foo => "bar"}) do|http|
|
|
9
|
+
http.headers['Cookie'] = 'foo=1;bar=2'
|
|
10
|
+
end
|
|
11
|
+
assert_equal "OPTIONSfoo=bar", curl.body_str
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def test_post
|
|
15
|
+
curl = Curl.post(TestServlet.url, {:foo => "bar"})
|
|
16
|
+
assert_equal "POST\nfoo=bar", curl.body_str
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def test_put
|
|
20
|
+
curl = Curl.put(TestServlet.url, {:foo => "bar"})
|
|
21
|
+
assert_equal "PUT\nfoo=bar", curl.body_str
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_patch
|
|
25
|
+
curl = Curl.patch(TestServlet.url, {:foo => "bar"})
|
|
26
|
+
assert_equal "PATCH\nfoo=bar", curl.body_str
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_options
|
|
30
|
+
curl = Curl.options(TestServlet.url, {:foo => "bar"})
|
|
31
|
+
assert_equal "OPTIONSfoo=bar", curl.body_str
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
include TestServerMethods
|
|
35
|
+
|
|
36
|
+
def setup
|
|
37
|
+
server_setup
|
|
38
|
+
end
|
|
39
|
+
end
|
data/tests/tc_curl_download.rb
CHANGED
|
@@ -7,7 +7,7 @@ class TestCurbCurlDownload < Test::Unit::TestCase
|
|
|
7
7
|
server_setup
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
def
|
|
10
|
+
def test_download_url_to_file_via_string
|
|
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
|
|
|
@@ -18,6 +18,49 @@ class TestCurbCurlDownload < Test::Unit::TestCase
|
|
|
18
18
|
File.unlink(dl_path) if File.exist?(dl_path)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
+
def test_download_url_to_file_via_file_io
|
|
22
|
+
dl_url = "http://127.0.0.1:9129/ext/curb_easy.c"
|
|
23
|
+
dl_path = File.join(Dir::tmpdir, "dl_url_test.file")
|
|
24
|
+
io = File.open(dl_path, 'wb')
|
|
25
|
+
|
|
26
|
+
curb = Curl::Easy.download(dl_url, io)
|
|
27
|
+
assert io.closed?
|
|
28
|
+
assert File.exist?(dl_path)
|
|
29
|
+
assert_equal File.read(File.join(File.dirname(__FILE__), '..','ext','curb_easy.c')), File.read(dl_path)
|
|
30
|
+
ensure
|
|
31
|
+
File.unlink(dl_path) if File.exist?(dl_path)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_download_url_to_file_via_io
|
|
35
|
+
dl_url = "http://127.0.0.1:9129/ext/curb_easy.c"
|
|
36
|
+
dl_path = File.join(Dir::tmpdir, "dl_url_test.file")
|
|
37
|
+
reader, writer = IO.pipe
|
|
38
|
+
|
|
39
|
+
# Write to local file
|
|
40
|
+
fork do
|
|
41
|
+
begin
|
|
42
|
+
writer.close
|
|
43
|
+
File.open(dl_path, 'wb') { |file| file << reader.read }
|
|
44
|
+
ensure
|
|
45
|
+
reader.close rescue IOError # if the stream has already been closed
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Download remote source
|
|
50
|
+
begin
|
|
51
|
+
reader.close
|
|
52
|
+
curb = Curl::Easy.download(dl_url, writer)
|
|
53
|
+
Process.wait
|
|
54
|
+
ensure
|
|
55
|
+
writer.close rescue IOError # if the stream has already been closed, which occurs in Easy::download
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
assert File.exist?(dl_path)
|
|
59
|
+
assert_equal File.read(File.join(File.dirname(__FILE__), '..','ext','curb_easy.c')), File.read(dl_path)
|
|
60
|
+
ensure
|
|
61
|
+
File.unlink(dl_path) if File.exist?(dl_path)
|
|
62
|
+
end
|
|
63
|
+
|
|
21
64
|
def test_download_bad_url_gives_404
|
|
22
65
|
dl_url = "http://127.0.0.1:9129/this_file_does_not_exist.html"
|
|
23
66
|
dl_path = File.join(Dir::tmpdir, "dl_url_test.file")
|