namelessjon-curb 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +51 -0
- data/README +128 -0
- data/Rakefile +303 -0
- data/doc.rb +42 -0
- data/ext/curb.c +337 -0
- data/ext/curb.h +41 -0
- data/ext/curb.rb +48 -0
- data/ext/curb_easy.c +2540 -0
- data/ext/curb_easy.h +94 -0
- data/ext/curb_errors.c +518 -0
- data/ext/curb_errors.h +117 -0
- data/ext/curb_macros.h +114 -0
- data/ext/curb_multi.c +323 -0
- data/ext/curb_multi.h +25 -0
- data/ext/curb_postfield.c +499 -0
- data/ext/curb_postfield.h +40 -0
- data/ext/curl.rb +2 -0
- data/ext/extconf.rb +81 -0
- data/tests/helper.rb +109 -0
- data/tests/tc_curl_easy.rb +495 -0
- data/tests/tc_curl_multi.rb +249 -0
- data/tests/tc_curl_postfield.rb +141 -0
- data/tests/unittests.rb +2 -0
- metadata +77 -0
data/doc.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
include FileUtils
|
3
|
+
|
4
|
+
begin
|
5
|
+
incflags = File.read('ext/Makefile')[/INCFLAGS\s*=\s*(.*)$/,1]
|
6
|
+
rescue Errno::ENOENT
|
7
|
+
$stderr.puts("No makefile found; run `rake ext/Makefile' first.")
|
8
|
+
end
|
9
|
+
|
10
|
+
pp_srcdir = 'ext'
|
11
|
+
|
12
|
+
rm_rf(tmpdir = '.doc-tmp')
|
13
|
+
mkdir(tmpdir)
|
14
|
+
|
15
|
+
begin
|
16
|
+
if ARGV.include?('--cpp')
|
17
|
+
begin
|
18
|
+
if `cpp --version` =~ /\(GCC\)/
|
19
|
+
# gnu cpp
|
20
|
+
$stderr.puts "Running GNU cpp over source"
|
21
|
+
|
22
|
+
Dir['ext/*.c'].each do |fn|
|
23
|
+
system("cpp -DRDOC_NEVER_DEFINED -C #{incflags} -o " +
|
24
|
+
"#{File.join(tmpdir, File.basename(fn))} #{fn}")
|
25
|
+
end
|
26
|
+
|
27
|
+
pp_srcdir = tmpdir
|
28
|
+
else
|
29
|
+
$stderr.puts "Not running cpp (non-GNU)"
|
30
|
+
end
|
31
|
+
rescue
|
32
|
+
# no cpp
|
33
|
+
$stderr.puts "No cpp found"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
system("rdoc --title='Curb - libcurl bindings for ruby' --main=README #{pp_srcdir}/*.c README LICENSE ext/curb.rb")
|
38
|
+
ensure
|
39
|
+
rm_rf(tmpdir)
|
40
|
+
end
|
41
|
+
|
42
|
+
|
data/ext/curb.c
ADDED
@@ -0,0 +1,337 @@
|
|
1
|
+
/* Curb - Libcurl(3) bindings for Ruby.
|
2
|
+
* Copyright (c)2006 Ross Bamford.
|
3
|
+
* Licensed under the Ruby License. See LICENSE for details.
|
4
|
+
*
|
5
|
+
* $Id: curb.c 35 2006-12-23 15:22:19Z roscopeco $
|
6
|
+
*/
|
7
|
+
|
8
|
+
#include "curb.h"
|
9
|
+
|
10
|
+
VALUE mCurl;
|
11
|
+
|
12
|
+
/* ================== VER QUERY FUNCS ==============*/
|
13
|
+
|
14
|
+
/*
|
15
|
+
* call-seq:
|
16
|
+
* Curl.ipv6? => true or false
|
17
|
+
*
|
18
|
+
* Returns true if the installed libcurl supports IPv6.
|
19
|
+
*/
|
20
|
+
static VALUE ruby_curl_ipv6_q(VALUE mod) {
|
21
|
+
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
|
22
|
+
return((ver->features & CURL_VERSION_IPV6) ? Qtrue : Qfalse);
|
23
|
+
}
|
24
|
+
|
25
|
+
/*
|
26
|
+
* call-seq:
|
27
|
+
* Curl.kerberos4? => true or false
|
28
|
+
*
|
29
|
+
* Returns true if the installed libcurl supports Kerberos4 authentication
|
30
|
+
* with FTP connections.
|
31
|
+
*/
|
32
|
+
static VALUE ruby_curl_kerberos4_q(VALUE mod) {
|
33
|
+
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
|
34
|
+
return((ver->features & CURL_VERSION_KERBEROS4) ? Qtrue : Qfalse);
|
35
|
+
}
|
36
|
+
|
37
|
+
/*
|
38
|
+
* call-seq:
|
39
|
+
* Curl.ssl? => true or false
|
40
|
+
*
|
41
|
+
* Returns true if the installed libcurl supports SSL connections.
|
42
|
+
* For libcurl versions < 7.10, always returns false.
|
43
|
+
*/
|
44
|
+
static VALUE ruby_curl_ssl_q(VALUE mod) {
|
45
|
+
#ifdef HAVE_CURL_VERSION_SSL
|
46
|
+
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
|
47
|
+
return((ver->features & CURL_VERSION_SSL) ? Qtrue : Qfalse);
|
48
|
+
#else
|
49
|
+
return Qfalse;
|
50
|
+
#endif
|
51
|
+
}
|
52
|
+
|
53
|
+
/*
|
54
|
+
* call-seq:
|
55
|
+
* Curl.libz? => true or false
|
56
|
+
*
|
57
|
+
* Returns true if the installed libcurl supports HTTP deflate
|
58
|
+
* using libz. For libcurl versions < 7.10, always returns false.
|
59
|
+
*/
|
60
|
+
static VALUE ruby_curl_libz_q(VALUE mod) {
|
61
|
+
#ifdef HAVE_CURL_VERSION_LIBZ
|
62
|
+
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
|
63
|
+
return((ver->features & CURL_VERSION_LIBZ) ? Qtrue : Qfalse);
|
64
|
+
#else
|
65
|
+
return Qfalse;
|
66
|
+
#endif
|
67
|
+
}
|
68
|
+
|
69
|
+
/*
|
70
|
+
* call-seq:
|
71
|
+
* Curl.ntlm? => true or false
|
72
|
+
*
|
73
|
+
* Returns true if the installed libcurl supports HTTP NTLM.
|
74
|
+
* For libcurl versions < 7.10.6, always returns false.
|
75
|
+
*/
|
76
|
+
static VALUE ruby_curl_ntlm_q(VALUE mod) {
|
77
|
+
#ifdef HAVE_CURL_VERSION_NTLM
|
78
|
+
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
|
79
|
+
return((ver->features & CURL_VERSION_NTLM) ? Qtrue : Qfalse);
|
80
|
+
#else
|
81
|
+
return Qfalse;
|
82
|
+
#endif
|
83
|
+
}
|
84
|
+
|
85
|
+
/*
|
86
|
+
* call-seq:
|
87
|
+
* Curl.gssnegotiate? => true or false
|
88
|
+
*
|
89
|
+
* Returns true if the installed libcurl supports HTTP GSS-Negotiate.
|
90
|
+
* For libcurl versions < 7.10.6, always returns false.
|
91
|
+
*/
|
92
|
+
static VALUE ruby_curl_gssnegotiate_q(VALUE mod) {
|
93
|
+
#ifdef HAVE_CURL_VERSION_GSSNEGOTIATE
|
94
|
+
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
|
95
|
+
return((ver->features & CURL_VERSION_GSSNEGOTIATE) ? Qtrue : Qfalse);
|
96
|
+
#else
|
97
|
+
return Qfalse;
|
98
|
+
#endif
|
99
|
+
}
|
100
|
+
|
101
|
+
/*
|
102
|
+
* call-seq:
|
103
|
+
* Curl.debug? => true or false
|
104
|
+
*
|
105
|
+
* Returns true if the installed libcurl was built with extra debug
|
106
|
+
* capabilities built-in. For libcurl versions < 7.10.6, always returns
|
107
|
+
* false.
|
108
|
+
*/
|
109
|
+
static VALUE ruby_curl_debug_q(VALUE mod) {
|
110
|
+
#ifdef HAVE_CURL_VERSION_DEBUG
|
111
|
+
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
|
112
|
+
return((ver->features & CURL_VERSION_DEBUG) ? Qtrue : Qfalse);
|
113
|
+
#else
|
114
|
+
return Qfalse;
|
115
|
+
#endif
|
116
|
+
}
|
117
|
+
|
118
|
+
/*
|
119
|
+
* call-seq:
|
120
|
+
* Curl.asyncdns? => true or false
|
121
|
+
*
|
122
|
+
* Returns true if the installed libcurl was built with support for
|
123
|
+
* asynchronous name lookups, which allows more exact timeouts (even
|
124
|
+
* on Windows) and less blocking when using the multi interface.
|
125
|
+
* For libcurl versions < 7.10.7, always returns false.
|
126
|
+
*/
|
127
|
+
static VALUE ruby_curl_asyncdns_q(VALUE mod) {
|
128
|
+
#ifdef HAVE_CURL_VERSION_ASYNCHDNS
|
129
|
+
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
|
130
|
+
return((ver->features & CURL_VERSION_ASYNCHDNS) ? Qtrue : Qfalse);
|
131
|
+
#else
|
132
|
+
return Qfalse;
|
133
|
+
#endif
|
134
|
+
}
|
135
|
+
|
136
|
+
/*
|
137
|
+
* call-seq:
|
138
|
+
* Curl.spnego? => true or false
|
139
|
+
*
|
140
|
+
* Returns true if the installed libcurl was built with support for SPNEGO
|
141
|
+
* authentication (Simple and Protected GSS-API Negotiation Mechanism, defined
|
142
|
+
* in RFC 2478). For libcurl versions < 7.10.8, always returns false.
|
143
|
+
*/
|
144
|
+
static VALUE ruby_curl_spnego_q(VALUE mod) {
|
145
|
+
#ifdef HAVE_CURL_VERSION_SPNEGO
|
146
|
+
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
|
147
|
+
return((ver->features & CURL_VERSION_SPNEGO) ? Qtrue : Qfalse);
|
148
|
+
#else
|
149
|
+
return Qfalse;
|
150
|
+
#endif
|
151
|
+
}
|
152
|
+
|
153
|
+
/*
|
154
|
+
* call-seq:
|
155
|
+
* Curl.largefile? => true or false
|
156
|
+
*
|
157
|
+
* Returns true if the installed libcurl was built with support for large
|
158
|
+
* files. For libcurl versions < 7.11.1, always returns false.
|
159
|
+
*/
|
160
|
+
static VALUE ruby_curl_largefile_q(VALUE mod) {
|
161
|
+
#ifdef HAVE_CURL_VERSION_LARGEFILE
|
162
|
+
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
|
163
|
+
return((ver->features & CURL_VERSION_LARGEFILE) ? Qtrue : Qfalse);
|
164
|
+
#else
|
165
|
+
return Qfalse;
|
166
|
+
#endif
|
167
|
+
}
|
168
|
+
|
169
|
+
/*
|
170
|
+
* call-seq:
|
171
|
+
* Curl.idn? => true or false
|
172
|
+
*
|
173
|
+
* Returns true if the installed libcurl was built with support for IDNA,
|
174
|
+
* domain names with international letters. For libcurl versions < 7.12.0,
|
175
|
+
* always returns false.
|
176
|
+
*/
|
177
|
+
static VALUE ruby_curl_idn_q(VALUE mod) {
|
178
|
+
#ifdef HAVE_CURL_VERSION_IDN
|
179
|
+
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
|
180
|
+
return((ver->features & CURL_VERSION_IDN) ? Qtrue : Qfalse);
|
181
|
+
#else
|
182
|
+
return Qfalse;
|
183
|
+
#endif
|
184
|
+
}
|
185
|
+
|
186
|
+
/*
|
187
|
+
* call-seq:
|
188
|
+
* Curl.sspi? => true or false
|
189
|
+
*
|
190
|
+
* Returns true if the installed libcurl was built with support for SSPI.
|
191
|
+
* This is only available on Windows and makes libcurl use Windows-provided
|
192
|
+
* functions for NTLM authentication. It also allows libcurl to use the current
|
193
|
+
* user and the current user's password without the app having to pass them on.
|
194
|
+
* For libcurl versions < 7.13.2, always returns false.
|
195
|
+
*/
|
196
|
+
static VALUE ruby_curl_sspi_q(VALUE mod) {
|
197
|
+
#ifdef HAVE_CURL_VERSION_SSPI
|
198
|
+
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
|
199
|
+
return((ver->features & CURL_VERSION_SSPI) ? Qtrue : Qfalse);
|
200
|
+
#else
|
201
|
+
return Qfalse;
|
202
|
+
#endif
|
203
|
+
}
|
204
|
+
|
205
|
+
/*
|
206
|
+
* call-seq:
|
207
|
+
* Curl.conv? => true or false
|
208
|
+
*
|
209
|
+
* Returns true if the installed libcurl was built with support for character
|
210
|
+
* conversions. For libcurl versions < 7.15.4, always returns false.
|
211
|
+
*/
|
212
|
+
static VALUE ruby_curl_conv_q(VALUE mod) {
|
213
|
+
#ifdef HAVE_CURL_VERSION_CONV
|
214
|
+
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
|
215
|
+
return((ver->features & CURL_VERSION_CONV) ? Qtrue : Qfalse);
|
216
|
+
#else
|
217
|
+
return Qfalse;
|
218
|
+
#endif
|
219
|
+
}
|
220
|
+
|
221
|
+
void Init_curb_core() {
|
222
|
+
// TODO we need to call curl_global_cleanup at exit!
|
223
|
+
curl_global_init(CURL_GLOBAL_ALL);
|
224
|
+
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
|
225
|
+
VALUE curlver, curllongver, curlvernum;
|
226
|
+
|
227
|
+
mCurl = rb_define_module("Curl");
|
228
|
+
|
229
|
+
curlver = rb_str_new2(ver->version);
|
230
|
+
curllongver = rb_str_new2(curl_version());
|
231
|
+
curlvernum = LONG2NUM(LIBCURL_VERSION_NUM);
|
232
|
+
|
233
|
+
rb_define_const(mCurl, "CURB_VERSION", rb_str_new2(CURB_VERSION));
|
234
|
+
rb_define_const(mCurl, "VERSION", curlver);
|
235
|
+
rb_define_const(mCurl, "CURL_VERSION", curlver);
|
236
|
+
rb_define_const(mCurl, "VERNUM", curlvernum);
|
237
|
+
rb_define_const(mCurl, "CURL_VERNUM", curlvernum);
|
238
|
+
rb_define_const(mCurl, "LONG_VERSION", curllongver);
|
239
|
+
rb_define_const(mCurl, "CURL_LONG_VERSION", curllongver);
|
240
|
+
|
241
|
+
/* Passed to on_debug handler to indicate that the data is informational text. */
|
242
|
+
rb_define_const(mCurl, "CURLINFO_TEXT", INT2FIX(CURLINFO_TEXT));
|
243
|
+
|
244
|
+
/* Passed to on_debug handler to indicate that the data is header (or header-like) data received from the peer. */
|
245
|
+
rb_define_const(mCurl, "CURLINFO_HEADER_IN", INT2FIX(CURLINFO_HEADER_IN));
|
246
|
+
|
247
|
+
/* Passed to on_debug handler to indicate that the data is header (or header-like) data sent to the peer. */
|
248
|
+
rb_define_const(mCurl, "CURLINFO_HEADER_OUT", INT2FIX(CURLINFO_HEADER_OUT));
|
249
|
+
|
250
|
+
/* Passed to on_debug handler to indicate that the data is protocol data received from the peer. */
|
251
|
+
rb_define_const(mCurl, "CURLINFO_DATA_IN", INT2FIX(CURLINFO_DATA_IN));
|
252
|
+
|
253
|
+
/* Passed to on_debug handler to indicate that the data is protocol data sent to the peer. */
|
254
|
+
rb_define_const(mCurl, "CURLINFO_DATA_OUT", INT2FIX(CURLINFO_DATA_OUT));
|
255
|
+
|
256
|
+
/* When passed to Curl::Easy#proxy_type , indicates that the proxy is an HTTP proxy. (libcurl >= 7.10) */
|
257
|
+
#ifdef HAVE_CURLPROXY_HTTP
|
258
|
+
rb_define_const(mCurl, "CURLPROXY_HTTP", INT2FIX(CURLPROXY_HTTP));
|
259
|
+
#else
|
260
|
+
rb_define_const(mCurl, "CURLPROXY_HTTP", INT2FIX(-1));
|
261
|
+
#endif
|
262
|
+
|
263
|
+
/* When passed to Curl::Easy#proxy_type , indicates that the proxy is a SOCKS4 proxy. (libcurl >= 7.15.2) */
|
264
|
+
#ifdef HAVE_CURLPROXY_SOCKS4
|
265
|
+
rb_define_const(mCurl, "CURLPROXY_SOCKS4", INT2FIX(CURLPROXY_SOCKS4));
|
266
|
+
#else
|
267
|
+
rb_define_const(mCurl, "CURLPROXY_SOCKS4", INT2FIX(-2));
|
268
|
+
#endif
|
269
|
+
|
270
|
+
/* When passed to Curl::Easy#proxy_type , indicates that the proxy is a SOCKS5 proxy. (libcurl >= 7.10) */
|
271
|
+
#ifdef HAVE_CURLPROXY_SOCKS5
|
272
|
+
rb_define_const(mCurl, "CURLPROXY_SOCKS5", INT2FIX(CURLPROXY_SOCKS5));
|
273
|
+
#else
|
274
|
+
rb_define_const(mCurl, "CURLPROXY_SOCKS5", INT2FIX(-2));
|
275
|
+
#endif
|
276
|
+
|
277
|
+
/* When passed to Curl::Easy#http_auth_types or Curl::Easy#proxy_auth_types, directs libcurl to use Basic authentication. */
|
278
|
+
#ifdef HAVE_CURLAUTH_BASIC
|
279
|
+
rb_define_const(mCurl, "CURLAUTH_BASIC", INT2FIX(CURLAUTH_BASIC));
|
280
|
+
#else
|
281
|
+
rb_define_const(mCurl, "CURLAUTH_BASIC", INT2FIX(0);
|
282
|
+
#endif
|
283
|
+
|
284
|
+
/* When passed to Curl::Easy#http_auth_types or Curl::Easy#proxy_auth_types, directs libcurl to use Digest authentication. */
|
285
|
+
#ifdef HAVE_CURLAUTH_DIGEST
|
286
|
+
rb_define_const(mCurl, "CURLAUTH_DIGEST", INT2FIX(CURLAUTH_DIGEST));
|
287
|
+
#else
|
288
|
+
rb_define_const(mCurl, "CURLAUTH_DIGEST", INT2FIX(0));
|
289
|
+
#endif
|
290
|
+
|
291
|
+
/* When passed to Curl::Easy#http_auth_types or Curl::Easy#proxy_auth_types, directs libcurl to use GSS Negotiate authentication. Requires a suitable GSS-API library. */
|
292
|
+
#ifdef HAVE_CURLAUTH_GSSNEGOTIATE
|
293
|
+
rb_define_const(mCurl, "CURLAUTH_GSSNEGOTIATE", INT2FIX(CURLAUTH_GSSNEGOTIATE));
|
294
|
+
#else
|
295
|
+
rb_define_const(mCurl, "CURLAUTH_GSSNEGOTIATE", INT2FIX(0));
|
296
|
+
#endif
|
297
|
+
|
298
|
+
/* When passed to Curl::Easy#http_auth_types or Curl::Easy#proxy_auth_types, directs libcurl to use HTTP NTLM authentication. Requires MS Windows or OpenSSL support. */
|
299
|
+
#ifdef HAVE_CURLAUTH_NTLM
|
300
|
+
rb_define_const(mCurl, "CURLAUTH_NTLM", INT2FIX(CURLAUTH_NTLM));
|
301
|
+
#else
|
302
|
+
rb_define_const(mCurl, "CURLAUTH_NTLM", INT2FIX(0));
|
303
|
+
#endif
|
304
|
+
|
305
|
+
/* When passed to Curl::Easy#http_auth_types or Curl::Easy#proxy_auth_types, allows libcurl to select any suitable authentication method except basic. */
|
306
|
+
#ifdef HAVE_CURLAUTH_ANYSAFE
|
307
|
+
rb_define_const(mCurl, "CURLAUTH_ANYSAFE", INT2FIX(CURLAUTH_ANYSAFE));
|
308
|
+
#else
|
309
|
+
rb_define_const(mCurl, "CURLAUTH_ANYSAFE", INT2FIX(0));
|
310
|
+
#endif
|
311
|
+
|
312
|
+
/* When passed to Curl::Easy#http_auth_types or Curl::Easy#proxy_auth_types, allows libcurl to select any suitable authentication method. */
|
313
|
+
#ifdef HAVE_CURLAUTH_ANY
|
314
|
+
rb_define_const(mCurl, "CURLAUTH_ANY", INT2FIX(CURLAUTH_ANY));
|
315
|
+
#else
|
316
|
+
rb_define_const(mCurl, "CURLAUTH_ANY", INT2FIX(0));
|
317
|
+
#endif
|
318
|
+
|
319
|
+
rb_define_singleton_method(mCurl, "ipv6?", ruby_curl_ipv6_q, 0);
|
320
|
+
rb_define_singleton_method(mCurl, "kerberos4?", ruby_curl_kerberos4_q, 0);
|
321
|
+
rb_define_singleton_method(mCurl, "ssl?", ruby_curl_ssl_q, 0);
|
322
|
+
rb_define_singleton_method(mCurl, "libz?", ruby_curl_libz_q, 0);
|
323
|
+
rb_define_singleton_method(mCurl, "ntlm?", ruby_curl_ntlm_q, 0);
|
324
|
+
rb_define_singleton_method(mCurl, "gssnegotiate?", ruby_curl_gssnegotiate_q, 0);
|
325
|
+
rb_define_singleton_method(mCurl, "debug?", ruby_curl_debug_q, 0);
|
326
|
+
rb_define_singleton_method(mCurl, "asyncdns?", ruby_curl_asyncdns_q, 0);
|
327
|
+
rb_define_singleton_method(mCurl, "spnego?", ruby_curl_spnego_q, 0);
|
328
|
+
rb_define_singleton_method(mCurl, "largefile?", ruby_curl_largefile_q, 0);
|
329
|
+
rb_define_singleton_method(mCurl, "idn?", ruby_curl_idn_q, 0);
|
330
|
+
rb_define_singleton_method(mCurl, "sspi?", ruby_curl_sspi_q, 0);
|
331
|
+
rb_define_singleton_method(mCurl, "conv?", ruby_curl_conv_q, 0);
|
332
|
+
|
333
|
+
init_curb_errors();
|
334
|
+
init_curb_easy();
|
335
|
+
init_curb_postfield();
|
336
|
+
init_curb_multi();
|
337
|
+
}
|
data/ext/curb.h
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
/* Curb - Libcurl(3) bindings for Ruby.
|
2
|
+
* Copyright (c)2006 Ross Bamford.
|
3
|
+
* Licensed under the Ruby License. See LICENSE for details.
|
4
|
+
*
|
5
|
+
* $Id: curb.h 39 2006-12-23 15:28:45Z roscopeco $
|
6
|
+
*/
|
7
|
+
|
8
|
+
#ifndef __CURB_H
|
9
|
+
#define __CURB_H
|
10
|
+
|
11
|
+
#include <ruby.h>
|
12
|
+
#include <curl/curl.h>
|
13
|
+
|
14
|
+
#include "curb_config.h"
|
15
|
+
#include "curb_easy.h"
|
16
|
+
#include "curb_errors.h"
|
17
|
+
#include "curb_postfield.h"
|
18
|
+
#include "curb_multi.h"
|
19
|
+
|
20
|
+
#include "curb_macros.h"
|
21
|
+
|
22
|
+
// These should be managed from the Rake 'release' task.
|
23
|
+
#define CURB_VERSION "0.2.4.0"
|
24
|
+
#define CURB_VER_NUM 224
|
25
|
+
#define CURB_VER_MAJ 0
|
26
|
+
#define CURB_VER_MIN 2
|
27
|
+
#define CURB_VER_MIC 4
|
28
|
+
#define CURB_VER_PATCH 0
|
29
|
+
|
30
|
+
|
31
|
+
// Maybe not yet defined in Ruby
|
32
|
+
#ifndef RSTRING_LEN
|
33
|
+
#define RSTRING_LEN(x) RSTRING(x)->len
|
34
|
+
#endif
|
35
|
+
|
36
|
+
extern VALUE mCurl;
|
37
|
+
|
38
|
+
extern void Init_curb_core();
|
39
|
+
|
40
|
+
#endif
|
41
|
+
|
data/ext/curb.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
begin
|
2
|
+
require 'curb_core'
|
3
|
+
rescue LoadError
|
4
|
+
$: << File.dirname(__FILE__)
|
5
|
+
require 'curb_core'
|
6
|
+
end
|
7
|
+
|
8
|
+
module Curl
|
9
|
+
class Easy
|
10
|
+
class << self
|
11
|
+
|
12
|
+
# call-seq:
|
13
|
+
# Curl::Easy.download(url, filename = url.split(/\?/).first.split(/\//).last) { |curl| ... }
|
14
|
+
#
|
15
|
+
# Stream the specified url (via perform) and save the data directly to the
|
16
|
+
# supplied filename (defaults to the last component of the URL path, which will
|
17
|
+
# usually be the filename most simple urls).
|
18
|
+
#
|
19
|
+
# If a block is supplied, it will be passed the curl instance prior to the
|
20
|
+
# perform call.
|
21
|
+
#
|
22
|
+
# *Note* that the semantics of the on_body handler are subtly changed when using
|
23
|
+
# download, to account for the automatic routing of data to the specified file: The
|
24
|
+
# data string is passed to the handler *before* it is written
|
25
|
+
# to the file, allowing the handler to perform mutative operations where
|
26
|
+
# necessary. As usual, the transfer will be aborted if the on_body handler
|
27
|
+
# returns a size that differs from the data chunk size - in this case, the
|
28
|
+
# offending chunk will *not* be written to the file, the file will be closed,
|
29
|
+
# and a Curl::Err::AbortedByCallbackError will be raised.
|
30
|
+
def download(url, filename = url.split(/\?/).first.split(/\//).last, &blk)
|
31
|
+
curl = Curl::Easy.new(url, &blk)
|
32
|
+
|
33
|
+
File.open(filename, "wb") do |output|
|
34
|
+
old_on_body = curl.on_body do |data|
|
35
|
+
result = old_on_body ? old_on_body.call(data) : data.length
|
36
|
+
output << data if result == data.length
|
37
|
+
result
|
38
|
+
end
|
39
|
+
|
40
|
+
curl.perform
|
41
|
+
end
|
42
|
+
|
43
|
+
return curl
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|