From ba4d8a2357702d58a00d8306f56b1e5cc7a963db Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Wed, 3 Nov 2021 12:38:48 +0100 Subject: [PATCH] Move axum crate into workspace subfolder (#458) * Move axum crate into workspace subfolder Over time I imagine we're gonna have other crates in this repo that provide utilities or integrations for axum. This prepares for that by moving the main axum crate into its own folder. The README situation is a bit annoying because we want `./README.md` for viewing the repo on github but `axum/README.md` for crates.io. For now I've just copy/pasted it and added CI step to make sure they're identical. * update changelog link * Add licenses to all examples * is this how you install `diff`? * or maybe this is how? * fix readme links * like this? * fix cargo-deny step * Try making root readme a symlink * remove compare readme step not needed since readme in repo root is now a symlink * Revert "Add licenses to all examples" This reverts commit ab321b7fb9cd9124400adf10914820d409751740. --- .github/workflows/CI.yml | 13 +- CHANGELOG.md | 481 +----------------- Cargo.toml | 96 +--- README.md | 158 +----- axum/CHANGELOG.md | 480 +++++++++++++++++ axum/Cargo.toml | 92 ++++ LICENSE => axum/LICENSE | 0 axum/README.md | 159 ++++++ {src => axum/src}/add_extension.rs | 0 {src => axum/src}/body.rs | 0 {src => axum/src}/body/stream_body.rs | 0 {src => axum/src}/clone_box_service.rs | 0 {src => axum/src}/docs/error_handling.md | 0 {src => axum/src}/docs/extract.md | 0 {src => axum/src}/docs/handlers_intro.md | 0 {src => axum/src}/docs/middleware.md | 0 {src => axum/src}/docs/response.md | 0 {src => axum/src}/docs/routing/fallback.md | 0 .../into_make_service_with_connect_info.md | 0 {src => axum/src}/docs/routing/layer.md | 0 {src => axum/src}/docs/routing/merge.md | 0 {src => axum/src}/docs/routing/nest.md | 0 {src => axum/src}/docs/routing/route.md | 0 {src => axum/src}/error.rs | 0 {src => axum/src}/error_handling/mod.rs | 0 {src => axum/src}/extract/connect_info.rs | 0 .../src}/extract/content_length_limit.rs | 0 {src => axum/src}/extract/extension.rs | 0 .../src}/extract/extractor_middleware.rs | 0 {src => axum/src}/extract/form.rs | 0 {src => axum/src}/extract/matched_path.rs | 0 {src => axum/src}/extract/mod.rs | 0 {src => axum/src}/extract/multipart.rs | 0 {src => axum/src}/extract/path/de.rs | 0 {src => axum/src}/extract/path/mod.rs | 0 {src => axum/src}/extract/query.rs | 0 {src => axum/src}/extract/raw_query.rs | 0 {src => axum/src}/extract/rejection.rs | 0 {src => axum/src}/extract/request_parts.rs | 0 {src => axum/src}/extract/tuple.rs | 0 {src => axum/src}/extract/typed_header.rs | 0 {src => axum/src}/extract/ws.rs | 0 {src => axum/src}/handler/future.rs | 0 {src => axum/src}/handler/into_service.rs | 0 {src => axum/src}/handler/mod.rs | 0 {src => axum/src}/json.rs | 0 {src => axum/src}/lib.rs | 0 {src => axum/src}/macros.rs | 0 {src => axum/src}/response/headers.rs | 0 {src => axum/src}/response/mod.rs | 0 {src => axum/src}/response/redirect.rs | 0 {src => axum/src}/response/sse.rs | 0 {src => axum/src}/routing/future.rs | 0 .../src}/routing/handler_method_routing.rs | 0 .../src}/routing/into_make_service.rs | 0 {src => axum/src}/routing/method_filter.rs | 0 .../src}/routing/method_not_allowed.rs | 0 {src => axum/src}/routing/mod.rs | 0 {src => axum/src}/routing/not_found.rs | 0 {src => axum/src}/routing/route.rs | 0 .../src}/routing/service_method_routing.rs | 0 {src => axum/src}/routing/strip_prefix.rs | 0 {src => axum/src}/routing/tests/fallback.rs | 0 .../src}/routing/tests/get_to_head.rs | 0 .../src}/routing/tests/handle_error.rs | 0 {src => axum/src}/routing/tests/merge.rs | 0 {src => axum/src}/routing/tests/mod.rs | 0 {src => axum/src}/routing/tests/nest.rs | 0 {src => axum/src}/test_helpers.rs | 0 {src => axum/src}/util.rs | 0 examples/async-graphql/Cargo.toml | 2 +- examples/chat/Cargo.toml | 2 +- examples/customize-extractor-error/Cargo.toml | 2 +- .../Cargo.toml | 2 +- examples/form/Cargo.toml | 2 +- examples/global-404-handler/Cargo.toml | 2 +- examples/graceful_shutdown/Cargo.toml | 2 +- examples/hello-world/Cargo.toml | 2 +- examples/http-proxy/Cargo.toml | 2 +- examples/jwt/Cargo.toml | 2 +- examples/key-value-store/Cargo.toml | 2 +- examples/low-level-rustls/Cargo.toml | 2 +- examples/multipart-form/Cargo.toml | 2 +- examples/oauth/Cargo.toml | 2 +- examples/print-request-response/Cargo.toml | 2 +- .../Cargo.toml | 2 +- examples/readme/Cargo.toml | 2 +- examples/reverse-proxy/Cargo.toml | 2 +- examples/sessions/Cargo.toml | 2 +- examples/sse/Cargo.toml | 2 +- examples/static-file-server/Cargo.toml | 2 +- examples/templates/Cargo.toml | 2 +- examples/testing/Cargo.toml | 2 +- examples/tls-rustls/Cargo.toml | 2 +- examples/todos/Cargo.toml | 2 +- examples/tokio-postgres/Cargo.toml | 2 +- examples/tracing-aka-logging/Cargo.toml | 2 +- examples/unix-domain-socket/Cargo.toml | 2 +- examples/validator/Cargo.toml | 2 +- examples/versioning/Cargo.toml | 2 +- examples/websockets/Cargo.toml | 2 +- 101 files changed, 778 insertions(+), 763 deletions(-) mode change 100644 => 120000 README.md create mode 100644 axum/CHANGELOG.md create mode 100644 axum/Cargo.toml rename LICENSE => axum/LICENSE (100%) create mode 100644 axum/README.md rename {src => axum/src}/add_extension.rs (100%) rename {src => axum/src}/body.rs (100%) rename {src => axum/src}/body/stream_body.rs (100%) rename {src => axum/src}/clone_box_service.rs (100%) rename {src => axum/src}/docs/error_handling.md (100%) rename {src => axum/src}/docs/extract.md (100%) rename {src => axum/src}/docs/handlers_intro.md (100%) rename {src => axum/src}/docs/middleware.md (100%) rename {src => axum/src}/docs/response.md (100%) rename {src => axum/src}/docs/routing/fallback.md (100%) rename {src => axum/src}/docs/routing/into_make_service_with_connect_info.md (100%) rename {src => axum/src}/docs/routing/layer.md (100%) rename {src => axum/src}/docs/routing/merge.md (100%) rename {src => axum/src}/docs/routing/nest.md (100%) rename {src => axum/src}/docs/routing/route.md (100%) rename {src => axum/src}/error.rs (100%) rename {src => axum/src}/error_handling/mod.rs (100%) rename {src => axum/src}/extract/connect_info.rs (100%) rename {src => axum/src}/extract/content_length_limit.rs (100%) rename {src => axum/src}/extract/extension.rs (100%) rename {src => axum/src}/extract/extractor_middleware.rs (100%) rename {src => axum/src}/extract/form.rs (100%) rename {src => axum/src}/extract/matched_path.rs (100%) rename {src => axum/src}/extract/mod.rs (100%) rename {src => axum/src}/extract/multipart.rs (100%) rename {src => axum/src}/extract/path/de.rs (100%) rename {src => axum/src}/extract/path/mod.rs (100%) rename {src => axum/src}/extract/query.rs (100%) rename {src => axum/src}/extract/raw_query.rs (100%) rename {src => axum/src}/extract/rejection.rs (100%) rename {src => axum/src}/extract/request_parts.rs (100%) rename {src => axum/src}/extract/tuple.rs (100%) rename {src => axum/src}/extract/typed_header.rs (100%) rename {src => axum/src}/extract/ws.rs (100%) rename {src => axum/src}/handler/future.rs (100%) rename {src => axum/src}/handler/into_service.rs (100%) rename {src => axum/src}/handler/mod.rs (100%) rename {src => axum/src}/json.rs (100%) rename {src => axum/src}/lib.rs (100%) rename {src => axum/src}/macros.rs (100%) rename {src => axum/src}/response/headers.rs (100%) rename {src => axum/src}/response/mod.rs (100%) rename {src => axum/src}/response/redirect.rs (100%) rename {src => axum/src}/response/sse.rs (100%) rename {src => axum/src}/routing/future.rs (100%) rename {src => axum/src}/routing/handler_method_routing.rs (100%) rename {src => axum/src}/routing/into_make_service.rs (100%) rename {src => axum/src}/routing/method_filter.rs (100%) rename {src => axum/src}/routing/method_not_allowed.rs (100%) rename {src => axum/src}/routing/mod.rs (100%) rename {src => axum/src}/routing/not_found.rs (100%) rename {src => axum/src}/routing/route.rs (100%) rename {src => axum/src}/routing/service_method_routing.rs (100%) rename {src => axum/src}/routing/strip_prefix.rs (100%) rename {src => axum/src}/routing/tests/fallback.rs (100%) rename {src => axum/src}/routing/tests/get_to_head.rs (100%) rename {src => axum/src}/routing/tests/handle_error.rs (100%) rename {src => axum/src}/routing/tests/merge.rs (100%) rename {src => axum/src}/routing/tests/mod.rs (100%) rename {src => axum/src}/routing/tests/nest.rs (100%) rename {src => axum/src}/test_helpers.rs (100%) rename {src => axum/src}/util.rs (100%) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 512af468..6c454a04 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -125,6 +125,15 @@ jobs: deny-check: name: cargo-deny check runs-on: ubuntu-latest + continue-on-error: ${{ matrix.checks == 'advisories' }} + strategy: + matrix: + checks: + - advisories + - bans licenses sources steps: - - uses: actions/checkout@v1 - - uses: EmbarkStudios/cargo-deny-action@v1 + - uses: actions/checkout@v2 + - uses: EmbarkStudios/cargo-deny-action@v1 + with: + command: check ${{ matrix.checks }} + arguments: --all-features --manifest-path axum/Cargo.toml diff --git a/CHANGELOG.md b/CHANGELOG.md index b94c87fe..12ca64c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,480 +1 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -# Unreleased - -- None - -# 0.3.0 (02. November, 2021) - -- Overall: - - **fixed:** All known compile time issues are resolved, including those with - `boxed` and those introduced by Rust 1.56 ([#404]) - - **breaking:** The router's type is now always `Router` regardless of how many routes or - middleware are applied ([#404]) - - This means router types are all always nameable: - - ```rust - fn my_routes() -> Router { - Router::new().route( - "/users", - post(|| async { "Hello, World!" }), - ) - } - ``` - - **breaking:** Added feature flags for HTTP1 and JSON. This enables removing a - few dependencies if your app only uses HTTP2 or doesn't use JSON. This is only a - breaking change if you depend on axum with `default_features = false`. ([#286]) - - **breaking:** `Route::boxed` and `BoxRoute` have been removed as they're no longer - necessary ([#404]) - - **breaking:** `Nested`, `Or` types are now private. They no longer had to be - public because `Router` is internally boxed ([#404]) - - **breaking:** Remove `routing::Layered` as it didn't actually do anything and - thus wasn't necessary - - **breaking:** Vendor `AddExtensionLayer` and `AddExtension` to reduce public - dependencies - - **breaking:** `body::BoxBody` is now a type alias for - `http_body::combinators::UnsyncBoxBody` and thus is no longer `Sync`. This - is because bodies are streams and requiring streams to be `Sync` is - unnecessary. - - **added:** Implement `IntoResponse` for `http_body::combinators::UnsyncBoxBody`. - - **added:** Add `Handler::into_make_service` for serving a handler without a - `Router`. - - **added:** Add `Handler::into_make_service_with_connect_info` for serving a - handler without a `Router`, and storing info about the incoming connection. - - **breaking:** axum's minimum supported rust version is now 1.54 -- Routing: - - Big internal refactoring of routing leading to several improvements ([#363]) - - **added:** Wildcard routes like `.route("/api/users/*rest", service)` are now supported. - - **fixed:** The order routes are added in no longer matters. - - **fixed:** Adding a conflicting route will now cause a panic instead of silently making - a route unreachable. - - **fixed:** Route matching is faster as number of routes increases. - - **breaking:** Handlers for multiple HTTP methods must be added in the same - `Router::route` call. So `.route("/", get(get_handler).post(post_handler))` and - _not_ `.route("/", get(get_handler)).route("/", post(post_handler))`. - - **fixed:** Correctly handle trailing slashes in routes: - - If a route with a trailing slash exists and a request without a trailing - slash is received, axum will send a 301 redirection to the route with the - trailing slash. - - Or vice versa if a route without a trailing slash exists and a request - with a trailing slash is received. - - This can be overridden by explicitly defining two routes: One with and one - without a trailing slash. - - **breaking:** Method routing for handlers has been moved from `axum::handler` - to `axum::routing`. So `axum::handler::get` now lives at `axum::routing::get` - ([#405]) - - **breaking:** Method routing for services has been moved from `axum::service` - to `axum::routing::service_method_routing`. So `axum::service::get` now lives at - `axum::routing::service_method_routing::get`, etc. ([#405]) - - **breaking:** `Router::or` renamed to `Router::merge` and will now panic on - overlapping routes. It now only accepts `Router`s and not general `Service`s. - Use `Router::fallback` for adding fallback routes ([#408]) - - **added:** `Router::fallback` for adding handlers for request that didn't - match any routes. `Router::fallback` must be use instead of `nest("/", _)` ([#408]) - - **breaking:** `EmptyRouter` has been renamed to `MethodNotAllowed` as it's only - used in method routers and not in path routers (`Router`) - - **breaking:** Remove support for routing based on the `CONNECT` method. An - example of combining axum with and HTTP proxy can be found [here][proxy] ([#428]) -- Extractors: - - **fixed:** Expand accepted content types for JSON requests ([#378]) - - **fixed:** Support deserializing `i128` and `u128` in `extract::Path` - - **breaking:** Automatically do percent decoding in `extract::Path` - ([#272]) - - **breaking:** Change `Connected::connect_info` to return `Self` and remove - the associated type `ConnectInfo` ([#396]) - - **added:** Add `extract::MatchedPath` for accessing path in router that - matched the request ([#412]) -- Error handling: - - **breaking:** Simplify error handling model ([#402]): - - All services part of the router are now required to be infallible. - - Error handling utilities have been moved to an `error_handling` module. - - `Router::check_infallible` has been removed since routers are always - infallible with the error handling changes. - - Error handling closures must now handle all errors and thus always return - something that implements `IntoResponse`. - - With these changes handling errors from fallible middleware is done like so: - - ```rust,no_run - use axum::{ - routing::get, - http::StatusCode, - error_handling::HandleErrorLayer, - response::IntoResponse, - Router, BoxError, - }; - use tower::ServiceBuilder; - use std::time::Duration; - - let middleware_stack = ServiceBuilder::new() - // Handle errors from middleware - // - // This middleware most be added above any fallible - // ones if you're using `ServiceBuilder`, due to how ordering works - .layer(HandleErrorLayer::new(handle_error)) - // Return an error after 30 seconds - .timeout(Duration::from_secs(30)); - - let app = Router::new() - .route("/", get(|| async { /* ... */ })) - .layer(middleware_stack); - - fn handle_error(_error: BoxError) -> impl IntoResponse { - StatusCode::REQUEST_TIMEOUT - } - ``` - - And handling errors from fallible leaf services is done like so: - - ```rust - use axum::{ - Router, service, - body::Body, - routing::service_method_routing::get, - response::IntoResponse, - http::{Request, Response}, - error_handling::HandleErrorExt, // for `.handle_error` - }; - use std::{io, convert::Infallible}; - use tower::service_fn; - - let app = Router::new() - .route( - "/", - get(service_fn(|_req: Request| async { - let contents = tokio::fs::read_to_string("some_file").await?; - Ok::<_, io::Error>(Response::new(Body::from(contents))) - })) - .handle_error(handle_io_error), - ); - - fn handle_io_error(error: io::Error) -> impl IntoResponse { - // ... - } - ``` -- Misc: - - `InvalidWebsocketVersionHeader` has been renamed to `InvalidWebSocketVersionHeader` ([#416]) - - `WebsocketKeyHeaderMissing` has been renamed to `WebSocketKeyHeaderMissing` ([#416]) - -[#339]: https://github.com/tokio-rs/axum/pull/339 -[#286]: https://github.com/tokio-rs/axum/pull/286 -[#272]: https://github.com/tokio-rs/axum/pull/272 -[#378]: https://github.com/tokio-rs/axum/pull/378 -[#363]: https://github.com/tokio-rs/axum/pull/363 -[#396]: https://github.com/tokio-rs/axum/pull/396 -[#402]: https://github.com/tokio-rs/axum/pull/402 -[#404]: https://github.com/tokio-rs/axum/pull/404 -[#405]: https://github.com/tokio-rs/axum/pull/405 -[#408]: https://github.com/tokio-rs/axum/pull/408 -[#412]: https://github.com/tokio-rs/axum/pull/412 -[#416]: https://github.com/tokio-rs/axum/pull/416 -[#428]: https://github.com/tokio-rs/axum/pull/428 -[proxy]: https://github.com/tokio-rs/axum/blob/main/examples/http-proxy/src/main.rs - -# 0.2.8 (07. October, 2021) - -- Document debugging handler type errors with "axum-debug" ([#372]) - -[#372]: https://github.com/tokio-rs/axum/pull/372 - -# 0.2.7 (06. October, 2021) - -- Bump minimum version of async-trait ([#370]) - -[#370]: https://github.com/tokio-rs/axum/pull/370 - -# 0.2.6 (02. October, 2021) - -- Clarify that `handler::any` and `service::any` only accepts standard HTTP - methods ([#337]) -- Document how to customize error responses from extractors ([#359]) - -[#337]: https://github.com/tokio-rs/axum/pull/337 -[#359]: https://github.com/tokio-rs/axum/pull/359 - -# 0.2.5 (18. September, 2021) - -- Add accessors for `TypedHeaderRejection` fields ([#317]) -- Improve docs for extractors ([#327]) - -[#317]: https://github.com/tokio-rs/axum/pull/317 -[#327]: https://github.com/tokio-rs/axum/pull/327 - -# 0.2.4 (10. September, 2021) - -- Document using `StreamExt::split` with `WebSocket` ([#291]) -- Document adding middleware to multiple groups of routes ([#293]) - -[#291]: https://github.com/tokio-rs/axum/pull/291 -[#293]: https://github.com/tokio-rs/axum/pull/293 - -# 0.2.3 (26. August, 2021) - -- **fixed:** Fix accidental breaking change introduced by internal refactor. - `BoxRoute` used to be `Sync` but was accidental made `!Sync` ([#273](https://github.com/tokio-rs/axum/pull/273)) - -# 0.2.2 (26. August, 2021) - -- **fixed:** Fix URI captures matching empty segments. This means requests with - URI `/` will no longer be matched by `/:key` ([#264](https://github.com/tokio-rs/axum/pull/264)) -- **fixed:** Remove needless trait bounds from `Router::boxed` ([#269](https://github.com/tokio-rs/axum/pull/269)) - -# 0.2.1 (24. August, 2021) - -- **added:** Add `Redirect::to` constructor ([#255](https://github.com/tokio-rs/axum/pull/255)) -- **added:** Document how to implement `IntoResponse` for custom error type ([#258](https://github.com/tokio-rs/axum/pull/258)) - -# 0.2.0 (23. August, 2021) - -- Overall: - - **fixed:** Overall compile time improvements. If you're having issues with compile time - please file an issue! ([#184](https://github.com/tokio-rs/axum/pull/184)) ([#198](https://github.com/tokio-rs/axum/pull/198)) ([#220](https://github.com/tokio-rs/axum/pull/220)) - - **changed:** Remove `prelude`. Explicit imports are now required ([#195](https://github.com/tokio-rs/axum/pull/195)) -- Routing: - - **added:** Add dedicated `Router` to replace the `RoutingDsl` trait ([#214](https://github.com/tokio-rs/axum/pull/214)) - - **added:** Add `Router::or` for combining routes ([#108](https://github.com/tokio-rs/axum/pull/108)) - - **fixed:** Support matching different HTTP methods for the same route that aren't defined - together. So `Router::new().route("/", get(...)).route("/", post(...))` now - accepts both `GET` and `POST`. Previously only `POST` would be accepted ([#224](https://github.com/tokio-rs/axum/pull/224)) - - **fixed:** `get` routes will now also be called for `HEAD` requests but will always have - the response body removed ([#129](https://github.com/tokio-rs/axum/pull/129)) - - **changed:** Replace `axum::route(...)` with `axum::Router::new().route(...)`. This means - there is now only one way to create a new router. Same goes for - `axum::routing::nest`. ([#215](https://github.com/tokio-rs/axum/pull/215)) - - **changed:** Implement `routing::MethodFilter` via [`bitflags`](https://crates.io/crates/bitflags) ([#158](https://github.com/tokio-rs/axum/pull/158)) - - **changed:** Move `handle_error` from `ServiceExt` to `service::OnMethod` ([#160](https://github.com/tokio-rs/axum/pull/160)) - - With these changes this app using 0.1: - - ```rust - use axum::{extract::Extension, prelude::*, routing::BoxRoute, AddExtensionLayer}; - - let app = route("/", get(|| async { "hi" })) - .nest("/api", api_routes()) - .layer(AddExtensionLayer::new(state)); - - fn api_routes() -> BoxRoute { - route( - "/users", - post(|Extension(state): Extension| async { "hi from nested" }), - ) - .boxed() - } - ``` - - Becomes this in 0.2: - - ```rust - use axum::{ - extract::Extension, - handler::{get, post}, - routing::BoxRoute, - Router, - }; - - let app = Router::new() - .route("/", get(|| async { "hi" })) - .nest("/api", api_routes()); - - fn api_routes() -> Router { - Router::new() - .route( - "/users", - post(|Extension(state): Extension| async { "hi from nested" }), - ) - .boxed() - } - ``` -- Extractors: - - **added:** Make `FromRequest` default to being generic over `body::Body` ([#146](https://github.com/tokio-rs/axum/pull/146)) - - **added:** Implement `std::error::Error` for all rejections ([#153](https://github.com/tokio-rs/axum/pull/153)) - - **added:** Add `OriginalUri` for extracting original request URI in nested services ([#197](https://github.com/tokio-rs/axum/pull/197)) - - **added:** Implement `FromRequest` for `http::Extensions` ([#169](https://github.com/tokio-rs/axum/pull/169)) - - **added:** Make `RequestParts::{new, try_into_request}` public so extractors can be used outside axum ([#194](https://github.com/tokio-rs/axum/pull/194)) - - **added:** Implement `FromRequest` for `axum::body::Body` ([#241](https://github.com/tokio-rs/axum/pull/241)) - - **changed:** Removed `extract::UrlParams` and `extract::UrlParamsMap`. Use `extract::Path` instead ([#154](https://github.com/tokio-rs/axum/pull/154)) - - **changed:** `extractor_middleware` now requires `RequestBody: Default` ([#167](https://github.com/tokio-rs/axum/pull/167)) - - **changed:** Convert `RequestAlreadyExtracted` to an enum with each possible error variant ([#167](https://github.com/tokio-rs/axum/pull/167)) - - **changed:** `extract::BodyStream` is no longer generic over the request body ([#234](https://github.com/tokio-rs/axum/pull/234)) - - **changed:** `extract::Body` has been renamed to `extract::RawBody` to avoid conflicting with `body::Body` ([#233](https://github.com/tokio-rs/axum/pull/233)) - - **changed:** `RequestParts` changes ([#153](https://github.com/tokio-rs/axum/pull/153)) - - `method` new returns an `&http::Method` - - `method_mut` new returns an `&mut http::Method` - - `take_method` has been removed - - `uri` new returns an `&http::Uri` - - `uri_mut` new returns an `&mut http::Uri` - - `take_uri` has been removed - - **changed:** Remove several rejection types that were no longer used ([#153](https://github.com/tokio-rs/axum/pull/153)) ([#154](https://github.com/tokio-rs/axum/pull/154)) -- Responses: - - **added:** Add `Headers` for easily customizing headers on a response ([#193](https://github.com/tokio-rs/axum/pull/193)) - - **added:** Add `Redirect` response ([#192](https://github.com/tokio-rs/axum/pull/192)) - - **added:** Add `body::StreamBody` for easily responding with a stream of byte chunks ([#237](https://github.com/tokio-rs/axum/pull/237)) - - **changed:** Add associated `Body` and `BodyError` types to `IntoResponse`. This is - required for returning responses with bodies other than `hyper::Body` from - handlers. See the docs for advice on how to implement `IntoResponse` ([#86](https://github.com/tokio-rs/axum/pull/86)) - - **changed:** `tower::util::Either` no longer implements `IntoResponse` ([#229](https://github.com/tokio-rs/axum/pull/229)) - - This `IntoResponse` from 0.1: - ```rust - use axum::{http::Response, prelude::*, response::IntoResponse}; - - struct MyResponse; - - impl IntoResponse for MyResponse { - fn into_response(self) -> Response { - Response::new(Body::empty()) - } - } - ``` - - Becomes this in 0.2: - ```rust - use axum::{body::Body, http::Response, response::IntoResponse}; - - struct MyResponse; - - impl IntoResponse for MyResponse { - type Body = Body; - type BodyError = ::Error; - - fn into_response(self) -> Response { - Response::new(Body::empty()) - } - } - ``` -- SSE: - - **added:** Add `response::sse::Sse`. This implements SSE using a response rather than a service ([#98](https://github.com/tokio-rs/axum/pull/98)) - - **changed:** Remove `axum::sse`. Its been replaced by `axum::response::sse` ([#98](https://github.com/tokio-rs/axum/pull/98)) - - Handler using SSE in 0.1: - ```rust - use axum::{ - prelude::*, - sse::{sse, Event}, - }; - use std::convert::Infallible; - - let app = route( - "/", - sse(|| async { - let stream = futures::stream::iter(vec![Ok::<_, Infallible>( - Event::default().data("hi there!"), - )]); - Ok::<_, Infallible>(stream) - }), - ); - ``` - - Becomes this in 0.2: - - ```rust - use axum::{ - handler::get, - response::sse::{Event, Sse}, - Router, - }; - use std::convert::Infallible; - - let app = Router::new().route( - "/", - get(|| async { - let stream = futures::stream::iter(vec![Ok::<_, Infallible>( - Event::default().data("hi there!"), - )]); - Sse::new(stream) - }), - ); - ``` -- WebSockets: - - **changed:** Change WebSocket API to use an extractor plus a response ([#121](https://github.com/tokio-rs/axum/pull/121)) - - **changed:** Make WebSocket `Message` an enum ([#116](https://github.com/tokio-rs/axum/pull/116)) - - **changed:** `WebSocket` now uses `Error` as its error type ([#150](https://github.com/tokio-rs/axum/pull/150)) - - Handler using WebSockets in 0.1: - - ```rust - use axum::{ - prelude::*, - ws::{ws, WebSocket}, - }; - - let app = route( - "/", - ws(|socket: WebSocket| async move { - // do stuff with socket - }), - ); - ``` - - Becomes this in 0.2: - - ```rust - use axum::{ - extract::ws::{WebSocket, WebSocketUpgrade}, - handler::get, - Router, - }; - - let app = Router::new().route( - "/", - get(|ws: WebSocketUpgrade| async move { - ws.on_upgrade(|socket: WebSocket| async move { - // do stuff with socket - }) - }), - ); - ``` -- Misc - - **added:** Add default feature `tower-log` which exposes `tower`'s `log` feature. ([#218](https://github.com/tokio-rs/axum/pull/218)) - - **changed:** Replace `body::BoxStdError` with `axum::Error`, which supports downcasting ([#150](https://github.com/tokio-rs/axum/pull/150)) - - **changed:** `EmptyRouter` now requires the response body to implement `Send + Sync + 'static'` ([#108](https://github.com/tokio-rs/axum/pull/108)) - - **changed:** `Router::check_infallible` now returns a `CheckInfallible` service. This - is to improve compile times ([#198](https://github.com/tokio-rs/axum/pull/198)) - - **changed:** `Router::into_make_service` now returns `routing::IntoMakeService` rather than - `tower::make::Shared` ([#229](https://github.com/tokio-rs/axum/pull/229)) - - **changed:** All usage of `tower::BoxError` has been replaced with `axum::BoxError` ([#229](https://github.com/tokio-rs/axum/pull/229)) - - **changed:** Several response future types have been moved into dedicated - `future` modules ([#133](https://github.com/tokio-rs/axum/pull/133)) - - **changed:** `EmptyRouter`, `ExtractorMiddleware`, `ExtractorMiddlewareLayer`, - and `QueryStringMissing` no longer implement `Copy` ([#132](https://github.com/tokio-rs/axum/pull/132)) - - **changed:** `service::OnMethod`, `handler::OnMethod`, and `routing::Nested` have new response future types ([#157](https://github.com/tokio-rs/axum/pull/157)) - -# 0.1.3 (06. August, 2021) - -- Fix stripping prefix when nesting services at `/` ([#91](https://github.com/tokio-rs/axum/pull/91)) -- Add support for WebSocket protocol negotiation ([#83](https://github.com/tokio-rs/axum/pull/83)) -- Use `pin-project-lite` instead of `pin-project` ([#95](https://github.com/tokio-rs/axum/pull/95)) -- Re-export `http` crate and `hyper::Server` ([#110](https://github.com/tokio-rs/axum/pull/110)) -- Fix `Query` and `Form` extractors giving bad request error when query string is empty. ([#117](https://github.com/tokio-rs/axum/pull/117)) -- Add `Path` extractor. ([#124](https://github.com/tokio-rs/axum/pull/124)) -- Fixed the implementation of `IntoResponse` of `(HeaderMap, T)` and `(StatusCode, HeaderMap, T)` would ignore headers from `T` ([#137](https://github.com/tokio-rs/axum/pull/137)) -- Deprecate `extract::UrlParams` and `extract::UrlParamsMap`. Use `extract::Path` instead ([#138](https://github.com/tokio-rs/axum/pull/138)) - -# 0.1.2 (01. August, 2021) - -- Implement `Stream` for `WebSocket` ([#52](https://github.com/tokio-rs/axum/pull/52)) -- Implement `Sink` for `WebSocket` ([#52](https://github.com/tokio-rs/axum/pull/52)) -- Implement `Deref` most extractors ([#56](https://github.com/tokio-rs/axum/pull/56)) -- Return `405 Method Not Allowed` for unsupported method for route ([#63](https://github.com/tokio-rs/axum/pull/63)) -- Add extractor for remote connection info ([#55](https://github.com/tokio-rs/axum/pull/55)) -- Improve error message of `MissingExtension` rejections ([#72](https://github.com/tokio-rs/axum/pull/72)) -- Improve documentation for routing ([#71](https://github.com/tokio-rs/axum/pull/71)) -- Clarify required response body type when routing to `tower::Service`s ([#69](https://github.com/tokio-rs/axum/pull/69)) -- Add `axum::body::box_body` to converting an `http_body::Body` to `axum::body::BoxBody` ([#69](https://github.com/tokio-rs/axum/pull/69)) -- Add `axum::sse` for Server-Sent Events ([#75](https://github.com/tokio-rs/axum/pull/75)) -- Mention required dependencies in docs ([#77](https://github.com/tokio-rs/axum/pull/77)) -- Fix WebSockets failing on Firefox ([#76](https://github.com/tokio-rs/axum/pull/76)) - -# 0.1.1 (30. July, 2021) - -- Misc readme fixes. - -# 0.1.0 (30. July, 2021) - -- Initial release. +axum's changelog has moved and now lives [here](https://github.com/tokio-rs/axum/blob/main/axum/CHANGELOG.md). diff --git a/Cargo.toml b/Cargo.toml index d4acebe5..156fa711 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,95 +1,5 @@ -[package] -name = "axum" -version = "0.3.0" -authors = ["David Pedersen "] -categories = ["asynchronous", "network-programming", "web-programming"] -description = "Web framework that focuses on ergonomics and modularity" -edition = "2018" -homepage = "https://github.com/tokio-rs/axum" -keywords = ["http", "web", "framework"] -license = "MIT" -readme = "README.md" -repository = "https://github.com/tokio-rs/axum" - [workspace] -members = ["examples/*"] - -[features] -default = ["http1", "json", "tower-log"] -http1 = ["hyper/http1"] -http2 = ["hyper/http2"] -json = ["serde_json", "mime"] -multipart = ["multer", "mime"] -tower-log = ["tower/log"] -ws = ["tokio-tungstenite", "sha-1", "base64"] - -[dependencies] -async-trait = "0.1.43" -bitflags = "1.0" -bytes = "1.0" -futures-util = { version = "0.3", default-features = false, features = ["alloc"] } -http = "0.2" -http-body = "0.4.4" -hyper = { version = "0.14.14", features = ["server", "tcp", "stream"] } -matchit = "0.4.4" -percent-encoding = "2.1" -pin-project-lite = "0.2.7" -serde = "1.0" -serde_urlencoded = "0.7" -sync_wrapper = "0.1.1" -tokio = { version = "1", features = ["time"] } -tokio-util = "0.6" -tower = { version = "0.4.10", default-features = false, features = ["util", "buffer", "make"] } -tower-http = { version = "0.1", features = ["add-extension", "map-response-body"] } -tower-layer = "0.3" -tower-service = "0.3" - -# optional dependencies -base64 = { optional = true, version = "0.13" } -headers = { optional = true, version = "0.3" } -mime = { optional = true, version = "0.3" } -multer = { optional = true, version = "2.0.0" } -serde_json = { version = "1.0", optional = true } -sha-1 = { optional = true, version = "0.9.6" } -tokio-tungstenite = { optional = true, version = "0.15" } - -[dev-dependencies] -futures = "0.3" -reqwest = { version = "0.11", features = ["json", "stream"] } -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -tokio = { version = "1.6.1", features = ["macros", "rt", "rt-multi-thread", "net"] } -tokio-stream = "0.1" -tracing = "0.1" -uuid = { version = "0.8", features = ["serde", "v4"] } -anyhow = "1.0" - -[dev-dependencies.tower] -package = "tower" -version = "0.4.10" -features = [ - "util", - "timeout", - "limit", - "load-shed", - "steer", - "filter", -] - -[dev-dependencies.tower-http] -version = "0.1" -features = ["full"] - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = ["--cfg", "docsrs"] - -[package.metadata.playground] -features = [ - "http1", - "http2", - "json", - "multipart", - "tower", - "ws", +members = [ + "axum", + "examples/*", ] diff --git a/README.md b/README.md deleted file mode 100644 index 08e48453..00000000 --- a/README.md +++ /dev/null @@ -1,157 +0,0 @@ -# axum - -`axum` is a web application framework that focuses on ergonomics and modularity. - -[![Build status](https://github.com/tokio-rs/axum/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/tokio-rs/axum/actions/workflows/CI.yml) -[![Crates.io](https://img.shields.io/crates/v/axum)](https://crates.io/crates/axum) -[![Documentation](https://docs.rs/axum/badge.svg)](https://docs.rs/axum) - -More information about this crate can be found in the [crate documentation][docs]. - -## High level features - -- Route requests to handlers with a macro free API. -- Declaratively parse requests using extractors. -- Simple and predictable error handling model. -- Generate responses with minimal boilerplate. -- Take full advantage of the [`tower`] and [`tower-http`] ecosystem of - middleware, services, and utilities. - -In particular the last point is what sets `axum` apart from other frameworks. -`axum` doesn't have its own middleware system but instead uses -[`tower::Service`]. This means `axum` gets timeouts, tracing, compression, -authorization, and more, for free. It also enables you to share middleware with -applications written using [`hyper`] or [`tonic`]. - -## Usage example - -```rust -use axum::{ - routing::{get, post}, - http::StatusCode, - response::IntoResponse, - Json, Router, -}; -use serde::{Deserialize, Serialize}; -use std::net::SocketAddr; - -#[tokio::main] -async fn main() { - // initialize tracing - tracing_subscriber::fmt::init(); - - // build our application with a route - let app = Router::new() - // `GET /` goes to `root` - .route("/", get(root)) - // `POST /users` goes to `create_user` - .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(); -} - -// basic handler that responds with a static string -async fn root() -> &'static str { - "Hello, World!" -} - -async fn create_user( - // this argument tells axum to parse the request body - // as JSON into a `CreateUser` type - Json(payload): Json, -) -> impl IntoResponse { - // insert your application logic here - let user = User { - id: 1337, - username: payload.username, - }; - - // this will be converted into a JSON response - // with a status code of `201 Created` - (StatusCode::CREATED, Json(user)) -} - -// the input to our `create_user` handler -#[derive(Deserialize)] -struct CreateUser { - username: String, -} - -// the output to our `create_user` handler -#[derive(Serialize)] -struct User { - id: u64, - username: String, -} -``` - -You can find this [example][readme-example] as well as other example projects in -the [example directory][examples]. - -See the [crate documentation][docs] for way more examples. - -## Performance - -`axum` is a relatively thin layer on top of [`hyper`] and adds very little -overhead. So `axum`'s performance is comparable to [`hyper`]. You can find a -benchmark [here](https://github.com/programatik29/rust-web-benchmarks). - -## Safety - -This crate uses `#![forbid(unsafe_code)]` to ensure everything is implemented in -100% safe Rust. - -## Minimum supported Rust version - -axum's MSRV is 1.54. - -## Examples - -The [examples] folder contains various examples of how to use `axum`. The -[docs] also have lots of examples - -## Getting Help - -In the `axum`'s repo we also have a [number of examples][examples] showing how -to put everything together. You're also welcome to ask in the [Discord -channel][chat] or open an [issue] with your question. - -## Community projects - -See [here](ECOSYSTEM.md) for a list of community maintained crates and projects -built with axum. - -## Contributing - -:balloon: Thanks for your help improving the project! We are so happy to have -you! We have a [contributing guide][guide] to help you get involved in the -`axum` project. - -## License - -This project is licensed under the [MIT license](LICENSE). - -### Contribution - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in `axum` by you, shall be licensed as MIT, without any -additional terms or conditions. - -[readme-example]: https://github.com/tokio-rs/axum/tree/main/examples/readme -[examples]: https://github.com/tokio-rs/axum/tree/main/examples -[docs]: https://docs.rs/axum -[`tower`]: https://crates.io/crates/tower -[`hyper`]: https://crates.io/crates/hyper -[`tower-http`]: https://crates.io/crates/tower-http -[`tonic`]: https://crates.io/crates/tonic -[guide]: CONTRIBUTING.md -[chat]: https://discord.gg/tokio -[issue]: https://github.com/tokio-rs/axum/issues/new -[`tower::Service`]: https://docs.rs/tower/latest/tower/trait.Service.html diff --git a/README.md b/README.md new file mode 120000 index 00000000..7deece5a --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +axum/README.md \ No newline at end of file diff --git a/axum/CHANGELOG.md b/axum/CHANGELOG.md new file mode 100644 index 00000000..b94c87fe --- /dev/null +++ b/axum/CHANGELOG.md @@ -0,0 +1,480 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +# Unreleased + +- None + +# 0.3.0 (02. November, 2021) + +- Overall: + - **fixed:** All known compile time issues are resolved, including those with + `boxed` and those introduced by Rust 1.56 ([#404]) + - **breaking:** The router's type is now always `Router` regardless of how many routes or + middleware are applied ([#404]) + + This means router types are all always nameable: + + ```rust + fn my_routes() -> Router { + Router::new().route( + "/users", + post(|| async { "Hello, World!" }), + ) + } + ``` + - **breaking:** Added feature flags for HTTP1 and JSON. This enables removing a + few dependencies if your app only uses HTTP2 or doesn't use JSON. This is only a + breaking change if you depend on axum with `default_features = false`. ([#286]) + - **breaking:** `Route::boxed` and `BoxRoute` have been removed as they're no longer + necessary ([#404]) + - **breaking:** `Nested`, `Or` types are now private. They no longer had to be + public because `Router` is internally boxed ([#404]) + - **breaking:** Remove `routing::Layered` as it didn't actually do anything and + thus wasn't necessary + - **breaking:** Vendor `AddExtensionLayer` and `AddExtension` to reduce public + dependencies + - **breaking:** `body::BoxBody` is now a type alias for + `http_body::combinators::UnsyncBoxBody` and thus is no longer `Sync`. This + is because bodies are streams and requiring streams to be `Sync` is + unnecessary. + - **added:** Implement `IntoResponse` for `http_body::combinators::UnsyncBoxBody`. + - **added:** Add `Handler::into_make_service` for serving a handler without a + `Router`. + - **added:** Add `Handler::into_make_service_with_connect_info` for serving a + handler without a `Router`, and storing info about the incoming connection. + - **breaking:** axum's minimum supported rust version is now 1.54 +- Routing: + - Big internal refactoring of routing leading to several improvements ([#363]) + - **added:** Wildcard routes like `.route("/api/users/*rest", service)` are now supported. + - **fixed:** The order routes are added in no longer matters. + - **fixed:** Adding a conflicting route will now cause a panic instead of silently making + a route unreachable. + - **fixed:** Route matching is faster as number of routes increases. + - **breaking:** Handlers for multiple HTTP methods must be added in the same + `Router::route` call. So `.route("/", get(get_handler).post(post_handler))` and + _not_ `.route("/", get(get_handler)).route("/", post(post_handler))`. + - **fixed:** Correctly handle trailing slashes in routes: + - If a route with a trailing slash exists and a request without a trailing + slash is received, axum will send a 301 redirection to the route with the + trailing slash. + - Or vice versa if a route without a trailing slash exists and a request + with a trailing slash is received. + - This can be overridden by explicitly defining two routes: One with and one + without a trailing slash. + - **breaking:** Method routing for handlers has been moved from `axum::handler` + to `axum::routing`. So `axum::handler::get` now lives at `axum::routing::get` + ([#405]) + - **breaking:** Method routing for services has been moved from `axum::service` + to `axum::routing::service_method_routing`. So `axum::service::get` now lives at + `axum::routing::service_method_routing::get`, etc. ([#405]) + - **breaking:** `Router::or` renamed to `Router::merge` and will now panic on + overlapping routes. It now only accepts `Router`s and not general `Service`s. + Use `Router::fallback` for adding fallback routes ([#408]) + - **added:** `Router::fallback` for adding handlers for request that didn't + match any routes. `Router::fallback` must be use instead of `nest("/", _)` ([#408]) + - **breaking:** `EmptyRouter` has been renamed to `MethodNotAllowed` as it's only + used in method routers and not in path routers (`Router`) + - **breaking:** Remove support for routing based on the `CONNECT` method. An + example of combining axum with and HTTP proxy can be found [here][proxy] ([#428]) +- Extractors: + - **fixed:** Expand accepted content types for JSON requests ([#378]) + - **fixed:** Support deserializing `i128` and `u128` in `extract::Path` + - **breaking:** Automatically do percent decoding in `extract::Path` + ([#272]) + - **breaking:** Change `Connected::connect_info` to return `Self` and remove + the associated type `ConnectInfo` ([#396]) + - **added:** Add `extract::MatchedPath` for accessing path in router that + matched the request ([#412]) +- Error handling: + - **breaking:** Simplify error handling model ([#402]): + - All services part of the router are now required to be infallible. + - Error handling utilities have been moved to an `error_handling` module. + - `Router::check_infallible` has been removed since routers are always + infallible with the error handling changes. + - Error handling closures must now handle all errors and thus always return + something that implements `IntoResponse`. + + With these changes handling errors from fallible middleware is done like so: + + ```rust,no_run + use axum::{ + routing::get, + http::StatusCode, + error_handling::HandleErrorLayer, + response::IntoResponse, + Router, BoxError, + }; + use tower::ServiceBuilder; + use std::time::Duration; + + let middleware_stack = ServiceBuilder::new() + // Handle errors from middleware + // + // This middleware most be added above any fallible + // ones if you're using `ServiceBuilder`, due to how ordering works + .layer(HandleErrorLayer::new(handle_error)) + // Return an error after 30 seconds + .timeout(Duration::from_secs(30)); + + let app = Router::new() + .route("/", get(|| async { /* ... */ })) + .layer(middleware_stack); + + fn handle_error(_error: BoxError) -> impl IntoResponse { + StatusCode::REQUEST_TIMEOUT + } + ``` + + And handling errors from fallible leaf services is done like so: + + ```rust + use axum::{ + Router, service, + body::Body, + routing::service_method_routing::get, + response::IntoResponse, + http::{Request, Response}, + error_handling::HandleErrorExt, // for `.handle_error` + }; + use std::{io, convert::Infallible}; + use tower::service_fn; + + let app = Router::new() + .route( + "/", + get(service_fn(|_req: Request| async { + let contents = tokio::fs::read_to_string("some_file").await?; + Ok::<_, io::Error>(Response::new(Body::from(contents))) + })) + .handle_error(handle_io_error), + ); + + fn handle_io_error(error: io::Error) -> impl IntoResponse { + // ... + } + ``` +- Misc: + - `InvalidWebsocketVersionHeader` has been renamed to `InvalidWebSocketVersionHeader` ([#416]) + - `WebsocketKeyHeaderMissing` has been renamed to `WebSocketKeyHeaderMissing` ([#416]) + +[#339]: https://github.com/tokio-rs/axum/pull/339 +[#286]: https://github.com/tokio-rs/axum/pull/286 +[#272]: https://github.com/tokio-rs/axum/pull/272 +[#378]: https://github.com/tokio-rs/axum/pull/378 +[#363]: https://github.com/tokio-rs/axum/pull/363 +[#396]: https://github.com/tokio-rs/axum/pull/396 +[#402]: https://github.com/tokio-rs/axum/pull/402 +[#404]: https://github.com/tokio-rs/axum/pull/404 +[#405]: https://github.com/tokio-rs/axum/pull/405 +[#408]: https://github.com/tokio-rs/axum/pull/408 +[#412]: https://github.com/tokio-rs/axum/pull/412 +[#416]: https://github.com/tokio-rs/axum/pull/416 +[#428]: https://github.com/tokio-rs/axum/pull/428 +[proxy]: https://github.com/tokio-rs/axum/blob/main/examples/http-proxy/src/main.rs + +# 0.2.8 (07. October, 2021) + +- Document debugging handler type errors with "axum-debug" ([#372]) + +[#372]: https://github.com/tokio-rs/axum/pull/372 + +# 0.2.7 (06. October, 2021) + +- Bump minimum version of async-trait ([#370]) + +[#370]: https://github.com/tokio-rs/axum/pull/370 + +# 0.2.6 (02. October, 2021) + +- Clarify that `handler::any` and `service::any` only accepts standard HTTP + methods ([#337]) +- Document how to customize error responses from extractors ([#359]) + +[#337]: https://github.com/tokio-rs/axum/pull/337 +[#359]: https://github.com/tokio-rs/axum/pull/359 + +# 0.2.5 (18. September, 2021) + +- Add accessors for `TypedHeaderRejection` fields ([#317]) +- Improve docs for extractors ([#327]) + +[#317]: https://github.com/tokio-rs/axum/pull/317 +[#327]: https://github.com/tokio-rs/axum/pull/327 + +# 0.2.4 (10. September, 2021) + +- Document using `StreamExt::split` with `WebSocket` ([#291]) +- Document adding middleware to multiple groups of routes ([#293]) + +[#291]: https://github.com/tokio-rs/axum/pull/291 +[#293]: https://github.com/tokio-rs/axum/pull/293 + +# 0.2.3 (26. August, 2021) + +- **fixed:** Fix accidental breaking change introduced by internal refactor. + `BoxRoute` used to be `Sync` but was accidental made `!Sync` ([#273](https://github.com/tokio-rs/axum/pull/273)) + +# 0.2.2 (26. August, 2021) + +- **fixed:** Fix URI captures matching empty segments. This means requests with + URI `/` will no longer be matched by `/:key` ([#264](https://github.com/tokio-rs/axum/pull/264)) +- **fixed:** Remove needless trait bounds from `Router::boxed` ([#269](https://github.com/tokio-rs/axum/pull/269)) + +# 0.2.1 (24. August, 2021) + +- **added:** Add `Redirect::to` constructor ([#255](https://github.com/tokio-rs/axum/pull/255)) +- **added:** Document how to implement `IntoResponse` for custom error type ([#258](https://github.com/tokio-rs/axum/pull/258)) + +# 0.2.0 (23. August, 2021) + +- Overall: + - **fixed:** Overall compile time improvements. If you're having issues with compile time + please file an issue! ([#184](https://github.com/tokio-rs/axum/pull/184)) ([#198](https://github.com/tokio-rs/axum/pull/198)) ([#220](https://github.com/tokio-rs/axum/pull/220)) + - **changed:** Remove `prelude`. Explicit imports are now required ([#195](https://github.com/tokio-rs/axum/pull/195)) +- Routing: + - **added:** Add dedicated `Router` to replace the `RoutingDsl` trait ([#214](https://github.com/tokio-rs/axum/pull/214)) + - **added:** Add `Router::or` for combining routes ([#108](https://github.com/tokio-rs/axum/pull/108)) + - **fixed:** Support matching different HTTP methods for the same route that aren't defined + together. So `Router::new().route("/", get(...)).route("/", post(...))` now + accepts both `GET` and `POST`. Previously only `POST` would be accepted ([#224](https://github.com/tokio-rs/axum/pull/224)) + - **fixed:** `get` routes will now also be called for `HEAD` requests but will always have + the response body removed ([#129](https://github.com/tokio-rs/axum/pull/129)) + - **changed:** Replace `axum::route(...)` with `axum::Router::new().route(...)`. This means + there is now only one way to create a new router. Same goes for + `axum::routing::nest`. ([#215](https://github.com/tokio-rs/axum/pull/215)) + - **changed:** Implement `routing::MethodFilter` via [`bitflags`](https://crates.io/crates/bitflags) ([#158](https://github.com/tokio-rs/axum/pull/158)) + - **changed:** Move `handle_error` from `ServiceExt` to `service::OnMethod` ([#160](https://github.com/tokio-rs/axum/pull/160)) + + With these changes this app using 0.1: + + ```rust + use axum::{extract::Extension, prelude::*, routing::BoxRoute, AddExtensionLayer}; + + let app = route("/", get(|| async { "hi" })) + .nest("/api", api_routes()) + .layer(AddExtensionLayer::new(state)); + + fn api_routes() -> BoxRoute { + route( + "/users", + post(|Extension(state): Extension| async { "hi from nested" }), + ) + .boxed() + } + ``` + + Becomes this in 0.2: + + ```rust + use axum::{ + extract::Extension, + handler::{get, post}, + routing::BoxRoute, + Router, + }; + + let app = Router::new() + .route("/", get(|| async { "hi" })) + .nest("/api", api_routes()); + + fn api_routes() -> Router { + Router::new() + .route( + "/users", + post(|Extension(state): Extension| async { "hi from nested" }), + ) + .boxed() + } + ``` +- Extractors: + - **added:** Make `FromRequest` default to being generic over `body::Body` ([#146](https://github.com/tokio-rs/axum/pull/146)) + - **added:** Implement `std::error::Error` for all rejections ([#153](https://github.com/tokio-rs/axum/pull/153)) + - **added:** Add `OriginalUri` for extracting original request URI in nested services ([#197](https://github.com/tokio-rs/axum/pull/197)) + - **added:** Implement `FromRequest` for `http::Extensions` ([#169](https://github.com/tokio-rs/axum/pull/169)) + - **added:** Make `RequestParts::{new, try_into_request}` public so extractors can be used outside axum ([#194](https://github.com/tokio-rs/axum/pull/194)) + - **added:** Implement `FromRequest` for `axum::body::Body` ([#241](https://github.com/tokio-rs/axum/pull/241)) + - **changed:** Removed `extract::UrlParams` and `extract::UrlParamsMap`. Use `extract::Path` instead ([#154](https://github.com/tokio-rs/axum/pull/154)) + - **changed:** `extractor_middleware` now requires `RequestBody: Default` ([#167](https://github.com/tokio-rs/axum/pull/167)) + - **changed:** Convert `RequestAlreadyExtracted` to an enum with each possible error variant ([#167](https://github.com/tokio-rs/axum/pull/167)) + - **changed:** `extract::BodyStream` is no longer generic over the request body ([#234](https://github.com/tokio-rs/axum/pull/234)) + - **changed:** `extract::Body` has been renamed to `extract::RawBody` to avoid conflicting with `body::Body` ([#233](https://github.com/tokio-rs/axum/pull/233)) + - **changed:** `RequestParts` changes ([#153](https://github.com/tokio-rs/axum/pull/153)) + - `method` new returns an `&http::Method` + - `method_mut` new returns an `&mut http::Method` + - `take_method` has been removed + - `uri` new returns an `&http::Uri` + - `uri_mut` new returns an `&mut http::Uri` + - `take_uri` has been removed + - **changed:** Remove several rejection types that were no longer used ([#153](https://github.com/tokio-rs/axum/pull/153)) ([#154](https://github.com/tokio-rs/axum/pull/154)) +- Responses: + - **added:** Add `Headers` for easily customizing headers on a response ([#193](https://github.com/tokio-rs/axum/pull/193)) + - **added:** Add `Redirect` response ([#192](https://github.com/tokio-rs/axum/pull/192)) + - **added:** Add `body::StreamBody` for easily responding with a stream of byte chunks ([#237](https://github.com/tokio-rs/axum/pull/237)) + - **changed:** Add associated `Body` and `BodyError` types to `IntoResponse`. This is + required for returning responses with bodies other than `hyper::Body` from + handlers. See the docs for advice on how to implement `IntoResponse` ([#86](https://github.com/tokio-rs/axum/pull/86)) + - **changed:** `tower::util::Either` no longer implements `IntoResponse` ([#229](https://github.com/tokio-rs/axum/pull/229)) + + This `IntoResponse` from 0.1: + ```rust + use axum::{http::Response, prelude::*, response::IntoResponse}; + + struct MyResponse; + + impl IntoResponse for MyResponse { + fn into_response(self) -> Response { + Response::new(Body::empty()) + } + } + ``` + + Becomes this in 0.2: + ```rust + use axum::{body::Body, http::Response, response::IntoResponse}; + + struct MyResponse; + + impl IntoResponse for MyResponse { + type Body = Body; + type BodyError = ::Error; + + fn into_response(self) -> Response { + Response::new(Body::empty()) + } + } + ``` +- SSE: + - **added:** Add `response::sse::Sse`. This implements SSE using a response rather than a service ([#98](https://github.com/tokio-rs/axum/pull/98)) + - **changed:** Remove `axum::sse`. Its been replaced by `axum::response::sse` ([#98](https://github.com/tokio-rs/axum/pull/98)) + + Handler using SSE in 0.1: + ```rust + use axum::{ + prelude::*, + sse::{sse, Event}, + }; + use std::convert::Infallible; + + let app = route( + "/", + sse(|| async { + let stream = futures::stream::iter(vec![Ok::<_, Infallible>( + Event::default().data("hi there!"), + )]); + Ok::<_, Infallible>(stream) + }), + ); + ``` + + Becomes this in 0.2: + + ```rust + use axum::{ + handler::get, + response::sse::{Event, Sse}, + Router, + }; + use std::convert::Infallible; + + let app = Router::new().route( + "/", + get(|| async { + let stream = futures::stream::iter(vec![Ok::<_, Infallible>( + Event::default().data("hi there!"), + )]); + Sse::new(stream) + }), + ); + ``` +- WebSockets: + - **changed:** Change WebSocket API to use an extractor plus a response ([#121](https://github.com/tokio-rs/axum/pull/121)) + - **changed:** Make WebSocket `Message` an enum ([#116](https://github.com/tokio-rs/axum/pull/116)) + - **changed:** `WebSocket` now uses `Error` as its error type ([#150](https://github.com/tokio-rs/axum/pull/150)) + + Handler using WebSockets in 0.1: + + ```rust + use axum::{ + prelude::*, + ws::{ws, WebSocket}, + }; + + let app = route( + "/", + ws(|socket: WebSocket| async move { + // do stuff with socket + }), + ); + ``` + + Becomes this in 0.2: + + ```rust + use axum::{ + extract::ws::{WebSocket, WebSocketUpgrade}, + handler::get, + Router, + }; + + let app = Router::new().route( + "/", + get(|ws: WebSocketUpgrade| async move { + ws.on_upgrade(|socket: WebSocket| async move { + // do stuff with socket + }) + }), + ); + ``` +- Misc + - **added:** Add default feature `tower-log` which exposes `tower`'s `log` feature. ([#218](https://github.com/tokio-rs/axum/pull/218)) + - **changed:** Replace `body::BoxStdError` with `axum::Error`, which supports downcasting ([#150](https://github.com/tokio-rs/axum/pull/150)) + - **changed:** `EmptyRouter` now requires the response body to implement `Send + Sync + 'static'` ([#108](https://github.com/tokio-rs/axum/pull/108)) + - **changed:** `Router::check_infallible` now returns a `CheckInfallible` service. This + is to improve compile times ([#198](https://github.com/tokio-rs/axum/pull/198)) + - **changed:** `Router::into_make_service` now returns `routing::IntoMakeService` rather than + `tower::make::Shared` ([#229](https://github.com/tokio-rs/axum/pull/229)) + - **changed:** All usage of `tower::BoxError` has been replaced with `axum::BoxError` ([#229](https://github.com/tokio-rs/axum/pull/229)) + - **changed:** Several response future types have been moved into dedicated + `future` modules ([#133](https://github.com/tokio-rs/axum/pull/133)) + - **changed:** `EmptyRouter`, `ExtractorMiddleware`, `ExtractorMiddlewareLayer`, + and `QueryStringMissing` no longer implement `Copy` ([#132](https://github.com/tokio-rs/axum/pull/132)) + - **changed:** `service::OnMethod`, `handler::OnMethod`, and `routing::Nested` have new response future types ([#157](https://github.com/tokio-rs/axum/pull/157)) + +# 0.1.3 (06. August, 2021) + +- Fix stripping prefix when nesting services at `/` ([#91](https://github.com/tokio-rs/axum/pull/91)) +- Add support for WebSocket protocol negotiation ([#83](https://github.com/tokio-rs/axum/pull/83)) +- Use `pin-project-lite` instead of `pin-project` ([#95](https://github.com/tokio-rs/axum/pull/95)) +- Re-export `http` crate and `hyper::Server` ([#110](https://github.com/tokio-rs/axum/pull/110)) +- Fix `Query` and `Form` extractors giving bad request error when query string is empty. ([#117](https://github.com/tokio-rs/axum/pull/117)) +- Add `Path` extractor. ([#124](https://github.com/tokio-rs/axum/pull/124)) +- Fixed the implementation of `IntoResponse` of `(HeaderMap, T)` and `(StatusCode, HeaderMap, T)` would ignore headers from `T` ([#137](https://github.com/tokio-rs/axum/pull/137)) +- Deprecate `extract::UrlParams` and `extract::UrlParamsMap`. Use `extract::Path` instead ([#138](https://github.com/tokio-rs/axum/pull/138)) + +# 0.1.2 (01. August, 2021) + +- Implement `Stream` for `WebSocket` ([#52](https://github.com/tokio-rs/axum/pull/52)) +- Implement `Sink` for `WebSocket` ([#52](https://github.com/tokio-rs/axum/pull/52)) +- Implement `Deref` most extractors ([#56](https://github.com/tokio-rs/axum/pull/56)) +- Return `405 Method Not Allowed` for unsupported method for route ([#63](https://github.com/tokio-rs/axum/pull/63)) +- Add extractor for remote connection info ([#55](https://github.com/tokio-rs/axum/pull/55)) +- Improve error message of `MissingExtension` rejections ([#72](https://github.com/tokio-rs/axum/pull/72)) +- Improve documentation for routing ([#71](https://github.com/tokio-rs/axum/pull/71)) +- Clarify required response body type when routing to `tower::Service`s ([#69](https://github.com/tokio-rs/axum/pull/69)) +- Add `axum::body::box_body` to converting an `http_body::Body` to `axum::body::BoxBody` ([#69](https://github.com/tokio-rs/axum/pull/69)) +- Add `axum::sse` for Server-Sent Events ([#75](https://github.com/tokio-rs/axum/pull/75)) +- Mention required dependencies in docs ([#77](https://github.com/tokio-rs/axum/pull/77)) +- Fix WebSockets failing on Firefox ([#76](https://github.com/tokio-rs/axum/pull/76)) + +# 0.1.1 (30. July, 2021) + +- Misc readme fixes. + +# 0.1.0 (30. July, 2021) + +- Initial release. diff --git a/axum/Cargo.toml b/axum/Cargo.toml new file mode 100644 index 00000000..4f9e8a43 --- /dev/null +++ b/axum/Cargo.toml @@ -0,0 +1,92 @@ +[package] +name = "axum" +version = "0.3.0" +authors = ["David Pedersen "] +categories = ["asynchronous", "network-programming", "web-programming"] +description = "Web framework that focuses on ergonomics and modularity" +edition = "2018" +homepage = "https://github.com/tokio-rs/axum" +keywords = ["http", "web", "framework"] +license = "MIT" +readme = "README.md" +repository = "https://github.com/tokio-rs/axum" + +[features] +default = ["http1", "json", "tower-log"] +http1 = ["hyper/http1"] +http2 = ["hyper/http2"] +json = ["serde_json", "mime"] +multipart = ["multer", "mime"] +tower-log = ["tower/log"] +ws = ["tokio-tungstenite", "sha-1", "base64"] + +[dependencies] +async-trait = "0.1.43" +bitflags = "1.0" +bytes = "1.0" +futures-util = { version = "0.3", default-features = false, features = ["alloc"] } +http = "0.2" +http-body = "0.4.4" +hyper = { version = "0.14.14", features = ["server", "tcp", "stream"] } +matchit = "0.4.4" +percent-encoding = "2.1" +pin-project-lite = "0.2.7" +serde = "1.0" +serde_urlencoded = "0.7" +sync_wrapper = "0.1.1" +tokio = { version = "1", features = ["time"] } +tokio-util = "0.6" +tower = { version = "0.4.10", default-features = false, features = ["util", "buffer", "make"] } +tower-http = { version = "0.1", features = ["add-extension", "map-response-body"] } +tower-layer = "0.3" +tower-service = "0.3" + +# optional dependencies +base64 = { optional = true, version = "0.13" } +headers = { optional = true, version = "0.3" } +mime = { optional = true, version = "0.3" } +multer = { optional = true, version = "2.0.0" } +serde_json = { version = "1.0", optional = true } +sha-1 = { optional = true, version = "0.9.6" } +tokio-tungstenite = { optional = true, version = "0.15" } + +[dev-dependencies] +futures = "0.3" +reqwest = { version = "0.11", features = ["json", "stream"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +tokio = { version = "1.6.1", features = ["macros", "rt", "rt-multi-thread", "net"] } +tokio-stream = "0.1" +tracing = "0.1" +uuid = { version = "0.8", features = ["serde", "v4"] } +anyhow = "1.0" + +[dev-dependencies.tower] +package = "tower" +version = "0.4.10" +features = [ + "util", + "timeout", + "limit", + "load-shed", + "steer", + "filter", +] + +[dev-dependencies.tower-http] +version = "0.1" +features = ["full"] + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[package.metadata.playground] +features = [ + "http1", + "http2", + "json", + "multipart", + "tower", + "ws", +] diff --git a/LICENSE b/axum/LICENSE similarity index 100% rename from LICENSE rename to axum/LICENSE diff --git a/axum/README.md b/axum/README.md new file mode 100644 index 00000000..defd00eb --- /dev/null +++ b/axum/README.md @@ -0,0 +1,159 @@ +# axum + +`axum` is a web application framework that focuses on ergonomics and modularity. + +[![Build status](https://github.com/tokio-rs/axum/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/tokio-rs/axum/actions/workflows/CI.yml) +[![Crates.io](https://img.shields.io/crates/v/axum)](https://crates.io/crates/axum) +[![Documentation](https://docs.rs/axum/badge.svg)](https://docs.rs/axum) + +More information about this crate can be found in the [crate documentation][docs]. + +## High level features + +- Route requests to handlers with a macro free API. +- Declaratively parse requests using extractors. +- Simple and predictable error handling model. +- Generate responses with minimal boilerplate. +- Take full advantage of the [`tower`] and [`tower-http`] ecosystem of + middleware, services, and utilities. + +In particular the last point is what sets `axum` apart from other frameworks. +`axum` doesn't have its own middleware system but instead uses +[`tower::Service`]. This means `axum` gets timeouts, tracing, compression, +authorization, and more, for free. It also enables you to share middleware with +applications written using [`hyper`] or [`tonic`]. + +## Usage example + +```rust +use axum::{ + routing::{get, post}, + http::StatusCode, + response::IntoResponse, + Json, Router, +}; +use serde::{Deserialize, Serialize}; +use std::net::SocketAddr; + +#[tokio::main] +async fn main() { + // initialize tracing + tracing_subscriber::fmt::init(); + + // build our application with a route + let app = Router::new() + // `GET /` goes to `root` + .route("/", get(root)) + // `POST /users` goes to `create_user` + .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(); +} + +// basic handler that responds with a static string +async fn root() -> &'static str { + "Hello, World!" +} + +async fn create_user( + // this argument tells axum to parse the request body + // as JSON into a `CreateUser` type + Json(payload): Json, +) -> impl IntoResponse { + // insert your application logic here + let user = User { + id: 1337, + username: payload.username, + }; + + // this will be converted into a JSON response + // with a status code of `201 Created` + (StatusCode::CREATED, Json(user)) +} + +// the input to our `create_user` handler +#[derive(Deserialize)] +struct CreateUser { + username: String, +} + +// the output to our `create_user` handler +#[derive(Serialize)] +struct User { + id: u64, + username: String, +} +``` + +You can find this [example][readme-example] as well as other example projects in +the [example directory][examples]. + +See the [crate documentation][docs] for way more examples. + +## Performance + +`axum` is a relatively thin layer on top of [`hyper`] and adds very little +overhead. So `axum`'s performance is comparable to [`hyper`]. You can find a +benchmark [here](https://github.com/programatik29/rust-web-benchmarks). + +## Safety + +This crate uses `#![forbid(unsafe_code)]` to ensure everything is implemented in +100% safe Rust. + +## Minimum supported Rust version + +axum's MSRV is 1.54. + +## Examples + +The [examples] folder contains various examples of how to use `axum`. The +[docs] also have lots of examples + +## Getting Help + +In the `axum`'s repo we also have a [number of examples][examples] showing how +to put everything together. You're also welcome to ask in the [Discord +channel][chat] or open an [issue] with your question. + +## Community projects + +See [here](ecosystem) for a list of community maintained crates and projects +built with axum. + +## Contributing + +:balloon: Thanks for your help improving the project! We are so happy to have +you! We have a [contributing guide][contributing] to help you get involved in the +`axum` project. + +## License + +This project is licensed under the [MIT license](license). + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in `axum` by you, shall be licensed as MIT, without any +additional terms or conditions. + +[readme-example]: https://github.com/tokio-rs/axum/tree/main/examples/readme +[examples]: https://github.com/tokio-rs/axum/tree/main/examples +[docs]: https://docs.rs/axum +[`tower`]: https://crates.io/crates/tower +[`hyper`]: https://crates.io/crates/hyper +[`tower-http`]: https://crates.io/crates/tower-http +[`tonic`]: https://crates.io/crates/tonic +[contributing]: https://github.com/tokio-rs/axum/blob/main/CONTRIBUTING.md +[chat]: https://discord.gg/tokio +[issue]: https://github.com/tokio-rs/axum/issues/new +[`tower::Service`]: https://docs.rs/tower/latest/tower/trait.Service.html +[ecosystem]: https://github.com/tokio-rs/axum/blob/main/ECOSYSTEM.md +[license]: https://github.com/tokio-rs/axum/blob/main/LICENSE diff --git a/src/add_extension.rs b/axum/src/add_extension.rs similarity index 100% rename from src/add_extension.rs rename to axum/src/add_extension.rs diff --git a/src/body.rs b/axum/src/body.rs similarity index 100% rename from src/body.rs rename to axum/src/body.rs diff --git a/src/body/stream_body.rs b/axum/src/body/stream_body.rs similarity index 100% rename from src/body/stream_body.rs rename to axum/src/body/stream_body.rs diff --git a/src/clone_box_service.rs b/axum/src/clone_box_service.rs similarity index 100% rename from src/clone_box_service.rs rename to axum/src/clone_box_service.rs diff --git a/src/docs/error_handling.md b/axum/src/docs/error_handling.md similarity index 100% rename from src/docs/error_handling.md rename to axum/src/docs/error_handling.md diff --git a/src/docs/extract.md b/axum/src/docs/extract.md similarity index 100% rename from src/docs/extract.md rename to axum/src/docs/extract.md diff --git a/src/docs/handlers_intro.md b/axum/src/docs/handlers_intro.md similarity index 100% rename from src/docs/handlers_intro.md rename to axum/src/docs/handlers_intro.md diff --git a/src/docs/middleware.md b/axum/src/docs/middleware.md similarity index 100% rename from src/docs/middleware.md rename to axum/src/docs/middleware.md diff --git a/src/docs/response.md b/axum/src/docs/response.md similarity index 100% rename from src/docs/response.md rename to axum/src/docs/response.md diff --git a/src/docs/routing/fallback.md b/axum/src/docs/routing/fallback.md similarity index 100% rename from src/docs/routing/fallback.md rename to axum/src/docs/routing/fallback.md diff --git a/src/docs/routing/into_make_service_with_connect_info.md b/axum/src/docs/routing/into_make_service_with_connect_info.md similarity index 100% rename from src/docs/routing/into_make_service_with_connect_info.md rename to axum/src/docs/routing/into_make_service_with_connect_info.md diff --git a/src/docs/routing/layer.md b/axum/src/docs/routing/layer.md similarity index 100% rename from src/docs/routing/layer.md rename to axum/src/docs/routing/layer.md diff --git a/src/docs/routing/merge.md b/axum/src/docs/routing/merge.md similarity index 100% rename from src/docs/routing/merge.md rename to axum/src/docs/routing/merge.md diff --git a/src/docs/routing/nest.md b/axum/src/docs/routing/nest.md similarity index 100% rename from src/docs/routing/nest.md rename to axum/src/docs/routing/nest.md diff --git a/src/docs/routing/route.md b/axum/src/docs/routing/route.md similarity index 100% rename from src/docs/routing/route.md rename to axum/src/docs/routing/route.md diff --git a/src/error.rs b/axum/src/error.rs similarity index 100% rename from src/error.rs rename to axum/src/error.rs diff --git a/src/error_handling/mod.rs b/axum/src/error_handling/mod.rs similarity index 100% rename from src/error_handling/mod.rs rename to axum/src/error_handling/mod.rs diff --git a/src/extract/connect_info.rs b/axum/src/extract/connect_info.rs similarity index 100% rename from src/extract/connect_info.rs rename to axum/src/extract/connect_info.rs diff --git a/src/extract/content_length_limit.rs b/axum/src/extract/content_length_limit.rs similarity index 100% rename from src/extract/content_length_limit.rs rename to axum/src/extract/content_length_limit.rs diff --git a/src/extract/extension.rs b/axum/src/extract/extension.rs similarity index 100% rename from src/extract/extension.rs rename to axum/src/extract/extension.rs diff --git a/src/extract/extractor_middleware.rs b/axum/src/extract/extractor_middleware.rs similarity index 100% rename from src/extract/extractor_middleware.rs rename to axum/src/extract/extractor_middleware.rs diff --git a/src/extract/form.rs b/axum/src/extract/form.rs similarity index 100% rename from src/extract/form.rs rename to axum/src/extract/form.rs diff --git a/src/extract/matched_path.rs b/axum/src/extract/matched_path.rs similarity index 100% rename from src/extract/matched_path.rs rename to axum/src/extract/matched_path.rs diff --git a/src/extract/mod.rs b/axum/src/extract/mod.rs similarity index 100% rename from src/extract/mod.rs rename to axum/src/extract/mod.rs diff --git a/src/extract/multipart.rs b/axum/src/extract/multipart.rs similarity index 100% rename from src/extract/multipart.rs rename to axum/src/extract/multipart.rs diff --git a/src/extract/path/de.rs b/axum/src/extract/path/de.rs similarity index 100% rename from src/extract/path/de.rs rename to axum/src/extract/path/de.rs diff --git a/src/extract/path/mod.rs b/axum/src/extract/path/mod.rs similarity index 100% rename from src/extract/path/mod.rs rename to axum/src/extract/path/mod.rs diff --git a/src/extract/query.rs b/axum/src/extract/query.rs similarity index 100% rename from src/extract/query.rs rename to axum/src/extract/query.rs diff --git a/src/extract/raw_query.rs b/axum/src/extract/raw_query.rs similarity index 100% rename from src/extract/raw_query.rs rename to axum/src/extract/raw_query.rs diff --git a/src/extract/rejection.rs b/axum/src/extract/rejection.rs similarity index 100% rename from src/extract/rejection.rs rename to axum/src/extract/rejection.rs diff --git a/src/extract/request_parts.rs b/axum/src/extract/request_parts.rs similarity index 100% rename from src/extract/request_parts.rs rename to axum/src/extract/request_parts.rs diff --git a/src/extract/tuple.rs b/axum/src/extract/tuple.rs similarity index 100% rename from src/extract/tuple.rs rename to axum/src/extract/tuple.rs diff --git a/src/extract/typed_header.rs b/axum/src/extract/typed_header.rs similarity index 100% rename from src/extract/typed_header.rs rename to axum/src/extract/typed_header.rs diff --git a/src/extract/ws.rs b/axum/src/extract/ws.rs similarity index 100% rename from src/extract/ws.rs rename to axum/src/extract/ws.rs diff --git a/src/handler/future.rs b/axum/src/handler/future.rs similarity index 100% rename from src/handler/future.rs rename to axum/src/handler/future.rs diff --git a/src/handler/into_service.rs b/axum/src/handler/into_service.rs similarity index 100% rename from src/handler/into_service.rs rename to axum/src/handler/into_service.rs diff --git a/src/handler/mod.rs b/axum/src/handler/mod.rs similarity index 100% rename from src/handler/mod.rs rename to axum/src/handler/mod.rs diff --git a/src/json.rs b/axum/src/json.rs similarity index 100% rename from src/json.rs rename to axum/src/json.rs diff --git a/src/lib.rs b/axum/src/lib.rs similarity index 100% rename from src/lib.rs rename to axum/src/lib.rs diff --git a/src/macros.rs b/axum/src/macros.rs similarity index 100% rename from src/macros.rs rename to axum/src/macros.rs diff --git a/src/response/headers.rs b/axum/src/response/headers.rs similarity index 100% rename from src/response/headers.rs rename to axum/src/response/headers.rs diff --git a/src/response/mod.rs b/axum/src/response/mod.rs similarity index 100% rename from src/response/mod.rs rename to axum/src/response/mod.rs diff --git a/src/response/redirect.rs b/axum/src/response/redirect.rs similarity index 100% rename from src/response/redirect.rs rename to axum/src/response/redirect.rs diff --git a/src/response/sse.rs b/axum/src/response/sse.rs similarity index 100% rename from src/response/sse.rs rename to axum/src/response/sse.rs diff --git a/src/routing/future.rs b/axum/src/routing/future.rs similarity index 100% rename from src/routing/future.rs rename to axum/src/routing/future.rs diff --git a/src/routing/handler_method_routing.rs b/axum/src/routing/handler_method_routing.rs similarity index 100% rename from src/routing/handler_method_routing.rs rename to axum/src/routing/handler_method_routing.rs diff --git a/src/routing/into_make_service.rs b/axum/src/routing/into_make_service.rs similarity index 100% rename from src/routing/into_make_service.rs rename to axum/src/routing/into_make_service.rs diff --git a/src/routing/method_filter.rs b/axum/src/routing/method_filter.rs similarity index 100% rename from src/routing/method_filter.rs rename to axum/src/routing/method_filter.rs diff --git a/src/routing/method_not_allowed.rs b/axum/src/routing/method_not_allowed.rs similarity index 100% rename from src/routing/method_not_allowed.rs rename to axum/src/routing/method_not_allowed.rs diff --git a/src/routing/mod.rs b/axum/src/routing/mod.rs similarity index 100% rename from src/routing/mod.rs rename to axum/src/routing/mod.rs diff --git a/src/routing/not_found.rs b/axum/src/routing/not_found.rs similarity index 100% rename from src/routing/not_found.rs rename to axum/src/routing/not_found.rs diff --git a/src/routing/route.rs b/axum/src/routing/route.rs similarity index 100% rename from src/routing/route.rs rename to axum/src/routing/route.rs diff --git a/src/routing/service_method_routing.rs b/axum/src/routing/service_method_routing.rs similarity index 100% rename from src/routing/service_method_routing.rs rename to axum/src/routing/service_method_routing.rs diff --git a/src/routing/strip_prefix.rs b/axum/src/routing/strip_prefix.rs similarity index 100% rename from src/routing/strip_prefix.rs rename to axum/src/routing/strip_prefix.rs diff --git a/src/routing/tests/fallback.rs b/axum/src/routing/tests/fallback.rs similarity index 100% rename from src/routing/tests/fallback.rs rename to axum/src/routing/tests/fallback.rs diff --git a/src/routing/tests/get_to_head.rs b/axum/src/routing/tests/get_to_head.rs similarity index 100% rename from src/routing/tests/get_to_head.rs rename to axum/src/routing/tests/get_to_head.rs diff --git a/src/routing/tests/handle_error.rs b/axum/src/routing/tests/handle_error.rs similarity index 100% rename from src/routing/tests/handle_error.rs rename to axum/src/routing/tests/handle_error.rs diff --git a/src/routing/tests/merge.rs b/axum/src/routing/tests/merge.rs similarity index 100% rename from src/routing/tests/merge.rs rename to axum/src/routing/tests/merge.rs diff --git a/src/routing/tests/mod.rs b/axum/src/routing/tests/mod.rs similarity index 100% rename from src/routing/tests/mod.rs rename to axum/src/routing/tests/mod.rs diff --git a/src/routing/tests/nest.rs b/axum/src/routing/tests/nest.rs similarity index 100% rename from src/routing/tests/nest.rs rename to axum/src/routing/tests/nest.rs diff --git a/src/test_helpers.rs b/axum/src/test_helpers.rs similarity index 100% rename from src/test_helpers.rs rename to axum/src/test_helpers.rs diff --git a/src/util.rs b/axum/src/util.rs similarity index 100% rename from src/util.rs rename to axum/src/util.rs diff --git a/examples/async-graphql/Cargo.toml b/examples/async-graphql/Cargo.toml index f652ece3..cc95ba6f 100644 --- a/examples/async-graphql/Cargo.toml +++ b/examples/async-graphql/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } tokio = { version = "1.0", features = ["full"] } tracing = "0.1" tracing-subscriber = "0.2" diff --git a/examples/chat/Cargo.toml b/examples/chat/Cargo.toml index caac5502..cf743ffa 100644 --- a/examples/chat/Cargo.toml +++ b/examples/chat/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../..", features = ["ws"] } +axum = { path = "../../axum", features = ["ws"] } futures = "0.3" tokio = { version = "1", features = ["full"] } tower = { version = "0.4", features = ["util"] } diff --git a/examples/customize-extractor-error/Cargo.toml b/examples/customize-extractor-error/Cargo.toml index 7b558431..f624c5cc 100644 --- a/examples/customize-extractor-error/Cargo.toml +++ b/examples/customize-extractor-error/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } tokio = { version = "1.0", features = ["full"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/examples/error-handling-and-dependency-injection/Cargo.toml b/examples/error-handling-and-dependency-injection/Cargo.toml index 2e4aba38..a2632cd0 100644 --- a/examples/error-handling-and-dependency-injection/Cargo.toml +++ b/examples/error-handling-and-dependency-injection/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } tokio = { version = "1.0", features = ["full"] } tower = { version = "0.4", features = ["util"] } tracing = "0.1" diff --git a/examples/form/Cargo.toml b/examples/form/Cargo.toml index bb59f213..d2148a0d 100644 --- a/examples/form/Cargo.toml +++ b/examples/form/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } tokio = { version = "1.0", features = ["full"] } tracing = "0.1" tracing-subscriber = "0.2" diff --git a/examples/global-404-handler/Cargo.toml b/examples/global-404-handler/Cargo.toml index d4165388..8892180a 100644 --- a/examples/global-404-handler/Cargo.toml +++ b/examples/global-404-handler/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } tokio = { version = "1.0", features = ["full"] } tower = { version = "0.4", features = ["util"] } tracing = "0.1" diff --git a/examples/graceful_shutdown/Cargo.toml b/examples/graceful_shutdown/Cargo.toml index ddb9a4d2..87163dc0 100644 --- a/examples/graceful_shutdown/Cargo.toml +++ b/examples/graceful_shutdown/Cargo.toml @@ -5,5 +5,5 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } tokio = { version = "1.0", features = ["full"] } diff --git a/examples/hello-world/Cargo.toml b/examples/hello-world/Cargo.toml index ab8f44dd..36b5dfc6 100644 --- a/examples/hello-world/Cargo.toml +++ b/examples/hello-world/Cargo.toml @@ -5,5 +5,5 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } tokio = { version = "1.0", features = ["full"] } diff --git a/examples/http-proxy/Cargo.toml b/examples/http-proxy/Cargo.toml index 833068df..ed22e520 100644 --- a/examples/http-proxy/Cargo.toml +++ b/examples/http-proxy/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } tokio = { version = "1.0", features = ["full"] } hyper = { version = "0.14", features = ["full"] } tower = { version = "0.4", features = ["make"] } diff --git a/examples/jwt/Cargo.toml b/examples/jwt/Cargo.toml index 201ead4b..a0770dea 100644 --- a/examples/jwt/Cargo.toml +++ b/examples/jwt/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../..", features = ["headers"] } +axum = { path = "../../axum", features = ["headers"] } tokio = { version = "1.0", features = ["full"] } tracing = "0.1" tracing-subscriber = "0.2" diff --git a/examples/key-value-store/Cargo.toml b/examples/key-value-store/Cargo.toml index 0f936de5..4aa6dc70 100644 --- a/examples/key-value-store/Cargo.toml +++ b/examples/key-value-store/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } tokio = { version = "1.0", features = ["full"] } tracing = "0.1" tracing-subscriber = "0.2" diff --git a/examples/low-level-rustls/Cargo.toml b/examples/low-level-rustls/Cargo.toml index b9650cfa..7597d71f 100644 --- a/examples/low-level-rustls/Cargo.toml +++ b/examples/low-level-rustls/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } hyper = { version = "0.14", features = ["full"] } tokio = { version = "1", features = ["full"] } tokio-rustls = "0.22" diff --git a/examples/multipart-form/Cargo.toml b/examples/multipart-form/Cargo.toml index 5716047d..870ddd6d 100644 --- a/examples/multipart-form/Cargo.toml +++ b/examples/multipart-form/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../..", features = ["multipart"] } +axum = { path = "../../axum", features = ["multipart"] } tokio = { version = "1.0", features = ["full"] } tracing = "0.1" tracing-subscriber = "0.2" diff --git a/examples/oauth/Cargo.toml b/examples/oauth/Cargo.toml index 44e68cd4..f8818e26 100644 --- a/examples/oauth/Cargo.toml +++ b/examples/oauth/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../..", features = ["headers"] } +axum = { path = "../../axum", features = ["headers"] } tokio = { version = "1.0", features = ["full"] } tracing = "0.1" tracing-subscriber = "0.2" diff --git a/examples/print-request-response/Cargo.toml b/examples/print-request-response/Cargo.toml index 8a7f5b59..31dc4bd9 100644 --- a/examples/print-request-response/Cargo.toml +++ b/examples/print-request-response/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } tokio = { version = "1.0", features = ["full"] } tracing = "0.1" tracing-subscriber = "0.2" diff --git a/examples/query-params-with-empty-strings/Cargo.toml b/examples/query-params-with-empty-strings/Cargo.toml index ffed6f87..5b360a29 100644 --- a/examples/query-params-with-empty-strings/Cargo.toml +++ b/examples/query-params-with-empty-strings/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } tokio = { version = "1.0", features = ["full"] } serde = { version = "1.0", features = ["derive"] } tower = { version = "0.4", features = ["util"] } diff --git a/examples/readme/Cargo.toml b/examples/readme/Cargo.toml index 0fe437b3..84f3c977 100644 --- a/examples/readme/Cargo.toml +++ b/examples/readme/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.68" tokio = { version = "1.0", features = ["full"] } diff --git a/examples/reverse-proxy/Cargo.toml b/examples/reverse-proxy/Cargo.toml index 4a13668f..2d081ab1 100644 --- a/examples/reverse-proxy/Cargo.toml +++ b/examples/reverse-proxy/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2018" [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } hyper = { version = "0.14", features = ["full"] } tokio = { version = "1", features = ["full"] } tracing = "0.1" diff --git a/examples/sessions/Cargo.toml b/examples/sessions/Cargo.toml index 967306a4..57402619 100644 --- a/examples/sessions/Cargo.toml +++ b/examples/sessions/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } tokio = { version = "1.0", features = ["full"] } tracing = "0.1" tracing-subscriber = "0.2" diff --git a/examples/sse/Cargo.toml b/examples/sse/Cargo.toml index 48c0996d..136ff85f 100644 --- a/examples/sse/Cargo.toml +++ b/examples/sse/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../..", features = ["headers"] } +axum = { path = "../../axum", features = ["headers"] } tokio = { version = "1.0", features = ["full"] } tracing = "0.1" tracing-subscriber = "0.2" diff --git a/examples/static-file-server/Cargo.toml b/examples/static-file-server/Cargo.toml index b9175002..a564248f 100644 --- a/examples/static-file-server/Cargo.toml +++ b/examples/static-file-server/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } tokio = { version = "1.0", features = ["full"] } tracing = "0.1" tracing-subscriber = "0.2" diff --git a/examples/templates/Cargo.toml b/examples/templates/Cargo.toml index 332faaef..db1e7b92 100644 --- a/examples/templates/Cargo.toml +++ b/examples/templates/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } tokio = { version = "1.0", features = ["full"] } tracing = "0.1" tracing-subscriber = "0.2" diff --git a/examples/testing/Cargo.toml b/examples/testing/Cargo.toml index 7ed1a252..e066f03d 100644 --- a/examples/testing/Cargo.toml +++ b/examples/testing/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } tokio = { version = "1.0", features = ["full"] } tracing = "0.1" tracing-subscriber = "0.2" diff --git a/examples/tls-rustls/Cargo.toml b/examples/tls-rustls/Cargo.toml index 2b97ed83..bfd88a05 100644 --- a/examples/tls-rustls/Cargo.toml +++ b/examples/tls-rustls/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } axum-server = { version = "0.2", features = ["tls-rustls"] } tokio = { version = "1", features = ["full"] } tracing = "0.1" diff --git a/examples/todos/Cargo.toml b/examples/todos/Cargo.toml index c12acae9..1fd74546 100644 --- a/examples/todos/Cargo.toml +++ b/examples/todos/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } tokio = { version = "1.0", features = ["full"] } tracing = "0.1" tracing-subscriber = "0.2" diff --git a/examples/tokio-postgres/Cargo.toml b/examples/tokio-postgres/Cargo.toml index b70476e9..18c6aed8 100644 --- a/examples/tokio-postgres/Cargo.toml +++ b/examples/tokio-postgres/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } tokio = { version = "1.0", features = ["full"] } tracing = "0.1" tracing-subscriber = "0.2" diff --git a/examples/tracing-aka-logging/Cargo.toml b/examples/tracing-aka-logging/Cargo.toml index b2811c0f..1949bced 100644 --- a/examples/tracing-aka-logging/Cargo.toml +++ b/examples/tracing-aka-logging/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } tokio = { version = "1.0", features = ["full"] } tracing = "0.1" tracing-subscriber = "0.2" diff --git a/examples/unix-domain-socket/Cargo.toml b/examples/unix-domain-socket/Cargo.toml index 45efd623..11d17f8c 100644 --- a/examples/unix-domain-socket/Cargo.toml +++ b/examples/unix-domain-socket/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } tokio = { version = "1.0", features = ["full"] } tracing = "0.1" tracing-subscriber = "0.2" diff --git a/examples/validator/Cargo.toml b/examples/validator/Cargo.toml index 4f989f5c..13b4b313 100644 --- a/examples/validator/Cargo.toml +++ b/examples/validator/Cargo.toml @@ -6,7 +6,7 @@ version = "0.1.0" [dependencies] async-trait = "0.1" -axum = { path = "../.." } +axum = { path = "../../axum" } http-body = "0.4.3" serde = { version = "1.0", features = ["derive"] } thiserror = "1.0.29" diff --git a/examples/versioning/Cargo.toml b/examples/versioning/Cargo.toml index 389416d3..317f7eee 100644 --- a/examples/versioning/Cargo.toml +++ b/examples/versioning/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../.." } +axum = { path = "../../axum" } tokio = { version = "1.0", features = ["full"] } tracing = "0.1" tracing-subscriber = "0.2" diff --git a/examples/websockets/Cargo.toml b/examples/websockets/Cargo.toml index 08f51e4d..00907815 100644 --- a/examples/websockets/Cargo.toml +++ b/examples/websockets/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" publish = false [dependencies] -axum = { path = "../..", features = ["ws", "headers"] } +axum = { path = "../../axum", features = ["ws", "headers"] } tokio = { version = "1.0", features = ["full"] } tracing = "0.1" tracing-subscriber = "0.2"