curb 0.8.5 → 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 +7 -0
- data/ext/curb.h +5 -9
- data/ext/curb_easy.c +48 -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 +4 -17
- data/lib/curl/easy.rb +69 -59
- data/lib/curl.rb +6 -1
- data/tests/bug_crash_on_progress.rb +41 -1
- data/tests/bug_issue102.rb +17 -0
- data/tests/helper.rb +6 -1
- data/tests/tc_curl_download.rb +1 -1
- data/tests/tc_curl_easy.rb +17 -4
- data/tests/tc_curl_multi.rb +1 -1
- metadata +23 -24
- 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));
|
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;
|
|
@@ -3097,6 +3125,13 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3097
3125
|
case CURLOPT_NOPROGRESS:
|
|
3098
3126
|
case CURLOPT_NOSIGNAL:
|
|
3099
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;
|
|
3100
3135
|
case CURLOPT_NOBODY: {
|
|
3101
3136
|
int type = rb_type(val);
|
|
3102
3137
|
VALUE value;
|
|
@@ -3129,19 +3164,25 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3129
3164
|
VALUE cookiejar = val;
|
|
3130
3165
|
CURB_OBJECT_HSETTER(ruby_curl_easy, cookiejar);
|
|
3131
3166
|
} break;
|
|
3167
|
+
case CURLOPT_TCP_NODELAY: {
|
|
3168
|
+
curl_easy_setopt(rbce->curl, CURLOPT_TCP_NODELAY, FIX2LONG(val));
|
|
3169
|
+
} break;
|
|
3132
3170
|
case CURLOPT_RESUME_FROM: {
|
|
3133
3171
|
curl_easy_setopt(rbce->curl, CURLOPT_RESUME_FROM, FIX2LONG(val));
|
|
3134
3172
|
} break;
|
|
3135
3173
|
case CURLOPT_FAILONERROR: {
|
|
3136
3174
|
curl_easy_setopt(rbce->curl, CURLOPT_FAILONERROR, FIX2LONG(val));
|
|
3137
3175
|
} break;
|
|
3176
|
+
case CURLOPT_SSL_CIPHER_LIST: {
|
|
3177
|
+
curl_easy_setopt(rbce->curl, CURLOPT_SSL_CIPHER_LIST, StringValueCStr(val));
|
|
3178
|
+
} break;
|
|
3138
3179
|
#if HAVE_CURLOPT_GSSAPI_DELEGATION
|
|
3139
3180
|
case CURLOPT_GSSAPI_DELEGATION: {
|
|
3140
3181
|
curl_easy_setopt(rbce->curl, CURLOPT_GSSAPI_DELEGATION, FIX2LONG(val));
|
|
3141
3182
|
} break;
|
|
3142
3183
|
#endif
|
|
3143
3184
|
default:
|
|
3144
|
-
|
|
3185
|
+
rb_raise(rb_eTypeError, "Curb unsupported option");
|
|
3145
3186
|
}
|
|
3146
3187
|
|
|
3147
3188
|
return val;
|
|
@@ -3247,7 +3288,7 @@ static VALUE ruby_curl_easy_unescape(VALUE self, VALUE str) {
|
|
|
3247
3288
|
|
|
3248
3289
|
/*
|
|
3249
3290
|
* call-seq:
|
|
3250
|
-
* Curl::Easy.error(code) => String
|
|
3291
|
+
* Curl::Easy.error(code) => [ErrCode, String]
|
|
3251
3292
|
*
|
|
3252
3293
|
* translate an internal libcurl error to ruby error class
|
|
3253
3294
|
*/
|
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;
|
data/ext/curb_multi.c
CHANGED
|
@@ -4,13 +4,17 @@
|
|
|
4
4
|
*
|
|
5
5
|
*/
|
|
6
6
|
#include "curb_config.h"
|
|
7
|
-
#
|
|
8
|
-
|
|
7
|
+
#include <ruby.h>
|
|
8
|
+
#ifdef HAVE_RUBY_ST_H
|
|
9
9
|
#include <ruby/st.h>
|
|
10
10
|
#else
|
|
11
|
-
#include <ruby.h>
|
|
12
11
|
#include <st.h>
|
|
13
12
|
#endif
|
|
13
|
+
|
|
14
|
+
#ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
|
|
15
|
+
#include <ruby/thread.h>
|
|
16
|
+
#endif
|
|
17
|
+
|
|
14
18
|
#include "curb_easy.h"
|
|
15
19
|
#include "curb_errors.h"
|
|
16
20
|
#include "curb_postfield.h"
|
|
@@ -64,7 +68,7 @@ rb_hash_clear_i(VALUE key, VALUE value, VALUE dummy) {
|
|
|
64
68
|
|
|
65
69
|
static void curl_multi_free(ruby_curl_multi *rbcm) {
|
|
66
70
|
|
|
67
|
-
if (rbcm && !rbcm->requests == Qnil && rb_type(rbcm->requests) == T_HASH &&
|
|
71
|
+
if (rbcm && !rbcm->requests == Qnil && rb_type(rbcm->requests) == T_HASH && RHASH_SIZE(rbcm->requests) > 0) {
|
|
68
72
|
|
|
69
73
|
rb_hash_foreach( rbcm->requests, (int (*)())curl_multi_flush_easy, (VALUE)rbcm );
|
|
70
74
|
|
|
@@ -262,12 +266,9 @@ VALUE ruby_curl_multi_add(VALUE self, VALUE easy) {
|
|
|
262
266
|
*/
|
|
263
267
|
VALUE ruby_curl_multi_remove(VALUE self, VALUE easy) {
|
|
264
268
|
ruby_curl_multi *rbcm;
|
|
265
|
-
ruby_curl_easy *rbce;
|
|
266
269
|
|
|
267
270
|
Data_Get_Struct(self, ruby_curl_multi, rbcm);
|
|
268
271
|
|
|
269
|
-
Data_Get_Struct(easy, ruby_curl_easy, rbce);
|
|
270
|
-
|
|
271
272
|
rb_curl_multi_remove(rbcm,easy);
|
|
272
273
|
|
|
273
274
|
return self;
|
|
@@ -471,7 +472,7 @@ void cleanup_crt_fd(fd_set *os_set, fd_set *crt_set)
|
|
|
471
472
|
}
|
|
472
473
|
#endif
|
|
473
474
|
|
|
474
|
-
#
|
|
475
|
+
#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
|
475
476
|
struct _select_set {
|
|
476
477
|
int maxfd;
|
|
477
478
|
fd_set *fdread, *fdwrite, *fdexcep;
|
|
@@ -511,7 +512,7 @@ VALUE ruby_curl_multi_perform(int argc, VALUE *argv, VALUE self) {
|
|
|
511
512
|
long timeout_milliseconds;
|
|
512
513
|
struct timeval tv = {0, 0};
|
|
513
514
|
VALUE block = Qnil;
|
|
514
|
-
#
|
|
515
|
+
#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
|
515
516
|
struct _select_set fdset_args;
|
|
516
517
|
#endif
|
|
517
518
|
|
|
@@ -570,17 +571,24 @@ VALUE ruby_curl_multi_perform(int argc, VALUE *argv, VALUE self) {
|
|
|
570
571
|
create_crt_fd(&fdexcep, &crt_fdexcep);
|
|
571
572
|
#endif
|
|
572
573
|
|
|
573
|
-
#
|
|
574
|
+
#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
|
574
575
|
fdset_args.maxfd = maxfd+1;
|
|
575
576
|
fdset_args.fdread = &fdread;
|
|
576
577
|
fdset_args.fdwrite = &fdwrite;
|
|
577
578
|
fdset_args.fdexcep = &fdexcep;
|
|
578
579
|
fdset_args.tv = &tv;
|
|
580
|
+
#ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
|
|
581
|
+
rc = (int)(VALUE) rb_thread_call_without_gvl((void *(*)(void *))curb_select, &fdset_args, RUBY_UBF_IO, 0);
|
|
582
|
+
#elif HAVE_RB_THREAD_BLOCKING_REGION
|
|
579
583
|
rc = rb_thread_blocking_region(curb_select, &fdset_args, RUBY_UBF_IO, 0);
|
|
584
|
+
#elif HAVE_RB_THREAD_FD_SELECT
|
|
585
|
+
rc = rb_thread_fd_select(maxfd+1, &fdread, &fdwrite, &fdexcep, &tv);
|
|
580
586
|
#else
|
|
581
587
|
rc = rb_thread_select(maxfd+1, &fdread, &fdwrite, &fdexcep, &tv);
|
|
582
588
|
#endif
|
|
583
589
|
|
|
590
|
+
#endif
|
|
591
|
+
|
|
584
592
|
#ifdef _WIN32
|
|
585
593
|
cleanup_crt_fd(&fdread, &crt_fdread);
|
|
586
594
|
cleanup_crt_fd(&fdwrite, &crt_fdwrite);
|