-
Notifications
You must be signed in to change notification settings - Fork 125
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
state: move instantiation into State::from_request (#526)
This refactors the service implementation a little bit to instantiate the State via a dedicated method. The underlying goal is to allow users to use Gotham without having to use its handler. The motivation for that is to allow: - Not requiring handlers to be unwind safe. - Injecting extra things into the state that came from the socket (besides the client address), such as client TLS certificates.
- Loading branch information
Showing
8 changed files
with
169 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -81,5 +81,7 @@ members = [ | |
# finalizer | ||
"examples/finalizers/", | ||
|
||
# custom_service | ||
"examples/custom_service/", | ||
|
||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
[package] | ||
name = "gotham_examples_custom_service" | ||
description = "Using Gotham in a pre-existing Hyper service" | ||
version = "0.0.0" | ||
publish = false | ||
edition = "2018" | ||
|
||
[dependencies] | ||
anyhow = "1.0" | ||
futures = "0.3" | ||
gotham = { path = "../../gotham" } | ||
http = "0.2" | ||
hyper = { version = "0.14", features = ["full"] } | ||
tokio = { version = "1.0", features = ["full"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Custom Service | ||
|
||
An example of using Gotham within a pre-existing Hyper service. This is useful | ||
for advanced use cases where you might want to wrap Gotham in order logic, or | ||
pre-populate your state handing it off to Gotham. | ||
|
||
## License | ||
|
||
Licensed under your option of: | ||
|
||
* [MIT License](../../LICENSE-MIT) | ||
* [Apache License, Version 2.0](../../LICENSE-APACHE) | ||
|
||
## Community | ||
|
||
The following policies guide participation in our project and our community: | ||
|
||
* [Code of conduct](../../CODE_OF_CONDUCT.md) | ||
* [Contributing](../../CONTRIBUTING.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
//! An example usage of Gotham from another service. | ||
use anyhow::{Context as _, Error}; | ||
use futures::future::{BoxFuture, FutureExt}; | ||
use gotham::{ | ||
router::{builder::*, Router}, | ||
service::call_handler, | ||
state::State, | ||
}; | ||
use http::{Request, Response}; | ||
use hyper::{server::conn::Http, service::Service, Body}; | ||
use std::net::SocketAddr; | ||
use std::panic::AssertUnwindSafe; | ||
use std::task; | ||
use tokio::net::TcpListener; | ||
|
||
#[derive(Clone)] | ||
struct MyService { | ||
router: Router, | ||
addr: SocketAddr, | ||
} | ||
|
||
impl Service<Request<Body>> for MyService { | ||
type Response = Response<Body>; | ||
type Error = Error; | ||
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>; | ||
|
||
fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> task::Poll<Result<(), Self::Error>> { | ||
task::Poll::Ready(Ok(())) | ||
} | ||
|
||
fn call(&mut self, req: Request<Body>) -> Self::Future { | ||
// NOTE: You don't *have* to use call_handler for this (you could use `router.handle`), but | ||
// call_handler will catch panics and return en error response. | ||
let state = State::from_request(req, self.addr); | ||
call_handler(self.router.clone(), AssertUnwindSafe(state)).boxed() | ||
} | ||
} | ||
|
||
pub fn say_hello(state: State) -> (State, &'static str) { | ||
(state, "hello world") | ||
} | ||
|
||
#[tokio::main] | ||
pub async fn main() -> Result<(), Error> { | ||
let router = build_simple_router(|route| { | ||
// For the path "/" invoke the handler "say_hello" | ||
route.get("/").to(say_hello); | ||
}); | ||
|
||
let addr = "127.0.0.1:7878"; | ||
let listener = TcpListener::bind(&addr).await?; | ||
|
||
println!("Listening for requests at http://{}", addr); | ||
|
||
loop { | ||
let (socket, addr) = listener | ||
.accept() | ||
.await | ||
.context("Error accepting connection")?; | ||
|
||
let service = MyService { | ||
router: router.clone(), | ||
addr, | ||
}; | ||
|
||
let task = async move { | ||
Http::new() | ||
.serve_connection(socket, service) | ||
.await | ||
.context("Error serving connection")?; | ||
|
||
Result::<_, Error>::Ok(()) | ||
}; | ||
|
||
tokio::spawn(task); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters