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-client
orh1-client-rustls
.- More config may be available from the underlying
http_client::Config
. - Easily turns into a
Client
viastd::convert::TryInto
.
- Extra
RequestBuilder
helpers 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-client
backend now uses a shared client for 'one-off' style (surf::get()
, etc) requests.- The
curl-client
andhyper-client
backends already did this.
- The
- The
wasm-client
feature 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_url
has 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-rustls
feature flag, for using theasync-h1
client withrustls
as the TLS backend.- The TLS backend for
h1-client
is stillasync-native-tls
.
- The TLS backend for
- Per-request middleware, provided by
RequestBuilder::middleware(&mut self, impl Middleware)
. AsRef<Headers>
andAsMut<Headers>
forsurf::Request
andsurf::Response
.
Fixes
- Relative redirects should now be handled by the
RedirectMiddleware
. - The
h1-client
feature should now properly work withhttp-client
6.3.0+ without additional feature specification.
Docs
- The
http
docs now link to the live, up-to-datehttp_types
docs.
Internal
- Various CI improvements.
2.1.0
This minor release contains follow-up fixes and improvements to Surf 2.0.
Additions
- Added a
hyper-client
cargo feature for enabeling a hyper client backend via http-client.
Fixes
- Fixed
base_url
not being propagated to theClient
instance 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
Client
which is able to make use of connection pooling under the hood. - Reduced generics for
Client
andMiddleware
. - Re-worked
Middleware
to 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/http
to http-types. surf::Request
added many methods that exist intide::Request
.surf::Response
added 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
Request
andResponse
betweenhttp_types
andsurf
now exist. http_types::{Error, Result}
are re-exported assurf::{Error, Result}
.- A new
h1-client
feature enables the new async-h1 backend. - Transcode responses from non-UTF8 charsets using the on-by-default
encoding
feature.
Removals
- Removed
native-client
feature flag in favor of directcurl-client
default. - Removed
hyper-client
feature 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-client
feature is no longer automatic and must be set via cargo features.- All client feature flags are now mutually exclusive.
curl-client
is 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 anyHttpClient
rather than taking anArc<dyn HttpClient>
.- (The http client is still stored internally as a dynamic pointer.)
HttpClient
has been upgraded to 6.0, removingClone
from the built in client backends.surf::Request
changed many methods to be like those intide::Request
.surf::Response
changed many methods to be like those intide::Response
.- Surf now uses
http-types::mime
instead of themime
crate. TryFrom<http_types::Request> for Request
is nowFrom<http_types::Request> for Request
.surf::Client
is no longer generic forC: HttpClient
.- Middleware now receives
surf::Request
and 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::RequestBuilder
rather than asurf::Request
.- Middleware can no longer be set for individual requests.
- Instead, use a
surf::Client
and register middleware viaclient.with(middleware)
. - Then, send the request from that client via
client.send()
e.g.let res = client.send(request).await?;
.
surf::Client
now can set a "base url" for that client viaclient.set_base_url()
.Client
is now built on top ofhttp-client
.surf::url
has been moved tosurf::http::url
, with asurf::Url
shortcut.
Internal
- Reduce copies when parsing URLs.
- Now only depends on
futures_util
rather than all offutures
. wasm-client
now 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:
RequestBuilder
now has a.query()
function for setting structured querystrings. - Changed:
Client::send()
andRequestBuilder::send()
are now plain async functions and no longer returnBoxFuture
s. - Changed:
surf::url
has been moved tosurf::http::url
, with asurf::Url
shortcut.
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-client
feature flag in favor of directcurl-client
default.
Changes
wasm-client
feature is no longer automatic and must be set via cargo features.- All client feature flags are now mutually exclusive.
curl-client
is 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 anyHttpClient
rather than taking anArc<dyn HttpClient>
.- (The http client is still stored internally as a dynamic pointer.)
HttpClient
has been upgraded to 6.0, removingClone
from the built in client backends.
Fixes
- Surf can once again build with
--no-default-features
(and no client). - Doc updates
Internal
wasm-client
now 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::Request
added many methods that exist intide::Request
.surf::Response
added 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
Request
andResponse
betweenhttp_types
andsurf
now exist.
Changes
surf::Request
changed many methods to be like those intide::Request
.surf::Response
changed many methods to be like those intide::Response
.- Surf now uses
http_types::mime
instead of themime
crate. TryFrom<http_types::Request> for Request
is nowFrom<http_types::Request> for Request
.surf::Client
is no longer generic forC: HttpClient
.- Middleware now receives
surf::Request
and 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::RequestBuilder
rather than asurf::Request
.- Middleware can no longer be set for individual requests.
- Instead, use a
surf::Client
and 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::Client
now can set a "base url" for that client viaclient.set_base_url()
.
Fixes
From<http_types::Request> for Request
now properly propagates all properties.- A cloned
surf::Client
no 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_util
rather than all offutures
.