PackageTrack
Sign in Get early access

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 2026
2018 2019 2020 2021 2022 2023 2024 2025 2026
Release Pre-release Withdrawn

Releases

latest 38
  1. 0.7.0 15 Jun 2026
    Release notes

    Changes since 0.6.11

    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: add DeadlineBody for non-resetting body timeouts, applied via the new RequestBodyDeadlineLayer and ResponseBodyDeadlineLayer (#688)

      Unlike TimeoutBody, which resets its deadline on every frame, DeadlineBody caps 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 strong ETag support to ServeDir, including If-Match and If-None-Match precondition handling per RFC 9110. 304 Not Modified responses now carry the ETag and Last-Modified validators (#691)

    • fs: add a Backend trait to make ServeDir work with non-filesystem sources (e.g. embedded assets or object storage). The default TokioBackend preserves existing behavior. Use ServeDir::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: add html_as_default_extension option to ServeDir, appending .html when the request path has no extension (#519)

    • fs: add redirect_path_prefix option to ServeDir, prepending a prefix on trailing-slash redirects so the service can be mounted under a sub-path (#486)

    • validate-request: add ValidateRequestHeaderLayer::has_header_value() to reject requests when a header does not have an expected value (#360)

    • body: UnsyncBoxBody::new() constructor and From<ServeFileSystemResponseBody> conversion to avoid double-boxing when combining ServeDir responses with other body types (#537)

    • limit: implement Default for limit::ResponseBody when the wrapped body also implements Default (#679)

    Changed

    • breaking: compression: the middleware now handles the * wildcard and identity;q=0 in Accept-Encoding per RFC 9110 §12.5.3. Requests that previously fell back to identity (e.g. *;q=0 or identity;q=0 with 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 the SizeAbove predicate threshold from u16 to u64, allowing minimum sizes above 64 KiB (#704)

    • breaking: remove the implicit no-op tokio and async-compression features. These were kept as no-op features in 0.6.x for backwards compatibility after the switch to dep: syntax in #642. Downstream crates that activate tower-http/tokio or tower http/async-compression should 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. GrpcCode and GrpcFailureClass are now #[non_exhaustive], and GrpcStatus is exported from the classify module (#422)

    • breaking: follow-redirect: FollowRedirect now forwards request Extensions to redirected requests instead of dropping them. The Standard policy drops extensions on cross-origin redirections (same-origin keeps them). Opt out with FollowRedirectLayer::preserve_extensions(false); keep specific types with FilterCredentials::allow_extension::<T>() or all of them with keep_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, so FilterCredentials no longer re-sends Cookie/Authorization to a same-origin target reached after cross-origin hop. Custom Policy::on_request impls now see the previous hop's filtered request, not the original. (#706)

    • trace: DefaultOnRequest, DefaultOnResponse, DefaultOnFailure, and DefaultOnEos now 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 the Vary header defaults (#674)

    • MSRV bumped from 1.64 to 1.65 (#684)

    Fixed

    • fs: ServeDir and ServeFile now emit a Vary: Accept-Encoding response
      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 return 404 Not Found instead of serving the file (#678)
    • fs: fix ServeDir stripping 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: fire on_eos when the inner body reports is_end_stream with a precise content-length (#687)
    • on-early-drop: suppress the early-drop guard when is_end_stream is reported after a data frame (#687)
    • set-header: make SetMultipleRequestHeaders and SetMultipleResponseHeaders Clone for non-Clone HTTP bodies (#703)

    Thanks

    New Contributors

    Open source →
    Release notes

    Changes since 0.6.11

    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: add DeadlineBody for non-resetting body timeouts, applied via the new RequestBodyDeadlineLayer and ResponseBodyDeadlineLayer (#688)

      Unlike TimeoutBody, which resets its deadline on every frame, DeadlineBody caps 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 strong ETag support to ServeDir, including If-Match and If-None-Match precondition handling per RFC 9110. 304 Not Modified responses now carry the ETag and Last-Modified validators (#691)

    • fs: add a Backend trait to make ServeDir work with non-filesystem sources (e.g. embedded assets or object storage). The default TokioBackend preserves existing behavior. Use ServeDir::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: add html_as_default_extension option to ServeDir, appending .html when the request path has no extension (#519)

    • fs: add redirect_path_prefix option to ServeDir, prepending a prefix on trailing-slash redirects so the service can be mounted under a sub-path (#486)

    • validate-request: add ValidateRequestHeaderLayer::has_header_value() to reject requests when a header does not have an expected value (#360)

    • body: UnsyncBoxBody::new() constructor and From<ServeFileSystemResponseBody> conversion to avoid double-boxing when combining ServeDir responses with other body types (#537)

    • limit: implement Default for limit::ResponseBody when the wrapped body also implements Default (#679)

    Changed

    • breaking: compression: the middleware now handles the * wildcard and identity;q=0 in Accept-Encoding per RFC 9110 §12.5.3. Requests that previously fell back to identity (e.g. *;q=0 or identity;q=0 with 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 the SizeAbove predicate threshold from u16 to u64, allowing minimum sizes above 64 KiB (#704)

    • breaking: remove the implicit no-op tokio and async-compression features. These were kept as no-op features in 0.6.x for backwards compatibility after the switch to dep: syntax in #642. Downstream crates that activate tower-http/tokio or tower-http/async-compression should 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. GrpcCode and GrpcFailureClass are now #[non_exhaustive], and GrpcStatus is exported from the classify module (#422)

    • breaking: follow-redirect: FollowRedirect now forwards request Extensions to redirected requests instead of dropping them. The Standard policy drops extensions on cross-origin redirections (same-origin keeps them). Opt out with FollowRedirectLayer::preserve_extensions(false); keep specific types with FilterCredentials::allow_extension::<T>() or all of them with keep_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, so FilterCredentials no longer re-sends Cookie/Authorization to a same-origin target reached after a cross-origin hop. Custom Policy::on_request impls now see the previous hop's filtered request, not the original. (#706)

    • trace: DefaultOnRequest, DefaultOnResponse, DefaultOnFailure, and DefaultOnEos now 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 the Vary header defaults (#674)

    • MSRV bumped from 1.64 to 1.65 (#684)

    Fixed

    • fs: ServeDir and ServeFile now emit a Vary: Accept-Encoding response 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 return 404 Not Found instead of serving the file (#678)
    • fs: fix ServeDir stripping 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: fire on_eos when the inner body reports is_end_stream with a precise content-length (#687)
    • on-early-drop: suppress the early-drop guard when is_end_stream is reported after a data frame (#687)
    • set-header: make SetMultipleRequestHeaders and SetMultipleResponseHeaders Clone for non-Clone HTTP bodies (#703)
    Open source →
  2. 0.6.11 18 May 2026
    Release notes

    Added

    • set-header: add SetMultipleResponseHeadersLayer and
      SetMultipleResponseHeader for setting multiple response headers at once.
      Supports overriding, appending, and if_not_present modes. 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: add SetMultipleRequestHeadersLayer and
      SetMultipleRequestHeaders for setting multiple request headers at once,
      mirroring the response-side API (#677)

    • classify: add From<i32> and From<NonZeroI32> impls for GrpcCode.
      Unrecognized status codes map to GrpcCode::Unknown (#506)

    Changed

    • compression: compress application/grpc-web responses. Previously all
      application/grpc* content types were excluded from compression; now only
      application/grpc (non-web) is excluded (#408)

    Fixed

    • fs: fix ServeDir returning 500 instead of 405 for non-GET/HEAD requests
      when call_fallback_on_method_not_allowed is enabled but no fallback service
      is configured (#587)
    • fs: remove duplicate cfg attribute on is_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

    Full Changelog: tower-http-0.6.10...tower-http-0.6.11

    Open source →
    Release notes

    Added

    • set-header: add SetMultipleResponseHeadersLayer and SetMultipleResponseHeader for setting multiple response headers at once. Supports overriding, appending, and if_not_present modes. 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: add SetMultipleRequestHeadersLayer and SetMultipleRequestHeaders for setting multiple request headers at once, mirroring the response-side API (#677)

    • classify: add From<i32> and From<NonZeroI32> impls for GrpcCode. Unrecognized status codes map to GrpcCode::Unknown (#506)

    Changed

    • compression: compress application/grpc-web responses. Previously all application/grpc* content types were excluded from compression; now only application/grpc (non-web) is excluded (#408)

    Fixed

    • fs: fix ServeDir returning 500 instead of 405 for non-GET/HEAD requests when call_fallback_on_method_not_allowed is enabled but no fallback service is configured (#587)
    • fs: remove duplicate cfg attribute on is_reserved_dos_name (#675)
    Open source →
  3. 0.6.10 06 May 2026
    Release notes

    Added

    • follow-redirect: expose Attempt::method() and Attempt::previous_method()
      so redirect policies can react to method changes across redirects (e.g.
      POST to GET on 301/303) (#559)

    Fixed

    • Restore tokio and async-compression as 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

    Open source →
    Release notes

    Added

    • follow-redirect: expose Attempt::method() and Attempt::previous_method() so redirect policies can react to method changes across redirects (e.g. POST to GET on 301/303) (#559)

    Fixed

    • Restore tokio and async-compression as no-op features. These will be removed next breaking release (#667)
    Open source →
  4. 0.6.9 05 May 2026
    Release notes

    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::OnFailure hook with
      EarlyDropsAsFailures. Place this layer inside a TraceLayer so 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: make AsyncReadBody::with_capacity public (#415)

    Changed:

    • The implicit async-compression feature is removed (#642)
    • The implicit tokio feature is removed (#628)
    • fs: no longer auto-enables the tracing crate feature; enable tracing
      explicitly to restore error logging on ServeDir IO failures (#614)

    Fixed

    • trace: restore failure classification at end-of-stream (#483)
    • follow-redirect: support unicode URLs (swaps iri-string dep for
      url) (#646)
    • fs: reject reserved Windows DOS device names (CON, COM1, etc.) in
      ServeDir (#663)

    All the PRs

    New Contributors

    Full Changelog: tower-http-0.6.8...tower-http-0.6.9

    Open source →
    Release notes

    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::OnFailure hook with EarlyDropsAsFailures. Place this layer inside a TraceLayer so 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: make AsyncReadBody::with_capacity public (#415)

    Changed:

    • The implicit async-compression feature is removed (#642)
    • The implicit tokio feature is removed (#628)
    • fs: no longer auto-enables the tracing crate feature; enable tracing explicitly to restore error logging on ServeDir IO failures (#614)

    Fixed

    • trace: restore failure classification at end-of-stream (#483)
    • follow-redirect: support unicode URLs (swaps iri-string dep for url) (#646)
    • fs: reject reserved Windows DOS device names (CON, COM1, etc.) in ServeDir (#663)
    Open source →
  5. 0.6.8 08 Dec 2025
    Release notes

    Fixed

    • Disable multiple_members in Gzip decoder, since HTTP context only uses one
      member. (#621)

    What's Changed

    New Contributors

    Full Changelog: tower-http-0.6.7...tower-http-0.6.8

    Open source →
    Release notes

    Fixed

    • Disable multiple_members in Gzip decoder, since HTTP context only uses one member. (#621)
    Open source →
  6. 0.6.7 24 Nov 2025
    Release notes

    Added

    • TimeoutLayer::with_status_code(status) to define the status code returned
      when timeout is reached. (#599)

    Deprecated

    • auth::require_authorization is too basic for real-world. (#591)
    • TimeoutLayer::new() should be replaced with
      TimeoutLayer::with_status_code(). (Previously was
      StatusCode::REQUEST_TIMEOUT) (#599)

    Fixed

    • on_eos is now called even for successful responses. (#580)
    • ServeDir: call fallback when filename is invalid (#586)
    • decompression will not fail when body is empty (#618)

    New Contributors

    Full Changelog: tower-http-0.6.6...tower-http-0.6.7

    Open source →
    Release notes

    Added

    • TimeoutLayer::with_status_code(status) to define the status code returned when timeout is reached. (#599)

    Deprecated

    • auth::require_authorization is too basic for real-world. (#591)
    • TimeoutLayer::new() should be replaced with TimeoutLayer::with_status_code(). (Previously was StatusCode::REQUEST_TIMEOUT) (#599)

    Fixed

    • on_eos is now called even for successful responses. (#580)
    • ServeDir: call fallback when filename is invalid (#586)
    • decompression will not fail when body is empty (#618)
    Open source →
  7. 0.6.6 03 Jun 2025
    Release notes

    Fixed

    • compression: fix panic when looking in vary header (#578)

    New Contributors

    Full Changelog: tower-http-0.6.5...tower-http-0.6.6

    Open source →
    Release notes

    Fixed

    • compression: fix panic when looking in vary header (#578)
    Open source →
  8. 0.6.5 02 Jun 2025 withdrawn
    Release notes

    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-encoding if already set (#572)

    New Contributors

    Full Changelog: tower-http-0.6.4...tower-http-0.6.5

    Open source →
    Release notes

    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-encoding if already set (#572)
    Open source →
  9. 0.6.4 10 May 2025
    Release notes

    Added

    • decompression: Support HTTP responses containing multiple ZSTD frames (#548)
    • The ServiceExt trait for chaining layers onto an arbitrary http service just
      like ServiceBuilderExt allows for ServiceBuilder (#563)

    Fixed

    • Remove unnecessary trait bounds on S::Error for Service impls of
      RequestBodyTimeout<S> and ResponseBodyTimeout<S> (#533)
    • compression: Respect is_end_stream (#535)
    • Fix a rare panic in fs::ServeDir (#553)
    • Fix invalid content-lenght of 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)
    Open source →
    Release notes

    Added

    • decompression: Support HTTP responses containing multiple ZSTD frames (#548)
    • The ServiceExt trait for chaining layers onto an arbitrary http service just like ServiceBuilderExt allows for ServiceBuilder (#563)

    Fixed

    • Remove unnecessary trait bounds on S::Error for Service impls of RequestBodyTimeout<S> and ResponseBodyTimeout<S> (#533)
    • compression: Respect is_end_stream (#535)
    • Fix a rare panic in fs::ServeDir (#553)
    • Fix invalid content-lenght of 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)
    Open source →
  10. 0.6.3 07 May 2025 withdrawn
    Release notes

    This release was yanked because its definition of ServiceExt was 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.

    Open source →
    Release notes

    This release was yanked because its definition of ServiceExt was 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.

    Open source →
  11. 0.6.2 18 Nov 2024
    Release notes

    Changed:

    • CompressionBody<B> now propagates B's size hint in its http_body::Body implementation, if compression is disabled (#531)
      • this allows a content-length to be included in an HTTP message with this body for those cases
    Open source →
  12. 0.6.1 23 Sep 2024
    Release notes

    Fixed

    • decompression: reuse scratch buffer to significantly reduce allocations and improve performance (#521)
    Open source →
  13. 0.6.0 19 Sep 2024
    Release notes

    Changed:

    • body module is disabled except for catch-panic, decompression-*, fs, or limit features (BREAKING) (#477)
    • Update to tower 0.5 (#503)

    Fixed

    • fs: Precompression of static files now supports files without a file extension (#507)
    Open source →
  14. 0.5.2 23 Feb 2024
    Release notes

    Added:

    • compression: Will now send a vary: accept-encoding header on compressed responses (#399)
    • compression: Support x-gzip as equivalent to gzip in accept-encoding request 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
    Open source →
  15. 0.5.1 14 Jan 2024
    Release notes

    Added

    • fs: Support files precompressed with zstd in ServeFile
    • trace: Add default generic parameters for ResponseBody and ResponseFuture (#455)
    • trace: Add type aliases HttpMakeClassifier and GrpcMakeClassifier (#455)

    Fixed

    • cors: Keep Vary headers set by the inner service when setting response headers (#398)
    • fs: ServeDir now no longer redirects from /directory to /directory/ if append_index_html_on_directories is disabled (#421)
    Open source →
  16. 0.5.0 21 Nov 2023
    Release notes

    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
    Open source →
  17. 0.4.4 01 Sep 2023

    Nothing published for this version

  18. 0.4.3 20 Jul 2023

    Nothing published for this version

  19. 0.4.2 19 Jul 2023
    Release notes

    Added

    • cors: Add support for private network preflights (#373)
    • compression: Implement Default for DecompressionBody (#370)

    Changed

    • compression: Update to async-compression 0.4 (#371)

    Fixed

    • compression: Override default brotli compression level 11 -> 4 (#356)
    • trace: Simplify dynamic tracing level application (#380)
    • normalize_path: Fix path normalization for preceding slashes (#359)
    Open source →
  20. 0.4.1 20 Jun 2023
    Release notes

    Added

    • request_id: Derive Default for MakeRequestUuid (#335)
    • fs: Derive Default for ServeFileSystemResponseBody (#336)
    • compression: Expose compression quality on the CompressionLayer (#333)

    Fixed

    • compression: Improve parsing of Accept-Encoding request header (#220)
    • normalize_path: Fix path normalization of index route (#347)
    • decompression: Enable multiple_members for GzipDecoder (#354)
    Open source →
  21. 0.4.0 24 Feb 2023
    Release notes

    Added

    • decompression: Add RequestDecompression middleware (#282)
    • compression: Implement Default for CompressionBody (#323)
    • compression, decompression: Support zstd (de)compression (#322)

    Changed

    • serve_dir: ServeDir and ServeFile's error types are now Infallible and any IO errors will be converted into responses. Use try_call to generate error responses manually (BREAKING) (#283)
    • serve_dir: ServeDir::fallback and ServeDir::not_found_service now requires the fallback service to use Infallible as its error type (BREAKING) (#283)
    • compression, decompression: Tweak prefered compression encodings (#325)

    Removed

    • Removed RequireAuthorization in favor of ValidateRequest (BREAKING) (#290)

    Fixed

    • serve_dir: Don't include identity in Content-Encoding header (#317)
    • compression: Do compress SVGs (#321)
    • serve_dir: In ServeDir, convert io::ErrorKind::NotADirectory to 404 Not Found (#331)
    Open source →
  22. 0.3.5 02 Dec 2022
    Release notes

    Added

    • Add NormalizePath middleware (#275)
    • Add ValidateRequest middleware (#289)
    • Add RequestBodyTimeout middleware (#303)

    Changed

    • Bump Minimum Supported Rust Version to 1.60 (#299)

    Fixed

    • trace: Correctly identify gRPC requests in default on_response callback (#278)
    • cors: Panic if a wildcard (*) is passed to AllowOrigin::list. Use AllowOrigin::any() instead (#285)
    • serve_dir: Call the fallback on non-uft8 request paths (#310)
    Open source →
  23. 0.3.4 06 Jun 2022
    Release notes

    Added

    • Add Timeout middleware (#270)
    • Add RequestBodyLimit middleware (#271)
    Open source →
  24. 0.3.3 08 May 2022
    Release notes

    Added

    • serve_dir: Add ServeDir::call_fallback_on_method_not_allowed to allow calling the fallback for requests that aren't GET or HEAD (#264)
    • request_id: Add MakeRequestUuid for generating request ids using UUIDs (#266)

    Fixed

    • serve_dir: Include Allow header for 405 Method Not Allowed responses (#263)
    Open source →
  25. 0.3.2 29 Apr 2022
    Release notes

    Fixed

    • serve_dir: Fix empty request parts being passed to ServeDir's fallback instead of the actual ones (#258)
    Open source →
  26. 0.3.1 28 Apr 2022
    Release notes

    Fixed

    • cors: Only send a single origin in Access-Control-Allow-Origin header 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)
    Open source →
  27. 0.3.0 25 Apr 2022
    Release notes

    Added

    • fs: Add ServeDir::{fallback, not_found_service} for calling another service if the file cannot be found (#243)
    • fs: Add SetStatus to override status codes (#248)
    • ServeDir and ServeFile now respond with 405 Method Not Allowed to requests where the method isn't GET or HEAD (#249)
    • cors: Added CorsLayer::very_permissive which is like CorsLayer::permissive except 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 Vary header (#237)

    Changed

    • cors: Removed allow-credentials: true from CorsLayer::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 Any in combination with .allow_credentials(true). This configuration worked before, but resulted in browsers ignoring the allow-credentials header, 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)
    Open source →
  28. 0.2.5 11 Mar 2022

    Nothing published for this version

  29. 0.2.4 07 Mar 2022
    Release notes

    Added

    • Added CatchPanic middleware which catches panics and converts them into 500 Internal Server responses (#214)

    Fixed

    • Make parsing of Accept-Encoding more robust (#220)
    Open source →
  30. 0.2.3 18 Feb 2022
    Release notes

    Changed

    • Update to tokio-util 0.7 (#221)

    Fixed

    • The CORS layer / service methods allow_headers, allow_methods, allow_origin and expose_headers now do nothing if given an empty Vec, instead of sending the respective header with an empty value (#218)
    Open source →
  31. 0.2.2 08 Feb 2022
    Release notes

    Fixed

    • Add Vary headers for CORS preflight responses (#216)
    Open source →
  32. 0.2.1 21 Jan 2022
    Release notes

    Added

    • Support Last-Modified (and friends) headers in ServeDir and ServeFile (#145)
    • Add AsyncRequireAuthorization::layer (#195)

    Fixed

    • Fix build error for certain feature sets (#209)
    • Cors: Set Vary header (#199)
    • ServeDir and ServeFile: Fix potential directory traversal attack due to improper path validation on Windows (#204)
    Open source →
  33. 0.2.0 01 Dec 2021 withdrawn
    Release notes

    Added

    • builder: Add ServiceBuilderExt which adds methods to tower::ServiceBuilder for adding middleware from tower-http (#106)
    • request_id: Add SetRequestId and PropagateRequestId middleware (#150)
    • trace: Add DefaultMakeSpan::level to make log level of tracing spans easily configurable (#124)
    • trace: Add LatencyUnit::Seconds for 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 Range requests (#173)
    • fs: Properly support HEAD requests which return no body and have the Content-Length header set (#169)

    Changed

    • AddAuthorization, InFlightRequests, SetRequestHeader, SetResponseHeader, AddExtension, MapRequestBody and MapResponseBody now requires underlying service to use http::Request<ReqBody> and http::Response<ResBody> as request and responses (#182) (BREAKING)
    • set_header: Remove unnecessary generic parameter from SetRequestHeaderLayer and SetResponseHeaderLayer. 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 uses Box<dyn std::error::Error + Send + Sync> as its error type which they previously weren't (#166) (BREAKING)
    • fs: Change response body type of ServeDir and ServeFile to ServeFileSystemResponseBody and ServeFileSystemResponseFuture (#187) (BREAKING)
    • auth: Change AuthorizeRequest and AsyncAuthorizeRequest traits to be simpler (#192) (BREAKING)

    Removed

    • compression, decompression: Remove BodyOrIoError. Its been replaced with Box<dyn std::error::Error + Send + Sync> (#166) (BREAKING)
    • compression, decompression: Remove the compression and decompression feature. They were unnecessary and compression-full/decompression-full can be used to get full compression/decompression support. For more granular control, [compression|decompression]-gzip, [compression|decompression]-br and [compression|decompression]-deflate may be used instead (#170) (BREAKING)
    Open source →
  34. 0.1.3 22 Jan 2022

    Nothing published for this version

  35. 0.1.2 13 Nov 2021 withdrawn
    Release notes
    • New middleware: Add Cors for setting [CORS] headers (#112)
    • New middleware: Add AsyncRequireAuthorization (#118)
    • Compression: Don't recompress HTTP responses (#140)
    • Compression and Decompression: Pass configuration from layer into middleware (#132)
    • ServeDir and ServeFile: Improve performance (#137)
    • Compression: Remove needless ResBody::Error: Into<BoxError> bounds (#117)
    • ServeDir: Percent decode path segments (#129)
    • ServeDir: Use correct redirection status (#130)
    • ServeDir: Return 404 Not Found on requests to directories if append_index_html_on_directories is set to false (#122)
    Open source →
  36. 0.1.1 02 Jul 2021 withdrawn
    Release notes
    • Add example of using SharedClassifier.
    • Add StatusInRangeAsFailures which 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 Debug for NeverClassifyEos.
    • Update iri-string to 0.4.
    • Add ClassifyResponse::map_failure_class and ClassifyEos::map_failure_class for transforming the failure classification using a function.
    • Clarify exactly when each Trace callback is called.
    • Add AddAuthorizationLayer for setting the Authorization header on requests.
    Open source →
  37. 0.1.0 28 May 2021 withdrawn
    Release notes
    • Initial release.
    Open source →
  38. 0.0.0 10 Mar 2017

    Nothing published for this version

Every package, every release, already written down.

The archive is open and free. Watching your own project is what we are building next.

Browse the archive