- Fix
Curl::Easy#put_data=with non-Stringto_spayloads so upload length calculation does not read non-String objects as Ruby strings. - Guard
Curl::Easy#cloneagainstcurl_easy_duphandleallocation failure so clone raisesNoMemErrorinstead of dereferencing a NULL handle. - Guard
Curl::Multilifecycle during activeperformcalls so closing a multi handle from callbacks or perform blocks raises instead of freeing an in-use libcurl multi handle. - Reject adding an active
Curl::Easyhandle to a secondCurl::Multibefore setup mutates request state. - Restore one-shot request state for
HEAD,PATCH, andPUTrequests after success or callback/error unwinds so later requests do not inherit stale method/body options. - Validate
Curl::Easy#put_data=before mutating libcurl upload options, preventing failed setup paths from leaving stale upload callbacks installed. - Preserve
CURLOPT_RESOLVEvalues set throughEasy#setacross repeated performs, and allow resolve/FTP command entries that convert to strings. - Fix older build fallback paths for
curl_multi_waitand no-GVLselect. - Add regression coverage for multi lifecycle guards, active easy reuse, request state cleanup, upload setup rollback, resolve persistence, and string-convertible resolve/FTP command entries.
- Fix
Curl::PostFieldGC marking so block-backed content fields remain valid across GC and compaction. - Fix upload read/seek callbacks to preserve Ruby exceptions, avoid unsafe unwinds through libcurl, and reject reads larger than libcurl's supplied buffer.
- Fix multipart POST/PATCH/PUT cleanup so partially built native forms are freed when form construction raises.
- Restore
Curl::Easy#last_errorafterEasy#closeby reattaching the libcurl error buffer to the reinitialized handle. - Fix
Curl::Easy#clonewithput_dataso upload callbacks and upload state belong to the clone instead of the original handle. - Add regression coverage for native callback, multipart cleanup, clone upload, close/error-buffer, and
PostFieldGC safety.
- Fix Ruby 4.x compatibility in
Curl::Multi
Curl::Multi#closenow permanently closes the multi handle. Code that previously calledcloseand then reused the sameCurl::Multiinstance must now allocate a new multi handle instead.Curl::Multi.autoclosecontinues to use the internal reusable cleanup path for implicit autoclose and fiber-scheduler reuse.- Callback exceptions raised during
Multi#performand scheduler-drivenEasy#performare 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. post_body=and rawCURLOPT_POSTFIELDSassignments 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.closeandresetare 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.
- Improve Ruby 4.x and newer libcurl compatibility by addressing typed-data conversion and deprecation issues in the extension build.
- Fix
post_body,CURLOPT_POSTFIELDS, multipart form reuse, andresolvecleanup so request buffers and per-request native state stay valid across setup, mutation, and reset. - Tighten
Curl::EasyandCurl::Multilifecycle cleanup to reduce leaks and stale handle references, including explicit clearing of idleeasy.multiback-references when a multi is closed. - Rework deferred callback exception handling for
EasyandMultiso 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. - Preserve the original callback exception for frozen
Curl::Easyhandles instead of raisingFrozenError. - Improve Fiber scheduler integration so scheduler-driven
Easy#performreuses the shared multi correctly, keeps yielding timers/perform blocks while deferred completions drain, and wakes the originating waiter when deferred callback errors surface. - 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.
- Add
Curl::Easy#http_versiongetter/setter along with HTTP/2 TLS/prior-knowledge constants so clients can force a specific HTTP protocol. - Fix rare
Multi#performsegfault with GC.compact by recovering the Easy whenCURLINFO_PRIVATEis stale and pruning unknown handles. - Store
ruby_curl_easy*inCURLOPT_PRIVATEand use it for all libcurl callbacks (write/header/progress/debug) so GC.compact can’t invalidate stored VALUE pointers. - Pass
ruby_curl_easyas libcurl userdata for default body/header handlers so GC.compact can’t invalidate stored VALUE pointers. - Safer GC: detach
EasyfromMultiduring free to avoid dangling references. - add work around for libcurl 8.16.0 max redirects regression
- Clarify cookie behavior in README and RDoc:
- Differentiate between manual
cookiesheader and the libcurl cookie engine - Add
cookielist=helper and examples for manipulating engine cookies (ALL/SESS/FLUSH/RELOAD) - Note that
cookies = ''clears the manual Cookie header;nilhas no effect
- Differentiate between manual
- Add support for
CURLOPT_REQUEST_TARGET(libcurl ≥ 7.55), includingeasy.request_target=setter, tests, and README usage notes - Clarify that instance
easy.http_postdoes not accept a URL argument; useCurl::Easy.http_post(url, ...)or seteasy.urlfirst - Use after free fix
- Fix on_redirect callback being triggered when follow_location=false and max_redirects=0
- Add support for CURLOPT_NOPROXY option (#441)
- Fix Curl.spnego? to check for both CURL_VERSION_SPNEGO and CURL_VERSION_GSSNEGOTIATE (#227)
- Add Fiber scheduler awareness for Curl::Multi: prefer scheduler-friendly socket-action path and
rb_thread_fd_selectwhen available (non-Windows)- 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)
- When using request method HEAD ensure CURLOPT_NOBODY is set to 1 automatically
- Compiler checks run in parallel when building the extension JOBS=n to adjust concurrency of configure checks and build concurrency
- CI tests now run on Windows and MacOS
-
Add support for CURLOPT_RESOLVE
require 'resolv' uri = URI.parse("https://google.com/") resolved_ip = Resolv.getaddress(uri.host) # perform DNS lookup once mapping = "#{uri.host}:#{uri.port}:#{resolved_ip}" http = Curl::Easy.new("https://google.com/") http.setopt(Curl::CURLOPT_RESOLVE, [mapping]) http.get assert_match(/GET/, http.body)
-
allow configuration curl multi MAX_HOST_CONNECTIONS (#460)
https://curl.se/libcurl/c/CURLMOPT_MAX_HOST_CONNECTIONS.html
- Fix for proxy headers see #457
- Add CI for Ruby 2.7, Ruby 3.3 and 3.4
- PUT and PATCH requests now behave like POST requests with multipart form data supporting http_post, http_put, and http_patch with PostField arguments
-
Clean up easy handle after failing to add to a multi handle
-
With newer versions of libcurl we can use curl_easy_escape instead of curl_escape, this should improve character encoding support
-
When available use curl_multi_wait for greater system compatibility, users of libcurl 7.28.0 and later should benefit from this change
-
Improve easy handle cloning to deep copy related lists, headers, cookies , proxy_headers, ftp_commands and resolve list.
-
FTP: Document correct way to perform NLST/LIST (don’t use
ftp_commandsfor data-transfer commands). Add README section for HTTP proxy tunnel usage and examples, including full LIST snippets. Map the following libcurl options throughEasy#set::dirlistonly->CURLOPT_DIRLISTONLY:ftp_use_epsv->CURLOPT_FTP_USE_EPSV:ftp_use_eprt->CURLOPT_FTP_USE_EPRT:ftp_skip_pasv_ip->CURLOPT_FTP_SKIP_PASV_IPAlso expandftp_commandsRDoc with guidance to avoid LIST/NLST/PASV/EPSV there. Add a basic regression test intests/tc_ftp_options.rbensuring these options can be set without raising.
-
Updating test suite and internal tools for ruby 3.4
-
CURLOPT_COOKIELIST support see examples:
easy.setopt(Curl::CURLOPT_COOKIELIST, "Set-Cookie: c1=v1; domain=localhost; expires=#{expires.httpdate};")
easy.setopt(Curl::CURLOPT_COOKIELIST, [ ['.localhost', 'TRUE', '/', 'FALSE', 0, 'session', '42'].join("\t"),
['.localhost', 'TRUE', '/', 'FALSE', 0, 'session2', '84'].join("\t"), '', ].join("\n") )- Add :on_missing to callbacks supported by Curl::Multi.http
- Fix for PUT request length calculation
- see: #451
- Fix a double quote issue when evaluating cert's path
- see: #454
- Add shorter response_code alias -> code
Curl.get("https://github.com/taf2/curb").code # -> 200
- Improve exception handling from callback functions to ensure correct error line number is reported
- Resolve many compiler warnings
- Adjust how we handle exceptions to handle more cases
- Address alloc function T_DATA see: https://bugs.ruby-lang.org/issues/18007
- Add CURLOPT_PROXY_SSL_VERIFYHOST support
- Fix for exception handling in non standard callback functions on_redirect, on_complete
- Fix missing response code when using Curl::Multi.http with a block
- Fix to ensure redirect handler is called even when follow location is true
- Fix nested Curl.get/post inside of a block
r1 = Curl.get("http://example.com/1") {|http| r2 = Curl.get("http://example.com/2") {|h| } } r1.body # previously was r2's body... this is now fixed
- Restore compatibility with older libcurl installs
- Correctly set empty headers e.g. http.headers['Accept'] = '' # to remove the header from the request
- Add Ruby 3.1 to tests
- Support curlopt_protocols and curlopt_redir_protocols.
- Improved error handling via last_error tracking
- Added support for CURLOPT_RANGE
- Fixes for haproxy protocol via CURLOPT_HAPROXYPROTOCOL
- Ensure dev environments don't use older versions of rake when working on curb (not a production dependency)
- Many readmen updates - more windows support documentation
- Support added for CURLOPT_STDERR
- Fix build with curl
7.62.0 - Support building against Ruby
1.8to help people migrate to the future and beyond
- Improve
timeout=to allow Floating point values which will automatically switch totimeout_ms - Add
SOCKS5_HOSTNAMEsupport - Added
Curl::Multi.autocloseandCurl::Multi#closeto improve connection handling. In past releases connection clean up only ever happens when GC runs. Now in this release you can explicitly control connections viamulti.closeor have it always close your connections withCurl::Multi.autoclose=true
- Request handling reduces C (lines of code), and might resolve segfault when mixing curb with ruby timeout
- Timeout change for anyone who expected
0.9to equal0orinfinity
- Guard use of
CURLOPT_RESOLVEin#if HAVE_CURLOPT_RESOLVE - Prevent
NoMethodErrorwhen no HTTP Status Curl.urlalizewill miss raw url's query params- Fix SSL versions constant names
- Add
Curl::Easy#resolvemethod to implement static IP overrides, bypassing DNS - Add new curl features
- Allow extending
Curl::Easyand having a different number of constructor arguments thanCurl::Easyallows
- Fix
multi.pipeline:HAVE_CURLMOPT_PIPELININGwas never defined - Eliminate warnings on Ruby
2.4.1 - Hang in
select() - Revert 'Experimenting with adding multi handle cleanup after every request, normally would be cleaned up with GC
(problem addressed by fix hang in
select()) - Prevent errant callbacks once the handle is cleaned up
- Add
PATCHsupport? - Add support for
CURLOPT_PATH_AS_IS - Add
.cookielistmethod toCurb::Easy - Improved Windows compatibility
- Correctly check for constants that may not be present in older versions of Curl
- Breaking change - Change base class for exceptions from
ExceptiontoStandardError
- Segmentation fault (introduced with commit 50ab567)
- Use 64-bit int for key in hash of active easy handles, to avoid clobbering on 32-bit systems
- Fix
http_auth_typesfor:anyand:anysafe - Use
LONG2NUMandNUM2LONGto support all values of thelongtype - Support empty reason phrases in the HTTP status line
- Implement setting of
CURLOPT_MAXCONNECTS - Implement setting of
CURLOPT_FORBID_REUSE - Ability to specify specific allowed TLS versions when connecting
- Add support for
HTTP/2.0and multiplexing - Experimenting with adding multi handle cleanup after every request, normally would be cleaned up with GC
- Fix regression in
timeout/timeout_mshandling
- Remove
CURLAUTH_ANYas the default for authentication setting, as too many services in the world don't respond correctly with a401but instead403so the option rarely works as we'd hope - Use the memory address as the key to correctly keep a hash of active easy handles alive in the multi handle -- should resolve existing reports of memory leaks as well as crashes under some conditions
- Only append query string if it exists
- Setting any of
CURLOPT_HEADER,CURLOPT_NOPROGRESS,CURLOPT_NOSIGNAL,CURLOPT_HTTPGETdid not work (introduced in commits4358d04and14e9b53) - Compilation for curl versions before
7.40.0 Curl::Multi.httpcall of theon_completecallback expects unsupplied parameter
- Add
Curl::HTTP_2_0, andCurl.http2? - Support
CURLOPT_UNIX_SOCKET_PATHinCurl::Easy - Add
timeout_ms/connect_timeout_msoptions - Add
on_redirectcallback handling to.http
- Restore support for older,
pre-7.17versions of curl (fixes CentOS 5 compatibility) - Improve Ruby
2.2.xsupport (userb_thread_fd_selectinstead ofrb_thread_select)
- Add SOCKS4A support
- Allow custom ssl cipher lists
- Add install instructions for Windows
- Make it possible easily reset the Thread current handle (
Curl.reset)
- Add support for the new error
CURLM_ADDED_ALREADYintroduced at curl7.33.0 - Add conditionals for new
URLM_ADDED_ALREADYerror Curl#urlalize-CGI.escapefor param values- Use correct HTTP verb for DELETE requests (was
delete, and some servers are apparently case sensitive) - Typo in
ext/curb_errors.c:BadBasswordError->BadPasswordError - Status method now returns the last status in the response header
- Support Ruby
2.2.0 - Support
CURLOPT_TCP_NODELAYinCurl::Easy - Raise an exception if
curbdoesn't know how to handle aCURLOPT - Expose license via gemspec
- Implement seek function for multi-pass authentication uploads
- Guard against a curl without GSSAPI delegation compiled in
- Added
extconf.rbentry forappconnect - Reset handle before each call when using "super simple API"
- Added support for
app_connect_timefromlibcurl - Alias
body_strtobodyandheader_strtohead
- Setting
post_bodytonildoes not reset data posted inhttp(:GET) - Various spurious/inconsequential warnings
Curl.headusesOPTIONSmethod instead ofHEADmethod
- Make "super simple API" more efficient by storing
Curl::Easyinstance inThread.current - GSSAPI: Add required flags for GSSAPI delegation support
- GSSAPI: Allow setting of the new delegation flag
- GSSAPI: Implement support for libcurl SPNEGO flags in curb
- Clang compatibility
- Allow string data with simpler interface e.g.
Curl.post('...', 'data')
- Error installing on Ubuntu
- Protect callbacks from reset/close
Curl::Multinot actually performing HTTP requests in cases when the:max_connects >= number of requests- Build error when compiled with
-Werror=format-security postalizeparameter escaping
- Support
CURLINFO_REDIRECT_URL - Support
CURLOPT_RESUME_FROMinCurl::Easy - Add
.statustoCurl::Easyinstances - Support
CURLOPT_FAILONERROR - Add even easier interface:
Curl.get/Curl.post/ e.t.c
- Breaking change -
on_failureonly fires for 5xx responses
- Error in README section for HTTP POST file upload.
- Add a default for
resolve_modetoCURL_IPRESOLVE_WHATEVERe.g.:auto - Add
on_redirectandon_missingcallbacks for 3xx/4xx responses - Allow
http_post(array_of_fields)when using multipart form posts
- Check for obsolete, since it appears to be gone from later versions of libcurl per issue #100
- Regression in PUT requests with NULL bytes (caused by
RSTRING_PTR=>StringValueCStrchange)
- Restore compatibility with 0.7.16 (e.g. suport for building without
CURLOPT_SEEKDATA, etc) - Use
rb_thread_blocking_regionwhen available in place ofrb_thread_selectfor ruby 1.9.x - Copy-paste mistake which made it impossible to set
CURLOPT_SSL_VERIFYHOSTto2 - Copy-paste mistake that caused
CURLOPT_SSL_VERIFYPEERto be overwritten by the value ofuse_netrcsetting
- Warn on exceptions in success/failure/complete callbacks
- Use
StringValueCStrmore instead of the less safeRSTRING_PTR - Defaulting
CURLOPT_SSL_VERIFYHOSTto2to make it consistent with cURLs default value
- Add better support for timeouts - issue 48
- Improve stability, avoid bus errors when raising in callbacks
- Allow Content-Length header when sending a PUT request
- Better handling of cacert
- Support
CURLOPT_IPRESOLVE - Allow
PostField.file#to_s - Minor refactoring to how
PostField.filehandles strings - Accept symbol and any object that
responds_to?(:to_s)foreasy.http(:verb) - Free memory sooner after a request finishes instead of waiting for garbage collection
- Fix crash when sending nil for the
http_putbody - Fix inspect for
Curl::Easy, thanks Hongli Lai - Fix unit test assertions for
Curl::Multi, thanks Hongli Lai
Curl::Multiperform is more robust process callbacks before exiting the loop - issue 24. Thanks to igrigorik and ramsingla- improve
Curl::Multiidle callback robustness, trigger callbacks more often - issue 24. Thanks to igrigorik and ramsingla
- fix bug in http_* when http_delete or http("verb") raises an exception
- add support for autoreferrer e.g. if follow_location=true it will pass that along
- minor fix for no signal instead of INT2FIX Check boolean value
- add support to set the http version e.g.
easy.version = Curl::HTTP_1_1 - add support to disable libcurls internal use of signals.
- Support rubinius
- allow Multi.download to be called without a block
- add additional
Multi.downloadexamples
- Start tracking high level changes
- Add
Curl::Easy#close- hard close an easy handle - Add
Curl::Easy#reset- reset all settings but keep connections alive - Maintain persistent connections for single easy handles