curb 1.0.0 → 1.0.2

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: b338d766fda8dfadab0c602cdad4a9f15a529bb495725b15ca5def63a9d8390a
4
+ data.tar.gz: 5b074f1154e3da7ce37eee89e6e5a577a2c09202b6baee72afd2098eac986bd7
5
5
  SHA512:
6
- metadata.gz: df6ab81576ef567878331724c1600c59ff923be34d3a71bd31d07e4999880743e73c31a502bab8aaece54099fd5142bf954dbf004fffd38f0e6698750e3f9682
7
- data.tar.gz: 5b7b867979da88d328e9f71a4a6eb7183430de26902311cb8678b443a6c53cf50aa62952f277bc2c2821bafc2af48c0e28067f7dce512ff7c2912b195bc27ad5
6
+ metadata.gz: 59a25fdf7add62512432495a89d6c8832513ecbc94bb14e7e5720abbfbfea24e0ae52c77fe10497871c6683f39e6988ff184088318e06a14848ab764db38bea2
7
+ data.tar.gz: 4fc8fb4b8111f102107cabc002f1b1a11d2f73e9b66d188ebaf3027a803c90868184c751a3448639bf23ca62eace0a227769aff716a4ba0a8a39b23888346097
data/README.markdown CHANGED
@@ -1,11 +1,12 @@
1
- # Curb - Libcurl bindings for Ruby [![Build Status](https://travis-ci.org/taf2/curb.svg?branch=master)](https://travis-ci.org/taf2/curb)
1
+ # Curb - Libcurl bindings for Ruby
2
2
 
