1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-01-18 05:41:50 +01:00

move state to request object

This commit is contained in:
Nikolay Kim 2017-11-26 21:18:38 -08:00
parent 8e0a7f44d4
commit 5a3b6638a7
12 changed files with 81 additions and 71 deletions

View File

@ -12,7 +12,7 @@ use actix_web::middlewares::RequestSession;
use futures::stream::{once, Once}; use futures::stream::{once, Once};
/// somple handle /// somple handle
fn index(mut req: HttpRequest, state: &()) -> Result<HttpResponse> { fn index(mut req: HttpRequest) -> Result<HttpResponse> {
println!("{:?}", req); println!("{:?}", req);
if let Ok(ch) = req.payload_mut().readany() { if let Ok(ch) = req.payload_mut().readany() {
if let futures::Async::Ready(Some(d)) = ch { if let futures::Async::Ready(Some(d)) = ch {
@ -32,7 +32,7 @@ fn index(mut req: HttpRequest, state: &()) -> Result<HttpResponse> {
} }
/// somple handle /// somple handle
fn index_async(req: HttpRequest, state: &()) -> Once<actix_web::Frame, Error> fn index_async(req: HttpRequest) -> Once<actix_web::Frame, Error>
{ {
println!("{:?}", req); println!("{:?}", req);
@ -44,7 +44,7 @@ fn index_async(req: HttpRequest, state: &()) -> Once<actix_web::Frame, Error>
} }
/// handle with path parameters like `/user/{name}/` /// handle with path parameters like `/user/{name}/`
fn with_param(req: HttpRequest, state: &()) -> Result<HttpResponse> fn with_param(req: HttpRequest) -> Result<HttpResponse>
{ {
println!("{:?}", req); println!("{:?}", req);
@ -75,7 +75,7 @@ fn main() {
// async handler // async handler
.resource("/async/{name}", |r| r.async(Method::GET, index_async)) .resource("/async/{name}", |r| r.async(Method::GET, index_async))
// redirect // redirect
.resource("/", |r| r.handler(Method::GET, |req, _| { .resource("/", |r| r.handler(Method::GET, |req| {
println!("{:?}", req); println!("{:?}", req);
Ok(httpcodes::HTTPFound Ok(httpcodes::HTTPFound

View File

@ -1,3 +1,4 @@
#![cfg_attr(feature="cargo-clippy", allow(needless_pass_by_value))]
//! There are two level of statfulness in actix-web. Application has state //! There are two level of statfulness in actix-web. Application has state
//! that is shared across all handlers within same Application. //! that is shared across all handlers within same Application.
//! And individual handler can have state. //! And individual handler can have state.
@ -15,11 +16,11 @@ struct AppState {
} }
/// somple handle /// somple handle
fn index(req: HttpRequest, state: &AppState) -> HttpResponse { fn index(req: HttpRequest<AppState>) -> HttpResponse {
println!("{:?}", req); println!("{:?}", req);
state.counter.set(state.counter.get() + 1); req.state().counter.set(req.state().counter.get() + 1);
httpcodes::HTTPOk.with_body( httpcodes::HTTPOk.with_body(
format!("Num of requests: {}", state.counter.get())) format!("Num of requests: {}", req.state().counter.get()))
} }
/// `MyWebSocket` counts how many messages it receives from peer, /// `MyWebSocket` counts how many messages it receives from peer,
@ -36,7 +37,7 @@ impl Route for MyWebSocket {
/// Shared application state /// Shared application state
type State = AppState; type State = AppState;
fn request(mut req: HttpRequest, ctx: &mut HttpContext<Self>) -> RouteResult<Self> fn request(mut req: HttpRequest<AppState>, ctx: &mut HttpContext<Self>) -> RouteResult<Self>
{ {
let resp = ws::handshake(&req)?; let resp = ws::handshake(&req)?;
ctx.start(resp); ctx.start(resp);
@ -44,6 +45,7 @@ impl Route for MyWebSocket {
Reply::async(MyWebSocket{counter: 0}) Reply::async(MyWebSocket{counter: 0})
} }
} }
impl StreamHandler<ws::Message> for MyWebSocket {} impl StreamHandler<ws::Message> for MyWebSocket {}
impl Handler<ws::Message> for MyWebSocket { impl Handler<ws::Message> for MyWebSocket {
fn handle(&mut self, msg: ws::Message, ctx: &mut HttpContext<Self>) fn handle(&mut self, msg: ws::Message, ctx: &mut HttpContext<Self>)
@ -64,7 +66,6 @@ impl Handler<ws::Message> for MyWebSocket {
} }
} }
fn main() { fn main() {
::std::env::set_var("RUST_LOG", "actix_web=info"); ::std::env::set_var("RUST_LOG", "actix_web=info");
let _ = env_logger::init(); let _ = env_logger::init();

View File

@ -24,19 +24,21 @@ pub struct Application<S> {
impl<S: 'static> Application<S> { impl<S: 'static> Application<S> {
fn run(&self, mut req: HttpRequest) -> Task { fn run(&self, req: HttpRequest) -> Task {
let mut req = req.with_state(Rc::clone(&self.state));
if let Some((params, h)) = self.router.recognize(req.path()) { if let Some((params, h)) = self.router.recognize(req.path()) {
if let Some(params) = params { if let Some(params) = params {
req.set_match_info(params); req.set_match_info(params);
} }
h.handle(req, Rc::clone(&self.state)) h.handle(req)
} else { } else {
for (prefix, handler) in &self.handlers { for (prefix, handler) in &self.handlers {
if req.path().starts_with(prefix) { if req.path().starts_with(prefix) {
return handler.handle(req, Rc::clone(&self.state)) return handler.handle(req)
} }
} }
self.default.handle(req, Rc::clone(&self.state)) self.default.handle(req)
} }
} }
} }
@ -146,7 +148,7 @@ impl<S> ApplicationBuilder<S> where S: 'static {
/// let app = Application::default("/") /// let app = Application::default("/")
/// .resource("/test", |r| { /// .resource("/test", |r| {
/// r.get::<MyRoute>(); /// r.get::<MyRoute>();
/// r.handler(Method::HEAD, |req, state| { /// r.handler(Method::HEAD, |req| {
/// Ok(httpcodes::HTTPMethodNotAllowed) /// Ok(httpcodes::HTTPMethodNotAllowed)
/// }); /// });
/// }) /// })
@ -190,7 +192,7 @@ impl<S> ApplicationBuilder<S> where S: 'static {
/// ///
/// fn main() { /// fn main() {
/// let app = Application::default("/") /// let app = Application::default("/")
/// .handler("/test", |req, state| { /// .handler("/test", |req| {
/// match *req.method() { /// match *req.method() {
/// Method::GET => httpcodes::HTTPOk, /// Method::GET => httpcodes::HTTPOk,
/// Method::POST => httpcodes::HTTPMethodNotAllowed, /// Method::POST => httpcodes::HTTPMethodNotAllowed,
@ -201,7 +203,7 @@ impl<S> ApplicationBuilder<S> where S: 'static {
/// } /// }
/// ``` /// ```
pub fn handler<P, F, R>(&mut self, path: P, handler: F) -> &mut Self pub fn handler<P, F, R>(&mut self, path: P, handler: F) -> &mut Self
where F: Fn(HttpRequest, &S) -> R + 'static, where F: Fn(HttpRequest<S>) -> R + 'static,
R: Into<HttpResponse> + 'static, R: Into<HttpResponse> + 'static,
P: Into<String>, P: Into<String>,
{ {

View File

@ -29,7 +29,6 @@ pub struct HttpContext<A> where A: Actor<Context=HttpContext<A>> + Route,
address: ActorAddressCell<A>, address: ActorAddressCell<A>,
stream: VecDeque<Frame>, stream: VecDeque<Frame>,
wait: ActorWaitCell<A>, wait: ActorWaitCell<A>,
app_state: Rc<<A as Route>::State>,
disconnected: bool, disconnected: bool,
} }
@ -102,10 +101,9 @@ impl<A> AsyncContextApi<A> for HttpContext<A> where A: Actor<Context=Self> + Rou
} }
} }
impl<A> HttpContext<A> where A: Actor<Context=Self> + Route { impl<A> Default for HttpContext<A> where A: Actor<Context=Self> + Route {
pub fn new(state: Rc<<A as Route>::State>) -> HttpContext<A> fn default() -> HttpContext<A> {
{
HttpContext { HttpContext {
act: None, act: None,
state: ActorState::Started, state: ActorState::Started,
@ -114,10 +112,12 @@ impl<A> HttpContext<A> where A: Actor<Context=Self> + Route {
address: ActorAddressCell::default(), address: ActorAddressCell::default(),
wait: ActorWaitCell::default(), wait: ActorWaitCell::default(),
stream: VecDeque::new(), stream: VecDeque::new(),
app_state: state,
disconnected: false, disconnected: false,
} }
} }
}
impl<A> HttpContext<A> where A: Actor<Context=Self> + Route {
pub(crate) fn set_actor(&mut self, act: A) { pub(crate) fn set_actor(&mut self, act: A) {
self.act = Some(act) self.act = Some(act)
@ -126,11 +126,6 @@ impl<A> HttpContext<A> where A: Actor<Context=Self> + Route {
impl<A> HttpContext<A> where A: Actor<Context=Self> + Route { impl<A> HttpContext<A> where A: Actor<Context=Self> + Route {
/// Shared application state
pub fn state(&self) -> &<A as Route>::State {
&self.app_state
}
/// Start response processing /// Start response processing
pub fn start<R: Into<HttpResponse>>(&mut self, response: R) { pub fn start<R: Into<HttpResponse>>(&mut self, response: R) {
self.stream.push_back(Frame::Message(response.into())) self.stream.push_back(Frame::Message(response.into()))

View File

@ -35,9 +35,14 @@ pub(crate) enum Http1Result {
Switch, Switch,
} }
#[derive(Debug)]
enum Item {
Http1(HttpRequest),
Http2,
}
pub(crate) struct Http1<T: AsyncWrite + 'static, H: 'static> { pub(crate) struct Http1<T: AsyncWrite + 'static, H: 'static> {
router: Rc<Vec<H>>, router: Rc<Vec<H>>,
#[allow(dead_code)]
addr: Option<SocketAddr>, addr: Option<SocketAddr>,
stream: H1Writer<T>, stream: H1Writer<T>,
reader: Reader, reader: Reader,
@ -268,12 +273,6 @@ impl<T, H> Http1<T, H>
} }
} }
#[derive(Debug)]
enum Item {
Http1(HttpRequest),
Http2,
}
struct Reader { struct Reader {
h1: bool, h1: bool,
payload: Option<PayloadInfo>, payload: Option<PayloadInfo>,

View File

@ -1,6 +1,5 @@
//! Basic http responses //! Basic http responses
#![allow(non_upper_case_globals)] #![allow(non_upper_case_globals)]
use std::rc::Rc;
use http::StatusCode; use http::StatusCode;
use body::Body; use body::Body;
@ -70,7 +69,7 @@ impl StaticResponse {
} }
impl<S> RouteHandler<S> for StaticResponse { impl<S> RouteHandler<S> for StaticResponse {
fn handle(&self, _: HttpRequest, _: Rc<S>) -> Task { fn handle(&self, _: HttpRequest<S>) -> Task {
Task::reply(HttpResponse::new(self.0, Body::Empty)) Task::reply(HttpResponse::new(self.0, Body::Empty))
} }
} }

View File

@ -48,9 +48,9 @@ impl Default for HttpMessage {
} }
/// An HTTP Request /// An HTTP Request
pub struct HttpRequest(Rc<HttpMessage>); pub struct HttpRequest<S=()>(Rc<HttpMessage>, Rc<S>);
impl HttpRequest { impl HttpRequest<()> {
/// Construct a new Request. /// Construct a new Request.
#[inline] #[inline]
pub fn new(method: Method, path: String, version: Version, pub fn new(method: Method, path: String, version: Version,
@ -69,20 +69,36 @@ impl HttpRequest {
addr: None, addr: None,
payload: payload, payload: payload,
extensions: Extensions::new(), extensions: Extensions::new(),
}) }),
Rc::new(())
) )
} }
/// Construct request for error response.
pub(crate) fn for_error() -> HttpRequest { pub(crate) fn for_error() -> HttpRequest {
HttpRequest(Rc::new(HttpMessage::default())) HttpRequest(Rc::new(HttpMessage::default()), Rc::new(()))
} }
/// Construct new http request with state.
pub(crate) fn with_state<S>(self, state: Rc<S>) -> HttpRequest<S> {
HttpRequest(self.0, state)
}
}
impl<S> HttpRequest<S> {
/// get mutable reference for inner message
fn as_mut(&mut self) -> &mut HttpMessage { fn as_mut(&mut self) -> &mut HttpMessage {
let r: &HttpMessage = self.0.as_ref(); let r: &HttpMessage = self.0.as_ref();
#[allow(mutable_transmutes)] #[allow(mutable_transmutes)]
unsafe{mem::transmute(r)} unsafe{mem::transmute(r)}
} }
/// Shared application state
pub fn state(&self) -> &S {
&self.1
}
/// Protocol extensions. /// Protocol extensions.
#[inline] #[inline]
pub fn extensions(&mut self) -> &mut Extensions { pub fn extensions(&mut self) -> &mut Extensions {
@ -317,13 +333,13 @@ impl HttpRequest {
} }
} }
impl Clone for HttpRequest { impl<S> Clone for HttpRequest<S> {
fn clone(&self) -> HttpRequest { fn clone(&self) -> HttpRequest<S> {
HttpRequest(Rc::clone(&self.0)) HttpRequest(Rc::clone(&self.0), Rc::clone(&self.1))
} }
} }
impl fmt::Debug for HttpRequest { impl<S> fmt::Debug for HttpRequest<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let res = write!(f, "\nHttpRequest {:?} {}:{}\n", let res = write!(f, "\nHttpRequest {:?} {}:{}\n",
self.0.version, self.0.method, self.0.path); self.0.version, self.0.method, self.0.path);

View File

@ -1,4 +1,3 @@
use std::rc::Rc;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::collections::HashMap; use std::collections::HashMap;
@ -64,7 +63,7 @@ impl<S> Resource<S> where S: 'static {
/// Register handler for specified method. /// Register handler for specified method.
pub fn handler<F, R>(&mut self, method: Method, handler: F) pub fn handler<F, R>(&mut self, method: Method, handler: F)
where F: Fn(HttpRequest, &S) -> Result<R> + 'static, where F: Fn(HttpRequest<S>) -> Result<R> + 'static,
R: Into<HttpResponse> + 'static, R: Into<HttpResponse> + 'static,
{ {
self.routes.insert(method, Box::new(FnHandler::new(handler))); self.routes.insert(method, Box::new(FnHandler::new(handler)));
@ -72,7 +71,7 @@ impl<S> Resource<S> where S: 'static {
/// Register async handler for specified method. /// Register async handler for specified method.
pub fn async<F, R>(&mut self, method: Method, handler: F) pub fn async<F, R>(&mut self, method: Method, handler: F)
where F: Fn(HttpRequest, &S) -> R + 'static, where F: Fn(HttpRequest<S>) -> R + 'static,
R: Stream<Item=Frame, Error=Error> + 'static, R: Stream<Item=Frame, Error=Error> + 'static,
{ {
self.routes.insert(method, Box::new(StreamHandler::new(handler))); self.routes.insert(method, Box::new(StreamHandler::new(handler)));
@ -125,11 +124,11 @@ impl<S> Resource<S> where S: 'static {
impl<S: 'static> RouteHandler<S> for Resource<S> { impl<S: 'static> RouteHandler<S> for Resource<S> {
fn handle(&self, req: HttpRequest, state: Rc<S>) -> Task { fn handle(&self, req: HttpRequest<S>) -> Task {
if let Some(handler) = self.routes.get(req.method()) { if let Some(handler) = self.routes.get(req.method()) {
handler.handle(req, state) handler.handle(req)
} else { } else {
self.default.handle(req, state) self.default.handle(req)
} }
} }
} }

View File

@ -33,7 +33,7 @@ impl Frame {
#[allow(unused_variables)] #[allow(unused_variables)]
pub trait RouteHandler<S>: 'static { pub trait RouteHandler<S>: 'static {
/// Handle request /// Handle request
fn handle(&self, req: HttpRequest, state: Rc<S>) -> Task; fn handle(&self, req: HttpRequest<S>) -> Task;
/// Set route prefix /// Set route prefix
fn set_prefix(&mut self, prefix: String) {} fn set_prefix(&mut self, prefix: String) {}
@ -46,11 +46,11 @@ pub type RouteResult<T> = Result<Reply<T>, Error>;
#[allow(unused_variables)] #[allow(unused_variables)]
pub trait Route: Actor { pub trait Route: Actor {
/// Shared state. State is shared with all routes within same application /// Shared state. State is shared with all routes within same application
/// and could be accessed with `HttpContext::state()` method. /// and could be accessed with `HttpRequest::state()` method.
type State; type State;
/// Handle `EXPECT` header. By default respones with `HTTP/1.1 100 Continue` /// Handle `EXPECT` header. By default respones with `HTTP/1.1 100 Continue`
fn expect(req: &mut HttpRequest, ctx: &mut Self::Context) -> Result<(), Error> fn expect(req: &mut HttpRequest<Self::State>, ctx: &mut Self::Context) -> Result<(), Error>
where Self: Actor<Context=HttpContext<Self>> where Self: Actor<Context=HttpContext<Self>>
{ {
// handle expect header only for HTTP/1.1 // handle expect header only for HTTP/1.1
@ -80,7 +80,7 @@ pub trait Route: Actor {
/// request/response or websocket connection. /// request/response or websocket connection.
/// In that case `HttpContext::start` and `HttpContext::write` has to be used /// In that case `HttpContext::start` and `HttpContext::write` has to be used
/// for writing response. /// for writing response.
fn request(req: HttpRequest, ctx: &mut Self::Context) -> RouteResult<Self>; fn request(req: HttpRequest<Self::State>, ctx: &mut Self::Context) -> RouteResult<Self>;
/// This method creates `RouteFactory` for this actor. /// This method creates `RouteFactory` for this actor.
fn factory() -> RouteFactory<Self, Self::State> { fn factory() -> RouteFactory<Self, Self::State> {
@ -95,8 +95,8 @@ impl<A, S> RouteHandler<S> for RouteFactory<A, S>
where A: Actor<Context=HttpContext<A>> + Route<State=S>, where A: Actor<Context=HttpContext<A>> + Route<State=S>,
S: 'static S: 'static
{ {
fn handle(&self, mut req: HttpRequest, state: Rc<A::State>) -> Task { fn handle(&self, mut req: HttpRequest<A::State>) -> Task {
let mut ctx = HttpContext::new(state); let mut ctx = HttpContext::default();
// handle EXPECT header // handle EXPECT header
if req.headers().contains_key(header::EXPECT) { if req.headers().contains_key(header::EXPECT) {
@ -114,7 +114,7 @@ impl<A, S> RouteHandler<S> for RouteFactory<A, S>
/// Fn() route handler /// Fn() route handler
pub(crate) pub(crate)
struct FnHandler<S, R, F> struct FnHandler<S, R, F>
where F: Fn(HttpRequest, &S) -> R + 'static, where F: Fn(HttpRequest<S>) -> R + 'static,
R: Into<HttpResponse>, R: Into<HttpResponse>,
S: 'static, S: 'static,
{ {
@ -123,7 +123,7 @@ struct FnHandler<S, R, F>
} }
impl<S, R, F> FnHandler<S, R, F> impl<S, R, F> FnHandler<S, R, F>
where F: Fn(HttpRequest, &S) -> R + 'static, where F: Fn(HttpRequest<S>) -> R + 'static,
R: Into<HttpResponse> + 'static, R: Into<HttpResponse> + 'static,
S: 'static, S: 'static,
{ {
@ -133,19 +133,19 @@ impl<S, R, F> FnHandler<S, R, F>
} }
impl<S, R, F> RouteHandler<S> for FnHandler<S, R, F> impl<S, R, F> RouteHandler<S> for FnHandler<S, R, F>
where F: Fn(HttpRequest, &S) -> R + 'static, where F: Fn(HttpRequest<S>) -> R + 'static,
R: Into<HttpResponse> + 'static, R: Into<HttpResponse> + 'static,
S: 'static, S: 'static,
{ {
fn handle(&self, req: HttpRequest, state: Rc<S>) -> Task { fn handle(&self, req: HttpRequest<S>) -> Task {
Task::reply((self.f)(req, &state).into()) Task::reply((self.f)(req).into())
} }
} }
/// Async route handler /// Async route handler
pub(crate) pub(crate)
struct StreamHandler<S, R, F> struct StreamHandler<S, R, F>
where F: Fn(HttpRequest, &S) -> R + 'static, where F: Fn(HttpRequest<S>) -> R + 'static,
R: Stream<Item=Frame, Error=Error> + 'static, R: Stream<Item=Frame, Error=Error> + 'static,
S: 'static, S: 'static,
{ {
@ -154,7 +154,7 @@ struct StreamHandler<S, R, F>
} }
impl<S, R, F> StreamHandler<S, R, F> impl<S, R, F> StreamHandler<S, R, F>
where F: Fn(HttpRequest, &S) -> R + 'static, where F: Fn(HttpRequest<S>) -> R + 'static,
R: Stream<Item=Frame, Error=Error> + 'static, R: Stream<Item=Frame, Error=Error> + 'static,
S: 'static, S: 'static,
{ {
@ -164,11 +164,11 @@ impl<S, R, F> StreamHandler<S, R, F>
} }
impl<S, R, F> RouteHandler<S> for StreamHandler<S, R, F> impl<S, R, F> RouteHandler<S> for StreamHandler<S, R, F>
where F: Fn(HttpRequest, &S) -> R + 'static, where F: Fn(HttpRequest<S>) -> R + 'static,
R: Stream<Item=Frame, Error=Error> + 'static, R: Stream<Item=Frame, Error=Error> + 'static,
S: 'static, S: 'static,
{ {
fn handle(&self, req: HttpRequest, state: Rc<S>) -> Task { fn handle(&self, req: HttpRequest<S>) -> Task {
Task::with_stream((self.f)(req, &state)) Task::with_stream((self.f)(req))
} }
} }

View File

@ -3,7 +3,6 @@
//! TODO: needs to re-implement actual files handling, current impl blocks //! TODO: needs to re-implement actual files handling, current impl blocks
use std::io; use std::io;
use std::io::Read; use std::io::Read;
use std::rc::Rc;
use std::fmt::Write; use std::fmt::Write;
use std::fs::{File, DirEntry}; use std::fs::{File, DirEntry};
use std::path::PathBuf; use std::path::PathBuf;
@ -137,7 +136,7 @@ impl<S: 'static> RouteHandler<S> for StaticFiles {
} }
} }
fn handle(&self, req: HttpRequest, _: Rc<S>) -> Task { fn handle(&self, req: HttpRequest<S>) -> Task {
if !self.accessible { if !self.accessible {
Task::reply(HTTPNotFound) Task::reply(HTTPNotFound)
} else { } else {

View File

@ -108,7 +108,7 @@ impl ResponseType for Message {
// /// `protocols` is a sequence of known protocols. On successful handshake, // /// `protocols` is a sequence of known protocols. On successful handshake,
// /// the returned response headers contain the first protocol in this list // /// the returned response headers contain the first protocol in this list
// /// which the server also knows. // /// which the server also knows.
pub fn handshake(req: &HttpRequest) -> Result<HttpResponse, WsHandshakeError> { pub fn handshake<S>(req: &HttpRequest<S>) -> Result<HttpResponse, WsHandshakeError> {
// WebSocket accepts only GET // WebSocket accepts only GET
if *req.method() != Method::GET { if *req.method() != Method::GET {
return Err(WsHandshakeError::GetMethodRequired) return Err(WsHandshakeError::GetMethodRequired)
@ -176,7 +176,7 @@ pub struct WsStream {
} }
impl WsStream { impl WsStream {
pub fn new(req: &mut HttpRequest) -> WsStream { pub fn new<S>(req: &mut HttpRequest<S>) -> WsStream {
WsStream { rx: req.take_payload(), buf: BytesMut::new(), closed: false, error_sent: false } WsStream { rx: req.take_payload(), buf: BytesMut::new(), closed: false, error_sent: false }
} }
} }

View File

@ -16,7 +16,7 @@ fn create_server<T, A>() -> HttpServer<T, A, Application<()>> {
HttpServer::new( HttpServer::new(
vec![Application::default("/") vec![Application::default("/")
.resource("/", |r| .resource("/", |r|
r.handler(Method::GET, |_, _| { r.handler(Method::GET, |_| {
Ok(httpcodes::HTTPOk) Ok(httpcodes::HTTPOk)
})) }))
.finish()]) .finish()])
@ -96,7 +96,7 @@ fn test_middlewares() {
response: act_num2, response: act_num2,
finish: act_num3}) finish: act_num3})
.resource("/", |r| .resource("/", |r|
r.handler(Method::GET, |_, _| { r.handler(Method::GET, |_| {
Ok(httpcodes::HTTPOk) Ok(httpcodes::HTTPOk)
})) }))
.finish()]) .finish()])