curb 1.3.7 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +38 -1
- data/Rakefile +12 -1
- data/ext/curb.c +17 -4
- data/ext/curb.h +4 -4
- data/ext/curb_easy.c +71 -31
- data/ext/curb_easy.h +1 -0
- data/ext/curb_multi.c +428 -95
- data/ext/curb_multi.h +4 -0
- data/ext/curb_postfield.c +31 -31
- data/ext/extconf.rb +6 -0
- data/lib/curl/easy.rb +18 -9
- data/lib/curl.rb +49 -12
- data/tests/helper.rb +122 -3
- data/tests/tc_curl_easy.rb +59 -4
- data/tests/tc_curl_easy_cookielist.rb +8 -4
- data/tests/tc_curl_multi.rb +29 -0
- data/tests/tc_curl_multi_poll.rb +223 -0
- data/tests/tc_curl_multi_socket_poller.rb +374 -0
- data/tests/tc_curl_postfield.rb +39 -0
- data/tests/tc_fiber_scheduler.rb +101 -2
- data/tests/tc_ractor.rb +94 -0
- metadata +8 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9f3088ba29db67ea56c9587898267648a704c8acbcb9e95cb58318c3464deb12
|
|
4
|
+
data.tar.gz: 40134cd41f0704c2aaa3b65ca6507987f6e8bc755c4530c9361ccd25f4831c17
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 29ffbf5bb4301db5729aff433a938251622c8483a29f5fa0f5344b52573048964c9863d00d254b42d01ff172291a1b469ea10f1fa9757b58fe4743a66c7078a5
|
|
7
|
+
data.tar.gz: d2e21e48891f398af31a7b2dd8d99a2465f82bb97d9caecda8ac4cb69fb599e894c3172bc56a6106a28d7761b03743fc78ee80701b3051ac673b7b6f1ed27ea9
|
data/README.md
CHANGED
|
@@ -205,7 +205,7 @@ end
|
|
|
205
205
|
`curb` is a libcurl binding and intentionally supports protocols beyond HTTP.
|
|
206
206
|
Do not pass untrusted URLs to `Curl.get`, `Curl::Easy.new`, or related raw
|
|
207
207
|
helpers without application-level validation. For user-supplied URLs, enable the
|
|
208
|
-
|
|
208
|
+
safety policy for the current Ractor before making requests:
|
|
209
209
|
|
|
210
210
|
```ruby
|
|
211
211
|
Curl.safe! do |config|
|
|
@@ -257,6 +257,42 @@ configured. For untrusted or large responses, use `on_body`, `download`, and/or
|
|
|
257
257
|
`max_body_bytes` is enforced for downloads as well as buffered responses and
|
|
258
258
|
custom body callbacks.
|
|
259
259
|
|
|
260
|
+
## Ractor support
|
|
261
|
+
|
|
262
|
+
On Ruby 3.0+, curb can perform requests from multiple Ractors when it is built
|
|
263
|
+
against a libcurl that reports the `CURL_VERSION_THREADSAFE` capability
|
|
264
|
+
(libcurl 7.84.0 or newer). Check `Curl::RACTOR_SAFE` at runtime. Builds that do
|
|
265
|
+
not meet those requirements continue to work in the main Ractor but do not
|
|
266
|
+
advertise native Ractor safety.
|
|
267
|
+
|
|
268
|
+
Create `Curl::Easy` and `Curl::Multi` handles inside the Ractor that uses them;
|
|
269
|
+
do not operate on the same native handle concurrently from different Ractors.
|
|
270
|
+
Safety configuration, `Curl::Multi.default_timeout`, `Curl::Multi.autoclose`,
|
|
271
|
+
and deferred cleanup queues are isolated per Ractor. Call `Curl.safe!` in each
|
|
272
|
+
Ractor that needs the safety policy:
|
|
273
|
+
|
|
274
|
+
```ruby
|
|
275
|
+
raise "this curb build is not Ractor-safe" unless Curl::RACTOR_SAFE
|
|
276
|
+
|
|
277
|
+
workers = 4.times.map do
|
|
278
|
+
Ractor.new do
|
|
279
|
+
Curl.safe! { |config| config.protocols = [:http, :https] }
|
|
280
|
+
easy = Curl::Easy.new("https://example.com/")
|
|
281
|
+
easy.perform
|
|
282
|
+
easy.response_code
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
# Ruby 4.0 uses Ractor#value; earlier Ractor releases use Ractor#take.
|
|
287
|
+
statuses = workers.map do |worker|
|
|
288
|
+
worker.respond_to?(:value) ? worker.value : worker.take
|
|
289
|
+
end
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Curb enables `CURLOPT_NOSIGNAL` on newly initialized and reset Easy handles by
|
|
293
|
+
default so separate handles can be used safely from parallel Ruby execution.
|
|
294
|
+
Applications can still override the option explicitly when required.
|
|
295
|
+
|
|
260
296
|
## You will need
|
|
261
297
|
|
|
262
298
|
* A working Ruby installation (`2.0.0+` will work but `2.1+` preferred) (it's possible it still works with 1.8.7 but you'd have to tell me if not...)
|
|
@@ -278,6 +314,7 @@ an explicit CI target.
|
|
|
278
314
|
|
|
279
315
|
| Gem Version | Release Date | libcurl versions |
|
|
280
316
|
| ----------- | -------------- | ----------------- |
|
|
317
|
+
| 1.4.0 | Sep 27, 2026 | 7.58 – 8.21.0 |
|
|
281
318
|
| 1.3.7 | Jul 10, 2026 | 7.58 – 8.21.0 |
|
|
282
319
|
| 1.3.6 | Jun 17, 2026 | 7.58 – 8.20.0 |
|
|
283
320
|
| 1.3.5 | May 14, 2026 | 7.58 – 8.20.0 |
|
data/Rakefile
CHANGED
|
@@ -126,7 +126,18 @@ end
|
|
|
126
126
|
|
|
127
127
|
RubyMemcheck.config(**ruby_memcheck_config)
|
|
128
128
|
namespace :test do
|
|
129
|
-
|
|
129
|
+
# Ruby pools fiber stacks next to each other, about 1MB apart. Valgrind
|
|
130
|
+
# treats a stack-pointer jump smaller than --max-stackframe (2MB) as an
|
|
131
|
+
# ordinary call or return rather than a switch to another stack, and marks
|
|
132
|
+
# the memory in between, which can hold another fiber's stack, as
|
|
133
|
+
# inaccessible. Later reads of that fiber's stack (turning a block into a
|
|
134
|
+
# Proc, GC marking suspended fibers) are then reported as invalid. Spacing
|
|
135
|
+
# fiber stacks wider than that lets valgrind recognize every fiber switch.
|
|
136
|
+
task :valgrind_env do
|
|
137
|
+
ENV['RUBY_FIBER_MACHINE_STACK_SIZE'] ||= (4 * 1024 * 1024).to_s
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
RubyMemcheck::TestTask.new(valgrind: [:compile, :valgrind_env]) do|t|
|
|
130
141
|
t.test_files = FileList['tests/tc_*.rb']
|
|
131
142
|
t.verbose = false
|
|
132
143
|
end
|
data/ext/curb.c
CHANGED
|
@@ -243,25 +243,38 @@ static void finalize_curb_core(VALUE data) {
|
|
|
243
243
|
|
|
244
244
|
void Init_curb_core() {
|
|
245
245
|
curl_version_info_data *ver;
|
|
246
|
-
VALUE curlver, curllongver, curlvernum;
|
|
246
|
+
VALUE curbver, curlver, curllongver, curlvernum;
|
|
247
|
+
int ractor_safe = 0;
|
|
247
248
|
|
|
248
249
|
curl_global_init(CURL_GLOBAL_ALL);
|
|
249
250
|
rb_set_end_proc(finalize_curb_core, Qnil);
|
|
250
251
|
ver = curl_version_info(CURLVERSION_NOW);
|
|
251
252
|
|
|
253
|
+
#if defined(HAVE_RB_EXT_RACTOR_SAFE) && defined(HAVE_CURL_VERSION_THREADSAFE)
|
|
254
|
+
/* Ractors execute native methods in parallel. Only opt in when both Ruby
|
|
255
|
+
* provides the safety marker and libcurl advertises thread-safe global
|
|
256
|
+
* initialization. Individual Curl handles remain Ractor-owned. */
|
|
257
|
+
if (ver && (ver->features & CURL_VERSION_THREADSAFE)) {
|
|
258
|
+
rb_ext_ractor_safe(1);
|
|
259
|
+
ractor_safe = 1;
|
|
260
|
+
}
|
|
261
|
+
#endif
|
|
262
|
+
|
|
252
263
|
mCurl = rb_define_module("Curl");
|
|
253
264
|
|
|
254
|
-
|
|
255
|
-
|
|
265
|
+
curbver = rb_obj_freeze(rb_str_new2(CURB_VERSION));
|
|
266
|
+
curlver = rb_obj_freeze(rb_str_new2(ver->version));
|
|
267
|
+
curllongver = rb_obj_freeze(rb_str_new2(curl_version()));
|
|
256
268
|
curlvernum = LONG2NUM(LIBCURL_VERSION_NUM);
|
|
257
269
|
|
|
258
|
-
rb_define_const(mCurl, "CURB_VERSION",
|
|
270
|
+
rb_define_const(mCurl, "CURB_VERSION", curbver);
|
|
259
271
|
rb_define_const(mCurl, "VERSION", curlver);
|
|
260
272
|
rb_define_const(mCurl, "CURL_VERSION", curlver);
|
|
261
273
|
rb_define_const(mCurl, "VERNUM", curlvernum);
|
|
262
274
|
rb_define_const(mCurl, "CURL_VERNUM", curlvernum);
|
|
263
275
|
rb_define_const(mCurl, "LONG_VERSION", curllongver);
|
|
264
276
|
rb_define_const(mCurl, "CURL_LONG_VERSION", curllongver);
|
|
277
|
+
rb_define_const(mCurl, "RACTOR_SAFE", ractor_safe ? Qtrue : Qfalse);
|
|
265
278
|
|
|
266
279
|
/* Passed to on_debug handler to indicate that the data is informational text. */
|
|
267
280
|
rb_define_const(mCurl, "CURLINFO_TEXT", LONG2NUM(CURLINFO_TEXT));
|
data/ext/curb.h
CHANGED
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
#include "curb_macros.h"
|
|
29
29
|
|
|
30
30
|
// These should be managed from the Rake 'release' task.
|
|
31
|
-
#define CURB_VERSION "1.
|
|
32
|
-
#define CURB_VER_NUM
|
|
31
|
+
#define CURB_VERSION "1.4.0"
|
|
32
|
+
#define CURB_VER_NUM 1040
|
|
33
33
|
#define CURB_VER_MAJ 1
|
|
34
|
-
#define CURB_VER_MIN
|
|
35
|
-
#define CURB_VER_MIC
|
|
34
|
+
#define CURB_VER_MIN 4
|
|
35
|
+
#define CURB_VER_MIC 0
|
|
36
36
|
#define CURB_VER_PATCH 0
|
|
37
37
|
|
|
38
38
|
|
data/ext/curb_easy.c
CHANGED
|
@@ -66,6 +66,17 @@ static struct curl_slist *duplicate_curl_slist(struct curl_slist *list);
|
|
|
66
66
|
static size_t proc_data_handler(char *stream, size_t size, size_t nmemb, VALUE proc);
|
|
67
67
|
static int curb_array_includes_string(VALUE list, VALUE value);
|
|
68
68
|
|
|
69
|
+
static void curb_easy_apply_thread_defaults(ruby_curl_easy *rbce) {
|
|
70
|
+
#ifdef HAVE_CURLOPT_NOSIGNAL
|
|
71
|
+
CURLcode ecode = curl_easy_setopt(rbce->curl, CURLOPT_NOSIGNAL, 1L);
|
|
72
|
+
if (ecode != CURLE_OK) {
|
|
73
|
+
raise_curl_easy_error_exception(ecode);
|
|
74
|
+
}
|
|
75
|
+
#else
|
|
76
|
+
(void)rbce;
|
|
77
|
+
#endif
|
|
78
|
+
}
|
|
79
|
+
|
|
69
80
|
/* ================== CURL HANDLER FUNCS ==============*/
|
|
70
81
|
|
|
71
82
|
static int curb_ipv4_is_unsafe_destination(const unsigned char *ip) {
|
|
@@ -1501,6 +1512,7 @@ static VALUE ruby_curl_easy_initialize(int argc, VALUE *argv, VALUE self) {
|
|
|
1501
1512
|
ruby_curl_easy_zero(rbce);
|
|
1502
1513
|
rbce->self = self;
|
|
1503
1514
|
|
|
1515
|
+
curb_easy_apply_thread_defaults(rbce);
|
|
1504
1516
|
curl_easy_setopt(rbce->curl, CURLOPT_ERRORBUFFER, &rbce->err_buf);
|
|
1505
1517
|
|
|
1506
1518
|
rb_easy_set("url", url);
|
|
@@ -1659,6 +1671,7 @@ static VALUE ruby_curl_easy_close(VALUE self) {
|
|
|
1659
1671
|
ruby_curl_easy_zero(rbce);
|
|
1660
1672
|
rbce->self = self;
|
|
1661
1673
|
|
|
1674
|
+
curb_easy_apply_thread_defaults(rbce);
|
|
1662
1675
|
curl_easy_setopt(rbce->curl, CURLOPT_ERRORBUFFER, rbce->err_buf);
|
|
1663
1676
|
|
|
1664
1677
|
/* give the new curl handle a reference back to the ruby object */
|
|
@@ -1703,6 +1716,7 @@ static VALUE ruby_curl_easy_reset(VALUE self) {
|
|
|
1703
1716
|
ruby_curl_easy_zero(rbce);
|
|
1704
1717
|
rbce->self = self;
|
|
1705
1718
|
|
|
1719
|
+
curb_easy_apply_thread_defaults(rbce);
|
|
1706
1720
|
curl_easy_setopt(rbce->curl, CURLOPT_ERRORBUFFER, &rbce->err_buf);
|
|
1707
1721
|
|
|
1708
1722
|
/* reset clobbers the private setting, so reset it to self */
|
|
@@ -2552,6 +2566,41 @@ static VALUE ruby_curl_easy_proxy_type_get(VALUE self) {
|
|
|
2552
2566
|
(!strncmp("anysafe",node,7)) ? CURLAUTH_ANYSAFE : \
|
|
2553
2567
|
(!strncmp("any",node,3)) ? CURLAUTH_ANY : 0
|
|
2554
2568
|
#endif
|
|
2569
|
+
/*
|
|
2570
|
+
* Convert the arguments to http_auth_types= / proxy_auth_types= into a
|
|
2571
|
+
* CURLAUTH bitmask. Accepts nil, an Integer mask, or one or more auth type
|
|
2572
|
+
* names (symbols/strings), either as separate args or as a single Array.
|
|
2573
|
+
*/
|
|
2574
|
+
static long ruby_curl_easy_auth_types_to_mask(VALUE args_ary) {
|
|
2575
|
+
long i, len;
|
|
2576
|
+
char* node = NULL;
|
|
2577
|
+
long mask = 0;
|
|
2578
|
+
VALUE first;
|
|
2579
|
+
|
|
2580
|
+
/* easy.http_auth_types = [:basic, :digest] arrives as a single Array arg */
|
|
2581
|
+
if (RARRAY_LEN(args_ary) == 1 && RB_TYPE_P(rb_ary_entry(args_ary,0), T_ARRAY)) {
|
|
2582
|
+
args_ary = rb_ary_entry(args_ary,0);
|
|
2583
|
+
}
|
|
2584
|
+
|
|
2585
|
+
len = RARRAY_LEN(args_ary);
|
|
2586
|
+
first = rb_ary_entry(args_ary,0);
|
|
2587
|
+
|
|
2588
|
+
if (len == 1 && (first == Qnil || TYPE(first) == T_FIXNUM || TYPE(first) == T_BIGNUM)) {
|
|
2589
|
+
return first == Qnil ? 0 : NUM2LONG(first);
|
|
2590
|
+
}
|
|
2591
|
+
|
|
2592
|
+
// we could have multiple values, but they should be symbols
|
|
2593
|
+
// rb_obj_as_string always yields a String, even if to_s misbehaves;
|
|
2594
|
+
// RSTRING_PTR on a raw rb_funcall result would crash if #to_s returned
|
|
2595
|
+
// a non-String (e.g. a Fixnum, whose VALUE isn't a real pointer).
|
|
2596
|
+
for( i = 0; i < len; ++i ) {
|
|
2597
|
+
VALUE node_str = rb_obj_as_string(rb_ary_entry(args_ary,i));
|
|
2598
|
+
node = StringValuePtr(node_str);
|
|
2599
|
+
mask |= CURL_HTTPAUTH_STR_TO_NUM(node);
|
|
2600
|
+
}
|
|
2601
|
+
return mask;
|
|
2602
|
+
}
|
|
2603
|
+
|
|
2555
2604
|
/*
|
|
2556
2605
|
* call-seq:
|
|
2557
2606
|
* easy.http_auth_types = fixnum or nil => fixnum or nil
|
|
@@ -2561,37 +2610,14 @@ static VALUE ruby_curl_easy_proxy_type_get(VALUE self) {
|
|
|
2561
2610
|
* +perform+ calls. This is a bitmap made by ORing together the
|
|
2562
2611
|
* Curl::CURLAUTH constants.
|
|
2563
2612
|
*/
|
|
2564
|
-
static VALUE ruby_curl_easy_http_auth_types_set(int argc, VALUE *argv, VALUE self) {
|
|
2613
|
+
static VALUE ruby_curl_easy_http_auth_types_set(int argc, VALUE *argv, VALUE self) {
|
|
2565
2614
|
ruby_curl_easy *rbce;
|
|
2566
2615
|
VALUE args_ary;
|
|
2567
|
-
long i, len;
|
|
2568
|
-
char* node = NULL;
|
|
2569
|
-
long mask = 0;
|
|
2570
2616
|
|
|
2571
2617
|
rb_scan_args(argc, argv, "*", &args_ary);
|
|
2572
2618
|
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
2573
2619
|
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
if (len == 1 && (rb_ary_entry(args_ary,0) == Qnil || TYPE(rb_ary_entry(args_ary,0)) == T_FIXNUM ||
|
|
2577
|
-
TYPE(rb_ary_entry(args_ary,0)) == T_BIGNUM)) {
|
|
2578
|
-
if (rb_ary_entry(args_ary,0) == Qnil) {
|
|
2579
|
-
rbce->http_auth_types = 0;
|
|
2580
|
-
}
|
|
2581
|
-
else {
|
|
2582
|
-
rbce->http_auth_types = NUM2LONG(rb_ary_entry(args_ary,0));
|
|
2583
|
-
}
|
|
2584
|
-
}
|
|
2585
|
-
else {
|
|
2586
|
-
// we could have multiple values, but they should be symbols
|
|
2587
|
-
node = RSTRING_PTR(rb_funcall(rb_ary_entry(args_ary,0),rb_intern("to_s"),0));
|
|
2588
|
-
mask = CURL_HTTPAUTH_STR_TO_NUM(node);
|
|
2589
|
-
for( i = 1; i < len; ++i ) {
|
|
2590
|
-
node = RSTRING_PTR(rb_funcall(rb_ary_entry(args_ary,i),rb_intern("to_s"),0));
|
|
2591
|
-
mask |= CURL_HTTPAUTH_STR_TO_NUM(node);
|
|
2592
|
-
}
|
|
2593
|
-
rbce->http_auth_types = mask;
|
|
2594
|
-
}
|
|
2620
|
+
rbce->http_auth_types = ruby_curl_easy_auth_types_to_mask(args_ary);
|
|
2595
2621
|
return LONG2NUM(rbce->http_auth_types);
|
|
2596
2622
|
}
|
|
2597
2623
|
|
|
@@ -2609,13 +2635,21 @@ static VALUE ruby_curl_easy_http_auth_types_get(VALUE self) {
|
|
|
2609
2635
|
/*
|
|
2610
2636
|
* call-seq:
|
|
2611
2637
|
* easy.proxy_auth_types = fixnum or nil => fixnum or nil
|
|
2638
|
+
* easy.proxy_auth_types = [:basic,:digest,:digest_ie,:gssnegotiate, :ntlm, :any, :anysafe]
|
|
2612
2639
|
*
|
|
2613
2640
|
* Set the proxy authentication types that may be used for the following
|
|
2614
2641
|
* +perform+ calls. This is a bitmap made by ORing together the
|
|
2615
2642
|
* Curl::CURLAUTH constants.
|
|
2616
2643
|
*/
|
|
2617
|
-
static VALUE ruby_curl_easy_proxy_auth_types_set(VALUE
|
|
2618
|
-
|
|
2644
|
+
static VALUE ruby_curl_easy_proxy_auth_types_set(int argc, VALUE *argv, VALUE self) {
|
|
2645
|
+
ruby_curl_easy *rbce;
|
|
2646
|
+
VALUE args_ary;
|
|
2647
|
+
|
|
2648
|
+
rb_scan_args(argc, argv, "*", &args_ary);
|
|
2649
|
+
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
2650
|
+
|
|
2651
|
+
rbce->proxy_auth_types = ruby_curl_easy_auth_types_to_mask(args_ary);
|
|
2652
|
+
return LONG2NUM(rbce->proxy_auth_types);
|
|
2619
2653
|
}
|
|
2620
2654
|
|
|
2621
2655
|
/*
|
|
@@ -6067,8 +6101,9 @@ static VALUE ruby_curl_easy_escape(VALUE self, VALUE svalue) {
|
|
|
6067
6101
|
|
|
6068
6102
|
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
6069
6103
|
|
|
6070
|
-
/* NOTE: make sure the value is a string
|
|
6071
|
-
|
|
6104
|
+
/* NOTE: make sure the value is a string; rb_obj_as_string always yields a
|
|
6105
|
+
* String, even if the object's to_s misbehaves and returns a non-String. */
|
|
6106
|
+
if( rb_type(str) != T_STRING ) { str = rb_obj_as_string(str); }
|
|
6072
6107
|
|
|
6073
6108
|
#if (LIBCURL_VERSION_NUM >= 0x070f04)
|
|
6074
6109
|
result = (char*)curl_easy_escape(rbce->curl, StringValuePtr(str), (int)RSTRING_LEN(str));
|
|
@@ -6098,6 +6133,11 @@ static VALUE ruby_curl_easy_unescape(VALUE self, VALUE str) {
|
|
|
6098
6133
|
|
|
6099
6134
|
TypedData_Get_Struct(self, ruby_curl_easy, &ruby_curl_easy_data_type, rbce);
|
|
6100
6135
|
|
|
6136
|
+
/* Coerce as its own statement before use below - StringValuePtr and
|
|
6137
|
+
* RSTRING_LEN are sibling args to the same call and C does not guarantee
|
|
6138
|
+
* left-to-right evaluation order between them. */
|
|
6139
|
+
StringValue(str);
|
|
6140
|
+
|
|
6101
6141
|
#if (LIBCURL_VERSION_NUM >= 0x070f04)
|
|
6102
6142
|
result = (char*)curl_easy_unescape(rbce->curl, StringValuePtr(str), (int)RSTRING_LEN(str), &rlen);
|
|
6103
6143
|
#else
|
|
@@ -6132,7 +6172,7 @@ void init_curb_easy() {
|
|
|
6132
6172
|
idNetworkPolicyNone = rb_intern("none");
|
|
6133
6173
|
idNetworkPolicyPublic = rb_intern("public");
|
|
6134
6174
|
|
|
6135
|
-
rbstrAmp = rb_str_new2("&");
|
|
6175
|
+
rbstrAmp = rb_obj_freeze(rb_str_new2("&"));
|
|
6136
6176
|
rb_global_variable(&rbstrAmp);
|
|
6137
6177
|
|
|
6138
6178
|
cCurlEasy = rb_define_class_under(mCurl, "Easy", rb_cObject);
|
|
@@ -6203,7 +6243,7 @@ void init_curb_easy() {
|
|
|
6203
6243
|
rb_define_method(cCurlEasy, "proxy_type", ruby_curl_easy_proxy_type_get, 0);
|
|
6204
6244
|
rb_define_method(cCurlEasy, "http_auth_types=", ruby_curl_easy_http_auth_types_set, -1);
|
|
6205
6245
|
rb_define_method(cCurlEasy, "http_auth_types", ruby_curl_easy_http_auth_types_get, 0);
|
|
6206
|
-
rb_define_method(cCurlEasy, "proxy_auth_types=", ruby_curl_easy_proxy_auth_types_set, 1);
|
|
6246
|
+
rb_define_method(cCurlEasy, "proxy_auth_types=", ruby_curl_easy_proxy_auth_types_set, -1);
|
|
6207
6247
|
rb_define_method(cCurlEasy, "proxy_auth_types", ruby_curl_easy_proxy_auth_types_get, 0);
|
|
6208
6248
|
rb_define_method(cCurlEasy, "max_redirects=", ruby_curl_easy_max_redirects_set, 1);
|
|
6209
6249
|
rb_define_method(cCurlEasy, "max_redirects", ruby_curl_easy_max_redirects_get, 0);
|
data/ext/curb_easy.h
CHANGED
|
@@ -112,6 +112,7 @@ typedef struct {
|
|
|
112
112
|
curb_cidr_rule *network_allowed_cidr_rules;
|
|
113
113
|
char **network_allowed_hosts;
|
|
114
114
|
|
|
115
|
+
/* attachment_sequence of the multi at the time this easy was last added. */
|
|
115
116
|
unsigned long multi_attachment_generation;
|
|
116
117
|
curl_off_t downloaded_body_bytes;
|
|
117
118
|
size_t network_allowed_cidr_rule_count;
|