Commit graph

108 commits

Author SHA1 Message Date
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 Pedersen
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 <jplatte@users.noreply.github.com>

* 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 <jplatte@users.noreply.github.com>
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 Pedersen
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 <programatik29@gmail.com>
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
David Pedersen
5ae94b6a24
Group items in changelog differently (#238) 2021-08-22 14:38:59 +02:00
David Pedersen
80a8355eff
Remove generic parameter from BodyStream (#234)
I think `BodyStream` is more useful without being generic over the
request body.

I'm also looking into adding a response body from a stream called
`StreamBody` which will work pretty much opposite to this.
2021-08-22 11:33:38 +02:00
David Pedersen
add3dc36f9
Rename extract::Body to extract::RawBody (#233) 2021-08-21 20:04:39 +02:00