curb 1.0.0 → 1.0.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dce5f49b09bacccf705e3d25ba29031dd4fc82c2721860eef02bb4a8af2dd0e2
4
- data.tar.gz: 9456ed69688f2236bdd17f338e26faaf46b91f0fd4e51b3a48d5551ff8fdc433
3
+ metadata.gz: b452d79ee28ee380d6741f39f9fbf826a33a46d473fa4444edb6a56a122af8f8
4
+ data.tar.gz: '094812699e5b64584d6dd02a17b16884ee696a20dbf324c05498a46509e39b16'
5
5
  SHA512:
6
- metadata.gz: df6ab81576ef567878331724c1600c59ff923be34d3a71bd31d07e4999880743e73c31a502bab8aaece54099fd5142bf954dbf004fffd38f0e6698750e3f9682
7
- data.tar.gz: 5b7b867979da88d328e9f71a4a6eb7183430de26902311cb8678b443a6c53cf50aa62952f277bc2c2821bafc2af48c0e28067f7dce512ff7c2912b195bc27ad5
6
+ metadata.gz: 0df71c1a4eb7896f89da78a79ba9160d5606aa235b89544e08630c558a7cebb1220ec026f99f404915f52e15162cf2c988a66abe04932c3cd1104a1784bd3056
7
+ data.tar.gz: '08fba6b5b9a9404f839e4110b0d485e1595be36554345abb88a05482183204f4e0f13001a7731db75e89ca890bfa8ad19ccced63dfecd0e766f1b825ff5e9f1a'
data/README.markdown CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Curb (probably CUrl-RuBy or something) provides Ruby-language bindings for the
7
7
  libcurl(3), a fully-featured client-side URL transfer library.
8
- cURL and libcurl live at [http://curl.haxx.se/](http://curl.haxx.se/) .
8
+ cURL and libcurl live at [https://curl.se/libcurl/](https://curl.se/libcurl/) .
9
9
 
10
10
  Curb is a work-in-progress, and currently only supports libcurl's `easy` and `multi` modes.
11
11
 
@@ -14,9 +14,31 @@ Curb is a work-in-progress, and currently only supports libcurl's `easy` and `mu
14
14
  Curb is copyright (c)2006 Ross Bamford, and released under the terms of the
15
15
  Ruby license. See the LICENSE file for the gory details.
16
16
 
17
+ ## Easy mode
18
+
19
+ Get stuff
20
+ ```
21
+ res = Curl.get("https://www.google.com/")
22
+ puts res.response_code
23
+ puts res.header_str
24
+ puts res.body
25
+ ```
26
+
27
+ Post stuff
28
+ ```
29
+ res = Curl.post("https://your-server.com/endpoint", {post: "this"}.to_json) {|http|
30
+ http.headers["Content-Type"] = "application/json"
31
+ }
32
+ puts res.response_code
33
+ puts res.header_str
34
+ puts res.body
35
+ ```
36
+
37
+
38
+
17
39
  ## You will need
18
40
 
19
- * A working Ruby installation (`1.8.7+` will work but `2.1+` preferred)
41
+ * A working Ruby installation (`2.0.0+` will work but `2.1+` preferred) (it's possible it still works with 1.8.7 but you'd have to tell me if not...)
20
42
  * A working libcurl development installation
21
43
  (Ideally one of the versions listed in the compatibility chart below that maps to your `curb` version)
22
44
  * A sane build environment (e.g. gcc, make)
@@ -29,7 +51,8 @@ tested and reported to work across a variety of platforms / rubies)
29
51
 
30
52
  | Gem Version | Release Date | libcurl versions |
31
53
  | ----------- | ----------- | ---------------- |
32
- | 0.9.8 | Jan 2019 | 7.58 - 7.63 |
54
+ | 1.0.0 | Jan 2022 | 7.58 - 7.81 |
55
+ | 0.9.8 | Jan 2019 | 7.58 - 7.81 |
33
56
  | 0.9.7 | Nov 2018 | 7.56 - 7.60 |
34
57
  | 0.9.6 | May 2018 | 7.51 - 7.59 |
35
58
  | 0.9.5 | May 2018 | 7.51 - 7.59 |
@@ -43,7 +66,7 @@ tested and reported to work across a variety of platforms / rubies)
43
66
  $ gem install curb
