Skip to content

Commit

Permalink
Upgrade to http-body 1.0 (#348)
Browse files Browse the repository at this point in the history
* punt on examples for now

* remove dependency on hyper

* port to http-body 1.0

* note which types from http_body_util is in our public api

* wrap body types

* fix some warnings

* comment out compression stuff for now

* validate-request docs

* trace

* timeout

* set_status

* set_header

* serve_dir

* redirect

* follow_redirect

* sensitive_headers

* request_id

* propagate_header

* normalize_path

* in_flight_requests

* map_response_body

* map_request_body

* limit

* lib

* cors

* classify

* add_extension

* catch_panic

* add_authorization

* require_authorization + async_require_authorization

* builder

* format

* fixes

* fix docs

* fix cargo hack

* is this breaking patches in Cargo.toml?

* update to 1.0 of dependencies

* porting compression like this seems to work \o/

* use `BodyExt::collect` in tests

* compression is back!

* and thats decompression!

* remove hyper specific test

* Update examples/axum-key-value-store/src/main.rs

Co-authored-by: Jonas Platte <jplatte+git@posteo.de>

* bring back client examples

* fix doc tests

* forgot ServiceBuilderExt

* changelog

* Fix potential ordering issues with `BodyIntoStream`

* don't delegate `is_end_stream`

* fix typos

* use std::task::ready

* uncomment CompressionLayer in examples

* Derive default

* format

* bring back hyper compat test

* remove lint. Lets just add this back later. Wanna merge now

---------

Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
  • Loading branch information
davidpdrsn and jplatte authored Nov 21, 2023
1 parent d2eadcb commit 04361b7
Show file tree
Hide file tree
Showing 60 changed files with 1,135 additions and 939 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[workspace]
resolver = "2"
members = [
"tower-http",
"examples/*",
Expand Down
6 changes: 6 additions & 0 deletions examples/axum-key-value-store/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
fn main() {
eprintln!("this example has not yet been updated to hyper 1.0");
}

/*
use axum::{
body::Bytes,
extract::{Path, State},
Expand Down Expand Up @@ -108,3 +113,4 @@ async fn set_key(Path(path): Path<String>, state: State<AppState>, value: Bytes)
// See https://github.com/tokio-rs/axum/blob/main/examples/testing/src/main.rs for an example of
// how to test axum apps
*/
6 changes: 6 additions & 0 deletions examples/tonic-key-value-store/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
fn main() {
eprint!("this example has not yet been updated to hyper 1.0");
}

/*
use bytes::Bytes;
use clap::Parser;
use futures::StreamExt;
Expand Down Expand Up @@ -370,3 +375,4 @@ mod tests {
addr
}
}
*/
6 changes: 6 additions & 0 deletions examples/warp-key-value-store/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
fn main() {
eprint!("this example has not yet been updated to hyper 1.0");
}

/*
use bytes::Bytes;
use clap::Parser;
use hyper::{
Expand Down Expand Up @@ -222,3 +227,4 @@ mod tests {
addr
}
}
*/
3 changes: 3 additions & 0 deletions tower-http/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## 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])

## Removed
Expand All @@ -27,6 +29,7 @@ http-range-header to `0.4`

[#418]: https://github.com/tower-rs/tower-http/pull/418
[#433]: https://github.com/tower-rs/tower-http/pull/433
[#348]: https://github.com/tower-rs/tower-http/pull/348
[#368]: https://github.com/tower-rs/tower-http/pull/368

# 0.4.2 (July 19, 2023)
Expand Down
16 changes: 10 additions & 6 deletions tower-http/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "tower-http"
description = "Tower middleware and utilities for HTTP clients and servers"
version = "0.4.2"
version = "0.4.4"
authors = ["Tower Maintainers <team@tower-rs.com>"]
edition = "2018"
license = "MIT"
Expand All @@ -15,8 +15,9 @@ rust-version = "1.66"
[dependencies]
bitflags = "2.0.2"
bytes = "1"
http = "0.2.7"
http-body = "0.4.5"
http = "1.0"
http-body = "1.0.0"
http-body-util = "0.1.0"
pin-project-lite = "0.2.7"
tower-layer = "0.3"
tower-service = "0.3"
Expand All @@ -38,16 +39,19 @@ httpdate = { version = "1.0", optional = true }
uuid = { version = "1.0", features = ["v4"], optional = true }

[dev-dependencies]
async-trait = "0.1"
brotli = "3"
bytes = "1"
flate2 = "1.0"
brotli = "3"
hyper = { version = "0.14", features = ["full"] }
futures-util = "0.3.14"
hyper-util = { version = "0.1", features = ["client-legacy", "http1", "tokio"] }
once_cell = "1"
serde_json = "1.0"
sync_wrapper = "0.1.1"
tokio = { version = "1", features = ["full"] }
tower = { version = "0.4.10", features = ["buffer", "util", "retry", "make", "timeout"] }
tracing-subscriber = "0.3"
uuid = { version = "1.0", features = ["v4"] }
serde_json = "1.0"
zstd = "0.12"

[features]
Expand Down
11 changes: 6 additions & 5 deletions tower-http/src/add_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
//! use tower_http::add_extension::AddExtensionLayer;
//! use tower::{Service, ServiceExt, ServiceBuilder, service_fn};
//! use http::{Request, Response};
//! use hyper::Body;
//! use bytes::Bytes;
//! use http_body_util::Full;
//! use std::{sync::Arc, convert::Infallible};
//!
//! # struct DatabaseConnectionPool;
Expand All @@ -21,11 +22,11 @@
//! pool: DatabaseConnectionPool,
//! }
//!
//! async fn handle(req: Request<Body>) -> Result<Response<Body>, Infallible> {
//! async fn handle(req: Request<Full<Bytes>>) -> Result<Response<Full<Bytes>>, Infallible> {
//! // Grab the state from the request extensions.
//! let state = req.extensions().get::<Arc<State>>().unwrap();
//!
//! Ok(Response::new(Body::empty()))
//! Ok(Response::new(Full::default()))
//! }
//!
//! # #[tokio::main]
Expand All @@ -44,7 +45,7 @@
//! let response = service
//! .ready()
//! .await?
//! .call(Request::new(Body::empty()))
//! .call(Request::new(Full::default()))
//! .await?;
//! # Ok(())
//! # }
Expand Down Expand Up @@ -137,8 +138,8 @@ where
mod tests {
#[allow(unused_imports)]
use super::*;
use crate::test_helpers::Body;
use http::Response;
use hyper::Body;
use std::{convert::Infallible, sync::Arc};
use tower::{service_fn, ServiceBuilder, ServiceExt};

Expand Down
28 changes: 14 additions & 14 deletions tower-http/src/auth/add_authorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@
//! ```
//! use tower_http::validate_request::{ValidateRequestHeader, ValidateRequestHeaderLayer};
//! use tower_http::auth::AddAuthorizationLayer;
//! use hyper::{Request, Response, Body, Error};
//! use http::{StatusCode, header::AUTHORIZATION};
//! use tower::{Service, ServiceExt, ServiceBuilder, service_fn};
//! # async fn handle(request: Request<Body>) -> Result<Response<Body>, Error> {
//! # Ok(Response::new(Body::empty()))
//! use http::{Request, Response, StatusCode, header::AUTHORIZATION};
//! use tower::{Service, ServiceExt, ServiceBuilder, service_fn, BoxError};
//! use http_body_util::Full;
//! use bytes::Bytes;
//! # async fn handle(request: Request<Full<Bytes>>) -> Result<Response<Full<Bytes>>, BoxError> {
//! # Ok(Response::new(Full::default()))
//! # }
//!
//! # #[tokio::main]
//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! # async fn main() -> Result<(), BoxError> {
//! # let service_that_requires_auth = ValidateRequestHeader::basic(
//! # tower::service_fn(handle),
//! # "username",
Expand All @@ -30,7 +31,7 @@
//! let response = client
//! .ready()
//! .await?
//! .call(Request::new(Body::empty()))
//! .call(Request::new(Full::default()))
//! .await?;
//!
//! assert_eq!(StatusCode::OK, response.status());
Expand Down Expand Up @@ -84,7 +85,7 @@ impl AddAuthorizationLayer {
///
/// # Panics
///
/// Panics if the token is not a valid [`HeaderValue`](http::header::HeaderValue).
/// Panics if the token is not a valid [`HeaderValue`].
pub fn bearer(token: &str) -> Self {
let value =
HeaderValue::try_from(format!("Bearer {}", token)).expect("token is not valid header");
Expand Down Expand Up @@ -147,7 +148,7 @@ impl<S> AddAuthorization<S> {
///
/// # Panics
///
/// Panics if the token is not a valid [`HeaderValue`](http::header::HeaderValue).
/// Panics if the token is not a valid [`HeaderValue`].
pub fn bearer(inner: S, token: &str) -> Self {
AddAuthorizationLayer::bearer(token).layer(inner)
}
Expand Down Expand Up @@ -187,12 +188,11 @@ where

#[cfg(test)]
mod tests {
use crate::validate_request::ValidateRequestHeaderLayer;

#[allow(unused_imports)]
use super::*;
use crate::test_helpers::Body;
use crate::validate_request::ValidateRequestHeaderLayer;
use http::{Response, StatusCode};
use hyper::Body;
use std::convert::Infallible;
use tower::{BoxError, Service, ServiceBuilder, ServiceExt};

#[tokio::test]
Expand Down Expand Up @@ -245,7 +245,7 @@ mod tests {
let auth = request.headers().get(http::header::AUTHORIZATION).unwrap();
assert!(auth.is_sensitive());

Ok::<_, hyper::Error>(Response::new(Body::empty()))
Ok::<_, Infallible>(Response::new(Body::empty()))
});

let mut client = AddAuthorization::bearer(svc, "foo").as_sensitive(true);
Expand Down
38 changes: 20 additions & 18 deletions tower-http/src/auth/async_require_authorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
//!
//! ```
//! use tower_http::auth::{AsyncRequireAuthorizationLayer, AsyncAuthorizeRequest};
//! use hyper::{Request, Response, Body, Error};
//! use http::{StatusCode, header::AUTHORIZATION};
//! use tower::{Service, ServiceExt, ServiceBuilder, service_fn};
//! use http::{Request, Response, StatusCode, header::AUTHORIZATION};
//! use tower::{Service, ServiceExt, ServiceBuilder, service_fn, BoxError};
//! use futures_util::future::BoxFuture;
//! use bytes::Bytes;
//! use http_body_util::Full;
//!
//! #[derive(Clone, Copy)]
//! struct MyAuth;
Expand All @@ -19,7 +20,7 @@
//! B: Send + Sync + 'static,
//! {
//! type RequestBody = B;
//! type ResponseBody = Body;
//! type ResponseBody = Full<Bytes>;
//! type Future = BoxFuture<'static, Result<Request<B>, Response<Self::ResponseBody>>>;
//!
//! fn authorize(&mut self, mut request: Request<B>) -> Self::Future {
Expand All @@ -33,7 +34,7 @@
//! } else {
//! let unauthorized_response = Response::builder()
//! .status(StatusCode::UNAUTHORIZED)
//! .body(Body::empty())
//! .body(Full::<Bytes>::default())
//! .unwrap();
//!
//! Err(unauthorized_response)
Expand All @@ -47,10 +48,10 @@
//! # None
//! }
//!
//! #[derive(Debug)]
//! #[derive(Debug, Clone)]
//! struct UserId(String);
//!
//! async fn handle(request: Request<Body>) -> Result<Response<Body>, Error> {
//! async fn handle(request: Request<Full<Bytes>>) -> Result<Response<Full<Bytes>>, BoxError> {
//! // Access the `UserId` that was set in `on_authorized`. If `handle` gets called the
//! // request was authorized and `UserId` will be present.
//! let user_id = request
Expand All @@ -60,11 +61,11 @@
//!
//! println!("request from {:?}", user_id);
//!
//! Ok(Response::new(Body::empty()))
//! Ok(Response::new(Full::default()))
//! }
//!
//! # #[tokio::main]
//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! # async fn main() -> Result<(), BoxError> {
//! let service = ServiceBuilder::new()
//! // Authorize requests using `MyAuth`
//! .layer(AsyncRequireAuthorizationLayer::new(MyAuth))
Expand All @@ -77,10 +78,11 @@
//!
//! ```
//! use tower_http::auth::{AsyncRequireAuthorizationLayer, AsyncAuthorizeRequest};
//! use hyper::{Request, Response, Body, Error};
//! use http::StatusCode;
//! use tower::{Service, ServiceExt, ServiceBuilder};
//! use http::{Request, Response, StatusCode};
//! use tower::{Service, ServiceExt, ServiceBuilder, BoxError};
//! use futures_util::future::BoxFuture;
//! use http_body_util::Full;
//! use bytes::Bytes;
//!
//! async fn check_auth<B>(request: &Request<B>) -> Option<UserId> {
//! // ...
Expand All @@ -90,21 +92,21 @@
//! #[derive(Debug)]
//! struct UserId(String);
//!
//! async fn handle(request: Request<Body>) -> Result<Response<Body>, Error> {
//! async fn handle(request: Request<Full<Bytes>>) -> Result<Response<Full<Bytes>>, BoxError> {
//! # todo!();
//! // ...
//! }
//!
//! # #[tokio::main]
//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! # async fn main() -> Result<(), BoxError> {
//! let service = ServiceBuilder::new()
//! .layer(AsyncRequireAuthorizationLayer::new(|request: Request<Body>| async move {
//! .layer(AsyncRequireAuthorizationLayer::new(|request: Request<Full<Bytes>>| async move {
//! if let Some(user_id) = check_auth(&request).await {
//! Ok(request)
//! } else {
//! let unauthorized_response = Response::builder()
//! .status(StatusCode::UNAUTHORIZED)
//! .body(Body::empty())
//! .body(Full::<Bytes>::default())
//! .unwrap();
//!
//! Err(unauthorized_response)
Expand Down Expand Up @@ -306,9 +308,9 @@ where
mod tests {
#[allow(unused_imports)]
use super::*;
use crate::test_helpers::Body;
use futures_util::future::BoxFuture;
use http::{header, StatusCode};
use hyper::Body;
use tower::{BoxError, ServiceBuilder, ServiceExt};

#[derive(Clone, Copy)]
Expand Down Expand Up @@ -346,7 +348,7 @@ mod tests {
}
}

#[derive(Debug)]
#[derive(Clone, Debug)]
struct UserId(String);

#[tokio::test]
Expand Down
Loading

0 comments on commit 04361b7

Please sign in to comment.