codders-curb 0.8.0

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