From e6d04d24cce00d4f0d08da518325f0ecdf195b5e Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Fri, 1 Mar 2019 23:59:44 -0800 Subject: [PATCH] move fs to separate crate --- Cargo.toml | 6 + Makefile | 14 - actix-web-fs/CHANGES.md | 5 + actix-web-fs/Cargo.toml | 42 +++ actix-web-fs/README.md | 82 +++++ src/fs.rs => actix-web-fs/src/lib.rs | 30 +- examples/basic.rs | 2 +- src/app.rs | 118 ++----- src/framed_app.rs | 240 -------------- src/framed_handler.rs | 379 ---------------------- src/framed_route.rs | 448 --------------------------- src/helpers.rs | 180 ----------- src/lib.rs | 3 +- src/resource.rs | 39 +-- tests/test_server.rs | 2 +- 15 files changed, 184 insertions(+), 1406 deletions(-) delete mode 100644 Makefile create mode 100644 actix-web-fs/CHANGES.md create mode 100644 actix-web-fs/Cargo.toml create mode 100644 actix-web-fs/README.md rename src/fs.rs => actix-web-fs/src/lib.rs (99%) delete mode 100644 src/framed_app.rs delete mode 100644 src/framed_handler.rs delete mode 100644 src/framed_route.rs delete mode 100644 src/helpers.rs diff --git a/Cargo.toml b/Cargo.toml index 6a61c780..e9c298fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,12 @@ codecov = { repository = "actix/actix-web2", branch = "master", service = "githu name = "actix_web" path = "src/lib.rs" +[workspace] +members = [ + ".", + "actix-web-fs", +] + [features] default = ["brotli", "flate2-c"] diff --git a/Makefile b/Makefile deleted file mode 100644 index e3b8b2cf..00000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -.PHONY: default build test doc book clean - -CARGO_FLAGS := --features "$(FEATURES) alpn tls" - -default: test - -build: - cargo build $(CARGO_FLAGS) - -test: build clippy - cargo test $(CARGO_FLAGS) - -doc: build - cargo doc --no-deps $(CARGO_FLAGS) diff --git a/actix-web-fs/CHANGES.md b/actix-web-fs/CHANGES.md new file mode 100644 index 00000000..b93e282a --- /dev/null +++ b/actix-web-fs/CHANGES.md @@ -0,0 +1,5 @@ +# Changes + +## [0.1.0] - 2018-10-x + +* Initial impl diff --git a/actix-web-fs/Cargo.toml b/actix-web-fs/Cargo.toml new file mode 100644 index 00000000..5900a936 --- /dev/null +++ b/actix-web-fs/Cargo.toml @@ -0,0 +1,42 @@ +[package] +name = "actix-web-fs" +version = "0.1.0" +authors = ["Nikolay Kim "] +description = "Static files support for Actix web." +readme = "README.md" +keywords = ["actix", "http", "async", "futures"] +homepage = "https://actix.rs" +repository = "https://github.com/actix/actix-web.git" +documentation = "https://actix.rs/api/actix-web/stable/actix_web/" +categories = ["asynchronous", "web-programming::http-server"] +license = "MIT/Apache-2.0" +edition = "2018" +workspace = ".." + +[lib] +name = "actix_web_fs" +path = "src/lib.rs" + +[dependencies] +actix-web = { path=".." } +actix-http = { git = "https://github.com/actix/actix-http.git" } +actix-service = { git = "https://github.com/actix/actix-net.git" } + +bytes = "0.4" +futures = "0.1" +derive_more = "0.14" +log = "0.4" +mime = "0.3" +mime_guess = "2.0.0-alpha" +percent-encoding = "1.0" +v_htmlescape = "0.4" + +[dev-dependencies] +actix-rt = "0.1.0" +#actix-server = { version="0.2", features=["ssl"] } +actix-server = { git = "https://github.com/actix/actix-net.git", features=["ssl"] } +actix-http = { git = "https://github.com/actix/actix-http.git", features=["ssl"] } +actix-http-test = { git = "https://github.com/actix/actix-http.git", features=["ssl"] } +rand = "0.6" +env_logger = "0.6" +serde_derive = "1.0" diff --git a/actix-web-fs/README.md b/actix-web-fs/README.md new file mode 100644 index 00000000..c7e195de --- /dev/null +++ b/actix-web-fs/README.md @@ -0,0 +1,82 @@ +# Actix web [![Build Status](https://travis-ci.org/actix/actix-web.svg?branch=master)](https://travis-ci.org/actix/actix-web) [![Build status](https://ci.appveyor.com/api/projects/status/kkdb4yce7qhm5w85/branch/master?svg=true)](https://ci.appveyor.com/project/fafhrd91/actix-web-hdy9d/branch/master) [![codecov](https://codecov.io/gh/actix/actix-web/branch/master/graph/badge.svg)](https://codecov.io/gh/actix/actix-web) [![crates.io](https://meritbadge.herokuapp.com/actix-web)](https://crates.io/crates/actix-web) [![Join the chat at https://gitter.im/actix/actix](https://badges.gitter.im/actix/actix.svg)](https://gitter.im/actix/actix?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +Actix web is a simple, pragmatic and extremely fast web framework for Rust. + +* Supported *HTTP/1.x* and [*HTTP/2.0*](https://actix.rs/docs/http2/) protocols +* Streaming and pipelining +* Keep-alive and slow requests handling +* Client/server [WebSockets](https://actix.rs/docs/websockets/) support +* Transparent content compression/decompression (br, gzip, deflate) +* Configurable [request routing](https://actix.rs/docs/url-dispatch/) +* Multipart streams +* Static assets +* SSL support with OpenSSL or `native-tls` +* Middlewares ([Logger, Session, CORS, CSRF, etc](https://actix.rs/docs/middleware/)) +* Includes an asynchronous [HTTP client](https://actix.rs/actix-web/actix_web/client/index.html) +* Built on top of [Actix actor framework](https://github.com/actix/actix) +* Experimental [Async/Await](https://github.com/mehcode/actix-web-async-await) support. + +## Documentation & community resources + +* [User Guide](https://actix.rs/docs/) +* [API Documentation (Development)](https://actix.rs/actix-web/actix_web/) +* [API Documentation (Releases)](https://actix.rs/api/actix-web/stable/actix_web/) +* [Chat on gitter](https://gitter.im/actix/actix) +* Cargo package: [actix-web](https://crates.io/crates/actix-web) +* Minimum supported Rust version: 1.31 or later + +## Example + +```rust +extern crate actix_web; +use actix_web::{http, server, App, Path, Responder}; + +fn index(info: Path<(u32, String)>) -> impl Responder { + format!("Hello {}! id:{}", info.1, info.0) +} + +fn main() { + server::new( + || App::new() + .route("/{id}/{name}/index.html", http::Method::GET, index)) + .bind("127.0.0.1:8080").unwrap() + .run(); +} +``` + +### More examples + +* [Basics](https://github.com/actix/examples/tree/master/basics/) +* [Stateful](https://github.com/actix/examples/tree/master/state/) +* [Protobuf support](https://github.com/actix/examples/tree/master/protobuf/) +* [Multipart streams](https://github.com/actix/examples/tree/master/multipart/) +* [Simple websocket](https://github.com/actix/examples/tree/master/websocket/) +* [Tera](https://github.com/actix/examples/tree/master/template_tera/) / + [Askama](https://github.com/actix/examples/tree/master/template_askama/) templates +* [Diesel integration](https://github.com/actix/examples/tree/master/diesel/) +* [r2d2](https://github.com/actix/examples/tree/master/r2d2/) +* [SSL / HTTP/2.0](https://github.com/actix/examples/tree/master/tls/) +* [Tcp/Websocket chat](https://github.com/actix/examples/tree/master/websocket-chat/) +* [Json](https://github.com/actix/examples/tree/master/json/) + +You may consider checking out +[this directory](https://github.com/actix/examples/tree/master/) for more examples. + +## Benchmarks + +* [TechEmpower Framework Benchmark](https://www.techempower.com/benchmarks/#section=data-r16&hw=ph&test=plaintext) + +## License + +This project is licensed under either of + +* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)) +* MIT license ([LICENSE-MIT](LICENSE-MIT) or [http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT)) + +at your option. + +## Code of Conduct + +Contribution to the actix-web crate is organized under the terms of the +Contributor Covenant, the maintainer of actix-web, @fafhrd91, promises to +intervene to uphold that code of conduct. diff --git a/src/fs.rs b/actix-web-fs/src/lib.rs similarity index 99% rename from src/fs.rs rename to actix-web-fs/src/lib.rs index 3c83af6e..c2ac5f3a 100644 --- a/src/fs.rs +++ b/actix-web-fs/src/lib.rs @@ -27,15 +27,14 @@ use actix_http::http::header::{ }; use actix_http::http::{ContentEncoding, Method, StatusCode}; use actix_http::{HttpMessage, Response}; +use actix_service::boxed::BoxedNewService; use actix_service::{NewService, Service}; +use actix_web::{ + blocking, FromRequest, HttpRequest, Responder, ServiceRequest, ServiceResponse, +}; use futures::future::{err, ok, FutureResult}; -use crate::blocking; -use crate::handler::FromRequest; -use crate::helpers::HttpDefaultNewService; -use crate::request::HttpRequest; -use crate::responder::Responder; -use crate::service::{ServiceRequest, ServiceResponse}; +type HttpNewService

= BoxedNewService<(), ServiceRequest

, ServiceResponse, (), ()>; ///Describes `StaticFiles` configiration /// @@ -101,6 +100,7 @@ pub trait StaticFileConfig: Default { ///[StaticFileConfig](trait.StaticFileConfig.html) #[derive(Default)] pub struct DefaultConfig; + impl StaticFileConfig for DefaultConfig {} /// Return the MIME type associated with a filename extension (case-insensitive). @@ -716,9 +716,7 @@ pub struct StaticFiles { directory: PathBuf, index: Option, show_index: bool, - default: Rc< - RefCell, ServiceResponse>>>>, - >, + default: Rc>>>>, renderer: Rc, _chunk_size: usize, _follow_symlinks: bool, @@ -817,9 +815,7 @@ pub struct StaticFilesService { directory: PathBuf, index: Option, show_index: bool, - default: Rc< - RefCell, ServiceResponse>>>>, - >, + default: Rc>>>>, renderer: Rc, _chunk_size: usize, _follow_symlinks: bool, @@ -838,8 +834,8 @@ impl Service for StaticFilesService { fn call(&mut self, req: Self::Request) -> Self::Future { let mut req = req; - let real_path = match PathBuf::from_request(&mut req).poll() { - Ok(Async::Ready(item)) => item, + let real_path = match PathBufWrp::from_request(&mut req).poll() { + Ok(Async::Ready(item)) => item.0, Ok(Async::NotReady) => unreachable!(), Err(e) => return err(Error::from(e)), }; @@ -888,7 +884,9 @@ impl Service for StaticFilesService { } } -impl

FromRequest

for PathBuf { +struct PathBufWrp(PathBuf); + +impl

FromRequest

for PathBufWrp { type Error = UriSegmentError; type Future = FutureResult; @@ -917,7 +915,7 @@ impl

FromRequest

for PathBuf { } } - ok(buf) + ok(PathBufWrp(buf)) } } diff --git a/examples/basic.rs b/examples/basic.rs index 9f4701eb..a18581f9 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -2,7 +2,7 @@ use futures::IntoFuture; use actix_http::{h1, http::Method, Response}; use actix_server::Server; -use actix_web2::{middleware, App, Error, HttpRequest, Resource}; +use actix_web::{middleware, App, Error, HttpRequest, Resource}; fn index(req: HttpRequest) -> &'static str { println!("REQ: {:?}", req); diff --git a/src/app.rs b/src/app.rs index 6ed9b144..7c077706 100644 --- a/src/app.rs +++ b/src/app.rs @@ -5,6 +5,7 @@ use std::rc::Rc; use actix_http::body::{Body, MessageBody}; use actix_http::{Extensions, PayloadStream, Request, Response}; use actix_router::{Path, ResourceDef, ResourceInfo, Router, Url}; +use actix_service::boxed::{self, BoxedNewService, BoxedService}; use actix_service::{ AndThenNewService, ApplyNewService, IntoNewService, IntoNewTransform, NewService, NewTransform, Service, @@ -12,13 +13,12 @@ use actix_service::{ use futures::future::{ok, Either, FutureResult}; use futures::{Async, Future, IntoFuture, Poll}; -use crate::helpers::{ - BoxedHttpNewService, BoxedHttpService, DefaultNewService, HttpDefaultNewService, -}; use crate::resource::Resource; use crate::service::{ServiceRequest, ServiceResponse}; use crate::state::{State, StateFactory, StateFactoryResult}; +type HttpService

