curb 0.3.7 → 0.4.2.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.

@@ -1,7 +1,7 @@
1
1
  /* curb_errors.h - Ruby exception types for curl errors
2
- * Copyright (c)2006 Ross Bamford.
2
+ * Copyright (c)2006 Ross Bamford.
3
3
  * Licensed under the Ruby License. See LICENSE for details.
4
- *
4
+ *
5
5
  * $Id: curb_errors.h 4 2006-11-17 18:35:31Z roscopeco $
6
6
  */
7
7
  #ifndef __CURB_ERRORS_H
@@ -1,7 +1,7 @@
1
1
  /* curb_easy.c - Curl easy mode
2
- * Copyright (c)2008 Todd A. Fisher.
2
+ * Copyright (c)2008 Todd A. Fisher.
3
3
  * Licensed under the Ruby License. See LICENSE for details.
4
- *
4
+ *
5
5
  * $Id$
6
6
  */
7
7
 
@@ -66,17 +66,18 @@ static void curl_multi_free(ruby_curl_multi *rbcm) {
66
66
  //rb_hash_clear(rbcm->requests)
67
67
  rbcm->requests = Qnil;
68
68
  }
69
+ free(rbcm);
69
70
  }
70
71
 
71
72
  /*
72
73
  * call-seq:
73
74
  * Curl::Multi.new => #<Curl::Easy...>
74
- *
75
+ *
75
76
  * Create a new Curl::Multi instance
76
77
  */
