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,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