= BoxedService, ServiceResponse, ()>; +type HttpNewService

= BoxedNewService<(), ServiceRequest

, ServiceResponse, (), ()>; type BoxedResponse = Box>; pub trait HttpServiceFactory { @@ -31,18 +31,9 @@ pub trait HttpServiceFactory { /// Application builder pub struct App { - services: Vec<( - ResourceDef, - BoxedHttpNewService, ServiceResponse>, - )>, - default: Option, ServiceResponse>>>, - defaults: Vec< - Rc< - RefCell< - Option, ServiceResponse>>>, - >, - >, - >, + services: Vec<(ResourceDef, HttpNewService

)>, + default: Option>>, + defaults: Vec>>>>>, endpoint: T, factory_ref: Rc>>>, extensions: Extensions, @@ -181,10 +172,8 @@ where let rdef = ResourceDef::new(path); let resource = f(Resource::new()); self.defaults.push(resource.get_default()); - self.services.push(( - rdef, - Box::new(HttpNewService::new(resource.into_new_service())), - )); + self.services + .push((rdef, boxed::new_service(resource.into_new_service()))); self } @@ -203,9 +192,9 @@ where > + 'static, { // create and configure default resource - self.default = Some(Rc::new(Box::new(DefaultNewService::new( - f(Resource::new()).into_new_service(), - )))); + self.default = Some(Rc::new(boxed::new_service( + f(Resource::new()).into_new_service().map_init_err(|_| ()), + ))); self } @@ -223,7 +212,7 @@ where { self.services.push(( rdef.into(), - Box::new(HttpNewService::new(factory.into_new_service())), + boxed::new_service(factory.into_new_service().map_init_err(|_| ())), )); self } @@ -422,15 +411,10 @@ impl