3
+ * [CI Build Status](https://github.com/taf2/curb/actions/workflows/CI.yml)
3
4
  * [rubydoc rdoc](http://www.rubydoc.info/github/taf2/curb/)
4
5
  * [github project](http://github.com/taf2/curb/tree/master)
5
6
 
6
7
  Curb (probably CUrl-RuBy or something) provides Ruby-language bindings for the
7
8
  libcurl(3), a fully-featured client-side URL transfer library.
8
- cURL and libcurl live at [http://curl.haxx.se/](http://curl.haxx.se/) .
9
+ cURL and libcurl live at [https://curl.se/libcurl/](https://curl.se/libcurl/) .
9
10
 
10
11
  Curb is a work-in-progress, and currently only supports libcurl's `easy` and `multi` modes.
11
12
 
@@ -14,9 +15,31 @@ Curb is a work-in-progress, and currently only supports libcurl's `easy` and `mu
14
15
  Curb is copyright (c)2006 Ross Bamford, and released under the terms of the
15
16
  Ruby license. See the LICENSE file for the gory details.
16
17
 
18
+ ## Easy mode
19
+
20
+ Get stuff
21
+ ```
22
+ res = Curl.get("https://www.google.com/")
23
+ puts res.response_code
24
+ puts res.header_str
25
+ puts res.body
26
+ ```
27
+
28
+ Post stuff
29
+ ```
30
+ res = Curl.post("https://your-server.com/endpoint", {post: "this"}.to_json) {|http|
31
+ http.headers["Content-Type"] = "application/json"
32
+ }
33
+ puts res.response_code
34
+ puts res.header_str
35
+ puts res.body
36
+ ```
37
+
38
+
39
+
17
40
  ## You will need
18
41
 
19
- * A working Ruby installation (`1.8.7+` will work but `2.1+` preferred)
42
+ * 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
43
  * A working libcurl development installation
21
44
  (Ideally one of the versions listed in the compatibility chart below that maps to your `curb` version)
22
45
  * A sane build environment (e.g. gcc, make)
@@ -29,7 +52,8 @@ tested and reported to work across a variety of platforms / rubies)
29
52
 
30
53
  | Gem Version | Release Date | libcurl versions |
31
54
  | ----------- | ----------- | ---------------- |
32
- | 0.9.8 | Jan 2019 | 7.58 - 7.63 |
55
+ | 1.0.0 | Jan 2022 | 7.58 - 7.81 |
56
+ | 0.9.8 | Jan 2019 | 7.58 - 7.81 |
33
57
  | 0.9.7 | Nov 2018 | 7.56 - 7.60 |
34
58
  | 0.9.6 | May 2018 | 7.51 - 7.59 |
35
59
  | 0.9.5 | May 2018 | 7.51 - 7.59 |
@@ -43,7 +67,7 @@ tested and reported to work across a variety of platforms / rubies)
43
67
  $ gem install curb
44
68
 
45
69
  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
70
+ 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
71
  line (alter paths to your curl location, but remember to use forward slashes):
48
72
 
49
73
  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/Rakefile CHANGED
@@ -10,13 +10,6 @@ CLOBBER.include '**/*.log'
10
10
  CLOBBER.include '**/Makefile'
11
11
  CLOBBER.include '**/extconf.h'
12
12
 
13
- # Not available for really old rubies, but that's ok.
14
- begin
15
- require 'pry'
16
- rescue LoadError
17
- puts "Failed to load pry."
18
- end
19
-
20
13
  # Load support ruby and rake files (in this order)
21
14
  Dir.glob('tasks/*.rb').each { |r| load r}
22
15
  Dir.glob('tasks/*.rake').each { |r| load r}
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");
@@ -1072,6 +1076,10 @@ void Init_curb_core() {
1072
1076
  CURB_DEFINE(CURLOPT_HAPROXYPROTOCOL);
1073
1077
  #endif
1074
1078
 
1079
+ #if HAVE_CURLOPT_PROXY_SSL_VERIFYHOST
1080
+ CURB_DEFINE(CURLOPT_PROXY_SSL_VERIFYHOST);
1081
+ #endif
1082
+
1075
1083
  #if HAVE_CURLPROTO_RTMPTE
1076
1084
  CURB_DEFINE(CURLPROTO_RTMPTE);
1077
1085
  #endif
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.2"
32
+ #define CURB_VER_NUM 1002
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 2
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
 
@@ -3646,6 +3653,11 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
3646
3653
  case CURLOPT_SSL_SESSIONID_CACHE:
3647
3654
  curl_easy_setopt(rbce->curl, CURLOPT_SSL_SESSIONID_CACHE, NUM2LONG(val));
3648
3655
  break;
3656
+ #endif
3657
+ #if HAVE_CURLOPT_PROXY_SSL_VERIFYHOST
3658
+ case CURLOPT_PROXY_SSL_VERIFYHOST:
3659
+ curl_easy_setopt(rbce->curl, CURLOPT_PROXY_SSL_VERIFYHOST, NUM2LONG(val));
3660
+ break;
3649
3661
  #endif
3650
3662
  default:
3651
3663
  rb_raise(rb_eTypeError, "Curb unsupported option");
@@ -3763,6 +3775,7 @@ static VALUE ruby_curl_easy_error_message(VALUE klass, VALUE code) {
3763
3775
  }
3764
3776
 
3765
3777
  /* =================== INIT LIB =====================*/
3778
+ // TODO: https://bugs.ruby-lang.org/issues/18007
3766
3779
  void init_curb_easy() {
3767
3780
  idCall = rb_intern("call");
3768
3781
  idJoin = rb_intern("join");
data/ext/curb_macros.h CHANGED
@@ -156,4 +156,10 @@
156
156
  #define CURB_DEFINE(name) \
157
157
  rb_define_const(mCurl, #name, LONG2NUM(name))
158
158
 
159
+ #define CURB_RB_CALLBACK_RAISE(context) \
160
+ VALUE exception = rb_errinfo(); \
161
+ const char *msg = rb_respond_to(exception,rb_intern("message")) ? RSTRING_PTR(rb_funcall(exception, rb_intern("message"), 0)) : ""; \
162
+ rb_set_errinfo(Qnil); \
163
+ rb_raise(eCurlErrAbortedByCallback, "Operation was aborted by an application callback[%s]:\"%s\"", context, msg);
164
+
159
165
  #endif
data/ext/curb_multi.c CHANGED
@@ -43,10 +43,6 @@ static void rb_curl_multi_remove(ruby_curl_multi *rbcm, VALUE easy);
43
43
  static void rb_curl_multi_read_info(VALUE self, CURLM *mptr);
44
44
  static void rb_curl_multi_run(VALUE self, CURLM *multi_handle, int *still_running);
45
45
 
46
- static VALUE callback_exception(VALUE unused) {
47
- return Qfalse;
48
- }
49
-
50
46
  void curl_multi_free(ruby_curl_multi *rbcm) {
51
47
  curl_multi_cleanup(rbcm->handle);
52
48
  free(rbcm);
@@ -64,7 +60,7 @@ static void ruby_curl_multi_init(ruby_curl_multi *rbcm) {
64
60
 
65
61
  /*
66
62
  * call-seq:
67
- * Curl::Multi.new => #&lt;Curl::Easy...&gt;
63
+ * Curl::Multi.new => #<Curl::Easy...>
68
64
  *
69
65
  * Create a new Curl::Multi instance
70
66
  */
@@ -132,7 +128,7 @@ VALUE ruby_curl_multi_get_autoclose(VALUE klass) {
132
128
 
133
129
  /*
134
130
  * call-seq:
135
- * multi.requests => [#&lt;Curl::Easy...&gt;, ...]
131
+ * multi.requests => [#<Curl::Easy...>, ...]
136
132
  *
137
133
  * Returns an array containing all the active requests on this Curl::Multi object.
138
134
  */
@@ -274,7 +270,7 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
274
270
  long response_code = -1;
275
271
  VALUE easy;
276
272
  ruby_curl_easy *rbce = NULL;
277
- VALUE callargs, val = Qtrue;
273
+ VALUE callargs;
278
274
 
279
275
  CURLcode ecode = curl_easy_getinfo(easy_handle, CURLINFO_PRIVATE, (char**)&easy);
280
276
 
@@ -295,55 +291,73 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
295
291
  raise_curl_easy_error_exception(ecode);
296
292
  }
297
293
 
294
+ int status;
295
+
298
296
  if (!rb_easy_nil("complete_proc")) {
299
297
  callargs = rb_ary_new3(2, rb_easy_get("complete_proc"), easy);
300
298
  rbce->callback_active = 1;
301
- val = rb_rescue(call_status_handler1, callargs, callback_exception, Qnil);
299
+ rb_protect(call_status_handler1, callargs, &status);
302
300
  rbce->callback_active = 0;
303
- //rb_funcall( rb_easy_get("complete_proc"), idCall, 1, easy );
301
+ if (status) {
302
+ CURB_RB_CALLBACK_RAISE("complete")
303
+ }
304
304
  }
305
305
 
306
+ #ifdef HAVE_CURLINFO_RESPONSE_CODE
306
307
  curl_easy_getinfo(rbce->curl, CURLINFO_RESPONSE_CODE, &response_code);
308
+ #else
309
+ // old libcurl
310
+ curl_easy_getinfo(rbce->curl, CURLINFO_HTTP_CODE, &response_code);
311
+ #endif
312
+ long redirect_count;
313
+ curl_easy_getinfo(rbce->curl, CURLINFO_REDIRECT_COUNT, &redirect_count);
307
314
 
308
315
  if (result != 0) {
309
316
  if (!rb_easy_nil("failure_proc")) {
310
317
  callargs = rb_ary_new3(3, rb_easy_get("failure_proc"), easy, rb_curl_easy_error(result));
311
318
  rbce->callback_active = 1;
312
- val = rb_rescue(call_status_handler2, callargs, callback_exception, Qnil);
319
+ rb_protect(call_status_handler2, callargs, &status);
313
320
  rbce->callback_active = 0;
314
- //rb_funcall( rb_easy_get("failure_proc"), idCall, 2, easy, rb_curl_easy_error(result) );
321
+ if (status) {
322
+ CURB_RB_CALLBACK_RAISE("failure")
323
+ }
315
324
  }
316
- }
317
- else if (!rb_easy_nil("success_proc") &&
325
+ } else if (!rb_easy_nil("success_proc") &&
318
326
  ((response_code >= 200 && response_code < 300) || response_code == 0)) {
319
327
  /* NOTE: we allow response_code == 0, in the case of non http requests e.g. reading from disk */
320
328
  callargs = rb_ary_new3(2, rb_easy_get("success_proc"), easy);
321
329
  rbce->callback_active = 1;
322
- val = rb_rescue(call_status_handler1, callargs, callback_exception, Qnil);
330
+ rb_protect(call_status_handler1, callargs, &status);
323
331
  rbce->callback_active = 0;
324
- //rb_funcall( rb_easy_get("success_proc"), idCall, 1, easy );
325
- }
326
- else if (!rb_easy_nil("redirect_proc") &&
327
- (response_code >= 300 && response_code < 400)) {
332
+ if (status) {
333
+ CURB_RB_CALLBACK_RAISE("success")
334
+ }
335
+ } else if (!rb_easy_nil("redirect_proc") && ((response_code >= 300 && response_code < 400) || redirect_count > 0) ) {
328
336
  rbce->callback_active = 1;
329
337
  callargs = rb_ary_new3(3, rb_easy_get("redirect_proc"), easy, rb_curl_easy_error(result));
330
338
  rbce->callback_active = 0;
331
- val = rb_rescue(call_status_handler2, callargs, callback_exception, Qnil);
332
- }
333
- else if (!rb_easy_nil("missing_proc") &&
339
+ rb_protect(call_status_handler2, callargs, &status);
340
+ if (status) {
341
+ CURB_RB_CALLBACK_RAISE("redirect")
342
+ }
343
+ } else if (!rb_easy_nil("missing_proc") &&
334
344
  (response_code >= 400 && response_code < 500)) {
335
345
  rbce->callback_active = 1;
336
346
  callargs = rb_ary_new3(3, rb_easy_get("missing_proc"), easy, rb_curl_easy_error(result));
337
347
  rbce->callback_active = 0;
338
- val = rb_rescue(call_status_handler2, callargs, callback_exception, Qnil);
339
- }
340
- else if (!rb_easy_nil("failure_proc") &&
348
+ rb_protect(call_status_handler2, callargs, &status);
349
+ if (status) {
350
+ CURB_RB_CALLBACK_RAISE("missing")
351
+ }
352
+ } else if (!rb_easy_nil("failure_proc") &&
341
353
  (response_code >= 500 && response_code <= 999)) {
342
354
  callargs = rb_ary_new3(3, rb_easy_get("failure_proc"), easy, rb_curl_easy_error(result));
343
355
  rbce->callback_active = 1;
344
- val = rb_rescue(call_status_handler2, callargs, callback_exception, Qnil);
356
+ rb_protect(call_status_handler2, callargs, &status);
345
357
  rbce->callback_active = 0;
346
- //rb_funcall( rb_easy_get("failure_proc"), idCall, 2, easy, rb_curl_easy_error(result) );
358
+ if (status) {
359
+ CURB_RB_CALLBACK_RAISE("failure")
360
+ }
347
361
  }
348
362
 
349
363
  }
@@ -627,6 +641,8 @@ void init_curb_multi() {
627
641
  idCall = rb_intern("call");
628
642
  cCurlMulti = rb_define_class_under(mCurl, "Multi", rb_cObject);
629
643
 
644
+ rb_undef_alloc_func(cCurlMulti);
645
+
630
646
  /* Class methods */
631
647
  rb_define_singleton_method(cCurlMulti, "new", ruby_curl_multi_new, 0);
632
648
  rb_define_singleton_method(cCurlMulti, "default_timeout=", ruby_curl_multi_set_default_timeout, 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
@@ -498,6 +498,8 @@ void init_curb_postfield() {
498
498
 
499
499
  cCurlPostField = rb_define_class_under(mCurl, "PostField", rb_cObject);
500
500
 
501
+ rb_undef_alloc_func(cCurlPostField);
502
+
501
503
  /* Class methods */
502
504
  rb_define_singleton_method(cCurlPostField, "content", ruby_curl_postfield_new_content, -1);
503
505
  rb_define_singleton_method(cCurlPostField, "file", ruby_curl_postfield_new_file, -1);
data/ext/curb_upload.c CHANGED
@@ -72,6 +72,7 @@ VALUE ruby_curl_upload_offset_get(VALUE self) {
72
72
  /* =================== INIT LIB =====================*/
73
73
  void init_curb_upload() {
74
74
  cCurlUpload = rb_define_class_under(mCurl, "Upload", rb_cObject);
75
+ rb_undef_alloc_func(cCurlUpload);
75
76
  rb_define_singleton_method(cCurlUpload, "new", ruby_curl_upload_new, 0);
76
77
  rb_define_method(cCurlUpload, "stream=", ruby_curl_upload_stream_set, 1);
77
78
  rb_define_method(cCurlUpload, "stream", ruby_curl_upload_stream_get, 0);
data/ext/extconf.rb CHANGED
@@ -405,6 +405,8 @@ have_constant "curlopt_path_as_is"
405
405
  # added in 7.43.0
406
406
  have_constant "curlopt_pipewait"
407
407
 
408
+ have_constant "curlopt_proxy_ssl_verifyhost"
409
+
408
410
  # protocol constants
409
411
  have_constant "curlproto_all"
410
412
  have_constant "curlproto_dict"
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
@@ -20,11 +20,21 @@ class BugCrashOnDebug < Test::Unit::TestCase
20
20
  end
21
21
  puts 'b'
22
22
  c = Curl::Easy.new('http://127.0.0.1:9999/test')
23
- c.on_debug do|x|
24
- puts x.inspect
25
- raise "error" # this will get swallowed
23
+ did_raise = false
24
+ did_call = false
25
+ begin
26
+ c.on_success do|x|
27
+ puts x.inspect
28
+ did_call = true
29
+ raise "error" # this will get swallowed
30
+ end
31
+ c.perform
32
+ rescue => e
33
+ did_raise = true
26
34
  end
27
- c.perform
35
+ puts c.response_code
36
+ assert did_raise
37
+ assert did_call
28
38
  puts 'c'
29
39
  ensure
30
40
  puts 'd'
@@ -28,7 +28,8 @@ class BugCrashOnDebug < Test::Unit::TestCase
28
28
  assert_equal 'Curl::Err::AbortedByCallbackError', e.class.to_s
29
29
  c.close
30
30
  ensure
31
- server.shutdown
31
+ server&.shutdown
32
+ thread&.exit
32
33
  end
33
34
 
34
35
  def test_on_progress_abort
@@ -67,7 +68,8 @@ class BugCrashOnDebug < Test::Unit::TestCase
67
68
  assert_equal 'Curl::Err::AbortedByCallbackError', e.class.to_s
68
69
  c.close
69
70
  ensure
70
- server.shutdown
71
+ server&.shutdown
72
+ thread&.exit
71
73
  end
72
74
 
73
75
  end
@@ -0,0 +1,91 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
+ require 'webrick'
3
+ class ::WEBrick::HTTPServer ; def access_log(config, req, res) ; end ; end
4
+ class ::WEBrick::BasicLog ; def log(level, data) ; end ; end
5
+
6
+ class BugFollowRedirect288 < Test::Unit::TestCase
7
+ def test_follow_redirect_with_no_redirect
8
+ server = WEBrick::HTTPServer.new( :Port => 9999 )
9
+ server.mount_proc("/test") do|req,res|
10
+ res.body = "hi"
11
+ res['Content-Type'] = "text/html"
12
+ end
13
+ server.mount_proc("/redirect_to_test") do|req,res|
14
+ res.set_redirect(WEBrick::HTTPStatus::TemporaryRedirect, "/test")
15
+ end
16
+
17
+ thread = Thread.new(server) do|srv|
18
+ srv.start
19
+ end
20
+
21
+ c = Curl::Easy.new('http://127.0.0.1:9999/test')
22
+ did_call_redirect = false
23
+ c.on_redirect do|x|
24
+ did_call_redirect = true
25
+ end
26
+ c.perform
27
+
28
+ assert !did_call_redirect, "should reach this point redirect should not have been called"
29
+
30
+ c = Curl::Easy.new('http://127.0.0.1:9999/test')
31
+ did_call_redirect = false
32
+ c.on_redirect do|x|
33
+ did_call_redirect = true
34
+ end
35
+ c.follow_location = true
36
+ c.perform
37
+
38
+ assert_equal 0, c.redirect_count
39
+ assert !did_call_redirect, "should reach this point redirect should not have been called"
40
+
41
+ c = Curl::Easy.new('http://127.0.0.1:9999/redirect_to_test')
42
+ did_call_redirect = false
43
+ c.on_redirect do|x|
44
+ did_call_redirect = true
45
+ end
46
+ c.perform
47
+ assert_equal 307, c.response_code
48
+
49
+ assert did_call_redirect, "we should have called on_redirect"
50
+
51
+ c = Curl::Easy.new('http://127.0.0.1:9999/redirect_to_test')
52
+ did_call_redirect = false
53
+ c.follow_location = true
54
+ # NOTE: while this API is not supported by libcurl e.g. there is no redirect function callback in libcurl we could
55
+ # add support in ruby for this by executing this callback if redirect_count is greater than 0 at the end of a request in curb_multi.c
56
+ c.on_redirect do|x|
57
+ did_call_redirect = true
58
+ end
59
+ c.perform
60
+ assert_equal 1, c.redirect_count
61
+ assert_equal 200, c.response_code
62
+
63
+ assert did_call_redirect, "we should have called on_redirect"
64
+
65
+ c.url = 'http://127.0.0.1:9999/test'
66
+ c.perform
67
+ assert_equal 0, c.redirect_count
68
+ assert_equal 200, c.response_code
69
+
70
+ did_raise = false
71
+ begin
72
+ c = Curl::Easy.new('http://127.0.0.1:9999/redirect_to_test')
73
+ did_call_redirect = false
74
+ c.on_redirect do|x|
75
+ raise "raise"
76
+ did_call_redirect = true
77
+ end
78
+ c.perform
79
+ rescue => e
80
+ did_raise = true
81
+ end
82
+ assert did_raise
83
+ assert_equal 307, c.response_code
84
+
85
+ ensure
86
+ server.stop
87
+ thread.join
88
+
89
+ end
90
+
91
+ 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
@@ -0,0 +1,40 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
+
3
+ require 'webrick'
4
+ class ::WEBrick::HTTPServer ; def access_log(config, req, res) ; end ; end
5
+ class ::WEBrick::BasicLog ; def log(level, data) ; end ; end
6
+
7
+ require 'curl'
8
+
9
+ class BugRaiseOnCallback < Test::Unit::TestCase
10
+
11
+ def test_on_complte
12
+ server = WEBrick::HTTPServer.new( :Port => 9999 )
13
+ server.mount_proc("/test") do|req,res|
14
+ res.body = "hi"
15
+ res['Content-Type'] = "text/html"
16
+ end
17
+ thread = Thread.new(server) do|srv|
18
+ srv.start
19
+ end
20
+ c = Curl::Easy.new('http://127.0.0.1:9999/test')
21
+ did_raise = false
22
+ begin
23
+ c.on_complete do|x|
24
+ assert_equal 'http://127.0.0.1:9999/test', x.url
25
+ raise "error complete" # this will get swallowed
26
+ end
27
+ c.perform
28
+ rescue => e
29
+ did_raise = true
30
+ end
31
+ assert did_raise, "we want to raise an exception if the ruby callbacks raise"
32
+
33
+ ensure
34
+ server.shutdown
35
+ thread.exit
36
+ end
37
+
38
+ end
39
+
40
+ #test_on_debug
@@ -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
@@ -713,9 +721,9 @@ class TestCurbCurlEasy < Test::Unit::TestCase
713
721
  on_success_called = false
714
722
  curl.on_success {|c|
715
723
  on_success_called = true
716
- assert_not_nil c.body_str
717
- assert_equal "", c.header_str
718
- assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body_str)
724
+ assert_not_nil c.body
725
+ assert_match /Content-Length: 7714/, c.head
726
+ assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body)
719
727
  }
720
728
  curl.perform
721
729
  assert on_success_called, "Success handler not called"
@@ -1139,7 +1147,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
1139
1147
  c = Curl::Easy.new($TEST_URL)
1140
1148
  c.on_success {|x| raise "error" }
1141
1149
  c.perform
1142
- rescue => e
1150
+ rescue Curl::Err::AbortedByCallbackError => e
1143
1151
  assert_equal 'Curl::Err::AbortedByCallbackError', e.class.to_s
1144
1152
  c.close
1145
1153
  end
@@ -74,7 +74,9 @@ class TestCurbCurlMulti < Test::Unit::TestCase
74
74
  assert did_complete
75
75
  after_open = open_fds.call
76
76
  #puts "after_open: #{after_open} before_open: #{before_open.inspect}"
77
- assert_equal 1, (after_open - before_open), "with max connections set to 1 at this point the connection to google should still be open"
77
+ # ruby process may keep a connection alive
78
+ assert (after_open - before_open) < 3, "with max connections set to 1 at this point the connection to google should still be open"
79
+ assert (after_open - before_open) > 0, "with max connections set to 1 at this point the connection to google should still be open"
78
80
  multi.close
79
81
 
80
82
  after_open = open_fds.call
@@ -480,7 +482,7 @@ class TestCurbCurlMulti < Test::Unit::TestCase
480
482
  { :url => TestServlet.url, :method => :get }
481
483
  ]
482
484
  Curl::Multi.http(urls, {:pipeline => true}) do|easy, code, method|
483
- assert_equal nil, code
485
+ assert_equal 200, code
484
486
  case method
485
487
  when :post
486
488
  assert_match(/POST/, easy.body_str)
@@ -494,20 +496,20 @@ class TestCurbCurlMulti < Test::Unit::TestCase
494
496
  end
495
497
 
496
498
  def test_multi_easy_http_with_max_connects
497
- urls = [
499
+ urls = [
498
500
  { :url => TestServlet.url + '?q=1', :method => :get },
499
501
  { :url => TestServlet.url + '?q=2', :method => :get },
500
502
  { :url => TestServlet.url + '?q=3', :method => :get }
501
503
  ]
502
504
  Curl::Multi.http(urls, {:pipeline => true, :max_connects => 1}) do|easy, code, method|
503
- assert_equal nil, code
505
+ assert_equal 200, code
504
506
  case method
505
507
  when :post
506
- assert_match(/POST/, easy.body_str)
508
+ assert_match(/POST/, easy.body)
507
509
  when :get
508
- assert_match(/GET/, easy.body_str)
510
+ assert_match(/GET/, easy.body)
509
511
  when :put
510
- assert_match(/PUT/, easy.body_str)
512
+ assert_match(/PUT/, easy.body)
511
513
  end
512
514
  end
513
515
  end
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.2
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-12-28 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
@@ -50,11 +50,14 @@ files:
50
50
  - tests/bug_crash_on_progress.rb
51
51
  - tests/bug_curb_easy_blocks_ruby_threads.rb
52
52
  - tests/bug_curb_easy_post_with_string_no_content_length_header.rb
53
+ - tests/bug_follow_redirect_288.rb
53
54
  - tests/bug_instance_post_differs_from_class_post.rb
54
55
  - tests/bug_issue102.rb
56
+ - tests/bug_issue277.rb
55
57
  - tests/bug_multi_segfault.rb
56
58
  - tests/bug_postfields_crash.rb
57
59
  - tests/bug_postfields_crash2.rb
60
+ - tests/bug_raise_on_callback.rb
58
61
  - tests/bug_require_last_or_segfault.rb
59
62
  - tests/bugtests.rb
60
63
  - tests/helper.rb
@@ -77,7 +80,7 @@ homepage: https://github.com/taf2/curb
77
80
  licenses:
78
81
  - MIT
79
82
  metadata: {}
80
- post_install_message:
83
+ post_install_message:
81
84
  rdoc_options:
82
85
  - "--main"
83
86
  - README.markdown
@@ -95,8 +98,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
98
  - !ruby/object:Gem::Version
96
99
  version: '0'
97
100
  requirements: []
98
- rubygems_version: 3.3.3
99
- signing_key:
101
+ rubygems_version: 3.2.33
102
+ signing_key:
100
103
  specification_version: 4
101
104
  summary: Ruby libcurl bindings
102
105
  test_files:
@@ -105,11 +108,14 @@ test_files:
105
108
  - tests/bug_crash_on_progress.rb
106
109
  - tests/bug_curb_easy_blocks_ruby_threads.rb
107
110
  - tests/bug_curb_easy_post_with_string_no_content_length_header.rb
111
+ - tests/bug_follow_redirect_288.rb
108
112
  - tests/bug_instance_post_differs_from_class_post.rb
109
113
  - tests/bug_issue102.rb
114
+ - tests/bug_issue277.rb
110
115
  - tests/bug_multi_segfault.rb
111
116
  - tests/bug_postfields_crash.rb
112
117
  - tests/bug_postfields_crash2.rb
118
+ - tests/bug_raise_on_callback.rb
113
119
  - tests/bug_require_last_or_segfault.rb
114
120
  - tests/bugtests.rb
115
121
  - tests/helper.rb