ghazel-curb 0.6.2.3 → 0.7.9.1

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.
data/ext/curb_easy.c CHANGED
@@ -26,21 +26,6 @@ static VALUE rbstrAmp;
26
26
  VALUE cCurlEasy;
27
27
 
28
28
 
29
- /* XXX: This is copy/pasted from ruby 1.8.7 for compatibility with ruby 1.8.6 */
30
-
31
- VALUE
32
- rb_hash_lookup_187(hash, key)
33
- VALUE hash, key;
34
- {
35
- VALUE val;
36
-
37
- if (!st_lookup(RHASH(hash)->tbl, key, &val)) {
38
- return Qnil; /* without Hash#default */
39
- }
40
- return val;
41
- }
42
-
43
-
44
29
  /* ================== CURL HANDLER FUNCS ==============*/
45
30
 
46
31
  /* These handle both body and header data */
@@ -72,7 +57,7 @@ static size_t read_data_handler(void *ptr,
72
57
  return 0;
73
58
  }
74
59
  }
75
- else {
60
+ else if (rb_respond_to(stream, rb_intern("to_s"))) {
76
61
  ruby_curl_upload *rbcu;
77
62
  VALUE str;
78
63
  size_t len;
@@ -83,6 +68,7 @@ static size_t read_data_handler(void *ptr,
83
68
  len = RSTRING_LEN(str);
84
69
  remaining = len - rbcu->offset;
85
70
  str_ptr = RSTRING_PTR(str);
71
+
86
72
  if( remaining < read_bytes ) {
87
73
  if( remaining > 0 ) {
88
74
  memcpy(ptr, str_ptr+rbcu->offset, remaining);
@@ -101,7 +87,9 @@ static size_t read_data_handler(void *ptr,
101
87
  }
102
88
  return read_bytes;
103
89
  }
104
-
90
+ else {
91
+ return 0;
92
+ }
105
93
  }
106
94
 
107
95
  static size_t proc_data_handler(char *stream,
@@ -149,88 +137,37 @@ static int proc_debug_handler(CURL *curl,
149
137
 
150
138
  /* ================== MARK/FREE FUNC ==================*/
151
139
  void curl_easy_mark(ruby_curl_easy *rbce) {
152
- #if 0
153
- rb_gc_mark(rbce->url);
154
- rb_gc_mark(rbce->proxy_url);
155
- rb_gc_mark(rbce->body_proc);
156
- rb_gc_mark(rbce->body_data);
157
- rb_gc_mark(rbce->header_proc);
158
- rb_gc_mark(rbce->header_data);
159
- rb_gc_mark(rbce->progress_proc);
160
- rb_gc_mark(rbce->debug_proc);
161
- rb_gc_mark(rbce->interface_hm);
162
- rb_gc_mark(rbce->userpwd);
163
- #if HAVE_CURLOPT_USERNAME
164
- rb_gc_mark(rbce->username);
165
- #endif
166
- #if HAVE_CURLOPT_PASSWORD
167
- rb_gc_mark(rbce->password);
168
- #endif
169
- rb_gc_mark(rbce->proxypwd);
170
- rb_gc_mark(rbce->headers);
171
- rb_gc_mark(rbce->cookies);
172
- rb_gc_mark(rbce->cookiefile);
173
- rb_gc_mark(rbce->cookiejar);
174
- rb_gc_mark(rbce->cert);
175
- rb_gc_mark(rbce->cacert);
176
- rb_gc_mark(rbce->certpassword);
177
- rb_gc_mark(rbce->certtype);
178
- rb_gc_mark(rbce->encoding);
179
- rb_gc_mark(rbce->useragent);
180
- rb_gc_mark(rbce->success_proc);
181
- rb_gc_mark(rbce->failure_proc);
182
- rb_gc_mark(rbce->complete_proc);
183
-
184
- rb_gc_mark(rbce->postdata_buffer);
185
- rb_gc_mark(rbce->bodybuf);
186
- rb_gc_mark(rbce->headerbuf);
187
-
188
- if( rbce->upload != Qnil ) {
189
- rb_gc_mark(rbce->upload);
190
- }
191
- #endif
192
- rb_gc_mark(rbce->opts);
140
+ if (!NIL_P(rbce->opts)) { rb_gc_mark(rbce->opts); }
141
+ if (!NIL_P(rbce->multi)) { rb_gc_mark(rbce->multi); }
193
142
  }
194
143
 
195
- void curl_easy_free(ruby_curl_easy *rbce) {
144
+ static void ruby_curl_easy_free(ruby_curl_easy *rbce) {
196
145
  if (rbce->curl_headers) {
197
146
  curl_slist_free_all(rbce->curl_headers);
198
147
  }
199
- curl_easy_cleanup(rbce->curl);
200
- free(rbce);
201
- }
202
148
 
149
+ if (rbce->curl_ftp_commands) {
150
+ curl_slist_free_all(rbce->curl_ftp_commands);
151
+ }
203
152
 
204
- /* ================= ALLOC METHODS ====================*/
205
-
206
- /*
207
- * call-seq:
208
- * Curl::Easy.new => #&lt;Curl::Easy...&gt;
209
- * Curl::Easy.new(url = nil) => #&lt;Curl::Easy...&gt;
210
- * Curl::Easy.new(url = nil) { |self| ... } => #&lt;Curl::Easy...&gt;
211
- *
212
- * Create a new Curl::Easy instance, optionally supplying the URL.
213
- * The block form allows further configuration to be supplied before
214
- * the instance is returned.
215
- */
216
- static VALUE ruby_curl_easy_new(int argc, VALUE *argv, VALUE klass) {
217
- CURLcode ecode;
218
- VALUE url, blk;
219
- VALUE new_curl;
220
- ruby_curl_easy *rbce;
153
+ if (rbce->curl) {
154
+ curl_easy_cleanup(rbce->curl);
155
+ }
156
+ }
221
157
 
222
- rb_scan_args(argc, argv, "01&", &url, &blk);
158
+ void curl_easy_free(ruby_curl_easy *rbce) {
159
+ ruby_curl_easy_free(rbce);
160
+ free(rbce);
161
+ }
223
162
 
224
- rbce = ALLOC(ruby_curl_easy);
225
163
 
226
- /* handler */
227
- rbce->curl = curl_easy_init();
164
+ /* ================= ALLOC METHODS ====================*/
228
165
 
166
+ static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
229
167
  rbce->opts = rb_hash_new();
230
168
 
231
- rb_easy_set("url", url);
232
-
233
169
  rbce->curl_headers = NULL;
170
+ rbce->curl_ftp_commands = NULL;
234
171
 
235
172
  /* various-typed opts */
236
173
  rbce->local_port = 0;
@@ -244,6 +181,11 @@ static VALUE ruby_curl_easy_new(int argc, VALUE *argv, VALUE klass) {
244
181
  rbce->connect_timeout = 0;
245
182
  rbce->dns_cache_timeout = 60;
246
183
  rbce->ftp_response_timeout = 0;
184
+ rbce->low_speed_limit = 0;
185
+ rbce->low_speed_time = 0;
186
+ rbce->ssl_version = -1;
187
+ rbce->use_ssl = -1;
188
+ rbce->ftp_filemethod = -1;
247
189
 
248
190
  /* bool opts */
249
191
  rbce->proxy_tunnel = 0;
@@ -257,9 +199,44 @@ static VALUE ruby_curl_easy_new(int argc, VALUE *argv, VALUE klass) {
257
199
  rbce->verbose = 0;
258
200
  rbce->multipart_form_post = 0;
259
201
  rbce->enable_cookies = 0;
202
+ rbce->ignore_content_length = 0;
203
+ }
204
+
205
+ /*
206
+ * call-seq:
207
+ * Curl::Easy.new => #&lt;Curl::Easy...&gt;
208
+ * Curl::Easy.new(url = nil) => #&lt;Curl::Easy...&gt;
209
+ * Curl::Easy.new(url = nil) { |self| ... } => #&lt;Curl::Easy...&gt;
210
+ *
211
+ * Create a new Curl::Easy instance, optionally supplying the URL.
212
+ * The block form allows further configuration to be supplied before
213
+ * the instance is returned.
214
+ */
215
+ static VALUE ruby_curl_easy_new(int argc, VALUE *argv, VALUE klass) {
216
+ CURLcode ecode;
217
+ VALUE url, blk;
218
+ VALUE new_curl;
219
+ ruby_curl_easy *rbce;
220
+
221
+ rb_scan_args(argc, argv, "01&", &url, &blk);
222
+
223
+ rbce = ALLOC(ruby_curl_easy);
224
+
225
+ /* handler */
226
+ rbce->curl = curl_easy_init();
227
+ if (!rbce->curl) {
228
+ rb_raise(eCurlErrFailedInit, "Failed to initialize easy handle");
229
+ }
260
230
 
261
231
  new_curl = Data_Wrap_Struct(klass, curl_easy_mark, curl_easy_free, rbce);
262
232
 
233
+ rbce->multi = Qnil;
234
+ rbce->opts = Qnil;
235
+
236
+ ruby_curl_easy_zero(rbce);
237
+
238
+ rb_easy_set("url", url);
239
+
263
240
  /* set the new_curl pointer to the curl handle */
264
241
  ecode = curl_easy_setopt(rbce->curl, CURLOPT_PRIVATE, (void*)new_curl);
265
242
  if (ecode != CURLE_OK) {
@@ -290,10 +267,83 @@ static VALUE ruby_curl_easy_clone(VALUE self) {
290
267
  memcpy(newrbce, rbce, sizeof(ruby_curl_easy));
291
268
  newrbce->curl = curl_easy_duphandle(rbce->curl);
292
269
  newrbce->curl_headers = NULL;
270
+ newrbce->curl_ftp_commands = NULL;
293
271
 
294
272
  return Data_Wrap_Struct(cCurlEasy, curl_easy_mark, curl_easy_free, newrbce);
295
273
  }
296
274
 
275
+ /*
276
+ * call-seq:
277
+ * easy.close => nil
278
+ *
279
+ * Close the Curl::Easy instance. Any open connections are closed
280
+ * The easy handle is reinitialized. If a previous multi handle was
281
+ * open it is set to nil and will be cleared after a GC.
282
+ */
283
+ static VALUE ruby_curl_easy_close(VALUE self) {
284
+ CURLcode ecode;
285
+ ruby_curl_easy *rbce;
286
+
287
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
288
+
289
+ ruby_curl_easy_free(rbce);
290
+
291
+ /* reinit the handle */
292
+ rbce->curl = curl_easy_init();
293
+ if (!rbce->curl) {
294
+ rb_raise(eCurlErrFailedInit, "Failed to initialize easy handle");
295
+ }
296
+
297
+ rbce->multi = Qnil;
298
+
299
+ ruby_curl_easy_zero(rbce);
300
+
301
+ /* give the new curl handle a reference back to the ruby object */
302
+ ecode = curl_easy_setopt(rbce->curl, CURLOPT_PRIVATE, (void*)self);
303
+ if (ecode != CURLE_OK) {
304
+ raise_curl_easy_error_exception(ecode);
305
+ }
306
+
307
+ return Qnil;
308
+ }
309
+
310
+ /*
311
+ * call-seq:
312
+ * easy.reset => Hash
313
+ *
314
+ * Reset the Curl::Easy instance, clears out all settings.
315
+ *
316
+ * from http://curl.haxx.se/libcurl/c/curl_easy_reset.html
317
+ * Re-initializes all options previously set on a specified CURL handle to the default values. This puts back the handle to the same state as it was in when it was just created with curl_easy_init(3).
318
+ * It does not change the following information kept in the handle: live connections, the Session ID cache, the DNS cache, the cookies and shares.
319
+ *
320
+ * The return value contains all settings stored.
321
+ */
322
+ static VALUE ruby_curl_easy_reset(VALUE self) {
323
+ CURLcode ecode;
324
+ ruby_curl_easy *rbce;
325
+ VALUE opts_dup;
326
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
327
+ opts_dup = rb_funcall(rbce->opts, rb_intern("dup"), 0);
328
+
329
+ curl_easy_reset(rbce->curl);
330
+ ruby_curl_easy_zero(rbce);
331
+
332
+ /* rest clobbers the private setting, so reset it to self */
333
+ ecode = curl_easy_setopt(rbce->curl, CURLOPT_PRIVATE, (void*)self);
334
+ if (ecode != CURLE_OK) {
335
+ raise_curl_easy_error_exception(ecode);
336
+ }
337
+
338
+ /* Free everything up */
339
+ if (rbce->curl_headers) {
340
+ curl_slist_free_all(rbce->curl_headers);
341
+ rbce->curl_headers = NULL;
342
+ }
343
+
344
+ return opts_dup;
345
+ }
346
+
297
347
 
298
348
  /* ================ OBJ ATTRIBUTES ==================*/
299
349
 
@@ -311,7 +361,7 @@ static VALUE ruby_curl_easy_url_set(VALUE self, VALUE url) {
311
361
 
312
362
  /*
313
363
  * call-seq:
314
- * easy.url => "http://some.url/"
364
+ * easy.url => string
315
365
  *
316
366
  * Obtain the URL that will be used by subsequent calls to +perform+.
317
367
  */
@@ -321,7 +371,7 @@ static VALUE ruby_curl_easy_url_get(VALUE self) {
321
371
 
322
372
  /*
323
373
  * call-seq:
324
- * easy.proxy_url = "some.url" => "some.url"
374
+ * easy.proxy_url = string => string
325
375
  *
326
376
  * Set the URL of the HTTP proxy to use for subsequent calls to +perform+.
327
377
  * The URL should specify the the host name or dotted IP address. To specify
@@ -350,7 +400,7 @@ static VALUE ruby_curl_easy_proxy_url_set(VALUE self, VALUE proxy_url) {
350
400
 
351
401
  /*
352
402
  * call-seq:
353
- * easy.proxy_url => "some.url"
403
+ * easy.proxy_url => string
354
404
  *
355
405
  * Obtain the HTTP Proxy URL that will be used by subsequent calls to +perform+.
356
406
  */
@@ -360,8 +410,8 @@ static VALUE ruby_curl_easy_proxy_url_get(VALUE self) {
360
410
 
361
411
  /*
362
412
  * call-seq:
363
- * easy.headers = "Header: val" => ["Header: val", ...]
364
- * easy.headers = {"Header" => "val" ..., "Header" => "val"} => ["Header: val", ...]
413
+ * easy.headers = "Header: val" => "Header: val"
414
+ * easy.headers = {"Header" => "val" ..., "Header" => "val"} => {"Header: val", ...}
365
415
  * easy.headers = ["Header: val" ..., "Header: val"] => ["Header: val", ...]
366
416
  *
367
417
  * Set custom HTTP headers for following requests. This can be used to add
@@ -375,7 +425,7 @@ static VALUE ruby_curl_easy_proxy_url_get(VALUE self) {
375
425
  * To remove a standard header (this is useful when removing libcurls default
376
426
  * 'Expect: 100-Continue' header when using HTTP form posts):
377
427
  *
378
- * easy.headers["Expect:"] = ''
428
+ * easy.headers["Expect"] = ''
379
429
  *
380
430
  * Anything passed to libcurl as a header will be converted to a string during
381
431
  * the perform step.
@@ -386,7 +436,7 @@ static VALUE ruby_curl_easy_headers_set(VALUE self, VALUE headers) {
386
436
 
387
437
  /*
388
438
  * call-seq:
389
- * easy.headers => Hash, Array or Str
439
+ * easy.headers => Hash, Array or Str
390
440
  *
391
441
  * Obtain the custom HTTP headers for following requests.
392
442
  */
@@ -401,7 +451,7 @@ static VALUE ruby_curl_easy_headers_get(VALUE self) {
401
451
 
402
452
  /*
403
453
  * call-seq:
404
- * easy.interface = "interface" => "interface"
454
+ * easy.interface = string => string
405
455
  *
406
456
  * Set the interface name to use as the outgoing network interface.
407
457
  * The name can be an interface name, an IP address or a host name.
@@ -412,7 +462,7 @@ static VALUE ruby_curl_easy_interface_set(VALUE self, VALUE interface_hm) {
412
462
 
413
463
  /*
414
464
  * call-seq:
415
- * easy.interface => "interface"
465
+ * easy.interface => string
416
466
  *
417
467
  * Obtain the interface name that is used as the outgoing network interface.
418
468
  * The name can be an interface name, an IP address or a host name.
@@ -423,7 +473,7 @@ static VALUE ruby_curl_easy_interface_get(VALUE self) {
423
473
 
424
474
  /*
425
475
  * call-seq:
426
- * easy.userpwd = "pwd string" => "pwd string"
476
+ * easy.userpwd = string => string
427
477
  *
428
478
  * Set the username/password string to use for subsequent calls to +perform+.
429
479
  * The supplied string should have the form "username:password"
@@ -434,7 +484,7 @@ static VALUE ruby_curl_easy_userpwd_set(VALUE self, VALUE userpwd) {
434
484
 
435
485
  /*
436
486
  * call-seq:
437
- * easy.userpwd => "pwd string"
487
+ * easy.userpwd => string
438
488
  *
439
489
  * Obtain the username/password string that will be used for subsequent
440
490
  * calls to +perform+.
@@ -445,7 +495,7 @@ static VALUE ruby_curl_easy_userpwd_get(VALUE self) {
445
495
 
446
496
  /*
447
497
  * call-seq:
448
- * easy.proxypwd = "pwd string" => "pwd string"
498
+ * easy.proxypwd = string => string
449
499
  *
450
500
  * Set the username/password string to use for proxy connection during
451
501
  * subsequent calls to +perform+. The supplied string should have the
@@ -457,7 +507,7 @@ static VALUE ruby_curl_easy_proxypwd_set(VALUE self, VALUE proxypwd) {
457
507
 
458
508
  /*
459
509
  * call-seq:
460
- * easy.proxypwd => "pwd string"
510
+ * easy.proxypwd => string
461
511
  *
462
512
  * Obtain the username/password string that will be used for proxy
463
513
  * connection during subsequent calls to +perform+. The supplied string
@@ -470,7 +520,7 @@ static VALUE ruby_curl_easy_proxypwd_get(VALUE self) {
470
520
 
471
521
  /*
472
522
  * call-seq:
473
- * easy.cookies = "name1=content1; name2=content2;" => "pwd string"
523
+ * easy.cookies = "name1=content1; name2=content2;" => string
474
524
  *
475
525
  * Set cookies to be sent by this Curl::Easy instance. The format of the string should
476
526
  * be NAME=CONTENTS, where NAME is the cookie name and CONTENTS is what the cookie should contain.
@@ -482,7 +532,7 @@ static VALUE ruby_curl_easy_cookies_set(VALUE self, VALUE cookies) {
482
532
 
483
533
  /*
484
534
  * call-seq:
485
- * easy.cookies => "name1=content1; name2=content2;"
535
+ * easy.cookies => "name1=content1; name2=content2;"
486
536
  *
487
537
  * Obtain the cookies for this Curl::Easy instance.
488
538
  */
@@ -492,7 +542,7 @@ static VALUE ruby_curl_easy_cookies_get(VALUE self) {
492
542
 
493
543
  /*
494
544
  * call-seq:
495
- * easy.cookiefile = "cookies.txt" => "pwd string"
545
+ * easy.cookiefile = string => string
496
546
  *
497
547
  * Set a file that contains cookies to be sent in subsequent requests by this Curl::Easy instance.
498
548
  *
@@ -505,7 +555,7 @@ static VALUE ruby_curl_easy_cookiefile_set(VALUE self, VALUE cookiefile) {
505
555
 
506
556
  /*
507
557
  * call-seq:
508
- * easy.cookiefile => "cookies.txt"
558
+ * easy.cookiefile => string
509
559
  *
510
560
  * Obtain the cookiefile file for this Curl::Easy instance.
511
561
  */
@@ -515,7 +565,7 @@ static VALUE ruby_curl_easy_cookiefile_get(VALUE self) {
515
565
 
516
566
  /*
517
567
  * call-seq:
518
- * easy.cookiejar = "cookiejar.file" => "pwd string"
568
+ * easy.cookiejar = string => string
519
569
  *
520
570
  * Set a cookiejar file to use for this Curl::Easy instance.
521
571
  * Cookies from the response will be written into this file.
@@ -529,7 +579,7 @@ static VALUE ruby_curl_easy_cookiejar_set(VALUE self, VALUE cookiejar) {
529
579
 
530
580
  /*
531
581
  * call-seq:
532
- * easy.cookiejar => "cookiejar.file"
582
+ * easy.cookiejar => string
533
583
  *
534
584
  * Obtain the cookiejar file to use for this Curl::Easy instance.
535
585
  */
@@ -539,7 +589,7 @@ static VALUE ruby_curl_easy_cookiejar_get(VALUE self) {
539
589
 
540
590
  /*
541
591
  * call-seq:
542
- * easy.cert = "cert.file" => ""
592
+ * easy.cert = string => ""
543
593
  *
544
594
  * Set a cert file to use for this Curl::Easy instance. This file
545
595
  * will be used to validate SSL connections.
@@ -551,7 +601,7 @@ static VALUE ruby_curl_easy_cert_set(VALUE self, VALUE cert) {
551
601
 
552
602
  /*
553
603
  * call-seq:
554
- * easy.cert => "cert.file"
604
+ * easy.cert => string
555
605
  *
556
606
  * Obtain the cert file to use for this Curl::Easy instance.
557
607
  */
@@ -561,7 +611,29 @@ static VALUE ruby_curl_easy_cert_get(VALUE self) {
561
611
 
562
612
  /*
563
613
  * call-seq:
564
- * easy.cacert = "cacert.file" => ""
614
+ * easy.cert_key = "cert_key.file" => ""
615
+ *
616
+ * Set a cert key to use for this Curl::Easy instance. This file
617
+ * will be used to validate SSL certificates.
618
+ *
619
+ */
620
+ static VALUE ruby_curl_easy_cert_key_set(VALUE self, VALUE cert_key) {
621
+ CURB_OBJECT_HSETTER(ruby_curl_easy, cert_key);
622
+ }
623
+
624
+ /*
625
+ * call-seq:
626
+ * easy.cert_key => "cert_key.file"
627
+ *
628
+ * Obtain the cert key file to use for this Curl::Easy instance.
629
+ */
630
+ static VALUE ruby_curl_easy_cert_key_get(VALUE self) {
631
+ CURB_OBJECT_HGETTER(ruby_curl_easy, cert_key);
632
+ }
633
+
634
+ /*
635
+ * call-seq:
636
+ * easy.cacert = string => ""
565
637
  *
566
638
  * Set a cacert bundle to use for this Curl::Easy instance. This file
567
639
  * will be used to validate SSL certificates.
@@ -573,7 +645,7 @@ static VALUE ruby_curl_easy_cacert_set(VALUE self, VALUE cacert) {
573
645
 
574
646
  /*
575
647
  * call-seq:
576
- * easy.cacert => "cacert.file"
648
+ * easy.cacert => string
577
649
  *
578
650
  * Obtain the cacert file to use for this Curl::Easy instance.
579
651
  */
@@ -583,7 +655,7 @@ static VALUE ruby_curl_easy_cacert_get(VALUE self) {
583
655
 
584
656
  /*
585
657
  * call-seq:
586
- * easy.certpassword = "cert password" => ""
658
+ * easy.certpassword = string => ""
587
659
  *
588
660
  * Set a password used to open the specified cert
589
661
  */
@@ -605,7 +677,7 @@ static VALUE ruby_curl_easy_certtype_set(VALUE self, VALUE certtype) {
605
677
 
606
678
  /*
607
679
  * call-seq:
608
- * easy.certtype => "cert.type"
680
+ * easy.certtype => string
609
681
  *
610
682
  * Obtain the cert type used for this Curl::Easy instance
611
683
  */
@@ -615,7 +687,7 @@ static VALUE ruby_curl_easy_certtype_get(VALUE self) {
615
687
 
616
688
  /*
617
689
  * call-seq:
618
- * easy.encoding= => "string"
690
+ * easy.encoding = string => string
619
691
  *
620
692
  * Set the accepted encoding types, curl will handle all of the decompression
621
693
  *
@@ -625,7 +697,7 @@ static VALUE ruby_curl_easy_encoding_set(VALUE self, VALUE encoding) {
625
697
  }
626
698
  /*
627
699
  * call-seq:
628
- * easy.encoding => "string"
700
+ * easy.encoding => string
629
701
  *
630
702
  * Get the set encoding types
631
703
  *
@@ -636,7 +708,7 @@ static VALUE ruby_curl_easy_encoding_get(VALUE self) {
636
708
 
637
709
  /*
638
710
  * call-seq:
639
- * easy.useragent = "Ruby/Curb" => ""
711
+ * easy.useragent = "Ruby/Curb" => ""
640
712
  *
641
713
  * Set the user agent string for this Curl::Easy instance
642
714
  *
@@ -657,7 +729,7 @@ static VALUE ruby_curl_easy_useragent_get(VALUE self) {
657
729
 
658
730
  /*
659
731
  * call-seq:
660
- * easy.post_body = "some=form%20data&to=send" => string or nil
732
+ * easy.post_body = "some=form%20data&to=send" => string or nil
661
733
  *
662
734
  * Sets the POST body of this Curl::Easy instance. This is expected to be
663
735
  * URL encoded; no additional processing or encoding is done on the string.
@@ -671,7 +743,7 @@ static VALUE ruby_curl_easy_post_body_set(VALUE self, VALUE post_body) {
671
743
 
672
744
  char *data;
673
745
  long len;
674
-
746
+
675
747
  Data_Get_Struct(self, ruby_curl_easy, rbce);
676
748
 
677
749
  curl = rbce->curl;
@@ -681,8 +753,18 @@ static VALUE ruby_curl_easy_post_body_set(VALUE self, VALUE post_body) {
681
753
  rb_easy_del("postdata_buffer");
682
754
 
683
755
  } else {
684
- data = StringValuePtr(post_body);
685
- len = RSTRING_LEN(post_body);
756
+ if (rb_type(post_body) == T_STRING) {
757
+ data = StringValuePtr(post_body);
758
+ len = RSTRING_LEN(post_body);
759
+ }
760
+ else if (rb_respond_to(post_body, rb_intern("to_s"))) {
761
+ VALUE str_body = rb_funcall(post_body, rb_intern("to_s"), 0);
762
+ data = StringValuePtr(str_body);
763
+ len = RSTRING_LEN(post_body);
764
+ }
765
+ else {
766
+ rb_raise(rb_eRuntimeError, "post data must respond_to .to_s");
767
+ }
686
768
 
687
769
  // Store the string, since it has to hang around for the duration of the
688
770
  // request. See CURLOPT_POSTFIELDS in the libcurl docs.
@@ -701,7 +783,7 @@ static VALUE ruby_curl_easy_post_body_set(VALUE self, VALUE post_body) {
701
783
 
702
784
  /*
703
785
  * call-seq:
704
- * easy.post_body => "string" or nil
786
+ * easy.post_body => string or nil
705
787
  *
706
788
  * Obtain the POST body used in this Curl::Easy instance.
707
789
  */
@@ -748,10 +830,14 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
748
830
  }
749
831
  }
750
832
 
833
+ // exit fast if the payload is empty
834
+ if (NIL_P(data)) { return data; }
835
+
751
836
  headers = rb_easy_get("headers");
752
837
  if( headers == Qnil ) {
753
838
  headers = rb_hash_new();
754
839
  }
840
+
755
841
  if (rb_respond_to(data, rb_intern("read"))) {
756
842
  VALUE stat = rb_funcall(data, rb_intern("stat"), 0);
757
843
  if( stat ) {
@@ -760,7 +846,7 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
760
846
  rb_hash_aset(headers, rb_str_new2("Expect"), rb_str_new2(""));
761
847
  }
762
848
  size = rb_funcall(stat, rb_intern("size"), 0);
763
- curl_easy_setopt(curl, CURLOPT_INFILESIZE, FIX2INT(size));
849
+ curl_easy_setopt(curl, CURLOPT_INFILESIZE, FIX2LONG(size));
764
850
  }
765
851
  else if( rb_hash_aref(headers, rb_str_new2("Transfer-Encoding")) == Qnil ) {
766
852
  rb_hash_aset(headers, rb_str_new2("Transfer-Encoding"), rb_str_new2("chunked"));
@@ -776,11 +862,29 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
776
862
  rb_raise(rb_eRuntimeError, "PUT data must respond to read or to_s");
777
863
  }
778
864
  rb_easy_set("headers",headers);
779
-
865
+
780
866
  // if we made it this far, all should be well.
781
867
  return data;
782
868
  }
783
869
 
870
+ /*
871
+ * call-seq:
872
+ * easy.ftp_commands = ["CWD /", "MKD directory"] => ["CWD /", ...]
873
+ *
874
+ * Explicitly sets the list of commands to execute on the FTP server when calling perform
875
+ */
876
+ static VALUE ruby_curl_easy_ftp_commands_set(VALUE self, VALUE ftp_commands) {
877
+ CURB_OBJECT_HSETTER(ruby_curl_easy, ftp_commands);
878
+ }
879
+
880
+ /*
881
+ * call-seq
882
+ * easy.ftp_commands => array or nil
883
+ */
884
+ static VALUE ruby_curl_easy_ftp_commands_get(VALUE self) {
885
+ CURB_OBJECT_HGETTER(ruby_curl_easy, ftp_commands);
886
+ }
887
+
784
888
  /* ================== IMMED ATTRS ==================*/
785
889
 
786
890
  /*
@@ -918,7 +1022,8 @@ static VALUE ruby_curl_easy_http_auth_types_set(int argc, VALUE *argv, VALUE sel
918
1022
 
919
1023
  rb_scan_args(argc, argv, "*", &args_ary);
920
1024
  Data_Get_Struct(self, ruby_curl_easy, rbce);
921
- len = RARRAY_LEN(args_ary);
1025
+
1026
+ len = (int)RARRAY_LEN(args_ary);
922
1027
 
923
1028
  if (len == 1 && (TYPE(rb_ary_entry(args_ary,0)) == T_FIXNUM || rb_ary_entry(args_ary,0) == Qnil)) {
924
1029
  if (rb_ary_entry(args_ary,0) == Qnil) {
@@ -1106,7 +1211,52 @@ static VALUE ruby_curl_easy_ftp_response_timeout_get(VALUE self, VALUE ftp_respo
1106
1211
 
1107
1212
  /*
1108
1213
  * call-seq:
1109
- * easy.username = "foo" => String
1214
+ * easy.low_speed_limit = fixnum or nil => fixnum or nil
1215
+ *
1216
+ * Set the transfer speed (in bytes per second) that the transfer should be
1217
+ * below during +low_speed_time+ seconds for the library to consider it too
1218
+ * slow and abort.
1219
+ */
1220
+ static VALUE ruby_curl_easy_low_speed_limit_set(VALUE self, VALUE low_speed_limit) {
1221
+ CURB_IMMED_SETTER(ruby_curl_easy, low_speed_limit, 0);
1222
+ }
1223
+
1224
+ /*
1225
+ * call-seq:
1226
+ * easy.low_speed_limit => fixnum or nil
1227
+ *
1228
+ * Obtain the minimum transfer speed over +low_speed+time+ below which the
1229
+ * transfer will be aborted.
1230
+ */
1231
+ static VALUE ruby_curl_easy_low_speed_limit_get(VALUE self, VALUE low_speed_limit) {
1232
+ CURB_IMMED_GETTER(ruby_curl_easy, low_speed_limit, 0);
1233
+ }
1234
+
1235
+ /*
1236
+ * call-seq:
1237
+ * easy.low_speed_time = fixnum or nil => fixnum or nil
1238
+ *
1239
+ * Set the time (in seconds) that the transfer should be below the
1240
+ * +low_speed_limit+ for the library to consider it too slow and abort.
1241
+ */
1242
+ static VALUE ruby_curl_easy_low_speed_time_set(VALUE self, VALUE low_speed_time) {
1243
+ CURB_IMMED_SETTER(ruby_curl_easy, low_speed_time, 0);
1244
+ }
1245
+
1246
+ /*
1247
+ * call-seq:
1248
+ * easy.low_speed_time => fixnum or nil
1249
+ *
1250
+ * Obtain the time that the transfer should be below +low_speed_limit+ for
1251
+ * the library to abort it.
1252
+ */
1253
+ static VALUE ruby_curl_easy_low_speed_time_get(VALUE self, VALUE low_speed_time) {
1254
+ CURB_IMMED_GETTER(ruby_curl_easy, low_speed_time, 0);
1255
+ }
1256
+
1257
+ /*
1258
+ * call-seq:
1259
+ * easy.username = string => string
1110
1260
  *
1111
1261
  * Set the HTTP Authentication username.
1112
1262
  */
@@ -1120,7 +1270,7 @@ static VALUE ruby_curl_easy_username_set(VALUE self, VALUE username) {
1120
1270
 
1121
1271
  /*
1122
1272
  * call-seq:
1123
- * easy.username => String
1273
+ * easy.username => string
1124
1274
  *
1125
1275
  * Get the current username
1126
1276
  */
@@ -1134,7 +1284,7 @@ static VALUE ruby_curl_easy_username_get(VALUE self, VALUE username) {
1134
1284
 
1135
1285
  /*
1136
1286
  * call-seq:
1137
- * easy.password = "foo" => String
1287
+ * easy.password = string => string
1138
1288
  *
1139
1289
  * Set the HTTP Authentication password.
1140
1290
  */
@@ -1148,7 +1298,7 @@ static VALUE ruby_curl_easy_password_set(VALUE self, VALUE password) {
1148
1298
 
1149
1299
  /*
1150
1300
  * call-seq:
1151
- * easy.password => String
1301
+ * easy.password => string
1152
1302
  *
1153
1303
  * Get the current password
1154
1304
  */
@@ -1160,11 +1310,75 @@ static VALUE ruby_curl_easy_password_get(VALUE self, VALUE password) {
1160
1310
  #endif
1161
1311
  }
1162
1312
 
1313
+ /*
1314
+ * call-seq:
1315
+ * easy.ssl_version = value => fixnum or nil
1316
+ *
1317
+ * Sets the version of SSL/TLS that libcurl will attempt to use. Valid
1318
+ * options are Curl::CURL_SSLVERSION_TLSv1, Curl::CURL_SSLVERSION::SSLv2,
1319
+ * Curl::CURL_SSLVERSION_SSLv3 and Curl::CURL_SSLVERSION_DEFAULT
1320
+ */
1321
+ static VALUE ruby_curl_easy_ssl_version_set(VALUE self, VALUE ssl_version) {
1322
+ CURB_IMMED_SETTER(ruby_curl_easy, ssl_version, -1);
1323
+ }
1324
+
1325
+ /*
1326
+ * call-seq:
1327
+ * easy.ssl_version => fixnum
1328
+ *
1329
+ * Get the version of SSL/TLS that libcurl will attempt to use.
1330
+ */
1331
+ static VALUE ruby_curl_easy_ssl_version_get(VALUE self, VALUE ssl_version) {
1332
+ CURB_IMMED_GETTER(ruby_curl_easy, ssl_version, -1);
1333
+ }
1334
+
1335
+ /*
1336
+ * call-seq:
1337
+ * easy.use_ssl = value => fixnum or nil
1338
+ *
1339
+ * Ensure libcurl uses SSL for FTP connections. Valid options are Curl::CURL_USESSL_NONE,
1340
+ * Curl::CURL_USESSL_TRY, Curl::CURL_USESSL_CONTROL, and Curl::CURL_USESSL_ALL.
1341
+ */
1342
+ static VALUE ruby_curl_easy_use_ssl_set(VALUE self, VALUE use_ssl) {
1343
+ CURB_IMMED_SETTER(ruby_curl_easy, use_ssl, -1);
1344
+ }
1345
+
1346
+ /*
1347
+ * call-seq:
1348
+ * easy.use_ssl => fixnum
1349
+ *
1350
+ * Get the desired level for using SSL on FTP connections.
1351
+ */
1352
+ static VALUE ruby_curl_easy_use_ssl_get(VALUE self, VALUE use_ssl) {
1353
+ CURB_IMMED_GETTER(ruby_curl_easy, use_ssl, -1);
1354
+ }
1355
+
1356
+ /*
1357
+ * call-seq:
1358
+ * easy.ftp_filemethod = value => fixnum or nil
1359
+ *
1360
+ * Controls how libcurl reaches files on the server. Valid options are Curl::CURL_MULTICWD,
1361
+ * Curl::CURL_NOCWD, and Curl::CURL_SINGLECWD (see libcurl docs for CURLOPT_FTP_METHOD).
1362
+ */
1363
+ static VALUE ruby_curl_easy_ftp_filemethod_set(VALUE self, VALUE ftp_filemethod) {
1364
+ CURB_IMMED_SETTER(ruby_curl_easy, ftp_filemethod, -1);
1365
+ }
1366
+
1367
+ /*
1368
+ * call-seq
1369
+ * easy.ftp_filemethod => fixnum
1370
+ *
1371
+ * Get the configuration for how libcurl will reach files on the server.
1372
+ */
1373
+ static VALUE ruby_curl_easy_ftp_filemethod_get(VALUE self, VALUE ftp_filemethod) {
1374
+ CURB_IMMED_GETTER(ruby_curl_easy, ftp_filemethod, -1);
1375
+ }
1376
+
1163
1377
  /* ================== BOOL ATTRS ===================*/
1164
1378
 
1165
1379
  /*
1166
1380
  * call-seq:
1167
- * proxy_tunnel = boolean => boolean
1381
+ * easy.proxy_tunnel = boolean => boolean
1168
1382
  *
1169
1383
  * Configure whether this Curl instance will use proxy tunneling.
1170
1384
  */
@@ -1174,7 +1388,7 @@ static VALUE ruby_curl_easy_proxy_tunnel_set(VALUE self, VALUE proxy_tunnel) {
1174
1388
 
1175
1389
  /*
1176
1390
  * call-seq:
1177
- * proxy_tunnel? => boolean
1391
+ * easy.proxy_tunnel? => boolean
1178
1392
  *
1179
1393
  * Determine whether this Curl instance will use proxy tunneling.
1180
1394
  */
@@ -1184,7 +1398,7 @@ static VALUE ruby_curl_easy_proxy_tunnel_q(VALUE self) {
1184
1398
 
1185
1399
  /*
1186
1400
  * call-seq:
1187
- * fetch_file_time = boolean => boolean
1401
+ * easy.fetch_file_time = boolean => boolean
1188
1402
  *
1189
1403
  * Configure whether this Curl instance will fetch remote file
1190
1404
  * times, if available.
@@ -1195,7 +1409,7 @@ static VALUE ruby_curl_easy_fetch_file_time_set(VALUE self, VALUE fetch_file_tim
1195
1409
 
1196
1410
  /*
1197
1411
  * call-seq:
1198
- * fetch_file_time? => boolean
1412
+ * easy.fetch_file_time? => boolean
1199
1413
  *
1200
1414
  * Determine whether this Curl instance will fetch remote file
1201
1415
  * times, if available.
@@ -1206,7 +1420,7 @@ static VALUE ruby_curl_easy_fetch_file_time_q(VALUE self) {
1206
1420
 
1207
1421
  /*
1208
1422
  * call-seq:
1209
- * ssl_verify_peer = boolean => boolean
1423
+ * easy.ssl_verify_peer = boolean => boolean
1210
1424
  *
1211
1425
  * Configure whether this Curl instance will verify the SSL peer
1212
1426
  * certificate. When true (the default), and the verification fails to
@@ -1224,7 +1438,7 @@ static VALUE ruby_curl_easy_ssl_verify_peer_set(VALUE self, VALUE ssl_verify_pee
1224
1438
 
1225
1439
  /*
1226
1440
  * call-seq:
1227
- * ssl_verify_peer? => boolean
1441
+ * easy.ssl_verify_peer? => boolean
1228
1442
  *
1229
1443
  * Determine whether this Curl instance will verify the SSL peer
1230
1444
  * certificate.
@@ -1235,7 +1449,7 @@ static VALUE ruby_curl_easy_ssl_verify_peer_q(VALUE self) {
1235
1449
 
1236
1450
  /*
1237
1451
  * call-seq:
1238
- * ssl_verify_host = boolean => boolean
1452
+ * easy.ssl_verify_host = boolean => boolean
1239
1453
  *
1240
1454
  * Configure whether this Curl instance will verify that the server cert
1241
1455
  * is for the server it is known as. When true (the default) the server
@@ -1252,7 +1466,7 @@ static VALUE ruby_curl_easy_ssl_verify_host_set(VALUE self, VALUE ssl_verify_hos
1252
1466
 
1253
1467
  /*
1254
1468
  * call-seq:
1255
- * ssl_verify_host? => boolean
1469
+ * easy.ssl_verify_host? => boolean
1256
1470
  *
1257
1471
  * Determine whether this Curl instance will verify that the server cert
1258
1472
  * is for the server it is known as.
@@ -1263,7 +1477,7 @@ static VALUE ruby_curl_easy_ssl_verify_host_q(VALUE self) {
1263
1477
 
1264
1478
  /*
1265
1479
  * call-seq:
1266
- * header_in_body = boolean => boolean
1480
+ * easy.header_in_body = boolean => boolean
1267
1481
  *
1268
1482
  * Configure whether this Curl instance will return HTTP headers
1269
1483
  * combined with body data. If this option is set true, both header
@@ -1275,10 +1489,10 @@ static VALUE ruby_curl_easy_header_in_body_set(VALUE self, VALUE header_in_body)
1275
1489
 
1276
1490
  /*
1277
1491
  * call-seq:
1278
- * header_in_body? => boolean
1492
+ * easy.header_in_body? => boolean
1279
1493
  *
1280
- * Determine whether this Curl instance will verify the SSL peer
1281
- * certificate.
1494
+ * Determine whether this Curl instance will return HTTP headers
1495
+ * combined with body data.
1282
1496
  */
1283
1497
  static VALUE ruby_curl_easy_header_in_body_q(VALUE self) {
1284
1498
  CURB_BOOLEAN_GETTER(ruby_curl_easy, header_in_body);
@@ -1286,7 +1500,7 @@ static VALUE ruby_curl_easy_header_in_body_q(VALUE self) {
1286
1500
 
1287
1501
  /*
1288
1502
  * call-seq:
1289
- * use_netrc = boolean => boolean
1503
+ * easy.use_netrc = boolean => boolean
1290
1504
  *
1291
1505
  * Configure whether this Curl instance will use data from the user's
1292
1506
  * .netrc file for FTP connections.
@@ -1297,7 +1511,7 @@ static VALUE ruby_curl_easy_use_netrc_set(VALUE self, VALUE use_netrc) {
1297
1511
 
1298
1512
  /*
1299
1513
  * call-seq:
1300
- * use_netrc? => boolean
1514
+ * easy.use_netrc? => boolean
1301
1515
  *
1302
1516
  * Determine whether this Curl instance will use data from the user's
1303
1517
  * .netrc file for FTP connections.
@@ -1308,7 +1522,7 @@ static VALUE ruby_curl_easy_use_netrc_q(VALUE self) {
1308
1522
 
1309
1523
  /*
1310
1524
  * call-seq:
1311
- * follow_location = boolean => boolean
1525
+ * easy.follow_location = boolean => boolean
1312
1526
  *
1313
1527
  * Configure whether this Curl instance will follow Location: headers
1314
1528
  * in HTTP responses. Redirects will only be followed to the extent
@@ -1317,10 +1531,29 @@ static VALUE ruby_curl_easy_use_netrc_q(VALUE self) {
1317
1531
  static VALUE ruby_curl_easy_follow_location_set(VALUE self, VALUE follow_location) {
1318
1532
  CURB_BOOLEAN_SETTER(ruby_curl_easy, follow_location);
1319
1533
  }
1534
+ /*
1535
+ * call-seq:
1536
+ *
1537
+ * easy = Curl::Easy.new
1538
+ * easy.autoreferer=true
1539
+ */
1540
+ static VALUE ruby_curl_easy_autoreferer_set(VALUE self, VALUE autoreferer) {
1541
+ ruby_curl_easy *rbce;
1542
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
1543
+
1544
+ if (Qtrue == autoreferer) {
1545
+ curl_easy_setopt(rbce->curl, CURLOPT_AUTOREFERER, 1);
1546
+ }
1547
+ else {
1548
+ curl_easy_setopt(rbce->curl, CURLOPT_AUTOREFERER, 0);
1549
+ }
1550
+
1551
+ return autoreferer;
1552
+ }
1320
1553
 
1321
1554
  /*
1322
1555
  * call-seq:
1323
- * follow_location? => boolean
1556
+ * easy.follow_location? => boolean
1324
1557
  *
1325
1558
  * Determine whether this Curl instance will follow Location: headers
1326
1559
  * in HTTP responses.
@@ -1331,7 +1564,7 @@ static VALUE ruby_curl_easy_follow_location_q(VALUE self) {
1331
1564
 
1332
1565
  /*
1333
1566
  * call-seq:
1334
- * unrestricted_auth = boolean => boolean
1567
+ * easy.unrestricted_auth = boolean => boolean
1335
1568
  *
1336
1569
  * Configure whether this Curl instance may use any HTTP authentication
1337
1570
  * method available when necessary.
@@ -1342,7 +1575,7 @@ static VALUE ruby_curl_easy_unrestricted_auth_set(VALUE self, VALUE unrestricted
1342
1575
 
1343
1576
  /*
1344
1577
  * call-seq:
1345
- * unrestricted_auth? => boolean
1578
+ * easy.unrestricted_auth? => boolean
1346
1579
  *
1347
1580
  * Determine whether this Curl instance may use any HTTP authentication
1348
1581
  * method available when necessary.
@@ -1416,7 +1649,7 @@ static VALUE ruby_curl_easy_enable_cookies_set(VALUE self, VALUE enable_cookies)
1416
1649
 
1417
1650
  /*
1418
1651
  * call-seq:
1419
- * easy.enable_cookies? => boolean
1652
+ * easy.enable_cookies? => boolean
1420
1653
  *
1421
1654
  * Determine whether the libcurl cookie engine is enabled for this
1422
1655
  * Curl::Easy instance.
@@ -1425,6 +1658,31 @@ static VALUE ruby_curl_easy_enable_cookies_q(VALUE self) {
1425
1658
  CURB_BOOLEAN_GETTER(ruby_curl_easy, enable_cookies);
1426
1659
  }
1427
1660
 
1661
+ /*
1662
+ * call-seq:
1663
+ * easy.ignore_content_length = boolean
1664
+ *
1665
+ * Configure whether this Curl::Easy instance should ignore the content
1666
+ * length header.
1667
+ */
1668
+ static VALUE ruby_curl_easy_ignore_content_length_set(VALUE self, VALUE ignore_content_length)
1669
+ {
1670
+ CURB_BOOLEAN_SETTER(ruby_curl_easy, ignore_content_length);
1671
+ }
1672
+
1673
+ /*
1674
+ * call-seq:
1675
+ * easy.ignore_content_length? => boolean
1676
+ *
1677
+ * Determine whether this Curl::Easy instance ignores the content
1678
+ * length header.
1679
+ */
1680
+ static VALUE ruby_curl_easy_ignore_content_length_q(VALUE self) {
1681
+ CURB_BOOLEAN_GETTER(ruby_curl_easy, ignore_content_length);
1682
+ }
1683
+
1684
+
1685
+
1428
1686
  /* ================= EVENT PROCS ================== */
1429
1687
 
1430
1688
  /*
@@ -1448,7 +1706,7 @@ static VALUE ruby_curl_easy_on_body_set(int argc, VALUE *argv, VALUE self) {
1448
1706
 
1449
1707
  /*
1450
1708
  * call-seq:
1451
- * easy.on_success { |easy| ... } => &lt;old handler&gt;
1709
+ * easy.on_success { |easy| ... } => &lt;old handler&gt;
1452
1710
  *
1453
1711
  * Assign or remove the +on_success+ handler for this Curl::Easy instance.
1454
1712
  * To remove a previously-supplied handler, call this method with no
@@ -1463,7 +1721,7 @@ static VALUE ruby_curl_easy_on_success_set(int argc, VALUE *argv, VALUE self) {
1463
1721
 
1464
1722
  /*
1465
1723
  * call-seq:
1466
- * easy.on_failure {|easy,code| ... } => &lt;old handler&gt;
1724
+ * easy.on_failure {|easy,code| ... } => &lt;old handler&gt;
1467
1725
  *
1468
1726
  * Assign or remove the +on_failure+ handler for this Curl::Easy instance.
1469
1727
  * To remove a previously-supplied handler, call this method with no
@@ -1478,7 +1736,7 @@ static VALUE ruby_curl_easy_on_failure_set(int argc, VALUE *argv, VALUE self) {
1478
1736
 
1479
1737
  /*
1480
1738
  * call-seq:
1481
- * easy.on_complete {|easy| ... } => &lt;old handler&gt;
1739
+ * easy.on_complete {|easy| ... } => &lt;old handler&gt;
1482
1740
  *
1483
1741
  * Assign or remove the +on_complete+ handler for this Curl::Easy instance.
1484
1742
  * To remove a previously-supplied handler, call this method with no
@@ -1580,16 +1838,28 @@ static VALUE cb_each_http_header(VALUE header, struct curl_slist **list) {
1580
1838
  return header_str;
1581
1839
  }
1582
1840
 
1841
+ /***********************************************
1842
+ * This is an rb_iterate callback used to set up ftp commands.
1843
+ */
1844
+ static VALUE cb_each_ftp_command(VALUE ftp_command, struct curl_slist **list) {
1845
+ VALUE ftp_command_string = rb_obj_as_string(ftp_command);
1846
+ *list = curl_slist_append(*list, StringValuePtr(ftp_command));
1847
+
1848
+ return ftp_command_string;
1849
+ }
1850
+
1583
1851
  /***********************************************
1584
1852
  *
1585
1853
  * Setup a connection
1586
1854
  *
1587
1855
  * Always returns Qtrue, rb_raise on error.
1588
1856
  */
1589
- VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce, struct curl_slist **hdrs ) {
1857
+ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
1590
1858
  // TODO this could do with a bit of refactoring...
1591
1859
  CURL *curl;
1592
1860
  VALUE url, _url = rb_easy_get("url");
1861
+ struct curl_slist **hdrs = &(rbce->curl_headers);
1862
+ struct curl_slist **cmds = &(rbce->curl_ftp_commands);
1593
1863
 
1594
1864
  curl = rbce->curl;
1595
1865
 
@@ -1696,7 +1966,6 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce, struct curl_slist **hdrs ) {
1696
1966
  /* general opts */
1697
1967
 
1698
1968
  curl_easy_setopt(curl, CURLOPT_HEADER, rbce->header_in_body);
1699
-
1700
1969
  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, rbce->follow_location);
1701
1970
  curl_easy_setopt(curl, CURLOPT_MAXREDIRS, rbce->max_redirs);
1702
1971
 
@@ -1717,6 +1986,9 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce, struct curl_slist **hdrs ) {
1717
1986
  curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, rbce->connect_timeout);
1718
1987
  curl_easy_setopt(curl, CURLOPT_DNS_CACHE_TIMEOUT, rbce->dns_cache_timeout);
1719
1988
 
1989
+ curl_easy_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, rbce->ignore_content_length);
1990
+
1991
+
1720
1992
  #if LIBCURL_VERSION_NUM >= 0x070a08
1721
1993
  curl_easy_setopt(curl, CURLOPT_FTP_RESPONSE_TIMEOUT, rbce->ftp_response_timeout);
1722
1994
  #else
@@ -1725,6 +1997,9 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce, struct curl_slist **hdrs ) {
1725
1997
  }
1726
1998
  #endif
1727
1999
 
2000
+ curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, rbce->low_speed_limit);
2001
+ curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, rbce->low_speed_time);
2002
+
1728
2003
  // Set up localport / proxy port
1729
2004
  // FIXME these won't get returned to default if they're unset Ruby
1730
2005
  if (rbce->proxy_port > 0) {
@@ -1803,6 +2078,9 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce, struct curl_slist **hdrs ) {
1803
2078
  if (!rb_easy_nil("certpassword")) {
1804
2079
  curl_easy_setopt(curl, CURLOPT_SSLCERTPASSWD, rb_easy_get_str("certpassword"));
1805
2080
  }
2081
+ if (!rb_easy_nil("cert_key")) {
2082
+ curl_easy_setopt(curl, CURLOPT_SSLKEY, rb_easy_get_str("cert_key"));
2083
+ }
1806
2084
  }
1807
2085
  if (!rb_easy_nil("cacert")) {
1808
2086
  #ifdef HAVE_CURL_CONFIG_CA
@@ -1811,7 +2089,25 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce, struct curl_slist **hdrs ) {
1811
2089
  curl_easy_setopt(curl, CURLOPT_CAINFO, "/usr/local/share/curl/curl-ca-bundle.crt");
1812
2090
  #endif
1813
2091
  }
2092
+
2093
+ #ifdef CURL_VERSION_SSL
2094
+ if (rbce->ssl_version > 0) {
2095
+ curl_easy_setopt(curl, CURLOPT_SSLVERSION, rbce->ssl_version);
2096
+ }
2097
+
2098
+ if (rbce->use_ssl > 0) {
2099
+ curl_easy_setopt(curl, CURB_FTPSSL, rbce->use_ssl);
2100
+ }
2101
+ #else
2102
+ if (rbce->ssl_version > 0 || rbce->use_ssl > 0) {
2103
+ rb_warn("libcurl is not configured with SSL support");
2104
+ }
2105
+ #endif
1814
2106
 
2107
+ if (rbce->ftp_filemethod > 0) {
2108
+ curl_easy_setopt(curl, CURLOPT_FTP_FILEMETHOD, rbce->ftp_filemethod);
2109
+ }
2110
+
1815
2111
  /* Set the user-agent string if specified */
1816
2112
  if (!rb_easy_nil("useragent")) {
1817
2113
  curl_easy_setopt(curl, CURLOPT_USERAGENT, rb_easy_get_str("useragent"));
@@ -1833,6 +2129,17 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce, struct curl_slist **hdrs ) {
1833
2129
  }
1834
2130
  }
1835
2131
 
2132
+ /* Setup FTP commands if necessary */
2133
+ if (!rb_easy_nil("ftp_commands")) {
2134
+ if (rb_easy_type_check("ftp_commands", T_ARRAY)) {
2135
+ rb_iterate(rb_each, rb_easy_get("ftp_commands"), cb_each_ftp_command, (VALUE)cmds);
2136
+ }
2137
+
2138
+ if (*cmds) {
2139
+ curl_easy_setopt(curl, CURLOPT_QUOTE, *cmds);
2140
+ }
2141
+ }
2142
+
1836
2143
  return Qnil;
1837
2144
  }
1838
2145
  /***********************************************
@@ -1841,17 +2148,24 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce, struct curl_slist **hdrs ) {
1841
2148
  *
1842
2149
  * Always returns Qtrue.
1843
2150
  */
1844
- VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce, struct curl_slist *headers ) {
2151
+ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
1845
2152
 
1846
2153
  CURL *curl = rbce->curl;
1847
-
1848
- // Free everything up
1849
- if (headers) {
1850
- curl_slist_free_all(headers);
2154
+ struct curl_slist *ftp_commands;
2155
+
2156
+ /* Free everything up */
2157
+ if (rbce->curl_headers) {
2158
+ curl_slist_free_all(rbce->curl_headers);
1851
2159
  rbce->curl_headers = NULL;
1852
2160
  }
1853
2161
 
1854
- // clean up a PUT request's curl options.
2162
+ ftp_commands = rbce->curl_ftp_commands;
2163
+ if (ftp_commands) {
2164
+ curl_slist_free_all(ftp_commands);
2165
+ rbce->curl_ftp_commands = NULL;
2166
+ }
2167
+
2168
+ /* clean up a PUT request's curl options. */
1855
2169
  if (!rb_easy_nil("upload")) {
1856
2170
  rb_easy_del("upload"); // set the upload object to Qnil to let the GC clean up
1857
2171
  curl_easy_setopt(curl, CURLOPT_UPLOAD, 0);
@@ -1876,10 +2190,13 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce, struct curl_slis
1876
2190
  static VALUE handle_perform(VALUE self, ruby_curl_easy *rbce) {
1877
2191
 
1878
2192
  VALUE ret;
1879
- VALUE multi = ruby_curl_multi_new(cCurlMulti);
1880
2193
 
1881
- rb_funcall(multi, rb_intern("add"), 1, self );
1882
- ret = rb_funcall(multi, rb_intern("perform"), 0);
2194
+ /* reuse existing multi handle for this easy handle */
2195
+ if (NIL_P(rbce->multi)) {
2196
+ rbce->multi = ruby_curl_multi_new(cCurlMulti);
2197
+ }
2198
+ rb_funcall(rbce->multi, rb_intern("add"), 1, self );
2199
+ ret = rb_funcall(rbce->multi, rb_intern("perform"), 0);
1883
2200
 
1884
2201
  /* check for errors in the easy response and raise exceptions if anything went wrong and their is no on_failure handler */
1885
2202
  if (rbce->last_result != 0 && rb_easy_nil("failure_proc")) {
@@ -1904,20 +2221,16 @@ static VALUE ruby_curl_easy_perform_get(VALUE self) {
1904
2221
  Data_Get_Struct(self, ruby_curl_easy, rbce);
1905
2222
  curl = rbce->curl;
1906
2223
 
2224
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
1907
2225
  curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
1908
2226
 
1909
2227
  return handle_perform(self,rbce);
1910
2228
  }
1911
2229
 
1912
2230
  /*
1913
- * call-seq:
1914
- * easy.http_delete
1915
- *
1916
- * DELETE the currently configured URL using the current options set for
1917
- * this Curl::Easy instance. This method always returns true, or raises
1918
- * an exception (defined under Curl::Err) on error.
2231
+ * Common implementation of easy.http(verb) and easy.http_delete
1919
2232
  */
1920
- static VALUE ruby_curl_easy_perform_delete(VALUE self) {
2233
+ static VALUE ruby_curl_easy_perform_verb_str(VALUE self, const char *verb) {
1921
2234
  ruby_curl_easy *rbce;
1922
2235
  CURL *curl;
1923
2236
  VALUE retval;
@@ -1925,7 +2238,7 @@ static VALUE ruby_curl_easy_perform_delete(VALUE self) {
1925
2238
  Data_Get_Struct(self, ruby_curl_easy, rbce);
1926
2239
  curl = rbce->curl;
1927
2240
 
1928
- curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
2241
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, verb);
1929
2242
 
1930
2243
  retval = handle_perform(self,rbce);
1931
2244
 
@@ -1934,6 +2247,39 @@ static VALUE ruby_curl_easy_perform_delete(VALUE self) {
1934
2247
  return retval;
1935
2248
  }
1936
2249
 
2250
+ /*
2251
+ * call-seq:
2252
+ * easy.http_delete
2253
+ *
2254
+ * DELETE the currently configured URL using the current options set for
2255
+ * this Curl::Easy instance. This method always returns true, or raises
2256
+ * an exception (defined under Curl::Err) on error.
2257
+ */
2258
+ static VALUE ruby_curl_easy_perform_delete(VALUE self) {
2259
+ return ruby_curl_easy_perform_verb_str(self, "DELETE");
2260
+ }
2261
+
2262
+ /*
2263
+ * call-seq:
2264
+ * easy.http(verb)
2265
+ *
2266
+ * Send an HTTP request with method set to verb, using the current options set for this Curl::Easy instance.
2267
+ * This method always returns true or raises an exception (defined under Curl::Err) on error.
2268
+ */
2269
+ static VALUE ruby_curl_easy_perform_verb(VALUE self, VALUE verb) {
2270
+ VALUE str_verb;
2271
+ if (rb_type(verb) == T_STRING) {
2272
+ return ruby_curl_easy_perform_verb_str(self, RSTRING_PTR(verb));
2273
+ }
2274
+ else if (rb_respond_to(verb,rb_intern("to_s"))) {
2275
+ str_verb = rb_funcall(verb, rb_intern("to_s"), 0);
2276
+ return ruby_curl_easy_perform_verb_str(self, RSTRING_PTR(str_verb));
2277
+ }
2278
+ else {
2279
+ rb_raise(rb_eRuntimeError, "Invalid HTTP VERB, must response to 'to_s'");
2280
+ }
2281
+ }
2282
+
1937
2283
  /*
1938
2284
  * call-seq:
1939
2285
  * easy.perform => true
@@ -1985,6 +2331,8 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
1985
2331
  Data_Get_Struct(self, ruby_curl_easy, rbce);
1986
2332
  curl = rbce->curl;
1987
2333
 
2334
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
2335
+
1988
2336
  if (rbce->multipart_form_post) {
1989
2337
  VALUE ret;
1990
2338
  struct curl_httppost *first = NULL, *last = NULL;
@@ -2006,12 +2354,22 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
2006
2354
 
2007
2355
  return ret;
2008
2356
  } else {
2009
- VALUE post_body;
2357
+ VALUE post_body = Qnil;
2358
+ /* TODO: check for PostField.file and raise error before to_s fails */
2010
2359
  if ((post_body = rb_funcall(args_ary, idJoin, 1, rbstrAmp)) == Qnil) {
2011
2360
  rb_raise(eCurlErrError, "Failed to join arguments");
2012
2361
  return Qnil;
2013
2362
  } else {
2014
- ruby_curl_easy_post_body_set(self, post_body);
2363
+ /* if the function call above returns an empty string because no additional arguments were passed this makes sure
2364
+ a previously set easy.post_body = "arg=foo&bar=bin" will be honored */
2365
+ if( post_body != Qnil && rb_type(post_body) == T_STRING && RSTRING_LEN(post_body) > 0 ) {
2366
+ ruby_curl_easy_post_body_set(self, post_body);
2367
+ }
2368
+
2369
+ /* if post body is not defined, set it so we enable POST header, even though the request body is empty */
2370
+ if( rb_easy_nil("postdata_buffer") ) {
2371
+ ruby_curl_easy_post_body_set(self, post_body);
2372
+ }
2015
2373
 
2016
2374
  return handle_perform(self,rbce);
2017
2375
  }
@@ -2065,6 +2423,40 @@ static VALUE ruby_curl_easy_set_head_option(VALUE self, VALUE onoff) {
2065
2423
 
2066
2424
  return onoff;
2067
2425
  }
2426
+ /*
2427
+ *call-seq:
2428
+ *
2429
+ * easy = Curl::Easy.new("url")
2430
+ * easy.version = Curl::HTTP_1_1
2431
+ * easy.version = Curl::HTTP_1_0
2432
+ * easy.version = Curl::HTTP_NONE
2433
+ *
2434
+ */
2435
+ static VALUE ruby_curl_easy_set_version(VALUE self, VALUE version) {
2436
+ ruby_curl_easy *rbce;
2437
+ //fprintf(stderr,"CURL_HTTP_VERSION_1_1: %d, CURL_HTTP_VERSION_1_0: %d, CURL_HTTP_VERSION_NONE: %d\n", CURL_HTTP_VERSION_1_1, CURL_HTTP_VERSION_1_0, CURL_HTTP_VERSION_NONE);
2438
+
2439
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2440
+
2441
+ curl_easy_setopt(rbce->curl, CURLOPT_HTTP_VERSION, FIX2INT(version));
2442
+
2443
+ return version;
2444
+ }
2445
+ /*
2446
+ * call-seq:
2447
+ *
2448
+ * easy = Curl::Easy.new
2449
+ * easy.nosignal = true
2450
+ */
2451
+ static VALUE ruby_curl_easy_set_nosignal(VALUE self, VALUE onoff) {
2452
+ ruby_curl_easy *rbce;
2453
+
2454
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2455
+
2456
+ curl_easy_setopt(rbce->curl, CURLOPT_NOSIGNAL, (Qtrue == onoff) ? 1 : 0);
2457
+
2458
+ return onoff;
2459
+ }
2068
2460
  /*
2069
2461
  *call-seq:
2070
2462
  * easy = Curl::Easy.new("url") do|c|
@@ -2102,6 +2494,7 @@ static VALUE ruby_curl_easy_perform_put(VALUE self, VALUE data) {
2102
2494
  Data_Get_Struct(self, ruby_curl_easy, rbce);
2103
2495
  curl = rbce->curl;
2104
2496
 
2497
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
2105
2498
  ruby_curl_easy_put_data_set(self, data);
2106
2499
 
2107
2500
  return handle_perform(self, rbce);
@@ -2194,6 +2587,30 @@ static VALUE ruby_curl_easy_response_code_get(VALUE self) {
2194
2587
  return LONG2NUM(code);
2195
2588
  }
2196
2589
 
2590
+ #if defined(HAVE_CURLINFO_PRIMARY_IP)
2591
+ /*
2592
+ * call-seq:
2593
+ * easy.primary_ip => "xx.xx.xx.xx" or nil
2594
+ *
2595
+ * Retrieve the resolved IP of the most recent connection
2596
+ * done with this curl handle. This string may be IPv6 if
2597
+ * that's enabled. This feature requires curl 7.19.x and above
2598
+ */
2599
+ static VALUE ruby_curl_easy_primary_ip_get(VALUE self) {
2600
+ ruby_curl_easy *rbce;
2601
+ char* ip;
2602
+
2603
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2604
+ curl_easy_getinfo(rbce->curl, CURLINFO_PRIMARY_IP, &ip);
2605
+
2606
+ if (ip && ip[0]) { // curl returns empty string if none
2607
+ return rb_str_new2(ip);
2608
+ } else {
2609
+ return Qnil;
2610
+ }
2611
+ }
2612
+ #endif
2613
+
2197
2614
  /*
2198
2615
  * call-seq:
2199
2616
  * easy.http_connect_code => fixnum
@@ -2358,7 +2775,7 @@ static VALUE ruby_curl_easy_redirect_time_get(VALUE self) {
2358
2775
 
2359
2776
  /*
2360
2777
  * call-seq:
2361
- * easy.redirect_count => integer
2778
+ * easy.redirect_count => integer
2362
2779
  *
2363
2780
  * Retrieve the total number of redirections that were actually followed.
2364
2781
  *
@@ -2606,7 +3023,7 @@ static VALUE ruby_curl_easy_os_errno_get(VALUE self) {
2606
3023
 
2607
3024
  /*
2608
3025
  * call-seq:
2609
- * easy.num_connects => integer
3026
+ * easy.num_connects => integer
2610
3027
  *
2611
3028
  * Retrieve the number of new connections libcurl had to create to achieve
2612
3029
  * the previous transfer (only the successful connects are counted).
@@ -2651,7 +3068,7 @@ Pass a pointer to a long to receive the last socket used by this curl session. I
2651
3068
 
2652
3069
  /*
2653
3070
  * call-seq:
2654
- * easy.content_type => "content/type" or nil
3071
+ * easy.ftp_entry_path => "C:\ftp\root\" or nil
2655
3072
  *
2656
3073
  * Retrieve the path of the entry path. That is the initial path libcurl ended
2657
3074
  * up in when logging on to the remote FTP server. This returns +nil+ if
@@ -2680,7 +3097,7 @@ static VALUE ruby_curl_easy_ftp_entry_path_get(VALUE self) {
2680
3097
 
2681
3098
  /*
2682
3099
  * call-seq:
2683
- * easy.inspect => "#<Curl::Easy http://google.com/>"
3100
+ * easy.inspect => "#<Curl::Easy http://google.com/>"
2684
3101
  */
2685
3102
  static VALUE ruby_curl_easy_inspect(VALUE self) {
2686
3103
  char buf[64];
@@ -2693,10 +3110,10 @@ static VALUE ruby_curl_easy_inspect(VALUE self) {
2693
3110
  /* "#<Net::HTTP http://www.google.com/:80 open=false>" */
2694
3111
  memcpy(buf,"#<Curl::Easy ", 13);
2695
3112
  memcpy(buf+13,RSTRING_PTR(url), (len - 13));
2696
- buf[len-1] = '>';
3113
+ buf[len++] = '>';
2697
3114
  return rb_str_new(buf,len);
2698
3115
  }
2699
- return rb_str_new2("#<Curl::Easy");
3116
+ return rb_str_new2("#<Curl::Easy>");
2700
3117
  }
2701
3118
 
2702
3119
 
@@ -2723,9 +3140,9 @@ static VALUE ruby_curl_easy_escape(VALUE self, VALUE svalue) {
2723
3140
  if( rb_type(str) != T_STRING ) { str = rb_funcall(str,rb_intern("to_s"),0); }
2724
3141
 
2725
3142
  #if (LIBCURL_VERSION_NUM >= 0x070f04)
2726
- result = (char*)curl_easy_escape(rbce->curl, StringValuePtr(str), RSTRING_LEN(str));
3143
+ result = (char*)curl_easy_escape(rbce->curl, StringValuePtr(str), (int)RSTRING_LEN(str));
2727
3144
  #else
2728
- result = (char*)curl_escape(StringValuePtr(str), RSTRING_LEN(str));
3145
+ result = (char*)curl_escape(StringValuePtr(str), (int)RSTRING_LEN(str));
2729
3146
  #endif
2730
3147
 
2731
3148
  rresult = rb_str_new2(result);
@@ -2736,7 +3153,7 @@ static VALUE ruby_curl_easy_escape(VALUE self, VALUE svalue) {
2736
3153
 
2737
3154
  /*
2738
3155
  * call-seq:
2739
- * easy.unescape("some%20text") => "some text"
3156
+ * easy.unescape("some%20text") => "some text"
2740
3157
  *
2741
3158
  * Convert the given URL encoded input string to a "plain string" and return
2742
3159
  * the result. All input characters that are URL encoded (%XX where XX is a
@@ -2751,7 +3168,7 @@ static VALUE ruby_curl_easy_unescape(VALUE self, VALUE str) {
2751
3168
  Data_Get_Struct(self, ruby_curl_easy, rbce);
2752
3169
 
2753
3170
  #if (LIBCURL_VERSION_NUM >= 0x070f04)
2754
- result = (char*)curl_easy_unescape(rbce->curl, StringValuePtr(str), RSTRING_LEN(str), &rlen);
3171
+ result = (char*)curl_easy_unescape(rbce->curl, StringValuePtr(str), (int)RSTRING_LEN(str), &rlen);
2755
3172
  #else
2756
3173
  result = (char*)curl_unescape(StringValuePtr(str), RSTRING_LEN(str));
2757
3174
  rlen = strlen(result);
@@ -2807,7 +3224,7 @@ static VALUE ruby_curl_easy_class_perform_get(int argc, VALUE *argv, VALUE klass
2807
3224
 
2808
3225
  /*
2809
3226
  * call-seq:
2810
- * Curl::Easy.http_delete(url) { |easy| ... } => #&lt;Curl::Easy...&gt;
3227
+ * Curl::Easy.http_delete(url) { |easy| ... } => #&lt;Curl::Easy...&gt;
2811
3228
  *
2812
3229
  * Convenience method that creates a new Curl::Easy instance with
2813
3230
  * the specified URL and calls +http_delete+, before returning the new instance.
@@ -2824,7 +3241,7 @@ static VALUE ruby_curl_easy_class_perform_delete(int argc, VALUE *argv, VALUE kl
2824
3241
 
2825
3242
  /*
2826
3243
  * call-seq:
2827
- * Curl::Easy.http_head(url) { |easy| ... } => #&lt;Curl::Easy...&gt;
3244
+ * Curl::Easy.http_head(url) { |easy| ... } => #&lt;Curl::Easy...&gt;
2828
3245
  *
2829
3246
  * Convenience method that creates a new Curl::Easy instance with
2830
3247
  * the specified URL and calls +http_head+, before returning the new instance.
@@ -2916,6 +3333,8 @@ void init_curb_easy() {
2916
3333
  rb_define_method(cCurlEasy, "cookiejar", ruby_curl_easy_cookiejar_get, 0);
2917
3334
  rb_define_method(cCurlEasy, "cert=", ruby_curl_easy_cert_set, 1);
2918
3335
  rb_define_method(cCurlEasy, "cert", ruby_curl_easy_cert_get, 0);
3336
+ rb_define_method(cCurlEasy, "cert_key=", ruby_curl_easy_cert_key_set, 1);
3337
+ rb_define_method(cCurlEasy, "cert_key", ruby_curl_easy_cert_key_get, 0);
2919
3338
  rb_define_method(cCurlEasy, "cacert=", ruby_curl_easy_cacert_set, 1);
2920
3339
  rb_define_method(cCurlEasy, "cacert", ruby_curl_easy_cacert_get, 0);
2921
3340
  rb_define_method(cCurlEasy, "certpassword=", ruby_curl_easy_certpassword_set, 1);
@@ -2928,6 +3347,8 @@ void init_curb_easy() {
2928
3347
  rb_define_method(cCurlEasy, "post_body=", ruby_curl_easy_post_body_set, 1);
2929
3348
  rb_define_method(cCurlEasy, "post_body", ruby_curl_easy_post_body_get, 0);
2930
3349
  rb_define_method(cCurlEasy, "put_data=", ruby_curl_easy_put_data_set, 1);
3350
+ rb_define_method(cCurlEasy, "ftp_commands=", ruby_curl_easy_ftp_commands_set, 1);
3351
+ rb_define_method(cCurlEasy, "ftp_commands", ruby_curl_easy_ftp_commands_get, 0);
2931
3352
 
2932
3353
  rb_define_method(cCurlEasy, "local_port=", ruby_curl_easy_local_port_set, 1);
2933
3354
  rb_define_method(cCurlEasy, "local_port", ruby_curl_easy_local_port_get, 0);
@@ -2951,6 +3372,16 @@ void init_curb_easy() {
2951
3372
  rb_define_method(cCurlEasy, "dns_cache_timeout", ruby_curl_easy_dns_cache_timeout_get, 0);
2952
3373
  rb_define_method(cCurlEasy, "ftp_response_timeout=", ruby_curl_easy_ftp_response_timeout_set, 1);
2953
3374
  rb_define_method(cCurlEasy, "ftp_response_timeout", ruby_curl_easy_ftp_response_timeout_get, 0);
3375
+ rb_define_method(cCurlEasy, "low_speed_limit=", ruby_curl_easy_low_speed_limit_set, 1);
3376
+ rb_define_method(cCurlEasy, "low_speed_limit", ruby_curl_easy_low_speed_limit_get, 0);
3377
+ rb_define_method(cCurlEasy, "low_speed_time=", ruby_curl_easy_low_speed_time_set, 1);
3378
+ rb_define_method(cCurlEasy, "low_speed_time", ruby_curl_easy_low_speed_time_get, 0);
3379
+ rb_define_method(cCurlEasy, "ssl_version=", ruby_curl_easy_ssl_version_set, 1);
3380
+ rb_define_method(cCurlEasy, "ssl_version", ruby_curl_easy_ssl_version_get, 0);
3381
+ rb_define_method(cCurlEasy, "use_ssl=", ruby_curl_easy_use_ssl_set, 1);
3382
+ rb_define_method(cCurlEasy, "use_ssl", ruby_curl_easy_use_ssl_get, 0);
3383
+ rb_define_method(cCurlEasy, "ftp_filemethod=", ruby_curl_easy_ftp_filemethod_set, 1);
3384
+ rb_define_method(cCurlEasy, "ftp_filemethod", ruby_curl_easy_ftp_filemethod_get, 0);
2954
3385
 
2955
3386
  rb_define_method(cCurlEasy, "username=", ruby_curl_easy_username_set, 1);
2956
3387
  rb_define_method(cCurlEasy, "username", ruby_curl_easy_username_get, 0);
@@ -2971,6 +3402,7 @@ void init_curb_easy() {
2971
3402
  rb_define_method(cCurlEasy, "use_netrc?", ruby_curl_easy_use_netrc_q, 0);
2972
3403
  rb_define_method(cCurlEasy, "follow_location=", ruby_curl_easy_follow_location_set, 1);
2973
3404
  rb_define_method(cCurlEasy, "follow_location?", ruby_curl_easy_follow_location_q, 0);
3405
+ rb_define_method(cCurlEasy, "autoreferer=", ruby_curl_easy_autoreferer_set, 1);
2974
3406
  rb_define_method(cCurlEasy, "unrestricted_auth=", ruby_curl_easy_unrestricted_auth_set, 1);
2975
3407
  rb_define_method(cCurlEasy, "unrestricted_auth?", ruby_curl_easy_unrestricted_auth_q, 0);
2976
3408
  rb_define_method(cCurlEasy, "verbose=", ruby_curl_easy_verbose_set, 1);
@@ -2979,6 +3411,8 @@ void init_curb_easy() {
2979
3411
  rb_define_method(cCurlEasy, "multipart_form_post?", ruby_curl_easy_multipart_form_post_q, 0);
2980
3412
  rb_define_method(cCurlEasy, "enable_cookies=", ruby_curl_easy_enable_cookies_set, 1);
2981
3413
  rb_define_method(cCurlEasy, "enable_cookies?", ruby_curl_easy_enable_cookies_q, 0);
3414
+ rb_define_method(cCurlEasy, "ignore_content_length=", ruby_curl_easy_ignore_content_length_set, 1);
3415
+ rb_define_method(cCurlEasy, "ignore_content_length?", ruby_curl_easy_ignore_content_length_q, 0);
2982
3416
 
2983
3417
  rb_define_method(cCurlEasy, "on_body", ruby_curl_easy_on_body_set, -1);
2984
3418
  rb_define_method(cCurlEasy, "on_header", ruby_curl_easy_on_header_set, -1);
@@ -2989,6 +3423,7 @@ void init_curb_easy() {
2989
3423
  rb_define_method(cCurlEasy, "on_complete", ruby_curl_easy_on_complete_set, -1);
2990
3424
 
2991
3425
  rb_define_method(cCurlEasy, "perform", ruby_curl_easy_perform, 0);
3426
+ rb_define_method(cCurlEasy, "http", ruby_curl_easy_perform_verb, 1);
2992
3427
  rb_define_method(cCurlEasy, "http_delete", ruby_curl_easy_perform_delete, 0);
2993
3428
  rb_define_method(cCurlEasy, "http_get", ruby_curl_easy_perform_get, 0);
2994
3429
  rb_define_method(cCurlEasy, "http_post", ruby_curl_easy_perform_post, -1);
@@ -2996,6 +3431,11 @@ void init_curb_easy() {
2996
3431
  rb_define_method(cCurlEasy, "http_put", ruby_curl_easy_perform_put, 1);
2997
3432
  rb_define_method(cCurlEasy, "head=", ruby_curl_easy_set_head_option, 1);
2998
3433
  rb_define_method(cCurlEasy, "delete=", ruby_curl_easy_set_delete_option, 1);
3434
+ rb_define_method(cCurlEasy, "version=", ruby_curl_easy_set_version, 1);
3435
+ rb_define_const(mCurl, "HTTP_1_1", LONG2NUM(CURL_HTTP_VERSION_1_1));
3436
+ rb_define_const(mCurl, "HTTP_1_0", LONG2NUM(CURL_HTTP_VERSION_1_0));
3437
+ rb_define_const(mCurl, "HTTP_NONE", LONG2NUM(CURL_HTTP_VERSION_NONE));
3438
+ rb_define_method(cCurlEasy, "nosignal=", ruby_curl_easy_set_nosignal, 1);
2999
3439
 
3000
3440
  /* Post-perform info methods */
3001
3441
  rb_define_method(cCurlEasy, "body_str", ruby_curl_easy_body_str_get, 0);
@@ -3003,6 +3443,9 @@ void init_curb_easy() {
3003
3443
 
3004
3444
  rb_define_method(cCurlEasy, "last_effective_url", ruby_curl_easy_last_effective_url_get, 0);
3005
3445
  rb_define_method(cCurlEasy, "response_code", ruby_curl_easy_response_code_get, 0);
3446
+ #if defined(HAVE_CURLINFO_PRIMARY_IP)
3447
+ rb_define_method(cCurlEasy, "primary_ip", ruby_curl_easy_primary_ip_get, 0);
3448
+ #endif
3006
3449
  rb_define_method(cCurlEasy, "http_connect_code", ruby_curl_easy_http_connect_code_get, 0);
3007
3450
  rb_define_method(cCurlEasy, "file_time", ruby_curl_easy_file_time_get, 0);
3008
3451
  rb_define_method(cCurlEasy, "total_time", ruby_curl_easy_total_time_get, 0);
@@ -3025,7 +3468,9 @@ void init_curb_easy() {
3025
3468
  rb_define_method(cCurlEasy, "os_errno", ruby_curl_easy_os_errno_get, 0);
3026
3469
  rb_define_method(cCurlEasy, "num_connects", ruby_curl_easy_num_connects_get, 0);
3027
3470
  rb_define_method(cCurlEasy, "ftp_entry_path", ruby_curl_easy_ftp_entry_path_get, 0);
3028
- rb_define_method(cCurlEasy, "inspect", ruby_curl_easy_inspect, 0);
3471
+
3472
+ rb_define_method(cCurlEasy, "close", ruby_curl_easy_close, 0);
3473
+ rb_define_method(cCurlEasy, "reset", ruby_curl_easy_reset, 0);
3029
3474
 
3030
3475
  /* Curl utils */
3031
3476
  rb_define_method(cCurlEasy, "escape", ruby_curl_easy_escape, 1);
@@ -3034,4 +3479,5 @@ void init_curb_easy() {
3034
3479
  /* Runtime support */
3035
3480
  rb_define_method(cCurlEasy, "clone", ruby_curl_easy_clone, 0);
3036
3481
  rb_define_alias(cCurlEasy, "dup", "clone");
3482
+ rb_define_method(cCurlEasy, "inspect", ruby_curl_easy_inspect, 0);
3037
3483
  }