curb 0.9.3 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.markdown +76 -21
- data/Rakefile +33 -20
- data/ext/banned.h +32 -0
- data/ext/curb.c +186 -14
- data/ext/curb.h +18 -5
- data/ext/curb_easy.c +493 -84
- data/ext/curb_easy.h +7 -0
- data/ext/curb_errors.c +86 -0
- data/ext/curb_multi.c +141 -218
- data/ext/curb_multi.h +0 -1
- data/ext/curb_postfield.c +7 -7
- data/ext/extconf.rb +74 -6
- data/lib/curb.rb +1 -0
- data/lib/curl/easy.rb +16 -9
- data/lib/curl/multi.rb +52 -13
- data/lib/curl.rb +20 -12
- data/tests/bug_issue277.rb +32 -0
- data/tests/helper.rb +96 -13
- data/tests/tc_curl.rb +31 -1
- data/tests/tc_curl_download.rb +3 -3
- data/tests/tc_curl_easy.rb +163 -42
- data/tests/tc_curl_easy_resolve.rb +16 -0
- data/tests/tc_curl_maxfilesize.rb +12 -0
- data/tests/tc_curl_multi.rb +118 -15
- data/tests/tc_curl_postfield.rb +29 -29
- data/tests/tc_curl_protocols.rb +37 -0
- data/tests/timeout.rb +21 -5
- metadata +33 -25
data/tests/tc_curl_download.rb
CHANGED
@@ -11,7 +11,7 @@ class TestCurbCurlDownload < Test::Unit::TestCase
|
|
11
11
|
dl_url = "http://127.0.0.1:9129/ext/curb_easy.c"
|
12
12
|
dl_path = File.join(Dir::tmpdir, "dl_url_test.file")
|
13
13
|
|
14
|
-
|
14
|
+
Curl::Easy.download(dl_url, dl_path)
|
15
15
|
assert File.exist?(dl_path)
|
16
16
|
assert_equal File.read(File.join(File.dirname(__FILE__), '..','ext','curb_easy.c')), File.read(dl_path)
|
17
17
|
ensure
|
@@ -23,7 +23,7 @@ class TestCurbCurlDownload < Test::Unit::TestCase
|
|
23
23
|
dl_path = File.join(Dir::tmpdir, "dl_url_test.file")
|
24
24
|
io = File.open(dl_path, 'wb')
|
25
25
|
|
26
|
-
|
26
|
+
Curl::Easy.download(dl_url, io)
|
27
27
|
assert io.closed?
|
28
28
|
assert File.exist?(dl_path)
|
29
29
|
assert_equal File.read(File.join(File.dirname(__FILE__), '..','ext','curb_easy.c')), File.read(dl_path)
|
@@ -49,7 +49,7 @@ class TestCurbCurlDownload < Test::Unit::TestCase
|
|
49
49
|
# Download remote source
|
50
50
|
begin
|
51
51
|
reader.close
|
52
|
-
|
52
|
+
Curl::Easy.download(dl_url, writer)
|
53
53
|
Process.wait
|
54
54
|
ensure
|
55
55
|
writer.close rescue IOError # if the stream has already been closed, which occurs in Easy::download
|
data/tests/tc_curl_easy.rb
CHANGED
@@ -5,11 +5,89 @@ end
|
|
5
5
|
|
6
6
|
class TestCurbCurlEasy < Test::Unit::TestCase
|
7
7
|
def test_global_reset
|
8
|
-
|
8
|
+
Curl.get($TEST_URL)
|
9
9
|
# in a Timeout block you should reset the thread current handle
|
10
10
|
Curl.reset
|
11
11
|
end
|
12
12
|
|
13
|
+
def test_nested_easy_methods
|
14
|
+
easy = Curl.get(TestServlet.url) {|http|
|
15
|
+
res = Curl.get(TestServlet.url + '/not_here')
|
16
|
+
assert_equal 404, res.response_code
|
17
|
+
}
|
18
|
+
assert_equal 200, easy.response_code
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_curlopt_stderr_with_file
|
22
|
+
# does not work with Tempfile directly
|
23
|
+
path = Tempfile.new('curb_test_curlopt_stderr').path
|
24
|
+
File.open(path, 'w') do |file|
|
25
|
+
easy = Curl::Easy.new(TestServlet.url)
|
26
|
+
easy.verbose = true
|
27
|
+
easy.setopt(Curl::CURLOPT_STDERR, file)
|
28
|
+
easy.perform
|
29
|
+
end
|
30
|
+
output = File.read(path)
|
31
|
+
|
32
|
+
assert_match(/HTTP\/1\.1\ 200\ OK(?:\ )?/, output)
|
33
|
+
assert_match('Host: 127.0.0.1:9129', output)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_curlopt_stderr_with_io
|
37
|
+
path = Tempfile.new('curb_test_curlopt_stderr').path
|
38
|
+
fd = IO.sysopen(path, 'w')
|
39
|
+
io = IO.for_fd(fd)
|
40
|
+
|
41
|
+
easy = Curl::Easy.new(TestServlet.url)
|
42
|
+
easy.verbose = true
|
43
|
+
easy.setopt(Curl::CURLOPT_STDERR, io)
|
44
|
+
easy.perform
|
45
|
+
|
46
|
+
|
47
|
+
output = File.read(path)
|
48
|
+
|
49
|
+
assert_match(output, 'HTTP/1.1 200 OK')
|
50
|
+
assert_match(output, 'Host: 127.0.0.1:9129')
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_curlopt_stderr_fails_with_tempdir
|
54
|
+
Tempfile.open('curb_test_curlopt_stderr') do |tempfile|
|
55
|
+
easy = Curl::Easy.new(TestServlet.url)
|
56
|
+
|
57
|
+
assert_raise(TypeError) do
|
58
|
+
easy.setopt(Curl::CURLOPT_STDERR, tempfile)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_curlopt_stderr_fails_with_stringio
|
64
|
+
stringio = StringIO.new
|
65
|
+
easy = Curl::Easy.new(TestServlet.url)
|
66
|
+
|
67
|
+
assert_raise(TypeError) do
|
68
|
+
easy.setopt(Curl::CURLOPT_STDERR, stringio)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_curlopt_stderr_fails_with_string
|
73
|
+
string = String.new
|
74
|
+
easy = Curl::Easy.new(TestServlet.url)
|
75
|
+
|
76
|
+
assert_raise(TypeError) do
|
77
|
+
easy.setopt(Curl::CURLOPT_STDERR, string)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_exception
|
82
|
+
begin
|
83
|
+
Curl.get('NOT_FOUND_URL')
|
84
|
+
rescue
|
85
|
+
assert true
|
86
|
+
rescue Exception
|
87
|
+
assert false, "We should raise StandardError"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
13
91
|
def test_threads
|
14
92
|
t = []
|
15
93
|
5.times do
|
@@ -18,20 +96,17 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
18
96
|
c = Curl.get($TEST_URL)
|
19
97
|
assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body_str)
|
20
98
|
assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body)
|
21
|
-
assert_equal "", c.header_str
|
22
|
-
assert_equal "", c.head
|
23
99
|
end
|
24
100
|
end
|
25
101
|
end
|
26
102
|
|
27
|
-
t.each {|
|
103
|
+
t.each {|x| x.join }
|
28
104
|
end
|
29
105
|
|
30
106
|
def test_class_perform_01
|
31
107
|
assert_instance_of Curl::Easy, c = Curl::Easy.perform($TEST_URL)
|
32
108
|
assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body_str)
|
33
109
|
assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body)
|
34
|
-
assert_equal "", c.header_str
|
35
110
|
end
|
36
111
|
|
37
112
|
def test_class_perform_02
|
@@ -39,12 +114,11 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
39
114
|
assert_instance_of Curl::Easy, c = Curl::Easy.perform($TEST_URL) { |curl| curl.on_body { |d| data << d; d.length } }
|
40
115
|
|
41
116
|
assert_nil c.body_str
|
42
|
-
assert_equal "", c.header_str
|
43
117
|
assert_match(/^# DO NOT REMOVE THIS COMMENT/, data)
|
44
118
|
end
|
45
119
|
|
46
120
|
def test_class_perform_03
|
47
|
-
assert_raise(Curl::Err::CouldntReadError) {
|
121
|
+
assert_raise(Curl::Err::CouldntReadError) { Curl::Easy.perform($TEST_URL + "nonexistent") }
|
48
122
|
end
|
49
123
|
|
50
124
|
def test_new_01
|
@@ -134,7 +208,6 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
134
208
|
c = Curl::Easy.new($TEST_URL)
|
135
209
|
assert_equal true, c.http_get
|
136
210
|
assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body_str)
|
137
|
-
assert_equal "", c.header_str
|
138
211
|
end
|
139
212
|
|
140
213
|
def test_get_02
|
@@ -146,7 +219,6 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
146
219
|
assert_equal true, c.http_get
|
147
220
|
|
148
221
|
assert_nil c.body_str
|
149
|
-
assert_equal "", c.header_str
|
150
222
|
assert_match(/^# DO NOT REMOVE THIS COMMENT/, data)
|
151
223
|
end
|
152
224
|
|
@@ -329,29 +401,69 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
329
401
|
c.max_redirects = nil
|
330
402
|
assert_nil c.max_redirects
|
331
403
|
end
|
332
|
-
|
404
|
+
|
405
|
+
def test_timeout_with_floats
|
406
|
+
c = Curl::Easy.new($TEST_URL)
|
407
|
+
|
408
|
+
c.timeout = 1.5
|
409
|
+
assert_equal 1500, c.timeout_ms
|
410
|
+
assert_equal 1.5, c.timeout
|
411
|
+
end
|
412
|
+
|
413
|
+
def test_timeout_with_negative
|
414
|
+
c = Curl::Easy.new($TEST_URL)
|
415
|
+
|
416
|
+
c.timeout = -1.5
|
417
|
+
assert_equal 0, c.timeout
|
418
|
+
assert_equal 0, c.timeout_ms
|
419
|
+
|
420
|
+
c.timeout = -4.8
|
421
|
+
assert_equal 0, c.timeout
|
422
|
+
assert_equal 0, c.timeout_ms
|
423
|
+
end
|
424
|
+
|
333
425
|
def test_timeout_01
|
334
426
|
c = Curl::Easy.new($TEST_URL)
|
335
|
-
|
336
|
-
|
337
|
-
|
427
|
+
|
428
|
+
assert_equal 0, c.timeout
|
429
|
+
|
338
430
|
c.timeout = 3
|
339
431
|
assert_equal 3, c.timeout
|
340
|
-
|
341
|
-
c.timeout =
|
342
|
-
|
432
|
+
|
433
|
+
c.timeout = 0
|
434
|
+
assert_equal 0, c.timeout
|
343
435
|
end
|
344
436
|
|
345
437
|
def test_timeout_ms_01
|
346
438
|
c = Curl::Easy.new($TEST_URL)
|
347
439
|
|
348
|
-
|
440
|
+
assert_equal 0, c.timeout_ms
|
349
441
|
|
350
442
|
c.timeout_ms = 100
|
351
443
|
assert_equal 100, c.timeout_ms
|
352
444
|
|
353
445
|
c.timeout_ms = nil
|
354
|
-
|
446
|
+
assert_equal 0, c.timeout_ms
|
447
|
+
end
|
448
|
+
|
449
|
+
def test_timeout_ms_with_floats
|
450
|
+
c = Curl::Easy.new($TEST_URL)
|
451
|
+
|
452
|
+
c.timeout_ms = 55.5
|
453
|
+
assert_equal 55, c.timeout_ms
|
454
|
+
assert_equal 0.055, c.timeout
|
455
|
+
end
|
456
|
+
|
457
|
+
def test_timeout_ms_with_negative
|
458
|
+
c = Curl::Easy.new($TEST_URL)
|
459
|
+
|
460
|
+
c.timeout_ms = -1.5
|
461
|
+
assert_equal 0, c.timeout
|
462
|
+
assert_equal 0, c.timeout_ms
|
463
|
+
|
464
|
+
c.timeout_ms = -4.8
|
465
|
+
assert_equal 0, c.timeout
|
466
|
+
assert_equal 0, c.timeout_ms
|
355
467
|
end
|
356
468
|
|
357
469
|
def test_connect_timeout_01
|
@@ -595,6 +707,15 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
595
707
|
assert_equal "some.file", c.cookiejar
|
596
708
|
end
|
597
709
|
|
710
|
+
def test_cookielist
|
711
|
+
c = Curl::Easy.new TestServlet.url
|
712
|
+
c.enable_cookies = true
|
713
|
+
c.post_body = URI.encode_www_form('c' => 'somename=somevalue')
|
714
|
+
assert_nil c.cookielist
|
715
|
+
c.perform
|
716
|
+
assert_match(/somevalue/, c.cookielist.join(''))
|
717
|
+
end
|
718
|
+
|
598
719
|
def test_on_success
|
599
720
|
curl = Curl::Easy.new($TEST_URL)
|
600
721
|
on_success_called = false
|
@@ -657,7 +778,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
657
778
|
retries = 0
|
658
779
|
begin
|
659
780
|
count = 0
|
660
|
-
|
781
|
+
Curl::Easy.send("http_#{method}", TestServlet.url) do|c|
|
661
782
|
count += 1
|
662
783
|
assert_equal Curl::Easy, c.class
|
663
784
|
end
|
@@ -679,8 +800,8 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
679
800
|
Curl::PostField.file('bar', File.expand_path(File.join(File.dirname(__FILE__),'..','README.markdown')))
|
680
801
|
]
|
681
802
|
curl.http_post(fields)
|
682
|
-
assert_match
|
683
|
-
assert_match
|
803
|
+
assert_match(/HTTP POST file upload/, curl.body_str)
|
804
|
+
assert_match(/Content-Disposition: form-data/, curl.body_str)
|
684
805
|
end
|
685
806
|
|
686
807
|
def test_post_with_body_remote
|
@@ -706,8 +827,8 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
706
827
|
curl.multipart_form_post = true
|
707
828
|
pf = Curl::PostField.file('readme', File.expand_path(File.join(File.dirname(__FILE__),'..','README.markdown')))
|
708
829
|
curl.http_post(pf)
|
709
|
-
assert_match
|
710
|
-
assert_match
|
830
|
+
assert_match(/HTTP POST file upload/, curl.body_str)
|
831
|
+
assert_match(/Content-Disposition: form-data/, curl.body_str)
|
711
832
|
end
|
712
833
|
|
713
834
|
def test_delete_remote
|
@@ -729,7 +850,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
729
850
|
redirect = curl.header_str.match(/Location: (.*)/)
|
730
851
|
|
731
852
|
assert_equal '', curl.body_str
|
732
|
-
assert_match
|
853
|
+
assert_match('/nonexistent', redirect[1])
|
733
854
|
end
|
734
855
|
|
735
856
|
def test_head_accessor
|
@@ -740,7 +861,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
740
861
|
redirect = curl.header_str.match(/Location: (.*)/)
|
741
862
|
|
742
863
|
assert_equal '', curl.body_str
|
743
|
-
assert_match
|
864
|
+
assert_match('/nonexistent', redirect[1])
|
744
865
|
curl.head = false
|
745
866
|
curl.perform
|
746
867
|
assert_equal 'GET', curl.body_str
|
@@ -750,11 +871,11 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
750
871
|
curl = Curl::Easy.new(TestServlet.url)
|
751
872
|
curl.headers['Content-Type'] = 'application/json'
|
752
873
|
assert curl.http_put("message")
|
753
|
-
assert_match
|
754
|
-
assert_match
|
755
|
-
assert_match
|
756
|
-
assert_match
|
757
|
-
assert_match
|
874
|
+
assert_match(/^PUT/, curl.body_str)
|
875
|
+
assert_match(/message$/, curl.body_str)
|
876
|
+
assert_match(/message$/, curl.body)
|
877
|
+
assert_match(/application\/json/, curl.header_str)
|
878
|
+
assert_match(/application\/json/, curl.head)
|
758
879
|
end
|
759
880
|
|
760
881
|
def test_put_data
|
@@ -763,8 +884,8 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
763
884
|
|
764
885
|
curl.perform
|
765
886
|
|
766
|
-
assert_match
|
767
|
-
assert_match
|
887
|
+
assert_match(/^PUT/, curl.body_str)
|
888
|
+
assert_match(/message$/, curl.body_str)
|
768
889
|
end
|
769
890
|
|
770
891
|
# https://github.com/taf2/curb/issues/101
|
@@ -774,8 +895,8 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
774
895
|
|
775
896
|
curl.perform
|
776
897
|
|
777
|
-
assert_match
|
778
|
-
assert_match
|
898
|
+
assert_match(/^PUT/, curl.body_str)
|
899
|
+
assert_match("a\0b", curl.body_str)
|
779
900
|
end
|
780
901
|
|
781
902
|
def test_put_nil_data_no_crash
|
@@ -790,7 +911,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
790
911
|
File.open(__FILE__,'rb') do|f|
|
791
912
|
assert curl.http_put(f)
|
792
913
|
end
|
793
|
-
assert_equal "PUT\n#{File.read(__FILE__)}", curl.body_str
|
914
|
+
assert_equal "PUT\n#{File.read(__FILE__)}", curl.body_str.tr("\r", '')
|
794
915
|
end
|
795
916
|
|
796
917
|
def test_put_class_method
|
@@ -800,7 +921,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
800
921
|
assert_equal Curl::Easy, c.class
|
801
922
|
end
|
802
923
|
assert_equal 1, count
|
803
|
-
assert_equal "PUT\n#{File.read(__FILE__)}", curl.body_str
|
924
|
+
assert_equal "PUT\n#{File.read(__FILE__)}", curl.body_str.tr("\r", '')
|
804
925
|
end
|
805
926
|
|
806
927
|
# Generate a self-signed cert with
|
@@ -809,7 +930,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
809
930
|
def test_cert
|
810
931
|
curl = Curl::Easy.new(TestServlet.url)
|
811
932
|
curl.cert= File.join(File.dirname(__FILE__),"cert.pem")
|
812
|
-
assert_match
|
933
|
+
assert_match(/cert.pem$/,curl.cert)
|
813
934
|
end
|
814
935
|
|
815
936
|
def test_cert_with_password
|
@@ -817,7 +938,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
817
938
|
path = File.join(File.dirname(__FILE__),"cert.pem")
|
818
939
|
curl.certpassword = 'password'
|
819
940
|
curl.cert = path
|
820
|
-
assert_match
|
941
|
+
assert_match(/cert.pem$/,curl.cert)
|
821
942
|
end
|
822
943
|
|
823
944
|
def test_cert_type
|
@@ -838,7 +959,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
838
959
|
def test_ca_cert
|
839
960
|
curl = Curl::Easy.new(TestServlet.url)
|
840
961
|
curl.cacert= File.join(File.dirname(__FILE__),"cacert.pem")
|
841
|
-
assert_match
|
962
|
+
assert_match(/cacert.pem$/, curl.cacert)
|
842
963
|
end
|
843
964
|
|
844
965
|
def test_user_agent
|
@@ -896,7 +1017,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
896
1017
|
easy.http_post(pf)
|
897
1018
|
|
898
1019
|
assert_not_equal(0,easy.body_str.size)
|
899
|
-
assert_equal(easy.body_str,File.read(readme))
|
1020
|
+
assert_equal(easy.body_str.tr("\r", ''), File.read(readme))
|
900
1021
|
end
|
901
1022
|
|
902
1023
|
|
@@ -992,8 +1113,8 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
992
1113
|
curl.headers['Accept'] = '*/*'
|
993
1114
|
curl.headers['Authorization'] = 'Foo Bar Biz Baz'
|
994
1115
|
curl.http_put(rd)
|
995
|
-
assert_match
|
996
|
-
assert_match
|
1116
|
+
assert_match(/^PUT/, curl.body_str)
|
1117
|
+
assert_match(/hello$/, curl.body_str)
|
997
1118
|
curl.header_str
|
998
1119
|
curl.body_str
|
999
1120
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
2
|
+
|
3
|
+
class TestCurbCurlEasyResolve < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@easy = Curl::Easy.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_resolve
|
9
|
+
@easy.resolve = [ "example.com:80:127.0.0.1" ]
|
10
|
+
assert_equal @easy.resolve, [ "example.com:80:127.0.0.1" ]
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_empty_resolve
|
14
|
+
assert_equal @easy.resolve, nil
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
2
|
+
|
3
|
+
class TestCurbCurlMaxFileSize < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@easy = Curl::Easy.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_maxfilesize
|
9
|
+
@easy.set(Curl::CURLOPT_MAXFILESIZE, 5000000)
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
data/tests/tc_curl_multi.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
2
|
+
require 'set'
|
2
3
|
|
3
4
|
class TestCurbCurlMulti < Test::Unit::TestCase
|
4
5
|
def teardown
|
@@ -6,6 +7,110 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
6
7
|
ObjectSpace.garbage_collect
|
7
8
|
end
|
8
9
|
|
10
|
+
# for https://github.com/taf2/curb/issues/277
|
11
|
+
# must connect to an external
|
12
|
+
def test_connection_keepalive
|
13
|
+
# this test fails with libcurl 7.22.0. I didn't investigate, but it may be related
|
14
|
+
# to CURLOPT_MAXCONNECTS bug fixed in 7.30.0:
|
15
|
+
# https://github.com/curl/curl/commit/e87e76e2dc108efb1cae87df496416f49c55fca0
|
16
|
+
omit("Skip, libcurl too old (< 7.22.0)") if Curl::CURL_VERSION.split('.')[1].to_i <= 22
|
17
|
+
|
18
|
+
@server.shutdown if @server
|
19
|
+
@test_thread.kill if @test_thread
|
20
|
+
@server = nil
|
21
|
+
File.unlink(locked_file)
|
22
|
+
Curl::Multi.autoclose = true
|
23
|
+
assert Curl::Multi.autoclose
|
24
|
+
# XXX: thought maybe we can clean house here to have the full suite pass in osx... but for now running this test in isolate does pass
|
25
|
+
# additionally, if ss allows this to pass on linux without requesting google i think this is a good trade off... leaving some of the thoughts below
|
26
|
+
# in hopes that coming back to this later will find it and remember how to fix it
|
27
|
+
# types = Set.new
|
28
|
+
# close_types = Set.new([TCPServer,TCPSocket,Socket,Curl::Multi, Curl::Easy,WEBrick::Log])
|
29
|
+
# ObjectSpace.each_object {|o|
|
30
|
+
# if o.respond_to?(:close)
|
31
|
+
# types << o.class
|
32
|
+
# end
|
33
|
+
# if close_types.include?(o.class)
|
34
|
+
# o.close
|
35
|
+
# end
|
36
|
+
# }
|
37
|
+
#puts "unique types: #{types.to_a.join("\n")}"
|
38
|
+
GC.start # cleanup FDs left over from other tests
|
39
|
+
server_setup
|
40
|
+
GC.start # cleanup FDs left over from other tests
|
41
|
+
|
42
|
+
if `which ss`.strip.size == 0
|
43
|
+
# osx need lsof still :(
|
44
|
+
open_fds = lambda do
|
45
|
+
out = `/usr/sbin/lsof -p #{Process.pid} | egrep "TCP|UDP"`# | egrep ':#{TestServlet.port} ' | egrep ESTABLISHED`# | wc -l`.strip.to_i
|
46
|
+
#puts out.lines.join("\n")
|
47
|
+
out.lines.size
|
48
|
+
end
|
49
|
+
else
|
50
|
+
ss = `which ss`.strip
|
51
|
+
open_fds = lambda do
|
52
|
+
`#{ss} -n4 state established dport = :#{TestServlet.port} | wc -l`.strip.to_i
|
53
|
+
end
|
54
|
+
end
|
55
|
+
Curl::Multi.autoclose = false
|
56
|
+
before_open = open_fds.call
|
57
|
+
#puts "before_open: #{before_open.inspect}"
|
58
|
+
assert !Curl::Multi.autoclose
|
59
|
+
multi = Curl::Multi.new
|
60
|
+
multi.max_connects = 1 # limit to 1 connection within the multi handle
|
61
|
+
|
62
|
+
did_complete = false
|
63
|
+
5.times do |n|
|
64
|
+
easy = Curl::Easy.new(TestServlet.url) do |curl|
|
65
|
+
curl.timeout = 5 # ensure we don't hang for ever connecting to an external host
|
66
|
+
curl.on_complete {
|
67
|
+
did_complete = true
|
68
|
+
}
|
69
|
+
end
|
70
|
+
multi.add(easy)
|
71
|
+
end
|
72
|
+
|
73
|
+
multi.perform
|
74
|
+
assert did_complete
|
75
|
+
after_open = open_fds.call
|
76
|
+
#puts "after_open: #{after_open} before_open: #{before_open.inspect}"
|
77
|
+
assert_equal 1, (after_open - before_open), "with max connections set to 1 at this point the connection to google should still be open"
|
78
|
+
multi.close
|
79
|
+
|
80
|
+
after_open = open_fds.call
|
81
|
+
#puts "after_open: #{after_open} before_open: #{before_open.inspect}"
|
82
|
+
assert_equal 0, (after_open - before_open), "after closing the multi handle all connections should be closed"
|
83
|
+
|
84
|
+
Curl::Multi.autoclose = true
|
85
|
+
multi = Curl::Multi.new
|
86
|
+
did_complete = false
|
87
|
+
5.times do |n|
|
88
|
+
easy = Curl::Easy.new(TestServlet.url) do |curl|
|
89
|
+
curl.timeout = 5 # ensure we don't hang for ever connecting to an external host
|
90
|
+
curl.on_complete {
|
91
|
+
did_complete = true
|
92
|
+
}
|
93
|
+
end
|
94
|
+
multi.add(easy)
|
95
|
+
end
|
96
|
+
|
97
|
+
multi.perform
|
98
|
+
assert did_complete
|
99
|
+
after_open = open_fds.call
|
100
|
+
#puts "after_open: #{after_open} before_open: #{before_open.inspect}"
|
101
|
+
assert_equal 0, (after_open - before_open), "auto close the connections"
|
102
|
+
ensure
|
103
|
+
Curl::Multi.autoclose = false # restore default
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_connection_autoclose
|
107
|
+
assert !Curl::Multi.autoclose
|
108
|
+
Curl::Multi.autoclose = true
|
109
|
+
assert Curl::Multi.autoclose
|
110
|
+
ensure
|
111
|
+
Curl::Multi.autoclose = false # restore default
|
112
|
+
end
|
113
|
+
|
9
114
|
def test_new_multi_01
|
10
115
|
d1 = ""
|
11
116
|
c1 = Curl::Easy.new($TEST_URL) do |curl|
|
@@ -125,7 +230,7 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
125
230
|
def test_requests
|
126
231
|
m = Curl::Multi.new
|
127
232
|
|
128
|
-
assert_equal(
|
233
|
+
assert_equal(0, m.requests.length, 'A new Curl::Multi handle should have no requests')
|
129
234
|
|
130
235
|
10.times do
|
131
236
|
m.add(Curl::Easy.new($TEST_URL))
|
@@ -135,7 +240,7 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
135
240
|
|
136
241
|
m.perform
|
137
242
|
|
138
|
-
assert_equal(
|
243
|
+
assert_equal(0, m.requests.length, 'A new Curl::Multi handle should have no requests after a perform')
|
139
244
|
end
|
140
245
|
|
141
246
|
def test_cancel
|
@@ -148,7 +253,7 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
148
253
|
|
149
254
|
m.cancel!
|
150
255
|
|
151
|
-
assert_equal(
|
256
|
+
assert_equal(0, m.requests.size, 'A new Curl::Multi handle should have no requests after being canceled')
|
152
257
|
end
|
153
258
|
|
154
259
|
def test_with_success
|
@@ -192,7 +297,7 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
192
297
|
c1.on_success do|c|
|
193
298
|
success_called1 = true
|
194
299
|
#puts "success 1 called: #{c.body_str.inspect}"
|
195
|
-
|
300
|
+
assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body_str)
|
196
301
|
end
|
197
302
|
|
198
303
|
c1.on_failure do|c,rc|
|
@@ -331,7 +436,6 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
331
436
|
Curl::Multi.download(urls,{},{},downloads) do|curl,download_path|
|
332
437
|
assert_equal 200, curl.response_code
|
333
438
|
assert File.exist?(download_path)
|
334
|
-
store = file_info[File.basename(download_path)]
|
335
439
|
assert_equal file_info[File.basename(download_path)][:size], File.size(download_path), "incomplete download: #{download_path}"
|
336
440
|
end
|
337
441
|
ensure
|
@@ -346,7 +450,7 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
346
450
|
]
|
347
451
|
Curl::Multi.post(urls, {:follow_location => true, :multipart_form_post => true}, {:pipeline => true}) do|easy|
|
348
452
|
str = easy.body_str
|
349
|
-
assert_match
|
453
|
+
assert_match(/POST/, str)
|
350
454
|
fields = {}
|
351
455
|
str.gsub(/POST\n/,'').split('&').map{|sv| k, v = sv.split('='); fields[k] = v }
|
352
456
|
expected = urls.find{|s| s[:url] == easy.last_effective_url }
|
@@ -361,8 +465,8 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
361
465
|
{ :url => TestServlet.url, :method => :put, :put_data => "message",
|
362
466
|
:headers => {'Content-Type' => 'application/json' } }]
|
363
467
|
Curl::Multi.put(urls, {}, {:pipeline => true}) do|easy|
|
364
|
-
assert_match
|
365
|
-
assert_match
|
468
|
+
assert_match(/PUT/, easy.body_str)
|
469
|
+
assert_match(/message/, easy.body_str)
|
366
470
|
end
|
367
471
|
end
|
368
472
|
|
@@ -379,11 +483,11 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
379
483
|
assert_equal nil, code
|
380
484
|
case method
|
381
485
|
when :post
|
382
|
-
assert_match
|
486
|
+
assert_match(/POST/, easy.body_str)
|
383
487
|
when :get
|
384
|
-
assert_match
|
488
|
+
assert_match(/GET/, easy.body_str)
|
385
489
|
when :put
|
386
|
-
assert_match
|
490
|
+
assert_match(/PUT/, easy.body_str)
|
387
491
|
end
|
388
492
|
#puts "#{easy.body_str.inspect}, #{method.inspect}, #{code.inspect}"
|
389
493
|
end
|
@@ -399,11 +503,11 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
399
503
|
assert_equal nil, code
|
400
504
|
case method
|
401
505
|
when :post
|
402
|
-
assert_match
|
506
|
+
assert_match(/POST/, easy.body_str)
|
403
507
|
when :get
|
404
|
-
assert_match
|
508
|
+
assert_match(/GET/, easy.body_str)
|
405
509
|
when :put
|
406
|
-
assert_match
|
510
|
+
assert_match(/PUT/, easy.body_str)
|
407
511
|
end
|
408
512
|
end
|
409
513
|
end
|
@@ -485,5 +589,4 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
485
589
|
def setup
|
486
590
|
server_setup
|
487
591
|
end
|
488
|
-
|
489
592
|
end
|