curb 1.0.1 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b452d79ee28ee380d6741f39f9fbf826a33a46d473fa4444edb6a56a122af8f8
4
- data.tar.gz: '094812699e5b64584d6dd02a17b16884ee696a20dbf324c05498a46509e39b16'
3
+ metadata.gz: e28b1d05b46460867acfadc87bbe422d58d8f2cdb93397fa6ded906b01cd7dab
4
+ data.tar.gz: 33e7037c1c2b23a793ec96c73bc80c008939c880702f884d2b258d4afd18c368
5
5
  SHA512:
6
- metadata.gz: 0df71c1a4eb7896f89da78a79ba9160d5606aa235b89544e08630c558a7cebb1220ec026f99f404915f52e15162cf2c988a66abe04932c3cd1104a1784bd3056
7
- data.tar.gz: '08fba6b5b9a9404f839e4110b0d485e1595be36554345abb88a05482183204f4e0f13001a7731db75e89ca890bfa8ad19ccced63dfecd0e766f1b825ff5e9f1a'
6
+ metadata.gz: 6eb448726a4fdce1e0832e36a45b2c8e0a078fbc2c04b3fe34f87fc38397f5c4ecc4fe621aed5637750c5c7a7a9d05b30c03f9f7db153c23d3694eb6adb464e8
7
+ data.tar.gz: 624e3f39af79eff874784a662776debc2b405378c6cdc963a50dee525d36aa225cc5f40558f9b35b396c222416006f66c29fc6193e651b5aa84093fdd52cb2ba
data/README.markdown CHANGED
@@ -1,5 +1,6 @@
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
 
@@ -11,26 +12,38 @@ Curb is a work-in-progress, and currently only supports libcurl's `easy` and `mu
11
12
 
12
13
  ## License
13
14
 
14
- Curb is copyright (c)2006 Ross Bamford, and released under the terms of the
15
+ Curb is copyright (c) 2006 Ross Bamford, and released under the terms of the
15
16
  Ruby license. See the LICENSE file for the gory details.
16
17
 
17
18
  ## Easy mode
18
19
 
19
- Get stuff
20
+ GET request
20
21
  ```
21
- res = Curl.get("https://www.google.com/")
22
- puts res.response_code
23
- puts res.header_str
22
+ res = Curl.get("https://www.google.com/") {|http|
23
+ http.timeout = 10 # raise exception if request/response not handled within 10 seconds
24
+ }
25
+ puts res.code
26
+ puts res.head
24
27
  puts res.body
25
28
  ```
26
29
 
27
- Post stuff
30
+ POST request
28
31
  ```
29
32
  res = Curl.post("https://your-server.com/endpoint", {post: "this"}.to_json) {|http|
30
33
  http.headers["Content-Type"] = "application/json"
31
34
  }
32
- puts res.response_code
33
- puts res.header_str
35
+ puts res.code
36
+ puts res.head
37
+ puts res.body
38
+ ```
39
+
40
+ PATCH request
41
+ ```
42
+ res = Curl.patch("https://your-server.com/endpoint", {post: "this"}.to_json) {|http|
43
+ http.headers["Content-Type"] = "application/json"
44
+ }
45
+ puts res.code
46
+ puts res.head
34
47
  puts res.body
35
48
  ```
36
49
 
data/Rakefile CHANGED
@@ -2,6 +2,7 @@
2
2
  #
3
3
  require 'rake/clean'
4
4
  require 'rake/testtask'
5
+ require "ruby_memcheck"
5
6
 
6
7
  CLEAN.include '**/*.o'
7
8
  CLEAN.include "**/*.#{(defined?(RbConfig) ? RbConfig : Config)::MAKEFILE_CONFIG['DLEXT']}"
@@ -10,13 +11,6 @@ CLOBBER.include '**/*.log'
10
11
  CLOBBER.include '**/Makefile'
11
12
  CLOBBER.include '**/extconf.h'
12
13
 
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
14
  # Load support ruby and rake files (in this order)
21
15
  Dir.glob('tasks/*.rb').each { |r| load r}
22
16
  Dir.glob('tasks/*.rake').each { |r| load r}
@@ -97,6 +91,14 @@ else
97
91
  task :alltests => [:unittests, :bugtests]
98
92
  end
99
93
 
94
+ RubyMemcheck.config(binary_name: 'curb_core')
95
+ namespace :test do
96
+ RubyMemcheck::TestTask.new(valgrind: :compile) do|t|
97
+ t.test_files = FileList['tests/tc_*.rb']
98
+ t.verbose = false
99
+ end
100
+ end
101
+
100
102
  Rake::TestTask.new(:unittests) do |t|
101
103
  t.test_files = FileList['tests/tc_*.rb']
102
104
  t.verbose = false
