curb 0.9.6 → 0.9.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.markdown +27 -7
- data/Rakefile +26 -10
- data/ext/banned.h +32 -0
- data/ext/curb.c +20 -0
- data/ext/curb.h +12 -4
- data/ext/curb_easy.c +250 -19
- data/ext/curb_easy.h +3 -0
- data/ext/curb_errors.c +7 -0
- data/ext/curb_multi.c +126 -161
- data/ext/curb_multi.h +0 -1
- data/ext/extconf.rb +12 -0
- data/lib/curb.rb +1 -0
- data/lib/curl.rb +5 -6
- data/lib/curl/easy.rb +7 -1
- data/lib/curl/multi.rb +42 -3
- data/tests/bug_issue277.rb +32 -0
- data/tests/helper.rb +80 -1
- data/tests/tc_curl.rb +30 -0
- data/tests/tc_curl_easy.rb +110 -16
- data/tests/tc_curl_maxfilesize.rb +12 -0
- data/tests/tc_curl_multi.rb +68 -5
- data/tests/tc_curl_postfield.rb +29 -29
- metadata +12 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ecd73a0ad8d98960321b8d523e25bad95ff25e8900e8acb187051ca40c7a1cba
|
4
|
+
data.tar.gz: c154996d92946fe83fa12d695b073d5026e4a55e92efd177bfad021461f2b313
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48854a4f0d77befe0e81b31a3d39e826b2ef65d58d0226b617a355ba8d063ab4998853a8709ae6d2e3c4629c09ff987099398a1c884b76d95dcf956d941fc660
|
7
|
+
data.tar.gz: 3291675a74eb40f42d936bb65689da7d5f295e038ed019482d2cf115ba878232ce4e40aeb125d0fe786b5e82428320938ff3c75592a5c54a2d51fbe8589a0931
|
data/README.markdown
CHANGED
@@ -7,7 +7,7 @@ Curb (probably CUrl-RuBy or something) provides Ruby-language bindings for the
|
|
7
7
|
libcurl(3), a fully-featured client-side URL transfer library.
|
8
8
|
cURL and libcurl live at [http://curl.haxx.se/](http://curl.haxx.se/) .
|
9
9
|
|
10
|
-
Curb is a work-in-progress, and currently only supports libcurl's
|
10
|
+
Curb is a work-in-progress, and currently only supports libcurl's `easy` and `multi` modes.
|
11
11
|
|
12
12
|
## License
|
13
13
|
|
@@ -16,10 +16,26 @@ Ruby license. See the LICENSE file for the gory details.
|
|
16
16
|
|
17
17
|
## You will need
|
18
18
|
|
19
|
-
* A working Ruby installation (1.8
|
20
|
-
* A working
|
19
|
+
* A working Ruby installation (`1.8.7+` will work but `2.1+` preferred)
|
20
|
+
* A working libcurl development installation
|
21
|
+
(Ideally one of the versions listed in the compatibility chart below that maps to your `curb` version)
|
21
22
|
* A sane build environment (e.g. gcc, make)
|
22
23
|
|
24
|
+
## Version Compatibility chart
|
25
|
+
|
26
|
+
A **non-exhaustive** set of compatibility versions of the libcurl library
|
27
|
+
with this gem are as follows. (Note that these are only the ones that have been
|
28
|
+
tested and reported to work across a variety of platforms / rubies)
|
29
|
+
|
30
|
+
| Gem Version | Release Date | libcurl versions |
|
31
|
+
| ----------- | ----------- | ---------------- |
|
32
|
+
| 0.9.8 | Jan 2019 | 7.58 - 7.63 |
|
33
|
+
| 0.9.7 | Nov 2018 | 7.56 - 7.60 |
|
34
|
+
| 0.9.6 | May 2018 | 7.51 - 7.59 |
|
35
|
+
| 0.9.5 | May 2018 | 7.51 - 7.59 |
|
36
|
+
| 0.9.4 | Aug 2017 | 7.41 - 7.58 |
|
37
|
+
| 0.9.3 | Apr 2016 | 7.26 - 7.58 |
|
38
|
+
|
23
39
|
## Installation...
|
24
40
|
|
25
41
|
... will usually be as simple as:
|
@@ -30,7 +46,11 @@ On Windows, make sure you're using the [DevKit](http://rubyinstaller.org/downloa
|
|
30
46
|
the [development version of libcurl](http://curl.haxx.se/gknw.net/7.39.0/dist-w32/curl-7.39.0-devel-mingw32.zip). Unzip, then run this in your command
|
31
47
|
line (alter paths to your curl location, but remember to use forward slashes):
|
32
48
|
|
33
|
-
gem install curb --platform=ruby -- --with-curl-lib=C:/curl-7.39.0-devel-mingw32/
|
49
|
+
gem install curb --platform=ruby -- --with-curl-lib=C:/curl-7.39.0-devel-mingw32/lib --with-curl-include=C:/curl-7.39.0-devel-mingw32/include
|
50
|
+
|
51
|
+
Note that with Windows moving from one method of compiling to another as of Ruby `2.4` (DevKit -> MYSYS2),
|
52
|
+
the usage of Ruby `2.4+` with this gem on windows is unlikely to work. It is advised to use the
|
53
|
+
latest version of Ruby 2.3 available [HERE](https://dl.bintray.com/oneclick/rubyinstaller/rubyinstaller-2.3.3.exe)
|
34
54
|
|
35
55
|
Or, if you downloaded the archive:
|
36
56
|
|
@@ -134,9 +154,9 @@ c.perform
|
|
134
154
|
### HTTP "insecure" SSL connections (like curl -k, --insecure) to avoid Curl::Err::SSLCACertificateError:
|
135
155
|
|
136
156
|
```ruby
|
137
|
-
|
138
|
-
|
139
|
-
|
157
|
+
c = Curl::Easy.new("https://github.com/")
|
158
|
+
c.ssl_verify_peer = false
|
159
|
+
c.perform
|
140
160
|
```
|
141
161
|
|
142
162
|
### Supplying custom handlers:
|
data/Rakefile
CHANGED
@@ -2,11 +2,6 @@
|
|
2
2
|
#
|
3
3
|
require 'rake/clean'
|
4
4
|
require 'rake/testtask'
|
5
|
-
begin
|
6
|
-
require 'rdoc/task'
|
7
|
-
rescue LoadError => e
|
8
|
-
require 'rake/rdoctask'
|
9
|
-
end
|
10
5
|
|
11
6
|
CLEAN.include '**/*.o'
|
12
7
|
CLEAN.include "**/*.#{(defined?(RbConfig) ? RbConfig : Config)::MAKEFILE_CONFIG['DLEXT']}"
|
@@ -15,6 +10,22 @@ CLOBBER.include '**/*.log'
|
|
15
10
|
CLOBBER.include '**/Makefile'
|
16
11
|
CLOBBER.include '**/extconf.h'
|
17
12
|
|
13
|
+
# Not available for really old rubies, but that's ok.
|
14
|
+
begin
|
15
|
+
require 'pry'
|
16
|
+
rescue LoadError
|
17
|
+
puts "Failed to load pry."
|
18
|
+
end
|
19
|
+
|
20
|
+
# Load support ruby and rake files (in this order)
|
21
|
+
Dir.glob('tasks/*.rb').each { |r| load r}
|
22
|
+
Dir.glob('tasks/*.rake').each { |r| load r}
|
23
|
+
|
24
|
+
desc 'Print Ruby major version (ie "2_5")'
|
25
|
+
task :ruby_version do
|
26
|
+
print current_ruby_major
|
27
|
+
end
|
28
|
+
|
18
29
|
def announce(msg='')
|
19
30
|
$stderr.puts msg
|
20
31
|
end
|
@@ -43,12 +54,11 @@ end
|
|
43
54
|
make_program = (/mswin/ =~ RUBY_PLATFORM) ? 'nmake' : 'make'
|
44
55
|
MAKECMD = ENV['MAKE_CMD'] || make_program
|
45
56
|
MAKEOPTS = ENV['MAKE_OPTS'] || ''
|
46
|
-
|
47
57
|
CURB_SO = "ext/curb_core.#{(defined?(RbConfig) ? RbConfig : Config)::MAKEFILE_CONFIG['DLEXT']}"
|
48
58
|
|
49
59
|
file 'ext/Makefile' => 'ext/extconf.rb' do
|
50
60
|
Dir.chdir('ext') do
|
51
|
-
ruby
|
61
|
+
shell('ruby', 'extconf.rb', ENV['EXTCONF_OPTS'].to_s, live_stdout: STDOUT)
|
52
62
|
end
|
53
63
|
end
|
54
64
|
|
@@ -89,12 +99,12 @@ if ENV['RELTEST']
|
|
89
99
|
else
|
90
100
|
task :alltests => [:unittests, :bugtests]
|
91
101
|
end
|
92
|
-
|
102
|
+
|
93
103
|
Rake::TestTask.new(:unittests) do |t|
|
94
104
|
t.test_files = FileList['tests/tc_*.rb']
|
95
105
|
t.verbose = false
|
96
106
|
end
|
97
|
-
|
107
|
+
|
98
108
|
Rake::TestTask.new(:bugtests) do |t|
|
99
109
|
t.test_files = FileList['tests/bug_*.rb']
|
100
110
|
t.verbose = false
|
@@ -136,6 +146,12 @@ end
|
|
136
146
|
|
137
147
|
desc "Publish the RDoc documentation to project web site"
|
138
148
|
task :doc_upload => [ :doc ] do
|
149
|
+
begin
|
150
|
+
require 'rdoc/task'
|
151
|
+
rescue LoadError => e
|
152
|
+
require 'rake/rdoctask'
|
153
|
+
end
|
154
|
+
|
139
155
|
if ENV['RELTEST']
|
140
156
|
announce "Release Task Testing, skipping doc upload"
|
141
157
|
else
|
@@ -170,7 +186,7 @@ else
|
|
170
186
|
spec_source = File.read File.join(File.dirname(__FILE__),'curb.gemspec')
|
171
187
|
spec = nil
|
172
188
|
# see: http://gist.github.com/16215
|
173
|
-
Thread.new { spec = eval("
|
189
|
+
Thread.new { spec = eval("#{spec_source}") }.join
|
174
190
|
spec.validate
|
175
191
|
Gem::Package.build(spec)
|
176
192
|
end
|
data/ext/banned.h
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#ifndef BANNED_H
|
2
|
+
#define BANNED_H
|
3
|
+
|
4
|
+
/*
|
5
|
+
* This header lists functions that have been banned from our code base,
|
6
|
+
* because they're too easy to misuse (and even if used correctly,
|
7
|
+
* complicate audits). Including this header turns them into compile-time
|
8
|
+
* errors.
|
9
|
+
*/
|
10
|
+
|
11
|
+
#define BANNED(func) sorry_##func##_is_a_banned_function
|
12
|
+
|
13
|
+
#undef strcpy
|
14
|
+
#define strcpy(x,y) BANNED(strcpy)
|
15
|
+
#undef strcat
|
16
|
+
#define strcat(x,y) BANNED(strcat)
|
17
|
+
#undef strncpy
|
18
|
+
#define strncpy(x,y,n) BANNED(strncpy)
|
19
|
+
#undef strncat
|
20
|
+
#define strncat(x,y,n) BANNED(strncat)
|
21
|
+
|
22
|
+
#undef sprintf
|
23
|
+
#undef vsprintf
|
24
|
+
#ifdef HAVE_VARIADIC_MACROS
|
25
|
+
#define sprintf(...) BANNED(sprintf)
|
26
|
+
#define vsprintf(...) BANNED(vsprintf)
|
27
|
+
#else
|
28
|
+
#define sprintf(buf,fmt,arg) BANNED(sprintf)
|
29
|
+
#define vsprintf(buf,fmt,arg) BANNED(sprintf)
|
30
|
+
#endif
|
31
|
+
|
32
|
+
#endif /* BANNED_H */
|
data/ext/curb.c
CHANGED
@@ -352,6 +352,13 @@ void Init_curb_core() {
|
|
352
352
|
rb_define_const(mCurl, "CURLPROXY_SOCKS5", LONG2NUM(-2));
|
353
353
|
#endif
|
354
354
|
|
355
|
+
/* When passed to Curl::Easy#proxy_type , indicates that the proxy is a SOCKS5 proxy (and that the proxy should resolve the hostname). (libcurl >= 7.17.2) */
|
356
|
+
#ifdef HAVE_CURLPROXY_SOCKS5_HOSTNAME
|
357
|
+
rb_define_const(mCurl, "CURLPROXY_SOCKS5_HOSTNAME", LONG2NUM(CURLPROXY_SOCKS5_HOSTNAME));
|
358
|
+
#else
|
359
|
+
rb_define_const(mCurl, "CURLPROXY_SOCKS5_HOSTNAME", LONG2NUM(-2));
|
360
|
+
#endif
|
361
|
+
|
355
362
|
/* When passed to Curl::Easy#http_auth_types or Curl::Easy#proxy_auth_types, directs libcurl to use Basic authentication. */
|
356
363
|
#ifdef HAVE_CURLAUTH_BASIC
|
357
364
|
rb_define_const(mCurl, "CURLAUTH_BASIC", LONG2NUM(CURLAUTH_BASIC));
|
@@ -585,6 +592,9 @@ void Init_curb_core() {
|
|
585
592
|
CURB_DEFINE(CURLOPT_REFERER);
|
586
593
|
CURB_DEFINE(CURLOPT_USERAGENT);
|
587
594
|
CURB_DEFINE(CURLOPT_HTTPHEADER);
|
595
|
+
#if HAVE_CURLOPT_PROXYHEADER
|
596
|
+
CURB_DEFINE(CURLOPT_PROXYHEADER);
|
597
|
+
#endif
|
588
598
|
#if HAVE_CURLOPT_HTTP200ALIASES
|
589
599
|
CURB_DEFINE(CURLOPT_HTTP200ALIASES);
|
590
600
|
#endif
|
@@ -1030,6 +1040,16 @@ void Init_curb_core() {
|
|
1030
1040
|
CURB_DEFINE(CURLOPT_PIPEWAIT);
|
1031
1041
|
#endif
|
1032
1042
|
|
1043
|
+
#if HAVE_CURLOPT_TCP_KEEPALIVE
|
1044
|
+
CURB_DEFINE(CURLOPT_TCP_KEEPALIVE);
|
1045
|
+
CURB_DEFINE(CURLOPT_TCP_KEEPIDLE);
|
1046
|
+
CURB_DEFINE(CURLOPT_TCP_KEEPINTVL);
|
1047
|
+
#endif
|
1048
|
+
|
1049
|
+
#if HAVE_CURLOPT_HAPROXYPROTOCOL
|
1050
|
+
CURB_DEFINE(CURLOPT_HAPROXYPROTOCOL);
|
1051
|
+
#endif
|
1052
|
+
|
1033
1053
|
#if LIBCURL_VERSION_NUM >= 0x072B00 /* 7.43.0 */
|
1034
1054
|
CURB_DEFINE(CURLPIPE_NOTHING);
|
1035
1055
|
CURB_DEFINE(CURLPIPE_HTTP1);
|
data/ext/curb.h
CHANGED
@@ -9,8 +9,16 @@
|
|
9
9
|
#define __CURB_H
|
10
10
|
|
11
11
|
#include <ruby.h>
|
12
|
+
|
13
|
+
#ifdef HAVE_RUBY_IO_H
|
14
|
+
#include "ruby/io.h"
|
15
|
+
#else
|
16
|
+
#include "rubyio.h" // ruby 1.8
|
17
|
+
#endif
|
18
|
+
|
12
19
|
#include <curl/curl.h>
|
13
20
|
|
21
|
+
#include "banned.h"
|
14
22
|
#include "curb_config.h"
|
15
23
|
#include "curb_easy.h"
|
16
24
|
#include "curb_errors.h"
|
@@ -20,11 +28,11 @@
|
|
20
28
|
#include "curb_macros.h"
|
21
29
|
|
22
30
|
// These should be managed from the Rake 'release' task.
|
23
|
-
#define CURB_VERSION "0.9.
|
24
|
-
#define CURB_VER_NUM
|
31
|
+
#define CURB_VERSION "0.9.11"
|
32
|
+
#define CURB_VER_NUM 9011
|
25
33
|
#define CURB_VER_MAJ 0
|
26
|
-
#define CURB_VER_MIN
|
27
|
-
#define CURB_VER_MIC
|
34
|
+
#define CURB_VER_MIN 9
|
35
|
+
#define CURB_VER_MIC 11
|
28
36
|
#define CURB_VER_PATCH 0
|
29
37
|
|
30
38
|
|
data/ext/curb_easy.c
CHANGED
@@ -25,6 +25,12 @@ static VALUE rbstrAmp;
|
|
25
25
|
|
26
26
|
VALUE cCurlEasy;
|
27
27
|
|
28
|
+
// for Ruby 1.8
|
29
|
+
#ifndef HAVE_RB_IO_STDIO_FILE
|
30
|
+
static FILE * rb_io_stdio_file(rb_io_t *fptr) {
|
31
|
+
return fptr->f;
|
32
|
+
}
|
33
|
+
#endif
|
28
34
|
|
29
35
|
/* ================== CURL HANDLER FUNCS ==============*/
|
30
36
|
|
@@ -223,6 +229,10 @@ static void ruby_curl_easy_free(ruby_curl_easy *rbce) {
|
|
223
229
|
curl_slist_free_all(rbce->curl_headers);
|
224
230
|
}
|
225
231
|
|
232
|
+
if (rbce->curl_proxy_headers) {
|
233
|
+
curl_slist_free_all(rbce->curl_proxy_headers);
|
234
|
+
}
|
235
|
+
|
226
236
|
if (rbce->curl_ftp_commands) {
|
227
237
|
curl_slist_free_all(rbce->curl_ftp_commands);
|
228
238
|
}
|
@@ -243,6 +253,7 @@ static void ruby_curl_easy_free(ruby_curl_easy *rbce) {
|
|
243
253
|
curl_easy_setopt(rbce->curl, CURLOPT_PROGRESSFUNCTION, NULL);
|
244
254
|
curl_easy_setopt(rbce->curl, CURLOPT_NOPROGRESS, 1);
|
245
255
|
curl_easy_cleanup(rbce->curl);
|
256
|
+
rbce->curl = NULL;
|
246
257
|
}
|
247
258
|
}
|
248
259
|
|
@@ -258,6 +269,7 @@ static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
|
258
269
|
rbce->opts = rb_hash_new();
|
259
270
|
|
260
271
|
rbce->curl_headers = NULL;
|
272
|
+
rbce->curl_proxy_headers = NULL;
|
261
273
|
rbce->curl_ftp_commands = NULL;
|
262
274
|
rbce->curl_resolve = NULL;
|
263
275
|
|
@@ -277,6 +289,8 @@ static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
|
277
289
|
rbce->ftp_response_timeout = 0;
|
278
290
|
rbce->low_speed_limit = 0;
|
279
291
|
rbce->low_speed_time = 0;
|
292
|
+
rbce->max_send_speed_large = 0;
|
293
|
+
rbce->max_recv_speed_large = 0;
|
280
294
|
rbce->ssl_version = -1;
|
281
295
|
rbce->use_ssl = -1;
|
282
296
|
rbce->ftp_filemethod = -1;
|
@@ -343,7 +357,8 @@ static VALUE ruby_curl_easy_initialize(int argc, VALUE *argv, VALUE self) {
|
|
343
357
|
|
344
358
|
rb_easy_set("url", url);
|
345
359
|
|
346
|
-
|
360
|
+
|
361
|
+
/* set the pointer to the curl handle */
|
347
362
|
ecode = curl_easy_setopt(rbce->curl, CURLOPT_PRIVATE, (void*)self);
|
348
363
|
if (ecode != CURLE_OK) {
|
349
364
|
raise_curl_easy_error_exception(ecode);
|
@@ -373,6 +388,7 @@ static VALUE ruby_curl_easy_clone(VALUE self) {
|
|
373
388
|
memcpy(newrbce, rbce, sizeof(ruby_curl_easy));
|
374
389
|
newrbce->curl = curl_easy_duphandle(rbce->curl);
|
375
390
|
newrbce->curl_headers = NULL;
|
391
|
+
newrbce->curl_proxy_headers = NULL;
|
376
392
|
newrbce->curl_ftp_commands = NULL;
|
377
393
|
newrbce->curl_resolve = NULL;
|
378
394
|
|
@@ -457,6 +473,12 @@ static VALUE ruby_curl_easy_reset(VALUE self) {
|
|
457
473
|
rbce->curl_headers = NULL;
|
458
474
|
}
|
459
475
|
|
476
|
+
/* Free everything up */
|
477
|
+
if (rbce->curl_proxy_headers) {
|
478
|
+
curl_slist_free_all(rbce->curl_proxy_headers);
|
479
|
+
rbce->curl_proxy_headers = NULL;
|
480
|
+
}
|
481
|
+
|
460
482
|
return opts_dup;
|
461
483
|
}
|
462
484
|
|
@@ -509,6 +531,10 @@ static VALUE ruby_curl_easy_headers_set(VALUE self, VALUE headers) {
|
|
509
531
|
CURB_OBJECT_HSETTER(ruby_curl_easy, headers);
|
510
532
|
}
|
511
533
|
|
534
|
+
static VALUE ruby_curl_easy_proxy_headers_set(VALUE self, VALUE proxy_headers) {
|
535
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, proxy_headers);
|
536
|
+
}
|
537
|
+
|
512
538
|
/*
|
513
539
|
* call-seq:
|
514
540
|
* easy.headers => Hash, Array or Str
|
@@ -524,6 +550,41 @@ static VALUE ruby_curl_easy_headers_get(VALUE self) {
|
|
524
550
|
return headers;
|
525
551
|
}
|
526
552
|
|
553
|
+
/*
|
554
|
+
* call-seq:
|
555
|
+
* easy.proxy_headers = "Header: val" => "Header: val"
|
556
|
+
* easy.proxy_headers = {"Header" => "val" ..., "Header" => "val"} => {"Header: val", ...}
|
557
|
+
* easy.proxy_headers = ["Header: val" ..., "Header: val"] => ["Header: val", ...]
|
558
|
+
*
|
559
|
+
*
|
560
|
+
* For example to set a standard or custom header:
|
561
|
+
*
|
562
|
+
* easy.proxy_headers["MyHeader"] = "myval"
|
563
|
+
*
|
564
|
+
* To remove a standard header (this is useful when removing libcurls default
|
565
|
+
* 'Expect: 100-Continue' header when using HTTP form posts):
|
566
|
+
*
|
567
|
+
* easy.proxy_headers["Expect"] = ''
|
568
|
+
*
|
569
|
+
* Anything passed to libcurl as a header will be converted to a string during
|
570
|
+
* the perform step.
|
571
|
+
*/
|
572
|
+
|
573
|
+
/*
|
574
|
+
* call-seq:
|
575
|
+
* easy.proxy_headers => Hash, Array or Str
|
576
|
+
*
|
577
|
+
* Obtain the custom HTTP proxy_headers for following requests.
|
578
|
+
*/
|
579
|
+
static VALUE ruby_curl_easy_proxy_headers_get(VALUE self) {
|
580
|
+
ruby_curl_easy *rbce;
|
581
|
+
VALUE proxy_headers;
|
582
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
583
|
+
proxy_headers = rb_easy_get("proxy_headers");//rb_hash_aref(rbce->opts, rb_intern("proxy_headers"));
|
584
|
+
if (proxy_headers == Qnil) { proxy_headers = rb_easy_set("proxy_headers", rb_hash_new()); }
|
585
|
+
return proxy_headers;
|
586
|
+
}
|
587
|
+
|
527
588
|
/*
|
528
589
|
* call-seq:
|
529
590
|
* easy.interface => string
|
@@ -1139,7 +1200,7 @@ static VALUE ruby_curl_easy_max_redirects_get(VALUE self) {
|
|
1139
1200
|
|
1140
1201
|
/*
|
1141
1202
|
* call-seq:
|
1142
|
-
* easy.timeout = fixnum or nil
|
1203
|
+
* easy.timeout = float, fixnum or nil => numeric
|
1143
1204
|
*
|
1144
1205
|
* Set the maximum time in seconds that you allow the libcurl transfer
|
1145
1206
|
* operation to take. Normally, name lookups can take a considerable time
|
@@ -1148,20 +1209,39 @@ static VALUE ruby_curl_easy_max_redirects_get(VALUE self) {
|
|
1148
1209
|
*
|
1149
1210
|
* Set to nil (or zero) to disable timeout (it will then only timeout
|
1150
1211
|
* on the system's internal timeouts).
|
1212
|
+
*
|
1213
|
+
* Uses timeout_ms internally instead of timeout because it allows for
|
1214
|
+
* better precision and libcurl will use the last set value when both
|
1215
|
+
* timeout and timeout_ms are set.
|
1216
|
+
*
|
1151
1217
|
*/
|
1152
|
-
static VALUE ruby_curl_easy_timeout_set(VALUE self, VALUE
|
1153
|
-
|
1218
|
+
static VALUE ruby_curl_easy_timeout_set(VALUE self, VALUE timeout_s) {
|
1219
|
+
ruby_curl_easy *rbce;
|
1220
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
1221
|
+
|
1222
|
+
if (Qnil == timeout_s || NUM2DBL(timeout_s) <= 0.0) {
|
1223
|
+
rbce->timeout_ms = 0;
|
1224
|
+
} else {
|
1225
|
+
rbce->timeout_ms = (unsigned long)(NUM2DBL(timeout_s) * 1000);
|
1226
|
+
}
|
1227
|
+
|
1228
|
+
return DBL2NUM(rbce->timeout_ms / 1000.0);
|
1154
1229
|
}
|
1155
1230
|
|
1156
1231
|
/*
|
1157
1232
|
* call-seq:
|
1158
|
-
* easy.timeout =>
|
1233
|
+
* easy.timeout => numeric
|
1159
1234
|
*
|
1160
1235
|
* Obtain the maximum time in seconds that you allow the libcurl transfer
|
1161
1236
|
* operation to take.
|
1237
|
+
*
|
1238
|
+
* Uses timeout_ms internally instead of timeout.
|
1239
|
+
*
|
1162
1240
|
*/
|
1163
|
-
static VALUE ruby_curl_easy_timeout_get(VALUE self
|
1164
|
-
|
1241
|
+
static VALUE ruby_curl_easy_timeout_get(VALUE self) {
|
1242
|
+
ruby_curl_easy *rbce;
|
1243
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
1244
|
+
return DBL2NUM(rbce->timeout_ms / 1000.0);
|
1165
1245
|
}
|
1166
1246
|
|
1167
1247
|
/*
|
@@ -1177,7 +1257,16 @@ static VALUE ruby_curl_easy_timeout_get(VALUE self, VALUE timeout) {
|
|
1177
1257
|
* on the system's internal timeouts).
|
1178
1258
|
*/
|
1179
1259
|
static VALUE ruby_curl_easy_timeout_ms_set(VALUE self, VALUE timeout_ms) {
|
1180
|
-
|
1260
|
+
ruby_curl_easy *rbce;
|
1261
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
1262
|
+
|
1263
|
+
if (Qnil == timeout_ms || NUM2DBL(timeout_ms) <= 0.0) {
|
1264
|
+
rbce->timeout_ms = 0;
|
1265
|
+
} else {
|
1266
|
+
rbce->timeout_ms = NUM2ULONG(timeout_ms);
|
1267
|
+
}
|
1268
|
+
|
1269
|
+
return ULONG2NUM(rbce->timeout_ms);
|
1181
1270
|
}
|
1182
1271
|
|
1183
1272
|
/*
|
@@ -1187,8 +1276,10 @@ static VALUE ruby_curl_easy_timeout_ms_set(VALUE self, VALUE timeout_ms) {
|
|
1187
1276
|
* Obtain the maximum time in milliseconds that you allow the libcurl transfer
|
1188
1277
|
* operation to take.
|
1189
1278
|
*/
|
1190
|
-
static VALUE ruby_curl_easy_timeout_ms_get(VALUE self
|
1191
|
-
|
1279
|
+
static VALUE ruby_curl_easy_timeout_ms_get(VALUE self) {
|
1280
|
+
ruby_curl_easy *rbce;
|
1281
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
1282
|
+
return LONG2NUM(rbce->timeout_ms);
|
1192
1283
|
}
|
1193
1284
|
|
1194
1285
|
/*
|
@@ -1338,6 +1429,46 @@ static VALUE ruby_curl_easy_low_speed_time_get(VALUE self, VALUE low_speed_time)
|
|
1338
1429
|
CURB_IMMED_GETTER(ruby_curl_easy, low_speed_time, 0);
|
1339
1430
|
}
|
1340
1431
|
|
1432
|
+
/*
|
1433
|
+
* call-seq:
|
1434
|
+
* easy.max_send_speed_large = fixnum or nil => fixnum or nil
|
1435
|
+
*
|
1436
|
+
* Set the maximal sending transfer speed (in bytes per second)
|
1437
|
+
*/
|
1438
|
+
static VALUE ruby_curl_easy_max_send_speed_large_set(VALUE self, VALUE max_send_speed_large) {
|
1439
|
+
CURB_IMMED_SETTER(ruby_curl_easy, max_send_speed_large, 0);
|
1440
|
+
}
|
1441
|
+
|
1442
|
+
/*
|
1443
|
+
* call-seq:
|
1444
|
+
* easy.max_send_speed_large = fixnum or nil => fixnum or nil
|
1445
|
+
*
|
1446
|
+
* Get the maximal sending transfer speed (in bytes per second)
|
1447
|
+
*/
|
1448
|
+
static VALUE ruby_curl_easy_max_send_speed_large_get(VALUE self, VALUE max_send_speed_large) {
|
1449
|
+
CURB_IMMED_GETTER(ruby_curl_easy, max_send_speed_large, 0);
|
1450
|
+
}
|
1451
|
+
|
1452
|
+
/*
|
1453
|
+
* call-seq:
|
1454
|
+
* easy.max_recv_speed_large = fixnum or nil => fixnum or nil
|
1455
|
+
*
|
1456
|
+
* Set the maximal receiving transfer speed (in bytes per second)
|
1457
|
+
*/
|
1458
|
+
static VALUE ruby_curl_easy_max_recv_speed_large_set(VALUE self, VALUE max_recv_speed_large) {
|
1459
|
+
CURB_IMMED_SETTER(ruby_curl_easy, max_recv_speed_large, 0);
|
1460
|
+
}
|
1461
|
+
|
1462
|
+
/*
|
1463
|
+
* call-seq:
|
1464
|
+
* easy.max_recv_speed_large = fixnum or nil => fixnum or nil
|
1465
|
+
*
|
1466
|
+
* Get the maximal receiving transfer speed (in bytes per second)
|
1467
|
+
*/
|
1468
|
+
static VALUE ruby_curl_easy_max_recv_speed_large_get(VALUE self, VALUE max_recv_speed_large) {
|
1469
|
+
CURB_IMMED_GETTER(ruby_curl_easy, max_recv_speed_large, 0);
|
1470
|
+
}
|
1471
|
+
|
1341
1472
|
/*
|
1342
1473
|
* call-seq:
|
1343
1474
|
* easy.username = string => string
|
@@ -2012,6 +2143,38 @@ static VALUE cb_each_http_header(VALUE header, VALUE wrap) {
|
|
2012
2143
|
return header_str;
|
2013
2144
|
}
|
2014
2145
|
|
2146
|
+
/***********************************************
|
2147
|
+
* This is an rb_iterate callback used to set up http proxy headers.
|
2148
|
+
*/
|
2149
|
+
static VALUE cb_each_http_proxy_header(VALUE proxy_header, VALUE wrap) {
|
2150
|
+
struct curl_slist **list;
|
2151
|
+
VALUE proxy_header_str = Qnil;
|
2152
|
+
|
2153
|
+
Data_Get_Struct(wrap, struct curl_slist *, list);
|
2154
|
+
|
2155
|
+
//rb_p(proxy_header);
|
2156
|
+
|
2157
|
+
if (rb_type(proxy_header) == T_ARRAY) {
|
2158
|
+
// we're processing a hash, proxy header is [name, val]
|
2159
|
+
VALUE name, value;
|
2160
|
+
|
2161
|
+
name = rb_obj_as_string(rb_ary_entry(proxy_header, 0));
|
2162
|
+
value = rb_obj_as_string(rb_ary_entry(proxy_header, 1));
|
2163
|
+
|
2164
|
+
// This is a bit inefficient, but we don't want to be modifying
|
2165
|
+
// the actual values in the original hash.
|
2166
|
+
proxy_header_str = rb_str_plus(name, rb_str_new2(": "));
|
2167
|
+
proxy_header_str = rb_str_plus(proxy_header_str, value);
|
2168
|
+
} else {
|
2169
|
+
proxy_header_str = rb_obj_as_string(proxy_header);
|
2170
|
+
}
|
2171
|
+
|
2172
|
+
//rb_p(header_str);
|
2173
|
+
|
2174
|
+
*list = curl_slist_append(*list, StringValuePtr(proxy_header_str));
|
2175
|
+
return proxy_header_str;
|
2176
|
+
}
|
2177
|
+
|
2015
2178
|
/***********************************************
|
2016
2179
|
* This is an rb_iterate callback used to set up ftp commands.
|
2017
2180
|
*/
|
@@ -2051,6 +2214,7 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
2051
2214
|
CURL *curl;
|
2052
2215
|
VALUE url, _url = rb_easy_get("url");
|
2053
2216
|
struct curl_slist **hdrs = &(rbce->curl_headers);
|
2217
|
+
struct curl_slist **phdrs = &(rbce->curl_proxy_headers);
|
2054
2218
|
struct curl_slist **cmds = &(rbce->curl_ftp_commands);
|
2055
2219
|
struct curl_slist **rslv = &(rbce->curl_resolve);
|
2056
2220
|
|
@@ -2061,7 +2225,6 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
2061
2225
|
}
|
2062
2226
|
|
2063
2227
|
url = rb_check_string_type(_url);
|
2064
|
-
|
2065
2228
|
curl_easy_setopt(curl, CURLOPT_URL, StringValuePtr(url));
|
2066
2229
|
|
2067
2230
|
// network stuff and auth
|
@@ -2174,15 +2337,14 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
2174
2337
|
|
2175
2338
|
curl_easy_setopt(curl, CURLOPT_UNRESTRICTED_AUTH, rbce->unrestricted_auth);
|
2176
2339
|
|
2177
|
-
|
2178
|
-
|
2179
|
-
|
2180
|
-
|
2181
|
-
if (rbce->timeout_ms && rbce->timeout_ms > 0) {
|
2182
|
-
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, rbce->timeout_ms);
|
2183
|
-
}
|
2340
|
+
#if HAVE_CURLOPT_TIMEOUT_MS
|
2341
|
+
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, rbce->timeout_ms);
|
2342
|
+
#endif
|
2343
|
+
|
2184
2344
|
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, rbce->connect_timeout);
|
2345
|
+
#if HAVE_CURLOPT_CONNECTTIMEOUT_MS
|
2185
2346
|
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, rbce->connect_timeout_ms);
|
2347
|
+
#endif
|
2186
2348
|
curl_easy_setopt(curl, CURLOPT_DNS_CACHE_TIMEOUT, rbce->dns_cache_timeout);
|
2187
2349
|
|
2188
2350
|
curl_easy_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, rbce->ignore_content_length);
|
@@ -2201,6 +2363,9 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
2201
2363
|
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, rbce->low_speed_limit);
|
2202
2364
|
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, rbce->low_speed_time);
|
2203
2365
|
|
2366
|
+
curl_easy_setopt(curl, CURLOPT_MAX_RECV_SPEED_LARGE, rbce->max_recv_speed_large);
|
2367
|
+
curl_easy_setopt(curl, CURLOPT_MAX_SEND_SPEED_LARGE, rbce->max_send_speed_large);
|
2368
|
+
|
2204
2369
|
// Set up localport / proxy port
|
2205
2370
|
// FIXME these won't get returned to default if they're unset Ruby
|
2206
2371
|
if (rbce->proxy_port > 0) {
|
@@ -2334,6 +2499,25 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
2334
2499
|
}
|
2335
2500
|
}
|
2336
2501
|
|
2502
|
+
#if HAVE_CURLOPT_PROXYHEADER
|
2503
|
+
/* Setup HTTP proxy headers if necessary */
|
2504
|
+
curl_easy_setopt(curl, CURLOPT_PROXYHEADER, NULL); // XXX: maybe we shouldn't be clearing this?
|
2505
|
+
|
2506
|
+
if (!rb_easy_nil("proxy_headers")) {
|
2507
|
+
if (rb_easy_type_check("proxy_headers", T_ARRAY) || rb_easy_type_check("proxy_headers", T_HASH)) {
|
2508
|
+
VALUE wrap = Data_Wrap_Struct(rb_cObject, 0, 0, phdrs);
|
2509
|
+
rb_iterate(rb_each, rb_easy_get("proxy_headers"), cb_each_http_proxy_header, wrap);
|
2510
|
+
} else {
|
2511
|
+
VALUE proxy_headers_str = rb_obj_as_string(rb_easy_get("proxy_headers"));
|
2512
|
+
*phdrs = curl_slist_append(*hdrs, StringValuePtr(proxy_headers_str));
|
2513
|
+
}
|
2514
|
+
|
2515
|
+
if (*phdrs) {
|
2516
|
+
curl_easy_setopt(curl, CURLOPT_PROXYHEADER, *phdrs);
|
2517
|
+
}
|
2518
|
+
}
|
2519
|
+
#endif
|
2520
|
+
|
2337
2521
|
/* Setup FTP commands if necessary */
|
2338
2522
|
if (!rb_easy_nil("ftp_commands")) {
|
2339
2523
|
if (rb_easy_type_check("ftp_commands", T_ARRAY)) {
|
@@ -2346,6 +2530,7 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
2346
2530
|
}
|
2347
2531
|
}
|
2348
2532
|
|
2533
|
+
#if HAVE_CURLOPT_RESOLVE
|
2349
2534
|
/* Setup resolve list if necessary */
|
2350
2535
|
if (!rb_easy_nil("resolve")) {
|
2351
2536
|
if (rb_easy_type_check("resolve", T_ARRAY)) {
|
@@ -2357,6 +2542,7 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
2357
2542
|
curl_easy_setopt(curl, CURLOPT_RESOLVE, *rslv);
|
2358
2543
|
}
|
2359
2544
|
}
|
2545
|
+
#endif
|
2360
2546
|
|
2361
2547
|
return Qnil;
|
2362
2548
|
}
|
@@ -2364,7 +2550,7 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
2364
2550
|
*
|
2365
2551
|
* Clean up a connection
|
2366
2552
|
*
|
2367
|
-
* Always returns
|
2553
|
+
* Always returns Qnil.
|
2368
2554
|
*/
|
2369
2555
|
VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
|
2370
2556
|
|
@@ -2378,6 +2564,11 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
|
|
2378
2564
|
rbce->curl_headers = NULL;
|
2379
2565
|
}
|
2380
2566
|
|
2567
|
+
if (rbce->curl_proxy_headers) {
|
2568
|
+
curl_slist_free_all(rbce->curl_proxy_headers);
|
2569
|
+
rbce->curl_proxy_headers = NULL;
|
2570
|
+
}
|
2571
|
+
|
2381
2572
|
ftp_commands = rbce->curl_ftp_commands;
|
2382
2573
|
if (ftp_commands) {
|
2383
2574
|
curl_slist_free_all(ftp_commands);
|
@@ -2399,6 +2590,9 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
|
|
2399
2590
|
curl_easy_setopt(curl, CURLOPT_INFILESIZE, 0);
|
2400
2591
|
}
|
2401
2592
|
|
2593
|
+
// set values on cleanup to nil
|
2594
|
+
rb_easy_del("multi");
|
2595
|
+
|
2402
2596
|
return Qnil;
|
2403
2597
|
}
|
2404
2598
|
|
@@ -3263,6 +3457,7 @@ static VALUE ruby_curl_easy_last_result(VALUE self) {
|
|
3263
3457
|
static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
3264
3458
|
ruby_curl_easy *rbce;
|
3265
3459
|
long option = NUM2LONG(opt);
|
3460
|
+
rb_io_t *open_f_ptr;
|
3266
3461
|
|
3267
3462
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
3268
3463
|
|
@@ -3383,6 +3578,34 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
3383
3578
|
curl_easy_setopt(rbce->curl, CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t) NUM2LL(val));
|
3384
3579
|
} break;
|
3385
3580
|
#endif
|
3581
|
+
#if HAVE_CURLOPT_MAXFILESIZE
|
3582
|
+
case CURLOPT_MAXFILESIZE:
|
3583
|
+
curl_easy_setopt(rbce->curl, CURLOPT_MAXFILESIZE, NUM2LONG(val));
|
3584
|
+
break;
|
3585
|
+
#endif
|
3586
|
+
#if HAVE_CURLOPT_TCP_KEEPALIVE
|
3587
|
+
case CURLOPT_TCP_KEEPALIVE:
|
3588
|
+
curl_easy_setopt(rbce->curl, CURLOPT_TCP_KEEPALIVE, NUM2LONG(val));
|
3589
|
+
break;
|
3590
|
+
case CURLOPT_TCP_KEEPIDLE:
|
3591
|
+
curl_easy_setopt(rbce->curl, CURLOPT_TCP_KEEPIDLE, NUM2LONG(val));
|
3592
|
+
break;
|
3593
|
+
case CURLOPT_TCP_KEEPINTVL:
|
3594
|
+
curl_easy_setopt(rbce->curl, CURLOPT_TCP_KEEPINTVL, NUM2LONG(val));
|
3595
|
+
break;
|
3596
|
+
#endif
|
3597
|
+
#if HAVE_CURLOPT_HAPROXYPROTOCOL
|
3598
|
+
case CURLOPT_HAPROXYPROTOCOL:
|
3599
|
+
curl_easy_setopt(rbce->curl, CURLOPT_HAPROXYPROTOCOL, NUM2LONG(val));
|
3600
|
+
break;
|
3601
|
+
#endif
|
3602
|
+
case CURLOPT_STDERR:
|
3603
|
+
// libcurl requires raw FILE pointer and this should be IO object in Ruby.
|
3604
|
+
// Tempfile or StringIO won't work.
|
3605
|
+
Check_Type(val, T_FILE);
|
3606
|
+
GetOpenFile(val, open_f_ptr);
|
3607
|
+
curl_easy_setopt(rbce->curl, CURLOPT_STDERR, rb_io_stdio_file(open_f_ptr));
|
3608
|
+
break;
|
3386
3609
|
default:
|
3387
3610
|
rb_raise(rb_eTypeError, "Curb unsupported option");
|
3388
3611
|
}
|
@@ -3518,6 +3741,10 @@ void init_curb_easy() {
|
|
3518
3741
|
/* Attributes for config next perform */
|
3519
3742
|
rb_define_method(cCurlEasy, "url", ruby_curl_easy_url_get, 0);
|
3520
3743
|
rb_define_method(cCurlEasy, "proxy_url", ruby_curl_easy_proxy_url_get, 0);
|
3744
|
+
|
3745
|
+
rb_define_method(cCurlEasy, "proxy_headers=", ruby_curl_easy_proxy_headers_set, 1);
|
3746
|
+
rb_define_method(cCurlEasy, "proxy_headers", ruby_curl_easy_proxy_headers_get, 0);
|
3747
|
+
|
3521
3748
|
rb_define_method(cCurlEasy, "headers=", ruby_curl_easy_headers_set, 1);
|
3522
3749
|
rb_define_method(cCurlEasy, "headers", ruby_curl_easy_headers_get, 0);
|
3523
3750
|
rb_define_method(cCurlEasy, "interface", ruby_curl_easy_interface_get, 0);
|
@@ -3577,6 +3804,10 @@ void init_curb_easy() {
|
|
3577
3804
|
rb_define_method(cCurlEasy, "low_speed_limit", ruby_curl_easy_low_speed_limit_get, 0);
|
3578
3805
|
rb_define_method(cCurlEasy, "low_speed_time=", ruby_curl_easy_low_speed_time_set, 1);
|
3579
3806
|
rb_define_method(cCurlEasy, "low_speed_time", ruby_curl_easy_low_speed_time_get, 0);
|
3807
|
+
rb_define_method(cCurlEasy, "max_send_speed_large=", ruby_curl_easy_max_send_speed_large_set, 1);
|
3808
|
+
rb_define_method(cCurlEasy, "max_send_speed_large", ruby_curl_easy_max_send_speed_large_get, 0);
|
3809
|
+
rb_define_method(cCurlEasy, "max_recv_speed_large=", ruby_curl_easy_max_recv_speed_large_set, 1);
|
3810
|
+
rb_define_method(cCurlEasy, "max_recv_speed_large", ruby_curl_easy_max_recv_speed_large_get, 0);
|
3580
3811
|
rb_define_method(cCurlEasy, "ssl_version=", ruby_curl_easy_ssl_version_set, 1);
|
3581
3812
|
rb_define_method(cCurlEasy, "ssl_version", ruby_curl_easy_ssl_version_get, 0);
|
3582
3813
|
rb_define_method(cCurlEasy, "use_ssl=", ruby_curl_easy_use_ssl_set, 1);
|