curb 0.7.15 → 1.0.0
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 +283 -0
- data/Rakefile +38 -26
- data/ext/banned.h +32 -0
- data/ext/curb.c +903 -46
- data/ext/curb.h +20 -11
- data/ext/curb_easy.c +1039 -565
- data/ext/curb_easy.h +12 -0
- data/ext/curb_errors.c +127 -18
- data/ext/curb_errors.h +8 -5
- data/ext/curb_macros.h +10 -6
- data/ext/curb_multi.c +245 -167
- data/ext/curb_multi.h +0 -1
- data/ext/curb_upload.c +2 -2
- data/ext/extconf.rb +314 -20
- data/lib/curb.rb +2 -308
- data/lib/curl/easy.rb +489 -0
- data/lib/curl/multi.rb +287 -0
- data/lib/curl.rb +68 -1
- data/tests/bug_crash_on_debug.rb +39 -0
- data/tests/bug_crash_on_progress.rb +73 -0
- data/tests/bug_curb_easy_blocks_ruby_threads.rb +2 -2
- data/tests/bug_issue102.rb +17 -0
- data/tests/bug_require_last_or_segfault.rb +1 -1
- data/tests/helper.rb +120 -16
- data/tests/signals.rb +33 -0
- data/tests/tc_curl.rb +69 -0
- data/tests/tc_curl_download.rb +4 -4
- data/tests/tc_curl_easy.rb +327 -43
- data/tests/tc_curl_easy_resolve.rb +16 -0
- data/tests/tc_curl_easy_setopt.rb +31 -0
- data/tests/tc_curl_maxfilesize.rb +12 -0
- data/tests/tc_curl_multi.rb +141 -15
- data/tests/tc_curl_postfield.rb +29 -29
- data/tests/tc_curl_protocols.rb +37 -0
- data/tests/timeout.rb +30 -6
- metadata +61 -58
- data/README +0 -177
data/ext/curb_easy.c
CHANGED
|
@@ -25,9 +25,19 @@ static VALUE rbstrAmp;
|
|
|
25
25
|
|
|
26
26
|
VALUE cCurlEasy;
|
|
27
27
|
|
|
28
|
+
// for Ruby 1.8
|
|
29
|
+
#ifndef HAVE_RB_IO_STDIO_FILE
|
|
30
|
+
static FILE * rb_io_stdio_file(rb_io_t *fptr) {
|
|
31
|
+
return fptr->f;
|
|
32
|
+
}
|
|
33
|
+
#endif
|
|
28
34
|
|
|
29
35
|
/* ================== CURL HANDLER FUNCS ==============*/
|
|
30
36
|
|
|
37
|
+
static VALUE callback_exception(VALUE unused) {
|
|
38
|
+
return Qfalse;
|
|
39
|
+
}
|
|
40
|
+
|
|
31
41
|
/* These handle both body and header data */
|
|
32
42
|
static size_t default_data_handler(char *stream,
|
|
33
43
|
size_t size,
|
|
@@ -92,6 +102,25 @@ static size_t read_data_handler(void *ptr,
|
|
|
92
102
|
}
|
|
93
103
|
}
|
|
94
104
|
|
|
105
|
+
int seek_data_handler(ruby_curl_easy *rbce,
|
|
106
|
+
curl_off_t offset,
|
|
107
|
+
int origin) {
|
|
108
|
+
|
|
109
|
+
VALUE upload = rb_easy_get("upload");
|
|
110
|
+
VALUE stream = ruby_curl_upload_stream_get(upload);
|
|
111
|
+
|
|
112
|
+
if (rb_respond_to(stream, rb_intern("seek"))) {
|
|
113
|
+
rb_funcall(stream, rb_intern("seek"), 2, SEEK_SET, offset);
|
|
114
|
+
} else {
|
|
115
|
+
ruby_curl_upload *rbcu;
|
|
116
|
+
Data_Get_Struct(upload, ruby_curl_upload, rbcu);
|
|
117
|
+
// This OK because curl only uses SEEK_SET as per the documentation
|
|
118
|
+
rbcu->offset = offset;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return 0;
|
|
122
|
+
}
|
|
123
|
+
|
|
95
124
|
static size_t proc_data_handler(char *stream,
|
|
96
125
|
size_t size,
|
|
97
126
|
size_t nmemb,
|
|
@@ -111,27 +140,81 @@ static size_t proc_data_handler(char *stream,
|
|
|
111
140
|
}
|
|
112
141
|
}
|
|
113
142
|
|
|
143
|
+
static size_t proc_data_handler_body(char *stream,
|
|
144
|
+
size_t size,
|
|
145
|
+
size_t nmemb,
|
|
146
|
+
ruby_curl_easy *rbce)
|
|
147
|
+
{
|
|
148
|
+
size_t ret;
|
|
149
|
+
rbce->callback_active = 1;
|
|
150
|
+
ret = proc_data_handler(stream, size, nmemb, rb_easy_get("body_proc"));
|
|
151
|
+
rbce->callback_active = 0;
|
|
152
|
+
return ret;
|
|
153
|
+
}
|
|
154
|
+
static size_t proc_data_handler_header(char *stream,
|
|
155
|
+
size_t size,
|
|
156
|
+
size_t nmemb,
|
|
157
|
+
ruby_curl_easy *rbce)
|
|
158
|
+
{
|
|
159
|
+
size_t ret;
|
|
160
|
+
rbce->callback_active = 1;
|
|
161
|
+
ret = proc_data_handler(stream, size, nmemb, rb_easy_get("header_proc"));
|
|
162
|
+
rbce->callback_active = 0;
|
|
163
|
+
return ret;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
static VALUE call_progress_handler(VALUE ary) {
|
|
168
|
+
return rb_funcall(rb_ary_entry(ary, 0), idCall, 4,
|
|
169
|
+
rb_ary_entry(ary, 1), // rb_float_new(dltotal),
|
|
170
|
+
rb_ary_entry(ary, 2), // rb_float_new(dlnow),
|
|
171
|
+
rb_ary_entry(ary, 3), // rb_float_new(ultotal),
|
|
172
|
+
rb_ary_entry(ary, 4)); // rb_float_new(ulnow));
|
|
173
|
+
}
|
|
174
|
+
|
|
114
175
|
static int proc_progress_handler(VALUE proc,
|
|
115
176
|
double dltotal,
|
|
116
177
|
double dlnow,
|
|
117
178
|
double ultotal,
|
|
118
179
|
double ulnow) {
|
|
119
180
|
VALUE procret;
|
|
181
|
+
VALUE callargs = rb_ary_new2(5);
|
|
120
182
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
183
|
+
rb_ary_store(callargs, 0, proc);
|
|
184
|
+
rb_ary_store(callargs, 1, rb_float_new(dltotal));
|
|
185
|
+
rb_ary_store(callargs, 2, rb_float_new(dlnow));
|
|
186
|
+
rb_ary_store(callargs, 3, rb_float_new(ultotal));
|
|
187
|
+
rb_ary_store(callargs, 4, rb_float_new(ulnow));
|
|
188
|
+
|
|
189
|
+
//v = rb_rescue(range_check, (VALUE)args, range_failed, 0);
|
|
190
|
+
//procret = rb_funcall(proc, idCall, 4, rb_float_new(dltotal),
|
|
191
|
+
// rb_float_new(dlnow),
|
|
192
|
+
// rb_float_new(ultotal),
|
|
193
|
+
// rb_float_new(ulnow));
|
|
194
|
+
procret = rb_rescue(call_progress_handler, callargs, callback_exception, Qnil);
|
|
125
195
|
|
|
126
196
|
return(((procret == Qfalse) || (procret == Qnil)) ? -1 : 0);
|
|
127
197
|
}
|
|
128
198
|
|
|
199
|
+
static VALUE call_debug_handler(VALUE ary) {
|
|
200
|
+
return rb_funcall(rb_ary_entry(ary, 0), idCall, 2,
|
|
201
|
+
rb_ary_entry(ary, 1), // INT2NUM(type),
|
|
202
|
+
rb_ary_entry(ary, 2)); // rb_str_new(data, data_len)
|
|
203
|
+
}
|
|
129
204
|
static int proc_debug_handler(CURL *curl,
|
|
130
205
|
curl_infotype type,
|
|
131
206
|
char *data,
|
|
132
207
|
size_t data_len,
|
|
133
208
|
VALUE proc) {
|
|
134
|
-
|
|
209
|
+
VALUE callargs = rb_ary_new2(3);
|
|
210
|
+
rb_ary_store(callargs, 0, proc);
|
|
211
|
+
rb_ary_store(callargs, 1, INT2NUM(type));
|
|
212
|
+
rb_ary_store(callargs, 2, rb_str_new(data, data_len));
|
|
213
|
+
rb_rescue(call_debug_handler, callargs, callback_exception, Qnil);
|
|
214
|
+
/* no way to indicate to libcurl that we should break out given an exception in the on_debug handler...
|
|
215
|
+
* this means exceptions will be swallowed
|
|
216
|
+
*/
|
|
217
|
+
//rb_funcall(proc, idCall, 2, INT2NUM(type), rb_str_new(data, data_len));
|
|
135
218
|
return 0;
|
|
136
219
|
}
|
|
137
220
|
|
|
@@ -146,12 +229,31 @@ static void ruby_curl_easy_free(ruby_curl_easy *rbce) {
|
|
|
146
229
|
curl_slist_free_all(rbce->curl_headers);
|
|
147
230
|
}
|
|
148
231
|
|
|
232
|
+
if (rbce->curl_proxy_headers) {
|
|
233
|
+
curl_slist_free_all(rbce->curl_proxy_headers);
|
|
234
|
+
}
|
|
235
|
+
|
|
149
236
|
if (rbce->curl_ftp_commands) {
|
|
150
237
|
curl_slist_free_all(rbce->curl_ftp_commands);
|
|
151
238
|
}
|
|
152
239
|
|
|
240
|
+
if (rbce->curl_resolve) {
|
|
241
|
+
curl_slist_free_all(rbce->curl_resolve);
|
|
242
|
+
}
|
|
243
|
+
|
|
153
244
|
if (rbce->curl) {
|
|
245
|
+
/* disable any progress or debug events */
|
|
246
|
+
curl_easy_setopt(rbce->curl, CURLOPT_WRITEFUNCTION, NULL);
|
|
247
|
+
curl_easy_setopt(rbce->curl, CURLOPT_WRITEDATA, NULL);
|
|
248
|
+
curl_easy_setopt(rbce->curl, CURLOPT_HEADERFUNCTION, NULL);
|
|
249
|
+
curl_easy_setopt(rbce->curl, CURLOPT_HEADERDATA, NULL);
|
|
250
|
+
curl_easy_setopt(rbce->curl, CURLOPT_DEBUGFUNCTION, NULL);
|
|
251
|
+
curl_easy_setopt(rbce->curl, CURLOPT_DEBUGDATA, NULL);
|
|
252
|
+
curl_easy_setopt(rbce->curl, CURLOPT_VERBOSE, 0);
|
|
253
|
+
curl_easy_setopt(rbce->curl, CURLOPT_PROGRESSFUNCTION, NULL);
|
|
254
|
+
curl_easy_setopt(rbce->curl, CURLOPT_NOPROGRESS, 1);
|
|
154
255
|
curl_easy_cleanup(rbce->curl);
|
|
256
|
+
rbce->curl = NULL;
|
|
155
257
|
}
|
|
156
258
|
}
|
|
157
259
|
|
|
@@ -166,8 +268,12 @@ void curl_easy_free(ruby_curl_easy *rbce) {
|
|
|
166
268
|
static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
|
167
269
|
rbce->opts = rb_hash_new();
|
|
168
270
|
|
|
271
|
+
memset(rbce->err_buf, 0, sizeof(rbce->err_buf));
|
|
272
|
+
|
|
169
273
|
rbce->curl_headers = NULL;
|
|
274
|
+
rbce->curl_proxy_headers = NULL;
|
|
170
275
|
rbce->curl_ftp_commands = NULL;
|
|
276
|
+
rbce->curl_resolve = NULL;
|
|
171
277
|
|
|
172
278
|
/* various-typed opts */
|
|
173
279
|
rbce->local_port = 0;
|
|
@@ -178,20 +284,25 @@ static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
|
|
178
284
|
rbce->proxy_auth_types = 0;
|
|
179
285
|
rbce->max_redirs = -1;
|
|
180
286
|
rbce->timeout = 0;
|
|
287
|
+
rbce->timeout_ms = 0;
|
|
181
288
|
rbce->connect_timeout = 0;
|
|
289
|
+
rbce->connect_timeout_ms = 0;
|
|
182
290
|
rbce->dns_cache_timeout = 60;
|
|
183
291
|
rbce->ftp_response_timeout = 0;
|
|
184
292
|
rbce->low_speed_limit = 0;
|
|
185
293
|
rbce->low_speed_time = 0;
|
|
294
|
+
rbce->max_send_speed_large = 0;
|
|
295
|
+
rbce->max_recv_speed_large = 0;
|
|
186
296
|
rbce->ssl_version = -1;
|
|
187
297
|
rbce->use_ssl = -1;
|
|
188
298
|
rbce->ftp_filemethod = -1;
|
|
299
|
+
rbce->resolve_mode = CURL_IPRESOLVE_WHATEVER;
|
|
189
300
|
|
|
190
301
|
/* bool opts */
|
|
191
302
|
rbce->proxy_tunnel = 0;
|
|
192
303
|
rbce->fetch_file_time = 0;
|
|
193
304
|
rbce->ssl_verify_peer = 1;
|
|
194
|
-
rbce->ssl_verify_host =
|
|
305
|
+
rbce->ssl_verify_host = 2;
|
|
195
306
|
rbce->header_in_body = 0;
|
|
196
307
|
rbce->use_netrc = 0;
|
|
197
308
|
rbce->follow_location = 0;
|
|
@@ -200,6 +311,20 @@ static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
|
|
200
311
|
rbce->multipart_form_post = 0;
|
|
201
312
|
rbce->enable_cookies = 0;
|
|
202
313
|
rbce->ignore_content_length = 0;
|
|
314
|
+
rbce->callback_active = 0;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/*
|
|
318
|
+
* Allocate space for a Curl::Easy instance.
|
|
319
|
+
*/
|
|
320
|
+
static VALUE ruby_curl_easy_allocate(VALUE klass) {
|
|
321
|
+
ruby_curl_easy *rbce;
|
|
322
|
+
rbce = ALLOC(ruby_curl_easy);
|
|
323
|
+
rbce->curl = NULL;
|
|
324
|
+
rbce->opts = Qnil;
|
|
325
|
+
rbce->multi = Qnil;
|
|
326
|
+
ruby_curl_easy_zero(rbce);
|
|
327
|
+
return Data_Wrap_Struct(klass, curl_easy_mark, curl_easy_free, rbce);
|
|
203
328
|
}
|
|
204
329
|
|
|
205
330
|
/*
|
|
@@ -208,19 +333,18 @@ static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
|
|
208
333
|
* Curl::Easy.new(url = nil) => #<Curl::Easy...>
|
|
209
334
|
* Curl::Easy.new(url = nil) { |self| ... } => #<Curl::Easy...>
|
|
210
335
|
*
|
|
211
|
-
*
|
|
336
|
+
* Initialize a new Curl::Easy instance, optionally supplying the URL.
|
|
212
337
|
* The block form allows further configuration to be supplied before
|
|
213
338
|
* the instance is returned.
|
|
214
339
|
*/
|
|
215
|
-
static VALUE
|
|
340
|
+
static VALUE ruby_curl_easy_initialize(int argc, VALUE *argv, VALUE self) {
|
|
216
341
|
CURLcode ecode;
|
|
217
342
|
VALUE url, blk;
|
|
218
|
-
VALUE new_curl;
|
|
219
343
|
ruby_curl_easy *rbce;
|
|
220
344
|
|
|
221
345
|
rb_scan_args(argc, argv, "01&", &url, &blk);
|
|
222
346
|
|
|
223
|
-
|
|
347
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
224
348
|
|
|
225
349
|
/* handler */
|
|
226
350
|
rbce->curl = curl_easy_init();
|
|
@@ -228,26 +352,26 @@ static VALUE ruby_curl_easy_new(int argc, VALUE *argv, VALUE klass) {
|
|
|
228
352
|
rb_raise(eCurlErrFailedInit, "Failed to initialize easy handle");
|
|
229
353
|
}
|
|
230
354
|
|
|
231
|
-
new_curl = Data_Wrap_Struct(klass, curl_easy_mark, curl_easy_free, rbce);
|
|
232
|
-
|
|
233
355
|
rbce->multi = Qnil;
|
|
234
356
|
rbce->opts = Qnil;
|
|
235
357
|
|
|
236
358
|
ruby_curl_easy_zero(rbce);
|
|
237
359
|
|
|
360
|
+
curl_easy_setopt(rbce->curl, CURLOPT_ERRORBUFFER, &rbce->err_buf);
|
|
361
|
+
|
|
238
362
|
rb_easy_set("url", url);
|
|
239
363
|
|
|
240
|
-
/* set the
|
|
241
|
-
ecode = curl_easy_setopt(rbce->curl, CURLOPT_PRIVATE, (void*)
|
|
364
|
+
/* set the pointer to the curl handle */
|
|
365
|
+
ecode = curl_easy_setopt(rbce->curl, CURLOPT_PRIVATE, (void*)self);
|
|
242
366
|
if (ecode != CURLE_OK) {
|
|
243
367
|
raise_curl_easy_error_exception(ecode);
|
|
244
368
|
}
|
|
245
369
|
|
|
246
370
|
if (blk != Qnil) {
|
|
247
|
-
rb_funcall(blk, idCall, 1,
|
|
371
|
+
rb_funcall(blk, idCall, 1, self);
|
|
248
372
|
}
|
|
249
373
|
|
|
250
|
-
return
|
|
374
|
+
return self;
|
|
251
375
|
}
|
|
252
376
|
|
|
253
377
|
/*
|
|
@@ -267,7 +391,11 @@ static VALUE ruby_curl_easy_clone(VALUE self) {
|
|
|
267
391
|
memcpy(newrbce, rbce, sizeof(ruby_curl_easy));
|
|
268
392
|
newrbce->curl = curl_easy_duphandle(rbce->curl);
|
|
269
393
|
newrbce->curl_headers = NULL;
|
|
394
|
+
newrbce->curl_proxy_headers = NULL;
|
|
270
395
|
newrbce->curl_ftp_commands = NULL;
|
|
396
|
+
newrbce->curl_resolve = NULL;
|
|
397
|
+
|
|
398
|
+
curl_easy_setopt(rbce->curl, CURLOPT_ERRORBUFFER, &rbce->err_buf);
|
|
271
399
|
|
|
272
400
|
return Data_Wrap_Struct(cCurlEasy, curl_easy_mark, curl_easy_free, newrbce);
|
|
273
401
|
}
|
|
@@ -277,7 +405,7 @@ static VALUE ruby_curl_easy_clone(VALUE self) {
|
|
|
277
405
|
* easy.close => nil
|
|
278
406
|
*
|
|
279
407
|
* Close the Curl::Easy instance. Any open connections are closed
|
|
280
|
-
* The easy handle is reinitialized. If a previous multi handle was
|
|
408
|
+
* The easy handle is reinitialized. If a previous multi handle was
|
|
281
409
|
* open it is set to nil and will be cleared after a GC.
|
|
282
410
|
*/
|
|
283
411
|
static VALUE ruby_curl_easy_close(VALUE self) {
|
|
@@ -286,6 +414,10 @@ static VALUE ruby_curl_easy_close(VALUE self) {
|
|
|
286
414
|
|
|
287
415
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
288
416
|
|
|
417
|
+
if (rbce->callback_active) {
|
|
418
|
+
rb_raise(rb_eRuntimeError, "Cannot close an active curl handle within a callback");
|
|
419
|
+
}
|
|
420
|
+
|
|
289
421
|
ruby_curl_easy_free(rbce);
|
|
290
422
|
|
|
291
423
|
/* reinit the handle */
|
|
@@ -324,12 +456,19 @@ static VALUE ruby_curl_easy_reset(VALUE self) {
|
|
|
324
456
|
ruby_curl_easy *rbce;
|
|
325
457
|
VALUE opts_dup;
|
|
326
458
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
459
|
+
|
|
460
|
+
if (rbce->callback_active) {
|
|
461
|
+
rb_raise(rb_eRuntimeError, "Cannot close an active curl handle within a callback");
|
|
462
|
+
}
|
|
463
|
+
|
|
327
464
|
opts_dup = rb_funcall(rbce->opts, rb_intern("dup"), 0);
|
|
328
465
|
|
|
329
466
|
curl_easy_reset(rbce->curl);
|
|
330
467
|
ruby_curl_easy_zero(rbce);
|
|
331
468
|
|
|
332
|
-
|
|
469
|
+
curl_easy_setopt(rbce->curl, CURLOPT_ERRORBUFFER, &rbce->err_buf);
|
|
470
|
+
|
|
471
|
+
/* reset clobbers the private setting, so reset it to self */
|
|
333
472
|
ecode = curl_easy_setopt(rbce->curl, CURLOPT_PRIVATE, (void*)self);
|
|
334
473
|
if (ecode != CURLE_OK) {
|
|
335
474
|
raise_curl_easy_error_exception(ecode);
|
|
@@ -341,24 +480,18 @@ static VALUE ruby_curl_easy_reset(VALUE self) {
|
|
|
341
480
|
rbce->curl_headers = NULL;
|
|
342
481
|
}
|
|
343
482
|
|
|
483
|
+
/* Free everything up */
|
|
484
|
+
if (rbce->curl_proxy_headers) {
|
|
485
|
+
curl_slist_free_all(rbce->curl_proxy_headers);
|
|
486
|
+
rbce->curl_proxy_headers = NULL;
|
|
487
|
+
}
|
|
488
|
+
|
|
344
489
|
return opts_dup;
|
|
345
490
|
}
|
|
346
491
|
|
|
347
492
|
|
|
348
493
|
/* ================ OBJ ATTRIBUTES ==================*/
|
|
349
494
|
|
|
350
|
-
/*
|
|
351
|
-
* call-seq:
|
|
352
|
-
* easy.url = "http://some.url/" => "http://some.url/"
|
|
353
|
-
*
|
|
354
|
-
* Set the URL for subsequent calls to +perform+. It is acceptable
|
|
355
|
-
* (and even recommended) to reuse Curl::Easy instances by reassigning
|
|
356
|
-
* the URL between calls to +perform+.
|
|
357
|
-
*/
|
|
358
|
-
static VALUE ruby_curl_easy_url_set(VALUE self, VALUE url) {
|
|
359
|
-
CURB_OBJECT_HSETTER(ruby_curl_easy, url);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
495
|
/*
|
|
363
496
|
* call-seq:
|
|
364
497
|
* easy.url => string
|
|
@@ -369,35 +502,6 @@ static VALUE ruby_curl_easy_url_get(VALUE self) {
|
|
|
369
502
|
CURB_OBJECT_HGETTER(ruby_curl_easy, url);
|
|
370
503
|
}
|
|
371
504
|
|
|
372
|
-
/*
|
|
373
|
-
* call-seq:
|
|
374
|
-
* easy.proxy_url = string => string
|
|
375
|
-
*
|
|
376
|
-
* Set the URL of the HTTP proxy to use for subsequent calls to +perform+.
|
|
377
|
-
* The URL should specify the the host name or dotted IP address. To specify
|
|
378
|
-
* port number in this string, append :[port] to the end of the host name.
|
|
379
|
-
* The proxy string may be prefixed with [protocol]:// since any such prefix
|
|
380
|
-
* will be ignored. The proxy's port number may optionally be specified with
|
|
381
|
-
* the separate option proxy_port .
|
|
382
|
-
*
|
|
383
|
-
* When you tell the library to use an HTTP proxy, libcurl will transparently
|
|
384
|
-
* convert operations to HTTP even if you specify an FTP URL etc. This may have
|
|
385
|
-
* an impact on what other features of the library you can use, such as
|
|
386
|
-
* FTP specifics that don't work unless you tunnel through the HTTP proxy. Such
|
|
387
|
-
* tunneling is activated with proxy_tunnel = true.
|
|
388
|
-
*
|
|
389
|
-
* libcurl respects the environment variables *http_proxy*, *ftp_proxy*,
|
|
390
|
-
* *all_proxy* etc, if any of those is set. The proxy_url option does however
|
|
391
|
-
* override any possibly set environment variables.
|
|
392
|
-
*
|
|
393
|
-
* Starting with libcurl 7.14.1, the proxy host string given in environment
|
|
394
|
-
* variables can be specified the exact same way as the proxy can be set with
|
|
395
|
-
* proxy_url, including protocol prefix (http://) and embedded user + password.
|
|
396
|
-
*/
|
|
397
|
-
static VALUE ruby_curl_easy_proxy_url_set(VALUE self, VALUE proxy_url) {
|
|
398
|
-
CURB_OBJECT_HSETTER(ruby_curl_easy, proxy_url);
|
|
399
|
-
}
|
|
400
|
-
|
|
401
505
|
/*
|
|
402
506
|
* call-seq:
|
|
403
507
|
* easy.proxy_url => string
|
|
@@ -434,6 +538,10 @@ static VALUE ruby_curl_easy_headers_set(VALUE self, VALUE headers) {
|
|
|
434
538
|
CURB_OBJECT_HSETTER(ruby_curl_easy, headers);
|
|
435
539
|
}
|
|
436
540
|
|
|
541
|
+
static VALUE ruby_curl_easy_proxy_headers_set(VALUE self, VALUE proxy_headers) {
|
|
542
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, proxy_headers);
|
|
543
|
+
}
|
|
544
|
+
|
|
437
545
|
/*
|
|
438
546
|
* call-seq:
|
|
439
547
|
* easy.headers => Hash, Array or Str
|
|
@@ -444,42 +552,55 @@ static VALUE ruby_curl_easy_headers_get(VALUE self) {
|
|
|
444
552
|
ruby_curl_easy *rbce;
|
|
445
553
|
VALUE headers;
|
|
446
554
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
447
|
-
headers = rb_easy_get("headers");//rb_hash_aref(rbce->opts, rb_intern("headers"));
|
|
555
|
+
headers = rb_easy_get("headers");//rb_hash_aref(rbce->opts, rb_intern("headers"));
|
|
448
556
|
if (headers == Qnil) { headers = rb_easy_set("headers", rb_hash_new()); }
|
|
449
557
|
return headers;
|
|
450
558
|
}
|
|
451
559
|
|
|
452
560
|
/*
|
|
453
561
|
* call-seq:
|
|
454
|
-
* easy.
|
|
562
|
+
* easy.proxy_headers = "Header: val" => "Header: val"
|
|
563
|
+
* easy.proxy_headers = {"Header" => "val" ..., "Header" => "val"} => {"Header: val", ...}
|
|
564
|
+
* easy.proxy_headers = ["Header: val" ..., "Header: val"] => ["Header: val", ...]
|
|
455
565
|
*
|
|
456
|
-
*
|
|
457
|
-
*
|
|
566
|
+
*
|
|
567
|
+
* For example to set a standard or custom header:
|
|
568
|
+
*
|
|
569
|
+
* easy.proxy_headers["MyHeader"] = "myval"
|
|
570
|
+
*
|
|
571
|
+
* To remove a standard header (this is useful when removing libcurls default
|
|
572
|
+
* 'Expect: 100-Continue' header when using HTTP form posts):
|
|
573
|
+
*
|
|
574
|
+
* easy.proxy_headers["Expect"] = ''
|
|
575
|
+
*
|
|
576
|
+
* Anything passed to libcurl as a header will be converted to a string during
|
|
577
|
+
* the perform step.
|
|
458
578
|
*/
|
|
459
|
-
static VALUE ruby_curl_easy_interface_set(VALUE self, VALUE interface_hm) {
|
|
460
|
-
CURB_OBJECT_HSETTER(ruby_curl_easy, interface_hm);
|
|
461
|
-
}
|
|
462
579
|
|
|
463
580
|
/*
|
|
464
581
|
* call-seq:
|
|
465
|
-
* easy.
|
|
582
|
+
* easy.proxy_headers => Hash, Array or Str
|
|
466
583
|
*
|
|
467
|
-
* Obtain the
|
|
468
|
-
* The name can be an interface name, an IP address or a host name.
|
|
584
|
+
* Obtain the custom HTTP proxy_headers for following requests.
|
|
469
585
|
*/
|
|
470
|
-
static VALUE
|
|
471
|
-
|
|
586
|
+
static VALUE ruby_curl_easy_proxy_headers_get(VALUE self) {
|
|
587
|
+
ruby_curl_easy *rbce;
|
|
588
|
+
VALUE proxy_headers;
|
|
589
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
590
|
+
proxy_headers = rb_easy_get("proxy_headers");//rb_hash_aref(rbce->opts, rb_intern("proxy_headers"));
|
|
591
|
+
if (proxy_headers == Qnil) { proxy_headers = rb_easy_set("proxy_headers", rb_hash_new()); }
|
|
592
|
+
return proxy_headers;
|
|
472
593
|
}
|
|
473
594
|
|
|
474
595
|
/*
|
|
475
596
|
* call-seq:
|
|
476
|
-
* easy.
|
|
597
|
+
* easy.interface => string
|
|
477
598
|
*
|
|
478
|
-
*
|
|
479
|
-
* The
|
|
599
|
+
* Obtain the interface name that is used as the outgoing network interface.
|
|
600
|
+
* The name can be an interface name, an IP address or a host name.
|
|
480
601
|
*/
|
|
481
|
-
static VALUE
|
|
482
|
-
|
|
602
|
+
static VALUE ruby_curl_easy_interface_get(VALUE self) {
|
|
603
|
+
CURB_OBJECT_HGETTER(ruby_curl_easy, interface_hm);
|
|
483
604
|
}
|
|
484
605
|
|
|
485
606
|
/*
|
|
@@ -493,18 +614,6 @@ static VALUE ruby_curl_easy_userpwd_get(VALUE self) {
|
|
|
493
614
|
CURB_OBJECT_HGETTER(ruby_curl_easy, userpwd);
|
|
494
615
|
}
|
|
495
616
|
|
|
496
|
-
/*
|
|
497
|
-
* call-seq:
|
|
498
|
-
* easy.proxypwd = string => string
|
|
499
|
-
*
|
|
500
|
-
* Set the username/password string to use for proxy connection during
|
|
501
|
-
* subsequent calls to +perform+. The supplied string should have the
|
|
502
|
-
* form "username:password"
|
|
503
|
-
*/
|
|
504
|
-
static VALUE ruby_curl_easy_proxypwd_set(VALUE self, VALUE proxypwd) {
|
|
505
|
-
CURB_OBJECT_HSETTER(ruby_curl_easy, proxypwd);
|
|
506
|
-
}
|
|
507
|
-
|
|
508
617
|
/*
|
|
509
618
|
* call-seq:
|
|
510
619
|
* easy.proxypwd => string
|
|
@@ -517,19 +626,6 @@ static VALUE ruby_curl_easy_proxypwd_get(VALUE self) {
|
|
|
517
626
|
CURB_OBJECT_HGETTER(ruby_curl_easy, proxypwd);
|
|
518
627
|
}
|
|
519
628
|
|
|
520
|
-
|
|
521
|
-
/*
|
|
522
|
-
* call-seq:
|
|
523
|
-
* easy.cookies = "name1=content1; name2=content2;" => string
|
|
524
|
-
*
|
|
525
|
-
* Set cookies to be sent by this Curl::Easy instance. The format of the string should
|
|
526
|
-
* be NAME=CONTENTS, where NAME is the cookie name and CONTENTS is what the cookie should contain.
|
|
527
|
-
* Set multiple cookies in one string like this: "name1=content1; name2=content2;" etc.
|
|
528
|
-
*/
|
|
529
|
-
static VALUE ruby_curl_easy_cookies_set(VALUE self, VALUE cookies) {
|
|
530
|
-
CURB_OBJECT_HSETTER(ruby_curl_easy, cookies);
|
|
531
|
-
}
|
|
532
|
-
|
|
533
629
|
/*
|
|
534
630
|
* call-seq:
|
|
535
631
|
* easy.cookies => "name1=content1; name2=content2;"
|
|
@@ -540,19 +636,6 @@ static VALUE ruby_curl_easy_cookies_get(VALUE self) {
|
|
|
540
636
|
CURB_OBJECT_HGETTER(ruby_curl_easy, cookies);
|
|
541
637
|
}
|
|
542
638
|
|
|
543
|
-
/*
|
|
544
|
-
* call-seq:
|
|
545
|
-
* easy.cookiefile = string => string
|
|
546
|
-
*
|
|
547
|
-
* Set a file that contains cookies to be sent in subsequent requests by this Curl::Easy instance.
|
|
548
|
-
*
|
|
549
|
-
* *Note* that you must set enable_cookies true to enable the cookie
|
|
550
|
-
* engine, or this option will be ignored.
|
|
551
|
-
*/
|
|
552
|
-
static VALUE ruby_curl_easy_cookiefile_set(VALUE self, VALUE cookiefile) {
|
|
553
|
-
CURB_OBJECT_HSETTER(ruby_curl_easy, cookiefile);
|
|
554
|
-
}
|
|
555
|
-
|
|
556
639
|
/*
|
|
557
640
|
* call-seq:
|
|
558
641
|
* easy.cookiefile => string
|
|
@@ -563,20 +646,6 @@ static VALUE ruby_curl_easy_cookiefile_get(VALUE self) {
|
|
|
563
646
|
CURB_OBJECT_HGETTER(ruby_curl_easy, cookiefile);
|
|
564
647
|
}
|
|
565
648
|
|
|
566
|
-
/*
|
|
567
|
-
* call-seq:
|
|
568
|
-
* easy.cookiejar = string => string
|
|
569
|
-
*
|
|
570
|
-
* Set a cookiejar file to use for this Curl::Easy instance.
|
|
571
|
-
* Cookies from the response will be written into this file.
|
|
572
|
-
*
|
|
573
|
-
* *Note* that you must set enable_cookies true to enable the cookie
|
|
574
|
-
* engine, or this option will be ignored.
|
|
575
|
-
*/
|
|
576
|
-
static VALUE ruby_curl_easy_cookiejar_set(VALUE self, VALUE cookiejar) {
|
|
577
|
-
CURB_OBJECT_HSETTER(ruby_curl_easy, cookiejar);
|
|
578
|
-
}
|
|
579
|
-
|
|
580
649
|
/*
|
|
581
650
|
* call-seq:
|
|
582
651
|
* easy.cookiejar => string
|
|
@@ -730,29 +799,29 @@ static VALUE ruby_curl_easy_useragent_get(VALUE self) {
|
|
|
730
799
|
/*
|
|
731
800
|
* call-seq:
|
|
732
801
|
* easy.post_body = "some=form%20data&to=send" => string or nil
|
|
733
|
-
*
|
|
802
|
+
*
|
|
734
803
|
* Sets the POST body of this Curl::Easy instance. This is expected to be
|
|
735
804
|
* URL encoded; no additional processing or encoding is done on the string.
|
|
736
805
|
* The content-type header will be set to application/x-www-form-urlencoded.
|
|
737
|
-
*
|
|
806
|
+
*
|
|
738
807
|
* This is handy if you want to perform a POST against a Curl::Multi instance.
|
|
739
808
|
*/
|
|
740
809
|
static VALUE ruby_curl_easy_post_body_set(VALUE self, VALUE post_body) {
|
|
741
810
|
ruby_curl_easy *rbce;
|
|
742
811
|
CURL *curl;
|
|
743
|
-
|
|
812
|
+
|
|
744
813
|
char *data;
|
|
745
814
|
long len;
|
|
746
815
|
|
|
747
816
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
748
|
-
|
|
817
|
+
|
|
749
818
|
curl = rbce->curl;
|
|
750
|
-
|
|
819
|
+
|
|
751
820
|
if ( post_body == Qnil ) {
|
|
752
|
-
//rbce->postdata_buffer = Qnil;
|
|
753
821
|
rb_easy_del("postdata_buffer");
|
|
754
|
-
|
|
755
|
-
|
|
822
|
+
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
|
|
823
|
+
|
|
824
|
+
} else {
|
|
756
825
|
if (rb_type(post_body) == T_STRING) {
|
|
757
826
|
data = StringValuePtr(post_body);
|
|
758
827
|
len = RSTRING_LEN(post_body);
|
|
@@ -765,19 +834,19 @@ static VALUE ruby_curl_easy_post_body_set(VALUE self, VALUE post_body) {
|
|
|
765
834
|
else {
|
|
766
835
|
rb_raise(rb_eRuntimeError, "post data must respond_to .to_s");
|
|
767
836
|
}
|
|
768
|
-
|
|
769
|
-
// Store the string, since it has to hang around for the duration of the
|
|
837
|
+
|
|
838
|
+
// Store the string, since it has to hang around for the duration of the
|
|
770
839
|
// request. See CURLOPT_POSTFIELDS in the libcurl docs.
|
|
771
840
|
//rbce->postdata_buffer = post_body;
|
|
772
841
|
rb_easy_set("postdata_buffer", post_body);
|
|
773
|
-
|
|
842
|
+
|
|
774
843
|
curl_easy_setopt(curl, CURLOPT_POST, 1);
|
|
775
844
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
|
|
776
845
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
|
|
777
|
-
|
|
846
|
+
|
|
778
847
|
return post_body;
|
|
779
848
|
}
|
|
780
|
-
|
|
849
|
+
|
|
781
850
|
return Qnil;
|
|
782
851
|
}
|
|
783
852
|
|
|
@@ -794,7 +863,7 @@ static VALUE ruby_curl_easy_post_body_get(VALUE self) {
|
|
|
794
863
|
/*
|
|
795
864
|
* call-seq:
|
|
796
865
|
* easy.put_data = data => ""
|
|
797
|
-
*
|
|
866
|
+
*
|
|
798
867
|
* Points this Curl::Easy instance to data to be uploaded via PUT. This
|
|
799
868
|
* sets the request to a PUT type request - useful if you want to PUT via
|
|
800
869
|
* a multi handle.
|
|
@@ -818,9 +887,15 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
|
|
|
818
887
|
curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
|
|
819
888
|
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
|
|
820
889
|
curl_easy_setopt(curl, CURLOPT_READFUNCTION, (curl_read_callback)read_data_handler);
|
|
890
|
+
#if HAVE_CURLOPT_SEEKFUNCTION
|
|
891
|
+
curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, (curl_seek_callback)seek_data_handler);
|
|
892
|
+
#endif
|
|
821
893
|
curl_easy_setopt(curl, CURLOPT_READDATA, rbce);
|
|
894
|
+
#if HAVE_CURLOPT_SEEKDATA
|
|
895
|
+
curl_easy_setopt(curl, CURLOPT_SEEKDATA, rbce);
|
|
896
|
+
#endif
|
|
822
897
|
|
|
823
|
-
/*
|
|
898
|
+
/*
|
|
824
899
|
* we need to set specific headers for the PUT to work... so
|
|
825
900
|
* convert the internal headers structure to a HASH if one is set
|
|
826
901
|
*/
|
|
@@ -834,7 +909,7 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
|
|
|
834
909
|
if (NIL_P(data)) { return data; }
|
|
835
910
|
|
|
836
911
|
headers = rb_easy_get("headers");
|
|
837
|
-
if( headers == Qnil ) {
|
|
912
|
+
if( headers == Qnil ) {
|
|
838
913
|
headers = rb_hash_new();
|
|
839
914
|
}
|
|
840
915
|
|
|
@@ -846,14 +921,14 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
|
|
|
846
921
|
rb_hash_aset(headers, rb_str_new2("Expect"), rb_str_new2(""));
|
|
847
922
|
}
|
|
848
923
|
size = rb_funcall(stat, rb_intern("size"), 0);
|
|
849
|
-
curl_easy_setopt(curl, CURLOPT_INFILESIZE,
|
|
924
|
+
curl_easy_setopt(curl, CURLOPT_INFILESIZE, NUM2LONG(size));
|
|
850
925
|
}
|
|
851
926
|
else if( rb_hash_aref(headers, rb_str_new2("Content-Length")) == Qnil && rb_hash_aref(headers, rb_str_new2("Transfer-Encoding")) == Qnil ) {
|
|
852
927
|
rb_hash_aset(headers, rb_str_new2("Transfer-Encoding"), rb_str_new2("chunked"));
|
|
853
928
|
}
|
|
854
929
|
else if( rb_hash_aref(headers, rb_str_new2("Content-Length")) ) {
|
|
855
930
|
VALUE size = rb_funcall(rb_hash_aref(headers, rb_str_new2("Content-Length")), rb_intern("to_i"), 0);
|
|
856
|
-
curl_easy_setopt(curl, CURLOPT_INFILESIZE,
|
|
931
|
+
curl_easy_setopt(curl, CURLOPT_INFILESIZE, NUM2LONG(size));
|
|
857
932
|
}
|
|
858
933
|
}
|
|
859
934
|
else if (rb_respond_to(data, rb_intern("to_s"))) {
|
|
@@ -889,6 +964,25 @@ static VALUE ruby_curl_easy_ftp_commands_get(VALUE self) {
|
|
|
889
964
|
CURB_OBJECT_HGETTER(ruby_curl_easy, ftp_commands);
|
|
890
965
|
}
|
|
891
966
|
|
|
967
|
+
/*
|
|
968
|
+
* call-seq:
|
|
969
|
+
* easy.resolve = [ "example.com:80:127.0.0.1" ] => [ "example.com:80:127.0.0.1" ]
|
|
970
|
+
*
|
|
971
|
+
* Set the resolve list to statically resolve hostnames to IP addresses,
|
|
972
|
+
* bypassing DNS for matching hostname/port combinations.
|
|
973
|
+
*/
|
|
974
|
+
static VALUE ruby_curl_easy_resolve_set(VALUE self, VALUE resolve) {
|
|
975
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, resolve);
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
/*
|
|
979
|
+
* call-seq
|
|
980
|
+
* easy.resolve => array or nil
|
|
981
|
+
*/
|
|
982
|
+
static VALUE ruby_curl_easy_resolve_get(VALUE self) {
|
|
983
|
+
CURB_OBJECT_HGETTER(ruby_curl_easy, resolve);
|
|
984
|
+
}
|
|
985
|
+
|
|
892
986
|
/* ================== IMMED ATTRS ==================*/
|
|
893
987
|
|
|
894
988
|
/*
|
|
@@ -997,16 +1091,16 @@ static VALUE ruby_curl_easy_proxy_type_get(VALUE self) {
|
|
|
997
1091
|
(!strncmp("digest",node,6)) ? CURLAUTH_DIGEST : \
|
|
998
1092
|
(!strncmp("gssnegotiate",node,12)) ? CURLAUTH_GSSNEGOTIATE : \
|
|
999
1093
|
(!strncmp("ntlm",node,4)) ? CURLAUTH_NTLM : \
|
|
1000
|
-
(!strncmp("
|
|
1001
|
-
(!strncmp("
|
|
1002
|
-
#else
|
|
1094
|
+
(!strncmp("anysafe",node,7)) ? CURLAUTH_ANYSAFE : \
|
|
1095
|
+
(!strncmp("any",node,3)) ? CURLAUTH_ANY : 0
|
|
1096
|
+
#else
|
|
1003
1097
|
#define CURL_HTTPAUTH_STR_TO_NUM(node) \
|
|
1004
1098
|
(!strncmp("basic",node,5)) ? CURLAUTH_BASIC : \
|
|
1005
1099
|
(!strncmp("digest",node,6)) ? CURLAUTH_DIGEST : \
|
|
1006
1100
|
(!strncmp("gssnegotiate",node,12)) ? CURLAUTH_GSSNEGOTIATE : \
|
|
1007
1101
|
(!strncmp("ntlm",node,4)) ? CURLAUTH_NTLM : \
|
|
1008
|
-
(!strncmp("
|
|
1009
|
-
(!strncmp("
|
|
1102
|
+
(!strncmp("anysafe",node,7)) ? CURLAUTH_ANYSAFE : \
|
|
1103
|
+
(!strncmp("any",node,3)) ? CURLAUTH_ANY : 0
|
|
1010
1104
|
#endif
|
|
1011
1105
|
/*
|
|
1012
1106
|
* call-seq:
|
|
@@ -1020,21 +1114,22 @@ static VALUE ruby_curl_easy_proxy_type_get(VALUE self) {
|
|
|
1020
1114
|
static VALUE ruby_curl_easy_http_auth_types_set(int argc, VALUE *argv, VALUE self) {//VALUE self, VALUE http_auth_types) {
|
|
1021
1115
|
ruby_curl_easy *rbce;
|
|
1022
1116
|
VALUE args_ary;
|
|
1023
|
-
|
|
1117
|
+
long i, len;
|
|
1024
1118
|
char* node = NULL;
|
|
1025
|
-
long mask =
|
|
1119
|
+
long mask = 0;
|
|
1026
1120
|
|
|
1027
1121
|
rb_scan_args(argc, argv, "*", &args_ary);
|
|
1028
1122
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
1029
1123
|
|
|
1030
|
-
len =
|
|
1124
|
+
len = RARRAY_LEN(args_ary);
|
|
1031
1125
|
|
|
1032
|
-
if (len == 1 && (
|
|
1033
|
-
|
|
1126
|
+
if (len == 1 && (rb_ary_entry(args_ary,0) == Qnil || TYPE(rb_ary_entry(args_ary,0)) == T_FIXNUM ||
|
|
1127
|
+
TYPE(rb_ary_entry(args_ary,0)) == T_BIGNUM)) {
|
|
1128
|
+
if (rb_ary_entry(args_ary,0) == Qnil) {
|
|
1034
1129
|
rbce->http_auth_types = 0;
|
|
1035
1130
|
}
|
|
1036
1131
|
else {
|
|
1037
|
-
rbce->http_auth_types =
|
|
1132
|
+
rbce->http_auth_types = NUM2LONG(rb_ary_entry(args_ary,0));
|
|
1038
1133
|
}
|
|
1039
1134
|
}
|
|
1040
1135
|
else {
|
|
@@ -1047,7 +1142,7 @@ static VALUE ruby_curl_easy_http_auth_types_set(int argc, VALUE *argv, VALUE sel
|
|
|
1047
1142
|
}
|
|
1048
1143
|
rbce->http_auth_types = mask;
|
|
1049
1144
|
}
|
|
1050
|
-
return
|
|
1145
|
+
return LONG2NUM(rbce->http_auth_types);
|
|
1051
1146
|
}
|
|
1052
1147
|
|
|
1053
1148
|
/*
|
|
@@ -1112,7 +1207,7 @@ static VALUE ruby_curl_easy_max_redirects_get(VALUE self) {
|
|
|
1112
1207
|
|
|
1113
1208
|
/*
|
|
1114
1209
|
* call-seq:
|
|
1115
|
-
* easy.timeout = fixnum or nil
|
|
1210
|
+
* easy.timeout = float, fixnum or nil => numeric
|
|
1116
1211
|
*
|
|
1117
1212
|
* Set the maximum time in seconds that you allow the libcurl transfer
|
|
1118
1213
|
* operation to take. Normally, name lookups can take a considerable time
|
|
@@ -1121,20 +1216,77 @@ static VALUE ruby_curl_easy_max_redirects_get(VALUE self) {
|
|
|
1121
1216
|
*
|
|
1122
1217
|
* Set to nil (or zero) to disable timeout (it will then only timeout
|
|
1123
1218
|
* on the system's internal timeouts).
|
|
1219
|
+
*
|
|
1220
|
+
* Uses timeout_ms internally instead of timeout because it allows for
|
|
1221
|
+
* better precision and libcurl will use the last set value when both
|
|
1222
|
+
* timeout and timeout_ms are set.
|
|
1223
|
+
*
|
|
1124
1224
|
*/
|
|
1125
|
-
static VALUE ruby_curl_easy_timeout_set(VALUE self, VALUE
|
|
1126
|
-
|
|
1225
|
+
static VALUE ruby_curl_easy_timeout_set(VALUE self, VALUE timeout_s) {
|
|
1226
|
+
ruby_curl_easy *rbce;
|
|
1227
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
1228
|
+
|
|
1229
|
+
if (Qnil == timeout_s || NUM2DBL(timeout_s) <= 0.0) {
|
|
1230
|
+
rbce->timeout_ms = 0;
|
|
1231
|
+
} else {
|
|
1232
|
+
rbce->timeout_ms = (unsigned long)(NUM2DBL(timeout_s) * 1000);
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
return DBL2NUM(rbce->timeout_ms / 1000.0);
|
|
1127
1236
|
}
|
|
1128
1237
|
|
|
1129
1238
|
/*
|
|
1130
1239
|
* call-seq:
|
|
1131
|
-
* easy.timeout =>
|
|
1240
|
+
* easy.timeout => numeric
|
|
1132
1241
|
*
|
|
1133
1242
|
* Obtain the maximum time in seconds that you allow the libcurl transfer
|
|
1134
1243
|
* operation to take.
|
|
1244
|
+
*
|
|
1245
|
+
* Uses timeout_ms internally instead of timeout.
|
|
1246
|
+
*
|
|
1247
|
+
*/
|
|
1248
|
+
static VALUE ruby_curl_easy_timeout_get(VALUE self) {
|
|
1249
|
+
ruby_curl_easy *rbce;
|
|
1250
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
1251
|
+
return DBL2NUM(rbce->timeout_ms / 1000.0);
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
/*
|
|
1255
|
+
* call-seq:
|
|
1256
|
+
* easy.timeout_ms = fixnum or nil => fixnum or nil
|
|
1257
|
+
*
|
|
1258
|
+
* Set the maximum time in milliseconds that you allow the libcurl transfer
|
|
1259
|
+
* operation to take. Normally, name lookups can take a considerable time
|
|
1260
|
+
* and limiting operations to less than a few minutes risk aborting
|
|
1261
|
+
* perfectly normal operations.
|
|
1262
|
+
*
|
|
1263
|
+
* Set to nil (or zero) to disable timeout (it will then only timeout
|
|
1264
|
+
* on the system's internal timeouts).
|
|
1265
|
+
*/
|
|
1266
|
+
static VALUE ruby_curl_easy_timeout_ms_set(VALUE self, VALUE timeout_ms) {
|
|
1267
|
+
ruby_curl_easy *rbce;
|
|
1268
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
1269
|
+
|
|
1270
|
+
if (Qnil == timeout_ms || NUM2DBL(timeout_ms) <= 0.0) {
|
|
1271
|
+
rbce->timeout_ms = 0;
|
|
1272
|
+
} else {
|
|
1273
|
+
rbce->timeout_ms = NUM2ULONG(timeout_ms);
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
return ULONG2NUM(rbce->timeout_ms);
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
/*
|
|
1280
|
+
* call-seq:
|
|
1281
|
+
* easy.timeout_ms => fixnum or nil
|
|
1282
|
+
*
|
|
1283
|
+
* Obtain the maximum time in milliseconds that you allow the libcurl transfer
|
|
1284
|
+
* operation to take.
|
|
1135
1285
|
*/
|
|
1136
|
-
static VALUE
|
|
1137
|
-
|
|
1286
|
+
static VALUE ruby_curl_easy_timeout_ms_get(VALUE self) {
|
|
1287
|
+
ruby_curl_easy *rbce;
|
|
1288
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
1289
|
+
return LONG2NUM(rbce->timeout_ms);
|
|
1138
1290
|
}
|
|
1139
1291
|
|
|
1140
1292
|
/*
|
|
@@ -1163,6 +1315,32 @@ static VALUE ruby_curl_easy_connect_timeout_get(VALUE self, VALUE connect_timeou
|
|
|
1163
1315
|
CURB_IMMED_GETTER(ruby_curl_easy, connect_timeout, 0);
|
|
1164
1316
|
}
|
|
1165
1317
|
|
|
1318
|
+
/*
|
|
1319
|
+
* call-seq:
|
|
1320
|
+
* easy.connect_timeout_ms = fixnum or nil => fixnum or nil
|
|
1321
|
+
*
|
|
1322
|
+
* Set the maximum time in milliseconds that you allow the connection to the
|
|
1323
|
+
* server to take. This only limits the connection phase, once it has
|
|
1324
|
+
* connected, this option is of no more use.
|
|
1325
|
+
*
|
|
1326
|
+
* Set to nil (or zero) to disable connection timeout (it will then only
|
|
1327
|
+
* timeout on the system's internal timeouts).
|
|
1328
|
+
*/
|
|
1329
|
+
static VALUE ruby_curl_easy_connect_timeout_ms_set(VALUE self, VALUE connect_timeout_ms) {
|
|
1330
|
+
CURB_IMMED_SETTER(ruby_curl_easy, connect_timeout_ms, 0);
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
/*
|
|
1334
|
+
* call-seq:
|
|
1335
|
+
* easy.connect_timeout_ms => fixnum or nil
|
|
1336
|
+
*
|
|
1337
|
+
* Obtain the maximum time in milliseconds that you allow the connection to the
|
|
1338
|
+
* server to take.
|
|
1339
|
+
*/
|
|
1340
|
+
static VALUE ruby_curl_easy_connect_timeout_ms_get(VALUE self, VALUE connect_timeout_ms) {
|
|
1341
|
+
CURB_IMMED_GETTER(ruby_curl_easy, connect_timeout_ms, 0);
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1166
1344
|
/*
|
|
1167
1345
|
* call-seq:
|
|
1168
1346
|
* easy.dns_cache_timeout = fixnum or nil => fixnum or nil
|
|
@@ -1258,6 +1436,46 @@ static VALUE ruby_curl_easy_low_speed_time_get(VALUE self, VALUE low_speed_time)
|
|
|
1258
1436
|
CURB_IMMED_GETTER(ruby_curl_easy, low_speed_time, 0);
|
|
1259
1437
|
}
|
|
1260
1438
|
|
|
1439
|
+
/*
|
|
1440
|
+
* call-seq:
|
|
1441
|
+
* easy.max_send_speed_large = fixnum or nil => fixnum or nil
|
|
1442
|
+
*
|
|
1443
|
+
* Set the maximal sending transfer speed (in bytes per second)
|
|
1444
|
+
*/
|
|
1445
|
+
static VALUE ruby_curl_easy_max_send_speed_large_set(VALUE self, VALUE max_send_speed_large) {
|
|
1446
|
+
CURB_IMMED_SETTER(ruby_curl_easy, max_send_speed_large, 0);
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
/*
|
|
1450
|
+
* call-seq:
|
|
1451
|
+
* easy.max_send_speed_large = fixnum or nil => fixnum or nil
|
|
1452
|
+
*
|
|
1453
|
+
* Get the maximal sending transfer speed (in bytes per second)
|
|
1454
|
+
*/
|
|
1455
|
+
static VALUE ruby_curl_easy_max_send_speed_large_get(VALUE self, VALUE max_send_speed_large) {
|
|
1456
|
+
CURB_IMMED_GETTER(ruby_curl_easy, max_send_speed_large, 0);
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
/*
|
|
1460
|
+
* call-seq:
|
|
1461
|
+
* easy.max_recv_speed_large = fixnum or nil => fixnum or nil
|
|
1462
|
+
*
|
|
1463
|
+
* Set the maximal receiving transfer speed (in bytes per second)
|
|
1464
|
+
*/
|
|
1465
|
+
static VALUE ruby_curl_easy_max_recv_speed_large_set(VALUE self, VALUE max_recv_speed_large) {
|
|
1466
|
+
CURB_IMMED_SETTER(ruby_curl_easy, max_recv_speed_large, 0);
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
/*
|
|
1470
|
+
* call-seq:
|
|
1471
|
+
* easy.max_recv_speed_large = fixnum or nil => fixnum or nil
|
|
1472
|
+
*
|
|
1473
|
+
* Get the maximal receiving transfer speed (in bytes per second)
|
|
1474
|
+
*/
|
|
1475
|
+
static VALUE ruby_curl_easy_max_recv_speed_large_get(VALUE self, VALUE max_recv_speed_large) {
|
|
1476
|
+
CURB_IMMED_GETTER(ruby_curl_easy, max_recv_speed_large, 0);
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1261
1479
|
/*
|
|
1262
1480
|
* call-seq:
|
|
1263
1481
|
* easy.username = string => string
|
|
@@ -1275,7 +1493,7 @@ static VALUE ruby_curl_easy_username_set(VALUE self, VALUE username) {
|
|
|
1275
1493
|
/*
|
|
1276
1494
|
* call-seq:
|
|
1277
1495
|
* easy.username => string
|
|
1278
|
-
*
|
|
1496
|
+
*
|
|
1279
1497
|
* Get the current username
|
|
1280
1498
|
*/
|
|
1281
1499
|
static VALUE ruby_curl_easy_username_get(VALUE self, VALUE username) {
|
|
@@ -1303,7 +1521,7 @@ static VALUE ruby_curl_easy_password_set(VALUE self, VALUE password) {
|
|
|
1303
1521
|
/*
|
|
1304
1522
|
* call-seq:
|
|
1305
1523
|
* easy.password => string
|
|
1306
|
-
*
|
|
1524
|
+
*
|
|
1307
1525
|
* Get the current password
|
|
1308
1526
|
*/
|
|
1309
1527
|
static VALUE ruby_curl_easy_password_get(VALUE self, VALUE password) {
|
|
@@ -1319,8 +1537,16 @@ static VALUE ruby_curl_easy_password_get(VALUE self, VALUE password) {
|
|
|
1319
1537
|
* easy.ssl_version = value => fixnum or nil
|
|
1320
1538
|
*
|
|
1321
1539
|
* Sets the version of SSL/TLS that libcurl will attempt to use. Valid
|
|
1322
|
-
* options are
|
|
1323
|
-
*
|
|
1540
|
+
* options are:
|
|
1541
|
+
*
|
|
1542
|
+
* Curl::CURL_SSLVERSION_DEFAULT
|
|
1543
|
+
* Curl::CURL_SSLVERSION_TLSv1 (TLS 1.x)
|
|
1544
|
+
* Curl::CURL_SSLVERSION_SSLv2
|
|
1545
|
+
* Curl::CURL_SSLVERSION_SSLv3
|
|
1546
|
+
* Curl::CURL_SSLVERSION_TLSv1_0
|
|
1547
|
+
* Curl::CURL_SSLVERSION_TLSv1_1
|
|
1548
|
+
* Curl::CURL_SSLVERSION_TLSv1_2
|
|
1549
|
+
* Curl::CURL_SSLVERSION_TLSv1_3
|
|
1324
1550
|
*/
|
|
1325
1551
|
static VALUE ruby_curl_easy_ssl_version_set(VALUE self, VALUE ssl_version) {
|
|
1326
1552
|
CURB_IMMED_SETTER(ruby_curl_easy, ssl_version, -1);
|
|
@@ -1339,7 +1565,7 @@ static VALUE ruby_curl_easy_ssl_version_get(VALUE self, VALUE ssl_version) {
|
|
|
1339
1565
|
/*
|
|
1340
1566
|
* call-seq:
|
|
1341
1567
|
* easy.use_ssl = value => fixnum or nil
|
|
1342
|
-
*
|
|
1568
|
+
*
|
|
1343
1569
|
* Ensure libcurl uses SSL for FTP connections. Valid options are Curl::CURL_USESSL_NONE,
|
|
1344
1570
|
* Curl::CURL_USESSL_TRY, Curl::CURL_USESSL_CONTROL, and Curl::CURL_USESSL_ALL.
|
|
1345
1571
|
*/
|
|
@@ -1453,7 +1679,7 @@ static VALUE ruby_curl_easy_ssl_verify_peer_q(VALUE self) {
|
|
|
1453
1679
|
|
|
1454
1680
|
/*
|
|
1455
1681
|
* call-seq:
|
|
1456
|
-
* easy.ssl_verify_host =
|
|
1682
|
+
* easy.ssl_verify_host = [0, 1, 2] => [0, 1, 2]
|
|
1457
1683
|
*
|
|
1458
1684
|
* Configure whether this Curl instance will verify that the server cert
|
|
1459
1685
|
* is for the server it is known as. When true (the default) the server
|
|
@@ -1465,18 +1691,18 @@ static VALUE ruby_curl_easy_ssl_verify_peer_q(VALUE self) {
|
|
|
1465
1691
|
* The server could be lying. To control lying, see ssl_verify_peer? .
|
|
1466
1692
|
*/
|
|
1467
1693
|
static VALUE ruby_curl_easy_ssl_verify_host_set(VALUE self, VALUE ssl_verify_host) {
|
|
1468
|
-
|
|
1694
|
+
CURB_IMMED_SETTER(ruby_curl_easy, ssl_verify_host, 0);
|
|
1469
1695
|
}
|
|
1470
1696
|
|
|
1471
1697
|
/*
|
|
1472
1698
|
* call-seq:
|
|
1473
|
-
* easy.ssl_verify_host
|
|
1699
|
+
* easy.ssl_verify_host => number
|
|
1474
1700
|
*
|
|
1475
1701
|
* Determine whether this Curl instance will verify that the server cert
|
|
1476
1702
|
* is for the server it is known as.
|
|
1477
1703
|
*/
|
|
1478
|
-
static VALUE
|
|
1479
|
-
|
|
1704
|
+
static VALUE ruby_curl_easy_ssl_verify_host_get(VALUE self) {
|
|
1705
|
+
CURB_IMMED_GETTER(ruby_curl_easy, ssl_verify_host, 0);
|
|
1480
1706
|
}
|
|
1481
1707
|
|
|
1482
1708
|
/*
|
|
@@ -1524,17 +1750,6 @@ static VALUE ruby_curl_easy_use_netrc_q(VALUE self) {
|
|
|
1524
1750
|
CURB_BOOLEAN_GETTER(ruby_curl_easy, use_netrc);
|
|
1525
1751
|
}
|
|
1526
1752
|
|
|
1527
|
-
/*
|
|
1528
|
-
* call-seq:
|
|
1529
|
-
* easy.follow_location = boolean => boolean
|
|
1530
|
-
*
|
|
1531
|
-
* Configure whether this Curl instance will follow Location: headers
|
|
1532
|
-
* in HTTP responses. Redirects will only be followed to the extent
|
|
1533
|
-
* specified by +max_redirects+.
|
|
1534
|
-
*/
|
|
1535
|
-
static VALUE ruby_curl_easy_follow_location_set(VALUE self, VALUE follow_location) {
|
|
1536
|
-
CURB_BOOLEAN_SETTER(ruby_curl_easy, follow_location);
|
|
1537
|
-
}
|
|
1538
1753
|
/*
|
|
1539
1754
|
* call-seq:
|
|
1540
1755
|
*
|
|
@@ -1685,19 +1900,80 @@ static VALUE ruby_curl_easy_ignore_content_length_q(VALUE self) {
|
|
|
1685
1900
|
CURB_BOOLEAN_GETTER(ruby_curl_easy, ignore_content_length);
|
|
1686
1901
|
}
|
|
1687
1902
|
|
|
1903
|
+
/*
|
|
1904
|
+
* call-seq:
|
|
1905
|
+
* easy.resolve_mode => symbol
|
|
1906
|
+
*
|
|
1907
|
+
* Determines what type of IP address this Curl::Easy instance
|
|
1908
|
+
* resolves DNS names to.
|
|
1909
|
+
*/
|
|
1910
|
+
static VALUE ruby_curl_easy_resolve_mode(VALUE self) {
|
|
1911
|
+
ruby_curl_easy *rbce;
|
|
1912
|
+
unsigned short rm;
|
|
1913
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
1688
1914
|
|
|
1915
|
+
rm = rbce->resolve_mode;
|
|
1689
1916
|
|
|
1690
|
-
|
|
1917
|
+
switch(rm) {
|
|
1918
|
+
case CURL_IPRESOLVE_V4:
|
|
1919
|
+
return rb_easy_sym("ipv4");
|
|
1920
|
+
case CURL_IPRESOLVE_V6:
|
|
1921
|
+
return rb_easy_sym("ipv6");
|
|
1922
|
+
default:
|
|
1923
|
+
return rb_easy_sym("auto");
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1691
1926
|
|
|
1692
1927
|
/*
|
|
1693
1928
|
* call-seq:
|
|
1694
|
-
* easy.
|
|
1929
|
+
* easy.resolve_mode = symbol => symbol
|
|
1695
1930
|
*
|
|
1696
|
-
*
|
|
1697
|
-
*
|
|
1698
|
-
* attached block.
|
|
1931
|
+
* Configures what type of IP address this Curl::Easy instance
|
|
1932
|
+
* resolves DNS names to. Valid options are:
|
|
1699
1933
|
*
|
|
1700
|
-
*
|
|
1934
|
+
* [:auto] resolves DNS names to all IP versions your system allows
|
|
1935
|
+
* [:ipv4] resolves DNS names to IPv4 only
|
|
1936
|
+
* [:ipv6] resolves DNS names to IPv6 only
|
|
1937
|
+
*/
|
|
1938
|
+
static VALUE ruby_curl_easy_resolve_mode_set(VALUE self, VALUE resolve_mode) {
|
|
1939
|
+
if (TYPE(resolve_mode) != T_SYMBOL) {
|
|
1940
|
+
rb_raise(rb_eTypeError, "Must pass a symbol");
|
|
1941
|
+
return Qnil;
|
|
1942
|
+
} else {
|
|
1943
|
+
ruby_curl_easy *rbce;
|
|
1944
|
+
ID resolve_mode_id;
|
|
1945
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
1946
|
+
|
|
1947
|
+
resolve_mode_id = rb_to_id(resolve_mode);
|
|
1948
|
+
|
|
1949
|
+
if (resolve_mode_id == rb_intern("auto")) {
|
|
1950
|
+
rbce->resolve_mode = CURL_IPRESOLVE_WHATEVER;
|
|
1951
|
+
return resolve_mode;
|
|
1952
|
+
} else if (resolve_mode_id == rb_intern("ipv4")) {
|
|
1953
|
+
rbce->resolve_mode = CURL_IPRESOLVE_V4;
|
|
1954
|
+
return resolve_mode;
|
|
1955
|
+
} else if (resolve_mode_id == rb_intern("ipv6")) {
|
|
1956
|
+
rbce->resolve_mode = CURL_IPRESOLVE_V6;
|
|
1957
|
+
return resolve_mode;
|
|
1958
|
+
} else {
|
|
1959
|
+
rb_raise(rb_eArgError, "Must set to one of :auto, :ipv4, :ipv6");
|
|
1960
|
+
return Qnil;
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
|
|
1965
|
+
|
|
1966
|
+
/* ================= EVENT PROCS ================== */
|
|
1967
|
+
|
|
1968
|
+
/*
|
|
1969
|
+
* call-seq:
|
|
1970
|
+
* easy.on_body { |body_data| ... } => <old handler>
|
|
1971
|
+
*
|
|
1972
|
+
* Assign or remove the +on_body+ handler for this Curl::Easy instance.
|
|
1973
|
+
* To remove a previously-supplied handler, call this method with no
|
|
1974
|
+
* attached block.
|
|
1975
|
+
*
|
|
1976
|
+
* The +on_body+ handler is called for each chunk of response body passed back
|
|
1701
1977
|
* by libcurl during +perform+. It should perform any processing necessary,
|
|
1702
1978
|
* and return the actual number of bytes handled. Normally, this will
|
|
1703
1979
|
* equal the length of the data string, and CURL will continue processing.
|
|
@@ -1738,6 +2014,36 @@ static VALUE ruby_curl_easy_on_failure_set(int argc, VALUE *argv, VALUE self) {
|
|
|
1738
2014
|
CURB_HANDLER_PROC_HSETTER(ruby_curl_easy, failure_proc);
|
|
1739
2015
|
}
|
|
1740
2016
|
|
|
2017
|
+
/*
|
|
2018
|
+
* call-seq:
|
|
2019
|
+
* easy.on_missing {|easy,code| ... } => <old handler;>
|
|
2020
|
+
*
|
|
2021
|
+
* Assign or remove the on_missing handler for this Curl::Easy instance.
|
|
2022
|
+
* To remove a previously-supplied handler, call this method with no attached
|
|
2023
|
+
* block.
|
|
2024
|
+
*
|
|
2025
|
+
* The +on_missing+ handler is called when request is finished with a
|
|
2026
|
+
* status of 40x
|
|
2027
|
+
*/
|
|
2028
|
+
static VALUE ruby_curl_easy_on_missing_set(int argc, VALUE *argv, VALUE self) {
|
|
2029
|
+
CURB_HANDLER_PROC_HSETTER(ruby_curl_easy, missing_proc);
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
/*
|
|
2033
|
+
* call-seq:
|
|
2034
|
+
* easy.on_redirect {|easy,code| ... } => <old handler;>
|
|
2035
|
+
*
|
|
2036
|
+
* Assign or remove the on_redirect handler for this Curl::Easy instance.
|
|
2037
|
+
* To remove a previously-supplied handler, call this method with no attached
|
|
2038
|
+
* block.
|
|
2039
|
+
*
|
|
2040
|
+
* The +on_redirect+ handler is called when request is finished with a
|
|
2041
|
+
* status of 30x
|
|
2042
|
+
*/
|
|
2043
|
+
static VALUE ruby_curl_easy_on_redirect_set(int argc, VALUE *argv, VALUE self) {
|
|
2044
|
+
CURB_HANDLER_PROC_HSETTER(ruby_curl_easy, redirect_proc);
|
|
2045
|
+
}
|
|
2046
|
+
|
|
1741
2047
|
/*
|
|
1742
2048
|
* call-seq:
|
|
1743
2049
|
* easy.on_complete {|easy| ... } => <old handler>
|
|
@@ -1816,9 +2122,12 @@ static VALUE ruby_curl_easy_on_debug_set(int argc, VALUE *argv, VALUE self) {
|
|
|
1816
2122
|
/***********************************************
|
|
1817
2123
|
* This is an rb_iterate callback used to set up http headers.
|
|
1818
2124
|
*/
|
|
1819
|
-
static VALUE cb_each_http_header(VALUE header,
|
|
2125
|
+
static VALUE cb_each_http_header(VALUE header, VALUE wrap) {
|
|
2126
|
+
struct curl_slist **list;
|
|
1820
2127
|
VALUE header_str = Qnil;
|
|
1821
2128
|
|
|
2129
|
+
Data_Get_Struct(wrap, struct curl_slist *, list);
|
|
2130
|
+
|
|
1822
2131
|
//rb_p(header);
|
|
1823
2132
|
|
|
1824
2133
|
if (rb_type(header) == T_ARRAY) {
|
|
@@ -1842,28 +2151,80 @@ static VALUE cb_each_http_header(VALUE header, struct curl_slist **list) {
|
|
|
1842
2151
|
return header_str;
|
|
1843
2152
|
}
|
|
1844
2153
|
|
|
2154
|
+
/***********************************************
|
|
2155
|
+
* This is an rb_iterate callback used to set up http proxy headers.
|
|
2156
|
+
*/
|
|
2157
|
+
static VALUE cb_each_http_proxy_header(VALUE proxy_header, VALUE wrap) {
|
|
2158
|
+
struct curl_slist **list;
|
|
2159
|
+
VALUE proxy_header_str = Qnil;
|
|
2160
|
+
|
|
2161
|
+
Data_Get_Struct(wrap, struct curl_slist *, list);
|
|
2162
|
+
|
|
2163
|
+
//rb_p(proxy_header);
|
|
2164
|
+
|
|
2165
|
+
if (rb_type(proxy_header) == T_ARRAY) {
|
|
2166
|
+
// we're processing a hash, proxy header is [name, val]
|
|
2167
|
+
VALUE name, value;
|
|
2168
|
+
|
|
2169
|
+
name = rb_obj_as_string(rb_ary_entry(proxy_header, 0));
|
|
2170
|
+
value = rb_obj_as_string(rb_ary_entry(proxy_header, 1));
|
|
2171
|
+
|
|
2172
|
+
// This is a bit inefficient, but we don't want to be modifying
|
|
2173
|
+
// the actual values in the original hash.
|
|
2174
|
+
proxy_header_str = rb_str_plus(name, rb_str_new2(": "));
|
|
2175
|
+
proxy_header_str = rb_str_plus(proxy_header_str, value);
|
|
2176
|
+
} else {
|
|
2177
|
+
proxy_header_str = rb_obj_as_string(proxy_header);
|
|
2178
|
+
}
|
|
2179
|
+
|
|
2180
|
+
//rb_p(header_str);
|
|
2181
|
+
|
|
2182
|
+
*list = curl_slist_append(*list, StringValuePtr(proxy_header_str));
|
|
2183
|
+
return proxy_header_str;
|
|
2184
|
+
}
|
|
2185
|
+
|
|
1845
2186
|
/***********************************************
|
|
1846
2187
|
* This is an rb_iterate callback used to set up ftp commands.
|
|
1847
2188
|
*/
|
|
1848
|
-
static VALUE cb_each_ftp_command(VALUE ftp_command,
|
|
1849
|
-
|
|
2189
|
+
static VALUE cb_each_ftp_command(VALUE ftp_command, VALUE wrap) {
|
|
2190
|
+
struct curl_slist **list;
|
|
2191
|
+
VALUE ftp_command_string;
|
|
2192
|
+
Data_Get_Struct(wrap, struct curl_slist *, list);
|
|
2193
|
+
|
|
2194
|
+
ftp_command_string = rb_obj_as_string(ftp_command);
|
|
1850
2195
|
*list = curl_slist_append(*list, StringValuePtr(ftp_command));
|
|
1851
2196
|
|
|
1852
2197
|
return ftp_command_string;
|
|
1853
2198
|
}
|
|
1854
2199
|
|
|
2200
|
+
/***********************************************
|
|
2201
|
+
* This is an rb_iterate callback used to set up the resolve list.
|
|
2202
|
+
*/
|
|
2203
|
+
static VALUE cb_each_resolve(VALUE resolve, VALUE wrap) {
|
|
2204
|
+
struct curl_slist **list;
|
|
2205
|
+
VALUE resolve_string;
|
|
2206
|
+
Data_Get_Struct(wrap, struct curl_slist *, list);
|
|
2207
|
+
|
|
2208
|
+
resolve_string = rb_obj_as_string(resolve);
|
|
2209
|
+
*list = curl_slist_append(*list, StringValuePtr(resolve));
|
|
2210
|
+
|
|
2211
|
+
return resolve_string;
|
|
2212
|
+
}
|
|
2213
|
+
|
|
1855
2214
|
/***********************************************
|
|
1856
2215
|
*
|
|
1857
2216
|
* Setup a connection
|
|
1858
2217
|
*
|
|
1859
2218
|
* Always returns Qtrue, rb_raise on error.
|
|
1860
2219
|
*/
|
|
1861
|
-
VALUE ruby_curl_easy_setup(
|
|
2220
|
+
VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
1862
2221
|
// TODO this could do with a bit of refactoring...
|
|
1863
2222
|
CURL *curl;
|
|
1864
2223
|
VALUE url, _url = rb_easy_get("url");
|
|
1865
2224
|
struct curl_slist **hdrs = &(rbce->curl_headers);
|
|
2225
|
+
struct curl_slist **phdrs = &(rbce->curl_proxy_headers);
|
|
1866
2226
|
struct curl_slist **cmds = &(rbce->curl_ftp_commands);
|
|
2227
|
+
struct curl_slist **rslv = &(rbce->curl_resolve);
|
|
1867
2228
|
|
|
1868
2229
|
curl = rbce->curl;
|
|
1869
2230
|
|
|
@@ -1872,8 +2233,6 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
|
1872
2233
|
}
|
|
1873
2234
|
|
|
1874
2235
|
url = rb_check_string_type(_url);
|
|
1875
|
-
|
|
1876
|
-
// Need to configure the handler as per settings in rbce
|
|
1877
2236
|
curl_easy_setopt(curl, CURLOPT_URL, StringValuePtr(url));
|
|
1878
2237
|
|
|
1879
2238
|
// network stuff and auth
|
|
@@ -1921,8 +2280,8 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
|
1921
2280
|
|
|
1922
2281
|
// body/header procs
|
|
1923
2282
|
if (!rb_easy_nil("body_proc")) {
|
|
1924
|
-
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, (curl_write_callback)&
|
|
1925
|
-
curl_easy_setopt(curl, CURLOPT_WRITEDATA,
|
|
2283
|
+
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, (curl_write_callback)&proc_data_handler_body);
|
|
2284
|
+
curl_easy_setopt(curl, CURLOPT_WRITEDATA, rbce);
|
|
1926
2285
|
/* clear out the body_data if it was set */
|
|
1927
2286
|
rb_easy_del("body_data");
|
|
1928
2287
|
} else {
|
|
@@ -1932,8 +2291,8 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
|
1932
2291
|
}
|
|
1933
2292
|
|
|
1934
2293
|
if (!rb_easy_nil("header_proc")) {
|
|
1935
|
-
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, (curl_write_callback)&
|
|
1936
|
-
curl_easy_setopt(curl, CURLOPT_HEADERDATA,
|
|
2294
|
+
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, (curl_write_callback)&proc_data_handler_header);
|
|
2295
|
+
curl_easy_setopt(curl, CURLOPT_HEADERDATA, rbce);
|
|
1937
2296
|
/* clear out the header_data if it was set */
|
|
1938
2297
|
rb_easy_del("header_data");
|
|
1939
2298
|
} else {
|
|
@@ -1976,22 +2335,30 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
|
1976
2335
|
curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, rbce->proxy_tunnel);
|
|
1977
2336
|
curl_easy_setopt(curl, CURLOPT_FILETIME, rbce->fetch_file_time);
|
|
1978
2337
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, rbce->ssl_verify_peer);
|
|
1979
|
-
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, rbce->
|
|
2338
|
+
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, rbce->ssl_verify_host);
|
|
1980
2339
|
|
|
1981
2340
|
if ((rbce->use_netrc != Qnil) && (rbce->use_netrc != Qfalse)) {
|
|
1982
|
-
curl_easy_setopt(curl,
|
|
2341
|
+
curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
|
|
1983
2342
|
} else {
|
|
1984
|
-
curl_easy_setopt(curl,
|
|
2343
|
+
curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_IGNORED);
|
|
1985
2344
|
}
|
|
1986
2345
|
|
|
1987
2346
|
curl_easy_setopt(curl, CURLOPT_UNRESTRICTED_AUTH, rbce->unrestricted_auth);
|
|
1988
2347
|
|
|
1989
|
-
|
|
2348
|
+
#if HAVE_CURLOPT_TIMEOUT_MS
|
|
2349
|
+
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, rbce->timeout_ms);
|
|
2350
|
+
#endif
|
|
2351
|
+
|
|
1990
2352
|
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, rbce->connect_timeout);
|
|
2353
|
+
#if HAVE_CURLOPT_CONNECTTIMEOUT_MS
|
|
2354
|
+
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, rbce->connect_timeout_ms);
|
|
2355
|
+
#endif
|
|
1991
2356
|
curl_easy_setopt(curl, CURLOPT_DNS_CACHE_TIMEOUT, rbce->dns_cache_timeout);
|
|
1992
2357
|
|
|
1993
2358
|
curl_easy_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, rbce->ignore_content_length);
|
|
1994
2359
|
|
|
2360
|
+
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, rbce->resolve_mode);
|
|
2361
|
+
|
|
1995
2362
|
|
|
1996
2363
|
#if LIBCURL_VERSION_NUM >= 0x070a08
|
|
1997
2364
|
curl_easy_setopt(curl, CURLOPT_FTP_RESPONSE_TIMEOUT, rbce->ftp_response_timeout);
|
|
@@ -2004,6 +2371,9 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
|
2004
2371
|
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, rbce->low_speed_limit);
|
|
2005
2372
|
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, rbce->low_speed_time);
|
|
2006
2373
|
|
|
2374
|
+
curl_easy_setopt(curl, CURLOPT_MAX_RECV_SPEED_LARGE, rbce->max_recv_speed_large);
|
|
2375
|
+
curl_easy_setopt(curl, CURLOPT_MAX_SEND_SPEED_LARGE, rbce->max_send_speed_large);
|
|
2376
|
+
|
|
2007
2377
|
// Set up localport / proxy port
|
|
2008
2378
|
// FIXME these won't get returned to default if they're unset Ruby
|
|
2009
2379
|
if (rbce->proxy_port > 0) {
|
|
@@ -2036,21 +2406,20 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
|
2036
2406
|
#endif
|
|
2037
2407
|
}
|
|
2038
2408
|
|
|
2039
|
-
|
|
2409
|
+
/*
|
|
2410
|
+
* NOTE: we used to set CURLAUTH_ANY but see: http://curl.haxx.se/mail/lib-2015-06/0033.html
|
|
2411
|
+
*/
|
|
2412
|
+
if (rbce->http_auth_types != 0) {
|
|
2040
2413
|
#if LIBCURL_VERSION_NUM >= 0x070a06
|
|
2041
2414
|
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, rbce->http_auth_types);
|
|
2042
|
-
} else {
|
|
2043
|
-
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
|
|
2044
2415
|
#else
|
|
2045
2416
|
rb_warn("Installed libcurl is too old to support http_auth_types");
|
|
2046
2417
|
#endif
|
|
2047
2418
|
}
|
|
2048
2419
|
|
|
2049
|
-
if (rbce->proxy_auth_types
|
|
2420
|
+
if (rbce->proxy_auth_types != 0) {
|
|
2050
2421
|
#if LIBCURL_VERSION_NUM >= 0x070a07
|
|
2051
2422
|
curl_easy_setopt(curl, CURLOPT_PROXYAUTH, rbce->proxy_auth_types);
|
|
2052
|
-
} else {
|
|
2053
|
-
curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
|
|
2054
2423
|
#else
|
|
2055
2424
|
rb_warn("Installed libcurl is too old to support proxy_auth_types");
|
|
2056
2425
|
#endif
|
|
@@ -2077,7 +2446,9 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
|
2077
2446
|
|
|
2078
2447
|
/* Set up HTTPS cert handling if necessary */
|
|
2079
2448
|
if (!rb_easy_nil("cert")) {
|
|
2080
|
-
|
|
2449
|
+
if (!rb_easy_nil("certtype")) {
|
|
2450
|
+
curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, rb_easy_get_str("certtype"));
|
|
2451
|
+
}
|
|
2081
2452
|
curl_easy_setopt(curl, CURLOPT_SSLCERT, rb_easy_get_str("cert"));
|
|
2082
2453
|
if (!rb_easy_nil("certpassword")) {
|
|
2083
2454
|
curl_easy_setopt(curl, CURLOPT_SSLCERTPASSWD, rb_easy_get_str("certpassword"));
|
|
@@ -2086,13 +2457,15 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
|
2086
2457
|
curl_easy_setopt(curl, CURLOPT_SSLKEY, rb_easy_get_str("cert_key"));
|
|
2087
2458
|
}
|
|
2088
2459
|
}
|
|
2460
|
+
|
|
2089
2461
|
if (!rb_easy_nil("cacert")) {
|
|
2462
|
+
curl_easy_setopt(curl, CURLOPT_CAINFO, rb_easy_get_str("cacert"));
|
|
2463
|
+
}
|
|
2090
2464
|
#ifdef HAVE_CURL_CONFIG_CA
|
|
2465
|
+
else {
|
|
2091
2466
|
curl_easy_setopt(curl, CURLOPT_CAINFO, CURL_CONFIG_CA);
|
|
2092
|
-
#else
|
|
2093
|
-
curl_easy_setopt(curl, CURLOPT_CAINFO, "/usr/local/share/curl/curl-ca-bundle.crt");
|
|
2094
|
-
#endif
|
|
2095
2467
|
}
|
|
2468
|
+
#endif
|
|
2096
2469
|
|
|
2097
2470
|
#ifdef CURL_VERSION_SSL
|
|
2098
2471
|
if (rbce->ssl_version > 0) {
|
|
@@ -2107,7 +2480,7 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
|
2107
2480
|
rb_warn("libcurl is not configured with SSL support");
|
|
2108
2481
|
}
|
|
2109
2482
|
#endif
|
|
2110
|
-
|
|
2483
|
+
|
|
2111
2484
|
if (rbce->ftp_filemethod > 0) {
|
|
2112
2485
|
curl_easy_setopt(curl, CURLOPT_FTP_FILEMETHOD, rbce->ftp_filemethod);
|
|
2113
2486
|
}
|
|
@@ -2122,7 +2495,8 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
|
2122
2495
|
|
|
2123
2496
|
if (!rb_easy_nil("headers")) {
|
|
2124
2497
|
if (rb_easy_type_check("headers", T_ARRAY) || rb_easy_type_check("headers", T_HASH)) {
|
|
2125
|
-
|
|
2498
|
+
VALUE wrap = Data_Wrap_Struct(rb_cObject, 0, 0, hdrs);
|
|
2499
|
+
rb_iterate(rb_each, rb_easy_get("headers"), cb_each_http_header, wrap);
|
|
2126
2500
|
} else {
|
|
2127
2501
|
VALUE headers_str = rb_obj_as_string(rb_easy_get("headers"));
|
|
2128
2502
|
*hdrs = curl_slist_append(*hdrs, StringValuePtr(headers_str));
|
|
@@ -2133,10 +2507,30 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
|
2133
2507
|
}
|
|
2134
2508
|
}
|
|
2135
2509
|
|
|
2510
|
+
#if HAVE_CURLOPT_PROXYHEADER
|
|
2511
|
+
/* Setup HTTP proxy headers if necessary */
|
|
2512
|
+
curl_easy_setopt(curl, CURLOPT_PROXYHEADER, NULL); // XXX: maybe we shouldn't be clearing this?
|
|
2513
|
+
|
|
2514
|
+
if (!rb_easy_nil("proxy_headers")) {
|
|
2515
|
+
if (rb_easy_type_check("proxy_headers", T_ARRAY) || rb_easy_type_check("proxy_headers", T_HASH)) {
|
|
2516
|
+
VALUE wrap = Data_Wrap_Struct(rb_cObject, 0, 0, phdrs);
|
|
2517
|
+
rb_iterate(rb_each, rb_easy_get("proxy_headers"), cb_each_http_proxy_header, wrap);
|
|
2518
|
+
} else {
|
|
2519
|
+
VALUE proxy_headers_str = rb_obj_as_string(rb_easy_get("proxy_headers"));
|
|
2520
|
+
*phdrs = curl_slist_append(*hdrs, StringValuePtr(proxy_headers_str));
|
|
2521
|
+
}
|
|
2522
|
+
|
|
2523
|
+
if (*phdrs) {
|
|
2524
|
+
curl_easy_setopt(curl, CURLOPT_PROXYHEADER, *phdrs);
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
#endif
|
|
2528
|
+
|
|
2136
2529
|
/* Setup FTP commands if necessary */
|
|
2137
2530
|
if (!rb_easy_nil("ftp_commands")) {
|
|
2138
2531
|
if (rb_easy_type_check("ftp_commands", T_ARRAY)) {
|
|
2139
|
-
|
|
2532
|
+
VALUE wrap = Data_Wrap_Struct(rb_cObject, 0, 0, cmds);
|
|
2533
|
+
rb_iterate(rb_each, rb_easy_get("ftp_commands"), cb_each_ftp_command, wrap);
|
|
2140
2534
|
}
|
|
2141
2535
|
|
|
2142
2536
|
if (*cmds) {
|
|
@@ -2144,18 +2538,33 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) {
|
|
|
2144
2538
|
}
|
|
2145
2539
|
}
|
|
2146
2540
|
|
|
2541
|
+
#if HAVE_CURLOPT_RESOLVE
|
|
2542
|
+
/* Setup resolve list if necessary */
|
|
2543
|
+
if (!rb_easy_nil("resolve")) {
|
|
2544
|
+
if (rb_easy_type_check("resolve", T_ARRAY)) {
|
|
2545
|
+
VALUE wrap = Data_Wrap_Struct(rb_cObject, 0, 0, rslv);
|
|
2546
|
+
rb_iterate(rb_each, rb_easy_get("resolve"), cb_each_resolve, wrap);
|
|
2547
|
+
}
|
|
2548
|
+
|
|
2549
|
+
if (*rslv) {
|
|
2550
|
+
curl_easy_setopt(curl, CURLOPT_RESOLVE, *rslv);
|
|
2551
|
+
}
|
|
2552
|
+
}
|
|
2553
|
+
#endif
|
|
2554
|
+
|
|
2147
2555
|
return Qnil;
|
|
2148
2556
|
}
|
|
2149
2557
|
/***********************************************
|
|
2150
2558
|
*
|
|
2151
2559
|
* Clean up a connection
|
|
2152
2560
|
*
|
|
2153
|
-
* Always returns
|
|
2561
|
+
* Always returns Qnil.
|
|
2154
2562
|
*/
|
|
2155
2563
|
VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
|
|
2156
2564
|
|
|
2157
2565
|
CURL *curl = rbce->curl;
|
|
2158
2566
|
struct curl_slist *ftp_commands;
|
|
2567
|
+
struct curl_slist *resolve;
|
|
2159
2568
|
|
|
2160
2569
|
/* Free everything up */
|
|
2161
2570
|
if (rbce->curl_headers) {
|
|
@@ -2163,12 +2572,23 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
|
|
|
2163
2572
|
rbce->curl_headers = NULL;
|
|
2164
2573
|
}
|
|
2165
2574
|
|
|
2575
|
+
if (rbce->curl_proxy_headers) {
|
|
2576
|
+
curl_slist_free_all(rbce->curl_proxy_headers);
|
|
2577
|
+
rbce->curl_proxy_headers = NULL;
|
|
2578
|
+
}
|
|
2579
|
+
|
|
2166
2580
|
ftp_commands = rbce->curl_ftp_commands;
|
|
2167
2581
|
if (ftp_commands) {
|
|
2168
2582
|
curl_slist_free_all(ftp_commands);
|
|
2169
2583
|
rbce->curl_ftp_commands = NULL;
|
|
2170
2584
|
}
|
|
2171
2585
|
|
|
2586
|
+
resolve = rbce->curl_resolve;
|
|
2587
|
+
if (resolve) {
|
|
2588
|
+
curl_slist_free_all(resolve);
|
|
2589
|
+
rbce->curl_resolve = NULL;
|
|
2590
|
+
}
|
|
2591
|
+
|
|
2172
2592
|
/* clean up a PUT request's curl options. */
|
|
2173
2593
|
if (!rb_easy_nil("upload")) {
|
|
2174
2594
|
rb_easy_del("upload"); // set the upload object to Qnil to let the GC clean up
|
|
@@ -2178,57 +2598,10 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
|
|
|
2178
2598
|
curl_easy_setopt(curl, CURLOPT_INFILESIZE, 0);
|
|
2179
2599
|
}
|
|
2180
2600
|
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
/***********************************************
|
|
2185
|
-
*
|
|
2186
|
-
* This is the main worker for the perform methods (get, post, head, put).
|
|
2187
|
-
* It's not surfaced as a Ruby method - instead, the individual request
|
|
2188
|
-
* methods are responsible for setting up stuff specific to that type,
|
|
2189
|
-
* then calling this to handle common stuff and do the perform.
|
|
2190
|
-
*
|
|
2191
|
-
* Always returns Qtrue, rb_raise on error.
|
|
2192
|
-
*
|
|
2193
|
-
*/
|
|
2194
|
-
static VALUE handle_perform(VALUE self, ruby_curl_easy *rbce) {
|
|
2195
|
-
|
|
2196
|
-
VALUE ret;
|
|
2197
|
-
|
|
2198
|
-
/* reuse existing multi handle for this easy handle */
|
|
2199
|
-
if (NIL_P(rbce->multi)) {
|
|
2200
|
-
rbce->multi = ruby_curl_multi_new(cCurlMulti);
|
|
2201
|
-
}
|
|
2202
|
-
rb_funcall(rbce->multi, rb_intern("add"), 1, self );
|
|
2203
|
-
ret = rb_funcall(rbce->multi, rb_intern("perform"), 0);
|
|
2204
|
-
|
|
2205
|
-
/* check for errors in the easy response and raise exceptions if anything went wrong and their is no on_failure handler */
|
|
2206
|
-
if (rbce->last_result != 0 && rb_easy_nil("failure_proc")) {
|
|
2207
|
-
raise_curl_easy_error_exception(rbce->last_result);
|
|
2208
|
-
}
|
|
2209
|
-
|
|
2210
|
-
return ret;
|
|
2211
|
-
}
|
|
2212
|
-
|
|
2213
|
-
/*
|
|
2214
|
-
* call-seq:
|
|
2215
|
-
* easy.http_get => true
|
|
2216
|
-
*
|
|
2217
|
-
* GET the currently configured URL using the current options set for
|
|
2218
|
-
* this Curl::Easy instance. This method always returns true, or raises
|
|
2219
|
-
* an exception (defined under Curl::Err) on error.
|
|
2220
|
-
*/
|
|
2221
|
-
static VALUE ruby_curl_easy_perform_get(VALUE self) {
|
|
2222
|
-
ruby_curl_easy *rbce;
|
|
2223
|
-
CURL *curl;
|
|
2224
|
-
|
|
2225
|
-
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2226
|
-
curl = rbce->curl;
|
|
2227
|
-
|
|
2228
|
-
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
|
|
2229
|
-
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
|
|
2601
|
+
// set values on cleanup to nil
|
|
2602
|
+
rb_easy_del("multi");
|
|
2230
2603
|
|
|
2231
|
-
return
|
|
2604
|
+
return Qnil;
|
|
2232
2605
|
}
|
|
2233
2606
|
|
|
2234
2607
|
/*
|
|
@@ -2242,27 +2615,17 @@ static VALUE ruby_curl_easy_perform_verb_str(VALUE self, const char *verb) {
|
|
|
2242
2615
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2243
2616
|
curl = rbce->curl;
|
|
2244
2617
|
|
|
2618
|
+
memset(rbce->err_buf, 0, sizeof(rbce->err_buf));
|
|
2619
|
+
|
|
2245
2620
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, verb);
|
|
2246
2621
|
|
|
2247
|
-
retval =
|
|
2622
|
+
retval = rb_funcall(self, rb_intern("perform"), 0);
|
|
2248
2623
|
|
|
2249
2624
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
|
|
2250
2625
|
|
|
2251
2626
|
return retval;
|
|
2252
2627
|
}
|
|
2253
2628
|
|
|
2254
|
-
/*
|
|
2255
|
-
* call-seq:
|
|
2256
|
-
* easy.http_delete
|
|
2257
|
-
*
|
|
2258
|
-
* DELETE the currently configured URL using the current options set for
|
|
2259
|
-
* this Curl::Easy instance. This method always returns true, or raises
|
|
2260
|
-
* an exception (defined under Curl::Err) on error.
|
|
2261
|
-
*/
|
|
2262
|
-
static VALUE ruby_curl_easy_perform_delete(VALUE self) {
|
|
2263
|
-
return ruby_curl_easy_perform_verb_str(self, "DELETE");
|
|
2264
|
-
}
|
|
2265
|
-
|
|
2266
2629
|
/*
|
|
2267
2630
|
* call-seq:
|
|
2268
2631
|
* easy.http(verb)
|
|
@@ -2273,33 +2636,17 @@ static VALUE ruby_curl_easy_perform_delete(VALUE self) {
|
|
|
2273
2636
|
static VALUE ruby_curl_easy_perform_verb(VALUE self, VALUE verb) {
|
|
2274
2637
|
VALUE str_verb;
|
|
2275
2638
|
if (rb_type(verb) == T_STRING) {
|
|
2276
|
-
return ruby_curl_easy_perform_verb_str(self,
|
|
2639
|
+
return ruby_curl_easy_perform_verb_str(self, StringValueCStr(verb));
|
|
2277
2640
|
}
|
|
2278
2641
|
else if (rb_respond_to(verb,rb_intern("to_s"))) {
|
|
2279
2642
|
str_verb = rb_funcall(verb, rb_intern("to_s"), 0);
|
|
2280
|
-
return ruby_curl_easy_perform_verb_str(self,
|
|
2643
|
+
return ruby_curl_easy_perform_verb_str(self, StringValueCStr(str_verb));
|
|
2281
2644
|
}
|
|
2282
2645
|
else {
|
|
2283
2646
|
rb_raise(rb_eRuntimeError, "Invalid HTTP VERB, must response to 'to_s'");
|
|
2284
2647
|
}
|
|
2285
2648
|
}
|
|
2286
2649
|
|
|
2287
|
-
/*
|
|
2288
|
-
* call-seq:
|
|
2289
|
-
* easy.perform => true
|
|
2290
|
-
*
|
|
2291
|
-
* Transfer the currently configured URL using the options set for this
|
|
2292
|
-
* Curl::Easy instance. If this is an HTTP URL, it will be transferred via
|
|
2293
|
-
* the GET or HEAD request method.
|
|
2294
|
-
*/
|
|
2295
|
-
static VALUE ruby_curl_easy_perform(VALUE self) {
|
|
2296
|
-
ruby_curl_easy *rbce;
|
|
2297
|
-
|
|
2298
|
-
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2299
|
-
|
|
2300
|
-
return handle_perform(self,rbce);
|
|
2301
|
-
}
|
|
2302
|
-
|
|
2303
2650
|
/*
|
|
2304
2651
|
* call-seq:
|
|
2305
2652
|
* easy.http_post("url=encoded%20form%20data;and=so%20on") => true
|
|
@@ -2335,6 +2682,8 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
|
|
|
2335
2682
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2336
2683
|
curl = rbce->curl;
|
|
2337
2684
|
|
|
2685
|
+
memset(rbce->err_buf, 0, sizeof(rbce->err_buf));
|
|
2686
|
+
|
|
2338
2687
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
|
|
2339
2688
|
|
|
2340
2689
|
if (rbce->multipart_form_post) {
|
|
@@ -2345,6 +2694,17 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
|
|
|
2345
2694
|
for (i = 0; i < argc; i++) {
|
|
2346
2695
|
if (rb_obj_is_instance_of(argv[i], cCurlPostField)) {
|
|
2347
2696
|
append_to_form(argv[i], &first, &last);
|
|
2697
|
+
} else if (rb_type(argv[i]) == T_ARRAY) {
|
|
2698
|
+
// see: https://github.com/rvanlieshout/curb/commit/8bcdefddc0162484681ebd1a92d52a642666a445
|
|
2699
|
+
long c = 0, argv_len = RARRAY_LEN(argv[i]);
|
|
2700
|
+
for (; c < argv_len; ++c) {
|
|
2701
|
+
if (rb_obj_is_instance_of(rb_ary_entry(argv[i],c), cCurlPostField)) {
|
|
2702
|
+
append_to_form(rb_ary_entry(argv[i],c), &first, &last);
|
|
2703
|
+
} else {
|
|
2704
|
+
rb_raise(eCurlErrInvalidPostField, "You must use PostFields only with multipart form posts");
|
|
2705
|
+
return Qnil;
|
|
2706
|
+
}
|
|
2707
|
+
}
|
|
2348
2708
|
} else {
|
|
2349
2709
|
rb_raise(eCurlErrInvalidPostField, "You must use PostFields only with multipart form posts");
|
|
2350
2710
|
return Qnil;
|
|
@@ -2353,7 +2713,7 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
|
|
|
2353
2713
|
|
|
2354
2714
|
curl_easy_setopt(curl, CURLOPT_POST, 0);
|
|
2355
2715
|
curl_easy_setopt(curl, CURLOPT_HTTPPOST, first);
|
|
2356
|
-
ret =
|
|
2716
|
+
ret = rb_funcall(self, rb_intern("perform"), 0);
|
|
2357
2717
|
curl_formfree(first);
|
|
2358
2718
|
|
|
2359
2719
|
return ret;
|
|
@@ -2375,114 +2735,11 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
|
|
|
2375
2735
|
ruby_curl_easy_post_body_set(self, post_body);
|
|
2376
2736
|
}
|
|
2377
2737
|
|
|
2378
|
-
return
|
|
2738
|
+
return rb_funcall(self, rb_intern("perform"), 0);
|
|
2379
2739
|
}
|
|
2380
2740
|
}
|
|
2381
2741
|
}
|
|
2382
2742
|
|
|
2383
|
-
/*
|
|
2384
|
-
* call-seq:
|
|
2385
|
-
* easy.http_head => true
|
|
2386
|
-
*
|
|
2387
|
-
* Request headers from the currently configured URL using the HEAD
|
|
2388
|
-
* method and current options set for this Curl::Easy instance. This
|
|
2389
|
-
* method always returns true, or raises an exception (defined under
|
|
2390
|
-
* Curl::Err) on error.
|
|
2391
|
-
*
|
|
2392
|
-
*/
|
|
2393
|
-
static VALUE ruby_curl_easy_perform_head(VALUE self) {
|
|
2394
|
-
ruby_curl_easy *rbce;
|
|
2395
|
-
CURL *curl;
|
|
2396
|
-
VALUE ret;
|
|
2397
|
-
|
|
2398
|
-
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2399
|
-
curl = rbce->curl;
|
|
2400
|
-
|
|
2401
|
-
curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
|
|
2402
|
-
|
|
2403
|
-
ret = handle_perform(self,rbce);
|
|
2404
|
-
|
|
2405
|
-
curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
|
|
2406
|
-
return ret;
|
|
2407
|
-
}
|
|
2408
|
-
|
|
2409
|
-
/*
|
|
2410
|
-
*call-seq:
|
|
2411
|
-
* easy = Curl::Easy.new("url") do|c|
|
|
2412
|
-
* c.head = true
|
|
2413
|
-
* end
|
|
2414
|
-
* easy.perform
|
|
2415
|
-
*/
|
|
2416
|
-
static VALUE ruby_curl_easy_set_head_option(VALUE self, VALUE onoff) {
|
|
2417
|
-
ruby_curl_easy *rbce;
|
|
2418
|
-
|
|
2419
|
-
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2420
|
-
|
|
2421
|
-
if( onoff == Qtrue ) {
|
|
2422
|
-
curl_easy_setopt(rbce->curl, CURLOPT_NOBODY, 1);
|
|
2423
|
-
}
|
|
2424
|
-
else {
|
|
2425
|
-
curl_easy_setopt(rbce->curl, CURLOPT_NOBODY, 0);
|
|
2426
|
-
}
|
|
2427
|
-
|
|
2428
|
-
return onoff;
|
|
2429
|
-
}
|
|
2430
|
-
/*
|
|
2431
|
-
*call-seq:
|
|
2432
|
-
*
|
|
2433
|
-
* easy = Curl::Easy.new("url")
|
|
2434
|
-
* easy.version = Curl::HTTP_1_1
|
|
2435
|
-
* easy.version = Curl::HTTP_1_0
|
|
2436
|
-
* easy.version = Curl::HTTP_NONE
|
|
2437
|
-
*
|
|
2438
|
-
*/
|
|
2439
|
-
static VALUE ruby_curl_easy_set_version(VALUE self, VALUE version) {
|
|
2440
|
-
ruby_curl_easy *rbce;
|
|
2441
|
-
//fprintf(stderr,"CURL_HTTP_VERSION_1_1: %d, CURL_HTTP_VERSION_1_0: %d, CURL_HTTP_VERSION_NONE: %d\n", CURL_HTTP_VERSION_1_1, CURL_HTTP_VERSION_1_0, CURL_HTTP_VERSION_NONE);
|
|
2442
|
-
|
|
2443
|
-
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2444
|
-
|
|
2445
|
-
curl_easy_setopt(rbce->curl, CURLOPT_HTTP_VERSION, FIX2INT(version));
|
|
2446
|
-
|
|
2447
|
-
return version;
|
|
2448
|
-
}
|
|
2449
|
-
/*
|
|
2450
|
-
* call-seq:
|
|
2451
|
-
*
|
|
2452
|
-
* easy = Curl::Easy.new
|
|
2453
|
-
* easy.nosignal = true
|
|
2454
|
-
*/
|
|
2455
|
-
static VALUE ruby_curl_easy_set_nosignal(VALUE self, VALUE onoff) {
|
|
2456
|
-
ruby_curl_easy *rbce;
|
|
2457
|
-
|
|
2458
|
-
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2459
|
-
|
|
2460
|
-
curl_easy_setopt(rbce->curl, CURLOPT_NOSIGNAL, (Qtrue == onoff) ? 1 : 0);
|
|
2461
|
-
|
|
2462
|
-
return onoff;
|
|
2463
|
-
}
|
|
2464
|
-
/*
|
|
2465
|
-
*call-seq:
|
|
2466
|
-
* easy = Curl::Easy.new("url") do|c|
|
|
2467
|
-
* c.delete = true
|
|
2468
|
-
* end
|
|
2469
|
-
* easy.perform
|
|
2470
|
-
*/
|
|
2471
|
-
static VALUE ruby_curl_easy_set_delete_option(VALUE self, VALUE onoff) {
|
|
2472
|
-
ruby_curl_easy *rbce;
|
|
2473
|
-
|
|
2474
|
-
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2475
|
-
|
|
2476
|
-
if( onoff == Qtrue ) {
|
|
2477
|
-
curl_easy_setopt(rbce->curl, CURLOPT_CUSTOMREQUEST, "DELETE");
|
|
2478
|
-
}
|
|
2479
|
-
else {
|
|
2480
|
-
curl_easy_setopt(rbce->curl, CURLOPT_CUSTOMREQUEST, NULL);
|
|
2481
|
-
}
|
|
2482
|
-
|
|
2483
|
-
return onoff;
|
|
2484
|
-
}
|
|
2485
|
-
|
|
2486
2743
|
/*
|
|
2487
2744
|
* call-seq:
|
|
2488
2745
|
* easy.http_put(data) => true
|
|
@@ -2494,28 +2751,19 @@ static VALUE ruby_curl_easy_set_delete_option(VALUE self, VALUE onoff) {
|
|
|
2494
2751
|
static VALUE ruby_curl_easy_perform_put(VALUE self, VALUE data) {
|
|
2495
2752
|
ruby_curl_easy *rbce;
|
|
2496
2753
|
CURL *curl;
|
|
2497
|
-
|
|
2754
|
+
|
|
2498
2755
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2499
2756
|
curl = rbce->curl;
|
|
2500
|
-
|
|
2757
|
+
|
|
2758
|
+
memset(rbce->err_buf, 0, sizeof(rbce->err_buf));
|
|
2759
|
+
|
|
2501
2760
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
|
|
2502
2761
|
ruby_curl_easy_put_data_set(self, data);
|
|
2503
|
-
|
|
2504
|
-
return handle_perform(self, rbce);
|
|
2505
|
-
}
|
|
2506
2762
|
|
|
2507
|
-
|
|
2508
|
-
* call-seq:
|
|
2509
|
-
* Curl::Easy.http_put(url, data) {|c| ... }
|
|
2510
|
-
*
|
|
2511
|
-
* see easy.http_put
|
|
2512
|
-
*/
|
|
2513
|
-
static VALUE ruby_curl_easy_class_perform_put(VALUE klass, VALUE url, VALUE data) {
|
|
2514
|
-
VALUE c = ruby_curl_easy_new(1, &url, klass);
|
|
2515
|
-
ruby_curl_easy_perform_put(c, data);
|
|
2516
|
-
return c;
|
|
2763
|
+
return rb_funcall(self, rb_intern("perform"), 0);
|
|
2517
2764
|
}
|
|
2518
2765
|
|
|
2766
|
+
|
|
2519
2767
|
/* =================== DATA FUNCS =============== */
|
|
2520
2768
|
|
|
2521
2769
|
/*
|
|
@@ -2603,7 +2851,7 @@ static VALUE ruby_curl_easy_response_code_get(VALUE self) {
|
|
|
2603
2851
|
static VALUE ruby_curl_easy_primary_ip_get(VALUE self) {
|
|
2604
2852
|
ruby_curl_easy *rbce;
|
|
2605
2853
|
char* ip;
|
|
2606
|
-
|
|
2854
|
+
|
|
2607
2855
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2608
2856
|
curl_easy_getinfo(rbce->curl, CURLINFO_PRIMARY_IP, &ip);
|
|
2609
2857
|
|
|
@@ -2659,7 +2907,7 @@ static VALUE ruby_curl_easy_file_time_get(VALUE self) {
|
|
|
2659
2907
|
return LONG2NUM(time);
|
|
2660
2908
|
#else
|
|
2661
2909
|
rb_warn("Installed libcurl is too old to support file_time");
|
|
2662
|
-
return
|
|
2910
|
+
return LONG2NUM(0);
|
|
2663
2911
|
#endif
|
|
2664
2912
|
}
|
|
2665
2913
|
|
|
@@ -2714,6 +2962,29 @@ static VALUE ruby_curl_easy_connect_time_get(VALUE self) {
|
|
|
2714
2962
|
return rb_float_new(time);
|
|
2715
2963
|
}
|
|
2716
2964
|
|
|
2965
|
+
/*
|
|
2966
|
+
* call-seq:
|
|
2967
|
+
* easy.app_connect_time => float
|
|
2968
|
+
*
|
|
2969
|
+
* Retrieve the time, in seconds, it took from the start until the SSL/SSH
|
|
2970
|
+
* connect/handshake to the remote host was completed. This time is most often
|
|
2971
|
+
* very near to the pre transfer time, except for cases such as HTTP
|
|
2972
|
+
* pipelining where the pretransfer time can be delayed due to waits in line
|
|
2973
|
+
* for the pipeline and more.
|
|
2974
|
+
*/
|
|
2975
|
+
#if defined(HAVE_CURLINFO_APPCONNECT_TIME)
|
|
2976
|
+
static VALUE ruby_curl_easy_app_connect_time_get(VALUE self) {
|
|
2977
|
+
ruby_curl_easy *rbce;
|
|
2978
|
+
double time;
|
|
2979
|
+
|
|
2980
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2981
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_APPCONNECT_TIME, &time);
|
|
2982
|
+
|
|
2983
|
+
return rb_float_new(time);
|
|
2984
|
+
}
|
|
2985
|
+
#endif
|
|
2986
|
+
|
|
2987
|
+
|
|
2717
2988
|
/*
|
|
2718
2989
|
* call-seq:
|
|
2719
2990
|
* easy.pre_transfer_time => float
|
|
@@ -2796,11 +3067,41 @@ static VALUE ruby_curl_easy_redirect_count_get(VALUE self) {
|
|
|
2796
3067
|
return LONG2NUM(count);
|
|
2797
3068
|
#else
|
|
2798
3069
|
rb_warn("Installed libcurl is too old to support redirect_count");
|
|
2799
|
-
return
|
|
3070
|
+
return LONG2NUM(-1);
|
|
2800
3071
|
#endif
|
|
2801
3072
|
|
|
2802
3073
|
}
|
|
2803
3074
|
|
|
3075
|
+
/*
|
|
3076
|
+
* call-seq:
|
|
3077
|
+
* easy.redirect_url => "http://some.url" or nil
|
|
3078
|
+
*
|
|
3079
|
+
* Retrieve the URL a redirect would take you to if you
|
|
3080
|
+
* would enable CURLOPT_FOLLOWLOCATION.
|
|
3081
|
+
*
|
|
3082
|
+
* Requires libcurl 7.18.2 or higher, otherwise -1 is always returned.
|
|
3083
|
+
*/
|
|
3084
|
+
static VALUE ruby_curl_easy_redirect_url_get(VALUE self) {
|
|
3085
|
+
#ifdef HAVE_CURLINFO_REDIRECT_URL
|
|
3086
|
+
ruby_curl_easy *rbce;
|
|
3087
|
+
char* url;
|
|
3088
|
+
|
|
3089
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
3090
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_REDIRECT_URL, &url);
|
|
3091
|
+
|
|
3092
|
+
if (url && url[0]) { // curl returns empty string if none
|
|
3093
|
+
return rb_str_new2(url);
|
|
3094
|
+
} else {
|
|
3095
|
+
return Qnil;
|
|
3096
|
+
}
|
|
3097
|
+
#else
|
|
3098
|
+
rb_warn("Installed libcurl is too old to support redirect_url");
|
|
3099
|
+
return LONG2NUM(-1);
|
|
3100
|
+
#endif
|
|
3101
|
+
}
|
|
3102
|
+
|
|
3103
|
+
|
|
3104
|
+
|
|
2804
3105
|
/*
|
|
2805
3106
|
* call-seq:
|
|
2806
3107
|
* easy.uploaded_bytes => float
|
|
@@ -2923,7 +3224,10 @@ static VALUE ruby_curl_easy_ssl_verify_result_get(VALUE self) {
|
|
|
2923
3224
|
|
|
2924
3225
|
/* TODO CURLINFO_SSL_ENGINES
|
|
2925
3226
|
|
|
2926
|
-
Pass the address of a 'struct curl_slist *' to receive a linked-list of OpenSSL crypto-engines supported.
|
|
3227
|
+
Pass the address of a 'struct curl_slist *' to receive a linked-list of OpenSSL crypto-engines supported.
|
|
3228
|
+
Note that engines are normally implemented in separate dynamic libraries.
|
|
3229
|
+
Hence not all the returned engines may be available at run-time.
|
|
3230
|
+
NOTE: you must call curl_slist_free_all(3) on the list pointer once you're done with it, as libcurl will not free the data for you. (Added in 7.12.3)
|
|
2927
3231
|
*/
|
|
2928
3232
|
|
|
2929
3233
|
/*
|
|
@@ -3021,7 +3325,7 @@ static VALUE ruby_curl_easy_os_errno_get(VALUE self) {
|
|
|
3021
3325
|
return LONG2NUM(result);
|
|
3022
3326
|
#else
|
|
3023
3327
|
rb_warn("Installed libcurl is too old to support os_errno");
|
|
3024
|
-
return
|
|
3328
|
+
return LONG2NUM(0);
|
|
3025
3329
|
#endif
|
|
3026
3330
|
}
|
|
3027
3331
|
|
|
@@ -3050,17 +3354,45 @@ static VALUE ruby_curl_easy_num_connects_get(VALUE self) {
|
|
|
3050
3354
|
return LONG2NUM(result);
|
|
3051
3355
|
#else
|
|
3052
3356
|
rb_warn("Installed libcurl is too old to support num_connects");
|
|
3053
|
-
return
|
|
3357
|
+
return LONG2NUM(-1);
|
|
3054
3358
|
#endif
|
|
3055
3359
|
}
|
|
3056
3360
|
|
|
3057
3361
|
|
|
3058
|
-
/*
|
|
3362
|
+
/*
|
|
3363
|
+
* call-seq:
|
|
3364
|
+
* easy.cookielist => array
|
|
3365
|
+
*
|
|
3366
|
+
* Retrieves the cookies curl knows in an array of strings.
|
|
3367
|
+
* Returned strings are in Netscape cookiejar format or in Set-Cookie format.
|
|
3368
|
+
*
|
|
3369
|
+
* See also option CURLINFO_COOKIELIST of curl_easy_getopt(3) to see how libcurl behaves.
|
|
3370
|
+
*
|
|
3371
|
+
* (requires libcurl 7.14.1 or higher, otherwise -1 is always returned).
|
|
3372
|
+
*/
|
|
3373
|
+
static VALUE ruby_curl_easy_cookielist_get(VALUE self) {
|
|
3374
|
+
#ifdef HAVE_CURLINFO_COOKIELIST
|
|
3375
|
+
ruby_curl_easy *rbce;
|
|
3376
|
+
struct curl_slist *cookies;
|
|
3377
|
+
struct curl_slist *cookie;
|
|
3378
|
+
VALUE rb_cookies;
|
|
3059
3379
|
|
|
3060
|
-
|
|
3380
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
3381
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_COOKIELIST, &cookies);
|
|
3382
|
+
if (!cookies)
|
|
3383
|
+
return Qnil;
|
|
3384
|
+
rb_cookies = rb_ary_new();
|
|
3385
|
+
for (cookie = cookies; cookie; cookie = cookie->next)
|
|
3386
|
+
rb_ary_push(rb_cookies, rb_str_new2(cookie->data));
|
|
3387
|
+
curl_slist_free_all(cookies);
|
|
3388
|
+
return rb_cookies;
|
|
3389
|
+
|
|
3390
|
+
#else
|
|
3391
|
+
rb_warn("Installed libcurl is too old to support cookielist");
|
|
3392
|
+
return INT2FIX(-1);
|
|
3393
|
+
#endif
|
|
3394
|
+
}
|
|
3061
3395
|
|
|
3062
|
-
Pass a pointer to a 'struct curl_slist *' to receive a linked-list of all cookies cURL knows (expired ones, too). Don't forget to curl_slist_free_all(3) the list after it has been used. If there are no cookies (cookies for the handle have not been enabled or simply none have been received) 'struct curl_slist *' will be set to point to NULL. (Added in 7.14.1)
|
|
3063
|
-
*/
|
|
3064
3396
|
|
|
3065
3397
|
/* TODO this needs to be implemented. Could probably support CONNECT_ONLY by having this
|
|
3066
3398
|
* return an open Socket or something.
|
|
@@ -3099,6 +3431,239 @@ static VALUE ruby_curl_easy_ftp_entry_path_get(VALUE self) {
|
|
|
3099
3431
|
#endif
|
|
3100
3432
|
}
|
|
3101
3433
|
|
|
3434
|
+
/*
|
|
3435
|
+
* call-seq:
|
|
3436
|
+
* easy.multi => "#<Curl::Multi>"
|
|
3437
|
+
*/
|
|
3438
|
+
static VALUE ruby_curl_easy_multi_get(VALUE self) {
|
|
3439
|
+
ruby_curl_easy *rbce;
|
|
3440
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
3441
|
+
return rbce->multi;
|
|
3442
|
+
}
|
|
3443
|
+
|
|
3444
|
+
/*
|
|
3445
|
+
* call-seq:
|
|
3446
|
+
* easy.multi=multi => "#<Curl::Multi>"
|
|
3447
|
+
*/
|
|
3448
|
+
static VALUE ruby_curl_easy_multi_set(VALUE self, VALUE multi) {
|
|
3449
|
+
ruby_curl_easy *rbce;
|
|
3450
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
3451
|
+
rbce->multi = multi;
|
|
3452
|
+
return rbce->multi;
|
|
3453
|
+
}
|
|
3454
|
+
|
|
3455
|
+
/*
|
|
3456
|
+
* call-seq:
|
|
3457
|
+
* easy.last_result => 0
|
|
3458
|
+
*/
|
|
3459
|
+
static VALUE ruby_curl_easy_last_result(VALUE self) {
|
|
3460
|
+
ruby_curl_easy *rbce;
|
|
3461
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
3462
|
+
return LONG2NUM(rbce->last_result);
|
|
3463
|
+
}
|
|
3464
|
+
|
|
3465
|
+
/*
|
|
3466
|
+
* call-seq:
|
|
3467
|
+
* easy.last_error => "Error details" or nil
|
|
3468
|
+
*/
|
|
3469
|
+
static VALUE ruby_curl_easy_last_error(VALUE self) {
|
|
3470
|
+
ruby_curl_easy *rbce;
|
|
3471
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
3472
|
+
|
|
3473
|
+
if (rbce->err_buf[0]) { // curl returns NULL or empty string if none
|
|
3474
|
+
return rb_str_new2(rbce->err_buf);
|
|
3475
|
+
} else {
|
|
3476
|
+
return Qnil;
|
|
3477
|
+
}
|
|
3478
|
+
}
|
|
3479
|
+
|
|
3480
|
+
/*
|
|
3481
|
+
* call-seq:
|
|
3482
|
+
* easy.setopt Fixnum, value => value
|
|
3483
|
+
*
|
|
3484
|
+
* Initial access to libcurl curl_easy_setopt
|
|
3485
|
+
*/
|
|
3486
|
+
static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
3487
|
+
ruby_curl_easy *rbce;
|
|
3488
|
+
long option = NUM2LONG(opt);
|
|
3489
|
+
rb_io_t *open_f_ptr;
|
|
3490
|
+
|
|
3491
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
3492
|
+
|
|
3493
|
+
switch (option) {
|
|
3494
|
+
/* BEHAVIOR OPTIONS */
|
|
3495
|
+
case CURLOPT_VERBOSE: {
|
|
3496
|
+
VALUE verbose = val;
|
|
3497
|
+
CURB_BOOLEAN_SETTER(ruby_curl_easy, verbose);
|
|
3498
|
+
} break;
|
|
3499
|
+
case CURLOPT_FOLLOWLOCATION: {
|
|
3500
|
+
VALUE follow_location = val;
|
|
3501
|
+
CURB_BOOLEAN_SETTER(ruby_curl_easy, follow_location);
|
|
3502
|
+
} break;
|
|
3503
|
+
/* TODO: CALLBACK OPTIONS */
|
|
3504
|
+
/* TODO: ERROR OPTIONS */
|
|
3505
|
+
/* NETWORK OPTIONS */
|
|
3506
|
+
case CURLOPT_URL: {
|
|
3507
|
+
VALUE url = val;
|
|
3508
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, url);
|
|
3509
|
+
} break;
|
|
3510
|
+
case CURLOPT_CUSTOMREQUEST:
|
|
3511
|
+
curl_easy_setopt(rbce->curl, CURLOPT_CUSTOMREQUEST, NIL_P(val) ? NULL : StringValueCStr(val));
|
|
3512
|
+
break;
|
|
3513
|
+
case CURLOPT_HTTP_VERSION:
|
|
3514
|
+
curl_easy_setopt(rbce->curl, CURLOPT_HTTP_VERSION, NUM2LONG(val));
|
|
3515
|
+
break;
|
|
3516
|
+
case CURLOPT_PROXY: {
|
|
3517
|
+
VALUE proxy_url = val;
|
|
3518
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, proxy_url);
|
|
3519
|
+
} break;
|
|
3520
|
+
case CURLOPT_INTERFACE: {
|
|
3521
|
+
VALUE interface_hm = val;
|
|
3522
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, interface_hm);
|
|
3523
|
+
} break;
|
|
3524
|
+
case CURLOPT_HEADER:
|
|
3525
|
+
case CURLOPT_NOPROGRESS:
|
|
3526
|
+
case CURLOPT_NOSIGNAL:
|
|
3527
|
+
#if HAVE_CURLOPT_PATH_AS_IS
|
|
3528
|
+
case CURLOPT_PATH_AS_IS:
|
|
3529
|
+
#endif
|
|
3530
|
+
#if HAVE_CURLOPT_PIPEWAIT
|
|
3531
|
+
case CURLOPT_PIPEWAIT:
|
|
3532
|
+
#endif
|
|
3533
|
+
case CURLOPT_HTTPGET:
|
|
3534
|
+
case CURLOPT_NOBODY: {
|
|
3535
|
+
int type = rb_type(val);
|
|
3536
|
+
VALUE value;
|
|
3537
|
+
if (type == T_TRUE) {
|
|
3538
|
+
value = rb_int_new(1);
|
|
3539
|
+
} else if (type == T_FALSE) {
|
|
3540
|
+
value = rb_int_new(0);
|
|
3541
|
+
} else {
|
|
3542
|
+
value = rb_funcall(val, rb_intern("to_i"), 0);
|
|
3543
|
+
}
|
|
3544
|
+
curl_easy_setopt(rbce->curl, option, NUM2LONG(value));
|
|
3545
|
+
} break;
|
|
3546
|
+
case CURLOPT_POST: {
|
|
3547
|
+
curl_easy_setopt(rbce->curl, CURLOPT_POST, rb_type(val) == T_TRUE);
|
|
3548
|
+
} break;
|
|
3549
|
+
case CURLOPT_MAXCONNECTS: {
|
|
3550
|
+
curl_easy_setopt(rbce->curl, CURLOPT_MAXCONNECTS, NUM2LONG(val));
|
|
3551
|
+
} break;
|
|
3552
|
+
case CURLOPT_POSTFIELDS: {
|
|
3553
|
+
curl_easy_setopt(rbce->curl, CURLOPT_POSTFIELDS, NIL_P(val) ? NULL : StringValueCStr(val));
|
|
3554
|
+
} break;
|
|
3555
|
+
case CURLOPT_USERPWD: {
|
|
3556
|
+
VALUE userpwd = val;
|
|
3557
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, userpwd);
|
|
3558
|
+
} break;
|
|
3559
|
+
case CURLOPT_PROXYUSERPWD: {
|
|
3560
|
+
VALUE proxypwd = val;
|
|
3561
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, proxypwd);
|
|
3562
|
+
} break;
|
|
3563
|
+
case CURLOPT_COOKIE: {
|
|
3564
|
+
VALUE cookies = val;
|
|
3565
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, cookies);
|
|
3566
|
+
} break;
|
|
3567
|
+
case CURLOPT_COOKIEFILE: {
|
|
3568
|
+
VALUE cookiefile = val;
|
|
3569
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, cookiefile);
|
|
3570
|
+
} break;
|
|
3571
|
+
case CURLOPT_COOKIEJAR: {
|
|
3572
|
+
VALUE cookiejar = val;
|
|
3573
|
+
CURB_OBJECT_HSETTER(ruby_curl_easy, cookiejar);
|
|
3574
|
+
} break;
|
|
3575
|
+
case CURLOPT_TCP_NODELAY: {
|
|
3576
|
+
curl_easy_setopt(rbce->curl, CURLOPT_TCP_NODELAY, NUM2LONG(val));
|
|
3577
|
+
} break;
|
|
3578
|
+
case CURLOPT_RANGE: {
|
|
3579
|
+
curl_easy_setopt(rbce->curl, CURLOPT_RANGE, StringValueCStr(val));
|
|
3580
|
+
} break;
|
|
3581
|
+
case CURLOPT_RESUME_FROM: {
|
|
3582
|
+
curl_easy_setopt(rbce->curl, CURLOPT_RESUME_FROM, NUM2LONG(val));
|
|
3583
|
+
} break;
|
|
3584
|
+
case CURLOPT_FAILONERROR: {
|
|
3585
|
+
curl_easy_setopt(rbce->curl, CURLOPT_FAILONERROR, NUM2LONG(val));
|
|
3586
|
+
} break;
|
|
3587
|
+
case CURLOPT_SSL_CIPHER_LIST: {
|
|
3588
|
+
curl_easy_setopt(rbce->curl, CURLOPT_SSL_CIPHER_LIST, StringValueCStr(val));
|
|
3589
|
+
} break;
|
|
3590
|
+
case CURLOPT_FORBID_REUSE: {
|
|
3591
|
+
curl_easy_setopt(rbce->curl, CURLOPT_FORBID_REUSE, NUM2LONG(val));
|
|
3592
|
+
} break;
|
|
3593
|
+
#if HAVE_CURLOPT_GSSAPI_DELEGATION
|
|
3594
|
+
case CURLOPT_GSSAPI_DELEGATION: {
|
|
3595
|
+
curl_easy_setopt(rbce->curl, CURLOPT_GSSAPI_DELEGATION, NUM2LONG(val));
|
|
3596
|
+
} break;
|
|
3597
|
+
#endif
|
|
3598
|
+
#if HAVE_CURLOPT_UNIX_SOCKET_PATH
|
|
3599
|
+
case CURLOPT_UNIX_SOCKET_PATH: {
|
|
3600
|
+
curl_easy_setopt(rbce->curl, CURLOPT_UNIX_SOCKET_PATH, StringValueCStr(val));
|
|
3601
|
+
} break;
|
|
3602
|
+
#endif
|
|
3603
|
+
#if HAVE_CURLOPT_MAX_SEND_SPEED_LARGE
|
|
3604
|
+
case CURLOPT_MAX_SEND_SPEED_LARGE: {
|
|
3605
|
+
curl_easy_setopt(rbce->curl, CURLOPT_MAX_SEND_SPEED_LARGE, (curl_off_t) NUM2LL(val));
|
|
3606
|
+
} break;
|
|
3607
|
+
#endif
|
|
3608
|
+
#if HAVE_CURLOPT_MAX_RECV_SPEED_LARGE
|
|
3609
|
+
case CURLOPT_MAX_RECV_SPEED_LARGE: {
|
|
3610
|
+
curl_easy_setopt(rbce->curl, CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t) NUM2LL(val));
|
|
3611
|
+
} break;
|
|
3612
|
+
#endif
|
|
3613
|
+
#if HAVE_CURLOPT_MAXFILESIZE
|
|
3614
|
+
case CURLOPT_MAXFILESIZE:
|
|
3615
|
+
curl_easy_setopt(rbce->curl, CURLOPT_MAXFILESIZE, NUM2LONG(val));
|
|
3616
|
+
break;
|
|
3617
|
+
#endif
|
|
3618
|
+
#if HAVE_CURLOPT_TCP_KEEPALIVE
|
|
3619
|
+
case CURLOPT_TCP_KEEPALIVE:
|
|
3620
|
+
curl_easy_setopt(rbce->curl, CURLOPT_TCP_KEEPALIVE, NUM2LONG(val));
|
|
3621
|
+
break;
|
|
3622
|
+
case CURLOPT_TCP_KEEPIDLE:
|
|
3623
|
+
curl_easy_setopt(rbce->curl, CURLOPT_TCP_KEEPIDLE, NUM2LONG(val));
|
|
3624
|
+
break;
|
|
3625
|
+
case CURLOPT_TCP_KEEPINTVL:
|
|
3626
|
+
curl_easy_setopt(rbce->curl, CURLOPT_TCP_KEEPINTVL, NUM2LONG(val));
|
|
3627
|
+
break;
|
|
3628
|
+
#endif
|
|
3629
|
+
#if HAVE_CURLOPT_HAPROXYPROTOCOL
|
|
3630
|
+
case CURLOPT_HAPROXYPROTOCOL:
|
|
3631
|
+
curl_easy_setopt(rbce->curl, CURLOPT_HAPROXYPROTOCOL, NUM2LONG(val));
|
|
3632
|
+
break;
|
|
3633
|
+
#endif
|
|
3634
|
+
case CURLOPT_STDERR:
|
|
3635
|
+
// libcurl requires raw FILE pointer and this should be IO object in Ruby.
|
|
3636
|
+
// Tempfile or StringIO won't work.
|
|
3637
|
+
Check_Type(val, T_FILE);
|
|
3638
|
+
GetOpenFile(val, open_f_ptr);
|
|
3639
|
+
curl_easy_setopt(rbce->curl, CURLOPT_STDERR, rb_io_stdio_file(open_f_ptr));
|
|
3640
|
+
break;
|
|
3641
|
+
case CURLOPT_PROTOCOLS:
|
|
3642
|
+
case CURLOPT_REDIR_PROTOCOLS:
|
|
3643
|
+
curl_easy_setopt(rbce->curl, option, NUM2LONG(val));
|
|
3644
|
+
break;
|
|
3645
|
+
#if HAVE_CURLOPT_SSL_SESSIONID_CACHE
|
|
3646
|
+
case CURLOPT_SSL_SESSIONID_CACHE:
|
|
3647
|
+
curl_easy_setopt(rbce->curl, CURLOPT_SSL_SESSIONID_CACHE, NUM2LONG(val));
|
|
3648
|
+
break;
|
|
3649
|
+
#endif
|
|
3650
|
+
default:
|
|
3651
|
+
rb_raise(rb_eTypeError, "Curb unsupported option");
|
|
3652
|
+
}
|
|
3653
|
+
|
|
3654
|
+
return val;
|
|
3655
|
+
}
|
|
3656
|
+
|
|
3657
|
+
/*
|
|
3658
|
+
* call-seq:
|
|
3659
|
+
* easy.getinfo Fixnum => value
|
|
3660
|
+
*
|
|
3661
|
+
* Iniital access to libcurl curl_easy_getinfo, remember getinfo doesn't return the same values as setopt
|
|
3662
|
+
*/
|
|
3663
|
+
static VALUE ruby_curl_easy_get_opt(VALUE self, VALUE opt) {
|
|
3664
|
+
return Qnil;
|
|
3665
|
+
}
|
|
3666
|
+
|
|
3102
3667
|
/*
|
|
3103
3668
|
* call-seq:
|
|
3104
3669
|
* easy.inspect => "#<Curl::Easy http://google.com/>"
|
|
@@ -3113,7 +3678,7 @@ static VALUE ruby_curl_easy_inspect(VALUE self) {
|
|
|
3113
3678
|
size_t len = 13+((RSTRING_LEN(url) > 50) ? 50 : RSTRING_LEN(url));
|
|
3114
3679
|
/* "#<Net::HTTP http://www.google.com/:80 open=false>" */
|
|
3115
3680
|
memcpy(buf,"#<Curl::Easy ", 13);
|
|
3116
|
-
memcpy(buf+13,
|
|
3681
|
+
memcpy(buf+13,StringValueCStr(url), (len - 13));
|
|
3117
3682
|
buf[len++] = '>';
|
|
3118
3683
|
return rb_str_new(buf,len);
|
|
3119
3684
|
}
|
|
@@ -3174,7 +3739,7 @@ static VALUE ruby_curl_easy_unescape(VALUE self, VALUE str) {
|
|
|
3174
3739
|
#if (LIBCURL_VERSION_NUM >= 0x070f04)
|
|
3175
3740
|
result = (char*)curl_easy_unescape(rbce->curl, StringValuePtr(str), (int)RSTRING_LEN(str), &rlen);
|
|
3176
3741
|
#else
|
|
3177
|
-
result = (char*)curl_unescape(StringValuePtr(str), RSTRING_LEN(str));
|
|
3742
|
+
result = (char*)curl_unescape(StringValuePtr(str), (int)RSTRING_LEN(str));
|
|
3178
3743
|
rlen = strlen(result);
|
|
3179
3744
|
#endif
|
|
3180
3745
|
|
|
@@ -3189,114 +3754,14 @@ static VALUE ruby_curl_easy_unescape(VALUE self, VALUE str) {
|
|
|
3189
3754
|
|
|
3190
3755
|
/*
|
|
3191
3756
|
* call-seq:
|
|
3192
|
-
* Curl::Easy.
|
|
3193
|
-
*
|
|
3194
|
-
* Convenience method that creates a new Curl::Easy instance with
|
|
3195
|
-
* the specified URL and calls the general +perform+ method, before returning
|
|
3196
|
-
* the new instance. For HTTP URLs, this is equivalent to calling +http_get+.
|
|
3757
|
+
* Curl::Easy.error(code) => [ErrCode, String]
|
|
3197
3758
|
*
|
|
3198
|
-
*
|
|
3199
|
-
* the +http_get+ call.
|
|
3759
|
+
* translate an internal libcurl error to ruby error class
|
|
3200
3760
|
*/
|
|
3201
|
-
static VALUE
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
if (rb_block_given_p()) {
|
|
3205
|
-
rb_yield(c);
|
|
3206
|
-
}
|
|
3207
|
-
|
|
3208
|
-
ruby_curl_easy_perform(c);
|
|
3209
|
-
return c;
|
|
3761
|
+
static VALUE ruby_curl_easy_error_message(VALUE klass, VALUE code) {
|
|
3762
|
+
return rb_curl_easy_error(NUM2INT(code));
|
|
3210
3763
|
}
|
|
3211
3764
|
|
|
3212
|
-
/*
|
|
3213
|
-
* call-seq:
|
|
3214
|
-
* Curl::Easy.http_get(url) { |easy| ... } => #<Curl::Easy...>
|
|
3215
|
-
*
|
|
3216
|
-
* Convenience method that creates a new Curl::Easy instance with
|
|
3217
|
-
* the specified URL and calls +http_get+, before returning the new instance.
|
|
3218
|
-
*
|
|
3219
|
-
* If a block is supplied, the new instance will be yielded just prior to
|
|
3220
|
-
* the +http_get+ call.
|
|
3221
|
-
*/
|
|
3222
|
-
static VALUE ruby_curl_easy_class_perform_get(int argc, VALUE *argv, VALUE klass) {
|
|
3223
|
-
VALUE c = ruby_curl_easy_new(argc, argv, klass);
|
|
3224
|
-
|
|
3225
|
-
ruby_curl_easy_perform_get(c);
|
|
3226
|
-
return c;
|
|
3227
|
-
}
|
|
3228
|
-
|
|
3229
|
-
/*
|
|
3230
|
-
* call-seq:
|
|
3231
|
-
* Curl::Easy.http_delete(url) { |easy| ... } => #<Curl::Easy...>
|
|
3232
|
-
*
|
|
3233
|
-
* Convenience method that creates a new Curl::Easy instance with
|
|
3234
|
-
* the specified URL and calls +http_delete+, before returning the new instance.
|
|
3235
|
-
*
|
|
3236
|
-
* If a block is supplied, the new instance will be yielded just prior to
|
|
3237
|
-
* the +http_delete+ call.
|
|
3238
|
-
*/
|
|
3239
|
-
static VALUE ruby_curl_easy_class_perform_delete(int argc, VALUE *argv, VALUE klass) {
|
|
3240
|
-
VALUE c = ruby_curl_easy_new(argc, argv, klass);
|
|
3241
|
-
|
|
3242
|
-
ruby_curl_easy_perform_delete(c);
|
|
3243
|
-
return c;
|
|
3244
|
-
}
|
|
3245
|
-
|
|
3246
|
-
/*
|
|
3247
|
-
* call-seq:
|
|
3248
|
-
* Curl::Easy.http_head(url) { |easy| ... } => #<Curl::Easy...>
|
|
3249
|
-
*
|
|
3250
|
-
* Convenience method that creates a new Curl::Easy instance with
|
|
3251
|
-
* the specified URL and calls +http_head+, before returning the new instance.
|
|
3252
|
-
*
|
|
3253
|
-
* If a block is supplied, the new instance will be yielded just prior to
|
|
3254
|
-
* the +http_head+ call.
|
|
3255
|
-
*/
|
|
3256
|
-
static VALUE ruby_curl_easy_class_perform_head(int argc, VALUE *argv, VALUE klass) {
|
|
3257
|
-
VALUE c = ruby_curl_easy_new(argc, argv, klass);
|
|
3258
|
-
|
|
3259
|
-
ruby_curl_easy_perform_head(c);
|
|
3260
|
-
|
|
3261
|
-
return c;
|
|
3262
|
-
}
|
|
3263
|
-
|
|
3264
|
-
// TODO: add convenience method for http_post
|
|
3265
|
-
|
|
3266
|
-
/*
|
|
3267
|
-
* call-seq:
|
|
3268
|
-
* Curl::Easy.http_post(url, "some=urlencoded%20form%20data&and=so%20on") => true
|
|
3269
|
-
* Curl::Easy.http_post(url, "some=urlencoded%20form%20data", "and=so%20on", ...) => true
|
|
3270
|
-
* Curl::Easy.http_post(url, "some=urlencoded%20form%20data", Curl::PostField, "and=so%20on", ...) => true
|
|
3271
|
-
* Curl::Easy.http_post(url, Curl::PostField, Curl::PostField ..., Curl::PostField) => true
|
|
3272
|
-
*
|
|
3273
|
-
* POST the specified formdata to the currently configured URL using
|
|
3274
|
-
* the current options set for this Curl::Easy instance. This method
|
|
3275
|
-
* always returns true, or raises an exception (defined under
|
|
3276
|
-
* Curl::Err) on error.
|
|
3277
|
-
*
|
|
3278
|
-
* If you wish to use multipart form encoding, you'll need to supply a block
|
|
3279
|
-
* in order to set multipart_form_post true. See #http_post for more
|
|
3280
|
-
* information.
|
|
3281
|
-
*/
|
|
3282
|
-
static VALUE ruby_curl_easy_class_perform_post(int argc, VALUE *argv, VALUE klass) {
|
|
3283
|
-
VALUE url, fields;
|
|
3284
|
-
VALUE c;
|
|
3285
|
-
|
|
3286
|
-
rb_scan_args(argc, argv, "1*", &url, &fields);
|
|
3287
|
-
|
|
3288
|
-
c = ruby_curl_easy_new(1, &url, klass);
|
|
3289
|
-
|
|
3290
|
-
if (argc > 1) {
|
|
3291
|
-
ruby_curl_easy_perform_post(argc - 1, &argv[1], c);
|
|
3292
|
-
} else {
|
|
3293
|
-
ruby_curl_easy_perform_post(0, NULL, c);
|
|
3294
|
-
}
|
|
3295
|
-
|
|
3296
|
-
return c;
|
|
3297
|
-
}
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
3765
|
/* =================== INIT LIB =====================*/
|
|
3301
3766
|
void init_curb_easy() {
|
|
3302
3767
|
idCall = rb_intern("call");
|
|
@@ -3308,32 +3773,26 @@ void init_curb_easy() {
|
|
|
3308
3773
|
cCurlEasy = rb_define_class_under(mCurl, "Easy", rb_cObject);
|
|
3309
3774
|
|
|
3310
3775
|
/* Class methods */
|
|
3311
|
-
|
|
3312
|
-
rb_define_singleton_method(cCurlEasy, "
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
rb_define_singleton_method(cCurlEasy, "http_head", ruby_curl_easy_class_perform_head, -1);
|
|
3317
|
-
rb_define_singleton_method(cCurlEasy, "http_put", ruby_curl_easy_class_perform_put, 2);
|
|
3776
|
+
rb_define_alloc_func(cCurlEasy, ruby_curl_easy_allocate);
|
|
3777
|
+
rb_define_singleton_method(cCurlEasy, "error", ruby_curl_easy_error_message, 1);
|
|
3778
|
+
|
|
3779
|
+
/* Initialize method */
|
|
3780
|
+
rb_define_method(cCurlEasy, "initialize", ruby_curl_easy_initialize, -1);
|
|
3318
3781
|
|
|
3319
3782
|
/* Attributes for config next perform */
|
|
3320
|
-
rb_define_method(cCurlEasy, "url=", ruby_curl_easy_url_set, 1);
|
|
3321
3783
|
rb_define_method(cCurlEasy, "url", ruby_curl_easy_url_get, 0);
|
|
3322
|
-
rb_define_method(cCurlEasy, "proxy_url=", ruby_curl_easy_proxy_url_set, 1);
|
|
3323
3784
|
rb_define_method(cCurlEasy, "proxy_url", ruby_curl_easy_proxy_url_get, 0);
|
|
3785
|
+
|
|
3786
|
+
rb_define_method(cCurlEasy, "proxy_headers=", ruby_curl_easy_proxy_headers_set, 1);
|
|
3787
|
+
rb_define_method(cCurlEasy, "proxy_headers", ruby_curl_easy_proxy_headers_get, 0);
|
|
3788
|
+
|
|
3324
3789
|
rb_define_method(cCurlEasy, "headers=", ruby_curl_easy_headers_set, 1);
|
|
3325
3790
|
rb_define_method(cCurlEasy, "headers", ruby_curl_easy_headers_get, 0);
|
|
3326
|
-
rb_define_method(cCurlEasy, "interface=", ruby_curl_easy_interface_set, 1);
|
|
3327
3791
|
rb_define_method(cCurlEasy, "interface", ruby_curl_easy_interface_get, 0);
|
|
3328
|
-
rb_define_method(cCurlEasy, "userpwd=", ruby_curl_easy_userpwd_set, 1);
|
|
3329
3792
|
rb_define_method(cCurlEasy, "userpwd", ruby_curl_easy_userpwd_get, 0);
|
|
3330
|
-
rb_define_method(cCurlEasy, "proxypwd=", ruby_curl_easy_proxypwd_set, 1);
|
|
3331
3793
|
rb_define_method(cCurlEasy, "proxypwd", ruby_curl_easy_proxypwd_get, 0);
|
|
3332
|
-
rb_define_method(cCurlEasy, "cookies=", ruby_curl_easy_cookies_set, 1);
|
|
3333
3794
|
rb_define_method(cCurlEasy, "cookies", ruby_curl_easy_cookies_get, 0);
|
|
3334
|
-
rb_define_method(cCurlEasy, "cookiefile=", ruby_curl_easy_cookiefile_set, 1);
|
|
3335
3795
|
rb_define_method(cCurlEasy, "cookiefile", ruby_curl_easy_cookiefile_get, 0);
|
|
3336
|
-
rb_define_method(cCurlEasy, "cookiejar=", ruby_curl_easy_cookiejar_set, 1);
|
|
3337
3796
|
rb_define_method(cCurlEasy, "cookiejar", ruby_curl_easy_cookiejar_get, 0);
|
|
3338
3797
|
rb_define_method(cCurlEasy, "cert=", ruby_curl_easy_cert_set, 1);
|
|
3339
3798
|
rb_define_method(cCurlEasy, "cert", ruby_curl_easy_cert_get, 0);
|
|
@@ -3353,6 +3812,8 @@ void init_curb_easy() {
|
|
|
3353
3812
|
rb_define_method(cCurlEasy, "put_data=", ruby_curl_easy_put_data_set, 1);
|
|
3354
3813
|
rb_define_method(cCurlEasy, "ftp_commands=", ruby_curl_easy_ftp_commands_set, 1);
|
|
3355
3814
|
rb_define_method(cCurlEasy, "ftp_commands", ruby_curl_easy_ftp_commands_get, 0);
|
|
3815
|
+
rb_define_method(cCurlEasy, "resolve=", ruby_curl_easy_resolve_set, 1);
|
|
3816
|
+
rb_define_method(cCurlEasy, "resolve", ruby_curl_easy_resolve_get, 0);
|
|
3356
3817
|
|
|
3357
3818
|
rb_define_method(cCurlEasy, "local_port=", ruby_curl_easy_local_port_set, 1);
|
|
3358
3819
|
rb_define_method(cCurlEasy, "local_port", ruby_curl_easy_local_port_get, 0);
|
|
@@ -3370,8 +3831,12 @@ void init_curb_easy() {
|
|
|
3370
3831
|
rb_define_method(cCurlEasy, "max_redirects", ruby_curl_easy_max_redirects_get, 0);
|
|
3371
3832
|
rb_define_method(cCurlEasy, "timeout=", ruby_curl_easy_timeout_set, 1);
|
|
3372
3833
|
rb_define_method(cCurlEasy, "timeout", ruby_curl_easy_timeout_get, 0);
|
|
3834
|
+
rb_define_method(cCurlEasy, "timeout_ms=", ruby_curl_easy_timeout_ms_set, 1);
|
|
3835
|
+
rb_define_method(cCurlEasy, "timeout_ms", ruby_curl_easy_timeout_ms_get, 0);
|
|
3373
3836
|
rb_define_method(cCurlEasy, "connect_timeout=", ruby_curl_easy_connect_timeout_set, 1);
|
|
3374
3837
|
rb_define_method(cCurlEasy, "connect_timeout", ruby_curl_easy_connect_timeout_get, 0);
|
|
3838
|
+
rb_define_method(cCurlEasy, "connect_timeout_ms=", ruby_curl_easy_connect_timeout_ms_set, 1);
|
|
3839
|
+
rb_define_method(cCurlEasy, "connect_timeout_ms", ruby_curl_easy_connect_timeout_ms_get, 0);
|
|
3375
3840
|
rb_define_method(cCurlEasy, "dns_cache_timeout=", ruby_curl_easy_dns_cache_timeout_set, 1);
|
|
3376
3841
|
rb_define_method(cCurlEasy, "dns_cache_timeout", ruby_curl_easy_dns_cache_timeout_get, 0);
|
|
3377
3842
|
rb_define_method(cCurlEasy, "ftp_response_timeout=", ruby_curl_easy_ftp_response_timeout_set, 1);
|
|
@@ -3380,6 +3845,10 @@ void init_curb_easy() {
|
|
|
3380
3845
|
rb_define_method(cCurlEasy, "low_speed_limit", ruby_curl_easy_low_speed_limit_get, 0);
|
|
3381
3846
|
rb_define_method(cCurlEasy, "low_speed_time=", ruby_curl_easy_low_speed_time_set, 1);
|
|
3382
3847
|
rb_define_method(cCurlEasy, "low_speed_time", ruby_curl_easy_low_speed_time_get, 0);
|
|
3848
|
+
rb_define_method(cCurlEasy, "max_send_speed_large=", ruby_curl_easy_max_send_speed_large_set, 1);
|
|
3849
|
+
rb_define_method(cCurlEasy, "max_send_speed_large", ruby_curl_easy_max_send_speed_large_get, 0);
|
|
3850
|
+
rb_define_method(cCurlEasy, "max_recv_speed_large=", ruby_curl_easy_max_recv_speed_large_set, 1);
|
|
3851
|
+
rb_define_method(cCurlEasy, "max_recv_speed_large", ruby_curl_easy_max_recv_speed_large_get, 0);
|
|
3383
3852
|
rb_define_method(cCurlEasy, "ssl_version=", ruby_curl_easy_ssl_version_set, 1);
|
|
3384
3853
|
rb_define_method(cCurlEasy, "ssl_version", ruby_curl_easy_ssl_version_get, 0);
|
|
3385
3854
|
rb_define_method(cCurlEasy, "use_ssl=", ruby_curl_easy_use_ssl_set, 1);
|
|
@@ -3398,13 +3867,12 @@ void init_curb_easy() {
|
|
|
3398
3867
|
rb_define_method(cCurlEasy, "fetch_file_time?", ruby_curl_easy_fetch_file_time_q, 0);
|
|
3399
3868
|
rb_define_method(cCurlEasy, "ssl_verify_peer=", ruby_curl_easy_ssl_verify_peer_set, 1);
|
|
3400
3869
|
rb_define_method(cCurlEasy, "ssl_verify_peer?", ruby_curl_easy_ssl_verify_peer_q, 0);
|
|
3401
|
-
rb_define_method(cCurlEasy, "
|
|
3402
|
-
rb_define_method(cCurlEasy, "ssl_verify_host
|
|
3870
|
+
rb_define_method(cCurlEasy, "ssl_verify_host_integer=", ruby_curl_easy_ssl_verify_host_set, 1);
|
|
3871
|
+
rb_define_method(cCurlEasy, "ssl_verify_host", ruby_curl_easy_ssl_verify_host_get, 0);
|
|
3403
3872
|
rb_define_method(cCurlEasy, "header_in_body=", ruby_curl_easy_header_in_body_set, 1);
|
|
3404
3873
|
rb_define_method(cCurlEasy, "header_in_body?", ruby_curl_easy_header_in_body_q, 0);
|
|
3405
3874
|
rb_define_method(cCurlEasy, "use_netrc=", ruby_curl_easy_use_netrc_set, 1);
|
|
3406
3875
|
rb_define_method(cCurlEasy, "use_netrc?", ruby_curl_easy_use_netrc_q, 0);
|
|
3407
|
-
rb_define_method(cCurlEasy, "follow_location=", ruby_curl_easy_follow_location_set, 1);
|
|
3408
3876
|
rb_define_method(cCurlEasy, "follow_location?", ruby_curl_easy_follow_location_q, 0);
|
|
3409
3877
|
rb_define_method(cCurlEasy, "autoreferer=", ruby_curl_easy_autoreferer_set, 1);
|
|
3410
3878
|
rb_define_method(cCurlEasy, "unrestricted_auth=", ruby_curl_easy_unrestricted_auth_set, 1);
|
|
@@ -3417,6 +3885,8 @@ void init_curb_easy() {
|
|
|
3417
3885
|
rb_define_method(cCurlEasy, "enable_cookies?", ruby_curl_easy_enable_cookies_q, 0);
|
|
3418
3886
|
rb_define_method(cCurlEasy, "ignore_content_length=", ruby_curl_easy_ignore_content_length_set, 1);
|
|
3419
3887
|
rb_define_method(cCurlEasy, "ignore_content_length?", ruby_curl_easy_ignore_content_length_q, 0);
|
|
3888
|
+
rb_define_method(cCurlEasy, "resolve_mode", ruby_curl_easy_resolve_mode, 0);
|
|
3889
|
+
rb_define_method(cCurlEasy, "resolve_mode=", ruby_curl_easy_resolve_mode_set, 1);
|
|
3420
3890
|
|
|
3421
3891
|
rb_define_method(cCurlEasy, "on_body", ruby_curl_easy_on_body_set, -1);
|
|
3422
3892
|
rb_define_method(cCurlEasy, "on_header", ruby_curl_easy_on_header_set, -1);
|
|
@@ -3424,22 +3894,13 @@ void init_curb_easy() {
|
|
|
3424
3894
|
rb_define_method(cCurlEasy, "on_debug", ruby_curl_easy_on_debug_set, -1);
|
|
3425
3895
|
rb_define_method(cCurlEasy, "on_success", ruby_curl_easy_on_success_set, -1);
|
|
3426
3896
|
rb_define_method(cCurlEasy, "on_failure", ruby_curl_easy_on_failure_set, -1);
|
|
3897
|
+
rb_define_method(cCurlEasy, "on_missing", ruby_curl_easy_on_missing_set, -1);
|
|
3898
|
+
rb_define_method(cCurlEasy, "on_redirect", ruby_curl_easy_on_redirect_set, -1);
|
|
3427
3899
|
rb_define_method(cCurlEasy, "on_complete", ruby_curl_easy_on_complete_set, -1);
|
|
3428
3900
|
|
|
3429
|
-
rb_define_method(cCurlEasy, "perform", ruby_curl_easy_perform, 0);
|
|
3430
3901
|
rb_define_method(cCurlEasy, "http", ruby_curl_easy_perform_verb, 1);
|
|
3431
|
-
rb_define_method(cCurlEasy, "http_delete", ruby_curl_easy_perform_delete, 0);
|
|
3432
|
-
rb_define_method(cCurlEasy, "http_get", ruby_curl_easy_perform_get, 0);
|
|
3433
3902
|
rb_define_method(cCurlEasy, "http_post", ruby_curl_easy_perform_post, -1);
|
|
3434
|
-
rb_define_method(cCurlEasy, "http_head", ruby_curl_easy_perform_head, 0);
|
|
3435
3903
|
rb_define_method(cCurlEasy, "http_put", ruby_curl_easy_perform_put, 1);
|
|
3436
|
-
rb_define_method(cCurlEasy, "head=", ruby_curl_easy_set_head_option, 1);
|
|
3437
|
-
rb_define_method(cCurlEasy, "delete=", ruby_curl_easy_set_delete_option, 1);
|
|
3438
|
-
rb_define_method(cCurlEasy, "version=", ruby_curl_easy_set_version, 1);
|
|
3439
|
-
rb_define_const(mCurl, "HTTP_1_1", LONG2NUM(CURL_HTTP_VERSION_1_1));
|
|
3440
|
-
rb_define_const(mCurl, "HTTP_1_0", LONG2NUM(CURL_HTTP_VERSION_1_0));
|
|
3441
|
-
rb_define_const(mCurl, "HTTP_NONE", LONG2NUM(CURL_HTTP_VERSION_NONE));
|
|
3442
|
-
rb_define_method(cCurlEasy, "nosignal=", ruby_curl_easy_set_nosignal, 1);
|
|
3443
3904
|
|
|
3444
3905
|
/* Post-perform info methods */
|
|
3445
3906
|
rb_define_method(cCurlEasy, "body_str", ruby_curl_easy_body_str_get, 0);
|
|
@@ -3455,10 +3916,14 @@ void init_curb_easy() {
|
|
|
3455
3916
|
rb_define_method(cCurlEasy, "total_time", ruby_curl_easy_total_time_get, 0);
|
|
3456
3917
|
rb_define_method(cCurlEasy, "name_lookup_time", ruby_curl_easy_name_lookup_time_get, 0);
|
|
3457
3918
|
rb_define_method(cCurlEasy, "connect_time", ruby_curl_easy_connect_time_get, 0);
|
|
3919
|
+
#if defined(HAVE_CURLINFO_APPCONNECT_TIME)
|
|
3920
|
+
rb_define_method(cCurlEasy, "app_connect_time", ruby_curl_easy_app_connect_time_get, 0);
|
|
3921
|
+
#endif
|
|
3458
3922
|
rb_define_method(cCurlEasy, "pre_transfer_time", ruby_curl_easy_pre_transfer_time_get, 0);
|
|
3459
3923
|
rb_define_method(cCurlEasy, "start_transfer_time", ruby_curl_easy_start_transfer_time_get, 0);
|
|
3460
3924
|
rb_define_method(cCurlEasy, "redirect_time", ruby_curl_easy_redirect_time_get, 0);
|
|
3461
3925
|
rb_define_method(cCurlEasy, "redirect_count", ruby_curl_easy_redirect_count_get, 0);
|
|
3926
|
+
rb_define_method(cCurlEasy, "redirect_url", ruby_curl_easy_redirect_url_get, 0);
|
|
3462
3927
|
rb_define_method(cCurlEasy, "downloaded_bytes", ruby_curl_easy_downloaded_bytes_get, 0);
|
|
3463
3928
|
rb_define_method(cCurlEasy, "uploaded_bytes", ruby_curl_easy_uploaded_bytes_get, 0);
|
|
3464
3929
|
rb_define_method(cCurlEasy, "download_speed", ruby_curl_easy_download_speed_get, 0);
|
|
@@ -3471,6 +3936,7 @@ void init_curb_easy() {
|
|
|
3471
3936
|
rb_define_method(cCurlEasy, "content_type", ruby_curl_easy_content_type_get, 0);
|
|
3472
3937
|
rb_define_method(cCurlEasy, "os_errno", ruby_curl_easy_os_errno_get, 0);
|
|
3473
3938
|
rb_define_method(cCurlEasy, "num_connects", ruby_curl_easy_num_connects_get, 0);
|
|
3939
|
+
rb_define_method(cCurlEasy, "cookielist", ruby_curl_easy_cookielist_get, 0);
|
|
3474
3940
|
rb_define_method(cCurlEasy, "ftp_entry_path", ruby_curl_easy_ftp_entry_path_get, 0);
|
|
3475
3941
|
|
|
3476
3942
|
rb_define_method(cCurlEasy, "close", ruby_curl_easy_close, 0);
|
|
@@ -3484,4 +3950,12 @@ void init_curb_easy() {
|
|
|
3484
3950
|
rb_define_method(cCurlEasy, "clone", ruby_curl_easy_clone, 0);
|
|
3485
3951
|
rb_define_alias(cCurlEasy, "dup", "clone");
|
|
3486
3952
|
rb_define_method(cCurlEasy, "inspect", ruby_curl_easy_inspect, 0);
|
|
3953
|
+
|
|
3954
|
+
rb_define_method(cCurlEasy, "multi", ruby_curl_easy_multi_get, 0);
|
|
3955
|
+
rb_define_method(cCurlEasy, "multi=", ruby_curl_easy_multi_set, 1);
|
|
3956
|
+
rb_define_method(cCurlEasy, "last_result", ruby_curl_easy_last_result, 0);
|
|
3957
|
+
rb_define_method(cCurlEasy, "last_error", ruby_curl_easy_last_error, 0);
|
|
3958
|
+
|
|
3959
|
+
rb_define_method(cCurlEasy, "setopt", ruby_curl_easy_set_opt, 2);
|
|
3960
|
+
rb_define_method(cCurlEasy, "getinfo", ruby_curl_easy_get_opt, 1);
|
|
3487
3961
|
}
|