curb 1.3.5 → 1.3.7
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.md +90 -13
- data/Rakefile +8 -3
- data/doc.rb +48 -8
- data/ext/curb.c +33 -0
- data/ext/curb.h +3 -3
- data/ext/curb_easy.c +1471 -87
- data/ext/curb_easy.h +26 -0
- data/ext/curb_errors.c +2 -0
- data/ext/curb_errors.h +1 -0
- data/ext/curb_multi.c +257 -130
- data/ext/curb_multi.h +1 -0
- data/ext/extconf.rb +12 -0
- data/lib/curl/download.rb +160 -0
- data/lib/curl/easy.rb +113 -13
- data/lib/curl/multi.rb +172 -39
- data/lib/curl.rb +471 -11
- data/tests/bug_poison.rb +29 -0
- data/tests/helper.rb +178 -1
- data/tests/io_select_less_scheduler_probe.rb +105 -0
- data/tests/tc_curl_download.rb +86 -0
- data/tests/tc_curl_easy.rb +77 -0
- data/tests/tc_curl_easy_resolve.rb +2 -0
- data/tests/tc_curl_maxfilesize.rb +201 -1
- data/tests/tc_curl_multi.rb +258 -0
- data/tests/tc_curl_native_coverage.rb +1 -0
- data/tests/tc_curl_network_policy.rb +1475 -0
- data/tests/tc_curl_protocols.rb +351 -0
- data/tests/tc_fiber_scheduler.rb +373 -4
- data/tests/tc_ftp_options.rb +58 -0
- data/tests/tc_gc_compact.rb +53 -0
- data/tests/tc_test_server_methods.rb +15 -0
- metadata +9 -2
|
@@ -5,8 +5,208 @@ class TestCurbCurlMaxFileSize < Test::Unit::TestCase
|
|
|
5
5
|
@easy = Curl::Easy.new
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
-
def
|
|
8
|
+
def teardown
|
|
9
|
+
Curl.__send__(:clear_safe!) if Curl.respond_to?(:clear_safe!, true)
|
|
10
|
+
super
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def test_maxfilesize_setopt
|
|
9
14
|
@easy.set(Curl::CURLOPT_MAXFILESIZE, 5000000)
|
|
15
|
+
@easy.set(Curl::CURLOPT_MAXFILESIZE_LARGE, 5000000) if Curl.const_defined?(:CURLOPT_MAXFILESIZE_LARGE)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_max_body_bytes_exact_limit_succeeds
|
|
19
|
+
with_raw_http_response("HTTP/1.1 200 OK\r\nContent-Length: 8\r\n\r\n12345678") do |url|
|
|
20
|
+
@easy.url = url
|
|
21
|
+
@easy.max_body_bytes = 8
|
|
22
|
+
@easy.perform
|
|
23
|
+
|
|
24
|
+
assert_equal '12345678', @easy.body_str
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def test_max_body_bytes_rejects_large_buffered_response
|
|
29
|
+
with_raw_http_response("HTTP/1.1 200 OK\r\nContent-Length: 64\r\n\r\n#{'x' * 64}") do |url|
|
|
30
|
+
@easy.url = url
|
|
31
|
+
@easy.max_body_bytes = 10
|
|
32
|
+
|
|
33
|
+
assert_body_limit_error do
|
|
34
|
+
@easy.perform
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
assert_operator @easy.body_str.to_s.bytesize, :<=, 10
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def test_safe_get_accepts_max_body_bytes_as_second_argument
|
|
42
|
+
with_raw_http_response("HTTP/1.1 200 OK\r\nContent-Length: 64\r\n\r\n#{'x' * 64}") do |url|
|
|
43
|
+
assert_body_limit_error do
|
|
44
|
+
Curl.safe_get(url, :max_body_bytes => 10)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def test_safe_get_reapplies_max_body_bytes_after_user_block
|
|
50
|
+
with_raw_http_response("HTTP/1.1 200 OK\r\nContent-Length: 64\r\n\r\n#{'x' * 64}") do |url|
|
|
51
|
+
assert_body_limit_error do
|
|
52
|
+
Curl.safe_get(url, {}, :max_body_bytes => 10) do |easy|
|
|
53
|
+
easy.max_body_bytes = nil
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def test_safe_bang_max_body_bytes_applies_to_easy_perform
|
|
60
|
+
with_raw_http_response("HTTP/1.1 200 OK\r\nContent-Length: 64\r\n\r\n#{'x' * 64}") do |url|
|
|
61
|
+
Curl.safe! do |config|
|
|
62
|
+
config.max_body_bytes = 10
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
@easy.url = url
|
|
66
|
+
|
|
67
|
+
assert_body_limit_error do
|
|
68
|
+
@easy.perform
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def test_safe_bang_reapplies_max_body_bytes_after_shortcut_block
|
|
74
|
+
with_raw_http_response("HTTP/1.1 200 OK\r\nContent-Length: 64\r\n\r\n#{'x' * 64}") do |url|
|
|
75
|
+
Curl.safe! do |config|
|
|
76
|
+
config.max_body_bytes = 10
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
assert_body_limit_error do
|
|
80
|
+
Curl.get(url) do |easy|
|
|
81
|
+
easy.max_body_bytes = nil
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def test_safe_get_max_body_bytes_tightens_global_cap
|
|
88
|
+
with_raw_http_response("HTTP/1.1 200 OK\r\nContent-Length: 64\r\n\r\n#{'x' * 64}") do |url|
|
|
89
|
+
Curl.safe! do |config|
|
|
90
|
+
config.max_body_bytes = 1_000
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
assert_body_limit_error do
|
|
94
|
+
Curl.safe_get(url, :max_body_bytes => 10)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def test_safe_bang_rejects_negative_max_body_bytes
|
|
100
|
+
assert_raise(ArgumentError) do
|
|
101
|
+
Curl.safe! do |config|
|
|
102
|
+
config.max_body_bytes = -1
|
|
103
|
+
end
|
|
104
|
+
end
|
|
10
105
|
end
|
|
11
106
|
|
|
107
|
+
def test_safe_head_does_not_apply_body_cap_to_content_length
|
|
108
|
+
with_raw_http_response("HTTP/1.1 200 OK\r\nContent-Length: 65536\r\n\r\n") do |url|
|
|
109
|
+
easy = Curl.safe_head(url, :max_body_bytes => 1)
|
|
110
|
+
|
|
111
|
+
assert_equal 200, easy.response_code
|
|
112
|
+
assert_equal '', easy.body_str
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def test_max_body_bytes_rejects_chunked_response_without_content_length
|
|
117
|
+
chunks = ["1234", "5678", "90"]
|
|
118
|
+
response = +"HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"
|
|
119
|
+
chunks.each { |chunk| response << "#{chunk.bytesize.to_s(16)}\r\n#{chunk}\r\n" }
|
|
120
|
+
response << "0\r\n\r\n"
|
|
121
|
+
|
|
122
|
+
with_raw_http_response(response) do |url|
|
|
123
|
+
@easy.url = url
|
|
124
|
+
@easy.max_body_bytes = 8
|
|
125
|
+
|
|
126
|
+
assert_body_limit_error do
|
|
127
|
+
@easy.perform
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
assert_operator @easy.body_str.to_s.bytesize, :<=, 8
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def test_max_body_bytes_limits_on_body_callback
|
|
135
|
+
chunks = ["1234", "5678", "90"]
|
|
136
|
+
response = +"HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"
|
|
137
|
+
chunks.each { |chunk| response << "#{chunk.bytesize.to_s(16)}\r\n#{chunk}\r\n" }
|
|
138
|
+
response << "0\r\n\r\n"
|
|
139
|
+
seen = +''
|
|
140
|
+
|
|
141
|
+
with_raw_http_response(response) do |url|
|
|
142
|
+
@easy.url = url
|
|
143
|
+
@easy.max_body_bytes = 8
|
|
144
|
+
@easy.on_body { |data| seen << data; data.bytesize }
|
|
145
|
+
|
|
146
|
+
assert_body_limit_error do
|
|
147
|
+
@easy.perform
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
assert_equal '12345678', seen
|
|
151
|
+
assert_nil @easy.body_str
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def test_max_body_bytes_zero_clears_limit
|
|
156
|
+
with_raw_http_response("HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\n123456789012") do |url|
|
|
157
|
+
@easy.url = url
|
|
158
|
+
@easy.max_body_bytes = 1
|
|
159
|
+
@easy.max_body_bytes = 0
|
|
160
|
+
@easy.perform
|
|
161
|
+
|
|
162
|
+
assert_nil @easy.max_body_bytes
|
|
163
|
+
assert_equal '123456789012', @easy.body_str
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def test_max_body_bytes_counter_resets_between_reused_transfers
|
|
168
|
+
@easy.max_body_bytes = 8
|
|
169
|
+
|
|
170
|
+
with_raw_http_response("HTTP/1.1 200 OK\r\nContent-Length: 8\r\n\r\n12345678") do |url|
|
|
171
|
+
@easy.url = url
|
|
172
|
+
@easy.perform
|
|
173
|
+
assert_equal '12345678', @easy.body_str
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
with_raw_http_response("HTTP/1.1 200 OK\r\nContent-Length: 8\r\n\r\nabcdefgh") do |url|
|
|
177
|
+
@easy.url = url
|
|
178
|
+
@easy.perform
|
|
179
|
+
assert_equal 'abcdefgh', @easy.body_str
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
private
|
|
184
|
+
|
|
185
|
+
def assert_body_limit_error
|
|
186
|
+
assert_raise(Curl::Err::FileSizeExceededError) do
|
|
187
|
+
yield
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def with_raw_http_response(response)
|
|
192
|
+
server = TCPServer.new('127.0.0.1', 0)
|
|
193
|
+
port = server.addr[1]
|
|
194
|
+
thread = Thread.new do
|
|
195
|
+
socket = server.accept
|
|
196
|
+
begin
|
|
197
|
+
socket.readpartial(4096)
|
|
198
|
+
rescue EOFError
|
|
199
|
+
end
|
|
200
|
+
socket.write(response)
|
|
201
|
+
socket.close
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
yield "http://127.0.0.1:#{port}/"
|
|
205
|
+
ensure
|
|
206
|
+
server.close if server && !server.closed?
|
|
207
|
+
if thread
|
|
208
|
+
thread.join(5)
|
|
209
|
+
thread.kill if thread.alive?
|
|
210
|
+
end
|
|
211
|
+
end
|
|
12
212
|
end
|
data/tests/tc_curl_multi.rb
CHANGED
|
@@ -189,6 +189,23 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
|
189
189
|
second_multi.close if defined?(second_multi) && second_multi
|
|
190
190
|
end
|
|
191
191
|
|
|
192
|
+
def test_easy_multi_assignment_detaches_from_old_multi
|
|
193
|
+
multi = Curl::Multi.new
|
|
194
|
+
easy = Curl::Easy.new(TestServlet.url)
|
|
195
|
+
|
|
196
|
+
multi.add(easy)
|
|
197
|
+
easy.multi = nil
|
|
198
|
+
|
|
199
|
+
assert_nil easy.multi
|
|
200
|
+
assert_equal({}, multi.requests)
|
|
201
|
+
assert_nothing_raised { easy.close }
|
|
202
|
+
assert_nothing_raised { multi.close }
|
|
203
|
+
|
|
204
|
+
multi = nil
|
|
205
|
+
ensure
|
|
206
|
+
multi.close if defined?(multi) && multi
|
|
207
|
+
end
|
|
208
|
+
|
|
192
209
|
def test_close_makes_multi_unusable
|
|
193
210
|
multi = Curl::Multi.new
|
|
194
211
|
multi.close
|
|
@@ -752,6 +769,23 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
|
752
769
|
m.close if m
|
|
753
770
|
end
|
|
754
771
|
|
|
772
|
+
def test_native_safety_signatures_are_pruned_after_perform
|
|
773
|
+
m = Curl::Multi.new
|
|
774
|
+
easy = Curl::Easy.new($TEST_URL)
|
|
775
|
+
|
|
776
|
+
m.add(easy)
|
|
777
|
+
signatures = m.__send__(:__curb_native_safety_signatures)
|
|
778
|
+
assert_equal easy, m.requests[easy.object_id]
|
|
779
|
+
assert signatures.key?(easy.object_id)
|
|
780
|
+
|
|
781
|
+
m.perform
|
|
782
|
+
|
|
783
|
+
assert_equal 0, m.requests.length
|
|
784
|
+
assert_empty signatures
|
|
785
|
+
ensure
|
|
786
|
+
m.close if m
|
|
787
|
+
end
|
|
788
|
+
|
|
755
789
|
def test_easy_multi_is_cleared_after_perform
|
|
756
790
|
m = Curl::Multi.new
|
|
757
791
|
c = Curl::Easy.new($TEST_URL)
|
|
@@ -766,6 +800,21 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
|
766
800
|
m.close if m
|
|
767
801
|
end
|
|
768
802
|
|
|
803
|
+
def test_frozen_idle_easy_multi_reference_is_cleared_on_close
|
|
804
|
+
multi = Curl::Multi.new
|
|
805
|
+
easy = Curl::Easy.new($TEST_URL)
|
|
806
|
+
easy.freeze
|
|
807
|
+
|
|
808
|
+
easy.multi = multi
|
|
809
|
+
|
|
810
|
+
assert_same multi, easy.multi
|
|
811
|
+
assert_nothing_raised { multi.close }
|
|
812
|
+
assert_nil easy.multi
|
|
813
|
+
multi = nil
|
|
814
|
+
ensure
|
|
815
|
+
multi.close if multi
|
|
816
|
+
end
|
|
817
|
+
|
|
769
818
|
def test_easy_multi_is_available_during_completion_callbacks
|
|
770
819
|
multi = Curl::Multi.new
|
|
771
820
|
easy = Curl::Easy.new($TEST_URL)
|
|
@@ -991,6 +1040,193 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
|
991
1040
|
end
|
|
992
1041
|
end
|
|
993
1042
|
|
|
1043
|
+
def test_multi_download_refuses_existing_explicit_download_path
|
|
1044
|
+
root_uri = 'http://127.0.0.1:9129/ext/'
|
|
1045
|
+
|
|
1046
|
+
Dir.mktmpdir('curb-download-') do |download_dir|
|
|
1047
|
+
download_path = File.join(download_dir, 'curb_easy.c')
|
|
1048
|
+
File.write(download_path, 'sentinel')
|
|
1049
|
+
|
|
1050
|
+
assert_raise(Curl::DownloadTargetExistsError) do
|
|
1051
|
+
Curl::Multi.download([root_uri + 'curb_easy.c'], {}, {}, [download_path])
|
|
1052
|
+
end
|
|
1053
|
+
|
|
1054
|
+
assert_equal 'sentinel', File.read(download_path)
|
|
1055
|
+
end
|
|
1056
|
+
end
|
|
1057
|
+
|
|
1058
|
+
def test_multi_download_failed_transfer_does_not_publish_file_without_block
|
|
1059
|
+
Dir.mktmpdir('curb-download-') do |download_dir|
|
|
1060
|
+
download_path = File.join(download_dir, 'missing')
|
|
1061
|
+
|
|
1062
|
+
error = assert_raise(Curl::Multi::DownloadError) do
|
|
1063
|
+
Curl::Multi.download(['file:///curb/missing'], {}, {}, [download_path])
|
|
1064
|
+
end
|
|
1065
|
+
|
|
1066
|
+
assert !error.errors.empty?
|
|
1067
|
+
assert !File.exist?(download_path)
|
|
1068
|
+
end
|
|
1069
|
+
end
|
|
1070
|
+
|
|
1071
|
+
def test_multi_download_failed_transfer_does_not_publish_file_or_call_block
|
|
1072
|
+
called = false
|
|
1073
|
+
|
|
1074
|
+
Dir.mktmpdir('curb-download-') do |download_dir|
|
|
1075
|
+
download_path = File.join(download_dir, 'missing')
|
|
1076
|
+
|
|
1077
|
+
error = assert_raise(Curl::Multi::DownloadError) do
|
|
1078
|
+
Curl::Multi.download(['file:///curb/missing'], {}, {}, [download_path]) do |_curl, _path|
|
|
1079
|
+
called = true
|
|
1080
|
+
end
|
|
1081
|
+
end
|
|
1082
|
+
|
|
1083
|
+
assert !error.errors.empty?
|
|
1084
|
+
assert_equal false, called
|
|
1085
|
+
assert !File.exist?(download_path)
|
|
1086
|
+
end
|
|
1087
|
+
end
|
|
1088
|
+
|
|
1089
|
+
def test_multi_download_failed_transfer_closes_io_destination
|
|
1090
|
+
Dir.mktmpdir('curb-download-') do |download_dir|
|
|
1091
|
+
download_path = File.join(download_dir, 'missing')
|
|
1092
|
+
io = File.open(download_path, 'wb')
|
|
1093
|
+
|
|
1094
|
+
error = assert_raise(Curl::Multi::DownloadError) do
|
|
1095
|
+
Curl::Multi.download(['file:///curb/missing'], {}, {}, [io])
|
|
1096
|
+
end
|
|
1097
|
+
|
|
1098
|
+
assert !error.errors.any? { |e| e.is_a?(ArgumentError) }
|
|
1099
|
+
assert io.closed?
|
|
1100
|
+
assert_equal '', File.read(download_path)
|
|
1101
|
+
end
|
|
1102
|
+
end
|
|
1103
|
+
|
|
1104
|
+
def test_multi_download_preserves_body_limit_callback_error
|
|
1105
|
+
with_raw_http_response("HTTP/1.1 200 OK\r\nContent-Length: 64\r\n\r\n#{'x' * 64}") do |url|
|
|
1106
|
+
Dir.mktmpdir('curb-download-') do |download_dir|
|
|
1107
|
+
download_path = File.join(download_dir, 'too-large')
|
|
1108
|
+
|
|
1109
|
+
error = assert_raise(Curl::Err::FileSizeExceededError) do
|
|
1110
|
+
Curl::Multi.download([url], { :max_body_bytes => 10 }, {}, [download_path])
|
|
1111
|
+
end
|
|
1112
|
+
|
|
1113
|
+
assert_match(/Maximum body size exceeded/, error.message)
|
|
1114
|
+
assert !File.exist?(download_path)
|
|
1115
|
+
end
|
|
1116
|
+
end
|
|
1117
|
+
end
|
|
1118
|
+
|
|
1119
|
+
def test_multi_download_preserves_output_write_callback_error
|
|
1120
|
+
writer_error = Class.new(StandardError)
|
|
1121
|
+
|
|
1122
|
+
with_raw_http_response("HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\ndata") do |url|
|
|
1123
|
+
Dir.mktmpdir('curb-download-') do |download_dir|
|
|
1124
|
+
writer = File.open(File.join(download_dir, 'writer'), 'wb')
|
|
1125
|
+
writer.define_singleton_method(:write) do |_data|
|
|
1126
|
+
raise writer_error, 'writer failed'
|
|
1127
|
+
end
|
|
1128
|
+
|
|
1129
|
+
error = assert_raise(writer_error) do
|
|
1130
|
+
Curl::Multi.download([url], {}, {}, [writer])
|
|
1131
|
+
end
|
|
1132
|
+
|
|
1133
|
+
assert_equal 'writer failed', error.message
|
|
1134
|
+
assert writer.closed?
|
|
1135
|
+
end
|
|
1136
|
+
end
|
|
1137
|
+
end
|
|
1138
|
+
|
|
1139
|
+
def test_multi_download_safe_directory_rejects_unsafe_names
|
|
1140
|
+
root_uri = 'http://127.0.0.1:9129/ext/'
|
|
1141
|
+
|
|
1142
|
+
Dir.mktmpdir('curb-download-') do |download_dir|
|
|
1143
|
+
['../escape.c', '.env', 'nested/file', '/tmp/escape.c', "bad\0name"].each do |name|
|
|
1144
|
+
assert_raise(ArgumentError, "expected #{name.inspect} to be rejected") do
|
|
1145
|
+
Curl::Multi.download([root_uri + 'curb_easy.c'], {}, {}, [name], :download_dir => download_dir)
|
|
1146
|
+
end
|
|
1147
|
+
end
|
|
1148
|
+
end
|
|
1149
|
+
end
|
|
1150
|
+
|
|
1151
|
+
def test_multi_download_rejects_duplicate_destinations
|
|
1152
|
+
root_uri = 'http://127.0.0.1:9129/ext/'
|
|
1153
|
+
|
|
1154
|
+
Dir.mktmpdir('curb-download-') do |download_dir|
|
|
1155
|
+
assert_raise(ArgumentError) do
|
|
1156
|
+
Curl::Multi.download(
|
|
1157
|
+
[root_uri + 'curb_easy.c?one=1', root_uri + 'curb_easy.c?two=2'],
|
|
1158
|
+
{},
|
|
1159
|
+
{},
|
|
1160
|
+
nil,
|
|
1161
|
+
:download_dir => download_dir
|
|
1162
|
+
)
|
|
1163
|
+
end
|
|
1164
|
+
|
|
1165
|
+
assert !File.exist?(File.join(download_dir, 'curb_easy.c'))
|
|
1166
|
+
assert_equal [], Dir[File.join(download_dir, '.curb-download-*')]
|
|
1167
|
+
end
|
|
1168
|
+
end
|
|
1169
|
+
|
|
1170
|
+
def test_multi_download_safe_directory_strips_query_from_url_basename
|
|
1171
|
+
root_uri = 'http://127.0.0.1:9129/ext/'
|
|
1172
|
+
|
|
1173
|
+
Dir.mktmpdir('curb-download-') do |download_dir|
|
|
1174
|
+
Curl::Multi.download([root_uri + 'curb_easy.c?cache=1'], {}, {}, nil, :download_dir => download_dir)
|
|
1175
|
+
|
|
1176
|
+
download_path = File.join(download_dir, 'curb_easy.c')
|
|
1177
|
+
assert File.exist?(download_path)
|
|
1178
|
+
assert !File.exist?(File.join(download_dir, 'curb_easy.c?cache=1'))
|
|
1179
|
+
assert_equal File.read(File.join(File.dirname(__FILE__), '..','ext','curb_easy.c')), File.read(download_path)
|
|
1180
|
+
end
|
|
1181
|
+
end
|
|
1182
|
+
|
|
1183
|
+
def test_multi_download_hash_url_config_uses_hash_url
|
|
1184
|
+
root_uri = 'http://127.0.0.1:9129/ext/'
|
|
1185
|
+
|
|
1186
|
+
Dir.mktmpdir('curb-download-') do |download_dir|
|
|
1187
|
+
download_path = File.join(download_dir, 'curb_easy.c')
|
|
1188
|
+
|
|
1189
|
+
Curl::Multi.download([{ :url => root_uri + 'curb_easy.c', :method => :get }], {}, {}, [download_path]) do |curl, path|
|
|
1190
|
+
assert_equal 200, curl.response_code
|
|
1191
|
+
assert_equal download_path, path
|
|
1192
|
+
end
|
|
1193
|
+
|
|
1194
|
+
assert_equal File.read(File.join(File.dirname(__FILE__), '..','ext','curb_easy.c')), File.read(download_path)
|
|
1195
|
+
end
|
|
1196
|
+
end
|
|
1197
|
+
|
|
1198
|
+
def test_multi_download_duplicate_urls_use_distinct_explicit_paths
|
|
1199
|
+
url = "file://#{File.expand_path(File.join(File.dirname(__FILE__), '..','ext','curb_easy.c'))}"
|
|
1200
|
+
|
|
1201
|
+
Dir.mktmpdir('curb-download-') do |download_dir|
|
|
1202
|
+
paths = [
|
|
1203
|
+
File.join(download_dir, 'a.c'),
|
|
1204
|
+
File.join(download_dir, 'b.c')
|
|
1205
|
+
]
|
|
1206
|
+
completed_paths = []
|
|
1207
|
+
|
|
1208
|
+
Curl::Multi.download([url, url], {}, {}, paths) do |_curl, path|
|
|
1209
|
+
completed_paths << path
|
|
1210
|
+
end
|
|
1211
|
+
|
|
1212
|
+
assert_equal paths.sort, completed_paths.sort
|
|
1213
|
+
assert_equal File.read(paths[0]), File.read(paths[1])
|
|
1214
|
+
end
|
|
1215
|
+
end
|
|
1216
|
+
|
|
1217
|
+
def test_multi_download_accepts_indexed_hash_download_paths
|
|
1218
|
+
root_uri = 'http://127.0.0.1:9129/ext/'
|
|
1219
|
+
|
|
1220
|
+
Dir.mktmpdir('curb-download-') do |download_dir|
|
|
1221
|
+
download_path = File.join(download_dir, 'curb_easy.c')
|
|
1222
|
+
|
|
1223
|
+
Curl::Multi.download([root_uri + 'curb_easy.c'], {}, {}, {0 => download_path})
|
|
1224
|
+
|
|
1225
|
+
assert File.exist?(download_path)
|
|
1226
|
+
assert_equal File.read(File.join(File.dirname(__FILE__), '..','ext','curb_easy.c')), File.read(download_path)
|
|
1227
|
+
end
|
|
1228
|
+
end
|
|
1229
|
+
|
|
994
1230
|
def test_multi_easy_post_01
|
|
995
1231
|
urls = [
|
|
996
1232
|
{ :url => TestServlet.url + '?q=1', :post_fields => {'field1' => 'value1', 'k' => 'j'}},
|
|
@@ -1279,6 +1515,28 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
|
1279
1515
|
server_thread.kill if defined?(server_thread) && server_thread&.alive?
|
|
1280
1516
|
end
|
|
1281
1517
|
|
|
1518
|
+
def with_raw_http_response(response)
|
|
1519
|
+
server = TCPServer.new('127.0.0.1', 0)
|
|
1520
|
+
port = server.addr[1]
|
|
1521
|
+
thread = Thread.new do
|
|
1522
|
+
socket = server.accept
|
|
1523
|
+
begin
|
|
1524
|
+
socket.readpartial(4096)
|
|
1525
|
+
rescue EOFError
|
|
1526
|
+
end
|
|
1527
|
+
socket.write(response)
|
|
1528
|
+
socket.close
|
|
1529
|
+
end
|
|
1530
|
+
|
|
1531
|
+
yield "http://127.0.0.1:#{port}/"
|
|
1532
|
+
ensure
|
|
1533
|
+
server.close if defined?(server) && server && !server.closed?
|
|
1534
|
+
if defined?(thread) && thread
|
|
1535
|
+
thread.join(5)
|
|
1536
|
+
thread.kill if thread.alive?
|
|
1537
|
+
end
|
|
1538
|
+
end
|
|
1539
|
+
|
|
1282
1540
|
include TestServerMethods
|
|
1283
1541
|
|
|
1284
1542
|
def setup
|
|
@@ -70,6 +70,7 @@ class TestCurbCurlNativeCoverage < Test::Unit::TestCase
|
|
|
70
70
|
|
|
71
71
|
def test_clone_preserves_native_lists_after_original_handle_closes
|
|
72
72
|
easy = Curl::Easy.new("http://curb.invalid:#{TestServlet.port}#{TestServlet.path}")
|
|
73
|
+
easy.proxy_url = ""
|
|
73
74
|
easy.headers['X-Test'] = '1'
|
|
74
75
|
easy.proxy_headers['X-Proxy'] = '2'
|
|
75
76
|
easy.ftp_commands = ['PWD']
|