* feat(ws): make Message an enum to allow pattern matching
* fix(examples): update to new websockets `Message`
* fix(ws): remove wildcard imports
* fix(examples/chat): apply clippy's never_loop
* style: `cargo fmt`
* docs:add license notes above parts that are copied
* fix(ws): make CloseCode an alias to u16
* fix: move Message from src/ws/mod.rs to src/extract/ws.rs
* docs: add changelog entry about websocket messages
* fix: remove useless convertions to the same type
Adds associated `Body` and `BodyError` types to `IntoResponse`. This is required for returning responses with bodies other than `hyper::Body` from handlers. That wasn't previously possible.
This is a breaking change so should be shipped in 0.2.
With this you'll be able to do:
```rust
let one = route("/foo", get(|| async { "foo" }))
.route("/bar", get(|| async { "bar" }));
let two = route("/baz", get(|| async { "baz" }));
let app = one.or(two);
```
Fixes https://github.com/tokio-rs/axum/issues/101
As described in
https://github.com/tokio-rs/axum/pull/108#issuecomment-892811637, a
`HandleError` created from `axum::ServiceExt::handle_error` should _not_
implement `RoutingDsl` as that leads to confusing routing behavior.
The technique used here of adding another type parameter to
`HandleError` isn't very clean, I think. But the alternative is
duplicating `HandleError` and having two versions, which I think is less
desirable.
These types were moved around in
https://github.com/tokio-rs/axum/pull/130 but re-export from their old
location for backwards compatibility.
This removes the re-exports.
https://github.com/tokio-rs/axum/pull/129 was a breaking change, in part
because I had to remove the `Copy` impl from `OnMethod`.
For the sake of future proofing I think we should remove other `Copy`
impls from services as well. We can always bring them back once things
have matured more.
These types no longer implement `Copy`:
- `EmptyRouter`
- `ExtractorMiddleware`
- `ExtractorMiddlewareLayer`
Example usage:
```rust
use axum::{prelude::*, sse::{sse, Event, KeepAlive}};
use tokio_stream::StreamExt as _;
use futures::stream::{self, Stream};
use std::{
time::Duration,
convert::Infallible,
};
let app = route("/sse", sse(make_stream).keep_alive(KeepAlive::default()));
async fn make_stream(
// you can also put extractors here
) -> Result<impl Stream<Item = Result<Event, Infallible>>, Infallible> {
// A `Stream` that repeats an event every second
let stream = stream::repeat_with(|| Event::default().data("hi!"))
.map(Ok)
.throttle(Duration::from_secs(1));
Ok(stream)
}
```
Implementation is based on [warp's](https://github.com/seanmonstar/warp/blob/master/src/filters/sse.rs)
Axum expected the `Connection` header to be _exactly_ `upgrade`. Turns
out thats a bit too strict as this didn't work in Firefox.
Turns out `Connection` just has to contain `upgrade`. At least that is
what [warp does](https://github.com/seanmonstar/warp/blob/master/src/filters/ws.rs#L46).
Fixes https://github.com/tokio-rs/axum/issues/43
With this you can get the remote address like so:
```rust
use axum::{prelude::*, extract::ConnectInfo};
use std::net::SocketAddr;
let app = route("/", get(handler));
async fn handler(ConnectInfo(addr): ConnectInfo<SocketAddr>) -> String {
format!("Hello {}", addr)
}
// Starting the app with `into_make_service_with_connect_info` is required
// for `ConnectInfo` to work.
let make_svc = app.into_make_service_with_connect_info::<SocketAddr, _>();
hyper::Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(make_svc)
.await
.expect("server failed");
```
This API is fully generic and supports whatever transport layer you're using with Hyper. I've updated the unix domain socket example to extract `peer_creds` and `peer_addr`.