mirror of
https://github.com/zerotier/ratpack.git
synced 2026-05-22 16:27:23 -07:00
Merge branch 'state'
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
use http::{Request, Response, StatusCode};
|
||||
use hyper::Body;
|
||||
use ratpack::{app::App, compose_handler, handler::Params, Error, HTTPResult, ServerError};
|
||||
|
||||
async fn validate_authtoken(
|
||||
req: Request<Body>,
|
||||
resp: Option<Response<Body>>,
|
||||
_params: Params,
|
||||
app: App<State>,
|
||||
) -> HTTPResult {
|
||||
let token = req.headers().get("X-AuthToken");
|
||||
if token.is_none() {
|
||||
return Err(Error::StatusCode(StatusCode::UNAUTHORIZED));
|
||||
}
|
||||
|
||||
let token = token.unwrap();
|
||||
|
||||
let state = app.state().await;
|
||||
if state.is_none() {
|
||||
return Err(Error::StatusCode(StatusCode::UNAUTHORIZED));
|
||||
}
|
||||
|
||||
let state = state.unwrap();
|
||||
|
||||
if !(state.clone().lock().await.authtoken == token) {
|
||||
return Err(Error::StatusCode(StatusCode::UNAUTHORIZED));
|
||||
}
|
||||
|
||||
return Ok((req, resp));
|
||||
}
|
||||
|
||||
async fn hello(
|
||||
req: Request<Body>,
|
||||
_resp: Option<Response<Body>>,
|
||||
params: Params,
|
||||
_app: App<State>,
|
||||
) -> HTTPResult {
|
||||
let name = params.get("name").unwrap();
|
||||
let bytes = Body::from(format!("hello, {}!\n", name));
|
||||
|
||||
return Ok((
|
||||
req,
|
||||
Some(Response::builder().status(200).body(bytes).unwrap()),
|
||||
));
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct State {
|
||||
authtoken: &'static str,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), ServerError> {
|
||||
let mut app = App::with_state(State {
|
||||
authtoken: "867-5309",
|
||||
});
|
||||
app.get("/auth/:name", compose_handler!(validate_authtoken, hello));
|
||||
app.get("/:name", compose_handler!(hello));
|
||||
|
||||
app.serve("127.0.0.1:3000").await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
+10
-1
@@ -5,10 +5,14 @@ use ratpack::{app::App, compose_handler, handler::Params, Error, HTTPResult, Ser
|
||||
const DEFAULT_AUTHTOKEN: &str = "867-5309";
|
||||
const AUTHTOKEN_FILENAME: &str = "authtoken.secret";
|
||||
|
||||
#[derive(Clone)]
|
||||
struct State;
|
||||
|
||||
async fn validate_authtoken(
|
||||
req: Request<Body>,
|
||||
resp: Option<Response<Body>>,
|
||||
_params: Params,
|
||||
_app: App<State>,
|
||||
) -> HTTPResult {
|
||||
let token = req.headers().get("X-AuthToken");
|
||||
if token.is_none() {
|
||||
@@ -32,7 +36,12 @@ async fn validate_authtoken(
|
||||
return Ok((req, resp));
|
||||
}
|
||||
|
||||
async fn hello(req: Request<Body>, _resp: Option<Response<Body>>, params: Params) -> HTTPResult {
|
||||
async fn hello(
|
||||
req: Request<Body>,
|
||||
_resp: Option<Response<Body>>,
|
||||
params: Params,
|
||||
_app: App<State>,
|
||||
) -> HTTPResult {
|
||||
let name = params.get("name").unwrap();
|
||||
let bytes = Body::from(format!("hello, {}!\n", name));
|
||||
|
||||
|
||||
@@ -2,7 +2,15 @@ use http::{Request, Response};
|
||||
use hyper::Body;
|
||||
use ratpack::{app::App, compose_handler, handler::Params, HTTPResult, ServerError};
|
||||
|
||||
async fn hello(req: Request<Body>, _resp: Option<Response<Body>>, params: Params) -> HTTPResult {
|
||||
#[derive(Clone)]
|
||||
struct State;
|
||||
|
||||
async fn hello(
|
||||
req: Request<Body>,
|
||||
_resp: Option<Response<Body>>,
|
||||
params: Params,
|
||||
_app: App<State>,
|
||||
) -> HTTPResult {
|
||||
let name = params.get("name").unwrap();
|
||||
let bytes = Body::from(format!("hello, {}!\n", name));
|
||||
|
||||
|
||||
+15
-2
@@ -3,12 +3,25 @@ use hyper::Body;
|
||||
use log::LevelFilter;
|
||||
use ratpack::{app::App, compose_handler, handler::Params, HTTPResult, ServerError};
|
||||
|
||||
async fn log(req: Request<Body>, resp: Option<Response<Body>>, _params: Params) -> HTTPResult {
|
||||
#[derive(Clone)]
|
||||
struct State;
|
||||
|
||||
async fn log(
|
||||
req: Request<Body>,
|
||||
resp: Option<Response<Body>>,
|
||||
_params: Params,
|
||||
_app: App<State>,
|
||||
) -> HTTPResult {
|
||||
log::trace!("New request: {}", req.uri().path());
|
||||
Ok((req, resp))
|
||||
}
|
||||
|
||||
async fn hello(req: Request<Body>, _resp: Option<Response<Body>>, params: Params) -> HTTPResult {
|
||||
async fn hello(
|
||||
req: Request<Body>,
|
||||
_resp: Option<Response<Body>>,
|
||||
params: Params,
|
||||
_app: App<State>,
|
||||
) -> HTTPResult {
|
||||
let name = params.get("name").unwrap();
|
||||
log::info!("Saying hello to {}", name);
|
||||
let bytes = Body::from(format!("hello, {}!\n", name));
|
||||
|
||||
+28
-15
@@ -1,61 +1,74 @@
|
||||
use std::{convert::Infallible, net::SocketAddr};
|
||||
use std::{convert::Infallible, net::SocketAddr, sync::Arc};
|
||||
|
||||
use http::{Method, Request, Response, StatusCode};
|
||||
use hyper::{server::conn::Http, service::service_fn, Body};
|
||||
use tokio::net::TcpListener;
|
||||
use tokio::{net::TcpListener, sync::Mutex};
|
||||
|
||||
use crate::{handler::Handler, router::Router, Error, ServerError};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct App {
|
||||
router: Router,
|
||||
pub struct App<S: Clone + Send> {
|
||||
router: Router<S>,
|
||||
global_state: Option<Arc<Mutex<S>>>,
|
||||
}
|
||||
|
||||
impl App {
|
||||
impl<S: 'static + Clone + Send> App<S> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
router: Router::new(),
|
||||
global_state: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&mut self, path: &str, ch: Handler) {
|
||||
pub fn with_state(state: S) -> Self {
|
||||
Self {
|
||||
router: Router::new(),
|
||||
global_state: Some(Arc::new(Mutex::new(state))),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn state(&self) -> Option<Arc<Mutex<S>>> {
|
||||
self.global_state.clone()
|
||||
}
|
||||
|
||||
pub fn get(&mut self, path: &str, ch: Handler<S>) {
|
||||
self.router.add(Method::GET, path.to_string(), ch);
|
||||
}
|
||||
|
||||
pub fn post(&mut self, path: &str, ch: Handler) {
|
||||
pub fn post(&mut self, path: &str, ch: Handler<S>) {
|
||||
self.router.add(Method::POST, path.to_string(), ch);
|
||||
}
|
||||
|
||||
pub fn delete(&mut self, path: &str, ch: Handler) {
|
||||
pub fn delete(&mut self, path: &str, ch: Handler<S>) {
|
||||
self.router.add(Method::DELETE, path.to_string(), ch);
|
||||
}
|
||||
|
||||
pub fn put(&mut self, path: &str, ch: Handler) {
|
||||
pub fn put(&mut self, path: &str, ch: Handler<S>) {
|
||||
self.router.add(Method::PUT, path.to_string(), ch);
|
||||
}
|
||||
|
||||
pub fn options(&mut self, path: &str, ch: Handler) {
|
||||
pub fn options(&mut self, path: &str, ch: Handler<S>) {
|
||||
self.router.add(Method::OPTIONS, path.to_string(), ch);
|
||||
}
|
||||
|
||||
pub fn patch(&mut self, path: &str, ch: Handler) {
|
||||
pub fn patch(&mut self, path: &str, ch: Handler<S>) {
|
||||
self.router.add(Method::PATCH, path.to_string(), ch);
|
||||
}
|
||||
|
||||
pub fn head(&mut self, path: &str, ch: Handler) {
|
||||
pub fn head(&mut self, path: &str, ch: Handler<S>) {
|
||||
self.router.add(Method::HEAD, path.to_string(), ch);
|
||||
}
|
||||
|
||||
pub fn connect(&mut self, path: &str, ch: Handler) {
|
||||
pub fn connect(&mut self, path: &str, ch: Handler<S>) {
|
||||
self.router.add(Method::CONNECT, path.to_string(), ch);
|
||||
}
|
||||
|
||||
pub fn trace(&mut self, path: &str, ch: Handler) {
|
||||
pub fn trace(&mut self, path: &str, ch: Handler<S>) {
|
||||
self.router.add(Method::TRACE, path.to_string(), ch);
|
||||
}
|
||||
|
||||
pub async fn dispatch(&self, req: Request<Body>) -> Result<Response<Body>, Infallible> {
|
||||
match self.router.dispatch(req).await {
|
||||
match self.router.dispatch(req, self.clone()).await {
|
||||
Ok(resp) => Ok(resp),
|
||||
Err(e) => match e {
|
||||
Error::StatusCode(sc) => Ok(Response::builder()
|
||||
|
||||
+36
-17
@@ -1,6 +1,6 @@
|
||||
use std::{collections::BTreeMap, future::Future};
|
||||
|
||||
use crate::{HTTPResult, PinBox};
|
||||
use crate::{app::App, HTTPResult, PinBox};
|
||||
use async_recursion::async_recursion;
|
||||
|
||||
use http::{Request, Response};
|
||||
@@ -8,23 +8,25 @@ use hyper::Body;
|
||||
|
||||
pub type Params = BTreeMap<String, String>;
|
||||
|
||||
pub type HandlerFunc = fn(
|
||||
pub type HandlerFunc<S> = fn(
|
||||
req: Request<Body>,
|
||||
response: Option<Response<Body>>,
|
||||
params: Params,
|
||||
app: App<S>,
|
||||
) -> PinBox<dyn Future<Output = HTTPResult> + Send>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Handler {
|
||||
handler: HandlerFunc,
|
||||
next: Box<Option<Handler>>,
|
||||
pub struct Handler<S: Clone + Send> {
|
||||
handler: HandlerFunc<S>,
|
||||
next: Box<Option<Handler<S>>>,
|
||||
}
|
||||
|
||||
impl Handler
|
||||
impl<S> Handler<S>
|
||||
where
|
||||
Self: Send,
|
||||
S: Clone + Send,
|
||||
{
|
||||
pub fn new(handler: HandlerFunc, next: Option<Handler>) -> Self {
|
||||
pub fn new(handler: HandlerFunc<S>, next: Option<Handler<S>>) -> Self {
|
||||
Self {
|
||||
handler,
|
||||
next: Box::new(next),
|
||||
@@ -37,12 +39,13 @@ where
|
||||
req: Request<hyper::Body>,
|
||||
response: Option<Response<hyper::Body>>,
|
||||
params: Params,
|
||||
app: App<S>,
|
||||
) -> HTTPResult {
|
||||
let (req, response) = (self.handler)(req, response, params.clone()).await?;
|
||||
let (req, response) = (self.handler)(req, response, params.clone(), app.clone()).await?;
|
||||
if self.next.is_some() {
|
||||
return Ok((*self.clone().next)
|
||||
.unwrap()
|
||||
.perform(req, response, params)
|
||||
.perform(req, response, params, app)
|
||||
.await?);
|
||||
}
|
||||
|
||||
@@ -53,12 +56,15 @@ where
|
||||
mod tests {
|
||||
#[tokio::test]
|
||||
async fn test_handler_basic() {
|
||||
use crate::{Error, HTTPResult};
|
||||
use crate::{app::App, Error, HTTPResult};
|
||||
use http::{HeaderValue, Request, Response, StatusCode};
|
||||
use hyper::Body;
|
||||
|
||||
use super::Params;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct State;
|
||||
|
||||
// this method adds a header:
|
||||
// wakka: wakka wakka
|
||||
// to the request. that's it!
|
||||
@@ -66,6 +72,7 @@ mod tests {
|
||||
mut req: Request<Body>,
|
||||
_response: Option<Response<Body>>,
|
||||
_params: Params,
|
||||
_app: App<State>,
|
||||
) -> HTTPResult {
|
||||
let headers = req.headers_mut();
|
||||
headers.insert("wakka", HeaderValue::from_str("wakka wakka").unwrap());
|
||||
@@ -77,6 +84,7 @@ mod tests {
|
||||
req: Request<Body>,
|
||||
mut response: Option<Response<Body>>,
|
||||
_params: Params,
|
||||
_app: App<State>,
|
||||
) -> HTTPResult {
|
||||
if let Some(header) = req.headers().get("wakka") {
|
||||
if header != "wakka wakka" {
|
||||
@@ -99,26 +107,37 @@ mod tests {
|
||||
}
|
||||
|
||||
// single stage handler that never yields a response
|
||||
let bh = super::Handler::new(|req, resp, params| Box::pin(one(req, resp, params)), None);
|
||||
let bh = super::Handler::new(
|
||||
|req, resp, params, app| Box::pin(one(req, resp, params, app)),
|
||||
None,
|
||||
);
|
||||
let req = Request::default();
|
||||
let (req, response) = bh.perform(req, None, Params::new()).await.unwrap();
|
||||
let (req, response) = bh
|
||||
.perform(req, None, Params::new(), App::new())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert!(req.headers().get("wakka").is_some());
|
||||
assert!(response.is_none());
|
||||
|
||||
// two-stage handler; yields a response if the first one was good.
|
||||
let bh_two =
|
||||
super::Handler::new(|req, resp, params| Box::pin(two(req, resp, params)), None);
|
||||
let bh_two = super::Handler::new(
|
||||
|req, resp, params, app| Box::pin(two(req, resp, params, app)),
|
||||
None,
|
||||
);
|
||||
let bh = super::Handler::new(
|
||||
|req, resp, params| Box::pin(one(req, resp, params)),
|
||||
|req, resp, params, app| Box::pin(one(req, resp, params, app)),
|
||||
Some(bh_two.clone()),
|
||||
);
|
||||
let (_, response) = bh.perform(req, None, Params::new()).await.unwrap();
|
||||
let (_, response) = bh
|
||||
.perform(req, None, Params::new(), App::new())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert!(response.is_some() && response.unwrap().status() == StatusCode::OK);
|
||||
|
||||
assert!(bh_two
|
||||
.perform(Request::default(), None, Params::new())
|
||||
.perform(Request::default(), None, Params::new(), App::new())
|
||||
.await
|
||||
.is_err());
|
||||
|
||||
|
||||
+12
-7
@@ -4,10 +4,10 @@ macro_rules! compose_handler {
|
||||
{
|
||||
use $crate::handler::{HandlerFunc, Handler};
|
||||
{
|
||||
let mut funcs: Vec<HandlerFunc> = Vec::new();
|
||||
let mut funcs: Vec<HandlerFunc<_>> = Vec::new();
|
||||
|
||||
$(
|
||||
funcs.push(|req, resp, params| Box::pin($x(req, resp, params)));
|
||||
funcs.push(|req, resp, params, app| Box::pin($x(req, resp, params, app)));
|
||||
)*
|
||||
|
||||
if funcs.len() == 0 {
|
||||
@@ -16,7 +16,7 @@ macro_rules! compose_handler {
|
||||
|
||||
|
||||
let mut handlers = Vec::new();
|
||||
let mut last: Option<Handler> = None;
|
||||
let mut last: Option<Handler<_>> = None;
|
||||
funcs.reverse();
|
||||
|
||||
for func in funcs {
|
||||
@@ -36,7 +36,10 @@ mod tests {
|
||||
use http::{HeaderValue, Request, Response, StatusCode};
|
||||
use hyper::Body;
|
||||
|
||||
use crate::{handler::Params, Error, HTTPResult};
|
||||
use crate::{app::App, handler::Params, Error, HTTPResult};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct State;
|
||||
|
||||
// this method adds a header:
|
||||
// wakka: wakka wakka
|
||||
@@ -45,6 +48,7 @@ mod tests {
|
||||
mut req: Request<Body>,
|
||||
_response: Option<Response<Body>>,
|
||||
_params: Params,
|
||||
_app: App<State>,
|
||||
) -> HTTPResult {
|
||||
let headers = req.headers_mut();
|
||||
headers.insert("wakka", HeaderValue::from_str("wakka wakka").unwrap());
|
||||
@@ -56,6 +60,7 @@ mod tests {
|
||||
req: Request<Body>,
|
||||
mut response: Option<Response<Body>>,
|
||||
_params: Params,
|
||||
_app: App<State>,
|
||||
) -> HTTPResult {
|
||||
if let Some(header) = req.headers().get("wakka") {
|
||||
if header != "wakka wakka" {
|
||||
@@ -80,7 +85,7 @@ mod tests {
|
||||
let handler = compose_handler!(one, two);
|
||||
|
||||
let (req, response) = handler
|
||||
.perform(Request::default(), None, Params::new())
|
||||
.perform(Request::default(), None, Params::new(), App::new())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@@ -90,7 +95,7 @@ mod tests {
|
||||
let handler = compose_handler!(one);
|
||||
|
||||
let (req, response) = handler
|
||||
.perform(Request::default(), None, Params::new())
|
||||
.perform(Request::default(), None, Params::new(), App::new())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@@ -100,7 +105,7 @@ mod tests {
|
||||
let handler = compose_handler!(two);
|
||||
|
||||
assert!(handler
|
||||
.perform(Request::default(), None, Params::new())
|
||||
.perform(Request::default(), None, Params::new(), App::new())
|
||||
.await
|
||||
.is_err());
|
||||
}
|
||||
|
||||
+59
-28
@@ -1,30 +1,30 @@
|
||||
use http::{Request, Response};
|
||||
use hyper::Body;
|
||||
|
||||
use crate::{handler::Handler, path::Path, Error, HTTPResult};
|
||||
use crate::{app::App, handler::Handler, path::Path, Error, HTTPResult};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Route {
|
||||
pub struct Route<S: Clone + Send> {
|
||||
method: http::Method,
|
||||
path: Path,
|
||||
handler: Handler,
|
||||
handler: Handler<S>,
|
||||
}
|
||||
|
||||
impl PartialEq for Route {
|
||||
impl<S: Clone + Send> PartialEq for Route<S> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.method.to_string() == other.method.to_string() && self.path.eq(&other.path)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Route {}
|
||||
impl<S: Clone + Send> Eq for Route<S> {}
|
||||
|
||||
impl PartialOrd for Route {
|
||||
impl<S: Clone + Send> PartialOrd for Route<S> {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for Route {
|
||||
impl<S: Clone + Send> Ord for Route<S> {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
let left = self.method.to_string() + " " + &self.path.to_string();
|
||||
let right = other.method.to_string() + " " + &other.path.to_string();
|
||||
@@ -33,8 +33,8 @@ impl Ord for Route {
|
||||
}
|
||||
}
|
||||
|
||||
impl Route {
|
||||
fn new(method: http::Method, path: String, handler: Handler) -> Self {
|
||||
impl<S: Clone + Send> Route<S> {
|
||||
fn new(method: http::Method, path: String, handler: Handler<S>) -> Self {
|
||||
Self {
|
||||
method,
|
||||
handler,
|
||||
@@ -43,37 +43,46 @@ impl Route {
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
async fn dispatch(&self, provided: String, req: Request<hyper::Body>) -> HTTPResult {
|
||||
async fn dispatch(
|
||||
&self,
|
||||
provided: String,
|
||||
req: Request<hyper::Body>,
|
||||
app: App<S>,
|
||||
) -> HTTPResult {
|
||||
let params = self.path.extract(provided)?;
|
||||
|
||||
if self.method != req.method() {
|
||||
return Err(Error::StatusCode(http::StatusCode::NOT_FOUND));
|
||||
}
|
||||
|
||||
self.handler.perform(req, None, params).await
|
||||
self.handler.perform(req, None, params, app).await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Router(Vec<Route>);
|
||||
pub struct Router<S: Clone + Send>(Vec<Route<S>>);
|
||||
|
||||
impl Router {
|
||||
impl<S: Clone + Send> Router<S> {
|
||||
pub fn new() -> Self {
|
||||
Self(Vec::new())
|
||||
}
|
||||
|
||||
pub(crate) fn add(&mut self, method: http::Method, path: String, ch: Handler) -> Self {
|
||||
pub(crate) fn add(&mut self, method: http::Method, path: String, ch: Handler<S>) -> Self {
|
||||
self.0.push(Route::new(method, path, ch));
|
||||
self.clone()
|
||||
}
|
||||
|
||||
pub(crate) async fn dispatch(&self, req: Request<Body>) -> Result<Response<Body>, Error> {
|
||||
pub(crate) async fn dispatch(
|
||||
&self,
|
||||
req: Request<Body>,
|
||||
app: App<S>,
|
||||
) -> Result<Response<Body>, Error> {
|
||||
let path = req.uri().path().to_string();
|
||||
|
||||
for route in self.0.clone() {
|
||||
if route.path.matches(path.to_string()) && route.method.eq(req.method()) {
|
||||
let params = route.path.extract(path)?;
|
||||
let (_, response) = route.handler.perform(req, None, params).await?;
|
||||
let (_, response) = route.handler.perform(req, None, params, app).await?;
|
||||
if response.is_none() {
|
||||
return Err(Error::StatusCode(http::StatusCode::INTERNAL_SERVER_ERROR));
|
||||
}
|
||||
@@ -87,22 +96,28 @@ impl Router {
|
||||
}
|
||||
|
||||
mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_route_dynamic() {
|
||||
use http::{Method, Request, Response};
|
||||
use hyper::Body;
|
||||
|
||||
use crate::{
|
||||
app::App,
|
||||
handler::{Handler, Params},
|
||||
HTTPResult,
|
||||
};
|
||||
|
||||
use super::Route;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct State;
|
||||
|
||||
async fn handler_dynamic(
|
||||
req: Request<Body>,
|
||||
_response: Option<Response<Body>>,
|
||||
params: Params,
|
||||
_app: App<State>,
|
||||
) -> HTTPResult {
|
||||
return Ok((
|
||||
req,
|
||||
@@ -117,13 +132,13 @@ mod tests {
|
||||
Method::GET,
|
||||
"/a/:name/c".to_string(),
|
||||
Handler::new(
|
||||
|req, resp, params| Box::pin(handler_dynamic(req, resp, params)),
|
||||
|req, resp, params, app| Box::pin(handler_dynamic(req, resp, params, app)),
|
||||
None,
|
||||
),
|
||||
);
|
||||
|
||||
assert!(route
|
||||
.dispatch("/a".to_string(), Request::default())
|
||||
.dispatch("/a".to_string(), Request::default(), App::new())
|
||||
.await
|
||||
.is_err());
|
||||
assert!(route
|
||||
@@ -133,6 +148,7 @@ mod tests {
|
||||
.method(Method::POST)
|
||||
.body(Body::from("one=two".as_bytes()))
|
||||
.unwrap(),
|
||||
App::new(),
|
||||
)
|
||||
.await
|
||||
.is_err());
|
||||
@@ -141,7 +157,7 @@ mod tests {
|
||||
"erik", "adam", "sean", "travis", "joseph", "grant", "joy", "steve", "marc",
|
||||
] {
|
||||
assert!(route
|
||||
.dispatch("/a/:name/c".to_string(), Request::default())
|
||||
.dispatch("/a/:name/c".to_string(), Request::default(), App::new())
|
||||
.await
|
||||
.is_ok());
|
||||
|
||||
@@ -149,7 +165,7 @@ mod tests {
|
||||
|
||||
let body = hyper::body::to_bytes(
|
||||
route
|
||||
.dispatch(path.clone(), Request::default())
|
||||
.dispatch(path.clone(), Request::default(), App::new())
|
||||
.await
|
||||
.unwrap()
|
||||
.1
|
||||
@@ -162,7 +178,7 @@ mod tests {
|
||||
assert_eq!(body, format!("hello, {}", name).as_bytes());
|
||||
|
||||
let status = route
|
||||
.dispatch(path, Request::default())
|
||||
.dispatch(path, Request::default(), App::new())
|
||||
.await
|
||||
.unwrap()
|
||||
.1
|
||||
@@ -179,16 +195,21 @@ mod tests {
|
||||
use hyper::Body;
|
||||
|
||||
use crate::{
|
||||
app::App,
|
||||
handler::{Handler, Params},
|
||||
HTTPResult,
|
||||
};
|
||||
|
||||
use super::Route;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct State;
|
||||
|
||||
async fn handler_static(
|
||||
req: Request<Body>,
|
||||
_response: Option<Response<Body>>,
|
||||
_params: Params,
|
||||
_app: App<State>,
|
||||
) -> HTTPResult {
|
||||
return Ok((
|
||||
req,
|
||||
@@ -204,13 +225,13 @@ mod tests {
|
||||
Method::GET,
|
||||
"/a/b/c".to_string(),
|
||||
Handler::new(
|
||||
|req, resp, params| Box::pin(handler_static(req, resp, params)),
|
||||
|req, resp, params, app| Box::pin(handler_static(req, resp, params, app)),
|
||||
None,
|
||||
),
|
||||
);
|
||||
|
||||
assert!(route
|
||||
.dispatch("/a".to_string(), Request::default())
|
||||
.dispatch("/a".to_string(), Request::default(), App::new())
|
||||
.await
|
||||
.is_err());
|
||||
assert!(route
|
||||
@@ -220,18 +241,19 @@ mod tests {
|
||||
.method(Method::POST)
|
||||
.body(Body::from("one=two".as_bytes()))
|
||||
.unwrap(),
|
||||
App::new(),
|
||||
)
|
||||
.await
|
||||
.is_err());
|
||||
|
||||
assert!(route
|
||||
.dispatch("/a/b/c".to_string(), Request::default())
|
||||
.dispatch("/a/b/c".to_string(), Request::default(), App::new())
|
||||
.await
|
||||
.is_ok());
|
||||
|
||||
let body = hyper::body::to_bytes(
|
||||
route
|
||||
.dispatch("/a/b/c".to_string(), Request::default())
|
||||
.dispatch("/a/b/c".to_string(), Request::default(), App::new())
|
||||
.await
|
||||
.unwrap()
|
||||
.1
|
||||
@@ -244,7 +266,7 @@ mod tests {
|
||||
assert_eq!(body, "hello, world".as_bytes());
|
||||
|
||||
let status = route
|
||||
.dispatch("/a/b/c".to_string(), Request::default())
|
||||
.dispatch("/a/b/c".to_string(), Request::default(), App::new())
|
||||
.await
|
||||
.unwrap()
|
||||
.1
|
||||
@@ -258,16 +280,21 @@ mod tests {
|
||||
async fn test_router() {
|
||||
use super::Router;
|
||||
use crate::{
|
||||
app::App,
|
||||
handler::{Handler, Params},
|
||||
HTTPResult,
|
||||
};
|
||||
use http::{Method, Request, Response};
|
||||
use hyper::Body;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct State;
|
||||
|
||||
async fn handler_dynamic(
|
||||
req: Request<Body>,
|
||||
_response: Option<Response<Body>>,
|
||||
params: Params,
|
||||
_app: App<State>,
|
||||
) -> HTTPResult {
|
||||
return Ok((
|
||||
req,
|
||||
@@ -282,6 +309,7 @@ mod tests {
|
||||
req: Request<Body>,
|
||||
_response: Option<Response<Body>>,
|
||||
_params: Params,
|
||||
_app: App<State>,
|
||||
) -> HTTPResult {
|
||||
return Ok((
|
||||
req,
|
||||
@@ -299,7 +327,7 @@ mod tests {
|
||||
Method::GET,
|
||||
"/a/b/c".to_string(),
|
||||
Handler::new(
|
||||
|req, resp, params| Box::pin(handler_static(req, resp, params)),
|
||||
|req, resp, params, app| Box::pin(handler_static(req, resp, params, app)),
|
||||
None,
|
||||
),
|
||||
);
|
||||
@@ -308,7 +336,7 @@ mod tests {
|
||||
Method::GET,
|
||||
"/c/b/a/:name".to_string(),
|
||||
Handler::new(
|
||||
|req, resp, params| Box::pin(handler_dynamic(req, resp, params)),
|
||||
|req, resp, params, app| Box::pin(handler_dynamic(req, resp, params, app)),
|
||||
None,
|
||||
),
|
||||
);
|
||||
@@ -320,6 +348,7 @@ mod tests {
|
||||
.method(Method::GET)
|
||||
.body(Body::default())
|
||||
.unwrap(),
|
||||
App::new(),
|
||||
)
|
||||
.await;
|
||||
assert!(response.is_ok());
|
||||
@@ -337,6 +366,7 @@ mod tests {
|
||||
.method(Method::GET)
|
||||
.body(Body::default())
|
||||
.unwrap(),
|
||||
App::new(),
|
||||
)
|
||||
.await;
|
||||
assert!(response.is_ok());
|
||||
@@ -353,6 +383,7 @@ mod tests {
|
||||
.method(Method::GET)
|
||||
.body(Body::default())
|
||||
.unwrap(),
|
||||
App::new(),
|
||||
)
|
||||
.await;
|
||||
assert!(response.is_err());
|
||||
|
||||
Reference in New Issue
Block a user