curb 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of curb might be problematic. Click here for more details.
- data/LICENSE +51 -0
- data/README +106 -0
- data/Rakefile +302 -0
- data/doc.rb +42 -0
- data/ext/curb.c +333 -0
- data/ext/curb.h +39 -0
- data/ext/curb.rb +46 -0
- data/ext/curb_easy.c +2138 -0
- data/ext/curb_easy.h +73 -0
- data/ext/curb_errors.c +471 -0
- data/ext/curb_errors.h +106 -0
- data/ext/curb_macros.h +114 -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 +24 -0
- data/samples/gmail.rb +46 -0
- data/tests/alltests.rb +3 -0
- data/tests/bug_instance_post_differs_from_class_post.rb +53 -0
- data/tests/bug_require_last_or_segfault.rb +40 -0
- data/tests/helper.rb +15 -0
- data/tests/require_last_or_segfault_script.rb +36 -0
- data/tests/tc_curl_easy.rb +415 -0
- data/tests/tc_curl_postfield.rb +141 -0
- data/tests/unittests.rb +2 -0
- metadata +80 -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,333 @@
|
|
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 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 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 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 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 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 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 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 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 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 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 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;
|
226
|
+
|
227
|
+
mCurl = rb_define_module("Curl");
|
228
|
+
|
229
|
+
curlver = rb_str_new2(ver->version);
|
230
|
+
curllongver = rb_str_new2(curl_version());
|
231
|
+
|
232
|
+
rb_define_const(mCurl, "CURB_VERSION", rb_str_new2(CURB_VERSION));
|
233
|
+
rb_define_const(mCurl, "VERSION", curlver);
|
234
|
+
rb_define_const(mCurl, "CURL_VERSION", curlver);
|
235
|
+
rb_define_const(mCurl, "LONG_VERSION", curllongver);
|
236
|
+
rb_define_const(mCurl, "CURL_LONG_VERSION", curllongver);
|
237
|
+
|
238
|
+
/* Passed to on_debug handler to indicate that the data is informational text. */
|
239
|
+
rb_define_const(mCurl, "CURLINFO_TEXT", INT2FIX(CURLINFO_TEXT));
|
240
|
+
|
241
|
+
/* Passed to on_debug handler to indicate that the data is header (or header-like) data received from the peer. */
|
242
|
+
rb_define_const(mCurl, "CURLINFO_HEADER_IN", INT2FIX(CURLINFO_HEADER_IN));
|
243
|
+
|
244
|
+
/* Passed to on_debug handler to indicate that the data is header (or header-like) data sent to the peer. */
|
245
|
+
rb_define_const(mCurl, "CURLINFO_HEADER_OUT", INT2FIX(CURLINFO_HEADER_OUT));
|
246
|
+
|
247
|
+
/* Passed to on_debug handler to indicate that the data is protocol data received from the peer. */
|
248
|
+
rb_define_const(mCurl, "CURLINFO_DATA_IN", INT2FIX(CURLINFO_DATA_IN));
|
249
|
+
|
250
|
+
/* Passed to on_debug handler to indicate that the data is protocol data sent to the peer. */
|
251
|
+
rb_define_const(mCurl, "CURLINFO_DATA_OUT", INT2FIX(CURLINFO_DATA_OUT));
|
252
|
+
|
253
|
+
/* When passed to Curl::Easy#proxy_type , indicates that the proxy is an HTTP proxy. (libcurl >= 7.10) */
|
254
|
+
#ifdef CURLPROXY_HTTP
|
255
|
+
rb_define_const(mCurl, "CURLPROXY_HTTP", INT2FIX(CURLPROXY_HTTP));
|
256
|
+
#else
|
257
|
+
rb_define_const(mCurl, "CURLPROXY_HTTP", INT2FIX(-1));
|
258
|
+
#endif
|
259
|
+
|
260
|
+
/* When passed to Curl::Easy#proxy_type , indicates that the proxy is a SOCKS4 proxy. (libcurl >= 7.15.2) */
|
261
|
+
#ifdef CURLPROXY_SOCKS4
|
262
|
+
rb_define_const(mCurl, "CURLPROXY_SOCKS4", INT2FIX(CURLPROXY_SOCKS4));
|
263
|
+
#else
|
264
|
+
rb_define_const(mCurl, "CURLPROXY_SOCKS4", INT2FIX(-2));
|
265
|
+
#endif
|
266
|
+
|
267
|
+
/* When passed to Curl::Easy#proxy_type , indicates that the proxy is a SOCKS5 proxy. (libcurl >= 7.10) */
|
268
|
+
#ifdef CURLPROXY_SOCKS5
|
269
|
+
rb_define_const(mCurl, "CURLPROXY_SOCKS5", INT2FIX(CURLPROXY_SOCKS5));
|
270
|
+
#else
|
271
|
+
rb_define_const(mCurl, "CURLPROXY_SOCKS5", INT2FIX(-2));
|
272
|
+
#endif
|
273
|
+
|
274
|
+
/* When passed to Curl::Easy#http_auth_types or Curl::Easy#proxy_auth_types, directs libcurl to use Basic authentication. */
|
275
|
+
#ifdef CURLAUTH_BASIC
|
276
|
+
rb_define_const(mCurl, "CURLAUTH_BASIC", INT2FIX(CURLAUTH_BASIC));
|
277
|
+
#else
|
278
|
+
rb_define_const(mCurl, "CURLAUTH_BASIC", INT2FIX(0);
|
279
|
+
#endif
|
280
|
+
|
281
|
+
/* When passed to Curl::Easy#http_auth_types or Curl::Easy#proxy_auth_types, directs libcurl to use Digest authentication. */
|
282
|
+
#ifdef CURLAUTH_DIGEST
|
283
|
+
rb_define_const(mCurl, "CURLAUTH_DIGEST", INT2FIX(CURLAUTH_DIGEST));
|
284
|
+
#else
|
285
|
+
rb_define_const(mCurl, "CURLAUTH_DIGEST", INT2FIX(0));
|
286
|
+
#endif
|
287
|
+
|
288
|
+
/* 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. */
|
289
|
+
#ifdef CURLAUTH_GSSNEGOTIATE
|
290
|
+
rb_define_const(mCurl, "CURLAUTH_GSSNEGOTIATE", INT2FIX(CURLAUTH_GSSNEGOTIATE));
|
291
|
+
#else
|
292
|
+
rb_define_const(mCurl, "CURLAUTH_GSSNEGOTIATE", INT2FIX(0));
|
293
|
+
#endif
|
294
|
+
|
295
|
+
/* 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. */
|
296
|
+
#ifdef CURLAUTH_NTLM
|
297
|
+
rb_define_const(mCurl, "CURLAUTH_NTLM", INT2FIX(CURLAUTH_NTLM));
|
298
|
+
#else
|
299
|
+
rb_define_const(mCurl, "CURLAUTH_NTLM", INT2FIX(0));
|
300
|
+
#endif
|
301
|
+
|
302
|
+
/* When passed to Curl::Easy#http_auth_types or Curl::Easy#proxy_auth_types, allows libcurl to select any suitable authentication method except basic. */
|
303
|
+
#ifdef CURLAUTH_ANYSAFE
|
304
|
+
rb_define_const(mCurl, "CURLAUTH_ANYSAFE", INT2FIX(CURLAUTH_ANYSAFE));
|
305
|
+
#else
|
306
|
+
rb_define_const(mCurl, "CURLAUTH_ANYSAFE", INT2FIX(0));
|
307
|
+
#endif
|
308
|
+
|
309
|
+
/* When passed to Curl::Easy#http_auth_types or Curl::Easy#proxy_auth_types, allows libcurl to select any suitable authentication method. */
|
310
|
+
#ifdef CURLAUTH_ANY
|
311
|
+
rb_define_const(mCurl, "CURLAUTH_ANY", INT2FIX(CURLAUTH_ANY));
|
312
|
+
#else
|
313
|
+
rb_define_const(mCurl, "CURLAUTH_ANY", INT2FIX(0));
|
314
|
+
#endif
|
315
|
+
|
316
|
+
rb_define_singleton_method(mCurl, "ipv6?", ruby_curl_ipv6_q, 0);
|
317
|
+
rb_define_singleton_method(mCurl, "kerberos4?", ruby_curl_kerberos4_q, 0);
|
318
|
+
rb_define_singleton_method(mCurl, "ssl?", ruby_curl_ssl_q, 0);
|
319
|
+
rb_define_singleton_method(mCurl, "libz?", ruby_curl_libz_q, 0);
|
320
|
+
rb_define_singleton_method(mCurl, "ntlm?", ruby_curl_ntlm_q, 0);
|
321
|
+
rb_define_singleton_method(mCurl, "gssnegotiate?", ruby_curl_gssnegotiate_q, 0);
|
322
|
+
rb_define_singleton_method(mCurl, "debug?", ruby_curl_debug_q, 0);
|
323
|
+
rb_define_singleton_method(mCurl, "asyncdns?", ruby_curl_asyncdns_q, 0);
|
324
|
+
rb_define_singleton_method(mCurl, "spnego?", ruby_curl_spnego_q, 0);
|
325
|
+
rb_define_singleton_method(mCurl, "largefile?", ruby_curl_largefile_q, 0);
|
326
|
+
rb_define_singleton_method(mCurl, "idn?", ruby_curl_idn_q, 0);
|
327
|
+
rb_define_singleton_method(mCurl, "sspi?", ruby_curl_sspi_q, 0);
|
328
|
+
rb_define_singleton_method(mCurl, "conv?", ruby_curl_conv_q, 0);
|
329
|
+
|
330
|
+
init_curb_errors();
|
331
|
+
init_curb_easy();
|
332
|
+
init_curb_postfield();
|
333
|
+
}
|
data/ext/curb.h
ADDED
@@ -0,0 +1,39 @@
|
|
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_easy.h"
|
15
|
+
#include "curb_errors.h"
|
16
|
+
#include "curb_postfield.h"
|
17
|
+
|
18
|
+
#include "curb_macros.h"
|
19
|
+
|
20
|
+
// These should be managed from the Rake 'release' task.
|
21
|
+
#define CURB_VERSION "0.1.0"
|
22
|
+
#define CURB_VER_NUM 100
|
23
|
+
#define CURB_VER_MAJ 0
|
24
|
+
#define CURB_VER_MIN 1
|
25
|
+
#define CURB_VER_MIC 0
|
26
|
+
#define CURB_VER_PATCH 0
|
27
|
+
|
28
|
+
|
29
|
+
// Maybe not yet defined in Ruby
|
30
|
+
#ifndef RSTRING_LEN
|
31
|
+
#define RSTRING_LEN(x) RSTRING(x)->len
|
32
|
+
#endif
|
33
|
+
|
34
|
+
extern VALUE mCurl;
|
35
|
+
|
36
|
+
extern void Init_curb_core();
|
37
|
+
|
38
|
+
#endif
|
39
|
+
|
data/ext/curb.rb
ADDED
@@ -0,0 +1,46 @@
|
|
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)
|
31
|
+
curl = Curl::Easy.new(url) { |curl| yield curl if block_given? }
|
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
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|