curb 0.9.3 → 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.markdown +90 -22
- data/Rakefile +35 -20
- data/ext/banned.h +32 -0
- data/ext/curb.c +190 -14
- data/ext/curb.h +18 -5
- data/ext/curb_easy.c +514 -98
- data/ext/curb_easy.h +7 -0
- data/ext/curb_errors.c +86 -0
- data/ext/curb_macros.h +12 -0
- data/ext/curb_multi.c +178 -229
- data/ext/curb_multi.h +0 -1
- data/ext/curb_postfield.c +9 -7
- data/ext/curb_upload.c +1 -0
- data/ext/extconf.rb +76 -6
- data/lib/curb.rb +1 -0
- data/lib/curl/easy.rb +16 -9
- data/lib/curl/multi.rb +60 -14
- data/lib/curl.rb +20 -12
- data/tests/bug_crash_on_debug.rb +14 -28
- data/tests/bug_crash_on_progress.rb +7 -31
- data/tests/bug_curb_easy_blocks_ruby_threads.rb +8 -13
- data/tests/bug_curb_easy_post_with_string_no_content_length_header.rb +6 -30
- data/tests/bug_follow_redirect_288.rb +83 -0
- data/tests/bug_instance_post_differs_from_class_post.rb +3 -5
- data/tests/bug_issue277.rb +32 -0
- data/tests/bug_multi_segfault.rb +1 -0
- data/tests/bug_raise_on_callback.rb +29 -0
- data/tests/helper.rb +122 -13
- data/tests/tc_curl.rb +31 -1
- data/tests/tc_curl_download.rb +3 -3
- data/tests/tc_curl_easy.rb +167 -46
- data/tests/tc_curl_easy_resolve.rb +16 -0
- data/tests/tc_curl_maxfilesize.rb +12 -0
- data/tests/tc_curl_multi.rb +161 -18
- data/tests/tc_curl_postfield.rb +29 -29
- data/tests/tc_curl_protocols.rb +37 -0
- data/tests/timeout.rb +21 -5
- metadata +20 -8
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
|
-
static VALUE callback_exception(VALUE unused) {
|
37
|
+
static VALUE callback_exception(VALUE unused, VALUE exception) {
|
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,
|
@@ -223,12 +229,31 @@ static void ruby_curl_easy_free(ruby_curl_easy *rbce) {
|
|
223
229
|
curl_slist_free_all(rbce->curl_headers);
|
224
230
|
}
|
225
231
|
|
232
|
+
if (rbce->curl_proxy_headers) {
|
233
|
+
curl_slist_free_all(rbce->curl_proxy_headers);
|
234
|
+
}
|
235
|
+
|
226
236
|
if (rbce->curl_ftp_commands) {
|
227
237
|
curl_slist_free_all(rbce->curl_ftp_commands);
|
228
238
|
}
|
229
239
|
|
240
|
+
if (rbce->curl_resolve) {
|
241
|
+
curl_slist_free_all(rbce->curl_resolve);
|
242
|
+
}
|
243
|
+
|
230
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);
|
231
255
|
curl_easy_cleanup(rbce->curl);
|
256
|
+
rbce->curl = NULL;
|
232
257
|
}
|
233
258
|
}
|
234
259
|
|
@@ -243,8 +268,12 @@ void curl_easy_free(ruby_curl_easy *rbce) {
|
|
243
268
|
static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
244
269
|
rbce->opts = rb_hash_new();
|
245
270
|
|
271
|
+
memset(rbce->err_buf, 0, sizeof(rbce->err_buf));
|
272
|
+
|
246
273
|
rbce->curl_headers = NULL;
|
274
|
+
rbce->curl_proxy_headers = NULL;
|
247
275
|
rbce->curl_ftp_commands = NULL;
|
276
|
+
rbce->curl_resolve = NULL;
|
248
277
|
|
249
278
|
/* various-typed opts */
|
250
279
|
rbce->local_port = 0;
|
@@ -262,6 +291,8 @@ static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
|
262
291
|
rbce->ftp_response_timeout = 0;
|
263
292
|
rbce->low_speed_limit = 0;
|
264
293
|
rbce->low_speed_time = 0;
|
294
|
+
rbce->max_send_speed_large = 0;
|
295
|
+
rbce->max_recv_speed_large = 0;
|
265
296
|
rbce->ssl_version = -1;
|
266
297
|
rbce->use_ssl = -1;
|
267
298
|
rbce->ftp_filemethod = -1;
|
@@ -283,25 +314,37 @@ static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
|
283
314
|
rbce->callback_active = 0;
|
284
315
|
}
|
285
316
|
|
317
|
+
/*
|
318
|
+
* Allocate space for a Curl::Easy instance.
|
319
|
+
*/
|
320
|
+
static VALUE ruby_curl_easy_allocate(VALUE klass) {
|
321
|
+
ruby_curl_easy *rbce;
|
322
|
+
rbce = ALLOC(ruby_curl_easy);
|
323
|
+
rbce->curl = NULL;
|
324
|
+
rbce->opts = Qnil;
|
325
|
+
rbce->multi = Qnil;
|
326
|
+
ruby_curl_easy_zero(rbce);
|
327
|
+
return Data_Wrap_Struct(klass, curl_easy_mark, curl_easy_free, rbce);
|
328
|
+
}
|
329
|
+
|
286
330
|
/*
|
287
331
|
* call-seq:
|
288
|
-
* Curl::Easy.new =>
|
289
|
-
* Curl::Easy.new(url = nil) =>
|
290
|
-
* Curl::Easy.new(url = nil) { |self| ... } =>
|
332
|
+
* Curl::Easy.new => #<Curl::Easy...>
|
333
|
+
* Curl::Easy.new(url = nil) => #<Curl::Easy...>
|
334
|
+
* Curl::Easy.new(url = nil) { |self| ... } => #<Curl::Easy...>
|
291
335
|
*
|
292
|
-
*
|
336
|
+
* Initialize a new Curl::Easy instance, optionally supplying the URL.
|
293
337
|
* The block form allows further configuration to be supplied before
|
294
338
|
* the instance is returned.
|
295
339
|
*/
|
296
|
-
static VALUE
|
340
|
+
static VALUE ruby_curl_easy_initialize(int argc, VALUE *argv, VALUE self) {
|
297
341
|
CURLcode ecode;
|
298
342
|
VALUE url, blk;
|
299
|
-
VALUE new_curl;
|
300
343
|
ruby_curl_easy *rbce;
|
301
344
|
|
302
345
|
rb_scan_args(argc, argv, "01&", &url, &blk);
|
303
346
|
|
304
|
-
|
347
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
305
348
|
|
306
349
|
/* handler */
|
307
350
|
rbce->curl = curl_easy_init();
|
@@ -309,32 +352,32 @@ static VALUE ruby_curl_easy_new(int argc, VALUE *argv, VALUE klass) {
|
|
309
352
|
rb_raise(eCurlErrFailedInit, "Failed to initialize easy handle");
|
310
353
|
}
|
311
354
|
|
312
|
-
new_curl = Data_Wrap_Struct(klass, curl_easy_mark, curl_easy_free, rbce);
|
313
|
-
|
314
355
|
rbce->multi = Qnil;
|
315
356
|
rbce->opts = Qnil;
|
316
357
|
|
317
358
|
ruby_curl_easy_zero(rbce);
|
318
359
|
|
360
|
+
curl_easy_setopt(rbce->curl, CURLOPT_ERRORBUFFER, &rbce->err_buf);
|
361
|
+
|
319
362
|
rb_easy_set("url", url);
|
320
363
|
|
321
|
-
/* set the
|
322
|
-
ecode = curl_easy_setopt(rbce->curl, CURLOPT_PRIVATE, (void*)
|
364
|
+
/* set the pointer to the curl handle */
|
365
|
+
ecode = curl_easy_setopt(rbce->curl, CURLOPT_PRIVATE, (void*)self);
|
323
366
|
if (ecode != CURLE_OK) {
|
324
367
|
raise_curl_easy_error_exception(ecode);
|
325
368
|
}
|
326
369
|
|
327
370
|
if (blk != Qnil) {
|
328
|
-
rb_funcall(blk, idCall, 1,
|
371
|
+
rb_funcall(blk, idCall, 1, self);
|
329
372
|
}
|
330
373
|
|
331
|
-
return
|
374
|
+
return self;
|
332
375
|
}
|
333
376
|
|
334
377
|
/*
|
335
378
|
* call-seq:
|
336
|
-
* easy.clone =>
|
337
|
-
* easy.dup =>
|
379
|
+
* easy.clone => <easy clone>
|
380
|
+
* easy.dup => <easy clone>
|
338
381
|
*
|
339
382
|
* Clone this Curl::Easy instance, creating a new instance.
|
340
383
|
* This method duplicates the underlying CURL* handle.
|
@@ -348,7 +391,11 @@ static VALUE ruby_curl_easy_clone(VALUE self) {
|
|
348
391
|
memcpy(newrbce, rbce, sizeof(ruby_curl_easy));
|
349
392
|
newrbce->curl = curl_easy_duphandle(rbce->curl);
|
350
393
|
newrbce->curl_headers = NULL;
|
394
|
+
newrbce->curl_proxy_headers = NULL;
|
351
395
|
newrbce->curl_ftp_commands = NULL;
|
396
|
+
newrbce->curl_resolve = NULL;
|
397
|
+
|
398
|
+
curl_easy_setopt(rbce->curl, CURLOPT_ERRORBUFFER, &rbce->err_buf);
|
352
399
|
|
353
400
|
return Data_Wrap_Struct(cCurlEasy, curl_easy_mark, curl_easy_free, newrbce);
|
354
401
|
}
|
@@ -358,7 +405,7 @@ static VALUE ruby_curl_easy_clone(VALUE self) {
|
|
358
405
|
* easy.close => nil
|
359
406
|
*
|
360
407
|
* Close the Curl::Easy instance. Any open connections are closed
|
361
|
-
* The easy handle is reinitialized. If a previous multi handle was
|
408
|
+
* The easy handle is reinitialized. If a previous multi handle was
|
362
409
|
* open it is set to nil and will be cleared after a GC.
|
363
410
|
*/
|
364
411
|
static VALUE ruby_curl_easy_close(VALUE self) {
|
@@ -419,7 +466,9 @@ static VALUE ruby_curl_easy_reset(VALUE self) {
|
|
419
466
|
curl_easy_reset(rbce->curl);
|
420
467
|
ruby_curl_easy_zero(rbce);
|
421
468
|
|
422
|
-
|
469
|
+
curl_easy_setopt(rbce->curl, CURLOPT_ERRORBUFFER, &rbce->err_buf);
|
470
|
+
|
471
|
+
/* reset clobbers the private setting, so reset it to self */
|
423
472
|
ecode = curl_easy_setopt(rbce->curl, CURLOPT_PRIVATE, (void*)self);
|
424
473
|
if (ecode != CURLE_OK) {
|
425
474
|
raise_curl_easy_error_exception(ecode);
|
@@ -431,6 +480,12 @@ static VALUE ruby_curl_easy_reset(VALUE self) {
|
|
431
480
|
rbce->curl_headers = NULL;
|
432
481
|
}
|
433
482
|
|
483
|
+
/* Free everything up */
|
484
|
+
if (rbce->curl_proxy_headers) {
|
485
|
+
curl_slist_free_all(rbce->curl_proxy_headers);
|
486
|
+
rbce->curl_proxy_headers = NULL;
|
487
|
+
}
|
488
|
+
|
434
489
|
return opts_dup;
|
435
490
|
}
|
436
491
|
|
@@ -483,6 +538,10 @@ static VALUE ruby_curl_easy_headers_set(VALUE self, VALUE headers) {
|
|
483
538
|
CURB_OBJECT_HSETTER(ruby_curl_easy, headers);
|
484
539
|
}
|
485
540
|
|
541
|
+
static VALUE ruby_curl_easy_proxy_headers_set(VALUE self, VALUE proxy_headers) {
|
542
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, proxy_headers);
|
543
|
+
}
|
544
|
+
|
486
545
|
/*
|
487
546
|
* call-seq:
|
488
547
|
* easy.headers => Hash, Array or Str
|
@@ -493,11 +552,46 @@ static VALUE ruby_curl_easy_headers_get(VALUE self) {
|
|
493
552
|
ruby_curl_easy *rbce;
|
494
553
|
VALUE headers;
|
495
554
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
496
|
-
headers = rb_easy_get("headers");//rb_hash_aref(rbce->opts, rb_intern("headers"));
|
555
|
+
headers = rb_easy_get("headers");//rb_hash_aref(rbce->opts, rb_intern("headers"));
|
497
556
|
if (headers == Qnil) { headers = rb_easy_set("headers", rb_hash_new()); }
|
498
557
|
return headers;
|
499
558
|
}
|
500
559
|
|
560
|
+
/*
|
561
|
+
* call-seq:
|
562
|
+
* easy.proxy_headers = "Header: val" => "Header: val"
|
563
|
+
* easy.proxy_headers = {"Header" => "val" ..., "Header" => "val"} => {"Header: val", ...}
|
564
|
+
* easy.proxy_headers = ["Header: val" ..., "Header: val"] => ["Header: val", ...]
|
565
|
+
*
|
566
|
+
*
|
567
|
+
* For example to set a standard or custom header:
|
568
|
+
*
|
569
|
+
* easy.proxy_headers["MyHeader"] = "myval"
|
570
|
+
*
|
571
|
+
* To remove a standard header (this is useful when removing libcurls default
|
572
|
+
* 'Expect: 100-Continue' header when using HTTP form posts):
|
573
|
+
*
|
574
|
+
* easy.proxy_headers["Expect"] = ''
|
575
|
+
*
|
576
|
+
* Anything passed to libcurl as a header will be converted to a string during
|
577
|
+
* the perform step.
|
578
|
+
*/
|
579
|
+
|
580
|
+
/*
|
581
|
+
* call-seq:
|
582
|
+
* easy.proxy_headers => Hash, Array or Str
|
583
|
+
*
|
584
|
+
* Obtain the custom HTTP proxy_headers for following requests.
|
585
|
+
*/
|
586
|
+
static VALUE ruby_curl_easy_proxy_headers_get(VALUE self) {
|
587
|
+
ruby_curl_easy *rbce;
|
588
|
+
VALUE proxy_headers;
|
589
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
590
|
+
proxy_headers = rb_easy_get("proxy_headers");//rb_hash_aref(rbce->opts, rb_intern("proxy_headers"));
|
591
|
+
if (proxy_headers == Qnil) { proxy_headers = rb_easy_set("proxy_headers", rb_hash_new()); }
|
592
|
+
return proxy_headers;
|
593
|
+
}
|
594
|
+
|
501
595
|
/*
|
502
596
|
* call-seq:
|
503
597
|
* easy.interface => string
|
@@ -705,29 +799,29 @@ static VALUE ruby_curl_easy_useragent_get(VALUE self) {
|
|
705
799
|
/*
|
706
800
|
* call-seq:
|
707
801
|
* easy.post_body = "some=form%20data&to=send" => string or nil
|
708
|
-
*
|
802
|
+
*
|
709
803
|
* Sets the POST body of this Curl::Easy instance. This is expected to be
|
710
804
|
* URL encoded; no additional processing or encoding is done on the string.
|
711
805
|
* The content-type header will be set to application/x-www-form-urlencoded.
|
712
|
-
*
|
806
|
+
*
|
713
807
|
* This is handy if you want to perform a POST against a Curl::Multi instance.
|
714
808
|
*/
|
715
809
|
static VALUE ruby_curl_easy_post_body_set(VALUE self, VALUE post_body) {
|
716
810
|
ruby_curl_easy *rbce;
|
717
811
|
CURL *curl;
|
718
|
-
|
812
|
+
|
719
813
|
char *data;
|
720
814
|
long len;
|
721
815
|
|
722
816
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
723
|
-
|
817
|
+
|
724
818
|
curl = rbce->curl;
|
725
|
-
|
819
|
+
|
726
820
|
if ( post_body == Qnil ) {
|
727
821
|
rb_easy_del("postdata_buffer");
|
728
822
|
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
|
729
|
-
|
730
|
-
} else {
|
823
|
+
|
824
|
+
} else {
|
731
825
|
if (rb_type(post_body) == T_STRING) {
|
732
826
|
data = StringValuePtr(post_body);
|
733
827
|
len = RSTRING_LEN(post_body);
|
@@ -740,19 +834,19 @@ static VALUE ruby_curl_easy_post_body_set(VALUE self, VALUE post_body) {
|
|
740
834
|
else {
|
741
835
|
rb_raise(rb_eRuntimeError, "post data must respond_to .to_s");
|
742
836
|
}
|
743
|
-
|
744
|
-
// Store the string, since it has to hang around for the duration of the
|
837
|
+
|
838
|
+
// Store the string, since it has to hang around for the duration of the
|
745
839
|
// request. See CURLOPT_POSTFIELDS in the libcurl docs.
|
746
840
|
//rbce->postdata_buffer = post_body;
|
747
841
|
rb_easy_set("postdata_buffer", post_body);
|
748
|
-
|
842
|
+
|
749
843
|
curl_easy_setopt(curl, CURLOPT_POST, 1);
|
750
844
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
|
751
845
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
|
752
|
-
|
846
|
+
|
753
847
|
return post_body;
|
754
848
|
}
|
755
|
-
|
849
|
+
|
756
850
|
return Qnil;
|
757
851
|
}
|
758
852
|
|
@@ -769,7 +863,7 @@ static VALUE ruby_curl_easy_post_body_get(VALUE self) {
|
|
769
863
|
/*
|
770
864
|
* call-seq:
|
771
865
|
* easy.put_data = data => ""
|
772
|
-
*
|
866
|
+
*
|
773
867
|
* Points this Curl::Easy instance to data to be uploaded via PUT. This
|
774
868
|
* sets the request to a PUT type request - useful if you want to PUT via
|
775
869
|
* a multi handle.
|
@@ -801,7 +895,7 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
|
|
801
895
|
curl_easy_setopt(curl, CURLOPT_SEEKDATA, rbce);
|
802
896
|
#endif
|
803
897
|
|
804
|
-
/*
|
898
|
+
/*
|
805
899
|
* we need to set specific headers for the PUT to work... so
|
806
900
|
* convert the internal headers structure to a HASH if one is set
|
807
901
|
*/
|
@@ -815,7 +909,7 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
|
|
815
909
|
if (NIL_P(data)) { return data; }
|
816
910
|
|
817
911
|
headers = rb_easy_get("headers");
|
818
|
-
if( headers == Qnil ) {
|
912
|
+
if( headers == Qnil ) {
|
819
913
|
headers = rb_hash_new();
|
820
914
|
}
|
821
915
|
|
@@ -863,13 +957,32 @@ static VALUE ruby_curl_easy_ftp_commands_set(VALUE self, VALUE ftp_commands) {
|
|
863
957
|
}
|
864
958
|
|
865
959
|
/*
|
866
|
-
* call-seq
|
960
|
+
* call-seq:
|
867
961
|
* easy.ftp_commands => array or nil
|
868
962
|
*/
|
869
963
|
static VALUE ruby_curl_easy_ftp_commands_get(VALUE self) {
|
870
964
|
CURB_OBJECT_HGETTER(ruby_curl_easy, ftp_commands);
|
871
965
|
}
|
872
966
|
|
967
|
+
/*
|
968
|
+
* call-seq:
|
969
|
+
* easy.resolve = [ "example.com:80:127.0.0.1" ] => [ "example.com:80:127.0.0.1" ]
|
970
|
+
*
|
971
|
+
* Set the resolve list to statically resolve hostnames to IP addresses,
|
972
|
+
* bypassing DNS for matching hostname/port combinations.
|
973
|
+
*/
|
974
|
+
static VALUE ruby_curl_easy_resolve_set(VALUE self, VALUE resolve) {
|
975
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, resolve);
|
976
|
+
}
|
977
|
+
|
978
|
+
/*
|
979
|
+
* call-seq:
|
980
|
+
* easy.resolve => array or nil
|
981
|
+
*/
|
982
|
+
static VALUE ruby_curl_easy_resolve_get(VALUE self) {
|
983
|
+
CURB_OBJECT_HGETTER(ruby_curl_easy, resolve);
|
984
|
+
}
|
985
|
+
|
873
986
|
/* ================== IMMED ATTRS ==================*/
|
874
987
|
|
875
988
|
/*
|
@@ -980,7 +1093,7 @@ static VALUE ruby_curl_easy_proxy_type_get(VALUE self) {
|
|
980
1093
|
(!strncmp("ntlm",node,4)) ? CURLAUTH_NTLM : \
|
981
1094
|
(!strncmp("anysafe",node,7)) ? CURLAUTH_ANYSAFE : \
|
982
1095
|
(!strncmp("any",node,3)) ? CURLAUTH_ANY : 0
|
983
|
-
#else
|
1096
|
+
#else
|
984
1097
|
#define CURL_HTTPAUTH_STR_TO_NUM(node) \
|
985
1098
|
(!strncmp("basic",node,5)) ? CURLAUTH_BASIC : \
|
986
1099
|
(!strncmp("digest",node,6)) ? CURLAUTH_DIGEST : \
|
@@ -1012,7 +1125,7 @@ static VALUE ruby_curl_easy_http_auth_types_set(int argc, VALUE *argv, VALUE sel
|
|
1012
1125
|
|
1013
1126
|
if (len == 1 && (rb_ary_entry(args_ary,0) == Qnil || TYPE(rb_ary_entry(args_ary,0)) == T_FIXNUM ||
|
1014
1127
|
TYPE(rb_ary_entry(args_ary,0)) == T_BIGNUM)) {
|
1015
|
-
if (rb_ary_entry(args_ary,0) == Qnil) {
|
1128
|
+
if (rb_ary_entry(args_ary,0) == Qnil) {
|
1016
1129
|
rbce->http_auth_types = 0;
|
1017
1130
|
}
|
1018
1131
|
else {
|
@@ -1094,7 +1207,7 @@ static VALUE ruby_curl_easy_max_redirects_get(VALUE self) {
|
|
1094
1207
|
|
1095
1208
|
/*
|
1096
1209
|
* call-seq:
|
1097
|
-
* easy.timeout = fixnum or nil
|
1210
|
+
* easy.timeout = float, fixnum or nil => numeric
|
1098
1211
|
*
|
1099
1212
|
* Set the maximum time in seconds that you allow the libcurl transfer
|
1100
1213
|
* operation to take. Normally, name lookups can take a considerable time
|
@@ -1103,20 +1216,39 @@ static VALUE ruby_curl_easy_max_redirects_get(VALUE self) {
|
|
1103
1216
|
*
|
1104
1217
|
* Set to nil (or zero) to disable timeout (it will then only timeout
|
1105
1218
|
* on the system's internal timeouts).
|
1219
|
+
*
|
1220
|
+
* Uses timeout_ms internally instead of timeout because it allows for
|
1221
|
+
* better precision and libcurl will use the last set value when both
|
1222
|
+
* timeout and timeout_ms are set.
|
1223
|
+
*
|
1106
1224
|
*/
|
1107
|
-
static VALUE ruby_curl_easy_timeout_set(VALUE self, VALUE
|
1108
|
-
|
1225
|
+
static VALUE ruby_curl_easy_timeout_set(VALUE self, VALUE timeout_s) {
|
1226
|
+
ruby_curl_easy *rbce;
|
1227
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
1228
|
+
|
1229
|
+
if (Qnil == timeout_s || NUM2DBL(timeout_s) <= 0.0) {
|
1230
|
+
rbce->timeout_ms = 0;
|
1231
|
+
} else {
|
1232
|
+
rbce->timeout_ms = (unsigned long)(NUM2DBL(timeout_s) * 1000);
|
1233
|
+
}
|
1234
|
+
|
1235
|
+
return DBL2NUM(rbce->timeout_ms / 1000.0);
|
1109
1236
|
}
|
1110
1237
|
|
1111
1238
|
/*
|
1112
1239
|
* call-seq:
|
1113
|
-
* easy.timeout =>
|
1240
|
+
* easy.timeout => numeric
|
1114
1241
|
*
|
1115
1242
|
* Obtain the maximum time in seconds that you allow the libcurl transfer
|
1116
1243
|
* operation to take.
|
1244
|
+
*
|
1245
|
+
* Uses timeout_ms internally instead of timeout.
|
1246
|
+
*
|
1117
1247
|
*/
|
1118
|
-
static VALUE ruby_curl_easy_timeout_get(VALUE self
|
1119
|
-
|
1248
|
+
static VALUE ruby_curl_easy_timeout_get(VALUE self) {
|
1249
|
+
ruby_curl_easy *rbce;
|
1250
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
1251
|
+
return DBL2NUM(rbce->timeout_ms / 1000.0);
|
1120
1252
|
}
|
1121
1253
|
|
1122
1254
|
/*
|
@@ -1132,7 +1264,16 @@ static VALUE ruby_curl_easy_timeout_get(VALUE self, VALUE timeout) {
|
|
1132
1264
|
* on the system's internal timeouts).
|
1133
1265
|
*/
|
1134
1266
|
static VALUE ruby_curl_easy_timeout_ms_set(VALUE self, VALUE timeout_ms) {
|
1135
|
-
|
1267
|
+
ruby_curl_easy *rbce;
|
1268
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
1269
|
+
|
1270
|
+
if (Qnil == timeout_ms || NUM2DBL(timeout_ms) <= 0.0) {
|
1271
|
+
rbce->timeout_ms = 0;
|
1272
|
+
} else {
|
1273
|
+
rbce->timeout_ms = NUM2ULONG(timeout_ms);
|
1274
|
+
}
|
1275
|
+
|
1276
|
+
return ULONG2NUM(rbce->timeout_ms);
|
1136
1277
|
}
|
1137
1278
|
|
1138
1279
|
/*
|
@@ -1142,8 +1283,10 @@ static VALUE ruby_curl_easy_timeout_ms_set(VALUE self, VALUE timeout_ms) {
|
|
1142
1283
|
* Obtain the maximum time in milliseconds that you allow the libcurl transfer
|
1143
1284
|
* operation to take.
|
1144
1285
|
*/
|
1145
|
-
static VALUE ruby_curl_easy_timeout_ms_get(VALUE self
|
1146
|
-
|
1286
|
+
static VALUE ruby_curl_easy_timeout_ms_get(VALUE self) {
|
1287
|
+
ruby_curl_easy *rbce;
|
1288
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
1289
|
+
return LONG2NUM(rbce->timeout_ms);
|
1147
1290
|
}
|
1148
1291
|
|
1149
1292
|
/*
|
@@ -1168,7 +1311,7 @@ static VALUE ruby_curl_easy_connect_timeout_set(VALUE self, VALUE connect_timeou
|
|
1168
1311
|
* Obtain the maximum time in seconds that you allow the connection to the
|
1169
1312
|
* server to take.
|
1170
1313
|
*/
|
1171
|
-
static VALUE ruby_curl_easy_connect_timeout_get(VALUE self
|
1314
|
+
static VALUE ruby_curl_easy_connect_timeout_get(VALUE self) {
|
1172
1315
|
CURB_IMMED_GETTER(ruby_curl_easy, connect_timeout, 0);
|
1173
1316
|
}
|
1174
1317
|
|
@@ -1194,7 +1337,7 @@ static VALUE ruby_curl_easy_connect_timeout_ms_set(VALUE self, VALUE connect_tim
|
|
1194
1337
|
* Obtain the maximum time in milliseconds that you allow the connection to the
|
1195
1338
|
* server to take.
|
1196
1339
|
*/
|
1197
|
-
static VALUE ruby_curl_easy_connect_timeout_ms_get(VALUE self
|
1340
|
+
static VALUE ruby_curl_easy_connect_timeout_ms_get(VALUE self) {
|
1198
1341
|
CURB_IMMED_GETTER(ruby_curl_easy, connect_timeout_ms, 0);
|
1199
1342
|
}
|
1200
1343
|
|
@@ -1217,7 +1360,7 @@ static VALUE ruby_curl_easy_dns_cache_timeout_set(VALUE self, VALUE dns_cache_ti
|
|
1217
1360
|
*
|
1218
1361
|
* Obtain the dns cache timeout in seconds.
|
1219
1362
|
*/
|
1220
|
-
static VALUE ruby_curl_easy_dns_cache_timeout_get(VALUE self
|
1363
|
+
static VALUE ruby_curl_easy_dns_cache_timeout_get(VALUE self) {
|
1221
1364
|
CURB_IMMED_GETTER(ruby_curl_easy, dns_cache_timeout, -1);
|
1222
1365
|
}
|
1223
1366
|
|
@@ -1244,7 +1387,7 @@ static VALUE ruby_curl_easy_ftp_response_timeout_set(VALUE self, VALUE ftp_respo
|
|
1244
1387
|
*
|
1245
1388
|
* Obtain the maximum time that libcurl will wait for FTP command responses.
|
1246
1389
|
*/
|
1247
|
-
static VALUE ruby_curl_easy_ftp_response_timeout_get(VALUE self
|
1390
|
+
static VALUE ruby_curl_easy_ftp_response_timeout_get(VALUE self) {
|
1248
1391
|
CURB_IMMED_GETTER(ruby_curl_easy, ftp_response_timeout, 0);
|
1249
1392
|
}
|
1250
1393
|
|
@@ -1267,7 +1410,7 @@ static VALUE ruby_curl_easy_low_speed_limit_set(VALUE self, VALUE low_speed_limi
|
|
1267
1410
|
* Obtain the minimum transfer speed over +low_speed+time+ below which the
|
1268
1411
|
* transfer will be aborted.
|
1269
1412
|
*/
|
1270
|
-
static VALUE ruby_curl_easy_low_speed_limit_get(VALUE self
|
1413
|
+
static VALUE ruby_curl_easy_low_speed_limit_get(VALUE self) {
|
1271
1414
|
CURB_IMMED_GETTER(ruby_curl_easy, low_speed_limit, 0);
|
1272
1415
|
}
|
1273
1416
|
|
@@ -1289,10 +1432,50 @@ static VALUE ruby_curl_easy_low_speed_time_set(VALUE self, VALUE low_speed_time)
|
|
1289
1432
|
* Obtain the time that the transfer should be below +low_speed_limit+ for
|
1290
1433
|
* the library to abort it.
|
1291
1434
|
*/
|
1292
|
-
static VALUE ruby_curl_easy_low_speed_time_get(VALUE self
|
1435
|
+
static VALUE ruby_curl_easy_low_speed_time_get(VALUE self) {
|
1293
1436
|
CURB_IMMED_GETTER(ruby_curl_easy, low_speed_time, 0);
|
1294
1437
|
}
|
1295
1438
|
|
1439
|
+
/*
|
1440
|
+
* call-seq:
|
1441
|
+
* easy.max_send_speed_large = fixnum or nil => fixnum or nil
|
1442
|
+
*
|
1443
|
+
* Set the maximal sending transfer speed (in bytes per second)
|
1444
|
+
*/
|
1445
|
+
static VALUE ruby_curl_easy_max_send_speed_large_set(VALUE self, VALUE max_send_speed_large) {
|
1446
|
+
CURB_IMMED_SETTER(ruby_curl_easy, max_send_speed_large, 0);
|
1447
|
+
}
|
1448
|
+
|
1449
|
+
/*
|
1450
|
+
* call-seq:
|
1451
|
+
* easy.max_send_speed_large = fixnum or nil => fixnum or nil
|
1452
|
+
*
|
1453
|
+
* Get the maximal sending transfer speed (in bytes per second)
|
1454
|
+
*/
|
1455
|
+
static VALUE ruby_curl_easy_max_send_speed_large_get(VALUE self) {
|
1456
|
+
CURB_IMMED_GETTER(ruby_curl_easy, max_send_speed_large, 0);
|
1457
|
+
}
|
1458
|
+
|
1459
|
+
/*
|
1460
|
+
* call-seq:
|
1461
|
+
* easy.max_recv_speed_large = fixnum or nil => fixnum or nil
|
1462
|
+
*
|
1463
|
+
* Set the maximal receiving transfer speed (in bytes per second)
|
1464
|
+
*/
|
1465
|
+
static VALUE ruby_curl_easy_max_recv_speed_large_set(VALUE self, VALUE max_recv_speed_large) {
|
1466
|
+
CURB_IMMED_SETTER(ruby_curl_easy, max_recv_speed_large, 0);
|
1467
|
+
}
|
1468
|
+
|
1469
|
+
/*
|
1470
|
+
* call-seq:
|
1471
|
+
* easy.max_recv_speed_large = fixnum or nil => fixnum or nil
|
1472
|
+
*
|
1473
|
+
* Get the maximal receiving transfer speed (in bytes per second)
|
1474
|
+
*/
|
1475
|
+
static VALUE ruby_curl_easy_max_recv_speed_large_get(VALUE self) {
|
1476
|
+
CURB_IMMED_GETTER(ruby_curl_easy, max_recv_speed_large, 0);
|
1477
|
+
}
|
1478
|
+
|
1296
1479
|
/*
|
1297
1480
|
* call-seq:
|
1298
1481
|
* easy.username = string => string
|
@@ -1310,10 +1493,10 @@ static VALUE ruby_curl_easy_username_set(VALUE self, VALUE username) {
|
|
1310
1493
|
/*
|
1311
1494
|
* call-seq:
|
1312
1495
|
* easy.username => string
|
1313
|
-
*
|
1496
|
+
*
|
1314
1497
|
* Get the current username
|
1315
1498
|
*/
|
1316
|
-
static VALUE ruby_curl_easy_username_get(VALUE self
|
1499
|
+
static VALUE ruby_curl_easy_username_get(VALUE self) {
|
1317
1500
|
#if HAVE_CURLOPT_USERNAME
|
1318
1501
|
CURB_OBJECT_HGETTER(ruby_curl_easy, username);
|
1319
1502
|
#else
|
@@ -1338,10 +1521,10 @@ static VALUE ruby_curl_easy_password_set(VALUE self, VALUE password) {
|
|
1338
1521
|
/*
|
1339
1522
|
* call-seq:
|
1340
1523
|
* easy.password => string
|
1341
|
-
*
|
1524
|
+
*
|
1342
1525
|
* Get the current password
|
1343
1526
|
*/
|
1344
|
-
static VALUE ruby_curl_easy_password_get(VALUE self
|
1527
|
+
static VALUE ruby_curl_easy_password_get(VALUE self) {
|
1345
1528
|
#if HAVE_CURLOPT_PASSWORD
|
1346
1529
|
CURB_OBJECT_HGETTER(ruby_curl_easy, password);
|
1347
1530
|
#else
|
@@ -1363,6 +1546,7 @@ static VALUE ruby_curl_easy_password_get(VALUE self, VALUE password) {
|
|
1363
1546
|
* Curl::CURL_SSLVERSION_TLSv1_0
|
1364
1547
|
* Curl::CURL_SSLVERSION_TLSv1_1
|
1365
1548
|
* Curl::CURL_SSLVERSION_TLSv1_2
|
1549
|
+
* Curl::CURL_SSLVERSION_TLSv1_3
|
1366
1550
|
*/
|
1367
1551
|
static VALUE ruby_curl_easy_ssl_version_set(VALUE self, VALUE ssl_version) {
|
1368
1552
|
CURB_IMMED_SETTER(ruby_curl_easy, ssl_version, -1);
|
@@ -1374,14 +1558,14 @@ static VALUE ruby_curl_easy_ssl_version_set(VALUE self, VALUE ssl_version) {
|
|
1374
1558
|
*
|
1375
1559
|
* Get the version of SSL/TLS that libcurl will attempt to use.
|
1376
1560
|
*/
|
1377
|
-
static VALUE ruby_curl_easy_ssl_version_get(VALUE self
|
1561
|
+
static VALUE ruby_curl_easy_ssl_version_get(VALUE self) {
|
1378
1562
|
CURB_IMMED_GETTER(ruby_curl_easy, ssl_version, -1);
|
1379
1563
|
}
|
1380
1564
|
|
1381
1565
|
/*
|
1382
1566
|
* call-seq:
|
1383
1567
|
* easy.use_ssl = value => fixnum or nil
|
1384
|
-
*
|
1568
|
+
*
|
1385
1569
|
* Ensure libcurl uses SSL for FTP connections. Valid options are Curl::CURL_USESSL_NONE,
|
1386
1570
|
* Curl::CURL_USESSL_TRY, Curl::CURL_USESSL_CONTROL, and Curl::CURL_USESSL_ALL.
|
1387
1571
|
*/
|
@@ -1395,7 +1579,7 @@ static VALUE ruby_curl_easy_use_ssl_set(VALUE self, VALUE use_ssl) {
|
|
1395
1579
|
*
|
1396
1580
|
* Get the desired level for using SSL on FTP connections.
|
1397
1581
|
*/
|
1398
|
-
static VALUE ruby_curl_easy_use_ssl_get(VALUE self
|
1582
|
+
static VALUE ruby_curl_easy_use_ssl_get(VALUE self) {
|
1399
1583
|
CURB_IMMED_GETTER(ruby_curl_easy, use_ssl, -1);
|
1400
1584
|
}
|
1401
1585
|
|
@@ -1411,12 +1595,12 @@ static VALUE ruby_curl_easy_ftp_filemethod_set(VALUE self, VALUE ftp_filemethod)
|
|
1411
1595
|
}
|
1412
1596
|
|
1413
1597
|
/*
|
1414
|
-
* call-seq
|
1598
|
+
* call-seq:
|
1415
1599
|
* easy.ftp_filemethod => fixnum
|
1416
1600
|
*
|
1417
1601
|
* Get the configuration for how libcurl will reach files on the server.
|
1418
1602
|
*/
|
1419
|
-
static VALUE ruby_curl_easy_ftp_filemethod_get(VALUE self
|
1603
|
+
static VALUE ruby_curl_easy_ftp_filemethod_get(VALUE self) {
|
1420
1604
|
CURB_IMMED_GETTER(ruby_curl_easy, ftp_filemethod, -1);
|
1421
1605
|
}
|
1422
1606
|
|
@@ -1783,7 +1967,7 @@ static VALUE ruby_curl_easy_resolve_mode_set(VALUE self, VALUE resolve_mode) {
|
|
1783
1967
|
|
1784
1968
|
/*
|
1785
1969
|
* call-seq:
|
1786
|
-
* easy.on_body { |body_data| ... } =>
|
1970
|
+
* easy.on_body { |body_data| ... } => <old handler>
|
1787
1971
|
*
|
1788
1972
|
* Assign or remove the +on_body+ handler for this Curl::Easy instance.
|
1789
1973
|
* To remove a previously-supplied handler, call this method with no
|
@@ -1802,7 +1986,7 @@ static VALUE ruby_curl_easy_on_body_set(int argc, VALUE *argv, VALUE self) {
|
|
1802
1986
|
|
1803
1987
|
/*
|
1804
1988
|
* call-seq:
|
1805
|
-
* easy.on_success { |easy| ... } =>
|
1989
|
+
* easy.on_success { |easy| ... } => <old handler>
|
1806
1990
|
*
|
1807
1991
|
* Assign or remove the +on_success+ handler for this Curl::Easy instance.
|
1808
1992
|
* To remove a previously-supplied handler, call this method with no
|
@@ -1817,7 +2001,7 @@ static VALUE ruby_curl_easy_on_success_set(int argc, VALUE *argv, VALUE self) {
|
|
1817
2001
|
|
1818
2002
|
/*
|
1819
2003
|
* call-seq:
|
1820
|
-
* easy.on_failure {|easy,code| ... } =>
|
2004
|
+
* easy.on_failure {|easy,code| ... } => <old handler>
|
1821
2005
|
*
|
1822
2006
|
* Assign or remove the +on_failure+ handler for this Curl::Easy instance.
|
1823
2007
|
* To remove a previously-supplied handler, call this method with no
|
@@ -1832,13 +2016,13 @@ static VALUE ruby_curl_easy_on_failure_set(int argc, VALUE *argv, VALUE self) {
|
|
1832
2016
|
|
1833
2017
|
/*
|
1834
2018
|
* call-seq:
|
1835
|
-
* easy.on_missing {|easy,code| ... } =>
|
2019
|
+
* easy.on_missing {|easy,code| ... } => <old handler;>
|
1836
2020
|
*
|
1837
2021
|
* Assign or remove the on_missing handler for this Curl::Easy instance.
|
1838
2022
|
* To remove a previously-supplied handler, call this method with no attached
|
1839
2023
|
* block.
|
1840
2024
|
*
|
1841
|
-
* The +on_missing+ handler is called when request is finished with a
|
2025
|
+
* The +on_missing+ handler is called when request is finished with a
|
1842
2026
|
* status of 40x
|
1843
2027
|
*/
|
1844
2028
|
static VALUE ruby_curl_easy_on_missing_set(int argc, VALUE *argv, VALUE self) {
|
@@ -1847,13 +2031,13 @@ static VALUE ruby_curl_easy_on_missing_set(int argc, VALUE *argv, VALUE self) {
|
|
1847
2031
|
|
1848
2032
|
/*
|
1849
2033
|
* call-seq:
|
1850
|
-
* easy.on_redirect {|easy,code| ... } =>
|
2034
|
+
* easy.on_redirect {|easy,code| ... } => <old handler;>
|
1851
2035
|
*
|
1852
2036
|
* Assign or remove the on_redirect handler for this Curl::Easy instance.
|
1853
2037
|
* To remove a previously-supplied handler, call this method with no attached
|
1854
2038
|
* block.
|
1855
2039
|
*
|
1856
|
-
* The +on_redirect+ handler is called when request is finished with a
|
2040
|
+
* The +on_redirect+ handler is called when request is finished with a
|
1857
2041
|
* status of 30x
|
1858
2042
|
*/
|
1859
2043
|
static VALUE ruby_curl_easy_on_redirect_set(int argc, VALUE *argv, VALUE self) {
|
@@ -1862,7 +2046,7 @@ static VALUE ruby_curl_easy_on_redirect_set(int argc, VALUE *argv, VALUE self) {
|
|
1862
2046
|
|
1863
2047
|
/*
|
1864
2048
|
* call-seq:
|
1865
|
-
* easy.on_complete {|easy| ... } =>
|
2049
|
+
* easy.on_complete {|easy| ... } => <old handler>
|
1866
2050
|
*
|
1867
2051
|
* Assign or remove the +on_complete+ handler for this Curl::Easy instance.
|
1868
2052
|
* To remove a previously-supplied handler, call this method with no
|
@@ -1876,7 +2060,7 @@ static VALUE ruby_curl_easy_on_complete_set(int argc, VALUE *argv, VALUE self) {
|
|
1876
2060
|
|
1877
2061
|
/*
|
1878
2062
|
* call-seq:
|
1879
|
-
* easy.on_header { |header_data| ... } =>
|
2063
|
+
* easy.on_header { |header_data| ... } => <old handler>
|
1880
2064
|
*
|
1881
2065
|
* Assign or remove the +on_header+ handler for this Curl::Easy instance.
|
1882
2066
|
* To remove a previously-supplied handler, call this method with no
|
@@ -1892,7 +2076,7 @@ static VALUE ruby_curl_easy_on_header_set(int argc, VALUE *argv, VALUE self) {
|
|
1892
2076
|
|
1893
2077
|
/*
|
1894
2078
|
* call-seq:
|
1895
|
-
* easy.on_progress { |dl_total, dl_now, ul_total, ul_now| ... } =>
|
2079
|
+
* easy.on_progress { |dl_total, dl_now, ul_total, ul_now| ... } => <old handler>
|
1896
2080
|
*
|
1897
2081
|
* Assign or remove the +on_progress+ handler for this Curl::Easy instance.
|
1898
2082
|
* To remove a previously-supplied handler, call this method with no
|
@@ -1913,7 +2097,7 @@ static VALUE ruby_curl_easy_on_progress_set(int argc, VALUE *argv, VALUE self) {
|
|
1913
2097
|
|
1914
2098
|
/*
|
1915
2099
|
* call-seq:
|
1916
|
-
* easy.on_debug { |type, data| ... } =>
|
2100
|
+
* easy.on_debug { |type, data| ... } => <old handler>
|
1917
2101
|
*
|
1918
2102
|
* Assign or remove the +on_debug+ handler for this Curl::Easy instance.
|
1919
2103
|
* To remove a previously-supplied handler, call this method with no
|
@@ -1938,7 +2122,7 @@ static VALUE ruby_curl_easy_on_debug_set(int argc, VALUE *argv, VALUE self) {
|
|
1938
2122
|
/***********************************************
|
1939
2123
|
* This is an rb_iterate callback used to set up http headers.
|
1940
2124
|
*/
|
1941
|
-
static VALUE cb_each_http_header(VALUE header, VALUE wrap) {
|
2125
|
+
static VALUE cb_each_http_header(VALUE header, VALUE wrap, int _c, const VALUE *_ptr, VALUE unused) {
|
1942
2126
|
struct curl_slist **list;
|
1943
2127
|
VALUE header_str = Qnil;
|
1944
2128
|
|
@@ -1952,11 +2136,14 @@ static VALUE cb_each_http_header(VALUE header, VALUE wrap) {
|
|
1952
2136
|
|
1953
2137
|
name = rb_obj_as_string(rb_ary_entry(header, 0));
|
1954
2138
|
value = rb_obj_as_string(rb_ary_entry(header, 1));
|
1955
|
-
|
1956
|
-
|
1957
|
-
|
1958
|
-
|
1959
|
-
|
2139
|
+
if (rb_str_strlen(value) == 0) { // removing the header e.g. Accept: with nothing trailing should remove it see: https://curl.se/libcurl/c/CURLOPT_HTTPHEADER.html
|
2140
|
+
header_str = rb_str_plus(name, rb_str_new2(":"));
|
2141
|
+
} else {
|
2142
|
+
// This is a bit inefficient, but we don't want to be modifying
|
2143
|
+
// the actual values in the original hash.
|
2144
|
+
header_str = rb_str_plus(name, rb_str_new2(": "));
|
2145
|
+
header_str = rb_str_plus(header_str, value);
|
2146
|
+
}
|
1960
2147
|
} else {
|
1961
2148
|
header_str = rb_obj_as_string(header);
|
1962
2149
|
}
|
@@ -1967,10 +2154,42 @@ static VALUE cb_each_http_header(VALUE header, VALUE wrap) {
|
|
1967
2154
|
return header_str;
|
1968
2155
|
}
|
1969
2156
|
|
2157
|
+
/***********************************************
|
2158
|
+
* This is an rb_iterate callback used to set up http proxy headers.
|
2159
|
+
*/
|
2160
|
+
static VALUE cb_each_http_proxy_header(VALUE proxy_header, VALUE wrap, int _c, const VALUE *_ptr, VALUE unused) {
|
2161
|
+
struct curl_slist **list;
|
2162
|
+
VALUE proxy_header_str = Qnil;
|
2163
|
+
|
2164
|
+
Data_Get_Struct(wrap, struct curl_slist *, list);
|
2165
|
+
|
2166
|
+
//rb_p(proxy_header);
|
2167
|
+
|
2168
|
+
if (rb_type(proxy_header) == T_ARRAY) {
|
2169
|
+
// we're processing a hash, proxy header is [name, val]
|
2170
|
+
VALUE name, value;
|
2171
|
+
|
2172
|
+
name = rb_obj_as_string(rb_ary_entry(proxy_header, 0));
|
2173
|
+
value = rb_obj_as_string(rb_ary_entry(proxy_header, 1));
|
2174
|
+
|
2175
|
+
// This is a bit inefficient, but we don't want to be modifying
|
2176
|
+
// the actual values in the original hash.
|
2177
|
+
proxy_header_str = rb_str_plus(name, rb_str_new2(": "));
|
2178
|
+
proxy_header_str = rb_str_plus(proxy_header_str, value);
|
2179
|
+
} else {
|
2180
|
+
proxy_header_str = rb_obj_as_string(proxy_header);
|
2181
|
+
}
|
2182
|
+
|
2183
|
+
//rb_p(header_str);
|
2184
|
+
|
2185
|
+
*list = curl_slist_append(*list, StringValuePtr(proxy_header_str));
|
2186
|
+
return proxy_header_str;
|
2187
|
+
}
|
2188
|
+
|
1970
2189
|
/***********************************************
|
1971
2190
|
* This is an rb_iterate callback used to set up ftp commands.
|
1972
2191
|
*/
|
1973
|
-
static VALUE cb_each_ftp_command(VALUE ftp_command, VALUE wrap) {
|
2192
|
+
static VALUE cb_each_ftp_command(VALUE ftp_command, VALUE wrap, int _c, const VALUE *_ptr, VALUE unused) {
|
1974
2193
|
struct curl_slist **list;
|
1975
2194
|
VALUE ftp_command_string;
|
1976
2195
|
Data_Get_Struct(wrap, struct curl_slist *, list);
|
@@ -1981,6 +2200,20 @@ static VALUE cb_each_ftp_command(VALUE ftp_command, VALUE wrap) {
|
|
1981
2200
|
return ftp_command_string;
|
1982
2201
|
}
|
1983
2202
|
|
2203
|
+
/***********************************************
|
2204
|
+
* This is an rb_iterate callback used to set up the resolve list.
|
2205
|
+
*/
|
2206
|
+
static VALUE cb_each_resolve(VALUE resolve, VALUE wrap, int _c, const VALUE *_ptr, VALUE unused) {
|
2207
|
+
struct curl_slist **list;
|
2208
|
+
VALUE resolve_string;
|
2209
|
+
Data_Get_Struct(wrap, struct curl_slist *, list);
|
2210
|
+
|
2211
|
+
resolve_string = rb_obj_as_string(resolve);
|
2212
|
+
*list = curl_slist_append(*list, StringValuePtr(resolve));
|
2213
|
+
|
2214
|
+
return resolve_string;
|
2215
|
+
}
|
2216
|
+
|
1984
2217
|
/***********************************************
|
1985
2218
|
*
|
1986
2219
|
* Setup a connection
|
@@ -1992,7 +2225,9 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
1992
2225
|
CURL *curl;
|
1993
2226
|
VALUE url, _url = rb_easy_get("url");
|
1994
2227
|
struct curl_slist **hdrs = &(rbce->curl_headers);
|
2228
|
+
struct curl_slist **phdrs = &(rbce->curl_proxy_headers);
|
1995
2229
|
struct curl_slist **cmds = &(rbce->curl_ftp_commands);
|
2230
|
+
struct curl_slist **rslv = &(rbce->curl_resolve);
|
1996
2231
|
|
1997
2232
|
curl = rbce->curl;
|
1998
2233
|
|
@@ -2001,7 +2236,6 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
2001
2236
|
}
|
2002
2237
|
|
2003
2238
|
url = rb_check_string_type(_url);
|
2004
|
-
|
2005
2239
|
curl_easy_setopt(curl, CURLOPT_URL, StringValuePtr(url));
|
2006
2240
|
|
2007
2241
|
// network stuff and auth
|
@@ -2114,15 +2348,14 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
2114
2348
|
|
2115
2349
|
curl_easy_setopt(curl, CURLOPT_UNRESTRICTED_AUTH, rbce->unrestricted_auth);
|
2116
2350
|
|
2117
|
-
|
2118
|
-
|
2119
|
-
|
2120
|
-
|
2121
|
-
if (rbce->timeout_ms && rbce->timeout_ms > 0) {
|
2122
|
-
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, rbce->timeout_ms);
|
2123
|
-
}
|
2351
|
+
#if HAVE_CURLOPT_TIMEOUT_MS
|
2352
|
+
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, rbce->timeout_ms);
|
2353
|
+
#endif
|
2354
|
+
|
2124
2355
|
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, rbce->connect_timeout);
|
2356
|
+
#if HAVE_CURLOPT_CONNECTTIMEOUT_MS
|
2125
2357
|
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, rbce->connect_timeout_ms);
|
2358
|
+
#endif
|
2126
2359
|
curl_easy_setopt(curl, CURLOPT_DNS_CACHE_TIMEOUT, rbce->dns_cache_timeout);
|
2127
2360
|
|
2128
2361
|
curl_easy_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, rbce->ignore_content_length);
|
@@ -2141,6 +2374,9 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
2141
2374
|
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, rbce->low_speed_limit);
|
2142
2375
|
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, rbce->low_speed_time);
|
2143
2376
|
|
2377
|
+
curl_easy_setopt(curl, CURLOPT_MAX_RECV_SPEED_LARGE, rbce->max_recv_speed_large);
|
2378
|
+
curl_easy_setopt(curl, CURLOPT_MAX_SEND_SPEED_LARGE, rbce->max_send_speed_large);
|
2379
|
+
|
2144
2380
|
// Set up localport / proxy port
|
2145
2381
|
// FIXME these won't get returned to default if they're unset Ruby
|
2146
2382
|
if (rbce->proxy_port > 0) {
|
@@ -2247,7 +2483,7 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
2247
2483
|
rb_warn("libcurl is not configured with SSL support");
|
2248
2484
|
}
|
2249
2485
|
#endif
|
2250
|
-
|
2486
|
+
|
2251
2487
|
if (rbce->ftp_filemethod > 0) {
|
2252
2488
|
curl_easy_setopt(curl, CURLOPT_FTP_FILEMETHOD, rbce->ftp_filemethod);
|
2253
2489
|
}
|
@@ -2274,6 +2510,25 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
2274
2510
|
}
|
2275
2511
|
}
|
2276
2512
|
|
2513
|
+
#if HAVE_CURLOPT_PROXYHEADER
|
2514
|
+
/* Setup HTTP proxy headers if necessary */
|
2515
|
+
curl_easy_setopt(curl, CURLOPT_PROXYHEADER, NULL); // XXX: maybe we shouldn't be clearing this?
|
2516
|
+
|
2517
|
+
if (!rb_easy_nil("proxy_headers")) {
|
2518
|
+
if (rb_easy_type_check("proxy_headers", T_ARRAY) || rb_easy_type_check("proxy_headers", T_HASH)) {
|
2519
|
+
VALUE wrap = Data_Wrap_Struct(rb_cObject, 0, 0, phdrs);
|
2520
|
+
rb_iterate(rb_each, rb_easy_get("proxy_headers"), cb_each_http_proxy_header, wrap);
|
2521
|
+
} else {
|
2522
|
+
VALUE proxy_headers_str = rb_obj_as_string(rb_easy_get("proxy_headers"));
|
2523
|
+
*phdrs = curl_slist_append(*hdrs, StringValuePtr(proxy_headers_str));
|
2524
|
+
}
|
2525
|
+
|
2526
|
+
if (*phdrs) {
|
2527
|
+
curl_easy_setopt(curl, CURLOPT_PROXYHEADER, *phdrs);
|
2528
|
+
}
|
2529
|
+
}
|
2530
|
+
#endif
|
2531
|
+
|
2277
2532
|
/* Setup FTP commands if necessary */
|
2278
2533
|
if (!rb_easy_nil("ftp_commands")) {
|
2279
2534
|
if (rb_easy_type_check("ftp_commands", T_ARRAY)) {
|
@@ -2286,18 +2541,33 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
2286
2541
|
}
|
2287
2542
|
}
|
2288
2543
|
|
2544
|
+
#if HAVE_CURLOPT_RESOLVE
|
2545
|
+
/* Setup resolve list if necessary */
|
2546
|
+
if (!rb_easy_nil("resolve")) {
|
2547
|
+
if (rb_easy_type_check("resolve", T_ARRAY)) {
|
2548
|
+
VALUE wrap = Data_Wrap_Struct(rb_cObject, 0, 0, rslv);
|
2549
|
+
rb_iterate(rb_each, rb_easy_get("resolve"), cb_each_resolve, wrap);
|
2550
|
+
}
|
2551
|
+
|
2552
|
+
if (*rslv) {
|
2553
|
+
curl_easy_setopt(curl, CURLOPT_RESOLVE, *rslv);
|
2554
|
+
}
|
2555
|
+
}
|
2556
|
+
#endif
|
2557
|
+
|
2289
2558
|
return Qnil;
|
2290
2559
|
}
|
2291
2560
|
/***********************************************
|
2292
2561
|
*
|
2293
2562
|
* Clean up a connection
|
2294
2563
|
*
|
2295
|
-
* Always returns
|
2564
|
+
* Always returns Qnil.
|
2296
2565
|
*/
|
2297
2566
|
VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
|
2298
2567
|
|
2299
2568
|
CURL *curl = rbce->curl;
|
2300
2569
|
struct curl_slist *ftp_commands;
|
2570
|
+
struct curl_slist *resolve;
|
2301
2571
|
|
2302
2572
|
/* Free everything up */
|
2303
2573
|
if (rbce->curl_headers) {
|
@@ -2305,12 +2575,23 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
|
|
2305
2575
|
rbce->curl_headers = NULL;
|
2306
2576
|
}
|
2307
2577
|
|
2578
|
+
if (rbce->curl_proxy_headers) {
|
2579
|
+
curl_slist_free_all(rbce->curl_proxy_headers);
|
2580
|
+
rbce->curl_proxy_headers = NULL;
|
2581
|
+
}
|
2582
|
+
|
2308
2583
|
ftp_commands = rbce->curl_ftp_commands;
|
2309
2584
|
if (ftp_commands) {
|
2310
2585
|
curl_slist_free_all(ftp_commands);
|
2311
2586
|
rbce->curl_ftp_commands = NULL;
|
2312
2587
|
}
|
2313
2588
|
|
2589
|
+
resolve = rbce->curl_resolve;
|
2590
|
+
if (resolve) {
|
2591
|
+
curl_slist_free_all(resolve);
|
2592
|
+
rbce->curl_resolve = NULL;
|
2593
|
+
}
|
2594
|
+
|
2314
2595
|
/* clean up a PUT request's curl options. */
|
2315
2596
|
if (!rb_easy_nil("upload")) {
|
2316
2597
|
rb_easy_del("upload"); // set the upload object to Qnil to let the GC clean up
|
@@ -2320,6 +2601,9 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
|
|
2320
2601
|
curl_easy_setopt(curl, CURLOPT_INFILESIZE, 0);
|
2321
2602
|
}
|
2322
2603
|
|
2604
|
+
// set values on cleanup to nil
|
2605
|
+
//rb_easy_del("multi");
|
2606
|
+
|
2323
2607
|
return Qnil;
|
2324
2608
|
}
|
2325
2609
|
|
@@ -2334,6 +2618,8 @@ static VALUE ruby_curl_easy_perform_verb_str(VALUE self, const char *verb) {
|
|
2334
2618
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
2335
2619
|
curl = rbce->curl;
|
2336
2620
|
|
2621
|
+
memset(rbce->err_buf, 0, sizeof(rbce->err_buf));
|
2622
|
+
|
2337
2623
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, verb);
|
2338
2624
|
|
2339
2625
|
retval = rb_funcall(self, rb_intern("perform"), 0);
|
@@ -2399,6 +2685,8 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
|
|
2399
2685
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
2400
2686
|
curl = rbce->curl;
|
2401
2687
|
|
2688
|
+
memset(rbce->err_buf, 0, sizeof(rbce->err_buf));
|
2689
|
+
|
2402
2690
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
|
2403
2691
|
|
2404
2692
|
if (rbce->multipart_form_post) {
|
@@ -2470,6 +2758,8 @@ static VALUE ruby_curl_easy_perform_put(VALUE self, VALUE data) {
|
|
2470
2758
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
2471
2759
|
curl = rbce->curl;
|
2472
2760
|
|
2761
|
+
memset(rbce->err_buf, 0, sizeof(rbce->err_buf));
|
2762
|
+
|
2473
2763
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
|
2474
2764
|
ruby_curl_easy_put_data_set(self, data);
|
2475
2765
|
|
@@ -2488,6 +2778,10 @@ static VALUE ruby_curl_easy_perform_put(VALUE self, VALUE data) {
|
|
2488
2778
|
* your own body handler, this string will be empty.
|
2489
2779
|
*/
|
2490
2780
|
static VALUE ruby_curl_easy_body_str_get(VALUE self) {
|
2781
|
+
/*
|
2782
|
+
TODO: can we force_encoding on the return here if we see charset=utf-8 in the content-type header?
|
2783
|
+
Content-Type: application/json; charset=utf-8
|
2784
|
+
*/
|
2491
2785
|
CURB_OBJECT_HGETTER(ruby_curl_easy, body_data);
|
2492
2786
|
}
|
2493
2787
|
|
@@ -2564,7 +2858,7 @@ static VALUE ruby_curl_easy_response_code_get(VALUE self) {
|
|
2564
2858
|
static VALUE ruby_curl_easy_primary_ip_get(VALUE self) {
|
2565
2859
|
ruby_curl_easy *rbce;
|
2566
2860
|
char* ip;
|
2567
|
-
|
2861
|
+
|
2568
2862
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
2569
2863
|
curl_easy_getinfo(rbce->curl, CURLINFO_PRIMARY_IP, &ip);
|
2570
2864
|
|
@@ -2682,7 +2976,7 @@ static VALUE ruby_curl_easy_connect_time_get(VALUE self) {
|
|
2682
2976
|
* Retrieve the time, in seconds, it took from the start until the SSL/SSH
|
2683
2977
|
* connect/handshake to the remote host was completed. This time is most often
|
2684
2978
|
* very near to the pre transfer time, except for cases such as HTTP
|
2685
|
-
*
|
2979
|
+
* pipelining where the pretransfer time can be delayed due to waits in line
|
2686
2980
|
* for the pipeline and more.
|
2687
2981
|
*/
|
2688
2982
|
#if defined(HAVE_CURLINFO_APPCONNECT_TIME)
|
@@ -2789,7 +3083,7 @@ static VALUE ruby_curl_easy_redirect_count_get(VALUE self) {
|
|
2789
3083
|
* call-seq:
|
2790
3084
|
* easy.redirect_url => "http://some.url" or nil
|
2791
3085
|
*
|
2792
|
-
* Retrieve the URL a redirect would take you to if you
|
3086
|
+
* Retrieve the URL a redirect would take you to if you
|
2793
3087
|
* would enable CURLOPT_FOLLOWLOCATION.
|
2794
3088
|
*
|
2795
3089
|
* Requires libcurl 7.18.2 or higher, otherwise -1 is always returned.
|
@@ -3072,12 +3366,40 @@ static VALUE ruby_curl_easy_num_connects_get(VALUE self) {
|
|
3072
3366
|
}
|
3073
3367
|
|
3074
3368
|
|
3075
|
-
/*
|
3369
|
+
/*
|
3370
|
+
* call-seq:
|
3371
|
+
* easy.cookielist => array
|
3372
|
+
*
|
3373
|
+
* Retrieves the cookies curl knows in an array of strings.
|
3374
|
+
* Returned strings are in Netscape cookiejar format or in Set-Cookie format.
|
3375
|
+
*
|
3376
|
+
* See also option CURLINFO_COOKIELIST of curl_easy_getopt(3) to see how libcurl behaves.
|
3377
|
+
*
|
3378
|
+
* (requires libcurl 7.14.1 or higher, otherwise -1 is always returned).
|
3379
|
+
*/
|
3380
|
+
static VALUE ruby_curl_easy_cookielist_get(VALUE self) {
|
3381
|
+
#ifdef HAVE_CURLINFO_COOKIELIST
|
3382
|
+
ruby_curl_easy *rbce;
|
3383
|
+
struct curl_slist *cookies;
|
3384
|
+
struct curl_slist *cookie;
|
3385
|
+
VALUE rb_cookies;
|
3386
|
+
|
3387
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
3388
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_COOKIELIST, &cookies);
|
3389
|
+
if (!cookies)
|
3390
|
+
return Qnil;
|
3391
|
+
rb_cookies = rb_ary_new();
|
3392
|
+
for (cookie = cookies; cookie; cookie = cookie->next)
|
3393
|
+
rb_ary_push(rb_cookies, rb_str_new2(cookie->data));
|
3394
|
+
curl_slist_free_all(cookies);
|
3395
|
+
return rb_cookies;
|
3076
3396
|
|
3077
|
-
|
3397
|
+
#else
|
3398
|
+
rb_warn("Installed libcurl is too old to support cookielist");
|
3399
|
+
return INT2FIX(-1);
|
3400
|
+
#endif
|
3401
|
+
}
|
3078
3402
|
|
3079
|
-
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)
|
3080
|
-
*/
|
3081
3403
|
|
3082
3404
|
/* TODO this needs to be implemented. Could probably support CONNECT_ONLY by having this
|
3083
3405
|
* return an open Socket or something.
|
@@ -3147,6 +3469,21 @@ static VALUE ruby_curl_easy_last_result(VALUE self) {
|
|
3147
3469
|
return LONG2NUM(rbce->last_result);
|
3148
3470
|
}
|
3149
3471
|
|
3472
|
+
/*
|
3473
|
+
* call-seq:
|
3474
|
+
* easy.last_error => "Error details" or nil
|
3475
|
+
*/
|
3476
|
+
static VALUE ruby_curl_easy_last_error(VALUE self) {
|
3477
|
+
ruby_curl_easy *rbce;
|
3478
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
3479
|
+
|
3480
|
+
if (rbce->err_buf[0]) { // curl returns NULL or empty string if none
|
3481
|
+
return rb_str_new2(rbce->err_buf);
|
3482
|
+
} else {
|
3483
|
+
return Qnil;
|
3484
|
+
}
|
3485
|
+
}
|
3486
|
+
|
3150
3487
|
/*
|
3151
3488
|
* call-seq:
|
3152
3489
|
* easy.setopt Fixnum, value => value
|
@@ -3156,6 +3493,7 @@ static VALUE ruby_curl_easy_last_result(VALUE self) {
|
|
3156
3493
|
static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
3157
3494
|
ruby_curl_easy *rbce;
|
3158
3495
|
long option = NUM2LONG(opt);
|
3496
|
+
rb_io_t *open_f_ptr;
|
3159
3497
|
|
3160
3498
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
3161
3499
|
|
@@ -3193,6 +3531,12 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
3193
3531
|
case CURLOPT_HEADER:
|
3194
3532
|
case CURLOPT_NOPROGRESS:
|
3195
3533
|
case CURLOPT_NOSIGNAL:
|
3534
|
+
#if HAVE_CURLOPT_PATH_AS_IS
|
3535
|
+
case CURLOPT_PATH_AS_IS:
|
3536
|
+
#endif
|
3537
|
+
#if HAVE_CURLOPT_PIPEWAIT
|
3538
|
+
case CURLOPT_PIPEWAIT:
|
3539
|
+
#endif
|
3196
3540
|
case CURLOPT_HTTPGET:
|
3197
3541
|
case CURLOPT_NOBODY: {
|
3198
3542
|
int type = rb_type(val);
|
@@ -3238,6 +3582,9 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
3238
3582
|
case CURLOPT_TCP_NODELAY: {
|
3239
3583
|
curl_easy_setopt(rbce->curl, CURLOPT_TCP_NODELAY, NUM2LONG(val));
|
3240
3584
|
} break;
|
3585
|
+
case CURLOPT_RANGE: {
|
3586
|
+
curl_easy_setopt(rbce->curl, CURLOPT_RANGE, StringValueCStr(val));
|
3587
|
+
} break;
|
3241
3588
|
case CURLOPT_RESUME_FROM: {
|
3242
3589
|
curl_easy_setopt(rbce->curl, CURLOPT_RESUME_FROM, NUM2LONG(val));
|
3243
3590
|
} break;
|
@@ -3259,6 +3606,58 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
3259
3606
|
case CURLOPT_UNIX_SOCKET_PATH: {
|
3260
3607
|
curl_easy_setopt(rbce->curl, CURLOPT_UNIX_SOCKET_PATH, StringValueCStr(val));
|
3261
3608
|
} break;
|
3609
|
+
#endif
|
3610
|
+
#if HAVE_CURLOPT_MAX_SEND_SPEED_LARGE
|
3611
|
+
case CURLOPT_MAX_SEND_SPEED_LARGE: {
|
3612
|
+
curl_easy_setopt(rbce->curl, CURLOPT_MAX_SEND_SPEED_LARGE, (curl_off_t) NUM2LL(val));
|
3613
|
+
} break;
|
3614
|
+
#endif
|
3615
|
+
#if HAVE_CURLOPT_MAX_RECV_SPEED_LARGE
|
3616
|
+
case CURLOPT_MAX_RECV_SPEED_LARGE: {
|
3617
|
+
curl_easy_setopt(rbce->curl, CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t) NUM2LL(val));
|
3618
|
+
} break;
|
3619
|
+
#endif
|
3620
|
+
#if HAVE_CURLOPT_MAXFILESIZE
|
3621
|
+
case CURLOPT_MAXFILESIZE:
|
3622
|
+
curl_easy_setopt(rbce->curl, CURLOPT_MAXFILESIZE, NUM2LONG(val));
|
3623
|
+
break;
|
3624
|
+
#endif
|
3625
|
+
#if HAVE_CURLOPT_TCP_KEEPALIVE
|
3626
|
+
case CURLOPT_TCP_KEEPALIVE:
|
3627
|
+
curl_easy_setopt(rbce->curl, CURLOPT_TCP_KEEPALIVE, NUM2LONG(val));
|
3628
|
+
break;
|
3629
|
+
case CURLOPT_TCP_KEEPIDLE:
|
3630
|
+
curl_easy_setopt(rbce->curl, CURLOPT_TCP_KEEPIDLE, NUM2LONG(val));
|
3631
|
+
break;
|
3632
|
+
case CURLOPT_TCP_KEEPINTVL:
|
3633
|
+
curl_easy_setopt(rbce->curl, CURLOPT_TCP_KEEPINTVL, NUM2LONG(val));
|
3634
|
+
break;
|
3635
|
+
#endif
|
3636
|
+
#if HAVE_CURLOPT_HAPROXYPROTOCOL
|
3637
|
+
case CURLOPT_HAPROXYPROTOCOL:
|
3638
|
+
curl_easy_setopt(rbce->curl, CURLOPT_HAPROXYPROTOCOL, NUM2LONG(val));
|
3639
|
+
break;
|
3640
|
+
#endif
|
3641
|
+
case CURLOPT_STDERR:
|
3642
|
+
// libcurl requires raw FILE pointer and this should be IO object in Ruby.
|
3643
|
+
// Tempfile or StringIO won't work.
|
3644
|
+
Check_Type(val, T_FILE);
|
3645
|
+
GetOpenFile(val, open_f_ptr);
|
3646
|
+
curl_easy_setopt(rbce->curl, CURLOPT_STDERR, rb_io_stdio_file(open_f_ptr));
|
3647
|
+
break;
|
3648
|
+
case CURLOPT_PROTOCOLS:
|
3649
|
+
case CURLOPT_REDIR_PROTOCOLS:
|
3650
|
+
curl_easy_setopt(rbce->curl, option, NUM2LONG(val));
|
3651
|
+
break;
|
3652
|
+
#if HAVE_CURLOPT_SSL_SESSIONID_CACHE
|
3653
|
+
case CURLOPT_SSL_SESSIONID_CACHE:
|
3654
|
+
curl_easy_setopt(rbce->curl, CURLOPT_SSL_SESSIONID_CACHE, NUM2LONG(val));
|
3655
|
+
break;
|
3656
|
+
#endif
|
3657
|
+
#if HAVE_CURLOPT_PROXY_SSL_VERIFYHOST
|
3658
|
+
case CURLOPT_PROXY_SSL_VERIFYHOST:
|
3659
|
+
curl_easy_setopt(rbce->curl, CURLOPT_PROXY_SSL_VERIFYHOST, NUM2LONG(val));
|
3660
|
+
break;
|
3262
3661
|
#endif
|
3263
3662
|
default:
|
3264
3663
|
rb_raise(rb_eTypeError, "Curb unsupported option");
|
@@ -3376,6 +3775,7 @@ static VALUE ruby_curl_easy_error_message(VALUE klass, VALUE code) {
|
|
3376
3775
|
}
|
3377
3776
|
|
3378
3777
|
/* =================== INIT LIB =====================*/
|
3778
|
+
// TODO: https://bugs.ruby-lang.org/issues/18007
|
3379
3779
|
void init_curb_easy() {
|
3380
3780
|
idCall = rb_intern("call");
|
3381
3781
|
idJoin = rb_intern("join");
|
@@ -3386,12 +3786,19 @@ void init_curb_easy() {
|
|
3386
3786
|
cCurlEasy = rb_define_class_under(mCurl, "Easy", rb_cObject);
|
3387
3787
|
|
3388
3788
|
/* Class methods */
|
3389
|
-
|
3789
|
+
rb_define_alloc_func(cCurlEasy, ruby_curl_easy_allocate);
|
3390
3790
|
rb_define_singleton_method(cCurlEasy, "error", ruby_curl_easy_error_message, 1);
|
3391
3791
|
|
3792
|
+
/* Initialize method */
|
3793
|
+
rb_define_method(cCurlEasy, "initialize", ruby_curl_easy_initialize, -1);
|
3794
|
+
|
3392
3795
|
/* Attributes for config next perform */
|
3393
3796
|
rb_define_method(cCurlEasy, "url", ruby_curl_easy_url_get, 0);
|
3394
3797
|
rb_define_method(cCurlEasy, "proxy_url", ruby_curl_easy_proxy_url_get, 0);
|
3798
|
+
|
3799
|
+
rb_define_method(cCurlEasy, "proxy_headers=", ruby_curl_easy_proxy_headers_set, 1);
|
3800
|
+
rb_define_method(cCurlEasy, "proxy_headers", ruby_curl_easy_proxy_headers_get, 0);
|
3801
|
+
|
3395
3802
|
rb_define_method(cCurlEasy, "headers=", ruby_curl_easy_headers_set, 1);
|
3396
3803
|
rb_define_method(cCurlEasy, "headers", ruby_curl_easy_headers_get, 0);
|
3397
3804
|
rb_define_method(cCurlEasy, "interface", ruby_curl_easy_interface_get, 0);
|
@@ -3418,6 +3825,8 @@ void init_curb_easy() {
|
|
3418
3825
|
rb_define_method(cCurlEasy, "put_data=", ruby_curl_easy_put_data_set, 1);
|
3419
3826
|
rb_define_method(cCurlEasy, "ftp_commands=", ruby_curl_easy_ftp_commands_set, 1);
|
3420
3827
|
rb_define_method(cCurlEasy, "ftp_commands", ruby_curl_easy_ftp_commands_get, 0);
|
3828
|
+
rb_define_method(cCurlEasy, "resolve=", ruby_curl_easy_resolve_set, 1);
|
3829
|
+
rb_define_method(cCurlEasy, "resolve", ruby_curl_easy_resolve_get, 0);
|
3421
3830
|
|
3422
3831
|
rb_define_method(cCurlEasy, "local_port=", ruby_curl_easy_local_port_set, 1);
|
3423
3832
|
rb_define_method(cCurlEasy, "local_port", ruby_curl_easy_local_port_get, 0);
|
@@ -3449,6 +3858,10 @@ void init_curb_easy() {
|
|
3449
3858
|
rb_define_method(cCurlEasy, "low_speed_limit", ruby_curl_easy_low_speed_limit_get, 0);
|
3450
3859
|
rb_define_method(cCurlEasy, "low_speed_time=", ruby_curl_easy_low_speed_time_set, 1);
|
3451
3860
|
rb_define_method(cCurlEasy, "low_speed_time", ruby_curl_easy_low_speed_time_get, 0);
|
3861
|
+
rb_define_method(cCurlEasy, "max_send_speed_large=", ruby_curl_easy_max_send_speed_large_set, 1);
|
3862
|
+
rb_define_method(cCurlEasy, "max_send_speed_large", ruby_curl_easy_max_send_speed_large_get, 0);
|
3863
|
+
rb_define_method(cCurlEasy, "max_recv_speed_large=", ruby_curl_easy_max_recv_speed_large_set, 1);
|
3864
|
+
rb_define_method(cCurlEasy, "max_recv_speed_large", ruby_curl_easy_max_recv_speed_large_get, 0);
|
3452
3865
|
rb_define_method(cCurlEasy, "ssl_version=", ruby_curl_easy_ssl_version_set, 1);
|
3453
3866
|
rb_define_method(cCurlEasy, "ssl_version", ruby_curl_easy_ssl_version_get, 0);
|
3454
3867
|
rb_define_method(cCurlEasy, "use_ssl=", ruby_curl_easy_use_ssl_set, 1);
|
@@ -3508,6 +3921,7 @@ void init_curb_easy() {
|
|
3508
3921
|
|
3509
3922
|
rb_define_method(cCurlEasy, "last_effective_url", ruby_curl_easy_last_effective_url_get, 0);
|
3510
3923
|
rb_define_method(cCurlEasy, "response_code", ruby_curl_easy_response_code_get, 0);
|
3924
|
+
rb_define_method(cCurlEasy, "code", ruby_curl_easy_response_code_get, 0);
|
3511
3925
|
#if defined(HAVE_CURLINFO_PRIMARY_IP)
|
3512
3926
|
rb_define_method(cCurlEasy, "primary_ip", ruby_curl_easy_primary_ip_get, 0);
|
3513
3927
|
#endif
|
@@ -3536,6 +3950,7 @@ void init_curb_easy() {
|
|
3536
3950
|
rb_define_method(cCurlEasy, "content_type", ruby_curl_easy_content_type_get, 0);
|
3537
3951
|
rb_define_method(cCurlEasy, "os_errno", ruby_curl_easy_os_errno_get, 0);
|
3538
3952
|
rb_define_method(cCurlEasy, "num_connects", ruby_curl_easy_num_connects_get, 0);
|
3953
|
+
rb_define_method(cCurlEasy, "cookielist", ruby_curl_easy_cookielist_get, 0);
|
3539
3954
|
rb_define_method(cCurlEasy, "ftp_entry_path", ruby_curl_easy_ftp_entry_path_get, 0);
|
3540
3955
|
|
3541
3956
|
rb_define_method(cCurlEasy, "close", ruby_curl_easy_close, 0);
|
@@ -3553,6 +3968,7 @@ void init_curb_easy() {
|
|
3553
3968
|
rb_define_method(cCurlEasy, "multi", ruby_curl_easy_multi_get, 0);
|
3554
3969
|
rb_define_method(cCurlEasy, "multi=", ruby_curl_easy_multi_set, 1);
|
3555
3970
|
rb_define_method(cCurlEasy, "last_result", ruby_curl_easy_last_result, 0);
|
3971
|
+
rb_define_method(cCurlEasy, "last_error", ruby_curl_easy_last_error, 0);
|
3556
3972
|
|
3557
3973
|
rb_define_method(cCurlEasy, "setopt", ruby_curl_easy_set_opt, 2);
|
3558
3974
|
rb_define_method(cCurlEasy, "getinfo", ruby_curl_easy_get_opt, 1);
|