Commit Graph
111 Commits
Author SHA1 Message Date
David Pedersen 2957f48ace Mention MSRV bump in changelog 2021-11-02 17:58:21 +01:00
David Pedersen 6b69368895 Small changelog fixes 2021-11-02 17:55:42 +01:00
David Pedersen 9512d14c99 Add Handler::{into_make_service, into_make_service_with_connect_info} (#444)
* Make `IntoMakeService(WithConnectInfo)?` work with any Service

* Add `Handler::{into_make_service, into_make_service_with_connect_info}`

These are useful if you want to run a handler without a `Router`, for
example to make a proxy.
2021-11-02 17:11:18 +01:00
Michael Grigoryan 5e44295a82 Fix typo in CHANGELOG (#442) 2021-11-02 07:50:10 +01:00
David Pedersen 3d07d40e02 Remove Sync requirement from response bodies (#440)
As we learned [in Tonic] bodies don't need to be `Sync` because they can
only be polled from one thread at a time.

This changes axum's bodies to no longer require `Sync` and makes
`BoxBody` an alias for `UnsyncBoxBody<Bytes, axum::Error>`.

[in Tonic]: https://github.com/hyperium/tonic/issues/117
2021-11-01 22:37:16 +01:00
David Pedersen 9465128f3e Rework docs (#437)
This reworks axum's docs in an attempt to make things easier to find. Previously I wasn't a fan of those docs for the same topic were spread across the root module docs and more specific places like types and methods.

This changes it such that the root module docs only gives a high level introduction to a topic, perhaps with a small example, and then link to other places where all the details are. This means `Router` is now the single place to learn about routing, and etc for the topics like handlers and error handling.
2021-11-01 21:13:37 +00:00
David Pedersen a2627e9084 Remove support for CONNECT (#428)
Given how different `CONNECT` requests are I think its fine to require
users to handle them manually. Since they don't contain paths you
probably don't need a full routing framework 🤷

An example can be found [here](https://github.com/tokio-rs/axum/blob/main/examples/http-proxy/src/main.rs)

Fixes #418
2021-10-26 21:11:33 +00:00
David Pedersen 8fe4eaf1d5 Run middleware for requests with no matching route (#422)
While thinking about #419 I realized that `main` had a bug where
middleware wouldn't be called if no route matched the incoming request.
`Router` would just directly return a 404 without calling any
middleware.

This fixes by making the fallback default to a service that always
returns 404 and always calling that if no route matches.

Layers applied to the router is then also applied to the fallback.

Unfortunately this breaks #380 but I don't currently see a way to
support both. Auth middleware need to run _after_ routing because you
don't care about auth for unknown paths, but logging middleware need to
run _before_ routing because they do care about seeing requests for
unknown paths so they can log them...

Part of #419
2021-10-26 18:39:05 +02:00
David Pedersen 9b17d86b92 Update to matchit 0.4.4 (#417)
- Static vs dynamic paths are now supported meaning `/foo` and `/:key`
  are not considered to overlap.
- A bug we hit regarding trailing slashes is fixed.
2021-10-25 23:35:33 +00:00
David Pedersen e949c47df6 Fix inconsistent naming of WebSocket rejections (#416) 2021-10-25 23:09:47 +00:00
David Pedersen 68e44fa9da Vendor AddExtensionLayer and AddExtension (#414)
This remove tower-http from axum's public API. I would like to be able
to make breaking releases of tower-http without also having to ship a
breaking release of axum.
2021-10-25 22:08:59 +00:00
David Pedersen 0a3f69af0d Reorganize changelog (#413)
* Reorganize changelog

When it starts growing this big I think grouping it into topics is nice.

* misc fixes
2021-10-25 23:52:22 +02:00
David Pedersen 02a035fb14 Add MatchedPath extractor (#412)
Fixes #386
2021-10-25 21:38:29 +00:00
David Pedersen e43bdf0ecf Rename EmptyRouter to MethodNotAllowed (#411)
It is no longer needed in `Router` so can be changed to always return
`403 Method Not Allowed`.
2021-10-25 23:28:22 +02:00
David Pedersen 59819e42bf Correctly handle trailing slashes in routes (#410) 2021-10-25 20:42:49 +00:00
David Pedersen baf7cabfe1 Add test for middleware that return early (#409)
* Add test for middleware that return early

Turns out #408 fixed #380.

* changelog
2021-10-25 19:46:49 +00:00
David Pedersen 3626facbda Update changelog 2021-10-25 20:51:07 +02:00
David Pedersen 47017f90b3 Support deserializing i128 and u128 in extract::Path (#406)
Fixes https://github.com/tokio-rs/axum/issues/398
2021-10-24 20:27:51 +00:00
David Pedersen 7692baf837 Reorganize method routers for handlers and services (#405)
* Re-organize method routing for handlers

* Re-organize method routing for services

* changelog
2021-10-24 20:05:16 +00:00
David Pedersen 0ee7379d4f Fix compile time regression by boxing routes internally (#404)
This is a reimplementation of #401 but with the new matchit based router.

Fixes #399
2021-10-24 20:52:42 +02:00
David Pedersen f10508db0b Revamp error handling model (#402)
* Revamp error handling model

* changelog improvements and typo fixes

* Fix a few more Infallible bounds

* minor docs fixes
2021-10-24 17:33:03 +00:00
David PedersenandJonas Platte 1a78a3f224 "matchit" based router (#363)
* "matchit" based router

* Update changelog

* Remove dependency on `regex`

* Docs

* Fix typos

* Also mention route order in root module docs

* Update CHANGELOG.md

Co-authored-by: Jonas Platte <[email protected]>

* Document that `/:key` and `/foo` overlaps

* Provide good error message for wildcards in routes

* minor clean ups

* Make `Router` cheaper to clone

* Ensure middleware still only applies to routes above

* Remove call to issues from changelog

We're aware of the short coming :)

* Fix tests on 1.51

Co-authored-by: Jonas Platte <[email protected]>
2021-10-24 15:22:49 +02:00
David Pedersen 9fcc884374 Change Connected::connect_info to return Self (#396)
I've been thinking that having an associated type probably isn't
necessary. I imagine most users are either using `SocketAddr` to the
remote connection IP, or writing their own connection struct.
2021-10-19 23:06:15 +02:00
David Pedersen 554e3a0ad4 Remove routing::Layered (#383) 2021-10-13 12:21:22 +02:00
David Pedersen ce5834ab80 Expand accepted content types for JSON requests (#378)
* Expand accepted content types for JSON requests

Fixes https://github.com/tokio-rs/axum/issues/375

* changelog

* add test for content type without spaces

* Don't accept `text/json`

* small clean up
2021-10-08 14:51:22 +00:00
David Pedersen 2bedcc285b Update changelog with 0.2.8 2021-10-07 17:28:56 +02:00
David Pedersen a30f123f35 Update changelog with 0.2.7 2021-10-07 17:11:08 +02:00
David Pedersen afabded385 Percent decode automatically in extract::Path (#272)
* Percent decode automatically in `extract::Path`

Fixes https://github.com/tokio-rs/axum/issues/261

* return an error if path param contains invalid utf-8

* Mention automatic decoding in the docs

* Update changelog: This is a breaking change

* cleanup

* fix tests
2021-10-02 14:04:29 +00:00
David Pedersen 2c2bcd7754 Update changelog 2021-10-02 15:48:52 +02:00
David PedersenandProgramatik cc4ae6b297 Improve performance of BoxRoute (#339)
* Improve performance of `BoxRoute`

This is based on #315 but slightly shorter.

It removes the need for a `tower::buffer::Buffer` in `BoxRoute` which
improves performance.

* changelog

Co-authored-by: Programatik <[email protected]>
2021-10-02 13:43:59 +00:00
David Pedersen 7fae35020a Version 0.2.6 (#360) 2021-10-02 11:33:52 +00:00
David Pedersen 2a683417d1 Clarify what handler::any and service::any accepts (#337)
They only accept standard HTTP methods and don't think we can fix that
without breaking changes.

Fixes https://github.com/tokio-rs/axum/issues/289
2021-09-19 08:28:15 +00:00
David Pedersen bb5bcab116 Version 0.2.5 (#336)
- 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
2021-09-18 19:35:10 +02:00
Olivier Pinon 0c18caa10f Add accessors to TypedHeaderRejection fields (#317)
Fixes #316
2021-09-12 16:11:51 +00:00
David Pedersen 36665793c3 Version 0.2.4 (#313)
Contains some documentation improvements:

- 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
2021-09-10 16:01:14 +00:00
techno-tanoC c8a44105c2 Fix a pull request link in CHANGELOG.md (#307) 2021-09-07 06:33:08 +00:00
David Pedersen bdc39deef2 Version 0.2.3 (#274)
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))
2021-08-26 16:22:47 +02:00
David Pedersen 7b391d85c8 Version 0.2.2 (#271)
0.2.2 (24. 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` ([#264](https://github.com/tokio-rs/axum/pull/264))
2021-08-26 06:57:07 +00:00
David Pedersen 20f6c3b509 Remove needless traits bounds from Router::boxed (#269)
Turns out these bounds weren't actually needed.

I was hoping it would speed up compile times but that isn't the case.
2021-08-26 08:24:21 +02:00
David Pedersen 0d2db387a8 Fix URI captures matching empty segments (#264)
It was never the intention that `/:key` should match `/`. This fixes
that.

Part of https://github.com/tokio-rs/axum/issues/259
2021-08-24 18:27:06 +00:00
David Pedersen 9a082a74b0 Version 0.2.1 (#256)
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))
2021-08-24 12:53:57 +02:00
David Pedersen 3d4ef9dc32 Document how to implement IntoResponse for custom error type (#258)
Fixes https://github.com/tokio-rs/axum/issues/249
2021-08-24 12:42:10 +02:00
Jonas Platte 536b8ca4ec Add Redirect::to constructor (#255)
The motivation for this is established in the issue it fixes.

Resolves #248
2021-08-24 12:13:18 +02:00
David Pedersen 02e61dfdd6 Version 0.2.0 (#247)
- 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<Body> {
      route(
          "/users",
          post(|Extension(state): Extension<State>| 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<BoxRoute> {
      Router::new()
          .route(
              "/users",
              post(|Extension(state): Extension<State>| 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<Body> {
          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 = <Self::Body as axum::body::HttpBody>::Error;

      fn into_response(self) -> Response<Self::Body> {
          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))
2021-08-23 20:49:29 +02:00
David Pedersen c2bfaf26d8 Removing prelude is a "changed" not a "fixed" 2021-08-23 18:42:51 +02:00
David Pedersen cb6f5b95b3 Minor reordering of changelog 2021-08-23 18:40:07 +02:00
David Pedersen c8c8e6509b Add upgrade examples to the changelog (#245)
Shows how to upgrade

- General routing
- SSE
- WebSockets
2021-08-23 18:24:08 +02:00
David Pedersen a753eac23f Remove boxing from StreamBody (#241)
I just had a thought: Why should `response::Headers` be generic, but
`body::StreamBody` should not? `StreamBody` previously boxed the stream
to erase the generics. So we had `response::Headers<T>` but
`body::StreamBody`, without generics.

After thinking about it I think it actually makes sense for responses to
remain generic because you're able to use `impl IntoResponse` so you
don't have to name the generics.

Whereas in the case of `BodyStream` (an extractor) you cannot use `impl Trait`
so it makes sense to box the inner body to make the type easier to name. Besides,
`BodyStream` is mostly useful when the request body isn't `hyper::Body`, as
that already implements `Stream`.
2021-08-22 22:03:56 +02:00
David Pedersen b75c34b821 Fix typo 2021-08-22 16:12:05 +02:00
David Pedersen 2322d39800 Add StreamBody (#237)
This adds `StreamBody` which converts a `Stream` of `Bytes` into a `http_body::Body`.

---

As suggested by Kestrer on Discord it would make sense for axum to provide different kinds of body types other than `Empty`, `Full`, and `hyper::Body`. There is also some talk about [splitting up `hyper::Body`](https://github.com/hyperium/hyper/issues/2345) so this can be seen as getting started on that effort. axum's body types could be moved to hyper or http-body if thats the direction we decide on.

The types I'm thinking about adding are:

- `StreamBody`-  added in this PR
- `AsyncReadBody` - similar to [http-body#41](https://github.com/hyperium/http-body/pull/41/files)
- `ChannelBody` - similar to `hyper::Body::channel`
2021-08-22 14:41:51 +02:00