mirror of
https://github.com/actix/actix-web.git
synced 2024-12-30 12:00:38 +00:00
unify service builders
This commit is contained in:
parent
ca73f178c9
commit
d026821924
11 changed files with 300 additions and 619 deletions
|
@ -1,9 +1,8 @@
|
||||||
use std::{env, io};
|
use std::{env, io};
|
||||||
|
|
||||||
use actix_http::HttpMessage;
|
use actix_http::HttpMessage;
|
||||||
use actix_http::{h1, Request, Response};
|
use actix_http::{HttpService, Request, Response};
|
||||||
use actix_server::Server;
|
use actix_server::Server;
|
||||||
use actix_service::NewService;
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
use http::header::HeaderValue;
|
use http::header::HeaderValue;
|
||||||
|
@ -15,10 +14,9 @@ fn main() -> io::Result<()> {
|
||||||
|
|
||||||
Server::build()
|
Server::build()
|
||||||
.bind("echo", "127.0.0.1:8080", || {
|
.bind("echo", "127.0.0.1:8080", || {
|
||||||
h1::H1Service::build()
|
HttpService::build()
|
||||||
.client_timeout(1000)
|
.client_timeout(1000)
|
||||||
.client_disconnect(1000)
|
.client_disconnect(1000)
|
||||||
.server_hostname("localhost")
|
|
||||||
.finish(|mut req: Request| {
|
.finish(|mut req: Request| {
|
||||||
req.body().limit(512).and_then(|bytes: Bytes| {
|
req.body().limit(512).and_then(|bytes: Bytes| {
|
||||||
info!("request body: {:?}", bytes);
|
info!("request body: {:?}", bytes);
|
||||||
|
@ -27,7 +25,6 @@ fn main() -> io::Result<()> {
|
||||||
Ok(res.body(bytes))
|
Ok(res.body(bytes))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.map(|_| ())
|
|
||||||
})?
|
})?
|
||||||
.run()
|
.run()
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,8 @@ use std::{env, io};
|
||||||
|
|
||||||
use actix_http::http::HeaderValue;
|
use actix_http::http::HeaderValue;
|
||||||
use actix_http::HttpMessage;
|
use actix_http::HttpMessage;
|
||||||
use actix_http::{h1, Error, Request, Response};
|
use actix_http::{Error, HttpService, Request, Response};
|
||||||
use actix_server::Server;
|
use actix_server::Server;
|
||||||
use actix_service::NewService;
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
use log::info;
|
use log::info;
|
||||||
|
@ -24,12 +23,7 @@ fn main() -> io::Result<()> {
|
||||||
|
|
||||||
Server::build()
|
Server::build()
|
||||||
.bind("echo", "127.0.0.1:8080", || {
|
.bind("echo", "127.0.0.1:8080", || {
|
||||||
h1::H1Service::build()
|
HttpService::build().finish(|_req: Request| handle_request(_req))
|
||||||
.client_timeout(1000)
|
|
||||||
.client_disconnect(1000)
|
|
||||||
.server_hostname("localhost")
|
|
||||||
.finish(|_req: Request| handle_request(_req))
|
|
||||||
.map(|_| ())
|
|
||||||
})?
|
})?
|
||||||
.run()
|
.run()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use std::{env, io};
|
use std::{env, io};
|
||||||
|
|
||||||
use actix_http::{h1, Response};
|
use actix_http::{HttpService, Response};
|
||||||
use actix_server::Server;
|
use actix_server::Server;
|
||||||
use actix_service::NewService;
|
|
||||||
use futures::future;
|
use futures::future;
|
||||||
use http::header::HeaderValue;
|
use http::header::HeaderValue;
|
||||||
use log::info;
|
use log::info;
|
||||||
|
@ -13,17 +12,15 @@ fn main() -> io::Result<()> {
|
||||||
|
|
||||||
Server::build()
|
Server::build()
|
||||||
.bind("hello-world", "127.0.0.1:8080", || {
|
.bind("hello-world", "127.0.0.1:8080", || {
|
||||||
h1::H1Service::build()
|
HttpService::build()
|
||||||
.client_timeout(1000)
|
.client_timeout(1000)
|
||||||
.client_disconnect(1000)
|
.client_disconnect(1000)
|
||||||
.server_hostname("localhost")
|
|
||||||
.finish(|_req| {
|
.finish(|_req| {
|
||||||
info!("{:?}", _req);
|
info!("{:?}", _req);
|
||||||
let mut res = Response::Ok();
|
let mut res = Response::Ok();
|
||||||
res.header("x-head", HeaderValue::from_static("dummy value!"));
|
res.header("x-head", HeaderValue::from_static("dummy value!"));
|
||||||
future::ok::<_, ()>(res.body("Hello world!"))
|
future::ok::<_, ()>(res.body("Hello world!"))
|
||||||
})
|
})
|
||||||
.map(|_| ())
|
|
||||||
})?
|
})?
|
||||||
.run()
|
.run()
|
||||||
}
|
}
|
||||||
|
|
141
src/builder.rs
Normal file
141
src/builder.rs
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
use std::fmt::Debug;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
use actix_server_config::ServerConfig as SrvConfig;
|
||||||
|
use actix_service::{IntoNewService, NewService};
|
||||||
|
|
||||||
|
use crate::body::MessageBody;
|
||||||
|
use crate::config::{KeepAlive, ServiceConfig};
|
||||||
|
use crate::request::Request;
|
||||||
|
use crate::response::Response;
|
||||||
|
|
||||||
|
use crate::h1::H1Service;
|
||||||
|
use crate::h2::H2Service;
|
||||||
|
use crate::service::HttpService;
|
||||||
|
|
||||||
|
/// A http service builder
|
||||||
|
///
|
||||||
|
/// This type can be used to construct an instance of `http service` through a
|
||||||
|
/// builder-like pattern.
|
||||||
|
pub struct HttpServiceBuilder<T, S> {
|
||||||
|
keep_alive: KeepAlive,
|
||||||
|
client_timeout: u64,
|
||||||
|
client_disconnect: u64,
|
||||||
|
_t: PhantomData<(T, S)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, S> HttpServiceBuilder<T, S>
|
||||||
|
where
|
||||||
|
S: NewService<SrvConfig, Request = Request>,
|
||||||
|
S::Error: Debug + 'static,
|
||||||
|
S::Service: 'static,
|
||||||
|
{
|
||||||
|
/// Create instance of `ServiceConfigBuilder`
|
||||||
|
pub fn new() -> HttpServiceBuilder<T, S> {
|
||||||
|
HttpServiceBuilder {
|
||||||
|
keep_alive: KeepAlive::Timeout(5),
|
||||||
|
client_timeout: 5000,
|
||||||
|
client_disconnect: 0,
|
||||||
|
_t: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set server keep-alive setting.
|
||||||
|
///
|
||||||
|
/// By default keep alive is set to a 5 seconds.
|
||||||
|
pub fn keep_alive<U: Into<KeepAlive>>(mut self, val: U) -> Self {
|
||||||
|
self.keep_alive = val.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set server client timeout in milliseconds for first request.
|
||||||
|
///
|
||||||
|
/// Defines a timeout for reading client request header. If a client does not transmit
|
||||||
|
/// the entire set headers within this time, the request is terminated with
|
||||||
|
/// the 408 (Request Time-out) error.
|
||||||
|
///
|
||||||
|
/// To disable timeout set value to 0.
|
||||||
|
///
|
||||||
|
/// By default client timeout is set to 5000 milliseconds.
|
||||||
|
pub fn client_timeout(mut self, val: u64) -> Self {
|
||||||
|
self.client_timeout = val;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set server connection disconnect timeout in milliseconds.
|
||||||
|
///
|
||||||
|
/// Defines a timeout for disconnect connection. If a disconnect procedure does not complete
|
||||||
|
/// within this time, the request get dropped. This timeout affects secure connections.
|
||||||
|
///
|
||||||
|
/// To disable timeout set value to 0.
|
||||||
|
///
|
||||||
|
/// By default disconnect timeout is set to 3000 milliseconds.
|
||||||
|
pub fn client_disconnect(mut self, val: u64) -> Self {
|
||||||
|
self.client_disconnect = val;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
// #[cfg(feature = "ssl")]
|
||||||
|
// /// Configure alpn protocols for SslAcceptorBuilder.
|
||||||
|
// pub fn configure_openssl(
|
||||||
|
// builder: &mut openssl::ssl::SslAcceptorBuilder,
|
||||||
|
// ) -> io::Result<()> {
|
||||||
|
// let protos: &[u8] = b"\x02h2";
|
||||||
|
// builder.set_alpn_select_callback(|_, protos| {
|
||||||
|
// const H2: &[u8] = b"\x02h2";
|
||||||
|
// if protos.windows(3).any(|window| window == H2) {
|
||||||
|
// Ok(b"h2")
|
||||||
|
// } else {
|
||||||
|
// Err(openssl::ssl::AlpnError::NOACK)
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// builder.set_alpn_protos(&protos)?;
|
||||||
|
|
||||||
|
// Ok(())
|
||||||
|
// }
|
||||||
|
|
||||||
|
/// Finish service configuration and create *http service* for HTTP/1 protocol.
|
||||||
|
pub fn h1<F, B>(self, service: F) -> H1Service<T, S, B>
|
||||||
|
where
|
||||||
|
B: MessageBody + 'static,
|
||||||
|
F: IntoNewService<S, SrvConfig>,
|
||||||
|
S::Response: Into<Response<B>>,
|
||||||
|
{
|
||||||
|
let cfg = ServiceConfig::new(
|
||||||
|
self.keep_alive,
|
||||||
|
self.client_timeout,
|
||||||
|
self.client_disconnect,
|
||||||
|
);
|
||||||
|
H1Service::with_config(cfg, service.into_new_service())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Finish service configuration and create *http service* for HTTP/2 protocol.
|
||||||
|
pub fn h2<F, B>(self, service: F) -> H2Service<T, S, B>
|
||||||
|
where
|
||||||
|
B: MessageBody + 'static,
|
||||||
|
F: IntoNewService<S, SrvConfig>,
|
||||||
|
S::Response: Into<Response<B>>,
|
||||||
|
{
|
||||||
|
let cfg = ServiceConfig::new(
|
||||||
|
self.keep_alive,
|
||||||
|
self.client_timeout,
|
||||||
|
self.client_disconnect,
|
||||||
|
);
|
||||||
|
H2Service::with_config(cfg, service.into_new_service())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Finish service configuration and create `HttpService` instance.
|
||||||
|
pub fn finish<F, B>(self, service: F) -> HttpService<T, S, B>
|
||||||
|
where
|
||||||
|
B: MessageBody + 'static,
|
||||||
|
F: IntoNewService<S, SrvConfig>,
|
||||||
|
S::Response: Into<Response<B>>,
|
||||||
|
{
|
||||||
|
let cfg = ServiceConfig::new(
|
||||||
|
self.keep_alive,
|
||||||
|
self.client_timeout,
|
||||||
|
self.client_disconnect,
|
||||||
|
);
|
||||||
|
HttpService::with_config(cfg, service.into_new_service())
|
||||||
|
}
|
||||||
|
}
|
118
src/config.rs
118
src/config.rs
|
@ -1,12 +1,11 @@
|
||||||
use std::cell::UnsafeCell;
|
use std::cell::UnsafeCell;
|
||||||
|
use std::fmt;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use std::{fmt, net};
|
|
||||||
|
|
||||||
use bytes::BytesMut;
|
use bytes::BytesMut;
|
||||||
use futures::{future, Future};
|
use futures::{future, Future};
|
||||||
use log::error;
|
|
||||||
use time;
|
use time;
|
||||||
use tokio_timer::{sleep, Delay};
|
use tokio_timer::{sleep, Delay};
|
||||||
|
|
||||||
|
@ -90,11 +89,6 @@ impl ServiceConfig {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create worker settings builder.
|
|
||||||
pub fn build() -> ServiceConfigBuilder {
|
|
||||||
ServiceConfigBuilder::new()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
/// Keep alive duration if configured.
|
/// Keep alive duration if configured.
|
||||||
pub fn keep_alive(&self) -> Option<Duration> {
|
pub fn keep_alive(&self) -> Option<Duration> {
|
||||||
|
@ -177,116 +171,6 @@ impl ServiceConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A service config builder
|
|
||||||
///
|
|
||||||
/// This type can be used to construct an instance of `ServiceConfig` through a
|
|
||||||
/// builder-like pattern.
|
|
||||||
pub struct ServiceConfigBuilder {
|
|
||||||
keep_alive: KeepAlive,
|
|
||||||
client_timeout: u64,
|
|
||||||
client_disconnect: u64,
|
|
||||||
host: String,
|
|
||||||
addr: net::SocketAddr,
|
|
||||||
secure: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ServiceConfigBuilder {
|
|
||||||
/// Create instance of `ServiceConfigBuilder`
|
|
||||||
pub fn new() -> ServiceConfigBuilder {
|
|
||||||
ServiceConfigBuilder {
|
|
||||||
keep_alive: KeepAlive::Timeout(5),
|
|
||||||
client_timeout: 5000,
|
|
||||||
client_disconnect: 0,
|
|
||||||
secure: false,
|
|
||||||
host: "localhost".to_owned(),
|
|
||||||
addr: "127.0.0.1:8080".parse().unwrap(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Enable secure flag for current server.
|
|
||||||
/// This flags also enables `client disconnect timeout`.
|
|
||||||
///
|
|
||||||
/// By default this flag is set to false.
|
|
||||||
pub fn secure(mut self) -> Self {
|
|
||||||
self.secure = true;
|
|
||||||
if self.client_disconnect == 0 {
|
|
||||||
self.client_disconnect = 3000;
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set server keep-alive setting.
|
|
||||||
///
|
|
||||||
/// By default keep alive is set to a 5 seconds.
|
|
||||||
pub fn keep_alive<T: Into<KeepAlive>>(mut self, val: T) -> Self {
|
|
||||||
self.keep_alive = val.into();
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set server client timeout in milliseconds for first request.
|
|
||||||
///
|
|
||||||
/// Defines a timeout for reading client request header. If a client does not transmit
|
|
||||||
/// the entire set headers within this time, the request is terminated with
|
|
||||||
/// the 408 (Request Time-out) error.
|
|
||||||
///
|
|
||||||
/// To disable timeout set value to 0.
|
|
||||||
///
|
|
||||||
/// By default client timeout is set to 5000 milliseconds.
|
|
||||||
pub fn client_timeout(mut self, val: u64) -> Self {
|
|
||||||
self.client_timeout = val;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set server connection disconnect timeout in milliseconds.
|
|
||||||
///
|
|
||||||
/// Defines a timeout for disconnect connection. If a disconnect procedure does not complete
|
|
||||||
/// within this time, the request get dropped. This timeout affects secure connections.
|
|
||||||
///
|
|
||||||
/// To disable timeout set value to 0.
|
|
||||||
///
|
|
||||||
/// By default disconnect timeout is set to 3000 milliseconds.
|
|
||||||
pub fn client_disconnect(mut self, val: u64) -> Self {
|
|
||||||
self.client_disconnect = val;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set server host name.
|
|
||||||
///
|
|
||||||
/// Host name is used by application router aa a hostname for url
|
|
||||||
/// generation. Check [ConnectionInfo](./dev/struct.ConnectionInfo.
|
|
||||||
/// html#method.host) documentation for more information.
|
|
||||||
///
|
|
||||||
/// By default host name is set to a "localhost" value.
|
|
||||||
pub fn server_hostname(mut self, val: &str) -> Self {
|
|
||||||
self.host = val.to_owned();
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set server ip address.
|
|
||||||
///
|
|
||||||
/// Host name is used by application router aa a hostname for url
|
|
||||||
/// generation. Check [ConnectionInfo](./dev/struct.ConnectionInfo.
|
|
||||||
/// html#method.host) documentation for more information.
|
|
||||||
///
|
|
||||||
/// By default server address is set to a "127.0.0.1:8080"
|
|
||||||
pub fn server_address<S: net::ToSocketAddrs>(mut self, addr: S) -> Self {
|
|
||||||
match addr.to_socket_addrs() {
|
|
||||||
Err(err) => error!("Can not convert to SocketAddr: {}", err),
|
|
||||||
Ok(mut addrs) => {
|
|
||||||
if let Some(addr) = addrs.next() {
|
|
||||||
self.addr = addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Finish service configuration and create `ServiceConfig` object.
|
|
||||||
pub fn finish(&mut self) -> ServiceConfig {
|
|
||||||
ServiceConfig::new(self.keep_alive, self.client_timeout, self.client_disconnect)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Date {
|
struct Date {
|
||||||
bytes: [u8; DATE_VALUE_LENGTH],
|
bytes: [u8; DATE_VALUE_LENGTH],
|
||||||
pos: usize,
|
pos: usize,
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::net;
|
|
||||||
|
|
||||||
use actix_codec::{AsyncRead, AsyncWrite, Framed};
|
use actix_codec::{AsyncRead, AsyncWrite, Framed};
|
||||||
use actix_server_config::ServerConfig as SrvConfig;
|
use actix_server_config::ServerConfig as SrvConfig;
|
||||||
|
@ -8,7 +7,6 @@ use actix_service::{IntoNewService, NewService, Service};
|
||||||
use actix_utils::cloneable::CloneableService;
|
use actix_utils::cloneable::CloneableService;
|
||||||
use futures::future::{ok, FutureResult};
|
use futures::future::{ok, FutureResult};
|
||||||
use futures::{try_ready, Async, Future, IntoFuture, Poll, Stream};
|
use futures::{try_ready, Async, Future, IntoFuture, Poll, Stream};
|
||||||
use log::error;
|
|
||||||
|
|
||||||
use crate::body::MessageBody;
|
use crate::body::MessageBody;
|
||||||
use crate::config::{KeepAlive, ServiceConfig};
|
use crate::config::{KeepAlive, ServiceConfig};
|
||||||
|
@ -57,11 +55,6 @@ where
|
||||||
_t: PhantomData,
|
_t: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create builder for `HttpService` instance.
|
|
||||||
pub fn build() -> H1ServiceBuilder<T, S> {
|
|
||||||
H1ServiceBuilder::new()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S, B> NewService<SrvConfig> for H1Service<T, S, B>
|
impl<T, S, B> NewService<SrvConfig> for H1Service<T, S, B>
|
||||||
|
@ -89,135 +82,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A http/1 new service builder
|
|
||||||
///
|
|
||||||
/// This type can be used to construct an instance of `ServiceConfig` through a
|
|
||||||
/// builder-like pattern.
|
|
||||||
pub struct H1ServiceBuilder<T, S> {
|
|
||||||
keep_alive: KeepAlive,
|
|
||||||
client_timeout: u64,
|
|
||||||
client_disconnect: u64,
|
|
||||||
host: String,
|
|
||||||
addr: net::SocketAddr,
|
|
||||||
secure: bool,
|
|
||||||
_t: PhantomData<(T, S)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, S> H1ServiceBuilder<T, S>
|
|
||||||
where
|
|
||||||
S: NewService<SrvConfig, Request = Request>,
|
|
||||||
S::Error: Debug,
|
|
||||||
{
|
|
||||||
/// Create instance of `ServiceConfigBuilder`
|
|
||||||
pub fn new() -> H1ServiceBuilder<T, S> {
|
|
||||||
H1ServiceBuilder {
|
|
||||||
keep_alive: KeepAlive::Timeout(5),
|
|
||||||
client_timeout: 5000,
|
|
||||||
client_disconnect: 0,
|
|
||||||
secure: false,
|
|
||||||
host: "localhost".to_owned(),
|
|
||||||
addr: "127.0.0.1:8080".parse().unwrap(),
|
|
||||||
_t: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Enable secure flag for current server.
|
|
||||||
/// This flags also enables `client disconnect timeout`.
|
|
||||||
///
|
|
||||||
/// By default this flag is set to false.
|
|
||||||
pub fn secure(mut self) -> Self {
|
|
||||||
self.secure = true;
|
|
||||||
if self.client_disconnect == 0 {
|
|
||||||
self.client_disconnect = 3000;
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set server keep-alive setting.
|
|
||||||
///
|
|
||||||
/// By default keep alive is set to a 5 seconds.
|
|
||||||
pub fn keep_alive<U: Into<KeepAlive>>(mut self, val: U) -> Self {
|
|
||||||
self.keep_alive = val.into();
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set server client timeout in milliseconds for first request.
|
|
||||||
///
|
|
||||||
/// Defines a timeout for reading client request header. If a client does not transmit
|
|
||||||
/// the entire set headers within this time, the request is terminated with
|
|
||||||
/// the 408 (Request Time-out) error.
|
|
||||||
///
|
|
||||||
/// To disable timeout set value to 0.
|
|
||||||
///
|
|
||||||
/// By default client timeout is set to 5000 milliseconds.
|
|
||||||
pub fn client_timeout(mut self, val: u64) -> Self {
|
|
||||||
self.client_timeout = val;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set server connection disconnect timeout in milliseconds.
|
|
||||||
///
|
|
||||||
/// Defines a timeout for disconnect connection. If a disconnect procedure does not complete
|
|
||||||
/// within this time, the request get dropped. This timeout affects secure connections.
|
|
||||||
///
|
|
||||||
/// To disable timeout set value to 0.
|
|
||||||
///
|
|
||||||
/// By default disconnect timeout is set to 3000 milliseconds.
|
|
||||||
pub fn client_disconnect(mut self, val: u64) -> Self {
|
|
||||||
self.client_disconnect = val;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set server host name.
|
|
||||||
///
|
|
||||||
/// Host name is used by application router aa a hostname for url
|
|
||||||
/// generation. Check [ConnectionInfo](./dev/struct.ConnectionInfo.
|
|
||||||
/// html#method.host) documentation for more information.
|
|
||||||
///
|
|
||||||
/// By default host name is set to a "localhost" value.
|
|
||||||
pub fn server_hostname(mut self, val: &str) -> Self {
|
|
||||||
self.host = val.to_owned();
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set server ip address.
|
|
||||||
///
|
|
||||||
/// Host name is used by application router aa a hostname for url
|
|
||||||
/// generation. Check [ConnectionInfo](./dev/struct.ConnectionInfo.
|
|
||||||
/// html#method.host) documentation for more information.
|
|
||||||
///
|
|
||||||
/// By default server address is set to a "127.0.0.1:8080"
|
|
||||||
pub fn server_address<U: net::ToSocketAddrs>(mut self, addr: U) -> Self {
|
|
||||||
match addr.to_socket_addrs() {
|
|
||||||
Err(err) => error!("Can not convert to SocketAddr: {}", err),
|
|
||||||
Ok(mut addrs) => {
|
|
||||||
if let Some(addr) = addrs.next() {
|
|
||||||
self.addr = addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Finish service configuration and create `H1Service` instance.
|
|
||||||
pub fn finish<F, B>(self, service: F) -> H1Service<T, S, B>
|
|
||||||
where
|
|
||||||
B: MessageBody,
|
|
||||||
F: IntoNewService<S, SrvConfig>,
|
|
||||||
{
|
|
||||||
let cfg = ServiceConfig::new(
|
|
||||||
self.keep_alive,
|
|
||||||
self.client_timeout,
|
|
||||||
self.client_disconnect,
|
|
||||||
);
|
|
||||||
H1Service {
|
|
||||||
cfg,
|
|
||||||
srv: service.into_new_service(),
|
|
||||||
_t: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct H1ServiceResponse<T, S: NewService<SrvConfig, Request = Request>, B> {
|
pub struct H1ServiceResponse<T, S: NewService<SrvConfig, Request = Request>, B> {
|
||||||
fut: <S::Future as IntoFuture>::Future,
|
fut: <S::Future as IntoFuture>::Future,
|
||||||
|
|
|
@ -59,11 +59,6 @@ where
|
||||||
_t: PhantomData,
|
_t: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create builder for `HttpService` instance.
|
|
||||||
pub fn build() -> H2ServiceBuilder<T, S> {
|
|
||||||
H2ServiceBuilder::new()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S, B> NewService<SrvConfig> for H2Service<T, S, B>
|
impl<T, S, B> NewService<SrvConfig> for H2Service<T, S, B>
|
||||||
|
@ -91,136 +86,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A http/2 new service builder
|
|
||||||
///
|
|
||||||
/// This type can be used to construct an instance of `ServiceConfig` through a
|
|
||||||
/// builder-like pattern.
|
|
||||||
pub struct H2ServiceBuilder<T, S> {
|
|
||||||
keep_alive: KeepAlive,
|
|
||||||
client_timeout: u64,
|
|
||||||
client_disconnect: u64,
|
|
||||||
host: String,
|
|
||||||
addr: net::SocketAddr,
|
|
||||||
secure: bool,
|
|
||||||
_t: PhantomData<(T, S)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, S> H2ServiceBuilder<T, S>
|
|
||||||
where
|
|
||||||
S: NewService<SrvConfig, Request = Request>,
|
|
||||||
S::Service: 'static,
|
|
||||||
S::Error: Debug + 'static,
|
|
||||||
{
|
|
||||||
/// Create instance of `H2ServiceBuilder`
|
|
||||||
pub fn new() -> H2ServiceBuilder<T, S> {
|
|
||||||
H2ServiceBuilder {
|
|
||||||
keep_alive: KeepAlive::Timeout(5),
|
|
||||||
client_timeout: 5000,
|
|
||||||
client_disconnect: 0,
|
|
||||||
secure: false,
|
|
||||||
host: "localhost".to_owned(),
|
|
||||||
addr: "127.0.0.1:8080".parse().unwrap(),
|
|
||||||
_t: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Enable secure flag for current server.
|
|
||||||
/// This flags also enables `client disconnect timeout`.
|
|
||||||
///
|
|
||||||
/// By default this flag is set to false.
|
|
||||||
pub fn secure(mut self) -> Self {
|
|
||||||
self.secure = true;
|
|
||||||
if self.client_disconnect == 0 {
|
|
||||||
self.client_disconnect = 3000;
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set server keep-alive setting.
|
|
||||||
///
|
|
||||||
/// By default keep alive is set to a 5 seconds.
|
|
||||||
pub fn keep_alive<U: Into<KeepAlive>>(mut self, val: U) -> Self {
|
|
||||||
self.keep_alive = val.into();
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set server client timeout in milliseconds for first request.
|
|
||||||
///
|
|
||||||
/// Defines a timeout for reading client request header. If a client does not transmit
|
|
||||||
/// the entire set headers within this time, the request is terminated with
|
|
||||||
/// the 408 (Request Time-out) error.
|
|
||||||
///
|
|
||||||
/// To disable timeout set value to 0.
|
|
||||||
///
|
|
||||||
/// By default client timeout is set to 5000 milliseconds.
|
|
||||||
pub fn client_timeout(mut self, val: u64) -> Self {
|
|
||||||
self.client_timeout = val;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set server connection disconnect timeout in milliseconds.
|
|
||||||
///
|
|
||||||
/// Defines a timeout for disconnect connection. If a disconnect procedure does not complete
|
|
||||||
/// within this time, the request get dropped. This timeout affects secure connections.
|
|
||||||
///
|
|
||||||
/// To disable timeout set value to 0.
|
|
||||||
///
|
|
||||||
/// By default disconnect timeout is set to 3000 milliseconds.
|
|
||||||
pub fn client_disconnect(mut self, val: u64) -> Self {
|
|
||||||
self.client_disconnect = val;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set server host name.
|
|
||||||
///
|
|
||||||
/// Host name is used by application router aa a hostname for url
|
|
||||||
/// generation. Check [ConnectionInfo](./dev/struct.ConnectionInfo.
|
|
||||||
/// html#method.host) documentation for more information.
|
|
||||||
///
|
|
||||||
/// By default host name is set to a "localhost" value.
|
|
||||||
pub fn server_hostname(mut self, val: &str) -> Self {
|
|
||||||
self.host = val.to_owned();
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set server ip address.
|
|
||||||
///
|
|
||||||
/// Host name is used by application router aa a hostname for url
|
|
||||||
/// generation. Check [ConnectionInfo](./dev/struct.ConnectionInfo.
|
|
||||||
/// html#method.host) documentation for more information.
|
|
||||||
///
|
|
||||||
/// By default server address is set to a "127.0.0.1:8080"
|
|
||||||
pub fn server_address<U: net::ToSocketAddrs>(mut self, addr: U) -> Self {
|
|
||||||
match addr.to_socket_addrs() {
|
|
||||||
Err(err) => error!("Can not convert to SocketAddr: {}", err),
|
|
||||||
Ok(mut addrs) => {
|
|
||||||
if let Some(addr) = addrs.next() {
|
|
||||||
self.addr = addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Finish service configuration and create `H1Service` instance.
|
|
||||||
pub fn finish<F, B>(self, service: F) -> H2Service<T, S, B>
|
|
||||||
where
|
|
||||||
B: MessageBody,
|
|
||||||
F: IntoNewService<S, SrvConfig>,
|
|
||||||
{
|
|
||||||
let cfg = ServiceConfig::new(
|
|
||||||
self.keep_alive,
|
|
||||||
self.client_timeout,
|
|
||||||
self.client_disconnect,
|
|
||||||
);
|
|
||||||
H2Service {
|
|
||||||
cfg,
|
|
||||||
srv: service.into_new_service(),
|
|
||||||
_t: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct H2ServiceResponse<T, S: NewService<SrvConfig, Request = Request>, B> {
|
pub struct H2ServiceResponse<T, S: NewService<SrvConfig, Request = Request>, B> {
|
||||||
fut: <S::Future as IntoFuture>::Future,
|
fut: <S::Future as IntoFuture>::Future,
|
||||||
|
|
|
@ -69,6 +69,7 @@
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
pub mod body;
|
pub mod body;
|
||||||
|
mod builder;
|
||||||
pub mod client;
|
pub mod client;
|
||||||
mod config;
|
mod config;
|
||||||
mod extensions;
|
mod extensions;
|
||||||
|
@ -89,7 +90,8 @@ pub mod h2;
|
||||||
pub mod test;
|
pub mod test;
|
||||||
pub mod ws;
|
pub mod ws;
|
||||||
|
|
||||||
pub use self::config::{KeepAlive, ServiceConfig, ServiceConfigBuilder};
|
pub use self::builder::HttpServiceBuilder;
|
||||||
|
pub use self::config::{KeepAlive, ServiceConfig};
|
||||||
pub use self::error::{Error, ResponseError, Result};
|
pub use self::error::{Error, ResponseError, Result};
|
||||||
pub use self::extensions::Extensions;
|
pub use self::extensions::Extensions;
|
||||||
pub use self::httpmessage::HttpMessage;
|
pub use self::httpmessage::HttpMessage;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::{fmt, io, net};
|
use std::{fmt, io};
|
||||||
|
|
||||||
use actix_codec::{AsyncRead, AsyncWrite, Framed, FramedParts};
|
use actix_codec::{AsyncRead, AsyncWrite, Framed, FramedParts};
|
||||||
use actix_server_config::ServerConfig as SrvConfig;
|
use actix_server_config::ServerConfig as SrvConfig;
|
||||||
|
@ -12,11 +12,11 @@ use h2::server::{self, Handshake};
|
||||||
use log::error;
|
use log::error;
|
||||||
|
|
||||||
use crate::body::MessageBody;
|
use crate::body::MessageBody;
|
||||||
|
use crate::builder::HttpServiceBuilder;
|
||||||
use crate::config::{KeepAlive, ServiceConfig};
|
use crate::config::{KeepAlive, ServiceConfig};
|
||||||
use crate::error::DispatchError;
|
use crate::error::DispatchError;
|
||||||
use crate::request::Request;
|
use crate::request::Request;
|
||||||
use crate::response::Response;
|
use crate::response::Response;
|
||||||
|
|
||||||
use crate::{h1, h2::Dispatcher};
|
use crate::{h1, h2::Dispatcher};
|
||||||
|
|
||||||
/// `NewService` HTTP1.1/HTTP2 transport implementation
|
/// `NewService` HTTP1.1/HTTP2 transport implementation
|
||||||
|
@ -46,7 +46,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create new `HttpService` instance with config.
|
/// Create new `HttpService` instance with config.
|
||||||
pub fn with_config<F: IntoNewService<S, SrvConfig>>(
|
pub(crate) fn with_config<F: IntoNewService<S, SrvConfig>>(
|
||||||
cfg: ServiceConfig,
|
cfg: ServiceConfig,
|
||||||
service: F,
|
service: F,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -88,155 +88,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A http service factory builder
|
|
||||||
///
|
|
||||||
/// This type can be used to construct an instance of `ServiceConfig` through a
|
|
||||||
/// builder-like pattern.
|
|
||||||
pub struct HttpServiceBuilder<T, S> {
|
|
||||||
keep_alive: KeepAlive,
|
|
||||||
client_timeout: u64,
|
|
||||||
client_disconnect: u64,
|
|
||||||
host: String,
|
|
||||||
addr: net::SocketAddr,
|
|
||||||
secure: bool,
|
|
||||||
_t: PhantomData<(T, S)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, S> HttpServiceBuilder<T, S>
|
|
||||||
where
|
|
||||||
S: NewService<SrvConfig, Request = Request>,
|
|
||||||
S::Service: 'static,
|
|
||||||
S::Error: Debug + 'static,
|
|
||||||
{
|
|
||||||
/// Create instance of `HttpServiceBuilder` type
|
|
||||||
pub fn new() -> HttpServiceBuilder<T, S> {
|
|
||||||
HttpServiceBuilder {
|
|
||||||
keep_alive: KeepAlive::Timeout(5),
|
|
||||||
client_timeout: 5000,
|
|
||||||
client_disconnect: 0,
|
|
||||||
secure: false,
|
|
||||||
host: "localhost".to_owned(),
|
|
||||||
addr: "127.0.0.1:8080".parse().unwrap(),
|
|
||||||
_t: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Enable secure flag for current server.
|
|
||||||
/// This flags also enables `client disconnect timeout`.
|
|
||||||
///
|
|
||||||
/// By default this flag is set to false.
|
|
||||||
pub fn secure(mut self) -> Self {
|
|
||||||
self.secure = true;
|
|
||||||
if self.client_disconnect == 0 {
|
|
||||||
self.client_disconnect = 3000;
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set server keep-alive setting.
|
|
||||||
///
|
|
||||||
/// By default keep alive is set to a 5 seconds.
|
|
||||||
pub fn keep_alive<U: Into<KeepAlive>>(mut self, val: U) -> Self {
|
|
||||||
self.keep_alive = val.into();
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set server client timeout in milliseconds for first request.
|
|
||||||
///
|
|
||||||
/// Defines a timeout for reading client request header. If a client does not transmit
|
|
||||||
/// the entire set headers within this time, the request is terminated with
|
|
||||||
/// the 408 (Request Time-out) error.
|
|
||||||
///
|
|
||||||
/// To disable timeout set value to 0.
|
|
||||||
///
|
|
||||||
/// By default client timeout is set to 5000 milliseconds.
|
|
||||||
pub fn client_timeout(mut self, val: u64) -> Self {
|
|
||||||
self.client_timeout = val;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set server connection disconnect timeout in milliseconds.
|
|
||||||
///
|
|
||||||
/// Defines a timeout for disconnect connection. If a disconnect procedure does not complete
|
|
||||||
/// within this time, the request get dropped. This timeout affects secure connections.
|
|
||||||
///
|
|
||||||
/// To disable timeout set value to 0.
|
|
||||||
///
|
|
||||||
/// By default disconnect timeout is set to 3000 milliseconds.
|
|
||||||
pub fn client_disconnect(mut self, val: u64) -> Self {
|
|
||||||
self.client_disconnect = val;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set server host name.
|
|
||||||
///
|
|
||||||
/// Host name is used by application router aa a hostname for url
|
|
||||||
/// generation. Check [ConnectionInfo](./dev/struct.ConnectionInfo.
|
|
||||||
/// html#method.host) documentation for more information.
|
|
||||||
///
|
|
||||||
/// By default host name is set to a "localhost" value.
|
|
||||||
pub fn server_hostname(mut self, val: &str) -> Self {
|
|
||||||
self.host = val.to_owned();
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set server ip address.
|
|
||||||
///
|
|
||||||
/// Host name is used by application router aa a hostname for url
|
|
||||||
/// generation. Check [ConnectionInfo](./dev/struct.ConnectionInfo.
|
|
||||||
/// html#method.host) documentation for more information.
|
|
||||||
///
|
|
||||||
/// By default server address is set to a "127.0.0.1:8080"
|
|
||||||
pub fn server_address<U: net::ToSocketAddrs>(mut self, addr: U) -> Self {
|
|
||||||
match addr.to_socket_addrs() {
|
|
||||||
Err(err) => error!("Can not convert to SocketAddr: {}", err),
|
|
||||||
Ok(mut addrs) => {
|
|
||||||
if let Some(addr) = addrs.next() {
|
|
||||||
self.addr = addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
// #[cfg(feature = "ssl")]
|
|
||||||
// /// Configure alpn protocols for SslAcceptorBuilder.
|
|
||||||
// pub fn configure_openssl(
|
|
||||||
// builder: &mut openssl::ssl::SslAcceptorBuilder,
|
|
||||||
// ) -> io::Result<()> {
|
|
||||||
// let protos: &[u8] = b"\x02h2";
|
|
||||||
// builder.set_alpn_select_callback(|_, protos| {
|
|
||||||
// const H2: &[u8] = b"\x02h2";
|
|
||||||
// if protos.windows(3).any(|window| window == H2) {
|
|
||||||
// Ok(b"h2")
|
|
||||||
// } else {
|
|
||||||
// Err(openssl::ssl::AlpnError::NOACK)
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// builder.set_alpn_protos(&protos)?;
|
|
||||||
|
|
||||||
// Ok(())
|
|
||||||
// }
|
|
||||||
|
|
||||||
/// Finish service configuration and create `HttpService` instance.
|
|
||||||
pub fn finish<F, B>(self, service: F) -> HttpService<T, S, B>
|
|
||||||
where
|
|
||||||
B: MessageBody,
|
|
||||||
F: IntoNewService<S, SrvConfig>,
|
|
||||||
{
|
|
||||||
let cfg = ServiceConfig::new(
|
|
||||||
self.keep_alive,
|
|
||||||
self.client_timeout,
|
|
||||||
self.client_disconnect,
|
|
||||||
);
|
|
||||||
HttpService {
|
|
||||||
cfg,
|
|
||||||
srv: service.into_new_service(),
|
|
||||||
_t: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct HttpServiceResponse<T, S: NewService<SrvConfig>, B> {
|
pub struct HttpServiceResponse<T, S: NewService<SrvConfig>, B> {
|
||||||
fut: <S::Future as IntoFuture>::Future,
|
fut: <S::Future as IntoFuture>::Future,
|
||||||
|
|
|
@ -3,7 +3,7 @@ use bytes::Bytes;
|
||||||
use futures::future::{self, ok};
|
use futures::future::{self, ok};
|
||||||
|
|
||||||
use actix_http::HttpMessage;
|
use actix_http::HttpMessage;
|
||||||
use actix_http::{client, h1, Request, Response};
|
use actix_http::{client, HttpService, Request, Response};
|
||||||
use actix_http_test::TestServer;
|
use actix_http_test::TestServer;
|
||||||
|
|
||||||
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
||||||
|
@ -32,7 +32,7 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
||||||
fn test_h1_v2() {
|
fn test_h1_v2() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let mut srv = TestServer::new(move || {
|
let mut srv = TestServer::new(move || {
|
||||||
h1::H1Service::build()
|
HttpService::build()
|
||||||
.finish(|_| future::ok::<_, ()>(Response::Ok().body(STR)))
|
.finish(|_| future::ok::<_, ()>(Response::Ok().body(STR)))
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
});
|
});
|
||||||
|
@ -66,7 +66,7 @@ fn test_h1_v2() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_connection_close() {
|
fn test_connection_close() {
|
||||||
let mut srv = TestServer::new(move || {
|
let mut srv = TestServer::new(move || {
|
||||||
h1::H1Service::build()
|
HttpService::build()
|
||||||
.finish(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
.finish(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
});
|
});
|
||||||
|
@ -80,7 +80,7 @@ fn test_connection_close() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_with_query_parameter() {
|
fn test_with_query_parameter() {
|
||||||
let mut srv = TestServer::new(move || {
|
let mut srv = TestServer::new(move || {
|
||||||
h1::H1Service::build()
|
HttpService::build()
|
||||||
.finish(|req: Request| {
|
.finish(|req: Request| {
|
||||||
if req.uri().query().unwrap().contains("qp=") {
|
if req.uri().query().unwrap().contains("qp=") {
|
||||||
ok::<_, ()>(Response::Ok().finish())
|
ok::<_, ()>(Response::Ok().finish())
|
||||||
|
|
|
@ -10,20 +10,18 @@ use futures::stream::once;
|
||||||
|
|
||||||
use actix_http::body::Body;
|
use actix_http::body::Body;
|
||||||
use actix_http::{
|
use actix_http::{
|
||||||
body, client, h1, h2, http, Error, HttpMessage as HttpMessage2, HttpService,
|
body, client, http, Error, HttpMessage as HttpMessage2, HttpService, KeepAlive,
|
||||||
KeepAlive, Request, Response,
|
Request, Response,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_h1() {
|
fn test_h1() {
|
||||||
let mut srv = TestServer::new(|| {
|
let mut srv = TestServer::new(|| {
|
||||||
h1::H1Service::build()
|
HttpService::build()
|
||||||
.keep_alive(KeepAlive::Disabled)
|
.keep_alive(KeepAlive::Disabled)
|
||||||
.client_timeout(1000)
|
.client_timeout(1000)
|
||||||
.client_disconnect(1000)
|
.client_disconnect(1000)
|
||||||
.server_hostname("localhost")
|
.h1(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
||||||
.finish(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
|
||||||
.map(|_| ())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let req = client::ClientRequest::get(srv.url("/")).finish().unwrap();
|
let req = client::ClientRequest::get(srv.url("/")).finish().unwrap();
|
||||||
|
@ -38,7 +36,6 @@ fn test_h1_2() {
|
||||||
.keep_alive(KeepAlive::Disabled)
|
.keep_alive(KeepAlive::Disabled)
|
||||||
.client_timeout(1000)
|
.client_timeout(1000)
|
||||||
.client_disconnect(1000)
|
.client_disconnect(1000)
|
||||||
.server_hostname("localhost")
|
|
||||||
.finish(|req: Request| {
|
.finish(|req: Request| {
|
||||||
assert_eq!(req.version(), http::Version::HTTP_11);
|
assert_eq!(req.version(), http::Version::HTTP_11);
|
||||||
future::ok::<_, ()>(Response::Ok().finish())
|
future::ok::<_, ()>(Response::Ok().finish())
|
||||||
|
@ -83,8 +80,8 @@ fn test_h2() -> std::io::Result<()> {
|
||||||
.clone()
|
.clone()
|
||||||
.map_err(|e| println!("Openssl error: {}", e))
|
.map_err(|e| println!("Openssl error: {}", e))
|
||||||
.and_then(
|
.and_then(
|
||||||
h2::H2Service::build()
|
HttpService::build()
|
||||||
.finish(|_| future::ok::<_, Error>(Response::Ok().finish()))
|
.h2(|_| future::ok::<_, Error>(Response::Ok().finish()))
|
||||||
.map_err(|_| ()),
|
.map_err(|_| ()),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -129,8 +126,8 @@ fn test_h2_body() -> std::io::Result<()> {
|
||||||
.clone()
|
.clone()
|
||||||
.map_err(|e| println!("Openssl error: {}", e))
|
.map_err(|e| println!("Openssl error: {}", e))
|
||||||
.and_then(
|
.and_then(
|
||||||
h2::H2Service::build()
|
HttpService::build()
|
||||||
.finish(|mut req: Request<_>| {
|
.h2(|mut req: Request<_>| {
|
||||||
req.body()
|
req.body()
|
||||||
.limit(1024 * 1024)
|
.limit(1024 * 1024)
|
||||||
.and_then(|body| Ok(Response::Ok().body(body)))
|
.and_then(|body| Ok(Response::Ok().body(body)))
|
||||||
|
@ -153,10 +150,9 @@ fn test_h2_body() -> std::io::Result<()> {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_slow_request() {
|
fn test_slow_request() {
|
||||||
let srv = TestServer::new(|| {
|
let srv = TestServer::new(|| {
|
||||||
h1::H1Service::build()
|
HttpService::build()
|
||||||
.client_timeout(100)
|
.client_timeout(100)
|
||||||
.finish(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
.h1(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
||||||
.map(|_| ())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
|
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
|
||||||
|
@ -167,9 +163,9 @@ fn test_slow_request() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_malformed_request() {
|
fn test_http1_malformed_request() {
|
||||||
let srv = TestServer::new(|| {
|
let srv = TestServer::new(|| {
|
||||||
h1::H1Service::new(|_| future::ok::<_, ()>(Response::Ok().finish())).map(|_| ())
|
HttpService::build().h1(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
|
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
|
||||||
|
@ -180,11 +176,9 @@ fn test_malformed_request() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_keepalive() {
|
fn test_http1_keepalive() {
|
||||||
let srv = TestServer::new(|| {
|
let srv = TestServer::new(|| {
|
||||||
h1::H1Service::build()
|
HttpService::build().h1(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
||||||
.finish(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
|
||||||
.map(|_| ())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
|
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
|
||||||
|
@ -200,12 +194,11 @@ fn test_keepalive() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_keepalive_timeout() {
|
fn test_http1_keepalive_timeout() {
|
||||||
let srv = TestServer::new(|| {
|
let srv = TestServer::new(|| {
|
||||||
h1::H1Service::build()
|
HttpService::build()
|
||||||
.keep_alive(1)
|
.keep_alive(1)
|
||||||
.finish(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
.h1(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
||||||
.map(|_| ())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
|
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
|
||||||
|
@ -221,11 +214,9 @@ fn test_keepalive_timeout() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_keepalive_close() {
|
fn test_http1_keepalive_close() {
|
||||||
let srv = TestServer::new(|| {
|
let srv = TestServer::new(|| {
|
||||||
h1::H1Service::build()
|
HttpService::build().h1(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
||||||
.finish(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
|
||||||
.map(|_| ())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
|
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
|
||||||
|
@ -241,11 +232,9 @@ fn test_keepalive_close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_keepalive_http10_default_close() {
|
fn test_http10_keepalive_default_close() {
|
||||||
let srv = TestServer::new(|| {
|
let srv = TestServer::new(|| {
|
||||||
h1::H1Service::build()
|
HttpService::build().h1(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
||||||
.finish(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
|
||||||
.map(|_| ())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
|
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
|
||||||
|
@ -260,11 +249,9 @@ fn test_keepalive_http10_default_close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_keepalive_http10() {
|
fn test_http10_keepalive() {
|
||||||
let srv = TestServer::new(|| {
|
let srv = TestServer::new(|| {
|
||||||
h1::H1Service::build()
|
HttpService::build().h1(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
||||||
.finish(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
|
||||||
.map(|_| ())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
|
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
|
||||||
|
@ -286,12 +273,11 @@ fn test_keepalive_http10() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_keepalive_disabled() {
|
fn test_http1_keepalive_disabled() {
|
||||||
let srv = TestServer::new(|| {
|
let srv = TestServer::new(|| {
|
||||||
h1::H1Service::build()
|
HttpService::build()
|
||||||
.keep_alive(KeepAlive::Disabled)
|
.keep_alive(KeepAlive::Disabled)
|
||||||
.finish(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
.h1(|_| future::ok::<_, ()>(Response::Ok().finish()))
|
||||||
.map(|_| ())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
|
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
|
||||||
|
@ -313,7 +299,7 @@ fn test_content_length() {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut srv = TestServer::new(|| {
|
let mut srv = TestServer::new(|| {
|
||||||
h1::H1Service::new(|req: Request| {
|
HttpService::build().h1(|req: Request| {
|
||||||
let indx: usize = req.uri().path()[1..].parse().unwrap();
|
let indx: usize = req.uri().path()[1..].parse().unwrap();
|
||||||
let statuses = [
|
let statuses = [
|
||||||
StatusCode::NO_CONTENT,
|
StatusCode::NO_CONTENT,
|
||||||
|
@ -325,7 +311,6 @@ fn test_content_length() {
|
||||||
];
|
];
|
||||||
future::ok::<_, ()>(Response::new(statuses[indx]))
|
future::ok::<_, ()>(Response::new(statuses[indx]))
|
||||||
})
|
})
|
||||||
.map(|_| ())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let header = HeaderName::from_static("content-length");
|
let header = HeaderName::from_static("content-length");
|
||||||
|
@ -356,6 +341,65 @@ fn test_content_length() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: fix
|
||||||
|
// #[test]
|
||||||
|
// fn test_h2_content_length() {
|
||||||
|
// use actix_http::http::{
|
||||||
|
// header::{HeaderName, HeaderValue},
|
||||||
|
// StatusCode,
|
||||||
|
// };
|
||||||
|
// let openssl = ssl_acceptor().unwrap();
|
||||||
|
|
||||||
|
// let mut srv = TestServer::new(move || {
|
||||||
|
// openssl
|
||||||
|
// .clone()
|
||||||
|
// .map_err(|e| println!("Openssl error: {}", e))
|
||||||
|
// .and_then(
|
||||||
|
// HttpService::build()
|
||||||
|
// .h2(|req: Request| {
|
||||||
|
// let indx: usize = req.uri().path()[1..].parse().unwrap();
|
||||||
|
// let statuses = [
|
||||||
|
// StatusCode::NO_CONTENT,
|
||||||
|
// StatusCode::CONTINUE,
|
||||||
|
// StatusCode::SWITCHING_PROTOCOLS,
|
||||||
|
// StatusCode::PROCESSING,
|
||||||
|
// StatusCode::OK,
|
||||||
|
// StatusCode::NOT_FOUND,
|
||||||
|
// ];
|
||||||
|
// future::ok::<_, ()>(Response::new(statuses[indx]))
|
||||||
|
// })
|
||||||
|
// .map_err(|_| ()),
|
||||||
|
// )
|
||||||
|
// });
|
||||||
|
|
||||||
|
// let header = HeaderName::from_static("content-length");
|
||||||
|
// let value = HeaderValue::from_static("0");
|
||||||
|
|
||||||
|
// {
|
||||||
|
// for i in 0..4 {
|
||||||
|
// let req = client::ClientRequest::get(srv.surl(&format!("/{}", i)))
|
||||||
|
// .finish()
|
||||||
|
// .unwrap();
|
||||||
|
// let response = srv.send_request(req).unwrap();
|
||||||
|
// assert_eq!(response.headers().get(&header), None);
|
||||||
|
|
||||||
|
// let req = client::ClientRequest::head(srv.surl(&format!("/{}", i)))
|
||||||
|
// .finish()
|
||||||
|
// .unwrap();
|
||||||
|
// let response = srv.send_request(req).unwrap();
|
||||||
|
// assert_eq!(response.headers().get(&header), None);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for i in 4..6 {
|
||||||
|
// let req = client::ClientRequest::get(srv.surl(&format!("/{}", i)))
|
||||||
|
// .finish()
|
||||||
|
// .unwrap();
|
||||||
|
// let response = srv.send_request(req).unwrap();
|
||||||
|
// assert_eq!(response.headers().get(&header), Some(&value));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_headers() {
|
fn test_headers() {
|
||||||
let data = STR.repeat(10);
|
let data = STR.repeat(10);
|
||||||
|
@ -363,7 +407,7 @@ fn test_headers() {
|
||||||
|
|
||||||
let mut srv = TestServer::new(move || {
|
let mut srv = TestServer::new(move || {
|
||||||
let data = data.clone();
|
let data = data.clone();
|
||||||
h1::H1Service::new(move |_| {
|
HttpService::build().h1(move |_| {
|
||||||
let mut builder = Response::Ok();
|
let mut builder = Response::Ok();
|
||||||
for idx in 0..90 {
|
for idx in 0..90 {
|
||||||
builder.header(
|
builder.header(
|
||||||
|
@ -384,9 +428,8 @@ fn test_headers() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
future::ok::<_, ()>(builder.body(data.clone()))
|
future::ok::<_, ()>(builder.body(data.clone()))
|
||||||
}).map(|_| ())
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut connector = srv.new_connector();
|
let mut connector = srv.new_connector();
|
||||||
|
|
||||||
let req = srv.get().finish().unwrap();
|
let req = srv.get().finish().unwrap();
|
||||||
|
@ -399,6 +442,52 @@ fn test_headers() {
|
||||||
assert_eq!(bytes, Bytes::from(data2));
|
assert_eq!(bytes, Bytes::from(data2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_h2_headers() {
|
||||||
|
let data = STR.repeat(10);
|
||||||
|
let data2 = data.clone();
|
||||||
|
let openssl = ssl_acceptor().unwrap();
|
||||||
|
|
||||||
|
let mut srv = TestServer::new(move || {
|
||||||
|
let data = data.clone();
|
||||||
|
openssl
|
||||||
|
.clone()
|
||||||
|
.map_err(|e| println!("Openssl error: {}", e))
|
||||||
|
.and_then(
|
||||||
|
HttpService::build().h2(move |_| {
|
||||||
|
let mut builder = Response::Ok();
|
||||||
|
for idx in 0..90 {
|
||||||
|
builder.header(
|
||||||
|
format!("X-TEST-{}", idx).as_str(),
|
||||||
|
"TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
|
||||||
|
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
|
||||||
|
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
|
||||||
|
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
|
||||||
|
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
|
||||||
|
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
|
||||||
|
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
|
||||||
|
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
|
||||||
|
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
|
||||||
|
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
|
||||||
|
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
|
||||||
|
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST \
|
||||||
|
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST ",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
future::ok::<_, ()>(builder.body(data.clone()))
|
||||||
|
}).map_err(|_| ()))
|
||||||
|
});
|
||||||
|
let mut connector = srv.new_connector();
|
||||||
|
|
||||||
|
let req = client::ClientRequest::get(srv.surl("/")).finish().unwrap();
|
||||||
|
let mut response = srv.block_on(req.send(&mut connector)).unwrap();
|
||||||
|
assert!(response.status().is_success());
|
||||||
|
|
||||||
|
// read response
|
||||||
|
let bytes = srv.block_on(response.body()).unwrap();
|
||||||
|
assert_eq!(bytes, Bytes::from(data2));
|
||||||
|
}
|
||||||
|
|
||||||
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
||||||
Hello World Hello World Hello World Hello World Hello World \
|
Hello World Hello World Hello World Hello World Hello World \
|
||||||
Hello World Hello World Hello World Hello World Hello World \
|
Hello World Hello World Hello World Hello World Hello World \
|
||||||
|
@ -424,7 +513,7 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
||||||
#[test]
|
#[test]
|
||||||
fn test_body() {
|
fn test_body() {
|
||||||
let mut srv = TestServer::new(|| {
|
let mut srv = TestServer::new(|| {
|
||||||
h1::H1Service::new(|_| future::ok::<_, ()>(Response::Ok().body(STR))).map(|_| ())
|
HttpService::build().h1(|_| future::ok::<_, ()>(Response::Ok().body(STR)))
|
||||||
});
|
});
|
||||||
|
|
||||||
let req = srv.get().finish().unwrap();
|
let req = srv.get().finish().unwrap();
|
||||||
|
@ -439,7 +528,7 @@ fn test_body() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_head_empty() {
|
fn test_head_empty() {
|
||||||
let mut srv = TestServer::new(|| {
|
let mut srv = TestServer::new(|| {
|
||||||
h1::H1Service::new(|_| ok::<_, ()>(Response::Ok().body(STR))).map(|_| ())
|
HttpService::build().h1(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
||||||
});
|
});
|
||||||
|
|
||||||
let req = client::ClientRequest::head(srv.url("/")).finish().unwrap();
|
let req = client::ClientRequest::head(srv.url("/")).finish().unwrap();
|
||||||
|
@ -462,10 +551,9 @@ fn test_head_empty() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_head_binary() {
|
fn test_head_binary() {
|
||||||
let mut srv = TestServer::new(|| {
|
let mut srv = TestServer::new(|| {
|
||||||
h1::H1Service::new(|_| {
|
HttpService::build().h1(|_| {
|
||||||
ok::<_, ()>(Response::Ok().content_length(STR.len() as u64).body(STR))
|
ok::<_, ()>(Response::Ok().content_length(STR.len() as u64).body(STR))
|
||||||
})
|
})
|
||||||
.map(|_| ())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let req = client::ClientRequest::head(srv.url("/")).finish().unwrap();
|
let req = client::ClientRequest::head(srv.url("/")).finish().unwrap();
|
||||||
|
@ -488,7 +576,7 @@ fn test_head_binary() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_head_binary2() {
|
fn test_head_binary2() {
|
||||||
let mut srv = TestServer::new(|| {
|
let mut srv = TestServer::new(|| {
|
||||||
h1::H1Service::new(|_| ok::<_, ()>(Response::Ok().body(STR))).map(|_| ())
|
HttpService::build().h1(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
||||||
});
|
});
|
||||||
|
|
||||||
let req = client::ClientRequest::head(srv.url("/")).finish().unwrap();
|
let req = client::ClientRequest::head(srv.url("/")).finish().unwrap();
|
||||||
|
@ -507,14 +595,13 @@ fn test_head_binary2() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_body_length() {
|
fn test_body_length() {
|
||||||
let mut srv = TestServer::new(|| {
|
let mut srv = TestServer::new(|| {
|
||||||
h1::H1Service::new(|_| {
|
HttpService::build().h1(|_| {
|
||||||
let body = once(Ok(Bytes::from_static(STR.as_ref())));
|
let body = once(Ok(Bytes::from_static(STR.as_ref())));
|
||||||
ok::<_, ()>(
|
ok::<_, ()>(
|
||||||
Response::Ok()
|
Response::Ok()
|
||||||
.body(Body::from_message(body::SizedStream::new(STR.len(), body))),
|
.body(Body::from_message(body::SizedStream::new(STR.len(), body))),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(|_| ())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let req = srv.get().finish().unwrap();
|
let req = srv.get().finish().unwrap();
|
||||||
|
@ -529,11 +616,10 @@ fn test_body_length() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_body_chunked_explicit() {
|
fn test_body_chunked_explicit() {
|
||||||
let mut srv = TestServer::new(|| {
|
let mut srv = TestServer::new(|| {
|
||||||
h1::H1Service::new(|_| {
|
HttpService::build().h1(|_| {
|
||||||
let body = once::<_, Error>(Ok(Bytes::from_static(STR.as_ref())));
|
let body = once::<_, Error>(Ok(Bytes::from_static(STR.as_ref())));
|
||||||
ok::<_, ()>(Response::Ok().streaming(body))
|
ok::<_, ()>(Response::Ok().streaming(body))
|
||||||
})
|
})
|
||||||
.map(|_| ())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let req = srv.get().finish().unwrap();
|
let req = srv.get().finish().unwrap();
|
||||||
|
@ -550,7 +636,7 @@ fn test_body_chunked_explicit() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_body_chunked_implicit() {
|
fn test_body_chunked_implicit() {
|
||||||
let mut srv = TestServer::new(|| {
|
let mut srv = TestServer::new(|| {
|
||||||
h1::H1Service::new(|_| {
|
HttpService::build().h1(|_| {
|
||||||
let body = once::<_, Error>(Ok(Bytes::from_static(STR.as_ref())));
|
let body = once::<_, Error>(Ok(Bytes::from_static(STR.as_ref())));
|
||||||
ok::<_, ()>(Response::Ok().streaming(body))
|
ok::<_, ()>(Response::Ok().streaming(body))
|
||||||
})
|
})
|
||||||
|
@ -571,7 +657,7 @@ use actix_service::fn_cfg_factory;
|
||||||
#[test]
|
#[test]
|
||||||
fn test_response_http_error_handling() {
|
fn test_response_http_error_handling() {
|
||||||
let mut srv = TestServer::new(|| {
|
let mut srv = TestServer::new(|| {
|
||||||
h1::H1Service::new(fn_cfg_factory(|_: &ServerConfig| {
|
HttpService::build().h1(fn_cfg_factory(|_: &ServerConfig| {
|
||||||
Ok::<_, ()>(|_| {
|
Ok::<_, ()>(|_| {
|
||||||
let broken_header = Bytes::from_static(b"\0\0\0");
|
let broken_header = Bytes::from_static(b"\0\0\0");
|
||||||
ok::<_, ()>(
|
ok::<_, ()>(
|
||||||
|
|
Loading…
Reference in a new issue