curb 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f745e8a670b83facff3af44169290e38d59fc087
4
- data.tar.gz: 23258e4b6f84aaec880ffb050c8fd774f82728a7
3
+ metadata.gz: b3b322d2ebc81428defb20ae37afc57287d05cc7
4
+ data.tar.gz: e2b87dc289c5c0268b927d78afd5d1ccdd3b3e73
5
5
  SHA512:
6
- metadata.gz: 4f79f4530412869086922114a4a9170acd57e5a8b68c43b19616a3d31609d9f85ef94bf890cad9b57cdd4f7a59bf1257eeb7d20ca40781e72ec4a2f03fe91711
7
- data.tar.gz: 5f67114460a69c76e6e7835124e26825833c8de153232ba10bab032732481e2c694baf54976dcba80cd43fce37a75f1267a9e9c507d369dead6c924ebb829b67
6
+ metadata.gz: 56080e5ef72c525be4b575c74b3832aa62d1074923237922f1568d7c3027e2eb654770a5a6187e0cc1f359c5228cae0aa7ea02cb95cafe6218d848595cb1a1f9
7
+ data.tar.gz: c9625176e56a5bb0b3716b1d6c8604f3bcfe406933a78a1cb371e20b9b4c4072477c1cebb52772ce793ab94adc3cbf8b9cba8264df0a3bf2498fdabb23885852
@@ -11,8 +11,8 @@ 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
 
@@ -32,17 +32,17 @@ line (alter paths to your curl location, but remember to use forward slashes):
32
32
 
33
33
  gem install curb --platform=ruby -- --with-curl-lib=C:/curl-7.39.0-devel-mingw32/bin --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 install EXTCONF_OPTS='--with-curl-dir=/path/to/libcurl --prefix=/what/ever'
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,7 +134,7 @@ c.perform
134
134
  ### HTTP "insecure" SSL connections (like curl -k, --insecure) to avoid Curl::Err::SSLCACertificateError:
135
135
 
136
136
  ```ruby
137
- c = Curl::Easy.new("http://github.com/")
137
+ c = Curl::Easy.new("https://github.com/")
138
138
  c.ssl_verify_peer = false
139
139
  c.perform
140
140
  ```
@@ -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 HAVE_CURL_SSLVERSION_TLSv1_0
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 HAVE_CURL_SSLVERSION_TLSv1_1
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 HAVE_CURL_SSLVERSION_TLSv1_2
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,10 +20,10 @@
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.4"
24
- #define CURB_VER_NUM 904
23
+ #define CURB_VERSION "0.9.5"
24
+ #define CURB_VER_NUM 905
25
25
  #define CURB_VER_MAJ 0
26
- #define CURB_VER_MIN 4
26
+ #define CURB_VER_MIN 5
27
27
  #define CURB_VER_MIC 0
28
28
  #define CURB_VER_PATCH 0
29
29
 
@@ -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
- * Create a new Curl::Easy instance, optionally supplying the URL.
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 ruby_curl_easy_new(int argc, VALUE *argv, VALUE klass) {
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
- rbce = ALLOC(ruby_curl_easy);
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*)new_curl);
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, new_curl);
353
+ rb_funcall(blk, idCall, 1, self);
339
354
  }
340
355
 
341
- return new_curl;
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,18 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
2296
2346
  }
2297
2347
  }
2298
2348
 
2349
+ /* Setup resolve list if necessary */
2350
+ if (!rb_easy_nil("resolve")) {
2351
+ if (rb_easy_type_check("resolve", T_ARRAY)) {
2352
+ VALUE wrap = Data_Wrap_Struct(rb_cObject, 0, 0, rslv);
2353
+ rb_iterate(rb_each, rb_easy_get("resolve"), cb_each_resolve, wrap);
2354
+ }
2355
+
2356
+ if (*rslv) {
2357
+ curl_easy_setopt(curl, CURLOPT_RESOLVE, *rslv);
2358
+ }
2359
+ }
2360
+
2299
2361
  return Qnil;