44
67
 
45
68
  On Windows, make sure you're using the [DevKit](http://rubyinstaller.org/downloads/) and
46
- the [development version of libcurl](http://curl.haxx.se/gknw.net/7.39.0/dist-w32/curl-7.39.0-devel-mingw32.zip). Unzip, then run this in your command
69
+ the [development version of libcurl](http://curl.se/gknw.net/7.39.0/dist-w32/curl-7.39.0-devel-mingw32.zip). Unzip, then run this in your command
47
70
  line (alter paths to your curl location, but remember to use forward slashes):
48
71
 
49
72
  gem install curb --platform=ruby -- --with-curl-lib=C:/curl-7.39.0-devel-mingw32/lib --with-curl-include=C:/curl-7.39.0-devel-mingw32/include
data/ext/curb.c CHANGED
@@ -235,12 +235,16 @@ static VALUE ruby_curl_http2_q(VALUE mod) {
235
235
  #endif
236
236
  }
237
237
 
238
+ static void finalize_curb_core(VALUE data) {
239
+ curl_global_cleanup();
240
+ }
241
+
238
242
  void Init_curb_core() {
239
- // TODO we need to call curl_global_cleanup at exit!
240
243
  curl_version_info_data *ver;
241
244
  VALUE curlver, curllongver, curlvernum;
242
245
 
243
246
  curl_global_init(CURL_GLOBAL_ALL);
247
+ rb_set_end_proc(finalize_curb_core, Qnil);
244
248
  ver = curl_version_info(CURLVERSION_NOW);
245
249
 
246
250
  mCurl = rb_define_module("Curl");
data/ext/curb.h CHANGED
@@ -28,11 +28,11 @@
28
28
  #include "curb_macros.h"
29
29
 
30
30
  // These should be managed from the Rake 'release' task.
31
- #define CURB_VERSION "1.0.0"
32
- #define CURB_VER_NUM 1000
31
+ #define CURB_VERSION "1.0.1"
32
+ #define CURB_VER_NUM 1001
33
33
  #define CURB_VER_MAJ 1
34
34
  #define CURB_VER_MIN 0
35
- #define CURB_VER_MIC 0
35
+ #define CURB_VER_MIC 1
36
36
  #define CURB_VER_PATCH 0
37
37
 
38
38
 
data/ext/curb_easy.c CHANGED
@@ -329,9 +329,9 @@ static VALUE ruby_curl_easy_allocate(VALUE klass) {
329
329
 
330
330
  /*
331
331
  * call-seq:
332
- * Curl::Easy.new => #<Curl::Easy...>
333
- * Curl::Easy.new(url = nil) => #<Curl::Easy...>
334
- * Curl::Easy.new(url = nil) { |self| ... } => #<Curl::Easy...>
332
+ * Curl::Easy.new => #<Curl::Easy...>
333
+ * Curl::Easy.new(url = nil) => #<Curl::Easy...>
334
+ * Curl::Easy.new(url = nil) { |self| ... } => #<Curl::Easy...>
335
335
  *
336
336
  * Initialize a new Curl::Easy instance, optionally supplying the URL.
337
337
  * The block form allows further configuration to be supplied before
@@ -376,8 +376,8 @@ static VALUE ruby_curl_easy_initialize(int argc, VALUE *argv, VALUE self) {
376
376
 
377
377
  /*
378
378
  * call-seq:
379
- * easy.clone => #&lt;easy clone&gt;
380
- * easy.dup => #&lt;easy clone&gt;
379
+ * easy.clone => <easy clone>
380
+ * easy.dup => <easy clone>
381
381
  *
382
382
  * Clone this Curl::Easy instance, creating a new instance.
383
383
  * This method duplicates the underlying CURL* handle.
@@ -957,7 +957,7 @@ static VALUE ruby_curl_easy_ftp_commands_set(VALUE self, VALUE ftp_commands) {
957
957
  }
958
958
 
959
959
  /*
960
- * call-seq
960
+ * call-seq:
961
961
  * easy.ftp_commands => array or nil
962
962
  */
963
963
  static VALUE ruby_curl_easy_ftp_commands_get(VALUE self) {
@@ -976,7 +976,7 @@ static VALUE ruby_curl_easy_resolve_set(VALUE self, VALUE resolve) {
976
976
  }
977
977
 
978
978
  /*
979
- * call-seq
979
+ * call-seq:
980
980
  * easy.resolve => array or nil
981
981
  */
982
982
  static VALUE ruby_curl_easy_resolve_get(VALUE self) {
@@ -1595,7 +1595,7 @@ static VALUE ruby_curl_easy_ftp_filemethod_set(VALUE self, VALUE ftp_filemethod)
1595
1595
  }
1596
1596
 
1597
1597
  /*
1598
- * call-seq
1598
+ * call-seq:
1599
1599
  * easy.ftp_filemethod => fixnum
1600
1600
  *
1601
1601
  * Get the configuration for how libcurl will reach files on the server.
@@ -1967,7 +1967,7 @@ static VALUE ruby_curl_easy_resolve_mode_set(VALUE self, VALUE resolve_mode) {
1967
1967
 
1968
1968
  /*
1969
1969
  * call-seq:
1970
- * easy.on_body { |body_data| ... } => &lt;old handler&gt;
1970
+ * easy.on_body { |body_data| ... } => <old handler>
1971
1971
  *
1972
1972
  * Assign or remove the +on_body+ handler for this Curl::Easy instance.
1973
1973
  * To remove a previously-supplied handler, call this method with no
@@ -1986,7 +1986,7 @@ static VALUE ruby_curl_easy_on_body_set(int argc, VALUE *argv, VALUE self) {
1986
1986
 
1987
1987
  /*
1988
1988
  * call-seq:
1989
- * easy.on_success { |easy| ... } => &lt;old handler&gt;
1989
+ * easy.on_success { |easy| ... } => <old handler>
1990
1990
  *
1991
1991
  * Assign or remove the +on_success+ handler for this Curl::Easy instance.
1992
1992
  * To remove a previously-supplied handler, call this method with no
@@ -2001,7 +2001,7 @@ static VALUE ruby_curl_easy_on_success_set(int argc, VALUE *argv, VALUE self) {
2001
2001
 
2002
2002
  /*
2003
2003
  * call-seq:
2004
- * easy.on_failure {|easy,code| ... } => &lt;old handler&gt;
2004
+ * easy.on_failure {|easy,code| ... } => <old handler>
2005
2005
  *
2006
2006
  * Assign or remove the +on_failure+ handler for this Curl::Easy instance.
2007
2007
  * To remove a previously-supplied handler, call this method with no
@@ -2016,7 +2016,7 @@ static VALUE ruby_curl_easy_on_failure_set(int argc, VALUE *argv, VALUE self) {
2016
2016
 
2017
2017
  /*
2018
2018
  * call-seq:
2019
- * easy.on_missing {|easy,code| ... } => &lt;old handler;&gt;
2019
+ * easy.on_missing {|easy,code| ... } => <old handler;>
2020
2020
  *
2021
2021
  * Assign or remove the on_missing handler for this Curl::Easy instance.
2022
2022
  * To remove a previously-supplied handler, call this method with no attached
@@ -2031,7 +2031,7 @@ static VALUE ruby_curl_easy_on_missing_set(int argc, VALUE *argv, VALUE self) {
2031
2031
 
2032
2032
  /*
2033
2033
  * call-seq:
2034
- * easy.on_redirect {|easy,code| ... } => &lt;old handler;&gt;
2034
+ * easy.on_redirect {|easy,code| ... } => <old handler;>
2035
2035
  *
2036
2036
  * Assign or remove the on_redirect handler for this Curl::Easy instance.
2037
2037
  * To remove a previously-supplied handler, call this method with no attached
@@ -2046,7 +2046,7 @@ static VALUE ruby_curl_easy_on_redirect_set(int argc, VALUE *argv, VALUE self) {
2046
2046
 
2047
2047
  /*
2048
2048
  * call-seq:
2049
- * easy.on_complete {|easy| ... } => &lt;old handler&gt;
2049
+ * easy.on_complete {|easy| ... } => <old handler>
2050
2050
  *
2051
2051
  * Assign or remove the +on_complete+ handler for this Curl::Easy instance.
2052
2052
  * To remove a previously-supplied handler, call this method with no
@@ -2060,7 +2060,7 @@ static VALUE ruby_curl_easy_on_complete_set(int argc, VALUE *argv, VALUE self) {
2060
2060
 
2061
2061
  /*
2062
2062
  * call-seq:
2063
- * easy.on_header { |header_data| ... } => &lt;old handler&gt;
2063
+ * easy.on_header { |header_data| ... } => <old handler>
2064
2064
  *
2065
2065
  * Assign or remove the +on_header+ handler for this Curl::Easy instance.
2066
2066
  * To remove a previously-supplied handler, call this method with no
@@ -2076,7 +2076,7 @@ static VALUE ruby_curl_easy_on_header_set(int argc, VALUE *argv, VALUE self) {
2076
2076
 
2077
2077
  /*
2078
2078
  * call-seq:
2079
- * easy.on_progress { |dl_total, dl_now, ul_total, ul_now| ... } => &lt;old handler&gt;
2079
+ * easy.on_progress { |dl_total, dl_now, ul_total, ul_now| ... } => <old handler>
2080
2080
  *
2081
2081
  * Assign or remove the +on_progress+ handler for this Curl::Easy instance.
2082
2082
  * To remove a previously-supplied handler, call this method with no
@@ -2097,7 +2097,7 @@ static VALUE ruby_curl_easy_on_progress_set(int argc, VALUE *argv, VALUE self) {
2097
2097
 
2098
2098
  /*
2099
2099
  * call-seq:
2100
- * easy.on_debug { |type, data| ... } => &lt;old handler&gt;
2100
+ * easy.on_debug { |type, data| ... } => <old handler>
2101
2101
  *
2102
2102
  * Assign or remove the +on_debug+ handler for this Curl::Easy instance.
2103
2103
  * To remove a previously-supplied handler, call this method with no
@@ -2136,11 +2136,14 @@ static VALUE cb_each_http_header(VALUE header, VALUE wrap) {
2136
2136
 
2137
2137
  name = rb_obj_as_string(rb_ary_entry(header, 0));
2138
2138
  value = rb_obj_as_string(rb_ary_entry(header, 1));
2139
-
2140
- // This is a bit inefficient, but we don't want to be modifying
2141
- // the actual values in the original hash.
2142
- header_str = rb_str_plus(name, rb_str_new2(": "));
2143
- header_str = rb_str_plus(header_str, value);
2139
+ if (rb_str_strlen(value) == 0) { // removing the header e.g. Accept: with nothing trailing should remove it see: https://curl.se/libcurl/c/CURLOPT_HTTPHEADER.html
2140
+ header_str = rb_str_plus(name, rb_str_new2(":"));
2141
+ } else {
2142
+ // This is a bit inefficient, but we don't want to be modifying
2143
+ // the actual values in the original hash.
2144
+ header_str = rb_str_plus(name, rb_str_new2(": "));
2145
+ header_str = rb_str_plus(header_str, value);
2146
+ }
2144
2147
  } else {
2145
2148
  header_str = rb_obj_as_string(header);
2146
2149
  }
@@ -2775,6 +2778,10 @@ static VALUE ruby_curl_easy_perform_put(VALUE self, VALUE data) {
2775
2778
  * your own body handler, this string will be empty.
2776
2779
  */
2777
2780
  static VALUE ruby_curl_easy_body_str_get(VALUE self) {
2781
+ /*
2782
+ TODO: can we force_encoding on the return here if we see charset=utf-8 in the content-type header?
2783
+ Content-Type: application/json; charset=utf-8
2784
+ */
2778
2785
  CURB_OBJECT_HGETTER(ruby_curl_easy, body_data);
2779
2786
  }
2780
2787
 
data/ext/curb_multi.c CHANGED
@@ -64,7 +64,7 @@ static void ruby_curl_multi_init(ruby_curl_multi *rbcm) {
64
64
 
65
65
  /*
66
66
  * call-seq:
67
- * Curl::Multi.new => #&lt;Curl::Easy...&gt;
67
+ * Curl::Multi.new => #<Curl::Easy...>
68
68
  *
69
69
  * Create a new Curl::Multi instance
70
70
  */
@@ -132,7 +132,7 @@ VALUE ruby_curl_multi_get_autoclose(VALUE klass) {
132
132
 
133
133
  /*
134
134
  * call-seq:
135
- * multi.requests => [#&lt;Curl::Easy...&gt;, ...]
135
+ * multi.requests => [#<Curl::Easy...>, ...]
136
136
  *
137
137
  * Returns an array containing all the active requests on this Curl::Multi object.
138
138
  */
@@ -300,10 +300,14 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
300
300
  rbce->callback_active = 1;
301
301
  val = rb_rescue(call_status_handler1, callargs, callback_exception, Qnil);
302
302
  rbce->callback_active = 0;
303
- //rb_funcall( rb_easy_get("complete_proc"), idCall, 1, easy );
304
303
  }
305
304
 
305
+ #ifdef HAVE_CURLINFO_RESPONSE_CODE
306
306
  curl_easy_getinfo(rbce->curl, CURLINFO_RESPONSE_CODE, &response_code);
307
+ #else
308
+ // old libcurl
309
+ curl_easy_getinfo(rbce->curl, CURLINFO_HTTP_CODE, &response_code);
310
+ #endif
307
311
 
308
312
  if (result != 0) {
309
313
  if (!rb_easy_nil("failure_proc")) {
@@ -313,8 +317,7 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
313
317
  rbce->callback_active = 0;
314
318
  //rb_funcall( rb_easy_get("failure_proc"), idCall, 2, easy, rb_curl_easy_error(result) );
315
319
  }
316
- }
317
- else if (!rb_easy_nil("success_proc") &&
320
+ } else if (!rb_easy_nil("success_proc") &&
318
321
  ((response_code >= 200 && response_code < 300) || response_code == 0)) {
319
322
  /* NOTE: we allow response_code == 0, in the case of non http requests e.g. reading from disk */
320
323
  callargs = rb_ary_new3(2, rb_easy_get("success_proc"), easy);
@@ -322,22 +325,19 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
322
325
  val = rb_rescue(call_status_handler1, callargs, callback_exception, Qnil);
323
326
  rbce->callback_active = 0;
324
327
  //rb_funcall( rb_easy_get("success_proc"), idCall, 1, easy );
325
- }
326
- else if (!rb_easy_nil("redirect_proc") &&
328
+ } else if (!rb_easy_nil("redirect_proc") &&
327
329
  (response_code >= 300 && response_code < 400)) {
328
330
  rbce->callback_active = 1;
329
331
  callargs = rb_ary_new3(3, rb_easy_get("redirect_proc"), easy, rb_curl_easy_error(result));
330
332
  rbce->callback_active = 0;
331
333
  val = rb_rescue(call_status_handler2, callargs, callback_exception, Qnil);
332
- }
333
- else if (!rb_easy_nil("missing_proc") &&
334
+ } else if (!rb_easy_nil("missing_proc") &&
334
335
  (response_code >= 400 && response_code < 500)) {
335
336
  rbce->callback_active = 1;
336
337
  callargs = rb_ary_new3(3, rb_easy_get("missing_proc"), easy, rb_curl_easy_error(result));
337
338
  rbce->callback_active = 0;
338
339
  val = rb_rescue(call_status_handler2, callargs, callback_exception, Qnil);
339
- }
340
- else if (!rb_easy_nil("failure_proc") &&
340
+ } else if (!rb_easy_nil("failure_proc") &&
341
341
  (response_code >= 500 && response_code <= 999)) {
342
342
  callargs = rb_ary_new3(3, rb_easy_get("failure_proc"), easy, rb_curl_easy_error(result));
343
343
  rbce->callback_active = 1;
data/ext/curb_postfield.c CHANGED
@@ -195,9 +195,9 @@ void curl_postfield_free(ruby_curl_postfield *rbcpf) {
195
195
 
196
196
  /*
197
197
  * call-seq:
198
- * Curl::PostField.content(name, content) => #&lt;Curl::PostField...&gt;
199
- * Curl::PostField.content(name, content, content_type = nil) => #&lt;Curl::PostField...&gt;
200
- * Curl::PostField.content(name, content_type = nil) { |field| ... } => #&lt;Curl::PostField...&gt;
198
+ * Curl::PostField.content(name, content) => #<Curl::PostField...>
199
+ * Curl::PostField.content(name, content, content_type = nil) => #<Curl::PostField...>
200
+ * Curl::PostField.content(name, content_type = nil) { |field| ... } => #<Curl::PostField...>
201
201
  *
202
202
  * Create a new Curl::PostField, supplying the field name, content,
203
203
  * and, optionally, Content-type (curl will attempt to determine this if
@@ -241,9 +241,9 @@ static VALUE ruby_curl_postfield_new_content(int argc, VALUE *argv, VALUE klass)
241
241
 
242
242
  /*
243
243
  * call-seq:
244
- * Curl::PostField.file(name, local_file_name) => #&lt;Curl::PostField...&gt;
245
- * Curl::PostField.file(name, local_file_name, remote_file_name = local_file_name) => #&lt;Curl::PostField...&gt;
246
- * Curl::PostField.file(name, remote_file_name) { |field| ... } => #&lt;Curl::PostField...&gt;
244
+ * Curl::PostField.file(name, local_file_name) => #<Curl::PostField...>
245
+ * Curl::PostField.file(name, local_file_name, remote_file_name = local_file_name) => #<Curl::PostField...>
246
+ * Curl::PostField.file(name, remote_file_name) { |field| ... } => #<Curl::PostField...>
247
247
  *
248
248
  * Create a new Curl::PostField for a file upload field, supplying the local filename
249
249
  * to read from, and optionally the remote filename (defaults to the local name).
@@ -399,7 +399,7 @@ static VALUE ruby_curl_postfield_remote_file_get(VALUE self) {
399
399
 
400
400
  /*
401
401
  * call-seq:
402
- * field.set_content_proc { |field| ... } => &lt;old proc&gt;
402
+ * field.set_content_proc { |field| ... } => <old proc>
403
403
  *
404
404
  * Set a content proc for this field. This proc will be called during the
405
405
  * perform to supply the content for this field, overriding any setting
data/lib/curl/easy.rb CHANGED
@@ -21,7 +21,7 @@ module Curl
21
21
  #
22
22
  def status
23
23
  # Matches the last HTTP Status - following the HTTP protocol specification 'Status-Line = HTTP-Version SP Status-Code SP (Opt:)Reason-Phrase CRLF'
24
- statuses = self.header_str.scan(/HTTP\/\d(\.\d)?\s(\d+\s.*)\r\n/).map{ |match| match[1] }
24
+ statuses = self.header_str.to_s.scan(/HTTP\/\d(\.\d)?\s(\d+\s.*)\r\n/).map {|match| match[1] }
25
25
  statuses.last.strip if statuses.length > 0
26
26
  end
27
27
 
@@ -321,7 +321,7 @@ module Curl
321
321
 
322
322
  #
323
323
  # call-seq:
324
- # Curl::Easy.perform(url) { |easy| ... } => #&lt;Curl::Easy...&gt;
324
+ # Curl::Easy.perform(url) { |easy| ... } => #<Curl::Easy...>
325
325
  #
326
326
  # Convenience method that creates a new Curl::Easy instance with
327
327
  # the specified URL and calls the general +perform+ method, before returning
@@ -339,7 +339,7 @@ module Curl
339
339
 
340
340
  #
341
341
  # call-seq:
342
- # Curl::Easy.http_get(url) { |easy| ... } => #&lt;Curl::Easy...&gt;
342
+ # Curl::Easy.http_get(url) { |easy| ... } => #<Curl::Easy...>
343
343
  #
344
344
  # Convenience method that creates a new Curl::Easy instance with
345
345
  # the specified URL and calls +http_get+, before returning the new instance.
@@ -356,7 +356,7 @@ module Curl
356
356
 
357
357
  #
358
358
  # call-seq:
359
- # Curl::Easy.http_head(url) { |easy| ... } => #&lt;Curl::Easy...&gt;
359
+ # Curl::Easy.http_head(url) { |easy| ... } => #<Curl::Easy...>
360
360
  #
361
361
  # Convenience method that creates a new Curl::Easy instance with
362
362
  # the specified URL and calls +http_head+, before returning the new instance.
@@ -410,7 +410,7 @@ module Curl
410
410
 
411
411
  #
412
412
  # call-seq:
413
- # Curl::Easy.http_delete(url) { |easy| ... } => #&lt;Curl::Easy...&gt;
413
+ # Curl::Easy.http_delete(url) { |easy| ... } => #<Curl::Easy...>
414
414
  #
415
415
  # Convenience method that creates a new Curl::Easy instance with
416
416
  # the specified URL and calls +http_delete+, before returning the new instance.
data/lib/curl.rb CHANGED
@@ -9,12 +9,20 @@ require 'cgi'
9
9
  module Curl
10
10
 
11
11
  def self.http(verb, url, post_body=nil, put_data=nil, &block)
12
- handle = Thread.current[:curb_curl] ||= Curl::Easy.new
13
- handle.reset
12
+ if Thread.current[:curb_curl_yielding]
13
+ handle = Curl::Easy.new # we can't reuse this
14
+ else
15
+ handle = Thread.current[:curb_curl] ||= Curl::Easy.new
16
+ handle.reset
17
+ end
14
18
  handle.url = url
15
19
  handle.post_body = post_body if post_body
16
20
  handle.put_data = put_data if put_data
17
- yield handle if block_given?
21
+ if block_given?
22
+ Thread.current[:curb_curl_yielding] = true
23
+ yield handle
24
+ Thread.current[:curb_curl_yielding] = false
25
+ end
18
26
  handle.http(verb)
19
27
  handle
20
28
  end
@@ -0,0 +1,32 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
+
3
+
4
+ require 'curb'
5
+
6
+ class BugIssue102 < Test::Unit::TestCase
7
+
8
+ def test_gc_closewait
9
+ 100.times do
10
+ responses = {}
11
+ requests = ["http://www.google.co.uk/", "http://www.ruby-lang.org/"]
12
+ m = Curl::Multi.new
13
+ # add a few easy handles
14
+ requests.each do |url|
15
+ responses[url] = ""
16
+ c = Curl::Easy.new(url) do|curl|
17
+ curl.follow_location = true
18
+ curl.on_body{|data| responses[url] << data; data.size }
19
+ curl.on_success {|easy| #puts "success, add more easy handles"
20
+ }
21
+ end
22
+ m.add(c)
23
+ end
24
+
25
+ m.perform do
26
+ #puts "idling... can do some work here"
27
+ end
28
+ GC.start
29
+ end
30
+ end
31
+
32
+ end
@@ -10,6 +10,14 @@ class TestCurbCurlEasy < Test::Unit::TestCase
10
10
  Curl.reset
11
11
  end
12
12
 
13
+ def test_nested_easy_methods
14
+ easy = Curl.get(TestServlet.url) {|http|
15
+ res = Curl.get(TestServlet.url + '/not_here')
16
+ assert_equal 404, res.response_code
17
+ }
18
+ assert_equal 200, easy.response_code
19
+ end
20
+
13
21
  def test_curlopt_stderr_with_file
14
22
  # does not work with Tempfile directly
15
23
  path = Tempfile.new('curb_test_curlopt_stderr').path
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: curb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ross Bamford
8
8
  - Todd A. Fisher
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-01-14 00:00:00.000000000 Z
12
+ date: 2022-04-29 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Curb (probably CUrl-RuBy or something) provides Ruby-language bindings
15
15
  for the libcurl(3), a fully-featured client-side URL transfer library. cURL and
@@ -52,6 +52,7 @@ files:
52
52
  - tests/bug_curb_easy_post_with_string_no_content_length_header.rb
53
53
  - tests/bug_instance_post_differs_from_class_post.rb
54
54
  - tests/bug_issue102.rb
55
+ - tests/bug_issue277.rb
55
56
  - tests/bug_multi_segfault.rb
56
57
  - tests/bug_postfields_crash.rb
57
58
  - tests/bug_postfields_crash2.rb
@@ -77,7 +78,7 @@ homepage: https://github.com/taf2/curb
77
78
  licenses:
78
79
  - MIT
79
80
  metadata: {}
80
- post_install_message:
81
+ post_install_message:
81
82
  rdoc_options:
82
83
  - "--main"
83
84
  - README.markdown
@@ -95,36 +96,37 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
96
  - !ruby/object:Gem::Version
96
97
  version: '0'
97
98
  requirements: []
98
- rubygems_version: 3.3.3
99
- signing_key:
99
+ rubygems_version: 3.1.4
100
+ signing_key:
100
101
  specification_version: 4
101
102
  summary: Ruby libcurl bindings
102
103
  test_files:
104
+ - tests/tc_curl_multi.rb
103
105
  - tests/alltests.rb
104
- - tests/bug_crash_on_debug.rb
105
- - tests/bug_crash_on_progress.rb
106
- - tests/bug_curb_easy_blocks_ruby_threads.rb
107
- - tests/bug_curb_easy_post_with_string_no_content_length_header.rb
108
- - tests/bug_instance_post_differs_from_class_post.rb
109
- - tests/bug_issue102.rb
110
- - tests/bug_multi_segfault.rb
106
+ - tests/tc_curl_easy_setopt.rb
107
+ - tests/tc_curl.rb
111
108
  - tests/bug_postfields_crash.rb
109
+ - tests/bug_crash_on_progress.rb
110
+ - tests/helper.rb
111
+ - tests/bug_issue277.rb
112
112
  - tests/bug_postfields_crash2.rb
113
113
  - tests/bug_require_last_or_segfault.rb
114
- - tests/bugtests.rb
115
- - tests/helper.rb
116
- - tests/mem_check.rb
114
+ - tests/timeout.rb
115
+ - tests/bug_crash_on_debug.rb
116
+ - tests/unittests.rb
117
+ - tests/tc_curl_protocols.rb
118
+ - tests/bug_issue102.rb
119
+ - tests/bug_curb_easy_blocks_ruby_threads.rb
120
+ - tests/bug_multi_segfault.rb
121
+ - tests/bug_instance_post_differs_from_class_post.rb
117
122
  - tests/require_last_or_segfault_script.rb
118
- - tests/signals.rb
119
- - tests/tc_curl.rb
123
+ - tests/timeout_server.rb
120
124
  - tests/tc_curl_download.rb
121
125
  - tests/tc_curl_easy.rb
122
- - tests/tc_curl_easy_resolve.rb
123
- - tests/tc_curl_easy_setopt.rb
124
- - tests/tc_curl_maxfilesize.rb
125
- - tests/tc_curl_multi.rb
126
+ - tests/mem_check.rb
126
127
  - tests/tc_curl_postfield.rb
127
- - tests/tc_curl_protocols.rb
128
- - tests/timeout.rb
129
- - tests/timeout_server.rb
130
- - tests/unittests.rb
128
+ - tests/tc_curl_maxfilesize.rb
129
+ - tests/bugtests.rb
130
+ - tests/tc_curl_easy_resolve.rb
131
+ - tests/signals.rb
132
+ - tests/bug_curb_easy_post_with_string_no_content_length_header.rb