77
- static VALUE ruby_curl_multi_new(VALUE self) {
78
+ static VALUE ruby_curl_multi_new(VALUE klass) {
78
79
  VALUE new_curlm;
79
-
80
+
80
81
  ruby_curl_multi *rbcm = ALLOC(ruby_curl_multi);
81
82
 
82
83
  rbcm->handle = curl_multi_init();
@@ -85,8 +86,8 @@ static VALUE ruby_curl_multi_new(VALUE self) {
85
86
 
86
87
  rbcm->active = 0;
87
88
  rbcm->running = 0;
88
-
89
- new_curlm = Data_Wrap_Struct(cCurlMulti, curl_multi_mark, curl_multi_free, rbcm);
89
+
90
+ new_curlm = Data_Wrap_Struct(klass, curl_multi_mark, curl_multi_free, rbcm);
90
91
 
91
92
  return new_curlm;
92
93
  }
@@ -179,7 +180,7 @@ static VALUE ruby_curl_multi_add(VALUE self, VALUE easy) {
179
180
  * easy = Curl::Easy.new('url')
180
181
  *
181
182
  * multi.add(easy)
182
- *
183
+ *
183
184
  * # sometime later
184
185
  * multi.remove(easy)
185
186
  *
@@ -203,7 +204,7 @@ static void rb_curl_multi_remove(ruby_curl_multi *rbcm, VALUE easy) {
203
204
  CURLMcode result;
204
205
  ruby_curl_easy *rbce;
205
206
  Data_Get_Struct(easy, ruby_curl_easy, rbce);
206
-
207
+
207
208
  rbcm->active--;
208
209
 
209
210
  //printf( "calling rb_curl_multi_remove: 0x%X, active: %d\n", (long)easy, rbcm->active );
@@ -212,7 +213,7 @@ static void rb_curl_multi_remove(ruby_curl_multi *rbcm, VALUE easy) {
212
213
  if (result != 0) {
213
214
  raise_curl_multi_error_exception(result);
214
215
  }
215
-
216
+
216
217
  ruby_curl_easy_cleanup( easy, rbce, rbce->bodybuf, rbce->headerbuf, rbce->curl_headers );
217
218
  rbce->headerbuf = Qnil;
218
219
  rbce->bodybuf = Qnil;
@@ -248,15 +249,15 @@ static void rb_curl_multi_read_info(VALUE self, CURLM *multi_handle) {
248
249
  ruby_curl_multi_remove( self, rbce->self );
249
250
 
250
251
  if (rbce->complete_proc != Qnil) {
251
- rb_funcall( rbce->complete_proc, idCall, 1, self );
252
+ rb_funcall( rbce->complete_proc, idCall, 1, rbce->self );
252
253
  }
253
254
 
254
255
  long response_code = -1;
255
256
  curl_easy_getinfo(rbce->curl, CURLINFO_RESPONSE_CODE, &response_code);
256
-
257
+
257
258
  if (result != 0) {
258
259
  if (rbce->failure_proc != Qnil) {
259
- rb_funcall( rbce->failure_proc, idCall, 1, rbce->self );
260
+ rb_funcall( rbce->failure_proc, idCall, 2, rbce->self, INT2FIX(result) );
260
261
  }
261
262
  }
262
263
  else if (rbce->success_proc != Qnil &&
@@ -266,7 +267,7 @@ static void rb_curl_multi_read_info(VALUE self, CURLM *multi_handle) {
266
267
  }
267
268
  else if (rbce->failure_proc != Qnil &&
268
269
  (response_code >= 300 && response_code <= 999)) {
269
- rb_funcall( rbce->failure_proc, idCall, 1, rbce->self );
270
+ rb_funcall( rbce->failure_proc, idCall, 2, rbce->self, INT2FIX(result) );
270
271
  }
271
272
  rbce->self = Qnil;
272
273
  }
@@ -320,7 +321,7 @@ static VALUE ruby_curl_multi_perform(VALUE self) {
320
321
 
321
322
  rb_curl_multi_run( self, rbcm->handle, &(rbcm->running) );
322
323
 
323
- while(rbcm->running) {
324
+ while(rbcm->running) {
324
325
  FD_ZERO(&fdread);
325
326
  FD_ZERO(&fdwrite);
326
327
  FD_ZERO(&fdexcep);
@@ -331,7 +332,7 @@ static VALUE ruby_curl_multi_perform(VALUE self) {
331
332
  raise_curl_multi_error_exception(mcode);
332
333
  }
333
334
 
334
- #ifdef HAVE_CURL_MULTI_TIMEOUT
335
+ #ifdef HAVE_CURL_MULTI_TIMEOUT
335
336
  /* get the curl suggested time out */
336
337
  mcode = curl_multi_timeout(rbcm->handle, &timeout);
337
338
  if (mcode != CURLM_OK) {
@@ -353,7 +354,7 @@ static VALUE ruby_curl_multi_perform(VALUE self) {
353
354
  if (rb_block_given_p()) {
354
355
  rb_yield(self);
355
356
  }
356
-
357
+
357
358
  tv.tv_sec = timeout / 1000;
358
359
  tv.tv_usec = (timeout * 1000) % 1000000;
359
360
 
@@ -376,7 +377,7 @@ void init_curb_multi() {
376
377
  cCurlMulti = rb_define_class_under(mCurl, "Multi", rb_cObject);
377
378
 
378
379
  /* Class methods */
379
- rb_define_singleton_method(cCurlMulti, "new", ruby_curl_multi_new, -1);
380
+ rb_define_singleton_method(cCurlMulti, "new", ruby_curl_multi_new, 0);
380
381
 
381
382
  /* Instnace methods */
382
383
  rb_define_method(cCurlMulti, "max_connects=", ruby_curl_multi_max_connects, 1);
@@ -1,7 +1,7 @@
1
1
  /* curb_multi.h - Curl easy mode
2
- * Copyright (c)2008 Todd A. Fisher.
2
+ * Copyright (c)2008 Todd A. Fisher.
3
3
  * Licensed under the Ruby License. See LICENSE for details.
4
- *
4
+ *
5
5
  * $Id$
6
6
  */
7
7
  #ifndef __CURB_MULTI_H
@@ -0,0 +1,56 @@
1
+ /* curb_upload.c - Curl upload handle
2
+ * Copyright (c)2009 Todd A Fisher.
3
+ * Licensed under the Ruby License. See LICENSE for details.
4
+ */
5
+ #include "curb_upload.h"
6
+ extern VALUE mCurl;
7
+ VALUE cCurlUpload;
8
+
9
+ static void curl_upload_mark(ruby_curl_upload *rbcu) {
10
+ if (rbcu->stream) rb_gc_mark(rbcu->stream);
11
+ }
12
+ static void curl_upload_free(ruby_curl_upload *rbcu) {
13
+ free(rbcu);
14
+ }
15
+
16
+ VALUE ruby_curl_upload_new(VALUE klass) {
17
+ VALUE upload;
18
+ ruby_curl_upload *rbcu = ALLOC(ruby_curl_upload);
19
+ rbcu->stream = Qnil;
20
+ rbcu->offset = 0;
21
+ upload = Data_Wrap_Struct(klass, curl_upload_mark, curl_upload_free, rbcu);
22
+ return upload;
23
+ }
24
+
25
+ VALUE ruby_curl_upload_stream_set(VALUE self, VALUE stream) {
26
+ ruby_curl_upload *rbcu;
27
+ Data_Get_Struct(self, ruby_curl_upload, rbcu);
28
+ rbcu->stream = stream;
29
+ return stream;
30
+ }
31
+ VALUE ruby_curl_upload_stream_get(VALUE self) {
32
+ ruby_curl_upload *rbcu;
33
+ Data_Get_Struct(self, ruby_curl_upload, rbcu);
34
+ return rbcu->stream;
35
+ }
36
+ VALUE ruby_curl_upload_offset_set(VALUE self, VALUE offset) {
37
+ ruby_curl_upload *rbcu;
38
+ Data_Get_Struct(self, ruby_curl_upload, rbcu);
39
+ rbcu->offset = FIX2INT(offset);
40
+ return offset;
41
+ }
42
+ VALUE ruby_curl_upload_offset_get(VALUE self) {
43
+ ruby_curl_upload *rbcu;
44
+ Data_Get_Struct(self, ruby_curl_upload, rbcu);
45
+ return INT2FIX(rbcu->offset);
46
+ }
47
+
48
+ /* =================== INIT LIB =====================*/
49
+ void init_curb_upload() {
50
+ cCurlUpload = rb_define_class_under(mCurl, "Upload", rb_cObject);
51
+ rb_define_singleton_method(cCurlUpload, "new", ruby_curl_upload_new, 0);
52
+ rb_define_method(cCurlUpload, "stream=", ruby_curl_upload_stream_set, 1);
53
+ rb_define_method(cCurlUpload, "stream", ruby_curl_upload_stream_get, 0);
54
+ rb_define_method(cCurlUpload, "offset=", ruby_curl_upload_offset_set, 1);
55
+ rb_define_method(cCurlUpload, "offset", ruby_curl_upload_offset_get, 0);
56
+ }
@@ -0,0 +1,30 @@
1
+ /* curb_upload.h - Curl upload handle
2
+ * Copyright (c)2009 Todd A Fisher.
3
+ * Licensed under the Ruby License. See LICENSE for details.
4
+ */
5
+ #ifndef __CURB_UPLOAD_H
6
+ #define __CURB_UPLOAD_H
7
+
8
+ #include "curb.h"
9
+
10
+ #include <curl/easy.h>
11
+
12
+ /*
13
+ * Maintain the state of an upload e.g. for putting large streams with very little memory
14
+ * out to a server. via PUT requests
15
+ */
16
+ typedef struct {
17
+ VALUE stream;
18
+ size_t offset;
19
+ } ruby_curl_upload;
20
+
21
+ extern VALUE cCurlUpload;
22
+ void init_curb_upload();
23
+
24
+ VALUE ruby_curl_upload_new(VALUE klass);
25
+ VALUE ruby_curl_upload_stream_set(VALUE self, VALUE stream);
26
+ VALUE ruby_curl_upload_stream_get(VALUE self);
27
+ VALUE ruby_curl_upload_offset_set(VALUE self, VALUE offset);
28
+ VALUE ruby_curl_upload_offset_get(VALUE self);
29
+
30
+ #endif
@@ -1,9 +1,4 @@
1
- begin
2
- require 'curb_core'
3
- rescue LoadError
4
- $: << File.dirname(__FILE__)
5
- require 'curb_core'
6
- end
1
+ require 'curb_core'
7
2
 
8
3
  module Curl
9
4
  class Easy
@@ -44,5 +39,32 @@ module Curl
44
39
  end
45
40
  end
46
41
  end
47
- end
42
+ class Multi
43
+ class << self
44
+ # call-seq:
45
+ # Curl::Multi.get('url1','url2','url3','url4','url5', :follow_location => true) do|easy|
46
+ # easy
47
+ # end
48
+ #
49
+ # Blocking call to fetch multiple url's in parallel.
50
+ def get(urls, easy_options={}, multi_options={}, &blk)
51
+ m = Curl::Multi.new
52
+ # configure the multi handle
53
+ multi_options.each do|k,v|
54
+ m.send("#{k}=", v)
55
+ end
48
56
 
57
+ # create and configure each easy handle
58
+ urls.each do|url|
59
+ c = Curl::Easy.new(url)
60
+ easy_options.each do|k,v|
61
+ c.send("#{k}=",v)
62
+ end
63
+ c.on_complete {|curl| blk.call curl }
64
+ m.add(c)
65
+ end
66
+ m.perform
67
+ end
68
+ end
69
+ end
70
+ end
@@ -21,7 +21,7 @@ require 'webrick'
21
21
  # or to test with multiple threads set it to false
22
22
  # this is important since, some code paths will change depending
23
23
  # on the presence of multiple threads
24
- TEST_SINGLE_THREADED=false
24
+ TEST_SINGLE_THREADED=true
25
25
 
26
26
  # keep webrick quiet
27
27
  class ::WEBrick::HTTPServer
@@ -76,6 +76,7 @@ class TestServlet < WEBrick::HTTPServlet::AbstractServlet
76
76
  end
77
77
 
78
78
  def do_PUT(req,res)
79
+ res['X-Requested-Content-Type'] = req.content_type
79
80
  respond_with("PUT\n#{req.body}",req,res)
80
81
  end
81
82
 
@@ -105,6 +106,8 @@ module TestServerMethods
105
106
  server = WEBrick::HTTPServer.new :Port => port, :DocumentRoot => File.expand_path(File.dirname(__FILE__))
106
107
 
107
108
  server.mount(servlet.path, servlet)
109
+ server.mount("/ext", WEBrick::HTTPServlet::FileHandler, File.join(File.dirname(__FILE__),'..','ext'))
110
+
108
111
  trap("INT") { server.shutdown }
109
112
  GC.start
110
113
  wr.flush
@@ -119,6 +122,7 @@ module TestServerMethods
119
122
  @server = WEBrick::HTTPServer.new :Port => port, :DocumentRoot => File.expand_path(File.dirname(__FILE__))
120
123
 
121
124
  @server.mount(servlet.path, servlet)
125
+ @server.mount("/ext", WEBrick::HTTPServlet::FileHandler, File.join(File.dirname(__FILE__),'..','ext'))
122
126
  queue = Queue.new # synchronize the thread startup to the main thread
123
127
 
124
128
  @test_thread = Thread.new { queue << 1; @server.start }
@@ -13,6 +13,9 @@ class TestCurbCurlDownload < Test::Unit::TestCase
13
13
 
14
14
  curb = Curl::Easy.download(dl_url, dl_path)
15
15
  assert File.exist?(dl_path)
16
+ assert_equal File.read(File.join(File.dirname(__FILE__), '..','ext','curb_easy.c')), File.read(dl_path)
17
+ ensure
18
+ File.unlink(dl_path) if File.exist?(dl_path)
16
19
  end
17
20
 
18
21
  def test_download_bad_url_gives_404
@@ -22,6 +25,8 @@ class TestCurbCurlDownload < Test::Unit::TestCase
22
25
  curb = Curl::Easy.download(dl_url, dl_path)
23
26
  assert_equal Curl::Easy, curb.class
24
27
  assert_equal 404, curb.response_code
28
+ ensure
29
+ File.unlink(dl_path) if File.exist?(dl_path)
25
30
  end
26
31
 
27
32
  end
@@ -2,7 +2,7 @@ require File.join(File.dirname(__FILE__), 'helper')
2
2
 
3
3
  class TestCurbCurlEasy < Test::Unit::TestCase
4
4
  def test_class_perform_01
5
- assert_instance_of Curl::Easy, c = Curl::Easy.perform($TEST_URL)
5
+ assert_instance_of Curl::Easy, c = Curl::Easy.perform($TEST_URL)
6
6
  assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body_str)
7
7
  assert_equal "", c.header_str
8
8
  end
@@ -22,6 +22,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
22
22
 
23
23
  def test_new_01
24
24
  c = Curl::Easy.new
25
+ assert_equal Curl::Easy, c.class
25
26
  assert_nil c.url
26
27
  assert_nil c.body_str
27
28
  assert_nil c.header_str
@@ -54,8 +55,19 @@ class TestCurbCurlEasy < Test::Unit::TestCase
54
55
  assert_equal $TEST_URL, c.url
55
56
  assert_equal blk, c.on_body # sets handler nil, returns old handler
56
57
  assert_equal nil, c.on_body
57
- end
58
-
58
+ end
59
+
60
+ class Foo < Curl::Easy
61
+ end
62
+ def test_new_05
63
+ # can use Curl::Easy as a base class
64
+ c = Foo.new
65
+ assert_equal Foo, c.class
66
+ c.url = $TEST_URL
67
+ c.perform
68
+ assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body_str)
69
+ end
70
+
59
71
  def test_escape
60
72
  c = Curl::Easy.new
61
73
 
@@ -471,7 +483,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
471
483
  curl = Curl::Easy.new("#{$TEST_URL.gsub(/file:\/\//,'')}/not_here")
472
484
  on_failure_called = false
473
485
  curl.on_success {|c| } # make sure we get the failure call even though this handler is defined
474
- curl.on_failure {|c| on_failure_called = true }
486
+ curl.on_failure {|c,code| on_failure_called = true }
475
487
  curl.perform
476
488
  assert on_failure_called, "Failure handler not called"
477
489
  end
@@ -520,9 +532,19 @@ class TestCurbCurlEasy < Test::Unit::TestCase
520
532
 
521
533
  def test_put_remote
522
534
  curl = Curl::Easy.new(TestServlet.url)
535
+ curl.headers['Content-Type'] = 'application/json'
523
536
  assert curl.http_put("message")
524
537
  assert_match /^PUT/, curl.body_str
525
538
  assert_match /message$/, curl.body_str
539
+ assert_match /application\/json/, curl.header_str
540
+ end
541
+
542
+ def test_put_remote_file
543
+ curl = Curl::Easy.new(TestServlet.url)
544
+ File.open(__FILE__,'r') do|f|
545
+ assert curl.http_put(f)
546
+ end
547
+ assert_equal "PUT\n#{File.read(__FILE__)}", curl.body_str
526
548
  end
527
549
 
528
550
  include TestServerMethods
@@ -146,7 +146,7 @@ class TestCurbCurlMulti < Test::Unit::TestCase
146
146
  #assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body_str)
147
147
  end
148
148
 
149
- c1.on_failure do|c|
149
+ c1.on_failure do|c,rc|
150
150
  #puts "failure called: #{c.body_str.inspect}"
151
151
  end
152
152
 
@@ -180,7 +180,7 @@ class TestCurbCurlMulti < Test::Unit::TestCase
180
180
  def t_method
181
181
  @buf = ""
182
182
  @m = Curl::Multi.new
183
- 10.times do
183
+ 10.times do|i|
184
184
  c = Curl::Easy.new($TEST_URL)
185
185
  c.on_success{|b| @buf << b.body_str }
186
186
  ObjectSpace.garbage_collect
@@ -246,4 +246,22 @@ class TestCurbCurlMulti < Test::Unit::TestCase
246
246
  end
247
247
  =end
248
248
 
249
+ def test_multi_easy_get_01
250
+ urls = []
251
+ root_uri = 'http://127.0.0.1:9129/ext/'
252
+ # send a request to fetch all c files in the ext dir
253
+ Dir[File.dirname(__FILE__) + "/../ext/*.c"].each do|path|
254
+ urls << root_uri + File.basename(path)
255
+ end
256
+ Curl::Multi.get(urls, {:follow_location => true}, {:pipeline => true}) do|curl|
257
+ assert_equal 200, curl.response_code
258
+ end
259
+ end
260
+
261
+ include TestServerMethods
262
+
263
+ def setup
264
+ server_setup
265
+ end
266
+
249
267
  end
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.3.7
4
+ version: 0.4.2.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-06-17 00:00:00 -04:00
13
+ date: 2009-06-25 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies: []
16
16
 
@@ -36,6 +36,7 @@ files:
36
36
  - ext/curb_errors.c
37
37
  - ext/curb_multi.c
38
38
  - ext/curb_postfield.c
39
+ - ext/curb_upload.c
39
40
  - ext/curb.h
40
41
  - ext/curb_config.h
41
42
  - ext/curb_easy.h
@@ -43,6 +44,7 @@ files:
43
44
  - ext/curb_macros.h
44
45
  - ext/curb_multi.h
45
46
  - ext/curb_postfield.h
47
+ - ext/curb_upload.h
46
48
  has_rdoc: true
47
49
  homepage: http://curb.rubyforge.org/
48
50
  licenses: []