codders-curb 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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,143 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
+
3
+ class TestCurbCurlPostfield < Test::Unit::TestCase
4
+ def test_private_new
5
+ assert_raise(NoMethodError) { Curl::PostField.new }
6
+ end
7
+
8
+ def test_new_content_01
9
+ pf = Curl::PostField.content('foo', 'bar')
10
+
11
+ assert_equal 'foo', pf.name
12
+ assert_equal 'bar', pf.content
13
+ assert_nil pf.content_type
14
+ assert_nil pf.local_file
15
+ assert_nil pf.remote_file
16
+ assert_nil pf.set_content_proc
17
+ end
18
+
19
+ def test_new_content_02
20
+ pf = Curl::PostField.content('foo', 'bar', 'text/html')
21
+
22
+ assert_equal 'foo', pf.name
23
+ assert_equal 'bar', pf.content
24
+ assert_equal 'text/html', pf.content_type
25
+ assert_nil pf.local_file
26
+ assert_nil pf.remote_file
27
+ assert_nil pf.set_content_proc
28
+ end
29
+
30
+ def test_new_content_03
31
+ l = lambda { |field| "never gets run" }
32
+ pf = Curl::PostField.content('foo', &l)
33
+
34
+ assert_equal 'foo', pf.name
35
+ assert_nil pf.content
36
+ assert_nil pf.content_type
37
+ assert_nil pf.local_file
38
+ assert_nil pf.remote_file
39
+
40
+ # N.B. This doesn't just get the proc, but also removes it.
41
+ assert_equal l, pf.set_content_proc
42
+ end
43
+
44
+ def test_new_content_04
45
+ l = lambda { |field| "never gets run" }
46
+ pf = Curl::PostField.content('foo', 'text/html', &l)
47
+
48
+ assert_equal 'foo', pf.name
49
+ assert_nil pf.content
50
+ assert_equal 'text/html', pf.content_type
51
+ assert_nil pf.local_file
52
+ assert_nil pf.remote_file
53
+
54
+ # N.B. This doesn't just get the proc, but also removes it.
55
+ assert_equal l, pf.set_content_proc
56
+ end
57
+
58
+
59
+ def test_new_file_01
60
+ pf = Curl::PostField.file('foo', 'localname')
61
+
62
+ assert_equal 'foo', pf.name
63
+ assert_equal 'localname', pf.local_file
64
+ assert_equal 'localname', pf.remote_file
65
+ assert_nothing_raised { pf.to_s }
66
+ assert_nil pf.content_type
67
+ assert_nil pf.content
68
+ assert_nil pf.set_content_proc
69
+ end
70
+
71
+ def test_new_file_02
72
+ pf = Curl::PostField.file('foo', 'localname', 'remotename')
73
+
74
+ assert_equal 'foo', pf.name
75
+ assert_equal 'localname', pf.local_file
76
+ assert_equal 'remotename', pf.remote_file
77
+ assert_nil pf.content_type
78
+ assert_nil pf.content
79
+ assert_nil pf.set_content_proc
80
+ end
81
+
82
+ def test_new_file_03
83
+ l = lambda { |field| "never gets run" }
84
+ pf = Curl::PostField.file('foo', 'remotename', &l)
85
+
86
+ assert_equal 'foo', pf.name
87
+ assert_equal 'remotename', pf.remote_file
88
+ assert_nil pf.local_file
89
+ assert_nil pf.content_type
90
+ assert_nil pf.content
91
+
92
+ # N.B. This doesn't just get the proc, but also removes it.
93
+ assert_equal l, pf.set_content_proc
94
+ end
95
+
96
+ def test_new_file_04
97
+ assert_raise(ArgumentError) do
98
+ # no local name, no block
99
+ Curl::PostField.file('foo')
100
+ end
101
+
102
+ assert_raise(ArgumentError) do
103
+ # no remote name with block
104
+ Curl::PostField.file('foo') { |field| "never runs" }
105
+ end
106
+ end
107
+
108
+ def test_new_file_05
109
+ # local gets ignored when supplying a block, but remote
110
+ # is still set up properly.
111
+ l = lambda { |field| "never runs" }
112
+ pf = Curl::PostField.file('foo', 'local', 'remote', &l)
113
+
114
+ assert_equal 'foo', pf.name
115
+ assert_equal 'remote', pf.remote_file
116
+ assert_nil pf.local_file
117
+ assert_nil pf.content_type
118
+ assert_nil pf.content
119
+
120
+ assert_equal l, pf.set_content_proc
121
+ end
122
+
123
+ def test_to_s_01
124
+ pf = Curl::PostField.content('foo', 'bar')
125
+ assert_equal "foo=bar", pf.to_s
126
+ end
127
+
128
+ def test_to_s_02
129
+ pf = Curl::PostField.content('foo', 'bar ton')
130
+ assert_equal "foo=bar%20ton", pf.to_s
131
+ end
132
+
133
+ def test_to_s_03
134
+ pf = Curl::PostField.content('foo') { |field| field.name.upcase + "BAR" }
135
+ assert_equal "foo=FOOBAR", pf.to_s
136
+ end
137
+
138
+ def test_to_s_04
139
+ pf = Curl::PostField.file('foo.file', 'bar.file')
140
+ assert_nothing_raised { pf.to_s }
141
+ #assert_raise(Curl::Err::InvalidPostFieldError) { pf.to_s }
142
+ end
143
+ end
data/tests/timeout.rb ADDED
@@ -0,0 +1,100 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
+
3
+ # Run server with: ruby -rubygems timeout_server.rb -p 9128
4
+
5
+ # Note that curl requires all timeouts to be integers -
6
+ # curl_easy_setopt does not have a provision for floating-point values
7
+
8
+ class TestCurbTimeouts < Test::Unit::TestCase
9
+ def test_no_timeout_by_default
10
+ curl = Curl::Easy.new(wait_url(2))
11
+ start = Time.now
12
+ assert_equal true, curl.http_get
13
+ elapsed = Time.now - start
14
+ assert elapsed > 2
15
+ end
16
+
17
+ def test_overall_timeout_on_dead_transfer
18
+ curl = Curl::Easy.new(wait_url(2))
19
+ curl.timeout = 1
20
+ assert_raise(Curl::Err::TimeoutError) do
21
+ curl.http_get
22
+ end
23
+ end
24
+
25
+ def test_clearing_timeout
26
+ curl = Curl::Easy.new(wait_url(2))
27
+ curl.timeout = 1
28
+ curl.timeout = nil
29
+ start = Time.now
30
+ assert_equal true, curl.http_get
31
+ elapsed = Time.now - start
32
+ assert elapsed > 2
33
+ end
34
+
35
+ def test_overall_timeout_on_slow_transfer
36
+ curl = Curl::Easy.new(serve_url(100, 2, 3))
37
+ curl.timeout = 1
38
+ # transfer is aborted despite data being exchanged
39
+ assert_raise(Curl::Err::TimeoutError) do
40
+ curl.http_get
41
+ end
42
+ end
43
+
44
+ def test_low_speed_time_on_slow_transfer
45
+ curl = Curl::Easy.new(serve_url(100, 1, 3))
46
+ curl.low_speed_time = 2
47
+ # use default low_speed_limit of 1
48
+ assert true, curl.http_get
49
+ end
50
+
51
+ def test_low_speed_time_on_very_slow_transfer
52
+ # send data slower than required
53
+ curl = Curl::Easy.new(serve_url(10, 2, 3))
54
+ curl.low_speed_time = 1
55
+ # XXX for some reason this test fails if low speed limit is not specified
56
+ curl.low_speed_limit = 1
57
+ # use default low_speed_limit of 1
58
+ assert_raise(Curl::Err::TimeoutError) do
59
+ curl.http_get
60
+ end
61
+ end
62
+
63
+ def test_low_speed_limit_on_slow_transfer
64
+ curl = Curl::Easy.new(serve_url(10, 1, 3))
65
+ curl.low_speed_time = 2
66
+ curl.low_speed_limit = 1000
67
+ assert_raise(Curl::Err::TimeoutError) do
68
+ curl.http_get
69
+ end
70
+ end
71
+
72
+ def test_clearing_low_speed_time
73
+ curl = Curl::Easy.new(serve_url(100, 2, 3))
74
+ curl.low_speed_time = 1
75
+ curl.low_speed_time = nil
76
+ assert_equal true, curl.http_get
77
+ end
78
+
79
+ def test_clearing_low_speed_limit
80
+ curl = Curl::Easy.new(serve_url(10, 1, 3))
81
+ curl.low_speed_time = 2
82
+ curl.low_speed_limit = 1000
83
+ curl.low_speed_limit = nil
84
+ assert_equal true, curl.http_get
85
+ end
86
+
87
+ private
88
+
89
+ def wait_url(time)
90
+ "#{server_base}/wait/#{time}"
91
+ end
92
+
93
+ def serve_url(chunk_size, time, count)
94
+ "#{server_base}/serve/#{chunk_size}/every/#{time}/for/#{count}"
95
+ end
96
+
97
+ def server_base
98
+ 'http://127.0.0.1:9128'
99
+ end
100
+ end
@@ -0,0 +1,33 @@
1
+ # This Sinatra application must be run with mongrel
2
+ # or possibly with unicorn for the serve action to work properly.
3
+ # See http://efreedom.com/Question/1-3669674/Streaming-Data-Sinatra-Rack-Application
4
+
5
+ require 'sinatra'
6
+
7
+ get '/wait/:time' do |time|
8
+ time = time.to_i
9
+ sleep(time)
10
+ "Slept #{time} at #{Time.now}"
11
+ end
12
+
13
+ # http://efreedom.com/Question/1-3027435/Way-Flush-Html-Wire-Sinatra
14
+ class Streamer
15
+ def initialize(time, chunks)
16
+ @time = time
17
+ @chunks = chunks
18
+ end
19
+
20
+ def each
21
+ @chunks.each do |chunk|
22
+ sleep(@time)
23
+ yield chunk
24
+ end
25
+ end
26
+ end
27
+
28
+ get '/serve/:chunk_size/every/:time/for/:count' do |chunk_size, time, count|
29
+ chunk_size, time, count = chunk_size.to_i, time.to_i, count.to_i
30
+ chunk = 'x' * chunk_size
31
+ chunks = [chunk] * count
32
+ Streamer.new(time, chunks)
33
+ end
@@ -0,0 +1,2 @@
1
+ $: << $TESTDIR = File.expand_path(File.dirname(__FILE__))
2
+ Dir[File.join($TESTDIR, 'tc_*.rb')].each { |lib| require lib }
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: codders-curb
3
+ version: !ruby/object:Gem::Version
4
+ hash: 63
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 8
9
+ - 0
10
+ version: 0.8.0
11
+ platform: ruby
12
+ authors:
13
+ - Ross Bamford
14
+ - Todd A. Fisher
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2012-01-19 00:00:00 Z
20
+ dependencies: []
21
+
22
+ description: Curb (probably CUrl-RuBy or something) provides Ruby-language bindings for the libcurl(3), a fully-featured client-side URL transfer library. cURL and libcurl live at http://curl.haxx.se/
23
+ email: todd.fisher@gmail.com
24
+ executables: []
25
+
26
+ extensions:
27
+ - ext/extconf.rb
28
+ extra_rdoc_files:
29
+ - LICENSE
30
+ - README
31
+ files:
32
+ - LICENSE
33
+ - README
34
+ - Rakefile
35
+ - doc.rb
36
+ - ext/extconf.rb
37
+ - lib/curb.rb
38
+ - lib/curl/easy.rb
39
+ - lib/curl/multi.rb
40
+ - lib/curl.rb
41
+ - ext/curb.c
42
+ - ext/curb_easy.c
43
+ - ext/curb_errors.c
44
+ - ext/curb_multi.c
45
+ - ext/curb_postfield.c
46
+ - ext/curb_upload.c
47
+ - ext/curb.h
48
+ - ext/curb_easy.h
49
+ - ext/curb_errors.h
50
+ - ext/curb_macros.h
51
+ - ext/curb_multi.h
52
+ - ext/curb_postfield.h
53
+ - ext/curb_upload.h
54
+ - tests/alltests.rb
55
+ - tests/bug_crash_on_debug.rb
56
+ - tests/bug_crash_on_progress.rb
57
+ - tests/bug_curb_easy_blocks_ruby_threads.rb
58
+ - tests/bug_curb_easy_post_with_string_no_content_length_header.rb
59
+ - tests/bug_instance_post_differs_from_class_post.rb
60
+ - tests/bug_multi_segfault.rb
61
+ - tests/bug_postfields_crash.rb
62
+ - tests/bug_postfields_crash2.rb
63
+ - tests/bug_require_last_or_segfault.rb
64
+ - tests/bugtests.rb
65
+ - tests/helper.rb
66
+ - tests/mem_check.rb
67
+ - tests/require_last_or_segfault_script.rb
68
+ - tests/tc_curl_download.rb
69
+ - tests/tc_curl_easy.rb
70
+ - tests/tc_curl_easy_setopt.rb
71
+ - tests/tc_curl_multi.rb
72
+ - tests/tc_curl_postfield.rb
73
+ - tests/timeout.rb
74
+ - tests/timeout_server.rb
75
+ - tests/unittests.rb
76
+ homepage: http://curb.rubyforge.org/
77
+ licenses: []
78
+
79
+ post_install_message:
80
+ rdoc_options:
81
+ - --main
82
+ - README
83
+ require_paths:
84
+ - lib
85
+ - ext
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ hash: 3
92
+ segments:
93
+ - 0
94
+ version: "0"
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ hash: 3
101
+ segments:
102
+ - 0
103
+ version: "0"
104
+ requirements: []
105
+
106
+ rubyforge_project: curb
107
+ rubygems_version: 1.8.10
108
+ signing_key:
109
+ specification_version: 3
110
+ summary: Ruby libcurl bindings
111
+ test_files:
112
+ - tests/alltests.rb
113
+ - tests/bug_crash_on_debug.rb
114
+ - tests/bug_crash_on_progress.rb
115
+ - tests/bug_curb_easy_blocks_ruby_threads.rb
116
+ - tests/bug_curb_easy_post_with_string_no_content_length_header.rb
117
+ - tests/bug_instance_post_differs_from_class_post.rb
118
+ - tests/bug_multi_segfault.rb
119
+ - tests/bug_postfields_crash.rb
120
+ - tests/bug_postfields_crash2.rb
121
+ - tests/bug_require_last_or_segfault.rb
122
+ - tests/bugtests.rb
123
+ - tests/helper.rb
124
+ - tests/mem_check.rb
125
+ - tests/require_last_or_segfault_script.rb
126
+ - tests/tc_curl_download.rb
127
+ - tests/tc_curl_easy.rb
128
+ - tests/tc_curl_easy_setopt.rb
129
+ - tests/tc_curl_multi.rb
130
+ - tests/tc_curl_postfield.rb
131
+ - tests/timeout.rb
132
+ - tests/timeout_server.rb
133
+ - tests/unittests.rb