data/ext/curb.c CHANGED
@@ -1076,6 +1076,10 @@ void Init_curb_core() {
1076
1076
  CURB_DEFINE(CURLOPT_HAPROXYPROTOCOL);
1077
1077
  #endif
1078
1078
 
1079
+ #if HAVE_CURLOPT_PROXY_SSL_VERIFYHOST
1080
+ CURB_DEFINE(CURLOPT_PROXY_SSL_VERIFYHOST);
1081
+ #endif
1082
+
1079
1083
  #if HAVE_CURLPROTO_RTMPTE
1080
1084
  CURB_DEFINE(CURLPROTO_RTMPTE);
1081
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.1"
32
- #define CURB_VER_NUM 1001
31
+ #define CURB_VERSION "1.0.5"
32
+ #define CURB_VER_NUM 1005
33
33
  #define CURB_VER_MAJ 1
34
34
  #define CURB_VER_MIN 0
35
- #define CURB_VER_MIC 1
35
+ #define CURB_VER_MIC 5
36
36
  #define CURB_VER_PATCH 0
37
37
 
38
38
 
data/ext/curb_easy.c CHANGED
@@ -34,7 +34,7 @@ static FILE * rb_io_stdio_file(rb_io_t *fptr) {
34
34
 
35
35
  /* ================== CURL HANDLER FUNCS ==============*/
36
36
 
37
- static VALUE callback_exception(VALUE unused) {
37
+ static VALUE callback_exception(VALUE unused, VALUE exception) {
38
38
  return Qfalse;
39
39
  }
40
40
 
@@ -1311,7 +1311,7 @@ static VALUE ruby_curl_easy_connect_timeout_set(VALUE self, VALUE connect_timeou
1311
1311
  * Obtain the maximum time in seconds that you allow the connection to the
1312
1312
  * server to take.
1313
1313
  */
1314
- static VALUE ruby_curl_easy_connect_timeout_get(VALUE self, VALUE connect_timeout) {
1314
+ static VALUE ruby_curl_easy_connect_timeout_get(VALUE self) {
1315
1315
  CURB_IMMED_GETTER(ruby_curl_easy, connect_timeout, 0);
1316
1316
  }
1317
1317
 
@@ -1337,7 +1337,7 @@ static VALUE ruby_curl_easy_connect_timeout_ms_set(VALUE self, VALUE connect_tim
1337
1337
  * Obtain the maximum time in milliseconds that you allow the connection to the
1338
1338
  * server to take.
1339
1339
  */
1340
- static VALUE ruby_curl_easy_connect_timeout_ms_get(VALUE self, VALUE connect_timeout_ms) {
1340
+ static VALUE ruby_curl_easy_connect_timeout_ms_get(VALUE self) {
1341
1341
  CURB_IMMED_GETTER(ruby_curl_easy, connect_timeout_ms, 0);
1342
1342
  }
1343
1343
 
@@ -1360,7 +1360,7 @@ static VALUE ruby_curl_easy_dns_cache_timeout_set(VALUE self, VALUE dns_cache_ti
1360
1360
  *
1361
1361
  * Obtain the dns cache timeout in seconds.
1362
1362
  */
1363
- static VALUE ruby_curl_easy_dns_cache_timeout_get(VALUE self, VALUE dns_cache_timeout) {
1363
+ static VALUE ruby_curl_easy_dns_cache_timeout_get(VALUE self) {
1364
1364
  CURB_IMMED_GETTER(ruby_curl_easy, dns_cache_timeout, -1);
1365
1365
  }
1366
1366
 
@@ -1387,7 +1387,7 @@ static VALUE ruby_curl_easy_ftp_response_timeout_set(VALUE self, VALUE ftp_respo
1387
1387
  *
1388
1388
  * Obtain the maximum time that libcurl will wait for FTP command responses.
1389
1389
  */
1390
- static VALUE ruby_curl_easy_ftp_response_timeout_get(VALUE self, VALUE ftp_response_timeout) {
1390
+ static VALUE ruby_curl_easy_ftp_response_timeout_get(VALUE self) {
1391
1391
  CURB_IMMED_GETTER(ruby_curl_easy, ftp_response_timeout, 0);
1392
1392
  }
1393
1393
 
@@ -1410,7 +1410,7 @@ static VALUE ruby_curl_easy_low_speed_limit_set(VALUE self, VALUE low_speed_limi
1410
1410
  * Obtain the minimum transfer speed over +low_speed+time+ below which the
1411
1411
  * transfer will be aborted.
1412
1412
  */
1413
- static VALUE ruby_curl_easy_low_speed_limit_get(VALUE self, VALUE low_speed_limit) {
1413
+ static VALUE ruby_curl_easy_low_speed_limit_get(VALUE self) {
1414
1414
  CURB_IMMED_GETTER(ruby_curl_easy, low_speed_limit, 0);
1415
1415
  }
1416
1416
 
@@ -1432,7 +1432,7 @@ static VALUE ruby_curl_easy_low_speed_time_set(VALUE self, VALUE low_speed_time)
1432
1432
  * Obtain the time that the transfer should be below +low_speed_limit+ for
1433
1433
  * the library to abort it.
1434
1434
  */
1435
- static VALUE ruby_curl_easy_low_speed_time_get(VALUE self, VALUE low_speed_time) {
1435
+ static VALUE ruby_curl_easy_low_speed_time_get(VALUE self) {
1436
1436
  CURB_IMMED_GETTER(ruby_curl_easy, low_speed_time, 0);
1437
1437
  }
1438
1438
 
@@ -1452,7 +1452,7 @@ static VALUE ruby_curl_easy_max_send_speed_large_set(VALUE self, VALUE max_send_
1452
1452
  *
1453
1453
  * Get the maximal sending transfer speed (in bytes per second)
1454
1454
  */
1455
- static VALUE ruby_curl_easy_max_send_speed_large_get(VALUE self, VALUE max_send_speed_large) {
1455
+ static VALUE ruby_curl_easy_max_send_speed_large_get(VALUE self) {
1456
1456
  CURB_IMMED_GETTER(ruby_curl_easy, max_send_speed_large, 0);
1457
1457
  }
1458
1458
 
@@ -1472,7 +1472,7 @@ static VALUE ruby_curl_easy_max_recv_speed_large_set(VALUE self, VALUE max_recv_
1472
1472
  *
1473
1473
  * Get the maximal receiving transfer speed (in bytes per second)
1474
1474
  */
1475
- static VALUE ruby_curl_easy_max_recv_speed_large_get(VALUE self, VALUE max_recv_speed_large) {
1475
+ static VALUE ruby_curl_easy_max_recv_speed_large_get(VALUE self) {
1476
1476
  CURB_IMMED_GETTER(ruby_curl_easy, max_recv_speed_large, 0);
1477
1477
  }
1478
1478
 
@@ -1496,7 +1496,7 @@ static VALUE ruby_curl_easy_username_set(VALUE self, VALUE username) {
1496
1496
  *
1497
1497
  * Get the current username
1498
1498
  */
1499
- static VALUE ruby_curl_easy_username_get(VALUE self, VALUE username) {
1499
+ static VALUE ruby_curl_easy_username_get(VALUE self) {
1500
1500
  #if HAVE_CURLOPT_USERNAME
1501
1501
  CURB_OBJECT_HGETTER(ruby_curl_easy, username);
1502
1502
  #else
@@ -1524,7 +1524,7 @@ static VALUE ruby_curl_easy_password_set(VALUE self, VALUE password) {
1524
1524
  *
1525
1525
  * Get the current password
1526
1526
  */
1527
- static VALUE ruby_curl_easy_password_get(VALUE self, VALUE password) {
1527
+ static VALUE ruby_curl_easy_password_get(VALUE self) {
1528
1528
  #if HAVE_CURLOPT_PASSWORD
1529
1529
  CURB_OBJECT_HGETTER(ruby_curl_easy, password);
1530
1530
  #else
@@ -1558,7 +1558,7 @@ static VALUE ruby_curl_easy_ssl_version_set(VALUE self, VALUE ssl_version) {
1558
1558
  *
1559
1559
  * Get the version of SSL/TLS that libcurl will attempt to use.
1560
1560
  */
1561
- static VALUE ruby_curl_easy_ssl_version_get(VALUE self, VALUE ssl_version) {
1561
+ static VALUE ruby_curl_easy_ssl_version_get(VALUE self) {
1562
1562
  CURB_IMMED_GETTER(ruby_curl_easy, ssl_version, -1);
1563
1563
  }
1564
1564
 
@@ -1579,7 +1579,7 @@ static VALUE ruby_curl_easy_use_ssl_set(VALUE self, VALUE use_ssl) {
1579
1579
  *
1580
1580
  * Get the desired level for using SSL on FTP connections.
1581
1581
  */
1582
- static VALUE ruby_curl_easy_use_ssl_get(VALUE self, VALUE use_ssl) {
1582
+ static VALUE ruby_curl_easy_use_ssl_get(VALUE self) {
1583
1583
  CURB_IMMED_GETTER(ruby_curl_easy, use_ssl, -1);
1584
1584
  }
1585
1585
 
@@ -1600,7 +1600,7 @@ static VALUE ruby_curl_easy_ftp_filemethod_set(VALUE self, VALUE ftp_filemethod)
1600
1600
  *
1601
1601
  * Get the configuration for how libcurl will reach files on the server.
1602
1602
  */
1603
- static VALUE ruby_curl_easy_ftp_filemethod_get(VALUE self, VALUE ftp_filemethod) {
1603
+ static VALUE ruby_curl_easy_ftp_filemethod_get(VALUE self) {
1604
1604
  CURB_IMMED_GETTER(ruby_curl_easy, ftp_filemethod, -1);
1605
1605
  }
1606
1606
 
@@ -2122,7 +2122,7 @@ static VALUE ruby_curl_easy_on_debug_set(int argc, VALUE *argv, VALUE self) {
2122
2122
  /***********************************************
2123
2123
  * This is an rb_iterate callback used to set up http headers.
2124
2124
  */
2125
- static VALUE cb_each_http_header(VALUE header, VALUE wrap) {
2125
+ static VALUE cb_each_http_header(VALUE header, VALUE wrap, int _c, const VALUE *_ptr, VALUE unused) {
2126
2126
  struct curl_slist **list;
2127
2127
  VALUE header_str = Qnil;
2128
2128
 
@@ -2157,7 +2157,7 @@ static VALUE cb_each_http_header(VALUE header, VALUE wrap) {
2157
2157
  /***********************************************
2158
2158
  * This is an rb_iterate callback used to set up http proxy headers.
2159
2159
  */
2160
- static VALUE cb_each_http_proxy_header(VALUE proxy_header, VALUE wrap) {
2160
+ static VALUE cb_each_http_proxy_header(VALUE proxy_header, VALUE wrap, int _c, const VALUE *_ptr, VALUE unused) {
2161
2161
  struct curl_slist **list;
2162
2162
  VALUE proxy_header_str = Qnil;
2163
2163
 
@@ -2189,7 +2189,7 @@ static VALUE cb_each_http_proxy_header(VALUE proxy_header, VALUE wrap) {
2189
2189
  /***********************************************
2190
2190
  * This is an rb_iterate callback used to set up ftp commands.
2191
2191
  */
2192
- static VALUE cb_each_ftp_command(VALUE ftp_command, VALUE wrap) {
2192
+ static VALUE cb_each_ftp_command(VALUE ftp_command, VALUE wrap, int _c, const VALUE *_ptr, VALUE unused) {
2193
2193
  struct curl_slist **list;
2194
2194
  VALUE ftp_command_string;
2195
2195
  Data_Get_Struct(wrap, struct curl_slist *, list);
@@ -2203,7 +2203,7 @@ static VALUE cb_each_ftp_command(VALUE ftp_command, VALUE wrap) {
2203
2203
  /***********************************************
2204
2204
  * This is an rb_iterate callback used to set up the resolve list.
2205
2205
  */
2206
- static VALUE cb_each_resolve(VALUE resolve, VALUE wrap) {
2206
+ static VALUE cb_each_resolve(VALUE resolve, VALUE wrap, int _c, const VALUE *_ptr, VALUE unused) {
2207
2207
  struct curl_slist **list;
2208
2208
  VALUE resolve_string;
2209
2209
  Data_Get_Struct(wrap, struct curl_slist *, list);
@@ -2602,7 +2602,7 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
2602
2602
  }
2603
2603
 
2604
2604
  // set values on cleanup to nil
2605
- rb_easy_del("multi");
2605
+ //rb_easy_del("multi");
2606
2606
 
2607
2607
  return Qnil;
2608
2608
  }
@@ -3653,6 +3653,11 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
3653
3653
  case CURLOPT_SSL_SESSIONID_CACHE:
3654
3654
  curl_easy_setopt(rbce->curl, CURLOPT_SSL_SESSIONID_CACHE, NUM2LONG(val));
3655
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;
3656
3661
  #endif
3657
3662
  default:
3658
3663
  rb_raise(rb_eTypeError, "Curb unsupported option");
@@ -3770,6 +3775,7 @@ static VALUE ruby_curl_easy_error_message(VALUE klass, VALUE code) {
3770
3775
  }
3771
3776
 
3772
3777
  /* =================== INIT LIB =====================*/
3778
+ // TODO: https://bugs.ruby-lang.org/issues/18007
3773
3779
  void init_curb_easy() {
3774
3780
  idCall = rb_intern("call");
3775
3781
  idJoin = rb_intern("join");
@@ -3915,6 +3921,7 @@ void init_curb_easy() {
3915
3921
 
3916
3922
  rb_define_method(cCurlEasy, "last_effective_url", ruby_curl_easy_last_effective_url_get, 0);
3917
3923
  rb_define_method(cCurlEasy, "response_code", ruby_curl_easy_response_code_get, 0);
3924
+ rb_define_method(cCurlEasy, "code", ruby_curl_easy_response_code_get, 0);
3918
3925
  #if defined(HAVE_CURLINFO_PRIMARY_IP)
3919
3926
  rb_define_method(cCurlEasy, "primary_ip", ruby_curl_easy_primary_ip_get, 0);
3920
3927
  #endif
data/ext/curb_macros.h CHANGED
@@ -156,4 +156,16 @@
156
156
  #define CURB_DEFINE(name) \
157
157
  rb_define_const(mCurl, #name, LONG2NUM(name))
158
158
 
159
+ /* copy and raise exception */
160
+ #define CURB_CHECK_RB_CALLBACK_RAISE(did_raise) \
161
+ VALUE exception = rb_hash_aref(did_raise, rb_easy_hkey("error")); \
162
+ if (FIX2INT(rb_hash_size(did_raise)) > 0 && exception != Qnil) { \
163
+ rb_hash_clear(did_raise); \
164
+ VALUE message = rb_funcall(exception, rb_intern("message"), 0); \
165
+ VALUE aborted_exception = rb_exc_new_str(eCurlErrAbortedByCallback, message); \
166
+ VALUE backtrace = rb_funcall(exception, rb_intern("backtrace"), 0); \
167
+ rb_funcall(aborted_exception, rb_intern("set_backtrace"), 1, backtrace); \
168
+ rb_exc_raise(aborted_exception); \
169
+ }
170
+
159
171
  #endif
data/ext/curb_multi.c CHANGED
@@ -43,8 +43,25 @@ 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;
46
+ static VALUE callback_exception(VALUE did_raise, VALUE exception) {
47
+ // TODO: we could have an option to enable exception reporting
48
+ /* VALUE ret = rb_funcall(exception, rb_intern("message"), 0);
49
+ VALUE trace = rb_funcall(exception, rb_intern("backtrace"), 0);
50
+ if (RB_TYPE_P(trace, T_ARRAY) && RARRAY_LEN(trace) > 0) {
51
+ printf("we got an exception: %s:%d\n", StringValueCStr(ret), RARRAY_LEN(trace));
52
+ VALUE sep = rb_str_new_cstr("\n");
53
+ VALUE trace_lines = rb_ary_join(trace, sep);
54
+ if (RB_TYPE_P(trace_lines, T_STRING)) {
55
+ printf("%s\n", StringValueCStr(trace_lines));
56
+ } else {
57
+ printf("trace is not a string??\n");
58
+ }
59
+ } else {
60
+ printf("we got an exception: %s\nno stack available\n", StringValueCStr(ret));
61
+ }
62
+ */
63
+ rb_hash_aset(did_raise, rb_easy_hkey("error"), exception);
64
+ return exception;
48
65
  }
49
66
 
50
67
  void curl_multi_free(ruby_curl_multi *rbcm) {
@@ -274,7 +291,7 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
274
291
  long response_code = -1;
275
292
  VALUE easy;
276
293
  ruby_curl_easy *rbce = NULL;
277
- VALUE callargs, val = Qtrue;
294
+ VALUE callargs;
278
295
 
279
296
  CURLcode ecode = curl_easy_getinfo(easy_handle, CURLINFO_PRIVATE, (char**)&easy);
280
297
 
@@ -295,11 +312,14 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
295
312
  raise_curl_easy_error_exception(ecode);
296
313
  }
297
314
 
315
+ VALUE did_raise = rb_hash_new();
316
+
298
317
  if (!rb_easy_nil("complete_proc")) {
299
318
  callargs = rb_ary_new3(2, rb_easy_get("complete_proc"), easy);
300
319
  rbce->callback_active = 1;
301
- val = rb_rescue(call_status_handler1, callargs, callback_exception, Qnil);
320
+ rb_rescue(call_status_handler1, callargs, callback_exception, did_raise);
302
321
  rbce->callback_active = 0;
322
+ CURB_CHECK_RB_CALLBACK_RAISE(did_raise);
303
323
  }
304
324
 
305
325
  #ifdef HAVE_CURLINFO_RESPONSE_CODE
@@ -308,42 +328,46 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
308
328
  // old libcurl
309
329
  curl_easy_getinfo(rbce->curl, CURLINFO_HTTP_CODE, &response_code);
310
330
  #endif
331
+ long redirect_count;
332
+ curl_easy_getinfo(rbce->curl, CURLINFO_REDIRECT_COUNT, &redirect_count);
311
333
 
312
334
  if (result != 0) {
313
335
  if (!rb_easy_nil("failure_proc")) {
314
336
  callargs = rb_ary_new3(3, rb_easy_get("failure_proc"), easy, rb_curl_easy_error(result));
315
337
  rbce->callback_active = 1;
316
- val = rb_rescue(call_status_handler2, callargs, callback_exception, Qnil);
338
+ rb_rescue(call_status_handler2, callargs, callback_exception, did_raise);
317
339
  rbce->callback_active = 0;
318
- //rb_funcall( rb_easy_get("failure_proc"), idCall, 2, easy, rb_curl_easy_error(result) );
340
+ CURB_CHECK_RB_CALLBACK_RAISE(did_raise);
319
341
  }
320
342
  } else if (!rb_easy_nil("success_proc") &&
321
343
  ((response_code >= 200 && response_code < 300) || response_code == 0)) {
322
344
  /* NOTE: we allow response_code == 0, in the case of non http requests e.g. reading from disk */
323
345
  callargs = rb_ary_new3(2, rb_easy_get("success_proc"), easy);
324
346
  rbce->callback_active = 1;
325
- val = rb_rescue(call_status_handler1, callargs, callback_exception, Qnil);
347
+ rb_rescue(call_status_handler1, callargs, callback_exception, did_raise);
326
348
  rbce->callback_active = 0;
327
- //rb_funcall( rb_easy_get("success_proc"), idCall, 1, easy );
328
- } else if (!rb_easy_nil("redirect_proc") &&
329
- (response_code >= 300 && response_code < 400)) {
349
+ CURB_CHECK_RB_CALLBACK_RAISE(did_raise);
350
+
351
+ } else if (!rb_easy_nil("redirect_proc") && ((response_code >= 300 && response_code < 400) || redirect_count > 0) ) {
330
352
  rbce->callback_active = 1;
331
353
  callargs = rb_ary_new3(3, rb_easy_get("redirect_proc"), easy, rb_curl_easy_error(result));
332
354
  rbce->callback_active = 0;
333
- val = rb_rescue(call_status_handler2, callargs, callback_exception, Qnil);
355
+ rb_rescue(call_status_handler2, callargs, callback_exception, did_raise);
356
+ CURB_CHECK_RB_CALLBACK_RAISE(did_raise);
334
357
  } else if (!rb_easy_nil("missing_proc") &&
335
358
  (response_code >= 400 && response_code < 500)) {
336
359
  rbce->callback_active = 1;
337
360
  callargs = rb_ary_new3(3, rb_easy_get("missing_proc"), easy, rb_curl_easy_error(result));
338
361
  rbce->callback_active = 0;
339
- val = rb_rescue(call_status_handler2, callargs, callback_exception, Qnil);
362
+ rb_rescue(call_status_handler2, callargs, callback_exception, did_raise);
363
+ CURB_CHECK_RB_CALLBACK_RAISE(did_raise);
340
364
  } else if (!rb_easy_nil("failure_proc") &&
341
365
  (response_code >= 500 && response_code <= 999)) {
342
366
  callargs = rb_ary_new3(3, rb_easy_get("failure_proc"), easy, rb_curl_easy_error(result));
343
367
  rbce->callback_active = 1;
344
- val = rb_rescue(call_status_handler2, callargs, callback_exception, Qnil);
368
+ rb_rescue(call_status_handler2, callargs, callback_exception, did_raise);
345
369
  rbce->callback_active = 0;
346
- //rb_funcall( rb_easy_get("failure_proc"), idCall, 2, easy, rb_curl_easy_error(result) );
370
+ CURB_CHECK_RB_CALLBACK_RAISE(did_raise);
347
371
  }
348
372
 
349
373
  }
@@ -627,6 +651,8 @@ void init_curb_multi() {
627
651
  idCall = rb_intern("call");
628
652
  cCurlMulti = rb_define_class_under(mCurl, "Multi", rb_cObject);
629
653
 
654
+ rb_undef_alloc_func(cCurlMulti);
655
+
630
656
  /* Class methods */
631
657
  rb_define_singleton_method(cCurlMulti, "new", ruby_curl_multi_new, 0);
632
658
  rb_define_singleton_method(cCurlMulti, "default_timeout=", ruby_curl_multi_set_default_timeout, 1);
data/ext/curb_postfield.c CHANGED
@@ -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/multi.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
  module Curl
3
3
  class Multi
4
+ class DownloadError < RuntimeError
5
+ attr_accessor :errors
6
+ end
4
7
  class << self
5
8
  # call-seq:
6
9
  # Curl::Multi.get(['url1','url2','url3','url4','url5'], :follow_location => true) do|easy|
@@ -241,7 +244,11 @@ module Curl
241
244
  errors << e
242
245
  end
243
246
  }
244
- raise errors unless errors.empty?
247
+ if errors.any?
248
+ de = Curl::Multi::DownloadError.new
249
+ de.errors = errors
250
+ raise de
251
+ end
245
252
  end
246
253
  end
247
254
 
@@ -1,37 +1,23 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
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
3
  class BugCrashOnDebug < Test::Unit::TestCase
4
+ include BugTestServerSetupTeardown
10
5
 
11
6
  def test_on_debug
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
- puts 'a'
18
- thread = Thread.new(server) do|srv|
19
- srv.start
20
- end
21
- puts 'b'
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
7
+ c = Curl::Easy.new("http://127.0.0.1:#{@port}/test")
8
+ did_raise = false
9
+ did_call = false
10
+ begin
11
+ c.on_success do|x|
12
+ did_call = true
13
+ raise "error" # this will get swallowed
14
+ end
15
+ c.perform
16
+ rescue => e
17
+ did_raise = true
26
18
  end
27
- c.perform
28
- puts 'c'
29
- ensure
30
- puts 'd'
31
- server.shutdown
32
- puts 'e'
33
- puts thread.exit
34
- puts 'f'
19
+ assert did_raise
20
+ assert did_call
35
21
  end
36
22
 
37
23
  end
@@ -1,22 +1,10 @@
1
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
2
 
6
3
  class BugCrashOnDebug < Test::Unit::TestCase
7
-
8
- def test_on_progress_raise
9
- server = WEBrick::HTTPServer.new( :Port => 9999 )
10
- server.mount_proc("/test") do|req,res|
11
- res.body = "hi"
12
- res['Content-Type'] = "text/html"
13
- end
4
+ include BugTestServerSetupTeardown
14
5
 
15
- thread = Thread.new(server) do|srv|
16
- srv.start
17
- end
18
-
19
- c = Curl::Easy.new('http://127.0.0.1:9999/test')
6
+ def test_on_progress_raise
7
+ c = Curl::Easy.new("http://127.0.0.1:#{@port}/test")
20
8
  c.on_progress do|x|
21
9
  raise "error"
22
10
  end
@@ -27,21 +15,9 @@ class BugCrashOnDebug < Test::Unit::TestCase
27
15
  rescue => e
28
16
  assert_equal 'Curl::Err::AbortedByCallbackError', e.class.to_s
29
17
  c.close
30
- ensure
31
- server.shutdown
32
18
  end
33
19
 
34
20
  def test_on_progress_abort
35
- server = WEBrick::HTTPServer.new( :Port => 9999 )
36
- server.mount_proc("/test") do|req,res|
37
- res.body = "hi"
38
- res['Content-Type'] = "text/html"
39
- end
40
-
41
- thread = Thread.new(server) do|srv|
42
- srv.start
43
- end
44
-
45
21
  # see: https://github.com/taf2/curb/issues/192,
46
22
  # to pass:
47
23
  #
@@ -54,20 +30,20 @@ class BugCrashOnDebug < Test::Unit::TestCase
54
30
  #
55
31
  # notice no return keyword
56
32
  #
57
- c = Curl::Easy.new('http://127.0.0.1:9999/test')
33
+ c = Curl::Easy.new("http://127.0.0.1:#{@port}/test")
34
+ did_progress = false
58
35
  c.on_progress do|x|
59
- puts "we're in the progress callback"
36
+ did_progress = true
60
37
  return false
61
38
  end
62
39
  c.perform
40
+ assert did_progress
63
41
 
64
42
  assert false, "should not reach this point"
65
43
 
66
44
  rescue => e
67
45
  assert_equal 'Curl::Err::AbortedByCallbackError', e.class.to_s
68
46
  c.close
69
- ensure
70
- server.shutdown
71
47
  end
72
48
 
73
49
  end
@@ -1,21 +1,19 @@
1
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
2
 
6
3
  class BugTestInstancePostDiffersFromClassPost < Test::Unit::TestCase
7
- def test_bug
8
- server = WEBrick::HTTPServer.new( :Port => 9999 )
9
- server.mount_proc("/test") do|req,res|
4
+ include BugTestServerSetupTeardown
5
+
6
+ def setup
7
+ @port = 9999
8
+ @response_proc = lambda do|res|
10
9
  sleep 0.5
11
10
  res.body = "hi"
12
11
  res['Content-Type'] = "text/html"
13
12
  end
13
+ super
14
+ end
14
15
 
15
- thread = Thread.new(server) do|srv|
16
- srv.start
17
- end
18
-
16
+ def test_bug
19
17
  threads = []
20
18
  timer = Time.now
21
19
 
@@ -45,8 +43,5 @@ class BugTestInstancePostDiffersFromClassPost < Test::Unit::TestCase
45
43
  puts "requested in #{single_time}"
46
44
 
47
45
  assert single_time > multi_time
48
-
49
- server.shutdown
50
- thread.join
51
46
  end
52
47
  end
@@ -22,26 +22,15 @@ end
22
22
  Any insight you care to share would be helpful. Thanks.
23
23
  =end
24
24
  require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
25
- require 'webrick'
26
- class ::WEBrick::HTTPServer ; def access_log(config, req, res) ; end ; end
27
- class ::WEBrick::BasicLog ; def log(level, data) ; end ; end
28
25
 
29
26
  class BugCurbEasyPostWithStringNoContentLengthHeader < Test::Unit::TestCase
30
- def test_bug_workaround
31
- server = WEBrick::HTTPServer.new( :Port => 9999 )
32
- server.mount_proc("/test") do|req,res|
33
- assert_equal '15', req['Content-Length']
34
- res.body = "hi"
35
- res['Content-Type'] = "text/html"
36
- end
27
+ include BugTestServerSetupTeardown
37
28
 
38
- thread = Thread.new(server) do|srv|
39
- srv.start
40
- end
29
+ def test_bug_workaround
41
30
  params = {:cat => "hat", :foo => "bar"}
42
31
 
43
32
  post_body = params.map{|f,k| "#{Curl::Easy.new.escape(f)}=#{Curl::Easy.new.escape(k)}"}.join('&')
44
- c = Curl::Easy.http_post("http://127.0.0.1:9999/test",post_body) do |curl|
33
+ c = Curl::Easy.http_post("http://127.0.0.1:#{@port}/test",post_body) do |curl|
45
34
  curl.headers["User-Agent"] = "Curl/Ruby"
46
35
  curl.headers["X-Tender-Auth"] = "A Token"
47
36
  curl.headers["Accept"] = "application/vnd.tender-v1+json"
@@ -50,23 +39,12 @@ class BugCurbEasyPostWithStringNoContentLengthHeader < Test::Unit::TestCase
50
39
  curl.enable_cookies = true
51
40
  end
52
41
 
53
- server.shutdown
54
- thread.join
55
42
  end
56
- def test_bug
57
- server = WEBrick::HTTPServer.new( :Port => 9999 )
58
- server.mount_proc("/test") do|req,res|
59
- assert_equal '15', req['Content-Length']
60
- res.body = "hi"
61
- res['Content-Type'] = "text/html"
62
- end
63
43
 
64
- thread = Thread.new(server) do|srv|
65
- srv.start
66
- end
44
+ def test_bug
67
45
  params = {:cat => "hat", :foo => "bar"}
68
46
 
69
- c = Curl::Easy.http_post("http://127.0.0.1:9999/test") do |curl|
47
+ c = Curl::Easy.http_post("http://127.0.0.1:#{@port}/test") do |curl|
70
48
  curl.headers["User-Agent"] = "Curl/Ruby"
71
49
  curl.headers["X-Tender-Auth"] = "A Token"
72
50
  curl.headers["Accept"] = "application/vnd.tender-v1+json"
@@ -76,8 +54,6 @@ class BugCurbEasyPostWithStringNoContentLengthHeader < Test::Unit::TestCase
76
54
  curl.follow_location = true
77
55
  curl.enable_cookies = true
78
56
  end
79
-
80
- server.shutdown
81
- thread.join
82
57
  end
58
+
83
59
  end
@@ -0,0 +1,83 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
+
3
+ class BugFollowRedirect288 < Test::Unit::TestCase
4
+ include BugTestServerSetupTeardown
5
+
6
+ def setup
7
+ @port = 9999
8
+ super
9
+ @server.mount_proc("/redirect_to_test") do|req,res|
10
+ res.set_redirect(WEBrick::HTTPStatus::TemporaryRedirect, "/test")
11
+ end
12
+ end
13
+
14
+ def test_follow_redirect_with_no_redirect
15
+
16
+ c = Curl::Easy.new('http://127.0.0.1:9999/test')
17
+ did_call_redirect = false
18
+ c.on_redirect do|x|
19
+ did_call_redirect = true
20
+ end
21
+ c.perform
22
+
23
+ assert !did_call_redirect, "should reach this point redirect should not have been called"
24
+
25
+ c = Curl::Easy.new('http://127.0.0.1:9999/test')
26
+ did_call_redirect = false
27
+ c.on_redirect do|x|
28
+ did_call_redirect = true
29
+ end
30
+ c.follow_location = true
31
+ c.perform
32
+
33
+ assert_equal 0, c.redirect_count
34
+ assert !did_call_redirect, "should reach this point redirect should not have been called"
35
+
36
+ c = Curl::Easy.new('http://127.0.0.1:9999/redirect_to_test')
37
+ did_call_redirect = false
38
+ c.on_redirect do|x|
39
+ did_call_redirect = true
40
+ end
41
+ c.perform
42
+ assert_equal 307, c.response_code
43
+
44
+ assert did_call_redirect, "we should have called on_redirect"
45
+
46
+ c = Curl::Easy.new('http://127.0.0.1:9999/redirect_to_test')
47
+ did_call_redirect = false
48
+ c.follow_location = true
49
+ # NOTE: while this API is not supported by libcurl e.g. there is no redirect function callback in libcurl we could
50
+ # 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
51
+ c.on_redirect do|x|
52
+ did_call_redirect = true
53
+ end
54
+ c.perform
55
+ assert_equal 1, c.redirect_count
56
+ assert_equal 200, c.response_code
57
+
58
+ assert did_call_redirect, "we should have called on_redirect"
59
+
60
+ c.url = 'http://127.0.0.1:9999/test'
61
+ c.perform
62
+ assert_equal 0, c.redirect_count
63
+ assert_equal 200, c.response_code
64
+
65
+ puts "checking for raise support"
66
+ did_raise = false
67
+ begin
68
+ c = Curl::Easy.new('http://127.0.0.1:9999/redirect_to_test')
69
+ did_call_redirect = false
70
+ c.on_redirect do|x|
71
+ raise "raise"
72
+ did_call_redirect = true
73
+ end
74
+ c.perform
75
+ rescue => e
76
+ did_raise = true
77
+ end
78
+ assert_equal 307, c.response_code
79
+ assert did_raise
80
+
81
+ end
82
+
83
+ end
@@ -35,15 +35,13 @@ class BugTestInstancePostDiffersFromClassPost < Test::Unit::TestCase
35
35
  end
36
36
 
37
37
  def do_test
38
- c = Curl::Easy.http_post('https://www.google.com/accounts/ServiceLoginAuth',
39
- Curl::PostField.content('ltmpl','m_blanco'))
38
+ c = Curl::Easy.http_post('https://www.google.com/accounts/ServiceLoginAuth', Curl::PostField.content('ltmpl','m_blanco'))
40
39
  body_c, header_c = c.body_str, c.header_str
41
40
 
42
41
  sleep 2
43
42
 
44
- c.http_post('https://www.google.com/accounts/ServiceLoginAuth',
45
- Curl::PostField.content('ltmpl','m_blanco'))
46
- body_i, header_i = c.body_str, c.header_str
43
+ c.http_post('https://www.google.com/accounts/ServiceLoginAuth', Curl::PostField.content('ltmpl','m_blanco'))
44
+ body_i, header_i = c.body, c.head
47
45
 
48
46
  # timestamps will differ, just check first bit. We wont get here if
49
47
  # the bug bites anyway...
@@ -3,6 +3,7 @@
3
3
  # irb: multi = Curl::Multi.new
4
4
  # irb: exit
5
5
  # <main>:47140: [BUG] Bus Error
6
+ require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
6
7
  $:.unshift File.expand_path(File.join(File.dirname(__FILE__),'..','ext'))
7
8
  $:.unshift File.expand_path(File.join(File.dirname(__FILE__),'..','lib'))
8
9
  require 'curb'
@@ -0,0 +1,29 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
+
3
+ class BugRaiseOnCallback < Test::Unit::TestCase
4
+ include BugTestServerSetupTeardown
5
+
6
+ def setup
7
+ @port = 9999
8
+ super
9
+ end
10
+
11
+ def test_on_complte
12
+ c = Curl::Easy.new('http://127.0.0.1:9999/test')
13
+ did_raise = false
14
+ begin
15
+ c.on_complete do|x|
16
+ assert_equal 'http://127.0.0.1:9999/test', x.url
17
+ raise "error complete" # this will get swallowed
18
+ end
19
+ c.perform
20
+ rescue => e
21
+ did_raise = true
22
+ end
23
+ assert did_raise, "we want to raise an exception if the ruby callbacks raise"
24
+
25
+ end
26
+
27
+ end
28
+
29
+ #test_on_debug
data/tests/helper.rb CHANGED
@@ -135,6 +135,32 @@ class TestServlet < WEBrick::HTTPServlet::AbstractServlet
135
135
 
136
136
  end
137
137
 
138
+ module BugTestServerSetupTeardown
139
+ def setup
140
+ @port ||= 9992
141
+ @server = WEBrick::HTTPServer.new( :Port => @port )
142
+ @server.mount_proc("/test") do|req,res|
143
+ if @response_proc
144
+ @response_proc.call(res)
145
+ else
146
+ res.body = "hi"
147
+ res['Content-Type'] = "text/html"
148
+ end
149
+ end
150
+
151
+ @thread = Thread.new(@server) do|srv|
152
+ srv.start
153
+ end
154
+ end
155
+
156
+ def teardown
157
+ while @server.status != :Shutdown
158
+ @server.shutdown
159
+ end
160
+ @thread.join
161
+ end
162
+ end
163
+
138
164
  module TestServerMethods
139
165
  def locked_file
140
166
  File.join(File.dirname(__FILE__),"server_lock-#{@__port}")
@@ -13,9 +13,9 @@ class TestCurbCurlEasy < Test::Unit::TestCase
13
13
  def test_nested_easy_methods
14
14
  easy = Curl.get(TestServlet.url) {|http|
15
15
  res = Curl.get(TestServlet.url + '/not_here')
16
- assert_equal 404, res.response_code
16
+ assert_equal 404, res.code
17
17
  }
18
- assert_equal 200, easy.response_code
18
+ assert_equal 200, easy.code
19
19
  end
20
20
 
21
21
  def test_curlopt_stderr_with_file
@@ -721,9 +721,9 @@ class TestCurbCurlEasy < Test::Unit::TestCase
721
721
  on_success_called = false
722
722
  curl.on_success {|c|
723
723
  on_success_called = true
724
- assert_not_nil c.body_str
725
- assert_equal "", c.header_str
726
- assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body_str)
724
+ assert_not_nil c.body
725
+ assert_match(/Content-Length: /, c.head)
726
+ assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body)
727
727
  }
728
728
  curl.perform
729
729
  assert on_success_called, "Success handler not called"
@@ -1147,7 +1147,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
1147
1147
  c = Curl::Easy.new($TEST_URL)
1148
1148
  c.on_success {|x| raise "error" }
1149
1149
  c.perform
1150
- rescue => e
1150
+ rescue Curl::Err::AbortedByCallbackError => e
1151
1151
  assert_equal 'Curl::Err::AbortedByCallbackError', e.class.to_s
1152
1152
  c.close
1153
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
@@ -159,6 +161,44 @@ class TestCurbCurlMulti < Test::Unit::TestCase
159
161
 
160
162
  end
161
163
 
164
+ def test_multi_easy_get
165
+ n = 1
166
+ urls = []
167
+ n.times { urls << $TEST_URL }
168
+ Curl::Multi.get(urls, {timeout: 5}) {|easy|
169
+ assert_match(/file:/, easy.last_effective_url)
170
+ }
171
+ end
172
+
173
+ def test_multi_easy_get_with_error
174
+ begin
175
+ did_raise = false
176
+ n = 3
177
+ urls = []
178
+ n.times { urls << $TEST_URL }
179
+ error_line_number_should_be = nil
180
+ Curl::Multi.get(urls, {timeout: 5}) {|easy|
181
+ # if we got this right the error will be reported to be on the line below our error_line_number_should_be
182
+ error_line_number_should_be = __LINE__
183
+ raise
184
+ }
185
+
186
+ rescue Curl::Err::AbortedByCallbackError => e
187
+ did_raise = true
188
+ in_file = e.backtrace.detect {|err| err.match?(File.basename(__FILE__)) }
189
+ in_file_stack = e.backtrace.select {|err| err.match?(File.basename(__FILE__)) }
190
+ assert_match(__FILE__, in_file)
191
+ in_file.gsub!(__FILE__)
192
+ parts = in_file.split(':')
193
+ parts.shift
194
+ line_no = parts.shift.to_i
195
+ assert_equal error_line_number_should_be+1, line_no.to_i
196
+ end
197
+
198
+ assert did_raise, "we should have raised an exception"
199
+
200
+ end
201
+
162
202
  # NOTE: if this test runs slowly on Mac OSX, it is probably due to the use of a port install curl+ssl+ares install
163
203
  # on my MacBook, this causes curl_easy_init to take nearly 0.01 seconds / * 100 below is 1 second too many!
164
204
  def test_n_requests
@@ -480,7 +520,7 @@ class TestCurbCurlMulti < Test::Unit::TestCase
480
520
  { :url => TestServlet.url, :method => :get }
481
521
  ]
482
522
  Curl::Multi.http(urls, {:pipeline => true}) do|easy, code, method|
483
- assert_equal nil, code
523
+ assert_equal 200, code
484
524
  case method
485
525
  when :post
486
526
  assert_match(/POST/, easy.body_str)
@@ -494,20 +534,20 @@ class TestCurbCurlMulti < Test::Unit::TestCase
494
534
  end
495
535
 
496
536
  def test_multi_easy_http_with_max_connects
497
- urls = [
537
+ urls = [
498
538
  { :url => TestServlet.url + '?q=1', :method => :get },
499
539
  { :url => TestServlet.url + '?q=2', :method => :get },
500
540
  { :url => TestServlet.url + '?q=3', :method => :get }
501
541
  ]
502
542
  Curl::Multi.http(urls, {:pipeline => true, :max_connects => 1}) do|easy, code, method|
503
- assert_equal nil, code
543
+ assert_equal 200, code
504
544
  case method
505
545
  when :post
506
- assert_match(/POST/, easy.body_str)
546
+ assert_match(/POST/, easy.body)
507
547
  when :get
508
- assert_match(/GET/, easy.body_str)
548
+ assert_match(/GET/, easy.body)
509
549
  when :put
510
- assert_match(/PUT/, easy.body_str)
550
+ assert_match(/PUT/, easy.body)
511
551
  end
512
552
  end
513
553
  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: 1.0.1
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ross Bamford
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-04-29 00:00:00.000000000 Z
12
+ date: 2023-01-04 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,12 +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
55
56
  - tests/bug_issue277.rb
56
57
  - tests/bug_multi_segfault.rb
57
58
  - tests/bug_postfields_crash.rb
58
59
  - tests/bug_postfields_crash2.rb
60
+ - tests/bug_raise_on_callback.rb
59
61
  - tests/bug_require_last_or_segfault.rb
60
62
  - tests/bugtests.rb
61
63
  - tests/helper.rb
@@ -96,37 +98,39 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
98
  - !ruby/object:Gem::Version
97
99
  version: '0'
98
100
  requirements: []
99
- rubygems_version: 3.1.4
101
+ rubygems_version: 3.2.33
100
102
  signing_key:
101
103
  specification_version: 4
102
104
  summary: Ruby libcurl bindings
103
105
  test_files:
104
- - tests/tc_curl_multi.rb
105
106
  - tests/alltests.rb
106
- - tests/tc_curl_easy_setopt.rb
107
- - tests/tc_curl.rb
108
- - tests/bug_postfields_crash.rb
107
+ - tests/bug_crash_on_debug.rb
109
108
  - tests/bug_crash_on_progress.rb
110
- - tests/helper.rb
109
+ - tests/bug_curb_easy_blocks_ruby_threads.rb
110
+ - tests/bug_curb_easy_post_with_string_no_content_length_header.rb
111
+ - tests/bug_follow_redirect_288.rb
112
+ - tests/bug_instance_post_differs_from_class_post.rb
113
+ - tests/bug_issue102.rb
111
114
  - tests/bug_issue277.rb
115
+ - tests/bug_multi_segfault.rb
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
- - 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
120
+ - tests/bugtests.rb
121
+ - tests/helper.rb
122
+ - tests/mem_check.rb
122
123
  - tests/require_last_or_segfault_script.rb
123
- - tests/timeout_server.rb
124
+ - tests/signals.rb
125
+ - tests/tc_curl.rb
124
126
  - tests/tc_curl_download.rb
125
127
  - tests/tc_curl_easy.rb
126
- - tests/mem_check.rb
127
- - tests/tc_curl_postfield.rb
128
- - tests/tc_curl_maxfilesize.rb
129
- - tests/bugtests.rb
130
128
  - tests/tc_curl_easy_resolve.rb
131
- - tests/signals.rb
132
- - tests/bug_curb_easy_post_with_string_no_content_length_header.rb
129
+ - tests/tc_curl_easy_setopt.rb
130
+ - tests/tc_curl_maxfilesize.rb
131
+ - tests/tc_curl_multi.rb
132
+ - tests/tc_curl_postfield.rb
133
+ - tests/tc_curl_protocols.rb
134
+ - tests/timeout.rb
135
+ - tests/timeout_server.rb
136
+ - tests/unittests.rb