Service for AppStateService

{ } pub struct AppFactory

{ - services: Rc< - Vec<( - ResourceDef, - BoxedHttpNewService, ServiceResponse>, - )>, - >, + services: Rc)>>, } -impl

NewService for AppFactory

{ +impl NewService for AppFactory

{ type Request = ServiceRequest

; type Response = ServiceResponse; type Error = (); @@ -454,8 +438,7 @@ impl

NewService for AppFactory

{ } } -type HttpServiceFut

= - Box, ServiceResponse>, Error = ()>>; +type HttpServiceFut

= Box, Error = ()>>; /// Create app service #[doc(hidden)] @@ -465,10 +448,7 @@ pub struct CreateAppService

{ enum CreateAppServiceItem

{ Future(Option, HttpServiceFut

), - Service( - ResourceDef, - BoxedHttpService, ServiceResponse>, - ), + Service(ResourceDef, HttpService

), } impl

Future for CreateAppService

{ @@ -522,7 +502,7 @@ impl

Future for CreateAppService

{ } pub struct AppService

{ - router: Router, ServiceResponse>>, + router: Router>, ready: Option<(ServiceRequest

, ResourceInfo)>, } @@ -561,68 +541,6 @@ impl Future for AppServiceResponse { } } -struct HttpNewService>>(T); - -impl HttpNewService -where - T: NewService, Response = ServiceResponse, Error = ()>, - T::Future: 'static, - ::Future: 'static, -{ - pub fn new(service: T) -> Self { - HttpNewService(service) - } -} - -impl NewService for HttpNewService -where - T: NewService, Response = ServiceResponse, Error = ()>, - T::Future: 'static, - T::Service: 'static, - ::Future: 'static, -{ - type Request = ServiceRequest

; - type Response = ServiceResponse; - type Error = (); - type InitError = (); - type Service = BoxedHttpService, Self::Response>; - type Future = Box>; - - fn new_service(&self, _: &()) -> Self::Future { - Box::new(self.0.new_service(&()).map_err(|_| ()).and_then(|service| { - let service: BoxedHttpService<_, _> = Box::new(HttpServiceWrapper { - service, - _t: PhantomData, - }); - Ok(service) - })) - } -} - -struct HttpServiceWrapper { - service: T, - _t: PhantomData<(P,)>, -} - -impl Service for HttpServiceWrapper -where - T::Future: 'static, - T: Service, Response = ServiceResponse, Error = ()>, -{ - type Request = ServiceRequest

; - type Response = ServiceResponse; - type Error = (); - type Future = BoxedResponse; - - fn poll_ready(&mut self) -> Poll<(), Self::Error> { - self.service.poll_ready().map_err(|_| ()) - } - - fn call(&mut self, req: ServiceRequest

) -> Self::Future { - Box::new(self.service.call(req)) - } -} - #[doc(hidden)] pub struct AppEntry

{ factory: Rc>>>, @@ -634,7 +552,7 @@ impl

AppEntry

{ } } -impl

NewService for AppEntry

