NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #2437 most downloaded on crates.io
The practical HTTP client that is fun to use.
Last release 3 months ago
05 Jul 2026
Ships unpredictably
gaps range from 1 weeks to 3.9 years
Nearly every release is documented
notes for 48 of 48 stable releases
Nothing withdrawn
no release was ever pulled
7 years old
49 releases · first in 2019
Bump minimum curl-sys version from 0.4.81 to 0.4.90
One column per quarter.
This release includes a handful of breaking changes, primarily around TLS backends and the TLS API. For more detail on these changes and how to adapt…
This release includes a handful of breaking changes, primarily around TLS backends and the TLS API. For more detail on these changes and how to adapt your code when upgrading from 1.x, please see the migration guide.
Configurable with a new tls module consolidated into tls::TlsConfig. The names of all individual options have been renamed, and include several small breaking changes. (#491)
config::CaCertificate renamed to tls::TrustStore, and expanded with new methods for selecting entire providers of CA certificates, beyond just a single PEM bundle.config::ClientCertificate has been renamed to tls::Identity with additional options for loading certificates and keys from other formats.config::PrivateKey has been moved to tls::PrivateKey.config::SslOption has been removed and merged into regular builder methods for tls::TlsConfig.NetworkInterface into multiple types in a new net::interface module, which has a more natural API and also supports combining multiple criteria for selecting an interface to bind to. (#494)config module into the net module. (#518)
config::Dialer and config::DialerParseError moved into net.config::IpVersion moved to net::IpVersion.config::DnCache and config::ResolveMap moved into net::dns.tls::Issuer. Not all backends support this option. (#491)trust-webpki-roots crate feature, which can be used with any TLS backend. This can be used automatically by default combined with rustls by enabling the rustls-tls-webpki-roots crate feature. (#492)Remove the restriction on curl-sys dependency versions from the prior release, now that the latest version of curl-sys fixes the DNS hanging issue. Ru
cargo update should be enough to pull in the latest version of Isahc 1.x and of curl-sys.Locked curl-sys to at most 0.4.87 due to a regression in the latest version that causes DNS to hang indefinitely on Windows. See #501 for more info.
Fix an agent panic in selector that would sometimes be triggered by multiple socket interests communicated from libcurl for the same socket. Error han
Debug impl for empty request bodies to distinguish between an empty body and no body.chore: Release package isahc version 1.8.0
chore: Release package isahc version 1.8.0
This is the first maintenance release in a few years and includes a few housekeeping items. No major changes or additions.
psl crate which provides the same functionality. (#477)once_cell has been removed in favor of the equivalent types now provided in std. (#478)Upgrade curl-sys to 0.4.55 to pull in libcurl 7.83.1, which contains security patches for the below vulnerabilities. (#394) @sagebind
curl-sys to 0.4.55 to pull in libcurl 7.83.1, which contains security patches for the below vulnerabilities. (#394) @sagebind
auto_referer option (disabled by default) which could potentially result in sensitive headers being passed to redirect targets unintentionally. (#393) @sagebind
Referer headers being included when two or more redirects are followed in a requestReferer headerReferer header when redirecting from an HTTPS URL to an HTTP URL, as per RFC 7231 recommendationUpdate curl-sys to 0.4.54 to pull in libcurl 7.83.0, which contains security patches for CVE-2022-22576, CVE-2022-27774, CVE-2022-27775, and CVE-2022-…
curl-sys to 0.4.54 to pull in libcurl 7.83.0, which contains security patches for CVE-2022-22576, CVE-2022-27774, CVE-2022-27775, and CVE-2022-27776. (#391) @david-perezAdd new `is_http_version_supported` function which allows you to check whether support for a particular HTTP version is available at runtime. When sta
is_http_version_supported function which allows you to check whether support for a particular HTTP version is available at runtime. When statically linking this will be entirely dependent on your build configuration, but if you are dynamically linking to libcurl then it will vary from system to system. (#368) @sagebindReplace trivial internal usage of chrono with httpdate to avoid any potential reference to CVE-2020-26235 in `time` 0.2. (#361) @sagebind
Cookie::builder and put arbitrary cookies into the cookie jar with CookieJar::set. (#264, #349) @jacobmischkabytes() convenience methods to ReadResponseExt and AsyncReadResponseExt which read the entire response body into a Vec<u8>. (#352) @sagebindtime 0.2. (#361) @sagebindGreatly reduce CPU usage, particularly when receiving long-running or large responses. This was caused by a bug where timeout timers were not being cl
Body::is_empty for HEAD responses (#341, #343)Expose connection info in errors with the addition of Error::local_addr and Error::remote_addr. This allows you to get the local & remote addresses in
Error::local_addr and Error::remote_addr. This allows you to get the local & remote addresses involved in a request, if any, even if an error occurs. (#336, #337) @sagebindExpect header to be configured via Configurable::expect_continue. (#303, #311, #340) @sagebindImprove the documentation on Error and ErrorKind and add Error::is_timeout.
Error and ErrorKind and add Error::is_timeout.Add support for using in-memory client certificates. (#89, #320)
Update Public Suffix List to 5cb7ed8 (#319) @teto-bot
Allow configuring low speed timeouts for transfers, either per-request or as a client default. (#316) @MoSal
0. @sagebindThis release contains some minor performance improvements as a result of some internal changes.
This release contains some minor performance improvements as a result of some internal changes.
select(2) backend to polling. This delivers some throughput improvements in some benchmarks involving concurrent requests. This also removes Isahc's reliance on loopback UDP sockets for selector wakeups. (#17, #243, #263) @sagebindAdd async json() response convenience method to deserialize JSON asynchronous responses to mirror the synchronous one. (#245, #291)
json() response convenience method to deserialize JSON asynchronous responses to mirror the synchronous one. (#245, #291)Fix parsing of quoted cookie values (#288) @theawless
Headers for HTTP/1.x are now always sent with a single trailing space after the colon (:). While not strictly necessary according to RFC 7230, it was
:). While not strictly necessary according to RFC 7230, it was uncommon formatting and poorly-written servers can choke on parsing such headers. (#286, #287)Update future type returned by AsyncReadResponseExt::copy_to to implement Send if both the reader and writer types implement Send. This allows it to w
AsyncReadResponseExt::copy_to to implement Send if both the reader and writer types implement Send. This allows it to work with multithreaded runtimes. (#283, #285)This was done to make it possible to add new errors without breaking changes, and to ensure that errors can always preserve upstream causes efficientl…
Body type has now been broken up into distinct AsyncBody and Body types, with the former implementing only AsyncRead and the latter implementing only Read. This was done to reduce confusion on how to produce and consume body content when in an asynchronous context without blocking. This also makes it possible to use synchronous Read sources such as a File as a request body when using the synchronous API, something that was previously difficult to do. (#202, #262)ResponseExt trait related to reading the response body have been extracted into two new extension traits: AsyncReadResponseExt and ReadResponseExt. Like the previous change, this was done to reduce confusion on which methods to use when consuming a response in an async context. The _async suffix previously used to distinguish between the sync and async methods has been dropped, as it is no longer necessary. (#202, #262)Error type has been significantly refactored and changed into a struct with a separate ErrorKind enum. This was done to make it possible to add new errors without breaking changes, and to ensure that errors can always preserve upstream causes efficiently. The error kinds have also been updated to be clearer and more distinct. (#182, #258)bytes crate is no longer a dependency and Body::from_maybe_shared has been removed. (#261)Configurable::dns_servers has been removed, as it is more likely to confuse users more than anything since it requires libcurl to be compiled with c-ares, which it isn't by default and is unlikely to be.Request, Response, and HttpClient from the prelude module. You will now have to import these directly. Importing large prelude modules can make code more confusing to read and is usually considered an anti-pattern. (#281)WARN to an INFO log. (#280)post_async example usage and improve various method docs. (#273)This was done to make it possible to add new errors without breaking changes, and to ensure that errors can always preserve upstream causes efficientl…
Body type has now been broken up into distinct AsyncBody and Body types, with the former implementing only AsyncRead and the latter implementing only Read. This was done to reduce confusion on how to produce and consume body content when in an asynchronous context without blocking. This also makes it possible to use synchronous Read sources such as a File as a request body when using the synchronous API, something that was previously difficult to do. (#202, #262)ResponseExt trait related to reading the response body have been extracted into two new extension traits: AsyncReadResponseExt and ReadResponseExt. Like the previous change, this was done to reduce confusion on which methods to use when consuming a response in an async context. The _async suffix previously used to distinguish between the sync and async methods has been dropped, as it is no longer necessary. (#202, #262)Error type has been significantly refactored and changed into a struct with a separate ErrorKind enum. This was done to make it possible to add new errors without breaking changes, and to ensure that errors can always preserve upstream causes efficiently. The error kinds have also been updated to be clearer and more distinct. (#182, #258)bytes crate is no longer a dependency and Body::from_maybe_shared has been removed. (#261)Configurable::dns_servers has been removed, as it is more likely to confuse users more than anything since it requires libcurl to be compiled with c-ares, which it isn't by default and is unlikely to be.Fix body length incorrectly returning the length of the compressed body when the server combines compression and Content-Length with auto decompressio
Content-Length with auto decompression enabled. (#265, #267)Add Configurable::ip_version which allows you to restrict resolving hostnames to a specific IP version. (#252, #253) @ArenM
Configurable::ip_version which allows you to restrict resolving hostnames to a specific IP version. (#252, #253) @ArenMFix a regression introduced in 0.9.11 resulting in client-wide redirect policies not being respected. (#250, #251) @sagebind
A surprisingly feature-focused patch release with a couple notable bugfixes. This October Isahc opted-in to Hacktoberfest, and we received a couple ad
A surprisingly feature-focused patch release with a couple notable bugfixes. This October Isahc opted-in to Hacktoberfest, and we received a couple additions from new contributors. Thanks!
HttpClientBuilder::connection_cache_ttl for configuring how long to keep connections open in the cache. (#93, #237) @gsquireHttpClient::cookie_jar, Configurable::cookie_jar, CookieJar::get_by_name, Cookie::value, and more! An example of how to use some of these have been added to examples/cookies.rs. (#215, #233) @sagebindio::Error. (#154, #246) @sagebindHttpClient cloneable. This makes it much more convenient to share a client instance between threads or tasks. (#241, #244) @braunsemiddleware-preview crate feature has been removed and the unstable-interceptors feature has been added. The API is still unstable, but addresses a number of problems with the old proposed middleware API. (#42, #206) @sagebindAdd automatic_decompression option to allow you to disable the automatic response body decompression or enable it on a per-request basis. (#227, #228)
automatic_decompression option to allow you to disable the automatic response body decompression or enable it on a per-request basis. (#227, #228)Add static-ssl feature to mirror curl/static-ssl (#225) @SecurityInsanity
Add title_case_headers option (#205, #218) @sagebind
Add new config::Dialer API that allows you to customize and override what sockets are connected to for a request, regardless of the host in the URL. S
config::Dialer API that allows you to customize and override what sockets are connected to for a request, regardless of the host in the URL. Static IP sockets and Unix sockets are initially supported. (#150, #207) @sagebindCURLOPT_NOBODY in Isahc. (#213, #214, #216) @sagebindFix empty and blank request header values not being sent. (#209, #210)
Upgrade curl to 0.4.30 to mitigate potential init-on-non-main-thread with certain TLS engines on certain platforms. (#189) @sagebind
Invalid read: Multi::close called twice (#198) @DBLouis
Multi::close called twice (#198) @DBLouisTrace level to reduce log noise (#195) @sagebindFix built-in user agent overriding client default headers. (#191) @sagebind
Add the ability to set default outgoing header values to include on all requests when building a custom client. Headers set on a request always take p
Implement Send for the opaque Future type returned by ResponseExt::text_async whenever the response body also implements Send. (#173, #175)
Send for the opaque Future type returned by ResponseExt::text_async whenever the response body also implements Send. (#173, #175)This release includes a number of API improvements and features, as well as a couple bug fixes. The API changes improve ease of use and ergonomics, in
Welcome to a new decade!
This release includes a number of API improvements and features, as well as a couple bug fixes. The API changes improve ease of use and ergonomics, incorporating the new 0.2 version of the http crate, as well as reduces the number of confusing types to help make finding what you are looking for easier in the documentation.
Configurable trait, which unifies the old methods from HttpClientBuilder and RequestBuilderExt into one place. The old methods have been removed, but most programs should compile without changes if the prelude is imported. (#48, #135)Body (#143):
Body::reader and Body::reader_sized have been renamed to Body::from_reader and Body::from_reader_sized, respectively.Body::bytes has been replaced with Body::from_maybe_shared, which uses type downcasting to accept a Bytes if given without having the bytes crate being part of the public API.Body no longer implements From<Bytes> for the reason above.Body::text, Body::text_async, and Body::json have all been removed in favor of the equivalent methods provided by ResponseExt. This was done because the body alone is often not enough information to decode responses in a correct manner. (#142)cookies feature is no longer enabled by default. (#141)Body from an AsyncRead must now be Sync so that Body implements Sync. (#172)text-decoding feature, enabled by default. (#156)Body::is_empty should not return true for a zero-length body that is present (as opposed to no body). (#144)VersionNegotiation more conservative (#159, #164)Don't ask for default features in futures-util because we do not use them. (#134) @jakobhellermann
futures-util because we do not use them. (#134) @jakobhellermannOnly request upgrade to HTTP/2 if it is actually available. (#131) @sagebind
Upgrade from futures-preview to futures 0.3. Largely the same as futures-preview, but a breaking change due to the crate switch. (#116) @sagebind
This release includes an upgrade to the much awaited futures 0.3, as well as some great new features and a few small breaking improvements to the API.
preferred_http_version() method has been removed in favor of a new VersionNegotiation API with more robust configuration, including support for HTTP/2 Prior Knowledge. Generally this will be a mechanical migration from preferred_http_version() to version_negotiation(). If you were previously passing in Version::HTTP_2 in order to enable HTTP/2 on insecure requests, you can now remove this as Isahc will include an Upgrade header and switch to HTTP/2 automatically by default. (#129) @sagebindssl_options() method that permits you to set multiple flags with greater granularity and control. (#128) @sagebindspnego which allows you to configure HTTP Negotiate. Basic and digest auth are also supported. (#115) @sagebindAdd a new metrics API for inspecting various request timing information. (#47, #88) @sagebind
This release adds several new options for configuring connection behavior on an HttpClient, as well as a couple important bug fixes.
This release adds several new options for configuring connection behavior on an HttpClient, as well as a couple important bug fixes.
Fix parsing headers with a colon in their value. Previously headers like Location: https://example.org were being truncated to Location: https. (#82)
Location: https://example.org were being truncated to Location: https. (#82) @puckipediaAdd ResponseExt::effective_uri for retrieving the last visited URI during a single request-response cycle.
ResponseExt::effective_uri for retrieving the last visited URI during a single request-response cycle. (#74)Add the ability to ignore SSL validation. (#71) @jlricon
Upgrade futures-preview dependencies to the latest and greatest of 0.3.0-alpha.18.
HttpClient::new() will now block fully until the client is actually initialized. Previously it would block on some things being initialized, and then return once the agent thread has started. This proved to be a bit too unusual, and had a tendency to cause extra delays for the first few requests being sent. This new behavior should feel much more predictable.HttpClient::new() now returns a Result since creating a client is fallible. Previously this method would panic if instantiation failed, which was not
HttpClient::new() now returns a Result<HttpClient, Error> since creating a client is fallible. Previously this method would panic if instantiation failed, which was not a very API.Default implementation for HttpClient has been removed, since instantiating it is fallible.HttpClient previously would cause any active transfers created by the client to return EOF after emptying the response body buffer. Now the curl multi handle will be kept alive until all transfers are completed or cancelled. In addition, reading from the response body will return a ConnectionAborted error if for some reason the transfer was stopped without finishing. (#65)The project has been renamed from cHTTP to Isahc! This also includes an adorable new project mascot... (#36, #54)
Body has changed from an usize to an u64. usize is too small to fit large file sizes on machines that have less than 64 bit pointer size. (#52)Error::Internal variant has been removed, as a panic is more suitable for the one situation that previously returned this error.Error::TooManyConnections variant has been removed, as it is an artifact from old cHTTP versions. Isahc has no artificial limit on the number of connections that can be used simultaneously outside of system limits.Your coding agent can read these notes before it upgrades. Set up the MCP server →