curb 0.9.1 → 0.9.2

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: d044ba4672e19b7fadd0097e309db4675b53c785
4
- data.tar.gz: 3b0ebdde6d818e9103dd665d1f1b33c042514f5b
3
+ metadata.gz: c2d299f9e0dce739a74ea53589cc402c4dc2ae2b
4
+ data.tar.gz: efd8d73f02b9da758c3861a93489e78bb770e4af
5
5
  SHA512:
6
- metadata.gz: a2daeabcdd2999b3ef7372c37baab4bebd0e56be7213ee82f8734f00bf798bde82de3888e02502f03e67d17bfb38f0fe49c306450eb83169287fa073ffb6b8b7
7
- data.tar.gz: 9ef11cfaa3007ebf26247d97f1ab3f59b403ce769a30bff0c3e4be336c52fe05a5f74b19a083eb79b5660f5e3fd30c41c9a68bdd1c831a0c0223cd2a1deb62b3
6
+ metadata.gz: 364eed3e88338d6c1c7fc8028181b82e945d8d605d171d470d319a434ad7198a2900fe600e4870ac2acc680a35df4e4506471d923cee020d707888168920276d
7
+ data.tar.gz: ad15467a00c66ee255ed5a605ed48426400a12901e673181c873cf56c7e793534b4b17304cd75b02fd7c15d8e51e2b7a6f1bd24e5dc36c3ffc35096ef6c1b030
@@ -1,4 +1,4 @@
1
- # Curb - Libcurl bindings for Ruby
1
+ # Curb - Libcurl bindings for Ruby [![Build Status](https://travis-ci.org/taf2/curb.svg?branch=master)](https://travis-ci.org/taf2/curb)
2
2
 