2300
2362
  }
2301
2363
  /***********************************************
@@ -2308,6 +2370,7 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
2308
2370
 
2309
2371
  CURL *curl = rbce->curl;
2310
2372
  struct curl_slist *ftp_commands;
2373
+ struct curl_slist *resolve;
2311
2374
 
2312
2375
  /* Free everything up */
2313
2376
  if (rbce->curl_headers) {
@@ -2321,6 +2384,12 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
2321
2384
  rbce->curl_ftp_commands = NULL;
2322
2385
  }
2323
2386
 
2387
+ resolve = rbce->curl_resolve;
2388
+ if (resolve) {
2389
+ curl_slist_free_all(resolve);
2390
+ rbce->curl_resolve = NULL;
2391
+ }
2392
+
2324
2393
  /* clean up a PUT request's curl options. */
2325
2394
  if (!rb_easy_nil("upload")) {
2326
2395
  rb_easy_del("upload"); // set the upload object to Qnil to let the GC clean up
@@ -2574,7 +2643,7 @@ static VALUE ruby_curl_easy_response_code_get(VALUE self) {
2574
2643
  static VALUE ruby_curl_easy_primary_ip_get(VALUE self) {
2575
2644
  ruby_curl_easy *rbce;
2576
2645
  char* ip;
2577
-
2646
+
2578
2647
  Data_Get_Struct(self, ruby_curl_easy, rbce);
2579
2648
  curl_easy_getinfo(rbce->curl, CURLINFO_PRIMARY_IP, &ip);
2580
2649
 
@@ -2799,7 +2868,7 @@ static VALUE ruby_curl_easy_redirect_count_get(VALUE self) {
2799
2868
  * call-seq:
2800
2869
  * easy.redirect_url => "http://some.url" or nil
2801
2870
  *
2802
- * Retrieve the URL a redirect would take you to if you
2871
+ * Retrieve the URL a redirect would take you to if you
2803
2872
  * would enable CURLOPT_FOLLOWLOCATION.
2804
2873
  *
2805
2874
  * Requires libcurl 7.18.2 or higher, otherwise -1 is always returned.
@@ -3233,6 +3302,9 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
3233
3302
  case CURLOPT_NOSIGNAL:
3234
3303
  #if HAVE_CURLOPT_PATH_AS_IS
3235
3304
  case CURLOPT_PATH_AS_IS:
3305
+ #endif
3306
+ #if HAVE_CURLOPT_PIPEWAIT
3307
+ case CURLOPT_PIPEWAIT:
3236
3308
  #endif
3237
3309
  case CURLOPT_HTTPGET:
3238
3310
  case CURLOPT_NOBODY: {
@@ -3300,6 +3372,16 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
3300
3372
  case CURLOPT_UNIX_SOCKET_PATH: {
3301
3373
  curl_easy_setopt(rbce->curl, CURLOPT_UNIX_SOCKET_PATH, StringValueCStr(val));
3302
3374
  } break;
3375
+ #endif
3376
+ #if HAVE_CURLOPT_MAX_SEND_SPEED_LARGE
3377
+ case CURLOPT_MAX_SEND_SPEED_LARGE: {
3378
+ curl_easy_setopt(rbce->curl, CURLOPT_MAX_SEND_SPEED_LARGE, (curl_off_t) NUM2LL(val));
3379
+ } break;
3380
+ #endif
3381
+ #if HAVE_CURLOPT_MAX_RECV_SPEED_LARGE
3382
+ case CURLOPT_MAX_RECV_SPEED_LARGE: {
3383
+ curl_easy_setopt(rbce->curl, CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t) NUM2LL(val));
3384
+ } break;
3303
3385
  #endif
3304
3386
  default:
3305
3387
  rb_raise(rb_eTypeError, "Curb unsupported option");
@@ -3427,9 +3509,12 @@ void init_curb_easy() {
3427
3509
  cCurlEasy = rb_define_class_under(mCurl, "Easy", rb_cObject);
3428
3510
 
3429
3511
  /* Class methods */
3430
- rb_define_singleton_method(cCurlEasy, "new", ruby_curl_easy_new, -1);
3512
+ rb_define_alloc_func(cCurlEasy, ruby_curl_easy_allocate);
3431
3513
  rb_define_singleton_method(cCurlEasy, "error", ruby_curl_easy_error_message, 1);
3432
3514
 
3515
+ /* Initialize method */
3516
+ rb_define_method(cCurlEasy, "initialize", ruby_curl_easy_initialize, -1);
3517
+
3433
3518
  /* Attributes for config next perform */
3434
3519
  rb_define_method(cCurlEasy, "url", ruby_curl_easy_url_get, 0);
3435
3520
  rb_define_method(cCurlEasy, "proxy_url", ruby_curl_easy_proxy_url_get, 0);
@@ -3459,6 +3544,8 @@ void init_curb_easy() {
3459
3544
  rb_define_method(cCurlEasy, "put_data=", ruby_curl_easy_put_data_set, 1);
3460
3545
  rb_define_method(cCurlEasy, "ftp_commands=", ruby_curl_easy_ftp_commands_set, 1);
3461
3546
  rb_define_method(cCurlEasy, "ftp_commands", ruby_curl_easy_ftp_commands_get, 0);
3547
+ rb_define_method(cCurlEasy, "resolve=", ruby_curl_easy_resolve_set, 1);
3548
+ rb_define_method(cCurlEasy, "resolve", ruby_curl_easy_resolve_get, 0);
3462
3549
 
3463
3550
  rb_define_method(cCurlEasy, "local_port=", ruby_curl_easy_local_port_set, 1);
3464
3551
  rb_define_method(cCurlEasy, "local_port", ruby_curl_easy_local_port_get, 0);
@@ -77,6 +77,7 @@ typedef struct {
77
77
 
78
78
  struct curl_slist *curl_headers;
79
79
  struct curl_slist *curl_ftp_commands;
80
+ struct curl_slist *curl_resolve;
80
81
 
81
82
  int last_result; /* last result code from multi loop */
82
83
 
@@ -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;
@@ -445,6 +458,61 @@ VALUE rb_curl_easy_error(CURLcode code) {
445
458
  exclz = eCurlErrSSLIssuerError;
446
459
  break;
447
460
  #endif
461
+
462
+ #ifdef HAVE_CURLE_FTP_PRET_FAILED
463
+ case CURLE_FTP_PRET_FAILED: /* 84 */
464
+ exclz = eCurlErrFTPPRETFailed;
465
+ break;
466
+ #endif
467
+
468
+ #ifdef HAVE_CURLE_RTSP_CSEQ_ERROR
469
+ case CURLE_RTSP_CSEQ_ERROR: /* 85 */
470
+ exclz = eCurlErrRTSPCseqError;
471
+ break;
472
+ #endif
473
+
474
+ #ifdef HAVE_CURLE_RTSP_SESSION_ERROR
475
+ case CURLE_RTSP_SESSION_ERROR: /* 86 */
476
+ exclz = eCurlErrRTSPSessionError;
477
+ break;
478
+ #endif
479
+
480
+ #ifdef HAVE_CURLE_FTP_BAD_FILE_LIST
481
+ case CURLE_FTP_BAD_FILE_LIST: /* 87 */
482
+ exclz = eCurlErrFTPBadFileList;
483
+ break;
484
+ #endif
485
+
486
+ #ifdef HAVE_CURLE_CHUNK_FAILED
487
+ case CURLE_CHUNK_FAILED: /* 88 */
488
+ exclz = eCurlErrChunkFailed;
489
+ break;
490
+ #endif
491
+
492
+ #ifdef HAVE_CURLE_NO_CONNECTION_AVAILABLE
493
+ case CURLE_NO_CONNECTION_AVAILABLE: /* 89 */
494
+ exclz = eCurlErrNoConnectionAvailable;
495
+ break;
496
+ #endif
497
+
498
+ #ifdef HAVE_CURLE_SSL_PINNEDPUBKEYNOTMATCH
499
+ case CURLE_SSL_PINNEDPUBKEYNOTMATCH: /* 90 */
500
+ exclz = eCurlErrSSLPinnedPubKeyNotMatch;
501
+ break;
502
+ #endif
503
+
504
+ #ifdef HAVE_CURLE_SSL_INVALIDCERTSTATUS
505
+ case CURLE_SSL_INVALIDCERTSTATUS: /* 91 */
506
+ exclz = eCurlErrSSLInvalidCertStatus;
507
+ break;
508
+ #endif
509
+
510
+ #ifdef HAVE_CURLE_HTTP2_STREAM
511
+ case CURLE_HTTP2_STREAM: /* 92 */
512
+ exclz = eCurlErrHTTP2Stream;
513
+ break;
514
+ #endif
515
+
448
516
  default:
449
517
  exclz = eCurlErrError;
450
518
  exmsg = "Unknown error result from libcurl";
@@ -532,6 +600,7 @@ void init_curb_errors() {
532
600
  eCurlErrLDAPError = rb_define_class_under(mCurlErr, "LDAPError", eCurlErrError);
533
601
  eCurlErrTelnetError = rb_define_class_under(mCurlErr, "TelnetError", eCurlErrError);
534
602
  eCurlErrTFTPError = rb_define_class_under(mCurlErr, "TFTPError", eCurlErrError);
603
+ eCurlErrRTSPError = rb_define_class_under(mCurlErr, "RTSPError", eCurlErrError);
535
604
 
536
605
  eCurlErrOK = rb_define_class_under(mCurlErr, "CurlOK", eCurlErrError);
537
606
  eCurlErrUnsupportedProtocol = rb_define_class_under(mCurlErr, "UnsupportedProtocolError", eCurlErrError);
@@ -657,4 +726,14 @@ void init_curb_errors() {
657
726
  eCurlErrTFTPNoSuchUser = rb_define_class_under(mCurlErr, "NoSuchUserError", eCurlErrTFTPError);
658
727
 
659
728
  eCurlErrInvalidPostField = rb_define_class_under(mCurlErr, "InvalidPostFieldError", eCurlErrError);
729
+
730
+ eCurlErrFTPPRETFailed = rb_define_class_under(mCurlErr, "PPRETFailedError", eCurlErrFTPError);
731
+ eCurlErrRTSPCseqError = rb_define_class_under(mCurlErr, "CseqError", eCurlErrRTSPError);
732
+ eCurlErrRTSPSessionError = rb_define_class_under(mCurlErr, "SessionError", eCurlErrRTSPError);
733
+ eCurlErrFTPBadFileList = rb_define_class_under(mCurlErr, "BadFileListError", eCurlErrFTPError);
734
+ eCurlErrChunkFailed = rb_define_class_under(mCurlErr, "ChunkFailedError", eCurlErrError);
735
+ eCurlErrNoConnectionAvailable = rb_define_class_under(mCurlErr, "NoConnectionAvailableError", eCurlErrError);
736
+ eCurlErrSSLPinnedPubKeyNotMatch = rb_define_class_under(mCurlErr, "SSLPinnedPubKeyNotMatchError", eCurlErrError);
737
+ eCurlErrSSLInvalidCertStatus = rb_define_class_under(mCurlErr, "SSLInvalidCertStatusError", eCurlErrError);
738
+ eCurlErrHTTP2Stream = rb_define_class_under(mCurlErr, "HTTP2StreamError", eCurlErrHTTPError);
660
739
  }
@@ -322,14 +322,14 @@ have_constant "curlopt_sslengine"
322
322
  have_constant "curlopt_sslengine_default"
323
323
  have_constant "curlopt_sslversion"
324
324
  have_constant "curl_sslversion_default"
325
- have_constant "curl_sslversion_tlsv1"
326
- have_constant "curl_sslversion_sslv2"
327
- have_constant "curl_sslversion_sslv3"
325
+ have_constant :CURL_SSLVERSION_TLSv1
326
+ have_constant :CURL_SSLVERSION_SSLv2
327
+ have_constant :CURL_SSLVERSION_SSLv3
328
328
 
329
329
  # Added in 7.34.0
330
- have_constant "curl_sslversion_tlsv1_0"
331
- have_constant "curl_sslversion_tlsv1_1"
332
- have_constant "curl_sslversion_tlsv1_2"
330
+ have_constant :CURL_SSLVERSION_TLSv1_0
331
+ have_constant :CURL_SSLVERSION_TLSv1_1
332
+ have_constant :CURL_SSLVERSION_TLSv1_2
333
333
 
334
334
  have_constant "curlopt_ssl_verifypeer"
335
335
  have_constant "curlopt_cainfo"
@@ -364,6 +364,16 @@ have_constant "curle_not_built_in"
364
364
 
365
365
  have_constant "curle_obsolete" # removed in 7.24 ?
366
366
 
367
+ have_constant "curle_ftp_pret_failed"
368
+ have_constant "curle_rtsp_cseq_error"
369
+ have_constant "curle_rtsp_session_error"
370
+ have_constant "curle_ftp_bad_file_list"
371
+ have_constant "curle_chunk_failed"
372
+ have_constant "curle_no_connection_available"
373
+ have_constant "curle_ssl_pinnedpubkeynotmatch"
374
+ have_constant "curle_ssl_invalidcertstatus"
375
+ have_constant "curle_http2_stream"
376
+
367
377
  # gssapi/spnego delegation related constants
368
378
  have_constant "curlopt_gssapi_delegation"
369
379
  have_constant "curlgssapi_delegation_policy_flag"
@@ -377,6 +387,9 @@ have_constant "curlopt_unix_socket_path"
377
387
  # added in 7.42.0
378
388
  have_constant "curlopt_path_as_is"
379
389
 
390
+ # added in 7.43.0
391
+ have_constant "curlopt_pipewait"
392
+
380
393
  if try_compile('int main() { return 0; }','-Wall')
381
394
  $CFLAGS << ' -Wall'
382
395
  end
@@ -48,7 +48,13 @@ module Curl
48
48
 
49
49
  def self.urlalize(url, params={})
50
50
  uri = URI(url)
51
- uri.query = params.map {|k,v| "#{URI.escape(k.to_s)}=#{URI.escape(v.to_s)}" }.join("&")
51
+ params_query = params.map {|k,v| "#{URI.escape(k.to_s)}=#{URI.escape(v.to_s)}" }.join("&")
52
+ # both uri.query and params_query not blank
53
+ if !(uri.query.nil? || uri.query.empty?) && !params_query.empty?
54
+ uri.query = "#{uri.query}&#{params_query}"
55
+ else
56
+ uri.query = "#{uri.query}#{params_query}"
57
+ end
52
58
  uri.to_s
53
59
  end
54
60
 
@@ -21,7 +21,7 @@ module Curl
21
21
  def status
22
22
  # Matches the last HTTP Status - following the HTTP protocol specification 'Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF'
23
23
  statuses = self.header_str.scan(/HTTP\/\d\.\d\s(\d+\s.*)\r\n/).map{ |match| match[0] }
24
- statuses.last.strip
24
+ statuses.last.strip if statuses.length > 0
25
25
  end
26
26
 
27
27
  #
@@ -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
4
+ version: 0.9.5
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: 2017-08-26 00:00:00.000000000 Z
12
+ date: 2018-05-28 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/bug_crash_on_debug.rb
102
- - tests/bug_crash_on_progress.rb
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/bugtests.rb
112
- - tests/helper.rb
113
- - tests/mem_check.rb
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/signals.rb
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/tc_curl_easy_setopt.rb
120
- - tests/tc_curl_multi.rb
121
+ - tests/mem_check.rb
121
122
  - tests/tc_curl_postfield.rb
122
- - tests/timeout.rb
123
- - tests/timeout_server.rb
124
- - tests/unittests.rb
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