curb 0.5.1.0 → 0.5.4.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/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.1.0"
24
- #define CURB_VER_NUM 510
23
+ #define CURB_VERSION "0.5.4.0"
24
+ #define CURB_VER_NUM 540
25
25
  #define CURB_VER_MAJ 0
26
26
  #define CURB_VER_MIN 5
27
- #define CURB_VER_MIC 1
27
+ #define CURB_VER_MIC 4
28
28
  #define CURB_VER_PATCH 0
29
29
 
30
30
 
data/ext/curb_easy.c CHANGED
@@ -1954,6 +1954,27 @@ static VALUE ruby_curl_easy_set_head_option(VALUE self, VALUE onoff) {
1954
1954
 
1955
1955
  return onoff;
1956
1956
  }
1957
+ /*
1958
+ *call-seq:
1959
+ * easy = Curl::Easy.new("url") do|c|
1960
+ * c.delete = true
1961
+ * end
1962
+ * easy.perform
1963
+ */
1964
+ static VALUE ruby_curl_easy_set_delete_option(VALUE self, VALUE onoff) {
1965
+ ruby_curl_easy *rbce;
1966
+
1967
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
1968
+
1969
+ if( onoff == Qtrue ) {
1970
+ curl_easy_setopt(rbce->curl, CURLOPT_CUSTOMREQUEST, "DELETE");
1971
+ }
1972
+ else {
1973
+ curl_easy_setopt(rbce->curl, CURLOPT_CUSTOMREQUEST, NULL);
1974
+ }
1975
+
1976
+ return onoff;
1977
+ }
1957
1978
 
1958
1979
  /*
1959
1980
  * call-seq:
@@ -2554,11 +2575,16 @@ static VALUE ruby_curl_easy_inspect(VALUE self) {
2554
2575
  char buf[64];
2555
2576
  ruby_curl_easy *rbce;
2556
2577
  Data_Get_Struct(self, ruby_curl_easy, rbce);
2557
- // "#<Net::HTTP http://www.google.com/:80 open=false>"
2558
- snprintf(buf,sizeof(buf),"#<Curl::Easy %s", RSTRING_PTR(rbce->url));
2559
- size_t r = strlen(buf);
2560
- buf[r-1] = '>';
2561
- return rb_str_new(buf,r);
2578
+ /* if we don't have a url set... we'll crash... */
2579
+ if(rbce->url != Qnil && rb_type(rbce->url) == T_STRING) {
2580
+ size_t len = 13+((RSTRING_LEN(rbce->url) > 50) ? 50 : RSTRING_LEN(rbce->url));
2581
+ /* "#<Net::HTTP http://www.google.com/:80 open=false>" */
2582
+ memcpy(buf,"#<Curl::Easy ", 13);
2583
+ memcpy(buf+13,RSTRING_PTR(rbce->url), (len - 13));
2584
+ buf[len-1] = '>';
2585
+ return rb_str_new(buf,len);
2586
+ }
2587
+ return rb_str_new2("#<Curl::Easy");
2562
2588
  }
2563
2589
 
2564
2590
 