{ +impl NewService for AppEntry

{ type Request = ServiceRequest

; type Response = ServiceResponse; type Error = (); diff --git a/src/framed_app.rs b/src/framed_app.rs deleted file mode 100644 index ba925414..00000000 --- a/src/framed_app.rs +++ /dev/null @@ -1,240 +0,0 @@ -use std::marker::PhantomData; -use std::rc::Rc; - -use actix_codec::Framed; -use actix_http::h1::Codec; -use actix_http::{Request, Response, SendResponse}; -use actix_router::{Path, Router, Url}; -use actix_service::{IntoNewService, NewService, Service}; -use actix_utils::cloneable::CloneableService; -use futures::{Async, Future, Poll}; -use tokio_io::{AsyncRead, AsyncWrite}; - -use crate::app::{HttpServiceFactory, State}; -use crate::framed_handler::FramedRequest; -use crate::helpers::{BoxedHttpNewService, BoxedHttpService, HttpNewService}; -use crate::request::Request as WebRequest; - -pub type FRequest = (Request, Framed); -type BoxedResponse = Box>; - -/// Application builder -pub struct FramedApp { - services: Vec<(String, BoxedHttpNewService, ()>)>, - state: State, -} - -impl FramedApp { - pub fn new() -> Self { - FramedApp { - services: Vec::new(), - state: State::new(()), - } - } -} - -impl FramedApp { - pub fn with(state: S) -> FramedApp { - FramedApp { - services: Vec::new(), - state: State::new(state), - } - } - - pub fn service(mut self, factory: U) -> Self - where - U: HttpServiceFactory, - U::Factory: NewService, Response = ()> + 'static, - ::Future: 'static, - ::Service: Service>, - <::Service as Service>::Future: 'static, - { - let path = factory.path().to_string(); - self.services.push(( - path, - Box::new(HttpNewService::new(factory.create(self.state.clone()))), - )); - self - } - - pub fn register_service(&mut self, factory: U) - where - U: HttpServiceFactory, - U::Factory: NewService, Response = ()> + 'static, - ::Future: 'static, - ::Service: Service>, - <::Service as Service>::Future: 'static, - { - let path = factory.path().to_string(); - self.services.push(( - path, - Box::new(HttpNewService::new(factory.create(self.state.clone()))), - )); - } -} - -impl IntoNewService> for FramedApp -where - T: AsyncRead + AsyncWrite, -{ - fn into_new_service(self) -> FramedAppFactory { - FramedAppFactory { - state: self.state, - services: Rc::new(self.services), - _t: PhantomData, - } - } -} - -#[derive(Clone)] -pub struct FramedAppFactory { - state: State, - services: Rc, ()>)>>, - _t: PhantomData, -} - -impl NewService for FramedAppFactory -where - T: AsyncRead + AsyncWrite, -{ - type Request = FRequest; - type Response = (); - type Error = (); - type InitError = (); - type Service = CloneableService>; - type Future = CreateService; - - fn new_service(&self) -> Self::Future { - CreateService { - fut: self - .services - .iter() - .map(|(path, service)| { - CreateServiceItem::Future(Some(path.clone()), service.new_service()) - }) - .collect(), - state: self.state.clone(), - } - } -} - -#[doc(hidden)] -pub struct CreateService { - fut: Vec>, - state: State, -} - -enum CreateServiceItem { - Future( - Option, - Box, ()>, Error = ()>>, - ), - Service(String, BoxedHttpService, ()>), -} - -impl Future for CreateService -where - T: AsyncRead + AsyncWrite, -{ - type Item = CloneableService>; - type Error = (); - - fn poll(&mut self) -> Poll { - let mut done = true; - - // poll http services - for item in &mut self.fut { - let res = match item { - CreateServiceItem::Future(ref mut path, ref mut fut) => { - match fut.poll()? { - Async::Ready(service) => Some((path.take().unwrap(), service)), - Async::NotReady => { - done = false; - None - } - } - } - CreateServiceItem::Service(_, _) => continue, - }; - - if let Some((path, service)) = res { - *item = CreateServiceItem::Service(path, service); - } - } - - if done { - let router = self - .fut - .drain(..) - .fold(Router::build(), |mut router, item| { - match item { - CreateServiceItem::Service(path, service) => { - router.path(&path, service) - } - CreateServiceItem::Future(_, _) => unreachable!(), - } - router - }); - Ok(Async::Ready(CloneableService::new(FramedAppService { - router: router.finish(), - state: self.state.clone(), - // default: self.default.take().expect("something is wrong"), - }))) - } else { - Ok(Async::NotReady) - } - } -} - -pub struct FramedAppService { - state: State, - router: Router, ()>>, -} - -impl Service for FramedAppService -where - T: AsyncRead + AsyncWrite, -{ - type Request = FRequest; - type Response = (); - type Error = (); - type Future = BoxedResponse; - - fn poll_ready(&mut self) -> Poll<(), Self::Error> { - // let mut ready = true; - // for service in &mut self.services { - // if let Async::NotReady = service.poll_ready()? { - // ready = false; - // } - // } - // if ready { - // Ok(Async::Ready(())) - // } else { - // Ok(Async::NotReady) - // } - Ok(Async::Ready(())) - } - - fn call(&mut self, (req, framed): (Request, Framed)) -> Self::Future { - let mut path = Path::new(Url::new(req.uri().clone())); - - if let Some((srv, _info)) = self.router.recognize_mut(&mut path) { - return srv.call(FramedRequest::new( - WebRequest::new(self.state.clone(), req, path), - framed, - )); - } - // for item in &mut self.services { - // req = match item.handle(req) { - // Ok(fut) => return fut, - // Err(req) => req, - // }; - // } - // self.default.call(req) - Box::new( - SendResponse::send(framed, Response::NotFound().finish().into()) - .map(|_| ()) - .map_err(|_| ()), - ) - } -} diff --git a/src/framed_handler.rs b/src/framed_handler.rs deleted file mode 100644 index 109b5f0a..00000000 --- a/src/framed_handler.rs +++ /dev/null @@ -1,379 +0,0 @@ -use std::marker::PhantomData; -use std::rc::Rc; - -use actix_codec::Framed; -use actix_http::{h1::Codec, Error}; -use actix_service::{NewService, Service}; -use futures::future::{ok, FutureResult}; -use futures::{Async, Future, IntoFuture, Poll}; -use log::error; - -use crate::handler::FromRequest; -use crate::request::Request; - -pub struct FramedError { - pub err: Error, - pub framed: Framed, -} - -pub struct FramedRequest { - req: Request, - framed: Framed, - param: Ex, -} - -impl FramedRequest { - pub fn new(req: Request, framed: Framed) -> Self { - Self { - req, - framed, - param: (), - } - } -} - -impl FramedRequest { - pub fn request(&self) -> &Request { - &self.req - } - - pub fn request_mut(&mut self) -> &mut Request { - &mut self.req - } - - pub fn into_parts(self) -> (Request, Framed, Ex) { - (self.req, self.framed, self.param) - } - - pub fn map(self, op: F) -> FramedRequest - where - F: FnOnce(Ex) -> Ex2, - { - FramedRequest { - req: self.req, - framed: self.framed, - param: op(self.param), - } - } -} - -/// T handler converter factory -pub trait FramedFactory: Clone + 'static -where - R: IntoFuture, - E: Into, -{ - fn call(&self, framed: Framed, param: T, extra: Ex) -> R; -} - -#[doc(hidden)] -pub struct FramedHandle -where - F: FramedFactory, - R: IntoFuture, - E: Into, -{ - hnd: F, - _t: PhantomData<(S, Io, Ex, T, R, E)>, -} - -impl FramedHandle -where - F: FramedFactory, - R: IntoFuture, - E: Into, -{ - pub fn new(hnd: F) -> Self { - FramedHandle { - hnd, - _t: PhantomData, - } - } -} -impl NewService for FramedHandle -where - F: FramedFactory, - R: IntoFuture, - E: Into, -{ - type Request = (T, FramedRequest); - type Response = (); - type Error = FramedError; - type InitError = (); - type Service = FramedHandleService; - type Future = FutureResult; - - fn new_service(&self) -> Self::Future { - ok(FramedHandleService { - hnd: self.hnd.clone(), - _t: PhantomData, - }) - } -} - -#[doc(hidden)] -pub struct FramedHandleService -where - F: FramedFactory, - R: IntoFuture, - E: Into, -{ - hnd: F, - _t: PhantomData<(S, Io, Ex, T, R, E)>, -} - -impl Service for FramedHandleService -where - F: FramedFactory, - R: IntoFuture, - E: Into, -{ - type Request = (T, FramedRequest); - type Response = (); - type Error = FramedError; - type Future = FramedHandleServiceResponse; - - fn poll_ready(&mut self) -> Poll<(), Self::Error> { - Ok(Async::Ready(())) - } - - fn call(&mut self, (param, framed): (T, FramedRequest)) -> Self::Future { - let (_, framed, ex) = framed.into_parts(); - FramedHandleServiceResponse { - fut: self.hnd.call(framed, param, ex).into_future(), - _t: PhantomData, - } - } -} - -#[doc(hidden)] -pub struct FramedHandleServiceResponse { - fut: F, - _t: PhantomData, -} - -impl Future for FramedHandleServiceResponse -where - F: Future, - F::Error: Into, -{ - type Item = (); - type Error = FramedError; - - fn poll(&mut self) -> Poll { - match self.fut.poll() { - Ok(Async::NotReady) => Ok(Async::NotReady), - Ok(Async::Ready(res)) => Ok(Async::Ready(res.into())), - Err(e) => { - let e: Error = e.into(); - error!("Error in handler: {:?}", e); - Ok(Async::Ready(())) - } - } - } -} - -pub struct FramedExtract -where - T: FromRequest, -{ - cfg: Rc, - _t: PhantomData<(Io, Ex)>, -} - -impl FramedExtract -where - T: FromRequest + 'static, -{ - pub fn new(cfg: T::Config) -> FramedExtract { - FramedExtract { - cfg: Rc::new(cfg), - _t: PhantomData, - } - } -} -impl NewService for FramedExtract -where - T: FromRequest + 'static, -{ - type Request = FramedRequest; - type Response = (T, FramedRequest); - type Error = FramedError; - type InitError = (); - type Service = FramedExtractService; - type Future = FutureResult; - - fn new_service(&self) -> Self::Future { - ok(FramedExtractService { - cfg: self.cfg.clone(), - _t: PhantomData, - }) - } -} - -pub struct FramedExtractService -where - T: FromRequest, -{ - cfg: Rc, - _t: PhantomData<(Io, Ex)>, -} - -impl Service for FramedExtractService -where - T: FromRequest + 'static, -{ - type Request = FramedRequest; - type Response = (T, FramedRequest); - type Error = FramedError; - type Future = FramedExtractResponse; - - fn poll_ready(&mut self) -> Poll<(), Self::Error> { - Ok(Async::Ready(())) - } - - fn call(&mut self, req: FramedRequest) -> Self::Future { - FramedExtractResponse { - fut: T::from_request(&req.request(), self.cfg.as_ref()), - req: Some(req), - } - } -} - -pub struct FramedExtractResponse -where - T: FromRequest + 'static, -{ - req: Option>, - fut: T::Future, -} - -impl Future for FramedExtractResponse -where - T: FromRequest + 'static, -{ - type Item = (T, FramedRequest); - type Error = FramedError; - - fn poll(&mut self) -> Poll { - match self.fut.poll() { - Ok(Async::NotReady) => Ok(Async::NotReady), - Ok(Async::Ready(item)) => Ok(Async::Ready((item, self.req.take().unwrap()))), - Err(err) => Err(FramedError { - err: err.into(), - framed: self.req.take().unwrap().into_parts().1, - }), - } - } -} - -macro_rules! factory_tuple ({ ($(($nex:tt, $Ex:ident)),+), $(($n:tt, $T:ident)),+} => { - impl FramedFactory for Func - where Func: Fn(Framed, $($Ex,)+ $($T,)+) -> Res + Clone + 'static, - $($T: FromRequest + 'static,)+ - Res: IntoFuture + 'static, - Err: Into, - { - fn call(&self, framed: Framed, param: ($($T,)+), extra: ($($Ex,)+)) -> Res { - (self)(framed, $(extra.$nex,)+ $(param.$n,)+) - } - } -}); - -macro_rules! factory_tuple_unit ({$(($n:tt, $T:ident)),+} => { - impl FramedFactory for Func - where Func: Fn(Framed, $($T,)+) -> Res + Clone + 'static, - $($T: FromRequest + 'static,)+ - Res: IntoFuture + 'static, - Err: Into, - { - fn call(&self, framed: Framed, param: ($($T,)+), _extra: () ) -> Res { - (self)(framed, $(param.$n,)+) - } - } -}); - -#[cfg_attr(rustfmt, rustfmt_skip)] -mod m { - use super::*; - -factory_tuple_unit!((0, A)); -factory_tuple!(((0, Aex)), (0, A)); -factory_tuple!(((0, Aex), (1, Bex)), (0, A)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex)), (0, A)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex)), (0, A)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex)), (0, A)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex), (5, Fex)), (0, A)); - -factory_tuple_unit!((0, A), (1, B)); -factory_tuple!(((0, Aex)), (0, A), (1, B)); -factory_tuple!(((0, Aex), (1, Bex)), (0, A), (1, B)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex)), (0, A), (1, B)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex)), (0, A), (1, B)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex)), (0, A), (1, B)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex), (5, Fex)), (0, A), (1, B)); - -factory_tuple_unit!((0, A), (1, B), (2, C)); -factory_tuple!(((0, Aex)), (0, A), (1, B), (2, C)); -factory_tuple!(((0, Aex), (1, Bex)), (0, A), (1, B), (2, C)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex)), (0, A), (1, B), (2, C)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex)), (0, A), (1, B), (2, C)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex)), (0, A), (1, B), (2, C)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex), (5, Fex)), (0, A), (1, B), (2, C)); - -factory_tuple_unit!((0, A), (1, B), (2, C), (3, D)); -factory_tuple!(((0, Aex)), (0, A), (1, B), (2, C), (3, D)); -factory_tuple!(((0, Aex), (1, Bex)), (0, A), (1, B), (2, C), (3, D)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex)), (0, A), (1, B), (2, C), (3, D)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex)), (0, A), (1, B), (2, C), (3, D)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex)), (0, A), (1, B), (2, C), (3, D)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex), (5, Fex)), (0, A), (1, B), (2, C), (3, D)); - -factory_tuple_unit!((0, A), (1, B), (2, C), (3, D), (4, E)); -factory_tuple!(((0, Aex)), (0, A), (1, B), (2, C), (3, D), (4, E)); -factory_tuple!(((0, Aex), (1, Bex)), (0, A), (1, B), (2, C), (3, D), (4, E)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex)), (0, A), (1, B), (2, C), (3, D), (4, E)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex)), (0, A), (1, B), (2, C), (3, D), (4, E)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex)), (0, A), (1, B), (2, C), (3, D), (4, E)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex), (5, Fex)), (0, A), (1, B), (2, C), (3, D), (4, E)); - -factory_tuple_unit!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F)); -factory_tuple!(((0, Aex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F)); -factory_tuple!(((0, Aex), (1, Bex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex), (5, Fex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F)); - -factory_tuple_unit!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G)); -factory_tuple!(((0, Aex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G)); -factory_tuple!(((0, Aex), (1, Bex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex), (5, Fex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G)); - -factory_tuple_unit!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H)); -factory_tuple!(((0, Aex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H)); -factory_tuple!(((0, Aex), (1, Bex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex), (5, Fex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H)); - -factory_tuple_unit!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I)); -factory_tuple!(((0, Aex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I)); -factory_tuple!(((0, Aex), (1, Bex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex), (5, Fex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I)); - -factory_tuple_unit!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J)); -factory_tuple!(((0, Aex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J)); -factory_tuple!(((0, Aex), (1, Bex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J)); -factory_tuple!(((0, Aex), (1, Bex), (2, Cex), (3, Dex), (4, Eex), (5, Fex)), (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J)); -} diff --git a/src/framed_route.rs b/src/framed_route.rs deleted file mode 100644 index 90555a9c..00000000 --- a/src/framed_route.rs +++ /dev/null @@ -1,448 +0,0 @@ -use std::marker::PhantomData; - -use actix_http::http::{HeaderName, HeaderValue, Method}; -use actix_http::Error; -use actix_service::{IntoNewService, NewService, NewServiceExt, Service}; -use futures::{try_ready, Async, Future, IntoFuture, Poll}; -use log::{debug, error}; -use tokio_io::{AsyncRead, AsyncWrite}; - -use crate::app::{HttpServiceFactory, State}; -use crate::framed_handler::{ - FramedError, FramedExtract, FramedFactory, FramedHandle, FramedRequest, -}; -use crate::handler::FromRequest; - -/// Resource route definition -/// -/// Route uses builder-like pattern for configuration. -/// If handler is not explicitly set, default *404 Not Found* handler is used. -pub struct FramedRoute { - service: T, - pattern: String, - methods: Vec, - headers: Vec<(HeaderName, HeaderValue)>, - state: PhantomData<(S, Io)>, -} - -impl FramedRoute { - pub fn build(path: &str) -> FramedRoutePatternBuilder { - FramedRoutePatternBuilder::new(path) - } - - pub fn get(path: &str) -> FramedRoutePatternBuilder { - FramedRoutePatternBuilder::new(path).method(Method::GET) - } - - pub fn post(path: &str) -> FramedRoutePatternBuilder { - FramedRoutePatternBuilder::new(path).method(Method::POST) - } - - pub fn put(path: &str) -> FramedRoutePatternBuilder { - FramedRoutePatternBuilder::new(path).method(Method::PUT) - } - - pub fn delete(path: &str) -> FramedRoutePatternBuilder { - FramedRoutePatternBuilder::new(path).method(Method::DELETE) - } -} - -impl FramedRoute -where - T: NewService< - Request = FramedRequest, - Response = (), - Error = FramedError, - > + 'static, -{ - pub fn new>(pattern: &str, factory: F) -> Self { - FramedRoute { - pattern: pattern.to_string(), - service: factory.into_new_service(), - headers: Vec::new(), - methods: Vec::new(), - state: PhantomData, - } - } - - pub fn method(mut self, method: Method) -> Self { - self.methods.push(method); - self - } - - pub fn header(mut self, name: HeaderName, value: HeaderValue) -> Self { - self.headers.push((name, value)); - self - } -} - -impl HttpServiceFactory for FramedRoute -where - Io: AsyncRead + AsyncWrite + 'static, - T: NewService< - Request = FramedRequest, - Response = (), - Error = FramedError, - > + 'static, - T::Service: 'static, -{ - type Factory = FramedRouteFactory; - - fn path(&self) -> &str { - &self.pattern - } - - fn create(self, state: State) -> Self::Factory { - FramedRouteFactory { - state, - service: self.service, - pattern: self.pattern, - methods: self.methods, - headers: self.headers, - _t: PhantomData, - } - } -} - -pub struct FramedRouteFactory { - service: T, - pattern: String, - methods: Vec, - headers: Vec<(HeaderName, HeaderValue)>, - state: State, - _t: PhantomData, -} - -impl NewService for FramedRouteFactory -where - Io: AsyncRead + AsyncWrite + 'static, - T: NewService< - Request = FramedRequest, - Response = (), - Error = FramedError, - > + 'static, - T::Service: 'static, -{ - type Request = FramedRequest; - type Response = T::Response; - type Error = (); - type InitError = T::InitError; - type Service = FramedRouteService; - type Future = CreateRouteService; - - fn new_service(&self) -> Self::Future { - CreateRouteService { - fut: self.service.new_service(), - pattern: self.pattern.clone(), - methods: self.methods.clone(), - headers: self.headers.clone(), - state: self.state.clone(), - _t: PhantomData, - } - } -} - -pub struct CreateRouteService { - fut: T::Future, - pattern: String, - methods: Vec, - headers: Vec<(HeaderName, HeaderValue)>, - state: State, - _t: PhantomData, -} - -impl Future for CreateRouteService -where - T: NewService< - Request = FramedRequest, - Response = (), - Error = FramedError, - >, -{ - type Item = FramedRouteService; - type Error = T::InitError; - - fn poll(&mut self) -> Poll { - let service = try_ready!(self.fut.poll()); - - Ok(Async::Ready(FramedRouteService { - service, - state: self.state.clone(), - pattern: self.pattern.clone(), - methods: self.methods.clone(), - headers: self.headers.clone(), - _t: PhantomData, - })) - } -} - -pub struct FramedRouteService { - service: T, - pattern: String, - methods: Vec, - headers: Vec<(HeaderName, HeaderValue)>, - state: State, - _t: PhantomData, -} - -impl Service for FramedRouteService -where - Io: AsyncRead + AsyncWrite + 'static, - T: Service, Response = (), Error = FramedError> - + 'static, -{ - type Request = FramedRequest; - type Response = (); - type Error = (); - type Future = FramedRouteServiceResponse; - - fn poll_ready(&mut self) -> Poll<(), Self::Error> { - self.service.poll_ready().map_err(|e| { - debug!("Service not available: {}", e.err); - () - }) - } - - fn call(&mut self, req: FramedRequest) -> Self::Future { - FramedRouteServiceResponse { - fut: self.service.call(req), - send: None, - _t: PhantomData, - } - } -} - -// impl HttpService<(Request, Framed)> for FramedRouteService -// where -// Io: AsyncRead + AsyncWrite + 'static, -// S: 'static, -// T: Service, Response = (), Error = FramedError> + 'static, -// { -// fn handle( -// &mut self, -// (req, framed): (Request, Framed), -// ) -> Result)> { -// if self.methods.is_empty() -// || !self.methods.is_empty() && self.methods.contains(req.method()) -// { -// if let Some(params) = self.pattern.match_with_params(&req, 0) { -// return Ok(FramedRouteServiceResponse { -// fut: self.service.call(FramedRequest::new( -// WebRequest::new(self.state.clone(), req, params), -// framed, -// )), -// send: None, -// _t: PhantomData, -// }); -// } -// } -// Err((req, framed)) -// } -// } - -#[doc(hidden)] -pub struct FramedRouteServiceResponse { - fut: F, - send: Option>>, - _t: PhantomData, -} - -impl Future for FramedRouteServiceResponse -where - F: Future>, - Io: AsyncRead + AsyncWrite + 'static, -{ - type Item = (); - type Error = (); - - fn poll(&mut self) -> Poll { - if let Some(ref mut fut) = self.send { - return match fut.poll() { - Ok(Async::NotReady) => Ok(Async::NotReady), - Ok(Async::Ready(_)) => Ok(Async::Ready(())), - Err(e) => { - debug!("Error during error response send: {}", e); - Err(()) - } - }; - }; - - match self.fut.poll() { - Ok(Async::NotReady) => Ok(Async::NotReady), - Ok(Async::Ready(_)) => Ok(Async::Ready(())), - Err(e) => { - error!("Error occurred during request handling: {}", e.err); - Err(()) - } - } - } -} - -pub struct FramedRoutePatternBuilder { - pattern: String, - methods: Vec, - headers: Vec<(HeaderName, HeaderValue)>, - state: PhantomData<(Io, S)>, -} - -impl FramedRoutePatternBuilder { - fn new(path: &str) -> FramedRoutePatternBuilder { - FramedRoutePatternBuilder { - pattern: path.to_string(), - methods: Vec::new(), - headers: Vec::new(), - state: PhantomData, - } - } - - pub fn method(mut self, method: Method) -> Self { - self.methods.push(method); - self - } - - pub fn map>( - self, - md: F, - ) -> FramedRouteBuilder - where - T: NewService< - Request = FramedRequest, - Response = FramedRequest, - Error = FramedError, - InitError = (), - >, - { - FramedRouteBuilder { - service: md.into_new_service(), - pattern: self.pattern, - methods: self.methods, - headers: self.headers, - state: PhantomData, - } - } - - pub fn with( - self, - handler: F, - ) -> FramedRoute< - Io, - impl NewService< - Request = FramedRequest, - Response = (), - Error = FramedError, - InitError = (), - >, - S, - > - where - F: FramedFactory, - P: FromRequest + 'static, - R: IntoFuture, - E: Into, - { - FramedRoute { - service: FramedExtract::new(P::Config::default()) - .and_then(FramedHandle::new(handler)), - pattern: self.pattern, - methods: self.methods, - headers: self.headers, - state: PhantomData, - } - } -} - -pub struct FramedRouteBuilder { - service: T, - pattern: String, - methods: Vec, - headers: Vec<(HeaderName, HeaderValue)>, - state: PhantomData<(Io, S, U1, U2)>, -} - -impl FramedRouteBuilder -where - T: NewService< - Request = FramedRequest, - Response = FramedRequest, - Error = FramedError, - InitError = (), - >, -{ - pub fn new>(path: &str, factory: F) -> Self { - FramedRouteBuilder { - service: factory.into_new_service(), - pattern: path.to_string(), - methods: Vec::new(), - headers: Vec::new(), - state: PhantomData, - } - } - - pub fn method(mut self, method: Method) -> Self { - self.methods.push(method); - self - } - - pub fn map>( - self, - md: F, - ) -> FramedRouteBuilder< - Io, - S, - impl NewService< - Request = FramedRequest, - Response = FramedRequest, - Error = FramedError, - InitError = (), - >, - U1, - U3, - > - where - K: NewService< - Request = FramedRequest, - Response = FramedRequest, - Error = FramedError, - InitError = (), - >, - { - FramedRouteBuilder { - service: self.service.from_err().and_then(md.into_new_service()), - pattern: self.pattern, - methods: self.methods, - headers: self.headers, - state: PhantomData, - } - } - - pub fn with( - self, - handler: F, - ) -> FramedRoute< - Io, - impl NewService< - Request = FramedRequest, - Response = (), - Error = FramedError, - InitError = (), - >, - S, - > - where - F: FramedFactory, - P: FromRequest + 'static, - R: IntoFuture, - E: Into, - { - FramedRoute { - service: self - .service - .and_then(FramedExtract::new(P::Config::default())) - .and_then(FramedHandle::new(handler)), - pattern: self.pattern, - methods: self.methods, - headers: self.headers, - state: PhantomData, - } - } -} diff --git a/src/helpers.rs b/src/helpers.rs deleted file mode 100644 index 860a02a4..00000000 --- a/src/helpers.rs +++ /dev/null @@ -1,180 +0,0 @@ -use actix_http::Response; -use actix_service::{NewService, Service}; -use futures::future::{ok, FutureResult}; -use futures::{Future, Poll}; - -pub(crate) type BoxedHttpService = Box< - Service< - Request = Req, - Response = Res, - Error = (), - Future = Box>, - >, ->; - -pub(crate) type BoxedHttpNewService = Box< - NewService< - Request = Req, - Response = Res, - Error = (), - InitError = (), - Service = BoxedHttpService, - Future = Box, Error = ()>>, - >, ->; - -pub(crate) struct HttpNewService(T); - -impl HttpNewService -where - T: NewService, - T::Response: 'static, - T::Future: 'static, - T::Service: Service, - ::Future: 'static, -{ - pub fn new(service: T) -> Self { - HttpNewService(service) - } -} - -impl NewService for HttpNewService -where - T: NewService, - T::Request: 'static, - T::Response: 'static, - T::Future: 'static, - T::Service: Service + 'static, - ::Future: 'static, -{ - type Request = T::Request; - type Response = T::Response; - type Error = (); - type InitError = (); - type Service = BoxedHttpService; - type Future = Box>; - - fn new_service(&self, _: &()) -> Self::Future { - Box::new(self.0.new_service(&()).map_err(|_| ()).and_then(|service| { - let service: BoxedHttpService<_, _> = - Box::new(HttpServiceWrapper { service }); - Ok(service) - })) - } -} - -struct HttpServiceWrapper { - service: T, -} - -impl Service for HttpServiceWrapper -where - T: Service, - T::Request: 'static, - T::Response: 'static, - T::Future: 'static, -{ - type Request = T::Request; - type Response = T::Response; - type Error = (); - type Future = Box>; - - fn poll_ready(&mut self) -> Poll<(), Self::Error> { - self.service.poll_ready().map_err(|_| ()) - } - - fn call(&mut self, req: Self::Request) -> Self::Future { - Box::new(self.service.call(req).map_err(|_| ())) - } -} - -pub(crate) fn not_found(_: Req) -> FutureResult { - ok(Response::NotFound().finish()) -} - -pub(crate) type HttpDefaultService = Box< - Service< - Request = Req, - Response = Res, - Error = (), - Future = Box>, - >, ->; - -pub(crate) type HttpDefaultNewService = Box< - NewService< - Request = Req, - Response = Res, - Error = (), - InitError = (), - Service = HttpDefaultService, - Future = Box, Error = ()>>, - >, ->; - -pub(crate) struct DefaultNewService { - service: T, -} - -impl DefaultNewService -where - T: NewService + 'static, - T::Future: 'static, - ::Future: 'static, -{ - pub fn new(service: T) -> Self { - DefaultNewService { service } - } -} - -impl NewService for DefaultNewService -where - T: NewService + 'static, - T::Request: 'static, - T::Future: 'static, - T::Service: 'static, - ::Future: 'static, -{ - type Request = T::Request; - type Response = T::Response; - type Error = (); - type InitError = (); - type Service = HttpDefaultService; - type Future = Box>; - - fn new_service(&self, _: &()) -> Self::Future { - Box::new( - self.service - .new_service(&()) - .map_err(|_| ()) - .and_then(|service| { - let service: HttpDefaultService<_, _> = - Box::new(DefaultServiceWrapper { service }); - Ok(service) - }), - ) - } -} - -struct DefaultServiceWrapper { - service: T, -} - -impl Service for DefaultServiceWrapper -where - T: Service + 'static, - T::Future: 'static, -{ - type Request = T::Request; - type Response = T::Response; - type Error = (); - type Future = Box>; - - fn poll_ready(&mut self) -> Poll<(), Self::Error> { - self.service.poll_ready().map_err(|_| ()) - } - - fn call(&mut self, req: T::Request) -> Self::Future { - Box::new(self.service.call(req).map_err(|_| ())) - } -} diff --git a/src/lib.rs b/src/lib.rs index f09c11ce..b4b12eb1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,11 +3,10 @@ mod app; mod extractor; pub mod handler; -mod helpers; +// mod helpers; // mod info; pub mod blocking; pub mod filter; -pub mod fs; pub mod middleware; mod request; mod resource; diff --git a/src/resource.rs b/src/resource.rs index 88f7ae5a..80ac8d83 100644 --- a/src/resource.rs +++ b/src/resource.rs @@ -2,6 +2,7 @@ use std::cell::RefCell; use std::rc::Rc; use actix_http::{http::Method, Error, Response}; +use actix_service::boxed::{self, BoxedNewService, BoxedService}; use actix_service::{ ApplyNewService, IntoNewService, IntoNewTransform, NewService, NewTransform, Service, }; @@ -9,11 +10,13 @@ use futures::future::{ok, Either, FutureResult}; use futures::{Async, Future, IntoFuture, Poll}; use crate::handler::{AsyncFactory, Factory, FromRequest}; -use crate::helpers::{DefaultNewService, HttpDefaultNewService, HttpDefaultService}; use crate::responder::Responder; use crate::route::{CreateRouteService, Route, RouteBuilder, RouteService}; use crate::service::{ServiceRequest, ServiceResponse}; +type HttpService

= BoxedService, ServiceResponse, ()>; +type HttpNewService

= BoxedNewService<(), ServiceRequest

, ServiceResponse, (), ()>; + /// Resource route definition /// /// Route uses builder-like pattern for configuration. @@ -21,9 +24,7 @@ use crate::service::{ServiceRequest, ServiceResponse}; pub struct Resource> { routes: Vec>, endpoint: T, - default: Rc< - RefCell, ServiceResponse>>>>, - >, + default: Rc>>>>, factory_ref: Rc>>>, } @@ -277,17 +278,14 @@ where > + 'static, { // create and configure default resource - self.default = Rc::new(RefCell::new(Some(Rc::new(Box::new( - DefaultNewService::new(f(Resource::new()).into_new_service()), + self.default = Rc::new(RefCell::new(Some(Rc::new(boxed::new_service( + f(Resource::new()).into_new_service().map_init_err(|_| ()), ))))); self } - pub(crate) fn get_default( - &self, - ) -> Rc, ServiceResponse>>>>> - { + pub(crate) fn get_default(&self) -> Rc>>>> { self.default.clone() } } @@ -313,12 +311,10 @@ where pub struct ResourceFactory

{ routes: Vec>, - default: Rc< - RefCell, ServiceResponse>>>>, - >, + default: Rc>>>>, } -impl

NewService for ResourceFactory

{ +impl NewService for ResourceFactory

{ type Request = ServiceRequest

; type Response = ServiceResponse; type Error = (); @@ -352,15 +348,8 @@ enum CreateRouteServiceItem

{ pub struct CreateResourceService

{ fut: Vec>, - default: Option, ServiceResponse>>, - default_fut: Option< - Box< - Future< - Item = HttpDefaultService, ServiceResponse>, - Error = (), - >, - >, - >, + default: Option>, + default_fut: Option, Error = ()>>>, } impl

Future for CreateResourceService

{ @@ -413,7 +402,7 @@ impl

Future for CreateResourceService

{ pub struct ResourceService

{ routes: Vec>, - default: Option, ServiceResponse>>, + default: Option>, } impl

Service for ResourceService

{ @@ -461,7 +450,7 @@ impl

ResourceEndpoint

{ } } -impl

NewService for ResourceEndpoint

{ +impl NewService for ResourceEndpoint

{ type Request = ServiceRequest

; type Response = ServiceResponse; type Error = (); diff --git a/tests/test_server.rs b/tests/test_server.rs index 2d01d270..590cc0e7 100644 --- a/tests/test_server.rs +++ b/tests/test_server.rs @@ -12,7 +12,7 @@ use flate2::write::ZlibDecoder; use futures::stream::once; //Future, Stream use rand::{distributions::Alphanumeric, Rng}; -use actix_web2::{middleware, App}; +use actix_web::{middleware, App}; const STR: &str = "Hello World Hello World Hello World Hello World Hello World \ Hello World Hello World Hello World Hello World Hello World \