curb 1.4.0 → 1.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9f3088ba29db67ea56c9587898267648a704c8acbcb9e95cb58318c3464deb12
4
- data.tar.gz: 40134cd41f0704c2aaa3b65ca6507987f6e8bc755c4530c9361ccd25f4831c17
3
+ metadata.gz: b3e51fdd9738a5fa5c1a7a393d09518ce25078374d4dde2929de0825817b4d84
4
+ data.tar.gz: a6ad92343bdfd8fee02f23be8ce808722793fa55cb1f4b1be03cdd1c1d65eeaa
5
5
  SHA512:
6
- metadata.gz: 29ffbf5bb4301db5729aff433a938251622c8483a29f5fa0f5344b52573048964c9863d00d254b42d01ff172291a1b469ea10f1fa9757b58fe4743a66c7078a5
7
- data.tar.gz: d2e21e48891f398af31a7b2dd8d99a2465f82bb97d9caecda8ac4cb69fb599e894c3172bc56a6106a28d7761b03743fc78ee80701b3051ac673b7b6f1ed27ea9
6
+ metadata.gz: 7a88d188c5511dc5d28e918bff804d73a4b855880eefe9fb45eb840803cb177a7767572a852599a47c697cd47a218206da5d838366e3f5f1f57b20096d861ce6
7
+ data.tar.gz: 2c7094094a6227ec09ccab48810269b528b876e1f4dbeca459124e44b963d6d71f3100486637f67ec2282199192f5327e809634ad4ed92add7d409f73ca23a13
data/ChangeLog.md ADDED
@@ -0,0 +1,432 @@
1
+ # ChangeLog
2
+ ## 1.4.1 (unreleased)
3
+ * Fix CI fixtures for Windows file-URL normalization and libcurl/libpsl localhost cookie loading. Keep parallel multipart Ractor coverage on Windows without triggering Ruby VM bug #21537 through explicit worker GC; retain multipart compaction coverage in the PostField tests. Include this changelog and the transfer-guard regression tests in the gem package.
4
+ * Make `Curl.safe!` default to `network_policy = :public`, including calls without a configuration block. Global safe mode, `safe_*` helpers, and `Easy#safe_http!` now default to a configurable 10 MiB response-body cap, enforced for buffered responses and body callbacks. Explicit helper limits cannot weaken a tighter global cap. Trusted private destinations require an explicit global policy opt-out; raw requests outside safe mode retain their existing defaults. Add regression coverage for default SSRF blocking, multi policy refresh, body limits, and explicit overrides.
5
+ * Complete idle easy-handle detachment during repeated `initialize`, `close`, and `reset`: clear native attachment counts and Ruby request bookkeeping so the handle can be re-added immediately. Check failed libcurl escape/unescape allocations before accessing their results, raising `Curl::Err::CurlError`, and free returned buffers even if Ruby string allocation raises.
6
+ * Guard active multi transfers across GVL-releasing waits: reject access to attached easy handles and native multi mutations from other threads, including close/reset/clone, option changes, and removal. Reject destructive easy lifecycle operations and `setopt` while a transfer is active, while preserving cloning from callbacks on the performing thread. Release ownership on exceptions and interruption, and preserve it when reusing an autoclosed multi. Add concurrency regression tests for polling and socket-action performs.
7
+ * Protect multipart form construction from reentrant `Curl::Easy` access during field callbacks and string coercion, and keep the native lifecycle guard active through form cleanup. Use private native snapshots for multipart payloads so later callbacks, threads, or GC compaction cannot invalidate earlier fields. Avoid per-field VM-global GC root registration and an extra libcurl form copy; release temporary metadata snapshots immediately after form construction. Add regression coverage for POST/PATCH/PUT, exception recovery, string mutation, and compaction.
8
+ * Fix compiler-dependent crashes in multipart `Curl::PostField` uploads by coercing direct and block-provided content to strings before reading their pointers and lengths. Preserve `TypeError` for values without valid `to_str` conversion. Add regression coverage for content and buffered file fields, optional content types, and embedded NUL bytes.
9
+ * Fix SSRF protection in `Curl.safe_*` and `Curl::Easy#safe_http!`: enforce `network_policy = :public` alongside HTTP/HTTPS protocol limits, blocking loopback, private, and link-local destinations by default. Apply existing proxy and destination-override controls, and prevent weaker global or per-handle network policies from disabling protection. Safe helpers now reject trusted local services too; use raw helpers with explicit protocol limits for those requests. Response-body limits use the safe-mode default and can be configured through `max_body_bytes`. Add regression coverage for safe helpers, policy reapplication, and multi transfers.
10
+ * Fix crashes and uninitialized-memory reads when native operations are called on `Curl::Easy.allocate` or subclasses whose initializer omits `super`: reject uninitialized handles with `Curl::Err::FailedInitError`, initialize connection-info outputs, and check libcurl errors. Repeated `initialize` now detaches and frees the previous handle and rejects reinitialization during callbacks or native operations. Add regression coverage for allocation, subclasses, getters, lifecycle operations, and repeated initialization.
11
+ * Fix a use-after-free when `Curl::Easy#clone` or `#dup` is called from a callback during a multipart request: detach the temporary form from the clone before the original request frees it, and reset the clone's callback state. Supply new `PostField` objects to send a multipart request with the clone. Add regression coverage for body, header, progress, debug, and completion callbacks.
12
+
13
+ ## 1.4.0
14
+ * Fix crashes when a user-supplied value's `#to_s` returns a non-String (e.g. a Fixnum): `Curl::PostField#to_s` (name and content coercion), `Curl::Easy#http_auth_types=`, and `Curl::Easy#escape` now use `rb_obj_as_string` instead of trusting a raw `#to_s` result, and `Curl::Easy#unescape` coerces its argument before use. Previously these passed the unchecked result straight to raw C string macros (`RSTRING_PTR`/`RSTRING_LEN`), which could segfault instead of raising.
15
+ * Fix `Curl::Easy#http_auth_types = [:basic, :digest]` (the documented array form), which previously stringified the whole Array and set no auth types.
16
+ * `Curl::Easy#proxy_auth_types=` now accepts auth type symbols (`:basic`, `[:basic, :ntlm]`, etc.) like `http_auth_types=`, in addition to an Integer mask.
17
+ * Fix a curl handle leak in `Curl::PostField#to_s` when the content proc, `#to_s`, or UTF-8 conversion raised.
18
+ * Add guarded Ractor support on Ruby 3.0+ with thread-safe libcurl builds: isolate mutable configuration and cleanup queues per Ractor, freeze exported string constants, default Easy handles to `CURLOPT_NOSIGNAL`, and cover concurrent Easy requests with regression tests.
19
+ * `Curl::Multi#perform` now waits with `curl_multi_poll` (libcurl 7.68+) instead of `curl_multi_fdset`/`select`. Sockets numbered above `FD_SETSIZE` (1024), common in long-running servers, no longer fall back to fixed 100ms sleeps (20 sequential GETs: 4.0s → 12ms); `Thread#raise`, `Thread#kill` and signals interrupt the wait immediately through `curl_multi_wakeup`; and idle waits follow libcurl's timeout instead of a fixed 100ms sleep. Older libcurl keeps the previous wait loop.
20
+ * Under a Fiber scheduler, the socket-action loop now mirrors libcurl's sockets into one epoll (Linux) or kqueue (macOS/BSD) descriptor and waits on it with the scheduler's `io_wait` hook. This avoids the optional `io_select` hook, which Async implements by starting a thread per call (50 concurrent downloads with a CPU-busy Ruby thread: 637ms → 131ms), and fixes schedulers without `io_select` waiting up to `Curl::Multi.default_timeout` behind an idle socket. Platforms without epoll/kqueue keep the previous paths.
21
+ * Make completion processing in `Curl::Multi` O(1) per finished transfer instead of copying every attached handle (16,000 transfers: 6.5s → 2.6s).
22
+ * Scheduler-driven `Curl::Easy#perform` now queues completions instead of scanning every waiter on each drive-loop pass.
23
+ * Fix an invalid `timeval` in the fallback wait loop when `Curl::Multi.default_timeout` exceeds 1000, and drop a retry loop for `CURLM_CALL_MULTI_PERFORM`, which libcurl has not returned since 7.20.
24
+ * Test suite: fix cookie-list tests on libcurl 8.22+ with libpsl (#483), fix a WEBrick teardown race that could hang CI (notably the valgrind job), space fiber stacks apart in `rake test:valgrind` so valgrind tracks fiber switches instead of reporting false invalid reads, skip wall-clock bounds under valgrind, and add coverage for the new wait paths, poller cleanup, and completion/waiter bookkeeping.
25
+
26
+ ## 1.3.7
27
+ * Pin `Curl::Easy` wrappers during GC compaction so libcurl completion dispatch cannot follow a stale Ruby object reference (#482).
28
+ * Fix FTP option configuration (#481): add `Curl::Easy#ftp_create_missing_dirs` and its setter, export the available `CURLFTP_CREATE_DIR_*` mode constants, and route detected scalar/string FTP options through `Curl::Easy#set`.
29
+ * Make `Curl::Multi#perform` and scheduler-driven `Curl::Easy#perform` nonblocking under Fiber schedulers while preserving cancellation and final-yield behavior, including schedulers without `io_select`.
30
+
31
+ ## 1.3.6
32
+ * Removing long standing potential for mis-use with the Thread.current caching of easy handles (potentially a breaking change for some but more likely a fix)
33
+ * Add safe request mode for fetching untrusted HTTP(S) URLs: `Curl.safe!`, `Curl.safe_get`, and `Curl::Easy#safe_http!`.
34
+ * Add `CURLOPT_CONNECT_TO`, `Curl::Easy#connect_to`, `CURLOPT_DOH_URL`, `Curl::Easy#doh_url`, and DoH SSL verification options.
35
+ * Restore Ruby 2.6 CI coverage and fix `Curl::Easy#perform` on Ruby 2.6 by avoiding finalizer-backed `ObjectSpace::WeakMap` entries for idle `Curl::Easy` references, including frozen easy handles.
36
+ * Extend Ruby 4.0.x valgrind test handling to Ruby 4.0.5 by filtering Ruby VM Fiber/block-handler noise while preserving reports for errors originating in `curb_core`.
37
+ * Harden `Curl::Easy`/`Curl::Multi` cleanup against re-entrant close during coercion and stale multi attachments.
38
+
39
+ ## 1.3.5
40
+ * Improve Ruby 4.0.4 valgrind test handling by filtering Ruby VM Fiber/block-handler noise while preserving reports for errors originating in `curb_core`.
41
+ * Fix `Curl::Multi` socket-action Fiber scheduler handling with libcurl 8.20.0 by honoring libcurl timer deadlines, matching Ruby IO wrapper modes to socket interest, and using scheduler `io_select` for multi-fd waits.
42
+ * Fix `Curl::Multi#perform` so work added during the final idle yield is processed before autoclose, avoiding dropped queued requests.
43
+
44
+ ## 1.3.4
45
+ * Fix `Curl::Multi` socket-action dispatch so ready sockets are collected before calling back into libcurl, avoiding invalid access when socket interest changes during iteration.
46
+ * Keep the Fiber scheduler socket-action IO cache registered with Ruby GC during `_socket_perform` and clear it during cleanup, avoiding stale Ruby object references under valgrind.
47
+ * Make Fiber scheduler tests avoid hardcoded port `9993` so local listeners or concurrent valgrind runs do not break the release suite.
48
+
49
+ ## 1.3.3
50
+ * Skip the NTLM-specific username/password assertion when libcurl was built without NTLM support so newer libcurl builds do not fail by falling back to Basic auth.
51
+ * Fix `Curl::Easy#put_data=` with non-String `to_s` payloads so upload length calculation does not read non-String objects as Ruby strings.
52
+ * Guard `Curl::Easy#clone` against `curl_easy_duphandle` allocation failure so clone raises `NoMemError` instead of dereferencing a NULL handle.
53
+ * Guard `Curl::Multi` lifecycle during active `perform` calls so closing a multi handle from callbacks or perform blocks raises instead of freeing an in-use libcurl multi handle.
54
+ * Reject adding an active `Curl::Easy` handle to a second `Curl::Multi` before setup mutates request state.
55
+ * Restore one-shot request state for `HEAD`, `PATCH`, and `PUT` requests after success or callback/error unwinds so later requests do not inherit stale method/body options.
56
+ * Validate `Curl::Easy#put_data=` before mutating libcurl upload options, preventing failed setup paths from leaving stale upload callbacks installed.
57
+ * Preserve `CURLOPT_RESOLVE` values set through `Easy#set` across repeated performs, and allow resolve/FTP command entries that convert to strings.
58
+ * Fix older build fallback paths for `curl_multi_wait` and no-GVL `select`.
59
+ * Fix the Fiber scheduler socket-action path so single-socket waits pass the actual ready events back to libcurl, avoiding incomplete HTTP responses on macOS CI.
60
+ * Make legacy bug tests avoid hardcoded port `9999` so local SSH tunnels or other listeners do not break the release suite.
61
+ * Add regression coverage for multi lifecycle guards, active easy reuse, request state cleanup, upload setup rollback, resolve persistence, string-convertible resolve/FTP command entries, and scheduler socket waits.
62
+
63
+ ## 1.3.2
64
+ * Fix `Curl::PostField` GC marking so block-backed content fields remain valid across GC and compaction.
65
+ * Fix upload read/seek callbacks to preserve Ruby exceptions, avoid unsafe unwinds through libcurl, and reject reads larger than libcurl's supplied buffer.
66
+ * Fix multipart POST/PATCH/PUT cleanup so partially built native forms are freed when form construction raises.
67
+ * Restore `Curl::Easy#last_error` after `Easy#close` by reattaching the libcurl error buffer to the reinitialized handle.
68
+ * Fix `Curl::Easy#clone` with `put_data` so upload callbacks and upload state belong to the clone instead of the original handle.
69
+ * Add regression coverage for native callback, multipart cleanup, clone upload, close/error-buffer, and `PostField` GC safety.
70
+
71
+ ## 1.3.1
72
+ * Fix Ruby 4.x compatibility in `Curl::Multi`
73
+
74
+ ## 1.3.0
75
+ ### Breaking Changes
76
+ * `Curl::Multi#close` now permanently closes the multi handle. Code that previously called `close` and then reused the same `Curl::Multi` instance must now allocate a new multi handle instead. `Curl::Multi.autoclose` continues to use the internal reusable cleanup path for implicit autoclose and fiber-scheduler reuse.
77
+ * Callback exceptions raised during `Multi#perform` and scheduler-driven `Easy#perform` are now deferred until in-flight sibling transfers finish draining, and queued replacement work is no longer started once a deferred callback exception is pending. Applications that relied on immediate aborts or that enqueue new work from completion callbacks after a sibling failure may observe different control flow.
78
+ * `post_body=` and raw `CURLOPT_POSTFIELDS` assignments now snapshot the assigned Ruby string instead of aliasing later mutations to the caller's buffer. In addition, `easy.setopt(Curl::CURLOPT_POSTFIELDS, nil)` now clears the request body without implicitly switching the request back to GET; callers that relied on the old method-reset behavior must now set the method explicitly.
79
+ * `close` and `reset` are now blocked while progress, debug, and upload-read callbacks are active, matching the existing restriction for body and header callbacks. Code that performed cleanup directly inside those callbacks must move that work outside the callback.
80
+
81
+ ### Changes
82
+ * Improve Ruby 4.x and newer libcurl compatibility by addressing typed-data conversion and deprecation issues in the extension build.
83
+ * Fix `post_body`, `CURLOPT_POSTFIELDS`, multipart form reuse, and `resolve` cleanup so request buffers and per-request native state stay valid across setup, mutation, and reset.
84
+ * Tighten `Curl::Easy` and `Curl::Multi` lifecycle cleanup to reduce leaks and stale handle references, including explicit clearing of idle `easy.multi` back-references when a multi is closed.
85
+ * Rework deferred callback exception handling for `Easy` and `Multi` so callback failures are re-raised on the originating request after sibling work drains, queued replacement work does not start once a deferred exception is pending, and deferred implicit-multi cleanup stays thread-affine.
86
+ * Preserve the original callback exception for frozen `Curl::Easy` handles instead of raising `FrozenError`.
87
+ * Improve Fiber scheduler integration so scheduler-driven `Easy#perform` reuses the shared multi correctly, keeps yielding timers/perform blocks while deferred completions drain, and wakes the originating waiter when deferred callback errors surface.
88
+ * Add leak-trace tooling plus broader regression coverage for cleanup, callback, scheduler, GC.compact, and test-server stale-lock edge cases; CI now runs the valgrind suite on Linux Ruby 4.0.
89
+
90
+ ## 1.2.2
91
+ * Add `Curl::Easy#http_version` getter/setter along with HTTP/2 TLS/prior-knowledge constants so clients can force a specific HTTP protocol.
92
+ * Fix rare `Multi#perform` segfault with GC.compact by recovering the Easy when `CURLINFO_PRIVATE` is stale and pruning unknown handles.
93
+ * Store `ruby_curl_easy*` in `CURLOPT_PRIVATE` and use it for all libcurl callbacks (write/header/progress/debug) so GC.compact can’t invalidate stored VALUE pointers.
94
+ * Pass `ruby_curl_easy` as libcurl userdata for default body/header handlers so GC.compact can’t invalidate stored VALUE pointers.
95
+ * Safer GC: detach `Easy` from `Multi` during free to avoid dangling references.
96
+ * add work around for libcurl 8.16.0 max redirects regression
97
+
98
+ ## 1.2.1
99
+ * Clarify cookie behavior in README and RDoc:
100
+ - Differentiate between manual `cookies` header and the libcurl cookie engine
101
+ - Add `cookielist=` helper and examples for manipulating engine cookies (ALL/SESS/FLUSH/RELOAD)
102
+ - Note that `cookies = ''` clears the manual Cookie header; `nil` has no effect
103
+ * Add support for `CURLOPT_REQUEST_TARGET` (libcurl ≥ 7.55), including `easy.request_target=` setter, tests, and README usage notes
104
+ * Clarify that instance `easy.http_post` does not accept a URL argument; use `Curl::Easy.http_post(url, ...)` or set `easy.url` first
105
+ * Use after free fix
106
+
107
+ ## 1.2.0
108
+ * Fix on_redirect callback being triggered when follow_location=false and max_redirects=0
109
+ * Add support for CURLOPT_NOPROXY option (#441)
110
+ * Fix Curl.spnego? to check for both CURL_VERSION_SPNEGO and CURL_VERSION_GSSNEGOTIATE (#227)
111
+ * Add Fiber scheduler awareness for Curl::Multi: prefer scheduler-friendly socket-action path and `rb_thread_fd_select` when available (non-Windows)
112
+ - Add compile-time CURB_SOCKET_DEBUG flag to enable optional socket-action debug logging in curb_multi.c (default off; set CURB_SOCKET_DEBUG=1 when running extconf)
113
+ * When using request method HEAD ensure CURLOPT_NOBODY is set to 1 automatically
114
+ * Compiler checks run in parallel when building the extension JOBS=n to adjust concurrency of configure checks and build concurrency
115
+ * CI tests now run on Windows and MacOS
116
+
117
+ ## 1.1.0
118
+ * Add support for CURLOPT_RESOLVE
119
+ ```ruby
120
+ require 'resolv'
121
+ uri = URI.parse("https://google.com/")
122
+ resolved_ip = Resolv.getaddress(uri.host) # perform DNS lookup once
123
+ mapping = "#{uri.host}:#{uri.port}:#{resolved_ip}"
124
+
125
+ http = Curl::Easy.new("https://google.com/")
126
+ http.setopt(Curl::CURLOPT_RESOLVE, [mapping])
127
+
128
+ http.get
129
+
130
+ assert_match(/GET/, http.body)
131
+ ```
132
+ * allow configuration curl multi MAX_HOST_CONNECTIONS (#460)
133
+
134
+ https://curl.se/libcurl/c/CURLMOPT_MAX_HOST_CONNECTIONS.html
135
+ ## 1.0.9
136
+ * Fix for proxy headers see #457
137
+ * Add CI for Ruby 2.7, Ruby 3.3 and 3.4
138
+ ## 1.0.8
139
+ * PUT and PATCH requests now behave like POST requests with multipart form data supporting http_post, http_put, and http_patch with PostField arguments
140
+ ## 1.0.7
141
+ * Clean up easy handle after failing to add to a multi handle
142
+ * With newer versions of libcurl we can use curl_easy_escape instead of curl_escape, this should improve character encoding support
143
+ * When available use curl_multi_wait for greater system compatibility, users of libcurl 7.28.0 and later should benefit from this change
144
+ * Improve easy handle cloning to deep copy related lists, headers, cookies , proxy_headers, ftp_commands and resolve list.
145
+
146
+ * FTP: Document correct way to perform NLST/LIST (don’t use `ftp_commands` for data-transfer commands). Add README section for HTTP proxy tunnel usage and examples, including full LIST snippets. Map the following libcurl options through `Easy#set`:
147
+ - `:dirlistonly` -> `CURLOPT_DIRLISTONLY`
148
+ - `:ftp_use_epsv` -> `CURLOPT_FTP_USE_EPSV`
149
+ - `:ftp_use_eprt` -> `CURLOPT_FTP_USE_EPRT`
150
+ - `:ftp_skip_pasv_ip` -> `CURLOPT_FTP_SKIP_PASV_IP`
151
+ Also expand `ftp_commands` RDoc with guidance to avoid LIST/NLST/PASV/EPSV there.
152
+ Add a basic regression test in `tests/tc_ftp_options.rb` ensuring these options can be set without raising.
153
+ * Updating test suite and internal tools for ruby 3.4
154
+ * CURLOPT_COOKIELIST support see examples:
155
+ ```ruby
156
+ easy.setopt(Curl::CURLOPT_COOKIELIST, "Set-Cookie: c1=v1; domain=localhost; expires=#{expires.httpdate};")
157
+ easy.setopt(Curl::CURLOPT_COOKIELIST, [ ['.localhost', 'TRUE', '/', 'FALSE', 0, 'session', '42'].join("\t"),
158
+ ['.localhost', 'TRUE', '/', 'FALSE', 0, 'session2', '84'].join("\t"), '', ].join("\n") )
159
+ ```
160
+ * Add :on_missing to callbacks supported by Curl::Multi.http
161
+
162
+ ## 1.0.6
163
+ * Fix for PUT request length calculation
164
+ - see: #451
165
+ * Fix a double quote issue when evaluating cert's path
166
+ - see: #454
167
+
168
+ ## 1.0.5
169
+ * Add shorter response_code alias -> code
170
+ ```
171
+ Curl.get("https://github.com/taf2/curb").code # -> 200
172
+ ```
173
+ ## 1.0.4
174
+ * Improve exception handling from callback functions to ensure correct error line number is reported
175
+ * Resolve many compiler warnings
176
+ ## 1.0.3
177
+ * Adjust how we handle exceptions to handle more cases
178
+ ## 1.0.2
179
+ * Address alloc function T_DATA see: https://bugs.ruby-lang.org/issues/18007
180
+ * Add CURLOPT_PROXY_SSL_VERIFYHOST support
181
+ * Fix for exception handling in non standard callback functions on_redirect, on_complete
182
+ * Fix missing response code when using Curl::Multi.http with a block
183
+ * Fix to ensure redirect handler is called even when follow location is true
184
+ ## 1.0.1
185
+ * Fix nested Curl.get/post inside of a block
186
+ ```ruby
187
+ r1 = Curl.get("http://example.com/1") {|http|
188
+ r2 = Curl.get("http://example.com/2") {|h|
189
+ }
190
+ }
191
+ r1.body # previously was r2's body... this is now fixed
192
+ ```
193
+ * Restore compatibility with older libcurl installs
194
+ * Correctly set empty headers e.g. http.headers['Accept'] = '' # to remove the header from the request
195
+ ## 1.0.0
196
+ * Add Ruby 3.1 to tests
197
+ * Support curlopt_protocols and curlopt_redir_protocols.
198
+ * Improved error handling via last_error tracking
199
+ * Added support for CURLOPT_RANGE
200
+
201
+ ## 0.9.11
202
+ * Fixes for haproxy protocol via CURLOPT_HAPROXYPROTOCOL
203
+ * Ensure dev environments don't use older versions of rake when working on curb (not a production dependency)
204
+ * Many readmen updates - more windows support documentation
205
+ * Support added for CURLOPT_STDERR
206
+ ## 0.9.8
207
+ ### Fixes
208
+ * Fix build with curl `7.62.0`
209
+ * Support building against Ruby `1.8` to help people migrate to the future and beyond
210
+ ### Enhancements
211
+ * Improve `timeout=` to allow Floating point values which will automatically switch to `timeout_ms`
212
+ * Add `SOCKS5_HOSTNAME` support
213
+ * Added `Curl::Multi.autoclose` and `Curl::Multi#close` to improve connection handling. In past releases connection
214
+ clean up only ever happens when GC runs. Now in this release you can explicitly control connections via
215
+ `multi.close` or have it always close your connections with `Curl::Multi.autoclose=true`
216
+ ### Breaking Changes
217
+ * Request handling reduces C (lines of code), and might resolve segfault when mixing curb with ruby timeout
218
+ * Timeout change for anyone who expected `0.9` to equal `0` or `infinity`
219
+
220
+ ## 0.9.7
221
+ ### Breaking Changes
222
+ ### Fixes
223
+ * Guard use of `CURLOPT_RESOLVE` in `#if HAVE_CURLOPT_RESOLVE`
224
+ * Prevent `NoMethodError` when no HTTP Status
225
+ * [`Curl.urlalize` will miss raw url's query params](https://github.com/taf2/curb/issues/330)
226
+ * [Fix SSL versions constant names](https://github.com/taf2/curb/pull/333)
227
+ ### Enhancements
228
+ * Add `Curl::Easy#resolve` method to implement static IP overrides, bypassing DNS
229
+ * [Add new curl features](https://github.com/taf2/curb/pull/331)
230
+ * [Allow extending `Curl::Easy` and having a different number of constructor arguments
231
+ than `Curl::Easy` allows](https://github.com/taf2/curb/pull/329)
232
+
233
+ ## 0.9.4
234
+ ### Fixes
235
+ * [Fix `multi.pipeline`: `HAVE_CURLMOPT_PIPELINING` was never defined](https://github.com/taf2/curb/issues/298)
236
+ * Eliminate warnings on Ruby `2.4.1`
237
+ * [Hang in `select()`](https://github.com/taf2/curb/issues/323)
238
+ * Revert 'Experimenting with adding multi handle cleanup after every request, normally would be cleaned up with GC
239
+ (problem addressed by fix hang in `select()`)
240
+ * Prevent errant callbacks once the handle is cleaned up
241
+ ### Enhancements
242
+ * Add `PATCH` support?
243
+ * Add support for `CURLOPT_PATH_AS_IS`
244
+ * Add `.cookielist` method to `Curb::Easy`
245
+ * Improved Windows compatibility
246
+
247
+ ## 0.9.3
248
+ ### Fixes
249
+ * Correctly check for constants that may not be present in older versions of Curl
250
+
251
+ ## 0.9.2
252
+ * **Breaking change** - Change base class for exceptions from `Exception` to `StandardError`
253
+ ### Fixes
254
+ * [Segmentation fault (introduced with commit 50ab567)](https://github.com/taf2/curb/issues/240)
255
+ * Use 64-bit int for key in hash of active easy handles, to avoid clobbering on 32-bit systems
256
+ * [Fix `http_auth_types` for `:any` and `:anysafe`](https://github.com/taf2/curb/issues/291)
257
+ * [Use `LONG2NUM` and `NUM2LONG` to support all values of the `long` type](https://github.com/taf2/curb/issues/295)
258
+ * [Support empty reason phrases in the HTTP status line](https://github.com/taf2/curb/issues/292)
259
+ ### Enhancements
260
+ * Implement setting of `CURLOPT_MAXCONNECTS`
261
+ * Implement setting of `CURLOPT_FORBID_REUSE`
262
+ * Ability to specify specific allowed TLS versions when connecting
263
+ * Add support for `HTTP/2.0` and multiplexing
264
+ * Experimenting with adding multi handle cleanup after every request, normally would be cleaned up with GC
265
+
266
+ ## 0.9.1
267
+ ### Fixes
268
+ * Fix regression in `timeout`/`timeout_ms` handling
269
+
270
+ ## 0.9.0
271
+ ### Fixes
272
+ * Remove `CURLAUTH_ANY` as the default for authentication setting, as too many services in the world don't
273
+ respond correctly with a `401` but instead `403` so the option rarely works as we'd hope
274
+ * Use the memory address as the key to correctly keep a hash of active easy handles alive in the multi handle -- should
275
+ resolve existing reports of memory leaks as well as crashes under some conditions
276
+
277
+ ## 0.8.9
278
+ ### Fixes
279
+ * Only append query string if it exists
280
+ * Setting any of `CURLOPT_HEADER`, `CURLOPT_NOPROGRESS`, `CURLOPT_NOSIGNAL`, `CURLOPT_HTTPGET` did not work
281
+ (introduced in commits `4358d04` and `14e9b53`)
282
+ * Compilation for curl versions before `7.40.0`
283
+ * [`Curl::Multi.http` call of the `on_complete` callback expects unsupplied
284
+ parameter](https://github.com/taf2/curb/issues/270)
285
+ ### Enhancements
286
+ * Add `Curl::HTTP_2_0`, and `Curl.http2?`
287
+ * Support `CURLOPT_UNIX_SOCKET_PATH` in `Curl::Easy`
288
+ * Add `timeout_ms`/`connect_timeout_ms` options
289
+ * Add `on_redirect` callback handling to `.http`
290
+
291
+ ## 0.8.8
292
+ ### Fixes
293
+ * [`Curl::Easy.http_get` broken on macOS](https://github.com/taf2/curb/pull/242)
294
+
295
+ ## 0.8.7
296
+ ### Breaking Changes
297
+ ### Fixes
298
+ * Restore support for older, `pre-7.17` versions of curl (fixes CentOS 5 compatibility)
299
+ * Improve Ruby `2.2.x` support (use `rb_thread_fd_select` instead of `rb_thread_select`)
300
+ ### Enhancements
301
+ * Add SOCKS4A support
302
+ * Allow custom ssl cipher lists
303
+ * Add install instructions for Windows
304
+ * Make it possible easily reset the Thread current handle (`Curl.reset`)
305
+
306
+ ## 0.8.6
307
+ ### Breaking Changes
308
+ ### Fixes
309
+ * Add support for the new error `CURLM_ADDED_ALREADY` introduced at curl `7.33.0`
310
+ * Add conditionals for new `URLM_ADDED_ALREADY` error
311
+ * `Curl#urlalize` - `CGI.escape` for param values
312
+ * Use correct HTTP verb for DELETE requests (was `delete`, and some servers are apparently case sensitive)
313
+ * Typo in `ext/curb_errors.c`: `BadBasswordError` -> `BadPasswordError`
314
+ * Status method now returns the last status in the response header
315
+ ### Enhancements
316
+ * Support Ruby `2.2.0`
317
+ * Support `CURLOPT_TCP_NODELAY` in `Curl::Easy`
318
+ * Raise an exception if `curb` doesn't know how to handle a `CURLOPT`
319
+ * Expose license via gemspec
320
+ * Implement seek function for multi-pass authentication uploads
321
+
322
+ ## 0.8.5
323
+ ### Fixes
324
+ * Guard against a curl without GSSAPI delegation compiled in
325
+ * Added `extconf.rb` entry for `appconnect`
326
+ * Reset handle before each call when using "super simple API"
327
+ ### Enhancements
328
+ * Added support for `app_connect_time` from `libcurl`
329
+ * Alias `body_str` to `body` and `header_str` to `head`
330
+
331
+ ## 0.8.4
332
+ ### Fixes
333
+ * [Setting `post_body` to `nil` does not reset data posted in `http(:GET)`](https://github.com/taf2/curb/issues/133)
334
+ * Various spurious/inconsequential warnings
335
+ * `Curl.head` uses `OPTIONS` method instead of `HEAD` method
336
+ ### Enhancements
337
+ * Make "super simple API" more efficient by storing `Curl::Easy` instance in `Thread.current`
338
+ * GSSAPI: Add required flags for GSSAPI delegation support
339
+ * GSSAPI: Allow setting of the new delegation flag
340
+ * GSSAPI: Implement support for libcurl SPNEGO flags in curb
341
+
342
+ ## 0.8.3
343
+ ### Fixes
344
+ * [Exception raised when process is signaled](https://github.com/taf2/curb/issues/117)
345
+ * [Curb always appends a query to request uris](https://github.com/taf2/curb/issues/137)
346
+
347
+ ## 0.8.2
348
+ ### Fixes
349
+ * Clang compatibility
350
+ ### Enhancements
351
+ * Allow string data with simpler interface e.g. `Curl.post('...', 'data')`
352
+
353
+ ## 0.8.1
354
+ ### Fixes
355
+ * [Error installing on Ubuntu](https://github.com/taf2/curb/issues/106)
356
+ * Protect callbacks from reset/close
357
+ * `Curl::Multi` not actually performing HTTP requests in cases when the `:max_connects >= number of requests`
358
+ * Build error when compiled with `-Werror=format-security`
359
+ * `postalize` parameter escaping
360
+ ### Enhancements
361
+ * Support `CURLINFO_REDIRECT_URL`
362
+ * Support `CURLOPT_RESUME_FROM` in `Curl::Easy`
363
+ * Add `.status` to `Curl::Easy` instances
364
+ * Support `CURLOPT_FAILONERROR`
365
+ * Add even easier interface: `Curl.get` / `Curl.post` / e.t.c
366
+
367
+ ## 0.8.0
368
+ * **Breaking change** - `on_failure` only fires for 5xx responses
369
+ ### Fixes
370
+ * Error in README section for HTTP POST file upload.
371
+ ### Enhancements
372
+ * Add a default for `resolve_mode` to `CURL_IPRESOLVE_WHATEVER` e.g. `:auto`
373
+ * Add `on_redirect` and `on_missing` callbacks for 3xx/4xx responses
374
+ * Allow `http_post(array_of_fields)` when using multipart form posts
375
+
376
+ ## 0.7.18
377
+ ### Fixes
378
+ * Check for obsolete, since it appears to be gone from later versions of libcurl per issue #100
379
+ * Regression in PUT requests with NULL bytes (caused by `RSTRING_PTR` => `StringValueCStr` change)
380
+
381
+ ## 0.7.17
382
+ ### Fixes
383
+ * Restore compatibility with 0.7.16 (e.g. suport for building without `CURLOPT_SEEKDATA`, etc)
384
+ * Use `rb_thread_blocking_region` when available in place of `rb_thread_select` for ruby 1.9.x
385
+ * Copy-paste mistake which made it impossible to set `CURLOPT_SSL_VERIFYHOST` to `2`
386
+ * Copy-paste mistake that caused `CURLOPT_SSL_VERIFYPEER` to be overwritten by the value of `use_netrc` setting
387
+ ### Enhancements
388
+ * Warn on exceptions in success/failure/complete callbacks
389
+ * Use `StringValueCStr` more instead of the less safe `RSTRING_PTR`
390
+ * Defaulting `CURLOPT_SSL_VERIFYHOST` to `2` to make it consistent with cURLs default value
391
+
392
+ ## 0.7.16
393
+ * Add better support for timeouts - issue 48
394
+ * Improve stability, avoid bus errors when raising in callbacks
395
+ * Allow Content-Length header when sending a PUT request
396
+ * Better handling of cacert
397
+ * Support `CURLOPT_IPRESOLVE`
398
+ * Allow `PostField.file#to_s`
399
+ * Minor refactoring to how `PostField.file` handles strings
400
+ * Accept symbol and any object that `responds_to?(:to_s)` for `easy.http(:verb)`
401
+ * Free memory sooner after a request finishes instead of waiting for garbage collection
402
+ * Fix crash when sending nil for the `http_put` body
403
+ * Fix inspect for `Curl::Easy`, thanks Hongli Lai
404
+ * Fix unit test assertions for `Curl::Multi`, thanks Hongli Lai
405
+
406
+ ## 0.7.7
407
+ * `Curl::Multi` perform is more robust process callbacks before exiting the loop - issue 24.
408
+ Thanks to igrigorik and ramsingla
409
+ * improve `Curl::Multi` idle callback robustness, trigger callbacks more often - issue 24.
410
+ Thanks to igrigorik and ramsingla
411
+
412
+ ## 0.7.6
413
+ * fix bug in http_* when http_delete or http("verb") raises an exception
414
+ * add support for autoreferrer e.g. if follow_location=true it will pass that along
415
+
416
+ ## 0.7.5
417
+ * minor fix for no signal instead of INT2FIX Check boolean value
418
+
419
+ ## 0.7.4
420
+ * add support to set the http version e.g. `easy.version = Curl::HTTP_1_1`
421
+ * add support to disable libcurls internal use of signals.
422
+
423
+ ## 0.7.3
424
+ * Support rubinius
425
+ * allow Multi.download to be called without a block
426
+ * add additional `Multi.download` examples
427
+
428
+ ## 0.7.2
429
+ * Start tracking high level changes
430
+ * Add `Curl::Easy#close` - hard close an easy handle
431
+ * Add `Curl::Easy#reset` - reset all settings but keep connections alive
432
+ * Maintain persistent connections for single easy handles
data/README.md CHANGED
@@ -205,12 +205,15 @@ 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
- safety policy for the current Ractor before making requests:
208
+ safety policy for the current Ractor before making requests. `Curl.safe!` defaults
209
+ to HTTP/HTTPS and `network_policy = :public`, blocking local/private destinations
210
+ even when called without a block. Safe mode also defaults to a 10 MiB
211
+ (10,485,760-byte) response-body limit:
209
212
 
210
213
  ```ruby
211
214
  Curl.safe! do |config|
212
- config.network_policy = :public # block local/private destination IPs
213
- config.max_body_bytes = 1_000_000 # cap buffered/callback response bytes
215
+ config.network_policy = :public # default; block local/private destination IPs
216
+ config.max_body_bytes = 1_000_000 # optional tighter cap; default is 10 MiB
214
217
  end
215
218
 
216
219
  curl = Curl.get(user_url) # allows only http/https, including redirects
@@ -226,8 +229,25 @@ Curl.safe! do |config|
226
229
  end
227
230
  ```
228
231
 
229
- For local per-handle policy instead of process-wide policy, use
230
- `easy.safe_http!` and `easy.max_body_bytes = ...` before `perform`.
232
+ For local per-handle policy, use `easy.safe_http!` before `perform`, or use
233
+ `Curl.safe_get`, `Curl.safe_post`, and the other `safe_*` helpers. These enforce
234
+ HTTP/HTTPS for requests and redirects and enable `network_policy = :public`,
235
+ even when the global policy permits private destinations. This rejects local
236
+ services as well as private and link-local addresses, including metadata endpoints.
237
+ The proxy and destination-override controls below apply, with any explicit
238
+ exceptions from `Curl.safe!` honored. Unsupported libcurl builds fail closed.
239
+ Safe helpers and `easy.safe_http!` default to the global safe-mode body limit,
240
+ or 10 MiB when global safe mode is not enabled. Override it explicitly with
241
+ `Curl.safe_get(user_url, :max_body_bytes => 1_000_000)` or
242
+ `easy.safe_http!(:max_body_bytes => 20 * 1024 * 1024)`. A tighter global limit
243
+ always takes precedence. Set `config.max_body_bytes = nil` (or `0`) to disable
244
+ the global cap; a helper's explicit `:max_body_bytes => nil` or `0` disables its
245
+ own cap, but cannot bypass a global cap or an existing tighter handle limit.
246
+ Raw requests outside safe mode remain unlimited unless configured otherwise.
247
+ These limits cover body bytes, not response headers.
248
+ For trusted local services, use the raw helpers with explicit protocol limits.
249
+ If global safe mode is enabled, explicitly set `config.network_policy = :none`
250
+ to opt out of peer-address filtering; `safe_*` helpers still enforce `:public`.
231
251
 
232
252
  With `network_policy = :public`, curb checks peer addresses when libcurl opens
233
253
  the socket and blocks local/private destinations. Proxies, `resolve`,
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.4.0"
32
- #define CURB_VER_NUM 1040
31
+ #define CURB_VERSION "1.4.1"
32
+ #define CURB_VER_NUM 1041
33
33
  #define CURB_VER_MAJ 1
34
34
  #define CURB_VER_MIN 4
35
- #define CURB_VER_MIC 0
35
+ #define CURB_VER_MIC 1
36
36
  #define CURB_VER_PATCH 0
37
37
 
38
38