Releases: http-rs/surf
2.3.2
2.3.1
Fixed git base of 2.3.0
2.3.0
surf is a modular Rust HTTP client built for rapid development. It comes with a powerful middleware system and feature-swappable backend implementations. It is part of the http-rs project and a counterpart to the tide server framework. Check out the docs or join us on Zulip
(v2.3.0 was yanked, faulty git base - v2.3.1 instead)
Additions
surf::Config, a way to configuresurf::Client-s!Config::add_header()- client-wide headersConfig::set_base_url()- client-wide base urlConfig::set_http_keep_alive()Config::set_tcp_no_delay()Config::set_timeout()- per-request timeout.Config::set_max_connections_per_host()Config::set_tls_config()- only available onh1-clientorh1-client-rustls.- More config may be available from the underlying
http_client::Config. - Easily turns into a
Clientviastd::convert::TryInto.
- Extra
RequestBuilderhelpers for setting the body from different sources.body_json(),body_string(),body_bytes(),body_file().
Client::request()for making arbitrary HTTP-method requests from a client.
Improvements
- The
h1-clientbackend now uses a shared client for 'one-off' style (surf::get(), etc) requests.- The
curl-clientandhyper-clientbackends already did this.
- The
- The
wasm-clientfeature now pulls ingetrandom's"js"feature.- This isn't a problem since the wasm client only works in a web/emscripten environment anyways.
Deprecations
Client::set_base_urlhas been deprecated in favor ofConfig.
Docs
- Several docs fixes
- Minor 'branding' changes
2.2.0
surf is a modular Rust HTTP client built for rapid development. It comes with a powerful middleware system and feature-swappable backend implementations. It is part of the http-rs project and a counterpart to the tide server framework. Check out the docs or join us on Zulip
Overview
If you use the h1-client, upgrading to this release is recommended.
Additions
h1-client-rustlsfeature flag, for using theasync-h1client withrustlsas the TLS backend.- The TLS backend for
h1-clientis stillasync-native-tls.
- The TLS backend for
- Per-request middleware, provided by
RequestBuilder::middleware(&mut self, impl Middleware). AsRef<Headers>andAsMut<Headers>forsurf::Requestandsurf::Response.
Fixes
- Relative redirects should now be handled by the
RedirectMiddleware. - The
h1-clientfeature should now properly work withhttp-client6.3.0+ without additional feature specification.
Docs
- The
httpdocs now link to the live, up-to-datehttp_typesdocs.
Internal
- Various CI improvements.
2.1.0
This minor release contains follow-up fixes and improvements to Surf 2.0.
Additions
- Added a
hyper-clientcargo feature for enabeling a hyper client backend via http-client.
Fixes
- Fixed
base_urlnot being propagated to theClientinstance in middleware.
Documentation
- Updated documentation for
set_base_url().
2.0.0
This major release of Surf contains substantial improvements through a variety of changes and additions.
(Note: this is a cumulative list of changes since Surf 1.0.3)
Notable mentions include:
- Uses stable standard library
futures! - Much more type compatibility with Tide via http-types!
- Re-usable
Clientwhich is able to make use of connection pooling under the hood. - Reduced generics for
ClientandMiddleware. - Re-worked
Middlewareto useasync_trait.
Major Changes
Surf 2 contains some large API changes, as noted here:
http-types
Surf has switched the common backing type interface (surf::http) from the http (hyperium/http) crate to http-types, which covers a larger set of HTTP-related functionality than hyperium/http does, and allows Surf to use the url standard.
This affects any type that came from surf::http, such as StatusCode (old|new), and includes some new patterns, such as Body.
For more information, see this blog post.
Errors
surf::Exception, which was a plain Box<dyn Error + Send + Sync + 'static>, is no more.
Surf now exports a structured surf::Error type, which holds a StatusCode alongside a dynamic error object.
Just like anyhow, any error can be cast to this type using the ? operator.
For more information, see this blog post.
Middleware
New middleware:
use surf::middleware::{Middleware, Next};
use surf::{Client, Request, Response, Result};
#[surf::utils::async_trait]
impl Middleware for Logger {
async fn handle(
&self,
req: Request,
client: Client,
next: Next<'_>,
) -> Result<Response> {
Ok(res)
}
}RequestBuilder
The top-level convenience request methods, surf::get(), surf::post(), etc, now return a RequestBuilder rather than a Request directly.
Most RequestBuilder functions have shorthand names: RequestBuilder::body() compared to Request::set_body().
let res = surf::get("http://example.org") // Now returns a `surf::RequestBuilder`!
.header(a_header, a_value)
.body(a_body)
.await?;Overall usage was kept the same where possible and reasonable, however now a surf::Client must be used when using middleware.
let client = surf::client()
.with(some_middleware);
let res = client::post(url)
.header(a_header, a_value)
.body(a_body)
.await?;Alternately:
let client = surf::client()
.with(some_middleware);
let req = surf::post(url)
.header(a_header, a_value)
.body(a_body);
let res = client.send(req).await?;Mime
Surf has switched from the mime crate to surf::http::Mime from http-types.
For more information, see this blog post.
Additions
- Switched from
hyperium/httpto http-types. surf::Requestadded many methods that exist intide::Request.surf::Responseadded many methods that exist intide::Response.surf::http, an export ofhttp_types, similar totide::http.surf::middleware::Redirect, a middleware to handle redirect status codes.- All conversions for
RequestandResponsebetweenhttp_typesandsurfnow exist. http_types::{Error, Result}are re-exported assurf::{Error, Result}.- A new
h1-clientfeature enables the new async-h1 backend. - Transcode responses from non-UTF8 charsets using the on-by-default
encodingfeature.
Removals
- Removed
native-clientfeature flag in favor of directcurl-clientdefault. - Removed
hyper-clientfeature flag. (Pending re-addition, see: #234) - Removed
Request::body_string(),Request::body_json(), etc.- This functionality is now done via
Body, orClient::recv_json(),RequestBuilder::recv_json(), etc.
- This functionality is now done via
Changes
- Updated to use stable
futures. wasm-clientfeature is no longer automatic and must be set via cargo features.- All client feature flags are now mutually exclusive.
curl-clientis the default. surf::method_name"one-off" methods now use a shared client internally if the client iscurl-client. (Default)Client::with_http_client()is now generic for anyHttpClientrather than taking anArc<dyn HttpClient>.- (The http client is still stored internally as a dynamic pointer.)
HttpClienthas been upgraded to 6.0, removingClonefrom the built in client backends.surf::Requestchanged many methods to be like those intide::Request.surf::Responsechanged many methods to be like those intide::Response.- Surf now uses
http-types::mimeinstead of themimecrate. TryFrom<http_types::Request> for Requestis nowFrom<http_types::Request> for Request.surf::Clientis no longer generic forC: HttpClient.- Middleware now receives
surf::Requestand returnsResult<surf::Response, E>, and no longer requires a generic bound. - Middleware now uses async-trait, which is exported as
surf::utils::async_trait. - The logger middleware is now exported as
surf::middleware::Logger. (Note: this middleware is used by default.) surf::{method}()e.g.surf::get()now returns asurf::RequestBuilderrather than asurf::Request.- Middleware can no longer be set for individual requests.
- Instead, use a
surf::Clientand register middleware viaclient.with(middleware). - Then, send the request from that client via
client.send()e.g.let res = client.send(request).await?;.
surf::Clientnow can set a "base url" for that client viaclient.set_base_url().Clientis now built on top ofhttp-client.surf::urlhas been moved tosurf::http::url, with asurf::Urlshortcut.
Internal
- Reduce copies when parsing URLs.
- Now only depends on
futures_utilrather than all offutures. wasm-clientnow has proper headless browser CI testing.- Use Clippy in CI.
- Set up an MSRV in CI.
- Stop hitting the network when running tests.
Changes since 2.0.0-alpha.7
- Added:
RequestBuildernow has a.query()function for setting structured querystrings. - Changed:
Client::send()andRequestBuilder::send()are now plain async functions and no longer returnBoxFutures. - Changed:
surf::urlhas been moved tosurf::http::url, with asurf::Urlshortcut.
v2.0.0-alpha.7
-
Merged pull request #245 from taiki-e/rust_2018_idioms
Downgrade rust_2018_idioms from forbid to warn
2.0.0-alpha.6
This is an alpha release in preparation of 2.0.0, so you can start using Surf with stable futures. The aim is for this to be the last 2.0 alpha release.
As of this release, surf::get(), surf::post(), etc, now use a globally shared client internally, allowing for easier access to optimizations such as connection pooling.
Removals
- Removed
native-clientfeature flag in favor of directcurl-clientdefault.
Changes
wasm-clientfeature is no longer automatic and must be set via cargo features.- All client feature flags are now mutually exclusive.
curl-clientis the default. surf::method_name"one-off" methods now use a shared client internally if the client iscurl-client. (Default)Client::with_http_client()is now generic for anyHttpClientrather than taking anArc<dyn HttpClient>.- (The http client is still stored internally as a dynamic pointer.)
HttpClienthas been upgraded to 6.0, removingClonefrom the built in client backends.
Fixes
- Surf can once again build with
--no-default-features(and no client). - Doc updates
Internal
wasm-clientnow has proper headless browser CI testing.
2.0.0-alpha.5
This is an alpha release in preparation of 2.0.0, so you can start using Surf with stable futures. There may be significant breaking changes before the final 2.0 release. Until thin, we recommend pinning to the particular alpha:
[dependencies]
surf = "= 2.0.0-alpha.5"This alpha release notably contains much more API parity with Tide, particularly for surf::Request, surf::Response, and surf::middleware::Middleware. Middleware also is now implemented using async-trait. Additionally, surf::Client is no longer generic and now instead holds the internal HttpClient as a dynamic trait object.
These changes mean that surf middleware must undergo the following changes:
Old middleware:
impl<C: HttpClient> Middleware<C> for Logger {
fn handle<'a>(
&'a self,
req: Request,
client: C,
next: Next<'a, C>,
) -> BoxFuture<'a, Result<Response, http_types::Error>> {
Box::pin(async move {
Ok(res)
})
}
}New middleware:
#[surf::utils::async_trait]
impl Middleware for Logger {
async fn handle(
&self,
req: Request,
client: Client,
next: Next<'_>,
) -> Result<Response> {
Ok(res)
}
}This alpha release also contains large changes to how the surf::Request and surf::Client APIs are structured, adding a surf::RequestBuilder which is now returned from methods such as surf::get(...). Overall usage structure was kept the same where possible and reasonable, however now a surf::Client must be used when using middleware.
let client = surf::client()
.with(some_middleware);
let req = surf::post(url) // Now returns a `surf::RequestBuilder`!
.header(a_header, a_value)
.body(a_body);
let res = client.send(req).await?;Additions
surf::Requestadded many methods that exist intide::Request.surf::Responseadded many methods that exist intide::Response.surf::http, an export ofhttp_types, similar totide::http.surf::middleware::Redirect, a middleware to handle redirect status codes.- All conversions for
RequestandResponsebetweenhttp_typesandsurfnow exist.
Changes
surf::Requestchanged many methods to be like those intide::Request.surf::Responsechanged many methods to be like those intide::Response.- Surf now uses
http_types::mimeinstead of themimecrate. TryFrom<http_types::Request> for Requestis nowFrom<http_types::Request> for Request.surf::Clientis no longer generic forC: HttpClient.- Middleware now receives
surf::Requestand returnsResult<surf::Response, E>, and no longer requires a generic bound. - Middleware now uses async-trait, which is exported as
surf::utils::async_trait. - The logger middleware is now exported as
surf::middleware::Logger. (Note: this middleware is used by default.) surf::{method}()e.g.surf::get()now returns asurf::RequestBuilderrather than asurf::Request.- Middleware can no longer be set for individual requests.
- Instead, use a
surf::Clientand register middleware viaclient.with(middleware). - Then, send the request from that client via
client.send(req)e.g.let res = client.send(request).await?;.
surf::Clientnow can set a "base url" for that client viaclient.set_base_url().
Fixes
From<http_types::Request> for Requestnow properly propagates all properties.- A cloned
surf::Clientno longer adds middleware onto its ancestor's middleware stack. - Some feature flags are now correct.
Internal
- Use Clippy in CI.
- Improved examples.
- Now only depends on
futures_utilrather than all offutures.