curb 1.0.3 → 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.markdown +20 -8
- data/Rakefile +9 -0
- data/ext/curb.h +3 -3
- data/ext/curb_easy.c +20 -19
- data/ext/curb_macros.h +11 -5
- data/ext/curb_multi.c +23 -19
- data/tests/bug_crash_on_debug.rb +2 -26
- data/tests/bug_crash_on_progress.rb +7 -33
- data/tests/bug_curb_easy_blocks_ruby_threads.rb +8 -13
- data/tests/bug_curb_easy_post_with_string_no_content_length_header.rb +6 -30
- data/tests/bug_follow_redirect_288.rb +10 -18
- data/tests/bug_instance_post_differs_from_class_post.rb +3 -5
- data/tests/bug_multi_segfault.rb +1 -0
- data/tests/bug_raise_on_callback.rb +6 -17
- data/tests/helper.rb +26 -0
- data/tests/tc_curl_easy.rb +3 -3
- data/tests/tc_curl_multi.rb +30 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e28b1d05b46460867acfadc87bbe422d58d8f2cdb93397fa6ded906b01cd7dab
|
4
|
+
data.tar.gz: 33e7037c1c2b23a793ec96c73bc80c008939c880702f884d2b258d4afd18c368
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6eb448726a4fdce1e0832e36a45b2c8e0a078fbc2c04b3fe34f87fc38397f5c4ecc4fe621aed5637750c5c7a7a9d05b30c03f9f7db153c23d3694eb6adb464e8
|
7
|
+
data.tar.gz: 624e3f39af79eff874784a662776debc2b405378c6cdc963a50dee525d36aa225cc5f40558f9b35b396c222416006f66c29fc6193e651b5aa84093fdd52cb2ba
|
data/README.markdown
CHANGED
@@ -12,26 +12,38 @@ Curb is a work-in-progress, and currently only supports libcurl's `easy` and `mu
|
|
12
12
|
|
13
13
|
## License
|
14
14
|
|
15
|
-
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
|
16
16
|
Ruby license. See the LICENSE file for the gory details.
|
17
17
|
|
18
18
|
## Easy mode
|
19
19
|
|
20
|
-
|
20
|
+
GET request
|
21
21
|
```
|
22
|
-
res = Curl.get("https://www.google.com/")
|
23
|
-
|
24
|
-
|
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
|
25
27
|
puts res.body
|
26
28
|
```
|
27
29
|
|
28
|
-
|
30
|
+
POST request
|
29
31
|
```
|
30
32
|
res = Curl.post("https://your-server.com/endpoint", {post: "this"}.to_json) {|http|
|
31
33
|
http.headers["Content-Type"] = "application/json"
|
32
34
|
}
|
33
|
-
puts res.
|
34
|
-
puts res.
|
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
|
35
47
|
puts res.body
|
36
48
|
```
|
37
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']}"
|
@@ -90,6 +91,14 @@ else
|
|
90
91
|
task :alltests => [:unittests, :bugtests]
|
91
92
|
end
|
92
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
|
+
|
93
102
|
Rake::TestTask.new(:unittests) do |t|
|
94
103
|
t.test_files = FileList['tests/tc_*.rb']
|
95
104
|
t.verbose = false
|
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.
|
32
|
-
#define CURB_VER_NUM
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
}
|
@@ -3921,6 +3921,7 @@ void init_curb_easy() {
|
|
3921
3921
|
|
3922
3922
|
rb_define_method(cCurlEasy, "last_effective_url", ruby_curl_easy_last_effective_url_get, 0);
|
3923
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);
|
3924
3925
|
#if defined(HAVE_CURLINFO_PRIMARY_IP)
|
3925
3926
|
rb_define_method(cCurlEasy, "primary_ip", ruby_curl_easy_primary_ip_get, 0);
|
3926
3927
|
#endif
|
data/ext/curb_macros.h
CHANGED
@@ -156,10 +156,16 @@
|
|
156
156
|
#define CURB_DEFINE(name) \
|
157
157
|
rb_define_const(mCurl, #name, LONG2NUM(name))
|
158
158
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
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
|
+
}
|
164
170
|
|
165
171
|
#endif
|
data/ext/curb_multi.c
CHANGED
@@ -44,6 +44,22 @@ 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
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
|
+
*/
|
47
63
|
rb_hash_aset(did_raise, rb_easy_hkey("error"), exception);
|
48
64
|
return exception;
|
49
65
|
}
|
@@ -296,7 +312,6 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
|
|
296
312
|
raise_curl_easy_error_exception(ecode);
|
297
313
|
}
|
298
314
|
|
299
|
-
int status;
|
300
315
|
VALUE did_raise = rb_hash_new();
|
301
316
|
|
302
317
|
if (!rb_easy_nil("complete_proc")) {
|
@@ -304,9 +319,7 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
|
|
304
319
|
rbce->callback_active = 1;
|
305
320
|
rb_rescue(call_status_handler1, callargs, callback_exception, did_raise);
|
306
321
|
rbce->callback_active = 0;
|
307
|
-
|
308
|
-
CURB_RB_CALLBACK_RAISE("complete")
|
309
|
-
}
|
322
|
+
CURB_CHECK_RB_CALLBACK_RAISE(did_raise);
|
310
323
|
}
|
311
324
|
|
312
325
|
#ifdef HAVE_CURLINFO_RESPONSE_CODE
|
@@ -324,9 +337,7 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
|
|
324
337
|
rbce->callback_active = 1;
|
325
338
|
rb_rescue(call_status_handler2, callargs, callback_exception, did_raise);
|
326
339
|
rbce->callback_active = 0;
|
327
|
-
|
328
|
-
CURB_RB_CALLBACK_RAISE("failure")
|
329
|
-
}
|
340
|
+
CURB_CHECK_RB_CALLBACK_RAISE(did_raise);
|
330
341
|
}
|
331
342
|
} else if (!rb_easy_nil("success_proc") &&
|
332
343
|
((response_code >= 200 && response_code < 300) || response_code == 0)) {
|
@@ -335,35 +346,28 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
|
|
335
346
|
rbce->callback_active = 1;
|
336
347
|
rb_rescue(call_status_handler1, callargs, callback_exception, did_raise);
|
337
348
|
rbce->callback_active = 0;
|
338
|
-
|
339
|
-
|
340
|
-
}
|
349
|
+
CURB_CHECK_RB_CALLBACK_RAISE(did_raise);
|
350
|
+
|
341
351
|
} else if (!rb_easy_nil("redirect_proc") && ((response_code >= 300 && response_code < 400) || redirect_count > 0) ) {
|
342
352
|
rbce->callback_active = 1;
|
343
353
|
callargs = rb_ary_new3(3, rb_easy_get("redirect_proc"), easy, rb_curl_easy_error(result));
|
344
354
|
rbce->callback_active = 0;
|
345
355
|
rb_rescue(call_status_handler2, callargs, callback_exception, did_raise);
|
346
|
-
|
347
|
-
CURB_RB_CALLBACK_RAISE("redirect")
|
348
|
-
}
|
356
|
+
CURB_CHECK_RB_CALLBACK_RAISE(did_raise);
|
349
357
|
} else if (!rb_easy_nil("missing_proc") &&
|
350
358
|
(response_code >= 400 && response_code < 500)) {
|
351
359
|
rbce->callback_active = 1;
|
352
360
|
callargs = rb_ary_new3(3, rb_easy_get("missing_proc"), easy, rb_curl_easy_error(result));
|
353
361
|
rbce->callback_active = 0;
|
354
362
|
rb_rescue(call_status_handler2, callargs, callback_exception, did_raise);
|
355
|
-
|
356
|
-
CURB_RB_CALLBACK_RAISE("missing")
|
357
|
-
}
|
363
|
+
CURB_CHECK_RB_CALLBACK_RAISE(did_raise);
|
358
364
|
} else if (!rb_easy_nil("failure_proc") &&
|
359
365
|
(response_code >= 500 && response_code <= 999)) {
|
360
366
|
callargs = rb_ary_new3(3, rb_easy_get("failure_proc"), easy, rb_curl_easy_error(result));
|
361
367
|
rbce->callback_active = 1;
|
362
368
|
rb_rescue(call_status_handler2, callargs, callback_exception, did_raise);
|
363
369
|
rbce->callback_active = 0;
|
364
|
-
|
365
|
-
CURB_RB_CALLBACK_RAISE("failure")
|
366
|
-
}
|
370
|
+
CURB_CHECK_RB_CALLBACK_RAISE(did_raise);
|
367
371
|
}
|
368
372
|
|
369
373
|
}
|
data/tests/bug_crash_on_debug.rb
CHANGED
@@ -1,30 +1,14 @@
|
|
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
|
-
|
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')
|
7
|
+
c = Curl::Easy.new("http://127.0.0.1:#{@port}/test")
|
23
8
|
did_raise = false
|
24
9
|
did_call = false
|
25
10
|
begin
|
26
11
|
c.on_success do|x|
|
27
|
-
puts x.inspect
|
28
12
|
did_call = true
|
29
13
|
raise "error" # this will get swallowed
|
30
14
|
end
|
@@ -32,16 +16,8 @@ class BugCrashOnDebug < Test::Unit::TestCase
|
|
32
16
|
rescue => e
|
33
17
|
did_raise = true
|
34
18
|
end
|
35
|
-
puts c.response_code
|
36
19
|
assert did_raise
|
37
20
|
assert did_call
|
38
|
-
puts 'c'
|
39
|
-
ensure
|
40
|
-
puts 'd'
|
41
|
-
server.shutdown
|
42
|
-
puts 'e'
|
43
|
-
puts thread.exit
|
44
|
-
puts 'f'
|
45
21
|
end
|
46
22
|
|
47
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
|
-
|
16
|
-
|
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,22 +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
|
-
thread&.exit
|
33
18
|
end
|
34
19
|
|
35
20
|
def test_on_progress_abort
|
36
|
-
server = WEBrick::HTTPServer.new( :Port => 9999 )
|
37
|
-
server.mount_proc("/test") do|req,res|
|
38
|
-
res.body = "hi"
|
39
|
-
res['Content-Type'] = "text/html"
|
40
|
-
end
|
41
|
-
|
42
|
-
thread = Thread.new(server) do|srv|
|
43
|
-
srv.start
|
44
|
-
end
|
45
|
-
|
46
21
|
# see: https://github.com/taf2/curb/issues/192,
|
47
22
|
# to pass:
|
48
23
|
#
|
@@ -55,21 +30,20 @@ class BugCrashOnDebug < Test::Unit::TestCase
|
|
55
30
|
#
|
56
31
|
# notice no return keyword
|
57
32
|
#
|
58
|
-
c = Curl::Easy.new(
|
33
|
+
c = Curl::Easy.new("http://127.0.0.1:#{@port}/test")
|
34
|
+
did_progress = false
|
59
35
|
c.on_progress do|x|
|
60
|
-
|
36
|
+
did_progress = true
|
61
37
|
return false
|
62
38
|
end
|
63
39
|
c.perform
|
40
|
+
assert did_progress
|
64
41
|
|
65
42
|
assert false, "should not reach this point"
|
66
43
|
|
67
44
|
rescue => e
|
68
45
|
assert_equal 'Curl::Err::AbortedByCallbackError', e.class.to_s
|
69
46
|
c.close
|
70
|
-
ensure
|
71
|
-
server&.shutdown
|
72
|
-
thread&.exit
|
73
47
|
end
|
74
48
|
|
75
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
|
-
|
8
|
-
|
9
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
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
|
@@ -1,22 +1,17 @@
|
|
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 BugFollowRedirect288 < Test::Unit::TestCase
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
server.mount_proc("/redirect_to_test") do|req,res|
|
4
|
+
include BugTestServerSetupTeardown
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@port = 9999
|
8
|
+
super
|
9
|
+
@server.mount_proc("/redirect_to_test") do|req,res|
|
14
10
|
res.set_redirect(WEBrick::HTTPStatus::TemporaryRedirect, "/test")
|
15
11
|
end
|
12
|
+
end
|
16
13
|
|
17
|
-
|
18
|
-
srv.start
|
19
|
-
end
|
14
|
+
def test_follow_redirect_with_no_redirect
|
20
15
|
|
21
16
|
c = Curl::Easy.new('http://127.0.0.1:9999/test')
|
22
17
|
did_call_redirect = false
|
@@ -67,6 +62,7 @@ class BugFollowRedirect288 < Test::Unit::TestCase
|
|
67
62
|
assert_equal 0, c.redirect_count
|
68
63
|
assert_equal 200, c.response_code
|
69
64
|
|
65
|
+
puts "checking for raise support"
|
70
66
|
did_raise = false
|
71
67
|
begin
|
72
68
|
c = Curl::Easy.new('http://127.0.0.1:9999/redirect_to_test')
|
@@ -79,12 +75,8 @@ class BugFollowRedirect288 < Test::Unit::TestCase
|
|
79
75
|
rescue => e
|
80
76
|
did_raise = true
|
81
77
|
end
|
82
|
-
assert did_raise
|
83
78
|
assert_equal 307, c.response_code
|
84
|
-
|
85
|
-
ensure
|
86
|
-
server.stop
|
87
|
-
thread.join
|
79
|
+
assert did_raise
|
88
80
|
|
89
81
|
end
|
90
82
|
|
@@ -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
|
-
|
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...
|
data/tests/bug_multi_segfault.rb
CHANGED
@@ -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'
|
@@ -1,22 +1,14 @@
|
|
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 BugRaiseOnCallback < Test::Unit::TestCase
|
4
|
+
include BugTestServerSetupTeardown
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@port = 9999
|
8
|
+
super
|
9
|
+
end
|
10
10
|
|
11
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
12
|
c = Curl::Easy.new('http://127.0.0.1:9999/test')
|
21
13
|
did_raise = false
|
22
14
|
begin
|
@@ -30,9 +22,6 @@ class BugRaiseOnCallback < Test::Unit::TestCase
|
|
30
22
|
end
|
31
23
|
assert did_raise, "we want to raise an exception if the ruby callbacks raise"
|
32
24
|
|
33
|
-
ensure
|
34
|
-
server.shutdown
|
35
|
-
thread.exit
|
36
25
|
end
|
37
26
|
|
38
27
|
end
|
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}")
|
data/tests/tc_curl_easy.rb
CHANGED
@@ -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.
|
16
|
+
assert_equal 404, res.code
|
17
17
|
}
|
18
|
-
assert_equal 200, easy.
|
18
|
+
assert_equal 200, easy.code
|
19
19
|
end
|
20
20
|
|
21
21
|
def test_curlopt_stderr_with_file
|
@@ -722,7 +722,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
722
722
|
curl.on_success {|c|
|
723
723
|
on_success_called = true
|
724
724
|
assert_not_nil c.body
|
725
|
-
assert_match
|
725
|
+
assert_match(/Content-Length: /, c.head)
|
726
726
|
assert_match(/^# DO NOT REMOVE THIS COMMENT/, c.body)
|
727
727
|
}
|
728
728
|
curl.perform
|
data/tests/tc_curl_multi.rb
CHANGED
@@ -166,10 +166,39 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
166
166
|
urls = []
|
167
167
|
n.times { urls << $TEST_URL }
|
168
168
|
Curl::Multi.get(urls, {timeout: 5}) {|easy|
|
169
|
-
|
169
|
+
assert_match(/file:/, easy.last_effective_url)
|
170
170
|
}
|
171
171
|
end
|
172
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
|
+
|
173
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
|
174
203
|
# on my MacBook, this causes curl_easy_init to take nearly 0.01 seconds / * 100 below is 1 second too many!
|
175
204
|
def test_n_requests
|
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.
|
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:
|
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
|