1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-06-12 02:09:36 +00:00

update server service requirenments

This commit is contained in:
Nikolay Kim 2019-03-11 15:09:42 -07:00
parent 6436004194
commit ad43ca735b
7 changed files with 130 additions and 92 deletions

View file

@ -2,8 +2,8 @@ use std::{env, io};
use actix_codec::Framed;
use actix_http::{h1, Response, SendResponse, ServiceConfig};
use actix_server::Server;
use actix_service::NewService;
use actix_server::{Io, Server};
use actix_service::{fn_service, NewService};
use actix_utils::framed::IntoFramed;
use actix_utils::stream::TakeItem;
use futures::Future;
@ -14,7 +14,8 @@ fn main() -> io::Result<()> {
Server::build()
.bind("framed_hello", "127.0.0.1:8080", || {
IntoFramed::new(|| h1::Codec::new(ServiceConfig::default()))
fn_service(|io: Io<_>| Ok(io.into_parts().0))
.and_then(IntoFramed::new(|| h1::Codec::new(ServiceConfig::default())))
.and_then(TakeItem::new().map_err(|_| ()))
.and_then(|(_req, _framed): (_, Framed<_, _>)| {
SendResponse::send(_framed, Response::Ok().body("Hello world!"))

View file

@ -95,7 +95,7 @@ where
// }
/// Finish service configuration and create *http service* for HTTP/1 protocol.
pub fn h1<F, B>(self, service: F) -> H1Service<T, S, B>
pub fn h1<F, P, B>(self, service: F) -> H1Service<T, P, S, B>
where
B: MessageBody + 'static,
F: IntoNewService<S, SrvConfig>,
@ -110,7 +110,7 @@ where
}
/// Finish service configuration and create *http service* for HTTP/2 protocol.
pub fn h2<F, B>(self, service: F) -> H2Service<T, S, B>
pub fn h2<F, P, B>(self, service: F) -> H2Service<T, P, S, B>
where
B: MessageBody + 'static,
F: IntoNewService<S, SrvConfig>,
@ -125,7 +125,7 @@ where
}
/// Finish service configuration and create `HttpService` instance.
pub fn finish<F, B>(self, service: F) -> HttpService<T, S, B>
pub fn finish<F, P, B>(self, service: F) -> HttpService<T, P, S, B>
where
B: MessageBody + 'static,
F: IntoNewService<S, SrvConfig>,

View file

@ -2,7 +2,7 @@ use std::fmt::Debug;
use std::marker::PhantomData;
use actix_codec::{AsyncRead, AsyncWrite, Framed};
use actix_server_config::ServerConfig as SrvConfig;
use actix_server_config::{Io, ServerConfig as SrvConfig};
use actix_service::{IntoNewService, NewService, Service};
use actix_utils::cloneable::CloneableService;
use futures::future::{ok, FutureResult};
@ -19,13 +19,13 @@ use super::dispatcher::Dispatcher;
use super::Message;
/// `NewService` implementation for HTTP1 transport
pub struct H1Service<T, S, B> {
pub struct H1Service<T, P, S, B> {
srv: S,
cfg: ServiceConfig,
_t: PhantomData<(T, B)>,
_t: PhantomData<(T, P, B)>,
}
impl<T, S, B> H1Service<T, S, B>
impl<T, P, S, B> H1Service<T, P, S, B>
where
S: NewService<SrvConfig, Request = Request>,
S::Error: Debug,
@ -57,7 +57,7 @@ where
}
}
impl<T, S, B> NewService<SrvConfig> for H1Service<T, S, B>
impl<T, P, S, B> NewService<SrvConfig> for H1Service<T, P, S, B>
where
T: AsyncRead + AsyncWrite,
S: NewService<SrvConfig, Request = Request>,
@ -66,12 +66,12 @@ where
S::Service: 'static,
B: MessageBody,
{
type Request = T;
type Request = Io<T, P>;
type Response = ();
type Error = DispatchError;
type InitError = S::InitError;
type Service = H1ServiceHandler<T, S::Service, B>;
type Future = H1ServiceResponse<T, S, B>;
type Service = H1ServiceHandler<T, P, S::Service, B>;
type Future = H1ServiceResponse<T, P, S, B>;
fn new_service(&self, cfg: &SrvConfig) -> Self::Future {
H1ServiceResponse {
@ -83,13 +83,13 @@ where
}
#[doc(hidden)]
pub struct H1ServiceResponse<T, S: NewService<SrvConfig, Request = Request>, B> {
pub struct H1ServiceResponse<T, P, S: NewService<SrvConfig, Request = Request>, B> {
fut: <S::Future as IntoFuture>::Future,
cfg: Option<ServiceConfig>,
_t: PhantomData<(T, B)>,
_t: PhantomData<(T, P, B)>,
}
impl<T, S, B> Future for H1ServiceResponse<T, S, B>
impl<T, P, S, B> Future for H1ServiceResponse<T, P, S, B>
where
T: AsyncRead + AsyncWrite,
S: NewService<SrvConfig, Request = Request>,
@ -98,7 +98,7 @@ where
S::Response: Into<Response<B>>,
B: MessageBody,
{
type Item = H1ServiceHandler<T, S::Service, B>;
type Item = H1ServiceHandler<T, P, S::Service, B>;
type Error = S::InitError;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
@ -111,20 +111,20 @@ where
}
/// `Service` implementation for HTTP1 transport
pub struct H1ServiceHandler<T, S: 'static, B> {
pub struct H1ServiceHandler<T, P, S: 'static, B> {
srv: CloneableService<S>,
cfg: ServiceConfig,
_t: PhantomData<(T, B)>,
_t: PhantomData<(T, P, B)>,
}
impl<T, S, B> H1ServiceHandler<T, S, B>
impl<T, P, S, B> H1ServiceHandler<T, P, S, B>
where
S: Service<Request = Request>,
S::Error: Debug,
S::Response: Into<Response<B>>,
B: MessageBody,
{
fn new(cfg: ServiceConfig, srv: S) -> H1ServiceHandler<T, S, B> {
fn new(cfg: ServiceConfig, srv: S) -> H1ServiceHandler<T, P, S, B> {
H1ServiceHandler {
srv: CloneableService::new(srv),
cfg,
@ -133,7 +133,7 @@ where
}
}
impl<T, S, B> Service for H1ServiceHandler<T, S, B>
impl<T, P, S, B> Service for H1ServiceHandler<T, P, S, B>
where
T: AsyncRead + AsyncWrite,
S: Service<Request = Request>,
@ -141,7 +141,7 @@ where
S::Response: Into<Response<B>>,
B: MessageBody,
{
type Request = T;
type Request = Io<T, P>;
type Response = ();
type Error = DispatchError;
type Future = Dispatcher<T, S, B>;
@ -153,19 +153,19 @@ where
})
}
fn call(&mut self, req: T) -> Self::Future {
Dispatcher::new(req, self.cfg.clone(), self.srv.clone())
fn call(&mut self, req: Self::Request) -> Self::Future {
Dispatcher::new(req.into_parts().0, self.cfg.clone(), self.srv.clone())
}
}
/// `NewService` implementation for `OneRequestService` service
#[derive(Default)]
pub struct OneRequest<T> {
pub struct OneRequest<T, P> {
config: ServiceConfig,
_t: PhantomData<T>,
_t: PhantomData<(T, P)>,
}
impl<T> OneRequest<T>
impl<T, P> OneRequest<T, P>
where
T: AsyncRead + AsyncWrite,
{
@ -178,15 +178,15 @@ where
}
}
impl<T> NewService<SrvConfig> for OneRequest<T>
impl<T, P> NewService<SrvConfig> for OneRequest<T, P>
where
T: AsyncRead + AsyncWrite,
{
type Request = T;
type Request = Io<T, P>;
type Response = (Request, Framed<T, Codec>);
type Error = ParseError;
type InitError = ();
type Service = OneRequestService<T>;
type Service = OneRequestService<T, P>;
type Future = FutureResult<Self::Service, Self::InitError>;
fn new_service(&self, _: &SrvConfig) -> Self::Future {
@ -199,16 +199,16 @@ where
/// `Service` implementation for HTTP1 transport. Reads one request and returns
/// request and framed object.
pub struct OneRequestService<T> {
pub struct OneRequestService<T, P> {
config: ServiceConfig,
_t: PhantomData<T>,
_t: PhantomData<(T, P)>,
}
impl<T> Service for OneRequestService<T>
impl<T, P> Service for OneRequestService<T, P>
where
T: AsyncRead + AsyncWrite,
{
type Request = T;
type Request = Io<T, P>;
type Response = (Request, Framed<T, Codec>);
type Error = ParseError;
type Future = OneRequestServiceResponse<T>;
@ -217,9 +217,12 @@ where
Ok(Async::Ready(()))
}
fn call(&mut self, req: T) -> Self::Future {
fn call(&mut self, req: Self::Request) -> Self::Future {
OneRequestServiceResponse {
framed: Some(Framed::new(req, Codec::new(self.config.clone()))),
framed: Some(Framed::new(
req.into_parts().0,
Codec::new(self.config.clone()),
)),
}
}
}

View file

@ -3,7 +3,7 @@ use std::marker::PhantomData;
use std::{io, net};
use actix_codec::{AsyncRead, AsyncWrite, Framed};
use actix_server_config::ServerConfig as SrvConfig;
use actix_server_config::{Io, ServerConfig as SrvConfig};
use actix_service::{IntoNewService, NewService, Service};
use actix_utils::cloneable::CloneableService;
use bytes::Bytes;
@ -23,13 +23,13 @@ use crate::response::Response;
use super::dispatcher::Dispatcher;
/// `NewService` implementation for HTTP2 transport
pub struct H2Service<T, S, B> {
pub struct H2Service<T, P, S, B> {
srv: S,
cfg: ServiceConfig,
_t: PhantomData<(T, B)>,
_t: PhantomData<(T, P, B)>,
}
impl<T, S, B> H2Service<T, S, B>
impl<T, P, S, B> H2Service<T, P, S, B>
where
S: NewService<SrvConfig, Request = Request>,
S::Service: 'static,
@ -61,7 +61,7 @@ where
}
}
impl<T, S, B> NewService<SrvConfig> for H2Service<T, S, B>
impl<T, P, S, B> NewService<SrvConfig> for H2Service<T, P, S, B>
where
T: AsyncRead + AsyncWrite,
S: NewService<SrvConfig, Request = Request>,
@ -70,12 +70,12 @@ where
S::Response: Into<Response<B>>,
B: MessageBody + 'static,
{
type Request = T;
type Request = Io<T, P>;
type Response = ();
type Error = DispatchError;
type InitError = S::InitError;
type Service = H2ServiceHandler<T, S::Service, B>;
type Future = H2ServiceResponse<T, S, B>;
type Service = H2ServiceHandler<T, P, S::Service, B>;
type Future = H2ServiceResponse<T, P, S, B>;
fn new_service(&self, cfg: &SrvConfig) -> Self::Future {
H2ServiceResponse {
@ -87,13 +87,13 @@ where
}
#[doc(hidden)]
pub struct H2ServiceResponse<T, S: NewService<SrvConfig, Request = Request>, B> {
pub struct H2ServiceResponse<T, P, S: NewService<SrvConfig, Request = Request>, B> {
fut: <S::Future as IntoFuture>::Future,
cfg: Option<ServiceConfig>,
_t: PhantomData<(T, B)>,
_t: PhantomData<(T, P, B)>,
}
impl<T, S, B> Future for H2ServiceResponse<T, S, B>
impl<T, P, S, B> Future for H2ServiceResponse<T, P, S, B>
where
T: AsyncRead + AsyncWrite,
S: NewService<SrvConfig, Request = Request>,
@ -102,7 +102,7 @@ where
S::Error: Debug,
B: MessageBody + 'static,
{
type Item = H2ServiceHandler<T, S::Service, B>;
type Item = H2ServiceHandler<T, P, S::Service, B>;
type Error = S::InitError;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
@ -115,20 +115,20 @@ where
}
/// `Service` implementation for http/2 transport
pub struct H2ServiceHandler<T, S: 'static, B> {
pub struct H2ServiceHandler<T, P, S: 'static, B> {
srv: CloneableService<S>,
cfg: ServiceConfig,
_t: PhantomData<(T, B)>,
_t: PhantomData<(T, P, B)>,
}
impl<T, S, B> H2ServiceHandler<T, S, B>
impl<T, P, S, B> H2ServiceHandler<T, P, S, B>
where
S: Service<Request = Request> + 'static,
S::Error: Debug,
S::Response: Into<Response<B>>,
B: MessageBody + 'static,
{
fn new(cfg: ServiceConfig, srv: S) -> H2ServiceHandler<T, S, B> {
fn new(cfg: ServiceConfig, srv: S) -> H2ServiceHandler<T, P, S, B> {
H2ServiceHandler {
cfg,
srv: CloneableService::new(srv),
@ -137,7 +137,7 @@ where
}
}
impl<T, S, B> Service for H2ServiceHandler<T, S, B>
impl<T, P, S, B> Service for H2ServiceHandler<T, P, S, B>
where
T: AsyncRead + AsyncWrite,
S: Service<Request = Request> + 'static,
@ -145,7 +145,7 @@ where
S::Response: Into<Response<B>>,
B: MessageBody + 'static,
{
type Request = T;
type Request = Io<T, P>;
type Response = ();
type Error = DispatchError;
type Future = H2ServiceHandlerResponse<T, S, B>;
@ -157,12 +157,12 @@ where
})
}
fn call(&mut self, req: T) -> Self::Future {
fn call(&mut self, req: Self::Request) -> Self::Future {
H2ServiceHandlerResponse {
state: State::Handshake(
Some(self.srv.clone()),
Some(self.cfg.clone()),
server::handshake(req),
server::handshake(req.into_parts().0),
),
}
}

View file

@ -3,7 +3,7 @@ use std::marker::PhantomData;
use std::{fmt, io};
use actix_codec::{AsyncRead, AsyncWrite, Framed, FramedParts};
use actix_server_config::ServerConfig as SrvConfig;
use actix_server_config::{Io as ServerIo, Protocol, ServerConfig as SrvConfig};
use actix_service::{IntoNewService, NewService, Service};
use actix_utils::cloneable::CloneableService;
use bytes::{Buf, BufMut, Bytes, BytesMut};
@ -20,13 +20,27 @@ use crate::response::Response;
use crate::{h1, h2::Dispatcher};
/// `NewService` HTTP1.1/HTTP2 transport implementation
pub struct HttpService<T, S, B> {
pub struct HttpService<T, P, S, B> {
srv: S,
cfg: ServiceConfig,
_t: PhantomData<(T, B)>,
_t: PhantomData<(T, P, B)>,
}
impl<T, S, B> HttpService<T, S, B>
impl<T, S, B> HttpService<T, (), S, B>
where
S: NewService<SrvConfig, Request = Request>,
S::Service: 'static,
S::Error: Debug + 'static,
S::Response: Into<Response<B>>,
B: MessageBody + 'static,
{
/// Create builder for `HttpService` instance.
pub fn build() -> HttpServiceBuilder<T, S> {
HttpServiceBuilder::new()
}
}
impl<T, P, S, B> HttpService<T, P, S, B>
where
S: NewService<SrvConfig, Request = Request>,
S::Service: 'static,
@ -56,14 +70,9 @@ where
_t: PhantomData,
}
}
/// Create builder for `HttpService` instance.
pub fn build() -> HttpServiceBuilder<T, S> {
HttpServiceBuilder::new()
}
}
impl<T, S, B> NewService<SrvConfig> for HttpService<T, S, B>
impl<T, P, S, B> NewService<SrvConfig> for HttpService<T, P, S, B>
where
T: AsyncRead + AsyncWrite + 'static,
S: NewService<SrvConfig, Request = Request>,
@ -72,12 +81,12 @@ where
S::Response: Into<Response<B>>,
B: MessageBody + 'static,
{
type Request = T;
type Request = ServerIo<T, P>;
type Response = ();
type Error = DispatchError;
type InitError = S::InitError;
type Service = HttpServiceHandler<T, S::Service, B>;
type Future = HttpServiceResponse<T, S, B>;
type Service = HttpServiceHandler<T, P, S::Service, B>;
type Future = HttpServiceResponse<T, P, S, B>;
fn new_service(&self, cfg: &SrvConfig) -> Self::Future {
HttpServiceResponse {
@ -89,13 +98,13 @@ where
}
#[doc(hidden)]
pub struct HttpServiceResponse<T, S: NewService<SrvConfig>, B> {
pub struct HttpServiceResponse<T, P, S: NewService<SrvConfig>, B> {
fut: <S::Future as IntoFuture>::Future,
cfg: Option<ServiceConfig>,
_t: PhantomData<(T, B)>,
_t: PhantomData<(T, P, B)>,
}
impl<T, S, B> Future for HttpServiceResponse<T, S, B>
impl<T, P, S, B> Future for HttpServiceResponse<T, P, S, B>
where
T: AsyncRead + AsyncWrite,
S: NewService<SrvConfig, Request = Request>,
@ -104,7 +113,7 @@ where
S::Error: Debug,
B: MessageBody + 'static,
{
type Item = HttpServiceHandler<T, S::Service, B>;
type Item = HttpServiceHandler<T, P, S::Service, B>;
type Error = S::InitError;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
@ -117,20 +126,20 @@ where
}
/// `Service` implementation for http transport
pub struct HttpServiceHandler<T, S: 'static, B> {
pub struct HttpServiceHandler<T, P, S: 'static, B> {
srv: CloneableService<S>,
cfg: ServiceConfig,
_t: PhantomData<(T, B)>,
_t: PhantomData<(T, P, B)>,
}
impl<T, S, B> HttpServiceHandler<T, S, B>
impl<T, P, S, B> HttpServiceHandler<T, P, S, B>
where
S: Service<Request = Request> + 'static,
S::Error: Debug,
S::Response: Into<Response<B>>,
B: MessageBody + 'static,
{
fn new(cfg: ServiceConfig, srv: S) -> HttpServiceHandler<T, S, B> {
fn new(cfg: ServiceConfig, srv: S) -> HttpServiceHandler<T, P, S, B> {
HttpServiceHandler {
cfg,
srv: CloneableService::new(srv),
@ -139,7 +148,7 @@ where
}
}
impl<T, S, B> Service for HttpServiceHandler<T, S, B>
impl<T, P, S, B> Service for HttpServiceHandler<T, P, S, B>
where
T: AsyncRead + AsyncWrite + 'static,
S: Service<Request = Request> + 'static,
@ -147,7 +156,7 @@ where
S::Response: Into<Response<B>>,
B: MessageBody + 'static,
{
type Request = T;
type Request = ServerIo<T, P>;
type Response = ();
type Error = DispatchError;
type Future = HttpServiceHandlerResponse<T, S, B>;
@ -159,14 +168,37 @@ where
})
}
fn call(&mut self, req: T) -> Self::Future {
HttpServiceHandlerResponse {
state: State::Unknown(Some((
req,
BytesMut::with_capacity(14),
self.cfg.clone(),
self.srv.clone(),
))),
fn call(&mut self, req: Self::Request) -> Self::Future {
let (io, params, proto) = req.into_parts();
match proto {
Protocol::Http2 => {
let io = Io {
inner: io,
unread: None,
};
HttpServiceHandlerResponse {
state: State::Handshake(Some((
server::handshake(io),
self.cfg.clone(),
self.srv.clone(),
))),
}
}
Protocol::Http10 | Protocol::Http11 => HttpServiceHandlerResponse {
state: State::H1(h1::Dispatcher::new(
io,
self.cfg.clone(),
self.srv.clone(),
)),
},
_ => HttpServiceHandlerResponse {
state: State::Unknown(Some((
io,
BytesMut::with_capacity(14),
self.cfg.clone(),
self.srv.clone(),
))),
},
}
}
}

View file

@ -49,7 +49,7 @@ fn test_h1_2() {
}
#[cfg(feature = "ssl")]
fn ssl_acceptor<T>() -> std::io::Result<actix_server::ssl::OpensslAcceptor<T>> {
fn ssl_acceptor<T>() -> std::io::Result<actix_server::ssl::OpensslAcceptor<T, ()>> {
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
// load ssl keys
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();

View file

@ -2,7 +2,8 @@ use std::io;
use actix_codec::Framed;
use actix_http_test::TestServer;
use actix_service::NewService;
use actix_server::Io;
use actix_service::{fn_service, NewService};
use actix_utils::framed::IntoFramed;
use actix_utils::stream::TakeItem;
use bytes::{Bytes, BytesMut};
@ -35,7 +36,8 @@ fn ws_service(req: ws::Frame) -> impl Future<Item = ws::Message, Error = io::Err
#[test]
fn test_simple() {
let mut srv = TestServer::new(|| {
IntoFramed::new(|| h1::Codec::new(ServiceConfig::default()))
fn_service(|io: Io<_>| Ok(io.into_parts().0))
.and_then(IntoFramed::new(|| h1::Codec::new(ServiceConfig::default())))
.and_then(TakeItem::new().map_err(|_| ()))
.and_then(|(req, framed): (_, Framed<_, _>)| {
// validate request