curb 1.2.2 → 1.3.1
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 +4 -4
- data/ext/curb_easy.c +608 -215
- 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 +47 -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 +450 -1
- data/tests/tc_curl_multi.rb +573 -59
- data/tests/tc_curl_native_coverage.rb +130 -0
- data/tests/tc_curl_postfield.rb +161 -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,96 @@ 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
|
+
struct stream_seek_call_args {
|
|
111
|
+
VALUE stream;
|
|
112
|
+
curl_off_t offset;
|
|
113
|
+
int origin;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
static VALUE call_stream_seek(VALUE argp) {
|
|
117
|
+
struct stream_seek_call_args *args = (struct stream_seek_call_args *)argp;
|
|
118
|
+
return rb_funcall(args->stream, rb_intern("seek"), 2, LL2NUM(args->offset), INT2NUM(args->origin));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
struct proc_data_call_args {
|
|
122
|
+
char *stream;
|
|
123
|
+
size_t size;
|
|
124
|
+
size_t nmemb;
|
|
125
|
+
VALUE proc;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
static VALUE call_proc_data_handler_wrapped(VALUE argp) {
|
|
129
|
+
struct proc_data_call_args *args = (struct proc_data_call_args *)argp;
|
|
130
|
+
return ULONG2NUM((unsigned long)proc_data_handler(args->stream, args->size, args->nmemb, args->proc));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
struct easy_callback_dispatch_args {
|
|
134
|
+
ruby_curl_easy *rbce;
|
|
135
|
+
VALUE (*func)(VALUE);
|
|
136
|
+
VALUE arg;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
static VALUE call_with_easy_callback_active(VALUE argp) {
|
|
140
|
+
struct easy_callback_dispatch_args *args = (struct easy_callback_dispatch_args *)argp;
|
|
141
|
+
return with_easy_callback_active(args->rbce, args->func, args->arg);
|
|
142
|
+
}
|
|
143
|
+
|
|
45
144
|
/* Default body handler appends to easy.body_data buffer */
|
|
46
145
|
static size_t default_body_handler(char *stream,
|
|
47
146
|
size_t size,
|
|
@@ -83,8 +182,12 @@ static size_t read_data_handler(void *ptr,
|
|
|
83
182
|
|
|
84
183
|
if (rb_respond_to(stream, rb_intern("read"))) {//if (rb_respond_to(stream, rb_intern("to_s"))) {
|
|
85
184
|
/* copy read_bytes from stream into ptr */
|
|
86
|
-
|
|
185
|
+
struct stream_read_call_args args;
|
|
186
|
+
args.stream = stream;
|
|
187
|
+
args.read_bytes = read_bytes;
|
|
188
|
+
VALUE str = with_easy_callback_active(rbce, call_stream_read, (VALUE)&args);
|
|
87
189
|
if( str != Qnil ) {
|
|
190
|
+
StringValue(str);
|
|
88
191
|
memcpy(ptr, RSTRING_PTR(str), RSTRING_LEN(str));
|
|
89
192
|
return RSTRING_LEN(str);
|
|
90
193
|
}
|
|
@@ -98,8 +201,9 @@ static size_t read_data_handler(void *ptr,
|
|
|
98
201
|
size_t len;
|
|
99
202
|
size_t remaining;
|
|
100
203
|
char *str_ptr;
|
|
101
|
-
|
|
102
|
-
str =
|
|
204
|
+
TypedData_Get_Struct(upload, ruby_curl_upload, &ruby_curl_upload_data_type, rbcu);
|
|
205
|
+
str = with_easy_callback_active(rbce, call_stream_to_s, stream);
|
|
206
|
+
StringValue(str);
|
|
103
207
|
len = RSTRING_LEN(str);
|
|
104
208
|
remaining = len - rbcu->offset;
|
|
105
209
|
str_ptr = RSTRING_PTR(str);
|
|
@@ -131,10 +235,14 @@ int seek_data_handler(ruby_curl_easy *rbce,
|
|
|
131
235
|
VALUE stream = ruby_curl_upload_stream_get(upload);
|
|
132
236
|
|
|
133
237
|
if (rb_respond_to(stream, rb_intern("seek"))) {
|
|
134
|
-
|
|
238
|
+
struct stream_seek_call_args args;
|
|
239
|
+
args.stream = stream;
|
|
240
|
+
args.offset = offset;
|
|
241
|
+
args.origin = SEEK_SET;
|
|
242
|
+
with_easy_callback_active(rbce, call_stream_seek, (VALUE)&args);
|
|
135
243
|
} else {
|
|
136
244
|
ruby_curl_upload *rbcu;
|
|
137
|
-
|
|
245
|
+
TypedData_Get_Struct(upload, ruby_curl_upload, &ruby_curl_upload_data_type, rbcu);
|
|
138
246
|
// This OK because curl only uses SEEK_SET as per the documentation
|
|
139
247
|
rbcu->offset = offset;
|
|
140
248
|
}
|
|
@@ -166,22 +274,40 @@ static size_t proc_data_handler_body(char *stream,
|
|
|
166
274
|
size_t nmemb,
|
|
167
275
|
ruby_curl_easy *rbce)
|
|
168
276
|
{
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
277
|
+
struct proc_data_call_args args;
|
|
278
|
+
struct easy_callback_dispatch_args dispatch_args;
|
|
279
|
+
VALUE procret;
|
|
280
|
+
args.stream = stream;
|
|
281
|
+
args.size = size;
|
|
282
|
+
args.nmemb = nmemb;
|
|
283
|
+
args.proc = rb_easy_get("body_proc");
|
|
284
|
+
|
|
285
|
+
dispatch_args.rbce = rbce;
|
|
286
|
+
dispatch_args.func = call_proc_data_handler_wrapped;
|
|
287
|
+
dispatch_args.arg = (VALUE)&args;
|
|
288
|
+
procret = rb_rescue(call_with_easy_callback_active, (VALUE)&dispatch_args, callback_exception_store_on_easy, (VALUE)rbce);
|
|
289
|
+
|
|
290
|
+
return ((procret == Qfalse) || (procret == Qnil)) ? 0 : NUM2ULONG(procret);
|
|
174
291
|
}
|
|
175
292
|
static size_t proc_data_handler_header(char *stream,
|
|
176
293
|
size_t size,
|
|
177
294
|
size_t nmemb,
|
|
178
295
|
ruby_curl_easy *rbce)
|
|
179
296
|
{
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
297
|
+
struct proc_data_call_args args;
|
|
298
|
+
struct easy_callback_dispatch_args dispatch_args;
|
|
299
|
+
VALUE procret;
|
|
300
|
+
args.stream = stream;
|
|
301
|
+
args.size = size;
|
|
302
|
+
args.nmemb = nmemb;
|
|
303
|
+
args.proc = rb_easy_get("header_proc");
|
|
304
|
+
|
|
305
|
+
dispatch_args.rbce = rbce;
|
|
306
|
+
dispatch_args.func = call_proc_data_handler_wrapped;
|
|
307
|
+
dispatch_args.arg = (VALUE)&args;
|
|
308
|
+
procret = rb_rescue(call_with_easy_callback_active, (VALUE)&dispatch_args, callback_exception_store_on_easy, (VALUE)rbce);
|
|
309
|
+
|
|
310
|
+
return ((procret == Qfalse) || (procret == Qnil)) ? 0 : NUM2ULONG(procret);
|
|
185
311
|
}
|
|
186
312
|
|
|
187
313
|
|
|
@@ -193,6 +319,8 @@ static VALUE call_progress_handler(VALUE ary) {
|
|
|
193
319
|
rb_ary_entry(ary, 4)); // rb_float_new(ulnow));
|
|
194
320
|
}
|
|
195
321
|
|
|
322
|
+
/* CURLOPT_PROGRESSFUNCTION callback (deprecated since 7.32.0) */
|
|
323
|
+
#ifndef HAVE_CURLOPT_XFERINFOFUNCTION
|
|
196
324
|
static int proc_progress_handler(void *clientp,
|
|
197
325
|
double dltotal,
|
|
198
326
|
double dlnow,
|
|
@@ -212,15 +340,46 @@ static int proc_progress_handler(void *clientp,
|
|
|
212
340
|
rb_ary_store(callargs, 3, rb_float_new(ultotal));
|
|
213
341
|
rb_ary_store(callargs, 4, rb_float_new(ulnow));
|
|
214
342
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
343
|
+
struct easy_callback_dispatch_args dispatch_args;
|
|
344
|
+
dispatch_args.rbce = rbce;
|
|
345
|
+
dispatch_args.func = call_progress_handler;
|
|
346
|
+
dispatch_args.arg = callargs;
|
|
347
|
+
procret = rb_rescue(call_with_easy_callback_active, (VALUE)&dispatch_args, callback_exception, Qnil);
|
|
348
|
+
|
|
349
|
+
return(((procret == Qfalse) || (procret == Qnil)) ? -1 : 0);
|
|
350
|
+
}
|
|
351
|
+
#endif
|
|
352
|
+
|
|
353
|
+
/* CURLOPT_XFERINFOFUNCTION callback (since 7.32.0, replaces PROGRESSFUNCTION) */
|
|
354
|
+
#ifdef HAVE_CURLOPT_XFERINFOFUNCTION
|
|
355
|
+
static int proc_xferinfo_handler(void *clientp,
|
|
356
|
+
curl_off_t dltotal,
|
|
357
|
+
curl_off_t dlnow,
|
|
358
|
+
curl_off_t ultotal,
|
|
359
|
+
curl_off_t ulnow) {
|
|
360
|
+
ruby_curl_easy *rbce = (ruby_curl_easy *)clientp;
|
|
361
|
+
VALUE proc = rb_easy_get("progress_proc");
|
|
362
|
+
if (proc == Qnil) {
|
|
363
|
+
return 0;
|
|
364
|
+
}
|
|
365
|
+
VALUE procret;
|
|
366
|
+
VALUE callargs = rb_ary_new2(5);
|
|
367
|
+
|
|
368
|
+
rb_ary_store(callargs, 0, proc);
|
|
369
|
+
rb_ary_store(callargs, 1, LL2NUM(dltotal));
|
|
370
|
+
rb_ary_store(callargs, 2, LL2NUM(dlnow));
|
|
371
|
+
rb_ary_store(callargs, 3, LL2NUM(ultotal));
|
|
372
|
+
rb_ary_store(callargs, 4, LL2NUM(ulnow));
|
|
373
|
+
|
|
374
|
+
struct easy_callback_dispatch_args dispatch_args;
|
|
375
|
+
dispatch_args.rbce = rbce;
|
|
376
|
+
dispatch_args.func = call_progress_handler;
|
|
377
|
+
dispatch_args.arg = callargs;
|
|
378
|
+
procret = rb_rescue(call_with_easy_callback_active, (VALUE)&dispatch_args, callback_exception, Qnil);
|
|
221
379
|
|
|
222
380
|
return(((procret == Qfalse) || (procret == Qnil)) ? -1 : 0);
|
|
223
381
|
}
|
|
382
|
+
#endif
|
|
224
383
|
|
|
225
384
|
static VALUE call_debug_handler(VALUE ary) {
|
|
226
385
|
return rb_funcall(rb_ary_entry(ary, 0), idCall, 2,
|
|
@@ -241,7 +400,11 @@ static int proc_debug_handler(CURL *curl,
|
|
|
241
400
|
rb_ary_store(callargs, 0, proc);
|
|
242
401
|
rb_ary_store(callargs, 1, INT2NUM(type));
|
|
243
402
|
rb_ary_store(callargs, 2, rb_str_new(data, data_len));
|
|
244
|
-
|
|
403
|
+
struct easy_callback_dispatch_args dispatch_args;
|
|
404
|
+
dispatch_args.rbce = rbce;
|
|
405
|
+
dispatch_args.func = call_debug_handler;
|
|
406
|
+
dispatch_args.arg = callargs;
|
|
407
|
+
rb_rescue(call_with_easy_callback_active, (VALUE)&dispatch_args, callback_exception, Qnil);
|
|
245
408
|
/* no way to indicate to libcurl that we should break out given an exception in the on_debug handler...
|
|
246
409
|
* this means exceptions will be swallowed
|
|
247
410
|
*/
|
|
@@ -249,53 +412,121 @@ static int proc_debug_handler(CURL *curl,
|
|
|
249
412
|
return 0;
|
|
250
413
|
}
|
|
251
414
|
|
|
252
|
-
/* ================== MARK/FREE
|
|
253
|
-
void curl_easy_mark(
|
|
254
|
-
|
|
255
|
-
if (
|
|
415
|
+
/* ================== MARK/FREE/SIZE FUNCS ==================*/
|
|
416
|
+
static void curl_easy_mark(void *ptr) {
|
|
417
|
+
ruby_curl_easy *rbce = (ruby_curl_easy *)ptr;
|
|
418
|
+
if (rbce) {
|
|
419
|
+
if (!NIL_P(rbce->opts)) { rb_gc_mark(rbce->opts); }
|
|
420
|
+
if (!NIL_P(rbce->multi)) { rb_gc_mark(rbce->multi); }
|
|
421
|
+
if (!NIL_P(rbce->callback_error)) { rb_gc_mark(rbce->callback_error); }
|
|
422
|
+
}
|
|
256
423
|
}
|
|
257
424
|
|
|
258
|
-
static void
|
|
259
|
-
if (!rbce) {
|
|
425
|
+
static void ruby_curl_easy_clear_headers_list(ruby_curl_easy *rbce) {
|
|
426
|
+
if (!rbce || !rbce->curl_headers) {
|
|
260
427
|
return;
|
|
261
428
|
}
|
|
429
|
+
if (rbce->curl) {
|
|
430
|
+
curl_easy_setopt(rbce->curl, CURLOPT_HTTPHEADER, NULL);
|
|
431
|
+
}
|
|
432
|
+
curl_slist_free_all(rbce->curl_headers);
|
|
433
|
+
rbce->curl_headers = NULL;
|
|
434
|
+
}
|
|
262
435
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
436
|
+
static void ruby_curl_easy_clear_proxy_headers_list(ruby_curl_easy *rbce) {
|
|
437
|
+
if (!rbce || !rbce->curl_proxy_headers) {
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
#ifdef HAVE_CURLOPT_PROXYHEADER
|
|
441
|
+
if (rbce->curl) {
|
|
442
|
+
curl_easy_setopt(rbce->curl, CURLOPT_PROXYHEADER, NULL);
|
|
443
|
+
}
|
|
444
|
+
#endif
|
|
445
|
+
curl_slist_free_all(rbce->curl_proxy_headers);
|
|
446
|
+
rbce->curl_proxy_headers = NULL;
|
|
447
|
+
}
|
|
266
448
|
|
|
267
|
-
|
|
449
|
+
static void ruby_curl_easy_clear_ftp_commands_list(ruby_curl_easy *rbce) {
|
|
450
|
+
if (!rbce || !rbce->curl_ftp_commands) {
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
if (rbce->curl) {
|
|
454
|
+
curl_easy_setopt(rbce->curl, CURLOPT_QUOTE, NULL);
|
|
455
|
+
}
|
|
456
|
+
curl_slist_free_all(rbce->curl_ftp_commands);
|
|
457
|
+
rbce->curl_ftp_commands = NULL;
|
|
458
|
+
}
|
|
268
459
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
curl_multi_remove_handle(rbcm->handle, rbce->curl);
|
|
277
|
-
}
|
|
278
|
-
rb_curl_multi_forget_easy(rbcm, rbce);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
460
|
+
static void ruby_curl_easy_clear_resolve_list(ruby_curl_easy *rbce) {
|
|
461
|
+
if (!rbce || !rbce->curl_resolve) {
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
#ifdef HAVE_CURLOPT_RESOLVE
|
|
465
|
+
if (rbce->curl) {
|
|
466
|
+
curl_easy_setopt(rbce->curl, CURLOPT_RESOLVE, NULL);
|
|
281
467
|
}
|
|
468
|
+
#endif
|
|
469
|
+
curl_slist_free_all(rbce->curl_resolve);
|
|
470
|
+
rbce->curl_resolve = NULL;
|
|
471
|
+
}
|
|
282
472
|
|
|
283
|
-
|
|
284
|
-
|
|
473
|
+
/* Legacy wrapper for external callers */
|
|
474
|
+
void ruby_curl_easy_mark(ruby_curl_easy *rbce) {
|
|
475
|
+
curl_easy_mark((void *)rbce);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
static ruby_curl_multi *ruby_curl_multi_pointer_if_compatible(VALUE multi_val) {
|
|
479
|
+
if (NIL_P(multi_val) || !RB_TYPE_P(multi_val, T_DATA)) {
|
|
480
|
+
return NULL;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
#if defined(RTYPEDDATA_P) && defined(RTYPEDDATA_TYPE) && defined(RTYPEDDATA_DATA)
|
|
484
|
+
if (!RTYPEDDATA_P(multi_val)) {
|
|
485
|
+
return NULL;
|
|
285
486
|
}
|
|
286
487
|
|
|
287
|
-
if (
|
|
288
|
-
|
|
488
|
+
if (RTYPEDDATA_TYPE(multi_val) != &ruby_curl_multi_data_type) {
|
|
489
|
+
return NULL;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
return (ruby_curl_multi *)RTYPEDDATA_DATA(multi_val);
|
|
493
|
+
#else
|
|
494
|
+
if (!rb_typeddata_is_kind_of(multi_val, &ruby_curl_multi_data_type)) {
|
|
495
|
+
return NULL;
|
|
289
496
|
}
|
|
290
497
|
|
|
291
|
-
|
|
292
|
-
|
|
498
|
+
return DATA_PTR(multi_val);
|
|
499
|
+
#endif
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
static void ruby_curl_easy_free(ruby_curl_easy *rbce) {
|
|
503
|
+
if (!rbce) {
|
|
504
|
+
return;
|
|
293
505
|
}
|
|
294
506
|
|
|
295
|
-
if (rbce->
|
|
296
|
-
|
|
507
|
+
if (!NIL_P(rbce->multi)) {
|
|
508
|
+
VALUE multi_val = rbce->multi;
|
|
509
|
+
ruby_curl_multi *rbcm = ruby_curl_multi_pointer_if_compatible(multi_val);
|
|
510
|
+
|
|
511
|
+
rbce->multi = Qnil;
|
|
512
|
+
|
|
513
|
+
if (rbcm) {
|
|
514
|
+
/* Best-effort: ensure the handle is detached from the multi to avoid
|
|
515
|
+
* libcurl retaining a dangling pointer to a soon-to-be cleaned-up easy
|
|
516
|
+
* handle. This path runs during GC, so it must not invoke Ruby APIs that
|
|
517
|
+
* can allocate or raise. */
|
|
518
|
+
if (rbcm->handle && rbce->curl) {
|
|
519
|
+
curl_multi_remove_handle(rbcm->handle, rbce->curl);
|
|
520
|
+
}
|
|
521
|
+
rb_curl_multi_forget_easy(rbcm, rbce);
|
|
522
|
+
}
|
|
297
523
|
}
|
|
298
524
|
|
|
525
|
+
ruby_curl_easy_clear_headers_list(rbce);
|
|
526
|
+
ruby_curl_easy_clear_proxy_headers_list(rbce);
|
|
527
|
+
ruby_curl_easy_clear_ftp_commands_list(rbce);
|
|
528
|
+
ruby_curl_easy_clear_resolve_list(rbce);
|
|
529
|
+
|
|
299
530
|
if (rbce->curl) {
|
|
300
531
|
/* disable any progress or debug events */
|
|
301
532
|
curl_easy_setopt(rbce->curl, CURLOPT_WRITEFUNCTION, NULL);
|
|
@@ -305,7 +536,11 @@ static void ruby_curl_easy_free(ruby_curl_easy *rbce) {
|
|
|
305
536
|
curl_easy_setopt(rbce->curl, CURLOPT_DEBUGFUNCTION, NULL);
|
|
306
537
|
curl_easy_setopt(rbce->curl, CURLOPT_DEBUGDATA, NULL);
|
|
307
538
|
curl_easy_setopt(rbce->curl, CURLOPT_VERBOSE, 0);
|
|
539
|
+
#ifdef HAVE_CURLOPT_XFERINFOFUNCTION
|
|
540
|
+
curl_easy_setopt(rbce->curl, CURLOPT_XFERINFOFUNCTION, NULL);
|
|
541
|
+
#else
|
|
308
542
|
curl_easy_setopt(rbce->curl, CURLOPT_PROGRESSFUNCTION, NULL);
|
|
543
|
+
#endif
|
|
309
544
|
curl_easy_setopt(rbce->curl, CURLOPT_NOPROGRESS, 1);
|
|
310
545
|
curl_easy_cleanup(rbce->curl);
|
|
311
546
|
rbce->curl = NULL;
|
|
@@ -314,11 +549,45 @@ static void ruby_curl_easy_free(ruby_curl_easy *rbce) {
|
|
|
314
549
|
rbce->self = Qnil;
|
|
315
550
|
}
|
|
316
551
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
552
|
+
/* TypedData-compatible free function */
|
|
553
|
+
static void curl_easy_free(void *ptr) {
|
|
554
|
+
ruby_curl_easy *rbce = (ruby_curl_easy *)ptr;
|
|
555
|
+
if (rbce) {
|
|
556
|
+
ruby_curl_easy_free(rbce);
|
|
557
|
+
free(rbce);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/* Legacy wrapper for external callers (e.g., curb_multi) */
|
|
562
|
+
void ruby_curl_easy_free_wrapper(ruby_curl_easy *rbce) {
|
|
563
|
+
curl_easy_free((void *)rbce);
|
|
320
564
|
}
|
|
321
565
|
|
|
566
|
+
static size_t curl_easy_memsize(const void *ptr) {
|
|
567
|
+
const ruby_curl_easy *rbce = (const ruby_curl_easy *)ptr;
|
|
568
|
+
size_t size = sizeof(ruby_curl_easy);
|
|
569
|
+
/* Note: We don't count curl_slist or CURL handle memory as they're
|
|
570
|
+
* managed by libcurl and would require complex introspection */
|
|
571
|
+
(void)rbce; /* silence unused warning */
|
|
572
|
+
return size;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
const rb_data_type_t ruby_curl_easy_data_type = {
|
|
576
|
+
"Curl::Easy",
|
|
577
|
+
{
|
|
578
|
+
curl_easy_mark,
|
|
579
|
+
curl_easy_free,
|
|
580
|
+
curl_easy_memsize,
|
|
581
|
+
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
|
582
|
+
NULL, /* compact - not needed */
|
|
583
|
+
#endif
|
|
584
|
+
},
|
|
585
|
+
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
|
586
|
+
NULL, NULL, /* parent, data */
|
|
587
|
+
RUBY_TYPED_FREE_IMMEDIATELY
|
|
588
|
+
#endif
|
|
589
|
+
};
|
|
590
|
+
|
|
322
591
|
|
|
323
592
|
/* ================= ALLOC METHODS ====================*/
|
|
324
593
|
|
|
@@ -354,6 +623,7 @@ static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
|
|
354
623
|
rbce->ssl_version = -1;
|
|
355
624
|
rbce->use_ssl = -1;
|
|
356
625
|
rbce->ftp_filemethod = -1;
|
|
626
|
+
rbce->http_version = CURL_HTTP_VERSION_NONE;
|
|
357
627
|
rbce->resolve_mode = CURL_IPRESOLVE_WHATEVER;
|
|
358
628
|
|
|
359
629
|
/* bool opts */
|
|
@@ -371,6 +641,7 @@ static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
|
|
371
641
|
rbce->cookielist_engine_enabled = 0;
|
|
372
642
|
rbce->ignore_content_length = 0;
|
|
373
643
|
rbce->callback_active = 0;
|
|
644
|
+
rbce->callback_error = Qnil;
|
|
374
645
|
rbce->last_result = 0;
|
|
375
646
|
}
|
|
376
647
|
|
|
@@ -387,7 +658,7 @@ static VALUE ruby_curl_easy_allocate(VALUE klass) {
|
|
|
387
658
|
rbce->opts = Qnil;
|
|
388
659
|
rbce->multi = Qnil;
|
|
389
660
|
ruby_curl_easy_zero(rbce);
|
|
390
|
-
return
|
|
661
|
+
return TypedData_Wrap_Struct(klass, &ruby_curl_easy_data_type, rbce);
|
|
391
662
|
}
|
|
392
663
|
|
|
393
664
|
/*
|
|
@@ -407,7 +678,7 @@ static VALUE ruby_curl_easy_initialize(int argc, VALUE *argv, VALUE self) {
|
|
|
407
678
|
|
|
408
679
|
rb_scan_args(argc, argv, "01&", &url, &blk);
|
|
409
680
|
|
|
410
|
-
|
|
681
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
411
682
|
|
|
412
683
|
/* handler */
|
|
413
684
|
rbce->curl = curl_easy_init();
|
|
@@ -465,7 +736,7 @@ static struct curl_slist *duplicate_curl_slist(struct curl_slist *list) {
|
|
|
465
736
|
static VALUE ruby_curl_easy_clone(VALUE self) {
|
|
466
737
|
ruby_curl_easy *rbce, *newrbce;
|
|
467
738
|
|
|
468
|
-
|
|
739
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
469
740
|
|
|
470
741
|
newrbce = ALLOC(ruby_curl_easy);
|
|
471
742
|
if (!newrbce) {
|
|
@@ -483,6 +754,7 @@ static VALUE ruby_curl_easy_clone(VALUE self) {
|
|
|
483
754
|
|
|
484
755
|
/* A cloned easy should not retain ownership reference to the original multi. */
|
|
485
756
|
newrbce->multi = Qnil;
|
|
757
|
+
newrbce->callback_error = Qnil;
|
|
486
758
|
|
|
487
759
|
if (rbce->opts != Qnil) {
|
|
488
760
|
newrbce->opts = rb_funcall(rbce->opts, rb_intern("dup"), 0);
|
|
@@ -491,7 +763,7 @@ static VALUE ruby_curl_easy_clone(VALUE self) {
|
|
|
491
763
|
/* Set the error buffer on the new curl handle using the new err_buf */
|
|
492
764
|
curl_easy_setopt(newrbce->curl, CURLOPT_ERRORBUFFER, newrbce->err_buf);
|
|
493
765
|
|
|
494
|
-
VALUE clone =
|
|
766
|
+
VALUE clone = TypedData_Wrap_Struct(cCurlEasy, &ruby_curl_easy_data_type, newrbce);
|
|
495
767
|
newrbce->self = clone;
|
|
496
768
|
curl_easy_setopt(newrbce->curl, CURLOPT_PRIVATE, (void*)newrbce);
|
|
497
769
|
|
|
@@ -510,7 +782,7 @@ static VALUE ruby_curl_easy_close(VALUE self) {
|
|
|
510
782
|
CURLcode ecode;
|
|
511
783
|
ruby_curl_easy *rbce;
|
|
512
784
|
|
|
513
|
-
|
|
785
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
514
786
|
|
|
515
787
|
if (rbce->callback_active) {
|
|
516
788
|
rb_raise(rb_eRuntimeError, "Cannot close an active curl handle within a callback");
|
|
@@ -554,7 +826,7 @@ static VALUE ruby_curl_easy_reset(VALUE self) {
|
|
|
554
826
|
CURLcode ecode;
|
|
555
827
|
ruby_curl_easy *rbce;
|
|
556
828
|
VALUE opts_dup;
|
|
557
|
-
|
|
829
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
558
830
|
|
|
559
831
|
if (rbce->callback_active) {
|
|
560
832
|
rb_raise(rb_eRuntimeError, "Cannot close an active curl handle within a callback");
|
|
@@ -562,6 +834,7 @@ static VALUE ruby_curl_easy_reset(VALUE self) {
|
|
|
562
834
|
|
|
563
835
|
opts_dup = rb_funcall(rbce->opts, rb_intern("dup"), 0);
|
|
564
836
|
|
|
837
|
+
ruby_curl_easy_cleanup(self, rbce);
|
|
565
838
|
curl_easy_reset(rbce->curl);
|
|
566
839
|
ruby_curl_easy_zero(rbce);
|
|
567
840
|
rbce->self = self;
|
|
@@ -574,18 +847,6 @@ static VALUE ruby_curl_easy_reset(VALUE self) {
|
|
|
574
847
|
raise_curl_easy_error_exception(ecode);
|
|
575
848
|
}
|
|
576
849
|
|
|
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
850
|
return opts_dup;
|
|
590
851
|
}
|
|
591
852
|
|
|
@@ -651,7 +912,7 @@ static VALUE ruby_curl_easy_proxy_headers_set(VALUE self, VALUE proxy_headers) {
|
|
|
651
912
|
static VALUE ruby_curl_easy_headers_get(VALUE self) {
|
|
652
913
|
ruby_curl_easy *rbce;
|
|
653
914
|
VALUE headers;
|
|
654
|
-
|
|
915
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
655
916
|
headers = rb_easy_get("headers");//rb_hash_aref(rbce->opts, rb_intern("headers"));
|
|
656
917
|
if (headers == Qnil) { headers = rb_easy_set("headers", rb_hash_new()); }
|
|
657
918
|
return headers;
|
|
@@ -686,7 +947,7 @@ static VALUE ruby_curl_easy_headers_get(VALUE self) {
|
|
|
686
947
|
static VALUE ruby_curl_easy_proxy_headers_get(VALUE self) {
|
|
687
948
|
ruby_curl_easy *rbce;
|
|
688
949
|
VALUE proxy_headers;
|
|
689
|
-
|
|
950
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
690
951
|
proxy_headers = rb_easy_get("proxy_headers");//rb_hash_aref(rbce->opts, rb_intern("proxy_headers"));
|
|
691
952
|
if (proxy_headers == Qnil) { proxy_headers = rb_easy_set("proxy_headers", rb_hash_new()); }
|
|
692
953
|
return proxy_headers;
|
|
@@ -917,43 +1178,63 @@ static VALUE ruby_curl_easy_useragent_get(VALUE self) {
|
|
|
917
1178
|
*
|
|
918
1179
|
* This is handy if you want to perform a POST against a Curl::Multi instance.
|
|
919
1180
|
*/
|
|
920
|
-
static VALUE
|
|
1181
|
+
static VALUE ruby_curl_easy_post_body_set_with_mode(VALUE self, VALUE post_body, int force_http_get_on_nil) {
|
|
921
1182
|
ruby_curl_easy *rbce;
|
|
922
1183
|
CURL *curl;
|
|
923
1184
|
|
|
1185
|
+
VALUE body_str;
|
|
1186
|
+
VALUE retained_body_str;
|
|
924
1187
|
char *data;
|
|
925
1188
|
long len;
|
|
926
1189
|
|
|
927
|
-
|
|
1190
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
928
1191
|
|
|
929
1192
|
curl = rbce->curl;
|
|
930
1193
|
|
|
931
1194
|
if ( post_body == Qnil ) {
|
|
932
1195
|
rb_easy_del("postdata_buffer");
|
|
933
|
-
curl_easy_setopt(curl,
|
|
1196
|
+
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, NULL);
|
|
1197
|
+
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 0);
|
|
1198
|
+
if (force_http_get_on_nil) {
|
|
1199
|
+
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
|
|
1200
|
+
}
|
|
934
1201
|
|
|
935
1202
|
} else {
|
|
936
1203
|
if (rb_type(post_body) == T_STRING) {
|
|
937
|
-
|
|
938
|
-
len = RSTRING_LEN(post_body);
|
|
1204
|
+
body_str = post_body;
|
|
939
1205
|
}
|
|
940
1206
|
else if (rb_respond_to(post_body, rb_intern("to_s"))) {
|
|
941
|
-
|
|
942
|
-
data = StringValuePtr(str_body);
|
|
943
|
-
len = RSTRING_LEN(post_body);
|
|
1207
|
+
body_str = rb_funcall(post_body, rb_intern("to_s"), 0);
|
|
944
1208
|
}
|
|
945
1209
|
else {
|
|
946
1210
|
rb_raise(rb_eRuntimeError, "post data must respond_to .to_s");
|
|
947
1211
|
}
|
|
948
1212
|
|
|
1213
|
+
StringValue(body_str);
|
|
1214
|
+
|
|
949
1215
|
// Store the string, since it has to hang around for the duration of the
|
|
950
1216
|
// request. See CURLOPT_POSTFIELDS in the libcurl docs.
|
|
951
|
-
|
|
952
|
-
|
|
1217
|
+
#ifdef HAVE_CURLOPT_COPYPOSTFIELDS
|
|
1218
|
+
/*
|
|
1219
|
+
* libcurl copies the bytes immediately for COPYPOSTFIELDS, so retain a
|
|
1220
|
+
* matching Ruby snapshot for post_body instead of the caller's mutable
|
|
1221
|
+
* source string.
|
|
1222
|
+
*/
|
|
1223
|
+
retained_body_str = rb_str_dup(body_str);
|
|
1224
|
+
#else
|
|
1225
|
+
retained_body_str = body_str;
|
|
1226
|
+
#endif
|
|
1227
|
+
data = StringValuePtr(retained_body_str);
|
|
1228
|
+
len = RSTRING_LEN(retained_body_str);
|
|
1229
|
+
rb_easy_set("postdata_buffer", retained_body_str);
|
|
953
1230
|
|
|
954
1231
|
curl_easy_setopt(curl, CURLOPT_POST, 1);
|
|
955
|
-
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
|
|
956
1232
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
|
|
1233
|
+
#ifdef HAVE_CURLOPT_COPYPOSTFIELDS
|
|
1234
|
+
curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, data);
|
|
1235
|
+
#else
|
|
1236
|
+
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
|
|
1237
|
+
#endif
|
|
957
1238
|
|
|
958
1239
|
return post_body;
|
|
959
1240
|
}
|
|
@@ -961,6 +1242,10 @@ static VALUE ruby_curl_easy_post_body_set(VALUE self, VALUE post_body) {
|
|
|
961
1242
|
return Qnil;
|
|
962
1243
|
}
|
|
963
1244
|
|
|
1245
|
+
static VALUE ruby_curl_easy_post_body_set(VALUE self, VALUE post_body) {
|
|
1246
|
+
return ruby_curl_easy_post_body_set_with_mode(self, post_body, 1);
|
|
1247
|
+
}
|
|
1248
|
+
|
|
964
1249
|
/*
|
|
965
1250
|
* call-seq:
|
|
966
1251
|
* easy.post_body => string or nil
|
|
@@ -985,7 +1270,7 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
|
|
|
985
1270
|
VALUE upload;
|
|
986
1271
|
VALUE headers;
|
|
987
1272
|
|
|
988
|
-
|
|
1273
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
989
1274
|
|
|
990
1275
|
upload = ruby_curl_upload_new(cCurlUpload);
|
|
991
1276
|
ruby_curl_upload_stream_set(upload,data);
|
|
@@ -996,13 +1281,16 @@ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
|
|
|
996
1281
|
is complete or terminated... */
|
|
997
1282
|
|
|
998
1283
|
curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
|
|
1284
|
+
curl_easy_setopt(curl, CURLOPT_POST, 0);
|
|
1285
|
+
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, NULL);
|
|
1286
|
+
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 0);
|
|
999
1287
|
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
|
|
1000
1288
|
curl_easy_setopt(curl, CURLOPT_READFUNCTION, (curl_read_callback)read_data_handler);
|
|
1001
|
-
#
|
|
1289
|
+
#ifdef HAVE_CURLOPT_SEEKFUNCTION
|
|
1002
1290
|
curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, (curl_seek_callback)seek_data_handler);
|
|
1003
1291
|
#endif
|
|
1004
1292
|
curl_easy_setopt(curl, CURLOPT_READDATA, rbce);
|
|
1005
|
-
#
|
|
1293
|
+
#ifdef HAVE_CURLOPT_SEEKDATA
|
|
1006
1294
|
curl_easy_setopt(curl, CURLOPT_SEEKDATA, rbce);
|
|
1007
1295
|
#endif
|
|
1008
1296
|
|
|
@@ -1238,7 +1526,7 @@ static VALUE ruby_curl_easy_http_auth_types_set(int argc, VALUE *argv, VALUE sel
|
|
|
1238
1526
|
long mask = 0;
|
|
1239
1527
|
|
|
1240
1528
|
rb_scan_args(argc, argv, "*", &args_ary);
|
|
1241
|
-
|
|
1529
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
1242
1530
|
|
|
1243
1531
|
len = RARRAY_LEN(args_ary);
|
|
1244
1532
|
|
|
@@ -1343,7 +1631,7 @@ static VALUE ruby_curl_easy_max_redirects_get(VALUE self) {
|
|
|
1343
1631
|
*/
|
|
1344
1632
|
static VALUE ruby_curl_easy_timeout_set(VALUE self, VALUE timeout_s) {
|
|
1345
1633
|
ruby_curl_easy *rbce;
|
|
1346
|
-
|
|
1634
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
1347
1635
|
|
|
1348
1636
|
if (Qnil == timeout_s || NUM2DBL(timeout_s) <= 0.0) {
|
|
1349
1637
|
rbce->timeout_ms = 0;
|
|
@@ -1366,7 +1654,7 @@ static VALUE ruby_curl_easy_timeout_set(VALUE self, VALUE timeout_s) {
|
|
|
1366
1654
|
*/
|
|
1367
1655
|
static VALUE ruby_curl_easy_timeout_get(VALUE self) {
|
|
1368
1656
|
ruby_curl_easy *rbce;
|
|
1369
|
-
|
|
1657
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
1370
1658
|
return DBL2NUM(rbce->timeout_ms / 1000.0);
|
|
1371
1659
|
}
|
|
1372
1660
|
|
|
@@ -1384,7 +1672,7 @@ static VALUE ruby_curl_easy_timeout_get(VALUE self) {
|
|
|
1384
1672
|
*/
|
|
1385
1673
|
static VALUE ruby_curl_easy_timeout_ms_set(VALUE self, VALUE timeout_ms) {
|
|
1386
1674
|
ruby_curl_easy *rbce;
|
|
1387
|
-
|
|
1675
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
1388
1676
|
|
|
1389
1677
|
if (Qnil == timeout_ms || NUM2DBL(timeout_ms) <= 0.0) {
|
|
1390
1678
|
rbce->timeout_ms = 0;
|
|
@@ -1404,7 +1692,7 @@ static VALUE ruby_curl_easy_timeout_ms_set(VALUE self, VALUE timeout_ms) {
|
|
|
1404
1692
|
*/
|
|
1405
1693
|
static VALUE ruby_curl_easy_timeout_ms_get(VALUE self) {
|
|
1406
1694
|
ruby_curl_easy *rbce;
|
|
1407
|
-
|
|
1695
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
1408
1696
|
return LONG2NUM(rbce->timeout_ms);
|
|
1409
1697
|
}
|
|
1410
1698
|
|
|
@@ -1602,7 +1890,7 @@ static VALUE ruby_curl_easy_max_recv_speed_large_get(VALUE self) {
|
|
|
1602
1890
|
* Set the HTTP Authentication username.
|
|
1603
1891
|
*/
|
|
1604
1892
|
static VALUE ruby_curl_easy_username_set(VALUE self, VALUE username) {
|
|
1605
|
-
#
|
|
1893
|
+
#ifdef HAVE_CURLOPT_USERNAME
|
|
1606
1894
|
CURB_OBJECT_HSETTER(ruby_curl_easy, username);
|
|
1607
1895
|
#else
|
|
1608
1896
|
return Qnil;
|
|
@@ -1616,7 +1904,7 @@ static VALUE ruby_curl_easy_username_set(VALUE self, VALUE username) {
|
|
|
1616
1904
|
* Get the current username
|
|
1617
1905
|
*/
|
|
1618
1906
|
static VALUE ruby_curl_easy_username_get(VALUE self) {
|
|
1619
|
-
#
|
|
1907
|
+
#ifdef HAVE_CURLOPT_USERNAME
|
|
1620
1908
|
CURB_OBJECT_HGETTER(ruby_curl_easy, username);
|
|
1621
1909
|
#else
|
|
1622
1910
|
return Qnil;
|
|
@@ -1630,7 +1918,7 @@ static VALUE ruby_curl_easy_username_get(VALUE self) {
|
|
|
1630
1918
|
* Set the HTTP Authentication password.
|
|
1631
1919
|
*/
|
|
1632
1920
|
static VALUE ruby_curl_easy_password_set(VALUE self, VALUE password) {
|
|
1633
|
-
#
|
|
1921
|
+
#ifdef HAVE_CURLOPT_PASSWORD
|
|
1634
1922
|
CURB_OBJECT_HSETTER(ruby_curl_easy, password);
|
|
1635
1923
|
#else
|
|
1636
1924
|
return Qnil;
|
|
@@ -1644,7 +1932,7 @@ static VALUE ruby_curl_easy_password_set(VALUE self, VALUE password) {
|
|
|
1644
1932
|
* Get the current password
|
|
1645
1933
|
*/
|
|
1646
1934
|
static VALUE ruby_curl_easy_password_get(VALUE self) {
|
|
1647
|
-
#
|
|
1935
|
+
#ifdef HAVE_CURLOPT_PASSWORD
|
|
1648
1936
|
CURB_OBJECT_HGETTER(ruby_curl_easy, password);
|
|
1649
1937
|
#else
|
|
1650
1938
|
return Qnil;
|
|
@@ -1877,7 +2165,7 @@ static VALUE ruby_curl_easy_use_netrc_q(VALUE self) {
|
|
|
1877
2165
|
*/
|
|
1878
2166
|
static VALUE ruby_curl_easy_autoreferer_set(VALUE self, VALUE autoreferer) {
|
|
1879
2167
|
ruby_curl_easy *rbce;
|
|
1880
|
-
|
|
2168
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
1881
2169
|
|
|
1882
2170
|
if (Qtrue == autoreferer) {
|
|
1883
2171
|
curl_easy_setopt(rbce->curl, CURLOPT_AUTOREFERER, 1);
|
|
@@ -2034,7 +2322,7 @@ static VALUE ruby_curl_easy_ignore_content_length_q(VALUE self) {
|
|
|
2034
2322
|
static VALUE ruby_curl_easy_resolve_mode(VALUE self) {
|
|
2035
2323
|
ruby_curl_easy *rbce;
|
|
2036
2324
|
unsigned short rm;
|
|
2037
|
-
|
|
2325
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
2038
2326
|
|
|
2039
2327
|
rm = rbce->resolve_mode;
|
|
2040
2328
|
|
|
@@ -2066,7 +2354,7 @@ static VALUE ruby_curl_easy_resolve_mode_set(VALUE self, VALUE resolve_mode) {
|
|
|
2066
2354
|
} else {
|
|
2067
2355
|
ruby_curl_easy *rbce;
|
|
2068
2356
|
ID resolve_mode_id;
|
|
2069
|
-
|
|
2357
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
2070
2358
|
|
|
2071
2359
|
resolve_mode_id = rb_to_id(resolve_mode);
|
|
2072
2360
|
|
|
@@ -2086,6 +2374,46 @@ static VALUE ruby_curl_easy_resolve_mode_set(VALUE self, VALUE resolve_mode) {
|
|
|
2086
2374
|
}
|
|
2087
2375
|
}
|
|
2088
2376
|
|
|
2377
|
+
/*
|
|
2378
|
+
* call-seq:
|
|
2379
|
+
* easy.http_version = Curl::HTTP_1_1 => Curl::HTTP_1_1
|
|
2380
|
+
*
|
|
2381
|
+
* Force libcurl to use a specific HTTP protocol version. By default libcurl
|
|
2382
|
+
* negotiates the highest version supported by both peers. Supported constants
|
|
2383
|
+
* include Curl::HTTP_NONE, Curl::HTTP_1_0, Curl::HTTP_1_1, Curl::HTTP_2_0,
|
|
2384
|
+
* Curl::HTTP_2TLS, and Curl::HTTP_2_PRIOR_KNOWLEDGE (when provided by libcurl).
|
|
2385
|
+
*/
|
|
2386
|
+
static VALUE ruby_curl_easy_http_version_set(VALUE self, VALUE version) {
|
|
2387
|
+
ruby_curl_easy *rbce;
|
|
2388
|
+
long http_version;
|
|
2389
|
+
|
|
2390
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
2391
|
+
|
|
2392
|
+
if (NIL_P(version)) {
|
|
2393
|
+
http_version = CURL_HTTP_VERSION_NONE;
|
|
2394
|
+
} else {
|
|
2395
|
+
http_version = NUM2LONG(version);
|
|
2396
|
+
}
|
|
2397
|
+
|
|
2398
|
+
rbce->http_version = http_version;
|
|
2399
|
+
|
|
2400
|
+
return version;
|
|
2401
|
+
}
|
|
2402
|
+
|
|
2403
|
+
/*
|
|
2404
|
+
* call-seq:
|
|
2405
|
+
* easy.http_version => integer
|
|
2406
|
+
*
|
|
2407
|
+
* Returns the HTTP protocol version currently configured.
|
|
2408
|
+
*/
|
|
2409
|
+
static VALUE ruby_curl_easy_http_version_get(VALUE self) {
|
|
2410
|
+
ruby_curl_easy *rbce;
|
|
2411
|
+
|
|
2412
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
2413
|
+
|
|
2414
|
+
return LONG2NUM(rbce->http_version);
|
|
2415
|
+
}
|
|
2416
|
+
|
|
2089
2417
|
|
|
2090
2418
|
/* ================= EVENT PROCS ================== */
|
|
2091
2419
|
|
|
@@ -2250,7 +2578,7 @@ static VALUE cb_each_http_header(VALUE header, VALUE wrap, int _c, const VALUE *
|
|
|
2250
2578
|
struct curl_slist **list;
|
|
2251
2579
|
VALUE header_str = Qnil;
|
|
2252
2580
|
|
|
2253
|
-
|
|
2581
|
+
TypedData_Get_Struct(wrap, struct curl_slist *, &curl_slist_ptr_type, list);
|
|
2254
2582
|
|
|
2255
2583
|
//rb_p(header);
|
|
2256
2584
|
|
|
@@ -2289,7 +2617,7 @@ static VALUE cb_each_http_proxy_header(VALUE proxy_header, VALUE wrap, int _c, c
|
|
|
2289
2617
|
struct curl_slist **list;
|
|
2290
2618
|
VALUE proxy_header_str = Qnil;
|
|
2291
2619
|
|
|
2292
|
-
|
|
2620
|
+
TypedData_Get_Struct(wrap, struct curl_slist *, &curl_slist_ptr_type, list);
|
|
2293
2621
|
|
|
2294
2622
|
//rb_p(proxy_header);
|
|
2295
2623
|
|
|
@@ -2324,7 +2652,7 @@ static VALUE cb_each_http_proxy_header(VALUE proxy_header, VALUE wrap, int _c, c
|
|
|
2324
2652
|
static VALUE cb_each_ftp_command(VALUE ftp_command, VALUE wrap, int _c, const VALUE *_ptr, VALUE unused) {
|
|
2325
2653
|
struct curl_slist **list;
|
|
2326
2654
|
VALUE ftp_command_string;
|
|
2327
|
-
|
|
2655
|
+
TypedData_Get_Struct(wrap, struct curl_slist *, &curl_slist_ptr_type, list);
|
|
2328
2656
|
|
|
2329
2657
|
ftp_command_string = rb_obj_as_string(ftp_command);
|
|
2330
2658
|
struct curl_slist *new_list = curl_slist_append(*list, StringValuePtr(ftp_command));
|
|
@@ -2342,7 +2670,7 @@ static VALUE cb_each_ftp_command(VALUE ftp_command, VALUE wrap, int _c, const VA
|
|
|
2342
2670
|
static VALUE cb_each_resolve(VALUE resolve, VALUE wrap, int _c, const VALUE *_ptr, VALUE unused) {
|
|
2343
2671
|
struct curl_slist **list;
|
|
2344
2672
|
VALUE resolve_string;
|
|
2345
|
-
|
|
2673
|
+
TypedData_Get_Struct(wrap, struct curl_slist *, &curl_slist_ptr_type, list);
|
|
2346
2674
|
|
|
2347
2675
|
resolve_string = rb_obj_as_string(resolve);
|
|
2348
2676
|
struct curl_slist *new_list = curl_slist_append(*list, StringValuePtr(resolve));
|
|
@@ -2370,6 +2698,7 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2370
2698
|
struct curl_slist **rslv = &(rbce->curl_resolve);
|
|
2371
2699
|
|
|
2372
2700
|
curl = rbce->curl;
|
|
2701
|
+
rbce->callback_error = Qnil;
|
|
2373
2702
|
|
|
2374
2703
|
if (_url == Qnil) {
|
|
2375
2704
|
rb_raise(eCurlErrError, "No URL supplied");
|
|
@@ -2385,7 +2714,7 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2385
2714
|
curl_easy_setopt(curl, CURLOPT_INTERFACE, NULL);
|
|
2386
2715
|
}
|
|
2387
2716
|
|
|
2388
|
-
#if HAVE_CURLOPT_USERNAME
|
|
2717
|
+
#if defined(HAVE_CURLOPT_USERNAME) && defined(HAVE_CURLOPT_PASSWORD)
|
|
2389
2718
|
if (!rb_easy_nil("username")) {
|
|
2390
2719
|
curl_easy_setopt(curl, CURLOPT_USERNAME, rb_easy_get_str("username"));
|
|
2391
2720
|
} else {
|
|
@@ -2401,7 +2730,7 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2401
2730
|
|
|
2402
2731
|
if (!rb_easy_nil("userpwd")) {
|
|
2403
2732
|
curl_easy_setopt(curl, CURLOPT_USERPWD, rb_easy_get_str("userpwd"));
|
|
2404
|
-
#if HAVE_CURLOPT_USERNAME
|
|
2733
|
+
#if defined(HAVE_CURLOPT_USERNAME) && defined(HAVE_CURLOPT_PASSWORD)
|
|
2405
2734
|
} 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
2735
|
#else
|
|
2407
2736
|
} else {
|
|
@@ -2421,7 +2750,7 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2421
2750
|
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, rb_easy_get_str("proxypwd"));
|
|
2422
2751
|
}
|
|
2423
2752
|
|
|
2424
|
-
#
|
|
2753
|
+
#ifdef HAVE_CURLOPT_NOPROXY
|
|
2425
2754
|
if (rb_easy_nil("noproxy")) {
|
|
2426
2755
|
curl_easy_setopt(curl, CURLOPT_NOPROXY, NULL);
|
|
2427
2756
|
} else {
|
|
@@ -2459,12 +2788,21 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2459
2788
|
|
|
2460
2789
|
// progress and debug procs
|
|
2461
2790
|
if (!rb_easy_nil("progress_proc")) {
|
|
2791
|
+
#ifdef HAVE_CURLOPT_XFERINFOFUNCTION
|
|
2792
|
+
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, &proc_xferinfo_handler);
|
|
2793
|
+
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, rbce);
|
|
2794
|
+
#else
|
|
2462
2795
|
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, (curl_progress_callback)&proc_progress_handler);
|
|
2463
2796
|
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, rbce);
|
|
2797
|
+
#endif
|
|
2464
2798
|
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
|
|
2465
2799
|
} else {
|
|
2466
2800
|
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
|
|
2801
|
+
#ifdef HAVE_CURLOPT_XFERINFOFUNCTION
|
|
2802
|
+
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, rbce);
|
|
2803
|
+
#else
|
|
2467
2804
|
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, rbce);
|
|
2805
|
+
#endif
|
|
2468
2806
|
}
|
|
2469
2807
|
|
|
2470
2808
|
if (!rb_easy_nil("debug_proc")) {
|
|
@@ -2504,12 +2842,12 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2504
2842
|
|
|
2505
2843
|
curl_easy_setopt(curl, CURLOPT_UNRESTRICTED_AUTH, rbce->unrestricted_auth);
|
|
2506
2844
|
|
|
2507
|
-
#
|
|
2845
|
+
#ifdef HAVE_CURLOPT_TIMEOUT_MS
|
|
2508
2846
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, rbce->timeout_ms);
|
|
2509
2847
|
#endif
|
|
2510
2848
|
|
|
2511
2849
|
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, rbce->connect_timeout);
|
|
2512
|
-
#
|
|
2850
|
+
#ifdef HAVE_CURLOPT_CONNECTTIMEOUT_MS
|
|
2513
2851
|
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, rbce->connect_timeout_ms);
|
|
2514
2852
|
#endif
|
|
2515
2853
|
curl_easy_setopt(curl, CURLOPT_DNS_CACHE_TIMEOUT, rbce->dns_cache_timeout);
|
|
@@ -2517,6 +2855,9 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2517
2855
|
curl_easy_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, rbce->ignore_content_length);
|
|
2518
2856
|
|
|
2519
2857
|
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, rbce->resolve_mode);
|
|
2858
|
+
#if HAVE_CURLOPT_HTTP_VERSION
|
|
2859
|
+
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, rbce->http_version);
|
|
2860
|
+
#endif
|
|
2520
2861
|
|
|
2521
2862
|
|
|
2522
2863
|
#if LIBCURL_VERSION_NUM >= 0x070a08
|
|
@@ -2656,8 +2997,8 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2656
2997
|
|
|
2657
2998
|
if (!rb_easy_nil("headers")) {
|
|
2658
2999
|
if (rb_easy_type_check("headers", T_ARRAY) || rb_easy_type_check("headers", T_HASH)) {
|
|
2659
|
-
VALUE wrap =
|
|
2660
|
-
|
|
3000
|
+
VALUE wrap = TypedData_Wrap_Struct(rb_cObject, &curl_slist_ptr_type, hdrs);
|
|
3001
|
+
rb_block_call(rb_easy_get("headers"), rb_intern("each"), 0, NULL, cb_each_http_header, wrap);
|
|
2661
3002
|
} else {
|
|
2662
3003
|
VALUE headers_str = rb_obj_as_string(rb_easy_get("headers"));
|
|
2663
3004
|
struct curl_slist *new_list = curl_slist_append(*hdrs, StringValuePtr(headers_str));
|
|
@@ -2672,14 +3013,14 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2672
3013
|
}
|
|
2673
3014
|
}
|
|
2674
3015
|
|
|
2675
|
-
#
|
|
3016
|
+
#ifdef HAVE_CURLOPT_PROXYHEADER
|
|
2676
3017
|
/* Setup HTTP proxy headers if necessary */
|
|
2677
3018
|
curl_easy_setopt(curl, CURLOPT_PROXYHEADER, NULL); // XXX: maybe we shouldn't be clearing this?
|
|
2678
3019
|
|
|
2679
3020
|
if (!rb_easy_nil("proxy_headers")) {
|
|
2680
3021
|
if (rb_easy_type_check("proxy_headers", T_ARRAY) || rb_easy_type_check("proxy_headers", T_HASH)) {
|
|
2681
|
-
VALUE wrap =
|
|
2682
|
-
|
|
3022
|
+
VALUE wrap = TypedData_Wrap_Struct(rb_cObject, &curl_slist_ptr_type, phdrs);
|
|
3023
|
+
rb_block_call(rb_easy_get("proxy_headers"), rb_intern("each"), 0, NULL, cb_each_http_proxy_header, wrap);
|
|
2683
3024
|
} else {
|
|
2684
3025
|
VALUE proxy_headers_str = rb_obj_as_string(rb_easy_get("proxy_headers"));
|
|
2685
3026
|
struct curl_slist *new_list = curl_slist_append(*phdrs, StringValuePtr(proxy_headers_str));
|
|
@@ -2698,8 +3039,8 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2698
3039
|
/* Setup FTP commands if necessary */
|
|
2699
3040
|
if (!rb_easy_nil("ftp_commands")) {
|
|
2700
3041
|
if (rb_easy_type_check("ftp_commands", T_ARRAY)) {
|
|
2701
|
-
VALUE wrap =
|
|
2702
|
-
|
|
3042
|
+
VALUE wrap = TypedData_Wrap_Struct(rb_cObject, &curl_slist_ptr_type, cmds);
|
|
3043
|
+
rb_block_call(rb_easy_get("ftp_commands"), rb_intern("each"), 0, NULL, cb_each_ftp_command, wrap);
|
|
2703
3044
|
}
|
|
2704
3045
|
|
|
2705
3046
|
if (*cmds) {
|
|
@@ -2707,12 +3048,12 @@ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
|
|
|
2707
3048
|
}
|
|
2708
3049
|
}
|
|
2709
3050
|
|
|
2710
|
-
#
|
|
3051
|
+
#ifdef HAVE_CURLOPT_RESOLVE
|
|
2711
3052
|
/* Setup resolve list if necessary */
|
|
2712
3053
|
if (!rb_easy_nil("resolve")) {
|
|
2713
3054
|
if (rb_easy_type_check("resolve", T_ARRAY)) {
|
|
2714
|
-
VALUE wrap =
|
|
2715
|
-
|
|
3055
|
+
VALUE wrap = TypedData_Wrap_Struct(rb_cObject, &curl_slist_ptr_type, rslv);
|
|
3056
|
+
rb_block_call(rb_easy_get("resolve"), rb_intern("each"), 0, NULL, cb_each_resolve, wrap);
|
|
2716
3057
|
}
|
|
2717
3058
|
|
|
2718
3059
|
if (*rslv) {
|
|
@@ -2735,27 +3076,17 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
|
|
|
2735
3076
|
struct curl_slist *ftp_commands;
|
|
2736
3077
|
struct curl_slist *resolve;
|
|
2737
3078
|
|
|
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
|
-
}
|
|
3079
|
+
ruby_curl_easy_clear_headers_list(rbce);
|
|
3080
|
+
ruby_curl_easy_clear_proxy_headers_list(rbce);
|
|
2748
3081
|
|
|
2749
3082
|
ftp_commands = rbce->curl_ftp_commands;
|
|
2750
3083
|
if (ftp_commands) {
|
|
2751
|
-
|
|
2752
|
-
rbce->curl_ftp_commands = NULL;
|
|
3084
|
+
ruby_curl_easy_clear_ftp_commands_list(rbce);
|
|
2753
3085
|
}
|
|
2754
3086
|
|
|
2755
3087
|
resolve = rbce->curl_resolve;
|
|
2756
3088
|
if (resolve) {
|
|
2757
|
-
|
|
2758
|
-
rbce->curl_resolve = NULL;
|
|
3089
|
+
ruby_curl_easy_clear_resolve_list(rbce);
|
|
2759
3090
|
}
|
|
2760
3091
|
|
|
2761
3092
|
/* clean up a PUT request's curl options. */
|
|
@@ -2781,7 +3112,7 @@ static VALUE ruby_curl_easy_perform_verb_str(VALUE self, const char *verb) {
|
|
|
2781
3112
|
CURL *curl;
|
|
2782
3113
|
VALUE retval;
|
|
2783
3114
|
|
|
2784
|
-
|
|
3115
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
2785
3116
|
curl = rbce->curl;
|
|
2786
3117
|
|
|
2787
3118
|
memset(rbce->err_buf, 0, CURL_ERROR_SIZE);
|
|
@@ -2837,6 +3168,27 @@ static VALUE ruby_curl_easy_perform_verb(VALUE self, VALUE verb) {
|
|
|
2837
3168
|
}
|
|
2838
3169
|
}
|
|
2839
3170
|
|
|
3171
|
+
static VALUE call_easy_perform(VALUE self) {
|
|
3172
|
+
return rb_funcall(self, rb_intern("perform"), 0);
|
|
3173
|
+
}
|
|
3174
|
+
|
|
3175
|
+
struct easy_form_perform_args {
|
|
3176
|
+
CURL *curl;
|
|
3177
|
+
struct curl_httppost *first;
|
|
3178
|
+
};
|
|
3179
|
+
|
|
3180
|
+
static VALUE ensure_free_form_post(VALUE argp) {
|
|
3181
|
+
struct easy_form_perform_args *args = (struct easy_form_perform_args *)argp;
|
|
3182
|
+
if (args->curl) {
|
|
3183
|
+
curl_easy_setopt(args->curl, CURLOPT_HTTPPOST, NULL);
|
|
3184
|
+
}
|
|
3185
|
+
if (args->first) {
|
|
3186
|
+
curl_formfree(args->first);
|
|
3187
|
+
args->first = NULL;
|
|
3188
|
+
}
|
|
3189
|
+
return Qnil;
|
|
3190
|
+
}
|
|
3191
|
+
|
|
2840
3192
|
/*
|
|
2841
3193
|
* call-seq:
|
|
2842
3194
|
* easy.http_post("url=encoded%20form%20data;and=so%20on") => true
|
|
@@ -2869,7 +3221,7 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
|
|
|
2869
3221
|
|
|
2870
3222
|
rb_scan_args(argc, argv, "*", &args_ary);
|
|
2871
3223
|
|
|
2872
|
-
|
|
3224
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
2873
3225
|
curl = rbce->curl;
|
|
2874
3226
|
|
|
2875
3227
|
memset(rbce->err_buf, 0, CURL_ERROR_SIZE);
|
|
@@ -2903,8 +3255,8 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
|
|
|
2903
3255
|
|
|
2904
3256
|
curl_easy_setopt(curl, CURLOPT_POST, 0);
|
|
2905
3257
|
curl_easy_setopt(curl, CURLOPT_HTTPPOST, first);
|
|
2906
|
-
|
|
2907
|
-
|
|
3258
|
+
struct easy_form_perform_args perform_args = { curl, first };
|
|
3259
|
+
ret = rb_ensure(call_easy_perform, self, ensure_free_form_post, (VALUE)&perform_args);
|
|
2908
3260
|
|
|
2909
3261
|
return ret;
|
|
2910
3262
|
} else {
|
|
@@ -2952,7 +3304,7 @@ static VALUE ruby_curl_easy_perform_patch(int argc, VALUE *argv, VALUE self) {
|
|
|
2952
3304
|
VALUE args_ary;
|
|
2953
3305
|
|
|
2954
3306
|
rb_scan_args(argc, argv, "*", &args_ary);
|
|
2955
|
-
|
|
3307
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
2956
3308
|
curl = rbce->curl;
|
|
2957
3309
|
|
|
2958
3310
|
/* Clear the error buffer */
|
|
@@ -2990,8 +3342,8 @@ static VALUE ruby_curl_easy_perform_patch(int argc, VALUE *argv, VALUE self) {
|
|
|
2990
3342
|
curl_easy_setopt(curl, CURLOPT_POST, 0);
|
|
2991
3343
|
/* Use the built multipart form as the request body */
|
|
2992
3344
|
curl_easy_setopt(curl, CURLOPT_HTTPPOST, first);
|
|
2993
|
-
|
|
2994
|
-
|
|
3345
|
+
struct easy_form_perform_args perform_args = { curl, first };
|
|
3346
|
+
ret = rb_ensure(call_easy_perform, self, ensure_free_form_post, (VALUE)&perform_args);
|
|
2995
3347
|
return ret;
|
|
2996
3348
|
} else {
|
|
2997
3349
|
/* Join arguments into a raw PATCH body */
|
|
@@ -3027,7 +3379,7 @@ static VALUE ruby_curl_easy_perform_put(int argc, VALUE *argv, VALUE self) {
|
|
|
3027
3379
|
int i;
|
|
3028
3380
|
|
|
3029
3381
|
rb_scan_args(argc, argv, "*", &args_ary);
|
|
3030
|
-
|
|
3382
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3031
3383
|
curl = rbce->curl;
|
|
3032
3384
|
|
|
3033
3385
|
memset(rbce->err_buf, 0, CURL_ERROR_SIZE);
|
|
@@ -3072,8 +3424,8 @@ static VALUE ruby_curl_easy_perform_put(int argc, VALUE *argv, VALUE self) {
|
|
|
3072
3424
|
curl_easy_setopt(curl, CURLOPT_HTTPPOST, first);
|
|
3073
3425
|
/* Set the method explicitly to PUT */
|
|
3074
3426
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
|
|
3075
|
-
|
|
3076
|
-
|
|
3427
|
+
struct easy_form_perform_args perform_args = { curl, first };
|
|
3428
|
+
ret = rb_ensure(call_easy_perform, self, ensure_free_form_post, (VALUE)&perform_args);
|
|
3077
3429
|
return ret;
|
|
3078
3430
|
}
|
|
3079
3431
|
/* Fallback: join all arguments */
|
|
@@ -3133,7 +3485,7 @@ static VALUE ruby_curl_easy_last_effective_url_get(VALUE self) {
|
|
|
3133
3485
|
ruby_curl_easy *rbce;
|
|
3134
3486
|
char* url;
|
|
3135
3487
|
|
|
3136
|
-
|
|
3488
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3137
3489
|
curl_easy_getinfo(rbce->curl, CURLINFO_EFFECTIVE_URL, &url);
|
|
3138
3490
|
|
|
3139
3491
|
if (url && url[0]) { // curl returns empty string if none
|
|
@@ -3156,7 +3508,7 @@ static VALUE ruby_curl_easy_response_code_get(VALUE self) {
|
|
|
3156
3508
|
ruby_curl_easy *rbce;
|
|
3157
3509
|
long code;
|
|
3158
3510
|
|
|
3159
|
-
|
|
3511
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3160
3512
|
#ifdef HAVE_CURLINFO_RESPONSE_CODE
|
|
3161
3513
|
curl_easy_getinfo(rbce->curl, CURLINFO_RESPONSE_CODE, &code);
|
|
3162
3514
|
#else
|
|
@@ -3180,7 +3532,7 @@ static VALUE ruby_curl_easy_primary_ip_get(VALUE self) {
|
|
|
3180
3532
|
ruby_curl_easy *rbce;
|
|
3181
3533
|
char* ip;
|
|
3182
3534
|
|
|
3183
|
-
|
|
3535
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3184
3536
|
curl_easy_getinfo(rbce->curl, CURLINFO_PRIMARY_IP, &ip);
|
|
3185
3537
|
|
|
3186
3538
|
if (ip && ip[0]) { // curl returns empty string if none
|
|
@@ -3201,7 +3553,7 @@ static VALUE ruby_curl_easy_http_connect_code_get(VALUE self) {
|
|
|
3201
3553
|
ruby_curl_easy *rbce;
|
|
3202
3554
|
long code;
|
|
3203
3555
|
|
|
3204
|
-
|
|
3556
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3205
3557
|
curl_easy_getinfo(rbce->curl, CURLINFO_HTTP_CONNECTCODE, &code);
|
|
3206
3558
|
|
|
3207
3559
|
return LONG2NUM(code);
|
|
@@ -3229,7 +3581,7 @@ static VALUE ruby_curl_easy_file_time_get(VALUE self) {
|
|
|
3229
3581
|
ruby_curl_easy *rbce;
|
|
3230
3582
|
long time;
|
|
3231
3583
|
|
|
3232
|
-
|
|
3584
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3233
3585
|
curl_easy_getinfo(rbce->curl, CURLINFO_FILETIME, &time);
|
|
3234
3586
|
|
|
3235
3587
|
return LONG2NUM(time);
|
|
@@ -3250,7 +3602,7 @@ static VALUE ruby_curl_easy_total_time_get(VALUE self) {
|
|
|
3250
3602
|
ruby_curl_easy *rbce;
|
|
3251
3603
|
double time;
|
|
3252
3604
|
|
|
3253
|
-
|
|
3605
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3254
3606
|
curl_easy_getinfo(rbce->curl, CURLINFO_TOTAL_TIME, &time);
|
|
3255
3607
|
|
|
3256
3608
|
return rb_float_new(time);
|
|
@@ -3267,7 +3619,7 @@ static VALUE ruby_curl_easy_name_lookup_time_get(VALUE self) {
|
|
|
3267
3619
|
ruby_curl_easy *rbce;
|
|
3268
3620
|
double time;
|
|
3269
3621
|
|
|
3270
|
-
|
|
3622
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3271
3623
|
curl_easy_getinfo(rbce->curl, CURLINFO_NAMELOOKUP_TIME, &time);
|
|
3272
3624
|
|
|
3273
3625
|
return rb_float_new(time);
|
|
@@ -3284,7 +3636,7 @@ static VALUE ruby_curl_easy_connect_time_get(VALUE self) {
|
|
|
3284
3636
|
ruby_curl_easy *rbce;
|
|
3285
3637
|
double time;
|
|
3286
3638
|
|
|
3287
|
-
|
|
3639
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3288
3640
|
curl_easy_getinfo(rbce->curl, CURLINFO_CONNECT_TIME, &time);
|
|
3289
3641
|
|
|
3290
3642
|
return rb_float_new(time);
|
|
@@ -3305,7 +3657,7 @@ static VALUE ruby_curl_easy_app_connect_time_get(VALUE self) {
|
|
|
3305
3657
|
ruby_curl_easy *rbce;
|
|
3306
3658
|
double time;
|
|
3307
3659
|
|
|
3308
|
-
|
|
3660
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3309
3661
|
curl_easy_getinfo(rbce->curl, CURLINFO_APPCONNECT_TIME, &time);
|
|
3310
3662
|
|
|
3311
3663
|
return rb_float_new(time);
|
|
@@ -3326,7 +3678,7 @@ static VALUE ruby_curl_easy_pre_transfer_time_get(VALUE self) {
|
|
|
3326
3678
|
ruby_curl_easy *rbce;
|
|
3327
3679
|
double time;
|
|
3328
3680
|
|
|
3329
|
-
|
|
3681
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3330
3682
|
curl_easy_getinfo(rbce->curl, CURLINFO_PRETRANSFER_TIME, &time);
|
|
3331
3683
|
|
|
3332
3684
|
return rb_float_new(time);
|
|
@@ -3344,7 +3696,7 @@ static VALUE ruby_curl_easy_start_transfer_time_get(VALUE self) {
|
|
|
3344
3696
|
ruby_curl_easy *rbce;
|
|
3345
3697
|
double time;
|
|
3346
3698
|
|
|
3347
|
-
|
|
3699
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3348
3700
|
curl_easy_getinfo(rbce->curl, CURLINFO_STARTTRANSFER_TIME, &time);
|
|
3349
3701
|
|
|
3350
3702
|
return rb_float_new(time);
|
|
@@ -3366,7 +3718,7 @@ static VALUE ruby_curl_easy_redirect_time_get(VALUE self) {
|
|
|
3366
3718
|
ruby_curl_easy *rbce;
|
|
3367
3719
|
double time;
|
|
3368
3720
|
|
|
3369
|
-
|
|
3721
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3370
3722
|
curl_easy_getinfo(rbce->curl, CURLINFO_REDIRECT_TIME, &time);
|
|
3371
3723
|
|
|
3372
3724
|
return rb_float_new(time);
|
|
@@ -3389,7 +3741,7 @@ static VALUE ruby_curl_easy_redirect_count_get(VALUE self) {
|
|
|
3389
3741
|
ruby_curl_easy *rbce;
|
|
3390
3742
|
long count;
|
|
3391
3743
|
|
|
3392
|
-
|
|
3744
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3393
3745
|
curl_easy_getinfo(rbce->curl, CURLINFO_REDIRECT_COUNT, &count);
|
|
3394
3746
|
|
|
3395
3747
|
return LONG2NUM(count);
|
|
@@ -3414,7 +3766,7 @@ static VALUE ruby_curl_easy_redirect_url_get(VALUE self) {
|
|
|
3414
3766
|
ruby_curl_easy *rbce;
|
|
3415
3767
|
char* url;
|
|
3416
3768
|
|
|
3417
|
-
|
|
3769
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3418
3770
|
curl_easy_getinfo(rbce->curl, CURLINFO_REDIRECT_URL, &url);
|
|
3419
3771
|
|
|
3420
3772
|
if (url && url[0]) { // curl returns empty string if none
|
|
@@ -3439,12 +3791,17 @@ static VALUE ruby_curl_easy_redirect_url_get(VALUE self) {
|
|
|
3439
3791
|
*/
|
|
3440
3792
|
static VALUE ruby_curl_easy_uploaded_bytes_get(VALUE self) {
|
|
3441
3793
|
ruby_curl_easy *rbce;
|
|
3442
|
-
|
|
3794
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3443
3795
|
|
|
3444
|
-
|
|
3796
|
+
#ifdef HAVE_CURLINFO_SIZE_UPLOAD_T
|
|
3797
|
+
curl_off_t bytes;
|
|
3798
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_SIZE_UPLOAD_T, &bytes);
|
|
3799
|
+
return LL2NUM(bytes);
|
|
3800
|
+
#else
|
|
3801
|
+
double bytes;
|
|
3445
3802
|
curl_easy_getinfo(rbce->curl, CURLINFO_SIZE_UPLOAD, &bytes);
|
|
3446
|
-
|
|
3447
3803
|
return rb_float_new(bytes);
|
|
3804
|
+
#endif
|
|
3448
3805
|
}
|
|
3449
3806
|
|
|
3450
3807
|
/*
|
|
@@ -3456,12 +3813,17 @@ static VALUE ruby_curl_easy_uploaded_bytes_get(VALUE self) {
|
|
|
3456
3813
|
*/
|
|
3457
3814
|
static VALUE ruby_curl_easy_downloaded_bytes_get(VALUE self) {
|
|
3458
3815
|
ruby_curl_easy *rbce;
|
|
3459
|
-
|
|
3816
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3460
3817
|
|
|
3461
|
-
|
|
3818
|
+
#ifdef HAVE_CURLINFO_SIZE_DOWNLOAD_T
|
|
3819
|
+
curl_off_t bytes;
|
|
3820
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_SIZE_DOWNLOAD_T, &bytes);
|
|
3821
|
+
return LL2NUM(bytes);
|
|
3822
|
+
#else
|
|
3823
|
+
double bytes;
|
|
3462
3824
|
curl_easy_getinfo(rbce->curl, CURLINFO_SIZE_DOWNLOAD, &bytes);
|
|
3463
|
-
|
|
3464
3825
|
return rb_float_new(bytes);
|
|
3826
|
+
#endif
|
|
3465
3827
|
}
|
|
3466
3828
|
|
|
3467
3829
|
/*
|
|
@@ -3473,12 +3835,17 @@ static VALUE ruby_curl_easy_downloaded_bytes_get(VALUE self) {
|
|
|
3473
3835
|
*/
|
|
3474
3836
|
static VALUE ruby_curl_easy_upload_speed_get(VALUE self) {
|
|
3475
3837
|
ruby_curl_easy *rbce;
|
|
3476
|
-
|
|
3838
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3477
3839
|
|
|
3478
|
-
|
|
3840
|
+
#ifdef HAVE_CURLINFO_SPEED_UPLOAD_T
|
|
3841
|
+
curl_off_t bytes;
|
|
3842
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_SPEED_UPLOAD_T, &bytes);
|
|
3843
|
+
return LL2NUM(bytes);
|
|
3844
|
+
#else
|
|
3845
|
+
double bytes;
|
|
3479
3846
|
curl_easy_getinfo(rbce->curl, CURLINFO_SPEED_UPLOAD, &bytes);
|
|
3480
|
-
|
|
3481
3847
|
return rb_float_new(bytes);
|
|
3848
|
+
#endif
|
|
3482
3849
|
}
|
|
3483
3850
|
|
|
3484
3851
|
/*
|
|
@@ -3490,12 +3857,17 @@ static VALUE ruby_curl_easy_upload_speed_get(VALUE self) {
|
|
|
3490
3857
|
*/
|
|
3491
3858
|
static VALUE ruby_curl_easy_download_speed_get(VALUE self) {
|
|
3492
3859
|
ruby_curl_easy *rbce;
|
|
3493
|
-
|
|
3860
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3494
3861
|
|
|
3495
|
-
|
|
3862
|
+
#ifdef HAVE_CURLINFO_SPEED_DOWNLOAD_T
|
|
3863
|
+
curl_off_t bytes;
|
|
3864
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_SPEED_DOWNLOAD_T, &bytes);
|
|
3865
|
+
return LL2NUM(bytes);
|
|
3866
|
+
#else
|
|
3867
|
+
double bytes;
|
|
3496
3868
|
curl_easy_getinfo(rbce->curl, CURLINFO_SPEED_DOWNLOAD, &bytes);
|
|
3497
|
-
|
|
3498
3869
|
return rb_float_new(bytes);
|
|
3870
|
+
#endif
|
|
3499
3871
|
}
|
|
3500
3872
|
|
|
3501
3873
|
/*
|
|
@@ -3509,7 +3881,7 @@ static VALUE ruby_curl_easy_header_size_get(VALUE self) {
|
|
|
3509
3881
|
ruby_curl_easy *rbce;
|
|
3510
3882
|
long size;
|
|
3511
3883
|
|
|
3512
|
-
|
|
3884
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3513
3885
|
curl_easy_getinfo(rbce->curl, CURLINFO_HEADER_SIZE, &size);
|
|
3514
3886
|
|
|
3515
3887
|
return LONG2NUM(size);
|
|
@@ -3527,7 +3899,7 @@ static VALUE ruby_curl_easy_request_size_get(VALUE self) {
|
|
|
3527
3899
|
ruby_curl_easy *rbce;
|
|
3528
3900
|
long size;
|
|
3529
3901
|
|
|
3530
|
-
|
|
3902
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3531
3903
|
curl_easy_getinfo(rbce->curl, CURLINFO_REQUEST_SIZE, &size);
|
|
3532
3904
|
|
|
3533
3905
|
return LONG2NUM(size);
|
|
@@ -3544,7 +3916,7 @@ static VALUE ruby_curl_easy_ssl_verify_result_get(VALUE self) {
|
|
|
3544
3916
|
ruby_curl_easy *rbce;
|
|
3545
3917
|
long result;
|
|
3546
3918
|
|
|
3547
|
-
|
|
3919
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3548
3920
|
curl_easy_getinfo(rbce->curl, CURLINFO_SSL_VERIFYRESULT, &result);
|
|
3549
3921
|
|
|
3550
3922
|
return LONG2NUM(result);
|
|
@@ -3567,12 +3939,17 @@ NOTE: you must call curl_slist_free_all(3) on the list pointer once you're done
|
|
|
3567
3939
|
*/
|
|
3568
3940
|
static VALUE ruby_curl_easy_downloaded_content_length_get(VALUE self) {
|
|
3569
3941
|
ruby_curl_easy *rbce;
|
|
3570
|
-
|
|
3942
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3571
3943
|
|
|
3572
|
-
|
|
3944
|
+
#ifdef HAVE_CURLINFO_CONTENT_LENGTH_DOWNLOAD_T
|
|
3945
|
+
curl_off_t bytes;
|
|
3946
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &bytes);
|
|
3947
|
+
return LL2NUM(bytes);
|
|
3948
|
+
#else
|
|
3949
|
+
double bytes;
|
|
3573
3950
|
curl_easy_getinfo(rbce->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &bytes);
|
|
3574
|
-
|
|
3575
3951
|
return rb_float_new(bytes);
|
|
3952
|
+
#endif
|
|
3576
3953
|
}
|
|
3577
3954
|
|
|
3578
3955
|
/*
|
|
@@ -3583,12 +3960,17 @@ static VALUE ruby_curl_easy_downloaded_content_length_get(VALUE self) {
|
|
|
3583
3960
|
*/
|
|
3584
3961
|
static VALUE ruby_curl_easy_uploaded_content_length_get(VALUE self) {
|
|
3585
3962
|
ruby_curl_easy *rbce;
|
|
3586
|
-
|
|
3963
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3587
3964
|
|
|
3588
|
-
|
|
3965
|
+
#ifdef HAVE_CURLINFO_CONTENT_LENGTH_UPLOAD_T
|
|
3966
|
+
curl_off_t bytes;
|
|
3967
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_CONTENT_LENGTH_UPLOAD_T, &bytes);
|
|
3968
|
+
return LL2NUM(bytes);
|
|
3969
|
+
#else
|
|
3970
|
+
double bytes;
|
|
3589
3971
|
curl_easy_getinfo(rbce->curl, CURLINFO_CONTENT_LENGTH_UPLOAD, &bytes);
|
|
3590
|
-
|
|
3591
3972
|
return rb_float_new(bytes);
|
|
3973
|
+
#endif
|
|
3592
3974
|
}
|
|
3593
3975
|
|
|
3594
3976
|
/*
|
|
@@ -3604,7 +3986,7 @@ static VALUE ruby_curl_easy_content_type_get(VALUE self) {
|
|
|
3604
3986
|
ruby_curl_easy *rbce;
|
|
3605
3987
|
char* type;
|
|
3606
3988
|
|
|
3607
|
-
|
|
3989
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3608
3990
|
curl_easy_getinfo(rbce->curl, CURLINFO_CONTENT_TYPE, &type);
|
|
3609
3991
|
|
|
3610
3992
|
if (type && type[0]) { // curl returns empty string if none
|
|
@@ -3647,7 +4029,7 @@ static VALUE ruby_curl_easy_os_errno_get(VALUE self) {
|
|
|
3647
4029
|
ruby_curl_easy *rbce;
|
|
3648
4030
|
long result;
|
|
3649
4031
|
|
|
3650
|
-
|
|
4032
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3651
4033
|
curl_easy_getinfo(rbce->curl, CURLINFO_OS_ERRNO, &result);
|
|
3652
4034
|
|
|
3653
4035
|
return LONG2NUM(result);
|
|
@@ -3676,7 +4058,7 @@ static VALUE ruby_curl_easy_num_connects_get(VALUE self) {
|
|
|
3676
4058
|
ruby_curl_easy *rbce;
|
|
3677
4059
|
long result;
|
|
3678
4060
|
|
|
3679
|
-
|
|
4061
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3680
4062
|
curl_easy_getinfo(rbce->curl, CURLINFO_NUM_CONNECTS, &result);
|
|
3681
4063
|
|
|
3682
4064
|
return LONG2NUM(result);
|
|
@@ -3713,7 +4095,7 @@ static VALUE ruby_curl_easy_cookielist_get(VALUE self) {
|
|
|
3713
4095
|
struct curl_slist *cookie;
|
|
3714
4096
|
VALUE rb_cookies;
|
|
3715
4097
|
|
|
3716
|
-
|
|
4098
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3717
4099
|
curl_easy_getinfo(rbce->curl, CURLINFO_COOKIELIST, &cookies);
|
|
3718
4100
|
if (!cookies)
|
|
3719
4101
|
return Qnil;
|
|
@@ -3753,7 +4135,7 @@ static VALUE ruby_curl_easy_ftp_entry_path_get(VALUE self) {
|
|
|
3753
4135
|
ruby_curl_easy *rbce;
|
|
3754
4136
|
char* path = NULL;
|
|
3755
4137
|
|
|
3756
|
-
|
|
4138
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3757
4139
|
curl_easy_getinfo(rbce->curl, CURLINFO_FTP_ENTRY_PATH, &path);
|
|
3758
4140
|
|
|
3759
4141
|
if (path && path[0]) { // curl returns NULL or empty string if none
|
|
@@ -3773,7 +4155,7 @@ static VALUE ruby_curl_easy_ftp_entry_path_get(VALUE self) {
|
|
|
3773
4155
|
*/
|
|
3774
4156
|
static VALUE ruby_curl_easy_multi_get(VALUE self) {
|
|
3775
4157
|
ruby_curl_easy *rbce;
|
|
3776
|
-
|
|
4158
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3777
4159
|
return rbce->multi;
|
|
3778
4160
|
}
|
|
3779
4161
|
|
|
@@ -3783,7 +4165,12 @@ static VALUE ruby_curl_easy_multi_get(VALUE self) {
|
|
|
3783
4165
|
*/
|
|
3784
4166
|
static VALUE ruby_curl_easy_multi_set(VALUE self, VALUE multi) {
|
|
3785
4167
|
ruby_curl_easy *rbce;
|
|
3786
|
-
|
|
4168
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
4169
|
+
|
|
4170
|
+
if (!NIL_P(multi) && rb_obj_is_kind_of(multi, cCurlMulti) != Qtrue) {
|
|
4171
|
+
rb_raise(rb_eTypeError, "expected Curl::Multi or nil");
|
|
4172
|
+
}
|
|
4173
|
+
|
|
3787
4174
|
rbce->multi = multi;
|
|
3788
4175
|
return rbce->multi;
|
|
3789
4176
|
}
|
|
@@ -3794,7 +4181,7 @@ static VALUE ruby_curl_easy_multi_set(VALUE self, VALUE multi) {
|
|
|
3794
4181
|
*/
|
|
3795
4182
|
static VALUE ruby_curl_easy_last_result(VALUE self) {
|
|
3796
4183
|
ruby_curl_easy *rbce;
|
|
3797
|
-
|
|
4184
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3798
4185
|
return LONG2NUM(rbce->last_result);
|
|
3799
4186
|
}
|
|
3800
4187
|
|
|
@@ -3804,7 +4191,7 @@ static VALUE ruby_curl_easy_last_result(VALUE self) {
|
|
|
3804
4191
|
*/
|
|
3805
4192
|
static VALUE ruby_curl_easy_last_error(VALUE self) {
|
|
3806
4193
|
ruby_curl_easy *rbce;
|
|
3807
|
-
|
|
4194
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3808
4195
|
|
|
3809
4196
|
if (rbce->err_buf[0]) { // curl returns NULL or empty string if none
|
|
3810
4197
|
return rb_str_new2(rbce->err_buf);
|
|
@@ -3831,7 +4218,7 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3831
4218
|
long option = NUM2LONG(opt);
|
|
3832
4219
|
rb_io_t *open_f_ptr;
|
|
3833
4220
|
|
|
3834
|
-
|
|
4221
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
3835
4222
|
|
|
3836
4223
|
switch (option) {
|
|
3837
4224
|
/* BEHAVIOR OPTIONS */
|
|
@@ -3853,9 +4240,11 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3853
4240
|
case CURLOPT_CUSTOMREQUEST:
|
|
3854
4241
|
curl_easy_setopt(rbce->curl, CURLOPT_CUSTOMREQUEST, NIL_P(val) ? NULL : StringValueCStr(val));
|
|
3855
4242
|
break;
|
|
3856
|
-
case CURLOPT_HTTP_VERSION:
|
|
3857
|
-
|
|
3858
|
-
|
|
4243
|
+
case CURLOPT_HTTP_VERSION: {
|
|
4244
|
+
long http_version = NIL_P(val) ? CURL_HTTP_VERSION_NONE : NUM2LONG(val);
|
|
4245
|
+
rbce->http_version = http_version;
|
|
4246
|
+
curl_easy_setopt(rbce->curl, CURLOPT_HTTP_VERSION, http_version);
|
|
4247
|
+
} break;
|
|
3859
4248
|
case CURLOPT_PROXY: {
|
|
3860
4249
|
VALUE proxy_url = val;
|
|
3861
4250
|
CURB_OBJECT_HSETTER(ruby_curl_easy, proxy_url);
|
|
@@ -3867,10 +4256,10 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3867
4256
|
case CURLOPT_HEADER:
|
|
3868
4257
|
case CURLOPT_NOPROGRESS:
|
|
3869
4258
|
case CURLOPT_NOSIGNAL:
|
|
3870
|
-
#
|
|
4259
|
+
#ifdef HAVE_CURLOPT_PATH_AS_IS
|
|
3871
4260
|
case CURLOPT_PATH_AS_IS:
|
|
3872
4261
|
#endif
|
|
3873
|
-
#
|
|
4262
|
+
#ifdef HAVE_CURLOPT_PIPEWAIT
|
|
3874
4263
|
case CURLOPT_PIPEWAIT:
|
|
3875
4264
|
#endif
|
|
3876
4265
|
case CURLOPT_HTTPGET:
|
|
@@ -3893,7 +4282,7 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3893
4282
|
curl_easy_setopt(rbce->curl, CURLOPT_MAXCONNECTS, NUM2LONG(val));
|
|
3894
4283
|
} break;
|
|
3895
4284
|
case CURLOPT_POSTFIELDS: {
|
|
3896
|
-
|
|
4285
|
+
ruby_curl_easy_post_body_set_with_mode(self, val, 0);
|
|
3897
4286
|
} break;
|
|
3898
4287
|
case CURLOPT_USERPWD: {
|
|
3899
4288
|
VALUE userpwd = val;
|
|
@@ -3903,7 +4292,7 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3903
4292
|
VALUE proxypwd = val;
|
|
3904
4293
|
CURB_OBJECT_HSETTER(ruby_curl_easy, proxypwd);
|
|
3905
4294
|
} break;
|
|
3906
|
-
#
|
|
4295
|
+
#ifdef HAVE_CURLOPT_NOPROXY
|
|
3907
4296
|
case CURLOPT_NOPROXY: {
|
|
3908
4297
|
VALUE noproxy = val;
|
|
3909
4298
|
CURB_OBJECT_HSETTER(ruby_curl_easy, noproxy);
|
|
@@ -3921,7 +4310,7 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3921
4310
|
VALUE cookiejar = val;
|
|
3922
4311
|
CURB_OBJECT_HSETTER(ruby_curl_easy, cookiejar);
|
|
3923
4312
|
} break;
|
|
3924
|
-
#
|
|
4313
|
+
#ifdef HAVE_CURLOPT_REQUEST_TARGET
|
|
3925
4314
|
case CURLOPT_REQUEST_TARGET: {
|
|
3926
4315
|
/* Forward request-target directly to libcurl as a string. */
|
|
3927
4316
|
curl_easy_setopt(rbce->curl, CURLOPT_REQUEST_TARGET, NIL_P(val) ? NULL : StringValueCStr(val));
|
|
@@ -3931,7 +4320,7 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3931
4320
|
curl_easy_setopt(rbce->curl, CURLOPT_TCP_NODELAY, NUM2LONG(val));
|
|
3932
4321
|
} break;
|
|
3933
4322
|
/* FTP-specific toggles */
|
|
3934
|
-
#
|
|
4323
|
+
#ifdef HAVE_CURLOPT_DIRLISTONLY
|
|
3935
4324
|
case CURLOPT_DIRLISTONLY: {
|
|
3936
4325
|
int type = rb_type(val);
|
|
3937
4326
|
VALUE value;
|
|
@@ -3945,7 +4334,7 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3945
4334
|
curl_easy_setopt(rbce->curl, CURLOPT_DIRLISTONLY, NUM2LONG(value));
|
|
3946
4335
|
} break;
|
|
3947
4336
|
#endif
|
|
3948
|
-
#
|
|
4337
|
+
#ifdef HAVE_CURLOPT_FTP_USE_EPSV
|
|
3949
4338
|
case CURLOPT_FTP_USE_EPSV: {
|
|
3950
4339
|
int type = rb_type(val);
|
|
3951
4340
|
VALUE value;
|
|
@@ -3959,7 +4348,7 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3959
4348
|
curl_easy_setopt(rbce->curl, CURLOPT_FTP_USE_EPSV, NUM2LONG(value));
|
|
3960
4349
|
} break;
|
|
3961
4350
|
#endif
|
|
3962
|
-
#
|
|
4351
|
+
#ifdef HAVE_CURLOPT_FTP_USE_EPRT
|
|
3963
4352
|
case CURLOPT_FTP_USE_EPRT: {
|
|
3964
4353
|
int type = rb_type(val);
|
|
3965
4354
|
VALUE value;
|
|
@@ -3973,7 +4362,7 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3973
4362
|
curl_easy_setopt(rbce->curl, CURLOPT_FTP_USE_EPRT, NUM2LONG(value));
|
|
3974
4363
|
} break;
|
|
3975
4364
|
#endif
|
|
3976
|
-
#
|
|
4365
|
+
#ifdef HAVE_CURLOPT_FTP_SKIP_PASV_IP
|
|
3977
4366
|
case CURLOPT_FTP_SKIP_PASV_IP: {
|
|
3978
4367
|
int type = rb_type(val);
|
|
3979
4368
|
VALUE value;
|
|
@@ -4002,32 +4391,32 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
4002
4391
|
case CURLOPT_FORBID_REUSE: {
|
|
4003
4392
|
curl_easy_setopt(rbce->curl, CURLOPT_FORBID_REUSE, NUM2LONG(val));
|
|
4004
4393
|
} break;
|
|
4005
|
-
#
|
|
4394
|
+
#ifdef HAVE_CURLOPT_GSSAPI_DELEGATION
|
|
4006
4395
|
case CURLOPT_GSSAPI_DELEGATION: {
|
|
4007
4396
|
curl_easy_setopt(rbce->curl, CURLOPT_GSSAPI_DELEGATION, NUM2LONG(val));
|
|
4008
4397
|
} break;
|
|
4009
4398
|
#endif
|
|
4010
|
-
#
|
|
4399
|
+
#ifdef HAVE_CURLOPT_UNIX_SOCKET_PATH
|
|
4011
4400
|
case CURLOPT_UNIX_SOCKET_PATH: {
|
|
4012
4401
|
curl_easy_setopt(rbce->curl, CURLOPT_UNIX_SOCKET_PATH, StringValueCStr(val));
|
|
4013
4402
|
} break;
|
|
4014
4403
|
#endif
|
|
4015
|
-
#
|
|
4404
|
+
#ifdef HAVE_CURLOPT_MAX_SEND_SPEED_LARGE
|
|
4016
4405
|
case CURLOPT_MAX_SEND_SPEED_LARGE: {
|
|
4017
4406
|
curl_easy_setopt(rbce->curl, CURLOPT_MAX_SEND_SPEED_LARGE, (curl_off_t) NUM2LL(val));
|
|
4018
4407
|
} break;
|
|
4019
4408
|
#endif
|
|
4020
|
-
#
|
|
4409
|
+
#ifdef HAVE_CURLOPT_MAX_RECV_SPEED_LARGE
|
|
4021
4410
|
case CURLOPT_MAX_RECV_SPEED_LARGE: {
|
|
4022
4411
|
curl_easy_setopt(rbce->curl, CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t) NUM2LL(val));
|
|
4023
4412
|
} break;
|
|
4024
4413
|
#endif
|
|
4025
|
-
#
|
|
4414
|
+
#ifdef HAVE_CURLOPT_MAXFILESIZE
|
|
4026
4415
|
case CURLOPT_MAXFILESIZE:
|
|
4027
4416
|
curl_easy_setopt(rbce->curl, CURLOPT_MAXFILESIZE, NUM2LONG(val));
|
|
4028
4417
|
break;
|
|
4029
4418
|
#endif
|
|
4030
|
-
#
|
|
4419
|
+
#ifdef HAVE_CURLOPT_TCP_KEEPALIVE
|
|
4031
4420
|
case CURLOPT_TCP_KEEPALIVE:
|
|
4032
4421
|
curl_easy_setopt(rbce->curl, CURLOPT_TCP_KEEPALIVE, NUM2LONG(val));
|
|
4033
4422
|
break;
|
|
@@ -4038,7 +4427,7 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
4038
4427
|
curl_easy_setopt(rbce->curl, CURLOPT_TCP_KEEPINTVL, NUM2LONG(val));
|
|
4039
4428
|
break;
|
|
4040
4429
|
#endif
|
|
4041
|
-
#
|
|
4430
|
+
#ifdef HAVE_CURLOPT_HAPROXYPROTOCOL
|
|
4042
4431
|
case CURLOPT_HAPROXYPROTOCOL:
|
|
4043
4432
|
curl_easy_setopt(rbce->curl, CURLOPT_HAPROXYPROTOCOL, NUM2LONG(val));
|
|
4044
4433
|
break;
|
|
@@ -4057,12 +4446,12 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
4057
4446
|
case CURLOPT_REDIR_PROTOCOLS:
|
|
4058
4447
|
curl_easy_setopt(rbce->curl, option, NUM2LONG(val));
|
|
4059
4448
|
break;
|
|
4060
|
-
#
|
|
4449
|
+
#ifdef HAVE_CURLOPT_SSL_SESSIONID_CACHE
|
|
4061
4450
|
case CURLOPT_SSL_SESSIONID_CACHE:
|
|
4062
4451
|
curl_easy_setopt(rbce->curl, CURLOPT_SSL_SESSIONID_CACHE, NUM2LONG(val));
|
|
4063
4452
|
break;
|
|
4064
4453
|
#endif
|
|
4065
|
-
#
|
|
4454
|
+
#ifdef HAVE_CURLOPT_COOKIELIST
|
|
4066
4455
|
case CURLOPT_COOKIELIST: {
|
|
4067
4456
|
/* Forward to libcurl */
|
|
4068
4457
|
curl_easy_setopt(rbce->curl, CURLOPT_COOKIELIST, StringValueCStr(val));
|
|
@@ -4082,14 +4471,15 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
4082
4471
|
}
|
|
4083
4472
|
} break;
|
|
4084
4473
|
#endif
|
|
4085
|
-
#
|
|
4474
|
+
#ifdef HAVE_CURLOPT_PROXY_SSL_VERIFYHOST
|
|
4086
4475
|
case CURLOPT_PROXY_SSL_VERIFYHOST:
|
|
4087
4476
|
curl_easy_setopt(rbce->curl, CURLOPT_PROXY_SSL_VERIFYHOST, NUM2LONG(val));
|
|
4088
4477
|
break;
|
|
4089
4478
|
#endif
|
|
4090
|
-
#
|
|
4479
|
+
#ifdef HAVE_CURLOPT_RESOLVE
|
|
4091
4480
|
case CURLOPT_RESOLVE: {
|
|
4092
4481
|
struct curl_slist *list = NULL;
|
|
4482
|
+
ruby_curl_easy_clear_resolve_list(rbce);
|
|
4093
4483
|
if (NIL_P(val)) {
|
|
4094
4484
|
/* When nil is passed, we clear any previous resolve list */
|
|
4095
4485
|
list = NULL;
|
|
@@ -4144,7 +4534,7 @@ static VALUE ruby_curl_easy_get_opt(VALUE self, VALUE opt) {
|
|
|
4144
4534
|
static VALUE ruby_curl_easy_inspect(VALUE self) {
|
|
4145
4535
|
char buf[64];
|
|
4146
4536
|
ruby_curl_easy *rbce;
|
|
4147
|
-
|
|
4537
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
4148
4538
|
/* if we don't have a url set... we'll crash... */
|
|
4149
4539
|
if( !rb_easy_nil("url") && rb_easy_type_check("url", T_STRING)) {
|
|
4150
4540
|
VALUE url = rb_easy_get("url");
|
|
@@ -4176,7 +4566,7 @@ static VALUE ruby_curl_easy_escape(VALUE self, VALUE svalue) {
|
|
|
4176
4566
|
VALUE rresult;
|
|
4177
4567
|
VALUE str = svalue;
|
|
4178
4568
|
|
|
4179
|
-
|
|
4569
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
4180
4570
|
|
|
4181
4571
|
/* NOTE: make sure the value is a string, if not call to_s */
|
|
4182
4572
|
if( rb_type(str) != T_STRING ) { str = rb_funcall(str,rb_intern("to_s"),0); }
|
|
@@ -4207,7 +4597,7 @@ static VALUE ruby_curl_easy_unescape(VALUE self, VALUE str) {
|
|
|
4207
4597
|
char *result;
|
|
4208
4598
|
VALUE rresult;
|
|
4209
4599
|
|
|
4210
|
-
|
|
4600
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
4211
4601
|
|
|
4212
4602
|
#if (LIBCURL_VERSION_NUM >= 0x070f04)
|
|
4213
4603
|
result = (char*)curl_easy_unescape(rbce->curl, StringValuePtr(str), (int)RSTRING_LEN(str), &rlen);
|
|
@@ -4256,6 +4646,8 @@ void init_curb_easy() {
|
|
|
4256
4646
|
/* Attributes for config next perform */
|
|
4257
4647
|
rb_define_method(cCurlEasy, "url", ruby_curl_easy_url_get, 0);
|
|
4258
4648
|
rb_define_method(cCurlEasy, "proxy_url", ruby_curl_easy_proxy_url_get, 0);
|
|
4649
|
+
rb_define_method(cCurlEasy, "http_version=", ruby_curl_easy_http_version_set, 1);
|
|
4650
|
+
rb_define_method(cCurlEasy, "http_version", ruby_curl_easy_http_version_get, 0);
|
|
4259
4651
|
|
|
4260
4652
|
rb_define_method(cCurlEasy, "proxy_headers=", ruby_curl_easy_proxy_headers_set, 1);
|
|
4261
4653
|
rb_define_method(cCurlEasy, "proxy_headers", ruby_curl_easy_proxy_headers_get, 0);
|
|
@@ -4429,6 +4821,7 @@ void init_curb_easy() {
|
|
|
4429
4821
|
|
|
4430
4822
|
rb_define_method(cCurlEasy, "multi", ruby_curl_easy_multi_get, 0);
|
|
4431
4823
|
rb_define_method(cCurlEasy, "multi=", ruby_curl_easy_multi_set, 1);
|
|
4824
|
+
rb_define_private_method(cCurlEasy, "_take_callback_error", ruby_curl_easy_take_callback_error, 0);
|
|
4432
4825
|
rb_define_method(cCurlEasy, "last_result", ruby_curl_easy_last_result, 0);
|
|
4433
4826
|
rb_define_method(cCurlEasy, "last_error", ruby_curl_easy_last_error, 0);
|
|
4434
4827
|
|