curb 0.6.9 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of curb might be problematic. Click here for more details.

data/ext/curb.c CHANGED
@@ -255,6 +255,10 @@ void Init_curb_core() {
255
255
  /* Passed to on_debug handler to indicate that the data is protocol data sent to the peer. */
256
256
  rb_define_const(mCurl, "CURLINFO_DATA_OUT", INT2FIX(CURLINFO_DATA_OUT));
257
257
 
258
+ rb_define_const(mCurl, "CURL_MULTICWD", INT2FIX(CURLFTPMETHOD_MULTICWD));
259
+ rb_define_const(mCurl, "CURL_NOCWD", INT2FIX(CURLFTPMETHOD_NOCWD));
260
+ rb_define_const(mCurl, "CURL_SINGLECWD", INT2FIX(CURLFTPMETHOD_SINGLECWD));
261
+
258
262
  /* When passed to Curl::Easy#proxy_type , indicates that the proxy is an HTTP proxy. (libcurl >= 7.10) */
259
263
  #ifdef HAVE_CURLPROXY_HTTP
260
264
  rb_define_const(mCurl, "CURLPROXY_HTTP", INT2FIX(CURLPROXY_HTTP));
@@ -262,6 +266,28 @@ void Init_curb_core() {
262
266
  rb_define_const(mCurl, "CURLPROXY_HTTP", INT2FIX(-1));
263
267
  #endif
264
268
 
269
+ #ifdef CURL_VERSION_SSL
270
+ rb_define_const(mCurl, "CURL_SSLVERSION_DEFAULT", INT2FIX(CURL_SSLVERSION_DEFAULT));
271
+ rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1", INT2FIX(CURL_SSLVERSION_TLSv1));
272
+ rb_define_const(mCurl, "CURL_SSLVERSION_SSLv2", INT2FIX(CURL_SSLVERSION_SSLv2));
273
+ rb_define_const(mCurl, "CURL_SSLVERSION_SSLv3", INT2FIX(CURL_SSLVERSION_SSLv3));
274
+
275
+ rb_define_const(mCurl, "CURL_USESSL_CONTROL", INT2FIX(CURB_FTPSSL_CONTROL));
276
+ rb_define_const(mCurl, "CURL_USESSL_NONE", INT2FIX(CURB_FTPSSL_NONE));
277
+ rb_define_const(mCurl, "CURL_USESSL_TRY", INT2FIX(CURB_FTPSSL_TRY));
278
+ rb_define_const(mCurl, "CURL_USESSL_ALL", INT2FIX(CURB_FTPSSL_ALL));
279
+ #else
280
+ rb_define_const(mCurl, "CURL_SSLVERSION_DEFAULT", INT2FIX(-1));
281
+ rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1", INT2FIX(-1));
282
+ rb_define_const(mCurl, "CURL_SSLVERSION_SSLv2", INT2FIX(-1));
283
+ rb_define_const(mCurl, "CURL_SSLVERSION_SSLv3", INT2FIX(-1));
284
+
285
+ rb_define_const(mCurl, "CURL_USESSL_CONTROL", INT2FIX(-1));
286
+ rb_define_const(mCurl, "CURL_USESSL_NONE", INT2FIX(-1));
287
+ rb_define_const(mCurl, "CURL_USESSL_TRY", INT2FIX(-1));
288
+ rb_define_const(mCurl, "CURL_USESSL_ALL", INT2FIX(-1));
289
+ #endif
290
+
265
291
  /* When passed to Curl::Easy#proxy_type , indicates that the proxy is a SOCKS4 proxy. (libcurl >= 7.15.2) */
266
292
  #ifdef HAVE_CURLPROXY_SOCKS4
267
293
  rb_define_const(mCurl, "CURLPROXY_SOCKS4", INT2FIX(CURLPROXY_SOCKS4));
data/ext/curb.h CHANGED
@@ -20,11 +20,11 @@
20
20
  #include "curb_macros.h"
21
21
 
22
22
  // These should be managed from the Rake 'release' task.
23
- #define CURB_VERSION "0.6.9"
24
- #define CURB_VER_NUM 690
23
+ #define CURB_VERSION "0.7.0"
24
+ #define CURB_VER_NUM 700
25
25
  #define CURB_VER_MAJ 0
26
- #define CURB_VER_MIN 6
27
- #define CURB_VER_MIC 9
26
+ #define CURB_VER_MIN 7
27
+ #define CURB_VER_MIC 0
28
28
  #define CURB_VER_PATCH 0
29
29
 
30
30
 
@@ -141,6 +141,11 @@ void curl_easy_free(ruby_curl_easy *rbce) {
141
141
  if (rbce->curl_headers) {
142
142
  curl_slist_free_all(rbce->curl_headers);
143
143
  }
144
+
145
+ if (rbce->curl_ftp_commands) {
146
+ curl_slist_free_all(rbce->curl_ftp_commands);
147
+ }
148
+
144
149
  curl_easy_cleanup(rbce->curl);
145
150
  free(rbce);
146
151
  }
@@ -176,6 +181,7 @@ static VALUE ruby_curl_easy_new(int argc, VALUE *argv, VALUE klass) {
176
181
  rb_easy_set("url", url);
177
182
 
178
183
  rbce->curl_headers = NULL;
184
+ rbce->curl_ftp_commands = NULL;
179
185
 
180
186
  /* various-typed opts */
181
187
  rbce->local_port = 0;
@@ -189,6 +195,9 @@ static VALUE ruby_curl_easy_new(int argc, VALUE *argv, VALUE klass) {
189
195
  rbce->connect_timeout = 0;
190
196
  rbce->dns_cache_timeout = 60;
191
197
  rbce->ftp_response_timeout = 0;
198
+ rbce->ssl_version = -1;
199
+ rbce->use_ssl = -1;
200
+ rbce->ftp_filemethod = -1;
192
201
 
193
202
  /* bool opts */
194
203
  rbce->proxy_tunnel = 0;
@@ -235,6 +244,7 @@ static VALUE ruby_curl_easy_clone(VALUE self) {
235
244
  memcpy(newrbce, rbce, sizeof(ruby_curl_easy));
236
245
  newrbce->curl = curl_easy_duphandle(rbce->curl);
237
246
  newrbce->curl_headers = NULL;
247
+ newrbce->curl_ftp_commands = NULL;
238
248
 
239
249
  return Data_Wrap_Struct(cCurlEasy, curl_easy_mark, curl_easy_free, newrbce);
240
250
  }
@@ -256,7 +266,7 @@ static VALUE ruby_curl_easy_url_set(VALUE self, VALUE url) {
256
266
 
257
267
  /*
258
268
  * call-seq:
259
- * easy.url => "http://some.url/"
269
+ * easy.url => string
260
270
  *
261
271
  * Obtain the URL that will be used by subsequent calls to +perform+.
262
272
  */
@@ -266,7 +276,7 @@ static VALUE ruby_curl_easy_url_get(VALUE self) {
266
276
 
267
277
  /*
268
278
  * call-seq:
269
- * easy.proxy_url = "some.url" => "some.url"
279
+ * easy.proxy_url = string => string
270
280
  *
271
281
  * Set the URL of the HTTP proxy to use for subsequent calls to +perform+.
272
282
  * The URL should specify the the host name or dotted IP address. To specify
@@ -295,7 +305,7 @@ static VALUE ruby_curl_easy_proxy_url_set(VALUE self, VALUE proxy_url) {
295
305
 
296
306
  /*
297
307
  * call-seq:
298
- * easy.proxy_url => "some.url"
308
+ * easy.proxy_url => string
299
309
  *
300
310
  * Obtain the HTTP Proxy URL that will be used by subsequent calls to +perform+.
301
311
  */
@@ -305,8 +315,8 @@ static VALUE ruby_curl_easy_proxy_url_get(VALUE self) {
305
315
 
306
316
  /*
307
317
  * call-seq:
308
- * easy.headers = "Header: val" => ["Header: val", ...]
309
- * easy.headers = {"Header" => "val" ..., "Header" => "val"} => ["Header: val", ...]
318
+ * easy.headers = "Header: val" => "Header: val"
319
+ * easy.headers = {"Header" => "val" ..., "Header" => "val"} => {"Header: val", ...}
310
320
  * easy.headers = ["Header: val" ..., "Header: val"] => ["Header: val", ...]
311
321
  *
312
322
  * Set custom HTTP headers for following requests. This can be used to add
@@ -331,7 +341,7 @@ static VALUE ruby_curl_easy_headers_set(VALUE self, VALUE headers) {
331
341
 
332
342
  /*
333
343
  * call-seq:
334
- * easy.headers => Hash, Array or Str
344
+ * easy.headers => Hash, Array or Str
335
345
  *
336
346
  * Obtain the custom HTTP headers for following requests.
337
347
  */
@@ -346,7 +356,7 @@ static VALUE ruby_curl_easy_headers_get(VALUE self) {
346
356
 
347
357
  /*
348
358
  * call-seq:
349
- * easy.interface = "interface" => "interface"
359
+ * easy.interface = string => string
350
360
  *
351
361
  * Set the interface name to use as the outgoing network interface.
352
362
  * The name can be an interface name, an IP address or a host name.
@@ -357,7 +367,7 @@ static VALUE ruby_curl_easy_interface_set(VALUE self, VALUE interface_hm) {
357
367
 
358
368
  /*
359
369
  * call-seq:
360
- * easy.interface => "interface"
370
+ * easy.interface => string
361
371
  *
362
372
  * Obtain the interface name that is used as the outgoing network interface.
363
373
  * The name can be an interface name, an IP address or a host name.
@@ -368,7 +378,7 @@ static VALUE ruby_curl_easy_interface_get(VALUE self) {
368
378
 
369
379
  /*
370
380
  * call-seq:
371
- * easy.userpwd = "pwd string" => "pwd string"
381
+ * easy.userpwd = string => string
372
382
  *
373
383
  * Set the username/password string to use for subsequent calls to +perform+.
374
384
  * The supplied string should have the form "username:password"
@@ -379,7 +389,7 @@ static VALUE ruby_curl_easy_userpwd_set(VALUE self, VALUE userpwd) {
379
389
 
380
390
  /*
381
391
  * call-seq:
382
- * easy.userpwd => "pwd string"
392
+ * easy.userpwd => string
383
393
  *
384
394
  * Obtain the username/password string that will be used for subsequent
385
395
  * calls to +perform+.
@@ -390,7 +400,7 @@ static VALUE ruby_curl_easy_userpwd_get(VALUE self) {
390
400
 
391
401
  /*
392
402
  * call-seq:
393
- * easy.proxypwd = "pwd string" => "pwd string"
403
+ * easy.proxypwd = string => string
394
404
  *
395
405
  * Set the username/password string to use for proxy connection during
396
406
  * subsequent calls to +perform+. The supplied string should have the
@@ -402,7 +412,7 @@ static VALUE ruby_curl_easy_proxypwd_set(VALUE self, VALUE proxypwd) {
402
412
 
403
413
  /*
404
414
  * call-seq:
405
- * easy.proxypwd => "pwd string"
415
+ * easy.proxypwd => string
406
416
  *
407
417
  * Obtain the username/password string that will be used for proxy
408
418
  * connection during subsequent calls to +perform+. The supplied string
@@ -415,7 +425,7 @@ static VALUE ruby_curl_easy_proxypwd_get(VALUE self) {
415
425
 
416
426
  /*
417
427
  * call-seq:
418
- * easy.cookies = "name1=content1; name2=content2;" => "pwd string"
428
+ * easy.cookies = "name1=content1; name2=content2;" => string
419
429
  *
420
430
  * Set cookies to be sent by this Curl::Easy instance. The format of the string should
421
431
  * be NAME=CONTENTS, where NAME is the cookie name and CONTENTS is what the cookie should contain.
@@ -427,7 +437,7 @@ static VALUE ruby_curl_easy_cookies_set(VALUE self, VALUE cookies) {
427
437
 
428
438
  /*
429
439
  * call-seq:
430
- * easy.cookies => "name1=content1; name2=content2;"
440
+ * easy.cookies => "name1=content1; name2=content2;"
431
441
  *
432
442
  * Obtain the cookies for this Curl::Easy instance.
433
443
  */
@@ -437,7 +447,7 @@ static VALUE ruby_curl_easy_cookies_get(VALUE self) {
437
447
 
438
448
  /*
439
449
  * call-seq:
440
- * easy.cookiefile = "cookies.txt" => "pwd string"
450
+ * easy.cookiefile = string => string
441
451
  *
442
452
  * Set a file that contains cookies to be sent in subsequent requests by this Curl::Easy instance.
443
453
  *
@@ -450,7 +460,7 @@ static VALUE ruby_curl_easy_cookiefile_set(VALUE self, VALUE cookiefile) {
450
460
 
451
461
  /*
452
462
  * call-seq:
453
- * easy.cookiefile => "cookies.txt"
463
+ * easy.cookiefile => string
454
464
  *
455
465
  * Obtain the cookiefile file for this Curl::Easy instance.
456
466
  */
@@ -460,7 +470,7 @@ static VALUE ruby_curl_easy_cookiefile_get(VALUE self) {
460
470
 
461
471
  /*
462
472
  * call-seq:
463
- * easy.cookiejar = "cookiejar.file" => "pwd string"
473
+ * easy.cookiejar = string => string
464
474
  *
465
475
  * Set a cookiejar file to use for this Curl::Easy instance.
466
476
  * Cookies from the response will be written into this file.
@@ -474,7 +484,7 @@ static VALUE ruby_curl_easy_cookiejar_set(VALUE self, VALUE cookiejar) {
474
484
 
475
485
  /*
476
486
  * call-seq:
477
- * easy.cookiejar => "cookiejar.file"
487
+ * easy.cookiejar => string
478
488
  *
479
489
  * Obtain the cookiejar file to use for this Curl::Easy instance.
480
490
  */
@@ -484,7 +494,7 @@ static VALUE ruby_curl_easy_cookiejar_get(VALUE self) {
484
494
 
485
495
  /*
486
496
  * call-seq:
487
- * easy.cert = "cert.file" => ""
497
+ * easy.cert = string => ""
488
498
  *
489
499
  * Set a cert file to use for this Curl::Easy instance. This file
490
500
  * will be used to validate SSL connections.
@@ -496,7 +506,7 @@ static VALUE ruby_curl_easy_cert_set(VALUE self, VALUE cert) {
496
506
 
497
507
  /*
498
508
  * call-seq:
499
- * easy.cert => "cert.file"
509
+ * easy.cert => string
500
510
  *
501
511
  * Obtain the cert file to use for this Curl::Easy instance.
502
512
  */
@@ -528,7 +538,7 @@ static VALUE ruby_curl_easy_cert_key_get(VALUE self) {
528
538
 
529
539
  /*
530
540
  * call-seq:
531
- * easy.cacert = "cacert.file" => ""
541
+ * easy.cacert = string => ""
532
542
  *
533
543
  * Set a cacert bundle to use for this Curl::Easy instance. This file
534
544
  * will be used to validate SSL certificates.
@@ -540,7 +550,7 @@ static VALUE ruby_curl_easy_cacert_set(VALUE self, VALUE cacert) {
540
550
 
541
551
  /*
542
552
  * call-seq:
543
- * easy.cacert => "cacert.file"
553
+ * easy.cacert => string
544
554
  *
545
555
  * Obtain the cacert file to use for this Curl::Easy instance.
546
556
  */
@@ -550,7 +560,7 @@ static VALUE ruby_curl_easy_cacert_get(VALUE self) {
550
560
 
551
561
  /*
552
562
  * call-seq:
553
- * easy.certpassword = "cert password" => ""
563
+ * easy.certpassword = string => ""
554
564
  *
555
565
  * Set a password used to open the specified cert
556
566
  */
@@ -572,7 +582,7 @@ static VALUE ruby_curl_easy_certtype_set(VALUE self, VALUE certtype) {
572
582
 
573
583
  /*
574
584
  * call-seq:
575
- * easy.certtype => "cert.type"
585
+ * easy.certtype => string
576
586
  *
577
587
  * Obtain the cert type used for this Curl::Easy instance
578
588
  */
@@ -582,7 +592,7 @@ static VALUE ruby_curl_easy_certtype_get(VALUE self) {
582
592
 
583
593
  /*
584
594
  * call-seq:
585
- * easy.encoding= => "string"
595
+ * easy.encoding = string => string
586
596
  *
587
597
  * Set the accepted encoding types, curl will handle all of the decompression
588
598
  *
@@ -592,7 +602,7 @@ static VALUE ruby_curl_easy_encoding_set(VALUE self, VALUE encoding) {
592
602
  }
593
603
  /*
594
604
  * call-seq:
595
- * easy.encoding => "string"
605
+ * easy.encoding => string
596
606
  *
597
607
  * Get the set encoding types
598
608
  *
@@ -603,7 +613,7 @@ static VALUE ruby_curl_easy_encoding_get(VALUE self) {
603
613
 
604
614
  /*
605
615
  * call-seq:
606
- * easy.useragent = "Ruby/Curb" => ""
616
+ * easy.useragent = "Ruby/Curb" => ""
607
617
  *
608
618
  * Set the user agent string for this Curl::Easy instance
609
619
  *
@@ -624,7 +634,7 @@ static VALUE ruby_curl_easy_useragent_get(VALUE self) {
624
634
 
625
635
  /*
626
636
  * call-seq:
627
- * easy.post_body = "some=form%20data&to=send" => string or nil
637
+ * easy.post_body = "some=form%20data&to=send" => string or nil
628
638
  *
629
639
  * Sets the POST body of this Curl::Easy instance. This is expected to be
630
640
  * URL encoded; no additional processing or encoding is done on the string.
@@ -668,7 +678,7 @@ static VALUE ruby_curl_easy_post_body_set(VALUE self, VALUE post_body) {
668
678
 
669
679
  /*
670
680
  * call-seq:
671
- * easy.post_body => "string" or nil
681
+ * easy.post_body => string or nil
672
682
  *
673
683
  * Obtain the POST body used in this Curl::Easy instance.
674
684
  */
@@ -748,6 +758,24 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
748
758
  return data;
749
759
  }
750
760
 
761
+ /*
762
+ * call-seq:
763
+ * easy.ftp_commands = ["CWD /", "MKD directory"] => ["CWD /", ...]
764
+ *
765
+ * Explicitly sets the list of commands to execute on the FTP server when calling perform
766
+ */
767
+ static VALUE ruby_curl_easy_ftp_commands_set(VALUE self, VALUE ftp_commands) {
768
+ CURB_OBJECT_HSETTER(ruby_curl_easy, ftp_commands);
769
+ }
770
+
771
+ /*
772
+ * call-seq
773
+ * easy.ftp_commands => array or nil
774
+ */
775
+ static VALUE ruby_curl_easy_ftp_commands_get(VALUE self) {
776
+ CURB_OBJECT_HGETTER(ruby_curl_easy, ftp_commands);
777
+ }
778
+
751
779
  /* ================== IMMED ATTRS ==================*/
752
780
 
753
781
  /*
@@ -1073,7 +1101,7 @@ static VALUE ruby_curl_easy_ftp_response_timeout_get(VALUE self, VALUE ftp_respo
1073
1101
 
1074
1102
  /*
1075
1103
  * call-seq:
1076
- * easy.username = "foo" => String
1104
+ * easy.username = string => string
1077
1105
  *
1078
1106
  * Set the HTTP Authentication username.
1079
1107
  */
@@ -1087,7 +1115,7 @@ static VALUE ruby_curl_easy_username_set(VALUE self, VALUE username) {
1087
1115
 
1088
1116
  /*
1089
1117
  * call-seq:
1090
- * easy.username => String
1118
+ * easy.username => string
1091
1119
  *
1092
1120
  * Get the current username
1093
1121
  */
@@ -1101,7 +1129,7 @@ static VALUE ruby_curl_easy_username_get(VALUE self, VALUE username) {
1101
1129
 
1102
1130
  /*
1103
1131
  * call-seq:
1104
- * easy.password = "foo" => String
1132
+ * easy.password = string => string
1105
1133
  *
1106
1134
  * Set the HTTP Authentication password.
1107
1135
  */
@@ -1115,7 +1143,7 @@ static VALUE ruby_curl_easy_password_set(VALUE self, VALUE password) {
1115
1143
 
1116
1144
  /*
1117
1145
  * call-seq:
1118
- * easy.password => String
1146
+ * easy.password => string
1119
1147
  *
1120
1148
  * Get the current password
1121
1149
  */
@@ -1127,11 +1155,75 @@ static VALUE ruby_curl_easy_password_get(VALUE self, VALUE password) {
1127
1155
  #endif
1128
1156
  }
1129
1157
 
1158
+ /*
1159
+ * call-seq:
1160
+ * easy.ssl_version = value => fixnum or nil
1161
+ *
1162
+ * Sets the version of SSL/TLS that libcurl will attempt to use. Valid
1163
+ * options are Curl::CURL_SSLVERSION_TLSv1, Curl::CURL_SSLVERSION::SSLv2,
1164
+ * Curl::CURL_SSLVERSION_SSLv3 and Curl::CURL_SSLVERSION_DEFAULT
1165
+ */
1166
+ static VALUE ruby_curl_easy_ssl_version_set(VALUE self, VALUE ssl_version) {
1167
+ CURB_IMMED_SETTER(ruby_curl_easy, ssl_version, -1);
1168
+ }
1169
+
1170
+ /*
1171
+ * call-seq:
1172
+ * easy.ssl_version => fixnum
1173
+ *
1174
+ * Get the version of SSL/TLS that libcurl will attempt to use.
1175
+ */
1176
+ static VALUE ruby_curl_easy_ssl_version_get(VALUE self, VALUE ssl_version) {
1177
+ CURB_IMMED_GETTER(ruby_curl_easy, ssl_version, -1);
1178
+ }
1179
+
1180
+ /*
1181
+ * call-seq:
1182
+ * easy.use_ssl = value => fixnum or nil
1183
+ *
1184
+ * Ensure libcurl uses SSL for FTP connections. Valid options are Curl::CURL_USESSL_NONE,
1185
+ * Curl::CURL_USESSL_TRY, Curl::CURL_USESSL_CONTROL, and Curl::CURL_USESSL_ALL.
1186
+ */
1187
+ static VALUE ruby_curl_easy_use_ssl_set(VALUE self, VALUE use_ssl) {
1188
+ CURB_IMMED_SETTER(ruby_curl_easy, use_ssl, -1);
1189
+ }
1190
+
1191
+ /*
1192
+ * call-seq:
1193
+ * easy.use_ssl => fixnum
1194
+ *
1195
+ * Get the desired level for using SSL on FTP connections.
1196
+ */
1197
+ static VALUE ruby_curl_easy_use_ssl_get(VALUE self, VALUE use_ssl) {
1198
+ CURB_IMMED_GETTER(ruby_curl_easy, use_ssl, -1);
1199
+ }
1200
+
1201
+ /*
1202
+ * call-seq:
1203
+ * easy.ftp_filemethod = value => fixnum or nil
1204
+ *
1205
+ * Controls how libcurl reaches files on the server. Valid options are Curl::CURL_MULTICWD,
1206
+ * Curl::CURL_NOCWD, and Curl::CURL_SINGLECWD (see libcurl docs for CURLOPT_FTP_METHOD).
1207
+ */
1208
+ static VALUE ruby_curl_easy_ftp_filemethod_set(VALUE self, VALUE ftp_filemethod) {
1209
+ CURB_IMMED_SETTER(ruby_curl_easy, ftp_filemethod, -1);
1210
+ }
1211
+
1212
+ /*
1213
+ * call-seq
1214
+ * easy.ftp_filemethod => fixnum
1215
+ *
1216
+ * Get the configuration for how libcurl will reach files on the server.
1217
+ */
1218
+ static VALUE ruby_curl_easy_ftp_filemethod_get(VALUE self, VALUE ftp_filemethod) {
1219
+ CURB_IMMED_GETTER(ruby_curl_easy, ftp_filemethod, -1);
1220
+ }
1221
+
1130
1222
  /* ================== BOOL ATTRS ===================*/
1131
1223
 
1132
1224
  /*
1133
1225
  * call-seq:
1134
- * proxy_tunnel = boolean => boolean
1226
+ * easy.proxy_tunnel = boolean => boolean
1135
1227
  *
1136
1228
  * Configure whether this Curl instance will use proxy tunneling.
1137
1229
  */
@@ -1141,7 +1233,7 @@ static VALUE ruby_curl_easy_proxy_tunnel_set(VALUE self, VALUE proxy_tunnel) {
1141
1233
 
1142
1234
  /*
1143
1235
  * call-seq:
1144
- * proxy_tunnel? => boolean
1236
+ * easy.proxy_tunnel? => boolean
1145
1237
  *
1146
1238
  * Determine whether this Curl instance will use proxy tunneling.
1147
1239
  */
@@ -1151,7 +1243,7 @@ static VALUE ruby_curl_easy_proxy_tunnel_q(VALUE self) {
1151
1243
 
1152
1244
  /*
1153
1245
  * call-seq:
1154
- * fetch_file_time = boolean => boolean
1246
+ * easy.fetch_file_time = boolean => boolean
1155
1247
  *
1156
1248
  * Configure whether this Curl instance will fetch remote file
1157
1249
  * times, if available.
@@ -1162,7 +1254,7 @@ static VALUE ruby_curl_easy_fetch_file_time_set(VALUE self, VALUE fetch_file_tim
1162
1254
 
1163
1255
  /*
1164
1256
  * call-seq:
1165
- * fetch_file_time? => boolean
1257
+ * easy.fetch_file_time? => boolean
1166
1258
  *
1167
1259
  * Determine whether this Curl instance will fetch remote file
1168
1260
  * times, if available.
@@ -1173,7 +1265,7 @@ static VALUE ruby_curl_easy_fetch_file_time_q(VALUE self) {
1173
1265
 
1174
1266
  /*
1175
1267
  * call-seq:
1176
- * ssl_verify_peer = boolean => boolean
1268
+ * easy.ssl_verify_peer = boolean => boolean
1177
1269
  *
1178
1270
  * Configure whether this Curl instance will verify the SSL peer
1179
1271
  * certificate. When true (the default), and the verification fails to
@@ -1191,7 +1283,7 @@ static VALUE ruby_curl_easy_ssl_verify_peer_set(VALUE self, VALUE ssl_verify_pee
1191
1283
 
1192
1284
  /*
1193
1285
  * call-seq:
1194
- * ssl_verify_peer? => boolean
1286
+ * easy.ssl_verify_peer? => boolean
1195
1287
  *
1196
1288
  * Determine whether this Curl instance will verify the SSL peer
1197
1289
  * certificate.
@@ -1202,7 +1294,7 @@ static VALUE ruby_curl_easy_ssl_verify_peer_q(VALUE self) {
1202
1294
 
1203
1295
  /*
1204
1296
  * call-seq:
1205
- * ssl_verify_host = boolean => boolean
1297
+ * easy.ssl_verify_host = boolean => boolean
1206
1298
  *
1207
1299
  * Configure whether this Curl instance will verify that the server cert
1208
1300
  * is for the server it is known as. When true (the default) the server
@@ -1219,7 +1311,7 @@ static VALUE ruby_curl_easy_ssl_verify_host_set(VALUE self, VALUE ssl_verify_hos
1219
1311
 
1220
1312
  /*
1221
1313
  * call-seq:
1222
- * ssl_verify_host? => boolean
1314
+ * easy.ssl_verify_host? => boolean
1223
1315
  *
1224
1316
  * Determine whether this Curl instance will verify that the server cert
1225
1317
  * is for the server it is known as.
@@ -1230,7 +1322,7 @@ static VALUE ruby_curl_easy_ssl_verify_host_q(VALUE self) {
1230
1322
 
1231
1323
  /*
1232
1324
  * call-seq:
1233
- * header_in_body = boolean => boolean
1325
+ * easy.header_in_body = boolean => boolean
1234
1326
  *
1235
1327
  * Configure whether this Curl instance will return HTTP headers
1236
1328
  * combined with body data. If this option is set true, both header
@@ -1242,7 +1334,7 @@ static VALUE ruby_curl_easy_header_in_body_set(VALUE self, VALUE header_in_body)
1242
1334
 
1243
1335
  /*
1244
1336
  * call-seq:
1245
- * header_in_body? => boolean
1337
+ * easy.header_in_body? => boolean
1246
1338
  *
1247
1339
  * Determine whether this Curl instance will verify the SSL peer
1248
1340
  * certificate.
@@ -1253,7 +1345,7 @@ static VALUE ruby_curl_easy_header_in_body_q(VALUE self) {
1253
1345
 
1254
1346
  /*
1255
1347
  * call-seq:
1256
- * use_netrc = boolean => boolean
1348
+ * easy.use_netrc = boolean => boolean
1257
1349
  *
1258
1350
  * Configure whether this Curl instance will use data from the user's
1259
1351
  * .netrc file for FTP connections.
@@ -1264,7 +1356,7 @@ static VALUE ruby_curl_easy_use_netrc_set(VALUE self, VALUE use_netrc) {
1264
1356
 
1265
1357
  /*
1266
1358
  * call-seq:
1267
- * use_netrc? => boolean
1359
+ * easy.use_netrc? => boolean
1268
1360
  *
1269
1361
  * Determine whether this Curl instance will use data from the user's
1270
1362
  * .netrc file for FTP connections.
@@ -1275,7 +1367,7 @@ static VALUE ruby_curl_easy_use_netrc_q(VALUE self) {
1275
1367
 
1276
1368
  /*
1277
1369
  * call-seq:
1278
- * follow_location = boolean => boolean
1370
+ * easy.follow_location = boolean => boolean
1279
1371
  *
1280
1372
  * Configure whether this Curl instance will follow Location: headers
1281
1373
  * in HTTP responses. Redirects will only be followed to the extent
@@ -1287,7 +1379,7 @@ static VALUE ruby_curl_easy_follow_location_set(VALUE self, VALUE follow_locatio
1287
1379
 
1288
1380
  /*
1289
1381
  * call-seq:
1290
- * follow_location? => boolean
1382
+ * easy.follow_location? => boolean
1291
1383
  *
1292
1384
  * Determine whether this Curl instance will follow Location: headers
1293
1385
  * in HTTP responses.
@@ -1298,7 +1390,7 @@ static VALUE ruby_curl_easy_follow_location_q(VALUE self) {
1298
1390
 
1299
1391
  /*
1300
1392
  * call-seq:
1301
- * unrestricted_auth = boolean => boolean
1393
+ * easy.unrestricted_auth = boolean => boolean
1302
1394
  *
1303
1395
  * Configure whether this Curl instance may use any HTTP authentication
1304
1396
  * method available when necessary.
@@ -1309,7 +1401,7 @@ static VALUE ruby_curl_easy_unrestricted_auth_set(VALUE self, VALUE unrestricted
1309
1401
 
1310
1402
  /*
1311
1403
  * call-seq:
1312
- * unrestricted_auth? => boolean
1404
+ * easy.unrestricted_auth? => boolean
1313
1405
  *
1314
1406
  * Determine whether this Curl instance may use any HTTP authentication
1315
1407
  * method available when necessary.
@@ -1383,7 +1475,7 @@ static VALUE ruby_curl_easy_enable_cookies_set(VALUE self, VALUE enable_cookies)
1383
1475
 
1384
1476
  /*
1385
1477
  * call-seq:
1386
- * easy.enable_cookies? => boolean
1478
+ * easy.enable_cookies? => boolean
1387
1479
  *
1388
1480
  * Determine whether the libcurl cookie engine is enabled for this
1389
1481
  * Curl::Easy instance.
@@ -1415,7 +1507,7 @@ static VALUE ruby_curl_easy_on_body_set(int argc, VALUE *argv, VALUE self) {
1415
1507
 
1416
1508
  /*
1417
1509
  * call-seq:
1418
- * easy.on_success { |easy| ... } => <old handler>
1510
+ * easy.on_success { |easy| ... } => <old handler>
1419
1511
  *
1420
1512
  * Assign or remove the +on_success+ handler for this Curl::Easy instance.
1421
1513
  * To remove a previously-supplied handler, call this method with no
@@ -1430,7 +1522,7 @@ static VALUE ruby_curl_easy_on_success_set(int argc, VALUE *argv, VALUE self) {
1430
1522
 
1431
1523
  /*
1432
1524
  * call-seq:
1433
- * easy.on_failure {|easy,code| ... } => <old handler>
1525
+ * easy.on_failure {|easy,code| ... } => <old handler>
1434
1526
  *
1435
1527
  * Assign or remove the +on_failure+ handler for this Curl::Easy instance.
1436
1528
  * To remove a previously-supplied handler, call this method with no
@@ -1445,7 +1537,7 @@ static VALUE ruby_curl_easy_on_failure_set(int argc, VALUE *argv, VALUE self) {
1445
1537
 
1446
1538
  /*
1447
1539
  * call-seq:
1448
- * easy.on_complete {|easy| ... } => <old handler>
1540
+ * easy.on_complete {|easy| ... } => <old handler>
1449
1541
  *
1450
1542
  * Assign or remove the +on_complete+ handler for this Curl::Easy instance.
1451
1543
  * To remove a previously-supplied handler, call this method with no
@@ -1547,6 +1639,16 @@ static VALUE cb_each_http_header(VALUE header, struct curl_slist **list) {
1547
1639
  return header_str;
1548
1640
  }
1549
1641
 
1642
+ /***********************************************
1643
+ * This is an rb_iterate callback used to set up ftp commands.
1644
+ */
1645
+ static VALUE cb_each_ftp_command(VALUE ftp_command, struct curl_slist **list) {
1646
+ VALUE ftp_command_string = rb_obj_as_string(ftp_command);
1647
+ *list = curl_slist_append(*list, StringValuePtr(ftp_command));
1648
+
1649
+ return ftp_command_string;
1650
+ }
1651
+
1550
1652
  /***********************************************
1551
1653
  *
1552
1654
  * Setup a connection
@@ -1558,6 +1660,7 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
1558
1660
  CURL *curl;
1559
1661
  VALUE url, _url = rb_easy_get("url");
1560
1662
  struct curl_slist **hdrs = &(rbce->curl_headers);
1663
+ struct curl_slist **cmds = &(rbce->curl_ftp_commands);
1561
1664
 
1562
1665
  curl = rbce->curl;
1563
1666
 
@@ -1782,7 +1885,25 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
1782
1885
  curl_easy_setopt(curl, CURLOPT_CAINFO, "/usr/local/share/curl/curl-ca-bundle.crt");
1783
1886
  #endif
1784
1887
  }
1888
+
1889
+ #ifdef CURL_VERSION_SSL
1890
+ if (rbce->ssl_version > 0) {
1891
+ curl_easy_setopt(curl, CURLOPT_SSLVERSION, rbce->ssl_version);
1892
+ }
1893
+
1894
+ if (rbce->use_ssl > 0) {
1895
+ curl_easy_setopt(curl, CURB_FTPSSL, rbce->use_ssl);
1896
+ }
1897
+ #else
1898
+ if (rbce->ssl_version > 0 || rbce->use_ssl > 0) {
1899
+ rb_warn("libcurl is not configured with SSL support");
1900
+ }
1901
+ #endif
1785
1902
 
1903
+ if (rbce->ftp_filemethod > 0) {
1904
+ curl_easy_setopt(curl, CURLOPT_FTP_FILEMETHOD, rbce->ftp_filemethod);
1905
+ }
1906
+
1786
1907
  /* Set the user-agent string if specified */
1787
1908
  if (!rb_easy_nil("useragent")) {
1788
1909
  curl_easy_setopt(curl, CURLOPT_USERAGENT, rb_easy_get_str("useragent"));
@@ -1804,6 +1925,17 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
1804
1925
  }
1805
1926
  }
1806
1927
 
1928
+ /* Setup FTP commands if necessary */
1929
+ if (!rb_easy_nil("ftp_commands")) {
1930
+ if (rb_easy_type_check("ftp_commands", T_ARRAY)) {
1931
+ rb_iterate(rb_each, rb_easy_get("ftp_commands"), cb_each_ftp_command, (VALUE)cmds);
1932
+ }
1933
+
1934
+ if (*cmds) {
1935
+ curl_easy_setopt(curl, CURLOPT_QUOTE, *cmds);
1936
+ }
1937
+ }
1938
+
1807
1939
  return Qnil;
1808
1940
  }
1809
1941
  /***********************************************
@@ -1822,6 +1954,12 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
1822
1954
  rbce->curl_headers = NULL;
1823
1955
  }
1824
1956
 
1957
+ struct curl_slist *ftp_commands = rbce->curl_ftp_commands;
1958
+ if (ftp_commands) {
1959
+ curl_slist_free_all(ftp_commands);
1960
+ rbce->curl_ftp_commands = NULL;
1961
+ }
1962
+
1825
1963
  // clean up a PUT request's curl options.
1826
1964
  if (!rb_easy_nil("upload")) {
1827
1965
  rb_easy_del("upload"); // set the upload object to Qnil to let the GC clean up
@@ -2192,6 +2330,28 @@ static VALUE ruby_curl_easy_response_code_get(VALUE self) {
2192
2330
  return LONG2NUM(code);
2193
2331
  }
2194
2332
 
2333
+ /*
2334
+ * call-seq:
2335
+ * easy.primary_ip => "xx.xx.xx.xx" or nil
2336
+ *
2337
+ * Retrieve the resolved IP of the most recent connection
2338
+ * done with this curl handle. This string may be IPv6 if
2339
+ * that's enabled.
2340
+ */
2341
+ static VALUE ruby_curl_easy_primary_ip_get(VALUE self) {
2342
+ ruby_curl_easy *rbce;
2343
+ char* ip;
2344
+
2345
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2346
+ curl_easy_getinfo(rbce->curl, CURLINFO_PRIMARY_IP, &ip);
2347
+
2348
+ if (ip && ip[0]) { // curl returns empty string if none
2349
+ return rb_str_new2(ip);
2350
+ } else {
2351
+ return Qnil;
2352
+ }
2353
+ }
2354
+
2195
2355
  /*
2196
2356
  * call-seq:
2197
2357
  * easy.http_connect_code => fixnum
@@ -2356,7 +2516,7 @@ static VALUE ruby_curl_easy_redirect_time_get(VALUE self) {
2356
2516
 
2357
2517
  /*
2358
2518
  * call-seq:
2359
- * easy.redirect_count => integer
2519
+ * easy.redirect_count => integer
2360
2520
  *
2361
2521
  * Retrieve the total number of redirections that were actually followed.
2362
2522
  *
@@ -2604,7 +2764,7 @@ static VALUE ruby_curl_easy_os_errno_get(VALUE self) {
2604
2764
 
2605
2765
  /*
2606
2766
  * call-seq:
2607
- * easy.num_connects => integer
2767
+ * easy.num_connects => integer
2608
2768
  *
2609
2769
  * Retrieve the number of new connections libcurl had to create to achieve
2610
2770
  * the previous transfer (only the successful connects are counted).
@@ -2649,7 +2809,7 @@ Pass a pointer to a long to receive the last socket used by this curl session. I
2649
2809
 
2650
2810
  /*
2651
2811
  * call-seq:
2652
- * easy.content_type => "content/type" or nil
2812
+ * easy.ftp_entry_path => "C:\ftp\root\" or nil
2653
2813
  *
2654
2814
  * Retrieve the path of the entry path. That is the initial path libcurl ended
2655
2815
  * up in when logging on to the remote FTP server. This returns +nil+ if
@@ -2678,7 +2838,7 @@ static VALUE ruby_curl_easy_ftp_entry_path_get(VALUE self) {
2678
2838
 
2679
2839
  /*
2680
2840
  * call-seq:
2681
- * easy.inspect => "#<Curl::Easy http://google.com/>"
2841
+ * easy.inspect => "#<Curl::Easy http://google.com/>"
2682
2842
  */
2683
2843
  static VALUE ruby_curl_easy_inspect(VALUE self) {
2684
2844
  char buf[64];
@@ -2734,7 +2894,7 @@ static VALUE ruby_curl_easy_escape(VALUE self, VALUE svalue) {
2734
2894
 
2735
2895
  /*
2736
2896
  * call-seq:
2737
- * easy.unescape("some%20text") => "some text"
2897
+ * easy.unescape("some%20text") => "some text"
2738
2898
  *
2739
2899
  * Convert the given URL encoded input string to a "plain string" and return
2740
2900
  * the result. All input characters that are URL encoded (%XX where XX is a
@@ -2805,7 +2965,7 @@ static VALUE ruby_curl_easy_class_perform_get(int argc, VALUE *argv, VALUE klass
2805
2965
 
2806
2966
  /*
2807
2967
  * call-seq:
2808
- * Curl::Easy.http_delete(url) { |easy| ... } => #&lt;Curl::Easy...&gt;
2968
+ * Curl::Easy.http_delete(url) { |easy| ... } => #&lt;Curl::Easy...&gt;
2809
2969
  *
2810
2970
  * Convenience method that creates a new Curl::Easy instance with
2811
2971
  * the specified URL and calls +http_delete+, before returning the new instance.
@@ -2822,7 +2982,7 @@ static VALUE ruby_curl_easy_class_perform_delete(int argc, VALUE *argv, VALUE kl
2822
2982
 
2823
2983
  /*
2824
2984
  * call-seq:
2825
- * Curl::Easy.http_head(url) { |easy| ... } => #&lt;Curl::Easy...&gt;
2985
+ * Curl::Easy.http_head(url) { |easy| ... } => #&lt;Curl::Easy...&gt;
2826
2986
  *
2827
2987
  * Convenience method that creates a new Curl::Easy instance with
2828
2988
  * the specified URL and calls +http_head+, before returning the new instance.
@@ -2928,6 +3088,8 @@ void init_curb_easy() {
2928
3088
  rb_define_method(cCurlEasy, "post_body=", ruby_curl_easy_post_body_set, 1);
2929
3089
  rb_define_method(cCurlEasy, "post_body", ruby_curl_easy_post_body_get, 0);
2930
3090
  rb_define_method(cCurlEasy, "put_data=", ruby_curl_easy_put_data_set, 1);
3091
+ rb_define_method(cCurlEasy, "ftp_commands=", ruby_curl_easy_ftp_commands_set, 1);
3092
+ rb_define_method(cCurlEasy, "ftp_commands", ruby_curl_easy_ftp_commands_get, 0);
2931
3093
 
2932
3094
  rb_define_method(cCurlEasy, "local_port=", ruby_curl_easy_local_port_set, 1);
2933
3095
  rb_define_method(cCurlEasy, "local_port", ruby_curl_easy_local_port_get, 0);
@@ -2951,6 +3113,12 @@ void init_curb_easy() {
2951
3113
  rb_define_method(cCurlEasy, "dns_cache_timeout", ruby_curl_easy_dns_cache_timeout_get, 0);
2952
3114
  rb_define_method(cCurlEasy, "ftp_response_timeout=", ruby_curl_easy_ftp_response_timeout_set, 1);
2953
3115
  rb_define_method(cCurlEasy, "ftp_response_timeout", ruby_curl_easy_ftp_response_timeout_get, 0);
3116
+ rb_define_method(cCurlEasy, "ssl_version=", ruby_curl_easy_ssl_version_set, 1);
3117
+ rb_define_method(cCurlEasy, "ssl_version", ruby_curl_easy_ssl_version_get, 0);
3118
+ rb_define_method(cCurlEasy, "use_ssl=", ruby_curl_easy_use_ssl_set, 1);
3119
+ rb_define_method(cCurlEasy, "use_ssl", ruby_curl_easy_use_ssl_get, 0);
3120
+ rb_define_method(cCurlEasy, "ftp_filemethod=", ruby_curl_easy_ftp_filemethod_set, 1);
3121
+ rb_define_method(cCurlEasy, "ftp_filemethod", ruby_curl_easy_ftp_filemethod_get, 0);
2954
3122
 
2955
3123
  rb_define_method(cCurlEasy, "username=", ruby_curl_easy_username_set, 1);
2956
3124
  rb_define_method(cCurlEasy, "username", ruby_curl_easy_username_get, 0);
@@ -3004,6 +3172,7 @@ void init_curb_easy() {
3004
3172
 
3005
3173
  rb_define_method(cCurlEasy, "last_effective_url", ruby_curl_easy_last_effective_url_get, 0);
3006
3174
  rb_define_method(cCurlEasy, "response_code", ruby_curl_easy_response_code_get, 0);
3175
+ rb_define_method(cCurlEasy, "primary_ip", ruby_curl_easy_primary_ip_get, 0);
3007
3176
  rb_define_method(cCurlEasy, "http_connect_code", ruby_curl_easy_http_connect_code_get, 0);
3008
3177
  rb_define_method(cCurlEasy, "file_time", ruby_curl_easy_file_time_get, 0);
3009
3178
  rb_define_method(cCurlEasy, "total_time", ruby_curl_easy_total_time_get, 0);
@@ -11,6 +11,24 @@
11
11
 
12
12
  #include <curl/easy.h>
13
13
 
14
+ #ifdef CURL_VERSION_SSL
15
+ #if LIBCURL_VERSION_NUM >= 0x070b00
16
+ # if LIBCURL_VERSION_NUM <= 0x071004
17
+ # define CURB_FTPSSL CURLOPT_FTP_SSL
18
+ # define CURB_FTPSSL_ALL CURLFTPSSL_ALL
19
+ # define CURB_FTPSSL_TRY CURLFTPSSL_TRY
20
+ # define CURB_FTPSSL_CONTROL CURLFTPSSL_CONTROL
21
+ # define CURB_FTPSSL_NONE CURLFTPSSL_NONE
22
+ # else
23
+ # define CURB_FTPSSL CURLOPT_USE_SSL
24
+ # define CURB_FTPSSL_ALL CURLUSESSL_ALL
25
+ # define CURB_FTPSSL_TRY CURLUSESSL_TRY
26
+ # define CURB_FTPSSL_CONTROL CURLUSESSL_CONTROL
27
+ # define CURB_FTPSSL_NONE CURLUSESSL_NONE
28
+ # endif
29
+ #endif
30
+ #endif
31
+
14
32
  /* a lot of this *could* be kept in the handler itself,
15
33
  * but then we lose the ability to query it's status.
16
34
  */
@@ -32,6 +50,9 @@ typedef struct {
32
50
  unsigned long connect_timeout;
33
51
  long dns_cache_timeout;
34
52
  unsigned long ftp_response_timeout;
53
+ long ssl_version;
54
+ long use_ssl;
55
+ long ftp_filemethod;
35
56
 
36
57
  /* bool flags */
37
58
  char proxy_tunnel;
@@ -46,6 +67,7 @@ typedef struct {
46
67
  char multipart_form_post;
47
68
  char enable_cookies;
48
69
  struct curl_slist *curl_headers;
70
+ struct curl_slist *curl_ftp_commands;
49
71
 
50
72
  int last_result; /* last result code from multi loop */
51
73
 
@@ -142,6 +142,7 @@ module Curl
142
142
  m = Curl::Multi.new
143
143
  # configure the multi handle
144
144
  multi_options.each { |k,v| m.send("#{k}=", v) }
145
+ callbacks = [:on_progress,:on_debug,:on_failure,:on_success,:on_body,:on_header]
145
146
 
146
147
  urls_with_config.each do|conf|
147
148
  c = conf.dup # avoid being destructive to input
@@ -151,6 +152,12 @@ module Curl
151
152
 
152
153
  easy = Curl::Easy.new(url)
153
154
 
155
+ # assign callbacks
156
+ callbacks.each do |cb|
157
+ cbproc = c.delete(cb)
158
+ easy.send(cb,&cbproc) if cbproc
159
+ end
160
+
154
161
  case method
155
162
  when :post
156
163
  fields = c.delete(:post_fields)
@@ -181,6 +188,64 @@ module Curl
181
188
  end
182
189
  m.perform
183
190
  end
191
+
192
+ # call-seq:
193
+ #
194
+ # Curl::Multi.download(['http://example.com/p/a/t/h/file1.txt','http://example.com/p/a/t/h/file2.txt'])
195
+ #
196
+ # will create 2 new files file1.txt and file2.txt
197
+ #
198
+ # 2 files will be opened, and remain open until the call completes
199
+ #
200
+ # when using the :post or :put method, urls should be a hash, including the individual post fields per post
201
+ #
202
+ def download(urls,easy_options={},multi_options={},download_paths=nil,&blk)
203
+ procs = []
204
+ files = []
205
+ urls_with_config = []
206
+ url_to_download_paths = {}
207
+
208
+ urls.each_with_index do|urlcfg,i|
209
+ if urlcfg.is_a?(Hash)
210
+ url = url[:url]
211
+ else
212
+ url = urlcfg
213
+ end
214
+
215
+ if download_paths and download_paths[i]
216
+ download_path = download_paths[i]
217
+ else
218
+ download_path = File.basename(url)
219
+ end
220
+
221
+ lambda do|dp|
222
+ file = File.open(dp,"wb")
223
+ procs << (lambda {|data| file.write data; data.size })
224
+ files << file
225
+ end.call(download_path)
226
+
227
+ if urlcfg.is_a?(Hash)
228
+ urls_with_config << urlcfg.merge({:on_body => procs.last}.merge(easy_options))
229
+ else
230
+ urls_with_config << {:url => url, :on_body => procs.last, :method => :get}.merge(easy_options)
231
+ end
232
+ url_to_download_paths[url] = download_path # store for later
233
+ end
234
+
235
+ Curl::Multi.http(urls_with_config, multi_options) {|c,code,method| blk.call(c,url_to_download_paths[c.url]) }
236
+
237
+ ensure
238
+ errors = []
239
+ files.each {|f|
240
+ begin
241
+ f.close
242
+ rescue => e
243
+ errors << e
244
+ end
245
+ }
246
+ raise errors unless errors.empty?
247
+ end
248
+
184
249
  end
185
250
  end
186
251
  end
@@ -308,6 +308,27 @@ class TestCurbCurlMulti < Test::Unit::TestCase
308
308
  end
309
309
  end
310
310
 
311
+ def test_multi_easy_download_01
312
+ # test collecting response buffers to file e.g. on_body
313
+ root_uri = 'http://127.0.0.1:9129/ext/'
314
+ urls = []
315
+ downloads = []
316
+ file_info = {}
317
+ FileUtils.mkdir("tmp/")
318
+ Dir[File.dirname(__FILE__) + "/../ext/*.c"].each do|path|
319
+ urls << (root_uri + File.basename(path))
320
+ downloads << "tmp/" + File.basename(path)
321
+ file_info[File.basename(path)] = {:size => File.size(path)}
322
+ end
323
+ Curl::Multi.download(urls,{},{},downloads) do|curl,download_path|
324
+ assert_equal 200, curl.response_code
325
+ assert File.exist?(download_path)
326
+ assert file_info[File.basename(download_path)][:size], File.size(download_path)
327
+ end
328
+ ensure
329
+ FileUtils.rm_rf("tmp/")
330
+ end
331
+
311
332
  def test_multi_easy_post_01
312
333
  urls = [
313
334
  { :url => TestServlet.url + '?q=1', :post_fields => {'field1' => 'value1', 'k' => 'j'}},
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 6
8
- - 9
9
- version: 0.6.9
7
+ - 7
8
+ - 0
9
+ version: 0.7.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Ross Bamford
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-04-14 00:00:00 -04:00
18
+ date: 2010-04-18 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies: []
21
21