curb 0.7.15 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +5 -1
- data/Rakefile +7 -3
- data/ext/curb.c +600 -0
- data/ext/curb.h +5 -5
- data/ext/curb_easy.c +319 -393
- data/ext/curb_easy.h +1 -0
- data/ext/curb_errors.c +10 -0
- data/ext/curb_macros.h +4 -0
- data/ext/curb_multi.c +69 -13
- data/ext/extconf.rb +223 -3
- data/lib/curb.rb +2 -307
- data/lib/curl/easy.rb +385 -0
- data/lib/curl/multi.rb +244 -0
- data/tests/bug_crash_on_debug.rb +39 -0
- data/tests/bug_crash_on_progress.rb +33 -0
- data/tests/helper.rb +8 -0
- data/tests/tc_curl_download.rb +4 -4
- data/tests/tc_curl_easy.rb +110 -10
- data/tests/tc_curl_easy_setopt.rb +31 -0
- metadata +33 -41
data/ext/curb_easy.c
CHANGED
|
@@ -28,6 +28,10 @@ VALUE cCurlEasy;
|
|
|
28
28
|
|
|
29
29
|
/* ================== CURL HANDLER FUNCS ==============*/
|
|
30
30
|
|
|
31
|
+
static VALUE callback_exception(VALUE unused) {
|
|
32
|
+
return Qfalse;
|
|
33
|
+
}
|
|
34
|
+
|
|
31
35
|
/* These handle both body and header data */
|
|
32
36
|
static size_t default_data_handler(char *stream,
|
|
33
37
|
size_t size,
|
|
@@ -111,27 +115,56 @@ static size_t proc_data_handler(char *stream,
|
|
|
111
115
|
}
|
|
112
116
|
}
|
|
113
117
|
|
|
118
|
+
static VALUE call_progress_handler(VALUE ary) {
|
|
119
|
+
return rb_funcall(rb_ary_entry(ary, 0), idCall, 4,
|
|
120
|
+
rb_ary_entry(ary, 1), // rb_float_new(dltotal),
|
|
121
|
+
rb_ary_entry(ary, 2), // rb_float_new(dlnow),
|
|
122
|
+
rb_ary_entry(ary, 3), // rb_float_new(ultotal),
|
|
123
|
+
rb_ary_entry(ary, 4)); // rb_float_new(ulnow));
|
|
124
|
+
}
|
|
125
|
+
|
|
114
126
|
static int proc_progress_handler(VALUE proc,
|
|
115
127
|
double dltotal,
|
|
116
128
|
double dlnow,
|
|
117
129
|
double ultotal,
|
|
118
130
|
double ulnow) {
|
|
119
131
|
VALUE procret;
|
|
132
|
+
VALUE callargs = rb_ary_new2(5);
|
|
120
133
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
134
|
+
rb_ary_store(callargs, 0, proc);
|
|
135
|
+
rb_ary_store(callargs, 1, rb_float_new(dltotal));
|
|
136
|
+
rb_ary_store(callargs, 2, rb_float_new(dlnow));
|
|
137
|
+
rb_ary_store(callargs, 3, rb_float_new(ultotal));
|
|
138
|
+
rb_ary_store(callargs, 4, rb_float_new(ulnow));
|
|
139
|
+
|
|
140
|
+
//v = rb_rescue(range_check, (VALUE)args, range_failed, 0);
|
|
141
|
+
//procret = rb_funcall(proc, idCall, 4, rb_float_new(dltotal),
|
|
142
|
+
// rb_float_new(dlnow),
|
|
143
|
+
// rb_float_new(ultotal),
|
|
144
|
+
// rb_float_new(ulnow));
|
|
145
|
+
procret = rb_rescue(call_progress_handler, callargs, callback_exception, Qnil);
|
|
125
146
|
|
|
126
147
|
return(((procret == Qfalse) || (procret == Qnil)) ? -1 : 0);
|
|
127
148
|
}
|
|
128
149
|
|
|
150
|
+
static VALUE call_debug_handler(VALUE ary) {
|
|
151
|
+
return rb_funcall(rb_ary_entry(ary, 0), idCall, 2,
|
|
152
|
+
rb_ary_entry(ary, 1), // INT2FIX(type),
|
|
153
|
+
rb_ary_entry(ary, 2)); // rb_str_new(data, data_len)
|
|
154
|
+
}
|
|
129
155
|
static int proc_debug_handler(CURL *curl,
|
|
130
156
|
curl_infotype type,
|
|
131
157
|
char *data,
|
|
132
158
|
size_t data_len,
|
|
133
159
|
VALUE proc) {
|
|
134
|
-
|
|
160
|
+
VALUE procret;
|
|
161
|
+
VALUE callargs = rb_ary_new2(3);
|
|
162
|
+
rb_ary_store(callargs, 0, proc);
|
|
163
|
+
rb_ary_store(callargs, 1, INT2FIX(type));
|
|
164
|
+
rb_ary_store(callargs, 2, rb_str_new(data, data_len));
|
|
165
|
+
rb_rescue(call_debug_handler, callargs, callback_exception, Qnil);
|
|
166
|
+
// XXX: no way to indicate to libcurl that we should break out given an exception in the on_debug handler... this means exceptions will be swallowed
|
|
167
|
+
//rb_funcall(proc, idCall, 2, INT2FIX(type), rb_str_new(data, data_len));
|
|
135
168
|
return 0;
|
|
136
169
|
}
|
|
137
170
|
|
|
@@ -186,12 +219,13 @@ static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
|
|
186
219
|
rbce->ssl_version = -1;
|
|
187
220
|
rbce->use_ssl = -1;
|
|
188
221
|
rbce->ftp_filemethod = -1;
|
|
222
|
+
rbce->resolve_mode = CURL_IPRESOLVE_WHATEVER;
|
|
189
223
|
|
|
190
224
|
/* bool opts */
|
|
191
225
|
rbce->proxy_tunnel = 0;
|
|
192
226
|
rbce->fetch_file_time = 0;
|
|
193
227
|
rbce->ssl_verify_peer = 1;
|
|
194
|
-
rbce->ssl_verify_host =
|
|
228
|
+
rbce->ssl_verify_host = 2;
|
|
195
229
|
rbce->header_in_body = 0;
|
|
196
230
|
rbce->use_netrc = 0;
|
|
197
231
|
rbce->follow_location = 0;
|
|
@@ -347,18 +381,6 @@ static VALUE ruby_curl_easy_reset(VALUE self) {
|
|
|
347
381
|
|
|
348
382
|
/* ================ OBJ ATTRIBUTES ==================*/
|
|
349
383
|
|
|
350
|
-
/*
|
|
351
|
-
* call-seq:
|
|
352
|
-
* easy.url = "http://some.url/" => "http://some.url/"
|
|
353
|
-
*
|
|
354
|
-
* Set the URL for subsequent calls to +perform+. It is acceptable
|
|
355
|
-
* (and even recommended) to reuse Curl::Easy instances by reassigning
|
|
356
|
-
* the URL between calls to +perform+.
|
|
357
|
-
*/
|
|
358
|
-
static VALUE ruby_curl_easy_url_set(VALUE self, VALUE url) {
|
|
359
|
-
CURB_OBJECT_HSETTER(ruby_curl_easy, url);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
384
|
/*
|
|
363
385
|
* call-seq:
|
|
364
386
|
* easy.url => string
|
|
@@ -369,35 +391,6 @@ static VALUE ruby_curl_easy_url_get(VALUE self) {
|
|
|
369
391
|
CURB_OBJECT_HGETTER(ruby_curl_easy, url);
|
|
370
392
|
}
|
|
371
393
|
|
|
372
|
-
/*
|
|
373
|
-
* call-seq:
|
|
374
|
-
* easy.proxy_url = string => string
|
|
375
|
-
*
|
|
376
|
-
* Set the URL of the HTTP proxy to use for subsequent calls to +perform+.
|
|
377
|
-
* The URL should specify the the host name or dotted IP address. To specify
|
|
378
|
-
* port number in this string, append :[port] to the end of the host name.
|
|
379
|
-
* The proxy string may be prefixed with [protocol]:// since any such prefix
|
|
380
|
-
* will be ignored. The proxy's port number may optionally be specified with
|
|
381
|
-
* the separate option proxy_port .
|
|
382
|
-
*
|
|
383
|
-
* When you tell the library to use an HTTP proxy, libcurl will transparently
|
|
384
|
-
* convert operations to HTTP even if you specify an FTP URL etc. This may have
|
|
385
|
-
* an impact on what other features of the library you can use, such as
|
|
386
|
-
* FTP specifics that don't work unless you tunnel through the HTTP proxy. Such
|
|
387
|
-
* tunneling is activated with proxy_tunnel = true.
|
|
388
|
-
*
|
|
389
|
-
* libcurl respects the environment variables *http_proxy*, *ftp_proxy*,
|
|
390
|
-
* *all_proxy* etc, if any of those is set. The proxy_url option does however
|
|
391
|
-
* override any possibly set environment variables.
|
|
392
|
-
*
|
|
393
|
-
* Starting with libcurl 7.14.1, the proxy host string given in environment
|
|
394
|
-
* variables can be specified the exact same way as the proxy can be set with
|
|
395
|
-
* proxy_url, including protocol prefix (http://) and embedded user + password.
|
|
396
|
-
*/
|
|
397
|
-
static VALUE ruby_curl_easy_proxy_url_set(VALUE self, VALUE proxy_url) {
|
|
398
|
-
CURB_OBJECT_HSETTER(ruby_curl_easy, proxy_url);
|
|
399
|
-
}
|
|
400
|
-
|
|
401
394
|
/*
|
|
402
395
|
* call-seq:
|
|
403
396
|
* easy.proxy_url => string
|
|
@@ -449,17 +442,6 @@ static VALUE ruby_curl_easy_headers_get(VALUE self) {
|
|
|
449
442
|
return headers;
|
|
450
443
|
}
|
|
451
444
|
|
|
452
|
-
/*
|
|
453
|
-
* call-seq:
|
|
454
|
-
* easy.interface = string => string
|
|
455
|
-
*
|
|
456
|
-
* Set the interface name to use as the outgoing network interface.
|
|
457
|
-
* The name can be an interface name, an IP address or a host name.
|
|
458
|
-
*/
|
|
459
|
-
static VALUE ruby_curl_easy_interface_set(VALUE self, VALUE interface_hm) {
|
|
460
|
-
CURB_OBJECT_HSETTER(ruby_curl_easy, interface_hm);
|
|
461
|
-
}
|
|
462
|
-
|
|
463
445
|
/*
|
|
464
446
|
* call-seq:
|
|
465
447
|
* easy.interface => string
|
|
@@ -471,17 +453,6 @@ static VALUE ruby_curl_easy_interface_get(VALUE self) {
|
|
|
471
453
|
CURB_OBJECT_HGETTER(ruby_curl_easy, interface_hm);
|
|
472
454
|
}
|
|
473
455
|
|
|
474
|
-
/*
|
|
475
|
-
* call-seq:
|
|
476
|
-
* easy.userpwd = string => string
|
|
477
|
-
*
|
|
478
|
-
* Set the username/password string to use for subsequent calls to +perform+.
|
|
479
|
-
* The supplied string should have the form "username:password"
|
|
480
|
-
*/
|
|
481
|
-
static VALUE ruby_curl_easy_userpwd_set(VALUE self, VALUE userpwd) {
|
|
482
|
-
CURB_OBJECT_HSETTER(ruby_curl_easy, userpwd);
|
|
483
|
-
}
|
|
484
|
-
|
|
485
456
|
/*
|
|
486
457
|
* call-seq:
|
|
487
458
|
* easy.userpwd => string
|
|
@@ -493,18 +464,6 @@ static VALUE ruby_curl_easy_userpwd_get(VALUE self) {
|
|
|
493
464
|
CURB_OBJECT_HGETTER(ruby_curl_easy, userpwd);
|
|
494
465
|
}
|
|
495
466
|
|
|
496
|
-
/*
|
|
497
|
-
* call-seq:
|
|
498
|
-
* easy.proxypwd = string => string
|
|
499
|
-
*
|
|
500
|
-
* Set the username/password string to use for proxy connection during
|
|
501
|
-
* subsequent calls to +perform+. The supplied string should have the
|
|
502
|
-
* form "username:password"
|
|
503
|
-
*/
|
|
504
|
-
static VALUE ruby_curl_easy_proxypwd_set(VALUE self, VALUE proxypwd) {
|
|
505
|
-
CURB_OBJECT_HSETTER(ruby_curl_easy, proxypwd);
|
|
506
|
-
}
|
|
507
|
-
|
|
508
467
|
/*
|
|
509
468
|
* call-seq:
|
|
510
469
|
* easy.proxypwd => string
|
|
@@ -517,19 +476,6 @@ static VALUE ruby_curl_easy_proxypwd_get(VALUE self) {
|
|
|
517
476
|
CURB_OBJECT_HGETTER(ruby_curl_easy, proxypwd);
|
|
518
477
|
}
|
|
519
478
|
|
|
520
|
-
|
|
521
|
-
/*
|
|
522
|
-
* call-seq:
|
|
523
|
-
* easy.cookies = "name1=content1; name2=content2;" => string
|
|
524
|
-
*
|
|
525
|
-
* Set cookies to be sent by this Curl::Easy instance. The format of the string should
|
|
526
|
-
* be NAME=CONTENTS, where NAME is the cookie name and CONTENTS is what the cookie should contain.
|
|
527
|
-
* Set multiple cookies in one string like this: "name1=content1; name2=content2;" etc.
|
|
528
|
-
*/
|
|
529
|
-
static VALUE ruby_curl_easy_cookies_set(VALUE self, VALUE cookies) {
|
|
530
|
-
CURB_OBJECT_HSETTER(ruby_curl_easy, cookies);
|
|
531
|
-
}
|
|
532
|
-
|
|
533
479
|
/*
|
|
534
480
|
* call-seq:
|
|
535
481
|
* easy.cookies => "name1=content1; name2=content2;"
|
|
@@ -540,19 +486,6 @@ static VALUE ruby_curl_easy_cookies_get(VALUE self) {
|
|
|
540
486
|
CURB_OBJECT_HGETTER(ruby_curl_easy, cookies);
|
|
541
487
|
}
|
|
542
488
|
|
|
543
|
-
/*
|
|
544
|
-
* call-seq:
|
|
545
|
-
* easy.cookiefile = string => string
|
|
546
|
-
*
|
|
547
|
-
* Set a file that contains cookies to be sent in subsequent requests by this Curl::Easy instance.
|
|
548
|
-
*
|
|
549
|
-
* *Note* that you must set enable_cookies true to enable the cookie
|
|
550
|
-
* engine, or this option will be ignored.
|
|
551
|
-
*/
|
|
552
|
-
static VALUE ruby_curl_easy_cookiefile_set(VALUE self, VALUE cookiefile) {
|
|
553
|
-
CURB_OBJECT_HSETTER(ruby_curl_easy, cookiefile);
|
|
554
|
-
}
|
|
555
|
-
|
|
556
489
|
/*
|
|
557
490
|
* call-seq:
|
|
558
491
|
* easy.cookiefile => string
|
|
@@ -563,20 +496,6 @@ static VALUE ruby_curl_easy_cookiefile_get(VALUE self) {
|
|
|
563
496
|
CURB_OBJECT_HGETTER(ruby_curl_easy, cookiefile);
|
|
564
497
|
}
|
|
565
498
|
|
|
566
|
-
/*
|
|
567
|
-
* call-seq:
|
|
568
|
-
* easy.cookiejar = string => string
|
|
569
|
-
*
|
|
570
|
-
* Set a cookiejar file to use for this Curl::Easy instance.
|
|
571
|
-
* Cookies from the response will be written into this file.
|
|
572
|
-
*
|
|
573
|
-
* *Note* that you must set enable_cookies true to enable the cookie
|
|
574
|
-
* engine, or this option will be ignored.
|
|
575
|
-
*/
|
|
576
|
-
static VALUE ruby_curl_easy_cookiejar_set(VALUE self, VALUE cookiejar) {
|
|
577
|
-
CURB_OBJECT_HSETTER(ruby_curl_easy, cookiejar);
|
|
578
|
-
}
|
|
579
|
-
|
|
580
499
|
/*
|
|
581
500
|
* call-seq:
|
|
582
501
|
* easy.cookiejar => string
|
|
@@ -1453,7 +1372,7 @@ static VALUE ruby_curl_easy_ssl_verify_peer_q(VALUE self) {
|
|
|
1453
1372
|
|
|
1454
1373
|
/*
|
|
1455
1374
|
* call-seq:
|
|
1456
|
-
* easy.ssl_verify_host =
|
|
1375
|
+
* easy.ssl_verify_host = [0, 1, 2] => [0, 1, 2]
|
|
1457
1376
|
*
|
|
1458
1377
|
* Configure whether this Curl instance will verify that the server cert
|
|
1459
1378
|
* is for the server it is known as. When true (the default) the server
|
|
@@ -1465,18 +1384,18 @@ static VALUE ruby_curl_easy_ssl_verify_peer_q(VALUE self) {
|
|
|
1465
1384
|
* The server could be lying. To control lying, see ssl_verify_peer? .
|
|
1466
1385
|
*/
|
|
1467
1386
|
static VALUE ruby_curl_easy_ssl_verify_host_set(VALUE self, VALUE ssl_verify_host) {
|
|
1468
|
-
|
|
1387
|
+
CURB_IMMED_SETTER(ruby_curl_easy, ssl_verify_host, 0);
|
|
1469
1388
|
}
|
|
1470
1389
|
|
|
1471
1390
|
/*
|
|
1472
1391
|
* call-seq:
|
|
1473
|
-
* easy.ssl_verify_host
|
|
1392
|
+
* easy.ssl_verify_host => number
|
|
1474
1393
|
*
|
|
1475
1394
|
* Determine whether this Curl instance will verify that the server cert
|
|
1476
1395
|
* is for the server it is known as.
|
|
1477
1396
|
*/
|
|
1478
|
-
static VALUE
|
|
1479
|
-
|
|
1397
|
+
static VALUE ruby_curl_easy_ssl_verify_host_get(VALUE self) {
|
|
1398
|
+
CURB_IMMED_GETTER(ruby_curl_easy, ssl_verify_host, 0);
|
|
1480
1399
|
}
|
|
1481
1400
|
|
|
1482
1401
|
/*
|
|
@@ -1685,6 +1604,65 @@ static VALUE ruby_curl_easy_ignore_content_length_q(VALUE self) {
|
|
|
1685
1604
|
CURB_BOOLEAN_GETTER(ruby_curl_easy, ignore_content_length);
|
|
1686
1605
|
}
|
|
1687
1606
|
|
|
1607
|
+
/*
|
|
1608
|
+
* call-seq:
|
|
1609
|
+
* easy.resolve_mode => symbol
|
|
1610
|
+
*
|
|
1611
|
+
* Determines what type of IP address this Curl::Easy instance
|
|
1612
|
+
* resolves DNS names to.
|
|
1613
|
+
*/
|
|
1614
|
+
static VALUE ruby_curl_easy_resolve_mode(VALUE self) {
|
|
1615
|
+
ruby_curl_easy *rbce;
|
|
1616
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
1617
|
+
|
|
1618
|
+
unsigned short rm = rbce->resolve_mode;
|
|
1619
|
+
|
|
1620
|
+
switch(rm) {
|
|
1621
|
+
case CURL_IPRESOLVE_V4:
|
|
1622
|
+
return rb_easy_sym("ipv4");
|
|
1623
|
+
case CURL_IPRESOLVE_V6:
|
|
1624
|
+
return rb_easy_sym("ipv6");
|
|
1625
|
+
default:
|
|
1626
|
+
return rb_easy_sym("auto");
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
/*
|
|
1631
|
+
* call-seq:
|
|
1632
|
+
* easy.resolve_mode = symbol => symbol
|
|
1633
|
+
*
|
|
1634
|
+
* Configures what type of IP address this Curl::Easy instance
|
|
1635
|
+
* resolves DNS names to. Valid options are:
|
|
1636
|
+
*
|
|
1637
|
+
* [:auto] resolves DNS names to all IP versions your system allows
|
|
1638
|
+
* [:ipv4] resolves DNS names to IPv4 only
|
|
1639
|
+
* [:ipv6] resolves DNS names to IPv6 only
|
|
1640
|
+
*/
|
|
1641
|
+
static VALUE ruby_curl_easy_resolve_mode_set(VALUE self, VALUE resolve_mode) {
|
|
1642
|
+
if (TYPE(resolve_mode) != T_SYMBOL) {
|
|
1643
|
+
rb_raise(rb_eTypeError, "Must pass a symbol");
|
|
1644
|
+
return Qnil;
|
|
1645
|
+
} else {
|
|
1646
|
+
ruby_curl_easy *rbce;
|
|
1647
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
1648
|
+
|
|
1649
|
+
ID resolve_mode_id = rb_to_id(resolve_mode);
|
|
1650
|
+
|
|
1651
|
+
if (resolve_mode_id == rb_intern("auto")) {
|
|
1652
|
+
rbce->resolve_mode = CURL_IPRESOLVE_WHATEVER;
|
|
1653
|
+
return resolve_mode;
|
|
1654
|
+
} else if (resolve_mode_id == rb_intern("ipv4")) {
|
|
1655
|
+
rbce->resolve_mode = CURL_IPRESOLVE_V4;
|
|
1656
|
+
return resolve_mode;
|
|
1657
|
+
} else if (resolve_mode_id == rb_intern("ipv6")) {
|
|
1658
|
+
rbce->resolve_mode = CURL_IPRESOLVE_V6;
|
|
1659
|
+
return resolve_mode;
|
|
1660
|
+
} else {
|
|
1661
|
+
rb_raise(rb_eArgError, "Must set to one of :auto, :ipv4, :ipv6");
|
|
1662
|
+
return Qnil;
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
1688
1666
|
|
|
1689
1667
|
|
|
1690
1668
|
/* ================= EVENT PROCS ================== */
|
|
@@ -1738,6 +1716,36 @@ static VALUE ruby_curl_easy_on_failure_set(int argc, VALUE *argv, VALUE self) {
|
|
|
1738
1716
|
CURB_HANDLER_PROC_HSETTER(ruby_curl_easy, failure_proc);
|
|
1739
1717
|
}
|
|
1740
1718
|
|
|
1719
|
+
/*
|
|
1720
|
+
* call-seq:
|
|
1721
|
+
* easy.on_missing {|easy,code| ... } => <old handler;>
|
|
1722
|
+
*
|
|
1723
|
+
* Assign or remove the on_missing handler for this Curl::Easy instance.
|
|
1724
|
+
* To remove a previously-supplied handler, call this method with no attached
|
|
1725
|
+
* block.
|
|
1726
|
+
*
|
|
1727
|
+
* The +on_missing+ handler is called when request is finished with a
|
|
1728
|
+
* status of 40x
|
|
1729
|
+
*/
|
|
1730
|
+
static VALUE ruby_curl_easy_on_missing_set(int argc, VALUE *argv, VALUE self) {
|
|
1731
|
+
CURB_HANDLER_PROC_HSETTER(ruby_curl_easy, missing_proc);
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
/*
|
|
1735
|
+
* call-seq:
|
|
1736
|
+
* easy.on_redirect {|easy,code| ... } => <old handler;>
|
|
1737
|
+
*
|
|
1738
|
+
* Assign or remove the on_redirect handler for this Curl::Easy instance.
|
|
1739
|
+
* To remove a previously-supplied handler, call this method with no attached
|
|
1740
|
+
* block.
|
|
1741
|
+
*
|
|
1742
|
+
* The +on_redirect+ handler is called when request is finished with a
|
|
1743
|
+
* status of 30x
|
|
1744
|
+
*/
|
|
1745
|
+
static VALUE ruby_curl_easy_on_redirect_set(int argc, VALUE *argv, VALUE self) {
|
|
1746
|
+
CURB_HANDLER_PROC_HSETTER(ruby_curl_easy, redirect_proc);
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1741
1749
|
/*
|
|
1742
1750
|
* call-seq:
|
|
1743
1751
|
* easy.on_complete {|easy| ... } => <old handler>
|
|
@@ -1816,7 +1824,10 @@ static VALUE ruby_curl_easy_on_debug_set(int argc, VALUE *argv, VALUE self) {
|
|
|
1816
1824
|
/***********************************************
|
|
1817
1825
|
* This is an rb_iterate callback used to set up http headers.
|
|
1818
1826
|
*/
|
|
1819
|
-
static VALUE cb_each_http_header(VALUE header,
|
|
1827
|
+
static VALUE cb_each_http_header(VALUE header, VALUE wrap) {
|
|
1828
|
+
struct curl_slist **list;
|
|
1829
|
+
Data_Get_Struct(wrap, struct curl_slist *, list);
|
|
1830
|
+
|
|
1820
1831
|
VALUE header_str = Qnil;
|
|
1821
1832
|
|
|
1822
1833
|
//rb_p(header);
|
|
@@ -1845,7 +1856,10 @@ static VALUE cb_each_http_header(VALUE header, struct curl_slist **list) {
|
|
|
1845
1856
|
/***********************************************
|
|
1846
1857
|
* This is an rb_iterate callback used to set up ftp commands.
|
|
1847
1858
|
*/
|
|
1848
|
-
static VALUE cb_each_ftp_command(VALUE ftp_command,
|
|
1859
|
+
static VALUE cb_each_ftp_command(VALUE ftp_command, VALUE wrap) {
|
|
1860
|
+
struct curl_slist **list;
|
|
1861
|
+
Data_Get_Struct(wrap, struct curl_slist *, list);
|
|
1862
|
+
|
|
1849
1863
|
VALUE ftp_command_string = rb_obj_as_string(ftp_command);
|
|
1850
1864
|
*list = curl_slist_append(*list, StringValuePtr(ftp_command));
|
|
1851
1865
|
|
|
@@ -1873,7 +1887,6 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
|
1873
1887
|
|
|
1874
1888
|
url = rb_check_string_type(_url);
|
|
1875
1889
|
|
|
1876
|
-
// Need to configure the handler as per settings in rbce
|
|
1877
1890
|
curl_easy_setopt(curl, CURLOPT_URL, StringValuePtr(url));
|
|
1878
1891
|
|
|
1879
1892
|
// network stuff and auth
|
|
@@ -1976,12 +1989,12 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
|
1976
1989
|
curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, rbce->proxy_tunnel);
|
|
1977
1990
|
curl_easy_setopt(curl, CURLOPT_FILETIME, rbce->fetch_file_time);
|
|
1978
1991
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, rbce->ssl_verify_peer);
|
|
1979
|
-
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, rbce->
|
|
1992
|
+
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, rbce->ssl_verify_host);
|
|
1980
1993
|
|
|
1981
1994
|
if ((rbce->use_netrc != Qnil) && (rbce->use_netrc != Qfalse)) {
|
|
1982
|
-
curl_easy_setopt(curl,
|
|
1995
|
+
curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
|
|
1983
1996
|
} else {
|
|
1984
|
-
curl_easy_setopt(curl,
|
|
1997
|
+
curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_IGNORED);
|
|
1985
1998
|
}
|
|
1986
1999
|
|
|
1987
2000
|
curl_easy_setopt(curl, CURLOPT_UNRESTRICTED_AUTH, rbce->unrestricted_auth);
|
|
@@ -1992,6 +2005,8 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
|
1992
2005
|
|
|
1993
2006
|
curl_easy_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, rbce->ignore_content_length);
|
|
1994
2007
|
|
|
2008
|
+
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, rbce->resolve_mode);
|
|
2009
|
+
|
|
1995
2010
|
|
|
1996
2011
|
#if LIBCURL_VERSION_NUM >= 0x070a08
|
|
1997
2012
|
curl_easy_setopt(curl, CURLOPT_FTP_RESPONSE_TIMEOUT, rbce->ftp_response_timeout);
|
|
@@ -2077,7 +2092,9 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
|
2077
2092
|
|
|
2078
2093
|
/* Set up HTTPS cert handling if necessary */
|
|
2079
2094
|
if (!rb_easy_nil("cert")) {
|
|
2080
|
-
|
|
2095
|
+
if (!rb_easy_nil("certtype")) {
|
|
2096
|
+
curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, rb_easy_get_str("certtype"));
|
|
2097
|
+
}
|
|
2081
2098
|
curl_easy_setopt(curl, CURLOPT_SSLCERT, rb_easy_get_str("cert"));
|
|
2082
2099
|
if (!rb_easy_nil("certpassword")) {
|
|
2083
2100
|
curl_easy_setopt(curl, CURLOPT_SSLCERTPASSWD, rb_easy_get_str("certpassword"));
|
|
@@ -2086,13 +2103,15 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
|
2086
2103
|
curl_easy_setopt(curl, CURLOPT_SSLKEY, rb_easy_get_str("cert_key"));
|
|
2087
2104
|
}
|
|
2088
2105
|
}
|
|
2106
|
+
|
|
2089
2107
|
if (!rb_easy_nil("cacert")) {
|
|
2108
|
+
curl_easy_setopt(curl, CURLOPT_CAINFO, rb_easy_get_str("cacert"));
|
|
2109
|
+
}
|
|
2090
2110
|
#ifdef HAVE_CURL_CONFIG_CA
|
|
2111
|
+
else {
|
|
2091
2112
|
curl_easy_setopt(curl, CURLOPT_CAINFO, CURL_CONFIG_CA);
|
|
2092
|
-
#else
|
|
2093
|
-
curl_easy_setopt(curl, CURLOPT_CAINFO, "/usr/local/share/curl/curl-ca-bundle.crt");
|
|
2094
|
-
#endif
|
|
2095
2113
|
}
|
|
2114
|
+
#endif
|
|
2096
2115
|
|
|
2097
2116
|
#ifdef CURL_VERSION_SSL
|
|
2098
2117
|
if (rbce->ssl_version > 0) {
|
|
@@ -2122,7 +2141,8 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
|
2122
2141
|
|
|
2123
2142
|
if (!rb_easy_nil("headers")) {
|
|
2124
2143
|
if (rb_easy_type_check("headers", T_ARRAY) || rb_easy_type_check("headers", T_HASH)) {
|
|
2125
|
-
|
|
2144
|
+
VALUE wrap = Data_Wrap_Struct(rb_cObject, 0, 0, hdrs);
|
|
2145
|
+
rb_iterate(rb_each, rb_easy_get("headers"), cb_each_http_header, wrap);
|
|
2126
2146
|
} else {
|
|
2127
2147
|
VALUE headers_str = rb_obj_as_string(rb_easy_get("headers"));
|
|
2128
2148
|
*hdrs = curl_slist_append(*hdrs, StringValuePtr(headers_str));
|
|
@@ -2136,7 +2156,8 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
|
2136
2156
|
/* Setup FTP commands if necessary */
|
|
2137
2157
|
if (!rb_easy_nil("ftp_commands")) {
|
|
2138
2158
|
if (rb_easy_type_check("ftp_commands", T_ARRAY)) {
|
|
2139
|
-
|
|
2159
|
+
VALUE wrap = Data_Wrap_Struct(rb_cObject, 0, 0, cmds);
|
|
2160
|
+
rb_iterate(rb_each, rb_easy_get("ftp_commands"), cb_each_ftp_command, wrap);
|
|
2140
2161
|
}
|
|
2141
2162
|
|
|
2142
2163
|
if (*cmds) {
|
|
@@ -2181,35 +2202,6 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
|
|
|
2181
2202
|
return Qnil;
|
|
2182
2203
|
}
|
|
2183
2204
|
|
|
2184
|
-
/***********************************************
|
|
2185
|
-
*
|
|
2186
|
-
* This is the main worker for the perform methods (get, post, head, put).
|
|
2187
|
-
* It's not surfaced as a Ruby method - instead, the individual request
|
|
2188
|
-
* methods are responsible for setting up stuff specific to that type,
|
|
2189
|
-
* then calling this to handle common stuff and do the perform.
|
|
2190
|
-
*
|
|
2191
|
-
* Always returns Qtrue, rb_raise on error.
|
|
2192
|
-
*
|
|
2193
|
-
*/
|
|
2194
|
-
static VALUE handle_perform(VALUE self, ruby_curl_easy *rbce) {
|
|
2195
|
-
|
|
2196
|
-
VALUE ret;
|
|
2197
|
-
|
|
2198
|
-
/* reuse existing multi handle for this easy handle */
|
|
2199
|
-
if (NIL_P(rbce->multi)) {
|
|
2200
|
-
rbce->multi = ruby_curl_multi_new(cCurlMulti);
|
|
2201
|
-
}
|
|
2202
|
-
rb_funcall(rbce->multi, rb_intern("add"), 1, self );
|
|
2203
|
-
ret = rb_funcall(rbce->multi, rb_intern("perform"), 0);
|
|
2204
|
-
|
|
2205
|
-
/* check for errors in the easy response and raise exceptions if anything went wrong and their is no on_failure handler */
|
|
2206
|
-
if (rbce->last_result != 0 && rb_easy_nil("failure_proc")) {
|
|
2207
|
-
raise_curl_easy_error_exception(rbce->last_result);
|
|
2208
|
-
}
|
|
2209
|
-
|
|
2210
|
-
return ret;
|
|
2211
|
-
}
|
|
2212
|
-
|
|
2213
2205
|
/*
|
|
2214
2206
|
* call-seq:
|
|
2215
2207
|
* easy.http_get => true
|
|
@@ -2228,7 +2220,7 @@ static VALUE ruby_curl_easy_perform_get(VALUE self) {
|
|
|
2228
2220
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
|
|
2229
2221
|
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
|
|
2230
2222
|
|
|
2231
|
-
return
|
|
2223
|
+
return rb_funcall(self, rb_intern("perform"), 0);
|
|
2232
2224
|
}
|
|
2233
2225
|
|
|
2234
2226
|
/*
|
|
@@ -2244,7 +2236,7 @@ static VALUE ruby_curl_easy_perform_verb_str(VALUE self, const char *verb) {
|
|
|
2244
2236
|
|
|
2245
2237
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, verb);
|
|
2246
2238
|
|
|
2247
|
-
retval =
|
|
2239
|
+
retval = rb_funcall(self, rb_intern("perform"), 0);
|
|
2248
2240
|
|
|
2249
2241
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
|
|
2250
2242
|
|
|
@@ -2273,33 +2265,17 @@ static VALUE ruby_curl_easy_perform_delete(VALUE self) {
|
|
|
2273
2265
|
static VALUE ruby_curl_easy_perform_verb(VALUE self, VALUE verb) {
|
|
2274
2266
|
VALUE str_verb;
|
|
2275
2267
|
if (rb_type(verb) == T_STRING) {
|
|
2276
|
-
return ruby_curl_easy_perform_verb_str(self,
|
|
2268
|
+
return ruby_curl_easy_perform_verb_str(self, StringValueCStr(verb));
|
|
2277
2269
|
}
|
|
2278
2270
|
else if (rb_respond_to(verb,rb_intern("to_s"))) {
|
|
2279
2271
|
str_verb = rb_funcall(verb, rb_intern("to_s"), 0);
|
|
2280
|
-
return ruby_curl_easy_perform_verb_str(self,
|
|
2272
|
+
return ruby_curl_easy_perform_verb_str(self, StringValueCStr(str_verb));
|
|
2281
2273
|
}
|
|
2282
2274
|
else {
|
|
2283
2275
|
rb_raise(rb_eRuntimeError, "Invalid HTTP VERB, must response to 'to_s'");
|
|
2284
2276
|
}
|
|
2285
2277
|
}
|
|
2286
2278
|
|
|
2287
|
-
/*
|
|
2288
|
-
* call-seq:
|
|
2289
|
-
* easy.perform => true
|
|
2290
|
-
*
|
|
2291
|
-
* Transfer the currently configured URL using the options set for this
|
|
2292
|
-
* Curl::Easy instance. If this is an HTTP URL, it will be transferred via
|
|
2293
|
-
* the GET or HEAD request method.
|
|
2294
|
-
*/
|
|
2295
|
-
static VALUE ruby_curl_easy_perform(VALUE self) {
|
|
2296
|
-
ruby_curl_easy *rbce;
|
|
2297
|
-
|
|
2298
|
-
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2299
|
-
|
|
2300
|
-
return handle_perform(self,rbce);
|
|
2301
|
-
}
|
|
2302
|
-
|
|
2303
2279
|
/*
|
|
2304
2280
|
* call-seq:
|
|
2305
2281
|
* easy.http_post("url=encoded%20form%20data;and=so%20on") => true
|
|
@@ -2345,6 +2321,17 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
|
|
|
2345
2321
|
for (i = 0; i < argc; i++) {
|
|
2346
2322
|
if (rb_obj_is_instance_of(argv[i], cCurlPostField)) {
|
|
2347
2323
|
append_to_form(argv[i], &first, &last);
|
|
2324
|
+
} else if (rb_type(argv[i]) == T_ARRAY) {
|
|
2325
|
+
// see: https://github.com/rvanlieshout/curb/commit/8bcdefddc0162484681ebd1a92d52a642666a445
|
|
2326
|
+
int c = 0, argv_len = (int)RARRAY_LEN(argv[i]);
|
|
2327
|
+
for (; c < argv_len; ++c) {
|
|
2328
|
+
if (rb_obj_is_instance_of(rb_ary_entry(argv[i],c), cCurlPostField)) {
|
|
2329
|
+
append_to_form(rb_ary_entry(argv[i],c), &first, &last);
|
|
2330
|
+
} else {
|
|
2331
|
+
rb_raise(eCurlErrInvalidPostField, "You must use PostFields only with multipart form posts");
|
|
2332
|
+
return Qnil;
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2348
2335
|
} else {
|
|
2349
2336
|
rb_raise(eCurlErrInvalidPostField, "You must use PostFields only with multipart form posts");
|
|
2350
2337
|
return Qnil;
|
|
@@ -2353,7 +2340,7 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
|
|
|
2353
2340
|
|
|
2354
2341
|
curl_easy_setopt(curl, CURLOPT_POST, 0);
|
|
2355
2342
|
curl_easy_setopt(curl, CURLOPT_HTTPPOST, first);
|
|
2356
|
-
ret =
|
|
2343
|
+
ret = rb_funcall(self, rb_intern("perform"), 0);
|
|
2357
2344
|
curl_formfree(first);
|
|
2358
2345
|
|
|
2359
2346
|
return ret;
|
|
@@ -2375,7 +2362,7 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
|
|
|
2375
2362
|
ruby_curl_easy_post_body_set(self, post_body);
|
|
2376
2363
|
}
|
|
2377
2364
|
|
|
2378
|
-
return
|
|
2365
|
+
return rb_funcall(self, rb_intern("perform"), 0);
|
|
2379
2366
|
}
|
|
2380
2367
|
}
|
|
2381
2368
|
}
|
|
@@ -2400,7 +2387,7 @@ static VALUE ruby_curl_easy_perform_head(VALUE self) {
|
|
|
2400
2387
|
|
|
2401
2388
|
curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
|
|
2402
2389
|
|
|
2403
|
-
ret =
|
|
2390
|
+
ret = rb_funcall(self, rb_intern("perform"), 0);
|
|
2404
2391
|
|
|
2405
2392
|
curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
|
|
2406
2393
|
return ret;
|
|
@@ -2418,71 +2405,14 @@ static VALUE ruby_curl_easy_set_head_option(VALUE self, VALUE onoff) {
|
|
|
2418
2405
|
|
|
2419
2406
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2420
2407
|
|
|
2421
|
-
if(
|
|
2408
|
+
if (onoff == Qtrue) {
|
|
2422
2409
|
curl_easy_setopt(rbce->curl, CURLOPT_NOBODY, 1);
|
|
2423
|
-
}
|
|
2424
|
-
else {
|
|
2410
|
+
} else {
|
|
2425
2411
|
curl_easy_setopt(rbce->curl, CURLOPT_NOBODY, 0);
|
|
2426
2412
|
}
|
|
2427
2413
|
|
|
2428
2414
|
return onoff;
|
|
2429
2415
|
}
|
|
2430
|
-
/*
|
|
2431
|
-
*call-seq:
|
|
2432
|
-
*
|
|
2433
|
-
* easy = Curl::Easy.new("url")
|
|
2434
|
-
* easy.version = Curl::HTTP_1_1
|
|
2435
|
-
* easy.version = Curl::HTTP_1_0
|
|
2436
|
-
* easy.version = Curl::HTTP_NONE
|
|
2437
|
-
*
|
|
2438
|
-
*/
|
|
2439
|
-
static VALUE ruby_curl_easy_set_version(VALUE self, VALUE version) {
|
|
2440
|
-
ruby_curl_easy *rbce;
|
|
2441
|
-
//fprintf(stderr,"CURL_HTTP_VERSION_1_1: %d, CURL_HTTP_VERSION_1_0: %d, CURL_HTTP_VERSION_NONE: %d\n", CURL_HTTP_VERSION_1_1, CURL_HTTP_VERSION_1_0, CURL_HTTP_VERSION_NONE);
|
|
2442
|
-
|
|
2443
|
-
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2444
|
-
|
|
2445
|
-
curl_easy_setopt(rbce->curl, CURLOPT_HTTP_VERSION, FIX2INT(version));
|
|
2446
|
-
|
|
2447
|
-
return version;
|
|
2448
|
-
}
|
|
2449
|
-
/*
|
|
2450
|
-
* call-seq:
|
|
2451
|
-
*
|
|
2452
|
-
* easy = Curl::Easy.new
|
|
2453
|
-
* easy.nosignal = true
|
|
2454
|
-
*/
|
|
2455
|
-
static VALUE ruby_curl_easy_set_nosignal(VALUE self, VALUE onoff) {
|
|
2456
|
-
ruby_curl_easy *rbce;
|
|
2457
|
-
|
|
2458
|
-
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2459
|
-
|
|
2460
|
-
curl_easy_setopt(rbce->curl, CURLOPT_NOSIGNAL, (Qtrue == onoff) ? 1 : 0);
|
|
2461
|
-
|
|
2462
|
-
return onoff;
|
|
2463
|
-
}
|
|
2464
|
-
/*
|
|
2465
|
-
*call-seq:
|
|
2466
|
-
* easy = Curl::Easy.new("url") do|c|
|
|
2467
|
-
* c.delete = true
|
|
2468
|
-
* end
|
|
2469
|
-
* easy.perform
|
|
2470
|
-
*/
|
|
2471
|
-
static VALUE ruby_curl_easy_set_delete_option(VALUE self, VALUE onoff) {
|
|
2472
|
-
ruby_curl_easy *rbce;
|
|
2473
|
-
|
|
2474
|
-
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2475
|
-
|
|
2476
|
-
if( onoff == Qtrue ) {
|
|
2477
|
-
curl_easy_setopt(rbce->curl, CURLOPT_CUSTOMREQUEST, "DELETE");
|
|
2478
|
-
}
|
|
2479
|
-
else {
|
|
2480
|
-
curl_easy_setopt(rbce->curl, CURLOPT_CUSTOMREQUEST, NULL);
|
|
2481
|
-
}
|
|
2482
|
-
|
|
2483
|
-
return onoff;
|
|
2484
|
-
}
|
|
2485
|
-
|
|
2486
2416
|
/*
|
|
2487
2417
|
* call-seq:
|
|
2488
2418
|
* easy.http_put(data) => true
|
|
@@ -2494,28 +2424,17 @@ static VALUE ruby_curl_easy_set_delete_option(VALUE self, VALUE onoff) {
|
|
|
2494
2424
|
static VALUE ruby_curl_easy_perform_put(VALUE self, VALUE data) {
|
|
2495
2425
|
ruby_curl_easy *rbce;
|
|
2496
2426
|
CURL *curl;
|
|
2497
|
-
|
|
2427
|
+
|
|
2498
2428
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2499
2429
|
curl = rbce->curl;
|
|
2500
|
-
|
|
2430
|
+
|
|
2501
2431
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
|
|
2502
2432
|
ruby_curl_easy_put_data_set(self, data);
|
|
2503
|
-
|
|
2504
|
-
return handle_perform(self, rbce);
|
|
2505
|
-
}
|
|
2506
2433
|
|
|
2507
|
-
|
|
2508
|
-
* call-seq:
|
|
2509
|
-
* Curl::Easy.http_put(url, data) {|c| ... }
|
|
2510
|
-
*
|
|
2511
|
-
* see easy.http_put
|
|
2512
|
-
*/
|
|
2513
|
-
static VALUE ruby_curl_easy_class_perform_put(VALUE klass, VALUE url, VALUE data) {
|
|
2514
|
-
VALUE c = ruby_curl_easy_new(1, &url, klass);
|
|
2515
|
-
ruby_curl_easy_perform_put(c, data);
|
|
2516
|
-
return c;
|
|
2434
|
+
return rb_funcall(self, rb_intern("perform"), 0);
|
|
2517
2435
|
}
|
|
2518
2436
|
|
|
2437
|
+
|
|
2519
2438
|
/* =================== DATA FUNCS =============== */
|
|
2520
2439
|
|
|
2521
2440
|
/*
|
|
@@ -2923,7 +2842,10 @@ static VALUE ruby_curl_easy_ssl_verify_result_get(VALUE self) {
|
|
|
2923
2842
|
|
|
2924
2843
|
/* TODO CURLINFO_SSL_ENGINES
|
|
2925
2844
|
|
|
2926
|
-
Pass the address of a 'struct curl_slist *' to receive a linked-list of OpenSSL crypto-engines supported.
|
|
2845
|
+
Pass the address of a 'struct curl_slist *' to receive a linked-list of OpenSSL crypto-engines supported.
|
|
2846
|
+
Note that engines are normally implemented in separate dynamic libraries.
|
|
2847
|
+
Hence not all the returned engines may be available at run-time.
|
|
2848
|
+
NOTE: you must call curl_slist_free_all(3) on the list pointer once you're done with it, as libcurl will not free the data for you. (Added in 7.12.3)
|
|
2927
2849
|
*/
|
|
2928
2850
|
|
|
2929
2851
|
/*
|
|
@@ -3099,6 +3021,119 @@ static VALUE ruby_curl_easy_ftp_entry_path_get(VALUE self) {
|
|
|
3099
3021
|
#endif
|
|
3100
3022
|
}
|
|
3101
3023
|
|
|
3024
|
+
/*
|
|
3025
|
+
* call-seq:
|
|
3026
|
+
* easy.multi => "#<Curl::Multi>"
|
|
3027
|
+
*/
|
|
3028
|
+
static VALUE ruby_curl_easy_multi_get(VALUE self) {
|
|
3029
|
+
ruby_curl_easy *rbce;
|
|
3030
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
3031
|
+
return rbce->multi;
|
|
3032
|
+
}
|
|
3033
|
+
|
|
3034
|
+
/*
|
|
3035
|
+
* call-seq:
|
|
3036
|
+
* easy.multi=multi => "#<Curl::Multi>"
|
|
3037
|
+
*/
|
|
3038
|
+
static VALUE ruby_curl_easy_multi_set(VALUE self, VALUE multi) {
|
|
3039
|
+
ruby_curl_easy *rbce;
|
|
3040
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
3041
|
+
rbce->multi = multi;
|
|
3042
|
+
return rbce->multi;
|
|
3043
|
+
}
|
|
3044
|
+
|
|
3045
|
+
/*
|
|
3046
|
+
* call-seq:
|
|
3047
|
+
* easy.last_result => 0
|
|
3048
|
+
*/
|
|
3049
|
+
static VALUE ruby_curl_easy_last_result(VALUE self) {
|
|
3050
|
+
ruby_curl_easy *rbce;
|
|
3051
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
3052
|
+
return INT2FIX(rbce->last_result);
|
|
3053
|
+
}
|
|
3054
|
+
|
|
3055
|
+
/*
|
|
3056
|
+
* call-seq:
|
|
3057
|
+
* easy.setopt Fixnum, value => value
|
|
3058
|
+
*
|
|
3059
|
+
* Iniital access to libcurl curl_easy_setopt
|
|
3060
|
+
*/
|
|
3061
|
+
static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
3062
|
+
ruby_curl_easy *rbce;
|
|
3063
|
+
long option = FIX2LONG(opt);
|
|
3064
|
+
|
|
3065
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
3066
|
+
|
|
3067
|
+
switch (option) {
|
|
3068
|
+
/* BEHAVIOR OPTIONS */
|
|
3069
|
+
case CURLOPT_VERBOSE: {
|
|
3070
|
+
VALUE verbose = val;
|
|
3071
|
+
CURB_BOOLEAN_SETTER(ruby_curl_easy, verbose);
|
|
3072
|
+
} break;
|
|
3073
|
+
case CURLOPT_HEADER:
|
|
3074
|
+
case CURLOPT_NOPROGRESS:
|
|
3075
|
+
case CURLOPT_NOSIGNAL:
|
|
3076
|
+
curl_easy_setopt(rbce->curl, CURLOPT_NOSIGNAL, val == Qtrue ? 1 : 0);
|
|
3077
|
+
break;
|
|
3078
|
+
/* TODO: CALLBACK OPTIONS */
|
|
3079
|
+
/* TODO: ERROR OPTIONS */
|
|
3080
|
+
/* NETWORK OPTIONS */
|
|
3081
|
+
case CURLOPT_URL: {
|
|
3082
|
+
VALUE url = val;
|
|
3083
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, url);
|
|
3084
|
+
} break;
|
|
3085
|
+
case CURLOPT_CUSTOMREQUEST:
|
|
3086
|
+
curl_easy_setopt(rbce->curl, CURLOPT_CUSTOMREQUEST, NIL_P(val) ? NULL : StringValueCStr(val));
|
|
3087
|
+
break;
|
|
3088
|
+
case CURLOPT_HTTP_VERSION:
|
|
3089
|
+
curl_easy_setopt(rbce->curl, CURLOPT_HTTP_VERSION, FIX2INT(val));
|
|
3090
|
+
break;
|
|
3091
|
+
case CURLOPT_PROXY: {
|
|
3092
|
+
VALUE proxy_url = val;
|
|
3093
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, proxy_url);
|
|
3094
|
+
} break;
|
|
3095
|
+
case CURLOPT_INTERFACE: {
|
|
3096
|
+
VALUE interface_hm = val;
|
|
3097
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, interface_hm);
|
|
3098
|
+
} break;
|
|
3099
|
+
case CURLOPT_USERPWD: {
|
|
3100
|
+
VALUE userpwd = val;
|
|
3101
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, userpwd);
|
|
3102
|
+
} break;
|
|
3103
|
+
case CURLOPT_PROXYUSERPWD: {
|
|
3104
|
+
VALUE proxypwd = val;
|
|
3105
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, proxypwd);
|
|
3106
|
+
} break;
|
|
3107
|
+
case CURLOPT_COOKIE: {
|
|
3108
|
+
VALUE cookies = val;
|
|
3109
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, cookies);
|
|
3110
|
+
} break;
|
|
3111
|
+
case CURLOPT_COOKIEFILE: {
|
|
3112
|
+
VALUE cookiefile = val;
|
|
3113
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, cookiefile);
|
|
3114
|
+
} break;
|
|
3115
|
+
case CURLOPT_COOKIEJAR: {
|
|
3116
|
+
VALUE cookiejar = val;
|
|
3117
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, cookiejar);
|
|
3118
|
+
} break;
|
|
3119
|
+
|
|
3120
|
+
default:
|
|
3121
|
+
break;
|
|
3122
|
+
}
|
|
3123
|
+
|
|
3124
|
+
return val;
|
|
3125
|
+
}
|
|
3126
|
+
|
|
3127
|
+
/*
|
|
3128
|
+
* call-seq:
|
|
3129
|
+
* easy.getinfo Fixnum => value
|
|
3130
|
+
*
|
|
3131
|
+
* Iniital access to libcurl curl_easy_getinfo, remember getinfo doesn't return the same values as setopt
|
|
3132
|
+
*/
|
|
3133
|
+
static VALUE ruby_curl_easy_get_opt(VALUE self, VALUE opt) {
|
|
3134
|
+
return Qnil;
|
|
3135
|
+
}
|
|
3136
|
+
|
|
3102
3137
|
/*
|
|
3103
3138
|
* call-seq:
|
|
3104
3139
|
* easy.inspect => "#<Curl::Easy http://google.com/>"
|
|
@@ -3113,7 +3148,7 @@ static VALUE ruby_curl_easy_inspect(VALUE self) {
|
|
|
3113
3148
|
size_t len = 13+((RSTRING_LEN(url) > 50) ? 50 : RSTRING_LEN(url));
|
|
3114
3149
|
/* "#<Net::HTTP http://www.google.com/:80 open=false>" */
|
|
3115
3150
|
memcpy(buf,"#<Curl::Easy ", 13);
|
|
3116
|
-
memcpy(buf+13,
|
|
3151
|
+
memcpy(buf+13,StringValueCStr(url), (len - 13));
|
|
3117
3152
|
buf[len++] = '>';
|
|
3118
3153
|
return rb_str_new(buf,len);
|
|
3119
3154
|
}
|
|
@@ -3189,114 +3224,14 @@ static VALUE ruby_curl_easy_unescape(VALUE self, VALUE str) {
|
|
|
3189
3224
|
|
|
3190
3225
|
/*
|
|
3191
3226
|
* call-seq:
|
|
3192
|
-
* Curl::Easy.
|
|
3227
|
+
* Curl::Easy.error(code) => String
|
|
3193
3228
|
*
|
|
3194
|
-
*
|
|
3195
|
-
* the specified URL and calls the general +perform+ method, before returning
|
|
3196
|
-
* the new instance. For HTTP URLs, this is equivalent to calling +http_get+.
|
|
3197
|
-
*
|
|
3198
|
-
* If a block is supplied, the new instance will be yielded just prior to
|
|
3199
|
-
* the +http_get+ call.
|
|
3229
|
+
* translate an internal libcurl error to ruby error class
|
|
3200
3230
|
*/
|
|
3201
|
-
static VALUE
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
if (rb_block_given_p()) {
|
|
3205
|
-
rb_yield(c);
|
|
3206
|
-
}
|
|
3207
|
-
|
|
3208
|
-
ruby_curl_easy_perform(c);
|
|
3209
|
-
return c;
|
|
3231
|
+
static VALUE ruby_curl_easy_error_message(VALUE klass, VALUE code) {
|
|
3232
|
+
return rb_curl_easy_error(FIX2INT(code));
|
|
3210
3233
|
}
|
|
3211
3234
|
|
|
3212
|
-
/*
|
|
3213
|
-
* call-seq:
|
|
3214
|
-
* Curl::Easy.http_get(url) { |easy| ... } => #<Curl::Easy...>
|
|
3215
|
-
*
|
|
3216
|
-
* Convenience method that creates a new Curl::Easy instance with
|
|
3217
|
-
* the specified URL and calls +http_get+, before returning the new instance.
|
|
3218
|
-
*
|
|
3219
|
-
* If a block is supplied, the new instance will be yielded just prior to
|
|
3220
|
-
* the +http_get+ call.
|
|
3221
|
-
*/
|
|
3222
|
-
static VALUE ruby_curl_easy_class_perform_get(int argc, VALUE *argv, VALUE klass) {
|
|
3223
|
-
VALUE c = ruby_curl_easy_new(argc, argv, klass);
|
|
3224
|
-
|
|
3225
|
-
ruby_curl_easy_perform_get(c);
|
|
3226
|
-
return c;
|
|
3227
|
-
}
|
|
3228
|
-
|
|
3229
|
-
/*
|
|
3230
|
-
* call-seq:
|
|
3231
|
-
* Curl::Easy.http_delete(url) { |easy| ... } => #<Curl::Easy...>
|
|
3232
|
-
*
|
|
3233
|
-
* Convenience method that creates a new Curl::Easy instance with
|
|
3234
|
-
* the specified URL and calls +http_delete+, before returning the new instance.
|
|
3235
|
-
*
|
|
3236
|
-
* If a block is supplied, the new instance will be yielded just prior to
|
|
3237
|
-
* the +http_delete+ call.
|
|
3238
|
-
*/
|
|
3239
|
-
static VALUE ruby_curl_easy_class_perform_delete(int argc, VALUE *argv, VALUE klass) {
|
|
3240
|
-
VALUE c = ruby_curl_easy_new(argc, argv, klass);
|
|
3241
|
-
|
|
3242
|
-
ruby_curl_easy_perform_delete(c);
|
|
3243
|
-
return c;
|
|
3244
|
-
}
|
|
3245
|
-
|
|
3246
|
-
/*
|
|
3247
|
-
* call-seq:
|
|
3248
|
-
* Curl::Easy.http_head(url) { |easy| ... } => #<Curl::Easy...>
|
|
3249
|
-
*
|
|
3250
|
-
* Convenience method that creates a new Curl::Easy instance with
|
|
3251
|
-
* the specified URL and calls +http_head+, before returning the new instance.
|
|
3252
|
-
*
|
|
3253
|
-
* If a block is supplied, the new instance will be yielded just prior to
|
|
3254
|
-
* the +http_head+ call.
|
|
3255
|
-
*/
|
|
3256
|
-
static VALUE ruby_curl_easy_class_perform_head(int argc, VALUE *argv, VALUE klass) {
|
|
3257
|
-
VALUE c = ruby_curl_easy_new(argc, argv, klass);
|
|
3258
|
-
|
|
3259
|
-
ruby_curl_easy_perform_head(c);
|
|
3260
|
-
|
|
3261
|
-
return c;
|
|
3262
|
-
}
|
|
3263
|
-
|
|
3264
|
-
// TODO: add convenience method for http_post
|
|
3265
|
-
|
|
3266
|
-
/*
|
|
3267
|
-
* call-seq:
|
|
3268
|
-
* Curl::Easy.http_post(url, "some=urlencoded%20form%20data&and=so%20on") => true
|
|
3269
|
-
* Curl::Easy.http_post(url, "some=urlencoded%20form%20data", "and=so%20on", ...) => true
|
|
3270
|
-
* Curl::Easy.http_post(url, "some=urlencoded%20form%20data", Curl::PostField, "and=so%20on", ...) => true
|
|
3271
|
-
* Curl::Easy.http_post(url, Curl::PostField, Curl::PostField ..., Curl::PostField) => true
|
|
3272
|
-
*
|
|
3273
|
-
* POST the specified formdata to the currently configured URL using
|
|
3274
|
-
* the current options set for this Curl::Easy instance. This method
|
|
3275
|
-
* always returns true, or raises an exception (defined under
|
|
3276
|
-
* Curl::Err) on error.
|
|
3277
|
-
*
|
|
3278
|
-
* If you wish to use multipart form encoding, you'll need to supply a block
|
|
3279
|
-
* in order to set multipart_form_post true. See #http_post for more
|
|
3280
|
-
* information.
|
|
3281
|
-
*/
|
|
3282
|
-
static VALUE ruby_curl_easy_class_perform_post(int argc, VALUE *argv, VALUE klass) {
|
|
3283
|
-
VALUE url, fields;
|
|
3284
|
-
VALUE c;
|
|
3285
|
-
|
|
3286
|
-
rb_scan_args(argc, argv, "1*", &url, &fields);
|
|
3287
|
-
|
|
3288
|
-
c = ruby_curl_easy_new(1, &url, klass);
|
|
3289
|
-
|
|
3290
|
-
if (argc > 1) {
|
|
3291
|
-
ruby_curl_easy_perform_post(argc - 1, &argv[1], c);
|
|
3292
|
-
} else {
|
|
3293
|
-
ruby_curl_easy_perform_post(0, NULL, c);
|
|
3294
|
-
}
|
|
3295
|
-
|
|
3296
|
-
return c;
|
|
3297
|
-
}
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
3235
|
/* =================== INIT LIB =====================*/
|
|
3301
3236
|
void init_curb_easy() {
|
|
3302
3237
|
idCall = rb_intern("call");
|
|
@@ -3309,31 +3244,18 @@ void init_curb_easy() {
|
|
|
3309
3244
|
|
|
3310
3245
|
/* Class methods */
|
|
3311
3246
|
rb_define_singleton_method(cCurlEasy, "new", ruby_curl_easy_new, -1);
|
|
3312
|
-
rb_define_singleton_method(cCurlEasy, "
|
|
3313
|
-
rb_define_singleton_method(cCurlEasy, "http_delete", ruby_curl_easy_class_perform_delete, -1);
|
|
3314
|
-
rb_define_singleton_method(cCurlEasy, "http_get", ruby_curl_easy_class_perform_get, -1);
|
|
3315
|
-
rb_define_singleton_method(cCurlEasy, "http_post", ruby_curl_easy_class_perform_post, -1);
|
|
3316
|
-
rb_define_singleton_method(cCurlEasy, "http_head", ruby_curl_easy_class_perform_head, -1);
|
|
3317
|
-
rb_define_singleton_method(cCurlEasy, "http_put", ruby_curl_easy_class_perform_put, 2);
|
|
3247
|
+
rb_define_singleton_method(cCurlEasy, "error", ruby_curl_easy_error_message, 1);
|
|
3318
3248
|
|
|
3319
3249
|
/* Attributes for config next perform */
|
|
3320
|
-
rb_define_method(cCurlEasy, "url=", ruby_curl_easy_url_set, 1);
|
|
3321
3250
|
rb_define_method(cCurlEasy, "url", ruby_curl_easy_url_get, 0);
|
|
3322
|
-
rb_define_method(cCurlEasy, "proxy_url=", ruby_curl_easy_proxy_url_set, 1);
|
|
3323
3251
|
rb_define_method(cCurlEasy, "proxy_url", ruby_curl_easy_proxy_url_get, 0);
|
|
3324
3252
|
rb_define_method(cCurlEasy, "headers=", ruby_curl_easy_headers_set, 1);
|
|
3325
3253
|
rb_define_method(cCurlEasy, "headers", ruby_curl_easy_headers_get, 0);
|
|
3326
|
-
rb_define_method(cCurlEasy, "interface=", ruby_curl_easy_interface_set, 1);
|
|
3327
3254
|
rb_define_method(cCurlEasy, "interface", ruby_curl_easy_interface_get, 0);
|
|
3328
|
-
rb_define_method(cCurlEasy, "userpwd=", ruby_curl_easy_userpwd_set, 1);
|
|
3329
3255
|
rb_define_method(cCurlEasy, "userpwd", ruby_curl_easy_userpwd_get, 0);
|
|
3330
|
-
rb_define_method(cCurlEasy, "proxypwd=", ruby_curl_easy_proxypwd_set, 1);
|
|
3331
3256
|
rb_define_method(cCurlEasy, "proxypwd", ruby_curl_easy_proxypwd_get, 0);
|
|
3332
|
-
rb_define_method(cCurlEasy, "cookies=", ruby_curl_easy_cookies_set, 1);
|
|
3333
3257
|
rb_define_method(cCurlEasy, "cookies", ruby_curl_easy_cookies_get, 0);
|
|
3334
|
-
rb_define_method(cCurlEasy, "cookiefile=", ruby_curl_easy_cookiefile_set, 1);
|
|
3335
3258
|
rb_define_method(cCurlEasy, "cookiefile", ruby_curl_easy_cookiefile_get, 0);
|
|
3336
|
-
rb_define_method(cCurlEasy, "cookiejar=", ruby_curl_easy_cookiejar_set, 1);
|
|
3337
3259
|
rb_define_method(cCurlEasy, "cookiejar", ruby_curl_easy_cookiejar_get, 0);
|
|
3338
3260
|
rb_define_method(cCurlEasy, "cert=", ruby_curl_easy_cert_set, 1);
|
|
3339
3261
|
rb_define_method(cCurlEasy, "cert", ruby_curl_easy_cert_get, 0);
|
|
@@ -3398,8 +3320,8 @@ void init_curb_easy() {
|
|
|
3398
3320
|
rb_define_method(cCurlEasy, "fetch_file_time?", ruby_curl_easy_fetch_file_time_q, 0);
|
|
3399
3321
|
rb_define_method(cCurlEasy, "ssl_verify_peer=", ruby_curl_easy_ssl_verify_peer_set, 1);
|
|
3400
3322
|
rb_define_method(cCurlEasy, "ssl_verify_peer?", ruby_curl_easy_ssl_verify_peer_q, 0);
|
|
3401
|
-
rb_define_method(cCurlEasy, "
|
|
3402
|
-
rb_define_method(cCurlEasy, "ssl_verify_host
|
|
3323
|
+
rb_define_method(cCurlEasy, "ssl_verify_host_integer=", ruby_curl_easy_ssl_verify_host_set, 1);
|
|
3324
|
+
rb_define_method(cCurlEasy, "ssl_verify_host", ruby_curl_easy_ssl_verify_host_get, 0);
|
|
3403
3325
|
rb_define_method(cCurlEasy, "header_in_body=", ruby_curl_easy_header_in_body_set, 1);
|
|
3404
3326
|
rb_define_method(cCurlEasy, "header_in_body?", ruby_curl_easy_header_in_body_q, 0);
|
|
3405
3327
|
rb_define_method(cCurlEasy, "use_netrc=", ruby_curl_easy_use_netrc_set, 1);
|
|
@@ -3417,6 +3339,8 @@ void init_curb_easy() {
|
|
|
3417
3339
|
rb_define_method(cCurlEasy, "enable_cookies?", ruby_curl_easy_enable_cookies_q, 0);
|
|
3418
3340
|
rb_define_method(cCurlEasy, "ignore_content_length=", ruby_curl_easy_ignore_content_length_set, 1);
|
|
3419
3341
|
rb_define_method(cCurlEasy, "ignore_content_length?", ruby_curl_easy_ignore_content_length_q, 0);
|
|
3342
|
+
rb_define_method(cCurlEasy, "resolve_mode", ruby_curl_easy_resolve_mode, 0);
|
|
3343
|
+
rb_define_method(cCurlEasy, "resolve_mode=", ruby_curl_easy_resolve_mode_set, 1);
|
|
3420
3344
|
|
|
3421
3345
|
rb_define_method(cCurlEasy, "on_body", ruby_curl_easy_on_body_set, -1);
|
|
3422
3346
|
rb_define_method(cCurlEasy, "on_header", ruby_curl_easy_on_header_set, -1);
|
|
@@ -3424,9 +3348,10 @@ void init_curb_easy() {
|
|
|
3424
3348
|
rb_define_method(cCurlEasy, "on_debug", ruby_curl_easy_on_debug_set, -1);
|
|
3425
3349
|
rb_define_method(cCurlEasy, "on_success", ruby_curl_easy_on_success_set, -1);
|
|
3426
3350
|
rb_define_method(cCurlEasy, "on_failure", ruby_curl_easy_on_failure_set, -1);
|
|
3351
|
+
rb_define_method(cCurlEasy, "on_missing", ruby_curl_easy_on_missing_set, -1);
|
|
3352
|
+
rb_define_method(cCurlEasy, "on_redirect", ruby_curl_easy_on_redirect_set, -1);
|
|
3427
3353
|
rb_define_method(cCurlEasy, "on_complete", ruby_curl_easy_on_complete_set, -1);
|
|
3428
3354
|
|
|
3429
|
-
rb_define_method(cCurlEasy, "perform", ruby_curl_easy_perform, 0);
|
|
3430
3355
|
rb_define_method(cCurlEasy, "http", ruby_curl_easy_perform_verb, 1);
|
|
3431
3356
|
rb_define_method(cCurlEasy, "http_delete", ruby_curl_easy_perform_delete, 0);
|
|
3432
3357
|
rb_define_method(cCurlEasy, "http_get", ruby_curl_easy_perform_get, 0);
|
|
@@ -3434,12 +3359,6 @@ void init_curb_easy() {
|
|
|
3434
3359
|
rb_define_method(cCurlEasy, "http_head", ruby_curl_easy_perform_head, 0);
|
|
3435
3360
|
rb_define_method(cCurlEasy, "http_put", ruby_curl_easy_perform_put, 1);
|
|
3436
3361
|
rb_define_method(cCurlEasy, "head=", ruby_curl_easy_set_head_option, 1);
|
|
3437
|
-
rb_define_method(cCurlEasy, "delete=", ruby_curl_easy_set_delete_option, 1);
|
|
3438
|
-
rb_define_method(cCurlEasy, "version=", ruby_curl_easy_set_version, 1);
|
|
3439
|
-
rb_define_const(mCurl, "HTTP_1_1", LONG2NUM(CURL_HTTP_VERSION_1_1));
|
|
3440
|
-
rb_define_const(mCurl, "HTTP_1_0", LONG2NUM(CURL_HTTP_VERSION_1_0));
|
|
3441
|
-
rb_define_const(mCurl, "HTTP_NONE", LONG2NUM(CURL_HTTP_VERSION_NONE));
|
|
3442
|
-
rb_define_method(cCurlEasy, "nosignal=", ruby_curl_easy_set_nosignal, 1);
|
|
3443
3362
|
|
|
3444
3363
|
/* Post-perform info methods */
|
|
3445
3364
|
rb_define_method(cCurlEasy, "body_str", ruby_curl_easy_body_str_get, 0);
|
|
@@ -3484,4 +3403,11 @@ void init_curb_easy() {
|
|
|
3484
3403
|
rb_define_method(cCurlEasy, "clone", ruby_curl_easy_clone, 0);
|
|
3485
3404
|
rb_define_alias(cCurlEasy, "dup", "clone");
|
|
3486
3405
|
rb_define_method(cCurlEasy, "inspect", ruby_curl_easy_inspect, 0);
|
|
3406
|
+
|
|
3407
|
+
rb_define_method(cCurlEasy, "multi", ruby_curl_easy_multi_get, 0);
|
|
3408
|
+
rb_define_method(cCurlEasy, "multi=", ruby_curl_easy_multi_set, 1);
|
|
3409
|
+
rb_define_method(cCurlEasy, "last_result", ruby_curl_easy_last_result, 0);
|
|
3410
|
+
|
|
3411
|
+
rb_define_method(cCurlEasy, "setopt", ruby_curl_easy_set_opt, 2);
|
|
3412
|
+
rb_define_method(cCurlEasy, "getinfo", ruby_curl_easy_get_opt, 1);
|
|
3487
3413
|
}
|