gus-curb 0.8.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.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +51 -0
  3. data/README.markdown +230 -0
  4. data/Rakefile +320 -0
  5. data/doc.rb +42 -0
  6. data/ext/curb.c +997 -0
  7. data/ext/curb.h +48 -0
  8. data/ext/curb_easy.c +3466 -0
  9. data/ext/curb_easy.h +90 -0
  10. data/ext/curb_errors.c +660 -0
  11. data/ext/curb_errors.h +132 -0
  12. data/ext/curb_macros.h +159 -0
  13. data/ext/curb_multi.c +641 -0
  14. data/ext/curb_multi.h +26 -0
  15. data/ext/curb_postfield.c +523 -0
  16. data/ext/curb_postfield.h +40 -0
  17. data/ext/curb_upload.c +80 -0
  18. data/ext/curb_upload.h +30 -0
  19. data/ext/extconf.rb +392 -0
  20. data/lib/curb.rb +1 -0
  21. data/lib/curl.rb +64 -0
  22. data/lib/curl/easy.rb +480 -0
  23. data/lib/curl/multi.rb +248 -0
  24. data/tests/alltests.rb +3 -0
  25. data/tests/bug_crash_on_debug.rb +39 -0
  26. data/tests/bug_crash_on_progress.rb +73 -0
  27. data/tests/bug_curb_easy_blocks_ruby_threads.rb +52 -0
  28. data/tests/bug_curb_easy_post_with_string_no_content_length_header.rb +83 -0
  29. data/tests/bug_instance_post_differs_from_class_post.rb +53 -0
  30. data/tests/bug_issue102.rb +17 -0
  31. data/tests/bug_multi_segfault.rb +14 -0
  32. data/tests/bug_postfields_crash.rb +26 -0
  33. data/tests/bug_postfields_crash2.rb +57 -0
  34. data/tests/bug_require_last_or_segfault.rb +40 -0
  35. data/tests/bugtests.rb +9 -0
  36. data/tests/helper.rb +204 -0
  37. data/tests/mem_check.rb +65 -0
  38. data/tests/require_last_or_segfault_script.rb +36 -0
  39. data/tests/signals.rb +33 -0
  40. data/tests/tc_curl.rb +39 -0
  41. data/tests/tc_curl_download.rb +75 -0
  42. data/tests/tc_curl_easy.rb +1038 -0
  43. data/tests/tc_curl_easy_setopt.rb +31 -0
  44. data/tests/tc_curl_multi.rb +485 -0
  45. data/tests/tc_curl_postfield.rb +143 -0
  46. data/tests/timeout.rb +100 -0
  47. data/tests/timeout_server.rb +33 -0
  48. data/tests/unittests.rb +2 -0
  49. metadata +123 -0
