mirror of
https://github.com/tokio-rs/axum.git
synced 2024-11-21 14:46:32 +01:00
Add serve
function and remove Server
re-export (#1868)
This commit is contained in:
parent
6703f8634c
commit
c97967252d
86 changed files with 641 additions and 564 deletions
|
@ -41,9 +41,7 @@ use std::fmt;
|
|||
/// }
|
||||
///
|
||||
/// let app = Router::new().route("/list_things", get(list_things));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
///
|
||||
/// If the query string cannot be parsed it will reject the request with a `400
|
||||
|
|
|
@ -105,7 +105,7 @@ use axum_macros::__private_axum_test as test;
|
|||
pub(crate) mod test_helpers {
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use axum::{body::HttpBody, BoxError, Router};
|
||||
use axum::{extract::Request, response::Response, serve};
|
||||
|
||||
mod test_client {
|
||||
#![allow(dead_code)]
|
||||
|
|
|
@ -45,9 +45,7 @@ use prost::Message;
|
|||
/// }
|
||||
///
|
||||
/// let app = Router::new().route("/users", post(create_user));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
///
|
||||
/// # As response
|
||||
|
@ -85,9 +83,7 @@ use prost::Message;
|
|||
/// }
|
||||
///
|
||||
/// let app = Router::new().route("/users/:id", get(get_user));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "protobuf")))]
|
||||
|
|
|
@ -416,10 +416,8 @@ pub fn derive_from_request_parts(item: TokenStream) -> TokenStream {
|
|||
/// async fn main() {
|
||||
/// let app = Router::new().route("/", get(handler));
|
||||
///
|
||||
/// axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
/// .serve(app.into_make_service())
|
||||
/// .await
|
||||
/// .unwrap();
|
||||
/// let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
/// axum::serve(listener, app).await.unwrap();
|
||||
/// }
|
||||
///
|
||||
/// fn handler() -> &'static str {
|
||||
|
@ -438,10 +436,8 @@ pub fn derive_from_request_parts(item: TokenStream) -> TokenStream {
|
|||
/// # async fn main() {
|
||||
/// # let app = Router::new().route("/", get(handler));
|
||||
/// #
|
||||
/// # axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
/// # .serve(app.into_make_service())
|
||||
/// # .await
|
||||
/// # .unwrap();
|
||||
/// # let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
/// # axum::serve(listener, app).await.unwrap();
|
||||
/// # }
|
||||
/// #
|
||||
/// #[debug_handler]
|
||||
|
@ -468,10 +464,8 @@ pub fn derive_from_request_parts(item: TokenStream) -> TokenStream {
|
|||
/// # async {
|
||||
/// let app = Router::new().route("/", get(handler));
|
||||
///
|
||||
/// axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
/// .serve(app.into_make_service())
|
||||
/// .await
|
||||
/// .unwrap();
|
||||
/// let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
/// axum::serve(listener, app).await.unwrap();
|
||||
/// # };
|
||||
/// }
|
||||
///
|
||||
|
|
|
@ -40,12 +40,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- **added:** Add `axum::extract::Request` type alias where the body is `axum::body::Body` ([#1789])
|
||||
- **added:** Add `Router::as_service` and `Router::into_service` to workaround
|
||||
type inference issues when calling `ServiceExt` methods on a `Router` ([#1835])
|
||||
- **breaking:** Removed `axum::Server` as it was removed in hyper 1.0. Instead
|
||||
use `axum::serve(listener, service)` or hyper/hyper-util for more configuration options ([#1868])
|
||||
|
||||
[#1664]: https://github.com/tokio-rs/axum/pull/1664
|
||||
[#1751]: https://github.com/tokio-rs/axum/pull/1751
|
||||
[#1762]: https://github.com/tokio-rs/axum/pull/1762
|
||||
[#1835]: https://github.com/tokio-rs/axum/pull/1835
|
||||
[#1789]: https://github.com/tokio-rs/axum/pull/1789
|
||||
[#1868]: https://github.com/tokio-rs/axum/pull/1868
|
||||
|
||||
# 0.6.16 (18. April, 2023)
|
||||
|
||||
|
|
|
@ -51,6 +51,10 @@ tower = { version = "0.4.13", default-features = false, features = ["util"] }
|
|||
tower-layer = "0.3.2"
|
||||
tower-service = "0.3"
|
||||
|
||||
# wont need this when axum uses http-body 1.0
|
||||
hyper1 = { package = "hyper", version = "1.0.0-rc.3", features = ["server", "http1"] }
|
||||
tower-hyper-http-body-compat = { version = "0.1.4", features = ["server", "http1"] }
|
||||
|
||||
# optional dependencies
|
||||
axum-macros = { path = "../axum-macros", version = "0.3.7", optional = true }
|
||||
base64 = { version = "0.21.0", optional = true }
|
||||
|
@ -192,6 +196,7 @@ allowed = [
|
|||
"http_body",
|
||||
"hyper",
|
||||
"serde",
|
||||
"tokio",
|
||||
"tower_layer",
|
||||
"tower_service",
|
||||
]
|
||||
|
|
|
@ -54,13 +54,8 @@ async fn main() {
|
|||
.route("/users", post(create_user));
|
||||
|
||||
// run our app with hyper
|
||||
// `axum::Server` is a re-export of `hyper::Server`
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
// basic handler that responds with a static string
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use axum::{
|
||||
extract::State,
|
||||
routing::{get, post},
|
||||
Extension, Json, Router, Server,
|
||||
Extension, Json, Router,
|
||||
};
|
||||
use hyper::server::conn::AddrIncoming;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -164,7 +164,7 @@ impl BenchmarkBuilder {
|
|||
std::thread::spawn(move || {
|
||||
rt.block_on(async move {
|
||||
let incoming = AddrIncoming::from_listener(listener).unwrap();
|
||||
Server::builder(incoming)
|
||||
hyper::Server::builder(incoming)
|
||||
.serve(app.into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
|
@ -47,9 +47,7 @@ pin_project! {
|
|||
/// }
|
||||
///
|
||||
/// let app = Router::new().route("/", get(handler));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
///
|
||||
/// [`Stream`]: futures_util::stream::Stream
|
||||
|
|
|
@ -85,9 +85,7 @@ async fn handle_anyhow_error(err: anyhow::Error) -> (StatusCode, String) {
|
|||
format!("Something went wrong: {}", err),
|
||||
)
|
||||
}
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
# Applying fallible middleware
|
||||
|
@ -129,9 +127,7 @@ async fn handle_timeout_error(err: BoxError) -> (StatusCode, String) {
|
|||
)
|
||||
}
|
||||
}
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
# Running extractors for error handling
|
||||
|
@ -171,9 +167,7 @@ async fn handle_timeout_error(
|
|||
format!("`{} {}` failed with {}", method, uri, err),
|
||||
)
|
||||
}
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
[`tower::Service`]: `tower::Service`
|
||||
|
|
|
@ -47,9 +47,7 @@ async fn create_user(Json(payload): Json<CreateUser>) {
|
|||
}
|
||||
|
||||
let app = Router::new().route("/users", post(create_user));
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
# Common extractors
|
||||
|
@ -111,9 +109,7 @@ let app = Router::new()
|
|||
.route("/json", post(json))
|
||||
.route("/request", post(request))
|
||||
.route("/extension", post(extension));
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
# Applying multiple extractors
|
||||
|
@ -151,9 +147,7 @@ async fn get_user_things(
|
|||
|
||||
// ...
|
||||
}
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
# The order of extractors
|
||||
|
@ -253,9 +247,7 @@ async fn create_user(payload: Option<Json<Value>>) {
|
|||
}
|
||||
|
||||
let app = Router::new().route("/users", post(create_user));
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
Wrapping extractors in `Result` makes them optional and gives you the reason
|
||||
|
@ -295,9 +287,7 @@ async fn create_user(payload: Result<Json<Value>, JsonRejection>) {
|
|||
}
|
||||
|
||||
let app = Router::new().route("/users", post(create_user));
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
# Customizing extractor responses
|
||||
|
@ -452,9 +442,7 @@ async fn handler(ExtractUserAgent(user_agent): ExtractUserAgent) {
|
|||
}
|
||||
|
||||
let app = Router::new().route("/foo", get(handler));
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
## Implementing `FromRequest`
|
||||
|
@ -501,9 +489,7 @@ async fn handler(ValidatedBody(body): ValidatedBody) {
|
|||
}
|
||||
|
||||
let app = Router::new().route("/foo", get(handler));
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
## Cannot implement both `FromRequest` and `FromRequestParts`
|
||||
|
@ -624,9 +610,7 @@ async fn handler(user: AuthenticatedUser) {
|
|||
let state = State { /* ... */ };
|
||||
|
||||
let app = Router::new().route("/", get(handler)).layer(Extension(state));
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
# Request body limits
|
||||
|
|
|
@ -23,7 +23,5 @@ let app = Router::new().route(
|
|||
// All requests to `GET /` will be sent through `ConcurrencyLimitLayer`
|
||||
get(hander).layer(ConcurrencyLimitLayer::new(64)),
|
||||
);
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
|
|
@ -28,7 +28,5 @@ let app = Router::new().route(
|
|||
// `GET /foo` with a valid token will receive `200 OK`
|
||||
// `GET /foo` with a invalid token will receive `401 Unauthorized`
|
||||
// `POST /FOO` with a invalid token will receive `405 Method Not Allowed`
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
|
|
@ -55,9 +55,7 @@ let app = Router::new()
|
|||
.layer(TraceLayer::new_for_http())
|
||||
.layer(Extension(State {}))
|
||||
);
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
# Commonly used middleware
|
||||
|
@ -319,9 +317,7 @@ let app = Router::new()
|
|||
}))
|
||||
.layer(TimeoutLayer::new(Duration::from_secs(10)))
|
||||
);
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
See [`error_handling`](crate::error_handling) for more details on axum's error
|
||||
|
@ -376,9 +372,7 @@ let app = Router::new().route("/", get(handler));
|
|||
let app = ServiceBuilder::new()
|
||||
.layer(some_backpressure_sensitive_middleware)
|
||||
.service(app);
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
However when applying middleware around your whole application in this way
|
||||
|
@ -563,10 +557,8 @@ let app = Router::new();
|
|||
let app_with_middleware = middleware.layer(app);
|
||||
|
||||
# async {
|
||||
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
.serve(app_with_middleware.into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
axum::serve(listener, app_with_middleware.into_make_service()).await.unwrap();
|
||||
# };
|
||||
```
|
||||
|
||||
|
|
|
@ -21,12 +21,8 @@ async fn handler(ConnectInfo(addr): ConnectInfo<SocketAddr>) -> String {
|
|||
}
|
||||
|
||||
# async {
|
||||
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
.serve(
|
||||
app.into_make_service_with_connect_info::<SocketAddr>()
|
||||
)
|
||||
.await
|
||||
.expect("server failed");
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
axum::serve(listener, app.into_make_service_with_connect_info::<SocketAddr>()).await.unwrap();
|
||||
# };
|
||||
```
|
||||
|
||||
|
@ -36,9 +32,9 @@ You can implement custom a [`Connected`] like so:
|
|||
use axum::{
|
||||
extract::connect_info::{ConnectInfo, Connected},
|
||||
routing::get,
|
||||
serve::IncomingStream,
|
||||
Router,
|
||||
};
|
||||
use hyper::server::conn::AddrStream;
|
||||
|
||||
let app = Router::new().route("/", get(handler));
|
||||
|
||||
|
@ -53,8 +49,8 @@ struct MyConnectInfo {
|
|||
// ...
|
||||
}
|
||||
|
||||
impl Connected<&AddrStream> for MyConnectInfo {
|
||||
fn connect_info(target: &AddrStream) -> Self {
|
||||
impl Connected<IncomingStream<'_>> for MyConnectInfo {
|
||||
fn connect_info(target: IncomingStream<'_>) -> Self {
|
||||
MyConnectInfo {
|
||||
// ...
|
||||
}
|
||||
|
@ -62,12 +58,8 @@ impl Connected<&AddrStream> for MyConnectInfo {
|
|||
}
|
||||
|
||||
# async {
|
||||
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
.serve(
|
||||
app.into_make_service_with_connect_info::<MyConnectInfo>()
|
||||
)
|
||||
.await
|
||||
.expect("server failed");
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
axum::serve(listener, app.into_make_service_with_connect_info::<MyConnectInfo>()).await.unwrap();
|
||||
# };
|
||||
```
|
||||
|
||||
|
|
|
@ -24,9 +24,7 @@ let app = Router::new().nest("/api", api_routes);
|
|||
// Our app now accepts
|
||||
// - GET /api/users/:id
|
||||
// - POST /api/teams
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
# How the URI changes
|
||||
|
@ -59,9 +57,7 @@ async fn users_get(Path(params): Path<HashMap<String, String>>) {
|
|||
let users_api = Router::new().route("/users/:id", get(users_get));
|
||||
|
||||
let app = Router::new().nest("/:version/api", users_api);
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
# Differences from wildcard routes
|
||||
|
@ -83,9 +79,7 @@ let app = Router::new()
|
|||
// `uri` will contain `/foo`
|
||||
}))
|
||||
.nest("/bar", nested_router);
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
# Fallbacks
|
||||
|
|
|
@ -77,9 +77,7 @@ async fn get_root() {}
|
|||
async fn post_root() {}
|
||||
|
||||
async fn delete_root() {}
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
# More examples
|
||||
|
@ -105,9 +103,7 @@ async fn show_user(Path(id): Path<u64>) {}
|
|||
async fn do_users_action(Path((version, id)): Path<(String, u64)>) {}
|
||||
|
||||
async fn serve_asset(Path(path): Path<String>) {}
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
# Panics
|
||||
|
@ -120,9 +116,7 @@ use axum::{routing::get, Router};
|
|||
let app = Router::new()
|
||||
.route("/", get(|| async {}))
|
||||
.route("/", get(|| async {}));
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
The static route `/foo` and the dynamic route `/:key` are not considered to
|
||||
|
|
|
@ -26,7 +26,5 @@ let app = Router::new()
|
|||
// `GET /foo` with a valid token will receive `200 OK`
|
||||
// `GET /foo` with a invalid token will receive `401 Unauthorized`
|
||||
// `GET /not-found` with a invalid token will receive `404 Not Found`
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
|
|
@ -43,9 +43,7 @@ let app = Router::new()
|
|||
"/static/Cargo.toml",
|
||||
ServeFile::new("Cargo.toml"),
|
||||
);
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
Routing to arbitrary services in this way has complications for backpressure
|
||||
|
@ -64,9 +62,7 @@ let app = Router::new().route_service(
|
|||
"/",
|
||||
Router::new().route("/foo", get(|| async {})),
|
||||
);
|
||||
# async {
|
||||
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
# };
|
||||
# let _: Router = app;
|
||||
```
|
||||
|
||||
Use [`Router::nest`] instead.
|
||||
|
|
|
@ -13,9 +13,8 @@ let routes = Router::new()
|
|||
.with_state(AppState {});
|
||||
|
||||
# async {
|
||||
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
.serve(routes.into_make_service())
|
||||
.await;
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
axum::serve(listener, routes).await.unwrap();
|
||||
# };
|
||||
```
|
||||
|
||||
|
@ -40,9 +39,8 @@ fn routes() -> Router<AppState> {
|
|||
let routes = routes().with_state(AppState {});
|
||||
|
||||
# async {
|
||||
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
.serve(routes.into_make_service())
|
||||
.await;
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
axum::serve(listener, routes).await.unwrap();
|
||||
# };
|
||||
```
|
||||
|
||||
|
@ -64,9 +62,8 @@ fn routes(state: AppState) -> Router {
|
|||
let routes = routes(AppState {});
|
||||
|
||||
# async {
|
||||
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
.serve(routes.into_make_service())
|
||||
.await;
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
axum::serve(listener, routes).await.unwrap();
|
||||
# };
|
||||
```
|
||||
|
||||
|
@ -92,9 +89,8 @@ fn routes<S>(state: AppState) -> Router<S> {
|
|||
let routes = Router::new().nest("/api", routes(AppState {}));
|
||||
|
||||
# async {
|
||||
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
.serve(routes.into_make_service())
|
||||
.await;
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
axum::serve(listener, routes).await.unwrap();
|
||||
# };
|
||||
```
|
||||
|
||||
|
@ -133,9 +129,8 @@ let router: Router<()> = router.with_state(AppState {});
|
|||
// You cannot call `into_make_service` on a `Router<AppState>`
|
||||
// because it is still missing an `AppState`.
|
||||
# async {
|
||||
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
.serve(router.into_make_service())
|
||||
.await;
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
axum::serve(listener, router).await.unwrap();
|
||||
# };
|
||||
```
|
||||
|
||||
|
@ -163,9 +158,8 @@ let final_router: Router<()> = string_router.with_state("foo".to_owned());
|
|||
|
||||
// Since we have a `Router<()>` we can run it.
|
||||
# async {
|
||||
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
.serve(final_router.into_make_service())
|
||||
.await;
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
axum::serve(listener, final_router).await.unwrap();
|
||||
# };
|
||||
```
|
||||
|
||||
|
@ -190,9 +184,8 @@ let app = routes(AppState {});
|
|||
// We can only call `Router::into_make_service` on a `Router<()>`
|
||||
// but `app` is a `Router<AppState>`
|
||||
# async {
|
||||
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
.serve(app.into_make_service())
|
||||
.await;
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
# };
|
||||
```
|
||||
|
||||
|
@ -214,9 +207,8 @@ let app = routes(AppState {});
|
|||
|
||||
// We can now call `Router::into_make_service`
|
||||
# async {
|
||||
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
.serve(app.into_make_service())
|
||||
.await;
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
# };
|
||||
```
|
||||
|
||||
|
|
|
@ -40,9 +40,7 @@ use tower_service::Service;
|
|||
/// // Add middleware that inserts the state into all incoming request's
|
||||
/// // extensions.
|
||||
/// .layer(Extension(state));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
///
|
||||
/// If the extension is missing it will reject the request with a `500 Internal
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
//! [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info
|
||||
|
||||
use super::{Extension, FromRequestParts};
|
||||
use crate::middleware::AddExtension;
|
||||
use crate::{middleware::AddExtension, serve::IncomingStream};
|
||||
use async_trait::async_trait;
|
||||
use http::request::Parts;
|
||||
use hyper::server::conn::AddrStream;
|
||||
|
@ -89,6 +89,12 @@ impl Connected<&AddrStream> for SocketAddr {
|
|||
}
|
||||
}
|
||||
|
||||
impl Connected<IncomingStream<'_>> for SocketAddr {
|
||||
fn connect_info(target: IncomingStream<'_>) -> Self {
|
||||
target.remote_addr()
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, C, T> Service<T> for IntoMakeServiceWithConnectInfo<S, C>
|
||||
where
|
||||
S: Clone,
|
||||
|
@ -213,8 +219,9 @@ where
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{routing::get, test_helpers::TestClient, Router, Server};
|
||||
use std::net::{SocketAddr, TcpListener};
|
||||
use crate::{routing::get, test_helpers::TestClient, Router};
|
||||
use std::net::SocketAddr;
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
#[crate::test]
|
||||
async fn socket_addr() {
|
||||
|
@ -222,17 +229,19 @@ mod tests {
|
|||
format!("{addr}")
|
||||
}
|
||||
|
||||
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
|
||||
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
let addr = listener.local_addr().unwrap();
|
||||
|
||||
let (tx, rx) = tokio::sync::oneshot::channel();
|
||||
tokio::spawn(async move {
|
||||
let app = Router::new().route("/", get(handler));
|
||||
let server = Server::from_tcp(listener)
|
||||
.unwrap()
|
||||
.serve(app.into_make_service_with_connect_info::<SocketAddr>());
|
||||
tx.send(()).unwrap();
|
||||
server.await.expect("server error");
|
||||
crate::serve(
|
||||
listener,
|
||||
app.into_make_service_with_connect_info::<SocketAddr>(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
});
|
||||
rx.await.unwrap();
|
||||
|
||||
|
@ -250,8 +259,8 @@ mod tests {
|
|||
value: &'static str,
|
||||
}
|
||||
|
||||
impl Connected<&AddrStream> for MyConnectInfo {
|
||||
fn connect_info(_target: &AddrStream) -> Self {
|
||||
impl Connected<IncomingStream<'_>> for MyConnectInfo {
|
||||
fn connect_info(_target: IncomingStream<'_>) -> Self {
|
||||
Self {
|
||||
value: "it worked!",
|
||||
}
|
||||
|
@ -262,17 +271,19 @@ mod tests {
|
|||
addr.value
|
||||
}
|
||||
|
||||
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
|
||||
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
let addr = listener.local_addr().unwrap();
|
||||
|
||||
let (tx, rx) = tokio::sync::oneshot::channel();
|
||||
tokio::spawn(async move {
|
||||
let app = Router::new().route("/", get(handler));
|
||||
let server = Server::from_tcp(listener)
|
||||
.unwrap()
|
||||
.serve(app.into_make_service_with_connect_info::<MyConnectInfo>());
|
||||
tx.send(()).unwrap();
|
||||
server.await.expect("server error");
|
||||
crate::serve(
|
||||
listener,
|
||||
app.into_make_service_with_connect_info::<MyConnectInfo>(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
});
|
||||
rx.await.unwrap();
|
||||
|
||||
|
@ -306,7 +317,7 @@ mod tests {
|
|||
format!("{addr}")
|
||||
}
|
||||
|
||||
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
|
||||
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
let addr = listener.local_addr().unwrap();
|
||||
|
||||
tokio::spawn(async move {
|
||||
|
@ -314,10 +325,12 @@ mod tests {
|
|||
.route("/", get(handler))
|
||||
.layer(MockConnectInfo(SocketAddr::from(([0, 0, 0, 0], 1337))));
|
||||
|
||||
let server = Server::from_tcp(listener)
|
||||
.unwrap()
|
||||
.serve(app.into_make_service_with_connect_info::<SocketAddr>());
|
||||
server.await.expect("server error");
|
||||
crate::serve(
|
||||
listener,
|
||||
app.into_make_service_with_connect_info::<SocketAddr>(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
});
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
|
|
|
@ -20,9 +20,7 @@ use std::{collections::HashMap, sync::Arc};
|
|||
/// // `path` will be "/users/:id"
|
||||
/// })
|
||||
/// );
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
///
|
||||
/// # Accessing `MatchedPath` via extensions
|
||||
|
|
|
@ -48,9 +48,7 @@ use std::{
|
|||
/// }
|
||||
///
|
||||
/// let app = Router::new().route("/upload", post(upload));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "multipart")))]
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -42,9 +42,7 @@ use std::{fmt, sync::Arc};
|
|||
/// }
|
||||
///
|
||||
/// let app = Router::new().route("/users/:user_id/team/:team_id", get(users_teams_show));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
///
|
||||
/// If the path contains only one parameter, then you can omit the tuple.
|
||||
|
@ -62,9 +60,7 @@ use std::{fmt, sync::Arc};
|
|||
/// }
|
||||
///
|
||||
/// let app = Router::new().route("/users/:user_id", get(user_info));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
///
|
||||
/// Path segments also can be deserialized into any type that implements
|
||||
|
@ -103,9 +99,7 @@ use std::{fmt, sync::Arc};
|
|||
/// "/users/:user_id/team/:team_id",
|
||||
/// get(users_teams_show).post(users_teams_create),
|
||||
/// );
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
///
|
||||
/// If you wish to capture all path parameters you can use `HashMap` or `Vec`:
|
||||
|
@ -132,9 +126,7 @@ use std::{fmt, sync::Arc};
|
|||
///
|
||||
/// let app = Router::new()
|
||||
/// .route("/users/:user_id/team/:team_id", get(params_map).post(params_vec));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
///
|
||||
/// # Providing detailed rejection output
|
||||
|
|
|
@ -32,9 +32,7 @@ use serde::de::DeserializeOwned;
|
|||
/// }
|
||||
///
|
||||
/// let app = Router::new().route("/list_things", get(list_things));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
///
|
||||
/// If the query string cannot be parsed it will reject the request with a `400
|
||||
|
|
|
@ -25,9 +25,7 @@ use super::{
|
|||
/// async fn handler(RawForm(form): RawForm) {}
|
||||
///
|
||||
/// let app = Router::new().route("/", get(handler));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
#[derive(Debug)]
|
||||
pub struct RawForm(pub Bytes);
|
||||
|
|
|
@ -20,9 +20,7 @@ use std::convert::Infallible;
|
|||
/// }
|
||||
///
|
||||
/// let app = Router::new().route("/users", get(handler));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
#[derive(Debug)]
|
||||
pub struct RawQuery(pub Option<String>);
|
||||
|
|
|
@ -28,9 +28,7 @@ use std::convert::Infallible;
|
|||
/// );
|
||||
///
|
||||
/// let app = Router::new().nest("/api", api_routes);
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
///
|
||||
/// # Extracting via request extensions
|
||||
|
@ -65,9 +63,7 @@ use std::convert::Infallible;
|
|||
/// );
|
||||
///
|
||||
/// let app = Router::new().nest("/api", api_routes);
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
#[cfg(feature = "original-uri")]
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
|
@ -131,13 +131,11 @@ use std::{
|
|||
/// let method_router_with_state = get(handler)
|
||||
/// // provide the state so the handler can access it
|
||||
/// .with_state(state);
|
||||
/// # let _: axum::routing::MethodRouter = method_router_with_state;
|
||||
///
|
||||
/// async fn handler(State(state): State<AppState>) {
|
||||
/// // use `state`...
|
||||
/// }
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(method_router_with_state.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// ```
|
||||
///
|
||||
/// # With `Handler`
|
||||
|
@ -158,10 +156,8 @@ use std::{
|
|||
/// let handler_with_state = handler.with_state(state);
|
||||
///
|
||||
/// # async {
|
||||
/// axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
/// .serve(handler_with_state.into_make_service())
|
||||
/// .await
|
||||
/// .expect("server failed");
|
||||
/// let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
/// axum::serve(listener, handler_with_state.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// ```
|
||||
///
|
||||
|
|
|
@ -31,9 +31,7 @@
|
|||
//! }
|
||||
//! }
|
||||
//! }
|
||||
//! # async {
|
||||
//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
//! # };
|
||||
//! # let _: Router = app;
|
||||
//! ```
|
||||
//!
|
||||
//! # Passing data and/or state to an `on_upgrade` callback
|
||||
|
@ -62,9 +60,7 @@
|
|||
//! let app = Router::new()
|
||||
//! .route("/ws", get(handler))
|
||||
//! .with_state(AppState { /* ... */ });
|
||||
//! # async {
|
||||
//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
//! # };
|
||||
//! # let _: Router = app;
|
||||
//! ```
|
||||
//!
|
||||
//! # Read and write concurrently
|
||||
|
@ -108,7 +104,6 @@ use http::{
|
|||
request::Parts,
|
||||
Method, StatusCode,
|
||||
};
|
||||
use hyper::upgrade::{OnUpgrade, Upgraded};
|
||||
use sha1::{Digest, Sha1};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
|
@ -137,7 +132,7 @@ pub struct WebSocketUpgrade<F = DefaultOnFailedUpgrade> {
|
|||
/// The chosen protocol sent in the `Sec-WebSocket-Protocol` header of the response.
|
||||
protocol: Option<HeaderValue>,
|
||||
sec_websocket_key: HeaderValue,
|
||||
on_upgrade: OnUpgrade,
|
||||
on_upgrade: hyper1::upgrade::OnUpgrade,
|
||||
on_failed_upgrade: F,
|
||||
sec_websocket_protocol: Option<HeaderValue>,
|
||||
}
|
||||
|
@ -206,9 +201,7 @@ impl<F> WebSocketUpgrade<F> {
|
|||
/// // ...
|
||||
/// })
|
||||
/// }
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
pub fn protocols<I>(mut self, protocols: I) -> Self
|
||||
where
|
||||
|
@ -393,7 +386,7 @@ where
|
|||
|
||||
let on_upgrade = parts
|
||||
.extensions
|
||||
.remove::<OnUpgrade>()
|
||||
.remove::<hyper1::upgrade::OnUpgrade>()
|
||||
.ok_or(ConnectionNotUpgradable)?;
|
||||
|
||||
let sec_websocket_protocol = parts.headers.get(header::SEC_WEBSOCKET_PROTOCOL).cloned();
|
||||
|
@ -436,7 +429,7 @@ fn header_contains(headers: &HeaderMap, key: HeaderName, value: &'static str) ->
|
|||
/// See [the module level documentation](self) for more details.
|
||||
#[derive(Debug)]
|
||||
pub struct WebSocket {
|
||||
inner: WebSocketStream<Upgraded>,
|
||||
inner: WebSocketStream<hyper1::upgrade::Upgraded>,
|
||||
protocol: Option<HeaderValue>,
|
||||
}
|
||||
|
||||
|
|
|
@ -135,9 +135,7 @@ pub trait Handler<T, S>: Clone + Send + Sized + 'static {
|
|||
///
|
||||
/// let layered_handler = handler.layer(ConcurrencyLimitLayer::new(64));
|
||||
/// let app = Router::new().route("/", get(layered_handler));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
fn layer<L>(self, layer: L) -> Layered<L, Self, T, S>
|
||||
where
|
||||
|
|
|
@ -37,7 +37,6 @@ impl<H, T, S> HandlerService<H, T, S> {
|
|||
///
|
||||
/// ```rust
|
||||
/// use axum::{
|
||||
/// Server,
|
||||
/// handler::Handler,
|
||||
/// extract::State,
|
||||
/// http::{Uri, Method},
|
||||
|
@ -55,10 +54,8 @@ impl<H, T, S> HandlerService<H, T, S> {
|
|||
/// let app = handler.with_state(AppState {});
|
||||
///
|
||||
/// # async {
|
||||
/// Server::bind(&SocketAddr::from(([127, 0, 0, 1], 3000)))
|
||||
/// .serve(app.into_make_service())
|
||||
/// .await?;
|
||||
/// # Ok::<_, hyper::Error>(())
|
||||
/// let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
/// axum::serve(listener, app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// ```
|
||||
///
|
||||
|
@ -74,7 +71,6 @@ impl<H, T, S> HandlerService<H, T, S> {
|
|||
///
|
||||
/// ```rust
|
||||
/// use axum::{
|
||||
/// Server,
|
||||
/// handler::Handler,
|
||||
/// response::IntoResponse,
|
||||
/// extract::{ConnectInfo, State},
|
||||
|
@ -94,10 +90,11 @@ impl<H, T, S> HandlerService<H, T, S> {
|
|||
/// let app = handler.with_state(AppState {});
|
||||
///
|
||||
/// # async {
|
||||
/// Server::bind(&SocketAddr::from(([127, 0, 0, 1], 3000)))
|
||||
/// .serve(app.into_make_service_with_connect_info::<SocketAddr>())
|
||||
/// .await?;
|
||||
/// # Ok::<_, hyper::Error>(())
|
||||
/// let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
/// axum::serve(
|
||||
/// listener,
|
||||
/// app.into_make_service_with_connect_info::<SocketAddr>(),
|
||||
/// ).await.unwrap();
|
||||
/// # };
|
||||
/// ```
|
||||
///
|
||||
|
@ -179,3 +176,27 @@ where
|
|||
super::future::IntoServiceFuture::new(future)
|
||||
}
|
||||
}
|
||||
|
||||
// for `axum::serve(listener, handler)`
|
||||
#[cfg(feature = "tokio")]
|
||||
const _: () = {
|
||||
use crate::serve::IncomingStream;
|
||||
|
||||
impl<H, T, S> Service<IncomingStream<'_>> for HandlerService<H, T, S>
|
||||
where
|
||||
H: Clone,
|
||||
S: Clone,
|
||||
{
|
||||
type Response = Self;
|
||||
type Error = Infallible;
|
||||
type Future = std::future::Ready<Result<Self::Response, Self::Error>>;
|
||||
|
||||
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
fn call(&mut self, _req: IncomingStream<'_>) -> Self::Future {
|
||||
std::future::ready(Ok(self.clone()))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -50,9 +50,7 @@ use serde::{de::DeserializeOwned, Serialize};
|
|||
/// }
|
||||
///
|
||||
/// let app = Router::new().route("/users", post(create_user));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
///
|
||||
/// When used as a response, it can serialize any type that implements [`serde::Serialize`] to
|
||||
|
@ -87,9 +85,7 @@ use serde::{de::DeserializeOwned, Serialize};
|
|||
/// }
|
||||
///
|
||||
/// let app = Router::new().route("/users/:id", get(get_user));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
|
||||
|
|
|
@ -53,11 +53,9 @@
|
|||
//! // build our application with a single route
|
||||
//! let app = Router::new().route("/", get(|| async { "Hello, World!" }));
|
||||
//!
|
||||
//! // run it with hyper on localhost:3000
|
||||
//! axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
//! .serve(app.into_make_service())
|
||||
//! .await
|
||||
//! .unwrap();
|
||||
//! // run it on localhost:3000
|
||||
//! let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
//! axum::serve(listener, app).await.unwrap();
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
|
@ -82,9 +80,7 @@
|
|||
//! async fn get_foo() {}
|
||||
//! async fn post_foo() {}
|
||||
//! async fn foo_bar() {}
|
||||
//! # async {
|
||||
//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
//! # };
|
||||
//! # let _: Router = app;
|
||||
//! ```
|
||||
//!
|
||||
//! See [`Router`] for more details on routing.
|
||||
|
@ -145,9 +141,7 @@
|
|||
//! let app = Router::new()
|
||||
//! .route("/plain_text", get(plain_text))
|
||||
//! .route("/json", get(json));
|
||||
//! # async {
|
||||
//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
//! # };
|
||||
//! # let _: Router = app;
|
||||
//! ```
|
||||
//!
|
||||
//! See [`response`](crate::response) for more details on building responses.
|
||||
|
@ -202,9 +196,7 @@
|
|||
//! ) {
|
||||
//! // ...
|
||||
//! }
|
||||
//! # async {
|
||||
//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
//! # };
|
||||
//! # let _: Router = app;
|
||||
//! ```
|
||||
//!
|
||||
//! You should prefer using [`State`] if possible since it's more type safe. The downside is that
|
||||
|
@ -240,9 +232,7 @@
|
|||
//! ) {
|
||||
//! // ...
|
||||
//! }
|
||||
//! # async {
|
||||
//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
//! # };
|
||||
//! # let _: Router = app;
|
||||
//! ```
|
||||
//!
|
||||
//! The downside to this approach is that you'll get runtime errors
|
||||
|
@ -298,9 +288,7 @@
|
|||
//! struct CreateUserPayload {
|
||||
//! // ...
|
||||
//! }
|
||||
//! # async {
|
||||
//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
//! # };
|
||||
//! # let _: Router = app;
|
||||
//! ```
|
||||
//!
|
||||
//! The downside to this approach is that it's a little more verbose than using
|
||||
|
@ -356,7 +344,7 @@
|
|||
//! `matched-path` | Enables capturing of every request's router path and the [`MatchedPath`] extractor | Yes
|
||||
//! `multipart` | Enables parsing `multipart/form-data` requests with [`Multipart`] | No
|
||||
//! `original-uri` | Enables capturing of every request's original URI and the [`OriginalUri`] extractor | Yes
|
||||
//! `tokio` | Enables `tokio` as a dependency and `axum::Server`, `SSE` and `extract::connect_info` types. | Yes
|
||||
//! `tokio` | Enables `tokio` as a dependency and `axum::serve`, `SSE` and `extract::connect_info` types. | Yes
|
||||
//! `tower-log` | Enables `tower`'s `log` feature | Yes
|
||||
//! `tracing` | Log rejections from built-in extractors | No
|
||||
//! `ws` | Enables WebSockets support via [`extract::ws`] | No
|
||||
|
@ -377,7 +365,6 @@
|
|||
//! [`Timeout`]: tower::timeout::Timeout
|
||||
//! [examples]: https://github.com/tokio-rs/axum/tree/main/examples
|
||||
//! [`Router::merge`]: crate::routing::Router::merge
|
||||
//! [`axum::Server`]: hyper::server::Server
|
||||
//! [`Service`]: tower::Service
|
||||
//! [`Service::poll_ready`]: tower::Service::poll_ready
|
||||
//! [`Service`'s]: tower::Service
|
||||
|
@ -459,6 +446,8 @@ pub mod handler;
|
|||
pub mod middleware;
|
||||
pub mod response;
|
||||
pub mod routing;
|
||||
#[cfg(feature = "tokio")]
|
||||
pub mod serve;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_helpers;
|
||||
|
@ -470,9 +459,6 @@ pub use async_trait::async_trait;
|
|||
pub use headers;
|
||||
#[doc(no_inline)]
|
||||
pub use http;
|
||||
#[cfg(feature = "tokio")]
|
||||
#[doc(no_inline)]
|
||||
pub use hyper::Server;
|
||||
|
||||
#[doc(inline)]
|
||||
pub use self::extension::Extension;
|
||||
|
@ -496,6 +482,10 @@ pub use axum_core::{BoxError, Error, RequestExt, RequestPartsExt};
|
|||
#[cfg(feature = "macros")]
|
||||
pub use axum_macros::debug_handler;
|
||||
|
||||
#[cfg(feature = "tokio")]
|
||||
#[doc(inline)]
|
||||
pub use self::serve::serve;
|
||||
|
||||
pub use self::service_ext::ServiceExt;
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -84,9 +84,7 @@ use tower_service::Service;
|
|||
/// .route("/foo", post(other_handler))
|
||||
/// // The extractor will run before all routes
|
||||
/// .route_layer(from_extractor::<RequireAuth>());
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
///
|
||||
/// [`Bytes`]: bytes::Bytes
|
||||
|
|
|
@ -48,9 +48,7 @@ macro_rules! top_level_service_fn {
|
|||
///
|
||||
/// // Requests to `GET /` will go to `service`.
|
||||
/// let app = Router::new().route("/", get_service(service));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
///
|
||||
/// Note that `get` routes will also be called for `HEAD` requests but will have
|
||||
|
@ -109,9 +107,7 @@ macro_rules! top_level_handler_fn {
|
|||
///
|
||||
/// // Requests to `GET /` will go to `handler`.
|
||||
/// let app = Router::new().route("/", get(handler));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
///
|
||||
/// Note that `get` routes will also be called for `HEAD` requests but will have
|
||||
|
@ -180,9 +176,7 @@ macro_rules! chained_service_fn {
|
|||
/// // Requests to `POST /` will go to `service` and `GET /` will go to
|
||||
/// // `other_service`.
|
||||
/// let app = Router::new().route("/", post_service(service).get_service(other_service));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
///
|
||||
/// Note that `get` routes will also be called for `HEAD` requests but will have
|
||||
|
@ -244,9 +238,7 @@ macro_rules! chained_handler_fn {
|
|||
/// // Requests to `POST /` will go to `handler` and `GET /` will go to
|
||||
/// // `other_handler`.
|
||||
/// let app = Router::new().route("/", post(handler).get(other_handler));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
///
|
||||
/// Note that `get` routes will also be called for `HEAD` requests but will have
|
||||
|
@ -316,9 +308,7 @@ top_level_service_fn!(trace_service, TRACE);
|
|||
///
|
||||
/// // Requests to `POST /` will go to `service`.
|
||||
/// let app = Router::new().route("/", on_service(MethodFilter::POST, service));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
pub fn on_service<T, S>(filter: MethodFilter, svc: T) -> MethodRouter<S, T::Error>
|
||||
where
|
||||
|
@ -350,9 +340,7 @@ where
|
|||
///
|
||||
/// // All requests to `/` will go to `service`.
|
||||
/// let app = Router::new().route("/", any_service(service));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
///
|
||||
/// Additional methods can still be chained:
|
||||
|
@ -379,9 +367,7 @@ where
|
|||
///
|
||||
/// // `POST /` goes to `other_service`. All other requests go to `service`
|
||||
/// let app = Router::new().route("/", any_service(service).post_service(other_service));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
pub fn any_service<T, S>(svc: T) -> MethodRouter<S, T::Error>
|
||||
where
|
||||
|
@ -419,9 +405,7 @@ top_level_handler_fn!(trace, TRACE);
|
|||
///
|
||||
/// // Requests to `POST /` will go to `handler`.
|
||||
/// let app = Router::new().route("/", on(MethodFilter::POST, handler));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
pub fn on<H, T, S>(filter: MethodFilter, handler: H) -> MethodRouter<S, Infallible>
|
||||
where
|
||||
|
@ -446,9 +430,7 @@ where
|
|||
///
|
||||
/// // All requests to `/` will go to `handler`.
|
||||
/// let app = Router::new().route("/", any(handler));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
///
|
||||
/// Additional methods can still be chained:
|
||||
|
@ -465,9 +447,7 @@ where
|
|||
///
|
||||
/// // `POST /` goes to `other_handler`. All other requests go to `handler`
|
||||
/// let app = Router::new().route("/", any(handler).post(other_handler));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
pub fn any<H, T, S>(handler: H) -> MethodRouter<S, Infallible>
|
||||
where
|
||||
|
@ -587,9 +567,7 @@ where
|
|||
/// // Requests to `GET /` will go to `handler` and `DELETE /` will go to
|
||||
/// // `other_handler`
|
||||
/// let app = Router::new().route("/", get(handler).on(MethodFilter::DELETE, other_handler));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
#[track_caller]
|
||||
pub fn on<H, T>(self, filter: MethodFilter, handler: H) -> Self
|
||||
|
@ -632,7 +610,6 @@ impl MethodRouter<(), Infallible> {
|
|||
///
|
||||
/// ```rust
|
||||
/// use axum::{
|
||||
/// Server,
|
||||
/// handler::Handler,
|
||||
/// http::{Uri, Method},
|
||||
/// response::IntoResponse,
|
||||
|
@ -647,10 +624,8 @@ impl MethodRouter<(), Infallible> {
|
|||
/// let router = get(handler).post(handler);
|
||||
///
|
||||
/// # async {
|
||||
/// Server::bind(&SocketAddr::from(([127, 0, 0, 1], 3000)))
|
||||
/// .serve(router.into_make_service())
|
||||
/// .await?;
|
||||
/// # Ok::<_, hyper::Error>(())
|
||||
/// let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
/// axum::serve(listener, router.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// ```
|
||||
///
|
||||
|
@ -666,7 +641,6 @@ impl MethodRouter<(), Infallible> {
|
|||
///
|
||||
/// ```rust
|
||||
/// use axum::{
|
||||
/// Server,
|
||||
/// handler::Handler,
|
||||
/// response::IntoResponse,
|
||||
/// extract::ConnectInfo,
|
||||
|
@ -681,10 +655,8 @@ impl MethodRouter<(), Infallible> {
|
|||
/// let router = get(handler).post(handler);
|
||||
///
|
||||
/// # async {
|
||||
/// Server::bind(&SocketAddr::from(([127, 0, 0, 1], 3000)))
|
||||
/// .serve(router.into_make_service_with_connect_info::<SocketAddr>())
|
||||
/// .await?;
|
||||
/// # Ok::<_, hyper::Error>(())
|
||||
/// let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
/// axum::serve(listener, router.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// ```
|
||||
///
|
||||
|
@ -758,9 +730,7 @@ where
|
|||
///
|
||||
/// // Requests to `DELETE /` will go to `service`
|
||||
/// let app = Router::new().route("/", on_service(MethodFilter::DELETE, service));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
#[track_caller]
|
||||
pub fn on_service<T>(self, filter: MethodFilter, svc: T) -> Self
|
||||
|
@ -1261,6 +1231,26 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
// for `axum::serve(listener, router)`
|
||||
#[cfg(feature = "tokio")]
|
||||
const _: () = {
|
||||
use crate::serve::IncomingStream;
|
||||
|
||||
impl Service<IncomingStream<'_>> for MethodRouter<()> {
|
||||
type Response = Self;
|
||||
type Error = Infallible;
|
||||
type Future = std::future::Ready<Result<Self::Response, Self::Error>>;
|
||||
|
||||
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
fn call(&mut self, _req: IncomingStream<'_>) -> Self::Future {
|
||||
std::future::ready(Ok(self.clone()))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -1361,7 +1351,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn buiding_complex_router() {
|
||||
async fn buiding_complex_router() {
|
||||
let app = crate::Router::new().route(
|
||||
"/",
|
||||
// use the all the things :bomb:
|
||||
|
@ -1380,7 +1370,8 @@ mod tests {
|
|||
),
|
||||
);
|
||||
|
||||
crate::Server::bind(&"0.0.0.0:0".parse().unwrap()).serve(app.into_make_service());
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:0").await.unwrap();
|
||||
crate::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
#[crate::test]
|
||||
|
|
|
@ -413,10 +413,8 @@ impl Router {
|
|||
/// let app = Router::new().route("/", get(|| async { "Hi!" }));
|
||||
///
|
||||
/// # async {
|
||||
/// axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
/// .serve(app.into_make_service())
|
||||
/// .await
|
||||
/// .expect("server failed");
|
||||
/// let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
/// axum::serve(listener, app).await.unwrap();
|
||||
/// # };
|
||||
/// ```
|
||||
///
|
||||
|
@ -436,6 +434,26 @@ impl Router {
|
|||
}
|
||||
}
|
||||
|
||||
// for `axum::serve(listener, router)`
|
||||
#[cfg(feature = "tokio")]
|
||||
const _: () = {
|
||||
use crate::serve::IncomingStream;
|
||||
|
||||
impl Service<IncomingStream<'_>> for Router<()> {
|
||||
type Response = Self;
|
||||
type Error = Infallible;
|
||||
type Future = std::future::Ready<Result<Self::Response, Self::Error>>;
|
||||
|
||||
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
fn call(&mut self, _req: IncomingStream<'_>) -> Self::Future {
|
||||
std::future::ready(Ok(self.clone()))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
impl<B> Service<Request<B>> for Router<()>
|
||||
where
|
||||
B: HttpBody<Data = bytes::Bytes> + Send + 'static,
|
||||
|
|
234
axum/src/serve.rs
Normal file
234
axum/src/serve.rs
Normal file
|
@ -0,0 +1,234 @@
|
|||
//! Serve services.
|
||||
|
||||
use std::{convert::Infallible, io, net::SocketAddr};
|
||||
|
||||
use axum_core::{body::Body, extract::Request, response::Response};
|
||||
use futures_util::{future::poll_fn, FutureExt};
|
||||
use hyper1::server::conn::http1;
|
||||
use tokio::net::{TcpListener, TcpStream};
|
||||
use tower_hyper_http_body_compat::{HttpBody04ToHttpBody1, HttpBody1ToHttpBody04};
|
||||
use tower_service::Service;
|
||||
|
||||
/// Serve the service with the supplied listener.
|
||||
///
|
||||
/// This method of running a service is intentionally simple and doesn't support any configuration.
|
||||
/// Use hyper or hyper-util if you need configuration.
|
||||
///
|
||||
/// It only supports HTTP/1.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Serving a [`Router`]:
|
||||
///
|
||||
/// ```
|
||||
/// use axum::{Router, routing::get};
|
||||
///
|
||||
/// # async {
|
||||
/// let router = Router::new().route("/", get(|| async { "Hello, World!" }));
|
||||
///
|
||||
/// let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
/// axum::serve(listener, router).await.unwrap();
|
||||
/// # };
|
||||
/// ```
|
||||
///
|
||||
/// See also [`Router::into_make_service_with_connect_info`].
|
||||
///
|
||||
/// Serving a [`MethodRouter`]:
|
||||
///
|
||||
/// ```
|
||||
/// use axum::routing::get;
|
||||
///
|
||||
/// # async {
|
||||
/// let router = get(|| async { "Hello, World!" });
|
||||
///
|
||||
/// let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
/// axum::serve(listener, router).await.unwrap();
|
||||
/// # };
|
||||
/// ```
|
||||
///
|
||||
/// See also [`MethodRouter::into_make_service_with_connect_info`].
|
||||
///
|
||||
/// Serving a [`Handler`]:
|
||||
///
|
||||
/// ```
|
||||
/// use axum::handler::HandlerWithoutStateExt;
|
||||
///
|
||||
/// # async {
|
||||
/// async fn handler() -> &'static str {
|
||||
/// "Hello, World!"
|
||||
/// }
|
||||
///
|
||||
/// let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
/// axum::serve(listener, handler.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// ```
|
||||
///
|
||||
/// See also [`HandlerWithoutStateExt::into_make_service_with_connect_info`] and
|
||||
/// [`HandlerService::into_make_service_with_connect_info`].
|
||||
///
|
||||
/// [`Router`]: crate::Router
|
||||
/// [`Router::into_make_service_with_connect_info`]: crate::Router::into_make_service_with_connect_info
|
||||
/// [`MethodRouter`]: crate::routing::MethodRouter
|
||||
/// [`MethodRouter::into_make_service_with_connect_info`]: crate::routing::MethodRouter::into_make_service_with_connect_info
|
||||
/// [`Handler`]: crate::handler::Handler
|
||||
/// [`HandlerWithoutStateExt::into_make_service_with_connect_info`]: crate::handler::HandlerWithoutStateExt::into_make_service_with_connect_info
|
||||
/// [`HandlerService::into_make_service_with_connect_info`]: crate::handler::HandlerService::into_make_service_with_connect_info
|
||||
#[cfg(feature = "tokio")]
|
||||
pub async fn serve<M, S>(tcp_listener: TcpListener, mut make_service: M) -> io::Result<()>
|
||||
where
|
||||
M: for<'a> Service<IncomingStream<'a>, Error = Infallible, Response = S>,
|
||||
S: Service<Request, Response = Response, Error = Infallible> + Clone + Send + 'static,
|
||||
S::Future: Send,
|
||||
{
|
||||
loop {
|
||||
let (tcp_stream, remote_addr) = tcp_listener.accept().await?;
|
||||
|
||||
poll_fn(|cx| make_service.poll_ready(cx))
|
||||
.await
|
||||
.unwrap_or_else(|err| match err {});
|
||||
|
||||
let mut service = make_service
|
||||
.call(IncomingStream {
|
||||
tcp_stream: &tcp_stream,
|
||||
remote_addr,
|
||||
})
|
||||
.await
|
||||
.unwrap_or_else(|err| match err {});
|
||||
|
||||
let service = hyper1::service::service_fn(move |req: Request<hyper1::body::Incoming>| {
|
||||
let req = req.map(|body| {
|
||||
// wont need this when axum uses http-body 1.0
|
||||
let http_body_04 = HttpBody1ToHttpBody04::new(body);
|
||||
Body::new(http_body_04)
|
||||
});
|
||||
|
||||
// doing this saves cloning the service just to await the service being ready
|
||||
//
|
||||
// services like `Router` are always ready, so assume the service
|
||||
// we're running here is also always ready...
|
||||
match futures_util::future::poll_fn(|cx| service.poll_ready(cx)).now_or_never() {
|
||||
Some(Ok(())) => {}
|
||||
Some(Err(err)) => match err {},
|
||||
None => {
|
||||
// ...otherwise load shed
|
||||
let mut res = Response::new(HttpBody04ToHttpBody1::new(Body::empty()));
|
||||
*res.status_mut() = http::StatusCode::SERVICE_UNAVAILABLE;
|
||||
return std::future::ready(Ok(res)).left_future();
|
||||
}
|
||||
}
|
||||
|
||||
let future = service.call(req);
|
||||
|
||||
async move {
|
||||
let response = future
|
||||
.await
|
||||
.unwrap_or_else(|err| match err {})
|
||||
// wont need this when axum uses http-body 1.0
|
||||
.map(HttpBody04ToHttpBody1::new);
|
||||
|
||||
Ok::<_, Infallible>(response)
|
||||
}
|
||||
.right_future()
|
||||
});
|
||||
|
||||
tokio::task::spawn(async move {
|
||||
match http1::Builder::new()
|
||||
.serve_connection(tcp_stream, service)
|
||||
// for websockets
|
||||
.with_upgrades()
|
||||
.await
|
||||
{
|
||||
Ok(()) => {}
|
||||
Err(_err) => {
|
||||
// This error only appears when the client doesn't send a request and
|
||||
// terminate the connection.
|
||||
//
|
||||
// If client sends one request then terminate connection whenever, it doesn't
|
||||
// appear.
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// An incoming stream.
|
||||
///
|
||||
/// Used with [`serve`] and [`IntoMakeServiceWithConnectInfo`].
|
||||
///
|
||||
/// [`IntoMakeServiceWithConnectInfo`]: crate::extract::connect_info::IntoMakeServiceWithConnectInfo
|
||||
#[derive(Debug)]
|
||||
pub struct IncomingStream<'a> {
|
||||
tcp_stream: &'a TcpStream,
|
||||
remote_addr: SocketAddr,
|
||||
}
|
||||
|
||||
impl IncomingStream<'_> {
|
||||
/// Returns the local address that this stream is bound to.
|
||||
pub fn local_addr(&self) -> std::io::Result<SocketAddr> {
|
||||
self.tcp_stream.local_addr()
|
||||
}
|
||||
|
||||
/// Returns the remote address that this stream is bound to.
|
||||
pub fn remote_addr(&self) -> SocketAddr {
|
||||
self.remote_addr
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
handler::{Handler, HandlerWithoutStateExt},
|
||||
routing::get,
|
||||
Router,
|
||||
};
|
||||
|
||||
#[allow(dead_code, unused_must_use)]
|
||||
async fn if_it_compiles_it_works() {
|
||||
let router: Router = Router::new();
|
||||
|
||||
let addr = "0.0.0.0:0";
|
||||
|
||||
// router
|
||||
serve(TcpListener::bind(addr).await.unwrap(), router.clone());
|
||||
serve(
|
||||
TcpListener::bind(addr).await.unwrap(),
|
||||
router.clone().into_make_service(),
|
||||
);
|
||||
serve(
|
||||
TcpListener::bind(addr).await.unwrap(),
|
||||
router.into_make_service_with_connect_info::<SocketAddr>(),
|
||||
);
|
||||
|
||||
// method router
|
||||
serve(TcpListener::bind(addr).await.unwrap(), get(handler));
|
||||
serve(
|
||||
TcpListener::bind(addr).await.unwrap(),
|
||||
get(handler).into_make_service(),
|
||||
);
|
||||
serve(
|
||||
TcpListener::bind(addr).await.unwrap(),
|
||||
get(handler).into_make_service_with_connect_info::<SocketAddr>(),
|
||||
);
|
||||
|
||||
// handler
|
||||
serve(
|
||||
TcpListener::bind(addr).await.unwrap(),
|
||||
handler.into_service(),
|
||||
);
|
||||
serve(
|
||||
TcpListener::bind(addr).await.unwrap(),
|
||||
handler.with_state(()),
|
||||
);
|
||||
serve(
|
||||
TcpListener::bind(addr).await.unwrap(),
|
||||
handler.into_make_service(),
|
||||
);
|
||||
serve(
|
||||
TcpListener::bind(addr).await.unwrap(),
|
||||
handler.into_make_service_with_connect_info::<SocketAddr>(),
|
||||
);
|
||||
}
|
||||
|
||||
async fn handler() {}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
#![allow(clippy::disallowed_names)]
|
||||
|
||||
use crate::{body::HttpBody, BoxError};
|
||||
use crate::{extract::Request, response::Response, serve};
|
||||
|
||||
mod test_client;
|
||||
pub(crate) use self::test_client::*;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use super::{BoxError, HttpBody};
|
||||
use super::{serve, Request, Response};
|
||||
use bytes::Bytes;
|
||||
use http::{
|
||||
header::{HeaderName, HeaderValue},
|
||||
Request, StatusCode,
|
||||
StatusCode,
|
||||
};
|
||||
use hyper::Server;
|
||||
use std::net::{SocketAddr, TcpListener};
|
||||
use std::{convert::Infallible, net::SocketAddr};
|
||||
use tokio::net::TcpListener;
|
||||
use tower::make::Shared;
|
||||
use tower_service::Service;
|
||||
|
||||
|
@ -15,25 +15,22 @@ pub(crate) struct TestClient {
|
|||
}
|
||||
|
||||
impl TestClient {
|
||||
pub(crate) fn new<S, ResBody>(svc: S) -> Self
|
||||
pub(crate) fn new<S>(svc: S) -> Self
|
||||
where
|
||||
S: Service<Request<hyper::Body>, Response = http::Response<ResBody>>
|
||||
+ Clone
|
||||
+ Send
|
||||
+ 'static,
|
||||
ResBody: HttpBody + Send + 'static,
|
||||
ResBody::Data: Send,
|
||||
ResBody::Error: Into<BoxError>,
|
||||
S: Service<Request, Response = Response, Error = Infallible> + Clone + Send + 'static,
|
||||
S::Future: Send,
|
||||
S::Error: Into<BoxError>,
|
||||
{
|
||||
let listener = TcpListener::bind("127.0.0.1:0").expect("Could not bind ephemeral socket");
|
||||
let std_listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
|
||||
std_listener.set_nonblocking(true).unwrap();
|
||||
let listener = TcpListener::from_std(std_listener).unwrap();
|
||||
|
||||
let addr = listener.local_addr().unwrap();
|
||||
println!("Listening on {addr}");
|
||||
|
||||
tokio::spawn(async move {
|
||||
let server = Server::from_tcp(listener).unwrap().serve(Shared::new(svc));
|
||||
server.await.expect("server error");
|
||||
serve(listener, Shared::new(svc))
|
||||
.await
|
||||
.expect("server error")
|
||||
});
|
||||
|
||||
let client = reqwest::Client::builder()
|
||||
|
|
|
@ -27,9 +27,7 @@ use std::convert::Infallible;
|
|||
/// }
|
||||
///
|
||||
/// let app = Router::new().route("/users/:user_id/team/:team_id", get(users_teams_show));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// # let _: Router = app;
|
||||
/// ```
|
||||
///
|
||||
/// # As response
|
||||
|
|
|
@ -25,6 +25,8 @@ skip-tree = [
|
|||
{ name = "spin" },
|
||||
# lots still pulls in syn 1.x
|
||||
{ name = "syn" },
|
||||
# until 1.0 is out we're pulling in both 0.14 and 1.0-rc.x
|
||||
{ name = "hyper" },
|
||||
]
|
||||
|
||||
[sources]
|
||||
|
|
|
@ -10,18 +10,16 @@ use axum::{
|
|||
routing::get,
|
||||
Router,
|
||||
};
|
||||
use std::net::SocketAddr;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let app = Router::new().route("/", get(handler));
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
println!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
println!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn handler() -> Result<(), AppError> {
|
||||
|
|
|
@ -18,7 +18,6 @@ use axum::{
|
|||
use futures::{sink::SinkExt, stream::StreamExt};
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
net::SocketAddr,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
use tokio::sync::broadcast;
|
||||
|
@ -53,12 +52,11 @@ async fn main() {
|
|||
.route("/websocket", get(websocket_handler))
|
||||
.with_state(app_state);
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn websocket_handler(
|
||||
|
|
|
@ -14,7 +14,6 @@ use axum::{
|
|||
routing::post,
|
||||
Router,
|
||||
};
|
||||
use std::net::SocketAddr;
|
||||
use tower::ServiceBuilder;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
|
@ -32,12 +31,11 @@ async fn main() {
|
|||
.route("/", post(handler))
|
||||
.layer(ServiceBuilder::new().layer(middleware::from_fn(print_request_body)));
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
// middleware that shows how to consume the request body upfront
|
||||
|
|
|
@ -40,10 +40,8 @@ async fn main() {
|
|||
|
||||
async fn serve(app: Router, port: u16) {
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], port));
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn html() -> impl IntoResponse {
|
||||
|
|
|
@ -9,7 +9,6 @@ mod derive_from_request;
|
|||
mod with_rejection;
|
||||
|
||||
use axum::{routing::post, Router};
|
||||
use std::net::SocketAddr;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
#[tokio::main]
|
||||
|
@ -29,10 +28,9 @@ async fn main() {
|
|||
.route("/derive-from-request", post(derive_from_request::handler));
|
||||
|
||||
// Run our application
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ use axum::{
|
|||
Router,
|
||||
};
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
use std::net::SocketAddr;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
#[tokio::main]
|
||||
|
@ -30,12 +29,11 @@ async fn main() {
|
|||
let app = Router::new().route("/users/:user_id/teams/:team_id", get(handler));
|
||||
|
||||
// run it
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
println!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn handler(Path(params): Path<Params>) -> impl IntoResponse {
|
||||
|
|
|
@ -17,7 +17,7 @@ use axum::{
|
|||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
use std::{net::SocketAddr, sync::Arc};
|
||||
use std::sync::Arc;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
use uuid::Uuid;
|
||||
|
||||
|
@ -42,12 +42,11 @@ async fn main() {
|
|||
.with_state(user_repo);
|
||||
|
||||
// Run our application
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
/// Handler for `GET /users/:id`.
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
use axum::{extract::Form, response::Html, routing::get, Router};
|
||||
use serde::Deserialize;
|
||||
use std::net::SocketAddr;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
#[tokio::main]
|
||||
|
@ -22,13 +21,12 @@ async fn main() {
|
|||
// build our application with some routes
|
||||
let app = Router::new().route("/", get(show_form).post(accept_form));
|
||||
|
||||
// run it with hyper
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
// run it
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn show_form() -> Html<&'static str> {
|
||||
|
|
|
@ -10,7 +10,6 @@ use axum::{
|
|||
routing::get,
|
||||
Router,
|
||||
};
|
||||
use std::net::SocketAddr;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
#[tokio::main]
|
||||
|
@ -30,12 +29,11 @@ async fn main() {
|
|||
let app = app.fallback(handler_404);
|
||||
|
||||
// run it
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn handler() -> Html<&'static str> {
|
||||
|
|
|
@ -6,4 +6,5 @@ publish = false
|
|||
|
||||
[dependencies]
|
||||
axum = { path = "../../axum" }
|
||||
hyper = { version = "0.14", features = ["full"] }
|
||||
tokio = { version = "1.0", features = ["full"] }
|
||||
|
|
|
@ -17,7 +17,7 @@ async fn main() {
|
|||
// run it
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
println!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
hyper::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
.with_graceful_shutdown(shutdown_signal())
|
||||
.await
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
use axum::response::{IntoResponse, Response};
|
||||
use axum::{http, routing::get, Router};
|
||||
use std::net::SocketAddr;
|
||||
|
||||
fn app() -> Router {
|
||||
Router::new().route("/get-head", get(get_head_handler))
|
||||
|
@ -14,12 +13,11 @@ fn app() -> Router {
|
|||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app().into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
println!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app()).await.unwrap();
|
||||
}
|
||||
|
||||
// GET routes will also be called for HEAD requests but will have the response body removed.
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
//! ```
|
||||
|
||||
use axum::{response::Html, routing::get, Router};
|
||||
use std::net::SocketAddr;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
|
@ -13,12 +12,11 @@ async fn main() {
|
|||
let app = Router::new().route("/", get(handler));
|
||||
|
||||
// run it
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
println!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
println!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn handler() -> Html<&'static str> {
|
||||
|
|
|
@ -52,7 +52,7 @@ async fn main() {
|
|||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
hyper::Server::bind(&addr)
|
||||
.http1_preserve_header_case(true)
|
||||
.http1_title_case_headers(true)
|
||||
.serve(Shared::new(service))
|
||||
|
|
|
@ -19,7 +19,7 @@ use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, Validation}
|
|||
use once_cell::sync::Lazy;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
use std::{fmt::Display, net::SocketAddr};
|
||||
use std::fmt::Display;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
// Quick instructions
|
||||
|
@ -67,13 +67,11 @@ async fn main() {
|
|||
.route("/protected", get(protected))
|
||||
.route("/authorize", post(authorize));
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn protected(claims: Claims) -> Result<String, AuthError> {
|
||||
|
|
|
@ -19,7 +19,6 @@ use axum::{
|
|||
use std::{
|
||||
borrow::Cow,
|
||||
collections::HashMap,
|
||||
net::SocketAddr,
|
||||
sync::{Arc, RwLock},
|
||||
time::Duration,
|
||||
};
|
||||
|
@ -74,12 +73,11 @@ async fn main() {
|
|||
.with_state(Arc::clone(&shared_state));
|
||||
|
||||
// Run our app with hyper
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
type SharedState = Arc<RwLock<AppState>>;
|
||||
|
|
|
@ -28,7 +28,7 @@ async fn main() {
|
|||
b: incoming_v6,
|
||||
};
|
||||
|
||||
axum::Server::builder(combined)
|
||||
hyper::Server::builder(combined)
|
||||
.serve(app.into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
|
@ -10,7 +10,6 @@ use axum::{
|
|||
routing::get,
|
||||
Router,
|
||||
};
|
||||
use std::net::SocketAddr;
|
||||
use tower_http::limit::RequestBodyLimitLayer;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
|
@ -34,12 +33,11 @@ async fn main() {
|
|||
.layer(tower_http::trace::TraceLayer::new_for_http());
|
||||
|
||||
// run it with hyper
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn show_form() -> Html<&'static str> {
|
||||
|
|
|
@ -25,7 +25,7 @@ use oauth2::{
|
|||
ClientSecret, CsrfToken, RedirectUrl, Scope, TokenResponse, TokenUrl,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{env, net::SocketAddr};
|
||||
use std::env;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
static COOKIE_NAME: &str = "SESSION";
|
||||
|
@ -56,13 +56,11 @@ async fn main() {
|
|||
.route("/logout", get(logout))
|
||||
.with_state(app_state);
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
|
@ -15,7 +15,6 @@ use axum::{
|
|||
Form, Json, RequestExt, Router,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::net::SocketAddr;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
#[tokio::main]
|
||||
|
@ -31,12 +30,11 @@ async fn main() {
|
|||
|
||||
let app = Router::new().route("/", post(handler));
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
|
|
@ -13,7 +13,6 @@ use axum::{
|
|||
routing::post,
|
||||
Router,
|
||||
};
|
||||
use std::net::SocketAddr;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
#[tokio::main]
|
||||
|
@ -30,12 +29,11 @@ async fn main() {
|
|||
.route("/", post(|| async move { "Hello from `POST /`" }))
|
||||
.layer(middleware::from_fn(print_request_response));
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn print_request_response(
|
||||
|
|
|
@ -17,7 +17,6 @@ use axum::{
|
|||
use metrics_exporter_prometheus::{Matcher, PrometheusBuilder, PrometheusHandle};
|
||||
use std::{
|
||||
future::ready,
|
||||
net::SocketAddr,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
@ -42,24 +41,22 @@ fn main_app() -> Router {
|
|||
async fn start_main_server() {
|
||||
let app = main_app();
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn start_metrics_server() {
|
||||
let app = metrics_app();
|
||||
|
||||
// NOTE: expose metrics enpoint on a different port
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3001));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3001")
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
|
|
|
@ -10,10 +10,11 @@ use std::{fmt, str::FromStr};
|
|||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
.serve(app().into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
println!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app()).await.unwrap();
|
||||
}
|
||||
|
||||
fn app() -> Router {
|
||||
|
|
|
@ -11,7 +11,6 @@ use axum::{
|
|||
Json, Router,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::net::SocketAddr;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
|
@ -26,13 +25,11 @@ async fn main() {
|
|||
.route("/users", post(create_user));
|
||||
|
||||
// run our app with hyper
|
||||
// `axum::Server` is a re-export of `hyper::Server`
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
// basic handler that responds with a static string
|
||||
|
|
|
@ -75,7 +75,7 @@ async fn main() {
|
|||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
hyper::Server::bind(&addr)
|
||||
.serve(tower::make::Shared::new(service))
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
|
@ -16,7 +16,6 @@ use axum::{
|
|||
Router,
|
||||
};
|
||||
use hyper::client::HttpConnector;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
type Client = hyper::client::Client<HttpConnector, Body>;
|
||||
|
||||
|
@ -28,12 +27,11 @@ async fn main() {
|
|||
|
||||
let app = Router::new().route("/", get(handler)).with_state(client);
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 4000));
|
||||
println!("reverse proxy listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:4000")
|
||||
.await
|
||||
.unwrap();
|
||||
println!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn handler(State(client): State<Client>, mut req: Request) -> Response {
|
||||
|
@ -54,10 +52,9 @@ async fn handler(State(client): State<Client>, mut req: Request) -> Response {
|
|||
async fn server() {
|
||||
let app = Router::new().route("/", get(|| async { "Hello, world!" }));
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
println!("server listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
println!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ use axum::{
|
|||
routing::{get, post, MethodRouter},
|
||||
Router,
|
||||
};
|
||||
use std::net::SocketAddr;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
|
@ -17,12 +16,11 @@ async fn main() {
|
|||
.merge(get_foo())
|
||||
.merge(post_foo());
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
println!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
println!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
fn root() -> Router {
|
||||
|
|
|
@ -21,7 +21,6 @@ use axum::{
|
|||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Debug;
|
||||
use std::net::SocketAddr;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
use uuid::Uuid;
|
||||
|
||||
|
@ -42,12 +41,11 @@ async fn main() {
|
|||
|
||||
let app = Router::new().route("/", get(handler)).with_state(store);
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn handler(user_id: UserIdFromSession) -> impl IntoResponse {
|
||||
|
|
|
@ -21,9 +21,10 @@ use axum::{
|
|||
Router,
|
||||
};
|
||||
use sqlx::postgres::{PgPool, PgPoolOptions};
|
||||
use tokio::net::TcpListener;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
use std::{net::SocketAddr, time::Duration};
|
||||
use std::time::Duration;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
|
@ -55,12 +56,9 @@ async fn main() {
|
|||
.with_state(pool);
|
||||
|
||||
// run it with hyper
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
let listener = TcpListener::bind("127.0.0.1:3000").await.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
// we can extract the connection pool with `State`
|
||||
|
|
|
@ -11,7 +11,7 @@ use axum::{
|
|||
Router,
|
||||
};
|
||||
use futures::stream::{self, Stream};
|
||||
use std::{convert::Infallible, net::SocketAddr, path::PathBuf, time::Duration};
|
||||
use std::{convert::Infallible, path::PathBuf, time::Duration};
|
||||
use tokio_stream::StreamExt as _;
|
||||
use tower_http::{services::ServeDir, trace::TraceLayer};
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
@ -37,12 +37,11 @@ async fn main() {
|
|||
.layer(TraceLayer::new_for_http());
|
||||
|
||||
// run it
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn sse_handler(
|
||||
|
|
|
@ -103,9 +103,9 @@ fn calling_serve_dir_from_a_handler() -> Router {
|
|||
|
||||
async fn serve(app: Router, port: u16) {
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], port));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.layer(TraceLayer::new_for_http()).into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app.layer(TraceLayer::new_for_http()))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use axum::{
|
|||
BoxError, Router,
|
||||
};
|
||||
use futures::{Stream, TryStreamExt};
|
||||
use std::{io, net::SocketAddr};
|
||||
use std::io;
|
||||
use tokio::{fs::File, io::BufWriter};
|
||||
use tokio_util::io::StreamReader;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
@ -39,12 +39,11 @@ async fn main() {
|
|||
.route("/", get(show_form).post(accept_form))
|
||||
.route("/file/:file_name", post(save_request_body));
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
// Handler that streams the request body to a file.
|
||||
|
|
|
@ -12,7 +12,6 @@ use axum::{
|
|||
routing::get,
|
||||
Router,
|
||||
};
|
||||
use std::net::SocketAddr;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
#[tokio::main]
|
||||
|
@ -29,12 +28,11 @@ async fn main() {
|
|||
let app = Router::new().route("/greet/:name", get(greet));
|
||||
|
||||
// run it
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn greet(extract::Path(name): extract::Path<String>) -> impl IntoResponse {
|
||||
|
|
|
@ -14,16 +14,14 @@ use axum::{
|
|||
Router,
|
||||
};
|
||||
use futures::{Sink, SinkExt, Stream, StreamExt};
|
||||
use std::net::SocketAddr;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
println!("listening on {addr}");
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app().into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
println!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app()).await.unwrap();
|
||||
}
|
||||
|
||||
fn app() -> Router {
|
||||
|
@ -94,17 +92,18 @@ where
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::net::Ipv4Addr;
|
||||
use std::net::{Ipv4Addr, SocketAddr};
|
||||
use tokio_tungstenite::tungstenite;
|
||||
|
||||
// We can integration test one handler by running the server in a background task and
|
||||
// connecting to it like any other client would.
|
||||
#[tokio::test]
|
||||
async fn integration_test() {
|
||||
let server = axum::Server::bind(&SocketAddr::from((Ipv4Addr::UNSPECIFIED, 0)))
|
||||
.serve(app().into_make_service());
|
||||
let addr = server.local_addr();
|
||||
tokio::spawn(server);
|
||||
let listener = tokio::net::TcpListener::bind(SocketAddr::from((Ipv4Addr::UNSPECIFIED, 0)))
|
||||
.await
|
||||
.unwrap();
|
||||
let addr = listener.local_addr().unwrap();
|
||||
tokio::spawn(axum::serve(listener, app()));
|
||||
|
||||
let (mut socket, _response) =
|
||||
tokio_tungstenite::connect_async(format!("ws://{addr}/integration-testable"))
|
||||
|
|
|
@ -24,14 +24,11 @@ async fn main() {
|
|||
.with(tracing_subscriber::fmt::layer())
|
||||
.init();
|
||||
|
||||
let addr = std::net::SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
|
||||
tracing::debug!("listening on {}", addr);
|
||||
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app().into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app()).await.unwrap();
|
||||
}
|
||||
|
||||
/// Having a function that produces our app makes it easy to call it from tests
|
||||
|
@ -63,7 +60,8 @@ mod tests {
|
|||
http::{self, Request, StatusCode},
|
||||
};
|
||||
use serde_json::{json, Value};
|
||||
use std::net::{SocketAddr, TcpListener};
|
||||
use std::net::SocketAddr;
|
||||
use tokio::net::TcpListener;
|
||||
use tower::Service; // for `call`
|
||||
use tower::ServiceExt; // for `oneshot` and `ready`
|
||||
|
||||
|
@ -131,15 +129,11 @@ mod tests {
|
|||
// You can also spawn a server and talk to it like any other HTTP server:
|
||||
#[tokio::test]
|
||||
async fn the_real_deal() {
|
||||
let listener = TcpListener::bind("0.0.0.0:0".parse::<SocketAddr>().unwrap()).unwrap();
|
||||
let listener = TcpListener::bind("0.0.0.0:0").await.unwrap();
|
||||
let addr = listener.local_addr().unwrap();
|
||||
|
||||
tokio::spawn(async move {
|
||||
axum::Server::from_tcp(listener)
|
||||
.unwrap()
|
||||
.serve(app().into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
axum::serve(listener, app()).await.unwrap();
|
||||
});
|
||||
|
||||
let client = hyper::Client::new();
|
||||
|
|
|
@ -93,10 +93,9 @@ async fn redirect_http_to_https(ports: Ports) {
|
|||
};
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], ports.http));
|
||||
tracing::debug!("http redirect listening on {}", addr);
|
||||
|
||||
axum::Server::bind(&addr)
|
||||
.serve(redirect.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, redirect.into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ use axum::{
|
|||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
net::SocketAddr,
|
||||
sync::{Arc, RwLock},
|
||||
time::Duration,
|
||||
};
|
||||
|
@ -68,12 +67,11 @@ async fn main() {
|
|||
)
|
||||
.with_state(db);
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
// The query parameters for todos index
|
||||
|
|
|
@ -13,7 +13,6 @@ use axum::{
|
|||
};
|
||||
use bb8::{Pool, PooledConnection};
|
||||
use bb8_postgres::PostgresConnectionManager;
|
||||
use std::net::SocketAddr;
|
||||
use tokio_postgres::NoTls;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
|
@ -41,13 +40,12 @@ async fn main() {
|
|||
)
|
||||
.with_state(pool);
|
||||
|
||||
// run it with hyper
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
// run it
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
type ConnectionPool = Pool<PostgresConnectionManager<NoTls>>;
|
||||
|
|
|
@ -12,7 +12,8 @@ use axum::{
|
|||
routing::get,
|
||||
Router,
|
||||
};
|
||||
use std::{net::SocketAddr, time::Duration};
|
||||
use std::time::Duration;
|
||||
use tokio::net::TcpListener;
|
||||
use tower_http::{classify::ServerErrorsFailureClass, trace::TraceLayer};
|
||||
use tracing::{info_span, Span};
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
@ -80,12 +81,9 @@ async fn main() {
|
|||
);
|
||||
|
||||
// run it
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
let listener = TcpListener::bind("127.0.0.1:3000").await.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn handler() -> Html<&'static str> {
|
||||
|
|
|
@ -63,7 +63,7 @@ mod unix {
|
|||
tokio::spawn(async {
|
||||
let app = Router::new().route("/", get(handler));
|
||||
|
||||
axum::Server::builder(ServerAccept { uds })
|
||||
hyper::Server::builder(ServerAccept { uds })
|
||||
.serve(app.into_make_service_with_connect_info::<UdsConnectInfo>())
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
|
@ -19,8 +19,8 @@ use axum::{
|
|||
Router,
|
||||
};
|
||||
use serde::{de::DeserializeOwned, Deserialize};
|
||||
use std::net::SocketAddr;
|
||||
use thiserror::Error;
|
||||
use tokio::net::TcpListener;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
use validator::Validate;
|
||||
|
||||
|
@ -38,13 +38,9 @@ async fn main() {
|
|||
let app = Router::new().route("/", get(handler));
|
||||
|
||||
// run it
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
let listener = TcpListener::bind("127.0.0.1:3000").await.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Validate)]
|
||||
|
|
|
@ -12,7 +12,7 @@ use axum::{
|
|||
routing::get,
|
||||
RequestPartsExt, Router,
|
||||
};
|
||||
use std::{collections::HashMap, net::SocketAddr};
|
||||
use std::collections::HashMap;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
#[tokio::main]
|
||||
|
@ -29,12 +29,11 @@ async fn main() {
|
|||
let app = Router::new().route("/:version/foo", get(handler));
|
||||
|
||||
// run it
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn handler(version: Version) {
|
||||
|
|
|
@ -66,12 +66,16 @@ async fn main() {
|
|||
);
|
||||
|
||||
// run it with hyper
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service_with_connect_info::<SocketAddr>())
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
axum::serve(
|
||||
listener,
|
||||
app.into_make_service_with_connect_info::<SocketAddr>(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
/// The handler for the HTTP request (this gets called when the HTTP GET lands at the start
|
||||
|
|
Loading…
Reference in a new issue