curb 0.9.4 → 0.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.markdown +17 -17
- data/ext/curb.c +13 -6
- data/ext/curb.h +4 -4
- data/ext/curb_easy.c +127 -38
- data/ext/curb_easy.h +1 -0
- data/ext/curb_errors.c +86 -0
- data/ext/curb_multi.c +0 -4
- data/ext/extconf.rb +22 -6
- data/lib/curl.rb +6 -2
- data/lib/curl/easy.rb +3 -3
- data/lib/curl/multi.rb +10 -10
- data/tests/helper.rb +10 -7
- data/tests/tc_curl.rb +31 -1
- data/tests/tc_curl_easy.rb +10 -0
- data/tests/tc_curl_easy_resolve.rb +16 -0
- metadata +21 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 074fa1f2330b83e471e524dcbef1f5ef869fd352
|
4
|
+
data.tar.gz: 52abfef2028f532f2070406117f66dc779913ccc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1eee7cc31175d70a6720c9f0f86958644e7fd9f179e82cc0b3a90e70dc3e5c4caa2cd0db06a3e1350ae88ef7c030e14e8d2c6e6d2dfba9e8c9b8872fe56fa421
|
7
|
+
data.tar.gz: 3191554e99e528b7e59801ad5322661fe95ebcfe83ced7f6658f1eda2ee6a2546b990b4c6ff9182a4242f15556443422dcc9be4f4005dfe0c72cb13da517d1b6
|
data/README.markdown
CHANGED
@@ -11,12 +11,12 @@ Curb is a work-in-progress, and currently only supports libcurl's 'easy' and 'mu
|
|
11
11
|
|
12
12
|
## License
|
13
13
|
|
14
|
-
Curb is copyright (c)2006 Ross Bamford, and released under the terms of the
|
15
|
-
Ruby license. See the LICENSE file for the gory details.
|
14
|
+
Curb is copyright (c)2006 Ross Bamford, and released under the terms of the
|
15
|
+
Ruby license. See the LICENSE file for the gory details.
|
16
16
|
|
17
17
|
## You will need
|
18
18
|
|
19
|
-
* A working Ruby installation (
|
19
|
+
* A working Ruby installation (2.1+)
|
20
20
|
* A working (lib)curl installation, with development stuff (7.5+, tested with 7.19.x)
|
21
21
|
* A sane build environment (e.g. gcc, make)
|
22
22
|
|
@@ -30,19 +30,19 @@ On Windows, make sure you're using the [DevKit](http://rubyinstaller.org/downloa
|
|
30
30
|
the [development version of libcurl](http://curl.haxx.se/gknw.net/7.39.0/dist-w32/curl-7.39.0-devel-mingw32.zip). Unzip, then run this in your command
|
31
31
|
line (alter paths to your curl location, but remember to use forward slashes):
|
32
32
|
|
33
|
-
gem install curb --platform=ruby -- --with-curl-lib=C:/curl-7.39.0-devel-mingw32/
|
33
|
+
gem install curb --platform=ruby -- --with-curl-lib=C:/curl-7.39.0-devel-mingw32/lib --with-curl-include=C:/curl-7.39.0-devel-mingw32/include
|
34
34
|
|
35
|
-
Or, if you downloaded the archive:
|
35
|
+
Or, if you downloaded the archive:
|
36
36
|
|
37
|
-
$ rake install
|
37
|
+
$ rake compile && rake install
|
38
38
|
|
39
39
|
If you have a weird setup, you might need extconf options. In this case, pass
|
40
40
|
them like so:
|
41
41
|
|
42
|
-
$ rake
|
43
|
-
|
42
|
+
$ rake compile EXTCONF_OPTS='--with-curl-dir=/path/to/libcurl --prefix=/what/ever' && rake install
|
43
|
+
|
44
44
|
Curb is tested only on GNU/Linux x86 and Mac OSX - YMMV on other platforms.
|
45
|
-
If you do use another platform and experience problems, or if you can
|
45
|
+
If you do use another platform and experience problems, or if you can
|
46
46
|
expand on the above instructions, please report the issue at http://github.com/taf2/curb/issues
|
47
47
|
|
48
48
|
On Ubuntu, the dependencies can be satisfied by installing the following packages:
|
@@ -52,7 +52,7 @@ On Ubuntu, the dependencies can be satisfied by installing the following package
|
|
52
52
|
On RedHat:
|
53
53
|
|
54
54
|
$ sudo yum install ruby-devel libcurl-devel openssl-devel
|
55
|
-
|
55
|
+
|
56
56
|
Curb has fairly extensive RDoc comments in the source. You can build the
|
57
57
|
documentation with:
|
58
58
|
|
@@ -80,7 +80,7 @@ puts http.body_str
|
|
80
80
|
http = Curl.post("http://www.google.com/", {:foo => "bar"})
|
81
81
|
puts http.body_str
|
82
82
|
|
83
|
-
http = Curl.get("http://www.google.com/") do|http|
|
83
|
+
http = Curl.get("http://www.google.com/") do |http|
|
84
84
|
http.headers['Cookie'] = 'foo=1;bar=2'
|
85
85
|
end
|
86
86
|
puts http.body_str
|
@@ -104,7 +104,7 @@ puts c.body_str
|
|
104
104
|
### Additional config:
|
105
105
|
|
106
106
|
```ruby
|
107
|
-
Curl::Easy.perform("http://www.google.co.uk") do |curl|
|
107
|
+
Curl::Easy.perform("http://www.google.co.uk") do |curl|
|
108
108
|
curl.headers["User-Agent"] = "myapp-0.0"
|
109
109
|
curl.verbose = true
|
110
110
|
end
|
@@ -113,7 +113,7 @@ end
|
|
113
113
|
Same thing, more manual:
|
114
114
|
|
115
115
|
```ruby
|
116
|
-
c = Curl::Easy.new("http://www.google.co.uk") do |curl|
|
116
|
+
c = Curl::Easy.new("http://www.google.co.uk") do |curl|
|
117
117
|
curl.headers["User-Agent"] = "myapp-0.0"
|
118
118
|
curl.verbose = true
|
119
119
|
end
|
@@ -134,9 +134,9 @@ c.perform
|
|
134
134
|
### HTTP "insecure" SSL connections (like curl -k, --insecure) to avoid Curl::Err::SSLCACertificateError:
|
135
135
|
|
136
136
|
```ruby
|
137
|
-
|
138
|
-
|
139
|
-
|
137
|
+
c = Curl::Easy.new("https://github.com/")
|
138
|
+
c.ssl_verify_peer = false
|
139
|
+
c.perform
|
140
140
|
```
|
141
141
|
|
142
142
|
### Supplying custom handlers:
|
@@ -194,7 +194,7 @@ puts (c.body_str.include? "You are using HTTP/2 right now!") ? "HTTP/2" : "HTTP/
|
|
194
194
|
# make multiple GET requests
|
195
195
|
easy_options = {:follow_location => true}
|
196
196
|
# Use Curl::CURLPIPE_MULTIPLEX for HTTP/2 multiplexing
|
197
|
-
multi_options = {:pipeline => Curl::CURLPIPE_HTTP1}
|
197
|
+
multi_options = {:pipeline => Curl::CURLPIPE_HTTP1}
|
198
198
|
|
199
199
|
Curl::Multi.get(['url1','url2','url3','url4','url5'], easy_options, multi_options) do|easy|
|
200
200
|
# do something interesting with the easy response
|
data/ext/curb.c
CHANGED
@@ -272,15 +272,15 @@ void Init_curb_core() {
|
|
272
272
|
/* Passed to on_debug handler to indicate that the data is protocol data sent to the peer. */
|
273
273
|
rb_define_const(mCurl, "CURLINFO_DATA_OUT", LONG2NUM(CURLINFO_DATA_OUT));
|
274
274
|
|
275
|
-
#ifdef HAVE_CURLFTPMETHOD_MULTICWD
|
275
|
+
#ifdef HAVE_CURLFTPMETHOD_MULTICWD
|
276
276
|
rb_define_const(mCurl, "CURL_MULTICWD", LONG2NUM(CURLFTPMETHOD_MULTICWD));
|
277
277
|
#endif
|
278
278
|
|
279
|
-
#ifdef HAVE_CURLFTPMETHOD_NOCWD
|
279
|
+
#ifdef HAVE_CURLFTPMETHOD_NOCWD
|
280
280
|
rb_define_const(mCurl, "CURL_NOCWD", LONG2NUM(CURLFTPMETHOD_NOCWD));
|
281
281
|
#endif
|
282
282
|
|
283
|
-
#ifdef HAVE_CURLFTPMETHOD_SINGLECWD
|
283
|
+
#ifdef HAVE_CURLFTPMETHOD_SINGLECWD
|
284
284
|
rb_define_const(mCurl, "CURL_SINGLECWD", LONG2NUM(CURLFTPMETHOD_SINGLECWD));
|
285
285
|
#endif
|
286
286
|
|
@@ -296,13 +296,13 @@ void Init_curb_core() {
|
|
296
296
|
rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1", LONG2NUM(CURL_SSLVERSION_TLSv1));
|
297
297
|
rb_define_const(mCurl, "CURL_SSLVERSION_SSLv2", LONG2NUM(CURL_SSLVERSION_SSLv2));
|
298
298
|
rb_define_const(mCurl, "CURL_SSLVERSION_SSLv3", LONG2NUM(CURL_SSLVERSION_SSLv3));
|
299
|
-
#if
|
299
|
+
#if HAVE_CURL_SSLVERSION_TLSV1_0
|
300
300
|
rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_0", LONG2NUM(CURL_SSLVERSION_TLSv1_0));
|
301
301
|
#endif
|
302
|
-
#if
|
302
|
+
#if HAVE_CURL_SSLVERSION_TLSV1_1
|
303
303
|
rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_1", LONG2NUM(CURL_SSLVERSION_TLSv1_1));
|
304
304
|
#endif
|
305
|
-
#if
|
305
|
+
#if HAVE_CURL_SSLVERSION_TLSV1_2
|
306
306
|
rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_2", LONG2NUM(CURL_SSLVERSION_TLSv1_2));
|
307
307
|
#endif
|
308
308
|
|
@@ -609,6 +609,9 @@ void Init_curb_core() {
|
|
609
609
|
#if LIBCURL_VERSION_NUM >= 0x072100 /* 7.33.0 */
|
610
610
|
CURB_DEFINE(CURL_HTTP_VERSION_2_0);
|
611
611
|
#endif
|
612
|
+
#if LIBCURL_VERSION_NUM >= 0x072f00 /* 7.47.0 */
|
613
|
+
CURB_DEFINE(CURL_HTTP_VERSION_2TLS);
|
614
|
+
#endif
|
612
615
|
#if HAVE_CURLOPT_IGNORE_CONTENT_LENGTH
|
613
616
|
CURB_DEFINE(CURLOPT_IGNORE_CONTENT_LENGTH);
|
614
617
|
#endif
|
@@ -1023,6 +1026,10 @@ void Init_curb_core() {
|
|
1023
1026
|
CURB_DEFINE(CURLOPT_UNIX_SOCKET_PATH);
|
1024
1027
|
#endif
|
1025
1028
|
|
1029
|
+
#if HAVE_CURLOPT_PIPEWAIT
|
1030
|
+
CURB_DEFINE(CURLOPT_PIPEWAIT);
|
1031
|
+
#endif
|
1032
|
+
|
1026
1033
|
#if LIBCURL_VERSION_NUM >= 0x072B00 /* 7.43.0 */
|
1027
1034
|
CURB_DEFINE(CURLPIPE_NOTHING);
|
1028
1035
|
CURB_DEFINE(CURLPIPE_HTTP1);
|
data/ext/curb.h
CHANGED
@@ -20,11 +20,11 @@
|
|
20
20
|
#include "curb_macros.h"
|
21
21
|
|
22
22
|
// These should be managed from the Rake 'release' task.
|
23
|
-
#define CURB_VERSION "0.9.
|
24
|
-
#define CURB_VER_NUM
|
23
|
+
#define CURB_VERSION "0.9.7"
|
24
|
+
#define CURB_VER_NUM 907
|
25
25
|
#define CURB_VER_MAJ 0
|
26
|
-
#define CURB_VER_MIN
|
27
|
-
#define CURB_VER_MIC
|
26
|
+
#define CURB_VER_MIN 9
|
27
|
+
#define CURB_VER_MIC 7
|
28
28
|
#define CURB_VER_PATCH 0
|
29
29
|
|
30
30
|
|
data/ext/curb_easy.c
CHANGED
@@ -30,7 +30,7 @@ VALUE cCurlEasy;
|
|
30
30
|
|
31
31
|
static VALUE callback_exception(VALUE unused) {
|
32
32
|
return Qfalse;
|
33
|
-
}
|
33
|
+
}
|
34
34
|
|
35
35
|
/* These handle both body and header data */
|
36
36
|
static size_t default_data_handler(char *stream,
|
@@ -227,6 +227,10 @@ static void ruby_curl_easy_free(ruby_curl_easy *rbce) {
|
|
227
227
|
curl_slist_free_all(rbce->curl_ftp_commands);
|
228
228
|
}
|
229
229
|
|
230
|
+
if (rbce->curl_resolve) {
|
231
|
+
curl_slist_free_all(rbce->curl_resolve);
|
232
|
+
}
|
233
|
+
|
230
234
|
if (rbce->curl) {
|
231
235
|
/* disable any progress or debug events */
|
232
236
|
curl_easy_setopt(rbce->curl, CURLOPT_WRITEFUNCTION, NULL);
|
@@ -255,6 +259,7 @@ static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
|
255
259
|
|
256
260
|
rbce->curl_headers = NULL;
|
257
261
|
rbce->curl_ftp_commands = NULL;
|
262
|
+
rbce->curl_resolve = NULL;
|
258
263
|
|
259
264
|
/* various-typed opts */
|
260
265
|
rbce->local_port = 0;
|
@@ -293,25 +298,37 @@ static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
|
293
298
|
rbce->callback_active = 0;
|
294
299
|
}
|
295
300
|
|
301
|
+
/*
|
302
|
+
* Allocate space for a Curl::Easy instance.
|
303
|
+
*/
|
304
|
+
static VALUE ruby_curl_easy_allocate(VALUE klass) {
|
305
|
+
ruby_curl_easy *rbce;
|
306
|
+
rbce = ALLOC(ruby_curl_easy);
|
307
|
+
rbce->curl = NULL;
|
308
|
+
rbce->opts = Qnil;
|
309
|
+
rbce->multi = Qnil;
|
310
|
+
ruby_curl_easy_zero(rbce);
|
311
|
+
return Data_Wrap_Struct(klass, curl_easy_mark, curl_easy_free, rbce);
|
312
|
+
}
|
313
|
+
|
296
314
|
/*
|
297
315
|
* call-seq:
|
298
316
|
* Curl::Easy.new => #<Curl::Easy...>
|
299
317
|
* Curl::Easy.new(url = nil) => #<Curl::Easy...>
|
300
318
|
* Curl::Easy.new(url = nil) { |self| ... } => #<Curl::Easy...>
|
301
319
|
*
|
302
|
-
*
|
320
|
+
* Initialize a new Curl::Easy instance, optionally supplying the URL.
|
303
321
|
* The block form allows further configuration to be supplied before
|
304
322
|
* the instance is returned.
|
305
323
|
*/
|
306
|
-
static VALUE
|
324
|
+
static VALUE ruby_curl_easy_initialize(int argc, VALUE *argv, VALUE self) {
|
307
325
|
CURLcode ecode;
|
308
326
|
VALUE url, blk;
|
309
|
-
VALUE new_curl;
|
310
327
|
ruby_curl_easy *rbce;
|
311
328
|
|
312
329
|
rb_scan_args(argc, argv, "01&", &url, &blk);
|
313
330
|
|
314
|
-
|
331
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
315
332
|
|
316
333
|
/* handler */
|
317
334
|
rbce->curl = curl_easy_init();
|
@@ -319,8 +336,6 @@ static VALUE ruby_curl_easy_new(int argc, VALUE *argv, VALUE klass) {
|
|
319
336
|
rb_raise(eCurlErrFailedInit, "Failed to initialize easy handle");
|
320
337
|
}
|
321
338
|
|
322
|
-
new_curl = Data_Wrap_Struct(klass, curl_easy_mark, curl_easy_free, rbce);
|
323
|
-
|
324
339
|
rbce->multi = Qnil;
|
325
340
|
rbce->opts = Qnil;
|
326
341
|
|
@@ -329,16 +344,16 @@ static VALUE ruby_curl_easy_new(int argc, VALUE *argv, VALUE klass) {
|
|
329
344
|
rb_easy_set("url", url);
|
330
345
|
|
331
346
|
/* set the new_curl pointer to the curl handle */
|
332
|
-
ecode = curl_easy_setopt(rbce->curl, CURLOPT_PRIVATE, (void*)
|
347
|
+
ecode = curl_easy_setopt(rbce->curl, CURLOPT_PRIVATE, (void*)self);
|
333
348
|
if (ecode != CURLE_OK) {
|
334
349
|
raise_curl_easy_error_exception(ecode);
|
335
350
|
}
|
336
351
|
|
337
352
|
if (blk != Qnil) {
|
338
|
-
rb_funcall(blk, idCall, 1,
|
353
|
+
rb_funcall(blk, idCall, 1, self);
|
339
354
|
}
|
340
355
|
|
341
|
-
return
|
356
|
+
return self;
|
342
357
|
}
|
343
358
|
|
344
359
|
/*
|
@@ -359,6 +374,7 @@ static VALUE ruby_curl_easy_clone(VALUE self) {
|
|
359
374
|
newrbce->curl = curl_easy_duphandle(rbce->curl);
|
360
375
|
newrbce->curl_headers = NULL;
|
361
376
|
newrbce->curl_ftp_commands = NULL;
|
377
|
+
newrbce->curl_resolve = NULL;
|
362
378
|
|
363
379
|
return Data_Wrap_Struct(cCurlEasy, curl_easy_mark, curl_easy_free, newrbce);
|
364
380
|
}
|
@@ -368,7 +384,7 @@ static VALUE ruby_curl_easy_clone(VALUE self) {
|
|
368
384
|
* easy.close => nil
|
369
385
|
*
|
370
386
|
* Close the Curl::Easy instance. Any open connections are closed
|
371
|
-
* The easy handle is reinitialized. If a previous multi handle was
|
387
|
+
* The easy handle is reinitialized. If a previous multi handle was
|
372
388
|
* open it is set to nil and will be cleared after a GC.
|
373
389
|
*/
|
374
390
|
static VALUE ruby_curl_easy_close(VALUE self) {
|
@@ -503,7 +519,7 @@ static VALUE ruby_curl_easy_headers_get(VALUE self) {
|
|
503
519
|
ruby_curl_easy *rbce;
|
504
520
|
VALUE headers;
|
505
521
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
506
|
-
headers = rb_easy_get("headers");//rb_hash_aref(rbce->opts, rb_intern("headers"));
|
522
|
+
headers = rb_easy_get("headers");//rb_hash_aref(rbce->opts, rb_intern("headers"));
|
507
523
|
if (headers == Qnil) { headers = rb_easy_set("headers", rb_hash_new()); }
|
508
524
|
return headers;
|
509
525
|
}
|
@@ -715,29 +731,29 @@ static VALUE ruby_curl_easy_useragent_get(VALUE self) {
|
|
715
731
|
/*
|
716
732
|
* call-seq:
|
717
733
|
* easy.post_body = "some=form%20data&to=send" => string or nil
|
718
|
-
*
|
734
|
+
*
|
719
735
|
* Sets the POST body of this Curl::Easy instance. This is expected to be
|
720
736
|
* URL encoded; no additional processing or encoding is done on the string.
|
721
737
|
* The content-type header will be set to application/x-www-form-urlencoded.
|
722
|
-
*
|
738
|
+
*
|
723
739
|
* This is handy if you want to perform a POST against a Curl::Multi instance.
|
724
740
|
*/
|
725
741
|
static VALUE ruby_curl_easy_post_body_set(VALUE self, VALUE post_body) {
|
726
742
|
ruby_curl_easy *rbce;
|
727
743
|
CURL *curl;
|
728
|
-
|
744
|
+
|
729
745
|
char *data;
|
730
746
|
long len;
|
731
747
|
|
732
748
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
733
|
-
|
749
|
+
|
734
750
|
curl = rbce->curl;
|
735
|
-
|
751
|
+
|
736
752
|
if ( post_body == Qnil ) {
|
737
753
|
rb_easy_del("postdata_buffer");
|
738
754
|
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
|
739
|
-
|
740
|
-
} else {
|
755
|
+
|
756
|
+
} else {
|
741
757
|
if (rb_type(post_body) == T_STRING) {
|
742
758
|
data = StringValuePtr(post_body);
|
743
759
|
len = RSTRING_LEN(post_body);
|
@@ -750,19 +766,19 @@ static VALUE ruby_curl_easy_post_body_set(VALUE self, VALUE post_body) {
|
|
750
766
|
else {
|
751
767
|
rb_raise(rb_eRuntimeError, "post data must respond_to .to_s");
|
752
768
|
}
|
753
|
-
|
754
|
-
// Store the string, since it has to hang around for the duration of the
|
769
|
+
|
770
|
+
// Store the string, since it has to hang around for the duration of the
|
755
771
|
// request. See CURLOPT_POSTFIELDS in the libcurl docs.
|
756
772
|
//rbce->postdata_buffer = post_body;
|
757
773
|
rb_easy_set("postdata_buffer", post_body);
|
758
|
-
|
774
|
+
|
759
775
|
curl_easy_setopt(curl, CURLOPT_POST, 1);
|
760
776
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
|
761
777
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
|
762
|
-
|
778
|
+
|
763
779
|
return post_body;
|
764
780
|
}
|
765
|
-
|
781
|
+
|
766
782
|
return Qnil;
|
767
783
|
}
|
768
784
|
|
@@ -779,7 +795,7 @@ static VALUE ruby_curl_easy_post_body_get(VALUE self) {
|
|
779
795
|
/*
|
780
796
|
* call-seq:
|
781
797
|
* easy.put_data = data => ""
|
782
|
-
*
|
798
|
+
*
|
783
799
|
* Points this Curl::Easy instance to data to be uploaded via PUT. This
|
784
800
|
* sets the request to a PUT type request - useful if you want to PUT via
|
785
801
|
* a multi handle.
|
@@ -811,7 +827,7 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
|
|
811
827
|
curl_easy_setopt(curl, CURLOPT_SEEKDATA, rbce);
|
812
828
|
#endif
|
813
829
|
|
814
|
-
/*
|
830
|
+
/*
|
815
831
|
* we need to set specific headers for the PUT to work... so
|
816
832
|
* convert the internal headers structure to a HASH if one is set
|
817
833
|
*/
|
@@ -825,7 +841,7 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
|
|
825
841
|
if (NIL_P(data)) { return data; }
|
826
842
|
|
827
843
|
headers = rb_easy_get("headers");
|
828
|
-
if( headers == Qnil ) {
|
844
|
+
if( headers == Qnil ) {
|
829
845
|
headers = rb_hash_new();
|
830
846
|
}
|
831
847
|
|
@@ -880,6 +896,25 @@ static VALUE ruby_curl_easy_ftp_commands_get(VALUE self) {
|
|
880
896
|
CURB_OBJECT_HGETTER(ruby_curl_easy, ftp_commands);
|
881
897
|
}
|
882
898
|
|
899
|
+
/*
|
900
|
+
* call-seq:
|
901
|
+
* easy.resolve = [ "example.com:80:127.0.0.1" ] => [ "example.com:80:127.0.0.1" ]
|
902
|
+
*
|
903
|
+
* Set the resolve list to statically resolve hostnames to IP addresses,
|
904
|
+
* bypassing DNS for matching hostname/port combinations.
|
905
|
+
*/
|
906
|
+
static VALUE ruby_curl_easy_resolve_set(VALUE self, VALUE resolve) {
|
907
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, resolve);
|
908
|
+
}
|
909
|
+
|
910
|
+
/*
|
911
|
+
* call-seq
|
912
|
+
* easy.resolve => array or nil
|
913
|
+
*/
|
914
|
+
static VALUE ruby_curl_easy_resolve_get(VALUE self) {
|
915
|
+
CURB_OBJECT_HGETTER(ruby_curl_easy, resolve);
|
916
|
+
}
|
917
|
+
|
883
918
|
/* ================== IMMED ATTRS ==================*/
|
884
919
|
|
885
920
|
/*
|
@@ -990,7 +1025,7 @@ static VALUE ruby_curl_easy_proxy_type_get(VALUE self) {
|
|
990
1025
|
(!strncmp("ntlm",node,4)) ? CURLAUTH_NTLM : \
|
991
1026
|
(!strncmp("anysafe",node,7)) ? CURLAUTH_ANYSAFE : \
|
992
1027
|
(!strncmp("any",node,3)) ? CURLAUTH_ANY : 0
|
993
|
-
#else
|
1028
|
+
#else
|
994
1029
|
#define CURL_HTTPAUTH_STR_TO_NUM(node) \
|
995
1030
|
(!strncmp("basic",node,5)) ? CURLAUTH_BASIC : \
|
996
1031
|
(!strncmp("digest",node,6)) ? CURLAUTH_DIGEST : \
|
@@ -1022,7 +1057,7 @@ static VALUE ruby_curl_easy_http_auth_types_set(int argc, VALUE *argv, VALUE sel
|
|
1022
1057
|
|
1023
1058
|
if (len == 1 && (rb_ary_entry(args_ary,0) == Qnil || TYPE(rb_ary_entry(args_ary,0)) == T_FIXNUM ||
|
1024
1059
|
TYPE(rb_ary_entry(args_ary,0)) == T_BIGNUM)) {
|
1025
|
-
if (rb_ary_entry(args_ary,0) == Qnil) {
|
1060
|
+
if (rb_ary_entry(args_ary,0) == Qnil) {
|
1026
1061
|
rbce->http_auth_types = 0;
|
1027
1062
|
}
|
1028
1063
|
else {
|
@@ -1320,7 +1355,7 @@ static VALUE ruby_curl_easy_username_set(VALUE self, VALUE username) {
|
|
1320
1355
|
/*
|
1321
1356
|
* call-seq:
|
1322
1357
|
* easy.username => string
|
1323
|
-
*
|
1358
|
+
*
|
1324
1359
|
* Get the current username
|
1325
1360
|
*/
|
1326
1361
|
static VALUE ruby_curl_easy_username_get(VALUE self, VALUE username) {
|
@@ -1348,7 +1383,7 @@ static VALUE ruby_curl_easy_password_set(VALUE self, VALUE password) {
|
|
1348
1383
|
/*
|
1349
1384
|
* call-seq:
|
1350
1385
|
* easy.password => string
|
1351
|
-
*
|
1386
|
+
*
|
1352
1387
|
* Get the current password
|
1353
1388
|
*/
|
1354
1389
|
static VALUE ruby_curl_easy_password_get(VALUE self, VALUE password) {
|
@@ -1391,7 +1426,7 @@ static VALUE ruby_curl_easy_ssl_version_get(VALUE self, VALUE ssl_version) {
|
|
1391
1426
|
/*
|
1392
1427
|
* call-seq:
|
1393
1428
|
* easy.use_ssl = value => fixnum or nil
|
1394
|
-
*
|
1429
|
+
*
|
1395
1430
|
* Ensure libcurl uses SSL for FTP connections. Valid options are Curl::CURL_USESSL_NONE,
|
1396
1431
|
* Curl::CURL_USESSL_TRY, Curl::CURL_USESSL_CONTROL, and Curl::CURL_USESSL_ALL.
|
1397
1432
|
*/
|
@@ -1848,7 +1883,7 @@ static VALUE ruby_curl_easy_on_failure_set(int argc, VALUE *argv, VALUE self) {
|
|
1848
1883
|
* To remove a previously-supplied handler, call this method with no attached
|
1849
1884
|
* block.
|
1850
1885
|
*
|
1851
|
-
* The +on_missing+ handler is called when request is finished with a
|
1886
|
+
* The +on_missing+ handler is called when request is finished with a
|
1852
1887
|
* status of 40x
|
1853
1888
|
*/
|
1854
1889
|
static VALUE ruby_curl_easy_on_missing_set(int argc, VALUE *argv, VALUE self) {
|
@@ -1863,7 +1898,7 @@ static VALUE ruby_curl_easy_on_missing_set(int argc, VALUE *argv, VALUE self) {
|
|
1863
1898
|
* To remove a previously-supplied handler, call this method with no attached
|
1864
1899
|
* block.
|
1865
1900
|
*
|
1866
|
-
* The +on_redirect+ handler is called when request is finished with a
|
1901
|
+
* The +on_redirect+ handler is called when request is finished with a
|
1867
1902
|
* status of 30x
|
1868
1903
|
*/
|
1869
1904
|
static VALUE ruby_curl_easy_on_redirect_set(int argc, VALUE *argv, VALUE self) {
|
@@ -1991,6 +2026,20 @@ static VALUE cb_each_ftp_command(VALUE ftp_command, VALUE wrap) {
|
|
1991
2026
|
return ftp_command_string;
|
1992
2027
|
}
|
1993
2028
|
|
2029
|
+
/***********************************************
|
2030
|
+
* This is an rb_iterate callback used to set up the resolve list.
|
2031
|
+
*/
|
2032
|
+
static VALUE cb_each_resolve(VALUE resolve, VALUE wrap) {
|
2033
|
+
struct curl_slist **list;
|
2034
|
+
VALUE resolve_string;
|
2035
|
+
Data_Get_Struct(wrap, struct curl_slist *, list);
|
2036
|
+
|
2037
|
+
resolve_string = rb_obj_as_string(resolve);
|
2038
|
+
*list = curl_slist_append(*list, StringValuePtr(resolve));
|
2039
|
+
|
2040
|
+
return resolve_string;
|
2041
|
+
}
|
2042
|
+
|
1994
2043
|
/***********************************************
|
1995
2044
|
*
|
1996
2045
|
* Setup a connection
|
@@ -2003,6 +2052,7 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
2003
2052
|
VALUE url, _url = rb_easy_get("url");
|
2004
2053
|
struct curl_slist **hdrs = &(rbce->curl_headers);
|
2005
2054
|
struct curl_slist **cmds = &(rbce->curl_ftp_commands);
|
2055
|
+
struct curl_slist **rslv = &(rbce->curl_resolve);
|
2006
2056
|
|
2007
2057
|
curl = rbce->curl;
|
2008
2058
|
|
@@ -2257,7 +2307,7 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
2257
2307
|
rb_warn("libcurl is not configured with SSL support");
|
2258
2308
|
}
|
2259
2309
|
#endif
|
2260
|
-
|
2310
|
+
|
2261
2311
|
if (rbce->ftp_filemethod > 0) {
|
2262
2312
|
curl_easy_setopt(curl, CURLOPT_FTP_FILEMETHOD, rbce->ftp_filemethod);
|
2263
2313
|
}
|
@@ -2296,6 +2346,20 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
2296
2346
|
}
|
2297
2347
|
}
|
2298
2348
|
|
2349
|
+
#if HAVE_CURLOPT_RESOLVE
|
2350
|
+
/* Setup resolve list if necessary */
|
2351
|
+
if (!rb_easy_nil("resolve")) {
|
2352
|
+
if (rb_easy_type_check("resolve", T_ARRAY)) {
|
2353
|
+
VALUE wrap = Data_Wrap_Struct(rb_cObject, 0, 0, rslv);
|
2354
|
+
rb_iterate(rb_each, rb_easy_get("resolve"), cb_each_resolve, wrap);
|
2355
|
+
}
|
2356
|
+
|
2357
|
+
if (*rslv) {
|
2358
|
+
curl_easy_setopt(curl, CURLOPT_RESOLVE, *rslv);
|
2359
|
+
}
|
2360
|
+
}
|
2361
|
+
#endif
|
2362
|
+
|
2299
2363
|
return Qnil;
|
2300
2364
|
}
|
2301
2365
|
/***********************************************
|
@@ -2308,6 +2372,7 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
|
|
2308
2372
|
|
2309
2373
|
CURL *curl = rbce->curl;
|
2310
2374
|
struct curl_slist *ftp_commands;
|
2375
|
+
struct curl_slist *resolve;
|
2311
2376
|
|
2312
2377
|
/* Free everything up */
|
2313
2378
|
if (rbce->curl_headers) {
|
@@ -2321,6 +2386,12 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
|
|
2321
2386
|
rbce->curl_ftp_commands = NULL;
|
2322
2387
|
}
|
2323
2388
|
|
2389
|
+
resolve = rbce->curl_resolve;
|
2390
|
+
if (resolve) {
|
2391
|
+
curl_slist_free_all(resolve);
|
2392
|
+
rbce->curl_resolve = NULL;
|
2393
|
+
}
|
2394
|
+
|
2324
2395
|
/* clean up a PUT request's curl options. */
|
2325
2396
|
if (!rb_easy_nil("upload")) {
|
2326
2397
|
rb_easy_del("upload"); // set the upload object to Qnil to let the GC clean up
|
@@ -2574,7 +2645,7 @@ static VALUE ruby_curl_easy_response_code_get(VALUE self) {
|
|
2574
2645
|
static VALUE ruby_curl_easy_primary_ip_get(VALUE self) {
|
2575
2646
|
ruby_curl_easy *rbce;
|
2576
2647
|
char* ip;
|
2577
|
-
|
2648
|
+
|
2578
2649
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
2579
2650
|
curl_easy_getinfo(rbce->curl, CURLINFO_PRIMARY_IP, &ip);
|
2580
2651
|
|
@@ -2799,7 +2870,7 @@ static VALUE ruby_curl_easy_redirect_count_get(VALUE self) {
|
|
2799
2870
|
* call-seq:
|
2800
2871
|
* easy.redirect_url => "http://some.url" or nil
|
2801
2872
|
*
|
2802
|
-
* Retrieve the URL a redirect would take you to if you
|
2873
|
+
* Retrieve the URL a redirect would take you to if you
|
2803
2874
|
* would enable CURLOPT_FOLLOWLOCATION.
|
2804
2875
|
*
|
2805
2876
|
* Requires libcurl 7.18.2 or higher, otherwise -1 is always returned.
|
@@ -3233,6 +3304,9 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
3233
3304
|
case CURLOPT_NOSIGNAL:
|
3234
3305
|
#if HAVE_CURLOPT_PATH_AS_IS
|
3235
3306
|
case CURLOPT_PATH_AS_IS:
|
3307
|
+
#endif
|
3308
|
+
#if HAVE_CURLOPT_PIPEWAIT
|
3309
|
+
case CURLOPT_PIPEWAIT:
|
3236
3310
|
#endif
|
3237
3311
|
case CURLOPT_HTTPGET:
|
3238
3312
|
case CURLOPT_NOBODY: {
|
@@ -3300,6 +3374,16 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
3300
3374
|
case CURLOPT_UNIX_SOCKET_PATH: {
|
3301
3375
|
curl_easy_setopt(rbce->curl, CURLOPT_UNIX_SOCKET_PATH, StringValueCStr(val));
|
3302
3376
|
} break;
|
3377
|
+
#endif
|
3378
|
+
#if HAVE_CURLOPT_MAX_SEND_SPEED_LARGE
|
3379
|
+
case CURLOPT_MAX_SEND_SPEED_LARGE: {
|
3380
|
+
curl_easy_setopt(rbce->curl, CURLOPT_MAX_SEND_SPEED_LARGE, (curl_off_t) NUM2LL(val));
|
3381
|
+
} break;
|
3382
|
+
#endif
|
3383
|
+
#if HAVE_CURLOPT_MAX_RECV_SPEED_LARGE
|
3384
|
+
case CURLOPT_MAX_RECV_SPEED_LARGE: {
|
3385
|
+
curl_easy_setopt(rbce->curl, CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t) NUM2LL(val));
|
3386
|
+
} break;
|
3303
3387
|
#endif
|
3304
3388
|
default:
|
3305
3389
|
rb_raise(rb_eTypeError, "Curb unsupported option");
|
@@ -3427,9 +3511,12 @@ void init_curb_easy() {
|
|
3427
3511
|
cCurlEasy = rb_define_class_under(mCurl, "Easy", rb_cObject);
|
3428
3512
|
|
3429
3513
|
/* Class methods */
|
3430
|
-
|
3514
|
+
rb_define_alloc_func(cCurlEasy, ruby_curl_easy_allocate);
|
3431
3515
|
rb_define_singleton_method(cCurlEasy, "error", ruby_curl_easy_error_message, 1);
|
3432
3516
|
|
3517
|
+
/* Initialize method */
|
3518
|
+
rb_define_method(cCurlEasy, "initialize", ruby_curl_easy_initialize, -1);
|
3519
|
+
|
3433
3520
|
/* Attributes for config next perform */
|
3434
3521
|
rb_define_method(cCurlEasy, "url", ruby_curl_easy_url_get, 0);
|
3435
3522
|
rb_define_method(cCurlEasy, "proxy_url", ruby_curl_easy_proxy_url_get, 0);
|
@@ -3459,6 +3546,8 @@ void init_curb_easy() {
|
|
3459
3546
|
rb_define_method(cCurlEasy, "put_data=", ruby_curl_easy_put_data_set, 1);
|
3460
3547
|
rb_define_method(cCurlEasy, "ftp_commands=", ruby_curl_easy_ftp_commands_set, 1);
|
3461
3548
|
rb_define_method(cCurlEasy, "ftp_commands", ruby_curl_easy_ftp_commands_get, 0);
|
3549
|
+
rb_define_method(cCurlEasy, "resolve=", ruby_curl_easy_resolve_set, 1);
|
3550
|
+
rb_define_method(cCurlEasy, "resolve", ruby_curl_easy_resolve_get, 0);
|
3462
3551
|
|
3463
3552
|
rb_define_method(cCurlEasy, "local_port=", ruby_curl_easy_local_port_set, 1);
|
3464
3553
|
rb_define_method(cCurlEasy, "local_port", ruby_curl_easy_local_port_get, 0);
|
data/ext/curb_easy.h
CHANGED
data/ext/curb_errors.c
CHANGED
@@ -21,6 +21,7 @@ VALUE eCurlErrFileError;
|
|
21
21
|
VALUE eCurlErrLDAPError;
|
22
22
|
VALUE eCurlErrTelnetError;
|
23
23
|
VALUE eCurlErrTFTPError;
|
24
|
+
VALUE eCurlErrRTSPError;
|
24
25
|
|
25
26
|
/* Specific libcurl errors */
|
26
27
|
VALUE eCurlErrOK; /* not really an error but a return code */
|
@@ -127,6 +128,18 @@ VALUE mCurlErrUnknownOption;
|
|
127
128
|
VALUE eCurlErrInvalidPostField;
|
128
129
|
|
129
130
|
|
131
|
+
/* new errors */
|
132
|
+
VALUE eCurlErrFTPPRETFailed;
|
133
|
+
VALUE eCurlErrRTSPCseqError;
|
134
|
+
VALUE eCurlErrRTSPSessionError;
|
135
|
+
VALUE eCurlErrFTPBadFileList;
|
136
|
+
VALUE eCurlErrChunkFailed;
|
137
|
+
VALUE eCurlErrNoConnectionAvailable;
|
138
|
+
VALUE eCurlErrSSLPinnedPubKeyNotMatch;
|
139
|
+
VALUE eCurlErrSSLInvalidCertStatus;
|
140
|
+
VALUE eCurlErrHTTP2Stream;
|
141
|
+
|
142
|
+
|
130
143
|
VALUE rb_curl_easy_error(CURLcode code) {
|
131
144
|
VALUE exclz;
|
132
145
|
const char *exmsg = NULL;
|
@@ -294,9 +307,11 @@ VALUE rb_curl_easy_error(CURLcode code) {
|
|
294
307
|
exclz = eCurlErrObsolete;
|
295
308
|
break;
|
296
309
|
#endif
|
310
|
+
#if LIBCURL_VERSION_NUM < 0x073e00
|
297
311
|
case CURLE_SSL_PEER_CERTIFICATE: /* 51 - peer's certificate wasn't ok */
|
298
312
|
exclz = eCurlErrSSLPeerCertificate;
|
299
313
|
break;
|
314
|
+
#endif
|
300
315
|
case CURLE_GOT_NOTHING: /* 52 - when this is a specific error */
|
301
316
|
exclz = eCurlErrGotNothing;
|
302
317
|
break;
|
@@ -321,8 +336,13 @@ VALUE rb_curl_easy_error(CURLcode code) {
|
|
321
336
|
case CURLE_SSL_CIPHER: /* 59 - couldn't use specified cipher */
|
322
337
|
exclz = eCurlErrSSLCipher;
|
323
338
|
break;
|
339
|
+
#if LIBCURL_VERSION_NUM >= 0x073e00
|
340
|
+
case CURLE_PEER_FAILED_VERIFICATION: /* 60 - problem with the CA cert (path?) */
|
341
|
+
exclz = eCurlErrSSLPeerCertificate;
|
342
|
+
#else
|
324
343
|
case CURLE_SSL_CACERT: /* 60 - problem with the CA cert (path?) */
|
325
344
|
exclz = eCurlErrSSLCACertificate;
|
345
|
+
#endif
|
326
346
|
break;
|
327
347
|
case CURLE_BAD_CONTENT_ENCODING: /* 61 - Unrecognized transfer encoding */
|
328
348
|
exclz = eCurlErrBadContentEncoding;
|
@@ -445,6 +465,61 @@ VALUE rb_curl_easy_error(CURLcode code) {
|
|
445
465
|
exclz = eCurlErrSSLIssuerError;
|
446
466
|
break;
|
447
467
|
#endif
|
468
|
+
|
469
|
+
#ifdef HAVE_CURLE_FTP_PRET_FAILED
|
470
|
+
case CURLE_FTP_PRET_FAILED: /* 84 */
|
471
|
+
exclz = eCurlErrFTPPRETFailed;
|
472
|
+
break;
|
473
|
+
#endif
|
474
|
+
|
475
|
+
#ifdef HAVE_CURLE_RTSP_CSEQ_ERROR
|
476
|
+
case CURLE_RTSP_CSEQ_ERROR: /* 85 */
|
477
|
+
exclz = eCurlErrRTSPCseqError;
|
478
|
+
break;
|
479
|
+
#endif
|
480
|
+
|
481
|
+
#ifdef HAVE_CURLE_RTSP_SESSION_ERROR
|
482
|
+
case CURLE_RTSP_SESSION_ERROR: /* 86 */
|
483
|
+
exclz = eCurlErrRTSPSessionError;
|
484
|
+
break;
|
485
|
+
#endif
|
486
|
+
|
487
|
+
#ifdef HAVE_CURLE_FTP_BAD_FILE_LIST
|
488
|
+
case CURLE_FTP_BAD_FILE_LIST: /* 87 */
|
489
|
+
exclz = eCurlErrFTPBadFileList;
|
490
|
+
break;
|
491
|
+
#endif
|
492
|
+
|
493
|
+
#ifdef HAVE_CURLE_CHUNK_FAILED
|
494
|
+
case CURLE_CHUNK_FAILED: /* 88 */
|
495
|
+
exclz = eCurlErrChunkFailed;
|
496
|
+
break;
|
497
|
+
#endif
|
498
|
+
|
499
|
+
#ifdef HAVE_CURLE_NO_CONNECTION_AVAILABLE
|
500
|
+
case CURLE_NO_CONNECTION_AVAILABLE: /* 89 */
|
501
|
+
exclz = eCurlErrNoConnectionAvailable;
|
502
|
+
break;
|
503
|
+
#endif
|
504
|
+
|
505
|
+
#ifdef HAVE_CURLE_SSL_PINNEDPUBKEYNOTMATCH
|
506
|
+
case CURLE_SSL_PINNEDPUBKEYNOTMATCH: /* 90 */
|
507
|
+
exclz = eCurlErrSSLPinnedPubKeyNotMatch;
|
508
|
+
break;
|
509
|
+
#endif
|
510
|
+
|
511
|
+
#ifdef HAVE_CURLE_SSL_INVALIDCERTSTATUS
|
512
|
+
case CURLE_SSL_INVALIDCERTSTATUS: /* 91 */
|
513
|
+
exclz = eCurlErrSSLInvalidCertStatus;
|
514
|
+
break;
|
515
|
+
#endif
|
516
|
+
|
517
|
+
#ifdef HAVE_CURLE_HTTP2_STREAM
|
518
|
+
case CURLE_HTTP2_STREAM: /* 92 */
|
519
|
+
exclz = eCurlErrHTTP2Stream;
|
520
|
+
break;
|
521
|
+
#endif
|
522
|
+
|
448
523
|
default:
|
449
524
|
exclz = eCurlErrError;
|
450
525
|
exmsg = "Unknown error result from libcurl";
|
@@ -532,6 +607,7 @@ void init_curb_errors() {
|
|
532
607
|
eCurlErrLDAPError = rb_define_class_under(mCurlErr, "LDAPError", eCurlErrError);
|
533
608
|
eCurlErrTelnetError = rb_define_class_under(mCurlErr, "TelnetError", eCurlErrError);
|
534
609
|
eCurlErrTFTPError = rb_define_class_under(mCurlErr, "TFTPError", eCurlErrError);
|
610
|
+
eCurlErrRTSPError = rb_define_class_under(mCurlErr, "RTSPError", eCurlErrError);
|
535
611
|
|
536
612
|
eCurlErrOK = rb_define_class_under(mCurlErr, "CurlOK", eCurlErrError);
|
537
613
|
eCurlErrUnsupportedProtocol = rb_define_class_under(mCurlErr, "UnsupportedProtocolError", eCurlErrError);
|
@@ -657,4 +733,14 @@ void init_curb_errors() {
|
|
657
733
|
eCurlErrTFTPNoSuchUser = rb_define_class_under(mCurlErr, "NoSuchUserError", eCurlErrTFTPError);
|
658
734
|
|
659
735
|
eCurlErrInvalidPostField = rb_define_class_under(mCurlErr, "InvalidPostFieldError", eCurlErrError);
|
736
|
+
|
737
|
+
eCurlErrFTPPRETFailed = rb_define_class_under(mCurlErr, "PPRETFailedError", eCurlErrFTPError);
|
738
|
+
eCurlErrRTSPCseqError = rb_define_class_under(mCurlErr, "CseqError", eCurlErrRTSPError);
|
739
|
+
eCurlErrRTSPSessionError = rb_define_class_under(mCurlErr, "SessionError", eCurlErrRTSPError);
|
740
|
+
eCurlErrFTPBadFileList = rb_define_class_under(mCurlErr, "BadFileListError", eCurlErrFTPError);
|
741
|
+
eCurlErrChunkFailed = rb_define_class_under(mCurlErr, "ChunkFailedError", eCurlErrError);
|
742
|
+
eCurlErrNoConnectionAvailable = rb_define_class_under(mCurlErr, "NoConnectionAvailableError", eCurlErrError);
|
743
|
+
eCurlErrSSLPinnedPubKeyNotMatch = rb_define_class_under(mCurlErr, "SSLPinnedPubKeyNotMatchError", eCurlErrError);
|
744
|
+
eCurlErrSSLInvalidCertStatus = rb_define_class_under(mCurlErr, "SSLInvalidCertStatusError", eCurlErrError);
|
745
|
+
eCurlErrHTTP2Stream = rb_define_class_under(mCurlErr, "HTTP2StreamError", eCurlErrHTTPError);
|
660
746
|
}
|
data/ext/curb_multi.c
CHANGED
@@ -436,10 +436,6 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
|
|
436
436
|
//rb_funcall( rb_easy_get("failure_proc"), idCall, 2, easy, rb_curl_easy_error(result) );
|
437
437
|
}
|
438
438
|
|
439
|
-
if (val == Qfalse) {
|
440
|
-
rb_warn("uncaught exception from callback");
|
441
|
-
}
|
442
|
-
|
443
439
|
}
|
444
440
|
|
445
441
|
static void rb_curl_multi_read_info(VALUE self, CURLM *multi_handle) {
|
data/ext/extconf.rb
CHANGED
@@ -102,6 +102,9 @@ have_constant "curle_send_fail_rewind"
|
|
102
102
|
have_constant "curle_ssl_engine_initfailed"
|
103
103
|
have_constant "curle_login_denied"
|
104
104
|
|
105
|
+
# older than 7.10.0
|
106
|
+
have_constant "curlopt_nosignal"
|
107
|
+
|
105
108
|
# older than 7.16.0
|
106
109
|
have_constant "curlmopt_pipelining"
|
107
110
|
|
@@ -322,14 +325,14 @@ have_constant "curlopt_sslengine"
|
|
322
325
|
have_constant "curlopt_sslengine_default"
|
323
326
|
have_constant "curlopt_sslversion"
|
324
327
|
have_constant "curl_sslversion_default"
|
325
|
-
have_constant
|
326
|
-
have_constant
|
327
|
-
have_constant
|
328
|
+
have_constant :CURL_SSLVERSION_TLSv1
|
329
|
+
have_constant :CURL_SSLVERSION_SSLv2
|
330
|
+
have_constant :CURL_SSLVERSION_SSLv3
|
328
331
|
|
329
332
|
# Added in 7.34.0
|
330
|
-
have_constant
|
331
|
-
have_constant
|
332
|
-
have_constant
|
333
|
+
have_constant :CURL_SSLVERSION_TLSv1_0
|
334
|
+
have_constant :CURL_SSLVERSION_TLSv1_1
|
335
|
+
have_constant :CURL_SSLVERSION_TLSv1_2
|
333
336
|
|
334
337
|
have_constant "curlopt_ssl_verifypeer"
|
335
338
|
have_constant "curlopt_cainfo"
|
@@ -364,6 +367,16 @@ have_constant "curle_not_built_in"
|
|
364
367
|
|
365
368
|
have_constant "curle_obsolete" # removed in 7.24 ?
|
366
369
|
|
370
|
+
have_constant "curle_ftp_pret_failed"
|
371
|
+
have_constant "curle_rtsp_cseq_error"
|
372
|
+
have_constant "curle_rtsp_session_error"
|
373
|
+
have_constant "curle_ftp_bad_file_list"
|
374
|
+
have_constant "curle_chunk_failed"
|
375
|
+
have_constant "curle_no_connection_available"
|
376
|
+
have_constant "curle_ssl_pinnedpubkeynotmatch"
|
377
|
+
have_constant "curle_ssl_invalidcertstatus"
|
378
|
+
have_constant "curle_http2_stream"
|
379
|
+
|
367
380
|
# gssapi/spnego delegation related constants
|
368
381
|
have_constant "curlopt_gssapi_delegation"
|
369
382
|
have_constant "curlgssapi_delegation_policy_flag"
|
@@ -377,6 +390,9 @@ have_constant "curlopt_unix_socket_path"
|
|
377
390
|
# added in 7.42.0
|
378
391
|
have_constant "curlopt_path_as_is"
|
379
392
|
|
393
|
+
# added in 7.43.0
|
394
|
+
have_constant "curlopt_pipewait"
|
395
|
+
|
380
396
|
if try_compile('int main() { return 0; }','-Wall')
|
381
397
|
$CFLAGS << ' -Wall'
|
382
398
|
end
|
data/lib/curl.rb
CHANGED
@@ -6,7 +6,7 @@ require 'cgi'
|
|
6
6
|
|
7
7
|
# expose shortcut methods
|
8
8
|
module Curl
|
9
|
-
|
9
|
+
|
10
10
|
def self.http(verb, url, post_body=nil, put_data=nil, &block)
|
11
11
|
handle = Thread.current[:curb_curl] ||= Curl::Easy.new
|
12
12
|
handle.reset
|
@@ -48,7 +48,11 @@ module Curl
|
|
48
48
|
|
49
49
|
def self.urlalize(url, params={})
|
50
50
|
uri = URI(url)
|
51
|
-
|
51
|
+
# early return if we didn't specify any extra params
|
52
|
+
return uri.to_s if (params || {}).empty?
|
53
|
+
|
54
|
+
params_query = URI.encode_www_form(params || {})
|
55
|
+
uri.query = [uri.query.to_s, params_query].reject(&:empty?).join('&')
|
52
56
|
uri.to_s
|
53
57
|
end
|
54
58
|
|
data/lib/curl/easy.rb
CHANGED
@@ -19,9 +19,9 @@ module Curl
|
|
19
19
|
# easy.status => String
|
20
20
|
#
|
21
21
|
def status
|
22
|
-
# Matches the last HTTP Status - following the HTTP protocol specification 'Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF'
|
23
|
-
statuses = self.header_str.scan(/HTTP\/\d\.\d
|
24
|
-
statuses.last.strip
|
22
|
+
# Matches the last HTTP Status - following the HTTP protocol specification 'Status-Line = HTTP-Version SP Status-Code SP (Opt:)Reason-Phrase CRLF'
|
23
|
+
statuses = self.header_str.scan(/HTTP\/\d(\.\d)?\s(\d+\s.*)\r\n/).map{ |match| match[1] }
|
24
|
+
statuses.last.strip if statuses.length > 0
|
25
25
|
end
|
26
26
|
|
27
27
|
#
|
data/lib/curl/multi.rb
CHANGED
@@ -6,7 +6,7 @@ module Curl
|
|
6
6
|
# Curl::Multi.get(['url1','url2','url3','url4','url5'], :follow_location => true) do|easy|
|
7
7
|
# easy
|
8
8
|
# end
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# Blocking call to fetch multiple url's in parallel.
|
11
11
|
def get(urls, easy_options={}, multi_options={}, &blk)
|
12
12
|
url_confs = []
|
@@ -25,10 +25,10 @@ module Curl
|
|
25
25
|
# {:pipeline => Curl::CURLPIPE_HTTP1}) do|easy|
|
26
26
|
# easy_handle_on_request_complete
|
27
27
|
# end
|
28
|
-
#
|
28
|
+
#
|
29
29
|
# Blocking call to POST multiple form's in parallel.
|
30
|
-
#
|
31
|
-
# urls_with_config: is a hash of url's pointing to the postfields to send
|
30
|
+
#
|
31
|
+
# urls_with_config: is a hash of url's pointing to the postfields to send
|
32
32
|
# easy_options: are a set of common options to set on all easy handles
|
33
33
|
# multi_options: options to set on the Curl::Multi handle
|
34
34
|
#
|
@@ -49,10 +49,10 @@ module Curl
|
|
49
49
|
# {:pipeline => Curl::CURLPIPE_HTTP1}) do|easy|
|
50
50
|
# easy_handle_on_request_complete
|
51
51
|
# end
|
52
|
-
#
|
52
|
+
#
|
53
53
|
# Blocking call to POST multiple form's in parallel.
|
54
|
-
#
|
55
|
-
# urls_with_config: is a hash of url's pointing to the postfields to send
|
54
|
+
#
|
55
|
+
# urls_with_config: is a hash of url's pointing to the postfields to send
|
56
56
|
# easy_options: are a set of common options to set on all easy handles
|
57
57
|
# multi_options: options to set on the Curl::Multi handle
|
58
58
|
#
|
@@ -79,7 +79,7 @@ module Curl
|
|
79
79
|
# Blocking call to issue multiple HTTP requests with varying verb's.
|
80
80
|
#
|
81
81
|
# urls_with_config: is a hash of url's pointing to the easy handle options as well as the special option :method, that can by one of [:get, :post, :put, :delete, :head], when no verb is provided e.g. :method => nil -> GET is used
|
82
|
-
# multi_options: options for the multi handle
|
82
|
+
# multi_options: options for the multi handle
|
83
83
|
# blk: a callback, that yeilds when a handle is completed
|
84
84
|
#
|
85
85
|
def http(urls_with_config, multi_options={}, &blk)
|
@@ -128,7 +128,7 @@ module Curl
|
|
128
128
|
|
129
129
|
# headers is a special key
|
130
130
|
headers.each {|k,v| easy.headers[k] = v } if headers
|
131
|
-
|
131
|
+
|
132
132
|
#
|
133
133
|
# use the remaining options as specific configuration to the easy handle
|
134
134
|
# bad options should raise an undefined method error
|
@@ -175,7 +175,7 @@ module Curl
|
|
175
175
|
# Curl::Multi.download(['http://example.com/p/a/t/h/file1.txt','http://example.com/p/a/t/h/file2.txt']){|c|}
|
176
176
|
#
|
177
177
|
# will create 2 new files file1.txt and file2.txt
|
178
|
-
#
|
178
|
+
#
|
179
179
|
# 2 files will be opened, and remain open until the call completes
|
180
180
|
#
|
181
181
|
# when using the :post or :put method, urls should be a hash, including the individual post fields per post
|
data/tests/helper.rb
CHANGED
@@ -18,7 +18,7 @@ rescue LoadError
|
|
18
18
|
end
|
19
19
|
require 'fileutils'
|
20
20
|
|
21
|
-
$TEST_URL = "file://#{'/' if RUBY_DESCRIPTION =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/}#{
|
21
|
+
$TEST_URL = "file://#{'/' if RUBY_DESCRIPTION =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/}#{File.expand_path(__FILE__).tr('\\','/')}"
|
22
22
|
|
23
23
|
require 'thread'
|
24
24
|
require 'webrick'
|
@@ -30,19 +30,22 @@ require 'webrick'
|
|
30
30
|
TEST_SINGLE_THREADED=false
|
31
31
|
|
32
32
|
# keep webrick quiet
|
33
|
-
|
33
|
+
::WEBrick::HTTPServer.send(:remove_method,:access_log) if ::WEBrick::HTTPServer.instance_methods.include?(:access_log)
|
34
|
+
::WEBrick::BasicLog.send(:remove_method,:log) if ::WEBrick::BasicLog.instance_methods.include?(:log)
|
35
|
+
|
36
|
+
::WEBrick::HTTPServer.class_eval do
|
34
37
|
def access_log(config, req, res)
|
35
38
|
# nop
|
36
39
|
end
|
37
40
|
end
|
38
|
-
|
41
|
+
::WEBrick::BasicLog.class_eval do
|
39
42
|
def log(level, data)
|
40
43
|
# nop
|
41
44
|
end
|
42
45
|
end
|
43
46
|
|
44
47
|
#
|
45
|
-
# Simple test server to record number of times a request is sent/recieved of a specific
|
48
|
+
# Simple test server to record number of times a request is sent/recieved of a specific
|
46
49
|
# request type, e.g. GET,POST,PUT,DELETE
|
47
50
|
#
|
48
51
|
class TestServlet < WEBrick::HTTPServlet::AbstractServlet
|
@@ -94,7 +97,7 @@ class TestServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
94
97
|
if params and params['s'] == '500'
|
95
98
|
res.status = 500
|
96
99
|
elsif params and params['c']
|
97
|
-
cookie = URI.
|
100
|
+
cookie = URI.decode_www_form_component(params['c']).split('=')
|
98
101
|
res.cookies << WEBrick::Cookie.new(*cookie)
|
99
102
|
else
|
100
103
|
respond_with("POST\n#{req.body}",req,res)
|
@@ -147,7 +150,7 @@ module TestServerMethods
|
|
147
150
|
rd.close
|
148
151
|
rd = nil
|
149
152
|
|
150
|
-
# start up a webrick server for testing delete
|
153
|
+
# start up a webrick server for testing delete
|
151
154
|
server = WEBrick::HTTPServer.new :Port => port, :DocumentRoot => File.expand_path(File.dirname(__FILE__))
|
152
155
|
|
153
156
|
server.mount(servlet.path, servlet)
|
@@ -163,7 +166,7 @@ module TestServerMethods
|
|
163
166
|
rd.read
|
164
167
|
rd.close
|
165
168
|
else
|
166
|
-
# start up a webrick server for testing delete
|
169
|
+
# start up a webrick server for testing delete
|
167
170
|
@server = WEBrick::HTTPServer.new :Port => port, :DocumentRoot => File.expand_path(File.dirname(__FILE__))
|
168
171
|
|
169
172
|
@server.mount(servlet.path, servlet)
|
data/tests/tc_curl.rb
CHANGED
@@ -31,7 +31,37 @@ class TestCurl < Test::Unit::TestCase
|
|
31
31
|
assert_equal "OPTIONSfoo=bar", curl.body_str
|
32
32
|
end
|
33
33
|
|
34
|
-
|
34
|
+
def test_urlalize_without_extra_params
|
35
|
+
url_no_params = 'http://localhost/test'
|
36
|
+
url_with_params = 'http://localhost/test?a=1'
|
37
|
+
|
38
|
+
assert_equal(url_no_params, Curl.urlalize(url_no_params))
|
39
|
+
assert_equal(url_with_params, Curl.urlalize(url_with_params))
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_urlalize_with_nil_as_params
|
43
|
+
url = 'http://localhost/test'
|
44
|
+
assert_equal(url, Curl.urlalize(url, nil))
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_urlalize_with_extra_params
|
48
|
+
url_no_params = 'http://localhost/test'
|
49
|
+
url_with_params = 'http://localhost/test?a=1'
|
50
|
+
extra_params = { :b => 2 }
|
51
|
+
|
52
|
+
expected_url_no_params = 'http://localhost/test?b=2'
|
53
|
+
expected_url_with_params = 'http://localhost/test?a=1&b=2'
|
54
|
+
|
55
|
+
assert_equal(expected_url_no_params, Curl.urlalize(url_no_params, extra_params))
|
56
|
+
assert_equal(expected_url_with_params, Curl.urlalize(url_with_params, extra_params))
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_urlalize_does_not_strip_trailing_?
|
60
|
+
url_empty_params = 'http://localhost/test?'
|
61
|
+
assert_equal(url_empty_params, Curl.urlalize(url_empty_params))
|
62
|
+
end
|
63
|
+
|
64
|
+
include TestServerMethods
|
35
65
|
|
36
66
|
def setup
|
37
67
|
server_setup
|
data/tests/tc_curl_easy.rb
CHANGED
@@ -10,6 +10,16 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
10
10
|
Curl.reset
|
11
11
|
end
|
12
12
|
|
13
|
+
def test_exception
|
14
|
+
begin
|
15
|
+
Curl.get('NOT_FOUND_URL')
|
16
|
+
rescue
|
17
|
+
assert true
|
18
|
+
rescue Exception
|
19
|
+
assert false, "We should raise StandardError"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
13
23
|
def test_threads
|
14
24
|
t = []
|
15
25
|
5.times do
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
2
|
+
|
3
|
+
class TestCurbCurlEasyResolve < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@easy = Curl::Easy.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_resolve
|
9
|
+
@easy.resolve = [ "example.com:80:127.0.0.1" ]
|
10
|
+
assert_equal @easy.resolve, [ "example.com:80:127.0.0.1" ]
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_empty_resolve
|
14
|
+
assert_equal @easy.resolve, nil
|
15
|
+
end
|
16
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: curb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ross Bamford
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2018-11-26 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Curb (probably CUrl-RuBy or something) provides Ruby-language bindings
|
15
15
|
for the libcurl(3), a fully-featured client-side URL transfer library. cURL and
|
@@ -63,6 +63,7 @@ files:
|
|
63
63
|
- tests/tc_curl.rb
|
64
64
|
- tests/tc_curl_download.rb
|
65
65
|
- tests/tc_curl_easy.rb
|
66
|
+
- tests/tc_curl_easy_resolve.rb
|
66
67
|
- tests/tc_curl_easy_setopt.rb
|
67
68
|
- tests/tc_curl_multi.rb
|
68
69
|
- tests/tc_curl_postfield.rb
|
@@ -97,28 +98,29 @@ signing_key:
|
|
97
98
|
specification_version: 4
|
98
99
|
summary: Ruby libcurl bindings
|
99
100
|
test_files:
|
101
|
+
- tests/tc_curl_multi.rb
|
100
102
|
- tests/alltests.rb
|
101
|
-
- tests/
|
102
|
-
- tests/
|
103
|
-
- tests/bug_curb_easy_blocks_ruby_threads.rb
|
104
|
-
- tests/bug_curb_easy_post_with_string_no_content_length_header.rb
|
105
|
-
- tests/bug_instance_post_differs_from_class_post.rb
|
106
|
-
- tests/bug_issue102.rb
|
107
|
-
- tests/bug_multi_segfault.rb
|
103
|
+
- tests/tc_curl_easy_setopt.rb
|
104
|
+
- tests/tc_curl.rb
|
108
105
|
- tests/bug_postfields_crash.rb
|
106
|
+
- tests/bug_crash_on_progress.rb
|
107
|
+
- tests/helper.rb
|
109
108
|
- tests/bug_postfields_crash2.rb
|
110
109
|
- tests/bug_require_last_or_segfault.rb
|
111
|
-
- tests/
|
112
|
-
- tests/
|
113
|
-
- tests/
|
110
|
+
- tests/timeout.rb
|
111
|
+
- tests/bug_crash_on_debug.rb
|
112
|
+
- tests/unittests.rb
|
113
|
+
- tests/bug_issue102.rb
|
114
|
+
- tests/bug_curb_easy_blocks_ruby_threads.rb
|
115
|
+
- tests/bug_multi_segfault.rb
|
116
|
+
- tests/bug_instance_post_differs_from_class_post.rb
|
114
117
|
- tests/require_last_or_segfault_script.rb
|
115
|
-
- tests/
|
116
|
-
- tests/tc_curl.rb
|
118
|
+
- tests/timeout_server.rb
|
117
119
|
- tests/tc_curl_download.rb
|
118
120
|
- tests/tc_curl_easy.rb
|
119
|
-
- tests/
|
120
|
-
- tests/tc_curl_multi.rb
|
121
|
+
- tests/mem_check.rb
|
121
122
|
- tests/tc_curl_postfield.rb
|
122
|
-
- tests/
|
123
|
-
- tests/
|
124
|
-
- tests/
|
123
|
+
- tests/bugtests.rb
|
124
|
+
- tests/tc_curl_easy_resolve.rb
|
125
|
+
- tests/signals.rb
|
126
|
+
- tests/bug_curb_easy_post_with_string_no_content_length_header.rb
|