curb 1.2.2 → 1.3.2
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 +4 -4
- data/Rakefile +22 -0
- data/ext/curb.c +282 -231
- data/ext/curb.h +3 -3
- data/ext/curb_easy.c +766 -299
- data/ext/curb_easy.h +5 -0
- data/ext/curb_errors.c +5 -5
- data/ext/curb_errors.h +1 -1
- data/ext/curb_macros.h +14 -14
- data/ext/curb_multi.c +612 -142
- data/ext/curb_multi.h +3 -1
- data/ext/curb_postfield.c +48 -21
- data/ext/curb_postfield.h +1 -0
- data/ext/curb_upload.c +32 -9
- data/ext/curb_upload.h +2 -0
- data/ext/extconf.rb +42 -1
- data/lib/curl/easy.rb +154 -13
- data/lib/curl/multi.rb +69 -9
- data/lib/curl.rb +193 -0
- data/tests/helper.rb +222 -36
- data/tests/leak_trace.rb +237 -0
- data/tests/tc_curl_download.rb +6 -2
- data/tests/tc_curl_easy.rb +509 -1
- data/tests/tc_curl_multi.rb +573 -59
- data/tests/tc_curl_native_coverage.rb +145 -0
- data/tests/tc_curl_postfield.rb +176 -0
- data/tests/tc_fiber_scheduler.rb +342 -7
- data/tests/tc_gc_compact.rb +178 -16
- data/tests/tc_test_server_methods.rb +110 -0
- metadata +10 -14
- data/tests/test_basic.rb +0 -29
- data/tests/test_fiber_debug.rb +0 -69
- data/tests/test_fiber_simple.rb +0 -65
- data/tests/test_real_url.rb +0 -65
- data/tests/test_simple_fiber.rb +0 -34
data/ext/curb_easy.c
CHANGED
|
@@ -28,6 +28,14 @@ static VALUE rbstrAmp;
|
|
|
28
28
|
|
|
29
29
|
VALUE cCurlEasy;
|
|
30
30
|
|
|
31
|
+
/* Internal wrapper type for passing pointers through rb_iterate callbacks.
|
|
32
|
+
* No mark/free needed - these are temporary wrappers that don't own memory. */
|
|
33
|
+
static const rb_data_type_t curl_slist_ptr_type = {
|
|
34
|
+
"curl_slist_ptr_wrapper",
|
|
35
|
+
{ NULL, NULL, NULL },
|
|
36
|
+
NULL, NULL, 0
|
|
37
|
+
};
|
|
38
|
+
|
|
31
39
|
// for Ruby 1.8
|
|
32
40
|
#ifndef HAVE_RB_IO_STDIO_FILE
|
|
33
41
|
static FILE * rb_io_stdio_file(rb_io_t *fptr) {
|
|
@@ -35,6 +43,7 @@ static FILE * rb_io_stdio_file(rb_io_t *fptr) {
|
|
|
35
43
|
}
|
|
36
44
|
#endif
|
|
37
45
|
static struct curl_slist *duplicate_curl_slist(struct curl_slist *list);
|
|
46
|
+
static size_t proc_data_handler(char *stream, size_t size, size_t nmemb, VALUE proc);
|
|
38
47
|
|
|
39
48
|
/* ================== CURL HANDLER FUNCS ==============*/
|
|
40
49
|
|
|
@@ -42,6 +51,125 @@ static VALUE callback_exception(VALUE unused, VALUE exception) {
|
|
|
42
51
|
return Qfalse;
|
|
43
52
|
}
|
|
44
53
|
|
|
54
|
+
static VALUE callback_exception_store_on_easy(VALUE arg, VALUE exception) {
|
|
55
|
+
ruby_curl_easy *rbce = (ruby_curl_easy *)arg;
|
|
56
|
+
|
|
57
|
+
if (rbce && NIL_P(rbce->callback_error)) {
|
|
58
|
+
rbce->callback_error = exception;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return Qfalse;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
VALUE rb_curl_easy_take_callback_error(ruby_curl_easy *rbce) {
|
|
65
|
+
VALUE exception = Qnil;
|
|
66
|
+
|
|
67
|
+
if (!rbce) {
|
|
68
|
+
return Qnil;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
exception = rbce->callback_error;
|
|
72
|
+
rbce->callback_error = Qnil;
|
|
73
|
+
return exception;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static VALUE ruby_curl_easy_take_callback_error(VALUE self) {
|
|
77
|
+
ruby_curl_easy *rbce = NULL;
|
|
78
|
+
|
|
79
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
80
|
+
return rb_curl_easy_take_callback_error(rbce);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
static VALUE ensure_clear_easy_callback_active(VALUE arg) {
|
|
84
|
+
ruby_curl_easy *rbce = (ruby_curl_easy *)arg;
|
|
85
|
+
if (rbce) {
|
|
86
|
+
rbce->callback_active = 0;
|
|
87
|
+
}
|
|
88
|
+
return Qnil;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static VALUE with_easy_callback_active(ruby_curl_easy *rbce, VALUE (*func)(VALUE), VALUE arg) {
|
|
92
|
+
rbce->callback_active = 1;
|
|
93
|
+
return rb_ensure(func, arg, ensure_clear_easy_callback_active, (VALUE)rbce);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
struct stream_read_call_args {
|
|
97
|
+
VALUE stream;
|
|
98
|
+
size_t read_bytes;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
static VALUE call_stream_read(VALUE argp) {
|
|
102
|
+
struct stream_read_call_args *args = (struct stream_read_call_args *)argp;
|
|
103
|
+
return rb_funcall(args->stream, rb_intern("read"), 1, ULONG2NUM((unsigned long)args->read_bytes));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
static VALUE call_stream_to_s(VALUE stream) {
|
|
107
|
+
return rb_funcall(stream, rb_intern("to_s"), 0);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
static VALUE call_string_value(VALUE str) {
|
|
111
|
+
StringValue(str);
|
|
112
|
+
return str;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
struct stream_seek_call_args {
|
|
116
|
+
VALUE stream;
|
|
117
|
+
curl_off_t offset;
|
|
118
|
+
int origin;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
static VALUE call_stream_seek(VALUE argp) {
|
|
122
|
+
struct stream_seek_call_args *args = (struct stream_seek_call_args *)argp;
|
|
123
|
+
return rb_funcall(args->stream, rb_intern("seek"), 2, LL2NUM(args->offset), INT2NUM(args->origin));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
struct proc_data_call_args {
|
|
127
|
+
char *stream;
|
|
128
|
+
size_t size;
|
|
129
|
+
size_t nmemb;
|
|
130
|
+
VALUE proc;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
static VALUE call_proc_data_handler_wrapped(VALUE argp) {
|
|
134
|
+
struct proc_data_call_args *args = (struct proc_data_call_args *)argp;
|
|
135
|
+
return ULONG2NUM((unsigned long)proc_data_handler(args->stream, args->size, args->nmemb, args->proc));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
struct easy_callback_dispatch_args {
|
|
139
|
+
ruby_curl_easy *rbce;
|
|
140
|
+
VALUE (*func)(VALUE);
|
|
141
|
+
VALUE arg;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
static VALUE call_with_easy_callback_active(VALUE argp) {
|
|
145
|
+
struct easy_callback_dispatch_args *args = (struct easy_callback_dispatch_args *)argp;
|
|
146
|
+
return with_easy_callback_active(args->rbce, args->func, args->arg);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
static VALUE rescue_easy_callback(ruby_curl_easy *rbce, VALUE (*func)(VALUE), VALUE arg) {
|
|
150
|
+
struct easy_callback_dispatch_args dispatch_args;
|
|
151
|
+
dispatch_args.rbce = rbce;
|
|
152
|
+
dispatch_args.func = func;
|
|
153
|
+
dispatch_args.arg = arg;
|
|
154
|
+
return rb_rescue(call_with_easy_callback_active, (VALUE)&dispatch_args, callback_exception_store_on_easy, (VALUE)rbce);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
static size_t curl_read_abort_result(void) {
|
|
158
|
+
#ifdef CURL_READFUNC_ABORT
|
|
159
|
+
return CURL_READFUNC_ABORT;
|
|
160
|
+
#else
|
|
161
|
+
return 0;
|
|
162
|
+
#endif
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
static int curl_seek_fail_result(void) {
|
|
166
|
+
#ifdef CURL_SEEKFUNC_FAIL
|
|
167
|
+
return CURL_SEEKFUNC_FAIL;
|
|
168
|
+
#else
|
|
169
|
+
return 1;
|
|
170
|
+
#endif
|
|
171
|
+
}
|
|
172
|
+
|
|
45
173
|
/* Default body handler appends to easy.body_data buffer */
|
|
46
174
|
static size_t default_body_handler(char *stream,
|
|
47
175
|
size_t size,
|
|
@@ -79,14 +207,36 @@ static size_t read_data_handler(void *ptr,
|
|
|
79
207
|
ruby_curl_easy *rbce) {
|
|
80
208
|
VALUE upload = rb_easy_get("upload");
|
|
81
209
|
size_t read_bytes = (size*nmemb);
|
|
82
|
-
VALUE stream
|
|
210
|
+
VALUE stream;
|
|
211
|
+
|
|
212
|
+
if (NIL_P(upload)) {
|
|
213
|
+
return curl_read_abort_result();
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
stream = ruby_curl_upload_stream_get(upload);
|
|
83
217
|
|
|
84
218
|
if (rb_respond_to(stream, rb_intern("read"))) {//if (rb_respond_to(stream, rb_intern("to_s"))) {
|
|
85
219
|
/* copy read_bytes from stream into ptr */
|
|
86
|
-
|
|
220
|
+
struct stream_read_call_args args;
|
|
221
|
+
args.stream = stream;
|
|
222
|
+
args.read_bytes = read_bytes;
|
|
223
|
+
VALUE str = rescue_easy_callback(rbce, call_stream_read, (VALUE)&args);
|
|
87
224
|
if( str != Qnil ) {
|
|
88
|
-
|
|
89
|
-
|
|
225
|
+
size_t str_len;
|
|
226
|
+
|
|
227
|
+
str = rescue_easy_callback(rbce, call_string_value, str);
|
|
228
|
+
if (str == Qfalse || str == Qnil) {
|
|
229
|
+
return curl_read_abort_result();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
str_len = (size_t)RSTRING_LEN(str);
|
|
233
|
+
if (str_len > read_bytes) {
|
|
234
|
+
snprintf(rbce->err_buf, CURL_ERROR_SIZE, "read callback returned more data than requested");
|
|
235
|
+
return curl_read_abort_result();
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
memcpy(ptr, RSTRING_PTR(str), str_len);
|
|
239
|
+
return str_len;
|
|
90
240
|
}
|
|
91
241
|
else {
|
|
92
242
|
return 0;
|
|
@@ -98,9 +248,18 @@ static size_t read_data_handler(void *ptr,
|
|
|
98
248
|
size_t len;
|
|
99
249
|
size_t remaining;
|
|
100
250
|
char *str_ptr;
|
|
101
|
-
|
|
102
|
-
str =
|
|
251
|
+
TypedData_Get_Struct(upload, ruby_curl_upload, &ruby_curl_upload_data_type, rbcu);
|
|
252
|
+
str = rescue_easy_callback(rbce, call_stream_to_s, stream);
|
|
253
|
+
str = rescue_easy_callback(rbce, call_string_value, str);
|
|
254
|
+
if (str == Qfalse || str == Qnil) {
|
|
255
|
+
return curl_read_abort_result();
|
|
256
|
+
}
|
|
257
|
+
|
|
103
258
|
len = RSTRING_LEN(str);
|
|
259
|
+
if (rbcu->offset >= len) {
|
|
260
|
+
return 0;
|
|
261
|
+
}
|
|
262
|
+
|
|
104
263
|
remaining = len - rbcu->offset;
|
|
105
264
|
str_ptr = RSTRING_PTR(str);
|
|
106
265
|
|
|
@@ -128,13 +287,26 @@ int seek_data_handler(ruby_curl_easy *rbce,
|
|
|
128
287
|
int origin) {
|
|
129
288
|
|
|
130
289
|
VALUE upload = rb_easy_get("upload");
|
|
131
|
-
VALUE stream
|
|
290
|
+
VALUE stream;
|
|
291
|
+
|
|
292
|
+
if (NIL_P(upload)) {
|
|
293
|
+
return curl_seek_fail_result();
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
stream = ruby_curl_upload_stream_get(upload);
|
|
132
297
|
|
|
133
298
|
if (rb_respond_to(stream, rb_intern("seek"))) {
|
|
134
|
-
|
|
299
|
+
struct stream_seek_call_args args;
|
|
300
|
+
args.stream = stream;
|
|
301
|
+
args.offset = offset;
|
|
302
|
+
args.origin = origin;
|
|
303
|
+
rescue_easy_callback(rbce, call_stream_seek, (VALUE)&args);
|
|
304
|
+
if (!NIL_P(rbce->callback_error)) {
|
|
305
|
+
return curl_seek_fail_result();
|
|
306
|
+
}
|
|
135
307
|
} else {
|
|
136
308
|
ruby_curl_upload *rbcu;
|
|
137
|
-
|
|
309
|
+
TypedData_Get_Struct(upload, ruby_curl_upload, &ruby_curl_upload_data_type, rbcu);
|
|
138
310
|
// This OK because curl only uses SEEK_SET as per the documentation
|
|
139
311
|
rbcu->offset = offset;
|
|
140
312
|
}
|
|
@@ -166,22 +338,40 @@ static size_t proc_data_handler_body(char *stream,
|
|
|
166
338
|
size_t nmemb,
|
|
167
339
|
ruby_curl_easy *rbce)
|
|
168
340
|
{
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
341
|
+
struct proc_data_call_args args;
|
|
342
|
+
struct easy_callback_dispatch_args dispatch_args;
|
|
343
|
+
VALUE procret;
|
|
344
|
+
args.stream = stream;
|
|
345
|
+
args.size = size;
|
|
346
|
+
args.nmemb = nmemb;
|
|
347
|
+
args.proc = rb_easy_get("body_proc");
|
|
348
|
+
|
|
349
|
+
dispatch_args.rbce = rbce;
|
|
350
|
+
dispatch_args.func = call_proc_data_handler_wrapped;
|
|
351
|
+
dispatch_args.arg = (VALUE)&args;
|
|
352
|
+
procret = rb_rescue(call_with_easy_callback_active, (VALUE)&dispatch_args, callback_exception_store_on_easy, (VALUE)rbce);
|
|
353
|
+
|
|
354
|
+
return ((procret == Qfalse) || (procret == Qnil)) ? 0 : NUM2ULONG(procret);
|
|
174
355
|
}
|
|
175
356
|
static size_t proc_data_handler_header(char *stream,
|
|
176
357
|
size_t size,
|
|
177
358
|
size_t nmemb,
|
|
178
359
|
ruby_curl_easy *rbce)
|
|
179
360
|
{
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
361
|
+
struct proc_data_call_args args;
|
|
362
|
+
struct easy_callback_dispatch_args dispatch_args;
|
|
363
|
+
VALUE procret;
|
|
364
|
+
args.stream = stream;
|
|
365
|
+
args.size = size;
|
|
366
|
+
args.nmemb = nmemb;
|
|
367
|
+
args.proc = rb_easy_get("header_proc");
|
|
368
|
+
|
|
369
|
+
dispatch_args.rbce = rbce;
|
|
370
|
+
dispatch_args.func = call_proc_data_handler_wrapped;
|
|
371
|
+
dispatch_args.arg = (VALUE)&args;
|
|
372
|
+
procret = rb_rescue(call_with_easy_callback_active, (VALUE)&dispatch_args, callback_exception_store_on_easy, (VALUE)rbce);
|
|
373
|
+
|
|
374
|
+
return ((procret == Qfalse) || (procret == Qnil)) ? 0 : NUM2ULONG(procret);
|
|
185
375
|
}
|
|
186
376
|
|
|
187
377
|
|
|
@@ -193,6 +383,8 @@ static VALUE call_progress_handler(VALUE ary) {
|
|
|
193
383
|
rb_ary_entry(ary, 4)); // rb_float_new(ulnow));
|
|
194
384
|
}
|
|
195
385
|
|
|
386
|
+
/* CURLOPT_PROGRESSFUNCTION callback (deprecated since 7.32.0) */
|
|
387
|
+
#ifndef HAVE_CURLOPT_XFERINFOFUNCTION
|
|
196
388
|
static int proc_progress_handler(void *clientp,
|
|
197
389
|
double dltotal,
|
|
198
390
|
double dlnow,
|
|
@@ -212,15 +404,46 @@ static int proc_progress_handler(void *clientp,
|
|
|
212
404
|
rb_ary_store(callargs, 3, rb_float_new(ultotal));
|
|
213
405
|
rb_ary_store(callargs, 4, rb_float_new(ulnow));
|
|
214
406
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
procret = rb_rescue(call_progress_handler, callargs, callback_exception, Qnil);
|
|
407
|
+
struct easy_callback_dispatch_args dispatch_args;
|
|
408
|
+
dispatch_args.rbce = rbce;
|
|
409
|
+
dispatch_args.func = call_progress_handler;
|
|
410
|
+
dispatch_args.arg = callargs;
|
|
411
|
+
procret = rb_rescue(call_with_easy_callback_active, (VALUE)&dispatch_args, callback_exception, Qnil);
|
|
221
412
|
|
|
222
413
|
return(((procret == Qfalse) || (procret == Qnil)) ? -1 : 0);
|
|
223
414
|
}
|
|
415
|
+
#endif
|
|
416
|
+
|
|
417
|
+
/* CURLOPT_XFERINFOFUNCTION callback (since 7.32.0, replaces PROGRESSFUNCTION) */
|
|
418
|
+
#ifdef HAVE_CURLOPT_XFERINFOFUNCTION
|
|
419
|
+
static int proc_xferinfo_handler(void *clientp,
|
|
420
|
+
curl_off_t dltotal,
|
|
421
|
+
curl_off_t dlnow,
|
|
422
|
+
curl_off_t ultotal,
|
|
423
|
+
curl_off_t ulnow) {
|
|
424
|
+
ruby_curl_easy *rbce = (ruby_curl_easy *)clientp;
|
|
425
|
+
VALUE proc = rb_easy_get("progress_proc");
|
|
426
|
+
if (proc == Qnil) {
|
|
427
|
+
return 0;
|
|
428
|
+
}
|
|
429
|
+
VALUE procret;
|
|
430
|
+
VALUE callargs = rb_ary_new2(5);
|
|
431
|
+
|
|
432
|
+
rb_ary_store(callargs, 0, proc);
|
|
433
|
+
rb_ary_store(callargs, 1, LL2NUM(dltotal));
|
|
434
|
+
rb_ary_store(callargs, 2, LL2NUM(dlnow));
|
|
435
|
+
rb_ary_store(callargs, 3, LL2NUM(ultotal));
|
|
436
|
+
rb_ary_store(callargs, 4, LL2NUM(ulnow));
|
|
437
|
+
|
|
438
|
+
struct easy_callback_dispatch_args dispatch_args;
|
|
439
|
+
dispatch_args.rbce = rbce;
|
|
440
|
+
dispatch_args.func = call_progress_handler;
|
|
441
|
+
dispatch_args.arg = callargs;
|
|
442
|
+
procret = rb_rescue(call_with_easy_callback_active, (VALUE)&dispatch_args, callback_exception, Qnil);
|
|
443
|
+
|
|
444
|
+
return(((procret == Qfalse) || (procret == Qnil)) ? -1 : 0);
|
|
445
|
+
}
|
|
446
|
+
#endif
|
|
224
447
|
|
|
225
448
|
static VALUE call_debug_handler(VALUE ary) {
|
|
226
449
|
return rb_funcall(rb_ary_entry(ary, 0), idCall, 2,
|
|
@@ -241,7 +464,11 @@ static int proc_debug_handler(CURL *curl,
|
|
|
241
464
|
rb_ary_store(callargs, 0, proc);
|
|
242
465
|
rb_ary_store(callargs, 1, INT2NUM(type));
|
|
243
466
|
rb_ary_store(callargs, 2, rb_str_new(data, data_len));
|
|
244
|
-
|
|
467
|
+
struct easy_callback_dispatch_args dispatch_args;
|
|
468
|
+
dispatch_args.rbce = rbce;
|
|
469
|
+
dispatch_args.func = call_debug_handler;
|
|
470
|
+
dispatch_args.arg = callargs;
|
|
471
|
+
rb_rescue(call_with_easy_callback_active, (VALUE)&dispatch_args, callback_exception, Qnil);
|
|
245
472
|
/* no way to indicate to libcurl that we should break out given an exception in the on_debug handler...
|
|
246
473
|
* this means exceptions will be swallowed
|
|
247
474
|
*/
|
|
@@ -249,53 +476,121 @@ static int proc_debug_handler(CURL *curl,
|
|
|
249
476
|
return 0;
|
|
250
477
|
}
|
|
251
478
|
|
|
252
|
-
/* ================== MARK/FREE
|
|
253
|
-
void curl_easy_mark(
|
|
254
|
-
|
|
255
|
-
if (
|
|
479
|
+
/* ================== MARK/FREE/SIZE FUNCS ==================*/
|
|
480
|
+
static void curl_easy_mark(void *ptr) {
|
|
481
|
+
ruby_curl_easy *rbce = (ruby_curl_easy *)ptr;
|
|
482
|
+
if (rbce) {
|
|
483
|
+
if (!NIL_P(rbce->opts)) { rb_gc_mark(rbce->opts); }
|
|
484
|
+
if (!NIL_P(rbce->multi)) { rb_gc_mark(rbce->multi); }
|
|
485
|
+
if (!NIL_P(rbce->callback_error)) { rb_gc_mark(rbce->callback_error); }
|
|
486
|
+
}
|
|
256
487
|
}
|
|
257
488
|
|
|
258
|
-
static void
|
|
259
|
-
if (!rbce) {
|
|
489
|
+
static void ruby_curl_easy_clear_headers_list(ruby_curl_easy *rbce) {
|
|
490
|
+
if (!rbce || !rbce->curl_headers) {
|
|
260
491
|
return;
|
|
261
492
|
}
|
|
493
|
+
if (rbce->curl) {
|
|
494
|
+
curl_easy_setopt(rbce->curl, CURLOPT_HTTPHEADER, NULL);
|
|
495
|
+
}
|
|
496
|
+
curl_slist_free_all(rbce->curl_headers);
|
|
497
|
+
rbce->curl_headers = NULL;
|
|
498
|
+
}
|
|
262
499
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
500
|
+
static void ruby_curl_easy_clear_proxy_headers_list(ruby_curl_easy *rbce) {
|
|
501
|
+
if (!rbce || !rbce->curl_proxy_headers) {
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
#ifdef HAVE_CURLOPT_PROXYHEADER
|
|
505
|
+
if (rbce->curl) {
|
|
506
|
+
curl_easy_setopt(rbce->curl, CURLOPT_PROXYHEADER, NULL);
|
|
507
|
+
}
|
|
508
|
+
#endif
|
|
509
|
+
curl_slist_free_all(rbce->curl_proxy_headers);
|
|
510
|
+
rbce->curl_proxy_headers = NULL;
|
|
511
|
+
}
|
|
266
512
|
|
|
267
|
-
|
|
513
|
+
static void ruby_curl_easy_clear_ftp_commands_list(ruby_curl_easy *rbce) {
|
|
514
|
+
if (!rbce || !rbce->curl_ftp_commands) {
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
if (rbce->curl) {
|
|
518
|
+
curl_easy_setopt(rbce->curl, CURLOPT_QUOTE, NULL);
|
|
519
|
+
}
|
|
520
|
+
curl_slist_free_all(rbce->curl_ftp_commands);
|
|
521
|
+
rbce->curl_ftp_commands = NULL;
|
|
522
|
+
}
|
|
268
523
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
/* Best-effort: ensure the handle is detached from the multi to
|
|
273
|
-
* avoid libcurl retaining a dangling pointer to a soon-to-be
|
|
274
|
-
* cleaned-up easy handle. We cannot raise from GC, so ignore errors. */
|
|
275
|
-
if (rbcm->handle && rbce->curl) {
|
|
276
|
-
curl_multi_remove_handle(rbcm->handle, rbce->curl);
|
|
277
|
-
}
|
|
278
|
-
rb_curl_multi_forget_easy(rbcm, rbce);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
524
|
+
static void ruby_curl_easy_clear_resolve_list(ruby_curl_easy *rbce) {
|
|
525
|
+
if (!rbce || !rbce->curl_resolve) {
|
|
526
|
+
return;
|
|
281
527
|
}
|
|
528
|
+
#ifdef HAVE_CURLOPT_RESOLVE
|
|
529
|
+
if (rbce->curl) {
|
|
530
|
+
curl_easy_setopt(rbce->curl, CURLOPT_RESOLVE, NULL);
|
|
531
|
+
}
|
|
532
|
+
#endif
|
|
533
|
+
curl_slist_free_all(rbce->curl_resolve);
|
|
534
|
+
rbce->curl_resolve = NULL;
|
|
535
|
+
}
|
|
282
536
|
|
|
283
|
-
|
|
284
|
-
|
|
537
|
+
/* Legacy wrapper for external callers */
|
|
538
|
+
void ruby_curl_easy_mark(ruby_curl_easy *rbce) {
|
|
539
|
+
curl_easy_mark((void *)rbce);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
static ruby_curl_multi *ruby_curl_multi_pointer_if_compatible(VALUE multi_val) {
|
|
543
|
+
if (NIL_P(multi_val) || !RB_TYPE_P(multi_val, T_DATA)) {
|
|
544
|
+
return NULL;
|
|
285
545
|
}
|
|
286
546
|
|
|
287
|
-
|
|
288
|
-
|
|
547
|
+
#if defined(RTYPEDDATA_P) && defined(RTYPEDDATA_TYPE) && defined(RTYPEDDATA_DATA)
|
|
548
|
+
if (!RTYPEDDATA_P(multi_val)) {
|
|
549
|
+
return NULL;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
if (RTYPEDDATA_TYPE(multi_val) != &ruby_curl_multi_data_type) {
|
|
553
|
+
return NULL;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
return (ruby_curl_multi *)RTYPEDDATA_DATA(multi_val);
|
|
557
|
+
#else
|
|
558
|
+
if (!rb_typeddata_is_kind_of(multi_val, &ruby_curl_multi_data_type)) {
|
|
559
|
+
return NULL;
|
|
289
560
|
}
|
|
290
561
|
|
|
291
|
-
|
|
292
|
-
|
|
562
|
+
return DATA_PTR(multi_val);
|
|
563
|
+
#endif
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
static void ruby_curl_easy_free(ruby_curl_easy *rbce) {
|
|
567
|
+
if (!rbce) {
|
|
568
|
+
return;
|
|
293
569
|
}
|
|
294
570
|
|
|
295
|
-
if (rbce->
|
|
296
|
-
|
|
571
|
+
if (!NIL_P(rbce->multi)) {
|
|
572
|
+
VALUE multi_val = rbce->multi;
|
|
573
|
+
ruby_curl_multi *rbcm = ruby_curl_multi_pointer_if_compatible(multi_val);
|
|
574
|
+
|
|
575
|
+
rbce->multi = Qnil;
|
|
576
|
+
|
|
577
|
+
if (rbcm) {
|
|
578
|
+
/* Best-effort: ensure the handle is detached from the multi to avoid
|
|
579
|
+
* libcurl retaining a dangling pointer to a soon-to-be cleaned-up easy
|
|
580
|
+
* handle. This path runs during GC, so it must not invoke Ruby APIs that
|
|
581
|
+
* can allocate or raise. */
|
|
582
|
+
if (rbcm->handle && rbce->curl) {
|
|
583
|
+
curl_multi_remove_handle(rbcm->handle, rbce->curl);
|
|
584
|
+
}
|
|
585
|
+
rb_curl_multi_forget_easy(rbcm, rbce);
|
|
586
|
+
}
|
|
297
587
|
}
|
|
298
588
|
|
|
589
|
+
ruby_curl_easy_clear_headers_list(rbce);
|
|
590
|
+
ruby_curl_easy_clear_proxy_headers_list(rbce);
|
|
591
|
+
ruby_curl_easy_clear_ftp_commands_list(rbce);
|
|
592
|
+
ruby_curl_easy_clear_resolve_list(rbce);
|
|
593
|
+
|
|
299
594
|
if (rbce->curl) {
|
|
300
595
|
/* disable any progress or debug events */
|
|
301
596
|
curl_easy_setopt(rbce->curl, CURLOPT_WRITEFUNCTION, NULL);
|
|
@@ -305,7 +600,11 @@ static void ruby_curl_easy_free(ruby_curl_easy *rbce) {
|
|
|
305
600
|
curl_easy_setopt(rbce->curl, CURLOPT_DEBUGFUNCTION, NULL);
|
|
306
601
|
curl_easy_setopt(rbce->curl, CURLOPT_DEBUGDATA, NULL);
|
|
307
602
|
curl_easy_setopt(rbce->curl, CURLOPT_VERBOSE, 0);
|
|
603
|
+
#ifdef HAVE_CURLOPT_XFERINFOFUNCTION
|
|
604
|
+
curl_easy_setopt(rbce->curl, CURLOPT_XFERINFOFUNCTION, NULL);
|
|
605
|
+
#else
|
|
308
606
|
curl_easy_setopt(rbce->curl, CURLOPT_PROGRESSFUNCTION, NULL);
|
|
607
|
+
#endif
|
|
309
608
|
curl_easy_setopt(rbce->curl, CURLOPT_NOPROGRESS, 1);
|
|
310
609
|
curl_easy_cleanup(rbce->curl);
|
|
311
610
|
rbce->curl = NULL;
|
|
@@ -314,11 +613,45 @@ static void ruby_curl_easy_free(ruby_curl_easy *rbce) {
|
|
|
314
613
|
rbce->self = Qnil;
|
|
315
614
|
}
|
|
316
615
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
616
|
+
/* TypedData-compatible free function */
|
|
617
|
+
static void curl_easy_free(void *ptr) {
|
|
618
|
+
ruby_curl_easy *rbce = (ruby_curl_easy *)ptr;
|
|
619
|
+
if (rbce) {
|
|
620
|
+
ruby_curl_easy_free(rbce);
|
|
621
|
+
free(rbce);
|
|
622
|
+
}
|
|
320
623
|
}
|
|
321
624
|
|
|
625
|
+
/* Legacy wrapper for external callers (e.g., curb_multi) */
|
|
626
|
+
void ruby_curl_easy_free_wrapper(ruby_curl_easy *rbce) {
|
|
627
|
+
curl_easy_free((void *)rbce);
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
static size_t curl_easy_memsize(const void *ptr) {
|
|
631
|
+
const ruby_curl_easy *rbce = (const ruby_curl_easy *)ptr;
|
|
632
|
+
size_t size = sizeof(ruby_curl_easy);
|
|
633
|
+
/* Note: We don't count curl_slist or CURL handle memory as they're
|
|
634
|
+
* managed by libcurl and would require complex introspection */
|
|
635
|
+
(void)rbce; /* silence unused warning */
|
|
636
|
+
return size;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
const rb_data_type_t ruby_curl_easy_data_type = {
|
|
640
|
+
"Curl::Easy",
|
|
641
|
+
{
|
|
642
|
+
curl_easy_mark,
|
|
643
|
+
curl_easy_free,
|
|
644
|
+
curl_easy_memsize,
|
|
645
|
+
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
|
646
|
+
NULL, /* compact - not needed */
|
|
647
|
+
#endif
|
|
648
|
+
},
|
|
649
|
+
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
|
650
|
+
NULL, NULL, /* parent, data */
|
|
651
|
+
RUBY_TYPED_FREE_IMMEDIATELY
|
|
652
|
+
#endif
|
|
653
|
+
};
|
|
654
|
+
|
|
322
655
|
|
|
323
656
|
/* ================= ALLOC METHODS ====================*/
|
|
324
657
|
|
|
@@ -354,6 +687,7 @@ static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
|
|
354
687
|
rbce->ssl_version = -1;
|
|
355
688
|
rbce->use_ssl = -1;
|
|
356
689
|
rbce->ftp_filemethod = -1;
|
|
690
|
+
rbce->http_version = CURL_HTTP_VERSION_NONE;
|
|
357
691
|
rbce->resolve_mode = CURL_IPRESOLVE_WHATEVER;
|
|
358
692
|
|
|
359
693
|
/* bool opts */
|
|
@@ -371,6 +705,7 @@ static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
|
|
371
705
|
rbce->cookielist_engine_enabled = 0;
|
|
372
706
|
rbce->ignore_content_length = 0;
|
|
373
707
|
rbce->callback_active = 0;
|
|
708
|
+
rbce->callback_error = Qnil;
|
|
374
709
|
rbce->last_result = 0;
|
|
375
710
|
}
|
|
376
711
|
|
|
@@ -387,7 +722,7 @@ static VALUE ruby_curl_easy_allocate(VALUE klass) {
|
|
|
387
722
|
rbce->opts = Qnil;
|
|
388
723
|
rbce->multi = Qnil;
|
|
389
724
|
ruby_curl_easy_zero(rbce);
|
|
390
|
-
return
|
|
725
|
+
return TypedData_Wrap_Struct(klass, &ruby_curl_easy_data_type, rbce);
|
|
391
726
|
}
|
|
392
727
|
|
|
393
728
|
/*
|
|
@@ -407,7 +742,7 @@ static VALUE ruby_curl_easy_initialize(int argc, VALUE *argv, VALUE self) {
|
|
|
407
742
|
|
|
408
743
|
rb_scan_args(argc, argv, "01&", &url, &blk);
|
|
409
744
|
|
|
410
|
-
|
|
745
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
411
746
|
|
|
412
747
|
/* handler */
|
|
413
748
|
rbce->curl = curl_easy_init();
|
|
@@ -454,6 +789,24 @@ static struct curl_slist *duplicate_curl_slist(struct curl_slist *list) {
|
|
|
454
789
|
return dup;
|
|
455
790
|
}
|
|
456
791
|
|
|
792
|
+
static VALUE duplicate_upload(VALUE upload) {
|
|
793
|
+
ruby_curl_upload *rbcu, *newrbcu;
|
|
794
|
+
VALUE new_upload;
|
|
795
|
+
|
|
796
|
+
if (NIL_P(upload)) {
|
|
797
|
+
return Qnil;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
TypedData_Get_Struct(upload, ruby_curl_upload, &ruby_curl_upload_data_type, rbcu);
|
|
801
|
+
|
|
802
|
+
new_upload = ruby_curl_upload_new(cCurlUpload);
|
|
803
|
+
TypedData_Get_Struct(new_upload, ruby_curl_upload, &ruby_curl_upload_data_type, newrbcu);
|
|
804
|
+
newrbcu->stream = rbcu->stream;
|
|
805
|
+
newrbcu->offset = rbcu->offset;
|
|
806
|
+
|
|
807
|
+
return new_upload;
|
|
808
|
+
}
|
|
809
|
+
|
|
457
810
|
/*
|
|
458
811
|
* call-seq:
|
|
459
812
|
* easy.clone => <easy clone>
|
|
@@ -465,7 +818,7 @@ static struct curl_slist *duplicate_curl_slist(struct curl_slist *list) {
|
|
|
465
818
|
static VALUE ruby_curl_easy_clone(VALUE self) {
|
|
466
819
|
ruby_curl_easy *rbce, *newrbce;
|
|
467
820
|
|
|
468
|
-
|
|
821
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
469
822
|
|
|
470
823
|
newrbce = ALLOC(ruby_curl_easy);
|
|
471
824
|
if (!newrbce) {
|
|
@@ -483,6 +836,7 @@ static VALUE ruby_curl_easy_clone(VALUE self) {
|
|
|
483
836
|
|
|
484
837
|
/* A cloned easy should not retain ownership reference to the original multi. */
|
|
485
838
|
newrbce->multi = Qnil;
|
|
839
|
+
newrbce->callback_error = Qnil;
|
|
486
840
|
|
|
487
841
|
if (rbce->opts != Qnil) {
|
|
488
842
|
newrbce->opts = rb_funcall(rbce->opts, rb_intern("dup"), 0);
|
|
@@ -491,7 +845,22 @@ static VALUE ruby_curl_easy_clone(VALUE self) {
|
|
|
491
845
|
/* Set the error buffer on the new curl handle using the new err_buf */
|
|
492
846
|
curl_easy_setopt(newrbce->curl, CURLOPT_ERRORBUFFER, newrbce->err_buf);
|
|
493
847
|
|
|
494
|
-
|
|
848
|
+
if (newrbce->opts != Qnil) {
|
|
849
|
+
VALUE upload = rb_hash_aref(newrbce->opts, rb_easy_hkey("upload"));
|
|
850
|
+
if (!NIL_P(upload)) {
|
|
851
|
+
rb_hash_aset(newrbce->opts, rb_easy_hkey("upload"), duplicate_upload(upload));
|
|
852
|
+
curl_easy_setopt(newrbce->curl, CURLOPT_READFUNCTION, (curl_read_callback)read_data_handler);
|
|
853
|
+
curl_easy_setopt(newrbce->curl, CURLOPT_READDATA, newrbce);
|
|
854
|
+
#ifdef HAVE_CURLOPT_SEEKFUNCTION
|
|
855
|
+
curl_easy_setopt(newrbce->curl, CURLOPT_SEEKFUNCTION, (curl_seek_callback)seek_data_handler);
|
|
856
|
+
#endif
|
|
857
|
+
#ifdef HAVE_CURLOPT_SEEKDATA
|
|
858
|
+
curl_easy_setopt(newrbce->curl, CURLOPT_SEEKDATA, newrbce);
|
|
859
|
+
#endif
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
VALUE clone = TypedData_Wrap_Struct(cCurlEasy, &ruby_curl_easy_data_type, newrbce);
|
|
495
864
|
newrbce->self = clone;
|
|
496
865
|
curl_easy_setopt(newrbce->curl, CURLOPT_PRIVATE, (void*)newrbce);
|
|
497
866
|
|
|
@@ -510,7 +879,7 @@ static VALUE ruby_curl_easy_close(VALUE self) {
|
|
|
510
879
|
CURLcode ecode;
|
|
511
880
|
ruby_curl_easy *rbce;
|
|
512
881
|
|
|
513
|
-
|
|
882
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
514
883
|
|
|
515
884
|
if (rbce->callback_active) {
|
|
516
885
|
rb_raise(rb_eRuntimeError, "Cannot close an active curl handle within a callback");
|
|
@@ -529,6 +898,8 @@ static VALUE ruby_curl_easy_close(VALUE self) {
|
|
|
529
898
|
ruby_curl_easy_zero(rbce);
|
|
530
899
|
rbce->self = self;
|
|
531
900
|
|
|
901
|
+
curl_easy_setopt(rbce->curl, CURLOPT_ERRORBUFFER, rbce->err_buf);
|
|
902
|
+
|
|
532
903
|
/* give the new curl handle a reference back to the ruby object */
|
|
533
904
|
ecode = curl_easy_setopt(rbce->curl, CURLOPT_PRIVATE, (void*)rbce);
|
|
534
905
|
if (ecode != CURLE_OK) {
|
|
@@ -554,7 +925,7 @@ static VALUE ruby_curl_easy_reset(VALUE self) {
|
|
|
554
925
|
CURLcode ecode;
|
|
555
926
|
ruby_curl_easy *rbce;
|
|
556
927
|
VALUE opts_dup;
|
|
557
|
-
|
|
928
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
558
929
|
|
|
559
930
|
if (rbce->callback_active) {
|
|
560
931
|
rb_raise(rb_eRuntimeError, "Cannot close an active curl handle within a callback");
|
|
@@ -562,6 +933,7 @@ static VALUE ruby_curl_easy_reset(VALUE self) {
|
|
|
562
933
|
|
|
563
934
|
opts_dup = rb_funcall(rbce->opts, rb_intern("dup"), 0);
|
|
564
935
|
|
|
936
|
+
ruby_curl_easy_cleanup(self, rbce);
|
|
565
937
|
curl_easy_reset(rbce->curl);
|
|
566
938
|
ruby_curl_easy_zero(rbce);
|
|
567
939
|
rbce->self = self;
|
|
@@ -574,18 +946,6 @@ static VALUE ruby_curl_easy_reset(VALUE self) {
|
|
|
574
946
|
raise_curl_easy_error_exception(ecode);
|
|
575
947
|
}
|
|
576
948
|
|
|
577
|
-
/* Free everything up */
|
|
578
|
-
if (rbce->curl_headers) {
|
|
579
|
-
curl_slist_free_all(rbce->curl_headers);
|
|
580
|
-
rbce->curl_headers = NULL;
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
/* Free everything up */
|
|
584
|
-
if (rbce->curl_proxy_headers) {
|
|
585
|
-
curl_slist_free_all(rbce->curl_proxy_headers);
|
|
586
|
-
rbce->curl_proxy_headers = NULL;
|
|
587
|
-
}
|
|
588
|
-
|
|
589
949
|
return opts_dup;
|
|
590
950
|
}
|
|
591
951
|
|
|
@@ -651,7 +1011,7 @@ static VALUE ruby_curl_easy_proxy_headers_set(VALUE self, VALUE proxy_headers) {
|
|
|
651
1011
|
static VALUE ruby_curl_easy_headers_get(VALUE self) {
|
|
652
1012
|
ruby_curl_easy *rbce;
|
|
653
1013
|
VALUE headers;
|
|
654
|
-
|
|
1014
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
655
1015
|
headers = rb_easy_get("headers");//rb_hash_aref(rbce->opts, rb_intern("headers"));
|
|
656
1016
|
if (headers == Qnil) { headers = rb_easy_set("headers", rb_hash_new()); }
|
|
657
1017
|
return headers;
|
|
@@ -686,7 +1046,7 @@ static VALUE ruby_curl_easy_headers_get(VALUE self) {
|
|
|
686
1046
|
static VALUE ruby_curl_easy_proxy_headers_get(VALUE self) {
|
|
687
1047
|
ruby_curl_easy *rbce;
|
|
688
1048
|
VALUE proxy_headers;
|
|
689
|
-
|
|
1049
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
690
1050
|
proxy_headers = rb_easy_get("proxy_headers");//rb_hash_aref(rbce->opts, rb_intern("proxy_headers"));
|
|
691
1051
|
if (proxy_headers == Qnil) { proxy_headers = rb_easy_set("proxy_headers", rb_hash_new()); }
|
|
692
1052
|
return proxy_headers;
|
|
@@ -917,43 +1277,63 @@ static VALUE ruby_curl_easy_useragent_get(VALUE self) {
|
|
|
917
1277
|
*
|
|
918
1278
|
* This is handy if you want to perform a POST against a Curl::Multi instance.
|
|
919
1279
|
*/
|
|
920
|
-
static VALUE
|
|
1280
|
+
static VALUE ruby_curl_easy_post_body_set_with_mode(VALUE self, VALUE post_body, int force_http_get_on_nil) {
|
|
921
1281
|
ruby_curl_easy *rbce;
|
|
922
1282
|
CURL *curl;
|
|
923
1283
|
|
|
1284
|
+
VALUE body_str;
|
|
1285
|
+
VALUE retained_body_str;
|
|
924
1286
|
char *data;
|
|
925
1287
|
long len;
|
|
926
1288
|
|
|
927
|
-
|
|
1289
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
928
1290
|
|
|
929
1291
|
curl = rbce->curl;
|
|
930
1292
|
|
|
931
1293
|
if ( post_body == Qnil ) {
|
|
932
1294
|
rb_easy_del("postdata_buffer");
|
|
933
|
-
curl_easy_setopt(curl,
|
|
1295
|
+
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, NULL);
|
|
1296
|
+
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 0);
|
|
1297
|
+
if (force_http_get_on_nil) {
|
|
1298
|
+
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
|
|
1299
|
+
}
|
|
934
1300
|
|
|
935
1301
|
} else {
|
|
936
1302
|
if (rb_type(post_body) == T_STRING) {
|
|
937
|
-
|
|
938
|
-
len = RSTRING_LEN(post_body);
|
|
1303
|
+
body_str = post_body;
|
|
939
1304
|
}
|
|
940
1305
|
else if (rb_respond_to(post_body, rb_intern("to_s"))) {
|
|
941
|
-
|
|
942
|
-
data = StringValuePtr(str_body);
|
|
943
|
-
len = RSTRING_LEN(post_body);
|
|
1306
|
+
body_str = rb_funcall(post_body, rb_intern("to_s"), 0);
|
|
944
1307
|
}
|
|
945
1308
|
else {
|
|
946
1309
|
rb_raise(rb_eRuntimeError, "post data must respond_to .to_s");
|
|
947
1310
|
}
|
|
948
1311
|
|
|
1312
|
+
StringValue(body_str);
|
|
1313
|
+
|
|
949
1314
|
// Store the string, since it has to hang around for the duration of the
|
|
950
1315
|
// request. See CURLOPT_POSTFIELDS in the libcurl docs.
|
|
951
|
-
|
|
952
|
-
|
|
1316
|
+
#ifdef HAVE_CURLOPT_COPYPOSTFIELDS
|
|
1317
|
+
/*
|
|
1318
|
+
* libcurl copies the bytes immediately for COPYPOSTFIELDS, so retain a
|
|
1319
|
+
* matching Ruby snapshot for post_body instead of the caller's mutable
|
|
1320
|
+
* source string.
|
|
1321
|
+
*/
|
|
1322
|
+
retained_body_str = rb_str_dup(body_str);
|
|
1323
|
+
#else
|
|
1324
|
+
retained_body_str = body_str;
|
|
1325
|
+
#endif
|
|
1326
|
+
data = StringValuePtr(retained_body_str);
|
|
1327
|
+
len = RSTRING_LEN(retained_body_str);
|
|
1328
|
+
rb_easy_set("postdata_buffer", retained_body_str);
|
|
953
1329
|
|
|
954
1330
|
curl_easy_setopt(curl, CURLOPT_POST, 1);
|
|
955
|
-
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
|
|
956
1331
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
|
|
1332
|
+
#ifdef HAVE_CURLOPT_COPYPOSTFIELDS
|
|
1333
|
+
curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, data);
|
|
1334
|
+
#else
|
|
1335
|
+
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
|
|
1336
|
+
#endif
|
|
957
1337
|
|
|
958
1338
|
return post_body;
|
|
959
1339
|
}
|
|
@@ -961,6 +1341,10 @@ static VALUE ruby_curl_easy_post_body_set(VALUE self, VALUE post_body) {
|
|
|
961
1341
|
return Qnil;
|
|
962
1342
|
}
|
|
963
1343
|
|
|
1344
|
+
static VALUE ruby_curl_easy_post_body_set(VALUE self, VALUE post_body) {
|
|
1345
|
+
return ruby_curl_easy_post_body_set_with_mode(self, post_body, 1);
|
|
1346
|
+
}
|
|
1347
|
+
|
|
964
1348
|
/*
|
|
965
1349
|
* call-seq:
|
|
966
1350
|
* easy.post_body => string or nil
|
|
@@ -985,7 +1369,7 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
|
|
|
985
1369
|
VALUE upload;
|
|
986
1370
|
VALUE headers;
|
|
987
1371
|
|
|
988
|
-
|
|
1372
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
989
1373
|
|
|
990
1374
|
upload = ruby_curl_upload_new(cCurlUpload);
|
|
991
1375
|
ruby_curl_upload_stream_set(upload,data);
|
|
@@ -996,13 +1380,16 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
|
|
|
996
1380
|
is complete or terminated... */
|
|
997
1381
|
|
|
998
1382
|
curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
|
|
1383
|
+
curl_easy_setopt(curl, CURLOPT_POST, 0);
|
|
1384
|
+
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, NULL);
|
|
1385
|
+
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 0);
|
|
999
1386
|
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
|
|
1000
1387
|
curl_easy_setopt(curl, CURLOPT_READFUNCTION, (curl_read_callback)read_data_handler);
|
|
1001
|
-
#
|
|
1388
|
+
#ifdef HAVE_CURLOPT_SEEKFUNCTION
|
|
1002
1389
|
curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, (curl_seek_callback)seek_data_handler);
|
|
1003
1390
|
#endif
|
|
1004
1391
|
curl_easy_setopt(curl, CURLOPT_READDATA, rbce);
|
|
1005
|
-
#
|
|
1392
|
+
#ifdef HAVE_CURLOPT_SEEKDATA
|
|
1006
1393
|
curl_easy_setopt(curl, CURLOPT_SEEKDATA, rbce);
|
|
1007
1394
|
#endif
|
|
1008
1395
|
|
|
@@ -1238,7 +1625,7 @@ static VALUE ruby_curl_easy_http_auth_types_set(int argc, VALUE *argv, VALUE sel
|
|
|
1238
1625
|
long mask = 0;
|
|
1239
1626
|
|
|
1240
1627
|
rb_scan_args(argc, argv, "*", &args_ary);
|
|
1241
|
-
|
|
1628
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
1242
1629
|
|
|
1243
1630
|
len = RARRAY_LEN(args_ary);
|
|
1244
1631
|
|
|
@@ -1343,7 +1730,7 @@ static VALUE ruby_curl_easy_max_redirects_get(VALUE self) {
|
|
|
1343
1730
|
*/
|
|
1344
1731
|
static VALUE ruby_curl_easy_timeout_set(VALUE self, VALUE timeout_s) {
|
|
1345
1732
|
ruby_curl_easy *rbce;
|
|
1346
|
-
|
|
1733
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
1347
1734
|
|
|
1348
1735
|
if (Qnil == timeout_s || NUM2DBL(timeout_s) <= 0.0) {
|
|
1349
1736
|
rbce->timeout_ms = 0;
|
|
@@ -1366,7 +1753,7 @@ static VALUE ruby_curl_easy_timeout_set(VALUE self, VALUE timeout_s) {
|
|
|
1366
1753
|
*/
|
|
1367
1754
|
static VALUE ruby_curl_easy_timeout_get(VALUE self) {
|
|
1368
1755
|
ruby_curl_easy *rbce;
|
|
1369
|
-
|
|
1756
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
1370
1757
|
return DBL2NUM(rbce->timeout_ms / 1000.0);
|
|
1371
1758
|
}
|
|
1372
1759
|
|
|
@@ -1384,7 +1771,7 @@ static VALUE ruby_curl_easy_timeout_get(VALUE self) {
|
|
|
1384
1771
|
*/
|
|
1385
1772
|
static VALUE ruby_curl_easy_timeout_ms_set(VALUE self, VALUE timeout_ms) {
|
|
1386
1773
|
ruby_curl_easy *rbce;
|
|
1387
|
-
|
|
1774
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
1388
1775
|
|
|
1389
1776
|
if (Qnil == timeout_ms || NUM2DBL(timeout_ms) <= 0.0) {
|
|
1390
1777
|
rbce->timeout_ms = 0;
|
|
@@ -1404,7 +1791,7 @@ static VALUE ruby_curl_easy_timeout_ms_set(VALUE self, VALUE timeout_ms) {
|
|
|
1404
1791
|
*/
|
|
1405
1792
|
static VALUE ruby_curl_easy_timeout_ms_get(VALUE self) {
|
|
1406
1793
|
ruby_curl_easy *rbce;
|
|
1407
|
-
|
|
1794
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
1408
1795
|
return LONG2NUM(rbce->timeout_ms);
|
|
1409
1796
|
}
|
|
1410
1797
|
|
|
@@ -1602,7 +1989,7 @@ static VALUE ruby_curl_easy_max_recv_speed_large_get(VALUE self) {
|
|
|
1602
1989
|
* Set the HTTP Authentication username.
|
|
1603
1990
|
*/
|
|
1604
1991
|
static VALUE ruby_curl_easy_username_set(VALUE self, VALUE username) {
|
|
1605
|
-
#
|
|
1992
|
+
#ifdef HAVE_CURLOPT_USERNAME
|
|
1606
1993
|
CURB_OBJECT_HSETTER(ruby_curl_easy, username);
|
|
1607
1994
|
#else
|
|
1608
1995
|
return Qnil;
|
|
@@ -1616,7 +2003,7 @@ static VALUE ruby_curl_easy_username_set(VALUE self, VALUE username) {
|
|
|
1616
2003
|
* Get the current username
|
|
1617
2004
|
*/
|
|
1618
2005
|
static VALUE ruby_curl_easy_username_get(VALUE self) {
|
|
1619
|
-
#
|
|
2006
|
+
#ifdef HAVE_CURLOPT_USERNAME
|
|
1620
2007
|
CURB_OBJECT_HGETTER(ruby_curl_easy, username);
|
|
1621
2008
|
#else
|
|
1622
2009
|
return Qnil;
|
|
@@ -1630,7 +2017,7 @@ static VALUE ruby_curl_easy_username_get(VALUE self) {
|
|
|
1630
2017
|
* Set the HTTP Authentication password.
|
|
1631
2018
|
*/
|
|
1632
2019
|
static VALUE ruby_curl_easy_password_set(VALUE self, VALUE password) {
|
|
1633
|
-
#
|
|
2020
|
+
#ifdef HAVE_CURLOPT_PASSWORD
|
|
1634
2021
|
CURB_OBJECT_HSETTER(ruby_curl_easy, password);
|
|
1635
2022
|
#else
|
|
1636
2023
|
return Qnil;
|
|
@@ -1644,7 +2031,7 @@ static VALUE ruby_curl_easy_password_set(VALUE self, VALUE password) {
|
|
|
1644
2031
|
* Get the current password
|
|
1645
2032
|
*/
|
|
1646
2033
|
static VALUE ruby_curl_easy_password_get(VALUE self) {
|
|
1647
|
-
#
|
|
2034
|
+
#ifdef HAVE_CURLOPT_PASSWORD
|
|
1648
2035
|
CURB_OBJECT_HGETTER(ruby_curl_easy, password);
|
|
1649
2036
|
#else
|
|
1650
2037
|
return Qnil;
|
|
@@ -1877,7 +2264,7 @@ static VALUE ruby_curl_easy_use_netrc_q(VALUE self) {
|
|
|
1877
2264
|
*/
|
|
1878
2265
|
static VALUE ruby_curl_easy_autoreferer_set(VALUE self, VALUE autoreferer) {
|
|
1879
2266
|
ruby_curl_easy *rbce;
|
|
1880
|
-
|
|
2267
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
1881
2268
|
|
|
1882
2269
|
if (Qtrue == autoreferer) {
|
|
1883
2270
|
curl_easy_setopt(rbce->curl, CURLOPT_AUTOREFERER, 1);
|
|
@@ -2034,7 +2421,7 @@ static VALUE ruby_curl_easy_ignore_content_length_q(VALUE self) {
|
|
|
2034
2421
|
static VALUE ruby_curl_easy_resolve_mode(VALUE self) {
|
|
2035
2422
|
ruby_curl_easy *rbce;
|
|
2036
2423
|
unsigned short rm;
|
|
2037
|
-
|
|
2424
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
2038
2425
|
|
|
2039
2426
|
rm = rbce->resolve_mode;
|
|
2040
2427
|
|
|
@@ -2066,7 +2453,7 @@ static VALUE ruby_curl_easy_resolve_mode_set(VALUE self, VALUE resolve_mode) {
|
|
|
2066
2453
|
} else {
|
|
2067
2454
|
ruby_curl_easy *rbce;
|
|
2068
2455
|
ID resolve_mode_id;
|
|
2069
|
-
|
|
2456
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
2070
2457
|
|
|
2071
2458
|
resolve_mode_id = rb_to_id(resolve_mode);
|
|
2072
2459
|
|
|
@@ -2086,6 +2473,46 @@ static VALUE ruby_curl_easy_resolve_mode_set(VALUE self, VALUE resolve_mode) {
|
|
|
2086
2473
|
}
|
|
2087
2474
|
}
|
|
2088
2475
|
|
|
2476
|
+
/*
|
|
2477
|
+
* call-seq:
|
|
2478
|
+
* easy.http_version = Curl::HTTP_1_1 => Curl::HTTP_1_1
|
|
2479
|
+
*
|
|
2480
|
+
* Force libcurl to use a specific HTTP protocol version. By default libcurl
|
|
2481
|
+
* negotiates the highest version supported by both peers. Supported constants
|
|
2482
|
+
* include Curl::HTTP_NONE, Curl::HTTP_1_0, Curl::HTTP_1_1, Curl::HTTP_2_0,
|
|
2483
|
+
* Curl::HTTP_2TLS, and Curl::HTTP_2_PRIOR_KNOWLEDGE (when provided by libcurl).
|
|
2484
|
+
*/
|
|
2485
|
+
static VALUE ruby_curl_easy_http_version_set(VALUE self, VALUE version) {
|
|
2486
|
+
ruby_curl_easy *rbce;
|
|
2487
|
+
long http_version;
|
|
2488
|
+
|
|
2489
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
2490
|
+
|
|
2491
|
+
if (NIL_P(version)) {
|
|
2492
|
+
http_version = CURL_HTTP_VERSION_NONE;
|
|
2493
|
+
} else {
|
|
2494
|
+
http_version = NUM2LONG(version);
|
|
2495
|
+
}
|
|
2496
|
+
|
|
2497
|
+
rbce->http_version = http_version;
|
|
2498
|
+
|
|
2499
|
+
return version;
|
|
2500
|
+
}
|
|
2501
|
+
|
|
2502
|
+
/*
|
|
2503
|
+
* call-seq:
|
|
2504
|
+
* easy.http_version => integer
|
|
2505
|
+
*
|
|
2506
|
+
* Returns the HTTP protocol version currently configured.
|
|
2507
|
+
*/
|
|
2508
|
+
static VALUE ruby_curl_easy_http_version_get(VALUE self) {
|
|
2509
|
+
ruby_curl_easy *rbce;
|
|
2510
|
+
|
|
2511
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
2512
|
+
|
|
2513
|
+
return LONG2NUM(rbce->http_version);
|
|
2514
|
+
}
|
|
2515
|
+
|
|
2089
2516
|
|
|
2090
2517
|
/* ================= EVENT PROCS ================== */
|
|
2091
2518
|
|
|
@@ -2250,7 +2677,7 @@ static VALUE cb_each_http_header(VALUE header, VALUE wrap, int _c, const VALUE *
|
|
|
2250
2677
|
struct curl_slist **list;
|
|
2251
2678
|
VALUE header_str = Qnil;
|
|
2252
2679
|
|
|
2253
|
-
|
|
2680
|
+
TypedData_Get_Struct(wrap, struct curl_slist *, &curl_slist_ptr_type, list);
|
|
2254
2681
|
|
|
2255
2682
|
//rb_p(header);
|
|
2256
2683
|
|
|
@@ -2289,7 +2716,7 @@ static VALUE cb_each_http_proxy_header(VALUE proxy_header, VALUE wrap, int _c, c
|
|
|
2289
2716
|
struct curl_slist **list;
|
|
2290
2717
|
VALUE proxy_header_str = Qnil;
|
|
2291
2718
|
|
|
2292
|
-
|
|
2719
|
+
TypedData_Get_Struct(wrap, struct curl_slist *, &curl_slist_ptr_type, list);
|
|
2293
2720
|
|
|
2294
2721
|
//rb_p(proxy_header);
|
|
2295
2722
|
|
|
@@ -2324,7 +2751,7 @@ static VALUE cb_each_http_proxy_header(VALUE proxy_header, VALUE wrap, int _c, c
|
|
|
2324
2751
|
static VALUE cb_each_ftp_command(VALUE ftp_command, VALUE wrap, int _c, const VALUE *_ptr, VALUE unused) {
|
|
2325
2752
|
struct curl_slist **list;
|
|
2326
2753
|
VALUE ftp_command_string;
|
|
2327
|
-
|
|
2754
|
+
TypedData_Get_Struct(wrap, struct curl_slist *, &curl_slist_ptr_type, list);
|
|
2328
2755
|
|
|
2329
2756
|
ftp_command_string = rb_obj_as_string(ftp_command);
|
|
2330
2757
|
struct curl_slist *new_list = curl_slist_append(*list, StringValuePtr(ftp_command));
|
|
@@ -2342,7 +2769,7 @@ static VALUE cb_each_ftp_command(VALUE ftp_command, VALUE wrap, int _c, const VA
|
|
|
2342
2769
|
static VALUE cb_each_resolve(VALUE resolve, VALUE wrap, int _c, const VALUE *_ptr, VALUE unused) {
|
|
2343
2770
|
struct curl_slist **list;
|
|
2344
2771
|
VALUE resolve_string;
|
|
2345
|
-
|
|
2772
|
+
TypedData_Get_Struct(wrap, struct curl_slist *, &curl_slist_ptr_type, list);
|
|
2346
2773
|
|
|
2347
2774
|
resolve_string = rb_obj_as_string(resolve);
|
|
2348
2775
|
struct curl_slist *new_list = curl_slist_append(*list, StringValuePtr(resolve));
|
|
@@ -2370,6 +2797,7 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2370
2797
|
struct curl_slist **rslv = &(rbce->curl_resolve);
|
|
2371
2798
|
|
|
2372
2799
|
curl = rbce->curl;
|
|
2800
|
+
rbce->callback_error = Qnil;
|
|
2373
2801
|
|
|
2374
2802
|
if (_url == Qnil) {
|
|
2375
2803
|
rb_raise(eCurlErrError, "No URL supplied");
|
|
@@ -2385,7 +2813,7 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2385
2813
|
curl_easy_setopt(curl, CURLOPT_INTERFACE, NULL);
|
|
2386
2814
|
}
|
|
2387
2815
|
|
|
2388
|
-
#if HAVE_CURLOPT_USERNAME
|
|
2816
|
+
#if defined(HAVE_CURLOPT_USERNAME) && defined(HAVE_CURLOPT_PASSWORD)
|
|
2389
2817
|
if (!rb_easy_nil("username")) {
|
|
2390
2818
|
curl_easy_setopt(curl, CURLOPT_USERNAME, rb_easy_get_str("username"));
|
|
2391
2819
|
} else {
|
|
@@ -2401,7 +2829,7 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2401
2829
|
|
|
2402
2830
|
if (!rb_easy_nil("userpwd")) {
|
|
2403
2831
|
curl_easy_setopt(curl, CURLOPT_USERPWD, rb_easy_get_str("userpwd"));
|
|
2404
|
-
#if HAVE_CURLOPT_USERNAME
|
|
2832
|
+
#if defined(HAVE_CURLOPT_USERNAME) && defined(HAVE_CURLOPT_PASSWORD)
|
|
2405
2833
|
} else if (rb_easy_nil("username") && rb_easy_nil("password")) { /* don't set this even to NULL if we have set username and password */
|
|
2406
2834
|
#else
|
|
2407
2835
|
} else {
|
|
@@ -2421,7 +2849,7 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2421
2849
|
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, rb_easy_get_str("proxypwd"));
|
|
2422
2850
|
}
|
|
2423
2851
|
|
|
2424
|
-
#
|
|
2852
|
+
#ifdef HAVE_CURLOPT_NOPROXY
|
|
2425
2853
|
if (rb_easy_nil("noproxy")) {
|
|
2426
2854
|
curl_easy_setopt(curl, CURLOPT_NOPROXY, NULL);
|
|
2427
2855
|
} else {
|
|
@@ -2459,12 +2887,21 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2459
2887
|
|
|
2460
2888
|
// progress and debug procs
|
|
2461
2889
|
if (!rb_easy_nil("progress_proc")) {
|
|
2890
|
+
#ifdef HAVE_CURLOPT_XFERINFOFUNCTION
|
|
2891
|
+
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, &proc_xferinfo_handler);
|
|
2892
|
+
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, rbce);
|
|
2893
|
+
#else
|
|
2462
2894
|
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, (curl_progress_callback)&proc_progress_handler);
|
|
2463
2895
|
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, rbce);
|
|
2896
|
+
#endif
|
|
2464
2897
|
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
|
|
2465
2898
|
} else {
|
|
2466
2899
|
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
|
|
2900
|
+
#ifdef HAVE_CURLOPT_XFERINFOFUNCTION
|
|
2901
|
+
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, rbce);
|
|
2902
|
+
#else
|
|
2467
2903
|
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, rbce);
|
|
2904
|
+
#endif
|
|
2468
2905
|
}
|
|
2469
2906
|
|
|
2470
2907
|
if (!rb_easy_nil("debug_proc")) {
|
|
@@ -2504,12 +2941,12 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2504
2941
|
|
|
2505
2942
|
curl_easy_setopt(curl, CURLOPT_UNRESTRICTED_AUTH, rbce->unrestricted_auth);
|
|
2506
2943
|
|
|
2507
|
-
#
|
|
2944
|
+
#ifdef HAVE_CURLOPT_TIMEOUT_MS
|
|
2508
2945
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, rbce->timeout_ms);
|
|
2509
2946
|
#endif
|
|
2510
2947
|
|
|
2511
2948
|
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, rbce->connect_timeout);
|
|
2512
|
-
#
|
|
2949
|
+
#ifdef HAVE_CURLOPT_CONNECTTIMEOUT_MS
|
|
2513
2950
|
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, rbce->connect_timeout_ms);
|
|
2514
2951
|
#endif
|
|
2515
2952
|
curl_easy_setopt(curl, CURLOPT_DNS_CACHE_TIMEOUT, rbce->dns_cache_timeout);
|
|
@@ -2517,6 +2954,9 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2517
2954
|
curl_easy_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, rbce->ignore_content_length);
|
|
2518
2955
|
|
|
2519
2956
|
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, rbce->resolve_mode);
|
|
2957
|
+
#if HAVE_CURLOPT_HTTP_VERSION
|
|
2958
|
+
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, rbce->http_version);
|
|
2959
|
+
#endif
|
|
2520
2960
|
|
|
2521
2961
|
|
|
2522
2962
|
#if LIBCURL_VERSION_NUM >= 0x070a08
|
|
@@ -2656,8 +3096,8 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2656
3096
|
|
|
2657
3097
|
if (!rb_easy_nil("headers")) {
|
|
2658
3098
|
if (rb_easy_type_check("headers", T_ARRAY) || rb_easy_type_check("headers", T_HASH)) {
|
|
2659
|
-
VALUE wrap =
|
|
2660
|
-
|
|
3099
|
+
VALUE wrap = TypedData_Wrap_Struct(rb_cObject, &curl_slist_ptr_type, hdrs);
|
|
3100
|
+
rb_block_call(rb_easy_get("headers"), rb_intern("each"), 0, NULL, cb_each_http_header, wrap);
|
|
2661
3101
|
} else {
|
|
2662
3102
|
VALUE headers_str = rb_obj_as_string(rb_easy_get("headers"));
|
|
2663
3103
|
struct curl_slist *new_list = curl_slist_append(*hdrs, StringValuePtr(headers_str));
|
|
@@ -2672,14 +3112,14 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2672
3112
|
}
|
|
2673
3113
|
}
|
|
2674
3114
|
|
|
2675
|
-
#
|
|
3115
|
+
#ifdef HAVE_CURLOPT_PROXYHEADER
|
|
2676
3116
|
/* Setup HTTP proxy headers if necessary */
|
|
2677
3117
|
curl_easy_setopt(curl, CURLOPT_PROXYHEADER, NULL); // XXX: maybe we shouldn't be clearing this?
|
|
2678
3118
|
|
|
2679
3119
|
if (!rb_easy_nil("proxy_headers")) {
|
|
2680
3120
|
if (rb_easy_type_check("proxy_headers", T_ARRAY) || rb_easy_type_check("proxy_headers", T_HASH)) {
|
|
2681
|
-
VALUE wrap =
|
|
2682
|
-
|
|
3121
|
+
VALUE wrap = TypedData_Wrap_Struct(rb_cObject, &curl_slist_ptr_type, phdrs);
|
|
3122
|
+
rb_block_call(rb_easy_get("proxy_headers"), rb_intern("each"), 0, NULL, cb_each_http_proxy_header, wrap);
|
|
2683
3123
|
} else {
|
|
2684
3124
|
VALUE proxy_headers_str = rb_obj_as_string(rb_easy_get("proxy_headers"));
|
|
2685
3125
|
struct curl_slist *new_list = curl_slist_append(*phdrs, StringValuePtr(proxy_headers_str));
|
|
@@ -2698,8 +3138,8 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2698
3138
|
/* Setup FTP commands if necessary */
|
|
2699
3139
|
if (!rb_easy_nil("ftp_commands")) {
|
|
2700
3140
|
if (rb_easy_type_check("ftp_commands", T_ARRAY)) {
|
|
2701
|
-
VALUE wrap =
|
|
2702
|
-
|
|
3141
|
+
VALUE wrap = TypedData_Wrap_Struct(rb_cObject, &curl_slist_ptr_type, cmds);
|
|
3142
|
+
rb_block_call(rb_easy_get("ftp_commands"), rb_intern("each"), 0, NULL, cb_each_ftp_command, wrap);
|
|
2703
3143
|
}
|
|
2704
3144
|
|
|
2705
3145
|
if (*cmds) {
|
|
@@ -2707,12 +3147,12 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2707
3147
|
}
|
|
2708
3148
|
}
|
|
2709
3149
|
|
|
2710
|
-
#
|
|
3150
|
+
#ifdef HAVE_CURLOPT_RESOLVE
|
|
2711
3151
|
/* Setup resolve list if necessary */
|
|
2712
3152
|
if (!rb_easy_nil("resolve")) {
|
|
2713
3153
|
if (rb_easy_type_check("resolve", T_ARRAY)) {
|
|
2714
|
-
VALUE wrap =
|
|
2715
|
-
|
|
3154
|
+
VALUE wrap = TypedData_Wrap_Struct(rb_cObject, &curl_slist_ptr_type, rslv);
|
|
3155
|
+
rb_block_call(rb_easy_get("resolve"), rb_intern("each"), 0, NULL, cb_each_resolve, wrap);
|
|
2716
3156
|
}
|
|
2717
3157
|
|
|
2718
3158
|
if (*rslv) {
|
|
@@ -2735,27 +3175,17 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
|
|
|
2735
3175
|
struct curl_slist *ftp_commands;
|
|
2736
3176
|
struct curl_slist *resolve;
|
|
2737
3177
|
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
curl_slist_free_all(rbce->curl_headers);
|
|
2741
|
-
rbce->curl_headers = NULL;
|
|
2742
|
-
}
|
|
2743
|
-
|
|
2744
|
-
if (rbce->curl_proxy_headers) {
|
|
2745
|
-
curl_slist_free_all(rbce->curl_proxy_headers);
|
|
2746
|
-
rbce->curl_proxy_headers = NULL;
|
|
2747
|
-
}
|
|
3178
|
+
ruby_curl_easy_clear_headers_list(rbce);
|
|
3179
|
+
ruby_curl_easy_clear_proxy_headers_list(rbce);
|
|
2748
3180
|
|
|
2749
3181
|
ftp_commands = rbce->curl_ftp_commands;
|
|
2750
3182
|
if (ftp_commands) {
|
|
2751
|
-
|
|
2752
|
-
rbce->curl_ftp_commands = NULL;
|
|
3183
|
+
ruby_curl_easy_clear_ftp_commands_list(rbce);
|
|
2753
3184
|
}
|
|
2754
3185
|
|
|
2755
3186
|
resolve = rbce->curl_resolve;
|
|
2756
3187
|
if (resolve) {
|
|
2757
|
-
|
|
2758
|
-
rbce->curl_resolve = NULL;
|
|
3188
|
+
ruby_curl_easy_clear_resolve_list(rbce);
|
|
2759
3189
|
}
|
|
2760
3190
|
|
|
2761
3191
|
/* clean up a PUT request's curl options. */
|
|
@@ -2764,6 +3194,12 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
|
|
|
2764
3194
|
curl_easy_setopt(curl, CURLOPT_UPLOAD, 0);
|
|
2765
3195
|
curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
|
|
2766
3196
|
curl_easy_setopt(curl, CURLOPT_READDATA, NULL);
|
|
3197
|
+
#ifdef HAVE_CURLOPT_SEEKFUNCTION
|
|
3198
|
+
curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, NULL);
|
|
3199
|
+
#endif
|
|
3200
|
+
#ifdef HAVE_CURLOPT_SEEKDATA
|
|
3201
|
+
curl_easy_setopt(curl, CURLOPT_SEEKDATA, NULL);
|
|
3202
|
+
#endif
|
|
2767
3203
|
curl_easy_setopt(curl, CURLOPT_INFILESIZE, 0);
|
|
2768
3204
|
}
|
|
2769
3205
|
|
|
@@ -2781,7 +3217,7 @@ static VALUE ruby_curl_easy_perform_verb_str(VALUE self, const char *verb) {
|
|
|
2781
3217
|
CURL *curl;
|
|
2782
3218
|
VALUE retval;
|
|
2783
3219
|
|
|
2784
|
-
|
|
3220
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
2785
3221
|
curl = rbce->curl;
|
|
2786
3222
|
|
|
2787
3223
|
memset(rbce->err_buf, 0, CURL_ERROR_SIZE);
|
|
@@ -2837,6 +3273,76 @@ static VALUE ruby_curl_easy_perform_verb(VALUE self, VALUE verb) {
|
|
|
2837
3273
|
}
|
|
2838
3274
|
}
|
|
2839
3275
|
|
|
3276
|
+
static VALUE call_easy_perform(VALUE self) {
|
|
3277
|
+
return rb_funcall(self, rb_intern("perform"), 0);
|
|
3278
|
+
}
|
|
3279
|
+
|
|
3280
|
+
struct easy_form_perform_args {
|
|
3281
|
+
VALUE self;
|
|
3282
|
+
CURL *curl;
|
|
3283
|
+
int argc;
|
|
3284
|
+
VALUE *argv;
|
|
3285
|
+
struct curl_httppost *first;
|
|
3286
|
+
struct curl_httppost *last;
|
|
3287
|
+
int clear_customrequest;
|
|
3288
|
+
int form_set_on_curl;
|
|
3289
|
+
};
|
|
3290
|
+
|
|
3291
|
+
static void append_multipart_form_argument(VALUE arg,
|
|
3292
|
+
struct curl_httppost **first,
|
|
3293
|
+
struct curl_httppost **last) {
|
|
3294
|
+
if (rb_obj_is_instance_of(arg, cCurlPostField)) {
|
|
3295
|
+
append_to_form(arg, first, last);
|
|
3296
|
+
} else if (rb_type(arg) == T_ARRAY) {
|
|
3297
|
+
long j, argv_len = RARRAY_LEN(arg);
|
|
3298
|
+
for (j = 0; j < argv_len; ++j) {
|
|
3299
|
+
VALUE field = rb_ary_entry(arg, j);
|
|
3300
|
+
if (rb_obj_is_instance_of(field, cCurlPostField)) {
|
|
3301
|
+
append_to_form(field, first, last);
|
|
3302
|
+
} else {
|
|
3303
|
+
rb_raise(eCurlErrInvalidPostField,
|
|
3304
|
+
"You must use PostFields only with multipart form posts");
|
|
3305
|
+
}
|
|
3306
|
+
}
|
|
3307
|
+
} else {
|
|
3308
|
+
rb_raise(eCurlErrInvalidPostField,
|
|
3309
|
+
"You must use PostFields only with multipart form posts");
|
|
3310
|
+
}
|
|
3311
|
+
}
|
|
3312
|
+
|
|
3313
|
+
static VALUE build_and_perform_multipart_form(VALUE argp) {
|
|
3314
|
+
struct easy_form_perform_args *args = (struct easy_form_perform_args *)argp;
|
|
3315
|
+
int i;
|
|
3316
|
+
|
|
3317
|
+
for (i = 0; i < args->argc; i++) {
|
|
3318
|
+
append_multipart_form_argument(args->argv[i], &args->first, &args->last);
|
|
3319
|
+
}
|
|
3320
|
+
|
|
3321
|
+
curl_easy_setopt(args->curl, CURLOPT_POST, 0);
|
|
3322
|
+
curl_easy_setopt(args->curl, CURLOPT_HTTPPOST, args->first);
|
|
3323
|
+
args->form_set_on_curl = 1;
|
|
3324
|
+
|
|
3325
|
+
return call_easy_perform(args->self);
|
|
3326
|
+
}
|
|
3327
|
+
|
|
3328
|
+
static VALUE ensure_free_form_post(VALUE argp) {
|
|
3329
|
+
struct easy_form_perform_args *args = (struct easy_form_perform_args *)argp;
|
|
3330
|
+
if (args->curl) {
|
|
3331
|
+
if (args->form_set_on_curl) {
|
|
3332
|
+
curl_easy_setopt(args->curl, CURLOPT_HTTPPOST, NULL);
|
|
3333
|
+
}
|
|
3334
|
+
if (args->clear_customrequest) {
|
|
3335
|
+
curl_easy_setopt(args->curl, CURLOPT_CUSTOMREQUEST, NULL);
|
|
3336
|
+
}
|
|
3337
|
+
}
|
|
3338
|
+
if (args->first) {
|
|
3339
|
+
curl_formfree(args->first);
|
|
3340
|
+
args->first = NULL;
|
|
3341
|
+
}
|
|
3342
|
+
args->last = NULL;
|
|
3343
|
+
return Qnil;
|
|
3344
|
+
}
|
|
3345
|
+
|
|
2840
3346
|
/*
|
|
2841
3347
|
* call-seq:
|
|
2842
3348
|
* easy.http_post("url=encoded%20form%20data;and=so%20on") => true
|
|
@@ -2864,12 +3370,11 @@ static VALUE ruby_curl_easy_perform_verb(VALUE self, VALUE verb) {
|
|
|
2864
3370
|
static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
|
|
2865
3371
|
ruby_curl_easy *rbce;
|
|
2866
3372
|
CURL *curl;
|
|
2867
|
-
int i;
|
|
2868
3373
|
VALUE args_ary;
|
|
2869
3374
|
|
|
2870
3375
|
rb_scan_args(argc, argv, "*", &args_ary);
|
|
2871
3376
|
|
|
2872
|
-
|
|
3377
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
2873
3378
|
curl = rbce->curl;
|
|
2874
3379
|
|
|
2875
3380
|
memset(rbce->err_buf, 0, CURL_ERROR_SIZE);
|
|
@@ -2878,33 +3383,8 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
|
|
|
2878
3383
|
|
|
2879
3384
|
if (rbce->multipart_form_post) {
|
|
2880
3385
|
VALUE ret;
|
|
2881
|
-
struct
|
|
2882
|
-
|
|
2883
|
-
// Make the multipart form
|
|
2884
|
-
for (i = 0; i < argc; i++) {
|
|
2885
|
-
if (rb_obj_is_instance_of(argv[i], cCurlPostField)) {
|
|
2886
|
-
append_to_form(argv[i], &first, &last);
|
|
2887
|
-
} else if (rb_type(argv[i]) == T_ARRAY) {
|
|
2888
|
-
// see: https://github.com/rvanlieshout/curb/commit/8bcdefddc0162484681ebd1a92d52a642666a445
|
|
2889
|
-
long c = 0, argv_len = RARRAY_LEN(argv[i]);
|
|
2890
|
-
for (; c < argv_len; ++c) {
|
|
2891
|
-
if (rb_obj_is_instance_of(rb_ary_entry(argv[i],c), cCurlPostField)) {
|
|
2892
|
-
append_to_form(rb_ary_entry(argv[i],c), &first, &last);
|
|
2893
|
-
} else {
|
|
2894
|
-
rb_raise(eCurlErrInvalidPostField, "You must use PostFields only with multipart form posts");
|
|
2895
|
-
return Qnil;
|
|
2896
|
-
}
|
|
2897
|
-
}
|
|
2898
|
-
} else {
|
|
2899
|
-
rb_raise(eCurlErrInvalidPostField, "You must use PostFields only with multipart form posts");
|
|
2900
|
-
return Qnil;
|
|
2901
|
-
}
|
|
2902
|
-
}
|
|
2903
|
-
|
|
2904
|
-
curl_easy_setopt(curl, CURLOPT_POST, 0);
|
|
2905
|
-
curl_easy_setopt(curl, CURLOPT_HTTPPOST, first);
|
|
2906
|
-
ret = rb_funcall(self, rb_intern("perform"), 0);
|
|
2907
|
-
curl_formfree(first);
|
|
3386
|
+
struct easy_form_perform_args perform_args = { self, curl, argc, argv, NULL, NULL, 0, 0 };
|
|
3387
|
+
ret = rb_ensure(build_and_perform_multipart_form, (VALUE)&perform_args, ensure_free_form_post, (VALUE)&perform_args);
|
|
2908
3388
|
|
|
2909
3389
|
return ret;
|
|
2910
3390
|
} else {
|
|
@@ -2948,11 +3428,10 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
|
|
|
2948
3428
|
static VALUE ruby_curl_easy_perform_patch(int argc, VALUE *argv, VALUE self) {
|
|
2949
3429
|
ruby_curl_easy *rbce;
|
|
2950
3430
|
CURL *curl;
|
|
2951
|
-
int i;
|
|
2952
3431
|
VALUE args_ary;
|
|
2953
3432
|
|
|
2954
3433
|
rb_scan_args(argc, argv, "*", &args_ary);
|
|
2955
|
-
|
|
3434
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
2956
3435
|
curl = rbce->curl;
|
|
2957
3436
|
|
|
2958
3437
|
/* Clear the error buffer */
|
|
@@ -2963,35 +3442,8 @@ static VALUE ruby_curl_easy_perform_patch(int argc, VALUE *argv, VALUE self) {
|
|
|
2963
3442
|
|
|
2964
3443
|
if (rbce->multipart_form_post) {
|
|
2965
3444
|
VALUE ret;
|
|
2966
|
-
struct
|
|
2967
|
-
|
|
2968
|
-
/* Build the multipart form (same logic as for POST) */
|
|
2969
|
-
for (i = 0; i < argc; i++) {
|
|
2970
|
-
if (rb_obj_is_instance_of(argv[i], cCurlPostField)) {
|
|
2971
|
-
append_to_form(argv[i], &first, &last);
|
|
2972
|
-
} else if (rb_type(argv[i]) == T_ARRAY) {
|
|
2973
|
-
long j, argv_len = RARRAY_LEN(argv[i]);
|
|
2974
|
-
for (j = 0; j < argv_len; ++j) {
|
|
2975
|
-
if (rb_obj_is_instance_of(rb_ary_entry(argv[i], j), cCurlPostField)) {
|
|
2976
|
-
append_to_form(rb_ary_entry(argv[i], j), &first, &last);
|
|
2977
|
-
} else {
|
|
2978
|
-
rb_raise(eCurlErrInvalidPostField,
|
|
2979
|
-
"You must use PostFields only with multipart form posts");
|
|
2980
|
-
return Qnil;
|
|
2981
|
-
}
|
|
2982
|
-
}
|
|
2983
|
-
} else {
|
|
2984
|
-
rb_raise(eCurlErrInvalidPostField,
|
|
2985
|
-
"You must use PostFields only with multipart form posts");
|
|
2986
|
-
return Qnil;
|
|
2987
|
-
}
|
|
2988
|
-
}
|
|
2989
|
-
/* Disable the POST flag */
|
|
2990
|
-
curl_easy_setopt(curl, CURLOPT_POST, 0);
|
|
2991
|
-
/* Use the built multipart form as the request body */
|
|
2992
|
-
curl_easy_setopt(curl, CURLOPT_HTTPPOST, first);
|
|
2993
|
-
ret = rb_funcall(self, rb_intern("perform"), 0);
|
|
2994
|
-
curl_formfree(first);
|
|
3445
|
+
struct easy_form_perform_args perform_args = { self, curl, argc, argv, NULL, NULL, 1, 0 };
|
|
3446
|
+
ret = rb_ensure(build_and_perform_multipart_form, (VALUE)&perform_args, ensure_free_form_post, (VALUE)&perform_args);
|
|
2995
3447
|
return ret;
|
|
2996
3448
|
} else {
|
|
2997
3449
|
/* Join arguments into a raw PATCH body */
|
|
@@ -3024,10 +3476,9 @@ static VALUE ruby_curl_easy_perform_put(int argc, VALUE *argv, VALUE self) {
|
|
|
3024
3476
|
ruby_curl_easy *rbce;
|
|
3025
3477
|
CURL *curl;
|
|
3026
3478
|
VALUE args_ary;
|
|
3027
|
-
int i;
|
|
3028
3479
|
|
|
3029
3480
|
rb_scan_args(argc, argv, "*", &args_ary);
|
|
3030
|
-
|
|
3481
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3031
3482
|
curl = rbce->curl;
|
|
3032
3483
|
|
|
3033
3484
|
memset(rbce->err_buf, 0, CURL_ERROR_SIZE);
|
|
@@ -3047,33 +3498,8 @@ static VALUE ruby_curl_easy_perform_put(int argc, VALUE *argv, VALUE self) {
|
|
|
3047
3498
|
/* Otherwise, if multipart_form_post is true, use multipart logic */
|
|
3048
3499
|
else if (rbce->multipart_form_post) {
|
|
3049
3500
|
VALUE ret;
|
|
3050
|
-
struct
|
|
3051
|
-
|
|
3052
|
-
VALUE field = rb_ary_entry(args_ary, i);
|
|
3053
|
-
if (rb_obj_is_instance_of(field, cCurlPostField)) {
|
|
3054
|
-
append_to_form(field, &first, &last);
|
|
3055
|
-
} else if (rb_type(field) == T_ARRAY) {
|
|
3056
|
-
long j;
|
|
3057
|
-
for (j = 0; j < RARRAY_LEN(field); j++) {
|
|
3058
|
-
VALUE subfield = rb_ary_entry(field, j);
|
|
3059
|
-
if (rb_obj_is_instance_of(subfield, cCurlPostField)) {
|
|
3060
|
-
append_to_form(subfield, &first, &last);
|
|
3061
|
-
} else {
|
|
3062
|
-
rb_raise(eCurlErrInvalidPostField,
|
|
3063
|
-
"You must use PostFields only with multipart form posts");
|
|
3064
|
-
}
|
|
3065
|
-
}
|
|
3066
|
-
} else {
|
|
3067
|
-
rb_raise(eCurlErrInvalidPostField,
|
|
3068
|
-
"You must use PostFields only with multipart form posts");
|
|
3069
|
-
}
|
|
3070
|
-
}
|
|
3071
|
-
curl_easy_setopt(curl, CURLOPT_POST, 0);
|
|
3072
|
-
curl_easy_setopt(curl, CURLOPT_HTTPPOST, first);
|
|
3073
|
-
/* Set the method explicitly to PUT */
|
|
3074
|
-
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
|
|
3075
|
-
ret = rb_funcall(self, rb_intern("perform"), 0);
|
|
3076
|
-
curl_formfree(first);
|
|
3501
|
+
struct easy_form_perform_args perform_args = { self, curl, argc, argv, NULL, NULL, 1, 0 };
|
|
3502
|
+
ret = rb_ensure(build_and_perform_multipart_form, (VALUE)&perform_args, ensure_free_form_post, (VALUE)&perform_args);
|
|
3077
3503
|
return ret;
|
|
3078
3504
|
}
|
|
3079
3505
|
/* Fallback: join all arguments */
|
|
@@ -3133,7 +3559,7 @@ static VALUE ruby_curl_easy_last_effective_url_get(VALUE self) {
|
|
|
3133
3559
|
ruby_curl_easy *rbce;
|
|
3134
3560
|
char* url;
|
|
3135
3561
|
|
|
3136
|
-
|
|
3562
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3137
3563
|
curl_easy_getinfo(rbce->curl, CURLINFO_EFFECTIVE_URL, &url);
|
|
3138
3564
|
|
|
3139
3565
|
if (url && url[0]) { // curl returns empty string if none
|
|
@@ -3156,7 +3582,7 @@ static VALUE ruby_curl_easy_response_code_get(VALUE self) {
|
|
|
3156
3582
|
ruby_curl_easy *rbce;
|
|
3157
3583
|
long code;
|
|
3158
3584
|
|
|
3159
|
-
|
|
3585
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3160
3586
|
#ifdef HAVE_CURLINFO_RESPONSE_CODE
|
|
3161
3587
|
curl_easy_getinfo(rbce->curl, CURLINFO_RESPONSE_CODE, &code);
|
|
3162
3588
|
#else
|
|
@@ -3180,7 +3606,7 @@ static VALUE ruby_curl_easy_primary_ip_get(VALUE self) {
|
|
|
3180
3606
|
ruby_curl_easy *rbce;
|
|
3181
3607
|
char* ip;
|
|
3182
3608
|
|
|
3183
|
-
|
|
3609
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3184
3610
|
curl_easy_getinfo(rbce->curl, CURLINFO_PRIMARY_IP, &ip);
|
|
3185
3611
|
|
|
3186
3612
|
if (ip && ip[0]) { // curl returns empty string if none
|
|
@@ -3201,7 +3627,7 @@ static VALUE ruby_curl_easy_http_connect_code_get(VALUE self) {
|
|
|
3201
3627
|
ruby_curl_easy *rbce;
|
|
3202
3628
|
long code;
|
|
3203
3629
|
|
|
3204
|
-
|
|
3630
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3205
3631
|
curl_easy_getinfo(rbce->curl, CURLINFO_HTTP_CONNECTCODE, &code);
|
|
3206
3632
|
|
|
3207
3633
|
return LONG2NUM(code);
|
|
@@ -3229,7 +3655,7 @@ static VALUE ruby_curl_easy_file_time_get(VALUE self) {
|
|
|
3229
3655
|
ruby_curl_easy *rbce;
|
|
3230
3656
|
long time;
|
|
3231
3657
|
|
|
3232
|
-
|
|
3658
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3233
3659
|
curl_easy_getinfo(rbce->curl, CURLINFO_FILETIME, &time);
|
|
3234
3660
|
|
|
3235
3661
|
return LONG2NUM(time);
|
|
@@ -3250,7 +3676,7 @@ static VALUE ruby_curl_easy_total_time_get(VALUE self) {
|
|
|
3250
3676
|
ruby_curl_easy *rbce;
|
|
3251
3677
|
double time;
|
|
3252
3678
|
|
|
3253
|
-
|
|
3679
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3254
3680
|
curl_easy_getinfo(rbce->curl, CURLINFO_TOTAL_TIME, &time);
|
|
3255
3681
|
|
|
3256
3682
|
return rb_float_new(time);
|
|
@@ -3267,7 +3693,7 @@ static VALUE ruby_curl_easy_name_lookup_time_get(VALUE self) {
|
|
|
3267
3693
|
ruby_curl_easy *rbce;
|
|
3268
3694
|
double time;
|
|
3269
3695
|
|
|
3270
|
-
|
|
3696
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3271
3697
|
curl_easy_getinfo(rbce->curl, CURLINFO_NAMELOOKUP_TIME, &time);
|
|
3272
3698
|
|
|
3273
3699
|
return rb_float_new(time);
|
|
@@ -3284,7 +3710,7 @@ static VALUE ruby_curl_easy_connect_time_get(VALUE self) {
|
|
|
3284
3710
|
ruby_curl_easy *rbce;
|
|
3285
3711
|
double time;
|
|
3286
3712
|
|
|
3287
|
-
|
|
3713
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3288
3714
|
curl_easy_getinfo(rbce->curl, CURLINFO_CONNECT_TIME, &time);
|
|
3289
3715
|
|
|
3290
3716
|
return rb_float_new(time);
|
|
@@ -3305,7 +3731,7 @@ static VALUE ruby_curl_easy_app_connect_time_get(VALUE self) {
|
|
|
3305
3731
|
ruby_curl_easy *rbce;
|
|
3306
3732
|
double time;
|
|
3307
3733
|
|
|
3308
|
-
|
|
3734
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3309
3735
|
curl_easy_getinfo(rbce->curl, CURLINFO_APPCONNECT_TIME, &time);
|
|
3310
3736
|
|
|
3311
3737
|
return rb_float_new(time);
|
|
@@ -3326,7 +3752,7 @@ static VALUE ruby_curl_easy_pre_transfer_time_get(VALUE self) {
|
|
|
3326
3752
|
ruby_curl_easy *rbce;
|
|
3327
3753
|
double time;
|
|
3328
3754
|
|
|
3329
|
-
|
|
3755
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3330
3756
|
curl_easy_getinfo(rbce->curl, CURLINFO_PRETRANSFER_TIME, &time);
|
|
3331
3757
|
|
|
3332
3758
|
return rb_float_new(time);
|
|
@@ -3344,7 +3770,7 @@ static VALUE ruby_curl_easy_start_transfer_time_get(VALUE self) {
|
|
|
3344
3770
|
ruby_curl_easy *rbce;
|
|
3345
3771
|
double time;
|
|
3346
3772
|
|
|
3347
|
-
|
|
3773
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3348
3774
|
curl_easy_getinfo(rbce->curl, CURLINFO_STARTTRANSFER_TIME, &time);
|
|
3349
3775
|
|
|
3350
3776
|
return rb_float_new(time);
|
|
@@ -3366,7 +3792,7 @@ static VALUE ruby_curl_easy_redirect_time_get(VALUE self) {
|
|
|
3366
3792
|
ruby_curl_easy *rbce;
|
|
3367
3793
|
double time;
|
|
3368
3794
|
|
|
3369
|
-
|
|
3795
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3370
3796
|
curl_easy_getinfo(rbce->curl, CURLINFO_REDIRECT_TIME, &time);
|
|
3371
3797
|
|
|
3372
3798
|
return rb_float_new(time);
|
|
@@ -3389,7 +3815,7 @@ static VALUE ruby_curl_easy_redirect_count_get(VALUE self) {
|
|
|
3389
3815
|
ruby_curl_easy *rbce;
|
|
3390
3816
|
long count;
|
|
3391
3817
|
|
|
3392
|
-
|
|
3818
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3393
3819
|
curl_easy_getinfo(rbce->curl, CURLINFO_REDIRECT_COUNT, &count);
|
|
3394
3820
|
|
|
3395
3821
|
return LONG2NUM(count);
|
|
@@ -3414,7 +3840,7 @@ static VALUE ruby_curl_easy_redirect_url_get(VALUE self) {
|
|
|
3414
3840
|
ruby_curl_easy *rbce;
|
|
3415
3841
|
char* url;
|
|
3416
3842
|
|
|
3417
|
-
|
|
3843
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3418
3844
|
curl_easy_getinfo(rbce->curl, CURLINFO_REDIRECT_URL, &url);
|
|
3419
3845
|
|
|
3420
3846
|
if (url && url[0]) { // curl returns empty string if none
|
|
@@ -3439,12 +3865,17 @@ static VALUE ruby_curl_easy_redirect_url_get(VALUE self) {
|
|
|
3439
3865
|
*/
|
|
3440
3866
|
static VALUE ruby_curl_easy_uploaded_bytes_get(VALUE self) {
|
|
3441
3867
|
ruby_curl_easy *rbce;
|
|
3442
|
-
|
|
3868
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3443
3869
|
|
|
3444
|
-
|
|
3870
|
+
#ifdef HAVE_CURLINFO_SIZE_UPLOAD_T
|
|
3871
|
+
curl_off_t bytes;
|
|
3872
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_SIZE_UPLOAD_T, &bytes);
|
|
3873
|
+
return LL2NUM(bytes);
|
|
3874
|
+
#else
|
|
3875
|
+
double bytes;
|
|
3445
3876
|
curl_easy_getinfo(rbce->curl, CURLINFO_SIZE_UPLOAD, &bytes);
|
|
3446
|
-
|
|
3447
3877
|
return rb_float_new(bytes);
|
|
3878
|
+
#endif
|
|
3448
3879
|
}
|
|
3449
3880
|
|
|
3450
3881
|
/*
|
|
@@ -3456,12 +3887,17 @@ static VALUE ruby_curl_easy_uploaded_bytes_get(VALUE self) {
|
|
|
3456
3887
|
*/
|
|
3457
3888
|
static VALUE ruby_curl_easy_downloaded_bytes_get(VALUE self) {
|
|
3458
3889
|
ruby_curl_easy *rbce;
|
|
3459
|
-
|
|
3890
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3460
3891
|
|
|
3461
|
-
|
|
3892
|
+
#ifdef HAVE_CURLINFO_SIZE_DOWNLOAD_T
|
|
3893
|
+
curl_off_t bytes;
|
|
3894
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_SIZE_DOWNLOAD_T, &bytes);
|
|
3895
|
+
return LL2NUM(bytes);
|
|
3896
|
+
#else
|
|
3897
|
+
double bytes;
|
|
3462
3898
|
curl_easy_getinfo(rbce->curl, CURLINFO_SIZE_DOWNLOAD, &bytes);
|
|
3463
|
-
|
|
3464
3899
|
return rb_float_new(bytes);
|
|
3900
|
+
#endif
|
|
3465
3901
|
}
|
|
3466
3902
|
|
|
3467
3903
|
/*
|
|
@@ -3473,12 +3909,17 @@ static VALUE ruby_curl_easy_downloaded_bytes_get(VALUE self) {
|
|
|
3473
3909
|
*/
|
|
3474
3910
|
static VALUE ruby_curl_easy_upload_speed_get(VALUE self) {
|
|
3475
3911
|
ruby_curl_easy *rbce;
|
|
3476
|
-
|
|
3912
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3477
3913
|
|
|
3478
|
-
|
|
3914
|
+
#ifdef HAVE_CURLINFO_SPEED_UPLOAD_T
|
|
3915
|
+
curl_off_t bytes;
|
|
3916
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_SPEED_UPLOAD_T, &bytes);
|
|
3917
|
+
return LL2NUM(bytes);
|
|
3918
|
+
#else
|
|
3919
|
+
double bytes;
|
|
3479
3920
|
curl_easy_getinfo(rbce->curl, CURLINFO_SPEED_UPLOAD, &bytes);
|
|
3480
|
-
|
|
3481
3921
|
return rb_float_new(bytes);
|
|
3922
|
+
#endif
|
|
3482
3923
|
}
|
|
3483
3924
|
|
|
3484
3925
|
/*
|
|
@@ -3490,12 +3931,17 @@ static VALUE ruby_curl_easy_upload_speed_get(VALUE self) {
|
|
|
3490
3931
|
*/
|
|
3491
3932
|
static VALUE ruby_curl_easy_download_speed_get(VALUE self) {
|
|
3492
3933
|
ruby_curl_easy *rbce;
|
|
3493
|
-
|
|
3934
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3494
3935
|
|
|
3495
|
-
|
|
3936
|
+
#ifdef HAVE_CURLINFO_SPEED_DOWNLOAD_T
|
|
3937
|
+
curl_off_t bytes;
|
|
3938
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_SPEED_DOWNLOAD_T, &bytes);
|
|
3939
|
+
return LL2NUM(bytes);
|
|
3940
|
+
#else
|
|
3941
|
+
double bytes;
|
|
3496
3942
|
curl_easy_getinfo(rbce->curl, CURLINFO_SPEED_DOWNLOAD, &bytes);
|
|
3497
|
-
|
|
3498
3943
|
return rb_float_new(bytes);
|
|
3944
|
+
#endif
|
|
3499
3945
|
}
|
|
3500
3946
|
|
|
3501
3947
|
/*
|
|
@@ -3509,7 +3955,7 @@ static VALUE ruby_curl_easy_header_size_get(VALUE self) {
|
|
|
3509
3955
|
ruby_curl_easy *rbce;
|
|
3510
3956
|
long size;
|
|
3511
3957
|
|
|
3512
|
-
|
|
3958
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3513
3959
|
curl_easy_getinfo(rbce->curl, CURLINFO_HEADER_SIZE, &size);
|
|
3514
3960
|
|
|
3515
3961
|
return LONG2NUM(size);
|
|
@@ -3527,7 +3973,7 @@ static VALUE ruby_curl_easy_request_size_get(VALUE self) {
|
|
|
3527
3973
|
ruby_curl_easy *rbce;
|
|
3528
3974
|
long size;
|
|
3529
3975
|
|
|
3530
|
-
|
|
3976
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3531
3977
|
curl_easy_getinfo(rbce->curl, CURLINFO_REQUEST_SIZE, &size);
|
|
3532
3978
|
|
|
3533
3979
|
return LONG2NUM(size);
|
|
@@ -3544,7 +3990,7 @@ static VALUE ruby_curl_easy_ssl_verify_result_get(VALUE self) {
|
|
|
3544
3990
|
ruby_curl_easy *rbce;
|
|
3545
3991
|
long result;
|
|
3546
3992
|
|
|
3547
|
-
|
|
3993
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3548
3994
|
curl_easy_getinfo(rbce->curl, CURLINFO_SSL_VERIFYRESULT, &result);
|
|
3549
3995
|
|
|
3550
3996
|
return LONG2NUM(result);
|
|
@@ -3567,12 +4013,17 @@ NOTE: you must call curl_slist_free_all(3) on the list pointer once you're done
|
|
|
3567
4013
|
*/
|
|
3568
4014
|
static VALUE ruby_curl_easy_downloaded_content_length_get(VALUE self) {
|
|
3569
4015
|
ruby_curl_easy *rbce;
|
|
3570
|
-
|
|
4016
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3571
4017
|
|
|
3572
|
-
|
|
4018
|
+
#ifdef HAVE_CURLINFO_CONTENT_LENGTH_DOWNLOAD_T
|
|
4019
|
+
curl_off_t bytes;
|
|
4020
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &bytes);
|
|
4021
|
+
return LL2NUM(bytes);
|
|
4022
|
+
#else
|
|
4023
|
+
double bytes;
|
|
3573
4024
|
curl_easy_getinfo(rbce->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &bytes);
|
|
3574
|
-
|
|
3575
4025
|
return rb_float_new(bytes);
|
|
4026
|
+
#endif
|
|
3576
4027
|
}
|
|
3577
4028
|
|
|
3578
4029
|
/*
|
|
@@ -3583,12 +4034,17 @@ static VALUE ruby_curl_easy_downloaded_content_length_get(VALUE self) {
|
|
|
3583
4034
|
*/
|
|
3584
4035
|
static VALUE ruby_curl_easy_uploaded_content_length_get(VALUE self) {
|
|
3585
4036
|
ruby_curl_easy *rbce;
|
|
3586
|
-
|
|
4037
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3587
4038
|
|
|
3588
|
-
|
|
4039
|
+
#ifdef HAVE_CURLINFO_CONTENT_LENGTH_UPLOAD_T
|
|
4040
|
+
curl_off_t bytes;
|
|
4041
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_CONTENT_LENGTH_UPLOAD_T, &bytes);
|
|
4042
|
+
return LL2NUM(bytes);
|
|
4043
|
+
#else
|
|
4044
|
+
double bytes;
|
|
3589
4045
|
curl_easy_getinfo(rbce->curl, CURLINFO_CONTENT_LENGTH_UPLOAD, &bytes);
|
|
3590
|
-
|
|
3591
4046
|
return rb_float_new(bytes);
|
|
4047
|
+
#endif
|
|
3592
4048
|
}
|
|
3593
4049
|
|
|
3594
4050
|
/*
|
|
@@ -3604,7 +4060,7 @@ static VALUE ruby_curl_easy_content_type_get(VALUE self) {
|
|
|
3604
4060
|
ruby_curl_easy *rbce;
|
|
3605
4061
|
char* type;
|
|
3606
4062
|
|
|
3607
|
-
|
|
4063
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3608
4064
|
curl_easy_getinfo(rbce->curl, CURLINFO_CONTENT_TYPE, &type);
|
|
3609
4065
|
|
|
3610
4066
|
if (type && type[0]) { // curl returns empty string if none
|
|
@@ -3647,7 +4103,7 @@ static VALUE ruby_curl_easy_os_errno_get(VALUE self) {
|
|
|
3647
4103
|
ruby_curl_easy *rbce;
|
|
3648
4104
|
long result;
|
|
3649
4105
|
|
|
3650
|
-
|
|
4106
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3651
4107
|
curl_easy_getinfo(rbce->curl, CURLINFO_OS_ERRNO, &result);
|
|
3652
4108
|
|
|
3653
4109
|
return LONG2NUM(result);
|
|
@@ -3676,7 +4132,7 @@ static VALUE ruby_curl_easy_num_connects_get(VALUE self) {
|
|
|
3676
4132
|
ruby_curl_easy *rbce;
|
|
3677
4133
|
long result;
|
|
3678
4134
|
|
|
3679
|
-
|
|
4135
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3680
4136
|
curl_easy_getinfo(rbce->curl, CURLINFO_NUM_CONNECTS, &result);
|
|
3681
4137
|
|
|
3682
4138
|
return LONG2NUM(result);
|
|
@@ -3713,7 +4169,7 @@ static VALUE ruby_curl_easy_cookielist_get(VALUE self) {
|
|
|
3713
4169
|
struct curl_slist *cookie;
|
|
3714
4170
|
VALUE rb_cookies;
|
|
3715
4171
|
|
|
3716
|
-
|
|
4172
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3717
4173
|
curl_easy_getinfo(rbce->curl, CURLINFO_COOKIELIST, &cookies);
|
|
3718
4174
|
if (!cookies)
|
|
3719
4175
|
return Qnil;
|
|
@@ -3753,7 +4209,7 @@ static VALUE ruby_curl_easy_ftp_entry_path_get(VALUE self) {
|
|
|
3753
4209
|
ruby_curl_easy *rbce;
|
|
3754
4210
|
char* path = NULL;
|
|
3755
4211
|
|
|
3756
|
-
|
|
4212
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3757
4213
|
curl_easy_getinfo(rbce->curl, CURLINFO_FTP_ENTRY_PATH, &path);
|
|
3758
4214
|
|
|
3759
4215
|
if (path && path[0]) { // curl returns NULL or empty string if none
|
|
@@ -3773,7 +4229,7 @@ static VALUE ruby_curl_easy_ftp_entry_path_get(VALUE self) {
|
|
|
3773
4229
|
*/
|
|
3774
4230
|
static VALUE ruby_curl_easy_multi_get(VALUE self) {
|
|
3775
4231
|
ruby_curl_easy *rbce;
|
|
3776
|
-
|
|
4232
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3777
4233
|
return rbce->multi;
|
|
3778
4234
|
}
|
|
3779
4235
|
|
|
@@ -3783,7 +4239,12 @@ static VALUE ruby_curl_easy_multi_get(VALUE self) {
|
|
|
3783
4239
|
*/
|
|
3784
4240
|
static VALUE ruby_curl_easy_multi_set(VALUE self, VALUE multi) {
|
|
3785
4241
|
ruby_curl_easy *rbce;
|
|
3786
|
-
|
|
4242
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
4243
|
+
|
|
4244
|
+
if (!NIL_P(multi) && rb_obj_is_kind_of(multi, cCurlMulti) != Qtrue) {
|
|
4245
|
+
rb_raise(rb_eTypeError, "expected Curl::Multi or nil");
|
|
4246
|
+
}
|
|
4247
|
+
|
|
3787
4248
|
rbce->multi = multi;
|
|
3788
4249
|
return rbce->multi;
|
|
3789
4250
|
}
|
|
@@ -3794,7 +4255,7 @@ static VALUE ruby_curl_easy_multi_set(VALUE self, VALUE multi) {
|
|
|
3794
4255
|
*/
|
|
3795
4256
|
static VALUE ruby_curl_easy_last_result(VALUE self) {
|
|
3796
4257
|
ruby_curl_easy *rbce;
|
|
3797
|
-
|
|
4258
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3798
4259
|
return LONG2NUM(rbce->last_result);
|
|
3799
4260
|
}
|
|
3800
4261
|
|
|
@@ -3804,7 +4265,7 @@ static VALUE ruby_curl_easy_last_result(VALUE self) {
|
|
|
3804
4265
|
*/
|
|
3805
4266
|
static VALUE ruby_curl_easy_last_error(VALUE self) {
|
|
3806
4267
|
ruby_curl_easy *rbce;
|
|
3807
|
-
|
|
4268
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3808
4269
|
|
|
3809
4270
|
if (rbce->err_buf[0]) { // curl returns NULL or empty string if none
|
|
3810
4271
|
return rb_str_new2(rbce->err_buf);
|
|
@@ -3831,7 +4292,7 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3831
4292
|
long option = NUM2LONG(opt);
|
|
3832
4293
|
rb_io_t *open_f_ptr;
|
|
3833
4294
|
|
|
3834
|
-
|
|
4295
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3835
4296
|
|
|
3836
4297
|
switch (option) {
|
|
3837
4298
|
/* BEHAVIOR OPTIONS */
|
|
@@ -3853,9 +4314,11 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3853
4314
|
case CURLOPT_CUSTOMREQUEST:
|
|
3854
4315
|
curl_easy_setopt(rbce->curl, CURLOPT_CUSTOMREQUEST, NIL_P(val) ? NULL : StringValueCStr(val));
|
|
3855
4316
|
break;
|
|
3856
|
-
case CURLOPT_HTTP_VERSION:
|
|
3857
|
-
|
|
3858
|
-
|
|
4317
|
+
case CURLOPT_HTTP_VERSION: {
|
|
4318
|
+
long http_version = NIL_P(val) ? CURL_HTTP_VERSION_NONE : NUM2LONG(val);
|
|
4319
|
+
rbce->http_version = http_version;
|
|
4320
|
+
curl_easy_setopt(rbce->curl, CURLOPT_HTTP_VERSION, http_version);
|
|
4321
|
+
} break;
|
|
3859
4322
|
case CURLOPT_PROXY: {
|
|
3860
4323
|
VALUE proxy_url = val;
|
|
3861
4324
|
CURB_OBJECT_HSETTER(ruby_curl_easy, proxy_url);
|
|
@@ -3867,10 +4330,10 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3867
4330
|
case CURLOPT_HEADER:
|
|
3868
4331
|
case CURLOPT_NOPROGRESS:
|
|
3869
4332
|
case CURLOPT_NOSIGNAL:
|
|
3870
|
-
#
|
|
4333
|
+
#ifdef HAVE_CURLOPT_PATH_AS_IS
|
|
3871
4334
|
case CURLOPT_PATH_AS_IS:
|
|
3872
4335
|
#endif
|
|
3873
|
-
#
|
|
4336
|
+
#ifdef HAVE_CURLOPT_PIPEWAIT
|
|
3874
4337
|
case CURLOPT_PIPEWAIT:
|
|
3875
4338
|
#endif
|
|
3876
4339
|
case CURLOPT_HTTPGET:
|
|
@@ -3893,7 +4356,7 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3893
4356
|
curl_easy_setopt(rbce->curl, CURLOPT_MAXCONNECTS, NUM2LONG(val));
|
|
3894
4357
|
} break;
|
|
3895
4358
|
case CURLOPT_POSTFIELDS: {
|
|
3896
|
-
|
|
4359
|
+
ruby_curl_easy_post_body_set_with_mode(self, val, 0);
|
|
3897
4360
|
} break;
|
|
3898
4361
|
case CURLOPT_USERPWD: {
|
|
3899
4362
|
VALUE userpwd = val;
|
|
@@ -3903,7 +4366,7 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3903
4366
|
VALUE proxypwd = val;
|
|
3904
4367
|
CURB_OBJECT_HSETTER(ruby_curl_easy, proxypwd);
|
|
3905
4368
|
} break;
|
|
3906
|
-
#
|
|
4369
|
+
#ifdef HAVE_CURLOPT_NOPROXY
|
|
3907
4370
|
case CURLOPT_NOPROXY: {
|
|
3908
4371
|
VALUE noproxy = val;
|
|
3909
4372
|
CURB_OBJECT_HSETTER(ruby_curl_easy, noproxy);
|
|
@@ -3921,7 +4384,7 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3921
4384
|
VALUE cookiejar = val;
|
|
3922
4385
|
CURB_OBJECT_HSETTER(ruby_curl_easy, cookiejar);
|
|
3923
4386
|
} break;
|
|
3924
|
-
#
|
|
4387
|
+
#ifdef HAVE_CURLOPT_REQUEST_TARGET
|
|
3925
4388
|
case CURLOPT_REQUEST_TARGET: {
|
|
3926
4389
|
/* Forward request-target directly to libcurl as a string. */
|
|
3927
4390
|
curl_easy_setopt(rbce->curl, CURLOPT_REQUEST_TARGET, NIL_P(val) ? NULL : StringValueCStr(val));
|
|
@@ -3931,7 +4394,7 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3931
4394
|
curl_easy_setopt(rbce->curl, CURLOPT_TCP_NODELAY, NUM2LONG(val));
|
|
3932
4395
|
} break;
|
|
3933
4396
|
/* FTP-specific toggles */
|
|
3934
|
-
#
|
|
4397
|
+
#ifdef HAVE_CURLOPT_DIRLISTONLY
|
|
3935
4398
|
case CURLOPT_DIRLISTONLY: {
|
|
3936
4399
|
int type = rb_type(val);
|
|
3937
4400
|
VALUE value;
|
|
@@ -3945,7 +4408,7 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3945
4408
|
curl_easy_setopt(rbce->curl, CURLOPT_DIRLISTONLY, NUM2LONG(value));
|
|
3946
4409
|
} break;
|
|
3947
4410
|
#endif
|
|
3948
|
-
#
|
|
4411
|
+
#ifdef HAVE_CURLOPT_FTP_USE_EPSV
|
|
3949
4412
|
case CURLOPT_FTP_USE_EPSV: {
|
|
3950
4413
|
int type = rb_type(val);
|
|
3951
4414
|
VALUE value;
|
|
@@ -3959,7 +4422,7 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3959
4422
|
curl_easy_setopt(rbce->curl, CURLOPT_FTP_USE_EPSV, NUM2LONG(value));
|
|
3960
4423
|
} break;
|
|
3961
4424
|
#endif
|
|
3962
|
-
#
|
|
4425
|
+
#ifdef HAVE_CURLOPT_FTP_USE_EPRT
|
|
3963
4426
|
case CURLOPT_FTP_USE_EPRT: {
|
|
3964
4427
|
int type = rb_type(val);
|
|
3965
4428
|
VALUE value;
|
|
@@ -3973,7 +4436,7 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3973
4436
|
curl_easy_setopt(rbce->curl, CURLOPT_FTP_USE_EPRT, NUM2LONG(value));
|
|
3974
4437
|
} break;
|
|
3975
4438
|
#endif
|
|
3976
|
-
#
|
|
4439
|
+
#ifdef HAVE_CURLOPT_FTP_SKIP_PASV_IP
|
|
3977
4440
|
case CURLOPT_FTP_SKIP_PASV_IP: {
|
|
3978
4441
|
int type = rb_type(val);
|
|
3979
4442
|
VALUE value;
|
|
@@ -4002,32 +4465,32 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
4002
4465
|
case CURLOPT_FORBID_REUSE: {
|
|
4003
4466
|
curl_easy_setopt(rbce->curl, CURLOPT_FORBID_REUSE, NUM2LONG(val));
|
|
4004
4467
|
} break;
|
|
4005
|
-
#
|
|
4468
|
+
#ifdef HAVE_CURLOPT_GSSAPI_DELEGATION
|
|
4006
4469
|
case CURLOPT_GSSAPI_DELEGATION: {
|
|
4007
4470
|
curl_easy_setopt(rbce->curl, CURLOPT_GSSAPI_DELEGATION, NUM2LONG(val));
|
|
4008
4471
|
} break;
|
|
4009
4472
|
#endif
|
|
4010
|
-
#
|
|
4473
|
+
#ifdef HAVE_CURLOPT_UNIX_SOCKET_PATH
|
|
4011
4474
|
case CURLOPT_UNIX_SOCKET_PATH: {
|
|
4012
4475
|
curl_easy_setopt(rbce->curl, CURLOPT_UNIX_SOCKET_PATH, StringValueCStr(val));
|
|
4013
4476
|
} break;
|
|
4014
4477
|
#endif
|
|
4015
|
-
#
|
|
4478
|
+
#ifdef HAVE_CURLOPT_MAX_SEND_SPEED_LARGE
|
|
4016
4479
|
case CURLOPT_MAX_SEND_SPEED_LARGE: {
|
|
4017
4480
|
curl_easy_setopt(rbce->curl, CURLOPT_MAX_SEND_SPEED_LARGE, (curl_off_t) NUM2LL(val));
|
|
4018
4481
|
} break;
|
|
4019
4482
|
#endif
|
|
4020
|
-
#
|
|
4483
|
+
#ifdef HAVE_CURLOPT_MAX_RECV_SPEED_LARGE
|
|
4021
4484
|
case CURLOPT_MAX_RECV_SPEED_LARGE: {
|
|
4022
4485
|
curl_easy_setopt(rbce->curl, CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t) NUM2LL(val));
|
|
4023
4486
|
} break;
|
|
4024
4487
|
#endif
|
|
4025
|
-
#
|
|
4488
|
+
#ifdef HAVE_CURLOPT_MAXFILESIZE
|
|
4026
4489
|
case CURLOPT_MAXFILESIZE:
|
|
4027
4490
|
curl_easy_setopt(rbce->curl, CURLOPT_MAXFILESIZE, NUM2LONG(val));
|
|
4028
4491
|
break;
|
|
4029
4492
|
#endif
|
|
4030
|
-
#
|
|
4493
|
+
#ifdef HAVE_CURLOPT_TCP_KEEPALIVE
|
|
4031
4494
|
case CURLOPT_TCP_KEEPALIVE:
|
|
4032
4495
|
curl_easy_setopt(rbce->curl, CURLOPT_TCP_KEEPALIVE, NUM2LONG(val));
|
|
4033
4496
|
break;
|
|
@@ -4038,7 +4501,7 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
4038
4501
|
curl_easy_setopt(rbce->curl, CURLOPT_TCP_KEEPINTVL, NUM2LONG(val));
|
|
4039
4502
|
break;
|
|
4040
4503
|
#endif
|
|
4041
|
-
#
|
|
4504
|
+
#ifdef HAVE_CURLOPT_HAPROXYPROTOCOL
|
|
4042
4505
|
case CURLOPT_HAPROXYPROTOCOL:
|
|
4043
4506
|
curl_easy_setopt(rbce->curl, CURLOPT_HAPROXYPROTOCOL, NUM2LONG(val));
|
|
4044
4507
|
break;
|
|
@@ -4057,12 +4520,12 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
4057
4520
|
case CURLOPT_REDIR_PROTOCOLS:
|
|
4058
4521
|
curl_easy_setopt(rbce->curl, option, NUM2LONG(val));
|
|
4059
4522
|
break;
|
|
4060
|
-
#
|
|
4523
|
+
#ifdef HAVE_CURLOPT_SSL_SESSIONID_CACHE
|
|
4061
4524
|
case CURLOPT_SSL_SESSIONID_CACHE:
|
|
4062
4525
|
curl_easy_setopt(rbce->curl, CURLOPT_SSL_SESSIONID_CACHE, NUM2LONG(val));
|
|
4063
4526
|
break;
|
|
4064
4527
|
#endif
|
|
4065
|
-
#
|
|
4528
|
+
#ifdef HAVE_CURLOPT_COOKIELIST
|
|
4066
4529
|
case CURLOPT_COOKIELIST: {
|
|
4067
4530
|
/* Forward to libcurl */
|
|
4068
4531
|
curl_easy_setopt(rbce->curl, CURLOPT_COOKIELIST, StringValueCStr(val));
|
|
@@ -4082,14 +4545,15 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
4082
4545
|
}
|
|
4083
4546
|
} break;
|
|
4084
4547
|
#endif
|
|
4085
|
-
#
|
|
4548
|
+
#ifdef HAVE_CURLOPT_PROXY_SSL_VERIFYHOST
|
|
4086
4549
|
case CURLOPT_PROXY_SSL_VERIFYHOST:
|
|
4087
4550
|
curl_easy_setopt(rbce->curl, CURLOPT_PROXY_SSL_VERIFYHOST, NUM2LONG(val));
|
|
4088
4551
|
break;
|
|
4089
4552
|
#endif
|
|
4090
|
-
#
|
|
4553
|
+
#ifdef HAVE_CURLOPT_RESOLVE
|
|
4091
4554
|
case CURLOPT_RESOLVE: {
|
|
4092
4555
|
struct curl_slist *list = NULL;
|
|
4556
|
+
ruby_curl_easy_clear_resolve_list(rbce);
|
|
4093
4557
|
if (NIL_P(val)) {
|
|
4094
4558
|
/* When nil is passed, we clear any previous resolve list */
|
|
4095
4559
|
list = NULL;
|
|
@@ -4144,7 +4608,7 @@ static VALUE ruby_curl_easy_get_opt(VALUE self, VALUE opt) {
|
|
|
4144
4608
|
static VALUE ruby_curl_easy_inspect(VALUE self) {
|
|
4145
4609
|
char buf[64];
|
|
4146
4610
|
ruby_curl_easy *rbce;
|
|
4147
|
-
|
|
4611
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
4148
4612
|
/* if we don't have a url set... we'll crash... */
|
|
4149
4613
|
if( !rb_easy_nil("url") && rb_easy_type_check("url", T_STRING)) {
|
|
4150
4614
|
VALUE url = rb_easy_get("url");
|
|
@@ -4176,7 +4640,7 @@ static VALUE ruby_curl_easy_escape(VALUE self, VALUE svalue) {
|
|
|
4176
4640
|
VALUE rresult;
|
|
4177
4641
|
VALUE str = svalue;
|
|
4178
4642
|
|
|
4179
|
-
|
|
4643
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
4180
4644
|
|
|
4181
4645
|
/* NOTE: make sure the value is a string, if not call to_s */
|
|
4182
4646
|
if( rb_type(str) != T_STRING ) { str = rb_funcall(str,rb_intern("to_s"),0); }
|
|
@@ -4207,7 +4671,7 @@ static VALUE ruby_curl_easy_unescape(VALUE self, VALUE str) {
|
|
|
4207
4671
|
char *result;
|
|
4208
4672
|
VALUE rresult;
|
|
4209
4673
|
|
|
4210
|
-
|
|
4674
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
4211
4675
|
|
|
4212
4676
|
#if (LIBCURL_VERSION_NUM >= 0x070f04)
|
|
4213
4677
|
result = (char*)curl_easy_unescape(rbce->curl, StringValuePtr(str), (int)RSTRING_LEN(str), &rlen);
|
|
@@ -4256,6 +4720,8 @@ void init_curb_easy() {
|
|
|
4256
4720
|
/* Attributes for config next perform */
|
|
4257
4721
|
rb_define_method(cCurlEasy, "url", ruby_curl_easy_url_get, 0);
|
|
4258
4722
|
rb_define_method(cCurlEasy, "proxy_url", ruby_curl_easy_proxy_url_get, 0);
|
|
4723
|
+
rb_define_method(cCurlEasy, "http_version=", ruby_curl_easy_http_version_set, 1);
|
|
4724
|
+
rb_define_method(cCurlEasy, "http_version", ruby_curl_easy_http_version_get, 0);
|
|
4259
4725
|
|
|
4260
4726
|
rb_define_method(cCurlEasy, "proxy_headers=", ruby_curl_easy_proxy_headers_set, 1);
|
|
4261
4727
|
rb_define_method(cCurlEasy, "proxy_headers", ruby_curl_easy_proxy_headers_get, 0);
|
|
@@ -4429,6 +4895,7 @@ void init_curb_easy() {
|
|
|
4429
4895
|
|
|
4430
4896
|
rb_define_method(cCurlEasy, "multi", ruby_curl_easy_multi_get, 0);
|
|
4431
4897
|
rb_define_method(cCurlEasy, "multi=", ruby_curl_easy_multi_set, 1);
|
|
4898
|
+
rb_define_private_method(cCurlEasy, "_take_callback_error", ruby_curl_easy_take_callback_error, 0);
|
|
4432
4899
|
rb_define_method(cCurlEasy, "last_result", ruby_curl_easy_last_result, 0);
|
|
4433
4900
|
rb_define_method(cCurlEasy, "last_error", ruby_curl_easy_last_error, 0);
|
|
4434
4901
|
|