curb 0.8.4 → 0.8.8
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 +7 -0
- data/README.markdown +240 -0
- data/Rakefile +2 -7
- data/ext/curb.c +20 -0
- data/ext/curb.h +5 -9
- data/ext/curb_easy.c +79 -7
- data/ext/curb_errors.c +27 -16
- data/ext/curb_errors.h +8 -5
- data/ext/curb_multi.c +18 -10
- data/ext/extconf.rb +10 -17
- data/lib/curl/easy.rb +71 -59
- data/lib/curl.rb +7 -1
- data/tests/bug_crash_on_progress.rb +41 -1
- data/tests/bug_issue102.rb +1 -1
- data/tests/helper.rb +6 -1
- data/tests/tc_curl_download.rb +1 -1
- data/tests/tc_curl_easy.rb +22 -4
- data/tests/tc_curl_multi.rb +1 -1
- metadata +21 -29
- data/README +0 -194
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: b76360d30b92902398314af1674ec02db1ad9f74
|
|
4
|
+
data.tar.gz: 05ae393053e953fa773dcca22b50d18252c90244
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: e8777897444b5ad6dad48f0a56d78d9826d96a4e3cd3cd53d318c3f733d0242f8b7ece9600c6aa06f53125c37f4f7c144bd82da62f9619a0a94b560f1546617b
|
|
7
|
+
data.tar.gz: 77a42a5ad6b26233a3c7917c945d694d560474c54eab71023439ad840ef5af1fd0f5037d6e4dcae680273785e8870ab952d9dab6955c11b127533e2ef60b0adc
|
data/README.markdown
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# Curb - Libcurl bindings for Ruby
|
|
2
|
+
|
|
3
|
+
* [rubyforge rdoc](http://curb.rubyforge.org/)
|
|
4
|
+
* [rubyforge project](http://rubyforge.org/projects/curb)
|
|
5
|
+
* [github project](http://github.com/taf2/curb/tree/master)
|
|
6
|
+
|
|
7
|
+
Curb (probably CUrl-RuBy or something) provides Ruby-language bindings for the
|
|
8
|
+
libcurl(3), a fully-featured client-side URL transfer library.
|
|
9
|
+
cURL and libcurl live at [http://curl.haxx.se/](http://curl.haxx.se/) .
|
|
10
|
+
|
|
11
|
+
Curb is a work-in-progress, and currently only supports libcurl's 'easy' and 'multi' modes.
|
|
12
|
+
|
|
13
|
+
## License
|
|
14
|
+
|
|
15
|
+
Curb is copyright (c)2006 Ross Bamford, and released under the terms of the
|
|
16
|
+
Ruby license. See the LICENSE file for the gory details.
|
|
17
|
+
|
|
18
|
+
## You will need
|
|
19
|
+
|
|
20
|
+
* A working Ruby installation (1.8+, tested with 1.8.6, 1.8.7, 1.9.1, and 1.9.2)
|
|
21
|
+
* A working (lib)curl installation, with development stuff (7.5+, tested with 7.19.x)
|
|
22
|
+
* A sane build environment (e.g. gcc, make)
|
|
23
|
+
|
|
24
|
+
## Installation...
|
|
25
|
+
|
|
26
|
+
... will usually be as simple as:
|
|
27
|
+
|
|
28
|
+
$ gem install curb
|
|
29
|
+
|
|
30
|
+
On Windows, make sure you're using the [DevKit](http://rubyinstaller.org/downloads/) and
|
|
31
|
+
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
|
|
32
|
+
line (alter paths to your curl location, but remember to use forward slashes):
|
|
33
|
+
|
|
34
|
+
gem install curb --platform=ruby -- --with-curl-lib=C:/curl-7.39.0-devel-mingw32/bin --with-curl-include=C:/curl-7.39.0-devel-mingw32/include
|
|
35
|
+
|
|
36
|
+
Or, if you downloaded the archive:
|
|
37
|
+
|
|
38
|
+
$ rake install
|
|
39
|
+
|
|
40
|
+
If you have a weird setup, you might need extconf options. In this case, pass
|
|
41
|
+
them like so:
|
|
42
|
+
|
|
43
|
+
$ rake install EXTCONF_OPTS='--with-curl-dir=/path/to/libcurl --prefix=/what/ever'
|
|
44
|
+
|
|
45
|
+
Curb is tested only on GNU/Linux x86 and Mac OSX - YMMV on other platforms.
|
|
46
|
+
If you do use another platform and experience problems, or if you can
|
|
47
|
+
expand on the above instructions, please report the issue at http://github.com/taf2/curb/issues
|
|
48
|
+
|
|
49
|
+
On Ubuntu, the dependencies can be satisfied by installing the following packages:
|
|
50
|
+
|
|
51
|
+
$ sudo apt-get install libcurl3 libcurl3-gnutls libcurl4-openssl-dev
|
|
52
|
+
|
|
53
|
+
On RedHat:
|
|
54
|
+
|
|
55
|
+
$ sudo yum install ruby-devel libcurl-devel openssl-devel
|
|
56
|
+
|
|
57
|
+
Curb has fairly extensive RDoc comments in the source. You can build the
|
|
58
|
+
documentation with:
|
|
59
|
+
|
|
60
|
+
$ rake doc
|
|
61
|
+
|
|
62
|
+
## Usage & examples
|
|
63
|
+
|
|
64
|
+
Curb provides two classes:
|
|
65
|
+
|
|
66
|
+
* `Curl::Easy` - simple API, for day-to-day tasks.
|
|
67
|
+
* `Curl::Multi` - more advanced API, for operating on multiple URLs simultaneously.
|
|
68
|
+
|
|
69
|
+
### Super simple API (less typing)
|
|
70
|
+
|
|
71
|
+
```ruby
|
|
72
|
+
http = Curl.get("http://www.google.com/")
|
|
73
|
+
puts http.body_str
|
|
74
|
+
|
|
75
|
+
http = Curl.post("http://www.google.com/", {:foo => "bar"})
|
|
76
|
+
puts http.body_str
|
|
77
|
+
|
|
78
|
+
http = Curl.get("http://www.google.com/") do|http|
|
|
79
|
+
http.headers['Cookie'] = 'foo=1;bar=2'
|
|
80
|
+
end
|
|
81
|
+
puts http.body_str
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Simple fetch via HTTP:
|
|
85
|
+
|
|
86
|
+
```ruby
|
|
87
|
+
c = Curl::Easy.perform("http://www.google.co.uk")
|
|
88
|
+
puts c.body_str
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Same thing, more manual:
|
|
92
|
+
|
|
93
|
+
```ruby
|
|
94
|
+
c = Curl::Easy.new("http://www.google.co.uk")
|
|
95
|
+
c.perform
|
|
96
|
+
puts c.body_str
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Additional config:
|
|
100
|
+
|
|
101
|
+
```ruby
|
|
102
|
+
Curl::Easy.perform("http://www.google.co.uk") do |curl|
|
|
103
|
+
curl.headers["User-Agent"] = "myapp-0.0"
|
|
104
|
+
curl.verbose = true
|
|
105
|
+
end
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Same thing, more manual:
|
|
109
|
+
|
|
110
|
+
```ruby
|
|
111
|
+
c = Curl::Easy.new("http://www.google.co.uk") do |curl|
|
|
112
|
+
curl.headers["User-Agent"] = "myapp-0.0"
|
|
113
|
+
curl.verbose = true
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
c.perform
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### HTTP basic authentication:
|
|
120
|
+
|
|
121
|
+
```ruby
|
|
122
|
+
c = Curl::Easy.new("http://github.com/")
|
|
123
|
+
c.http_auth_types = :basic
|
|
124
|
+
c.username = 'foo'
|
|
125
|
+
c.password = 'bar'
|
|
126
|
+
c.perform
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### HTTP "insecure" SSL connections (like curl -k, --insecure) to avoid Curl::Err::SSLCACertificateError:
|
|
130
|
+
|
|
131
|
+
```ruby
|
|
132
|
+
c = Curl::Easy.new("http://github.com/")
|
|
133
|
+
c.ssl_verify_peer = false
|
|
134
|
+
c.perform
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Supplying custom handlers:
|
|
138
|
+
|
|
139
|
+
```ruby
|
|
140
|
+
c = Curl::Easy.new("http://www.google.co.uk")
|
|
141
|
+
|
|
142
|
+
c.on_body { |data| print(data) }
|
|
143
|
+
c.on_header { |data| print(data) }
|
|
144
|
+
|
|
145
|
+
c.perform
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Reusing Curls:
|
|
149
|
+
|
|
150
|
+
```ruby
|
|
151
|
+
c = Curl::Easy.new
|
|
152
|
+
|
|
153
|
+
["http://www.google.co.uk", "http://www.ruby-lang.org/"].map do |url|
|
|
154
|
+
c.url = url
|
|
155
|
+
c.perform
|
|
156
|
+
c.body_str
|
|
157
|
+
end
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### HTTP POST form:
|
|
161
|
+
|
|
162
|
+
```ruby
|
|
163
|
+
c = Curl::Easy.http_post("http://my.rails.box/thing/create",
|
|
164
|
+
Curl::PostField.content('thing[name]', 'box'),
|
|
165
|
+
Curl::PostField.content('thing[type]', 'storage'))
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### HTTP POST file upload:
|
|
169
|
+
|
|
170
|
+
```ruby
|
|
171
|
+
c = Curl::Easy.new("http://my.rails.box/files/upload")
|
|
172
|
+
c.multipart_form_post = true
|
|
173
|
+
c.http_post(Curl::PostField.file('thing[file]', 'myfile.rb'))
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Multi Interface (Basic HTTP GET):
|
|
177
|
+
|
|
178
|
+
```ruby
|
|
179
|
+
# make multiple GET requests
|
|
180
|
+
easy_options = {:follow_location => true}
|
|
181
|
+
multi_options = {:pipeline => true}
|
|
182
|
+
|
|
183
|
+
Curl::Multi.get('url1','url2','url3','url4','url5', easy_options, multi_options) do|easy|
|
|
184
|
+
# do something interesting with the easy response
|
|
185
|
+
puts easy.last_effective_url
|
|
186
|
+
end
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Multi Interface (Basic HTTP POST):
|
|
190
|
+
|
|
191
|
+
```ruby
|
|
192
|
+
# make multiple POST requests
|
|
193
|
+
easy_options = {:follow_location => true, :multipart_form_post => true}
|
|
194
|
+
multi_options = {:pipeline => true}
|
|
195
|
+
|
|
196
|
+
url_fields = [
|
|
197
|
+
{ :url => 'url1', :post_fields => {'f1' => 'v1'} },
|
|
198
|
+
{ :url => 'url2', :post_fields => {'f1' => 'v1'} },
|
|
199
|
+
{ :url => 'url3', :post_fields => {'f1' => 'v1'} }
|
|
200
|
+
]
|
|
201
|
+
|
|
202
|
+
Curl::Multi.post(url_fields, easy_options, multi_options) do|easy|
|
|
203
|
+
# do something interesting with the easy response
|
|
204
|
+
puts easy.last_effective_url
|
|
205
|
+
end
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Multi Interface (Advanced):
|
|
209
|
+
|
|
210
|
+
```ruby
|
|
211
|
+
responses = {}
|
|
212
|
+
requests = ["http://www.google.co.uk/", "http://www.ruby-lang.org/"]
|
|
213
|
+
m = Curl::Multi.new
|
|
214
|
+
# add a few easy handles
|
|
215
|
+
requests.each do |url|
|
|
216
|
+
responses[url] = ""
|
|
217
|
+
c = Curl::Easy.new(url) do|curl|
|
|
218
|
+
curl.follow_location = true
|
|
219
|
+
curl.on_body{|data| responses[url] << data; data.size }
|
|
220
|
+
curl.on_success {|easy| puts "success, add more easy handles" }
|
|
221
|
+
end
|
|
222
|
+
m.add(c)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
m.perform do
|
|
226
|
+
puts "idling... can do some work here"
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
requests.each do|url|
|
|
230
|
+
puts responses[url]
|
|
231
|
+
end
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Easy Callbacks
|
|
235
|
+
|
|
236
|
+
* `on_success` is called when the response code is 2xx
|
|
237
|
+
* `on_redirect` is called when the response code is 3xx
|
|
238
|
+
* `on_missing` is called when the response code is 4xx
|
|
239
|
+
* `on_failure` is called when the response code is 5xx
|
|
240
|
+
* `on_complete` is called in all cases.
|
data/Rakefile
CHANGED
|
@@ -68,11 +68,6 @@ end
|
|
|
68
68
|
desc "Compile the shared object"
|
|
69
69
|
task :compile => [CURB_SO]
|
|
70
70
|
|
|
71
|
-
desc "Create the markdown file"
|
|
72
|
-
task :markdown do
|
|
73
|
-
cp "README", "README.markdown"
|
|
74
|
-
end
|
|
75
|
-
|
|
76
71
|
desc "Install to your site_ruby directory"
|
|
77
72
|
task :install => :alltests do
|
|
78
73
|
m = make 'install'
|
|
@@ -171,13 +166,13 @@ else
|
|
|
171
166
|
|
|
172
167
|
desc 'Build gem'
|
|
173
168
|
task :package => :gemspec do
|
|
174
|
-
require 'rubygems/
|
|
169
|
+
require 'rubygems/package'
|
|
175
170
|
spec_source = File.read File.join(File.dirname(__FILE__),'curb.gemspec')
|
|
176
171
|
spec = nil
|
|
177
172
|
# see: http://gist.github.com/16215
|
|
178
173
|
Thread.new { spec = eval("$SAFE = 3\n#{spec_source}") }.join
|
|
179
174
|
spec.validate
|
|
180
|
-
Gem::
|
|
175
|
+
Gem::Package.build(spec)
|
|
181
176
|
end
|
|
182
177
|
|
|
183
178
|
task :static do
|
data/ext/curb.c
CHANGED
|
@@ -304,6 +304,13 @@ void Init_curb_core() {
|
|
|
304
304
|
rb_define_const(mCurl, "CURLPROXY_SOCKS4", INT2FIX(-2));
|
|
305
305
|
#endif
|
|
306
306
|
|
|
307
|
+
/* When passed to Curl::Easy#proxy_type , indicates that the proxy is a SOCKS4A proxy. (libcurl >= 7.18.0) */
|
|
308
|
+
#ifdef HAVE_CURLPROXY_SOCKS4A
|
|
309
|
+
rb_define_const(mCurl, "CURLPROXY_SOCKS4A", INT2FIX(CURLPROXY_SOCKS4A));
|
|
310
|
+
#else
|
|
311
|
+
rb_define_const(mCurl, "CURLPROXY_SOCKS4A", INT2FIX(-2));
|
|
312
|
+
#endif
|
|
313
|
+
|
|
307
314
|
/* When passed to Curl::Easy#proxy_type , indicates that the proxy is a SOCKS5 proxy. (libcurl >= 7.10) */
|
|
308
315
|
#ifdef HAVE_CURLPROXY_SOCKS5
|
|
309
316
|
rb_define_const(mCurl, "CURLPROXY_SOCKS5", INT2FIX(CURLPROXY_SOCKS5));
|
|
@@ -951,6 +958,19 @@ void Init_curb_core() {
|
|
|
951
958
|
CURB_DEFINE(CURLOPT_TELNETOPTIONS);
|
|
952
959
|
#endif
|
|
953
960
|
|
|
961
|
+
#if HAVE_CURLOPT_GSSAPI_DELEGATION
|
|
962
|
+
CURB_DEFINE(CURLOPT_GSSAPI_DELEGATION);
|
|
963
|
+
#endif
|
|
964
|
+
|
|
965
|
+
#if HAVE_CURLGSSAPI_DELEGATION_FLAG
|
|
966
|
+
CURB_DEFINE(CURLGSSAPI_DELEGATION_FLAG);
|
|
967
|
+
#endif
|
|
968
|
+
|
|
969
|
+
#if HAVE_CURLGSSAPI_DELEGATION_POLICY_FLAG
|
|
970
|
+
CURB_DEFINE(CURLGSSAPI_DELEGATION_POLICY_FLAG);
|
|
971
|
+
#endif
|
|
972
|
+
|
|
973
|
+
|
|
954
974
|
rb_define_const(mCurl, "HTTP_1_1", LONG2NUM(CURL_HTTP_VERSION_1_1));
|
|
955
975
|
rb_define_const(mCurl, "HTTP_1_0", LONG2NUM(CURL_HTTP_VERSION_1_0));
|
|
956
976
|
rb_define_const(mCurl, "HTTP_NONE", LONG2NUM(CURL_HTTP_VERSION_NONE));
|
data/ext/curb.h
CHANGED
|
@@ -20,11 +20,11 @@
|
|
|
20
20
|
#include "curb_macros.h"
|
|
21
21
|
|
|
22
22
|
// These should be managed from the Rake 'release' task.
|
|
23
|
-
#define CURB_VERSION "0.8.
|
|
24
|
-
#define CURB_VER_NUM
|
|
23
|
+
#define CURB_VERSION "0.8.8"
|
|
24
|
+
#define CURB_VER_NUM 808
|
|
25
25
|
#define CURB_VER_MAJ 0
|
|
26
26
|
#define CURB_VER_MIN 8
|
|
27
|
-
#define CURB_VER_MIC
|
|
27
|
+
#define CURB_VER_MIC 8
|
|
28
28
|
#define CURB_VER_PATCH 0
|
|
29
29
|
|
|
30
30
|
|
|
@@ -37,12 +37,8 @@
|
|
|
37
37
|
#define RSTRING_PTR(x) RSTRING(x)->ptr
|
|
38
38
|
#endif
|
|
39
39
|
|
|
40
|
-
#ifndef
|
|
41
|
-
#
|
|
42
|
-
#define RHASH_LEN(hash) RHASH(hash)->ntbl->num_entries
|
|
43
|
-
#else
|
|
44
|
-
#define RHASH_LEN(hash) RHASH(hash)->tbl->num_entries
|
|
45
|
-
#endif
|
|
40
|
+
#ifndef RHASH_SIZE
|
|
41
|
+
#define RHASH_SIZE(hash) RHASH(hash)->tbl->num_entries
|
|
46
42
|
#endif
|
|
47
43
|
|
|
48
44
|
extern VALUE mCurl;
|
data/ext/curb_easy.c
CHANGED
|
@@ -96,6 +96,25 @@ static size_t read_data_handler(void *ptr,
|
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
int seek_data_handler(ruby_curl_easy *rbce,
|
|
100
|
+
curl_off_t offset,
|
|
101
|
+
int origin) {
|
|
102
|
+
|
|
103
|
+
VALUE upload = rb_easy_get("upload");
|
|
104
|
+
VALUE stream = ruby_curl_upload_stream_get(upload);
|
|
105
|
+
|
|
106
|
+
if (rb_respond_to(stream, rb_intern("seek"))) {
|
|
107
|
+
rb_funcall(stream, rb_intern("seek"), 2, SEEK_SET, offset);
|
|
108
|
+
} else {
|
|
109
|
+
ruby_curl_upload *rbcu;
|
|
110
|
+
Data_Get_Struct(upload, ruby_curl_upload, rbcu);
|
|
111
|
+
// This OK because curl only uses SEEK_SET as per the documentation
|
|
112
|
+
rbcu->offset = offset;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return 0;
|
|
116
|
+
}
|
|
117
|
+
|
|
99
118
|
static size_t proc_data_handler(char *stream,
|
|
100
119
|
size_t size,
|
|
101
120
|
size_t nmemb,
|
|
@@ -772,7 +791,13 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
|
|
|
772
791
|
curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
|
|
773
792
|
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
|
|
774
793
|
curl_easy_setopt(curl, CURLOPT_READFUNCTION, (curl_read_callback)read_data_handler);
|
|
794
|
+
#if HAVE_CURLOPT_SEEKFUNCTION
|
|
795
|
+
curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, (curl_seek_callback)seek_data_handler);
|
|
796
|
+
#endif
|
|
775
797
|
curl_easy_setopt(curl, CURLOPT_READDATA, rbce);
|
|
798
|
+
#if HAVE_CURLOPT_SEEKDATA
|
|
799
|
+
curl_easy_setopt(curl, CURLOPT_SEEKDATA, rbce);
|
|
800
|
+
#endif
|
|
776
801
|
|
|
777
802
|
/*
|
|
778
803
|
* we need to set specific headers for the PUT to work... so
|
|
@@ -1637,9 +1662,10 @@ static VALUE ruby_curl_easy_ignore_content_length_q(VALUE self) {
|
|
|
1637
1662
|
*/
|
|
1638
1663
|
static VALUE ruby_curl_easy_resolve_mode(VALUE self) {
|
|
1639
1664
|
ruby_curl_easy *rbce;
|
|
1665
|
+
unsigned short rm;
|
|
1640
1666
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
1641
1667
|
|
|
1642
|
-
|
|
1668
|
+
rm = rbce->resolve_mode;
|
|
1643
1669
|
|
|
1644
1670
|
switch(rm) {
|
|
1645
1671
|
case CURL_IPRESOLVE_V4:
|
|
@@ -1668,9 +1694,10 @@ static VALUE ruby_curl_easy_resolve_mode_set(VALUE self, VALUE resolve_mode) {
|
|
|
1668
1694
|
return Qnil;
|
|
1669
1695
|
} else {
|
|
1670
1696
|
ruby_curl_easy *rbce;
|
|
1697
|
+
ID resolve_mode_id;
|
|
1671
1698
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
1672
1699
|
|
|
1673
|
-
|
|
1700
|
+
resolve_mode_id = rb_to_id(resolve_mode);
|
|
1674
1701
|
|
|
1675
1702
|
if (resolve_mode_id == rb_intern("auto")) {
|
|
1676
1703
|
rbce->resolve_mode = CURL_IPRESOLVE_WHATEVER;
|
|
@@ -1850,10 +1877,10 @@ static VALUE ruby_curl_easy_on_debug_set(int argc, VALUE *argv, VALUE self) {
|
|
|
1850
1877
|
*/
|
|
1851
1878
|
static VALUE cb_each_http_header(VALUE header, VALUE wrap) {
|
|
1852
1879
|
struct curl_slist **list;
|
|
1853
|
-
Data_Get_Struct(wrap, struct curl_slist *, list);
|
|
1854
|
-
|
|
1855
1880
|
VALUE header_str = Qnil;
|
|
1856
1881
|
|
|
1882
|
+
Data_Get_Struct(wrap, struct curl_slist *, list);
|
|
1883
|
+
|
|
1857
1884
|
//rb_p(header);
|
|
1858
1885
|
|
|
1859
1886
|
if (rb_type(header) == T_ARRAY) {
|
|
@@ -1882,9 +1909,10 @@ static VALUE cb_each_http_header(VALUE header, VALUE wrap) {
|
|
|
1882
1909
|
*/
|
|
1883
1910
|
static VALUE cb_each_ftp_command(VALUE ftp_command, VALUE wrap) {
|
|
1884
1911
|
struct curl_slist **list;
|
|
1912
|
+
VALUE ftp_command_string;
|
|
1885
1913
|
Data_Get_Struct(wrap, struct curl_slist *, list);
|
|
1886
1914
|
|
|
1887
|
-
|
|
1915
|
+
ftp_command_string = rb_obj_as_string(ftp_command);
|
|
1888
1916
|
*list = curl_slist_append(*list, StringValuePtr(ftp_command));
|
|
1889
1917
|
|
|
1890
1918
|
return ftp_command_string;
|
|
@@ -2578,6 +2606,29 @@ static VALUE ruby_curl_easy_connect_time_get(VALUE self) {
|
|
|
2578
2606
|
return rb_float_new(time);
|
|
2579
2607
|
}
|
|
2580
2608
|
|
|
2609
|
+
/*
|
|
2610
|
+
* call-seq:
|
|
2611
|
+
* easy.app_connect_time => float
|
|
2612
|
+
*
|
|
2613
|
+
* Retrieve the time, in seconds, it took from the start until the SSL/SSH
|
|
2614
|
+
* connect/handshake to the remote host was completed. This time is most often
|
|
2615
|
+
* very near to the pre transfer time, except for cases such as HTTP
|
|
2616
|
+
* pippelining where the pretransfer time can be delayed due to waits in line
|
|
2617
|
+
* for the pipeline and more.
|
|
2618
|
+
*/
|
|
2619
|
+
#if defined(HAVE_CURLINFO_APPCONNECT_TIME)
|
|
2620
|
+
static VALUE ruby_curl_easy_app_connect_time_get(VALUE self) {
|
|
2621
|
+
ruby_curl_easy *rbce;
|
|
2622
|
+
double time;
|
|
2623
|
+
|
|
2624
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2625
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_APPCONNECT_TIME, &time);
|
|
2626
|
+
|
|
2627
|
+
return rb_float_new(time);
|
|
2628
|
+
}
|
|
2629
|
+
#endif
|
|
2630
|
+
|
|
2631
|
+
|
|
2581
2632
|
/*
|
|
2582
2633
|
* call-seq:
|
|
2583
2634
|
* easy.pre_transfer_time => float
|
|
@@ -3074,6 +3125,13 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3074
3125
|
case CURLOPT_NOPROGRESS:
|
|
3075
3126
|
case CURLOPT_NOSIGNAL:
|
|
3076
3127
|
case CURLOPT_HTTPGET:
|
|
3128
|
+
break;
|
|
3129
|
+
case CURLOPT_POST: {
|
|
3130
|
+
curl_easy_setopt(rbce->curl, CURLOPT_POST, rb_type(val) == T_TRUE);
|
|
3131
|
+
} break;
|
|
3132
|
+
case CURLOPT_POSTFIELDS: {
|
|
3133
|
+
curl_easy_setopt(rbce->curl, CURLOPT_POSTFIELDS, NIL_P(val) ? NULL : StringValueCStr(val));
|
|
3134
|
+
} break;
|
|
3077
3135
|
case CURLOPT_NOBODY: {
|
|
3078
3136
|
int type = rb_type(val);
|
|
3079
3137
|
VALUE value;
|
|
@@ -3106,14 +3164,25 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3106
3164
|
VALUE cookiejar = val;
|
|
3107
3165
|
CURB_OBJECT_HSETTER(ruby_curl_easy, cookiejar);
|
|
3108
3166
|
} break;
|
|
3167
|
+
case CURLOPT_TCP_NODELAY: {
|
|
3168
|
+
curl_easy_setopt(rbce->curl, CURLOPT_TCP_NODELAY, FIX2LONG(val));
|
|
3169
|
+
} break;
|
|
3109
3170
|
case CURLOPT_RESUME_FROM: {
|
|
3110
3171
|
curl_easy_setopt(rbce->curl, CURLOPT_RESUME_FROM, FIX2LONG(val));
|
|
3111
3172
|
} break;
|
|
3112
3173
|
case CURLOPT_FAILONERROR: {
|
|
3113
3174
|
curl_easy_setopt(rbce->curl, CURLOPT_FAILONERROR, FIX2LONG(val));
|
|
3114
3175
|
} break;
|
|
3176
|
+
case CURLOPT_SSL_CIPHER_LIST: {
|
|
3177
|
+
curl_easy_setopt(rbce->curl, CURLOPT_SSL_CIPHER_LIST, StringValueCStr(val));
|
|
3178
|
+
} break;
|
|
3179
|
+
#if HAVE_CURLOPT_GSSAPI_DELEGATION
|
|
3180
|
+
case CURLOPT_GSSAPI_DELEGATION: {
|
|
3181
|
+
curl_easy_setopt(rbce->curl, CURLOPT_GSSAPI_DELEGATION, FIX2LONG(val));
|
|
3182
|
+
} break;
|
|
3183
|
+
#endif
|
|
3115
3184
|
default:
|
|
3116
|
-
|
|
3185
|
+
rb_raise(rb_eTypeError, "Curb unsupported option");
|
|
3117
3186
|
}
|
|
3118
3187
|
|
|
3119
3188
|
return val;
|
|
@@ -3219,7 +3288,7 @@ static VALUE ruby_curl_easy_unescape(VALUE self, VALUE str) {
|
|
|
3219
3288
|
|
|
3220
3289
|
/*
|
|
3221
3290
|
* call-seq:
|
|
3222
|
-
* Curl::Easy.error(code) => String
|
|
3291
|
+
* Curl::Easy.error(code) => [ErrCode, String]
|
|
3223
3292
|
*
|
|
3224
3293
|
* translate an internal libcurl error to ruby error class
|
|
3225
3294
|
*/
|
|
@@ -3364,6 +3433,9 @@ void init_curb_easy() {
|
|
|
3364
3433
|
rb_define_method(cCurlEasy, "total_time", ruby_curl_easy_total_time_get, 0);
|
|
3365
3434
|
rb_define_method(cCurlEasy, "name_lookup_time", ruby_curl_easy_name_lookup_time_get, 0);
|
|
3366
3435
|
rb_define_method(cCurlEasy, "connect_time", ruby_curl_easy_connect_time_get, 0);
|
|
3436
|
+
#if defined(HAVE_CURLINFO_APPCONNECT_TIME)
|
|
3437
|
+
rb_define_method(cCurlEasy, "app_connect_time", ruby_curl_easy_app_connect_time_get, 0);
|
|
3438
|
+
#endif
|
|
3367
3439
|
rb_define_method(cCurlEasy, "pre_transfer_time", ruby_curl_easy_pre_transfer_time_get, 0);
|
|
3368
3440
|
rb_define_method(cCurlEasy, "start_transfer_time", ruby_curl_easy_start_transfer_time_get, 0);
|
|
3369
3441
|
rb_define_method(cCurlEasy, "redirect_time", ruby_curl_easy_redirect_time_get, 0);
|
data/ext/curb_errors.c
CHANGED
|
@@ -32,13 +32,13 @@ VALUE eCurlErrNotBuiltIn;
|
|
|
32
32
|
VALUE eCurlErrProxyResolution;
|
|
33
33
|
VALUE eCurlErrHostResolution;
|
|
34
34
|
VALUE eCurlErrConnectFailed;
|
|
35
|
-
VALUE
|
|
35
|
+
VALUE eCurlErrFTPWeirdReply;
|
|
36
36
|
VALUE eCurlErrFTPAccessDenied;
|
|
37
37
|
VALUE eCurlErrFTPBadPassword;
|
|
38
|
-
VALUE
|
|
39
|
-
VALUE
|
|
40
|
-
VALUE
|
|
41
|
-
VALUE
|
|
38
|
+
VALUE eCurlErrFTPWeirdPassReply;
|
|
39
|
+
VALUE eCurlErrFTPWeirdUserReply;
|
|
40
|
+
VALUE eCurlErrFTPWeirdPasvReply;
|
|
41
|
+
VALUE eCurlErrFTPWeird227Format;
|
|
42
42
|
VALUE eCurlErrFTPCantGetHost;
|
|
43
43
|
VALUE eCurlErrFTPCantReconnect;
|
|
44
44
|
VALUE eCurlErrFTPCouldntSetBinary;
|
|
@@ -118,6 +118,9 @@ VALUE mCurlErrBadEasyHandle;
|
|
|
118
118
|
VALUE mCurlErrOutOfMemory;
|
|
119
119
|
VALUE mCurlErrInternalError;
|
|
120
120
|
VALUE mCurlErrBadSocket;
|
|
121
|
+
#if HAVE_CURLM_ADDED_ALREADY
|
|
122
|
+
VALUE mCurlErrAddedAlready;
|
|
123
|
+
#endif
|
|
121
124
|
VALUE mCurlErrUnknownOption;
|
|
122
125
|
|
|
123
126
|
/* binding errors */
|
|
@@ -161,7 +164,7 @@ VALUE rb_curl_easy_error(CURLcode code) {
|
|
|
161
164
|
exclz = eCurlErrConnectFailed;
|
|
162
165
|
break;
|
|
163
166
|
case CURLE_FTP_WEIRD_SERVER_REPLY: /* 8 */
|
|
164
|
-
exclz =
|
|
167
|
+
exclz = eCurlErrFTPWeirdReply;
|
|
165
168
|
break;
|
|
166
169
|
case CURLE_FTP_ACCESS_DENIED: /* 9 denied due to lack of access. */
|
|
167
170
|
exclz = eCurlErrFTPAccessDenied;
|
|
@@ -170,16 +173,16 @@ VALUE rb_curl_easy_error(CURLcode code) {
|
|
|
170
173
|
exclz = eCurlErrFTPBadPassword;
|
|
171
174
|
break;
|
|
172
175
|
case CURLE_FTP_WEIRD_PASS_REPLY: /* 11 */
|
|
173
|
-
exclz =
|
|
176
|
+
exclz = eCurlErrFTPWeirdPassReply;
|
|
174
177
|
break;
|
|
175
178
|
case CURLE_FTP_WEIRD_USER_REPLY: /* 12 */
|
|
176
|
-
exclz =
|
|
179
|
+
exclz = eCurlErrFTPWeirdUserReply;
|
|
177
180
|
break;
|
|
178
181
|
case CURLE_FTP_WEIRD_PASV_REPLY: /* 13 */
|
|
179
|
-
exclz =
|
|
182
|
+
exclz = eCurlErrFTPWeirdPasvReply;
|
|
180
183
|
break;
|
|
181
184
|
case CURLE_FTP_WEIRD_227_FORMAT: /* 14 */
|
|
182
|
-
exclz =
|
|
185
|
+
exclz = eCurlErrFTPWeird227Format;
|
|
183
186
|
break;
|
|
184
187
|
case CURLE_FTP_CANT_GET_HOST: /* 15 */
|
|
185
188
|
exclz = eCurlErrFTPCantGetHost;
|
|
@@ -492,6 +495,11 @@ VALUE rb_curl_multi_error(CURLMcode code) {
|
|
|
492
495
|
case CURLM_UNKNOWN_OPTION: /* 6 */
|
|
493
496
|
exclz = mCurlErrUnknownOption;
|
|
494
497
|
break;
|
|
498
|
+
#endif
|
|
499
|
+
#if HAVE_CURLM_ADDED_ALREADY
|
|
500
|
+
case CURLM_ADDED_ALREADY: /* 7 */
|
|
501
|
+
exclz = mCurlErrAddedAlready;
|
|
502
|
+
break;
|
|
495
503
|
#endif
|
|
496
504
|
default:
|
|
497
505
|
exclz = eCurlErrError;
|
|
@@ -535,13 +543,13 @@ void init_curb_errors() {
|
|
|
535
543
|
eCurlErrHostResolution = rb_define_class_under(mCurlErr, "HostResolutionError", eCurlErrError);
|
|
536
544
|
eCurlErrConnectFailed = rb_define_class_under(mCurlErr, "ConnectionFailedError", eCurlErrError);
|
|
537
545
|
|
|
538
|
-
|
|
546
|
+
eCurlErrFTPWeirdReply = rb_define_class_under(mCurlErr, "WeirdReplyError", eCurlErrFTPError);
|
|
539
547
|
eCurlErrFTPAccessDenied = rb_define_class_under(mCurlErr, "AccessDeniedError", eCurlErrFTPError);
|
|
540
|
-
eCurlErrFTPBadPassword = rb_define_class_under(mCurlErr, "
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
548
|
+
eCurlErrFTPBadPassword = rb_define_class_under(mCurlErr, "BadPasswordError", eCurlErrFTPError);
|
|
549
|
+
eCurlErrFTPWeirdPassReply = rb_define_class_under(mCurlErr, "WeirdPassReplyError", eCurlErrFTPError);
|
|
550
|
+
eCurlErrFTPWeirdUserReply = rb_define_class_under(mCurlErr, "WeirdUserReplyError", eCurlErrFTPError);
|
|
551
|
+
eCurlErrFTPWeirdPasvReply = rb_define_class_under(mCurlErr, "WeirdPasvReplyError", eCurlErrFTPError);
|
|
552
|
+
eCurlErrFTPWeird227Format = rb_define_class_under(mCurlErr, "Weird227FormatError", eCurlErrFTPError);
|
|
545
553
|
eCurlErrFTPCantGetHost = rb_define_class_under(mCurlErr, "CantGetHostError", eCurlErrFTPError);
|
|
546
554
|
eCurlErrFTPCantReconnect = rb_define_class_under(mCurlErr, "CantReconnectError", eCurlErrFTPError);
|
|
547
555
|
eCurlErrFTPCouldntSetBinary = rb_define_class_under(mCurlErr, "CouldntSetBinaryError", eCurlErrFTPError);
|
|
@@ -625,6 +633,9 @@ void init_curb_errors() {
|
|
|
625
633
|
mCurlErrOutOfMemory = rb_define_class_under(mCurlErr, "MultiOutOfMemory", eCurlErrError);
|
|
626
634
|
mCurlErrInternalError = rb_define_class_under(mCurlErr, "MultiInternalError", eCurlErrError);
|
|
627
635
|
mCurlErrBadSocket = rb_define_class_under(mCurlErr, "MultiBadSocket", eCurlErrError);
|
|
636
|
+
#if HAVE_CURLM_ADDED_ALREADY
|
|
637
|
+
mCurlErrAddedAlready = rb_define_class_under(mCurlErr, "MultiAddedAlready", eCurlErrError);
|
|
638
|
+
#endif
|
|
628
639
|
mCurlErrUnknownOption = rb_define_class_under(mCurlErr, "MultiUnknownOption", eCurlErrError);
|
|
629
640
|
|
|
630
641
|
eCurlErrLDAPInvalidURL = rb_define_class_under(mCurlErr, "InvalidLDAPURLError", eCurlErrLDAPError);
|
data/ext/curb_errors.h
CHANGED
|
@@ -30,13 +30,13 @@ extern VALUE eCurlErrMalformedURLUser;
|
|
|
30
30
|
extern VALUE eCurlErrProxyResolution;
|
|
31
31
|
extern VALUE eCurlErrHostResolution;
|
|
32
32
|
extern VALUE eCurlErrConnectFailed;
|
|
33
|
-
extern VALUE
|
|
33
|
+
extern VALUE eCurlErrFTPWeirdReply;
|
|
34
34
|
extern VALUE eCurlErrFTPAccessDenied;
|
|
35
35
|
extern VALUE eCurlErrFTPBadPassword;
|
|
36
|
-
extern VALUE
|
|
37
|
-
extern VALUE
|
|
38
|
-
extern VALUE
|
|
39
|
-
extern VALUE
|
|
36
|
+
extern VALUE eCurlErrFTPWeirdPassReply;
|
|
37
|
+
extern VALUE eCurlErrFTPWeirdUserReply;
|
|
38
|
+
extern VALUE eCurlErrFTPWeirdPasvReply;
|
|
39
|
+
extern VALUE eCurlErrFTPWeird227Format;
|
|
40
40
|
extern VALUE eCurlErrFTPCantGetHost;
|
|
41
41
|
extern VALUE eCurlErrFTPCantReconnect;
|
|
42
42
|
extern VALUE eCurlErrFTPCouldntSetBinary;
|
|
@@ -116,6 +116,9 @@ extern VALUE mCurlErrOutOfMemory;
|
|
|
116
116
|
extern VALUE mCurlErrInternalError;
|
|
117
117
|
extern VALUE mCurlErrBadSocket;
|
|
118
118
|
extern VALUE mCurlErrUnknownOption;
|
|
119
|
+
#if HAVE_CURLM_ADDED_ALREADY
|
|
120
|
+
extern VALUE mCurlErrAddedAlready;
|
|
121
|
+
#endif
|
|
119
122
|
|
|
120
123
|
/* binding errors */
|
|
121
124
|
extern VALUE eCurlErrInvalidPostField;
|