@@ -2573,13 +2599,17 @@ static VALUE ruby_curl_easy_inspect(VALUE self) {
2573
2599
  * converted to their "URL escaped" version (%NN where NN is a
2574
2600
  * two-digit hexadecimal number).
2575
2601
  */
2576
- static VALUE ruby_curl_easy_escape(VALUE self, VALUE str) {
2602
+ static VALUE ruby_curl_easy_escape(VALUE self, VALUE svalue) {
2577
2603
  ruby_curl_easy *rbce;
2578
2604
  char *result;
2579
2605
  VALUE rresult;
2606
+ VALUE str = svalue;
2580
2607
 
2581
2608
  Data_Get_Struct(self, ruby_curl_easy, rbce);
2582
2609
 
2610
+ /* NOTE: make sure the value is a string, if not call to_s */
2611
+ if( rb_type(str) != T_STRING ) { str = rb_funcall(str,rb_intern("to_s"),0); }
2612
+
2583
2613
  #if (LIBCURL_VERSION_NUM >= 0x070f04)
2584
2614
  result = (char*)curl_easy_escape(rbce->curl, StringValuePtr(str), RSTRING_LEN(str));
2585
2615
  #else
@@ -2847,6 +2877,7 @@ void init_curb_easy() {
2847
2877
  rb_define_method(cCurlEasy, "http_head", ruby_curl_easy_perform_head, 0);
2848
2878
  rb_define_method(cCurlEasy, "http_put", ruby_curl_easy_perform_put, 1);
2849
2879
  rb_define_method(cCurlEasy, "head=", ruby_curl_easy_set_head_option, 1);
2880
+ rb_define_method(cCurlEasy, "delete=", ruby_curl_easy_set_delete_option, 1);
2850
2881
 
2851
2882
  /* Post-perform info methods */
2852
2883
  rb_define_method(cCurlEasy, "body_str", ruby_curl_easy_body_str_get, 0);
data/lib/curb.rb CHANGED
@@ -63,22 +63,11 @@ module Curl
63
63
  #
64
64
  # Blocking call to fetch multiple url's in parallel.
65
65
  def get(urls, easy_options={}, multi_options={}, &blk)
66
- m = Curl::Multi.new
67
- # configure the multi handle
68
- multi_options.each do|k,v|
69
- m.send("#{k}=", v)
70
- end
71
-
72
- # create and configure each easy handle
66
+ url_confs = []
73
67
  urls.each do|url|
74
- c = Curl::Easy.new(url)
75
- easy_options.each do|k,v|
76
- c.send("#{k}=",v)
77
- end
78
- c.on_complete {|curl| blk.call curl } if blk
79
- m.add(c)
68
+ url_confs << {:url => url, :method => :get}.merge(easy_options)
80
69
  end
81
- m.perform
70
+ self.http(url_confs, multi_options) {|c,code,method| blk.call(c) }
82
71
  end
83
72
 
84
73
  # call-seq:
@@ -97,25 +86,95 @@ module Curl
97
86
  # easy_options: are a set of common options to set on all easy handles
98
87
  # multi_options: options to set on the Curl::Multi handle
99
88
  #
100
- def post(urls_with_config, easy_options, multi_options, &blk)
89
+ def post(urls_with_config, easy_options={}, multi_options={}, &blk)
90
+ url_confs = []
91
+ urls_with_config.each do|uconf|
92
+ url_confs << uconf.merge(:method => :post).merge(easy_options)
93
+ end
94
+ self.http(url_confs, multi_options) {|c,code,method| blk.call(c) }
95
+ end
96
+
97
+ # call-seq:
98
+ #
99
+ # Curl::Multi.put([{:url => 'url1', :put_data => "some message"},
100
+ # {:url => 'url2', :put_data => IO.read('filepath')},
101
+ # {:url => 'url3', :put_data => "maybe another string or socket?"],
102
+ # {:follow_location => true},
103
+ # {:pipeline => true }) do|easy|
104
+ # easy_handle_on_request_complete
105
+ # end
106
+ #
107
+ # Blocking call to POST multiple form's in parallel.
108
+ #
109
+ # urls_with_config: is a hash of url's pointing to the postfields to send
110
+ # easy_options: are a set of common options to set on all easy handles
111
+ # multi_options: options to set on the Curl::Multi handle
112
+ #
113
+ def put(urls_with_config, easy_options={}, multi_options={}, &blk)
114
+ url_confs = []
115
+ urls_with_config.each do|uconf|
116
+ url_confs << uconf.merge(:method => :put).merge(easy_options)
117
+ end
118
+ self.http(url_confs, multi_options) {|c,code,method| blk.call(c) }
119
+ end
120
+
121
+
122
+ # call-seq:
123
+ #
124
+ # Curl::Multi.http( [
125
+ # { :url => 'url1', :method => :post,
126
+ # :post_fields => {'field1' => 'value1', 'field2' => 'value2'} },
127
+ # { :url => 'url2', :method => :get,
128
+ # :follow_location => true, :max_redirects => 3 },
129
+ # { :url => 'url3', :method => :put, :put_data => File.open('file.txt','rb') },
130
+ # { :url => 'url4', :method => :head }
131
+ # ], {:pipeline => true})
132
+ #
133
+ # Blocking call to issue multiple HTTP requests with varying verb's.
134
+ #
135
+ # urls_with_config: is a hash of url's pointing to the easy handle options as well as the special option :method, that can by one of [:get, :post, :put, :delete, :head], when no verb is provided e.g. :method => nil -> GET is used
136
+ # multi_options: options for the multi handle
137
+ # blk: a callback, that yeilds when a handle is completed
138
+ #
139
+ def http(urls_with_config, multi_options={}, &blk)
101
140
  m = Curl::Multi.new
102
141
  # configure the multi handle
103
- multi_options.each do|k,v|
104
- m.send("#{k}=", v)
105
- end
142
+ multi_options.each { |k,v| m.send("#{k}=", v) }
106
143
 
107
144
  urls_with_config.each do|conf|
108
145
  c = conf.dup # avoid being destructive to input
109
- url = c.delete(:url)
110
- fields = c.delete(:post_fields)
111
- easy = Curl::Easy.new(url)
112
- # set the post post using the url fields
113
- easy.post_body = fields.map{|f,k| "#{easy.escape(f)}=#{easy.escape(k)}"}.join('&')
114
- # configure the easy handle
115
- easy_options.each do|k,v|
116
- easy.send("#{k}=",v)
146
+ url = c.delete(:url)
147
+ method = c.delete(:method)
148
+ headers = c.delete(:headers)
149
+
150
+ easy = Curl::Easy.new(url)
151
+
152
+ case method
153
+ when :post
154
+ fields = c.delete(:post_fields)
155
+ # set the post post using the url fields
156
+ easy.post_body = fields.map{|f,k| "#{easy.escape(f)}=#{easy.escape(k)}"}.join('&')
157
+ when :put
158
+ easy.put_data = c.delete(:put_data)
159
+ when :head
160
+ easy.head = true
161
+ when :delete
162
+ easy.delete = true
163
+ when :get
164
+ else
165
+ # XXX: nil is treated like a GET
117
166
  end
118
- easy.on_complete {|curl| blk.call curl } if blk
167
+
168
+ # headers is a special key
169
+ headers.each {|k,v| easy.headers[k] = v } if headers
170
+
171
+ #
172
+ # use the remaining options as specific configuration to the easy handle
173
+ # bad options should raise an undefined method error
174
+ #
175
+ c.each { |k,v| easy.send("#{k}=",v) }
176
+
177
+ easy.on_complete {|curl,code| blk.call(curl,code,method) } if blk
119
178
  m.add(easy)
120
179
  end
121
180
  m.perform
@@ -145,6 +145,15 @@ class TestCurbCurlEasy < Test::Unit::TestCase
145
145
 
146
146
  assert_not_equal c.last_effective_url, c.url
147
147
  end
148
+
149
+ def test_http_get_block
150
+ curl = Curl::Easy.http_get(TestServlet.url) do|c|
151
+ c.follow_location = true
152
+ c.max_redirects = 3
153
+ end
154
+ assert_equal curl.url, curl.last_effective_url
155
+ assert_equal 'GET', curl.body_str
156
+ end
148
157
 
149
158
  def test_local_port_01
150
159
  c = Curl::Easy.new($TEST_URL)
@@ -325,6 +325,40 @@ class TestCurbCurlMulti < Test::Unit::TestCase
325
325
  end
326
326
  end
327
327
 
328
+ def test_multi_easy_put_01
329
+ urls = [{ :url => TestServlet.url, :method => :put, :put_data => "message",
330
+ :headers => {'Content-Type' => 'application/json' } },
331
+ { :url => TestServlet.url, :method => :put, :put_data => "message",
332
+ :headers => {'Content-Type' => 'application/json' } }]
333
+ Curl::Multi.put(urls, {}, {:pipeline => true}) do|easy|
334
+ assert_match /PUT/, easy.body_str
335
+ assert_match /message/, easy.body_str
336
+ end
337
+ end
338
+
339
+ def test_multi_easy_http_01
340
+ urls = [
341
+ { :url => TestServlet.url + '?q=1', :method => :post, :post_fields => {'field1' => 'value1', 'k' => 'j'}},
342
+ { :url => TestServlet.url + '?q=2', :method => :post, :post_fields => {'field2' => 'value2', 'foo' => 'bar', 'i' => 'j' }},
343
+ { :url => TestServlet.url + '?q=3', :method => :post, :post_fields => {'field3' => 'value3', 'field4' => 'value4'}},
344
+ { :url => TestServlet.url, :method => :put, :put_data => "message",
345
+ :headers => {'Content-Type' => 'application/json' } },
346
+ { :url => TestServlet.url, :method => :get }
347
+ ]
348
+ Curl::Multi.http(urls, {:pipeline => true}) do|easy, code, method|
349
+ assert_equal nil, code
350
+ case method
351
+ when :post
352
+ assert_match /POST/, easy.body_str
353
+ when :get
354
+ assert_match /GET/, easy.body_str
355
+ when :put
356
+ assert_match /PUT/, easy.body_str
357
+ end
358
+ #puts "#{easy.body_str.inspect}, #{method.inspect}, #{code.inspect}"
359
+ end
360
+ end
361
+
328
362
  def test_mutli_recieves_500
329
363
  m = Curl::Multi.new
330
364
  e = Curl::Easy.new("http://127.0.0.1:9129/methods")
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.1.0
4
+ version: 0.5.4.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-08-11 00:00:00 -04:00
13
+ date: 2009-09-23 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies: []
16
16