curb 0.9.4 → 0.9.5

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 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