3
3
  * [rubydoc rdoc](http://www.rubydoc.info/github/taf2/curb/)
4
4
  * [github project](http://github.com/taf2/curb/tree/master)
@@ -172,14 +172,25 @@ c.multipart_form_post = true
172
172
  c.http_post(Curl::PostField.file('thing[file]', 'myfile.rb'))
173
173
  ```
174
174
 
175
+ ### Using HTTP/2
176
+
177
+ ```ruby
178
+ c = Curl::Easy.new("https://http2.akamai.com")
179
+ c.set(:HTTP_VERSION, Curl::HTTP_2_0)
180
+
181
+ c.perform
182
+ puts (c.body_str.include? "You are using HTTP/2 right now!") ? "HTTP/2" : "HTTP/1.x"
183
+ ```
184
+
175
185
  ### Multi Interface (Basic HTTP GET):
176
186
 
177
187
  ```ruby
178
188
  # make multiple GET requests
179
189
  easy_options = {:follow_location => true}
180
- multi_options = {:pipeline => true}
190
+ # Use Curl::CURLPIPE_MULTIPLEX for HTTP/2 multiplexing
191
+ multi_options = {:pipeline => Curl::CURLPIPE_HTTP1}
181
192
 
182
- Curl::Multi.get('url1','url2','url3','url4','url5', easy_options, multi_options) do|easy|
193
+ Curl::Multi.get(['url1','url2','url3','url4','url5'], easy_options, multi_options) do|easy|
183
194
  # do something interesting with the easy response
184
195
  puts easy.last_effective_url
185
196
  end
@@ -190,7 +201,8 @@ end
190
201
  ```ruby
191
202
  # make multiple POST requests
192
203
  easy_options = {:follow_location => true, :multipart_form_post => true}
193
- multi_options = {:pipeline => true}
204
+ multi_options = {:pipeline => Curl::CURLPIPE_HTTP1}
205
+
194
206
 
195
207
  url_fields = [
196
208
  { :url => 'url1', :post_fields => {'f1' => 'v1'} },
data/Rakefile CHANGED
@@ -69,7 +69,7 @@ desc "Compile the shared object"
69
69
  task :compile => [CURB_SO]
70
70
 
71
71
  desc "Install to your site_ruby directory"
72
- task :install => :alltests do
72
+ task :install do
73
73
  m = make 'install'
74
74
  fail "Make install failed (status #{m})" unless m == 0
75
75
  end
data/ext/curb.c CHANGED
@@ -258,122 +258,128 @@ void Init_curb_core() {
258
258
  rb_define_const(mCurl, "CURL_LONG_VERSION", curllongver);
259
259
 
260
260
  /* Passed to on_debug handler to indicate that the data is informational text. */
261
- rb_define_const(mCurl, "CURLINFO_TEXT", INT2FIX(CURLINFO_TEXT));
261
+ rb_define_const(mCurl, "CURLINFO_TEXT", LONG2NUM(CURLINFO_TEXT));
262
262
 
263
263
  /* Passed to on_debug handler to indicate that the data is header (or header-like) data received from the peer. */
264
- rb_define_const(mCurl, "CURLINFO_HEADER_IN", INT2FIX(CURLINFO_HEADER_IN));
264
+ rb_define_const(mCurl, "CURLINFO_HEADER_IN", LONG2NUM(CURLINFO_HEADER_IN));
265
265
 
266
266
  /* Passed to on_debug handler to indicate that the data is header (or header-like) data sent to the peer. */
267
- rb_define_const(mCurl, "CURLINFO_HEADER_OUT", INT2FIX(CURLINFO_HEADER_OUT));
267
+ rb_define_const(mCurl, "CURLINFO_HEADER_OUT", LONG2NUM(CURLINFO_HEADER_OUT));
268
268
 
269
269
  /* Passed to on_debug handler to indicate that the data is protocol data received from the peer. */
270
- rb_define_const(mCurl, "CURLINFO_DATA_IN", INT2FIX(CURLINFO_DATA_IN));
270
+ rb_define_const(mCurl, "CURLINFO_DATA_IN", LONG2NUM(CURLINFO_DATA_IN));
271
271
 
272
272
  /* Passed to on_debug handler to indicate that the data is protocol data sent to the peer. */
273
- rb_define_const(mCurl, "CURLINFO_DATA_OUT", INT2FIX(CURLINFO_DATA_OUT));
273
+ rb_define_const(mCurl, "CURLINFO_DATA_OUT", LONG2NUM(CURLINFO_DATA_OUT));
274
274
 
275
275
  #ifdef HAVE_CURLFTPMETHOD_MULTICWD
276
- rb_define_const(mCurl, "CURL_MULTICWD", INT2FIX(CURLFTPMETHOD_MULTICWD));
276
+ rb_define_const(mCurl, "CURL_MULTICWD", LONG2NUM(CURLFTPMETHOD_MULTICWD));
277
277
  #endif
278
278
 
279
279
  #ifdef HAVE_CURLFTPMETHOD_NOCWD
280
- rb_define_const(mCurl, "CURL_NOCWD", INT2FIX(CURLFTPMETHOD_NOCWD));
280
+ rb_define_const(mCurl, "CURL_NOCWD", LONG2NUM(CURLFTPMETHOD_NOCWD));
281
281
  #endif
282
282
 
283
283
  #ifdef HAVE_CURLFTPMETHOD_SINGLECWD
284
- rb_define_const(mCurl, "CURL_SINGLECWD", INT2FIX(CURLFTPMETHOD_SINGLECWD));
284
+ rb_define_const(mCurl, "CURL_SINGLECWD", LONG2NUM(CURLFTPMETHOD_SINGLECWD));
285
285
  #endif
286
286
 
287
287
  /* When passed to Curl::Easy#proxy_type , indicates that the proxy is an HTTP proxy. (libcurl >= 7.10) */
288
288
  #ifdef HAVE_CURLPROXY_HTTP
289
- rb_define_const(mCurl, "CURLPROXY_HTTP", INT2FIX(CURLPROXY_HTTP));
289
+ rb_define_const(mCurl, "CURLPROXY_HTTP", LONG2NUM(CURLPROXY_HTTP));
290
290
  #else
291
- rb_define_const(mCurl, "CURLPROXY_HTTP", INT2FIX(-1));
291
+ rb_define_const(mCurl, "CURLPROXY_HTTP", LONG2NUM(-1));
292
292
  #endif
293
293
 
294
294
  #ifdef CURL_VERSION_SSL
295
- rb_define_const(mCurl, "CURL_SSLVERSION_DEFAULT", INT2FIX(CURL_SSLVERSION_DEFAULT));
296
- rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1", INT2FIX(CURL_SSLVERSION_TLSv1));
297
- rb_define_const(mCurl, "CURL_SSLVERSION_SSLv2", INT2FIX(CURL_SSLVERSION_SSLv2));
298
- rb_define_const(mCurl, "CURL_SSLVERSION_SSLv3", INT2FIX(CURL_SSLVERSION_SSLv3));
299
-
300
- rb_define_const(mCurl, "CURL_USESSL_CONTROL", INT2FIX(CURB_FTPSSL_CONTROL));
301
- rb_define_const(mCurl, "CURL_USESSL_NONE", INT2FIX(CURB_FTPSSL_NONE));
302
- rb_define_const(mCurl, "CURL_USESSL_TRY", INT2FIX(CURB_FTPSSL_TRY));
303
- rb_define_const(mCurl, "CURL_USESSL_ALL", INT2FIX(CURB_FTPSSL_ALL));
295
+ rb_define_const(mCurl, "CURL_SSLVERSION_DEFAULT", LONG2NUM(CURL_SSLVERSION_DEFAULT));
296
+ rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1", LONG2NUM(CURL_SSLVERSION_TLSv1));
297
+ rb_define_const(mCurl, "CURL_SSLVERSION_SSLv2", LONG2NUM(CURL_SSLVERSION_SSLv2));
298
+ rb_define_const(mCurl, "CURL_SSLVERSION_SSLv3", LONG2NUM(CURL_SSLVERSION_SSLv3));
299
+ rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_0", LONG2NUM(CURL_SSLVERSION_TLSv1_0));
300
+ rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_1", LONG2NUM(CURL_SSLVERSION_TLSv1_1));
301
+ rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_2", LONG2NUM(CURL_SSLVERSION_TLSv1_2));
302
+
303
+ rb_define_const(mCurl, "CURL_USESSL_CONTROL", LONG2NUM(CURB_FTPSSL_CONTROL));
304
+ rb_define_const(mCurl, "CURL_USESSL_NONE", LONG2NUM(CURB_FTPSSL_NONE));
305
+ rb_define_const(mCurl, "CURL_USESSL_TRY", LONG2NUM(CURB_FTPSSL_TRY));
306
+ rb_define_const(mCurl, "CURL_USESSL_ALL", LONG2NUM(CURB_FTPSSL_ALL));
304
307
  #else
305
- rb_define_const(mCurl, "CURL_SSLVERSION_DEFAULT", INT2FIX(-1));
306
- rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1", INT2FIX(-1));
307
- rb_define_const(mCurl, "CURL_SSLVERSION_SSLv2", INT2FIX(-1));
308
- rb_define_const(mCurl, "CURL_SSLVERSION_SSLv3", INT2FIX(-1));
308
+ rb_define_const(mCurl, "CURL_SSLVERSION_DEFAULT", LONG2NUM(-1));
309
+ rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1", LONG2NUM(-1));
310
+ rb_define_const(mCurl, "CURL_SSLVERSION_SSLv2", LONG2NUM(-1));
311
+ rb_define_const(mCurl, "CURL_SSLVERSION_SSLv3", LONG2NUM(-1));
312
+ rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_0", LONG2NUM(-1));
313
+ rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_1", LONG2NUM(-1));
314
+ rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_2", LONG2NUM(-1));
309
315
 
310
- rb_define_const(mCurl, "CURL_USESSL_CONTROL", INT2FIX(-1));
311
- rb_define_const(mCurl, "CURL_USESSL_NONE", INT2FIX(-1));
312
- rb_define_const(mCurl, "CURL_USESSL_TRY", INT2FIX(-1));
313
- rb_define_const(mCurl, "CURL_USESSL_ALL", INT2FIX(-1));
316
+ rb_define_const(mCurl, "CURL_USESSL_CONTROL", LONG2NUM(-1));
317
+ rb_define_const(mCurl, "CURL_USESSL_NONE", LONG2NUM(-1));
318
+ rb_define_const(mCurl, "CURL_USESSL_TRY", LONG2NUM(-1));
319
+ rb_define_const(mCurl, "CURL_USESSL_ALL", LONG2NUM(-1));
314
320
  #endif
315
321
 
316
322
  /* When passed to Curl::Easy#proxy_type , indicates that the proxy is a SOCKS4 proxy. (libcurl >= 7.15.2) */
317
323
  #ifdef HAVE_CURLPROXY_SOCKS4
318
- rb_define_const(mCurl, "CURLPROXY_SOCKS4", INT2FIX(CURLPROXY_SOCKS4));
324
+ rb_define_const(mCurl, "CURLPROXY_SOCKS4", LONG2NUM(CURLPROXY_SOCKS4));
319
325
  #else
320
- rb_define_const(mCurl, "CURLPROXY_SOCKS4", INT2FIX(-2));
326
+ rb_define_const(mCurl, "CURLPROXY_SOCKS4", LONG2NUM(-2));
321
327
  #endif
322
328
 
323
329
  /* When passed to Curl::Easy#proxy_type , indicates that the proxy is a SOCKS4A proxy. (libcurl >= 7.18.0) */
324
330
  #ifdef HAVE_CURLPROXY_SOCKS4A
325
- rb_define_const(mCurl, "CURLPROXY_SOCKS4A", INT2FIX(CURLPROXY_SOCKS4A));
331
+ rb_define_const(mCurl, "CURLPROXY_SOCKS4A", LONG2NUM(CURLPROXY_SOCKS4A));
326
332
  #else
327
- rb_define_const(mCurl, "CURLPROXY_SOCKS4A", INT2FIX(-2));
333
+ rb_define_const(mCurl, "CURLPROXY_SOCKS4A", LONG2NUM(-2));
328
334
  #endif
329
335
 
330
336
  /* When passed to Curl::Easy#proxy_type , indicates that the proxy is a SOCKS5 proxy. (libcurl >= 7.10) */
331
337
  #ifdef HAVE_CURLPROXY_SOCKS5
332
- rb_define_const(mCurl, "CURLPROXY_SOCKS5", INT2FIX(CURLPROXY_SOCKS5));
338
+ rb_define_const(mCurl, "CURLPROXY_SOCKS5", LONG2NUM(CURLPROXY_SOCKS5));
333
339
  #else
334
- rb_define_const(mCurl, "CURLPROXY_SOCKS5", INT2FIX(-2));
340
+ rb_define_const(mCurl, "CURLPROXY_SOCKS5", LONG2NUM(-2));
335
341
  #endif
336
342
 
337
343
  /* When passed to Curl::Easy#http_auth_types or Curl::Easy#proxy_auth_types, directs libcurl to use Basic authentication. */
338
344
  #ifdef HAVE_CURLAUTH_BASIC
339
- rb_define_const(mCurl, "CURLAUTH_BASIC", INT2FIX(CURLAUTH_BASIC));
345
+ rb_define_const(mCurl, "CURLAUTH_BASIC", LONG2NUM(CURLAUTH_BASIC));
340
346
  #else
341
- rb_define_const(mCurl, "CURLAUTH_BASIC", INT2FIX(0));
347
+ rb_define_const(mCurl, "CURLAUTH_BASIC", LONG2NUM(0));
342
348
  #endif
343
349
 
344
350
  /* When passed to Curl::Easy#http_auth_types or Curl::Easy#proxy_auth_types, directs libcurl to use Digest authentication. */
345
351
  #ifdef HAVE_CURLAUTH_DIGEST
346
- rb_define_const(mCurl, "CURLAUTH_DIGEST", INT2FIX(CURLAUTH_DIGEST));
352
+ rb_define_const(mCurl, "CURLAUTH_DIGEST", LONG2NUM(CURLAUTH_DIGEST));
347
353
  #else
348
- rb_define_const(mCurl, "CURLAUTH_DIGEST", INT2FIX(0));
354
+ rb_define_const(mCurl, "CURLAUTH_DIGEST", LONG2NUM(0));
349
355
  #endif
350
356
 
351
357
  /* When passed to Curl::Easy#http_auth_types or Curl::Easy#proxy_auth_types, directs libcurl to use GSS Negotiate authentication. Requires a suitable GSS-API library. */
352
358
  #ifdef HAVE_CURLAUTH_GSSNEGOTIATE
353
- rb_define_const(mCurl, "CURLAUTH_GSSNEGOTIATE", INT2FIX(CURLAUTH_GSSNEGOTIATE));
359
+ rb_define_const(mCurl, "CURLAUTH_GSSNEGOTIATE", LONG2NUM(CURLAUTH_GSSNEGOTIATE));
354
360
  #else
355
- rb_define_const(mCurl, "CURLAUTH_GSSNEGOTIATE", INT2FIX(0));
361
+ rb_define_const(mCurl, "CURLAUTH_GSSNEGOTIATE", LONG2NUM(0));
356
362
  #endif
357
363
 
358
364
  /* When passed to Curl::Easy#http_auth_types or Curl::Easy#proxy_auth_types, directs libcurl to use HTTP NTLM authentication. Requires MS Windows or OpenSSL support. */
359
365
  #ifdef HAVE_CURLAUTH_NTLM
360
- rb_define_const(mCurl, "CURLAUTH_NTLM", INT2FIX(CURLAUTH_NTLM));
366
+ rb_define_const(mCurl, "CURLAUTH_NTLM", LONG2NUM(CURLAUTH_NTLM));
361
367
  #else
362
- rb_define_const(mCurl, "CURLAUTH_NTLM", INT2FIX(0));
368
+ rb_define_const(mCurl, "CURLAUTH_NTLM", LONG2NUM(0));
363
369
  #endif
364
370
 
365
371
  /* When passed to Curl::Easy#http_auth_types or Curl::Easy#proxy_auth_types, allows libcurl to select any suitable authentication method except basic. */
366
372
  #ifdef HAVE_CURLAUTH_ANYSAFE
367
- rb_define_const(mCurl, "CURLAUTH_ANYSAFE", INT2FIX(CURLAUTH_ANYSAFE));
373
+ rb_define_const(mCurl, "CURLAUTH_ANYSAFE", LONG2NUM(CURLAUTH_ANYSAFE));
368
374
  #else
369
- rb_define_const(mCurl, "CURLAUTH_ANYSAFE", INT2FIX(0));
375
+ rb_define_const(mCurl, "CURLAUTH_ANYSAFE", LONG2NUM(0));
370
376
  #endif
371
377
 
372
378
  /* When passed to Curl::Easy#http_auth_types or Curl::Easy#proxy_auth_types, allows libcurl to select any suitable authentication method. */
373
379
  #ifdef HAVE_CURLAUTH_ANY
374
- rb_define_const(mCurl, "CURLAUTH_ANY", INT2FIX(CURLAUTH_ANY));
380
+ rb_define_const(mCurl, "CURLAUTH_ANY", LONG2NUM(CURLAUTH_ANY));
375
381
  #else
376
- rb_define_const(mCurl, "CURLAUTH_ANY", INT2FIX(0));
382
+ rb_define_const(mCurl, "CURLAUTH_ANY", LONG2NUM(0));
377
383
  #endif
378
384
 
379
385
  CURB_DEFINE(CURLOPT_VERBOSE);
@@ -585,6 +591,9 @@ void Init_curb_core() {
585
591
  CURB_DEFINE(CURL_HTTP_VERSION_NONE);
586
592
  CURB_DEFINE(CURL_HTTP_VERSION_1_0);
587
593
  CURB_DEFINE(CURL_HTTP_VERSION_1_1);
594
+ #if LIBCURL_VERSION_NUM >= 0x072100 /* 7.33.0 */
595
+ CURB_DEFINE(CURL_HTTP_VERSION_2_0);
596
+ #endif
588
597
  #if HAVE_CURLOPT_IGNORE_CONTENT_LENGTH
589
598
  CURB_DEFINE(CURLOPT_IGNORE_CONTENT_LENGTH);
590
599
  #endif
@@ -886,6 +895,15 @@ void Init_curb_core() {
886
895
  #if HAVE_CURL_SSLVERSION_SSLv3
887
896
  CURB_DEFINE(CURL_SSLVERSION_SSLv3);
888
897
  #endif
898
+ #if HAVE_CURL_SSLVERSION_TLSv1_0
899
+ CURB_DEFINE(CURL_SSLVERSION_TLSv1_0);
900
+ #endif
901
+ #if HAVE_CURL_SSLVERSION_TLSv1_1
902
+ CURB_DEFINE(CURL_SSLVERSION_TLSv1_1);
903
+ #endif
904
+ #if HAVE_CURL_SSLVERSION_TLSv1_2
905
+ CURB_DEFINE(CURL_SSLVERSION_TLSv1_2);
906
+ #endif
889
907
  #if HAVE_CURLOPT_SSL_VERIFYPEER
890
908
  CURB_DEFINE(CURLOPT_SSL_VERIFYPEER);
891
909
  #endif
@@ -990,6 +1008,16 @@ void Init_curb_core() {
990
1008
  CURB_DEFINE(CURLOPT_UNIX_SOCKET_PATH);
991
1009
  #endif
992
1010
 
1011
+ #if LIBCURL_VERSION_NUM >= 0x072B00 /* 7.43.0 */
1012
+ CURB_DEFINE(CURLPIPE_NOTHING);
1013
+ CURB_DEFINE(CURLPIPE_HTTP1);
1014
+ CURB_DEFINE(CURLPIPE_MULTIPLEX);
1015
+
1016
+ rb_define_const(mCurl, "PIPE_NOTHING", LONG2NUM(CURLPIPE_NOTHING));
1017
+ rb_define_const(mCurl, "PIPE_HTTP1", LONG2NUM(CURLPIPE_HTTP1));
1018
+ rb_define_const(mCurl, "PIPE_MULTIPLEX", LONG2NUM(CURLPIPE_MULTIPLEX));
1019
+ #endif
1020
+
993
1021
  #if LIBCURL_VERSION_NUM >= 0x072100 /* 7.33.0 */
994
1022
  rb_define_const(mCurl, "HTTP_2_0", LONG2NUM(CURL_HTTP_VERSION_2_0));
995
1023
  #endif
@@ -997,6 +1025,8 @@ void Init_curb_core() {
997
1025
  rb_define_const(mCurl, "HTTP_1_0", LONG2NUM(CURL_HTTP_VERSION_1_0));
998
1026
  rb_define_const(mCurl, "HTTP_NONE", LONG2NUM(CURL_HTTP_VERSION_NONE));
999
1027
 
1028
+
1029
+
1000
1030
  rb_define_singleton_method(mCurl, "ipv6?", ruby_curl_ipv6_q, 0);
1001
1031
  rb_define_singleton_method(mCurl, "kerberos4?", ruby_curl_kerberos4_q, 0);
1002
1032
  rb_define_singleton_method(mCurl, "ssl?", ruby_curl_ssl_q, 0);
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.1"
24
- #define CURB_VER_NUM 901
23
+ #define CURB_VERSION "0.9.2"
24
+ #define CURB_VER_NUM 902
25
25
  #define CURB_VER_MAJ 0
26
- #define CURB_VER_MIN 1
26
+ #define CURB_VER_MIN 2
27
27
  #define CURB_VER_MIC 0
28
28
  #define CURB_VER_PATCH 0
29
29
 
@@ -192,7 +192,7 @@ static int proc_progress_handler(VALUE proc,
192
192
 
193
193
  static VALUE call_debug_handler(VALUE ary) {
194
194
  return rb_funcall(rb_ary_entry(ary, 0), idCall, 2,
195
- rb_ary_entry(ary, 1), // INT2FIX(type),
195
+ rb_ary_entry(ary, 1), // INT2NUM(type),
196
196
  rb_ary_entry(ary, 2)); // rb_str_new(data, data_len)
197
197
  }
198
198
  static int proc_debug_handler(CURL *curl,
@@ -202,13 +202,13 @@ static int proc_debug_handler(CURL *curl,
202
202
  VALUE proc) {
203
203
  VALUE callargs = rb_ary_new2(3);
204
204
  rb_ary_store(callargs, 0, proc);
205
- rb_ary_store(callargs, 1, INT2FIX(type));
205
+ rb_ary_store(callargs, 1, INT2NUM(type));
206
206
  rb_ary_store(callargs, 2, rb_str_new(data, data_len));
207
207
  rb_rescue(call_debug_handler, callargs, callback_exception, Qnil);
208
208
  /* no way to indicate to libcurl that we should break out given an exception in the on_debug handler...
209
209
  * this means exceptions will be swallowed
210
210
  */
211
- //rb_funcall(proc, idCall, 2, INT2FIX(type), rb_str_new(data, data_len));
211
+ //rb_funcall(proc, idCall, 2, INT2NUM(type), rb_str_new(data, data_len));
212
212
  return 0;
213
213
  }
214
214
 
@@ -827,14 +827,14 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
827
827
  rb_hash_aset(headers, rb_str_new2("Expect"), rb_str_new2(""));
828
828
  }
829
829
  size = rb_funcall(stat, rb_intern("size"), 0);
830
- curl_easy_setopt(curl, CURLOPT_INFILESIZE, FIX2LONG(size));
830
+ curl_easy_setopt(curl, CURLOPT_INFILESIZE, NUM2LONG(size));
831
831
  }
832
832
  else if( rb_hash_aref(headers, rb_str_new2("Content-Length")) == Qnil && rb_hash_aref(headers, rb_str_new2("Transfer-Encoding")) == Qnil ) {
833
833
  rb_hash_aset(headers, rb_str_new2("Transfer-Encoding"), rb_str_new2("chunked"));
834
834
  }
835
835
  else if( rb_hash_aref(headers, rb_str_new2("Content-Length")) ) {
836
836
  VALUE size = rb_funcall(rb_hash_aref(headers, rb_str_new2("Content-Length")), rb_intern("to_i"), 0);
837
- curl_easy_setopt(curl, CURLOPT_INFILESIZE, FIX2LONG(size));
837
+ curl_easy_setopt(curl, CURLOPT_INFILESIZE, NUM2LONG(size));
838
838
  }
839
839
  }
840
840
  else if (rb_respond_to(data, rb_intern("to_s"))) {
@@ -978,16 +978,16 @@ static VALUE ruby_curl_easy_proxy_type_get(VALUE self) {
978
978
  (!strncmp("digest",node,6)) ? CURLAUTH_DIGEST : \
979
979
  (!strncmp("gssnegotiate",node,12)) ? CURLAUTH_GSSNEGOTIATE : \
980
980
  (!strncmp("ntlm",node,4)) ? CURLAUTH_NTLM : \
981
- (!strncmp("any",node,3)) ? CURLAUTH_ANY : \
982
- (!strncmp("anysafe",node,7)) ? CURLAUTH_ANYSAFE : 0
981
+ (!strncmp("anysafe",node,7)) ? CURLAUTH_ANYSAFE : \
982
+ (!strncmp("any",node,3)) ? CURLAUTH_ANY : 0
983
983
  #else
984
984
  #define CURL_HTTPAUTH_STR_TO_NUM(node) \
985
985
  (!strncmp("basic",node,5)) ? CURLAUTH_BASIC : \
986
986
  (!strncmp("digest",node,6)) ? CURLAUTH_DIGEST : \
987
987
  (!strncmp("gssnegotiate",node,12)) ? CURLAUTH_GSSNEGOTIATE : \
988
988
  (!strncmp("ntlm",node,4)) ? CURLAUTH_NTLM : \
989
- (!strncmp("any",node,3)) ? CURLAUTH_ANY : \
990
- (!strncmp("anysafe",node,7)) ? CURLAUTH_ANYSAFE : 0
989
+ (!strncmp("anysafe",node,7)) ? CURLAUTH_ANYSAFE : \
990
+ (!strncmp("any",node,3)) ? CURLAUTH_ANY : 0
991
991
  #endif
992
992
  /*
993
993
  * call-seq:
@@ -1001,21 +1001,22 @@ static VALUE ruby_curl_easy_proxy_type_get(VALUE self) {
1001
1001
  static VALUE ruby_curl_easy_http_auth_types_set(int argc, VALUE *argv, VALUE self) {//VALUE self, VALUE http_auth_types) {
1002
1002
  ruby_curl_easy *rbce;
1003
1003
  VALUE args_ary;
1004
- int i, len;
1004
+ long i, len;
1005
1005
  char* node = NULL;
1006
- long mask = 0x000000;
1006
+ long mask = 0;
1007
1007
 
1008
1008
  rb_scan_args(argc, argv, "*", &args_ary);
1009
1009
  Data_Get_Struct(self, ruby_curl_easy, rbce);
1010
1010
 
1011
- len = (int)RARRAY_LEN(args_ary);
1011
+ len = RARRAY_LEN(args_ary);
1012
1012
 
1013
- if (len == 1 && (TYPE(rb_ary_entry(args_ary,0)) == T_FIXNUM || rb_ary_entry(args_ary,0) == Qnil)) {
1013
+ if (len == 1 && (rb_ary_entry(args_ary,0) == Qnil || TYPE(rb_ary_entry(args_ary,0)) == T_FIXNUM ||
1014
+ TYPE(rb_ary_entry(args_ary,0)) == T_BIGNUM)) {
1014
1015
  if (rb_ary_entry(args_ary,0) == Qnil) {
1015
1016
  rbce->http_auth_types = 0;
1016
1017
  }
1017
1018
  else {
1018
- rbce->http_auth_types = NUM2INT(rb_ary_entry(args_ary,0));
1019
+ rbce->http_auth_types = NUM2LONG(rb_ary_entry(args_ary,0));
1019
1020
  }
1020
1021
  }
1021
1022
  else {
@@ -1028,7 +1029,7 @@ static VALUE ruby_curl_easy_http_auth_types_set(int argc, VALUE *argv, VALUE sel
1028
1029
  }
1029
1030
  rbce->http_auth_types = mask;
1030
1031
  }
1031
- return INT2NUM(rbce->http_auth_types);
1032
+ return LONG2NUM(rbce->http_auth_types);
1032
1033
  }
1033
1034
 
1034
1035
  /*
@@ -1353,8 +1354,15 @@ static VALUE ruby_curl_easy_password_get(VALUE self, VALUE password) {
1353
1354
  * easy.ssl_version = value => fixnum or nil
1354
1355
  *
1355
1356
  * Sets the version of SSL/TLS that libcurl will attempt to use. Valid
1356
- * options are Curl::CURL_SSLVERSION_TLSv1, Curl::CURL_SSLVERSION::SSLv2,
1357
- * Curl::CURL_SSLVERSION_SSLv3 and Curl::CURL_SSLVERSION_DEFAULT
1357
+ * options are:
1358
+ *
1359
+ * Curl::CURL_SSLVERSION_DEFAULT
1360
+ * Curl::CURL_SSLVERSION_TLSv1 (TLS 1.x)
1361
+ * Curl::CURL_SSLVERSION_SSLv2
1362
+ * Curl::CURL_SSLVERSION_SSLv3
1363
+ * Curl::CURL_SSLVERSION_TLSv1_0
1364
+ * Curl::CURL_SSLVERSION_TLSv1_1
1365
+ * Curl::CURL_SSLVERSION_TLSv1_2
1358
1366
  */
1359
1367
  static VALUE ruby_curl_easy_ssl_version_set(VALUE self, VALUE ssl_version) {
1360
1368
  CURB_IMMED_SETTER(ruby_curl_easy, ssl_version, -1);
@@ -2168,7 +2176,7 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
2168
2176
  /*
2169
2177
  * NOTE: we used to set CURLAUTH_ANY but see: http://curl.haxx.se/mail/lib-2015-06/0033.html
2170
2178
  */
2171
- if (rbce->http_auth_types > 0) {
2179
+ if (rbce->http_auth_types != 0) {
2172
2180
  #if LIBCURL_VERSION_NUM >= 0x070a06
2173
2181
  curl_easy_setopt(curl, CURLOPT_HTTPAUTH, rbce->http_auth_types);
2174
2182
  #else
@@ -2176,7 +2184,7 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
2176
2184
  #endif
2177
2185
  }
2178
2186
 
2179
- if (rbce->proxy_auth_types > 0) {
2187
+ if (rbce->proxy_auth_types != 0) {
2180
2188
  #if LIBCURL_VERSION_NUM >= 0x070a07
2181
2189
  curl_easy_setopt(curl, CURLOPT_PROXYAUTH, rbce->proxy_auth_types);
2182
2190
  #else
@@ -2403,7 +2411,7 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
2403
2411
  append_to_form(argv[i], &first, &last);
2404
2412
  } else if (rb_type(argv[i]) == T_ARRAY) {
2405
2413
  // see: https://github.com/rvanlieshout/curb/commit/8bcdefddc0162484681ebd1a92d52a642666a445
2406
- int c = 0, argv_len = (int)RARRAY_LEN(argv[i]);
2414
+ long c = 0, argv_len = RARRAY_LEN(argv[i]);
2407
2415
  for (; c < argv_len; ++c) {
2408
2416
  if (rb_obj_is_instance_of(rb_ary_entry(argv[i],c), cCurlPostField)) {
2409
2417
  append_to_form(rb_ary_entry(argv[i],c), &first, &last);
@@ -2612,7 +2620,7 @@ static VALUE ruby_curl_easy_file_time_get(VALUE self) {
2612
2620
  return LONG2NUM(time);
2613
2621
  #else
2614
2622
  rb_warn("Installed libcurl is too old to support file_time");
2615
- return INT2FIX(0);
2623
+ return LONG2NUM(0);
2616
2624
  #endif
2617
2625
  }
2618
2626
 
@@ -2772,7 +2780,7 @@ static VALUE ruby_curl_easy_redirect_count_get(VALUE self) {
2772
2780
  return LONG2NUM(count);
2773
2781
  #else
2774
2782
  rb_warn("Installed libcurl is too old to support redirect_count");
2775
- return INT2FIX(-1);
2783
+ return LONG2NUM(-1);
2776
2784
  #endif
2777
2785
 
2778
2786
  }
@@ -2801,7 +2809,7 @@ static VALUE ruby_curl_easy_redirect_url_get(VALUE self) {
2801
2809
  }
2802
2810
  #else
2803
2811
  rb_warn("Installed libcurl is too old to support redirect_url");
2804
- return INT2FIX(-1);
2812
+ return LONG2NUM(-1);
2805
2813
  #endif
2806
2814
  }
2807
2815
 
@@ -3030,7 +3038,7 @@ static VALUE ruby_curl_easy_os_errno_get(VALUE self) {
3030
3038
  return LONG2NUM(result);
3031
3039
  #else
3032
3040
  rb_warn("Installed libcurl is too old to support os_errno");
3033
- return INT2FIX(0);
3041
+ return LONG2NUM(0);
3034
3042
  #endif
3035
3043
  }
3036
3044
 
@@ -3059,7 +3067,7 @@ static VALUE ruby_curl_easy_num_connects_get(VALUE self) {
3059
3067
  return LONG2NUM(result);
3060
3068
  #else
3061
3069
  rb_warn("Installed libcurl is too old to support num_connects");
3062
- return INT2FIX(-1);
3070
+ return LONG2NUM(-1);
3063
3071
  #endif
3064
3072
  }
3065
3073
 
@@ -3136,7 +3144,7 @@ static VALUE ruby_curl_easy_multi_set(VALUE self, VALUE multi) {
3136
3144
  static VALUE ruby_curl_easy_last_result(VALUE self) {
3137
3145
  ruby_curl_easy *rbce;
3138
3146
  Data_Get_Struct(self, ruby_curl_easy, rbce);
3139
- return INT2FIX(rbce->last_result);
3147
+ return LONG2NUM(rbce->last_result);
3140
3148
  }
3141
3149
 
3142
3150
  /*
@@ -3147,7 +3155,7 @@ static VALUE ruby_curl_easy_last_result(VALUE self) {
3147
3155
  */
3148
3156
  static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
3149
3157
  ruby_curl_easy *rbce;
3150
- long option = FIX2LONG(opt);
3158
+ long option = NUM2LONG(opt);
3151
3159
 
3152
3160
  Data_Get_Struct(self, ruby_curl_easy, rbce);
3153
3161
 
@@ -3172,7 +3180,7 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
3172
3180
  curl_easy_setopt(rbce->curl, CURLOPT_CUSTOMREQUEST, NIL_P(val) ? NULL : StringValueCStr(val));
3173
3181
  break;
3174
3182
  case CURLOPT_HTTP_VERSION:
3175
- curl_easy_setopt(rbce->curl, CURLOPT_HTTP_VERSION, FIX2INT(val));
3183
+ curl_easy_setopt(rbce->curl, CURLOPT_HTTP_VERSION, NUM2LONG(val));
3176
3184
  break;
3177
3185
  case CURLOPT_PROXY: {
3178
3186
  VALUE proxy_url = val;
@@ -3196,11 +3204,14 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
3196
3204
  } else {
3197
3205
  value = rb_funcall(val, rb_intern("to_i"), 0);
3198
3206
  }
3199
- curl_easy_setopt(rbce->curl, option, FIX2INT(value));
3207
+ curl_easy_setopt(rbce->curl, option, NUM2LONG(value));
3200
3208
  } break;
3201
3209
  case CURLOPT_POST: {
3202
3210
  curl_easy_setopt(rbce->curl, CURLOPT_POST, rb_type(val) == T_TRUE);
3203
3211
  } break;
3212
+ case CURLOPT_MAXCONNECTS: {
3213
+ curl_easy_setopt(rbce->curl, CURLOPT_MAXCONNECTS, NUM2LONG(val));
3214
+ } break;
3204
3215
  case CURLOPT_POSTFIELDS: {
3205
3216
  curl_easy_setopt(rbce->curl, CURLOPT_POSTFIELDS, NIL_P(val) ? NULL : StringValueCStr(val));
3206
3217
  } break;
@@ -3225,20 +3236,23 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
3225
3236
  CURB_OBJECT_HSETTER(ruby_curl_easy, cookiejar);
3226
3237
  } break;
3227
3238
  case CURLOPT_TCP_NODELAY: {
3228
- curl_easy_setopt(rbce->curl, CURLOPT_TCP_NODELAY, FIX2LONG(val));
3239
+ curl_easy_setopt(rbce->curl, CURLOPT_TCP_NODELAY, NUM2LONG(val));
3229
3240
  } break;
3230
3241
  case CURLOPT_RESUME_FROM: {
3231
- curl_easy_setopt(rbce->curl, CURLOPT_RESUME_FROM, FIX2LONG(val));
3242
+ curl_easy_setopt(rbce->curl, CURLOPT_RESUME_FROM, NUM2LONG(val));
3232
3243
  } break;
3233
3244
  case CURLOPT_FAILONERROR: {
3234
- curl_easy_setopt(rbce->curl, CURLOPT_FAILONERROR, FIX2LONG(val));
3245
+ curl_easy_setopt(rbce->curl, CURLOPT_FAILONERROR, NUM2LONG(val));
3235
3246
  } break;
3236
3247
  case CURLOPT_SSL_CIPHER_LIST: {
3237
3248
  curl_easy_setopt(rbce->curl, CURLOPT_SSL_CIPHER_LIST, StringValueCStr(val));
3238
3249
  } break;
3250
+ case CURLOPT_FORBID_REUSE: {
3251
+ curl_easy_setopt(rbce->curl, CURLOPT_FORBID_REUSE, NUM2LONG(val));
3252
+ } break;
3239
3253
  #if HAVE_CURLOPT_GSSAPI_DELEGATION
3240
3254
  case CURLOPT_GSSAPI_DELEGATION: {
3241
- curl_easy_setopt(rbce->curl, CURLOPT_GSSAPI_DELEGATION, FIX2LONG(val));
3255
+ curl_easy_setopt(rbce->curl, CURLOPT_GSSAPI_DELEGATION, NUM2LONG(val));
3242
3256
  } break;
3243
3257
  #endif
3244
3258
  #if HAVE_CURLOPT_UNIX_SOCKET_PATH
@@ -3338,7 +3352,7 @@ static VALUE ruby_curl_easy_unescape(VALUE self, VALUE str) {
3338
3352
  #if (LIBCURL_VERSION_NUM >= 0x070f04)
3339
3353
  result = (char*)curl_easy_unescape(rbce->curl, StringValuePtr(str), (int)RSTRING_LEN(str), &rlen);
3340
3354
  #else
3341
- result = (char*)curl_unescape(StringValuePtr(str), RSTRING_LEN(str));
3355
+ result = (char*)curl_unescape(StringValuePtr(str), (int)RSTRING_LEN(str));
3342
3356
  rlen = strlen(result);
3343
3357
  #endif
3344
3358
 
@@ -3358,7 +3372,7 @@ static VALUE ruby_curl_easy_unescape(VALUE self, VALUE str) {
3358
3372
  * translate an internal libcurl error to ruby error class
3359
3373
  */
3360
3374
  static VALUE ruby_curl_easy_error_message(VALUE klass, VALUE code) {
3361
- return rb_curl_easy_error(FIX2INT(code));
3375
+ return rb_curl_easy_error(NUM2INT(code));
3362
3376
  }
3363
3377
 
3364
3378
  /* =================== INIT LIB =====================*/
@@ -99,7 +99,7 @@
99
99
  \
100
100
  return oldproc;
101
101
 
102
- /* setter for numerics that are kept in c ints */
102
+ /* setter for numerics that are kept in c longs */
103
103
  #define CURB_IMMED_SETTER(type, attr, nilval) \
104
104
  type *ptr; \
105
105
  \
@@ -107,12 +107,12 @@
107
107
  if (attr == Qnil) { \
108
108
  ptr->attr = nilval; \
109
109
  } else { \
110
- ptr->attr = NUM2INT(attr); \
110
+ ptr->attr = NUM2LONG(attr); \
111
111
  } \
112
112
  \
113
113
  return attr; \
114
114
 
115
- /* setter for numerics that are kept in c ints */
115
+ /* setter for numerics that are kept in c longs */
116
116
  #define CURB_IMMED_GETTER(type, attr, nilval) \
117
117
  type *ptr; \
118
118
  \
@@ -120,7 +120,7 @@
120
120
  if (ptr->attr == nilval) { \
121
121
  return Qnil; \
122
122
  } else { \
123
- return INT2NUM(ptr->attr); \
123
+ return LONG2NUM(ptr->attr); \
124
124
  }
125
125
 
126
126
  /* special setter for port / port ranges */
@@ -131,7 +131,7 @@
131
131
  if (attr == Qnil) { \
132
132
  ptr->attr = 0; \
133
133
  } else { \
134
- int port = FIX2INT(attr); \
134
+ int port = NUM2INT(attr); \
135
135
  \
136
136
  if ((port) && ((port & 0xFFFF) == port)) { \
137
137
  ptr->attr = port; \
@@ -150,10 +150,10 @@
150
150
  if (ptr->attr == 0) { \
151
151
  return Qnil; \
152
152
  } else { \
153
- return INT2FIX(ptr->attr); \
153
+ return INT2NUM(ptr->attr); \
154
154
  }
155
155
 
156
156
  #define CURB_DEFINE(name) \
157
- rb_define_const(mCurl, #name, INT2FIX(name))
157
+ rb_define_const(mCurl, #name, LONG2NUM(name))
158
158
 
159
159
  #endif
@@ -47,37 +47,41 @@ static VALUE callback_exception(VALUE unused) {
47
47
  }
48
48
 
49
49
  static void curl_multi_mark(ruby_curl_multi *rbcm) {
50
- rb_gc_mark(rbcm->requests);
50
+ if (!NIL_P(rbcm->requests)) rb_gc_mark(rbcm->requests);
51
51
  }
52
52
 
53
- static void curl_multi_flush_easy(VALUE key, VALUE easy, ruby_curl_multi *rbcm) {
53
+ /* Hash#foreach callback for curl_multi_free */
54
+ static int curl_multi_flush_easy(VALUE key, VALUE easy, ruby_curl_multi *rbcm) {
54
55
  CURLMcode result;
55
56
  ruby_curl_easy *rbce;
56
57
 
57
- Data_Get_Struct(easy, ruby_curl_easy, rbce);
58
- result = curl_multi_remove_handle(rbcm->handle, rbce->curl);
59
- if (result != 0) {
60
- raise_curl_multi_error_exception(result);
58
+ // sometimes the type is T_ZOMBIE, e.g. after Ruby has received the SIGTERM signal
59
+ if (rb_type(easy) == T_DATA) {
60
+ Data_Get_Struct(easy, ruby_curl_easy, rbce);
61
+
62
+ result = curl_multi_remove_handle(rbcm->handle, rbce->curl);
63
+ if (result != 0) {
64
+ raise_curl_multi_error_exception(result);
65
+ }
61
66
  }
62
- }
63
67
 
64
- static int
65
- rb_hash_clear_i(VALUE key, VALUE value, VALUE dummy) {
66
68
  return ST_DELETE;
67
69
  }
68
70
 
69
- static void curl_multi_free(ruby_curl_multi *rbcm) {
71
+ void curl_multi_free(ruby_curl_multi *rbcm) {
70
72
  VALUE hash = rbcm->requests;
71
73
 
72
- if (rbcm && !NIL_P(hash) && rb_type(hash) == T_HASH && RHASH_SIZE(hash) > 0) {
74
+ if (!NIL_P(hash) && rb_type(hash) == T_HASH && RHASH_SIZE(hash) > 0) {
73
75
 
74
- rb_hash_foreach(hash, (int (*)())curl_multi_flush_easy, (VALUE)rbcm);
75
- rb_hash_foreach(hash, rb_hash_clear_i, 0);
76
+ rb_hash_foreach(hash, curl_multi_flush_easy, (VALUE)rbcm);
76
77
  /* rb_hash_clear(rbcm->requests); */
77
78
 
78
79
  rbcm->requests = Qnil;
79
80
  }
80
- curl_multi_cleanup(rbcm->handle);
81
+
82
+ if (rbcm->handle) {
83
+ curl_multi_cleanup(rbcm->handle);
84
+ }
81
85
  free(rbcm);
82
86
  }
83
87
 
@@ -116,7 +120,7 @@ VALUE ruby_curl_multi_new(VALUE klass) {
116
120
  *
117
121
  */
118
122
  VALUE ruby_curl_multi_set_default_timeout(VALUE klass, VALUE timeout) {
119
- cCurlMutiDefaulttimeout = FIX2LONG(timeout);
123
+ cCurlMutiDefaulttimeout = NUM2LONG(timeout);
120
124
  return timeout;
121
125
  }
122
126
 
@@ -128,7 +132,7 @@ VALUE ruby_curl_multi_set_default_timeout(VALUE klass, VALUE timeout) {
128
132
  *
129
133
  */
130
134
  VALUE ruby_curl_multi_get_default_timeout(VALUE klass) {
131
- return INT2FIX(cCurlMutiDefaulttimeout);
135
+ return LONG2NUM(cCurlMutiDefaulttimeout);
132
136
  }
133
137
 
134
138
  /* Hash#foreach callback for ruby_curl_multi_requests */
@@ -170,7 +174,7 @@ static VALUE ruby_curl_multi_idle(VALUE self) {
170
174
 
171
175
  Data_Get_Struct(self, ruby_curl_multi, rbcm);
172
176
 
173
- if ( FIX2INT( rb_funcall(rbcm->requests, rb_intern("length"), 0) ) == 0 ) {
177
+ if (RHASH_SIZE(rbcm->requests) == 0) {
174
178
  return Qtrue;
175
179
  } else {
176
180
  return Qfalse;
@@ -189,7 +193,15 @@ static VALUE ruby_curl_multi_max_connects(VALUE self, VALUE count) {
189
193
  ruby_curl_multi *rbcm;
190
194
 
191
195
  Data_Get_Struct(self, ruby_curl_multi, rbcm);
192
- curl_multi_setopt(rbcm->handle, CURLMOPT_MAXCONNECTS, NUM2INT(count));
196
+
197
+ if (!rbcm->handle) {
198
+ rbcm->handle = curl_multi_init();
199
+ if (!rbcm->handle) {
200
+ rb_raise(mCurlErrFailedInit, "Failed to initialize multi handle");
201
+ }
202
+ }
203
+
204
+ curl_multi_setopt(rbcm->handle, CURLMOPT_MAXCONNECTS, NUM2LONG(count));
193
205
  #endif
194
206
 
195
207
  return count;
@@ -200,20 +212,39 @@ static VALUE ruby_curl_multi_max_connects(VALUE self, VALUE count) {
200
212
  * multi = Curl::Multi.new
201
213
  * multi.pipeline = true
202
214
  *
203
- * Pass a long set to 1 to enable or 0 to disable. Enabling pipelining on a multi handle will make it
204
- * attempt to perform HTTP Pipelining as far as possible for transfers using this handle. This means
205
- * that if you add a second request that can use an already existing connection, the second request will
206
- * be "piped" on the same connection rather than being executed in parallel. (Added in 7.16.0)
215
+ * Pass a long set to 1 for HTTP/1.1 pipelining, 2 for HTTP/2 multiplexing, or 0 to disable.
216
+ * Enabling pipelining on a multi handle will make it attempt to perform HTTP Pipelining as
217
+ * far as possible for transfers using this handle. This means that if you add a second request
218
+ * that can use an already existing connection, the second request will be "piped" on the same
219
+ * connection rather than being executed in parallel. (Added in 7.16.0, multiplex added in 7.43.0)
207
220
  *
208
221
  */
209
- static VALUE ruby_curl_multi_pipeline(VALUE self, VALUE onoff) {
222
+ static VALUE ruby_curl_multi_pipeline(VALUE self, VALUE method) {
210
223
  #ifdef HAVE_CURLMOPT_PIPELINING
211
224
  ruby_curl_multi *rbcm;
212
225
 
226
+ long value;
227
+
228
+ if (method == Qtrue) {
229
+ value = 1;
230
+ } else if (method == Qfalse) {
231
+ value = 0;
232
+ } else {
233
+ value = NUM2LONG(method);
234
+ }
235
+
213
236
  Data_Get_Struct(self, ruby_curl_multi, rbcm);
214
- curl_multi_setopt(rbcm->handle, CURLMOPT_PIPELINING, onoff == Qtrue ? 1 : 0);
237
+
238
+ if (!rbcm->handle) {
239
+ rbcm->handle = curl_multi_init();
240
+ if (!rbcm->handle) {
241
+ rb_raise(mCurlErrFailedInit, "Failed to initialize multi handle");
242
+ }
243
+ }
244
+
245
+ curl_multi_setopt(rbcm->handle, CURLMOPT_PIPELINING, value);
215
246
  #endif
216
- return onoff;
247
+ return method == Qtrue ? 1 : 0;
217
248
  }
218
249
 
219
250
  /*
@@ -235,7 +266,7 @@ VALUE ruby_curl_multi_add(VALUE self, VALUE easy) {
235
266
  Data_Get_Struct(easy, ruby_curl_easy, rbce);
236
267
 
237
268
  // check if this curl handle has been added before adding again
238
- r = rb_hash_aref(rbcm->requests, INT2NUM((int)rbce->curl));
269
+ r = rb_hash_aref(rbcm->requests, LONG2NUM((long)rbce->curl));
239
270
  if ( r != Qnil ) {
240
271
  return Qnil;
241
272
  }
@@ -243,6 +274,13 @@ VALUE ruby_curl_multi_add(VALUE self, VALUE easy) {
243
274
  /* setup the easy handle */
244
275
  ruby_curl_easy_setup( rbce );
245
276
 
277
+ if (!rbcm->handle) {
278
+ rbcm->handle = curl_multi_init();
279
+ if (!rbcm->handle) {
280
+ rb_raise(mCurlErrFailedInit, "Failed to initialize multi handle");
281
+ }
282
+ }
283
+
246
284
  mcode = curl_multi_add_handle(rbcm->handle, rbce->curl);
247
285
  if (mcode != CURLM_CALL_MULTI_PERFORM && mcode != CURLM_OK) {
248
286
  raise_curl_multi_error_exception(mcode);
@@ -254,7 +292,10 @@ VALUE ruby_curl_multi_add(VALUE self, VALUE easy) {
254
292
  * If this number is not correct, the next call to curl_multi_perform will correct it. */
255
293
  rbcm->running++;
256
294
 
257
- rb_hash_aset( rbcm->requests, INT2NUM((int)rbce->curl), easy );
295
+ /* track a reference to associated multi handle */
296
+ rbce->multi = self;
297
+
298
+ rb_hash_aset( rbcm->requests, LONG2NUM((long)rbce->curl), easy );
258
299
 
259
300
  return self;
260
301
  }
@@ -278,6 +319,13 @@ VALUE ruby_curl_multi_remove(VALUE self, VALUE easy) {
278
319
 
279
320
  Data_Get_Struct(self, ruby_curl_multi, rbcm);
280
321
 
322
+ if (!rbcm->handle) {
323
+ rbcm->handle = curl_multi_init();
324
+ if (!rbcm->handle) {
325
+ rb_raise(mCurlErrFailedInit, "Failed to initialize multi handle");
326
+ }
327
+ }
328
+
281
329
  rb_curl_multi_remove(rbcm,easy);
282
330
 
283
331
  return self;
@@ -290,7 +338,7 @@ static void rb_curl_multi_remove(ruby_curl_multi *rbcm, VALUE easy) {
290
338
  Data_Get_Struct(easy, ruby_curl_easy, rbce);
291
339
 
292
340
  // check if this curl handle has been added before removing
293
- r = rb_hash_aref(rbcm->requests, INT2NUM((int)rbce->curl));
341
+ r = rb_hash_aref(rbcm->requests, LONG2NUM((long)rbce->curl));
294
342
  if ( r == Qnil ) {
295
343
  return;
296
344
  }
@@ -304,8 +352,8 @@ static void rb_curl_multi_remove(ruby_curl_multi *rbcm, VALUE easy) {
304
352
 
305
353
  ruby_curl_easy_cleanup( easy, rbce );
306
354
 
307
- // active should equal INT2FIX(RHASH(rbcm->requests)->tbl->num_entries)
308
- r = rb_hash_delete( rbcm->requests, INT2NUM((int)rbce->curl) );
355
+ // active should equal LONG2NUM(RHASH(rbcm->requests)->tbl->num_entries)
356
+ r = rb_hash_delete( rbcm->requests, LONG2NUM((long)rbce->curl) );
309
357
  if( r != easy || r == Qnil ) {
310
358
  rb_warn("Possibly lost track of Curl::Easy VALUE, it may not be reclaimed by GC");
311
359
  }
@@ -328,6 +376,13 @@ static VALUE ruby_curl_multi_cancel(VALUE self) {
328
376
  ruby_curl_multi *rbcm;
329
377
 
330
378
  Data_Get_Struct(self, ruby_curl_multi, rbcm);
379
+
380
+ if (!rbcm->handle) {
381
+ rbcm->handle = curl_multi_init();
382
+ if (!rbcm->handle) {
383
+ rb_raise(mCurlErrFailedInit, "Failed to initialize multi handle");
384
+ }
385
+ }
331
386
 
332
387
  rb_hash_foreach( rbcm->requests, ruby_curl_multi_cancel_callback, (VALUE)rbcm );
333
388
 
@@ -450,10 +505,11 @@ static void rb_curl_multi_run(VALUE self, CURLM *multi_handle, int *still_runnin
450
505
  mcode = curl_multi_perform(multi_handle, still_running);
451
506
  } while (mcode == CURLM_CALL_MULTI_PERFORM);
452
507
 
508
+
453
509
  if (mcode != CURLM_OK) {
454
510
  raise_curl_multi_error_exception(mcode);
455
511
  }
456
-
512
+
457
513
  }
458
514
 
459
515
  #ifdef _WIN32
@@ -517,7 +573,7 @@ static VALUE curb_select(void *args) {
517
573
  VALUE ruby_curl_multi_perform(int argc, VALUE *argv, VALUE self) {
518
574
  CURLMcode mcode;
519
575
  ruby_curl_multi *rbcm;
520
- int maxfd, rc;
576
+ int maxfd, rc = -1;
521
577
  fd_set fdread, fdwrite, fdexcep;
522
578
  #ifdef _WIN32
523
579
  fd_set crt_fdread, crt_fdwrite, crt_fdexcep;
@@ -627,7 +683,15 @@ VALUE ruby_curl_multi_perform(int argc, VALUE *argv, VALUE self) {
627
683
 
628
684
  rb_curl_multi_read_info( self, rbcm->handle );
629
685
  if (block != Qnil) { rb_funcall(block, rb_intern("call"), 1, self); }
630
-
686
+
687
+ /* do early cleanup */
688
+ VALUE hash = rbcm->requests;
689
+ if (!NIL_P(hash) && rb_type(hash) == T_HASH && RHASH_SIZE(hash) > 0) {
690
+ rb_hash_foreach(hash, curl_multi_flush_easy, (VALUE)rbcm);
691
+ }
692
+ curl_multi_cleanup(rbcm->handle);
693
+ rbcm->handle = NULL;
694
+
631
695
  return Qtrue;
632
696
  }
633
697
 
@@ -646,7 +710,7 @@ void init_curb_multi() {
646
710
  rb_define_method(cCurlMulti, "requests", ruby_curl_multi_requests, 0);
647
711
  rb_define_method(cCurlMulti, "idle?", ruby_curl_multi_idle, 0);
648
712
 
649
- /* Instnace methods */
713
+ /* Instance methods */
650
714
  rb_define_method(cCurlMulti, "max_connects=", ruby_curl_multi_max_connects, 1);
651
715
  rb_define_method(cCurlMulti, "pipeline=", ruby_curl_multi_pipeline, 1);
652
716
  rb_define_method(cCurlMulti, "add", ruby_curl_multi_add, 1);
@@ -56,7 +56,7 @@ VALUE ruby_curl_upload_stream_get(VALUE self) {
56
56
  VALUE ruby_curl_upload_offset_set(VALUE self, VALUE offset) {
57
57
  ruby_curl_upload *rbcu;
58
58
  Data_Get_Struct(self, ruby_curl_upload, rbcu);
59
- rbcu->offset = FIX2LONG(offset);
59
+ rbcu->offset = NUM2LONG(offset);
60
60
  return offset;
61
61
  }
62
62
  /*
@@ -66,7 +66,7 @@ VALUE ruby_curl_upload_offset_set(VALUE self, VALUE offset) {
66
66
  VALUE ruby_curl_upload_offset_get(VALUE self) {
67
67
  ruby_curl_upload *rbcu;
68
68
  Data_Get_Struct(self, ruby_curl_upload, rbcu);
69
- return INT2FIX(rbcu->offset);
69
+ return LONG2NUM(rbcu->offset);
70
70
  }
71
71
 
72
72
  /* =================== INIT LIB =====================*/
@@ -321,6 +321,9 @@ have_constant "curl_sslversion_default"
321
321
  have_constant :CURL_SSLVERSION_TLSv1
322
322
  have_constant :CURL_SSLVERSION_SSLv2
323
323
  have_constant :CURL_SSLVERSION_SSLv3
324
+ have_constant :CURL_SSLVERSION_TLSv1_0
325
+ have_constant :CURL_SSLVERSION_TLSv1_1
326
+ have_constant :CURL_SSLVERSION_TLSv1_2
324
327
  have_constant "curlopt_ssl_verifypeer"
325
328
  have_constant "curlopt_cainfo"
326
329
  have_constant "curlopt_issuercert"
@@ -6,7 +6,7 @@ module Curl
6
6
  alias body body_str
7
7
  alias head header_str
8
8
 
9
- class Error < Exception
9
+ class Error < StandardError
10
10
  attr_accessor :message, :code
11
11
  def initialize(code, msg)
12
12
  self.message = msg
@@ -20,7 +20,7 @@ module Curl
20
20
  #
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
- statuses = self.header_str.scan(/HTTP\/\d\.\d\s(\d+\s.+)\r\n/).map{ |match| match[0] }
23
+ statuses = self.header_str.scan(/HTTP\/\d\.\d\s(\d+\s.*)\r\n/).map{ |match| match[0] }
24
24
  statuses.last.strip
25
25
  end
26
26
 
@@ -22,7 +22,7 @@ module Curl
22
22
  # {:url => 'url2', :post_fields => {'field1' => 'value1', 'field2' => 'value2'}},
23
23
  # {:url => 'url3', :post_fields => {'field1' => 'value1', 'field2' => 'value2'}}],
24
24
  # { :follow_location => true, :multipart_form_post => true },
25
- # {:pipeline => true }) do|easy|
25
+ # {:pipeline => Curl::CURLPIPE_HTTP1}) do|easy|
26
26
  # easy_handle_on_request_complete
27
27
  # end
28
28
  #
@@ -46,7 +46,7 @@ module Curl
46
46
  # {:url => 'url2', :put_data => IO.read('filepath')},
47
47
  # {:url => 'url3', :put_data => "maybe another string or socket?"],
48
48
  # {:follow_location => true},
49
- # {:pipeline => true }) do|easy|
49
+ # {:pipeline => Curl::CURLPIPE_HTTP1}) do|easy|
50
50
  # easy_handle_on_request_complete
51
51
  # end
52
52
  #
@@ -74,7 +74,7 @@ module Curl
74
74
  # :follow_location => true, :max_redirects => 3 },
75
75
  # { :url => 'url3', :method => :put, :put_data => File.open('file.txt','rb') },
76
76
  # { :url => 'url4', :method => :head }
77
- # ], {:pipeline => true})
77
+ # ], {:pipeline => Curl::CURLPIPE_HTTP1})
78
78
  #
79
79
  # Blocking call to issue multiple HTTP requests with varying verb's.
80
80
  #
@@ -109,8 +109,12 @@ class TestCurbCurlMulti < Test::Unit::TestCase
109
109
 
110
110
  assert(m.idle?, 'A new Curl::Multi handle should be idle')
111
111
 
112
+ assert_nil e.multi
113
+
112
114
  m.add(e)
113
115
 
116
+ assert_not_nil e.multi
117
+
114
118
  assert((not m.idle?), 'A Curl::Multi handle with a request should not be idle')
115
119
 
116
120
  m.perform
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.1
4
+ version: 0.9.2
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: 2016-01-08 00:00:00.000000000 Z
12
+ date: 2016-04-10 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
@@ -70,7 +70,8 @@ files:
70
70
  - tests/timeout_server.rb
71
71
  - tests/unittests.rb
72
72
  homepage: http://curb.rubyforge.org/
73
- licenses: []
73
+ licenses:
74
+ - MIT
74
75
  metadata: {}
75
76
  post_install_message:
76
77
  rdoc_options: