tower-http
Tower middleware and utilities for HTTP clients and servers
0.7.0
409M downloads/mo
#282 most downloaded on crates.io
tower-rs/tower-http
What this package is like to depend on
Last release 2 months ago
15 Jun 2026
Release timing varies
gaps range from 2 weeks to 7 months
Most releases are documented
notes for 27 of 32 stable releases
6 versions withdrawn
withdrawn after publishing
9 years old
38 releases · first in 2017
6 releases in the last 12 months
see the full history below
Release timeline
38 releases · Mar 2017 to Jun 2026Releases
latest 38-
0.7.015 Jun 2026Release notes
Open source →Added
-
csrf: add cross-site request forgery (CSRF) protection middleware, porting the cross-origin protection scheme introduced in Go 1.25 (#699)use tower::ServiceBuilder; use tower_http::csrf::CsrfLayer; // Rejects cross-origin state-changing requests using `Sec-Fetch-Site`, // an `Origin` allow-list, and an `Origin`/`Host` fallback. No per-request // token state required. let layer = CsrfLayer::new().add_trusted_origin("https://example.com")?; let service = ServiceBuilder::new().layer(layer).service_fn(handler);
-
timeout: addDeadlineBodyfor non-resetting body timeouts, applied via the newRequestBodyDeadlineLayerandResponseBodyDeadlineLayer(#688)Unlike
TimeoutBody, which resets its deadline on every frame,DeadlineBodycaps the total time of a body transfer. A slow client trickling one byte at a time never trips an idle timeout but will trip a deadline.use std::time::Duration; use tower::ServiceBuilder; use tower_http::timeout::RequestBodyDeadlineLayer; // Abort the request body transfer after 30s total, regardless of how // frequently data arrives. let service = ServiceBuilder::new() .layer(RequestBodyDeadlineLayer::new(Duration::from_secs(30))) .service_fn(handler);
-
fs: add strongETagsupport toServeDir, includingIf-MatchandIf-None-Matchprecondition handling per RFC 9110.304 Not Modifiedresponses now carry theETagandLast-Modifiedvalidators (#691) -
fs: add aBackendtrait to makeServeDirwork with non-filesystem sources (e.g. embedded assets or object storage). The defaultTokioBackendpreserves existing behavior. UseServeDir::with_backend()to plug in custom implementations (#684)use tower_http::services::fs::ServeDir; // `MyBackend` implements `tower_http::services::fs::Backend`. // The default `ServeDir::new()` continues to use `TokioBackend` (local FS). let service = ServeDir::with_backend("assets", MyBackend::new());
-
fs: addhtml_as_default_extensionoption toServeDir, appending.htmlwhen the request path has no extension (#519) -
fs: addredirect_path_prefixoption toServeDir, prepending a prefix on trailing-slash redirects so the service can be mounted under a sub-path (#486) -
validate-request: addValidateRequestHeaderLayer::has_header_value()to reject requests when a header does not have an expected value (#360) -
body:UnsyncBoxBody::new()constructor andFrom<ServeFileSystemResponseBody>conversion to avoid double-boxing when combiningServeDirresponses with other body types (#537) -
limit: implementDefaultforlimit::ResponseBodywhen the wrapped body also implementsDefault(#679)
Changed
-
breaking:
compression: the middleware now handles the*wildcard andidentity;q=0in Accept-Encoding per RFC 9110 §12.5.3. Requests that previously fell back to identity (e.g.*;q=0oridentity;q=0with no other acceptable encoding) now receive a 406 Not Acceptable response. Clients that explicitly reject all encodings without listing an alternative will see different behavior. (#693) -
breaking:
compression: upgrade theSizeAbovepredicate threshold fromu16tou64, allowing minimum sizes above 64 KiB (#704) -
breaking: remove the implicit no-op
tokioandasync-compressionfeatures. These were kept as no-op features in 0.6.x for backwards compatibility after the switch todep:syntax in #642. Downstream crates that activatetower-http/tokioortower http/async-compressionshould remove those feature entries; the underlying dependencies are still pulled in transitively by the features that need them (e.g.compression-gzip,fs,timeout). (#628) -
breaking:
trace/classify: include the gRPC error message in tracing output.GrpcCodeandGrpcFailureClassare now#[non_exhaustive], andGrpcStatusis exported from theclassifymodule (#422) -
breaking:
follow-redirect:FollowRedirectnow forwards requestExtensionsto redirected requests instead of dropping them. TheStandardpolicy drops extensions on cross-origin redirections (same-origin keeps them). Opt out withFollowRedirectLayer::preserve_extensions(false); keep specific types withFilterCredentials::allow_extension::<T>()or all of them withkeep_all_extensions(). (#706)use tower_http::follow_redirect::FollowRedirectLayer; // 0.7.0 forwards request `Extensions` across redirects by default. // Restore the previous behavior (drop all extensions) with: let layer = FollowRedirectLayer::new().preserve_extensions(false);
-
breaking:
follow-redirect: header and extension filtering is now cumulative. A value a policy drops on one hop is no longer replayed on later hops, soFilterCredentialsno longer re-sendsCookie/Authorizationto a same-origin target reached after cross-origin hop. CustomPolicy::on_requestimpls now see the previous hop's filtered request, not the original. (#706) -
trace:DefaultOnRequest,DefaultOnResponse,DefaultOnFailure, andDefaultOnEosnow explicitly parent their tracing events to the request span rather than relying on the ambient span context. This fixes intermittent cases where events could appear without their request span attached (#690) -
cors: relax theVaryheader defaults (#674) -
MSRV bumped from 1.64 to 1.65 (#684)
Fixed
fs:ServeDirandServeFilenow emit aVary: Accept-Encodingresponse
header when precompressed serving is configured, ensuring caches correctly
distinguish between compressed and uncompressed variants (#692)- breaking:
services: reject a trailing slash for file paths. File requests with a trailing slash now return404 Not Foundinstead of serving the file (#678) fs: fixServeDirstripping the file extension when serving with identity encoding (#686)compression: forward trailers from the inner body after compression finishes, fixing dropped gRPC status trailers (#685)trace: fireon_eoswhen the inner body reportsis_end_streamwith a precise content-length (#687)on-early-drop: suppress the early-drop guard whenis_end_streamis reported after a data frame (#687)set-header: makeSetMultipleRequestHeadersandSetMultipleResponseHeadersClonefor non-CloneHTTP bodies (#703)
Thanks
New Contributors
- @muhamadazmy made their first contribution in #679
- @Isvane made their first contribution in #678
- @xiaoyawei made their first contribution in #422
- @dependabot[bot] made their first contribution in #696
- @its-the-shrimp made their first contribution in #519
- @yawn made their first contribution in #699
- @Jesse-Bakker made their first contribution in #703
- @junghwan16 made their first contribution in #705
- @claraphyll made their first contribution in #486
Release notes
Open source →Added
-
csrf: add cross-site request forgery (CSRF) protection middleware, porting the cross-origin protection scheme introduced in Go 1.25 (#699)use tower::ServiceBuilder; use tower_http::csrf::CsrfLayer; // Rejects cross-origin state-changing requests using `Sec-Fetch-Site`, // an `Origin` allow-list, and an `Origin`/`Host` fallback. No per-request // token state required. let layer = CsrfLayer::new().add_trusted_origin("https://example.com")?; let service = ServiceBuilder::new().layer(layer).service_fn(handler); -
timeout: addDeadlineBodyfor non-resetting body timeouts, applied via the newRequestBodyDeadlineLayerandResponseBodyDeadlineLayer(#688)Unlike
TimeoutBody, which resets its deadline on every frame,DeadlineBodycaps the total time of a body transfer. A slow client trickling one byte at a time never trips an idle timeout but will trip a deadline.use std::time::Duration; use tower::ServiceBuilder; use tower_http::timeout::RequestBodyDeadlineLayer; // Abort the request body transfer after 30s total, regardless of how // frequently data arrives. let service = ServiceBuilder::new() .layer(RequestBodyDeadlineLayer::new(Duration::from_secs(30))) .service_fn(handler); -
fs: add strongETagsupport toServeDir, includingIf-MatchandIf-None-Matchprecondition handling per RFC 9110.304 Not Modifiedresponses now carry theETagandLast-Modifiedvalidators (#691) -
fs: add aBackendtrait to makeServeDirwork with non-filesystem sources (e.g. embedded assets or object storage). The defaultTokioBackendpreserves existing behavior. UseServeDir::with_backend()to plug in custom implementations (#684)use tower_http::services::fs::ServeDir; // `MyBackend` implements `tower_http::services::fs::Backend`. // The default `ServeDir::new()` continues to use `TokioBackend` (local FS). let service = ServeDir::with_backend("assets", MyBackend::new()); -
fs: addhtml_as_default_extensionoption toServeDir, appending.htmlwhen the request path has no extension (#519) -
fs: addredirect_path_prefixoption toServeDir, prepending a prefix on trailing-slash redirects so the service can be mounted under a sub-path (#486) -
validate-request: addValidateRequestHeaderLayer::has_header_value()to reject requests when a header does not have an expected value (#360) -
body:UnsyncBoxBody::new()constructor andFrom<ServeFileSystemResponseBody>conversion to avoid double-boxing when combiningServeDirresponses with other body types (#537) -
limit: implementDefaultforlimit::ResponseBodywhen the wrapped body also implementsDefault(#679)
Changed
-
breaking:
compression: the middleware now handles the*wildcard andidentity;q=0in Accept-Encoding per RFC 9110 §12.5.3. Requests that previously fell back to identity (e.g.*;q=0oridentity;q=0with no other acceptable encoding) now receive a 406 Not Acceptable response. Clients that explicitly reject all encodings without listing an alternative will see different behavior. (#693) -
breaking:
compression: upgrade theSizeAbovepredicate threshold fromu16tou64, allowing minimum sizes above 64 KiB (#704) -
breaking: remove the implicit no-op
tokioandasync-compressionfeatures. These were kept as no-op features in 0.6.x for backwards compatibility after the switch todep:syntax in #642. Downstream crates that activatetower-http/tokioortower-http/async-compressionshould remove those feature entries; the underlying dependencies are still pulled in transitively by the features that need them (e.g.compression-gzip,fs,timeout). (#628) -
breaking:
trace/classify: include the gRPC error message in tracing output.GrpcCodeandGrpcFailureClassare now#[non_exhaustive], andGrpcStatusis exported from theclassifymodule (#422) -
breaking:
follow-redirect:FollowRedirectnow forwards requestExtensionsto redirected requests instead of dropping them. TheStandardpolicy drops extensions on cross-origin redirections (same-origin keeps them). Opt out withFollowRedirectLayer::preserve_extensions(false); keep specific types withFilterCredentials::allow_extension::<T>()or all of them withkeep_all_extensions(). (#706)use tower_http::follow_redirect::FollowRedirectLayer; // 0.7.0 forwards request `Extensions` across redirects by default. // Restore the previous behavior (drop all extensions) with: let layer = FollowRedirectLayer::new().preserve_extensions(false); -
breaking:
follow-redirect: header and extension filtering is now cumulative. A value a policy drops on one hop is no longer replayed on later hops, soFilterCredentialsno longer re-sendsCookie/Authorizationto a same-origin target reached after a cross-origin hop. CustomPolicy::on_requestimpls now see the previous hop's filtered request, not the original. (#706) -
trace:DefaultOnRequest,DefaultOnResponse,DefaultOnFailure, andDefaultOnEosnow explicitly parent their tracing events to the request span rather than relying on the ambient span context. This fixes intermittent cases where events could appear without their request span attached (#690) -
cors: relax theVaryheader defaults (#674) -
MSRV bumped from 1.64 to 1.65 (#684)
Fixed
fs:ServeDirandServeFilenow emit aVary: Accept-Encodingresponse header when precompressed serving is configured, ensuring caches correctly distinguish between compressed and uncompressed variants (#692)- breaking:
services: reject a trailing slash for file paths. File requests with a trailing slash now return404 Not Foundinstead of serving the file (#678) fs: fixServeDirstripping the file extension when serving with identity encoding (#686)compression: forward trailers from the inner body after compression finishes, fixing dropped gRPC status trailers (#685)trace: fireon_eoswhen the inner body reportsis_end_streamwith a precise content-length (#687)on-early-drop: suppress the early-drop guard whenis_end_streamis reported after a data frame (#687)set-header: makeSetMultipleRequestHeadersandSetMultipleResponseHeadersClonefor non-CloneHTTP bodies (#703)
-
-
0.6.1118 May 2026Release notes
Open source →Added
-
set-header: addSetMultipleResponseHeadersLayerand
SetMultipleResponseHeaderfor setting multiple response headers at once.
Supportsoverriding,appending, andif_not_presentmodes. Header
values can be fixed or computed dynamically via closures (#672)use http::{Response, header::{self, HeaderValue}}; use http_body::Body as _; use tower_http::set_header::response::SetMultipleResponseHeadersLayer; let layer = SetMultipleResponseHeadersLayer::overriding(vec![ (header::X_FRAME_OPTIONS, HeaderValue::from_static("DENY")).into(), (header::CONTENT_LENGTH, |res: &Response<MyBody>| { res.body().size_hint().exact() .map(|size| HeaderValue::from_str(&size.to_string()).unwrap()) }).into(), ]);
-
set-header: addSetMultipleRequestHeadersLayerand
SetMultipleRequestHeadersfor setting multiple request headers at once,
mirroring the response-side API (#677) -
classify: addFrom<i32>andFrom<NonZeroI32>impls forGrpcCode.
Unrecognized status codes map toGrpcCode::Unknown(#506)
Changed
compression: compressapplication/grpc-webresponses. Previously all
application/grpc*content types were excluded from compression; now only
application/grpc(non-web) is excluded (#408)
Fixed
fs: fixServeDirreturning 500 instead of 405 for non-GET/HEAD requests
whencall_fallback_on_method_not_allowedis enabled but no fallback service
is configured (#587)fs: remove duplicatecfgattribute onis_reserved_dos_name(#675)
All PRs
- ci: fix flaky encoding test, add nightly stress test job by @jlizen in #670
- ci: use static timeout in stress-test workflow by @jlizen in #671
- Fix serve_dir method not allowed handling when no fallback is configured by @soerenmeier in #587
- Do compress grpc-web responses by @bouk in #408
- add From impl for GrpcCode by @gshipilov in #506
- feat(set_header): refactor and improve multiple header middleware by @seun-ja in #672
- Remove duplicate cfg attribute for is_reserved_dos_name by @GlenDC in #675
- feat: set multiple request header by @seun-ja in #677
- chore: release 0.6.11 by @jlizen in #673
New Contributors
- @gshipilov made their first contribution in #506
- @seun-ja made their first contribution in #672
Full Changelog: tower-http-0.6.10...tower-http-0.6.11
Release notes
Open source →Added
-
set-header: addSetMultipleResponseHeadersLayerandSetMultipleResponseHeaderfor setting multiple response headers at once. Supportsoverriding,appending, andif_not_presentmodes. Header values can be fixed or computed dynamically via closures (#672)use http::{Response, header::{self, HeaderValue}}; use http_body::Body as _; use tower_http::set_header::response::SetMultipleResponseHeadersLayer; let layer = SetMultipleResponseHeadersLayer::overriding(vec![ (header::X_FRAME_OPTIONS, HeaderValue::from_static("DENY")).into(), (header::CONTENT_LENGTH, |res: &Response<MyBody>| { res.body().size_hint().exact() .map(|size| HeaderValue::from_str(&size.to_string()).unwrap()) }).into(), ]); -
set-header: addSetMultipleRequestHeadersLayerandSetMultipleRequestHeadersfor setting multiple request headers at once, mirroring the response-side API (#677) -
classify: addFrom<i32>andFrom<NonZeroI32>impls forGrpcCode. Unrecognized status codes map toGrpcCode::Unknown(#506)
Changed
compression: compressapplication/grpc-webresponses. Previously allapplication/grpc*content types were excluded from compression; now onlyapplication/grpc(non-web) is excluded (#408)
Fixed
-
-
0.6.1006 May 2026Release notes
Open source →Added
follow-redirect: exposeAttempt::method()andAttempt::previous_method()
so redirect policies can react to method changes across redirects (e.g.
POST to GET on 301/303) (#559)
Fixed
- Restore
tokioandasync-compressionas no-op features. These will be
removed next breaking release (#667)
What's Changed
- fix: restore tokio and async-compression as no-op features by @jlizen in #667
- fix gate-ing of atomic64 in tests by @alexanderkjall in #607
- follow_redirect: expose previous and next request methods by @lucab in #559
- chore: release tower-http 0.6.10 by @jlizen in #669
New Contributors
Full Changelog: tower-http-0.6.9...tower-http-0.6.10
Release notes
Open source →Added
follow-redirect: exposeAttempt::method()andAttempt::previous_method()so redirect policies can react to method changes across redirects (e.g. POST to GET on 301/303) (#559)
Fixed
- Restore
tokioandasync-compressionas no-op features. These will be removed next breaking release (#667)
-
0.6.905 May 2026Release notes
Open source →Added:
-
on-early-drop: middleware that detects when a response future or response
body is dropped before completion (#636)Two events get hooks: the response future being dropped before
the inner service produces a response, and the response body being
dropped before reaching end-of-stream.Install custom callbacks with
OnEarlyDropLayer::builder():use http::Request; use tower_http::on_early_drop::{OnBodyDropFn, OnEarlyDropLayer}; let layer = OnEarlyDropLayer::builder() .on_future_drop(|req: &Request<()>| { let uri = req.uri().clone(); move || eprintln!("future dropped for {}", uri) }) .on_body_drop(OnBodyDropFn::new(|req: &Request<()>| { let uri = req.uri().clone(); move |parts: &http::response::Parts| { let status = parts.status; move || eprintln!("body dropped for {} status {}", uri, status) } }));
Or route both events through a
trace::OnFailurehook with
EarlyDropsAsFailures. Place this layer inside aTraceLayerso the
emitted events inherit the request span:use tower::ServiceBuilder; use tower_http::on_early_drop::{OnEarlyDropLayer, EarlyDropsAsFailures}; use tower_http::trace::{DefaultOnFailure, TraceLayer}; let stack = ServiceBuilder::new() .layer(TraceLayer::new_for_http()) .layer(OnEarlyDropLayer::new( EarlyDropsAsFailures::new(DefaultOnFailure::default()), ));
-
fs: makeAsyncReadBody::with_capacitypublic (#415)
Changed:
- The implicit
async-compressionfeature is removed (#642) - The implicit
tokiofeature is removed (#628) fs: no longer auto-enables thetracingcrate feature; enabletracing
explicitly to restore error logging onServeDirIO failures (#614)
Fixed
trace: restore failure classification at end-of-stream (#483)follow-redirect: support unicode URLs (swapsiri-stringdep for
url) (#646)fs: reject reserved Windows DOS device names (CON,COM1, etc.) in
ServeDir(#663)
All the PRs
- ci: update deny action to v2 by @seanmonstar in #627
- chore: improve code comments clarity by @xibeiyoumian in #626
- ci: Update to actions/checkout v6 by @tottoto in #629
- ci: msrv resolver by @seanmonstar in #635
- chore: Remove resolved cargo-deny config by @tottoto in #631
- ci: Update to cargo-check-external-types 0.4.0 by @tottoto in #633
- examples: Use typed default value clap config by @tottoto in #634
- examples: Disable unused reqwest feature by @tottoto in #632
- examples: Update to reqwest 0.13 by @tottoto in #640
- Fix clippy warnings in warp-key-value-store example by @jplatte in #637
- ci: Use Swatinem/rust-cache@v2 to cache by @tottoto in #644
- ci: Remove unused working-directory config by @tottoto in #645
- Use cargo-deny graph config by @tottoto in #639
- Fix: follow redirect unicode in #646
- doc: remove mention of deprecated bearer method in lib.rs comment by @VojtaStanek in #641
- Allow Unicode-3.0 license by @tottoto in #648
- fix(docs): typo by @carlocorradini in #649
- fix: remove unused GzEncoder import in decompression in #647
- docs: update Example server in #652
- Don't automatically enable tracing for fs feature by @ginnyTheCat in #614
- examples: Remove unnecessary trait bound by @tottoto in #651
- Remove implicit async-compression feature by @tottoto in #642
- fix clippy warnings by @alexanderkjall in #659
- Check for reserved DOS names by @Darksonn in #663
- enable clippy for tower-http and fix current issues by @GlenDC in #407
- chore: remove implicit tokio feature by @WaterWhisperer in #628
- trace: adds back call to classify_eos on trailers by @markdingram in #483
- Make AsyncReadBody::with_capacity public by @bouk in #415
- examples: Use axum::body::to_bytes by @tottoto in #650
- ci: Remove unnecessary protoc setup by @tottoto in #665
- feat(on-early-drop): Add middleware for client early drop detection by @fbergero in #636
- chore: release tower-http 0.6.9 by @jlizen in #666
New Contributors
- @xibeiyoumian made their first contribution in #626
- @VojtaStanek made their first contribution in #641
- @carlocorradini made their first contribution in #649
- @ginnyTheCat made their first contribution in #614
- @alexanderkjall made their first contribution in #659
- @Darksonn made their first contribution in #663
- @WaterWhisperer made their first contribution in #628
- @bouk made their first contribution in #415
- @fbergero made their first contribution in #636
- @jlizen made their first contribution in #666
Full Changelog: tower-http-0.6.8...tower-http-0.6.9
Release notes
Open source →Added:
-
on-early-drop: middleware that detects when a response future or response body is dropped before completion (#636)Two events get hooks: the response future being dropped before the inner service produces a response, and the response body being dropped before reaching end-of-stream.
Install custom callbacks with
OnEarlyDropLayer::builder():use http::Request; use tower_http::on_early_drop::{OnBodyDropFn, OnEarlyDropLayer}; let layer = OnEarlyDropLayer::builder() .on_future_drop(|req: &Request<()>| { let uri = req.uri().clone(); move || eprintln!("future dropped for {}", uri) }) .on_body_drop(OnBodyDropFn::new(|req: &Request<()>| { let uri = req.uri().clone(); move |parts: &http::response::Parts| { let status = parts.status; move || eprintln!("body dropped for {} status {}", uri, status) } }));Or route both events through a
trace::OnFailurehook withEarlyDropsAsFailures. Place this layer inside aTraceLayerso the emitted events inherit the request span:use tower::ServiceBuilder; use tower_http::on_early_drop::{OnEarlyDropLayer, EarlyDropsAsFailures}; use tower_http::trace::{DefaultOnFailure, TraceLayer}; let stack = ServiceBuilder::new() .layer(TraceLayer::new_for_http()) .layer(OnEarlyDropLayer::new( EarlyDropsAsFailures::new(DefaultOnFailure::default()), )); -
fs: makeAsyncReadBody::with_capacitypublic (#415)
Changed:
- The implicit
async-compressionfeature is removed (#642) - The implicit
tokiofeature is removed (#628) fs: no longer auto-enables thetracingcrate feature; enabletracingexplicitly to restore error logging onServeDirIO failures (#614)
Fixed
-
-
0.6.808 Dec 2025Release notes
Open source →Fixed
- Disable
multiple_membersin Gzip decoder, since HTTP context only uses one
member. (#621)
What's Changed
- Disable
multiple_membersoption for gzip decoder by @ducaale in #621 - ci: Pin tracing in MSRV job by @ducaale in #622
- ci: Switch cargo-public-api-crates to cargo-check-external-types by @tottoto in #613
- Remove deprecated annotations and Refactor From implementations by @sinder38 in #608
- v0.6.8 by @seanmonstar in #624
New Contributors
Full Changelog: tower-http-0.6.7...tower-http-0.6.8
Release notes
Open source →Fixed
- Disable
multiple_membersin Gzip decoder, since HTTP context only uses one member. (#621)
- Disable
-
0.6.724 Nov 2025Release notes
Open source →Added
TimeoutLayer::with_status_code(status)to define the status code returned
when timeout is reached. (#599)
Deprecated
auth::require_authorizationis too basic for real-world. (#591)TimeoutLayer::new()should be replaced with
TimeoutLayer::with_status_code(). (Previously was
StatusCode::REQUEST_TIMEOUT) (#599)
Fixed
on_eosis now called even for successful responses. (#580)ServeDir: call fallback when filename is invalid (#586)decompressionwill not fail when body is empty (#618)
New Contributors
- @mladedav made their first contribution in #580
- @aryaveersr made their first contribution in #586
- @soerenmeier made their first contribution in #588
- @gjabell made their first contribution in #591
- @FalkWoldmann made their first contribution in #599
- @ducaale made their first contribution in #618
Full Changelog: tower-http-0.6.6...tower-http-0.6.7
Release notes
Open source →Added
TimeoutLayer::with_status_code(status)to define the status code returned when timeout is reached. (#599)
Deprecated
auth::require_authorizationis too basic for real-world. (#591)TimeoutLayer::new()should be replaced withTimeoutLayer::with_status_code(). (Previously wasStatusCode::REQUEST_TIMEOUT) (#599)
Fixed
-
0.6.603 Jun 2025Release notes
Open source →Fixed
- compression: fix panic when looking in vary header (#578)
New Contributors
Full Changelog: tower-http-0.6.5...tower-http-0.6.6
-
0.6.502 Jun 2025 withdrawnRelease notes
Open source →Added
- normalize_path: add
append_trailing_slash()mode (#547)
Fixed
- redirect: remove payload headers if redirect changes method to GET (#575)
- compression: avoid setting
vary: accept-encodingif already set (#572)
New Contributors
- @daalfox made their first contribution in #547
- @mherrerarendon made their first contribution in #574
- @linyihai made their first contribution in #575
Full Changelog: tower-http-0.6.4...tower-http-0.6.5
- normalize_path: add
-
0.6.410 May 2025Release notes
Open source →Added
- decompression: Support HTTP responses containing multiple ZSTD frames (#548)
- The
ServiceExttrait for chaining layers onto an arbitrary http service just
likeServiceBuilderExtallows forServiceBuilder(#563)
Fixed
- Remove unnecessary trait bounds on
S::ErrorforServiceimpls of
RequestBodyTimeout<S>andResponseBodyTimeout<S>(#533) - compression: Respect
is_end_stream(#535) - Fix a rare panic in
fs::ServeDir(#553) - Fix invalid
content-lenghtof 1 in response to range requests to empty
files (#556) - In
AsyncRequireAuthorization, use the original inner service after it is
ready, instead of using a clone (#561)
Release notes
Open source →Added
- decompression: Support HTTP responses containing multiple ZSTD frames (#548)
- The
ServiceExttrait for chaining layers onto an arbitrary http service just likeServiceBuilderExtallows forServiceBuilder(#563)
Fixed
- Remove unnecessary trait bounds on
S::ErrorforServiceimpls ofRequestBodyTimeout<S>andResponseBodyTimeout<S>(#533) - compression: Respect
is_end_stream(#535) - Fix a rare panic in
fs::ServeDir(#553) - Fix invalid
content-lenghtof 1 in response to range requests to empty files (#556) - In
AsyncRequireAuthorization, use the original inner service after it is ready, instead of using a clone (#561)
-
0.6.307 May 2025 withdrawnRelease notes
Open source →This release was yanked because its definition of
ServiceExtwas quite unhelpful, in a way that's very unlikely that anybody would start depending on within the small timeframe before this was yanked, but that was technically breaking to change.Release notes
Open source →This release was yanked because its definition of
ServiceExtwas quite unhelpful, in a way that's very unlikely that anybody would start depending on within the small timeframe before this was yanked, but that was technically breaking to change. -
0.6.218 Nov 2024Release notes
Open source →Changed:
CompressionBody<B>now propagatesB's size hint in itshttp_body::Bodyimplementation, if compression is disabled (#531)- this allows a
content-lengthto be included in an HTTP message with this body for those cases
- this allows a
-
0.6.123 Sep 2024Release notes
Open source →Fixed
- decompression: reuse scratch buffer to significantly reduce allocations and improve performance (#521)
-
0.6.019 Sep 2024Release notes
Open source →Changed:
bodymodule is disabled except forcatch-panic,decompression-*,fs, orlimitfeatures (BREAKING) (#477)- Update to
tower0.5 (#503)
Fixed
- fs: Precompression of static files now supports files without a file extension (#507)
-
0.5.223 Feb 2024Release notes
Open source →Added:
- compression: Will now send a
vary: accept-encodingheader on compressed responses (#399) - compression: Support
x-gzipas equivalent togzipinaccept-encodingrequest header (#467)
Fixed
- compression: Skip compression for range requests (#446)
- compression: Skip compression for SSE responses by default (#465)
- cors: Actually keep Vary headers set by the inner service when setting response headers (#473)
- Version 0.5.1 intended to ship this, but the implementation was buggy and didn't actually do anything
- compression: Will now send a
-
0.5.114 Jan 2024Release notes
Open source →Added
- fs: Support files precompressed with
zstdinServeFile - trace: Add default generic parameters for
ResponseBodyandResponseFuture(#455) - trace: Add type aliases
HttpMakeClassifierandGrpcMakeClassifier(#455)
Fixed
- fs: Support files precompressed with
-
0.5.021 Nov 2023Release notes
Open source →Changed
- Bump Minimum Supported Rust Version to 1.66 (#433)
- Update to http-body 1.0 (#348)
- Update to http 1.0 (#348)
- Preserve service error type in RequestDecompression (#368)
Fixed
- Accepts range headers with ranges where the end of range goes past the end of the document by bumping
http-range-header to
0.4
-
0.4.401 Sep 2023Nothing published for this version
-
0.4.320 Jul 2023Nothing published for this version
-
0.4.219 Jul 2023Release notes
Open source →Added
- cors: Add support for private network preflights (#373)
- compression: Implement
DefaultforDecompressionBody(#370)
Changed
- compression: Update to async-compression 0.4 (#371)
Fixed
-
0.4.120 Jun 2023Release notes
Open source →Added
- request_id: Derive
DefaultforMakeRequestUuid(#335) - fs: Derive
DefaultforServeFileSystemResponseBody(#336) - compression: Expose compression quality on the CompressionLayer (#333)
Fixed
- request_id: Derive
-
0.4.024 Feb 2023Release notes
Open source →Added
- decompression: Add
RequestDecompressionmiddleware (#282) - compression: Implement
DefaultforCompressionBody(#323) - compression, decompression: Support zstd (de)compression (#322)
Changed
- serve_dir:
ServeDirandServeFile's error types are nowInfallibleand any IO errors will be converted into responses. Usetry_callto generate error responses manually (BREAKING) (#283) - serve_dir:
ServeDir::fallbackandServeDir::not_found_servicenow requires the fallback service to useInfallibleas its error type (BREAKING) (#283) - compression, decompression: Tweak prefered compression encodings (#325)
Removed
- Removed
RequireAuthorizationin favor ofValidateRequest(BREAKING) (#290)
Fixed
- decompression: Add
-
0.3.502 Dec 2022Release notes
Open source →Added
- Add
NormalizePathmiddleware (#275) - Add
ValidateRequestmiddleware (#289) - Add
RequestBodyTimeoutmiddleware (#303)
Changed
- Bump Minimum Supported Rust Version to 1.60 (#299)
Fixed
- Add
-
0.3.406 Jun 2022Release notes
Open source → -
0.3.308 May 2022Release notes
Open source →Added
- serve_dir: Add
ServeDir::call_fallback_on_method_not_allowedto allow calling the fallback for requests that aren'tGETorHEAD(#264) - request_id: Add
MakeRequestUuidfor generating request ids using UUIDs (#266)
Fixed
- serve_dir: Include
Allowheader for405 Method Not Allowedresponses (#263)
- serve_dir: Add
-
0.3.229 Apr 2022Release notes
Open source →Fixed
- serve_dir: Fix empty request parts being passed to
ServeDir's fallback instead of the actual ones (#258)
- serve_dir: Fix empty request parts being passed to
-
0.3.128 Apr 2022Release notes
Open source →Fixed
- cors: Only send a single origin in
Access-Control-Allow-Originheader when a list of allowed origins is configured (the previous behavior of sending a comma-separated list like for allowed methods and allowed headers is not allowed by any standard)
- cors: Only send a single origin in
-
0.3.025 Apr 2022Release notes
Open source →Added
- fs: Add
ServeDir::{fallback, not_found_service}for calling another service if the file cannot be found (#243) - fs: Add
SetStatusto override status codes (#248) ServeDirandServeFilenow respond with405 Method Not Allowedto requests where the method isn'tGETorHEAD(#249)- cors: Added
CorsLayer::very_permissivewhich is likeCorsLayer::permissiveexcept it (truly) allows credentials. This is made possible by mirroring the request's origin as well as method and headers back as CORS-whitelisted ones (#237) - cors: Allow customizing the value(s) for the
Varyheader (#237)
Changed
- cors: Removed
allow-credentials: truefromCorsLayer::permissive. It never actually took effect in compliant browsers because it is mutually exclusive with the*wildcard (Any) on origins, methods and headers (#237) - cors: Rewrote the CORS middleware. Almost all existing usage patterns will continue to work. (BREAKING) (#237)
- cors: The CORS middleware will now panic if you try to use
Anyin combination with.allow_credentials(true). This configuration worked before, but resulted in browsers ignoring theallow-credentialsheader, which defeats the purpose of setting it and can be very annoying to debug (#237)
Fixed
- fs: Fix content-length calculation on range requests (#228)
- fs: Add
-
0.2.511 Mar 2022Nothing published for this version
-
0.2.407 Mar 2022Release notes
Open source →Added
- Added
CatchPanicmiddleware which catches panics and converts them into500 Internal Serverresponses (#214)
Fixed
- Make parsing of
Accept-Encodingmore robust (#220)
- Added
-
0.2.318 Feb 2022Release notes
Open source →Changed
- Update to tokio-util 0.7 (#221)
Fixed
- The CORS layer / service methods
allow_headers,allow_methods,allow_originandexpose_headersnow do nothing if given an emptyVec, instead of sending the respective header with an empty value (#218)
-
0.2.208 Feb 2022 -
0.2.121 Jan 2022Release notes
Open source →Added
- Support
Last-Modified(and friends) headers inServeDirandServeFile(#145) - Add
AsyncRequireAuthorization::layer(#195)
Fixed
- Support
-
0.2.001 Dec 2021 withdrawnRelease notes
Open source →Added
- builder: Add
ServiceBuilderExtwhich adds methods totower::ServiceBuilderfor adding middleware from tower-http (#106) - request_id: Add
SetRequestIdandPropagateRequestIdmiddleware (#150) - trace: Add
DefaultMakeSpan::levelto make log level of tracing spans easily configurable (#124) - trace: Add
LatencyUnit::Secondsfor formatting latencies as seconds (#179) - trace: Support customizing which status codes are considered failures by
GrpcErrorsAsFailures(#189) - compression: Support specifying predicates to choose when responses should
be compressed. This can be used to disable compression of small responses,
responses with a certain
content-type, or something user defined (#172) - fs: Ability to serve precompressed files (#156)
- fs: Support
Rangerequests (#173) - fs: Properly support HEAD requests which return no body and have the
Content-Lengthheader set (#169)
Changed
AddAuthorization,InFlightRequests,SetRequestHeader,SetResponseHeader,AddExtension,MapRequestBodyandMapResponseBodynow requires underlying service to usehttp::Request<ReqBody>andhttp::Response<ResBody>as request and responses (#182) (BREAKING)- set_header: Remove unnecessary generic parameter from
SetRequestHeaderLayerandSetResponseHeaderLayer. This removes the need (and possibility) to specify a body type for these layers (#148) (BREAKING) - compression, decompression: Change the response body error type to
Box<dyn std::error::Error + Send + Sync>. This makes them usable if the body they're wrapping usesBox<dyn std::error::Error + Send + Sync>as its error type which they previously weren't (#166) (BREAKING) - fs: Change response body type of
ServeDirandServeFiletoServeFileSystemResponseBodyandServeFileSystemResponseFuture(#187) (BREAKING) - auth: Change
AuthorizeRequestandAsyncAuthorizeRequesttraits to be simpler (#192) (BREAKING)
Removed
- compression, decompression: Remove
BodyOrIoError. Its been replaced withBox<dyn std::error::Error + Send + Sync>(#166) (BREAKING) - compression, decompression: Remove the
compressionanddecompressionfeature. They were unnecessary andcompression-full/decompression-fullcan be used to get full compression/decompression support. For more granular control,[compression|decompression]-gzip,[compression|decompression]-brand[compression|decompression]-deflatemay be used instead (#170) (BREAKING)
- builder: Add
-
0.1.322 Jan 2022Nothing published for this version
-
0.1.213 Nov 2021 withdrawnRelease notes
Open source →- New middleware: Add
Corsfor setting [CORS] headers (#112) - New middleware: Add
AsyncRequireAuthorization(#118) Compression: Don't recompress HTTP responses (#140)CompressionandDecompression: Pass configuration from layer into middleware (#132)ServeDirandServeFile: Improve performance (#137)Compression: Remove needlessResBody::Error: Into<BoxError>bounds (#117)ServeDir: Percent decode path segments (#129)ServeDir: Use correct redirection status (#130)ServeDir: Return404 Not Foundon requests to directories ifappend_index_html_on_directoriesis set tofalse(#122)
- New middleware: Add
-
0.1.102 Jul 2021 withdrawnRelease notes
Open source →- Add example of using
SharedClassifier. - Add
StatusInRangeAsFailureswhich is a response classifier that considers responses with status code in a certain range as failures. Useful for HTTP clients where both server errors (5xx) and client errors (4xx) are considered failures. - Implement
DebugforNeverClassifyEos. - Update iri-string to 0.4.
- Add
ClassifyResponse::map_failure_classandClassifyEos::map_failure_classfor transforming the failure classification using a function. - Clarify exactly when each
Tracecallback is called. - Add
AddAuthorizationLayerfor setting theAuthorizationheader on requests.
- Add example of using
-
0.1.028 May 2021 withdrawn -
0.0.010 Mar 2017Nothing published for this version