curb 0.5.4.0 → 0.5.7.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of curb might be problematic. Click here for more details.

data/README CHANGED
@@ -1,129 +1,157 @@
1
- == Curb - Libcurl bindings for Ruby
1
+ # Curb - Libcurl bindings for Ruby
2
2
 
3
- * http://curb.rubyforge.org/
4
- * http://rubyforge.org/projects/curb
5
- * http://github.com/taf2/curb/tree/master
3
+ + [rubyforge rdoc](http://curb.rubyforge.org/)
4
+ + [rubyforge project](http://rubyforge.org/projects/curb)
5
+ + [github project](http://github.com/taf2/curb/tree/master)
6
6
 
7
7
  Curb (probably CUrl-RuBy or something) provides Ruby-language bindings for the
8
8
  libcurl(3), a fully-featured client-side URL transfer library.
9
- cURL and libcurl live at http://curl.haxx.se/ .
9
+ cURL and libcurl live at [http://curl.haxx.se/](http://curl.haxx.se/) .
10
10
 
11
11
  Curb is a work-in-progress, and currently only supports libcurl's 'easy' and 'multi' modes.
12
12
 
13
- === License
13
+ ## License
14
14
 
15
- Curb is copyright (c) 2006 Ross Bamford, and released under the terms of the
15
+ Curb is copyright (c)2006 Ross Bamford, and released under the terms of the
16
16
  Ruby license. See the LICENSE file for the gory details.
17
17
 
18
- === You will need
18
+ ## You will need
19
19
 
20
- * A working Ruby installation (1.8+, tested with 1.8.5, 1.8.6, 1.8.7, and 1.9.1)
21
- * A working (lib)curl installation, with development stuff (7.5+, tested with 7.15)
22
- * A sane build environment
20
+ + A working Ruby installation (1.8+, tested with 1.8.6, 1.8.7, 1.9.1, and 1.9.2)
21
+ + A working (lib)curl installation, with development stuff (7.5+, tested with 7.19.x)
22
+ + A sane build environment (e.g. gcc, make)
23
23
 
24
- === Installation...
24
+ ## Installation...
25
25
 
26
26
  ... will usually be as simple as:
27
27
 
28
- $ gem install curb
28
+ $ gem install curb
29
29
 
30
30
  Or, if you downloaded the archive:
31
31
 
32
- $ rake install
32
+ $ rake install
33
33
 
34
34
  If you have a wierd setup, you might need extconf options. In this case, pass
35
35
  them like so:
36
36
 
37
- $ rake install EXTCONF_OPTS='--with-curl-dir=/path/to/libcurl --prefix=/what/ever'
37
+ $ rake install EXTCONF_OPTS='--with-curl-dir=/path/to/libcurl --prefix=/what/ever'
38
38
 
39
- Currently, Curb is tested only on GNU/Linux x86 - YMMV on other platforms.
39
+ Curb is tested only on GNU/Linux x86 and Mac OSX - YMMV on other platforms.
40
40
  If you do use another platform and experience problems, or if you can
41
- expand on the above instructions, please get in touch via the mailing
42
- list on Curb's Rubyforge page.
41
+ expand on the above instructions, please report the issue at http://github.com/taf2/curb/issues
43
42
 
44
43
  Curb has fairly extensive RDoc comments in the source. You can build the
45
44
  documentation with:
46
45
 
47
- $ rake doc
46
+ $ rake doc
48
47
 
49
- === Examples
48
+ ## Examples
50
49
 
51
- Simple fetch via HTTP:
50
+ ### Simple fetch via HTTP:
52
51
 
53
- c = Curl::Easy.perform("http://www.google.co.uk")
54
- puts c.body_str
52
+ c = Curl::Easy.perform("http://www.google.co.uk")
53
+ puts c.body_str
55
54
 
56
- Same thing, more manual:
55
+ ### Same thing, more manual:
57
56
 
58
- c = Curl::Easy.new("http://www.google.co.uk")
59
- c.perform
60
- puts c.body_str
57
+ c = Curl::Easy.new("http://www.google.co.uk")
58
+ c.perform
59
+ puts c.body_str
61
60
 
62
- Additional config:
61
+ ### Additional config:
63
62
 
64
- Curl::Easy.perform("http://www.google.co.uk") do |curl|
65
- curl.headers["User-Agent"] = "myapp-0.0"
66
- curl.verbose = true
67
- end
63
+ Curl::Easy.perform("http://www.google.co.uk") do |curl|
64
+ curl.headers["User-Agent"] = "myapp-0.0"
65
+ curl.verbose = true
66
+ end
68
67
 
69
- Same thing, more manual:
68
+ ### Same thing, more manual:
70
69
 
71
- c = Curl::Easy.new("http://www.google.co.uk") do |curl|
72
- curl.headers["User-Agent"] = "myapp-0.0"
73
- curl.verbose = true
74
- end
70
+ c = Curl::Easy.new("http://www.google.co.uk") do |curl|
71
+ curl.headers["User-Agent"] = "myapp-0.0"
72
+ curl.verbose = true
73
+ end
75
74
 
76
- c.perform
75
+ c.perform
77
76
 
78
- Supplying custom handlers:
77
+ ### Supplying custom handlers:
79
78
 
80
- c = Curl::Easy.new("http://www.google.co.uk")
79
+ c = Curl::Easy.new("http://www.google.co.uk")
81
80
 
82
- c.on_body { |data| print(data) }
83
- c.on_header { |data| print(data) }
81
+ c.on_body { |data| print(data) }
82
+ c.on_header { |data| print(data) }
84
83
 
85
- c.perform
84
+ c.perform
86
85
 
87
- Reusing Curls:
86
+ ### Reusing Curls:
88
87
 
89
- c = Curl::Easy.new
88
+ c = Curl::Easy.new
90
89
 
91
- ["http://www.google.co.uk", "http://www.ruby-lang.org/"].map do |url|
92
- c.url = url
93
- c.perform
94
- c.body_str
95
- end
96
-
97
- HTTP POST form:
98
-
99
- c = Curl::Easy.http_post("http://my.rails.box/thing/create",
100
- Curl::PostField.content('thing[name]', 'box',
101
- Curl::PostField.content('thing[type]', 'storage')
102
-
103
- HTTP POST file upload:
104
-
105
- c = Curl::Easy.new("http://my.rails.box/files/upload")
106
- c.multipart_form_post = true
107
- c.http_post(Curl::PostField.file('myfile.rb'))
108
-
109
- Multi Interface:
110
- responses = {}
111
- requests = ["http://www.google.co.uk/", "http://www.ruby-lang.org/"]
112
- m = Curl::Multi.new
113
- # add a few easy handles
114
- requests.each do |url|
115
- responses[url] = ""
116
- c = Curl::Easy.new(url) do|curl|
117
- curl.follow_location = true
118
- curl.on_body{|data| responses[url] << data; data.size }
90
+ ["http://www.google.co.uk", "http://www.ruby-lang.org/"].map do |url|
91
+ c.url = url
92
+ c.perform
93
+ c.body_str
119
94
  end
120
- m.add(c)
121
- end
122
95
 
123
- m.perform do
124
- puts "idling... can do some work here, including add new requests"
125
- end
96
+ ### HTTP POST form:
97
+
98
+ c = Curl::Easy.http_post("http://my.rails.box/thing/create",
99
+ Curl::PostField.content('thing[name]', 'box'),
100
+ Curl::PostField.content('thing[type]', 'storage'))
101
+
102
+ ### HTTP POST file upload:
103
+
104
+ c = Curl::Easy.new("http://my.rails.box/files/upload")
105
+ c.multipart_form_post = true
106
+ c.http_post(Curl::PostField.file('myfile.rb'))
107
+
108
+ ### Multi Interface (Basic HTTP GET):
109
+
110
+ # make multiple GET requests
111
+ easy_options = {:follow_location => true}
112
+ multi_options = {:pipeline => true}
126
113
 
127
- requests.each do|url|
128
- puts responses[url]
129
- end
114
+ Curl::Multi.get('url1','url2','url3','url4','url5', easy_options, multi_options) do|easy|
115
+ # do something interesting with the easy response
116
+ puts easy.last_effective_url
117
+ end
118
+
119
+ ### Multi Interface (Basic HTTP POST):
120
+
121
+ # make multiple POST requests
122
+ easy_options = {:follow_location => true, :multipart_form_post => true}
123
+ multi_options = {:pipeline => true}
124
+
125
+ url_fields = [
126
+ { :url => 'url1', :post_fields => {'f1' => 'v1'} },
127
+ { :url => 'url2', :post_fields => {'f1' => 'v1'} },
128
+ { :url => 'url3', :post_fields => {'f1' => 'v1'} }
129
+ ]
130
+
131
+ Curl::Multi.post(url_fields, easy_options, multi_options) do|easy|
132
+ # do something interesting with the easy response
133
+ puts easy.last_effective_url
134
+ end
135
+
136
+ ### Multi Interface (Advanced):
137
+
138
+ responses = {}
139
+ requests = ["http://www.google.co.uk/", "http://www.ruby-lang.org/"]
140
+ m = Curl::Multi.new
141
+ # add a few easy handles
142
+ requests.each do |url|
143
+ responses[url] = ""
144
+ c = Curl::Easy.new(url) do|curl|
145
+ curl.follow_location = true
146
+ curl.on_body{|data| responses[url] << data; data.size }
147
+ end
148
+ m.add(c)
149
+ end
150
+
151
+ m.perform do
152
+ puts "idling... can do some work here, including add new requests"
153
+ end
154
+
155
+ requests.each do|url|
156
+ puts responses[url]
157
+ end
data/Rakefile CHANGED
@@ -36,7 +36,8 @@ task :test_ver do
36
36
  end
37
37
 
38
38
  # Make tasks -----------------------------------------------------
39
- MAKECMD = ENV['MAKE_CMD'] || 'make'
39
+ make_program = (/mswin/ =~ RUBY_PLATFORM) ? 'nmake' : 'make'
40
+ MAKECMD = ENV['MAKE_CMD'] || make_program
40
41
  MAKEOPTS = ENV['MAKE_OPTS'] || ''
41
42
 
42
43
  CURB_SO = "ext/curb_core.#{Config::MAKEFILE_CONFIG['DLEXT']}"
@@ -80,7 +81,7 @@ task :tu => :unittests
80
81
  task :test => [:rmpid,:unittests]
81
82
 
82
83
  task :rmpid do
83
- sh "rm -rf tests/server_lock-*"
84
+ FileUtils.rm_rf Dir.glob("tests/server_lock-*")
84
85
  end
85
86
 
86
87
  if ENV['RELTEST']
@@ -155,6 +156,39 @@ else
155
156
  spec.validate
156
157
  Gem::Builder.new(spec).build
157
158
  end
159
+
160
+ task :static do
161
+ ENV['STATIC_BUILD'] = '1'
162
+ end
163
+
164
+ task :binary_gemspec => [:static, :compile] do
165
+ require 'erb'
166
+ ENV['BINARY_PACKAGE'] = '1'
167
+ tspec = ERB.new(File.read(File.join(File.dirname(__FILE__),'lib','curb.gemspec.erb')))
168
+
169
+ File.open(File.join(File.dirname(__FILE__),'curb-binary.gemspec'),'wb') do|f|
170
+ f << tspec.result
171
+ end
172
+ end
173
+
174
+ desc 'Strip extra strings from Binary'
175
+ task :binary_strip do
176
+ strip = '/usr/bin/strip'
177
+ if File.exist?(strip) and `#{strip} -h 2>&1`.match(/GNU/)
178
+ sh "#{strip} #{CURB_SO}"
179
+ end
180
+ end
181
+
182
+ desc 'Build gem'
183
+ task :binary_package => [:binary_gemspec, :binary_strip] do
184
+ require 'rubygems/specification'
185
+ spec_source = File.read File.join(File.dirname(__FILE__),'curb-binary.gemspec')
186
+ spec = nil
187
+ # see: http://gist.github.com/16215
188
+ Thread.new { spec = eval("$SAFE = 3\n#{spec_source}") }.join
189
+ spec.validate
190
+ Gem::Builder.new(spec).build
191
+ end
158
192
  end
159
193
 
160
194
  # --------------------------------------------------------------------
data/ext/curb.c CHANGED
@@ -220,10 +220,12 @@ static VALUE ruby_curl_conv_q(VALUE mod) {
220
220
 
221
221
  void Init_curb_core() {
222
222
  // TODO we need to call curl_global_cleanup at exit!
223
- curl_global_init(CURL_GLOBAL_ALL);
224
- curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
223
+ curl_version_info_data *ver;
225
224
  VALUE curlver, curllongver, curlvernum;
226
225
 
226
+ curl_global_init(CURL_GLOBAL_ALL);
227
+ ver = curl_version_info(CURLVERSION_NOW);
228
+
227
229
  mCurl = rb_define_module("Curl");
228
230
 
229
231
  curlver = rb_str_new2(ver->version);
data/ext/curb.h CHANGED
@@ -20,11 +20,11 @@
20
20
  #include "curb_macros.h"
21
21
 
22
22
  // These should be managed from the Rake 'release' task.
23
- #define CURB_VERSION "0.5.4.0"
24
- #define CURB_VER_NUM 540
23
+ #define CURB_VERSION "0.5.7.0"
24
+ #define CURB_VER_NUM 570
25
25
  #define CURB_VER_MAJ 0
26
26
  #define CURB_VER_MIN 5
27
- #define CURB_VER_MIC 4
27
+ #define CURB_VER_MIC 7
28
28
  #define CURB_VER_PATCH 0
29
29
 
30
30
 
@@ -58,11 +58,15 @@ static size_t read_data_handler(void *ptr,
58
58
  }
59
59
  else {
60
60
  ruby_curl_upload *rbcu;
61
+ VALUE str;
62
+ size_t len;
63
+ size_t remaining;
64
+ char *str_ptr;
61
65
  Data_Get_Struct(rbce->upload, ruby_curl_upload, rbcu);
62
- VALUE str = rb_funcall(stream, rb_intern("to_s"), 0);
63
- size_t len = RSTRING_LEN(str);
64
- size_t remaining = len - rbcu->offset;
65
- char *str_ptr = RSTRING_PTR(str);
66
+ str = rb_funcall(stream, rb_intern("to_s"), 0);
67
+ len = RSTRING_LEN(str);
68
+ remaining = len - rbcu->offset;
69
+ str_ptr = RSTRING_PTR(str);
66
70
  if( remaining < read_bytes ) {
67
71
  if( remaining > 0 ) {
68
72
  memcpy(ptr, str_ptr+rbcu->offset, remaining);
@@ -137,7 +141,7 @@ void curl_easy_mark(ruby_curl_easy *rbce) {
137
141
  rb_gc_mark(rbce->header_data);
138
142
  rb_gc_mark(rbce->progress_proc);
139
143
  rb_gc_mark(rbce->debug_proc);
140
- rb_gc_mark(rbce->interface);
144
+ rb_gc_mark(rbce->interface_hm);
141
145
  rb_gc_mark(rbce->userpwd);
142
146
  rb_gc_mark(rbce->proxypwd);
143
147
  rb_gc_mark(rbce->headers);
@@ -192,10 +196,11 @@ static VALUE ruby_curl_easy_new(int argc, VALUE *argv, VALUE klass) {
192
196
  CURLcode ecode;
193
197
  VALUE url, blk;
194
198
  VALUE new_curl;
199
+ ruby_curl_easy *rbce;
195
200
 
196
201
  rb_scan_args(argc, argv, "01&", &url, &blk);
197
202
 
198
- ruby_curl_easy *rbce = ALLOC(ruby_curl_easy);
203
+ rbce = ALLOC(ruby_curl_easy);
199
204
 
200
205
  /* handler */
201
206
  rbce->curl = curl_easy_init();
@@ -209,7 +214,7 @@ static VALUE ruby_curl_easy_new(int argc, VALUE *argv, VALUE klass) {
209
214
  rbce->header_proc = Qnil;
210
215
  rbce->progress_proc = Qnil;
211
216
  rbce->debug_proc = Qnil;
212
- rbce->interface = Qnil;
217
+ rbce->interface_hm = Qnil;
213
218
  rbce->userpwd = Qnil;
214
219
  rbce->proxypwd = Qnil;
215
220
  rbce->headers = rb_hash_new();
@@ -404,8 +409,8 @@ static VALUE ruby_curl_easy_headers_get(VALUE self) {
404
409
  * Set the interface name to use as the outgoing network interface.
405
410
  * The name can be an interface name, an IP address or a host name.
406
411
  */
407
- static VALUE ruby_curl_easy_interface_set(VALUE self, VALUE interface) {
408
- CURB_OBJECT_SETTER(ruby_curl_easy, interface);
412
+ static VALUE ruby_curl_easy_interface_set(VALUE self, VALUE interface_hm) {
413
+ CURB_OBJECT_SETTER(ruby_curl_easy, interface_hm);
409
414
  }
410
415
 
411
416
  /*
@@ -416,7 +421,7 @@ static VALUE ruby_curl_easy_interface_set(VALUE self, VALUE interface) {
416
421
  * The name can be an interface name, an IP address or a host name.
417
422
  */
418
423
  static VALUE ruby_curl_easy_interface_get(VALUE self) {
419
- CURB_OBJECT_GETTER(ruby_curl_easy, interface);
424
+ CURB_OBJECT_GETTER(ruby_curl_easy, interface_hm);
420
425
  }
421
426
 
422
427
  /*
@@ -716,10 +721,11 @@ static VALUE ruby_curl_easy_post_body_get(VALUE self) {
716
721
  static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
717
722
  ruby_curl_easy *rbce;
718
723
  CURL *curl;
719
-
724
+ VALUE upload;
725
+
720
726
  Data_Get_Struct(self, ruby_curl_easy, rbce);
721
727
 
722
- VALUE upload = ruby_curl_upload_new(cCurlUpload);
728
+ upload = ruby_curl_upload_new(cCurlUpload);
723
729
  ruby_curl_upload_stream_set(upload,data);
724
730
 
725
731
  curl = rbce->curl;
@@ -745,10 +751,11 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
745
751
  if (rb_respond_to(data, rb_intern("read"))) {
746
752
  VALUE stat = rb_funcall(data, rb_intern("stat"), 0);
747
753
  if( stat ) {
754
+ VALUE size;
748
755
  if( rb_hash_aref(rbce->headers, rb_str_new2("Expect")) == Qnil ) {
749
756
  rb_hash_aset(rbce->headers, rb_str_new2("Expect"), rb_str_new2(""));
750
757
  }
751
- VALUE size = rb_funcall(stat, rb_intern("size"), 0);
758
+ size = rb_funcall(stat, rb_intern("size"), 0);
752
759
  curl_easy_setopt(curl, CURLOPT_INFILESIZE, FIX2INT(size));
753
760
  }
754
761
  else if( rb_hash_aref(rbce->headers, rb_str_new2("Transfer-Encoding")) == Qnil ) {
@@ -1474,6 +1481,7 @@ static VALUE cb_each_http_header(VALUE header, struct curl_slist **list) {
1474
1481
  VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce, VALUE *body_buffer, VALUE *header_buffer, struct curl_slist **hdrs ) {
1475
1482
  // TODO this could do with a bit of refactoring...
1476
1483
  CURL *curl;
1484
+ VALUE url;
1477
1485
 
1478
1486
  curl = rbce->curl;
1479
1487
 
@@ -1481,14 +1489,14 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce, VALUE *body_buffer, VALUE *hea
1481
1489
  rb_raise(eCurlErrError, "No URL supplied");
1482
1490
  }
1483
1491
 
1484
- VALUE url = rb_check_string_type(rbce->url);
1492
+ url = rb_check_string_type(rbce->url);
1485
1493
 
1486
1494
  // Need to configure the handler as per settings in rbce
1487
1495
  curl_easy_setopt(curl, CURLOPT_URL, StringValuePtr(url));
1488
1496
 
1489
1497
  // network stuff and auth
1490
- if (rbce->interface != Qnil) {
1491
- curl_easy_setopt(curl, CURLOPT_INTERFACE, StringValuePtr(rbce->interface));
1498
+ if (rbce->interface_hm != Qnil) {
1499
+ curl_easy_setopt(curl, CURLOPT_INTERFACE, StringValuePtr(rbce->interface_hm));
1492
1500
  } else {
1493
1501
  curl_easy_setopt(curl, CURLOPT_INTERFACE, NULL);
1494
1502
  }
@@ -1768,9 +1776,10 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce, VALUE bodybuf, V
1768
1776
  */
1769
1777
  static VALUE handle_perform(VALUE self, ruby_curl_easy *rbce) {
1770
1778
 
1779
+ VALUE ret;
1771
1780
  VALUE multi = ruby_curl_multi_new(cCurlMulti);
1772
1781
  ruby_curl_multi_add(multi, self);
1773
- VALUE ret = rb_funcall(multi, rb_intern("perform"), 0);
1782
+ ret = rb_funcall(multi, rb_intern("perform"), 0);
1774
1783
 
1775
1784
  /* check for errors in the easy response and raise exceptions if anything went wrong and their is no on_failure handler */
1776
1785
  if( rbce->last_result != 0 && rbce->failure_proc == Qnil ) {
@@ -1811,13 +1820,14 @@ static VALUE ruby_curl_easy_perform_get(VALUE self) {
1811
1820
  static VALUE ruby_curl_easy_perform_delete(VALUE self) {
1812
1821
  ruby_curl_easy *rbce;
1813
1822
  CURL *curl;
1823
+ VALUE retval;
1814
1824
 
1815
1825
  Data_Get_Struct(self, ruby_curl_easy, rbce);
1816
1826
  curl = rbce->curl;
1817
1827
 
1818
1828
  curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
1819
1829
 
1820
- VALUE retval = handle_perform(self,rbce);
1830
+ retval = handle_perform(self,rbce);
1821
1831
 
1822
1832
  curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
1823
1833
 
@@ -1921,13 +1931,14 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
1921
1931
  static VALUE ruby_curl_easy_perform_head(VALUE self) {
1922
1932
  ruby_curl_easy *rbce;
1923
1933
  CURL *curl;
1934
+ VALUE ret;
1924
1935
 
1925
1936
  Data_Get_Struct(self, ruby_curl_easy, rbce);
1926
1937
  curl = rbce->curl;
1927
1938
 
1928
1939
  curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
1929
1940
 
1930
- VALUE ret = handle_perform(self,rbce);
1941
+ ret = handle_perform(self,rbce);
1931
1942
 
1932
1943
  curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
1933
1944
  return ret;
@@ -2748,10 +2759,11 @@ static VALUE ruby_curl_easy_class_perform_head(int argc, VALUE *argv, VALUE klas
2748
2759
  */
2749
2760
  static VALUE ruby_curl_easy_class_perform_post(int argc, VALUE *argv, VALUE klass) {
2750
2761
  VALUE url, fields;
2762
+ VALUE c;
2751
2763
 
2752
2764
  rb_scan_args(argc, argv, "1*", &url, &fields);
2753
2765
 
2754
- VALUE c = ruby_curl_easy_new(1, &url, klass);
2766
+ c = ruby_curl_easy_new(1, &url, klass);
2755
2767
 
2756
2768
  if (argc > 1) {
2757
2769
  ruby_curl_easy_perform_post(argc - 1, &argv[1], c);
@@ -28,7 +28,7 @@ typedef struct {
28
28
  VALUE header_data; /* unless a block is supplied (they'll be nil) */
29
29
  VALUE progress_proc;
30
30
  VALUE debug_proc;
31
- VALUE interface;
31
+ VALUE interface_hm;
32
32
  VALUE userpwd;
33
33
  VALUE proxypwd;
34
34
  VALUE headers; /* ruby array of strings with headers to set */
@@ -124,6 +124,7 @@ VALUE eCurlErrInvalidPostField;
124
124
  VALUE rb_curl_easy_error(CURLcode code) {
125
125
  VALUE exclz;
126
126
  const char *exmsg = NULL;
127
+ VALUE results;
127
128
 
128
129
  switch (code) {
129
130
  case CURLE_UNSUPPORTED_PROTOCOL: /* 1 */
@@ -436,7 +437,7 @@ VALUE rb_curl_easy_error(CURLcode code) {
436
437
  exmsg = curl_easy_strerror(code);
437
438
  }
438
439
 
439
- VALUE results = rb_ary_new2(2);
440
+ results = rb_ary_new2(2);
440
441
  rb_ary_push(results, exclz);
441
442
  rb_ary_push(results, rb_str_new2(exmsg));
442
443
  return results;
@@ -449,6 +450,7 @@ void raise_curl_easy_error_exception(CURLcode code) {
449
450
  VALUE rb_curl_multi_error(CURLMcode code) {
450
451
  VALUE exclz;
451
452
  const char *exmsg = NULL;
453
+ VALUE results;
452
454
 
453
455
  switch(code) {
454
456
  case CURLM_CALL_MULTI_PERFORM: /* -1 */
@@ -485,9 +487,10 @@ VALUE rb_curl_multi_error(CURLMcode code) {
485
487
  exmsg = curl_multi_strerror(code);
486
488
  }
487
489
 
488
- VALUE results = rb_ary_new2(2);
490
+ results = rb_ary_new2(2);
489
491
  rb_ary_push(results, exclz);
490
492
  rb_ary_push(results, rb_str_new2(exmsg));
493
+
491
494
  return results;
492
495
  }
493
496
  void raise_curl_multi_error_exception(CURLMcode code) {
@@ -597,6 +600,14 @@ void init_curb_errors() {
597
600
  eCurlErrSSLShutdownFailed = rb_define_class_under(mCurlErr, "SSLShutdownFailed", eCurlErrError);
598
601
  eCurlErrSSH = rb_define_class_under(mCurlErr, "SSH", eCurlErrError);
599
602
 
603
+ mCurlErrCallMultiPerform = rb_define_class_under(mCurlErr, "MultiPerform", eCurlErrError);
604
+ mCurlErrBadHandle = rb_define_class_under(mCurlErr, "MultiBadHandle", eCurlErrError);
605
+ mCurlErrBadEasyHandle = rb_define_class_under(mCurlErr, "MultiBadEasyHandle", eCurlErrError);
606
+ mCurlErrOutOfMemory = rb_define_class_under(mCurlErr, "MultiOutOfMemory", eCurlErrError);
607
+ mCurlErrInternalError = rb_define_class_under(mCurlErr, "MultiInternalError", eCurlErrError);
608
+ mCurlErrBadSocket = rb_define_class_under(mCurlErr, "MultiBadSocket", eCurlErrError);
609
+ mCurlErrUnknownOption = rb_define_class_under(mCurlErr, "MultiUnknownOption", eCurlErrError);
610
+
600
611
  eCurlErrLDAPInvalidURL = rb_define_class_under(mCurlErr, "InvalidLDAPURLError", eCurlErrLDAPError);
601
612
 
602
613
  eCurlErrFileSizeExceeded = rb_define_class_under(mCurlErr, "FileSizeExceededError", eCurlErrError);
@@ -45,13 +45,14 @@ static void curl_multi_flush_easy(VALUE key, VALUE easy, ruby_curl_multi *rbcm)
45
45
  //rb_curl_multi_remove(rbcm, easy);
46
46
  CURLMcode result;
47
47
  ruby_curl_easy *rbce;
48
+ VALUE r;
48
49
  Data_Get_Struct(easy, ruby_curl_easy, rbce);
49
50
  result = curl_multi_remove_handle(rbcm->handle, rbce->curl);
50
51
  if (result != 0) {
51
52
  raise_curl_multi_error_exception(result);
52
53
  }
53
54
  // XXX: easy handle may not be finished yet... so don't clean it GC pass will get it next time
54
- VALUE r = rb_hash_delete( rbcm->requests, easy );
55
+ r = rb_hash_delete( rbcm->requests, easy );
55
56
  if( r != easy || r == Qnil ) {
56
57
  rb_raise(rb_eRuntimeError, "Critical:: Unable to remove easy from requests");
57
58
  }
@@ -114,10 +115,11 @@ static int ruby_curl_multi_requests_callback(VALUE key, VALUE value, VALUE resul
114
115
  */
115
116
  static VALUE ruby_curl_multi_requests(VALUE self) {
116
117
  ruby_curl_multi *rbcm;
117
-
118
+ VALUE result_array;
119
+
118
120
  Data_Get_Struct(self, ruby_curl_multi, rbcm);
119
121
 
120
- VALUE result_array = rb_ary_new();
122
+ result_array = rb_ary_new();
121
123
 
122
124
  // iterate over the requests hash, and stuff references into the array.
123
125
  rb_hash_foreach( rbcm->requests, ruby_curl_multi_requests_callback, result_array );
@@ -242,10 +244,10 @@ VALUE ruby_curl_multi_add(VALUE self, VALUE easy) {
242
244
  */
243
245
  VALUE ruby_curl_multi_remove(VALUE self, VALUE easy) {
244
246
  ruby_curl_multi *rbcm;
247
+ ruby_curl_easy *rbce;
245
248
 
246
249
  Data_Get_Struct(self, ruby_curl_multi, rbcm);
247
250
 
248
- ruby_curl_easy *rbce;
249
251
  Data_Get_Struct(easy, ruby_curl_easy, rbce);
250
252
 
251
253
  rb_curl_multi_remove(rbcm,easy);
@@ -255,23 +257,23 @@ VALUE ruby_curl_multi_remove(VALUE self, VALUE easy) {
255
257
  static void rb_curl_multi_remove(ruby_curl_multi *rbcm, VALUE easy) {
256
258
  CURLMcode result;
257
259
  ruby_curl_easy *rbce;
258
- Data_Get_Struct(easy, ruby_curl_easy, rbce);
259
-
260
- rbcm->active--;
260
+ VALUE r;
261
261
 
262
- //printf( "calling rb_curl_multi_remove: 0x%X, active: %d\n", (long)easy, rbcm->active );
262
+ Data_Get_Struct(easy, ruby_curl_easy, rbce);
263
263
 
264
264
  result = curl_multi_remove_handle(rbcm->handle, rbce->curl);
265
265
  if (result != 0) {
266
266
  raise_curl_multi_error_exception(result);
267
267
  }
268
268
 
269
+ rbcm->active--;
270
+
269
271
  ruby_curl_easy_cleanup( easy, rbce, rbce->bodybuf, rbce->headerbuf, rbce->curl_headers );
270
272
  rbce->headerbuf = Qnil;
271
273
  rbce->bodybuf = Qnil;
272
274
 
273
275
  // active should equal INT2FIX(RHASH(rbcm->requests)->tbl->num_entries)
274
- VALUE r = rb_hash_delete( rbcm->requests, easy );
276
+ r = rb_hash_delete( rbcm->requests, easy );
275
277
  if( r != easy || r == Qnil ) {
276
278
  rb_raise(rb_eRuntimeError, "Critical:: Unable to remove easy from requests");
277
279
  }
@@ -305,7 +307,7 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
305
307
 
306
308
  long response_code = -1;
307
309
  ruby_curl_easy *rbce = NULL;
308
-
310
+ VALUE ref;
309
311
  CURLcode ecode = curl_easy_getinfo(easy_handle, CURLINFO_PRIVATE, (char**)&rbce);
310
312
 
311
313
  if (ecode != 0) {
@@ -322,21 +324,24 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
322
324
 
323
325
  curl_easy_getinfo(rbce->curl, CURLINFO_RESPONSE_CODE, &response_code);
324
326
 
327
+ ref = rbce->self;
328
+ /* break reference */
329
+ rbce->self = Qnil;
330
+
325
331
  if (result != 0) {
326
332
  if (rbce->failure_proc != Qnil) {
327
- rb_funcall( rbce->failure_proc, idCall, 2, rbce->self, rb_curl_easy_error(result) );
333
+ rb_funcall( rbce->failure_proc, idCall, 2, ref, rb_curl_easy_error(result) );
328
334
  }
329
335
  }
330
336
  else if (rbce->success_proc != Qnil &&
331
337
  ((response_code >= 200 && response_code < 300) || response_code == 0)) {
332
338
  /* NOTE: we allow response_code == 0, in the case of non http requests e.g. reading from disk */
333
- rb_funcall( rbce->success_proc, idCall, 1, rbce->self );
339
+ rb_funcall( rbce->success_proc, idCall, 1, ref );
334
340
  }
335
341
  else if (rbce->failure_proc != Qnil &&
336
342
  (response_code >= 300 && response_code <= 999)) {
337
- rb_funcall( rbce->failure_proc, idCall, 2, rbce->self, rb_curl_easy_error(result) );
343
+ rb_funcall( rbce->failure_proc, idCall, 2, ref, rb_curl_easy_error(result) );
338
344
  }
339
- rbce->self = Qnil;
340
345
  }
341
346
 
342
347
  static void rb_curl_multi_read_info(VALUE self, CURLM *multi_handle) {
@@ -480,6 +480,8 @@ static VALUE ruby_curl_postfield_to_str(VALUE self) {
480
480
 
481
481
  /* =================== INIT LIB =====================*/
482
482
  void init_curb_postfield() {
483
+ VALUE sc;
484
+
483
485
  idCall = rb_intern("call");
484
486
 
485
487
  cCurlPostField = rb_define_class_under(mCurl, "PostField", rb_cObject);
@@ -488,7 +490,7 @@ void init_curb_postfield() {
488
490
  rb_define_singleton_method(cCurlPostField, "content", ruby_curl_postfield_new_content, -1);
489
491
  rb_define_singleton_method(cCurlPostField, "file", ruby_curl_postfield_new_file, -1);
490
492
 
491
- VALUE sc = rb_singleton_class(cCurlPostField);
493
+ sc = rb_singleton_class(cCurlPostField);
492
494
  rb_undef(sc, rb_intern("new"));
493
495
 
494
496
  rb_define_method(cCurlPostField, "name=", ruby_curl_postfield_name_set, 1);
@@ -4,10 +4,16 @@ dir_config('curl')
4
4
 
5
5
  if find_executable('curl-config')
6
6
  $CFLAGS << " #{`curl-config --cflags`.strip}"
7
- $LIBS << " #{`curl-config --libs`.strip}"
7
+ if ENV['STATIC_BUILD']
8
+ $LIBS << " #{`curl-config --static-libs`.strip}"
9
+ else
10
+ $LIBS << " #{`curl-config --libs`.strip}"
11
+ end
8
12
  ca_bundle_path=`curl-config --ca`.strip
9
- $defs.push( %{-D HAVE_CURL_CONFIG_CA} )
10
- $defs.push( %{-D CURL_CONFIG_CA='#{ca_bundle_path.inspect}'} )
13
+ if !ca_bundle_path.nil? and ca_bundle_path != ''
14
+ $defs.push( %{-D HAVE_CURL_CONFIG_CA} )
15
+ $defs.push( %{-D CURL_CONFIG_CA='#{ca_bundle_path.inspect}'} )
16
+ end
11
17
  elsif !have_library('curl') or !have_header('curl/curl.h')
12
18
  fail <<-EOM
13
19
  Can't find libcurl or curl/curl.h
@@ -17,6 +23,17 @@ elsif !have_library('curl') or !have_header('curl/curl.h')
17
23
  EOM
18
24
  end
19
25
 
26
+ # Check arch flags
27
+ archs = $CFLAGS.scan(/-arch\s(.*?)\s/).first # get the first arch flag
28
+ if archs and archs.size >= 1
29
+ # need to reduce the number of archs...
30
+ # guess the first one is correct... at least the first one is probably the ruby installed arch...
31
+ # this could lead to compiled binaries that crash at runtime...
32
+ $CFLAGS.gsub!(/-arch\s(.*?)\s/,' ')
33
+ $CFLAGS << " -arch #{archs.first}"
34
+ puts "Selected arch: #{archs.first}"
35
+ end
36
+
20
37
  def define(s)
21
38
  $defs.push( format("-D HAVE_%s", s.to_s.upcase) )
22
39
  end
@@ -0,0 +1,10 @@
1
+ # From safis http://github.com/taf2/curb/issues#issue/5
2
+ # irb: require 'curb'
3
+ # irb: multi = Curl::Multi.new
4
+ # irb: exit
5
+ # <main>:47140: [BUG] Bus Error
6
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__),'..','ext'))
7
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__),'..','lib'))
8
+ require 'curb'
9
+ multi = Curl::Multi.new
10
+ exit
@@ -9,7 +9,7 @@ class TestCurbCurlDownload < Test::Unit::TestCase
9
9
 
10
10
  def test_download_url_to_file
11
11
  dl_url = "http://127.0.0.1:9129/ext/curb_easy.c"
12
- dl_path = File.join("/tmp/dl_url_test.file")
12
+ dl_path = File.join(Dir::tmpdir, "dl_url_test.file")
13
13
 
14
14
  curb = Curl::Easy.download(dl_url, dl_path)
15
15
  assert File.exist?(dl_path)
@@ -20,7 +20,7 @@ class TestCurbCurlDownload < Test::Unit::TestCase
20
20
 
21
21
  def test_download_bad_url_gives_404
22
22
  dl_url = "http://127.0.0.1:9129/this_file_does_not_exist.html"
23
- dl_path = File.join("/tmp/dl_url_test.file")
23
+ dl_path = File.join(Dir::tmpdir, "dl_url_test.file")
24
24
 
25
25
  curb = Curl::Easy.download(dl_url, dl_path)
26
26
  assert_equal Curl::Easy, curb.class
@@ -379,6 +379,39 @@ class TestCurbCurlMulti < Test::Unit::TestCase
379
379
  assert_equal "POST\nhello=world", e2.body_str
380
380
  end
381
381
 
382
+ def test_remove_exception_is_descriptive
383
+ m = Curl::Multi.new
384
+ c = Curl::Easy.new("http://blah.com")
385
+ m.remove(c)
386
+ rescue => e
387
+ assert_equal 'Invalid easy handle', e.message
388
+ assert_equal 0, m.requests.size
389
+ end
390
+
391
+ def test_retry_easy_handle
392
+ m = Curl::Multi.new
393
+
394
+ tries = 2
395
+
396
+ c1 = Curl::Easy.new('http://127.9.9.9') do |curl|
397
+ curl.on_failure {|c,e|
398
+ assert_equal [Curl::Err::ConnectionFailedError, "Couldn't connect to server"], e
399
+ if tries > 0
400
+ tries -= 1
401
+ m.add(c)
402
+ end
403
+ }
404
+ end
405
+
406
+ tries -= 1
407
+ m.add(c1)
408
+
409
+ while not m.requests.empty?
410
+ m.perform
411
+ end
412
+ assert_equal 0, tries
413
+ end
414
+
382
415
  include TestServerMethods
383
416
 
384
417
  def setup
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: curb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.4.0
4
+ version: 0.5.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ross Bamford
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-09-23 00:00:00 -04:00
13
+ date: 2009-11-23 00:00:00 -05:00
14
14
  default_executable:
15
15
  dependencies: []
16
16
 
@@ -29,22 +29,21 @@ files:
29
29
  - Rakefile
30
30
  - doc.rb
31
31
  - ext/extconf.rb
32
- - lib/curb.rb
33
32
  - lib/curl.rb
33
+ - lib/curb.rb
34
34
  - ext/curb.c
35
+ - ext/curb_upload.c
36
+ - ext/curb_postfield.c
35
37
  - ext/curb_easy.c
36
- - ext/curb_errors.c
37
38
  - ext/curb_multi.c
38
- - ext/curb_postfield.c
39
- - ext/curb_upload.c
40
- - ext/curb.h
41
- - ext/curb_config.h
42
- - ext/curb_easy.h
39
+ - ext/curb_errors.c
43
40
  - ext/curb_errors.h
44
- - ext/curb_macros.h
45
41
  - ext/curb_multi.h
42
+ - ext/curb.h
43
+ - ext/curb_easy.h
46
44
  - ext/curb_postfield.h
47
45
  - ext/curb_upload.h
46
+ - ext/curb_macros.h
48
47
  has_rdoc: true
49
48
  homepage: http://curb.rubyforge.org/
50
49
  licenses: []
@@ -71,19 +70,20 @@ required_rubygems_version: !ruby/object:Gem::Requirement
71
70
  requirements: []
72
71
 
73
72
  rubyforge_project: curb
74
- rubygems_version: 1.3.4
73
+ rubygems_version: 1.3.5
75
74
  signing_key:
76
75
  specification_version: 3
77
76
  summary: Ruby libcurl bindings
78
77
  test_files:
79
- - tests/alltests.rb
80
- - tests/bug_curb_easy_blocks_ruby_threads.rb
81
- - tests/bug_instance_post_differs_from_class_post.rb
82
78
  - tests/bug_require_last_or_segfault.rb
83
79
  - tests/helper.rb
80
+ - tests/tc_curl_postfield.rb
81
+ - tests/bug_instance_post_differs_from_class_post.rb
82
+ - tests/bug_multi_segfault.rb
83
+ - tests/alltests.rb
84
84
  - tests/require_last_or_segfault_script.rb
85
+ - tests/unittests.rb
86
+ - tests/tc_curl_multi.rb
85
87
  - tests/tc_curl_download.rb
86
88
  - tests/tc_curl_easy.rb
87
- - tests/tc_curl_multi.rb
88
- - tests/tc_curl_postfield.rb
89
- - tests/unittests.rb
89
+ - tests/bug_curb_easy_blocks_ruby_threads.rb
@@ -1,59 +0,0 @@
1
- #ifndef CURB_CONFIG_H
2
- #define CURB_CONFIG_H
3
- #define HAVE_CURL_CONFIG_CA 1
4
- #define CURL_CONFIG_CA ""
5
- #define HAVE_CURLINFO_REDIRECT_TIME 1
6
- #define HAVE_CURLINFO_RESPONSE_CODE 1
7
- #define HAVE_CURLINFO_FILETIME 1
8
- #define HAVE_CURLINFO_REDIRECT_COUNT 1
9
- #define HAVE_CURLINFO_OS_ERRNO 1
10
- #define HAVE_CURLINFO_NUM_CONNECTS 1
11
- #define HAVE_CURLINFO_FTP_ENTRY_PATH 1
12
- #define HAVE_CURL_VERSION_SSL 1
13
- #define HAVE_CURL_VERSION_LIBZ 1
14
- #define HAVE_CURL_VERSION_NTLM 1
15
- #define HAVE_CURL_VERSION_GSSNEGOTIATE 1
16
- #define HAVE_CURL_VERSION_DEBUG 1
17
- #define HAVE_CURL_VERSION_ASYNCHDNS 1
18
- #define HAVE_CURL_VERSION_SPNEGO 1
19
- #define HAVE_CURL_VERSION_LARGEFILE 1
20
- #define HAVE_CURL_VERSION_IDN 1
21
- #define HAVE_CURL_VERSION_SSPI 1
22
- #define HAVE_CURL_VERSION_CONV 1
23
- #define HAVE_CURLPROXY_HTTP 1
24
- #define HAVE_CURLPROXY_SOCKS4 1
25
- #define HAVE_CURLPROXY_SOCKS5 1
26
- #define HAVE_CURLAUTH_BASIC 1
27
- #define HAVE_CURLAUTH_DIGEST 1
28
- #define HAVE_CURLAUTH_GSSNEGOTIATE 1
29
- #define HAVE_CURLAUTH_NTLM 1
30
- #define HAVE_CURLAUTH_ANYSAFE 1
31
- #define HAVE_CURLAUTH_ANY 1
32
- #define HAVE_CURLE_TFTP_NOTFOUND 1
33
- #define HAVE_CURLE_TFTP_PERM 1
34
- #define HAVE_CURLE_TFTP_DISKFULL 1
35
- #define HAVE_CURLE_TFTP_ILLEGAL 1
36
- #define HAVE_CURLE_TFTP_UNKNOWNID 1
37
- #define HAVE_CURLE_TFTP_EXISTS 1
38
- #define HAVE_CURLE_TFTP_NOSUCHUSER 1
39
- #define HAVE_CURLE_SEND_FAIL_REWIND 1
40
- #define HAVE_CURLE_SSL_ENGINE_INITFAILED 1
41
- #define HAVE_CURLE_LOGIN_DENIED 1
42
- #define HAVE_CURLMOPT_MAXCONNECTS 1
43
- #define HAVE_CURLE_CONV_FAILED 1
44
- #define HAVE_CURLE_CONV_REQD 1
45
- #define HAVE_CURLE_SSL_CACERT_BADFILE 1
46
- #define HAVE_CURLE_REMOTE_FILE_NOT_FOUND 1
47
- #define HAVE_CURLE_SSH 1
48
- #define HAVE_CURLE_SSL_SHUTDOWN_FAILED 1
49
- #define HAVE_CURLE_AGAIN 1
50
- #define HAVE_CURLE_SSL_CRL_BADFILE 1
51
- #define HAVE_CURLE_SSL_ISSUER_ERROR 1
52
- #define HAVE_CURLM_BAD_SOCKET 1
53
- #define HAVE_CURLM_UNKNOWN_OPTION 1
54
- #define HAVE_CURL_MULTI_TIMEOUT 1
55
- #define HAVE_CURL_MULTI_FDSET 1
56
- #define HAVE_CURL_MULTI_PERFORM 1
57
- #define HAVE_RUBY19_ST_H 1
58
- #define HAVE_CURL_EASY_ESCAPE 1
59
- #endif