taf2-curb 0.4.8.0 → 0.4.9.0
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/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
|
|