Skip to content

Commit f726f16

Browse files
authored
Update to tower-http 0.4 (#1783)
1 parent 6a4825b commit f726f16

28 files changed

Lines changed: 131 additions & 193 deletions

File tree

axum-core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ axum = { path = "../axum", version = "0.6.0", features = ["headers"] }
2929
futures-util = "0.3"
3030
hyper = "0.14"
3131
tokio = { version = "1.0", features = ["macros"] }
32-
tower-http = { version = "0.3.4", features = ["limit"] }
32+
tower-http = { version = "0.4", features = ["limit"] }
3333

3434
[package.metadata.cargo-public-api-crates]
3535
allowed = [

axum-extra/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ and this project adheres to [Semantic Versioning].
77

88
# Unreleased
99

10+
- **breaking:** `SpaRouter::handle_error` has been removed ([#1783])
1011
- **breaking:** Change casing of `ProtoBuf` to `Protobuf` ([#1595])
1112

13+
[#1783]: https://github.com/tokio-rs/axum/pull/1783
1214
[#1595]: https://github.com/tokio-rs/axum/pull/1595
1315

1416
# 0.5.0 (12. February, 2022)

axum-extra/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ mime = "0.3"
4343
pin-project-lite = "0.2"
4444
tokio = "1.19"
4545
tower = { version = "0.4", default_features = false, features = ["util"] }
46-
tower-http = { version = "0.3", features = ["map-response-body"] }
46+
tower-http = { version = "0.4", features = ["map-response-body"] }
4747
tower-layer = "0.3"
4848
tower-service = "0.3"
4949

@@ -68,7 +68,7 @@ serde = { version = "1.0", features = ["derive"] }
6868
serde_json = "1.0.71"
6969
tokio = { version = "1.14", features = ["full"] }
7070
tower = { version = "0.4", features = ["util"] }
71-
tower-http = { version = "0.3", features = ["map-response-body", "timeout"] }
71+
tower-http = { version = "0.4", features = ["map-response-body", "timeout"] }
7272

7373
[package.metadata.docs.rs]
7474
all-features = true

axum-extra/src/routing/spa.rs

Lines changed: 13 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,15 @@
11
use axum::{
22
body::{Body, HttpBody},
3-
error_handling::HandleError,
4-
response::IntoResponse,
5-
routing::{get_service, Route},
63
Router,
74
};
8-
use http::{Request, StatusCode};
95
use std::{
106
any::type_name,
11-
convert::Infallible,
127
fmt,
13-
future::{ready, Ready},
14-
io,
158
marker::PhantomData,
169
path::{Path, PathBuf},
1710
sync::Arc,
1811
};
1912
use tower_http::services::{ServeDir, ServeFile};
20-
use tower_service::Service;
2113

2214
/// Router for single page applications.
2315
///
@@ -50,10 +42,9 @@ use tower_service::Service;
5042
/// - `GET /some/other/path` will serve `index.html` since there isn't another
5143
/// route for it
5244
/// - `GET /api/foo` will serve the `api_foo` handler function
53-
pub struct SpaRouter<S = (), B = Body, T = (), F = fn(io::Error) -> Ready<StatusCode>> {
45+
pub struct SpaRouter<S = (), B = Body> {
5446
paths: Arc<Paths>,
55-
handle_error: F,
56-
_marker: PhantomData<fn() -> (S, B, T)>,
47+
_marker: PhantomData<fn() -> (S, B)>,
5748
}
5849

5950
#[derive(Debug)]
@@ -63,7 +54,7 @@ struct Paths {
6354
index_file: PathBuf,
6455
}
6556

66-
impl<S, B> SpaRouter<S, B, (), fn(io::Error) -> Ready<StatusCode>> {
57+
impl<S, B> SpaRouter<S, B> {
6758
/// Create a new `SpaRouter`.
6859
///
6960
/// Assets will be served at `GET /{serve_assets_at}` from the directory at `assets_dir`.
@@ -80,13 +71,12 @@ impl<S, B> SpaRouter<S, B, (), fn(io::Error) -> Ready<StatusCode>> {
8071
assets_dir: path.to_owned(),
8172
index_file: path.join("index.html"),
8273
}),
83-
handle_error: |_| ready(StatusCode::INTERNAL_SERVER_ERROR),
8474
_marker: PhantomData,
8575
}
8676
}
8777
}
8878

89-
impl<S, B, T, F> SpaRouter<S, B, T, F> {
79+
impl<S, B> SpaRouter<S, B> {
9080
/// Set the path to the index file.
9181
///
9282
/// `path` must be relative to `assets_dir` passed to [`SpaRouter::new`].
@@ -114,72 +104,27 @@ impl<S, B, T, F> SpaRouter<S, B, T, F> {
114104
});
115105
self
116106
}
117-
118-
/// Change the function used to handle unknown IO errors.
119-
///
120-
/// `SpaRouter` automatically maps missing files and permission denied to
121-
/// `404 Not Found`. The callback given here will be used for other IO errors.
122-
///
123-
/// See [`axum::error_handling::HandleErrorLayer`] for more details.
124-
///
125-
/// # Example
126-
///
127-
/// ```
128-
/// use std::io;
129-
/// use axum_extra::routing::SpaRouter;
130-
/// use axum::{Router, http::{Method, Uri}};
131-
///
132-
/// let spa = SpaRouter::new("/assets", "dist").handle_error(handle_error);
133-
///
134-
/// async fn handle_error(method: Method, uri: Uri, err: io::Error) -> String {
135-
/// format!("{} {} failed with {}", method, uri, err)
136-
/// }
137-
///
138-
/// let app = Router::new().merge(spa);
139-
/// # let _: Router = app;
140-
/// ```
141-
pub fn handle_error<T2, F2>(self, f: F2) -> SpaRouter<S, B, T2, F2> {
142-
SpaRouter {
143-
paths: self.paths,
144-
handle_error: f,
145-
_marker: PhantomData,
146-
}
147-
}
148107
}
149108

150-
impl<S, B, F, T> From<SpaRouter<S, B, T, F>> for Router<S, B>
109+
impl<S, B> From<SpaRouter<S, B>> for Router<S, B>
151110
where
152-
F: Clone + Send + Sync + 'static,
153-
HandleError<Route<B, io::Error>, F, T>: Service<Request<B>, Error = Infallible>,
154-
<HandleError<Route<B, io::Error>, F, T> as Service<Request<B>>>::Response: IntoResponse + Send,
155-
<HandleError<Route<B, io::Error>, F, T> as Service<Request<B>>>::Future: Send,
156111
B: HttpBody + Send + 'static,
157-
T: 'static,
158112
S: Clone + Send + Sync + 'static,
159113
{
160-
fn from(spa: SpaRouter<S, B, T, F>) -> Router<S, B> {
161-
let assets_service = get_service(ServeDir::new(&spa.paths.assets_dir))
162-
.handle_error(spa.handle_error.clone());
163-
114+
fn from(spa: SpaRouter<S, B>) -> Router<S, B> {
115+
let assets_service = ServeDir::new(&spa.paths.assets_dir);
164116
Router::new()
165117
.nest_service(&spa.paths.assets_path, assets_service)
166-
.fallback_service(
167-
get_service(ServeFile::new(&spa.paths.index_file)).handle_error(spa.handle_error),
168-
)
118+
.fallback_service(ServeFile::new(&spa.paths.index_file))
169119
}
170120
}
171121

172-
impl<B, T, F> fmt::Debug for SpaRouter<B, T, F> {
122+
impl<B, T> fmt::Debug for SpaRouter<B, T> {
173123
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174-
let Self {
175-
paths,
176-
handle_error: _,
177-
_marker,
178-
} = self;
124+
let Self { paths, _marker } = self;
179125

180126
f.debug_struct("SpaRouter")
181127
.field("paths", &paths)
182-
.field("handle_error", &format_args!("{}", type_name::<F>()))
183128
.field("request_body_type", &format_args!("{}", type_name::<B>()))
184129
.field(
185130
"extractor_input_type",
@@ -189,14 +134,10 @@ impl<B, T, F> fmt::Debug for SpaRouter<B, T, F> {
189134
}
190135
}
191136

192-
impl<B, T, F> Clone for SpaRouter<B, T, F>
193-
where
194-
F: Clone,
195-
{
137+
impl<B, T> Clone for SpaRouter<B, T> {
196138
fn clone(&self) -> Self {
197139
Self {
198140
paths: self.paths.clone(),
199-
handle_error: self.handle_error,
200141
_marker: self._marker,
201142
}
202143
}
@@ -206,10 +147,8 @@ where
206147
mod tests {
207148
use super::*;
208149
use crate::test_helpers::*;
209-
use axum::{
210-
http::{Method, Uri},
211-
routing::get,
212-
};
150+
use axum::routing::get;
151+
use http::StatusCode;
213152

214153
#[tokio::test]
215154
async fn basic() {
@@ -253,21 +192,6 @@ mod tests {
253192
assert_eq!(res.text().await, "<strong>Hello, World!</strong>\n");
254193
}
255194

256-
// this should just compile
257-
#[allow(dead_code)]
258-
fn setting_error_handler() {
259-
async fn handle_error(method: Method, uri: Uri, err: io::Error) -> (StatusCode, String) {
260-
(
261-
StatusCode::INTERNAL_SERVER_ERROR,
262-
format!("{} {} failed. Error: {}", method, uri, err),
263-
)
264-
}
265-
266-
let spa = SpaRouter::new("/assets", "test_files").handle_error(handle_error);
267-
268-
Router::<(), Body>::new().merge(spa);
269-
}
270-
271195
#[allow(dead_code)]
272196
fn works_with_router_with_state() {
273197
let _: Router = Router::new()

axum/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
# Unreleased
99

10-
- None.
10+
- **changed:** Update to tower-http 0.4. axum is still compatible with tower-http 0.3
1111

1212
# 0.6.8 (24. February, 2023)
1313

axum/Cargo.toml

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,38 @@ tower-log = ["tower/log"]
2727
ws = ["tokio", "dep:tokio-tungstenite", "dep:sha1", "dep:base64"]
2828

2929
# Required for intra-doc links to resolve correctly
30-
__private_docs = ["tower/full", "tower-http/full"]
30+
__private_docs = [
31+
"tower/full",
32+
# all tower-http features except (de)?compression-zstd which doesn't
33+
# build on `--target armv5te-unknown-linux-musleabi`
34+
"tower-http/add-extension",
35+
"tower-http/auth",
36+
"tower-http/catch-panic",
37+
"tower-http/compression-br",
38+
"tower-http/compression-deflate",
39+
"tower-http/compression-gzip",
40+
"tower-http/cors",
41+
"tower-http/decompression-br",
42+
"tower-http/decompression-deflate",
43+
"tower-http/decompression-gzip",
44+
"tower-http/follow-redirect",
45+
"tower-http/fs",
46+
"tower-http/limit",
47+
"tower-http/map-request-body",
48+
"tower-http/map-response-body",
49+
"tower-http/metrics",
50+
"tower-http/normalize-path",
51+
"tower-http/propagate-header",
52+
"tower-http/redirect",
53+
"tower-http/request-id",
54+
"tower-http/sensitive-headers",
55+
"tower-http/set-header",
56+
"tower-http/set-status",
57+
"tower-http/timeout",
58+
"tower-http/trace",
59+
"tower-http/util",
60+
"tower-http/validate-request",
61+
]
3162

3263
[dependencies]
3364
async-trait = "0.1.43"
@@ -47,7 +78,7 @@ pin-project-lite = "0.2.7"
4778
serde = "1.0"
4879
sync_wrapper = "0.1.1"
4980
tower = { version = "0.4.13", default-features = false, features = ["util"] }
50-
tower-http = { version = "0.3.0", features = ["util", "map-response-body"] }
81+
tower-http = { version = "0.4", features = ["util", "map-response-body"] }
5182
tower-layer = "0.3.2"
5283
tower-service = "0.3"
5384

@@ -98,8 +129,38 @@ features = [
98129
]
99130

100131
[dev-dependencies.tower-http]
101-
version = "0.3.4"
102-
features = ["full"]
132+
version = "0.4"
133+
features = [
134+
# all tower-http features except (de)?compression-zstd which doesn't
135+
# build on `--target armv5te-unknown-linux-musleabi`
136+
"add-extension",
137+
"auth",
138+
"catch-panic",
139+
"compression-br",
140+
"compression-deflate",
141+
"compression-gzip",
142+
"cors",
143+
"decompression-br",
144+
"decompression-deflate",
145+
"decompression-gzip",
146+
"follow-redirect",
147+
"fs",
148+
"limit",
149+
"map-request-body",
150+
"map-response-body",
151+
"metrics",
152+
"normalize-path",
153+
"propagate-header",
154+
"redirect",
155+
"request-id",
156+
"sensitive-headers",
157+
"set-header",
158+
"set-status",
159+
"timeout",
160+
"trace",
161+
"util",
162+
"validate-request",
163+
]
103164

104165
[package.metadata.playground]
105166
features = [

axum/src/docs/method_routing/route_layer.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ use axum::{
1717
routing::get,
1818
Router,
1919
};
20-
use tower_http::auth::RequireAuthorizationLayer;
20+
use tower_http::validate_request::ValidateRequestHeaderLayer;
2121

2222
let app = Router::new().route(
2323
"/foo",
2424
get(|| async {})
25-
.route_layer(RequireAuthorizationLayer::bearer("password"))
25+
.route_layer(ValidateRequestHeaderLayer::bearer("password"))
2626
);
2727

2828
// `GET /foo` with a valid token will receive `200 OK`

axum/src/docs/routing/route_layer.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ use axum::{
1717
routing::get,
1818
Router,
1919
};
20-
use tower_http::auth::RequireAuthorizationLayer;
20+
use tower_http::validate_request::ValidateRequestHeaderLayer;
2121

2222
let app = Router::new()
2323
.route("/foo", get(|| async {}))
24-
.route_layer(RequireAuthorizationLayer::bearer("password"));
24+
.route_layer(ValidateRequestHeaderLayer::bearer("password"));
2525

2626
// `GET /foo` with a valid token will receive `200 OK`
2727
// `GET /foo` with a invalid token will receive `401 Unauthorized`

axum/src/docs/routing/route_service.md

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,10 @@ let app = Router::new()
3838
Ok::<_, Infallible>(res)
3939
})
4040
)
41-
.route(
41+
.route_service(
4242
// GET `/static/Cargo.toml` goes to a service from tower-http
4343
"/static/Cargo.toml",
44-
get_service(ServeFile::new("Cargo.toml"))
45-
// though we must handle any potential errors
46-
.handle_error(|error: io::Error| async move {
47-
(
48-
StatusCode::INTERNAL_SERVER_ERROR,
49-
format!("Unhandled internal error: {}", error),
50-
)
51-
})
44+
ServeFile::new("Cargo.toml"),
5245
);
5346
# async {
5447
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();

0 commit comments

Comments
 (0)