curb 0.8.4 → 0.9.11
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.
- checksums.yaml +7 -0
- data/README.markdown +277 -0
- data/Rakefile +29 -18
- data/ext/banned.h +32 -0
- data/ext/curb.c +161 -46
- data/ext/curb.h +14 -10
- data/ext/curb_easy.c +612 -97
- data/ext/curb_easy.h +6 -0
- data/ext/curb_errors.c +113 -16
- data/ext/curb_errors.h +8 -5
- data/ext/curb_macros.h +7 -7
- data/ext/curb_multi.c +175 -167
- data/ext/curb_multi.h +0 -1
- data/ext/curb_upload.c +2 -2
- data/ext/extconf.rb +52 -17
- data/lib/curb.rb +1 -0
- data/lib/curl/easy.rb +79 -59
- data/lib/curl/multi.rb +59 -20
- data/lib/curl.rb +15 -9
- data/tests/bug_crash_on_progress.rb +41 -1
- data/tests/bug_issue102.rb +1 -1
- data/tests/bug_issue277.rb +32 -0
- data/tests/helper.rb +102 -13
- data/tests/tc_curl.rb +31 -1
- data/tests/tc_curl_download.rb +4 -4
- data/tests/tc_curl_easy.rb +197 -42
- data/tests/tc_curl_easy_resolve.rb +16 -0
- data/tests/tc_curl_maxfilesize.rb +12 -0
- data/tests/tc_curl_multi.rb +82 -16
- data/tests/tc_curl_postfield.rb +29 -29
- data/tests/timeout.rb +10 -2
- metadata +51 -52
- data/README +0 -194
data/ext/curb_easy.c
CHANGED
|
@@ -25,12 +25,18 @@ static VALUE rbstrAmp;
|
|
|
25
25
|
|
|
26
26
|
VALUE cCurlEasy;
|
|
27
27
|
|
|
28
|
+
// for Ruby 1.8
|
|
29
|
+
#ifndef HAVE_RB_IO_STDIO_FILE
|
|
30
|
+
static FILE * rb_io_stdio_file(rb_io_t *fptr) {
|
|
31
|
+
return fptr->f;
|
|
32
|
+
}
|
|
33
|
+
#endif
|
|
28
34
|
|
|
29
35
|
/* ================== CURL HANDLER FUNCS ==============*/
|
|
30
36
|
|
|
31
37
|
static VALUE callback_exception(VALUE unused) {
|
|
32
38
|
return Qfalse;
|
|
33
|
-
}
|
|
39
|
+
}
|
|
34
40
|
|
|
35
41
|
/* These handle both body and header data */
|
|
36
42
|
static size_t default_data_handler(char *stream,
|
|
@@ -96,6 +102,25 @@ static size_t read_data_handler(void *ptr,
|
|
|
96
102
|
}
|
|
97
103
|
}
|
|
98
104
|
|
|
105
|
+
int seek_data_handler(ruby_curl_easy *rbce,
|
|
106
|
+
curl_off_t offset,
|
|
107
|
+
int origin) {
|
|
108
|
+
|
|
109
|
+
VALUE upload = rb_easy_get("upload");
|
|
110
|
+
VALUE stream = ruby_curl_upload_stream_get(upload);
|
|
111
|
+
|
|
112
|
+
if (rb_respond_to(stream, rb_intern("seek"))) {
|
|
113
|
+
rb_funcall(stream, rb_intern("seek"), 2, SEEK_SET, offset);
|
|
114
|
+
} else {
|
|
115
|
+
ruby_curl_upload *rbcu;
|
|
116
|
+
Data_Get_Struct(upload, ruby_curl_upload, rbcu);
|
|
117
|
+
// This OK because curl only uses SEEK_SET as per the documentation
|
|
118
|
+
rbcu->offset = offset;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return 0;
|
|
122
|
+
}
|
|
123
|
+
|
|
99
124
|
static size_t proc_data_handler(char *stream,
|
|
100
125
|
size_t size,
|
|
101
126
|
size_t nmemb,
|
|
@@ -173,7 +198,7 @@ static int proc_progress_handler(VALUE proc,
|
|
|
173
198
|
|
|
174
199
|
static VALUE call_debug_handler(VALUE ary) {
|
|
175
200
|
return rb_funcall(rb_ary_entry(ary, 0), idCall, 2,
|
|
176
|
-
rb_ary_entry(ary, 1), //
|
|
201
|
+
rb_ary_entry(ary, 1), // INT2NUM(type),
|
|
177
202
|
rb_ary_entry(ary, 2)); // rb_str_new(data, data_len)
|
|
178
203
|
}
|
|
179
204
|
static int proc_debug_handler(CURL *curl,
|
|
@@ -183,13 +208,13 @@ static int proc_debug_handler(CURL *curl,
|
|
|
183
208
|
VALUE proc) {
|
|
184
209
|
VALUE callargs = rb_ary_new2(3);
|
|
185
210
|
rb_ary_store(callargs, 0, proc);
|
|
186
|
-
rb_ary_store(callargs, 1,
|
|
211
|
+
rb_ary_store(callargs, 1, INT2NUM(type));
|
|
187
212
|
rb_ary_store(callargs, 2, rb_str_new(data, data_len));
|
|
188
213
|
rb_rescue(call_debug_handler, callargs, callback_exception, Qnil);
|
|
189
214
|
/* no way to indicate to libcurl that we should break out given an exception in the on_debug handler...
|
|
190
215
|
* this means exceptions will be swallowed
|
|
191
216
|
*/
|
|
192
|
-
//rb_funcall(proc, idCall, 2,
|
|
217
|
+
//rb_funcall(proc, idCall, 2, INT2NUM(type), rb_str_new(data, data_len));
|
|
193
218
|
return 0;
|
|
194
219
|
}
|
|
195
220
|
|
|
@@ -204,12 +229,31 @@ static void ruby_curl_easy_free(ruby_curl_easy *rbce) {
|
|
|
204
229
|
curl_slist_free_all(rbce->curl_headers);
|
|
205
230
|
}
|
|
206
231
|
|
|
232
|
+
if (rbce->curl_proxy_headers) {
|
|
233
|
+
curl_slist_free_all(rbce->curl_proxy_headers);
|
|
234
|
+
}
|
|
235
|
+
|
|
207
236
|
if (rbce->curl_ftp_commands) {
|
|
208
237
|
curl_slist_free_all(rbce->curl_ftp_commands);
|
|
209
238
|
}
|
|
210
239
|
|
|
240
|
+
if (rbce->curl_resolve) {
|
|
241
|
+
curl_slist_free_all(rbce->curl_resolve);
|
|
242
|
+
}
|
|
243
|
+
|
|
211
244
|
if (rbce->curl) {
|
|
245
|
+
/* disable any progress or debug events */
|
|
246
|
+
curl_easy_setopt(rbce->curl, CURLOPT_WRITEFUNCTION, NULL);
|
|
247
|
+
curl_easy_setopt(rbce->curl, CURLOPT_WRITEDATA, NULL);
|
|
248
|
+
curl_easy_setopt(rbce->curl, CURLOPT_HEADERFUNCTION, NULL);
|
|
249
|
+
curl_easy_setopt(rbce->curl, CURLOPT_HEADERDATA, NULL);
|
|
250
|
+
curl_easy_setopt(rbce->curl, CURLOPT_DEBUGFUNCTION, NULL);
|
|
251
|
+
curl_easy_setopt(rbce->curl, CURLOPT_DEBUGDATA, NULL);
|
|
252
|
+
curl_easy_setopt(rbce->curl, CURLOPT_VERBOSE, 0);
|
|
253
|
+
curl_easy_setopt(rbce->curl, CURLOPT_PROGRESSFUNCTION, NULL);
|
|
254
|
+
curl_easy_setopt(rbce->curl, CURLOPT_NOPROGRESS, 1);
|
|
212
255
|
curl_easy_cleanup(rbce->curl);
|
|
256
|
+
rbce->curl = NULL;
|
|
213
257
|
}
|
|
214
258
|
}
|
|
215
259
|
|
|
@@ -225,7 +269,9 @@ static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
|
|
225
269
|
rbce->opts = rb_hash_new();
|
|
226
270
|
|
|
227
271
|
rbce->curl_headers = NULL;
|
|
272
|
+
rbce->curl_proxy_headers = NULL;
|
|
228
273
|
rbce->curl_ftp_commands = NULL;
|
|
274
|
+
rbce->curl_resolve = NULL;
|
|
229
275
|
|
|
230
276
|
/* various-typed opts */
|
|
231
277
|
rbce->local_port = 0;
|
|
@@ -236,11 +282,15 @@ static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
|
|
236
282
|
rbce->proxy_auth_types = 0;
|
|
237
283
|
rbce->max_redirs = -1;
|
|
238
284
|
rbce->timeout = 0;
|
|
285
|
+
rbce->timeout_ms = 0;
|
|
239
286
|
rbce->connect_timeout = 0;
|
|
287
|
+
rbce->connect_timeout_ms = 0;
|
|
240
288
|
rbce->dns_cache_timeout = 60;
|
|
241
289
|
rbce->ftp_response_timeout = 0;
|
|
242
290
|
rbce->low_speed_limit = 0;
|
|
243
291
|
rbce->low_speed_time = 0;
|
|
292
|
+
rbce->max_send_speed_large = 0;
|
|
293
|
+
rbce->max_recv_speed_large = 0;
|
|
244
294
|
rbce->ssl_version = -1;
|
|
245
295
|
rbce->use_ssl = -1;
|
|
246
296
|
rbce->ftp_filemethod = -1;
|
|
@@ -262,25 +312,37 @@ static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
|
|
262
312
|
rbce->callback_active = 0;
|
|
263
313
|
}
|
|
264
314
|
|
|
315
|
+
/*
|
|
316
|
+
* Allocate space for a Curl::Easy instance.
|
|
317
|
+
*/
|
|
318
|
+
static VALUE ruby_curl_easy_allocate(VALUE klass) {
|
|
319
|
+
ruby_curl_easy *rbce;
|
|
320
|
+
rbce = ALLOC(ruby_curl_easy);
|
|
321
|
+
rbce->curl = NULL;
|
|
322
|
+
rbce->opts = Qnil;
|
|
323
|
+
rbce->multi = Qnil;
|
|
324
|
+
ruby_curl_easy_zero(rbce);
|
|
325
|
+
return Data_Wrap_Struct(klass, curl_easy_mark, curl_easy_free, rbce);
|
|
326
|
+
}
|
|
327
|
+
|
|
265
328
|
/*
|
|
266
329
|
* call-seq:
|
|
267
330
|
* Curl::Easy.new => #<Curl::Easy...>
|
|
268
331
|
* Curl::Easy.new(url = nil) => #<Curl::Easy...>
|
|
269
332
|
* Curl::Easy.new(url = nil) { |self| ... } => #<Curl::Easy...>
|
|
270
333
|
*
|
|
271
|
-
*
|
|
334
|
+
* Initialize a new Curl::Easy instance, optionally supplying the URL.
|
|
272
335
|
* The block form allows further configuration to be supplied before
|
|
273
336
|
* the instance is returned.
|
|
274
337
|
*/
|
|
275
|
-
static VALUE
|
|
338
|
+
static VALUE ruby_curl_easy_initialize(int argc, VALUE *argv, VALUE self) {
|
|
276
339
|
CURLcode ecode;
|
|
277
340
|
VALUE url, blk;
|
|
278
|
-
VALUE new_curl;
|
|
279
341
|
ruby_curl_easy *rbce;
|
|
280
342
|
|
|
281
343
|
rb_scan_args(argc, argv, "01&", &url, &blk);
|
|
282
344
|
|
|
283
|
-
|
|
345
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
284
346
|
|
|
285
347
|
/* handler */
|
|
286
348
|
rbce->curl = curl_easy_init();
|
|
@@ -288,8 +350,6 @@ static VALUE ruby_curl_easy_new(int argc, VALUE *argv, VALUE klass) {
|
|
|
288
350
|
rb_raise(eCurlErrFailedInit, "Failed to initialize easy handle");
|
|
289
351
|
}
|
|
290
352
|
|
|
291
|
-
new_curl = Data_Wrap_Struct(klass, curl_easy_mark, curl_easy_free, rbce);
|
|
292
|
-
|
|
293
353
|
rbce->multi = Qnil;
|
|
294
354
|
rbce->opts = Qnil;
|
|
295
355
|
|
|
@@ -297,17 +357,18 @@ static VALUE ruby_curl_easy_new(int argc, VALUE *argv, VALUE klass) {
|
|
|
297
357
|
|
|
298
358
|
rb_easy_set("url", url);
|
|
299
359
|
|
|
300
|
-
|
|
301
|
-
|
|
360
|
+
|
|
361
|
+
/* set the pointer to the curl handle */
|
|
362
|
+
ecode = curl_easy_setopt(rbce->curl, CURLOPT_PRIVATE, (void*)self);
|
|
302
363
|
if (ecode != CURLE_OK) {
|
|
303
364
|
raise_curl_easy_error_exception(ecode);
|
|
304
365
|
}
|
|
305
366
|
|
|
306
367
|
if (blk != Qnil) {
|
|
307
|
-
rb_funcall(blk, idCall, 1,
|
|
368
|
+
rb_funcall(blk, idCall, 1, self);
|
|
308
369
|
}
|
|
309
370
|
|
|
310
|
-
return
|
|
371
|
+
return self;
|
|
311
372
|
}
|
|
312
373
|
|
|
313
374
|
/*
|
|
@@ -327,7 +388,9 @@ static VALUE ruby_curl_easy_clone(VALUE self) {
|
|
|
327
388
|
memcpy(newrbce, rbce, sizeof(ruby_curl_easy));
|
|
328
389
|
newrbce->curl = curl_easy_duphandle(rbce->curl);
|
|
329
390
|
newrbce->curl_headers = NULL;
|
|
391
|
+
newrbce->curl_proxy_headers = NULL;
|
|
330
392
|
newrbce->curl_ftp_commands = NULL;
|
|
393
|
+
newrbce->curl_resolve = NULL;
|
|
331
394
|
|
|
332
395
|
return Data_Wrap_Struct(cCurlEasy, curl_easy_mark, curl_easy_free, newrbce);
|
|
333
396
|
}
|
|
@@ -337,7 +400,7 @@ static VALUE ruby_curl_easy_clone(VALUE self) {
|
|
|
337
400
|
* easy.close => nil
|
|
338
401
|
*
|
|
339
402
|
* Close the Curl::Easy instance. Any open connections are closed
|
|
340
|
-
* The easy handle is reinitialized. If a previous multi handle was
|
|
403
|
+
* The easy handle is reinitialized. If a previous multi handle was
|
|
341
404
|
* open it is set to nil and will be cleared after a GC.
|
|
342
405
|
*/
|
|
343
406
|
static VALUE ruby_curl_easy_close(VALUE self) {
|
|
@@ -410,6 +473,12 @@ static VALUE ruby_curl_easy_reset(VALUE self) {
|
|
|
410
473
|
rbce->curl_headers = NULL;
|
|
411
474
|
}
|
|
412
475
|
|
|
476
|
+
/* Free everything up */
|
|
477
|
+
if (rbce->curl_proxy_headers) {
|
|
478
|
+
curl_slist_free_all(rbce->curl_proxy_headers);
|
|
479
|
+
rbce->curl_proxy_headers = NULL;
|
|
480
|
+
}
|
|
481
|
+
|
|
413
482
|
return opts_dup;
|
|
414
483
|
}
|
|
415
484
|
|
|
@@ -462,6 +531,10 @@ static VALUE ruby_curl_easy_headers_set(VALUE self, VALUE headers) {
|
|
|
462
531
|
CURB_OBJECT_HSETTER(ruby_curl_easy, headers);
|
|
463
532
|
}
|
|
464
533
|
|
|
534
|
+
static VALUE ruby_curl_easy_proxy_headers_set(VALUE self, VALUE proxy_headers) {
|
|
535
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, proxy_headers);
|
|
536
|
+
}
|
|
537
|
+
|
|
465
538
|
/*
|
|
466
539
|
* call-seq:
|
|
467
540
|
* easy.headers => Hash, Array or Str
|
|
@@ -472,11 +545,46 @@ static VALUE ruby_curl_easy_headers_get(VALUE self) {
|
|
|
472
545
|
ruby_curl_easy *rbce;
|
|
473
546
|
VALUE headers;
|
|
474
547
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
475
|
-
headers = rb_easy_get("headers");//rb_hash_aref(rbce->opts, rb_intern("headers"));
|
|
548
|
+
headers = rb_easy_get("headers");//rb_hash_aref(rbce->opts, rb_intern("headers"));
|
|
476
549
|
if (headers == Qnil) { headers = rb_easy_set("headers", rb_hash_new()); }
|
|
477
550
|
return headers;
|
|
478
551
|
}
|
|
479
552
|
|
|
553
|
+
/*
|
|
554
|
+
* call-seq:
|
|
555
|
+
* easy.proxy_headers = "Header: val" => "Header: val"
|
|
556
|
+
* easy.proxy_headers = {"Header" => "val" ..., "Header" => "val"} => {"Header: val", ...}
|
|
557
|
+
* easy.proxy_headers = ["Header: val" ..., "Header: val"] => ["Header: val", ...]
|
|
558
|
+
*
|
|
559
|
+
*
|
|
560
|
+
* For example to set a standard or custom header:
|
|
561
|
+
*
|
|
562
|
+
* easy.proxy_headers["MyHeader"] = "myval"
|
|
563
|
+
*
|
|
564
|
+
* To remove a standard header (this is useful when removing libcurls default
|
|
565
|
+
* 'Expect: 100-Continue' header when using HTTP form posts):
|
|
566
|
+
*
|
|
567
|
+
* easy.proxy_headers["Expect"] = ''
|
|
568
|
+
*
|
|
569
|
+
* Anything passed to libcurl as a header will be converted to a string during
|
|
570
|
+
* the perform step.
|
|
571
|
+
*/
|
|
572
|
+
|
|
573
|
+
/*
|
|
574
|
+
* call-seq:
|
|
575
|
+
* easy.proxy_headers => Hash, Array or Str
|
|
576
|
+
*
|
|
577
|
+
* Obtain the custom HTTP proxy_headers for following requests.
|
|
578
|
+
*/
|
|
579
|
+
static VALUE ruby_curl_easy_proxy_headers_get(VALUE self) {
|
|
580
|
+
ruby_curl_easy *rbce;
|
|
581
|
+
VALUE proxy_headers;
|
|
582
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
583
|
+
proxy_headers = rb_easy_get("proxy_headers");//rb_hash_aref(rbce->opts, rb_intern("proxy_headers"));
|
|
584
|
+
if (proxy_headers == Qnil) { proxy_headers = rb_easy_set("proxy_headers", rb_hash_new()); }
|
|
585
|
+
return proxy_headers;
|
|
586
|
+
}
|
|
587
|
+
|
|
480
588
|
/*
|
|
481
589
|
* call-seq:
|
|
482
590
|
* easy.interface => string
|
|
@@ -684,29 +792,29 @@ static VALUE ruby_curl_easy_useragent_get(VALUE self) {
|
|
|
684
792
|
/*
|
|
685
793
|
* call-seq:
|
|
686
794
|
* easy.post_body = "some=form%20data&to=send" => string or nil
|
|
687
|
-
*
|
|
795
|
+
*
|
|
688
796
|
* Sets the POST body of this Curl::Easy instance. This is expected to be
|
|
689
797
|
* URL encoded; no additional processing or encoding is done on the string.
|
|
690
798
|
* The content-type header will be set to application/x-www-form-urlencoded.
|
|
691
|
-
*
|
|
799
|
+
*
|
|
692
800
|
* This is handy if you want to perform a POST against a Curl::Multi instance.
|
|
693
801
|
*/
|
|
694
802
|
static VALUE ruby_curl_easy_post_body_set(VALUE self, VALUE post_body) {
|
|
695
803
|
ruby_curl_easy *rbce;
|
|
696
804
|
CURL *curl;
|
|
697
|
-
|
|
805
|
+
|
|
698
806
|
char *data;
|
|
699
807
|
long len;
|
|
700
808
|
|
|
701
809
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
702
|
-
|
|
810
|
+
|
|
703
811
|
curl = rbce->curl;
|
|
704
|
-
|
|
812
|
+
|
|
705
813
|
if ( post_body == Qnil ) {
|
|
706
814
|
rb_easy_del("postdata_buffer");
|
|
707
815
|
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
|
|
708
|
-
|
|
709
|
-
} else {
|
|
816
|
+
|
|
817
|
+
} else {
|
|
710
818
|
if (rb_type(post_body) == T_STRING) {
|
|
711
819
|
data = StringValuePtr(post_body);
|
|
712
820
|
len = RSTRING_LEN(post_body);
|
|
@@ -719,19 +827,19 @@ static VALUE ruby_curl_easy_post_body_set(VALUE self, VALUE post_body) {
|
|
|
719
827
|
else {
|
|
720
828
|
rb_raise(rb_eRuntimeError, "post data must respond_to .to_s");
|
|
721
829
|
}
|
|
722
|
-
|
|
723
|
-
// Store the string, since it has to hang around for the duration of the
|
|
830
|
+
|
|
831
|
+
// Store the string, since it has to hang around for the duration of the
|
|
724
832
|
// request. See CURLOPT_POSTFIELDS in the libcurl docs.
|
|
725
833
|
//rbce->postdata_buffer = post_body;
|
|
726
834
|
rb_easy_set("postdata_buffer", post_body);
|
|
727
|
-
|
|
835
|
+
|
|
728
836
|
curl_easy_setopt(curl, CURLOPT_POST, 1);
|
|
729
837
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
|
|
730
838
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
|
|
731
|
-
|
|
839
|
+
|
|
732
840
|
return post_body;
|
|
733
841
|
}
|
|
734
|
-
|
|
842
|
+
|
|
735
843
|
return Qnil;
|
|
736
844
|
}
|
|
737
845
|
|
|
@@ -748,7 +856,7 @@ static VALUE ruby_curl_easy_post_body_get(VALUE self) {
|
|
|
748
856
|
/*
|
|
749
857
|
* call-seq:
|
|
750
858
|
* easy.put_data = data => ""
|
|
751
|
-
*
|
|
859
|
+
*
|
|
752
860
|
* Points this Curl::Easy instance to data to be uploaded via PUT. This
|
|
753
861
|
* sets the request to a PUT type request - useful if you want to PUT via
|
|
754
862
|
* a multi handle.
|
|
@@ -772,9 +880,15 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
|
|
|
772
880
|
curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
|
|
773
881
|
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
|
|
774
882
|
curl_easy_setopt(curl, CURLOPT_READFUNCTION, (curl_read_callback)read_data_handler);
|
|
883
|
+
#if HAVE_CURLOPT_SEEKFUNCTION
|
|
884
|
+
curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, (curl_seek_callback)seek_data_handler);
|
|
885
|
+
#endif
|
|
775
886
|
curl_easy_setopt(curl, CURLOPT_READDATA, rbce);
|
|
887
|
+
#if HAVE_CURLOPT_SEEKDATA
|
|
888
|
+
curl_easy_setopt(curl, CURLOPT_SEEKDATA, rbce);
|
|
889
|
+
#endif
|
|
776
890
|
|
|
777
|
-
/*
|
|
891
|
+
/*
|
|
778
892
|
* we need to set specific headers for the PUT to work... so
|
|
779
893
|
* convert the internal headers structure to a HASH if one is set
|
|
780
894
|
*/
|
|
@@ -788,7 +902,7 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
|
|
|
788
902
|
if (NIL_P(data)) { return data; }
|
|
789
903
|
|
|
790
904
|
headers = rb_easy_get("headers");
|
|
791
|
-
if( headers == Qnil ) {
|
|
905
|
+
if( headers == Qnil ) {
|
|
792
906
|
headers = rb_hash_new();
|
|
793
907
|
}
|
|
794
908
|
|
|
@@ -800,14 +914,14 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
|
|
|
800
914
|
rb_hash_aset(headers, rb_str_new2("Expect"), rb_str_new2(""));
|
|
801
915
|
}
|
|
802
916
|
size = rb_funcall(stat, rb_intern("size"), 0);
|
|
803
|
-
curl_easy_setopt(curl, CURLOPT_INFILESIZE,
|
|
917
|
+
curl_easy_setopt(curl, CURLOPT_INFILESIZE, NUM2LONG(size));
|
|
804
918
|
}
|
|
805
919
|
else if( rb_hash_aref(headers, rb_str_new2("Content-Length")) == Qnil && rb_hash_aref(headers, rb_str_new2("Transfer-Encoding")) == Qnil ) {
|
|
806
920
|
rb_hash_aset(headers, rb_str_new2("Transfer-Encoding"), rb_str_new2("chunked"));
|
|
807
921
|
}
|
|
808
922
|
else if( rb_hash_aref(headers, rb_str_new2("Content-Length")) ) {
|
|
809
923
|
VALUE size = rb_funcall(rb_hash_aref(headers, rb_str_new2("Content-Length")), rb_intern("to_i"), 0);
|
|
810
|
-
curl_easy_setopt(curl, CURLOPT_INFILESIZE,
|
|
924
|
+
curl_easy_setopt(curl, CURLOPT_INFILESIZE, NUM2LONG(size));
|
|
811
925
|
}
|
|
812
926
|
}
|
|
813
927
|
else if (rb_respond_to(data, rb_intern("to_s"))) {
|
|
@@ -843,6 +957,25 @@ static VALUE ruby_curl_easy_ftp_commands_get(VALUE self) {
|
|
|
843
957
|
CURB_OBJECT_HGETTER(ruby_curl_easy, ftp_commands);
|
|
844
958
|
}
|
|
845
959
|
|
|
960
|
+
/*
|
|
961
|
+
* call-seq:
|
|
962
|
+
* easy.resolve = [ "example.com:80:127.0.0.1" ] => [ "example.com:80:127.0.0.1" ]
|
|
963
|
+
*
|
|
964
|
+
* Set the resolve list to statically resolve hostnames to IP addresses,
|
|
965
|
+
* bypassing DNS for matching hostname/port combinations.
|
|
966
|
+
*/
|
|
967
|
+
static VALUE ruby_curl_easy_resolve_set(VALUE self, VALUE resolve) {
|
|
968
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, resolve);
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
/*
|
|
972
|
+
* call-seq
|
|
973
|
+
* easy.resolve => array or nil
|
|
974
|
+
*/
|
|
975
|
+
static VALUE ruby_curl_easy_resolve_get(VALUE self) {
|
|
976
|
+
CURB_OBJECT_HGETTER(ruby_curl_easy, resolve);
|
|
977
|
+
}
|
|
978
|
+
|
|
846
979
|
/* ================== IMMED ATTRS ==================*/
|
|
847
980
|
|
|
848
981
|
/*
|
|
@@ -951,16 +1084,16 @@ static VALUE ruby_curl_easy_proxy_type_get(VALUE self) {
|
|
|
951
1084
|
(!strncmp("digest",node,6)) ? CURLAUTH_DIGEST : \
|
|
952
1085
|
(!strncmp("gssnegotiate",node,12)) ? CURLAUTH_GSSNEGOTIATE : \
|
|
953
1086
|
(!strncmp("ntlm",node,4)) ? CURLAUTH_NTLM : \
|
|
954
|
-
(!strncmp("
|
|
955
|
-
(!strncmp("
|
|
956
|
-
#else
|
|
1087
|
+
(!strncmp("anysafe",node,7)) ? CURLAUTH_ANYSAFE : \
|
|
1088
|
+
(!strncmp("any",node,3)) ? CURLAUTH_ANY : 0
|
|
1089
|
+
#else
|
|
957
1090
|
#define CURL_HTTPAUTH_STR_TO_NUM(node) \
|
|
958
1091
|
(!strncmp("basic",node,5)) ? CURLAUTH_BASIC : \
|
|
959
1092
|
(!strncmp("digest",node,6)) ? CURLAUTH_DIGEST : \
|
|
960
1093
|
(!strncmp("gssnegotiate",node,12)) ? CURLAUTH_GSSNEGOTIATE : \
|
|
961
1094
|
(!strncmp("ntlm",node,4)) ? CURLAUTH_NTLM : \
|
|
962
|
-
(!strncmp("
|
|
963
|
-
(!strncmp("
|
|
1095
|
+
(!strncmp("anysafe",node,7)) ? CURLAUTH_ANYSAFE : \
|
|
1096
|
+
(!strncmp("any",node,3)) ? CURLAUTH_ANY : 0
|
|
964
1097
|
#endif
|
|
965
1098
|
/*
|
|
966
1099
|
* call-seq:
|
|
@@ -974,21 +1107,22 @@ static VALUE ruby_curl_easy_proxy_type_get(VALUE self) {
|
|
|
974
1107
|
static VALUE ruby_curl_easy_http_auth_types_set(int argc, VALUE *argv, VALUE self) {//VALUE self, VALUE http_auth_types) {
|
|
975
1108
|
ruby_curl_easy *rbce;
|
|
976
1109
|
VALUE args_ary;
|
|
977
|
-
|
|
1110
|
+
long i, len;
|
|
978
1111
|
char* node = NULL;
|
|
979
|
-
long mask =
|
|
1112
|
+
long mask = 0;
|
|
980
1113
|
|
|
981
1114
|
rb_scan_args(argc, argv, "*", &args_ary);
|
|
982
1115
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
983
1116
|
|
|
984
|
-
len =
|
|
1117
|
+
len = RARRAY_LEN(args_ary);
|
|
985
1118
|
|
|
986
|
-
if (len == 1 && (
|
|
987
|
-
|
|
1119
|
+
if (len == 1 && (rb_ary_entry(args_ary,0) == Qnil || TYPE(rb_ary_entry(args_ary,0)) == T_FIXNUM ||
|
|
1120
|
+
TYPE(rb_ary_entry(args_ary,0)) == T_BIGNUM)) {
|
|
1121
|
+
if (rb_ary_entry(args_ary,0) == Qnil) {
|
|
988
1122
|
rbce->http_auth_types = 0;
|
|
989
1123
|
}
|
|
990
1124
|
else {
|
|
991
|
-
rbce->http_auth_types =
|
|
1125
|
+
rbce->http_auth_types = NUM2LONG(rb_ary_entry(args_ary,0));
|
|
992
1126
|
}
|
|
993
1127
|
}
|
|
994
1128
|
else {
|
|
@@ -1001,7 +1135,7 @@ static VALUE ruby_curl_easy_http_auth_types_set(int argc, VALUE *argv, VALUE sel
|
|
|
1001
1135
|
}
|
|
1002
1136
|
rbce->http_auth_types = mask;
|
|
1003
1137
|
}
|
|
1004
|
-
return
|
|
1138
|
+
return LONG2NUM(rbce->http_auth_types);
|
|
1005
1139
|
}
|
|
1006
1140
|
|
|
1007
1141
|
/*
|
|
@@ -1066,7 +1200,7 @@ static VALUE ruby_curl_easy_max_redirects_get(VALUE self) {
|
|
|
1066
1200
|
|
|
1067
1201
|
/*
|
|
1068
1202
|
* call-seq:
|
|
1069
|
-
* easy.timeout = fixnum or nil
|
|
1203
|
+
* easy.timeout = float, fixnum or nil => numeric
|
|
1070
1204
|
*
|
|
1071
1205
|
* Set the maximum time in seconds that you allow the libcurl transfer
|
|
1072
1206
|
* operation to take. Normally, name lookups can take a considerable time
|
|
@@ -1075,20 +1209,77 @@ static VALUE ruby_curl_easy_max_redirects_get(VALUE self) {
|
|
|
1075
1209
|
*
|
|
1076
1210
|
* Set to nil (or zero) to disable timeout (it will then only timeout
|
|
1077
1211
|
* on the system's internal timeouts).
|
|
1212
|
+
*
|
|
1213
|
+
* Uses timeout_ms internally instead of timeout because it allows for
|
|
1214
|
+
* better precision and libcurl will use the last set value when both
|
|
1215
|
+
* timeout and timeout_ms are set.
|
|
1216
|
+
*
|
|
1078
1217
|
*/
|
|
1079
|
-
static VALUE ruby_curl_easy_timeout_set(VALUE self, VALUE
|
|
1080
|
-
|
|
1218
|
+
static VALUE ruby_curl_easy_timeout_set(VALUE self, VALUE timeout_s) {
|
|
1219
|
+
ruby_curl_easy *rbce;
|
|
1220
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
1221
|
+
|
|
1222
|
+
if (Qnil == timeout_s || NUM2DBL(timeout_s) <= 0.0) {
|
|
1223
|
+
rbce->timeout_ms = 0;
|
|
1224
|
+
} else {
|
|
1225
|
+
rbce->timeout_ms = (unsigned long)(NUM2DBL(timeout_s) * 1000);
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
return DBL2NUM(rbce->timeout_ms / 1000.0);
|
|
1081
1229
|
}
|
|
1082
1230
|
|
|
1083
1231
|
/*
|
|
1084
1232
|
* call-seq:
|
|
1085
|
-
* easy.timeout =>
|
|
1233
|
+
* easy.timeout => numeric
|
|
1086
1234
|
*
|
|
1087
1235
|
* Obtain the maximum time in seconds that you allow the libcurl transfer
|
|
1088
1236
|
* operation to take.
|
|
1237
|
+
*
|
|
1238
|
+
* Uses timeout_ms internally instead of timeout.
|
|
1239
|
+
*
|
|
1240
|
+
*/
|
|
1241
|
+
static VALUE ruby_curl_easy_timeout_get(VALUE self) {
|
|
1242
|
+
ruby_curl_easy *rbce;
|
|
1243
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
1244
|
+
return DBL2NUM(rbce->timeout_ms / 1000.0);
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
/*
|
|
1248
|
+
* call-seq:
|
|
1249
|
+
* easy.timeout_ms = fixnum or nil => fixnum or nil
|
|
1250
|
+
*
|
|
1251
|
+
* Set the maximum time in milliseconds that you allow the libcurl transfer
|
|
1252
|
+
* operation to take. Normally, name lookups can take a considerable time
|
|
1253
|
+
* and limiting operations to less than a few minutes risk aborting
|
|
1254
|
+
* perfectly normal operations.
|
|
1255
|
+
*
|
|
1256
|
+
* Set to nil (or zero) to disable timeout (it will then only timeout
|
|
1257
|
+
* on the system's internal timeouts).
|
|
1258
|
+
*/
|
|
1259
|
+
static VALUE ruby_curl_easy_timeout_ms_set(VALUE self, VALUE timeout_ms) {
|
|
1260
|
+
ruby_curl_easy *rbce;
|
|
1261
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
1262
|
+
|
|
1263
|
+
if (Qnil == timeout_ms || NUM2DBL(timeout_ms) <= 0.0) {
|
|
1264
|
+
rbce->timeout_ms = 0;
|
|
1265
|
+
} else {
|
|
1266
|
+
rbce->timeout_ms = NUM2ULONG(timeout_ms);
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
return ULONG2NUM(rbce->timeout_ms);
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
/*
|
|
1273
|
+
* call-seq:
|
|
1274
|
+
* easy.timeout_ms => fixnum or nil
|
|
1275
|
+
*
|
|
1276
|
+
* Obtain the maximum time in milliseconds that you allow the libcurl transfer
|
|
1277
|
+
* operation to take.
|
|
1089
1278
|
*/
|
|
1090
|
-
static VALUE
|
|
1091
|
-
|
|
1279
|
+
static VALUE ruby_curl_easy_timeout_ms_get(VALUE self) {
|
|
1280
|
+
ruby_curl_easy *rbce;
|
|
1281
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
1282
|
+
return LONG2NUM(rbce->timeout_ms);
|
|
1092
1283
|
}
|
|
1093
1284
|
|
|
1094
1285
|
/*
|
|
@@ -1117,6 +1308,32 @@ static VALUE ruby_curl_easy_connect_timeout_get(VALUE self, VALUE connect_timeou
|
|
|
1117
1308
|
CURB_IMMED_GETTER(ruby_curl_easy, connect_timeout, 0);
|
|
1118
1309
|
}
|
|
1119
1310
|
|
|
1311
|
+
/*
|
|
1312
|
+
* call-seq:
|
|
1313
|
+
* easy.connect_timeout_ms = fixnum or nil => fixnum or nil
|
|
1314
|
+
*
|
|
1315
|
+
* Set the maximum time in milliseconds that you allow the connection to the
|
|
1316
|
+
* server to take. This only limits the connection phase, once it has
|
|
1317
|
+
* connected, this option is of no more use.
|
|
1318
|
+
*
|
|
1319
|
+
* Set to nil (or zero) to disable connection timeout (it will then only
|
|
1320
|
+
* timeout on the system's internal timeouts).
|
|
1321
|
+
*/
|
|
1322
|
+
static VALUE ruby_curl_easy_connect_timeout_ms_set(VALUE self, VALUE connect_timeout_ms) {
|
|
1323
|
+
CURB_IMMED_SETTER(ruby_curl_easy, connect_timeout_ms, 0);
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
/*
|
|
1327
|
+
* call-seq:
|
|
1328
|
+
* easy.connect_timeout_ms => fixnum or nil
|
|
1329
|
+
*
|
|
1330
|
+
* Obtain the maximum time in milliseconds that you allow the connection to the
|
|
1331
|
+
* server to take.
|
|
1332
|
+
*/
|
|
1333
|
+
static VALUE ruby_curl_easy_connect_timeout_ms_get(VALUE self, VALUE connect_timeout_ms) {
|
|
1334
|
+
CURB_IMMED_GETTER(ruby_curl_easy, connect_timeout_ms, 0);
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1120
1337
|
/*
|
|
1121
1338
|
* call-seq:
|
|
1122
1339
|
* easy.dns_cache_timeout = fixnum or nil => fixnum or nil
|
|
@@ -1212,6 +1429,46 @@ static VALUE ruby_curl_easy_low_speed_time_get(VALUE self, VALUE low_speed_time)
|
|
|
1212
1429
|
CURB_IMMED_GETTER(ruby_curl_easy, low_speed_time, 0);
|
|
1213
1430
|
}
|
|
1214
1431
|
|
|
1432
|
+
/*
|
|
1433
|
+
* call-seq:
|
|
1434
|
+
* easy.max_send_speed_large = fixnum or nil => fixnum or nil
|
|
1435
|
+
*
|
|
1436
|
+
* Set the maximal sending transfer speed (in bytes per second)
|
|
1437
|
+
*/
|
|
1438
|
+
static VALUE ruby_curl_easy_max_send_speed_large_set(VALUE self, VALUE max_send_speed_large) {
|
|
1439
|
+
CURB_IMMED_SETTER(ruby_curl_easy, max_send_speed_large, 0);
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
/*
|
|
1443
|
+
* call-seq:
|
|
1444
|
+
* easy.max_send_speed_large = fixnum or nil => fixnum or nil
|
|
1445
|
+
*
|
|
1446
|
+
* Get the maximal sending transfer speed (in bytes per second)
|
|
1447
|
+
*/
|
|
1448
|
+
static VALUE ruby_curl_easy_max_send_speed_large_get(VALUE self, VALUE max_send_speed_large) {
|
|
1449
|
+
CURB_IMMED_GETTER(ruby_curl_easy, max_send_speed_large, 0);
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
/*
|
|
1453
|
+
* call-seq:
|
|
1454
|
+
* easy.max_recv_speed_large = fixnum or nil => fixnum or nil
|
|
1455
|
+
*
|
|
1456
|
+
* Set the maximal receiving transfer speed (in bytes per second)
|
|
1457
|
+
*/
|
|
1458
|
+
static VALUE ruby_curl_easy_max_recv_speed_large_set(VALUE self, VALUE max_recv_speed_large) {
|
|
1459
|
+
CURB_IMMED_SETTER(ruby_curl_easy, max_recv_speed_large, 0);
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
/*
|
|
1463
|
+
* call-seq:
|
|
1464
|
+
* easy.max_recv_speed_large = fixnum or nil => fixnum or nil
|
|
1465
|
+
*
|
|
1466
|
+
* Get the maximal receiving transfer speed (in bytes per second)
|
|
1467
|
+
*/
|
|
1468
|
+
static VALUE ruby_curl_easy_max_recv_speed_large_get(VALUE self, VALUE max_recv_speed_large) {
|
|
1469
|
+
CURB_IMMED_GETTER(ruby_curl_easy, max_recv_speed_large, 0);
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1215
1472
|
/*
|
|
1216
1473
|
* call-seq:
|
|
1217
1474
|
* easy.username = string => string
|
|
@@ -1229,7 +1486,7 @@ static VALUE ruby_curl_easy_username_set(VALUE self, VALUE username) {
|
|
|
1229
1486
|
/*
|
|
1230
1487
|
* call-seq:
|
|
1231
1488
|
* easy.username => string
|
|
1232
|
-
*
|
|
1489
|
+
*
|
|
1233
1490
|
* Get the current username
|
|
1234
1491
|
*/
|
|
1235
1492
|
static VALUE ruby_curl_easy_username_get(VALUE self, VALUE username) {
|
|
@@ -1257,7 +1514,7 @@ static VALUE ruby_curl_easy_password_set(VALUE self, VALUE password) {
|
|
|
1257
1514
|
/*
|
|
1258
1515
|
* call-seq:
|
|
1259
1516
|
* easy.password => string
|
|
1260
|
-
*
|
|
1517
|
+
*
|
|
1261
1518
|
* Get the current password
|
|
1262
1519
|
*/
|
|
1263
1520
|
static VALUE ruby_curl_easy_password_get(VALUE self, VALUE password) {
|
|
@@ -1273,8 +1530,15 @@ static VALUE ruby_curl_easy_password_get(VALUE self, VALUE password) {
|
|
|
1273
1530
|
* easy.ssl_version = value => fixnum or nil
|
|
1274
1531
|
*
|
|
1275
1532
|
* Sets the version of SSL/TLS that libcurl will attempt to use. Valid
|
|
1276
|
-
* options are
|
|
1277
|
-
*
|
|
1533
|
+
* options are:
|
|
1534
|
+
*
|
|
1535
|
+
* Curl::CURL_SSLVERSION_DEFAULT
|
|
1536
|
+
* Curl::CURL_SSLVERSION_TLSv1 (TLS 1.x)
|
|
1537
|
+
* Curl::CURL_SSLVERSION_SSLv2
|
|
1538
|
+
* Curl::CURL_SSLVERSION_SSLv3
|
|
1539
|
+
* Curl::CURL_SSLVERSION_TLSv1_0
|
|
1540
|
+
* Curl::CURL_SSLVERSION_TLSv1_1
|
|
1541
|
+
* Curl::CURL_SSLVERSION_TLSv1_2
|
|
1278
1542
|
*/
|
|
1279
1543
|
static VALUE ruby_curl_easy_ssl_version_set(VALUE self, VALUE ssl_version) {
|
|
1280
1544
|
CURB_IMMED_SETTER(ruby_curl_easy, ssl_version, -1);
|
|
@@ -1293,7 +1557,7 @@ static VALUE ruby_curl_easy_ssl_version_get(VALUE self, VALUE ssl_version) {
|
|
|
1293
1557
|
/*
|
|
1294
1558
|
* call-seq:
|
|
1295
1559
|
* easy.use_ssl = value => fixnum or nil
|
|
1296
|
-
*
|
|
1560
|
+
*
|
|
1297
1561
|
* Ensure libcurl uses SSL for FTP connections. Valid options are Curl::CURL_USESSL_NONE,
|
|
1298
1562
|
* Curl::CURL_USESSL_TRY, Curl::CURL_USESSL_CONTROL, and Curl::CURL_USESSL_ALL.
|
|
1299
1563
|
*/
|
|
@@ -1637,9 +1901,10 @@ static VALUE ruby_curl_easy_ignore_content_length_q(VALUE self) {
|
|
|
1637
1901
|
*/
|
|
1638
1902
|
static VALUE ruby_curl_easy_resolve_mode(VALUE self) {
|
|
1639
1903
|
ruby_curl_easy *rbce;
|
|
1904
|
+
unsigned short rm;
|
|
1640
1905
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
1641
1906
|
|
|
1642
|
-
|
|
1907
|
+
rm = rbce->resolve_mode;
|
|
1643
1908
|
|
|
1644
1909
|
switch(rm) {
|
|
1645
1910
|
case CURL_IPRESOLVE_V4:
|
|
@@ -1668,9 +1933,10 @@ static VALUE ruby_curl_easy_resolve_mode_set(VALUE self, VALUE resolve_mode) {
|
|
|
1668
1933
|
return Qnil;
|
|
1669
1934
|
} else {
|
|
1670
1935
|
ruby_curl_easy *rbce;
|
|
1936
|
+
ID resolve_mode_id;
|
|
1671
1937
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
1672
1938
|
|
|
1673
|
-
|
|
1939
|
+
resolve_mode_id = rb_to_id(resolve_mode);
|
|
1674
1940
|
|
|
1675
1941
|
if (resolve_mode_id == rb_intern("auto")) {
|
|
1676
1942
|
rbce->resolve_mode = CURL_IPRESOLVE_WHATEVER;
|
|
@@ -1748,7 +2014,7 @@ static VALUE ruby_curl_easy_on_failure_set(int argc, VALUE *argv, VALUE self) {
|
|
|
1748
2014
|
* To remove a previously-supplied handler, call this method with no attached
|
|
1749
2015
|
* block.
|
|
1750
2016
|
*
|
|
1751
|
-
* The +on_missing+ handler is called when request is finished with a
|
|
2017
|
+
* The +on_missing+ handler is called when request is finished with a
|
|
1752
2018
|
* status of 40x
|
|
1753
2019
|
*/
|
|
1754
2020
|
static VALUE ruby_curl_easy_on_missing_set(int argc, VALUE *argv, VALUE self) {
|
|
@@ -1763,7 +2029,7 @@ static VALUE ruby_curl_easy_on_missing_set(int argc, VALUE *argv, VALUE self) {
|
|
|
1763
2029
|
* To remove a previously-supplied handler, call this method with no attached
|
|
1764
2030
|
* block.
|
|
1765
2031
|
*
|
|
1766
|
-
* The +on_redirect+ handler is called when request is finished with a
|
|
2032
|
+
* The +on_redirect+ handler is called when request is finished with a
|
|
1767
2033
|
* status of 30x
|
|
1768
2034
|
*/
|
|
1769
2035
|
static VALUE ruby_curl_easy_on_redirect_set(int argc, VALUE *argv, VALUE self) {
|
|
@@ -1850,10 +2116,10 @@ static VALUE ruby_curl_easy_on_debug_set(int argc, VALUE *argv, VALUE self) {
|
|
|
1850
2116
|
*/
|
|
1851
2117
|
static VALUE cb_each_http_header(VALUE header, VALUE wrap) {
|
|
1852
2118
|
struct curl_slist **list;
|
|
1853
|
-
Data_Get_Struct(wrap, struct curl_slist *, list);
|
|
1854
|
-
|
|
1855
2119
|
VALUE header_str = Qnil;
|
|
1856
2120
|
|
|
2121
|
+
Data_Get_Struct(wrap, struct curl_slist *, list);
|
|
2122
|
+
|
|
1857
2123
|
//rb_p(header);
|
|
1858
2124
|
|
|
1859
2125
|
if (rb_type(header) == T_ARRAY) {
|
|
@@ -1877,19 +2143,66 @@ static VALUE cb_each_http_header(VALUE header, VALUE wrap) {
|
|
|
1877
2143
|
return header_str;
|
|
1878
2144
|
}
|
|
1879
2145
|
|
|
2146
|
+
/***********************************************
|
|
2147
|
+
* This is an rb_iterate callback used to set up http proxy headers.
|
|
2148
|
+
*/
|
|
2149
|
+
static VALUE cb_each_http_proxy_header(VALUE proxy_header, VALUE wrap) {
|
|
2150
|
+
struct curl_slist **list;
|
|
2151
|
+
VALUE proxy_header_str = Qnil;
|
|
2152
|
+
|
|
2153
|
+
Data_Get_Struct(wrap, struct curl_slist *, list);
|
|
2154
|
+
|
|
2155
|
+
//rb_p(proxy_header);
|
|
2156
|
+
|
|
2157
|
+
if (rb_type(proxy_header) == T_ARRAY) {
|
|
2158
|
+
// we're processing a hash, proxy header is [name, val]
|
|
2159
|
+
VALUE name, value;
|
|
2160
|
+
|
|
2161
|
+
name = rb_obj_as_string(rb_ary_entry(proxy_header, 0));
|
|
2162
|
+
value = rb_obj_as_string(rb_ary_entry(proxy_header, 1));
|
|
2163
|
+
|
|
2164
|
+
// This is a bit inefficient, but we don't want to be modifying
|
|
2165
|
+
// the actual values in the original hash.
|
|
2166
|
+
proxy_header_str = rb_str_plus(name, rb_str_new2(": "));
|
|
2167
|
+
proxy_header_str = rb_str_plus(proxy_header_str, value);
|
|
2168
|
+
} else {
|
|
2169
|
+
proxy_header_str = rb_obj_as_string(proxy_header);
|
|
2170
|
+
}
|
|
2171
|
+
|
|
2172
|
+
//rb_p(header_str);
|
|
2173
|
+
|
|
2174
|
+
*list = curl_slist_append(*list, StringValuePtr(proxy_header_str));
|
|
2175
|
+
return proxy_header_str;
|
|
2176
|
+
}
|
|
2177
|
+
|
|
1880
2178
|
/***********************************************
|
|
1881
2179
|
* This is an rb_iterate callback used to set up ftp commands.
|
|
1882
2180
|
*/
|
|
1883
2181
|
static VALUE cb_each_ftp_command(VALUE ftp_command, VALUE wrap) {
|
|
1884
2182
|
struct curl_slist **list;
|
|
2183
|
+
VALUE ftp_command_string;
|
|
1885
2184
|
Data_Get_Struct(wrap, struct curl_slist *, list);
|
|
1886
2185
|
|
|
1887
|
-
|
|
2186
|
+
ftp_command_string = rb_obj_as_string(ftp_command);
|
|
1888
2187
|
*list = curl_slist_append(*list, StringValuePtr(ftp_command));
|
|
1889
2188
|
|
|
1890
2189
|
return ftp_command_string;
|
|
1891
2190
|
}
|
|
1892
2191
|
|
|
2192
|
+
/***********************************************
|
|
2193
|
+
* This is an rb_iterate callback used to set up the resolve list.
|
|
2194
|
+
*/
|
|
2195
|
+
static VALUE cb_each_resolve(VALUE resolve, VALUE wrap) {
|
|
2196
|
+
struct curl_slist **list;
|
|
2197
|
+
VALUE resolve_string;
|
|
2198
|
+
Data_Get_Struct(wrap, struct curl_slist *, list);
|
|
2199
|
+
|
|
2200
|
+
resolve_string = rb_obj_as_string(resolve);
|
|
2201
|
+
*list = curl_slist_append(*list, StringValuePtr(resolve));
|
|
2202
|
+
|
|
2203
|
+
return resolve_string;
|
|
2204
|
+
}
|
|
2205
|
+
|
|
1893
2206
|
/***********************************************
|
|
1894
2207
|
*
|
|
1895
2208
|
* Setup a connection
|
|
@@ -1901,7 +2214,9 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
1901
2214
|
CURL *curl;
|
|
1902
2215
|
VALUE url, _url = rb_easy_get("url");
|
|
1903
2216
|
struct curl_slist **hdrs = &(rbce->curl_headers);
|
|
2217
|
+
struct curl_slist **phdrs = &(rbce->curl_proxy_headers);
|
|
1904
2218
|
struct curl_slist **cmds = &(rbce->curl_ftp_commands);
|
|
2219
|
+
struct curl_slist **rslv = &(rbce->curl_resolve);
|
|
1905
2220
|
|
|
1906
2221
|
curl = rbce->curl;
|
|
1907
2222
|
|
|
@@ -1910,7 +2225,6 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
1910
2225
|
}
|
|
1911
2226
|
|
|
1912
2227
|
url = rb_check_string_type(_url);
|
|
1913
|
-
|
|
1914
2228
|
curl_easy_setopt(curl, CURLOPT_URL, StringValuePtr(url));
|
|
1915
2229
|
|
|
1916
2230
|
// network stuff and auth
|
|
@@ -2023,8 +2337,14 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2023
2337
|
|
|
2024
2338
|
curl_easy_setopt(curl, CURLOPT_UNRESTRICTED_AUTH, rbce->unrestricted_auth);
|
|
2025
2339
|
|
|
2026
|
-
|
|
2340
|
+
#if HAVE_CURLOPT_TIMEOUT_MS
|
|
2341
|
+
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, rbce->timeout_ms);
|
|
2342
|
+
#endif
|
|
2343
|
+
|
|
2027
2344
|
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, rbce->connect_timeout);
|
|
2345
|
+
#if HAVE_CURLOPT_CONNECTTIMEOUT_MS
|
|
2346
|
+
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, rbce->connect_timeout_ms);
|
|
2347
|
+
#endif
|
|
2028
2348
|
curl_easy_setopt(curl, CURLOPT_DNS_CACHE_TIMEOUT, rbce->dns_cache_timeout);
|
|
2029
2349
|
|
|
2030
2350
|
curl_easy_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, rbce->ignore_content_length);
|
|
@@ -2043,6 +2363,9 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2043
2363
|
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, rbce->low_speed_limit);
|
|
2044
2364
|
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, rbce->low_speed_time);
|
|
2045
2365
|
|
|
2366
|
+
curl_easy_setopt(curl, CURLOPT_MAX_RECV_SPEED_LARGE, rbce->max_recv_speed_large);
|
|
2367
|
+
curl_easy_setopt(curl, CURLOPT_MAX_SEND_SPEED_LARGE, rbce->max_send_speed_large);
|
|
2368
|
+
|
|
2046
2369
|
// Set up localport / proxy port
|
|
2047
2370
|
// FIXME these won't get returned to default if they're unset Ruby
|
|
2048
2371
|
if (rbce->proxy_port > 0) {
|
|
@@ -2075,21 +2398,20 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2075
2398
|
#endif
|
|
2076
2399
|
}
|
|
2077
2400
|
|
|
2078
|
-
|
|
2401
|
+
/*
|
|
2402
|
+
* NOTE: we used to set CURLAUTH_ANY but see: http://curl.haxx.se/mail/lib-2015-06/0033.html
|
|
2403
|
+
*/
|
|
2404
|
+
if (rbce->http_auth_types != 0) {
|
|
2079
2405
|
#if LIBCURL_VERSION_NUM >= 0x070a06
|
|
2080
2406
|
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, rbce->http_auth_types);
|
|
2081
|
-
} else {
|
|
2082
|
-
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
|
|
2083
2407
|
#else
|
|
2084
2408
|
rb_warn("Installed libcurl is too old to support http_auth_types");
|
|
2085
2409
|
#endif
|
|
2086
2410
|
}
|
|
2087
2411
|
|
|
2088
|
-
if (rbce->proxy_auth_types
|
|
2412
|
+
if (rbce->proxy_auth_types != 0) {
|
|
2089
2413
|
#if LIBCURL_VERSION_NUM >= 0x070a07
|
|
2090
2414
|
curl_easy_setopt(curl, CURLOPT_PROXYAUTH, rbce->proxy_auth_types);
|
|
2091
|
-
} else {
|
|
2092
|
-
curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
|
|
2093
2415
|
#else
|
|
2094
2416
|
rb_warn("Installed libcurl is too old to support proxy_auth_types");
|
|
2095
2417
|
#endif
|
|
@@ -2150,7 +2472,7 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2150
2472
|
rb_warn("libcurl is not configured with SSL support");
|
|
2151
2473
|
}
|
|
2152
2474
|
#endif
|
|
2153
|
-
|
|
2475
|
+
|
|
2154
2476
|
if (rbce->ftp_filemethod > 0) {
|
|
2155
2477
|
curl_easy_setopt(curl, CURLOPT_FTP_FILEMETHOD, rbce->ftp_filemethod);
|
|
2156
2478
|
}
|
|
@@ -2177,6 +2499,25 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2177
2499
|
}
|
|
2178
2500
|
}
|
|
2179
2501
|
|
|
2502
|
+
#if HAVE_CURLOPT_PROXYHEADER
|
|
2503
|
+
/* Setup HTTP proxy headers if necessary */
|
|
2504
|
+
curl_easy_setopt(curl, CURLOPT_PROXYHEADER, NULL); // XXX: maybe we shouldn't be clearing this?
|
|
2505
|
+
|
|
2506
|
+
if (!rb_easy_nil("proxy_headers")) {
|
|
2507
|
+
if (rb_easy_type_check("proxy_headers", T_ARRAY) || rb_easy_type_check("proxy_headers", T_HASH)) {
|
|
2508
|
+
VALUE wrap = Data_Wrap_Struct(rb_cObject, 0, 0, phdrs);
|
|
2509
|
+
rb_iterate(rb_each, rb_easy_get("proxy_headers"), cb_each_http_proxy_header, wrap);
|
|
2510
|
+
} else {
|
|
2511
|
+
VALUE proxy_headers_str = rb_obj_as_string(rb_easy_get("proxy_headers"));
|
|
2512
|
+
*phdrs = curl_slist_append(*hdrs, StringValuePtr(proxy_headers_str));
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2515
|
+
if (*phdrs) {
|
|
2516
|
+
curl_easy_setopt(curl, CURLOPT_PROXYHEADER, *phdrs);
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2519
|
+
#endif
|
|
2520
|
+
|
|
2180
2521
|
/* Setup FTP commands if necessary */
|
|
2181
2522
|
if (!rb_easy_nil("ftp_commands")) {
|
|
2182
2523
|
if (rb_easy_type_check("ftp_commands", T_ARRAY)) {
|
|
@@ -2189,18 +2530,33 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2189
2530
|
}
|
|
2190
2531
|
}
|
|
2191
2532
|
|
|
2533
|
+
#if HAVE_CURLOPT_RESOLVE
|
|
2534
|
+
/* Setup resolve list if necessary */
|
|
2535
|
+
if (!rb_easy_nil("resolve")) {
|
|
2536
|
+
if (rb_easy_type_check("resolve", T_ARRAY)) {
|
|
2537
|
+
VALUE wrap = Data_Wrap_Struct(rb_cObject, 0, 0, rslv);
|
|
2538
|
+
rb_iterate(rb_each, rb_easy_get("resolve"), cb_each_resolve, wrap);
|
|
2539
|
+
}
|
|
2540
|
+
|
|
2541
|
+
if (*rslv) {
|
|
2542
|
+
curl_easy_setopt(curl, CURLOPT_RESOLVE, *rslv);
|
|
2543
|
+
}
|
|
2544
|
+
}
|
|
2545
|
+
#endif
|
|
2546
|
+
|
|
2192
2547
|
return Qnil;
|
|
2193
2548
|
}
|
|
2194
2549
|
/***********************************************
|
|
2195
2550
|
*
|
|
2196
2551
|
* Clean up a connection
|
|
2197
2552
|
*
|
|
2198
|
-
* Always returns
|
|
2553
|
+
* Always returns Qnil.
|
|
2199
2554
|
*/
|
|
2200
2555
|
VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
|
|
2201
2556
|
|
|
2202
2557
|
CURL *curl = rbce->curl;
|
|
2203
2558
|
struct curl_slist *ftp_commands;
|
|
2559
|
+
struct curl_slist *resolve;
|
|
2204
2560
|
|
|
2205
2561
|
/* Free everything up */
|
|
2206
2562
|
if (rbce->curl_headers) {
|
|
@@ -2208,12 +2564,23 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
|
|
|
2208
2564
|
rbce->curl_headers = NULL;
|
|
2209
2565
|
}
|
|
2210
2566
|
|
|
2567
|
+
if (rbce->curl_proxy_headers) {
|
|
2568
|
+
curl_slist_free_all(rbce->curl_proxy_headers);
|
|
2569
|
+
rbce->curl_proxy_headers = NULL;
|
|
2570
|
+
}
|
|
2571
|
+
|
|
2211
2572
|
ftp_commands = rbce->curl_ftp_commands;
|
|
2212
2573
|
if (ftp_commands) {
|
|
2213
2574
|
curl_slist_free_all(ftp_commands);
|
|
2214
2575
|
rbce->curl_ftp_commands = NULL;
|
|
2215
2576
|
}
|
|
2216
2577
|
|
|
2578
|
+
resolve = rbce->curl_resolve;
|
|
2579
|
+
if (resolve) {
|
|
2580
|
+
curl_slist_free_all(resolve);
|
|
2581
|
+
rbce->curl_resolve = NULL;
|
|
2582
|
+
}
|
|
2583
|
+
|
|
2217
2584
|
/* clean up a PUT request's curl options. */
|
|
2218
2585
|
if (!rb_easy_nil("upload")) {
|
|
2219
2586
|
rb_easy_del("upload"); // set the upload object to Qnil to let the GC clean up
|
|
@@ -2223,6 +2590,9 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
|
|
|
2223
2590
|
curl_easy_setopt(curl, CURLOPT_INFILESIZE, 0);
|
|
2224
2591
|
}
|
|
2225
2592
|
|
|
2593
|
+
// set values on cleanup to nil
|
|
2594
|
+
rb_easy_del("multi");
|
|
2595
|
+
|
|
2226
2596
|
return Qnil;
|
|
2227
2597
|
}
|
|
2228
2598
|
|
|
@@ -2314,7 +2684,7 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
|
|
|
2314
2684
|
append_to_form(argv[i], &first, &last);
|
|
2315
2685
|
} else if (rb_type(argv[i]) == T_ARRAY) {
|
|
2316
2686
|
// see: https://github.com/rvanlieshout/curb/commit/8bcdefddc0162484681ebd1a92d52a642666a445
|
|
2317
|
-
|
|
2687
|
+
long c = 0, argv_len = RARRAY_LEN(argv[i]);
|
|
2318
2688
|
for (; c < argv_len; ++c) {
|
|
2319
2689
|
if (rb_obj_is_instance_of(rb_ary_entry(argv[i],c), cCurlPostField)) {
|
|
2320
2690
|
append_to_form(rb_ary_entry(argv[i],c), &first, &last);
|
|
@@ -2467,7 +2837,7 @@ static VALUE ruby_curl_easy_response_code_get(VALUE self) {
|
|
|
2467
2837
|
static VALUE ruby_curl_easy_primary_ip_get(VALUE self) {
|
|
2468
2838
|
ruby_curl_easy *rbce;
|
|
2469
2839
|
char* ip;
|
|
2470
|
-
|
|
2840
|
+
|
|
2471
2841
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2472
2842
|
curl_easy_getinfo(rbce->curl, CURLINFO_PRIMARY_IP, &ip);
|
|
2473
2843
|
|
|
@@ -2523,7 +2893,7 @@ static VALUE ruby_curl_easy_file_time_get(VALUE self) {
|
|
|
2523
2893
|
return LONG2NUM(time);
|
|
2524
2894
|
#else
|
|
2525
2895
|
rb_warn("Installed libcurl is too old to support file_time");
|
|
2526
|
-
return
|
|
2896
|
+
return LONG2NUM(0);
|
|
2527
2897
|
#endif
|
|
2528
2898
|
}
|
|
2529
2899
|
|
|
@@ -2578,6 +2948,29 @@ static VALUE ruby_curl_easy_connect_time_get(VALUE self) {
|
|
|
2578
2948
|
return rb_float_new(time);
|
|
2579
2949
|
}
|
|
2580
2950
|
|
|
2951
|
+
/*
|
|
2952
|
+
* call-seq:
|
|
2953
|
+
* easy.app_connect_time => float
|
|
2954
|
+
*
|
|
2955
|
+
* Retrieve the time, in seconds, it took from the start until the SSL/SSH
|
|
2956
|
+
* connect/handshake to the remote host was completed. This time is most often
|
|
2957
|
+
* very near to the pre transfer time, except for cases such as HTTP
|
|
2958
|
+
* pippelining where the pretransfer time can be delayed due to waits in line
|
|
2959
|
+
* for the pipeline and more.
|
|
2960
|
+
*/
|
|
2961
|
+
#if defined(HAVE_CURLINFO_APPCONNECT_TIME)
|
|
2962
|
+
static VALUE ruby_curl_easy_app_connect_time_get(VALUE self) {
|
|
2963
|
+
ruby_curl_easy *rbce;
|
|
2964
|
+
double time;
|
|
2965
|
+
|
|
2966
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2967
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_APPCONNECT_TIME, &time);
|
|
2968
|
+
|
|
2969
|
+
return rb_float_new(time);
|
|
2970
|
+
}
|
|
2971
|
+
#endif
|
|
2972
|
+
|
|
2973
|
+
|
|
2581
2974
|
/*
|
|
2582
2975
|
* call-seq:
|
|
2583
2976
|
* easy.pre_transfer_time => float
|
|
@@ -2660,7 +3053,7 @@ static VALUE ruby_curl_easy_redirect_count_get(VALUE self) {
|
|
|
2660
3053
|
return LONG2NUM(count);
|
|
2661
3054
|
#else
|
|
2662
3055
|
rb_warn("Installed libcurl is too old to support redirect_count");
|
|
2663
|
-
return
|
|
3056
|
+
return LONG2NUM(-1);
|
|
2664
3057
|
#endif
|
|
2665
3058
|
|
|
2666
3059
|
}
|
|
@@ -2669,7 +3062,7 @@ static VALUE ruby_curl_easy_redirect_count_get(VALUE self) {
|
|
|
2669
3062
|
* call-seq:
|
|
2670
3063
|
* easy.redirect_url => "http://some.url" or nil
|
|
2671
3064
|
*
|
|
2672
|
-
* Retrieve the URL a redirect would take you to if you
|
|
3065
|
+
* Retrieve the URL a redirect would take you to if you
|
|
2673
3066
|
* would enable CURLOPT_FOLLOWLOCATION.
|
|
2674
3067
|
*
|
|
2675
3068
|
* Requires libcurl 7.18.2 or higher, otherwise -1 is always returned.
|
|
@@ -2689,7 +3082,7 @@ static VALUE ruby_curl_easy_redirect_url_get(VALUE self) {
|
|
|
2689
3082
|
}
|
|
2690
3083
|
#else
|
|
2691
3084
|
rb_warn("Installed libcurl is too old to support redirect_url");
|
|
2692
|
-
return
|
|
3085
|
+
return LONG2NUM(-1);
|
|
2693
3086
|
#endif
|
|
2694
3087
|
}
|
|
2695
3088
|
|
|
@@ -2918,7 +3311,7 @@ static VALUE ruby_curl_easy_os_errno_get(VALUE self) {
|
|
|
2918
3311
|
return LONG2NUM(result);
|
|
2919
3312
|
#else
|
|
2920
3313
|
rb_warn("Installed libcurl is too old to support os_errno");
|
|
2921
|
-
return
|
|
3314
|
+
return LONG2NUM(0);
|
|
2922
3315
|
#endif
|
|
2923
3316
|
}
|
|
2924
3317
|
|
|
@@ -2947,17 +3340,45 @@ static VALUE ruby_curl_easy_num_connects_get(VALUE self) {
|
|
|
2947
3340
|
return LONG2NUM(result);
|
|
2948
3341
|
#else
|
|
2949
3342
|
rb_warn("Installed libcurl is too old to support num_connects");
|
|
2950
|
-
return
|
|
3343
|
+
return LONG2NUM(-1);
|
|
2951
3344
|
#endif
|
|
2952
3345
|
}
|
|
2953
3346
|
|
|
2954
3347
|
|
|
2955
|
-
/*
|
|
3348
|
+
/*
|
|
3349
|
+
* call-seq:
|
|
3350
|
+
* easy.cookielist => array
|
|
3351
|
+
*
|
|
3352
|
+
* Retrieves the cookies curl knows in an array of strings.
|
|
3353
|
+
* Returned strings are in Netscape cookiejar format or in Set-Cookie format.
|
|
3354
|
+
*
|
|
3355
|
+
* See also option CURLINFO_COOKIELIST of curl_easy_getopt(3) to see how libcurl behaves.
|
|
3356
|
+
*
|
|
3357
|
+
* (requires libcurl 7.14.1 or higher, otherwise -1 is always returned).
|
|
3358
|
+
*/
|
|
3359
|
+
static VALUE ruby_curl_easy_cookielist_get(VALUE self) {
|
|
3360
|
+
#ifdef HAVE_CURLINFO_COOKIELIST
|
|
3361
|
+
ruby_curl_easy *rbce;
|
|
3362
|
+
struct curl_slist *cookies;
|
|
3363
|
+
struct curl_slist *cookie;
|
|
3364
|
+
VALUE rb_cookies;
|
|
2956
3365
|
|
|
2957
|
-
|
|
3366
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
3367
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_COOKIELIST, &cookies);
|
|
3368
|
+
if (!cookies)
|
|
3369
|
+
return Qnil;
|
|
3370
|
+
rb_cookies = rb_ary_new();
|
|
3371
|
+
for (cookie = cookies; cookie; cookie = cookie->next)
|
|
3372
|
+
rb_ary_push(rb_cookies, rb_str_new2(cookie->data));
|
|
3373
|
+
curl_slist_free_all(cookies);
|
|
3374
|
+
return rb_cookies;
|
|
3375
|
+
|
|
3376
|
+
#else
|
|
3377
|
+
rb_warn("Installed libcurl is too old to support cookielist");
|
|
3378
|
+
return INT2FIX(-1);
|
|
3379
|
+
#endif
|
|
3380
|
+
}
|
|
2958
3381
|
|
|
2959
|
-
Pass a pointer to a 'struct curl_slist *' to receive a linked-list of all cookies cURL knows (expired ones, too). Don't forget to curl_slist_free_all(3) the list after it has been used. If there are no cookies (cookies for the handle have not been enabled or simply none have been received) 'struct curl_slist *' will be set to point to NULL. (Added in 7.14.1)
|
|
2960
|
-
*/
|
|
2961
3382
|
|
|
2962
3383
|
/* TODO this needs to be implemented. Could probably support CONNECT_ONLY by having this
|
|
2963
3384
|
* return an open Socket or something.
|
|
@@ -3024,18 +3445,19 @@ static VALUE ruby_curl_easy_multi_set(VALUE self, VALUE multi) {
|
|
|
3024
3445
|
static VALUE ruby_curl_easy_last_result(VALUE self) {
|
|
3025
3446
|
ruby_curl_easy *rbce;
|
|
3026
3447
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
3027
|
-
return
|
|
3448
|
+
return LONG2NUM(rbce->last_result);
|
|
3028
3449
|
}
|
|
3029
3450
|
|
|
3030
3451
|
/*
|
|
3031
3452
|
* call-seq:
|
|
3032
3453
|
* easy.setopt Fixnum, value => value
|
|
3033
3454
|
*
|
|
3034
|
-
*
|
|
3455
|
+
* Initial access to libcurl curl_easy_setopt
|
|
3035
3456
|
*/
|
|
3036
3457
|
static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
3037
3458
|
ruby_curl_easy *rbce;
|
|
3038
|
-
long option =
|
|
3459
|
+
long option = NUM2LONG(opt);
|
|
3460
|
+
rb_io_t *open_f_ptr;
|
|
3039
3461
|
|
|
3040
3462
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
3041
3463
|
|
|
@@ -3060,7 +3482,7 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3060
3482
|
curl_easy_setopt(rbce->curl, CURLOPT_CUSTOMREQUEST, NIL_P(val) ? NULL : StringValueCStr(val));
|
|
3061
3483
|
break;
|
|
3062
3484
|
case CURLOPT_HTTP_VERSION:
|
|
3063
|
-
curl_easy_setopt(rbce->curl, CURLOPT_HTTP_VERSION,
|
|
3485
|
+
curl_easy_setopt(rbce->curl, CURLOPT_HTTP_VERSION, NUM2LONG(val));
|
|
3064
3486
|
break;
|
|
3065
3487
|
case CURLOPT_PROXY: {
|
|
3066
3488
|
VALUE proxy_url = val;
|
|
@@ -3073,6 +3495,12 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3073
3495
|
case CURLOPT_HEADER:
|
|
3074
3496
|
case CURLOPT_NOPROGRESS:
|
|
3075
3497
|
case CURLOPT_NOSIGNAL:
|
|
3498
|
+
#if HAVE_CURLOPT_PATH_AS_IS
|
|
3499
|
+
case CURLOPT_PATH_AS_IS:
|
|
3500
|
+
#endif
|
|
3501
|
+
#if HAVE_CURLOPT_PIPEWAIT
|
|
3502
|
+
case CURLOPT_PIPEWAIT:
|
|
3503
|
+
#endif
|
|
3076
3504
|
case CURLOPT_HTTPGET:
|
|
3077
3505
|
case CURLOPT_NOBODY: {
|
|
3078
3506
|
int type = rb_type(val);
|
|
@@ -3084,8 +3512,17 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3084
3512
|
} else {
|
|
3085
3513
|
value = rb_funcall(val, rb_intern("to_i"), 0);
|
|
3086
3514
|
}
|
|
3087
|
-
curl_easy_setopt(rbce->curl, option,
|
|
3515
|
+
curl_easy_setopt(rbce->curl, option, NUM2LONG(value));
|
|
3088
3516
|
} break;
|
|
3517
|
+
case CURLOPT_POST: {
|
|
3518
|
+
curl_easy_setopt(rbce->curl, CURLOPT_POST, rb_type(val) == T_TRUE);
|
|
3519
|
+
} break;
|
|
3520
|
+
case CURLOPT_MAXCONNECTS: {
|
|
3521
|
+
curl_easy_setopt(rbce->curl, CURLOPT_MAXCONNECTS, NUM2LONG(val));
|
|
3522
|
+
} break;
|
|
3523
|
+
case CURLOPT_POSTFIELDS: {
|
|
3524
|
+
curl_easy_setopt(rbce->curl, CURLOPT_POSTFIELDS, NIL_P(val) ? NULL : StringValueCStr(val));
|
|
3525
|
+
} break;
|
|
3089
3526
|
case CURLOPT_USERPWD: {
|
|
3090
3527
|
VALUE userpwd = val;
|
|
3091
3528
|
CURB_OBJECT_HSETTER(ruby_curl_easy, userpwd);
|
|
@@ -3106,14 +3543,71 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3106
3543
|
VALUE cookiejar = val;
|
|
3107
3544
|
CURB_OBJECT_HSETTER(ruby_curl_easy, cookiejar);
|
|
3108
3545
|
} break;
|
|
3546
|
+
case CURLOPT_TCP_NODELAY: {
|
|
3547
|
+
curl_easy_setopt(rbce->curl, CURLOPT_TCP_NODELAY, NUM2LONG(val));
|
|
3548
|
+
} break;
|
|
3109
3549
|
case CURLOPT_RESUME_FROM: {
|
|
3110
|
-
curl_easy_setopt(rbce->curl, CURLOPT_RESUME_FROM,
|
|
3550
|
+
curl_easy_setopt(rbce->curl, CURLOPT_RESUME_FROM, NUM2LONG(val));
|
|
3111
3551
|
} break;
|
|
3112
3552
|
case CURLOPT_FAILONERROR: {
|
|
3113
|
-
curl_easy_setopt(rbce->curl, CURLOPT_FAILONERROR,
|
|
3553
|
+
curl_easy_setopt(rbce->curl, CURLOPT_FAILONERROR, NUM2LONG(val));
|
|
3114
3554
|
} break;
|
|
3115
|
-
|
|
3555
|
+
case CURLOPT_SSL_CIPHER_LIST: {
|
|
3556
|
+
curl_easy_setopt(rbce->curl, CURLOPT_SSL_CIPHER_LIST, StringValueCStr(val));
|
|
3557
|
+
} break;
|
|
3558
|
+
case CURLOPT_FORBID_REUSE: {
|
|
3559
|
+
curl_easy_setopt(rbce->curl, CURLOPT_FORBID_REUSE, NUM2LONG(val));
|
|
3560
|
+
} break;
|
|
3561
|
+
#if HAVE_CURLOPT_GSSAPI_DELEGATION
|
|
3562
|
+
case CURLOPT_GSSAPI_DELEGATION: {
|
|
3563
|
+
curl_easy_setopt(rbce->curl, CURLOPT_GSSAPI_DELEGATION, NUM2LONG(val));
|
|
3564
|
+
} break;
|
|
3565
|
+
#endif
|
|
3566
|
+
#if HAVE_CURLOPT_UNIX_SOCKET_PATH
|
|
3567
|
+
case CURLOPT_UNIX_SOCKET_PATH: {
|
|
3568
|
+
curl_easy_setopt(rbce->curl, CURLOPT_UNIX_SOCKET_PATH, StringValueCStr(val));
|
|
3569
|
+
} break;
|
|
3570
|
+
#endif
|
|
3571
|
+
#if HAVE_CURLOPT_MAX_SEND_SPEED_LARGE
|
|
3572
|
+
case CURLOPT_MAX_SEND_SPEED_LARGE: {
|
|
3573
|
+
curl_easy_setopt(rbce->curl, CURLOPT_MAX_SEND_SPEED_LARGE, (curl_off_t) NUM2LL(val));
|
|
3574
|
+
} break;
|
|
3575
|
+
#endif
|
|
3576
|
+
#if HAVE_CURLOPT_MAX_RECV_SPEED_LARGE
|
|
3577
|
+
case CURLOPT_MAX_RECV_SPEED_LARGE: {
|
|
3578
|
+
curl_easy_setopt(rbce->curl, CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t) NUM2LL(val));
|
|
3579
|
+
} break;
|
|
3580
|
+
#endif
|
|
3581
|
+
#if HAVE_CURLOPT_MAXFILESIZE
|
|
3582
|
+
case CURLOPT_MAXFILESIZE:
|
|
3583
|
+
curl_easy_setopt(rbce->curl, CURLOPT_MAXFILESIZE, NUM2LONG(val));
|
|
3116
3584
|
break;
|
|
3585
|
+
#endif
|
|
3586
|
+
#if HAVE_CURLOPT_TCP_KEEPALIVE
|
|
3587
|
+
case CURLOPT_TCP_KEEPALIVE:
|
|
3588
|
+
curl_easy_setopt(rbce->curl, CURLOPT_TCP_KEEPALIVE, NUM2LONG(val));
|
|
3589
|
+
break;
|
|
3590
|
+
case CURLOPT_TCP_KEEPIDLE:
|
|
3591
|
+
curl_easy_setopt(rbce->curl, CURLOPT_TCP_KEEPIDLE, NUM2LONG(val));
|
|
3592
|
+
break;
|
|
3593
|
+
case CURLOPT_TCP_KEEPINTVL:
|
|
3594
|
+
curl_easy_setopt(rbce->curl, CURLOPT_TCP_KEEPINTVL, NUM2LONG(val));
|
|
3595
|
+
break;
|
|
3596
|
+
#endif
|
|
3597
|
+
#if HAVE_CURLOPT_HAPROXYPROTOCOL
|
|
3598
|
+
case CURLOPT_HAPROXYPROTOCOL:
|
|
3599
|
+
curl_easy_setopt(rbce->curl, CURLOPT_HAPROXYPROTOCOL, NUM2LONG(val));
|
|
3600
|
+
break;
|
|
3601
|
+
#endif
|
|
3602
|
+
case CURLOPT_STDERR:
|
|
3603
|
+
// libcurl requires raw FILE pointer and this should be IO object in Ruby.
|
|
3604
|
+
// Tempfile or StringIO won't work.
|
|
3605
|
+
Check_Type(val, T_FILE);
|
|
3606
|
+
GetOpenFile(val, open_f_ptr);
|
|
3607
|
+
curl_easy_setopt(rbce->curl, CURLOPT_STDERR, rb_io_stdio_file(open_f_ptr));
|
|
3608
|
+
break;
|
|
3609
|
+
default:
|
|
3610
|
+
rb_raise(rb_eTypeError, "Curb unsupported option");
|
|
3117
3611
|
}
|
|
3118
3612
|
|
|
3119
3613
|
return val;
|
|
@@ -3204,7 +3698,7 @@ static VALUE ruby_curl_easy_unescape(VALUE self, VALUE str) {
|
|
|
3204
3698
|
#if (LIBCURL_VERSION_NUM >= 0x070f04)
|
|
3205
3699
|
result = (char*)curl_easy_unescape(rbce->curl, StringValuePtr(str), (int)RSTRING_LEN(str), &rlen);
|
|
3206
3700
|
#else
|
|
3207
|
-
result = (char*)curl_unescape(StringValuePtr(str), RSTRING_LEN(str));
|
|
3701
|
+
result = (char*)curl_unescape(StringValuePtr(str), (int)RSTRING_LEN(str));
|
|
3208
3702
|
rlen = strlen(result);
|
|
3209
3703
|
#endif
|
|
3210
3704
|
|
|
@@ -3219,12 +3713,12 @@ static VALUE ruby_curl_easy_unescape(VALUE self, VALUE str) {
|
|
|
3219
3713
|
|
|
3220
3714
|
/*
|
|
3221
3715
|
* call-seq:
|
|
3222
|
-
* Curl::Easy.error(code) => String
|
|
3716
|
+
* Curl::Easy.error(code) => [ErrCode, String]
|
|
3223
3717
|
*
|
|
3224
3718
|
* translate an internal libcurl error to ruby error class
|
|
3225
3719
|
*/
|
|
3226
3720
|
static VALUE ruby_curl_easy_error_message(VALUE klass, VALUE code) {
|
|
3227
|
-
return rb_curl_easy_error(
|
|
3721
|
+
return rb_curl_easy_error(NUM2INT(code));
|
|
3228
3722
|
}
|
|
3229
3723
|
|
|
3230
3724
|
/* =================== INIT LIB =====================*/
|
|
@@ -3238,12 +3732,19 @@ void init_curb_easy() {
|
|
|
3238
3732
|
cCurlEasy = rb_define_class_under(mCurl, "Easy", rb_cObject);
|
|
3239
3733
|
|
|
3240
3734
|
/* Class methods */
|
|
3241
|
-
|
|
3735
|
+
rb_define_alloc_func(cCurlEasy, ruby_curl_easy_allocate);
|
|
3242
3736
|
rb_define_singleton_method(cCurlEasy, "error", ruby_curl_easy_error_message, 1);
|
|
3243
3737
|
|
|
3738
|
+
/* Initialize method */
|
|
3739
|
+
rb_define_method(cCurlEasy, "initialize", ruby_curl_easy_initialize, -1);
|
|
3740
|
+
|
|
3244
3741
|
/* Attributes for config next perform */
|
|
3245
3742
|
rb_define_method(cCurlEasy, "url", ruby_curl_easy_url_get, 0);
|
|
3246
3743
|
rb_define_method(cCurlEasy, "proxy_url", ruby_curl_easy_proxy_url_get, 0);
|
|
3744
|
+
|
|
3745
|
+
rb_define_method(cCurlEasy, "proxy_headers=", ruby_curl_easy_proxy_headers_set, 1);
|
|
3746
|
+
rb_define_method(cCurlEasy, "proxy_headers", ruby_curl_easy_proxy_headers_get, 0);
|
|
3747
|
+
|
|
3247
3748
|
rb_define_method(cCurlEasy, "headers=", ruby_curl_easy_headers_set, 1);
|
|
3248
3749
|
rb_define_method(cCurlEasy, "headers", ruby_curl_easy_headers_get, 0);
|
|
3249
3750
|
rb_define_method(cCurlEasy, "interface", ruby_curl_easy_interface_get, 0);
|
|
@@ -3270,6 +3771,8 @@ void init_curb_easy() {
|
|
|
3270
3771
|
rb_define_method(cCurlEasy, "put_data=", ruby_curl_easy_put_data_set, 1);
|
|
3271
3772
|
rb_define_method(cCurlEasy, "ftp_commands=", ruby_curl_easy_ftp_commands_set, 1);
|
|
3272
3773
|
rb_define_method(cCurlEasy, "ftp_commands", ruby_curl_easy_ftp_commands_get, 0);
|
|
3774
|
+
rb_define_method(cCurlEasy, "resolve=", ruby_curl_easy_resolve_set, 1);
|
|
3775
|
+
rb_define_method(cCurlEasy, "resolve", ruby_curl_easy_resolve_get, 0);
|
|
3273
3776
|
|
|
3274
3777
|
rb_define_method(cCurlEasy, "local_port=", ruby_curl_easy_local_port_set, 1);
|
|
3275
3778
|
rb_define_method(cCurlEasy, "local_port", ruby_curl_easy_local_port_get, 0);
|
|
@@ -3287,8 +3790,12 @@ void init_curb_easy() {
|
|
|
3287
3790
|
rb_define_method(cCurlEasy, "max_redirects", ruby_curl_easy_max_redirects_get, 0);
|
|
3288
3791
|
rb_define_method(cCurlEasy, "timeout=", ruby_curl_easy_timeout_set, 1);
|
|
3289
3792
|
rb_define_method(cCurlEasy, "timeout", ruby_curl_easy_timeout_get, 0);
|
|
3793
|
+
rb_define_method(cCurlEasy, "timeout_ms=", ruby_curl_easy_timeout_ms_set, 1);
|
|
3794
|
+
rb_define_method(cCurlEasy, "timeout_ms", ruby_curl_easy_timeout_ms_get, 0);
|
|
3290
3795
|
rb_define_method(cCurlEasy, "connect_timeout=", ruby_curl_easy_connect_timeout_set, 1);
|
|
3291
3796
|
rb_define_method(cCurlEasy, "connect_timeout", ruby_curl_easy_connect_timeout_get, 0);
|
|
3797
|
+
rb_define_method(cCurlEasy, "connect_timeout_ms=", ruby_curl_easy_connect_timeout_ms_set, 1);
|
|
3798
|
+
rb_define_method(cCurlEasy, "connect_timeout_ms", ruby_curl_easy_connect_timeout_ms_get, 0);
|
|
3292
3799
|
rb_define_method(cCurlEasy, "dns_cache_timeout=", ruby_curl_easy_dns_cache_timeout_set, 1);
|
|
3293
3800
|
rb_define_method(cCurlEasy, "dns_cache_timeout", ruby_curl_easy_dns_cache_timeout_get, 0);
|
|
3294
3801
|
rb_define_method(cCurlEasy, "ftp_response_timeout=", ruby_curl_easy_ftp_response_timeout_set, 1);
|
|
@@ -3297,6 +3804,10 @@ void init_curb_easy() {
|
|
|
3297
3804
|
rb_define_method(cCurlEasy, "low_speed_limit", ruby_curl_easy_low_speed_limit_get, 0);
|
|
3298
3805
|
rb_define_method(cCurlEasy, "low_speed_time=", ruby_curl_easy_low_speed_time_set, 1);
|
|
3299
3806
|
rb_define_method(cCurlEasy, "low_speed_time", ruby_curl_easy_low_speed_time_get, 0);
|
|
3807
|
+
rb_define_method(cCurlEasy, "max_send_speed_large=", ruby_curl_easy_max_send_speed_large_set, 1);
|
|
3808
|
+
rb_define_method(cCurlEasy, "max_send_speed_large", ruby_curl_easy_max_send_speed_large_get, 0);
|
|
3809
|
+
rb_define_method(cCurlEasy, "max_recv_speed_large=", ruby_curl_easy_max_recv_speed_large_set, 1);
|
|
3810
|
+
rb_define_method(cCurlEasy, "max_recv_speed_large", ruby_curl_easy_max_recv_speed_large_get, 0);
|
|
3300
3811
|
rb_define_method(cCurlEasy, "ssl_version=", ruby_curl_easy_ssl_version_set, 1);
|
|
3301
3812
|
rb_define_method(cCurlEasy, "ssl_version", ruby_curl_easy_ssl_version_get, 0);
|
|
3302
3813
|
rb_define_method(cCurlEasy, "use_ssl=", ruby_curl_easy_use_ssl_set, 1);
|
|
@@ -3364,6 +3875,9 @@ void init_curb_easy() {
|
|
|
3364
3875
|
rb_define_method(cCurlEasy, "total_time", ruby_curl_easy_total_time_get, 0);
|
|
3365
3876
|
rb_define_method(cCurlEasy, "name_lookup_time", ruby_curl_easy_name_lookup_time_get, 0);
|
|
3366
3877
|
rb_define_method(cCurlEasy, "connect_time", ruby_curl_easy_connect_time_get, 0);
|
|
3878
|
+
#if defined(HAVE_CURLINFO_APPCONNECT_TIME)
|
|
3879
|
+
rb_define_method(cCurlEasy, "app_connect_time", ruby_curl_easy_app_connect_time_get, 0);
|
|
3880
|
+
#endif
|
|
3367
3881
|
rb_define_method(cCurlEasy, "pre_transfer_time", ruby_curl_easy_pre_transfer_time_get, 0);
|
|
3368
3882
|
rb_define_method(cCurlEasy, "start_transfer_time", ruby_curl_easy_start_transfer_time_get, 0);
|
|
3369
3883
|
rb_define_method(cCurlEasy, "redirect_time", ruby_curl_easy_redirect_time_get, 0);
|
|
@@ -3381,6 +3895,7 @@ void init_curb_easy() {
|
|
|
3381
3895
|
rb_define_method(cCurlEasy, "content_type", ruby_curl_easy_content_type_get, 0);
|
|
3382
3896
|
rb_define_method(cCurlEasy, "os_errno", ruby_curl_easy_os_errno_get, 0);
|
|
3383
3897
|
rb_define_method(cCurlEasy, "num_connects", ruby_curl_easy_num_connects_get, 0);
|
|
3898
|
+
rb_define_method(cCurlEasy, "cookielist", ruby_curl_easy_cookielist_get, 0);
|
|
3384
3899
|
rb_define_method(cCurlEasy, "ftp_entry_path", ruby_curl_easy_ftp_entry_path_get, 0);
|
|
3385
3900
|
|
|
3386
3901
|
rb_define_method(cCurlEasy, "close", ruby_curl_easy_close, 0);
|