curb 0.9.1 → 0.9.2

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