taf2-curb 0.4.8.0 → 0.4.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/curb.h +3 -3
- data/ext/curb_easy.c +106 -79
- data/ext/curb_multi.c +66 -55
- data/ext/curb_postfield.c +1 -1
- data/ext/extconf.rb +3 -0
- data/tests/bug_curb_easy_blocks_ruby_threads.rb +1 -1
- data/tests/bug_instance_post_differs_from_class_post.rb +1 -1
- data/tests/bug_multi_segfault.rb +2 -2
- data/tests/helper.rb +9 -1
- data/tests/require_last_or_segfault_script.rb +2 -2
- data/tests/tc_curl_download.rb +1 -1
- data/tests/tc_curl_easy.rb +11 -1
- data/tests/tc_curl_multi.rb +25 -1
- data/tests/tc_curl_postfield.rb +1 -1
- metadata +2 -2
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.4.
|
24
|
-
#define CURB_VER_NUM
|
23
|
+
#define CURB_VERSION "0.4.9.0"
|
24
|
+
#define CURB_VER_NUM 490
|
25
25
|
#define CURB_VER_MAJ 0
|
26
26
|
#define CURB_VER_MIN 4
|
27
|
-
#define CURB_VER_MIC
|
27
|
+
#define CURB_VER_MIC 9
|
28
28
|
#define CURB_VER_PATCH 0
|
29
29
|
|
30
30
|
|
data/ext/curb_easy.c
CHANGED
@@ -82,32 +82,6 @@ static size_t read_data_handler(void *ptr,
|
|
82
82
|
return read_bytes;
|
83
83
|
}
|
84
84
|
|
85
|
-
// PutStream *pstream = (PutStream*)stream;
|
86
|
-
// size_t sent_bytes = (size * nmemb);
|
87
|
-
// size_t remaining = pstream->len - pstream->offset;
|
88
|
-
/*
|
89
|
-
|
90
|
-
// amount remaining is less then the buffer to send - can send it all
|
91
|
-
if( remaining < sent_bytes ) {
|
92
|
-
memcpy(ptr, pstream->buffer+pstream->offset, remaining);
|
93
|
-
sent_bytes = remaining;
|
94
|
-
pstream->offset += remaining;
|
95
|
-
}
|
96
|
-
else if( remaining > sent_bytes ) { // sent_bytes <= remaining - send what we can fit in the buffer(ptr)
|
97
|
-
memcpy(ptr, pstream->buffer+pstream->offset, sent_bytes);
|
98
|
-
pstream->offset += sent_bytes;
|
99
|
-
}
|
100
|
-
else { // they're equal
|
101
|
-
memcpy(ptr, pstream->buffer+pstream->offset, --sent_bytes);
|
102
|
-
pstream->offset += sent_bytes;
|
103
|
-
}
|
104
|
-
if (sent_bytes == 0) {
|
105
|
-
free(pstream);
|
106
|
-
}
|
107
|
-
*/
|
108
|
-
|
109
|
-
//printf("sent_bytes: %ld of %ld\n", sent_bytes, remaining);
|
110
|
-
//return sent_bytes;
|
111
85
|
}
|
112
86
|
|
113
87
|
static size_t proc_data_handler(char *stream,
|
@@ -731,6 +705,70 @@ static VALUE ruby_curl_easy_post_body_get(VALUE self) {
|
|
731
705
|
CURB_OBJECT_GETTER(ruby_curl_easy, postdata_buffer);
|
732
706
|
}
|
733
707
|
|
708
|
+
/*
|
709
|
+
* call-seq:
|
710
|
+
* easy.put_data = data => ""
|
711
|
+
*
|
712
|
+
* Points this Curl::Easy instance to data to be uploaded via PUT. This
|
713
|
+
* sets the request to a PUT type request - useful if you want to PUT via
|
714
|
+
* a multi handle.
|
715
|
+
*/
|
716
|
+
static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
|
717
|
+
ruby_curl_easy *rbce;
|
718
|
+
CURL *curl;
|
719
|
+
|
720
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
721
|
+
|
722
|
+
VALUE upload = ruby_curl_upload_new(cCurlUpload);
|
723
|
+
ruby_curl_upload_stream_set(upload,data);
|
724
|
+
|
725
|
+
curl = rbce->curl;
|
726
|
+
rbce->upload = upload; /* keep the upload object alive as long as
|
727
|
+
the easy handle is active or until the upload
|
728
|
+
is complete or terminated... */
|
729
|
+
|
730
|
+
curl_easy_setopt(curl, CURLOPT_NOBODY,0);
|
731
|
+
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
|
732
|
+
curl_easy_setopt(curl, CURLOPT_READFUNCTION, (curl_read_callback)read_data_handler);
|
733
|
+
curl_easy_setopt(curl, CURLOPT_READDATA, rbce);
|
734
|
+
|
735
|
+
/*
|
736
|
+
* we need to set specific headers for the PUT to work... so
|
737
|
+
* convert the internal headers structure to a HASH if one is set
|
738
|
+
*/
|
739
|
+
if (rbce->headers != Qnil) {
|
740
|
+
if (rb_type(rbce->headers) == T_ARRAY || rb_type(rbce->headers) == T_STRING) {
|
741
|
+
rb_raise(rb_eRuntimeError, "Must set headers as a HASH to modify the headers in an PUT request");
|
742
|
+
}
|
743
|
+
}
|
744
|
+
|
745
|
+
if (rb_respond_to(data, rb_intern("read"))) {
|
746
|
+
VALUE stat = rb_funcall(data, rb_intern("stat"), 0);
|
747
|
+
if( stat ) {
|
748
|
+
if( rb_hash_aref(rbce->headers, rb_str_new2("Expect")) == Qnil ) {
|
749
|
+
rb_hash_aset(rbce->headers, rb_str_new2("Expect"), rb_str_new2(""));
|
750
|
+
}
|
751
|
+
VALUE size = rb_funcall(stat, rb_intern("size"), 0);
|
752
|
+
curl_easy_setopt(curl, CURLOPT_INFILESIZE, FIX2INT(size));
|
753
|
+
}
|
754
|
+
else if( rb_hash_aref(rbce->headers, rb_str_new2("Transfer-Encoding")) == Qnil ) {
|
755
|
+
rb_hash_aset(rbce->headers, rb_str_new2("Transfer-Encoding"), rb_str_new2("chunked"));
|
756
|
+
}
|
757
|
+
}
|
758
|
+
else if (rb_respond_to(data, rb_intern("to_s"))) {
|
759
|
+
curl_easy_setopt(curl, CURLOPT_INFILESIZE, RSTRING_LEN(data));
|
760
|
+
if( rb_hash_aref(rbce->headers, rb_str_new2("Expect")) == Qnil ) {
|
761
|
+
rb_hash_aset(rbce->headers, rb_str_new2("Expect"), rb_str_new2(""));
|
762
|
+
}
|
763
|
+
}
|
764
|
+
else {
|
765
|
+
rb_raise(rb_eRuntimeError, "PUT data must respond to read or to_s");
|
766
|
+
}
|
767
|
+
|
768
|
+
// if we made it this far, all should be well.
|
769
|
+
return data;
|
770
|
+
}
|
771
|
+
|
734
772
|
/* ================== IMMED ATTRS ==================*/
|
735
773
|
|
736
774
|
/*
|
@@ -1632,7 +1670,11 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce, VALUE *body_buffer, VALUE *hea
|
|
1632
1670
|
}
|
1633
1671
|
if (rbce->cacert != Qnil) {
|
1634
1672
|
// XXX: This should really be using the output of 'curl-config --ca'
|
1673
|
+
#ifdef HAVE_CURL_CONFIG_CA
|
1674
|
+
curl_easy_setopt(curl, CURLOPT_CAINFO, CURL_CONFIG_CA);
|
1675
|
+
#else
|
1635
1676
|
curl_easy_setopt(curl, CURLOPT_CAINFO, "/usr/local/share/curl/curl-ca-bundle.crt");
|
1677
|
+
#endif
|
1636
1678
|
}
|
1637
1679
|
|
1638
1680
|
/* Set the user-agent string if specified */
|
@@ -1667,6 +1709,8 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce, VALUE *body_buffer, VALUE *hea
|
|
1667
1709
|
*/
|
1668
1710
|
VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce, VALUE bodybuf, VALUE headerbuf, struct curl_slist *headers ) {
|
1669
1711
|
|
1712
|
+
CURL *curl = rbce->curl;
|
1713
|
+
|
1670
1714
|
// Free everything up
|
1671
1715
|
if (headers) {
|
1672
1716
|
curl_slist_free_all(headers);
|
@@ -1701,6 +1745,15 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce, VALUE bodybuf, V
|
|
1701
1745
|
} else {
|
1702
1746
|
rbce->header_data = Qnil;
|
1703
1747
|
}
|
1748
|
+
|
1749
|
+
// clean up a PUT request's curl options.
|
1750
|
+
if (rbce->upload != Qnil) {
|
1751
|
+
rbce->upload = Qnil; // set the upload object to Qnil to let the GC clean up
|
1752
|
+
curl_easy_setopt(curl, CURLOPT_UPLOAD, 0);
|
1753
|
+
curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
|
1754
|
+
curl_easy_setopt(curl, CURLOPT_READDATA, NULL);
|
1755
|
+
curl_easy_setopt(curl, CURLOPT_INFILESIZE, 0);
|
1756
|
+
}
|
1704
1757
|
|
1705
1758
|
return Qnil;
|
1706
1759
|
}
|
@@ -1878,7 +1931,10 @@ static VALUE ruby_curl_easy_perform_head(VALUE self) {
|
|
1878
1931
|
|
1879
1932
|
curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
|
1880
1933
|
|
1881
|
-
|
1934
|
+
VALUE ret = handle_perform(self,rbce);
|
1935
|
+
|
1936
|
+
curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
|
1937
|
+
return ret;
|
1882
1938
|
}
|
1883
1939
|
|
1884
1940
|
/*
|
@@ -1914,61 +1970,14 @@ static VALUE ruby_curl_easy_set_head_option(VALUE self, VALUE onoff) {
|
|
1914
1970
|
static VALUE ruby_curl_easy_perform_put(VALUE self, VALUE data) {
|
1915
1971
|
ruby_curl_easy *rbce;
|
1916
1972
|
CURL *curl;
|
1917
|
-
|
1973
|
+
|
1918
1974
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
1919
|
-
|
1920
|
-
VALUE upload = ruby_curl_upload_new(cCurlUpload);
|
1921
|
-
ruby_curl_upload_stream_set(upload,data);
|
1922
|
-
|
1923
1975
|
curl = rbce->curl;
|
1924
|
-
|
1925
|
-
|
1926
|
-
|
1927
|
-
|
1928
|
-
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
|
1929
|
-
curl_easy_setopt(curl, CURLOPT_READFUNCTION, (curl_read_callback)read_data_handler);
|
1930
|
-
curl_easy_setopt(curl, CURLOPT_READDATA, rbce);
|
1931
|
-
|
1932
|
-
/*
|
1933
|
-
* we need to set specific headers for the PUT to work... so
|
1934
|
-
* convert the internal headers structure to a HASH if one is set
|
1935
|
-
*/
|
1936
|
-
if (rbce->headers != Qnil) {
|
1937
|
-
if (rb_type(rbce->headers) == T_ARRAY || rb_type(rbce->headers) == T_STRING) {
|
1938
|
-
rb_raise(rb_eRuntimeError, "Must set headers as a HASH to modify the headers in an http_put request");
|
1939
|
-
}
|
1940
|
-
}
|
1941
|
-
|
1942
|
-
if (rb_respond_to(data, rb_intern("read"))) {
|
1943
|
-
VALUE stat = rb_funcall(data, rb_intern("stat"), 0);
|
1944
|
-
if( stat ) {
|
1945
|
-
if( rb_hash_aref(rbce->headers, rb_str_new2("Expect")) == Qnil ) {
|
1946
|
-
rb_hash_aset(rbce->headers, rb_str_new2("Expect"), rb_str_new2(""));
|
1947
|
-
}
|
1948
|
-
VALUE size = rb_funcall(stat, rb_intern("size"), 0);
|
1949
|
-
curl_easy_setopt(curl, CURLOPT_INFILESIZE, FIX2INT(size));
|
1950
|
-
}
|
1951
|
-
else if( rb_hash_aref(rbce->headers, rb_str_new2("Transfer-Encoding")) == Qnil ) {
|
1952
|
-
rb_hash_aset(rbce->headers, rb_str_new2("Transfer-Encoding"), rb_str_new2("chunked"));
|
1953
|
-
}
|
1954
|
-
}
|
1955
|
-
else if (rb_respond_to(data, rb_intern("to_s"))) {
|
1956
|
-
curl_easy_setopt(curl, CURLOPT_INFILESIZE, RSTRING_LEN(data));
|
1957
|
-
if( rb_hash_aref(rbce->headers, rb_str_new2("Expect")) == Qnil ) {
|
1958
|
-
rb_hash_aset(rbce->headers, rb_str_new2("Expect"), rb_str_new2(""));
|
1959
|
-
}
|
1960
|
-
}
|
1961
|
-
else {
|
1962
|
-
rb_raise(rb_eRuntimeError, "PUT data must respond to read or to_s");
|
1963
|
-
}
|
1964
|
-
|
1976
|
+
|
1977
|
+
ruby_curl_easy_put_data_set(self, data);
|
1978
|
+
|
1965
1979
|
VALUE ret = handle_perform(self, rbce);
|
1966
|
-
|
1967
|
-
curl_easy_setopt(curl, CURLOPT_UPLOAD, 0);
|
1968
|
-
curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
|
1969
|
-
curl_easy_setopt(curl, CURLOPT_READDATA, NULL);
|
1970
|
-
curl_easy_setopt(curl, CURLOPT_INFILESIZE, 0);
|
1971
|
-
|
1980
|
+
|
1972
1981
|
return ret;
|
1973
1982
|
}
|
1974
1983
|
|
@@ -2531,6 +2540,21 @@ static VALUE ruby_curl_easy_ftp_entry_path_get(VALUE self) {
|
|
2531
2540
|
#endif
|
2532
2541
|
}
|
2533
2542
|
|
2543
|
+
/*
|
2544
|
+
* call-seq:
|
2545
|
+
* easy.inspect => "#<Curl::Easy http://google.com/>"
|
2546
|
+
*/
|
2547
|
+
static VALUE ruby_curl_easy_inspect(VALUE self) {
|
2548
|
+
char buf[64];
|
2549
|
+
ruby_curl_easy *rbce;
|
2550
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
2551
|
+
// "#<Net::HTTP http://www.google.com/:80 open=false>"
|
2552
|
+
snprintf(buf,sizeof(buf),"#<Curl::Easy %s", RSTRING_PTR(rbce->url));
|
2553
|
+
size_t r = strlen(buf);
|
2554
|
+
buf[r-1] = '>';
|
2555
|
+
return rb_str_new(buf,r);
|
2556
|
+
}
|
2557
|
+
|
2534
2558
|
|
2535
2559
|
/* ================== ESCAPING FUNCS ==============*/
|
2536
2560
|
|
@@ -2676,6 +2700,7 @@ static VALUE ruby_curl_easy_class_perform_head(int argc, VALUE *argv, VALUE klas
|
|
2676
2700
|
}
|
2677
2701
|
|
2678
2702
|
ruby_curl_easy_perform_head(c);
|
2703
|
+
|
2679
2704
|
return c;
|
2680
2705
|
}
|
2681
2706
|
|
@@ -2764,6 +2789,7 @@ void init_curb_easy() {
|
|
2764
2789
|
rb_define_method(cCurlEasy, "useragent", ruby_curl_easy_useragent_get, 0);
|
2765
2790
|
rb_define_method(cCurlEasy, "post_body=", ruby_curl_easy_post_body_set, 1);
|
2766
2791
|
rb_define_method(cCurlEasy, "post_body", ruby_curl_easy_post_body_get, 0);
|
2792
|
+
rb_define_method(cCurlEasy, "put_data=", ruby_curl_easy_put_data_set, 1);
|
2767
2793
|
|
2768
2794
|
rb_define_method(cCurlEasy, "local_port=", ruby_curl_easy_local_port_set, 1);
|
2769
2795
|
rb_define_method(cCurlEasy, "local_port", ruby_curl_easy_local_port_get, 0);
|
@@ -2855,6 +2881,7 @@ void init_curb_easy() {
|
|
2855
2881
|
rb_define_method(cCurlEasy, "os_errno", ruby_curl_easy_os_errno_get, 0);
|
2856
2882
|
rb_define_method(cCurlEasy, "num_connects", ruby_curl_easy_num_connects_get, 0);
|
2857
2883
|
rb_define_method(cCurlEasy, "ftp_entry_path", ruby_curl_easy_ftp_entry_path_get, 0);
|
2884
|
+
rb_define_method(cCurlEasy, "inspect", ruby_curl_easy_inspect, 0);
|
2858
2885
|
|
2859
2886
|
/* Curl utils */
|
2860
2887
|
rb_define_method(cCurlEasy, "escape", ruby_curl_easy_escape, 1);
|
data/ext/curb_multi.c
CHANGED
@@ -296,55 +296,57 @@ static VALUE ruby_curl_multi_cancel(VALUE self) {
|
|
296
296
|
return self;
|
297
297
|
}
|
298
298
|
|
299
|
-
static void
|
300
|
-
|
301
|
-
|
302
|
-
CURLcode ecode;
|
303
|
-
CURL *easy_handle;
|
299
|
+
static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int result) {
|
300
|
+
|
301
|
+
long response_code = -1;
|
304
302
|
ruby_curl_easy *rbce = NULL;
|
305
303
|
|
306
|
-
|
307
|
-
while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
|
304
|
+
CURLcode ecode = curl_easy_getinfo(easy_handle, CURLINFO_PRIVATE, (char**)&rbce);
|
308
305
|
|
309
|
-
|
310
|
-
|
311
|
-
|
306
|
+
if (ecode != 0) {
|
307
|
+
raise_curl_easy_error_exception(ecode);
|
308
|
+
}
|
312
309
|
|
313
|
-
|
314
|
-
result = msg->data.result;
|
315
|
-
if (easy_handle) {
|
316
|
-
ecode = curl_easy_getinfo(easy_handle, CURLINFO_PRIVATE, (char**)&rbce);
|
317
|
-
if (ecode != 0) {
|
318
|
-
raise_curl_easy_error_exception(ecode);
|
319
|
-
}
|
320
|
-
rbce->last_result = result; // save the last easy result code
|
321
|
-
ruby_curl_multi_remove( self, rbce->self );
|
310
|
+
rbce->last_result = result; /* save the last easy result code */
|
322
311
|
|
323
|
-
|
324
|
-
rb_funcall( rbce->complete_proc, idCall, 1, rbce->self );
|
325
|
-
}
|
312
|
+
ruby_curl_multi_remove( self, rbce->self );
|
326
313
|
|
327
|
-
|
328
|
-
|
314
|
+
if (rbce->complete_proc != Qnil) {
|
315
|
+
rb_funcall( rbce->complete_proc, idCall, 1, rbce->self );
|
316
|
+
}
|
329
317
|
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
else if (rbce->success_proc != Qnil &&
|
336
|
-
((response_code >= 200 && response_code < 300) || response_code == 0)) {
|
337
|
-
/* NOTE: we allow response_code == 0, in the case the file is being read from disk */
|
338
|
-
rb_funcall( rbce->success_proc, idCall, 1, rbce->self );
|
339
|
-
}
|
340
|
-
else if (rbce->failure_proc != Qnil &&
|
341
|
-
(response_code >= 300 && response_code <= 999)) {
|
342
|
-
rb_funcall( rbce->failure_proc, idCall, 2, rbce->self, rb_curl_easy_error(result) );
|
343
|
-
}
|
344
|
-
rbce->self = Qnil;
|
318
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_RESPONSE_CODE, &response_code);
|
319
|
+
|
320
|
+
if (result != 0) {
|
321
|
+
if (rbce->failure_proc != Qnil) {
|
322
|
+
rb_funcall( rbce->failure_proc, idCall, 2, rbce->self, rb_curl_easy_error(result) );
|
345
323
|
}
|
346
|
-
|
347
|
-
|
324
|
+
}
|
325
|
+
else if (rbce->success_proc != Qnil &&
|
326
|
+
((response_code >= 200 && response_code < 300) || response_code == 0)) {
|
327
|
+
/* NOTE: we allow response_code == 0, in the case of non http requests e.g. reading from disk */
|
328
|
+
rb_funcall( rbce->success_proc, idCall, 1, rbce->self );
|
329
|
+
}
|
330
|
+
else if (rbce->failure_proc != Qnil &&
|
331
|
+
(response_code >= 300 && response_code <= 999)) {
|
332
|
+
rb_funcall( rbce->failure_proc, idCall, 2, rbce->self, rb_curl_easy_error(result) );
|
333
|
+
}
|
334
|
+
rbce->self = Qnil;
|
335
|
+
}
|
336
|
+
|
337
|
+
static void rb_curl_multi_read_info(VALUE self, CURLM *multi_handle) {
|
338
|
+
int msgs_left, result;
|
339
|
+
CURLMsg *msg;
|
340
|
+
CURL *easy_handle;
|
341
|
+
|
342
|
+
/* check for finished easy handles and remove from the multi handle */
|
343
|
+
while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
|
344
|
+
if (msg->msg == CURLMSG_DONE) {
|
345
|
+
easy_handle = msg->easy_handle;
|
346
|
+
result = msg->data.result;
|
347
|
+
if (easy_handle) {
|
348
|
+
rb_curl_mutli_handle_complete(self, easy_handle, result);
|
349
|
+
}
|
348
350
|
}
|
349
351
|
}
|
350
352
|
}
|
@@ -385,7 +387,7 @@ VALUE ruby_curl_multi_perform(VALUE self) {
|
|
385
387
|
int maxfd, rc;
|
386
388
|
fd_set fdread, fdwrite, fdexcep;
|
387
389
|
|
388
|
-
long
|
390
|
+
long timeout_milliseconds;
|
389
391
|
struct timeval tv = {0, 0};
|
390
392
|
|
391
393
|
Data_Get_Struct(self, ruby_curl_multi, rbcm);
|
@@ -406,37 +408,46 @@ VALUE ruby_curl_multi_perform(VALUE self) {
|
|
406
408
|
|
407
409
|
#ifdef HAVE_CURL_MULTI_TIMEOUT
|
408
410
|
/* get the curl suggested time out */
|
409
|
-
mcode = curl_multi_timeout(rbcm->handle, &
|
411
|
+
mcode = curl_multi_timeout(rbcm->handle, &timeout_milliseconds);
|
410
412
|
if (mcode != CURLM_OK) {
|
411
413
|
raise_curl_multi_error_exception(mcode);
|
412
414
|
}
|
413
415
|
#else
|
414
416
|
/* libcurl doesn't have a timeout method defined... make a wild guess */
|
415
|
-
|
417
|
+
timeout_milliseconds = -1;
|
416
418
|
#endif
|
419
|
+
//printf("libcurl says wait: %ld ms or %ld s\n", timeout_milliseconds, timeout_milliseconds/1000);
|
417
420
|
|
418
|
-
if (
|
421
|
+
if (timeout_milliseconds == 0) { /* no delay */
|
419
422
|
rb_curl_multi_run( self, rbcm->handle, &(rbcm->running) );
|
420
423
|
continue;
|
421
424
|
}
|
422
|
-
else if
|
423
|
-
|
425
|
+
else if(timeout_milliseconds < 0) {
|
426
|
+
timeout_milliseconds = 500; /* wait half a second, libcurl doesn't know how long to wait */
|
424
427
|
}
|
425
|
-
|
426
|
-
if
|
427
|
-
|
428
|
+
#ifdef __APPLE_CC__
|
429
|
+
if(timeout_milliseconds > 1000) {
|
430
|
+
timeout_milliseconds = 1000; /* apple libcurl sometimes reports huge timeouts... let's cap it */
|
428
431
|
}
|
432
|
+
#endif
|
429
433
|
|
430
|
-
tv.tv_sec =
|
431
|
-
tv.tv_usec = (
|
434
|
+
tv.tv_sec = timeout_milliseconds / 1000; // convert milliseconds to seconds
|
435
|
+
tv.tv_usec = (timeout_milliseconds % 1000) * 1000; // get the remainder of milliseconds and convert to micro seconds
|
432
436
|
|
433
437
|
rc = rb_thread_select(maxfd+1, &fdread, &fdwrite, &fdexcep, &tv);
|
434
|
-
|
438
|
+
switch(rc) {
|
439
|
+
case -1:
|
435
440
|
rb_raise(rb_eRuntimeError, "select(): %s", strerror(errno));
|
441
|
+
break;
|
442
|
+
case 0:
|
443
|
+
if (rb_block_given_p()) {
|
444
|
+
rb_yield(self);
|
445
|
+
}
|
446
|
+
default:
|
447
|
+
rb_curl_multi_run( self, rbcm->handle, &(rbcm->running) );
|
448
|
+
break;
|
436
449
|
}
|
437
450
|
|
438
|
-
rb_curl_multi_run( self, rbcm->handle, &(rbcm->running) );
|
439
|
-
|
440
451
|
}
|
441
452
|
|
442
453
|
return Qtrue;
|
data/ext/curb_postfield.c
CHANGED
data/ext/extconf.rb
CHANGED
@@ -5,6 +5,9 @@ dir_config('curl')
|
|
5
5
|
if find_executable('curl-config')
|
6
6
|
$CFLAGS << " #{`curl-config --cflags`.strip}"
|
7
7
|
$LIBS << " #{`curl-config --libs`.strip}"
|
8
|
+
ca_bundle_path=`curl-config --ca`.strip
|
9
|
+
$defs.push( %{-D HAVE_CURL_CONFIG_CA} )
|
10
|
+
$defs.push( %{-D CURL_CONFIG_CA='#{ca_bundle_path.inspect}'} )
|
8
11
|
elsif !have_library('curl') or !have_header('curl/curl.h')
|
9
12
|
fail <<-EOM
|
10
13
|
Can't find libcurl or curl/curl.h
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'helper')
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
2
2
|
require 'webrick'
|
3
3
|
class ::WEBrick::HTTPServer ; def access_log(config, req, res) ; end ; end
|
4
4
|
class ::WEBrick::BasicLog ; def log(level, data) ; end ; end
|
@@ -23,7 +23,7 @@
|
|
23
23
|
# instance httppost. This bug is intermittent, but results in an
|
24
24
|
# exception from the first post when it occurs.
|
25
25
|
#
|
26
|
-
require File.join(File.dirname(__FILE__), 'helper')
|
26
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
27
27
|
|
28
28
|
class BugTestInstancePostDiffersFromClassPost < Test::Unit::TestCase
|
29
29
|
def test_bug
|
data/tests/bug_multi_segfault.rb
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
# irb: multi = Curl::Multi.new
|
4
4
|
# irb: exit
|
5
5
|
# <main>:47140: [BUG] Bus Error
|
6
|
-
$:.unshift File.join(File.dirname(__FILE__),'..','ext')
|
7
|
-
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
6
|
+
$:.unshift File.expand_path(File.join(File.dirname(__FILE__),'..','ext'))
|
7
|
+
$:.unshift File.expand_path(File.join(File.dirname(__FILE__),'..','lib'))
|
8
8
|
require 'curb'
|
9
9
|
multi = Curl::Multi.new
|
10
10
|
exit
|
data/tests/helper.rb
CHANGED
@@ -72,7 +72,15 @@ class TestServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def do_POST(req,res)
|
75
|
-
|
75
|
+
if req.body
|
76
|
+
params = {}
|
77
|
+
req.body.split('&').map{|s| k,v=s.split('='); params[k] = v }
|
78
|
+
end
|
79
|
+
if params and params['s'] == '500'
|
80
|
+
res.status = 500
|
81
|
+
else
|
82
|
+
respond_with("POST\n#{req.body}",req,res)
|
83
|
+
end
|
76
84
|
end
|
77
85
|
|
78
86
|
def do_PUT(req,res)
|
@@ -21,8 +21,8 @@
|
|
21
21
|
# Aborted
|
22
22
|
# ------------------------------------------------------------------
|
23
23
|
#
|
24
|
-
$:.unshift(File.join(File.dirname(__FILE__), '..', 'ext'))
|
25
|
-
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
24
|
+
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'ext')))
|
25
|
+
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
|
26
26
|
require 'curb'
|
27
27
|
require 'uri'
|
28
28
|
|
data/tests/tc_curl_download.rb
CHANGED
data/tests/tc_curl_easy.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'helper')
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
2
2
|
|
3
3
|
class TestCurbCurlEasy < Test::Unit::TestCase
|
4
4
|
def test_class_perform_01
|
@@ -555,6 +555,16 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
555
555
|
assert_match /^PUT/, curl.body_str
|
556
556
|
assert_match /message$/, curl.body_str
|
557
557
|
assert_match /application\/json/, curl.header_str
|
558
|
+
end
|
559
|
+
|
560
|
+
def test_put_data
|
561
|
+
curl = Curl::Easy.new(TestServlet.url)
|
562
|
+
curl.put_data = 'message'
|
563
|
+
|
564
|
+
curl.perform
|
565
|
+
|
566
|
+
assert_match /^PUT/, curl.body_str
|
567
|
+
assert_match /message$/, curl.body_str
|
558
568
|
end
|
559
569
|
|
560
570
|
def test_put_remote_file
|
data/tests/tc_curl_multi.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'helper')
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
2
2
|
|
3
3
|
class TestCurbCurlMulti < Test::Unit::TestCase
|
4
4
|
def teardown
|
@@ -54,6 +54,8 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
54
54
|
|
55
55
|
end
|
56
56
|
|
57
|
+
# NOTE: if this test runs slowly on Mac OSX, it is probably due to the use of a port install curl+ssl+ares install
|
58
|
+
# on my MacBook, this causes curl_easy_init to take nearly 0.01 seconds / * 100 below is 1 second too many!
|
57
59
|
def test_n_requests
|
58
60
|
n = 100
|
59
61
|
m = Curl::Multi.new
|
@@ -220,6 +222,7 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
220
222
|
m = nil
|
221
223
|
end
|
222
224
|
|
225
|
+
# This tests whether, ruby's GC will trash an out of scope easy handle
|
223
226
|
class TestForScope
|
224
227
|
attr_reader :buf
|
225
228
|
|
@@ -299,6 +302,7 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
299
302
|
Dir[File.dirname(__FILE__) + "/../ext/*.c"].each do|path|
|
300
303
|
urls << root_uri + File.basename(path)
|
301
304
|
end
|
305
|
+
urls = urls[0..(urls.size/2)] # keep it fast, webrick...
|
302
306
|
Curl::Multi.get(urls, {:follow_location => true}, {:pipeline => true}) do|curl|
|
303
307
|
assert_equal 200, curl.response_code
|
304
308
|
end
|
@@ -321,6 +325,26 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
321
325
|
end
|
322
326
|
end
|
323
327
|
|
328
|
+
def test_mutli_recieves_500
|
329
|
+
m = Curl::Multi.new
|
330
|
+
e = Curl::Easy.new("http://127.0.0.1:9129/methods")
|
331
|
+
failure = false
|
332
|
+
e.post_body = "hello=world&s=500"
|
333
|
+
e.on_failure{|c,r| failure = true }
|
334
|
+
e.on_success{|c| failure = false }
|
335
|
+
m.add(e)
|
336
|
+
m.perform
|
337
|
+
assert failure
|
338
|
+
e2 = Curl::Easy.new(TestServlet.url)
|
339
|
+
e2.post_body = "hello=world"
|
340
|
+
e2.on_failure{|c,r| failure = true }
|
341
|
+
m.add(e2)
|
342
|
+
m.perform
|
343
|
+
failure = false
|
344
|
+
assert !failure
|
345
|
+
assert_equal "POST\nhello=world", e2.body_str
|
346
|
+
end
|
347
|
+
|
324
348
|
include TestServerMethods
|
325
349
|
|
326
350
|
def setup
|
data/tests/tc_curl_postfield.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: taf2-curb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ross Bamford
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-07-
|
13
|
+
date: 2009-07-26 00:00:00 -07:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|