curb 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +13 -0
- data/ext/curb.c +4 -0
- data/ext/curb.h +3 -3
- data/ext/curb_easy.c +99 -108
- data/ext/curb_easy.h +2 -0
- data/ext/curb_multi.c +12 -0
- data/ext/extconf.rb +3 -0
- data/lib/curb.rb +1 -0
- data/lib/curl.rb +56 -0
- data/lib/curl/easy.rb +83 -0
- data/lib/curl/multi.rb +8 -4
- data/tests/bug_issue102.rb +17 -0
- data/tests/foo.rb +13 -0
- data/tests/helper.rb +13 -5
- data/tests/tc_curl.rb +39 -0
- data/tests/tc_curl_easy.rb +14 -0
- data/tests/tc_curl_multi.rb +20 -1
- metadata +45 -25
data/README
CHANGED
@@ -56,6 +56,19 @@ Curb provides two classes:
|
|
56
56
|
+ Curl::Easy - simple API, for day-to-day tasks.
|
57
57
|
+ Curl::Multi - more advanced API, for operating on multiple URLs simultaneously.
|
58
58
|
|
59
|
+
### Super simple API (less typing)
|
60
|
+
|
61
|
+
http = Curl.get("http://www.google.com/")
|
62
|
+
puts http.body_str
|
63
|
+
|
64
|
+
http = Curl.post("http://www.google.com/", {:foo => "bar"})
|
65
|
+
puts http.body_str
|
66
|
+
|
67
|
+
http = Curl.get("http://www.google.com/") do|http|
|
68
|
+
http.headers['Cookie'] = 'foo=1;bar=2'
|
69
|
+
end
|
70
|
+
puts http.body_str
|
71
|
+
|
59
72
|
### Simple fetch via HTTP:
|
60
73
|
|
61
74
|
c = Curl::Easy.perform("http://www.google.co.uk")
|
data/ext/curb.c
CHANGED
@@ -424,8 +424,12 @@ void Init_curb_core() {
|
|
424
424
|
CURB_DEFINE(CURLOPT_FAILONERROR);
|
425
425
|
#endif
|
426
426
|
CURB_DEFINE(CURLOPT_URL);
|
427
|
+
#if HAVE_CURLOPT_PROTOCOLS
|
427
428
|
CURB_DEFINE(CURLOPT_PROTOCOLS);
|
429
|
+
#endif
|
430
|
+
#if HAVE_CURLOPT_REDIR_PROTOCOLS
|
428
431
|
CURB_DEFINE(CURLOPT_REDIR_PROTOCOLS);
|
432
|
+
#endif
|
429
433
|
CURB_DEFINE(CURLOPT_PROXY);
|
430
434
|
CURB_DEFINE(CURLOPT_PROXYPORT);
|
431
435
|
#if HAVE_CURLOPT_PROXYTYPE
|
data/ext/curb.h
CHANGED
@@ -20,11 +20,11 @@
|
|
20
20
|
#include "curb_macros.h"
|
21
21
|
|
22
22
|
// These should be managed from the Rake 'release' task.
|
23
|
-
#define CURB_VERSION "0.8.
|
24
|
-
#define CURB_VER_NUM
|
23
|
+
#define CURB_VERSION "0.8.1"
|
24
|
+
#define CURB_VER_NUM 801
|
25
25
|
#define CURB_VER_MAJ 0
|
26
26
|
#define CURB_VER_MIN 8
|
27
|
-
#define CURB_VER_MIC
|
27
|
+
#define CURB_VER_MIC 1
|
28
28
|
#define CURB_VER_PATCH 0
|
29
29
|
|
30
30
|
|
data/ext/curb_easy.c
CHANGED
@@ -115,6 +115,30 @@ static size_t proc_data_handler(char *stream,
|
|
115
115
|
}
|
116
116
|
}
|
117
117
|
|
118
|
+
static size_t proc_data_handler_body(char *stream,
|
119
|
+
size_t size,
|
120
|
+
size_t nmemb,
|
121
|
+
ruby_curl_easy *rbce)
|
122
|
+
{
|
123
|
+
size_t ret;
|
124
|
+
rbce->callback_active = 1;
|
125
|
+
ret = proc_data_handler(stream, size, nmemb, rb_easy_get("body_proc"));
|
126
|
+
rbce->callback_active = 0;
|
127
|
+
return ret;
|
128
|
+
}
|
129
|
+
static size_t proc_data_handler_header(char *stream,
|
130
|
+
size_t size,
|
131
|
+
size_t nmemb,
|
132
|
+
ruby_curl_easy *rbce)
|
133
|
+
{
|
134
|
+
size_t ret;
|
135
|
+
rbce->callback_active = 1;
|
136
|
+
ret = proc_data_handler(stream, size, nmemb, rb_easy_get("header_proc"));
|
137
|
+
rbce->callback_active = 0;
|
138
|
+
return ret;
|
139
|
+
}
|
140
|
+
|
141
|
+
|
118
142
|
static VALUE call_progress_handler(VALUE ary) {
|
119
143
|
return rb_funcall(rb_ary_entry(ary, 0), idCall, 4,
|
120
144
|
rb_ary_entry(ary, 1), // rb_float_new(dltotal),
|
@@ -157,13 +181,14 @@ static int proc_debug_handler(CURL *curl,
|
|
157
181
|
char *data,
|
158
182
|
size_t data_len,
|
159
183
|
VALUE proc) {
|
160
|
-
VALUE procret;
|
161
184
|
VALUE callargs = rb_ary_new2(3);
|
162
185
|
rb_ary_store(callargs, 0, proc);
|
163
186
|
rb_ary_store(callargs, 1, INT2FIX(type));
|
164
187
|
rb_ary_store(callargs, 2, rb_str_new(data, data_len));
|
165
188
|
rb_rescue(call_debug_handler, callargs, callback_exception, Qnil);
|
166
|
-
|
189
|
+
/* no way to indicate to libcurl that we should break out given an exception in the on_debug handler...
|
190
|
+
* this means exceptions will be swallowed
|
191
|
+
*/
|
167
192
|
//rb_funcall(proc, idCall, 2, INT2FIX(type), rb_str_new(data, data_len));
|
168
193
|
return 0;
|
169
194
|
}
|
@@ -234,6 +259,7 @@ static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
|
234
259
|
rbce->multipart_form_post = 0;
|
235
260
|
rbce->enable_cookies = 0;
|
236
261
|
rbce->ignore_content_length = 0;
|
262
|
+
rbce->callback_active = 0;
|
237
263
|
}
|
238
264
|
|
239
265
|
/*
|
@@ -320,6 +346,10 @@ static VALUE ruby_curl_easy_close(VALUE self) {
|
|
320
346
|
|
321
347
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
322
348
|
|
349
|
+
if (rbce->callback_active) {
|
350
|
+
rb_raise(rb_eRuntimeError, "Cannot close an active curl handle within a callback");
|
351
|
+
}
|
352
|
+
|
323
353
|
ruby_curl_easy_free(rbce);
|
324
354
|
|
325
355
|
/* reinit the handle */
|
@@ -358,6 +388,11 @@ static VALUE ruby_curl_easy_reset(VALUE self) {
|
|
358
388
|
ruby_curl_easy *rbce;
|
359
389
|
VALUE opts_dup;
|
360
390
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
391
|
+
|
392
|
+
if (rbce->callback_active) {
|
393
|
+
rb_raise(rb_eRuntimeError, "Cannot close an active curl handle within a callback");
|
394
|
+
}
|
395
|
+
|
361
396
|
opts_dup = rb_funcall(rbce->opts, rb_intern("dup"), 0);
|
362
397
|
|
363
398
|
curl_easy_reset(rbce->curl);
|
@@ -1443,17 +1478,6 @@ static VALUE ruby_curl_easy_use_netrc_q(VALUE self) {
|
|
1443
1478
|
CURB_BOOLEAN_GETTER(ruby_curl_easy, use_netrc);
|
1444
1479
|
}
|
1445
1480
|
|
1446
|
-
/*
|
1447
|
-
* call-seq:
|
1448
|
-
* easy.follow_location = boolean => boolean
|
1449
|
-
*
|
1450
|
-
* Configure whether this Curl instance will follow Location: headers
|
1451
|
-
* in HTTP responses. Redirects will only be followed to the extent
|
1452
|
-
* specified by +max_redirects+.
|
1453
|
-
*/
|
1454
|
-
static VALUE ruby_curl_easy_follow_location_set(VALUE self, VALUE follow_location) {
|
1455
|
-
CURB_BOOLEAN_SETTER(ruby_curl_easy, follow_location);
|
1456
|
-
}
|
1457
1481
|
/*
|
1458
1482
|
* call-seq:
|
1459
1483
|
*
|
@@ -1872,7 +1896,7 @@ static VALUE cb_each_ftp_command(VALUE ftp_command, VALUE wrap) {
|
|
1872
1896
|
*
|
1873
1897
|
* Always returns Qtrue, rb_raise on error.
|
1874
1898
|
*/
|
1875
|
-
VALUE ruby_curl_easy_setup(
|
1899
|
+
VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
1876
1900
|
// TODO this could do with a bit of refactoring...
|
1877
1901
|
CURL *curl;
|
1878
1902
|
VALUE url, _url = rb_easy_get("url");
|
@@ -1934,8 +1958,8 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
1934
1958
|
|
1935
1959
|
// body/header procs
|
1936
1960
|
if (!rb_easy_nil("body_proc")) {
|
1937
|
-
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, (curl_write_callback)&
|
1938
|
-
curl_easy_setopt(curl, CURLOPT_WRITEDATA,
|
1961
|
+
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, (curl_write_callback)&proc_data_handler_body);
|
1962
|
+
curl_easy_setopt(curl, CURLOPT_WRITEDATA, rbce);
|
1939
1963
|
/* clear out the body_data if it was set */
|
1940
1964
|
rb_easy_del("body_data");
|
1941
1965
|
} else {
|
@@ -1945,8 +1969,8 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
1945
1969
|
}
|
1946
1970
|
|
1947
1971
|
if (!rb_easy_nil("header_proc")) {
|
1948
|
-
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, (curl_write_callback)&
|
1949
|
-
curl_easy_setopt(curl, CURLOPT_HEADERDATA,
|
1972
|
+
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, (curl_write_callback)&proc_data_handler_header);
|
1973
|
+
curl_easy_setopt(curl, CURLOPT_HEADERDATA, rbce);
|
1950
1974
|
/* clear out the header_data if it was set */
|
1951
1975
|
rb_easy_del("header_data");
|
1952
1976
|
} else {
|
@@ -2202,27 +2226,6 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
|
|
2202
2226
|
return Qnil;
|
2203
2227
|
}
|
2204
2228
|
|
2205
|
-
/*
|
2206
|
-
* call-seq:
|
2207
|
-
* easy.http_get => true
|
2208
|
-
*
|
2209
|
-
* GET the currently configured URL using the current options set for
|
2210
|
-
* this Curl::Easy instance. This method always returns true, or raises
|
2211
|
-
* an exception (defined under Curl::Err) on error.
|
2212
|
-
*/
|
2213
|
-
static VALUE ruby_curl_easy_perform_get(VALUE self) {
|
2214
|
-
ruby_curl_easy *rbce;
|
2215
|
-
CURL *curl;
|
2216
|
-
|
2217
|
-
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
2218
|
-
curl = rbce->curl;
|
2219
|
-
|
2220
|
-
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
|
2221
|
-
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
|
2222
|
-
|
2223
|
-
return rb_funcall(self, rb_intern("perform"), 0);
|
2224
|
-
}
|
2225
|
-
|
2226
2229
|
/*
|
2227
2230
|
* Common implementation of easy.http(verb) and easy.http_delete
|
2228
2231
|
*/
|
@@ -2243,18 +2246,6 @@ static VALUE ruby_curl_easy_perform_verb_str(VALUE self, const char *verb) {
|
|
2243
2246
|
return retval;
|
2244
2247
|
}
|
2245
2248
|
|
2246
|
-
/*
|
2247
|
-
* call-seq:
|
2248
|
-
* easy.http_delete
|
2249
|
-
*
|
2250
|
-
* DELETE the currently configured URL using the current options set for
|
2251
|
-
* this Curl::Easy instance. This method always returns true, or raises
|
2252
|
-
* an exception (defined under Curl::Err) on error.
|
2253
|
-
*/
|
2254
|
-
static VALUE ruby_curl_easy_perform_delete(VALUE self) {
|
2255
|
-
return ruby_curl_easy_perform_verb_str(self, "DELETE");
|
2256
|
-
}
|
2257
|
-
|
2258
2249
|
/*
|
2259
2250
|
* call-seq:
|
2260
2251
|
* easy.http(verb)
|
@@ -2367,52 +2358,6 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
|
|
2367
2358
|
}
|
2368
2359
|
}
|
2369
2360
|
|
2370
|
-
/*
|
2371
|
-
* call-seq:
|
2372
|
-
* easy.http_head => true
|
2373
|
-
*
|
2374
|
-
* Request headers from the currently configured URL using the HEAD
|
2375
|
-
* method and current options set for this Curl::Easy instance. This
|
2376
|
-
* method always returns true, or raises an exception (defined under
|
2377
|
-
* Curl::Err) on error.
|
2378
|
-
*
|
2379
|
-
*/
|
2380
|
-
static VALUE ruby_curl_easy_perform_head(VALUE self) {
|
2381
|
-
ruby_curl_easy *rbce;
|
2382
|
-
CURL *curl;
|
2383
|
-
VALUE ret;
|
2384
|
-
|
2385
|
-
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
2386
|
-
curl = rbce->curl;
|
2387
|
-
|
2388
|
-
curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
|
2389
|
-
|
2390
|
-
ret = rb_funcall(self, rb_intern("perform"), 0);
|
2391
|
-
|
2392
|
-
curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
|
2393
|
-
return ret;
|
2394
|
-
}
|
2395
|
-
|
2396
|
-
/*
|
2397
|
-
*call-seq:
|
2398
|
-
* easy = Curl::Easy.new("url") do|c|
|
2399
|
-
* c.head = true
|
2400
|
-
* end
|
2401
|
-
* easy.perform
|
2402
|
-
*/
|
2403
|
-
static VALUE ruby_curl_easy_set_head_option(VALUE self, VALUE onoff) {
|
2404
|
-
ruby_curl_easy *rbce;
|
2405
|
-
|
2406
|
-
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
2407
|
-
|
2408
|
-
if (onoff == Qtrue) {
|
2409
|
-
curl_easy_setopt(rbce->curl, CURLOPT_NOBODY, 1);
|
2410
|
-
} else {
|
2411
|
-
curl_easy_setopt(rbce->curl, CURLOPT_NOBODY, 0);
|
2412
|
-
}
|
2413
|
-
|
2414
|
-
return onoff;
|
2415
|
-
}
|
2416
2361
|
/*
|
2417
2362
|
* call-seq:
|
2418
2363
|
* easy.http_put(data) => true
|
@@ -2720,6 +2665,36 @@ static VALUE ruby_curl_easy_redirect_count_get(VALUE self) {
|
|
2720
2665
|
|
2721
2666
|
}
|
2722
2667
|
|
2668
|
+
/*
|
2669
|
+
* call-seq:
|
2670
|
+
* easy.redirect_url => "http://some.url" or nil
|
2671
|
+
*
|
2672
|
+
* Retrieve the URL a redirect would take you to if you
|
2673
|
+
* would enable CURLOPT_FOLLOWLOCATION.
|
2674
|
+
*
|
2675
|
+
* Requires libcurl 7.18.2 or higher, otherwise -1 is always returned.
|
2676
|
+
*/
|
2677
|
+
static VALUE ruby_curl_easy_redirect_url_get(VALUE self) {
|
2678
|
+
#ifdef HAVE_CURLINFO_REDIRECT_URL
|
2679
|
+
ruby_curl_easy *rbce;
|
2680
|
+
char* url;
|
2681
|
+
|
2682
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
2683
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_REDIRECT_URL, &url);
|
2684
|
+
|
2685
|
+
if (url && url[0]) { // curl returns empty string if none
|
2686
|
+
return rb_str_new2(url);
|
2687
|
+
} else {
|
2688
|
+
return Qnil;
|
2689
|
+
}
|
2690
|
+
#else
|
2691
|
+
rb_warn("Installed libcurl is too old to support redirect_url");
|
2692
|
+
return INT2FIX(-1);
|
2693
|
+
#endif
|
2694
|
+
}
|
2695
|
+
|
2696
|
+
|
2697
|
+
|
2723
2698
|
/*
|
2724
2699
|
* call-seq:
|
2725
2700
|
* easy.uploaded_bytes => float
|
@@ -3070,11 +3045,10 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
3070
3045
|
VALUE verbose = val;
|
3071
3046
|
CURB_BOOLEAN_SETTER(ruby_curl_easy, verbose);
|
3072
3047
|
} break;
|
3073
|
-
case
|
3074
|
-
|
3075
|
-
|
3076
|
-
|
3077
|
-
break;
|
3048
|
+
case CURLOPT_FOLLOWLOCATION: {
|
3049
|
+
VALUE follow_location = val;
|
3050
|
+
CURB_BOOLEAN_SETTER(ruby_curl_easy, follow_location);
|
3051
|
+
} break;
|
3078
3052
|
/* TODO: CALLBACK OPTIONS */
|
3079
3053
|
/* TODO: ERROR OPTIONS */
|
3080
3054
|
/* NETWORK OPTIONS */
|
@@ -3096,6 +3070,22 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
3096
3070
|
VALUE interface_hm = val;
|
3097
3071
|
CURB_OBJECT_HSETTER(ruby_curl_easy, interface_hm);
|
3098
3072
|
} break;
|
3073
|
+
case CURLOPT_HEADER:
|
3074
|
+
case CURLOPT_NOPROGRESS:
|
3075
|
+
case CURLOPT_NOSIGNAL:
|
3076
|
+
case CURLOPT_HTTPGET:
|
3077
|
+
case CURLOPT_NOBODY: {
|
3078
|
+
int type = rb_type(val);
|
3079
|
+
VALUE value;
|
3080
|
+
if (type == T_TRUE) {
|
3081
|
+
value = rb_int_new(1);
|
3082
|
+
} else if (type == T_FALSE) {
|
3083
|
+
value = rb_int_new(0);
|
3084
|
+
} else {
|
3085
|
+
value = rb_funcall(val, rb_intern("to_i"), 0);
|
3086
|
+
}
|
3087
|
+
curl_easy_setopt(rbce->curl, option, FIX2INT(value));
|
3088
|
+
} break;
|
3099
3089
|
case CURLOPT_USERPWD: {
|
3100
3090
|
VALUE userpwd = val;
|
3101
3091
|
CURB_OBJECT_HSETTER(ruby_curl_easy, userpwd);
|
@@ -3116,7 +3106,12 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
3116
3106
|
VALUE cookiejar = val;
|
3117
3107
|
CURB_OBJECT_HSETTER(ruby_curl_easy, cookiejar);
|
3118
3108
|
} break;
|
3119
|
-
|
3109
|
+
case CURLOPT_RESUME_FROM: {
|
3110
|
+
curl_easy_setopt(rbce->curl, CURLOPT_RESUME_FROM, FIX2LONG(val));
|
3111
|
+
} break;
|
3112
|
+
case CURLOPT_FAILONERROR: {
|
3113
|
+
curl_easy_setopt(rbce->curl, CURLOPT_FAILONERROR, FIX2LONG(val));
|
3114
|
+
} break;
|
3120
3115
|
default:
|
3121
3116
|
break;
|
3122
3117
|
}
|
@@ -3326,7 +3321,6 @@ void init_curb_easy() {
|
|
3326
3321
|
rb_define_method(cCurlEasy, "header_in_body?", ruby_curl_easy_header_in_body_q, 0);
|
3327
3322
|
rb_define_method(cCurlEasy, "use_netrc=", ruby_curl_easy_use_netrc_set, 1);
|
3328
3323
|
rb_define_method(cCurlEasy, "use_netrc?", ruby_curl_easy_use_netrc_q, 0);
|
3329
|
-
rb_define_method(cCurlEasy, "follow_location=", ruby_curl_easy_follow_location_set, 1);
|
3330
3324
|
rb_define_method(cCurlEasy, "follow_location?", ruby_curl_easy_follow_location_q, 0);
|
3331
3325
|
rb_define_method(cCurlEasy, "autoreferer=", ruby_curl_easy_autoreferer_set, 1);
|
3332
3326
|
rb_define_method(cCurlEasy, "unrestricted_auth=", ruby_curl_easy_unrestricted_auth_set, 1);
|
@@ -3353,12 +3347,8 @@ void init_curb_easy() {
|
|
3353
3347
|
rb_define_method(cCurlEasy, "on_complete", ruby_curl_easy_on_complete_set, -1);
|
3354
3348
|
|
3355
3349
|
rb_define_method(cCurlEasy, "http", ruby_curl_easy_perform_verb, 1);
|
3356
|
-
rb_define_method(cCurlEasy, "http_delete", ruby_curl_easy_perform_delete, 0);
|
3357
|
-
rb_define_method(cCurlEasy, "http_get", ruby_curl_easy_perform_get, 0);
|
3358
3350
|
rb_define_method(cCurlEasy, "http_post", ruby_curl_easy_perform_post, -1);
|
3359
|
-
rb_define_method(cCurlEasy, "http_head", ruby_curl_easy_perform_head, 0);
|
3360
3351
|
rb_define_method(cCurlEasy, "http_put", ruby_curl_easy_perform_put, 1);
|
3361
|
-
rb_define_method(cCurlEasy, "head=", ruby_curl_easy_set_head_option, 1);
|
3362
3352
|
|
3363
3353
|
/* Post-perform info methods */
|
3364
3354
|
rb_define_method(cCurlEasy, "body_str", ruby_curl_easy_body_str_get, 0);
|
@@ -3378,6 +3368,7 @@ void init_curb_easy() {
|
|
3378
3368
|
rb_define_method(cCurlEasy, "start_transfer_time", ruby_curl_easy_start_transfer_time_get, 0);
|
3379
3369
|
rb_define_method(cCurlEasy, "redirect_time", ruby_curl_easy_redirect_time_get, 0);
|
3380
3370
|
rb_define_method(cCurlEasy, "redirect_count", ruby_curl_easy_redirect_count_get, 0);
|
3371
|
+
rb_define_method(cCurlEasy, "redirect_url", ruby_curl_easy_redirect_url_get, 0);
|
3381
3372
|
rb_define_method(cCurlEasy, "downloaded_bytes", ruby_curl_easy_downloaded_bytes_get, 0);
|
3382
3373
|
rb_define_method(cCurlEasy, "uploaded_bytes", ruby_curl_easy_uploaded_bytes_get, 0);
|
3383
3374
|
rb_define_method(cCurlEasy, "download_speed", ruby_curl_easy_download_speed_get, 0);
|
data/ext/curb_easy.h
CHANGED
data/ext/curb_multi.c
CHANGED
@@ -354,7 +354,9 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
|
|
354
354
|
|
355
355
|
if (!rb_easy_nil("complete_proc")) {
|
356
356
|
callargs = rb_ary_new3(2, rb_easy_get("complete_proc"), easy);
|
357
|
+
rbce->callback_active = 1;
|
357
358
|
val = rb_rescue(call_status_handler1, callargs, callback_exception, Qnil);
|
359
|
+
rbce->callback_active = 0;
|
358
360
|
//rb_funcall( rb_easy_get("complete_proc"), idCall, 1, easy );
|
359
361
|
}
|
360
362
|
|
@@ -363,7 +365,9 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
|
|
363
365
|
if (result != 0) {
|
364
366
|
if (!rb_easy_nil("failure_proc")) {
|
365
367
|
callargs = rb_ary_new3(3, rb_easy_get("failure_proc"), easy, rb_curl_easy_error(result));
|
368
|
+
rbce->callback_active = 1;
|
366
369
|
val = rb_rescue(call_status_handler2, callargs, callback_exception, Qnil);
|
370
|
+
rbce->callback_active = 0;
|
367
371
|
//rb_funcall( rb_easy_get("failure_proc"), idCall, 2, easy, rb_curl_easy_error(result) );
|
368
372
|
}
|
369
373
|
}
|
@@ -371,23 +375,31 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
|
|
371
375
|
((response_code >= 200 && response_code < 300) || response_code == 0)) {
|
372
376
|
/* NOTE: we allow response_code == 0, in the case of non http requests e.g. reading from disk */
|
373
377
|
callargs = rb_ary_new3(2, rb_easy_get("success_proc"), easy);
|
378
|
+
rbce->callback_active = 1;
|
374
379
|
val = rb_rescue(call_status_handler1, callargs, callback_exception, Qnil);
|
380
|
+
rbce->callback_active = 0;
|
375
381
|
//rb_funcall( rb_easy_get("success_proc"), idCall, 1, easy );
|
376
382
|
}
|
377
383
|
else if (!rb_easy_nil("redirect_proc") &&
|
378
384
|
(response_code >= 300 && response_code < 400)) {
|
385
|
+
rbce->callback_active = 1;
|
379
386
|
callargs = rb_ary_new3(3, rb_easy_get("redirect_proc"), easy, rb_curl_easy_error(result));
|
387
|
+
rbce->callback_active = 0;
|
380
388
|
val = rb_rescue(call_status_handler2, callargs, callback_exception, Qnil);
|
381
389
|
}
|
382
390
|
else if (!rb_easy_nil("missing_proc") &&
|
383
391
|
(response_code >= 400 && response_code < 500)) {
|
392
|
+
rbce->callback_active = 1;
|
384
393
|
callargs = rb_ary_new3(3, rb_easy_get("missing_proc"), easy, rb_curl_easy_error(result));
|
394
|
+
rbce->callback_active = 0;
|
385
395
|
val = rb_rescue(call_status_handler2, callargs, callback_exception, Qnil);
|
386
396
|
}
|
387
397
|
else if (!rb_easy_nil("failure_proc") &&
|
388
398
|
(response_code >= 500 && response_code <= 999)) {
|
389
399
|
callargs = rb_ary_new3(3, rb_easy_get("failure_proc"), easy, rb_curl_easy_error(result));
|
400
|
+
rbce->callback_active = 1;
|
390
401
|
val = rb_rescue(call_status_handler2, callargs, callback_exception, Qnil);
|
402
|
+
rbce->callback_active = 0;
|
391
403
|
//rb_funcall( rb_easy_get("failure_proc"), idCall, 2, easy, rb_curl_easy_error(result) );
|
392
404
|
}
|
393
405
|
|
data/ext/extconf.rb
CHANGED
@@ -119,6 +119,9 @@ have_constant "curle_again"
|
|
119
119
|
have_constant "curle_ssl_crl_badfile"
|
120
120
|
have_constant "curle_ssl_issuer_error"
|
121
121
|
|
122
|
+
# added in 7.18.2
|
123
|
+
have_constant "curlinfo_redirect_url"
|
124
|
+
|
122
125
|
# username/password added in 7.19.1
|
123
126
|
have_constant "curlopt_username"
|
124
127
|
have_constant "curlopt_password"
|
data/lib/curb.rb
CHANGED
data/lib/curl.rb
CHANGED
@@ -1 +1,57 @@
|
|
1
1
|
require 'curb'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
# expose shortcut methods
|
5
|
+
module Curl
|
6
|
+
|
7
|
+
def self.http(verb, url, post_body=nil, put_data=nil, &block)
|
8
|
+
handle = Curl::Easy.new(url)
|
9
|
+
handle.post_body = post_body if post_body
|
10
|
+
handle.put_data = put_data if put_data
|
11
|
+
yield handle if block_given?
|
12
|
+
handle.http(verb)
|
13
|
+
handle
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.get(url, params={}, &block)
|
17
|
+
http :GET, urlalize(url, params), nil, nil, &block
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.post(url, params={}, &block)
|
21
|
+
http :POST, url, postalize(params), nil, &block
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.put(url, params={}, &block)
|
25
|
+
http :PUT, url, nil, postalize(params), &block
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.delete(url, params={}, &block)
|
29
|
+
http :DELETE, url, postalize(params), nil, &block
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.patch(url, params={}, &block)
|
33
|
+
http :PATCH, url, postalize(params), nil, &block
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.head(url, params={}, &block)
|
37
|
+
http :OPTIONS, urlalize(url, params), nil, nil, &block
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.options(url, params={}, &block)
|
41
|
+
http :OPTIONS, urlalize(url, params), nil, nil, &block
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.urlalize(url, params={})
|
45
|
+
query_str = params.map {|k,v| "#{URI.escape(k.to_s)}=#{URI.escape(v.to_s)}" }.join('&')
|
46
|
+
if url.match(/\?/)
|
47
|
+
"#{url}&#{query_str}"
|
48
|
+
else
|
49
|
+
"#{url}?#{query_str}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.postalize(params={})
|
54
|
+
params.map {|k,v| "#{URI.escape(k.to_s)}=#{URI.escape(v.to_s)}" }.join('&')
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
data/lib/curl/easy.rb
CHANGED
@@ -1,6 +1,23 @@
|
|
1
1
|
module Curl
|
2
2
|
class Easy
|
3
3
|
|
4
|
+
alias post http_post
|
5
|
+
alias put http_put
|
6
|
+
|
7
|
+
#
|
8
|
+
# call-seq:
|
9
|
+
# easy.status => String
|
10
|
+
#
|
11
|
+
def status
|
12
|
+
parts = self.header_str.split(/\s/)
|
13
|
+
status = []
|
14
|
+
parts.shift
|
15
|
+
while parts.size > 0 && parts.first != ''
|
16
|
+
status << parts.shift
|
17
|
+
end
|
18
|
+
status.join(' ')
|
19
|
+
end
|
20
|
+
|
4
21
|
#
|
5
22
|
# call-seq:
|
6
23
|
# easy.set :sym|Fixnum, value
|
@@ -213,6 +230,72 @@ module Curl
|
|
213
230
|
set :cookiejar, value
|
214
231
|
end
|
215
232
|
|
233
|
+
#
|
234
|
+
# call-seq:
|
235
|
+
# easy = Curl::Easy.new("url") do|c|
|
236
|
+
# c.head = true
|
237
|
+
# end
|
238
|
+
# easy.perform
|
239
|
+
#
|
240
|
+
def head=(onoff)
|
241
|
+
set :nobody, onoff
|
242
|
+
end
|
243
|
+
|
244
|
+
#
|
245
|
+
# call-seq:
|
246
|
+
# easy.follow_location = boolean => boolean
|
247
|
+
#
|
248
|
+
# Configure whether this Curl instance will follow Location: headers
|
249
|
+
# in HTTP responses. Redirects will only be followed to the extent
|
250
|
+
# specified by +max_redirects+.
|
251
|
+
#
|
252
|
+
def follow_location=(onoff)
|
253
|
+
set :followlocation, onoff
|
254
|
+
end
|
255
|
+
|
256
|
+
#
|
257
|
+
# call-seq:
|
258
|
+
# easy.http_head => true
|
259
|
+
#
|
260
|
+
# Request headers from the currently configured URL using the HEAD
|
261
|
+
# method and current options set for this Curl::Easy instance. This
|
262
|
+
# method always returns true, or raises an exception (defined under
|
263
|
+
# Curl::Err) on error.
|
264
|
+
#
|
265
|
+
def http_head
|
266
|
+
set :nobody, true
|
267
|
+
ret = self.perform
|
268
|
+
set :nobody, false
|
269
|
+
ret
|
270
|
+
end
|
271
|
+
|
272
|
+
#
|
273
|
+
# call-seq:
|
274
|
+
# easy.http_get => true
|
275
|
+
#
|
276
|
+
# GET the currently configured URL using the current options set for
|
277
|
+
# this Curl::Easy instance. This method always returns true, or raises
|
278
|
+
# an exception (defined under Curl::Err) on error.
|
279
|
+
#
|
280
|
+
def http_get
|
281
|
+
set :httpget, true
|
282
|
+
http :GET
|
283
|
+
end
|
284
|
+
alias get http_get
|
285
|
+
|
286
|
+
#
|
287
|
+
# call-seq:
|
288
|
+
# easy.http_delete
|
289
|
+
#
|
290
|
+
# DELETE the currently configured URL using the current options set for
|
291
|
+
# this Curl::Easy instance. This method always returns true, or raises
|
292
|
+
# an exception (defined under Curl::Err) on error.
|
293
|
+
#
|
294
|
+
def http_delete
|
295
|
+
self.http :DELETE
|
296
|
+
end
|
297
|
+
alias delete http_delete
|
298
|
+
|
216
299
|
class << self
|
217
300
|
|
218
301
|
#
|
data/lib/curl/multi.rb
CHANGED
@@ -157,13 +157,17 @@ module Curl
|
|
157
157
|
end
|
158
158
|
end
|
159
159
|
|
160
|
-
|
161
|
-
m.perform
|
160
|
+
if urls_with_config.empty?
|
161
|
+
m.perform
|
162
|
+
else
|
163
|
+
until urls_with_config.empty?
|
164
|
+
m.perform do
|
165
|
+
consume_free_handles.call
|
166
|
+
end
|
162
167
|
consume_free_handles.call
|
163
168
|
end
|
164
|
-
|
169
|
+
free_handles = nil
|
165
170
|
end
|
166
|
-
free_handles = nil
|
167
171
|
end
|
168
172
|
|
169
173
|
# call-seq:
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
2
|
+
|
3
|
+
class BugIssue102 < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_interface
|
6
|
+
test = "https://api.twitter.com/1/users/show.json?screen_name=TwitterAPI&include_entities=true"
|
7
|
+
ip = "192.168.1.61"
|
8
|
+
|
9
|
+
c = Curl::Easy.new do |curl|
|
10
|
+
curl.url = test
|
11
|
+
curl.interface = ip
|
12
|
+
end
|
13
|
+
|
14
|
+
c.perform
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
data/tests/foo.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'curb'
|
2
|
+
|
3
|
+
SSL_CERT = '/path/to/my/cert'
|
4
|
+
SSL_KEY = '/path/to/my/key'
|
5
|
+
|
6
|
+
curl = Curl::Easy.new('98.129.21.125')
|
7
|
+
curl.verbose = true
|
8
|
+
curl.cert = SSL_CERT
|
9
|
+
curl.cert_key = SSL_KEY
|
10
|
+
curl.follow_location = true
|
11
|
+
curl.ssl_verify_host = false
|
12
|
+
curl.ssl_verify_peer = false
|
13
|
+
curl.perform
|
data/tests/helper.rb
CHANGED
@@ -73,12 +73,12 @@ class TestServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
73
73
|
elsif req.path.match /error$/
|
74
74
|
res.status = 500
|
75
75
|
end
|
76
|
-
respond_with(
|
76
|
+
respond_with("GET#{req.query_string}",req,res)
|
77
77
|
end
|
78
78
|
|
79
79
|
def do_HEAD(req,res)
|
80
80
|
res['Location'] = "/nonexistent"
|
81
|
-
respond_with(
|
81
|
+
respond_with("HEAD#{req.query_string}",req,res)
|
82
82
|
end
|
83
83
|
|
84
84
|
def do_POST(req,res)
|
@@ -103,15 +103,23 @@ class TestServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
103
103
|
end
|
104
104
|
|
105
105
|
def do_DELETE(req,res)
|
106
|
-
respond_with(
|
106
|
+
respond_with("DELETE#{req.query_string}",req,res)
|
107
107
|
end
|
108
108
|
|
109
109
|
def do_PURGE(req,res)
|
110
|
-
respond_with(
|
110
|
+
respond_with("PURGE#{req.query_string}",req,res)
|
111
111
|
end
|
112
112
|
|
113
113
|
def do_COPY(req,res)
|
114
|
-
respond_with(
|
114
|
+
respond_with("COPY#{req.query_string}",req,res)
|
115
|
+
end
|
116
|
+
|
117
|
+
def do_PATCH(req,res)
|
118
|
+
respond_with("PATCH\n#{req.body}",req,res)
|
119
|
+
end
|
120
|
+
|
121
|
+
def do_OPTIONS(req,res)
|
122
|
+
respond_with("OPTIONS#{req.query_string}",req,res)
|
115
123
|
end
|
116
124
|
|
117
125
|
end
|
data/tests/tc_curl.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
2
|
+
|
3
|
+
class TestCurl < Test::Unit::TestCase
|
4
|
+
def test_get
|
5
|
+
curl = Curl.get(TestServlet.url, {:foo => "bar"})
|
6
|
+
assert_equal "GETfoo=bar", curl.body_str
|
7
|
+
|
8
|
+
curl = Curl.options(TestServlet.url, {:foo => "bar"}) do|http|
|
9
|
+
http.headers['Cookie'] = 'foo=1;bar=2'
|
10
|
+
end
|
11
|
+
assert_equal "OPTIONSfoo=bar", curl.body_str
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_post
|
15
|
+
curl = Curl.post(TestServlet.url, {:foo => "bar"})
|
16
|
+
assert_equal "POST\nfoo=bar", curl.body_str
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_put
|
20
|
+
curl = Curl.put(TestServlet.url, {:foo => "bar"})
|
21
|
+
assert_equal "PUT\nfoo=bar", curl.body_str
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_patch
|
25
|
+
curl = Curl.patch(TestServlet.url, {:foo => "bar"})
|
26
|
+
assert_equal "PATCH\nfoo=bar", curl.body_str
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_options
|
30
|
+
curl = Curl.options(TestServlet.url, {:foo => "bar"})
|
31
|
+
assert_equal "OPTIONSfoo=bar", curl.body_str
|
32
|
+
end
|
33
|
+
|
34
|
+
include TestServerMethods
|
35
|
+
|
36
|
+
def setup
|
37
|
+
server_setup
|
38
|
+
end
|
39
|
+
end
|
data/tests/tc_curl_easy.rb
CHANGED
@@ -988,6 +988,20 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
988
988
|
assert true, "raise in on debug has no effect"
|
989
989
|
end
|
990
990
|
|
991
|
+
def test_status_codes
|
992
|
+
curl = Curl::Easy.new(TestServlet.url)
|
993
|
+
curl.perform
|
994
|
+
assert_equal '200 OK', curl.status
|
995
|
+
end
|
996
|
+
|
997
|
+
def test_close_in_on_callbacks
|
998
|
+
curl = Curl::Easy.new(TestServlet.url)
|
999
|
+
curl.on_body {|d| curl.close; d.size }
|
1000
|
+
assert_raises RuntimeError do
|
1001
|
+
curl.perform
|
1002
|
+
end
|
1003
|
+
end
|
1004
|
+
|
991
1005
|
include TestServerMethods
|
992
1006
|
|
993
1007
|
def setup
|
data/tests/tc_curl_multi.rb
CHANGED
@@ -385,7 +385,26 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
385
385
|
end
|
386
386
|
end
|
387
387
|
|
388
|
-
def
|
388
|
+
def test_multi_easy_http_with_max_connects
|
389
|
+
urls = [
|
390
|
+
{ :url => TestServlet.url + '?q=1', :method => :get },
|
391
|
+
{ :url => TestServlet.url + '?q=2', :method => :get },
|
392
|
+
{ :url => TestServlet.url + '?q=3', :method => :get }
|
393
|
+
]
|
394
|
+
Curl::Multi.http(urls, {:pipeline => true, :max_connects => 1}) do|easy, code, method|
|
395
|
+
assert_equal nil, code
|
396
|
+
case method
|
397
|
+
when :post
|
398
|
+
assert_match /POST/, easy.body_str
|
399
|
+
when :get
|
400
|
+
assert_match /GET/, easy.body_str
|
401
|
+
when :put
|
402
|
+
assert_match /PUT/, easy.body_str
|
403
|
+
end
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
def test_multi_recieves_500
|
389
408
|
m = Curl::Multi.new
|
390
409
|
e = Curl::Easy.new("http://127.0.0.1:9129/methods")
|
391
410
|
failure = false
|
metadata
CHANGED
@@ -1,28 +1,34 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: curb
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 61
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 8
|
9
|
+
- 1
|
10
|
+
version: 0.8.1
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Ross Bamford
|
9
14
|
- Todd A. Fisher
|
10
15
|
autorequire:
|
11
16
|
bindir: bin
|
12
17
|
cert_chain: []
|
13
|
-
|
18
|
+
|
19
|
+
date: 2012-06-29 00:00:00 Z
|
14
20
|
dependencies: []
|
15
|
-
|
16
|
-
|
17
|
-
libcurl live at http://curl.haxx.se/
|
21
|
+
|
22
|
+
description: Curb (probably CUrl-RuBy or something) provides Ruby-language bindings for the libcurl(3), a fully-featured client-side URL transfer library. cURL and libcurl live at http://curl.haxx.se/
|
18
23
|
email: todd.fisher@gmail.com
|
19
24
|
executables: []
|
20
|
-
|
25
|
+
|
26
|
+
extensions:
|
21
27
|
- ext/extconf.rb
|
22
|
-
extra_rdoc_files:
|
28
|
+
extra_rdoc_files:
|
23
29
|
- LICENSE
|
24
30
|
- README
|
25
|
-
files:
|
31
|
+
files:
|
26
32
|
- LICENSE
|
27
33
|
- README
|
28
34
|
- Rakefile
|
@@ -51,14 +57,17 @@ files:
|
|
51
57
|
- tests/bug_curb_easy_blocks_ruby_threads.rb
|
52
58
|
- tests/bug_curb_easy_post_with_string_no_content_length_header.rb
|
53
59
|
- tests/bug_instance_post_differs_from_class_post.rb
|
60
|
+
- tests/bug_issue102.rb
|
54
61
|
- tests/bug_multi_segfault.rb
|
55
62
|
- tests/bug_postfields_crash.rb
|
56
63
|
- tests/bug_postfields_crash2.rb
|
57
64
|
- tests/bug_require_last_or_segfault.rb
|
58
65
|
- tests/bugtests.rb
|
66
|
+
- tests/foo.rb
|
59
67
|
- tests/helper.rb
|
60
68
|
- tests/mem_check.rb
|
61
69
|
- tests/require_last_or_segfault_script.rb
|
70
|
+
- tests/tc_curl.rb
|
62
71
|
- tests/tc_curl_download.rb
|
63
72
|
- tests/tc_curl_easy.rb
|
64
73
|
- tests/tc_curl_easy_setopt.rb
|
@@ -69,46 +78,57 @@ files:
|
|
69
78
|
- tests/unittests.rb
|
70
79
|
homepage: http://curb.rubyforge.org/
|
71
80
|
licenses: []
|
81
|
+
|
72
82
|
post_install_message:
|
73
|
-
rdoc_options:
|
83
|
+
rdoc_options:
|
74
84
|
- --main
|
75
85
|
- README
|
76
|
-
require_paths:
|
86
|
+
require_paths:
|
77
87
|
- lib
|
78
88
|
- ext
|
79
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
90
|
none: false
|
81
|
-
requirements:
|
82
|
-
- -
|
83
|
-
- !ruby/object:Gem::Version
|
84
|
-
|
85
|
-
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
hash: 3
|
95
|
+
segments:
|
96
|
+
- 0
|
97
|
+
version: "0"
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
99
|
none: false
|
87
|
-
requirements:
|
88
|
-
- -
|
89
|
-
- !ruby/object:Gem::Version
|
90
|
-
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
hash: 3
|
104
|
+
segments:
|
105
|
+
- 0
|
106
|
+
version: "0"
|
91
107
|
requirements: []
|
108
|
+
|
92
109
|
rubyforge_project: curb
|
93
|
-
rubygems_version: 1.8.
|
110
|
+
rubygems_version: 1.8.23
|
94
111
|
signing_key:
|
95
112
|
specification_version: 3
|
96
113
|
summary: Ruby libcurl bindings
|
97
|
-
test_files:
|
114
|
+
test_files:
|
98
115
|
- tests/alltests.rb
|
99
116
|
- tests/bug_crash_on_debug.rb
|
100
117
|
- tests/bug_crash_on_progress.rb
|
101
118
|
- tests/bug_curb_easy_blocks_ruby_threads.rb
|
102
119
|
- tests/bug_curb_easy_post_with_string_no_content_length_header.rb
|
103
120
|
- tests/bug_instance_post_differs_from_class_post.rb
|
121
|
+
- tests/bug_issue102.rb
|
104
122
|
- tests/bug_multi_segfault.rb
|
105
123
|
- tests/bug_postfields_crash.rb
|
106
124
|
- tests/bug_postfields_crash2.rb
|
107
125
|
- tests/bug_require_last_or_segfault.rb
|
108
126
|
- tests/bugtests.rb
|
127
|
+
- tests/foo.rb
|
109
128
|
- tests/helper.rb
|
110
129
|
- tests/mem_check.rb
|
111
130
|
- tests/require_last_or_segfault_script.rb
|
131
|
+
- tests/tc_curl.rb
|
112
132
|
- tests/tc_curl_download.rb
|
113
133
|
- tests/tc_curl_easy.rb
|
114
134
|
- tests/tc_curl_easy_setopt.rb
|