@@ -0,0 +1,36 @@
1
+ # From Vlad Jebelev:
2
+ #
3
+ # - if I have a require statement after "require 'curb'" and there is a
4
+ # POST with at least 1 field, the script will fail with a segmentation
5
+ # fault, e.g. the following sequence fails every time for me (Ruby 1.8.5):
6
+ # -----------------------------------------------------------------
7
+ # require 'curb'
8
+ # require 'uri'
9
+ #
10
+ # url = 'https://www.google.com/accounts/ServiceLoginAuth'
11
+ #
12
+ # c = Curl::Easy.http_post(
13
+ # 'https://www.google.com/accounts/ServiceLoginAuth',
14
+ # [Curl:: PostField.content('ltmpl','m_blanco')] ) do |curl|
15
+ # end
16
+ # ------------------------------------------------------------------
17
+ # :..dev/util$ ruby seg.rb
18
+ # seg.rb:6: [BUG] Segmentation fault
19
+ # ruby 1.8.5 (2006-08-25) [i686-linux]
20
+ #
21
+ # Aborted
22
+ # ------------------------------------------------------------------
23
+ #
24
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'ext')))
25
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
26
+ require 'curb'
27
+ require 'uri'
28
+
29
+ url = 'https://www.google.com/accounts/ServiceLoginAuth'
30
+
31
+ c = Curl::Easy.http_post('https://www.google.com/accounts/ServiceLoginAuth',
32
+ Curl:: PostField.content('ltmpl','m_blanco')) #do
33
+ # end
34
+
35
+ puts "success"
36
+
@@ -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
@@ -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
@@ -0,0 +1,75 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
+
3
+ class TestCurbCurlDownload < Test::Unit::TestCase
4
+ include TestServerMethods
5
+
6
+ def setup
7
+ server_setup
8
+ end
9
+
10
+ def test_download_url_to_file_via_string
11
+ dl_url = "http://127.0.0.1:9129/ext/curb_easy.c"
12
+ dl_path = File.join(Dir::tmpdir, "dl_url_test.file")
13
+
14
+ curb = Curl::Easy.download(dl_url, dl_path)
15
+ assert File.exist?(dl_path)
16
+ assert_equal File.read(File.join(File.dirname(__FILE__), '..','ext','curb_easy.c')), File.read(dl_path)
17
+ ensure
18
+ File.unlink(dl_path) if File.exist?(dl_path)
19
+ end
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
+
64
+ def test_download_bad_url_gives_404
65
+ dl_url = "http://127.0.0.1:9129/this_file_does_not_exist.html"
66
+ dl_path = File.join(Dir::tmpdir, "dl_url_test.file")
67
+
68
+ curb = Curl::Easy.download(dl_url, dl_path)
69
+ assert_equal Curl::Easy, curb.class
70
+ assert_equal 404, curb.response_code
71
+ ensure
72
+ File.unlink(dl_path) if File.exist?(dl_path)
73
+ end
74
+
75
+ end
@@ -0,0 +1,1038 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
+ class FooNoToS
3
+ undef to_s
4
+ end
5
+
6
+ class TestCurbCurlEasy < Test::Unit::TestCase
7
+ def test_threads
8
+ t = []
9
+ 5.times do
10
+ t << Thread.new do
11
+ 5.times do
12
+ c = Curl.get($TEST_URL)
13
+ assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body_str)
14
+ assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body)
15
+ assert_equal "", c.header_str
16
+ assert_equal "", c.head
17
+ end
18
+ end
19
+ end
20
+
21
+ t.each {|t| t.join }
22
+ end
23
+
24
+ def test_class_perform_01
25
+ assert_instance_of Curl::Easy, c = Curl::Easy.perform($TEST_URL)
26
+ assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body_str)
27
+ assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body)
28
+ assert_equal "", c.header_str
29
+ end
30
+
31
+ def test_class_perform_02
32
+ data = ""
33
+ assert_instance_of Curl::Easy, c = Curl::Easy.perform($TEST_URL) { |curl| curl.on_body { |d| data << d; d.length } }
34
+
35
+ assert_nil c.body_str
36
+ assert_equal "", c.header_str
37
+ assert_match(/^# DO NOT REMOVE THIS COMMENT/, data)
38
+ end
39
+
40
+ def test_class_perform_03
41
+ assert_raise(Curl::Err::CouldntReadError) { c = Curl::Easy.perform($TEST_URL + "nonexistent") }
42
+ end
43
+
44
+ def test_new_01
45
+ c = Curl::Easy.new
46
+ assert_equal Curl::Easy, c.class
47
+ assert_nil c.url
48
+ assert_nil c.body_str
49
+ assert_nil c.header_str
50
+ end
51
+
52
+ def test_new_02
53
+ c = Curl::Easy.new($TEST_URL)
54
+ assert_equal $TEST_URL, c.url
55
+ end
56
+
57
+ def test_new_03
58
+ blk = lambda { |i| i.length }
59
+
60
+ c = Curl::Easy.new do |curl|
61
+ curl.on_body(&blk)
62
+ end
63
+
64
+ assert_nil c.url
65
+ assert_equal blk, c.on_body # sets handler nil, returns old handler
66
+ assert_equal nil, c.on_body
67
+ end
68
+
69
+ def test_new_04
70
+ blk = lambda { |i| i.length }
71
+
72
+ c = Curl::Easy.new($TEST_URL) do |curl|
73
+ curl.on_body(&blk)
74
+ end
75
+
76
+ assert_equal $TEST_URL, c.url
77
+ assert_equal blk, c.on_body # sets handler nil, returns old handler
78
+ assert_equal nil, c.on_body
79
+ end
80
+
81
+ class Foo < Curl::Easy ; end
82
+ def test_new_05
83
+ # can use Curl::Easy as a base class
84
+ c = Foo.new
85
+ assert_equal Foo, c.class
86
+ c.url = $TEST_URL
87
+ c.perform
88
+ assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body_str)
89
+ end
90
+
91
+ # test invalid use of new
92
+ def test_new_06
93
+ Curl::Easy.new(TestServlet.url) do|curl|
94
+ curl.http_post
95
+ assert_equal "POST\n", curl.body_str
96
+ end
97
+ end
98
+
99
+ def test_escape
100
+ c = Curl::Easy.new
101
+
102
+ assert_equal "one%20two", c.escape('one two')
103
+ assert_equal "one%00two%20three", c.escape("one\000two three")
104
+ end
105
+
106
+ def test_unescape
107
+ c = Curl::Easy.new
108
+
109
+ assert_equal "one two", c.unescape('one%20two')
110
+
111
+ # prior to 7.15.4 embedded nulls cannot be unescaped
112
+ if Curl::VERNUM >= 0x070f04
113
+ assert_equal "one\000two three", c.unescape("one%00two%20three")
114
+ end
115
+ end
116
+
117
+ def test_headers
118
+ c = Curl::Easy.new($TEST_URL)
119
+
120
+ assert_equal({}, c.headers)
121
+ c.headers = "Expect:"
122
+ assert_equal "Expect:", c.headers
123
+ c.headers = ["Expect:", "User-Agent: myapp-0.0.0"]
124
+ assert_equal ["Expect:", "User-Agent: myapp-0.0.0"], c.headers
125
+ end
126
+
127
+ def test_get_01
128
+ c = Curl::Easy.new($TEST_URL)
129
+ assert_equal true, c.http_get
130
+ assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body_str)
131
+ assert_equal "", c.header_str
132
+ end
133
+
134
+ def test_get_02
135
+ data = ""
136
+ c = Curl::Easy.new($TEST_URL) do |curl|
137
+ curl.on_body { |d| data << d; d.length }
138
+ end
139
+
140
+ assert_equal true, c.http_get
141
+
142
+ assert_nil c.body_str
143
+ assert_equal "", c.header_str
144
+ assert_match(/^# DO NOT REMOVE THIS COMMENT/, data)
145
+ end
146
+
147
+ def test_get_03
148
+ c = Curl::Easy.new($TEST_URL + "nonexistent")
149
+ assert_raise(Curl::Err::CouldntReadError) { c.http_get }
150
+ assert_equal "", c.body_str
151
+ assert_equal "", c.header_str
152
+ end
153
+
154
+
155
+ def test_last_effective_url_01
156
+ c = Curl::Easy.new($TEST_URL)
157
+
158
+ assert_equal $TEST_URL, c.url
159
+ assert_nil c.last_effective_url
160
+
161
+ assert c.http_get
162
+
163
+ assert_equal c.url, c.last_effective_url
164
+ c.url = "file://some/new.url"
165
+
166
+ assert_not_equal c.last_effective_url, c.url
167
+ end
168
+
169
+ def test_http_get_block
170
+ curl = Curl::Easy.http_get(TestServlet.url) do|c|
171
+ c.follow_location = true
172
+ c.max_redirects = 3
173
+ end
174
+ assert_equal curl.url, curl.last_effective_url
175
+ assert_equal 'GET', curl.body_str
176
+ end
177
+
178
+ def test_local_port_01
179
+ c = Curl::Easy.new($TEST_URL)
180
+
181
+ assert_nil c.local_port
182
+ assert_nil c.local_port_range
183
+ assert_nil c.proxy_port
184
+
185
+ c.local_port = 88
186
+
187
+ assert_equal 88, c.local_port
188
+ assert_nil c.local_port_range
189
+ assert_nil c.proxy_port
190
+
191
+ c.local_port = nil
192
+
193
+ assert_nil c.local_port
194
+ assert_nil c.local_port_range
195
+ assert_nil c.proxy_port
196
+ end
197
+
198
+ def test_local_port_02
199
+ c = Curl::Easy.new($TEST_URL)
200
+
201
+ assert_nil c.local_port
202
+ assert_raise(ArgumentError) { c.local_port = 0 }
203
+ assert_raise(ArgumentError) { c.local_port = 65536 }
204
+ assert_raise(ArgumentError) { c.local_port = -1 }
205
+ end
206
+
207
+ def test_local_port_range_01
208
+ c = Curl::Easy.new($TEST_URL)
209
+
210
+ assert_nil c.local_port_range
211
+ assert_nil c.local_port
212
+ assert_nil c.proxy_port
213
+
214
+ c.local_port_range = 88
215
+ assert_equal 88, c.local_port_range
216
+ assert_nil c.local_port
217
+ assert_nil c.proxy_port
218
+
219
+ c.local_port_range = nil
220
+
221
+ assert_nil c.local_port_range
222
+ assert_nil c.local_port
223
+ assert_nil c.proxy_port
224
+ end
225
+
226
+ def test_local_port_range_02
227
+ c = Curl::Easy.new($TEST_URL)
228
+
229
+ assert_nil c.local_port_range
230
+ assert_raise(ArgumentError) { c.local_port_range = 0 }
231
+ assert_raise(ArgumentError) { c.local_port_range = 65536 }
232
+ assert_raise(ArgumentError) { c.local_port_range = -1 }
233
+ end
234
+
235
+ def test_proxy_url_01
236
+ c = Curl::Easy.new($TEST_URL)
237
+
238
+ assert_equal $TEST_URL, c.url
239
+ assert_nil c.proxy_url
240
+
241
+ c.proxy_url = "http://some.proxy"
242
+
243
+ assert_equal $TEST_URL, c.url
244
+ assert_equal "http://some.proxy", c.proxy_url
245
+
246
+ c.proxy_url = nil
247
+ assert_equal $TEST_URL, c.url
248
+ assert_nil c.proxy_url
249
+ end
250
+
251
+ def test_proxy_port_01
252
+ c = Curl::Easy.new($TEST_URL)
253
+
254
+ assert_nil c.local_port
255
+ assert_nil c.local_port_range
256
+ assert_nil c.proxy_port
257
+
258
+ c.proxy_port = 88
259
+
260
+ assert_equal 88, c.proxy_port
261
+ assert_nil c.local_port
262
+ assert_nil c.local_port_range
263
+
264
+ c.proxy_port = nil
265
+ assert_nil c.proxy_port
266
+ assert_nil c.local_port
267
+ assert_nil c.local_port_range
268
+ end
269
+
270
+ def test_proxy_port_02
271
+ c = Curl::Easy.new($TEST_URL)
272
+
273
+ assert_nil c.proxy_port
274
+ assert_raise(ArgumentError) { c.proxy_port = 0 }
275
+ assert_raise(ArgumentError) { c.proxy_port = 65536 }
276
+ assert_raise(ArgumentError) { c.proxy_port = -1 }
277
+ end
278
+
279
+ def test_proxy_type_01
280
+ c = Curl::Easy.new($TEST_URL)
281
+
282
+ assert_nil c.proxy_type
283
+
284
+ c.proxy_type = 3
285
+ assert_equal 3, c.proxy_type
286
+
287
+ c.proxy_type = nil
288
+ assert_nil c.proxy_type
289
+ end
290
+
291
+ def test_http_auth_types_01
292
+ c = Curl::Easy.new($TEST_URL)
293
+
294
+ assert_nil c.http_auth_types
295
+
296
+ c.http_auth_types = 3
297
+ assert_equal 3, c.http_auth_types
298
+
299
+ c.http_auth_types = nil
300
+ assert_nil c.http_auth_types
301
+ end
302
+
303
+ def test_proxy_auth_types_01
304
+ c = Curl::Easy.new($TEST_URL)
305
+
306
+ assert_nil c.proxy_auth_types
307
+
308
+ c.proxy_auth_types = 3
309
+ assert_equal 3, c.proxy_auth_types
310
+
311
+ c.proxy_auth_types = nil
312
+ assert_nil c.proxy_auth_types
313
+ end
314
+
315
+ def test_max_redirects_01
316
+ c = Curl::Easy.new($TEST_URL)
317
+
318
+ assert_nil c.max_redirects
319
+
320
+ c.max_redirects = 3
321
+ assert_equal 3, c.max_redirects
322
+
323
+ c.max_redirects = nil
324
+ assert_nil c.max_redirects
325
+ end
326
+
327
+ def test_timeout_01
328
+ c = Curl::Easy.new($TEST_URL)
329
+
330
+ assert_nil c.timeout
331
+
332
+ c.timeout = 3
333
+ assert_equal 3, c.timeout
334
+
335
+ c.timeout = nil
336
+ assert_nil c.timeout
337
+ end
338
+
339
+ def test_connect_timeout_01
340
+ c = Curl::Easy.new($TEST_URL)
341
+
342
+ assert_nil c.connect_timeout
343
+
344
+ c.connect_timeout = 3
345
+ assert_equal 3, c.connect_timeout
346
+
347
+ c.connect_timeout = nil
348
+ assert_nil c.connect_timeout
349
+ end
350
+
351
+ def test_ftp_response_timeout_01
352
+ c = Curl::Easy.new($TEST_URL)
353
+
354
+ assert_nil c.ftp_response_timeout
355
+
356
+ c.ftp_response_timeout = 3
357
+ assert_equal 3, c.ftp_response_timeout
358
+
359
+ c.ftp_response_timeout = nil
360
+ assert_nil c.ftp_response_timeout
361
+ end
362
+
363
+ def test_dns_cache_timeout_01
364
+ c = Curl::Easy.new($TEST_URL)
365
+
366
+ assert_equal 60, c.dns_cache_timeout
367
+
368
+ c.dns_cache_timeout = nil
369
+ assert_nil c.dns_cache_timeout
370
+
371
+ c.dns_cache_timeout = 30
372
+ assert_equal 30, c.dns_cache_timeout
373
+ end
374
+
375
+ def test_low_speed_limit_01
376
+ c = Curl::Easy.new($TEST_URL)
377
+
378
+ assert_nil c.low_speed_limit
379
+
380
+ c.low_speed_limit = 3
381
+ assert_equal 3, c.low_speed_limit
382
+
383
+ c.low_speed_limit = nil
384
+ assert_nil c.low_speed_limit
385
+ end
386
+
387
+ def test_low_speed_time_01
388
+ c = Curl::Easy.new($TEST_URL)
389
+
390
+ assert_nil c.low_speed_time
391
+
392
+ c.low_speed_time = 3
393
+ assert_equal 3, c.low_speed_time
394
+
395
+ c.low_speed_time = nil
396
+ assert_nil c.low_speed_time
397
+ end
398
+
399
+ def test_on_body
400
+ blk = lambda { |i| i.length }
401
+
402
+ c = Curl::Easy.new
403
+ c.on_body(&blk)
404
+
405
+ assert_equal blk, c.on_body # sets handler nil, returns old handler
406
+ assert_equal nil, c.on_body
407
+ end
408
+
409
+ def test_inspect_with_no_url
410
+ c = Curl::Easy.new
411
+ assert_equal '#<Curl::Easy>', c.inspect
412
+ end
413
+
414
+ def test_inspect_with_short_url
415
+ c = Curl::Easy.new('http://www.google.com/')
416
+ assert_equal "#<Curl::Easy http://www.google.com/>", c.inspect
417
+ end
418
+
419
+ def test_inspect_truncates_to_64_chars
420
+ base_url = 'http://www.google.com/'
421
+ truncated_url = base_url + 'x' * (64 - '#<Curl::Easy >'.size - base_url.size)
422
+ long_url = truncated_url + 'yyyy'
423
+ c = Curl::Easy.new(long_url)
424
+ assert_equal 64, c.inspect.size
425
+ assert_equal "#<Curl::Easy #{truncated_url}>", c.inspect
426
+ end
427
+
428
+ def test_on_header
429
+ blk = lambda { |i| i.length }
430
+
431
+ c = Curl::Easy.new
432
+ c.on_header(&blk)
433
+
434
+ assert_equal blk, c.on_header # sets handler nil, returns old handler
435
+ assert_equal nil, c.on_header
436
+ end
437
+
438
+ def test_on_progress
439
+ blk = lambda { |*args| true }
440
+
441
+ c = Curl::Easy.new
442
+ c.on_progress(&blk)
443
+
444
+ assert_equal blk, c.on_progress # sets handler nil, returns old handler
445
+ assert_equal nil, c.on_progress
446
+ end
447
+
448
+ def test_on_debug
449
+ blk = lambda { |*args| true }
450
+
451
+ c = Curl::Easy.new
452
+ c.on_debug(&blk)
453
+
454
+ assert_equal blk, c.on_debug # sets handler nil, returns old handler
455
+ assert_equal nil, c.on_debug
456
+ end
457
+
458
+ def test_proxy_tunnel
459
+ c = Curl::Easy.new
460
+ assert !c.proxy_tunnel?
461
+ assert c.proxy_tunnel = true
462
+ assert c.proxy_tunnel?
463
+ end
464
+
465
+ def test_fetch_file_time
466
+ c = Curl::Easy.new
467
+ assert !c.fetch_file_time?
468
+ assert c.fetch_file_time = true
469
+ assert c.fetch_file_time?
470
+ end
471
+
472
+ def test_ssl_verify_peer
473
+ c = Curl::Easy.new
474
+ assert c.ssl_verify_peer?
475
+ assert !c.ssl_verify_peer = false
476
+ assert !c.ssl_verify_peer?
477
+ end
478
+
479
+ def test_ssl_verify_host
480
+ c = Curl::Easy.new
481
+ assert c.ssl_verify_host?
482
+ c.ssl_verify_host = 0
483
+ c.ssl_verify_host = false
484
+ assert !c.ssl_verify_host?
485
+ end
486
+
487
+ def test_header_in_body
488
+ c = Curl::Easy.new
489
+ assert !c.header_in_body?
490
+ assert c.header_in_body = true
491
+ assert c.header_in_body?
492
+ end
493
+
494
+ def test_use_netrc
495
+ c = Curl::Easy.new
496
+ assert !c.use_netrc?
497
+ assert c.use_netrc = true
498
+ assert c.use_netrc?
499
+ end
500
+
501
+ def test_follow_location
502
+ c = Curl::Easy.new
503
+ assert !c.follow_location?
504
+ assert c.follow_location = true
505
+ assert c.follow_location?
506
+ end
507
+
508
+ def test_unrestricted_auth
509
+ c = Curl::Easy.new
510
+ assert !c.unrestricted_auth?
511
+ assert c.unrestricted_auth = true
512
+ assert c.unrestricted_auth?
513
+ end
514
+
515
+ def test_multipart_form_post
516
+ c = Curl::Easy.new
517
+ assert !c.multipart_form_post?
518
+ assert c.multipart_form_post = true
519
+ assert c.multipart_form_post?
520
+ end
521
+
522
+ def test_ignore_content_length
523
+ c = Curl::Easy.new
524
+ assert !c.ignore_content_length?
525
+ assert c.ignore_content_length = true
526
+ assert c.ignore_content_length?
527
+ end
528
+
529
+ def test_resolve_mode
530
+ c = Curl::Easy.new
531
+ assert_equal :auto, c.resolve_mode
532
+ c.resolve_mode = :ipv4
533
+ assert_equal :ipv4, c.resolve_mode
534
+ c.resolve_mode = :ipv6
535
+ assert_equal :ipv6, c.resolve_mode
536
+
537
+ assert_raises(ArgumentError) { c.resolve_mode = :bad }
538
+ end
539
+
540
+ def test_enable_cookies
541
+ c = Curl::Easy.new
542
+ assert !c.enable_cookies?
543
+ assert c.enable_cookies = true
544
+ assert c.enable_cookies?
545
+ end
546
+
547
+ def test_cookies_option
548
+ c = Curl::Easy.new
549
+ assert_nil c.cookies
550
+ assert_equal "name1=content1; name2=content2;", c.cookies = "name1=content1; name2=content2;"
551
+ assert_equal "name1=content1; name2=content2;", c.cookies
552
+ end
553
+
554
+ def test_cookiefile
555
+ c = Curl::Easy.new
556
+ assert_nil c.cookiefile
557
+ assert_equal "some.file", c.cookiefile = "some.file"
558
+ assert_equal "some.file", c.cookiefile
559
+ end
560
+
561
+ def test_cookiejar
562
+ c = Curl::Easy.new
563
+ assert_nil c.cookiejar
564
+ assert_equal "some.file", c.cookiejar = "some.file"
565
+ assert_equal "some.file", c.cookiejar
566
+ end
567
+
568
+ def test_on_success
569
+ curl = Curl::Easy.new($TEST_URL)
570
+ on_success_called = false
571
+ curl.on_success {|c|
572
+ on_success_called = true
573
+ assert_not_nil c.body_str
574
+ assert_equal "", c.header_str
575
+ assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body_str)
576
+ }
577
+ curl.perform
578
+ assert on_success_called, "Success handler not called"
579
+ end
580
+
581
+ def test_on_success_with_on_failure
582
+ curl = Curl::Easy.new(TestServlet.url + '/error')
583
+ on_failure_called = false
584
+ curl.on_success {|c| } # make sure we get the failure call even though this handler is defined
585
+ curl.on_failure {|c,code| on_failure_called = true }
586
+ curl.perform
587
+ assert_equal 500, curl.response_code
588
+ assert on_failure_called, "Failure handler not called"
589
+ end
590
+
591
+ def test_on_success_with_on_missing
592
+ curl = Curl::Easy.new(TestServlet.url + '/not_here')
593
+ on_missing_called = false
594
+ curl.on_success {|c| } # make sure we get the missing call even though this handler is defined
595
+ curl.on_missing {|c,code| on_missing_called = true }
596
+ curl.perform
597
+ assert_equal 404, curl.response_code
598
+ assert on_missing_called, "Missing handler not called"
599
+ end
600
+
601
+ def test_on_success_with_on_redirect
602
+ curl = Curl::Easy.new(TestServlet.url + '/redirect')
603
+ on_redirect_called = false
604
+ curl.on_success {|c| } # make sure we get the redirect call even though this handler is defined
605
+ curl.on_redirect {|c,code| on_redirect_called = true }
606
+ curl.perform
607
+ assert_equal 302, curl.response_code
608
+ assert on_redirect_called, "Redirect handler not called"
609
+ end
610
+
611
+ def test_get_remote
612
+ curl = Curl::Easy.new(TestServlet.url)
613
+ curl.http_get
614
+ assert_equal 'GET', curl.body_str
615
+ end
616
+
617
+ def test_post_remote
618
+ curl = Curl::Easy.new(TestServlet.url)
619
+ curl.http_post([Curl::PostField.content('document_id', 5)])
620
+ assert_equal "POST\ndocument_id=5", curl.unescape(curl.body_str)
621
+ end
622
+
623
+ def test_post_remote_is_easy_handle
624
+ # see: http://pastie.org/560852 and
625
+ # http://groups.google.com/group/curb---ruby-libcurl-bindings/browse_thread/thread/216bb2d9b037f347?hl=en
626
+ [:post, :get, :head, :delete].each do |method|
627
+ retries = 0
628
+ begin
629
+ count = 0
630
+ curl = Curl::Easy.send("http_#{method}", TestServlet.url) do|c|
631
+ count += 1
632
+ assert_equal Curl::Easy, c.class
633
+ end
634
+ assert_equal 1, count, "For request method: #{method.to_s.upcase}"
635
+ rescue Curl::Err::HostResolutionError => e # travis-ci.org fails to resolve... try again?
636
+ retries+=1
637
+ retry if retries < 3
638
+ raise e
639
+ end
640
+ end
641
+ end
642
+
643
+ # see: https://github.com/rvanlieshout/curb/commit/8bcdefddc0162484681ebd1a92d52a642666a445
644
+ def test_post_multipart_array_remote
645
+ curl = Curl::Easy.new(TestServlet.url)
646
+ curl.multipart_form_post = true
647
+ fields = [
648
+ Curl::PostField.file('foo', File.expand_path(File.join(File.dirname(__FILE__),'..','README.markdown'))),
649
+ Curl::PostField.file('bar', File.expand_path(File.join(File.dirname(__FILE__),'..','README.markdown')))
650
+ ]
651
+ curl.http_post(fields)
652
+ assert_match /HTTP POST file upload/, curl.body_str
653
+ assert_match /Content-Disposition: form-data/, curl.body_str
654
+ end
655
+
656
+ def test_post_with_body_remote
657
+ curl = Curl::Easy.new(TestServlet.url)
658
+ curl.post_body = 'foo=bar&encoded%20string=val'
659
+
660
+ curl.perform
661
+
662
+ assert_equal "POST\nfoo=bar&encoded%20string=val", curl.body_str
663
+ assert_equal 'foo=bar&encoded%20string=val', curl.post_body
664
+ end
665
+
666
+ def test_form_post_body_remote
667
+ curl = Curl::Easy.new(TestServlet.url)
668
+ curl.http_post('foo=bar', 'encoded%20string=val')
669
+
670
+ assert_equal "POST\nfoo=bar&encoded%20string=val", curl.body_str
671
+ assert_equal 'foo=bar&encoded%20string=val', curl.post_body
672
+ end
673
+
674
+ def test_post_multipart_file_remote
675
+ curl = Curl::Easy.new(TestServlet.url)
676
+ curl.multipart_form_post = true
677
+ pf = Curl::PostField.file('readme', File.expand_path(File.join(File.dirname(__FILE__),'..','README.markdown')))
678
+ curl.http_post(pf)
679
+ assert_match /HTTP POST file upload/, curl.body_str
680
+ assert_match /Content-Disposition: form-data/, curl.body_str
681
+ end
682
+
683
+ def test_delete_remote
684
+ curl = Curl::Easy.new(TestServlet.url)
685
+ curl.http_delete
686
+ assert_equal 'DELETE', curl.body_str
687
+ end
688
+
689
+ def test_arbitrary_http_verb
690
+ curl = Curl::Easy.new(TestServlet.url)
691
+ curl.http('PURGE')
692
+ assert_equal 'PURGE', curl.body_str
693
+ end
694
+
695
+ def test_head_remote
696
+ curl = Curl::Easy.new(TestServlet.url)
697
+ curl.http_head
698
+
699
+ redirect = curl.header_str.match(/Location: (.*)/)
700
+
701
+ assert_equal '', curl.body_str
702
+ assert_match '/nonexistent', redirect[1]
703
+ end
704
+
705
+ def test_head_accessor
706
+ curl = Curl::Easy.new(TestServlet.url)
707
+ curl.head = true
708
+ curl.perform
709
+
710
+ redirect = curl.header_str.match(/Location: (.*)/)
711
+
712
+ assert_equal '', curl.body_str
713
+ assert_match '/nonexistent', redirect[1]
714
+ curl.head = false
715
+ curl.perform
716
+ assert_equal 'GET', curl.body_str
717
+ end
718
+
719
+ def test_put_remote
720
+ curl = Curl::Easy.new(TestServlet.url)
721
+ curl.headers['Content-Type'] = 'application/json'
722
+ assert curl.http_put("message")
723
+ assert_match /^PUT/, curl.body_str
724
+ assert_match /message$/, curl.body_str
725
+ assert_match /message$/, curl.body
726
+ assert_match /application\/json/, curl.header_str
727
+ assert_match /application\/json/, curl.head
728
+ end
729
+
730
+ def test_put_data
731
+ curl = Curl::Easy.new(TestServlet.url)
732
+ curl.put_data = 'message'
733
+
734
+ curl.perform
735
+
736
+ assert_match /^PUT/, curl.body_str
737
+ assert_match /message$/, curl.body_str
738
+ end
739
+
740
+ # https://github.com/taf2/curb/issues/101
741
+ def test_put_data_null_bytes
742
+ curl = Curl::Easy.new(TestServlet.url)
743
+ curl.put_data = "a\0b"
744
+
745
+ curl.perform
746
+
747
+ assert_match /^PUT/, curl.body_str
748
+ assert_match "a\0b", curl.body_str
749
+ end
750
+
751
+ def test_put_nil_data_no_crash
752
+ curl = Curl::Easy.new(TestServlet.url)
753
+ curl.put_data = nil
754
+
755
+ curl.perform
756
+ end
757
+
758
+ def test_put_remote_file
759
+ curl = Curl::Easy.new(TestServlet.url)
760
+ File.open(__FILE__,'rb') do|f|
761
+ assert curl.http_put(f)
762
+ end
763
+ assert_equal "PUT\n#{File.read(__FILE__)}", curl.body_str
764
+ end
765
+
766
+ def test_put_class_method
767
+ count = 0
768
+ curl = Curl::Easy.http_put(TestServlet.url,File.open(__FILE__,'rb')) do|c|
769
+ count += 1
770
+ assert_equal Curl::Easy, c.class
771
+ end
772
+ assert_equal 1, count
773
+ assert_equal "PUT\n#{File.read(__FILE__)}", curl.body_str
774
+ end
775
+
776
+ # Generate a self-signed cert with
777
+ # openssl req -new -newkey rsa:1024 -days 365 -nodes -x509 \
778
+ # -keyout tests/cert.pem -out tests/cert.pem
779
+ def test_cert
780
+ curl = Curl::Easy.new(TestServlet.url)
781
+ curl.cert= File.join(File.dirname(__FILE__),"cert.pem")
782
+ assert_match /cert.pem$/,curl.cert
783
+ end
784
+
785
+ def test_cert_with_password
786
+ curl = Curl::Easy.new(TestServlet.url)
787
+ path = File.join(File.dirname(__FILE__),"cert.pem")
788
+ curl.certpassword = 'password'
789
+ curl.cert = path
790
+ assert_match /cert.pem$/,curl.cert
791
+ end
792
+
793
+ def test_cert_type
794
+ curl = Curl::Easy.new(TestServlet.url)
795
+ curl.certtype= "DER"
796
+ assert_equal "DER", curl.certtype
797
+ end
798
+
799
+ def test_default_certtype
800
+ curl = Curl::Easy.new(TestServlet.url)
801
+ assert_nil curl.certtype
802
+ curl.certtype = "PEM"
803
+ assert_equal "PEM", curl.certtype
804
+ end
805
+
806
+ # Generate a CA cert with instructions at
807
+ # http://technocage.com/~caskey/openssl/
808
+ def test_ca_cert
809
+ curl = Curl::Easy.new(TestServlet.url)
810
+ curl.cacert= File.join(File.dirname(__FILE__),"cacert.pem")
811
+ assert_match /cacert.pem$/, curl.cacert
812
+ end
813
+
814
+ def test_user_agent
815
+ curl = Curl::Easy.new(TestServlet.url)
816
+ curl.useragent= "Curb-Easy/Ruby"
817
+ assert_equal "Curb-Easy/Ruby",curl.useragent
818
+ end
819
+
820
+ def test_username_password
821
+ curl = Curl::Easy.new(TestServlet.url)
822
+ curl.username = "foo"
823
+ curl.password = "bar"
824
+ if !curl.username.nil?
825
+ assert_equal "foo", curl.username
826
+ assert_equal "bar", curl.password
827
+ else
828
+ curl.userpwd = "foo:bar"
829
+ end
830
+ curl.http_auth_types = :basic
831
+ #curl.verbose = true
832
+ curl.perform
833
+ assert_equal 'Basic Zm9vOmJhcg==', $auth_header
834
+ $auth_header = nil
835
+ # curl checks the auth type supported by the server, so we have to create a
836
+ # new easy handle if we're going to change the auth type...
837
+
838
+ curl = Curl::Easy.new(TestServlet.url)
839
+ curl.username = "foo"
840
+ curl.password = "bar"
841
+ if curl.username.nil?
842
+ curl.userpwd = "foo:bar"
843
+ end
844
+ curl.http_auth_types = :ntlm
845
+ curl.perform
846
+ assert_equal 'NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=', $auth_header
847
+ end
848
+
849
+ def test_primary_ip
850
+ curl = Curl::Easy.new(TestServlet.url)
851
+ if curl.respond_to?(:primary_ip)
852
+ curl.perform
853
+ assert_equal '127.0.0.1', curl.primary_ip
854
+ end
855
+ end
856
+
857
+ def test_post_streaming
858
+ readme = File.expand_path(File.join(File.dirname(__FILE__),'..','README.markdown'))
859
+
860
+ pf = Curl::PostField.file("filename", readme)
861
+
862
+ easy = Curl::Easy.new
863
+
864
+ easy.url = TestServlet.url
865
+ easy.multipart_form_post = true
866
+ easy.http_post(pf)
867
+
868
+ assert_not_equal(0,easy.body_str.size)
869
+ assert_equal(easy.body_str,File.read(readme))
870
+ end
871
+
872
+
873
+ def test_easy_close
874
+ easy = Curl::Easy.new
875
+ easy.close
876
+ easy.url = TestServlet.url
877
+ easy.http_get
878
+ end
879
+
880
+ def test_easy_reset
881
+ easy = Curl::Easy.new
882
+ easy.url = TestServlet.url + "?query=foo"
883
+ easy.http_get
884
+ settings = easy.reset
885
+ assert settings.key?(:url)
886
+ assert settings.key?(:body_data)
887
+ assert settings.key?(:header_data)
888
+ easy.url = TestServlet.url
889
+ easy.http_get
890
+ end
891
+
892
+ def test_easy_use_http_versions
893
+ easy = Curl::Easy.new
894
+ easy.url = TestServlet.url + "?query=foo"
895
+ #puts "http none: #{Curl::HTTP_NONE.inspect}"
896
+ #puts "http1.0: #{Curl::HTTP_1_0.inspect}"
897
+ #puts "http1.1: #{Curl::HTTP_1_1.inspect}"
898
+ easy.version = Curl::HTTP_1_1
899
+ #easy.verbose = true
900
+ easy.http_get
901
+ end
902
+
903
+ def test_easy_http_verbs
904
+ curl = Curl::Easy.new(TestServlet.url)
905
+ curl.http_delete
906
+ assert_equal 'DELETE', curl.body_str
907
+ curl.http_get
908
+ assert_equal 'GET', curl.body_str
909
+ curl.http_post
910
+ assert_equal "POST\n", curl.body_str
911
+ curl.http('PURGE')
912
+ assert_equal 'PURGE', curl.body_str
913
+ curl.http_put('hello')
914
+ assert_equal "PUT\nhello", curl.body_str
915
+ curl.http('COPY')
916
+ assert_equal 'COPY', curl.body_str
917
+ end
918
+
919
+ def test_easy_http_verbs_must_respond_to_str
920
+ # issue http://github.com/taf2/curb/issues#issue/45
921
+ assert_nothing_raised do
922
+ c = Curl::Easy.new ; c.url = 'http://example.com' ; c.http(:get)
923
+ end
924
+
925
+ assert_raise RuntimeError do
926
+ c = Curl::Easy.new ; c.url = 'http://example.com' ; c.http(FooNoToS.new)
927
+ end
928
+
929
+ end
930
+
931
+ # http://github.com/taf2/curb/issues/#issue/33
932
+ def test_easy_http_verbs_with_errors
933
+ curl = Curl::Easy.new("http://127.0.0.1:9012/") # test will fail if http server on port 9012
934
+ assert_raise Curl::Err::ConnectionFailedError do
935
+ curl.http_delete
936
+ end
937
+ curl.url = TestServlet.url
938
+ curl.http_get
939
+ assert_equal 'GET', curl.body_str
940
+ end
941
+
942
+ def test_easy_can_put_with_content_length
943
+ curl = Curl::Easy.new(TestServlet.url)
944
+ rd, wr = IO.pipe
945
+ buf = (("hello")* (1000 / 5))
946
+
947
+ producer = Thread.new do
948
+ 5.times do
949
+ wr << buf
950
+ sleep 0.1 # act as a slow producer
951
+ end
952
+ end
953
+
954
+ consumer = Thread.new do
955
+
956
+ #curl.verbose = true
957
+ curl.headers['Content-Length'] = buf.size * 5
958
+ curl.headers['User-Agent'] = "Something else"
959
+ curl.headers['Content-Type'] = "text/javascript"
960
+ curl.headers['Date'] = Time.now.httpdate
961
+ curl.headers['Host'] = 's3.amazonaws.com'
962
+ curl.headers['Accept'] = '*/*'
963
+ curl.headers['Authorization'] = 'Foo Bar Biz Baz'
964
+ curl.http_put(rd)
965
+ assert_match /^PUT/, curl.body_str
966
+ assert_match /hello$/, curl.body_str
967
+ curl.header_str
968
+ curl.body_str
969
+ end
970
+
971
+ producer.join
972
+ wr.close
973
+ consumer.join
974
+
975
+ end
976
+
977
+ def test_get_set_multi_on_easy
978
+ easy = Curl::Easy.new
979
+ assert_nil easy.multi
980
+ multi = Curl::Multi.new
981
+ easy.multi = multi
982
+ assert_not_nil easy.multi
983
+ assert_equal multi, easy.multi
984
+ end
985
+
986
+ def test_raise_on_progress
987
+ c = Curl::Easy.new($TEST_URL)
988
+ c.on_progress {|w,x,y,z| raise "error" }
989
+ c.perform
990
+ rescue => e
991
+ assert_equal 'Curl::Err::AbortedByCallbackError', e.class.to_s
992
+ c.close
993
+ end
994
+
995
+ def test_raise_on_success
996
+ c = Curl::Easy.new($TEST_URL)
997
+ c.on_success {|x| raise "error" }
998
+ c.perform
999
+ rescue => e
1000
+ assert_equal 'Curl::Err::AbortedByCallbackError', e.class.to_s
1001
+ c.close
1002
+ end
1003
+
1004
+ def test_raise_on_debug
1005
+ c = Curl::Easy.new($TEST_URL)
1006
+ c.on_debug { raise "error" }
1007
+ c.perform
1008
+ assert true, "raise in on debug has no effect"
1009
+ end
1010
+
1011
+ def test_status_codes
1012
+ curl = Curl::Easy.new(TestServlet.url)
1013
+ curl.perform
1014
+ assert_equal '200 OK', curl.status
1015
+ end
1016
+
1017
+ def test_close_in_on_callbacks
1018
+ curl = Curl::Easy.new(TestServlet.url)
1019
+ curl.on_body {|d| curl.close; d.size }
1020
+ assert_raises RuntimeError do
1021
+ curl.perform
1022
+ end
1023
+ end
1024
+
1025
+ def test_set_unsupported_options
1026
+ curl = Curl::Easy.new
1027
+ assert_raises TypeError do
1028
+ curl.set(99999, 1)
1029
+ end
1030
+ end
1031
+
1032
+ include TestServerMethods
1033
+
1034
+ def setup
1035
+ server_setup
1036
+ end
1037
+
1038
+ end