mirror of https://github.com/fafhrd91/actix-web
Merge branch 'master' into feat/tokio-blocking-pool
This commit is contained in:
commit
cc82ceb9c4
|
@ -1,6 +1,9 @@
|
||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2021-xx-xx
|
## Unreleased - 2021-xx-xx
|
||||||
|
|
||||||
|
|
||||||
|
## 4.0.0-beta.1 - 2021-01-07
|
||||||
### Added
|
### Added
|
||||||
* `Compat` middleware enabling generic response body/error type of middlewares like `Logger` and
|
* `Compat` middleware enabling generic response body/error type of middlewares like `Logger` and
|
||||||
`Compress` to be used in `middleware::Condition` and `Resource`, `Scope` services. [#1865]
|
`Compress` to be used in `middleware::Condition` and `Resource`, `Scope` services. [#1865]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "actix-web"
|
name = "actix-web"
|
||||||
version = "3.3.2"
|
version = "4.0.0-beta.1"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust"
|
description = "Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
@ -83,8 +83,8 @@ actix-utils = "3.0.0-beta.1"
|
||||||
actix-tls = { version = "3.0.0-beta.2", default-features = false, optional = true }
|
actix-tls = { version = "3.0.0-beta.2", default-features = false, optional = true }
|
||||||
|
|
||||||
actix-web-codegen = "0.4.0"
|
actix-web-codegen = "0.4.0"
|
||||||
actix-http = "2.2.0"
|
actix-http = "3.0.0-beta.1"
|
||||||
awc = { version = "2.0.3", default-features = false }
|
awc = { version = "3.0.0-beta.1", default-features = false }
|
||||||
|
|
||||||
ahash = "0.6"
|
ahash = "0.6"
|
||||||
bytes = "1"
|
bytes = "1"
|
||||||
|
@ -108,7 +108,7 @@ smallvec = "1.6"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix = "0.11.0-beta.1"
|
actix = "0.11.0-beta.1"
|
||||||
actix-http = { version = "2.2.0", features = ["actors"] }
|
actix-http = { version = "3.0.0-beta.1", features = ["actors"] }
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
env_logger = "0.8"
|
env_logger = "0.8"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
|
@ -125,6 +125,7 @@ codegen-units = 1
|
||||||
actix-web = { path = "." }
|
actix-web = { path = "." }
|
||||||
actix-http = { path = "actix-http" }
|
actix-http = { path = "actix-http" }
|
||||||
actix-http-test = { path = "actix-http-test" }
|
actix-http-test = { path = "actix-http-test" }
|
||||||
|
actix-web-actors = { path = "actix-web-actors" }
|
||||||
actix-web-codegen = { path = "actix-web-codegen" }
|
actix-web-codegen = { path = "actix-web-codegen" }
|
||||||
actix-multipart = { path = "actix-multipart" }
|
actix-multipart = { path = "actix-multipart" }
|
||||||
actix-files = { path = "actix-files" }
|
actix-files = { path = "actix-files" }
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2021-xx-xx
|
## Unreleased - 2021-xx-xx
|
||||||
|
|
||||||
|
|
||||||
|
## 0.6.0-beta.1 - 2021-01-07
|
||||||
* `HttpRange::parse` now has its own error type.
|
* `HttpRange::parse` now has its own error type.
|
||||||
* Update `bytes` to `1.0`. [#1813]
|
* Update `bytes` to `1.0`. [#1813]
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "actix-files"
|
name = "actix-files"
|
||||||
version = "0.5.0"
|
version = "0.6.0-beta.1"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Static file serving for Actix Web"
|
description = "Static file serving for Actix Web"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
@ -17,7 +17,7 @@ name = "actix_files"
|
||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-web = { version = "3.0.0", default-features = false }
|
actix-web = { version = "4.0.0-beta.1", default-features = false }
|
||||||
actix-service = "2.0.0-beta.2"
|
actix-service = "2.0.0-beta.2"
|
||||||
bitflags = "1"
|
bitflags = "1"
|
||||||
bytes = "1"
|
bytes = "1"
|
||||||
|
@ -32,4 +32,4 @@ v_htmlescape = "0.12"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-rt = "2.0.0-beta.1"
|
actix-rt = "2.0.0-beta.1"
|
||||||
actix-web = "3.0.0"
|
actix-web = "4.0.0-beta.1"
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2021-xx-xx
|
## Unreleased - 2021-xx-xx
|
||||||
|
|
||||||
|
|
||||||
|
## 3.0.0-beta.1 - 2021-01-07
|
||||||
* Update `bytes` to `1.0`. [#1813]
|
* Update `bytes` to `1.0`. [#1813]
|
||||||
|
|
||||||
[#1813]: https://github.com/actix/actix-web/pull/1813
|
[#1813]: https://github.com/actix/actix-web/pull/1813
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "actix-http-test"
|
name = "actix-http-test"
|
||||||
version = "2.1.0"
|
version = "3.0.0-beta.1"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Various helpers for Actix applications to use during testing"
|
description = "Various helpers for Actix applications to use during testing"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
@ -35,7 +35,7 @@ actix-tls = "3.0.0-beta.2"
|
||||||
actix-utils = "3.0.0-beta.1"
|
actix-utils = "3.0.0-beta.1"
|
||||||
actix-rt = "2.0.0-beta.1"
|
actix-rt = "2.0.0-beta.1"
|
||||||
actix-server = "2.0.0-beta.2"
|
actix-server = "2.0.0-beta.2"
|
||||||
awc = "2.0.0"
|
awc = "3.0.0-beta.1"
|
||||||
|
|
||||||
base64 = "0.13"
|
base64 = "0.13"
|
||||||
bytes = "1"
|
bytes = "1"
|
||||||
|
@ -51,5 +51,5 @@ time = { version = "0.2.7", default-features = false, features = ["std"] }
|
||||||
open-ssl = { version = "0.10", package = "openssl", optional = true }
|
open-ssl = { version = "0.10", package = "openssl", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-web = "3.0.0"
|
actix-web = "4.0.0-beta.1"
|
||||||
actix-http = "2.0.0"
|
actix-http = "3.0.0-beta.1"
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2021-xx-xx
|
## Unreleased - 2021-xx-xx
|
||||||
|
|
||||||
|
|
||||||
|
## 3.0.0-beta.1 - 2021-01-07
|
||||||
|
### Added
|
||||||
|
* Add `Http3` to `Protocol` enum for future compatibility and also mark `#[non_exhaustive]`.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
* Update `actix-*` dependencies to tokio `1.0` based versions. [#1813]
|
* Update `actix-*` dependencies to tokio `1.0` based versions. [#1813]
|
||||||
* Bumped `rand` to `0.8`.
|
* Bumped `rand` to `0.8`.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "actix-http"
|
name = "actix-http"
|
||||||
version = "2.2.0"
|
version = "3.0.0-beta.1"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "HTTP primitives for the Actix ecosystem"
|
description = "HTTP primitives for the Actix ecosystem"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
@ -52,7 +52,6 @@ bitflags = "1.2"
|
||||||
bytes = "1"
|
bytes = "1"
|
||||||
bytestring = "1"
|
bytestring = "1"
|
||||||
cookie = { version = "0.14.1", features = ["percent-encode"] }
|
cookie = { version = "0.14.1", features = ["percent-encode"] }
|
||||||
copyless = "0.1.4"
|
|
||||||
derive_more = "0.99.5"
|
derive_more = "0.99.5"
|
||||||
either = "1.5.3"
|
either = "1.5.3"
|
||||||
encoding_rs = "0.8"
|
encoding_rs = "0.8"
|
||||||
|
@ -86,7 +85,7 @@ flate2 = { version = "1.0.13", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-server = "2.0.0-beta.2"
|
actix-server = "2.0.0-beta.2"
|
||||||
actix-http-test = { version = "2.0.0", features = ["openssl"] }
|
actix-http-test = { version = "3.0.0-beta.1", features = ["openssl"] }
|
||||||
actix-tls = { version = "3.0.0-beta.2", features = ["openssl"] }
|
actix-tls = { version = "3.0.0-beta.2", features = ["openssl"] }
|
||||||
criterion = "0.3"
|
criterion = "0.3"
|
||||||
env_logger = "0.7"
|
env_logger = "0.7"
|
||||||
|
|
|
@ -3,8 +3,7 @@ use std::task::{Context, Poll};
|
||||||
use std::{fmt, mem};
|
use std::{fmt, mem};
|
||||||
|
|
||||||
use bytes::{Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
use futures_core::Stream;
|
use futures_core::{ready, Stream};
|
||||||
use futures_util::ready;
|
|
||||||
use pin_project::pin_project;
|
use pin_project::pin_project;
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::rc::Rc;
|
|
||||||
use std::task::{Context, Poll};
|
|
||||||
|
|
||||||
use actix_service::Service;
|
|
||||||
|
|
||||||
/// Service that allows to turn non-clone service to a service with `Clone` impl
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
/// CloneableService might panic with some creative use of thread local storage.
|
|
||||||
/// See https://github.com/actix/actix-web/issues/1295 for example
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub(crate) struct CloneableService<T>(Rc<RefCell<T>>);
|
|
||||||
|
|
||||||
impl<T> CloneableService<T> {
|
|
||||||
pub(crate) fn new(service: T) -> Self {
|
|
||||||
Self(Rc::new(RefCell::new(service)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Clone for CloneableService<T> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self(self.0.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Service<Req>, Req> Service<Req> for CloneableService<T> {
|
|
||||||
type Response = T::Response;
|
|
||||||
type Error = T::Error;
|
|
||||||
type Future = T::Future;
|
|
||||||
|
|
||||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
||||||
self.0.borrow_mut().poll_ready(cx)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call(&mut self, req: Req) -> Self::Future {
|
|
||||||
self.0.borrow_mut().call(req)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +1,11 @@
|
||||||
use std::{
|
use std::{
|
||||||
|
cell::RefCell,
|
||||||
collections::VecDeque,
|
collections::VecDeque,
|
||||||
fmt,
|
fmt,
|
||||||
future::Future,
|
future::Future,
|
||||||
io, mem, net,
|
io, mem, net,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
|
rc::Rc,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,17 +17,14 @@ use bytes::{Buf, BytesMut};
|
||||||
use log::{error, trace};
|
use log::{error, trace};
|
||||||
use pin_project::pin_project;
|
use pin_project::pin_project;
|
||||||
|
|
||||||
use crate::cloneable::CloneableService;
|
use crate::body::{Body, BodySize, MessageBody, ResponseBody};
|
||||||
use crate::config::ServiceConfig;
|
use crate::config::ServiceConfig;
|
||||||
use crate::error::{DispatchError, Error};
|
use crate::error::{DispatchError, Error};
|
||||||
use crate::error::{ParseError, PayloadError};
|
use crate::error::{ParseError, PayloadError};
|
||||||
use crate::httpmessage::HttpMessage;
|
|
||||||
use crate::request::Request;
|
use crate::request::Request;
|
||||||
use crate::response::Response;
|
use crate::response::Response;
|
||||||
use crate::{
|
use crate::service::HttpFlow;
|
||||||
body::{Body, BodySize, MessageBody, ResponseBody},
|
use crate::OnConnectData;
|
||||||
Extensions,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::codec::Codec;
|
use super::codec::Codec;
|
||||||
use super::payload::{Payload, PayloadSender, PayloadStatus};
|
use super::payload::{Payload, PayloadSender, PayloadStatus};
|
||||||
|
@ -78,7 +77,7 @@ where
|
||||||
U::Error: fmt::Display,
|
U::Error: fmt::Display,
|
||||||
{
|
{
|
||||||
Normal(#[pin] InnerDispatcher<T, S, B, X, U>),
|
Normal(#[pin] InnerDispatcher<T, S, B, X, U>),
|
||||||
Upgrade(Pin<Box<U::Future>>),
|
Upgrade(#[pin] U::Future),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project(project = InnerDispatcherProj)]
|
#[pin_project(project = InnerDispatcherProj)]
|
||||||
|
@ -92,10 +91,8 @@ where
|
||||||
U: Service<(Request, Framed<T, Codec>), Response = ()>,
|
U: Service<(Request, Framed<T, Codec>), Response = ()>,
|
||||||
U::Error: fmt::Display,
|
U::Error: fmt::Display,
|
||||||
{
|
{
|
||||||
service: CloneableService<S>,
|
flow: Rc<RefCell<HttpFlow<S, X, U>>>,
|
||||||
expect: CloneableService<X>,
|
on_connect_data: OnConnectData,
|
||||||
upgrade: Option<CloneableService<U>>,
|
|
||||||
on_connect_data: Extensions,
|
|
||||||
flags: Flags,
|
flags: Flags,
|
||||||
peer_addr: Option<net::SocketAddr>,
|
peer_addr: Option<net::SocketAddr>,
|
||||||
error: Option<DispatchError>,
|
error: Option<DispatchError>,
|
||||||
|
@ -180,10 +177,8 @@ where
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
stream: T,
|
stream: T,
|
||||||
config: ServiceConfig,
|
config: ServiceConfig,
|
||||||
service: CloneableService<S>,
|
services: Rc<RefCell<HttpFlow<S, X, U>>>,
|
||||||
expect: CloneableService<X>,
|
on_connect_data: OnConnectData,
|
||||||
upgrade: Option<CloneableService<U>>,
|
|
||||||
on_connect_data: Extensions,
|
|
||||||
peer_addr: Option<net::SocketAddr>,
|
peer_addr: Option<net::SocketAddr>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Dispatcher::with_timeout(
|
Dispatcher::with_timeout(
|
||||||
|
@ -192,9 +187,7 @@ where
|
||||||
config,
|
config,
|
||||||
BytesMut::with_capacity(HW_BUFFER_SIZE),
|
BytesMut::with_capacity(HW_BUFFER_SIZE),
|
||||||
None,
|
None,
|
||||||
service,
|
services,
|
||||||
expect,
|
|
||||||
upgrade,
|
|
||||||
on_connect_data,
|
on_connect_data,
|
||||||
peer_addr,
|
peer_addr,
|
||||||
)
|
)
|
||||||
|
@ -207,10 +200,8 @@ where
|
||||||
config: ServiceConfig,
|
config: ServiceConfig,
|
||||||
read_buf: BytesMut,
|
read_buf: BytesMut,
|
||||||
timeout: Option<Sleep>,
|
timeout: Option<Sleep>,
|
||||||
service: CloneableService<S>,
|
services: Rc<RefCell<HttpFlow<S, X, U>>>,
|
||||||
expect: CloneableService<X>,
|
on_connect_data: OnConnectData,
|
||||||
upgrade: Option<CloneableService<U>>,
|
|
||||||
on_connect_data: Extensions,
|
|
||||||
peer_addr: Option<net::SocketAddr>,
|
peer_addr: Option<net::SocketAddr>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let keepalive = config.keep_alive_enabled();
|
let keepalive = config.keep_alive_enabled();
|
||||||
|
@ -239,9 +230,7 @@ where
|
||||||
io: Some(io),
|
io: Some(io),
|
||||||
codec,
|
codec,
|
||||||
read_buf,
|
read_buf,
|
||||||
service,
|
flow: services,
|
||||||
expect,
|
|
||||||
upgrade,
|
|
||||||
on_connect_data,
|
on_connect_data,
|
||||||
flags,
|
flags,
|
||||||
peer_addr,
|
peer_addr,
|
||||||
|
@ -395,7 +384,8 @@ where
|
||||||
Poll::Ready(Ok(req)) => {
|
Poll::Ready(Ok(req)) => {
|
||||||
self.as_mut().send_continue();
|
self.as_mut().send_continue();
|
||||||
this = self.as_mut().project();
|
this = self.as_mut().project();
|
||||||
this.state.set(State::ServiceCall(this.service.call(req)));
|
let fut = this.flow.borrow_mut().service.call(req);
|
||||||
|
this.state.set(State::ServiceCall(fut));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Poll::Ready(Err(e)) => {
|
Poll::Ready(Err(e)) => {
|
||||||
|
@ -483,12 +473,14 @@ where
|
||||||
// Handle `EXPECT: 100-Continue` header
|
// Handle `EXPECT: 100-Continue` header
|
||||||
if req.head().expect() {
|
if req.head().expect() {
|
||||||
// set dispatcher state so the future is pinned.
|
// set dispatcher state so the future is pinned.
|
||||||
let task = self.as_mut().project().expect.call(req);
|
let mut this = self.as_mut().project();
|
||||||
self.as_mut().project().state.set(State::ExpectCall(task));
|
let task = this.flow.borrow_mut().expect.call(req);
|
||||||
|
this.state.set(State::ExpectCall(task));
|
||||||
} else {
|
} else {
|
||||||
// the same as above.
|
// the same as above.
|
||||||
let task = self.as_mut().project().service.call(req);
|
let mut this = self.as_mut().project();
|
||||||
self.as_mut().project().state.set(State::ServiceCall(task));
|
let task = this.flow.borrow_mut().service.call(req);
|
||||||
|
this.state.set(State::ServiceCall(task));
|
||||||
};
|
};
|
||||||
|
|
||||||
// eagerly poll the future for once(or twice if expect is resolved immediately).
|
// eagerly poll the future for once(or twice if expect is resolved immediately).
|
||||||
|
@ -499,8 +491,9 @@ where
|
||||||
// expect is resolved. continue loop and poll the service call branch.
|
// expect is resolved. continue loop and poll the service call branch.
|
||||||
Poll::Ready(Ok(req)) => {
|
Poll::Ready(Ok(req)) => {
|
||||||
self.as_mut().send_continue();
|
self.as_mut().send_continue();
|
||||||
let task = self.as_mut().project().service.call(req);
|
let mut this = self.as_mut().project();
|
||||||
self.as_mut().project().state.set(State::ServiceCall(task));
|
let task = this.flow.borrow_mut().service.call(req);
|
||||||
|
this.state.set(State::ServiceCall(task));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// future is pending. return Ok(()) to notify that a new state is
|
// future is pending. return Ok(()) to notify that a new state is
|
||||||
|
@ -568,9 +561,11 @@ where
|
||||||
req.head_mut().peer_addr = *this.peer_addr;
|
req.head_mut().peer_addr = *this.peer_addr;
|
||||||
|
|
||||||
// merge on_connect_ext data into request extensions
|
// merge on_connect_ext data into request extensions
|
||||||
req.extensions_mut().drain_from(this.on_connect_data);
|
this.on_connect_data.merge_into(&mut req);
|
||||||
|
|
||||||
if pl == MessageType::Stream && this.upgrade.is_some() {
|
if pl == MessageType::Stream
|
||||||
|
&& this.flow.borrow().upgrade.is_some()
|
||||||
|
{
|
||||||
this.messages.push_back(DispatcherMessage::Upgrade(req));
|
this.messages.push_back(DispatcherMessage::Upgrade(req));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -692,15 +687,11 @@ where
|
||||||
if let Some(deadline) =
|
if let Some(deadline) =
|
||||||
this.codec.config().client_disconnect_timer()
|
this.codec.config().client_disconnect_timer()
|
||||||
{
|
{
|
||||||
if let Some(timer) = this.ka_timer.as_mut().as_pin_mut()
|
if let Some(mut timer) =
|
||||||
|
this.ka_timer.as_mut().as_pin_mut()
|
||||||
{
|
{
|
||||||
timer.reset(deadline);
|
timer.as_mut().reset(deadline);
|
||||||
let _ = this
|
let _ = timer.poll(cx);
|
||||||
.ka_timer
|
|
||||||
.as_mut()
|
|
||||||
.as_pin_mut()
|
|
||||||
.unwrap()
|
|
||||||
.poll(cx);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// no shutdown timeout, drop socket
|
// no shutdown timeout, drop socket
|
||||||
|
@ -725,15 +716,14 @@ where
|
||||||
} else if let Some(deadline) =
|
} else if let Some(deadline) =
|
||||||
this.codec.config().keep_alive_expire()
|
this.codec.config().keep_alive_expire()
|
||||||
{
|
{
|
||||||
if let Some(timer) = this.ka_timer.as_mut().as_pin_mut() {
|
if let Some(mut timer) = this.ka_timer.as_mut().as_pin_mut() {
|
||||||
timer.reset(deadline);
|
timer.as_mut().reset(deadline);
|
||||||
let _ =
|
let _ = timer.poll(cx);
|
||||||
this.ka_timer.as_mut().as_pin_mut().unwrap().poll(cx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let Some(timer) = this.ka_timer.as_mut().as_pin_mut() {
|
} else if let Some(mut timer) = this.ka_timer.as_mut().as_pin_mut() {
|
||||||
timer.reset(*this.ka_expire);
|
timer.as_mut().reset(*this.ka_expire);
|
||||||
let _ = this.ka_timer.as_mut().as_pin_mut().unwrap().poll(cx);
|
let _ = timer.poll(cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Poll::Pending => {}
|
Poll::Pending => {}
|
||||||
|
@ -834,12 +824,17 @@ where
|
||||||
);
|
);
|
||||||
parts.write_buf = mem::take(inner_p.write_buf);
|
parts.write_buf = mem::take(inner_p.write_buf);
|
||||||
let framed = Framed::from_parts(parts);
|
let framed = Framed::from_parts(parts);
|
||||||
let upgrade =
|
let upgrade = inner_p
|
||||||
inner_p.upgrade.take().unwrap().call((req, framed));
|
.flow
|
||||||
|
.borrow_mut()
|
||||||
|
.upgrade
|
||||||
|
.take()
|
||||||
|
.unwrap()
|
||||||
|
.call((req, framed));
|
||||||
self.as_mut()
|
self.as_mut()
|
||||||
.project()
|
.project()
|
||||||
.inner
|
.inner
|
||||||
.set(DispatcherState::Upgrade(Box::pin(upgrade)));
|
.set(DispatcherState::Upgrade(upgrade));
|
||||||
return self.poll(cx);
|
return self.poll(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -890,7 +885,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DispatcherStateProj::Upgrade(fut) => fut.as_mut().poll(cx).map_err(|e| {
|
DispatcherStateProj::Upgrade(fut) => fut.poll(cx).map_err(|e| {
|
||||||
error!("Upgrade handler error: {}", e);
|
error!("Upgrade handler error: {}", e);
|
||||||
DispatchError::Upgrade
|
DispatchError::Upgrade
|
||||||
}),
|
}),
|
||||||
|
@ -1028,13 +1023,13 @@ mod tests {
|
||||||
lazy(|cx| {
|
lazy(|cx| {
|
||||||
let buf = TestBuffer::new("GET /test HTTP/1\r\n\r\n");
|
let buf = TestBuffer::new("GET /test HTTP/1\r\n\r\n");
|
||||||
|
|
||||||
|
let services = HttpFlow::new(ok_service(), ExpectHandler, None);
|
||||||
|
|
||||||
let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new(
|
let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new(
|
||||||
buf,
|
buf,
|
||||||
ServiceConfig::default(),
|
ServiceConfig::default(),
|
||||||
CloneableService::new(ok_service()),
|
services,
|
||||||
CloneableService::new(ExpectHandler),
|
OnConnectData::default(),
|
||||||
None,
|
|
||||||
Extensions::new(),
|
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1068,13 +1063,13 @@ mod tests {
|
||||||
|
|
||||||
let cfg = ServiceConfig::new(KeepAlive::Disabled, 1, 1, false, None);
|
let cfg = ServiceConfig::new(KeepAlive::Disabled, 1, 1, false, None);
|
||||||
|
|
||||||
|
let services = HttpFlow::new(echo_path_service(), ExpectHandler, None);
|
||||||
|
|
||||||
let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new(
|
let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new(
|
||||||
buf,
|
buf,
|
||||||
cfg,
|
cfg,
|
||||||
CloneableService::new(echo_path_service()),
|
services,
|
||||||
CloneableService::new(ExpectHandler),
|
OnConnectData::default(),
|
||||||
None,
|
|
||||||
Extensions::new(),
|
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1122,13 +1117,13 @@ mod tests {
|
||||||
|
|
||||||
let cfg = ServiceConfig::new(KeepAlive::Disabled, 1, 1, false, None);
|
let cfg = ServiceConfig::new(KeepAlive::Disabled, 1, 1, false, None);
|
||||||
|
|
||||||
|
let services = HttpFlow::new(echo_path_service(), ExpectHandler, None);
|
||||||
|
|
||||||
let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new(
|
let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new(
|
||||||
buf,
|
buf,
|
||||||
cfg,
|
cfg,
|
||||||
CloneableService::new(echo_path_service()),
|
services,
|
||||||
CloneableService::new(ExpectHandler),
|
OnConnectData::default(),
|
||||||
None,
|
|
||||||
Extensions::new(),
|
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1171,13 +1166,14 @@ mod tests {
|
||||||
lazy(|cx| {
|
lazy(|cx| {
|
||||||
let mut buf = TestSeqBuffer::empty();
|
let mut buf = TestSeqBuffer::empty();
|
||||||
let cfg = ServiceConfig::new(KeepAlive::Disabled, 0, 0, false, None);
|
let cfg = ServiceConfig::new(KeepAlive::Disabled, 0, 0, false, None);
|
||||||
|
|
||||||
|
let services = HttpFlow::new(echo_payload_service(), ExpectHandler, None);
|
||||||
|
|
||||||
let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new(
|
let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new(
|
||||||
buf.clone(),
|
buf.clone(),
|
||||||
cfg,
|
cfg,
|
||||||
CloneableService::new(echo_payload_service()),
|
services,
|
||||||
CloneableService::new(ExpectHandler),
|
OnConnectData::default(),
|
||||||
None,
|
|
||||||
Extensions::new(),
|
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1242,13 +1238,14 @@ mod tests {
|
||||||
lazy(|cx| {
|
lazy(|cx| {
|
||||||
let mut buf = TestSeqBuffer::empty();
|
let mut buf = TestSeqBuffer::empty();
|
||||||
let cfg = ServiceConfig::new(KeepAlive::Disabled, 0, 0, false, None);
|
let cfg = ServiceConfig::new(KeepAlive::Disabled, 0, 0, false, None);
|
||||||
|
|
||||||
|
let services = HttpFlow::new(echo_path_service(), ExpectHandler, None);
|
||||||
|
|
||||||
let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new(
|
let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new(
|
||||||
buf.clone(),
|
buf.clone(),
|
||||||
cfg,
|
cfg,
|
||||||
CloneableService::new(echo_path_service()),
|
services,
|
||||||
CloneableService::new(ExpectHandler),
|
OnConnectData::default(),
|
||||||
None,
|
|
||||||
Extensions::new(),
|
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1301,13 +1298,15 @@ mod tests {
|
||||||
lazy(|cx| {
|
lazy(|cx| {
|
||||||
let mut buf = TestSeqBuffer::empty();
|
let mut buf = TestSeqBuffer::empty();
|
||||||
let cfg = ServiceConfig::new(KeepAlive::Disabled, 0, 0, false, None);
|
let cfg = ServiceConfig::new(KeepAlive::Disabled, 0, 0, false, None);
|
||||||
|
|
||||||
|
let services =
|
||||||
|
HttpFlow::new(ok_service(), ExpectHandler, Some(UpgradeHandler));
|
||||||
|
|
||||||
let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new(
|
let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new(
|
||||||
buf.clone(),
|
buf.clone(),
|
||||||
cfg,
|
cfg,
|
||||||
CloneableService::new(ok_service()),
|
services,
|
||||||
CloneableService::new(ExpectHandler),
|
OnConnectData::default(),
|
||||||
Some(CloneableService::new(UpgradeHandler)),
|
|
||||||
Extensions::new(),
|
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
@ -12,12 +13,12 @@ use futures_core::ready;
|
||||||
use futures_util::future::ready;
|
use futures_util::future::ready;
|
||||||
|
|
||||||
use crate::body::MessageBody;
|
use crate::body::MessageBody;
|
||||||
use crate::cloneable::CloneableService;
|
|
||||||
use crate::config::ServiceConfig;
|
use crate::config::ServiceConfig;
|
||||||
use crate::error::{DispatchError, Error};
|
use crate::error::{DispatchError, Error};
|
||||||
use crate::request::Request;
|
use crate::request::Request;
|
||||||
use crate::response::Response;
|
use crate::response::Response;
|
||||||
use crate::{ConnectCallback, Extensions};
|
use crate::service::HttpFlow;
|
||||||
|
use crate::{ConnectCallback, OnConnectData};
|
||||||
|
|
||||||
use super::codec::Codec;
|
use super::codec::Codec;
|
||||||
use super::dispatcher::Dispatcher;
|
use super::dispatcher::Dispatcher;
|
||||||
|
@ -299,7 +300,7 @@ where
|
||||||
upgrade: Option<U::Service>,
|
upgrade: Option<U::Service>,
|
||||||
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
|
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
|
||||||
cfg: Option<ServiceConfig>,
|
cfg: Option<ServiceConfig>,
|
||||||
_phantom: PhantomData<(T, B)>,
|
_phantom: PhantomData<B>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S, B, X, U> Future for H1ServiceResponse<T, S, B, X, U>
|
impl<T, S, B, X, U> Future for H1ServiceResponse<T, S, B, X, U>
|
||||||
|
@ -337,7 +338,7 @@ where
|
||||||
.map_err(|e| log::error!("Init http service error: {:?}", e)))?;
|
.map_err(|e| log::error!("Init http service error: {:?}", e)))?;
|
||||||
this = self.as_mut().project();
|
this = self.as_mut().project();
|
||||||
*this.upgrade = Some(upgrade);
|
*this.upgrade = Some(upgrade);
|
||||||
this.fut_ex.set(None);
|
this.fut_upg.set(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = ready!(this
|
let result = ready!(this
|
||||||
|
@ -366,9 +367,7 @@ where
|
||||||
X: Service<Request>,
|
X: Service<Request>,
|
||||||
U: Service<(Request, Framed<T, Codec>)>,
|
U: Service<(Request, Framed<T, Codec>)>,
|
||||||
{
|
{
|
||||||
srv: CloneableService<S>,
|
flow: Rc<RefCell<HttpFlow<S, X, U>>>,
|
||||||
expect: CloneableService<X>,
|
|
||||||
upgrade: Option<CloneableService<U>>,
|
|
||||||
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
|
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
|
||||||
cfg: ServiceConfig,
|
cfg: ServiceConfig,
|
||||||
_phantom: PhantomData<B>,
|
_phantom: PhantomData<B>,
|
||||||
|
@ -387,15 +386,13 @@ where
|
||||||
{
|
{
|
||||||
fn new(
|
fn new(
|
||||||
cfg: ServiceConfig,
|
cfg: ServiceConfig,
|
||||||
srv: S,
|
service: S,
|
||||||
expect: X,
|
expect: X,
|
||||||
upgrade: Option<U>,
|
upgrade: Option<U>,
|
||||||
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
|
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
|
||||||
) -> H1ServiceHandler<T, S, B, X, U> {
|
) -> H1ServiceHandler<T, S, B, X, U> {
|
||||||
H1ServiceHandler {
|
H1ServiceHandler {
|
||||||
srv: CloneableService::new(srv),
|
flow: HttpFlow::new(service, expect, upgrade),
|
||||||
expect: CloneableService::new(expect),
|
|
||||||
upgrade: upgrade.map(CloneableService::new),
|
|
||||||
cfg,
|
cfg,
|
||||||
on_connect_ext,
|
on_connect_ext,
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
|
@ -421,7 +418,8 @@ where
|
||||||
type Future = Dispatcher<T, S, B, X, U>;
|
type Future = Dispatcher<T, S, B, X, U>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
let ready = self
|
let mut flow = self.flow.borrow_mut();
|
||||||
|
let ready = flow
|
||||||
.expect
|
.expect
|
||||||
.poll_ready(cx)
|
.poll_ready(cx)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
|
@ -431,8 +429,8 @@ where
|
||||||
})?
|
})?
|
||||||
.is_ready();
|
.is_ready();
|
||||||
|
|
||||||
let ready = self
|
let ready = flow
|
||||||
.srv
|
.service
|
||||||
.poll_ready(cx)
|
.poll_ready(cx)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
let e = e.into();
|
let e = e.into();
|
||||||
|
@ -442,7 +440,7 @@ where
|
||||||
.is_ready()
|
.is_ready()
|
||||||
&& ready;
|
&& ready;
|
||||||
|
|
||||||
let ready = if let Some(ref mut upg) = self.upgrade {
|
let ready = if let Some(ref mut upg) = flow.upgrade {
|
||||||
upg.poll_ready(cx)
|
upg.poll_ready(cx)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
let e = e.into();
|
let e = e.into();
|
||||||
|
@ -463,19 +461,14 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, (io, addr): (T, Option<net::SocketAddr>)) -> Self::Future {
|
fn call(&mut self, (io, addr): (T, Option<net::SocketAddr>)) -> Self::Future {
|
||||||
let mut connect_extensions = Extensions::new();
|
let on_connect_data =
|
||||||
if let Some(ref handler) = self.on_connect_ext {
|
OnConnectData::from_io(&io, self.on_connect_ext.as_deref());
|
||||||
// run on_connect_ext callback, populating connect extensions
|
|
||||||
handler(&io, &mut connect_extensions);
|
|
||||||
}
|
|
||||||
|
|
||||||
Dispatcher::new(
|
Dispatcher::new(
|
||||||
io,
|
io,
|
||||||
self.cfg.clone(),
|
self.cfg.clone(),
|
||||||
self.srv.clone(),
|
self.flow.clone(),
|
||||||
self.expect.clone(),
|
on_connect_data,
|
||||||
self.upgrade.clone(),
|
|
||||||
connect_extensions,
|
|
||||||
addr,
|
addr,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::net;
|
use std::net;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
use std::rc::Rc;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
use std::{cmp, convert::TryFrom};
|
use std::{cmp, convert::TryFrom};
|
||||||
|
|
||||||
|
@ -16,29 +18,28 @@ use http::header::{HeaderValue, CONNECTION, CONTENT_LENGTH, DATE, TRANSFER_ENCOD
|
||||||
use log::{error, trace};
|
use log::{error, trace};
|
||||||
|
|
||||||
use crate::body::{BodySize, MessageBody, ResponseBody};
|
use crate::body::{BodySize, MessageBody, ResponseBody};
|
||||||
use crate::cloneable::CloneableService;
|
|
||||||
use crate::config::ServiceConfig;
|
use crate::config::ServiceConfig;
|
||||||
use crate::error::{DispatchError, Error};
|
use crate::error::{DispatchError, Error};
|
||||||
use crate::httpmessage::HttpMessage;
|
|
||||||
use crate::message::ResponseHead;
|
use crate::message::ResponseHead;
|
||||||
use crate::payload::Payload;
|
use crate::payload::Payload;
|
||||||
use crate::request::Request;
|
use crate::request::Request;
|
||||||
use crate::response::Response;
|
use crate::response::Response;
|
||||||
use crate::Extensions;
|
use crate::service::HttpFlow;
|
||||||
|
use crate::OnConnectData;
|
||||||
|
|
||||||
const CHUNK_SIZE: usize = 16_384;
|
const CHUNK_SIZE: usize = 16_384;
|
||||||
|
|
||||||
/// Dispatcher for HTTP/2 protocol.
|
/// Dispatcher for HTTP/2 protocol.
|
||||||
#[pin_project::pin_project]
|
#[pin_project::pin_project]
|
||||||
pub struct Dispatcher<T, S, B>
|
pub struct Dispatcher<T, S, B, X, U>
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite + Unpin,
|
T: AsyncRead + AsyncWrite + Unpin,
|
||||||
S: Service<Request>,
|
S: Service<Request>,
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
{
|
{
|
||||||
service: CloneableService<S>,
|
flow: Rc<RefCell<HttpFlow<S, X, U>>>,
|
||||||
connection: Connection<T, Bytes>,
|
connection: Connection<T, Bytes>,
|
||||||
on_connect_data: Extensions,
|
on_connect_data: OnConnectData,
|
||||||
config: ServiceConfig,
|
config: ServiceConfig,
|
||||||
peer_addr: Option<net::SocketAddr>,
|
peer_addr: Option<net::SocketAddr>,
|
||||||
ka_expire: Instant,
|
ka_expire: Instant,
|
||||||
|
@ -46,7 +47,7 @@ where
|
||||||
_phantom: PhantomData<B>,
|
_phantom: PhantomData<B>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S, B> Dispatcher<T, S, B>
|
impl<T, S, B, X, U> Dispatcher<T, S, B, X, U>
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite + Unpin,
|
T: AsyncRead + AsyncWrite + Unpin,
|
||||||
S: Service<Request>,
|
S: Service<Request>,
|
||||||
|
@ -55,9 +56,9 @@ where
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
{
|
{
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
service: CloneableService<S>,
|
services: Rc<RefCell<HttpFlow<S, X, U>>>,
|
||||||
connection: Connection<T, Bytes>,
|
connection: Connection<T, Bytes>,
|
||||||
on_connect_data: Extensions,
|
on_connect_data: OnConnectData,
|
||||||
config: ServiceConfig,
|
config: ServiceConfig,
|
||||||
timeout: Option<Sleep>,
|
timeout: Option<Sleep>,
|
||||||
peer_addr: Option<net::SocketAddr>,
|
peer_addr: Option<net::SocketAddr>,
|
||||||
|
@ -79,7 +80,7 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
Dispatcher {
|
Dispatcher {
|
||||||
service,
|
flow: services,
|
||||||
config,
|
config,
|
||||||
peer_addr,
|
peer_addr,
|
||||||
connection,
|
connection,
|
||||||
|
@ -91,7 +92,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S, B> Future for Dispatcher<T, S, B>
|
impl<T, S, B, X, U> Future for Dispatcher<T, S, B, X, U>
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite + Unpin,
|
T: AsyncRead + AsyncWrite + Unpin,
|
||||||
S: Service<Request>,
|
S: Service<Request>,
|
||||||
|
@ -133,11 +134,11 @@ where
|
||||||
head.peer_addr = this.peer_addr;
|
head.peer_addr = this.peer_addr;
|
||||||
|
|
||||||
// merge on_connect_ext data into request extensions
|
// merge on_connect_ext data into request extensions
|
||||||
req.extensions_mut().drain_from(&mut this.on_connect_data);
|
this.on_connect_data.merge_into(&mut req);
|
||||||
|
|
||||||
let svc = ServiceResponse::<S::Future, S::Response, S::Error, B> {
|
let svc = ServiceResponse::<S::Future, S::Response, S::Error, B> {
|
||||||
state: ServiceResponseState::ServiceCall(
|
state: ServiceResponseState::ServiceCall(
|
||||||
this.service.call(req),
|
this.flow.borrow_mut().service.call(req),
|
||||||
Some(res),
|
Some(res),
|
||||||
),
|
),
|
||||||
config: this.config.clone(),
|
config: this.config.clone(),
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
@ -17,12 +18,12 @@ use h2::server::{self, Handshake};
|
||||||
use log::error;
|
use log::error;
|
||||||
|
|
||||||
use crate::body::MessageBody;
|
use crate::body::MessageBody;
|
||||||
use crate::cloneable::CloneableService;
|
|
||||||
use crate::config::ServiceConfig;
|
use crate::config::ServiceConfig;
|
||||||
use crate::error::{DispatchError, Error};
|
use crate::error::{DispatchError, Error};
|
||||||
use crate::request::Request;
|
use crate::request::Request;
|
||||||
use crate::response::Response;
|
use crate::response::Response;
|
||||||
use crate::{ConnectCallback, Extensions};
|
use crate::service::HttpFlow;
|
||||||
|
use crate::{ConnectCallback, OnConnectData};
|
||||||
|
|
||||||
use super::dispatcher::Dispatcher;
|
use super::dispatcher::Dispatcher;
|
||||||
|
|
||||||
|
@ -248,7 +249,7 @@ pub struct H2ServiceHandler<T, S, B>
|
||||||
where
|
where
|
||||||
S: Service<Request>,
|
S: Service<Request>,
|
||||||
{
|
{
|
||||||
srv: CloneableService<S>,
|
flow: Rc<RefCell<HttpFlow<S, (), ()>>>,
|
||||||
cfg: ServiceConfig,
|
cfg: ServiceConfig,
|
||||||
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
|
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
|
||||||
_phantom: PhantomData<B>,
|
_phantom: PhantomData<B>,
|
||||||
|
@ -265,12 +266,12 @@ where
|
||||||
fn new(
|
fn new(
|
||||||
cfg: ServiceConfig,
|
cfg: ServiceConfig,
|
||||||
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
|
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
|
||||||
srv: S,
|
service: S,
|
||||||
) -> H2ServiceHandler<T, S, B> {
|
) -> H2ServiceHandler<T, S, B> {
|
||||||
H2ServiceHandler {
|
H2ServiceHandler {
|
||||||
|
flow: HttpFlow::new(service, (), None),
|
||||||
cfg,
|
cfg,
|
||||||
on_connect_ext,
|
on_connect_ext,
|
||||||
srv: CloneableService::new(srv),
|
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,7 +291,7 @@ where
|
||||||
type Future = H2ServiceHandlerResponse<T, S, B>;
|
type Future = H2ServiceHandlerResponse<T, S, B>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
self.srv.poll_ready(cx).map_err(|e| {
|
self.flow.borrow_mut().service.poll_ready(cx).map_err(|e| {
|
||||||
let e = e.into();
|
let e = e.into();
|
||||||
error!("Service readiness error: {:?}", e);
|
error!("Service readiness error: {:?}", e);
|
||||||
DispatchError::Service(e)
|
DispatchError::Service(e)
|
||||||
|
@ -298,18 +299,15 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, (io, addr): (T, Option<net::SocketAddr>)) -> Self::Future {
|
fn call(&mut self, (io, addr): (T, Option<net::SocketAddr>)) -> Self::Future {
|
||||||
let mut connect_extensions = Extensions::new();
|
let on_connect_data =
|
||||||
if let Some(ref handler) = self.on_connect_ext {
|
OnConnectData::from_io(&io, self.on_connect_ext.as_deref());
|
||||||
// run on_connect_ext callback, populating connect extensions
|
|
||||||
handler(&io, &mut connect_extensions);
|
|
||||||
}
|
|
||||||
|
|
||||||
H2ServiceHandlerResponse {
|
H2ServiceHandlerResponse {
|
||||||
state: State::Handshake(
|
state: State::Handshake(
|
||||||
Some(self.srv.clone()),
|
Some(self.flow.clone()),
|
||||||
Some(self.cfg.clone()),
|
Some(self.cfg.clone()),
|
||||||
addr,
|
addr,
|
||||||
Some(connect_extensions),
|
on_connect_data,
|
||||||
server::handshake(io),
|
server::handshake(io),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -321,12 +319,12 @@ where
|
||||||
T: AsyncRead + AsyncWrite + Unpin,
|
T: AsyncRead + AsyncWrite + Unpin,
|
||||||
S::Future: 'static,
|
S::Future: 'static,
|
||||||
{
|
{
|
||||||
Incoming(Dispatcher<T, S, B>),
|
Incoming(Dispatcher<T, S, B, (), ()>),
|
||||||
Handshake(
|
Handshake(
|
||||||
Option<CloneableService<S>>,
|
Option<Rc<RefCell<HttpFlow<S, (), ()>>>>,
|
||||||
Option<ServiceConfig>,
|
Option<ServiceConfig>,
|
||||||
Option<net::SocketAddr>,
|
Option<net::SocketAddr>,
|
||||||
Option<Extensions>,
|
OnConnectData,
|
||||||
Handshake<T, Bytes>,
|
Handshake<T, Bytes>,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -365,10 +363,11 @@ where
|
||||||
ref mut handshake,
|
ref mut handshake,
|
||||||
) => match ready!(Pin::new(handshake).poll(cx)) {
|
) => match ready!(Pin::new(handshake).poll(cx)) {
|
||||||
Ok(conn) => {
|
Ok(conn) => {
|
||||||
|
let on_connect_data = std::mem::take(on_connect_data);
|
||||||
self.state = State::Incoming(Dispatcher::new(
|
self.state = State::Incoming(Dispatcher::new(
|
||||||
srv.take().unwrap(),
|
srv.take().unwrap(),
|
||||||
conn,
|
conn,
|
||||||
on_connect_data.take().unwrap(),
|
on_connect_data,
|
||||||
config.take().unwrap(),
|
config.take().unwrap(),
|
||||||
None,
|
None,
|
||||||
*peer_addr,
|
*peer_addr,
|
||||||
|
|
|
@ -19,7 +19,6 @@ mod macros;
|
||||||
pub mod body;
|
pub mod body;
|
||||||
mod builder;
|
mod builder;
|
||||||
pub mod client;
|
pub mod client;
|
||||||
mod cloneable;
|
|
||||||
mod config;
|
mod config;
|
||||||
#[cfg(feature = "compress")]
|
#[cfg(feature = "compress")]
|
||||||
pub mod encoding;
|
pub mod encoding;
|
||||||
|
@ -73,11 +72,49 @@ pub mod http {
|
||||||
pub use crate::message::ConnectionType;
|
pub use crate::message::ConnectionType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Http protocol
|
/// A major HTTP protocol version.
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
|
#[non_exhaustive]
|
||||||
pub enum Protocol {
|
pub enum Protocol {
|
||||||
Http1,
|
Http1,
|
||||||
Http2,
|
Http2,
|
||||||
|
Http3,
|
||||||
}
|
}
|
||||||
|
|
||||||
type ConnectCallback<IO> = dyn Fn(&IO, &mut Extensions);
|
type ConnectCallback<IO> = dyn Fn(&IO, &mut Extensions);
|
||||||
|
|
||||||
|
/// Container for data that extract with ConnectCallback.
|
||||||
|
///
|
||||||
|
/// # Implementation Details
|
||||||
|
/// Uses Option to reduce necessary allocations when merging with request extensions.
|
||||||
|
pub(crate) struct OnConnectData(Option<Extensions>);
|
||||||
|
|
||||||
|
impl Default for OnConnectData {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OnConnectData {
|
||||||
|
/// Construct by calling the on-connect callback with the underlying transport I/O.
|
||||||
|
pub(crate) fn from_io<T>(
|
||||||
|
io: &T,
|
||||||
|
on_connect_ext: Option<&ConnectCallback<T>>,
|
||||||
|
) -> Self {
|
||||||
|
let ext = on_connect_ext.map(|handler| {
|
||||||
|
let mut extensions = Extensions::new();
|
||||||
|
handler(io, &mut extensions);
|
||||||
|
extensions
|
||||||
|
});
|
||||||
|
|
||||||
|
Self(ext)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Merge self into given request's extensions.
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn merge_into(&mut self, req: &mut Request) {
|
||||||
|
if let Some(ref mut ext) = self.0 {
|
||||||
|
req.head.extensions.get_mut().drain_from(ext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ use std::net;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use copyless::BoxHelper;
|
|
||||||
|
|
||||||
use crate::extensions::Extensions;
|
use crate::extensions::Extensions;
|
||||||
use crate::header::HeaderMap;
|
use crate::header::HeaderMap;
|
||||||
|
@ -480,17 +479,17 @@ impl BoxedResponsePool {
|
||||||
BoxedResponseHead { head: Some(head) }
|
BoxedResponseHead { head: Some(head) }
|
||||||
} else {
|
} else {
|
||||||
BoxedResponseHead {
|
BoxedResponseHead {
|
||||||
head: Some(Box::alloc().init(ResponseHead::new(status))),
|
head: Some(Box::new(ResponseHead::new(status))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
/// Release request instance
|
/// Release request instance
|
||||||
fn release(&self, msg: Box<ResponseHead>) {
|
fn release(&self, mut msg: Box<ResponseHead>) {
|
||||||
let v = &mut self.0.borrow_mut();
|
let v = &mut self.0.borrow_mut();
|
||||||
if v.len() < 128 {
|
if v.len() < 128 {
|
||||||
msg.extensions.borrow_mut().clear();
|
msg.extensions.get_mut().clear();
|
||||||
v.push(msg);
|
v.push(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
@ -8,18 +9,16 @@ use actix_rt::net::TcpStream;
|
||||||
use actix_service::{pipeline_factory, IntoServiceFactory, Service, ServiceFactory};
|
use actix_service::{pipeline_factory, IntoServiceFactory, Service, ServiceFactory};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use futures_core::{ready, Future};
|
use futures_core::{ready, Future};
|
||||||
use futures_util::future::ok;
|
|
||||||
use h2::server::{self, Handshake};
|
use h2::server::{self, Handshake};
|
||||||
use pin_project::pin_project;
|
use pin_project::pin_project;
|
||||||
|
|
||||||
use crate::body::MessageBody;
|
use crate::body::MessageBody;
|
||||||
use crate::builder::HttpServiceBuilder;
|
use crate::builder::HttpServiceBuilder;
|
||||||
use crate::cloneable::CloneableService;
|
|
||||||
use crate::config::{KeepAlive, ServiceConfig};
|
use crate::config::{KeepAlive, ServiceConfig};
|
||||||
use crate::error::{DispatchError, Error};
|
use crate::error::{DispatchError, Error};
|
||||||
use crate::request::Request;
|
use crate::request::Request;
|
||||||
use crate::response::Response;
|
use crate::response::Response;
|
||||||
use crate::{h1, h2::Dispatcher, ConnectCallback, Extensions, Protocol};
|
use crate::{h1, h2::Dispatcher, ConnectCallback, OnConnectData, Protocol};
|
||||||
|
|
||||||
/// A `ServiceFactory` for HTTP/1.1 or HTTP/2 protocol.
|
/// A `ServiceFactory` for HTTP/1.1 or HTTP/2 protocol.
|
||||||
pub struct HttpService<T, S, B, X = h1::ExpectHandler, U = h1::UpgradeHandler> {
|
pub struct HttpService<T, S, B, X = h1::ExpectHandler, U = h1::UpgradeHandler> {
|
||||||
|
@ -175,9 +174,9 @@ where
|
||||||
Error = DispatchError,
|
Error = DispatchError,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
> {
|
> {
|
||||||
pipeline_factory(|io: TcpStream| {
|
pipeline_factory(|io: TcpStream| async {
|
||||||
let peer_addr = io.peer_addr().ok();
|
let peer_addr = io.peer_addr().ok();
|
||||||
ok((io, Protocol::Http1, peer_addr))
|
Ok((io, Protocol::Http1, peer_addr))
|
||||||
})
|
})
|
||||||
.and_then(self)
|
.and_then(self)
|
||||||
}
|
}
|
||||||
|
@ -227,7 +226,7 @@ mod openssl {
|
||||||
.map_err(TlsError::Tls)
|
.map_err(TlsError::Tls)
|
||||||
.map_init_err(|_| panic!()),
|
.map_init_err(|_| panic!()),
|
||||||
)
|
)
|
||||||
.and_then(|io: SslStream<TcpStream>| {
|
.and_then(|io: SslStream<TcpStream>| async {
|
||||||
let proto = if let Some(protos) = io.ssl().selected_alpn_protocol() {
|
let proto = if let Some(protos) = io.ssl().selected_alpn_protocol() {
|
||||||
if protos.windows(2).any(|window| window == b"h2") {
|
if protos.windows(2).any(|window| window == b"h2") {
|
||||||
Protocol::Http2
|
Protocol::Http2
|
||||||
|
@ -238,7 +237,7 @@ mod openssl {
|
||||||
Protocol::Http1
|
Protocol::Http1
|
||||||
};
|
};
|
||||||
let peer_addr = io.get_ref().peer_addr().ok();
|
let peer_addr = io.get_ref().peer_addr().ok();
|
||||||
ok((io, proto, peer_addr))
|
Ok((io, proto, peer_addr))
|
||||||
})
|
})
|
||||||
.and_then(self.map_err(TlsError::Service))
|
.and_then(self.map_err(TlsError::Service))
|
||||||
}
|
}
|
||||||
|
@ -295,7 +294,7 @@ mod rustls {
|
||||||
.map_err(TlsError::Tls)
|
.map_err(TlsError::Tls)
|
||||||
.map_init_err(|_| panic!()),
|
.map_init_err(|_| panic!()),
|
||||||
)
|
)
|
||||||
.and_then(|io: TlsStream<TcpStream>| {
|
.and_then(|io: TlsStream<TcpStream>| async {
|
||||||
let proto = if let Some(protos) = io.get_ref().1.get_alpn_protocol() {
|
let proto = if let Some(protos) = io.get_ref().1.get_alpn_protocol() {
|
||||||
if protos.windows(2).any(|window| window == b"h2") {
|
if protos.windows(2).any(|window| window == b"h2") {
|
||||||
Protocol::Http2
|
Protocol::Http2
|
||||||
|
@ -306,7 +305,7 @@ mod rustls {
|
||||||
Protocol::Http1
|
Protocol::Http1
|
||||||
};
|
};
|
||||||
let peer_addr = io.get_ref().0.peer_addr().ok();
|
let peer_addr = io.get_ref().0.peer_addr().ok();
|
||||||
ok((io, proto, peer_addr))
|
Ok((io, proto, peer_addr))
|
||||||
})
|
})
|
||||||
.and_then(self.map_err(TlsError::Service))
|
.and_then(self.map_err(TlsError::Service))
|
||||||
}
|
}
|
||||||
|
@ -371,7 +370,7 @@ where
|
||||||
upgrade: Option<U::Service>,
|
upgrade: Option<U::Service>,
|
||||||
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
|
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
|
||||||
cfg: ServiceConfig,
|
cfg: ServiceConfig,
|
||||||
_phantom: PhantomData<(T, B)>,
|
_phantom: PhantomData<B>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S, B, X, U> Future for HttpServiceResponse<T, S, B, X, U>
|
impl<T, S, B, X, U> Future for HttpServiceResponse<T, S, B, X, U>
|
||||||
|
@ -413,7 +412,7 @@ where
|
||||||
.map_err(|e| log::error!("Init http service error: {:?}", e)))?;
|
.map_err(|e| log::error!("Init http service error: {:?}", e)))?;
|
||||||
this = self.as_mut().project();
|
this = self.as_mut().project();
|
||||||
*this.upgrade = Some(upgrade);
|
*this.upgrade = Some(upgrade);
|
||||||
this.fut_ex.set(None);
|
this.fut_upg.set(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = ready!(this
|
let result = ready!(this
|
||||||
|
@ -441,14 +440,29 @@ where
|
||||||
X: Service<Request>,
|
X: Service<Request>,
|
||||||
U: Service<(Request, Framed<T, h1::Codec>)>,
|
U: Service<(Request, Framed<T, h1::Codec>)>,
|
||||||
{
|
{
|
||||||
srv: CloneableService<S>,
|
flow: Rc<RefCell<HttpFlow<S, X, U>>>,
|
||||||
expect: CloneableService<X>,
|
|
||||||
upgrade: Option<CloneableService<U>>,
|
|
||||||
cfg: ServiceConfig,
|
cfg: ServiceConfig,
|
||||||
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
|
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
|
||||||
_phantom: PhantomData<B>,
|
_phantom: PhantomData<B>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A collection of services that describe an HTTP request flow.
|
||||||
|
pub(super) struct HttpFlow<S, X, U> {
|
||||||
|
pub(super) service: S,
|
||||||
|
pub(super) expect: X,
|
||||||
|
pub(super) upgrade: Option<U>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, X, U> HttpFlow<S, X, U> {
|
||||||
|
pub(super) fn new(service: S, expect: X, upgrade: Option<U>) -> Rc<RefCell<Self>> {
|
||||||
|
Rc::new(RefCell::new(Self {
|
||||||
|
service,
|
||||||
|
expect,
|
||||||
|
upgrade,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T, S, B, X, U> HttpServiceHandler<T, S, B, X, U>
|
impl<T, S, B, X, U> HttpServiceHandler<T, S, B, X, U>
|
||||||
where
|
where
|
||||||
S: Service<Request>,
|
S: Service<Request>,
|
||||||
|
@ -463,7 +477,7 @@ where
|
||||||
{
|
{
|
||||||
fn new(
|
fn new(
|
||||||
cfg: ServiceConfig,
|
cfg: ServiceConfig,
|
||||||
srv: S,
|
service: S,
|
||||||
expect: X,
|
expect: X,
|
||||||
upgrade: Option<U>,
|
upgrade: Option<U>,
|
||||||
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
|
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
|
||||||
|
@ -471,9 +485,7 @@ where
|
||||||
HttpServiceHandler {
|
HttpServiceHandler {
|
||||||
cfg,
|
cfg,
|
||||||
on_connect_ext,
|
on_connect_ext,
|
||||||
srv: CloneableService::new(srv),
|
flow: HttpFlow::new(service, expect, upgrade),
|
||||||
expect: CloneableService::new(expect),
|
|
||||||
upgrade: upgrade.map(CloneableService::new),
|
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -498,7 +510,8 @@ where
|
||||||
type Future = HttpServiceHandlerResponse<T, S, B, X, U>;
|
type Future = HttpServiceHandlerResponse<T, S, B, X, U>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
let ready = self
|
let mut flow = self.flow.borrow_mut();
|
||||||
|
let ready = flow
|
||||||
.expect
|
.expect
|
||||||
.poll_ready(cx)
|
.poll_ready(cx)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
|
@ -508,8 +521,8 @@ where
|
||||||
})?
|
})?
|
||||||
.is_ready();
|
.is_ready();
|
||||||
|
|
||||||
let ready = self
|
let ready = flow
|
||||||
.srv
|
.service
|
||||||
.poll_ready(cx)
|
.poll_ready(cx)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
let e = e.into();
|
let e = e.into();
|
||||||
|
@ -519,7 +532,7 @@ where
|
||||||
.is_ready()
|
.is_ready()
|
||||||
&& ready;
|
&& ready;
|
||||||
|
|
||||||
let ready = if let Some(ref mut upg) = self.upgrade {
|
let ready = if let Some(ref mut upg) = flow.upgrade {
|
||||||
upg.poll_ready(cx)
|
upg.poll_ready(cx)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
let e = e.into();
|
let e = e.into();
|
||||||
|
@ -543,19 +556,16 @@ where
|
||||||
&mut self,
|
&mut self,
|
||||||
(io, proto, peer_addr): (T, Protocol, Option<net::SocketAddr>),
|
(io, proto, peer_addr): (T, Protocol, Option<net::SocketAddr>),
|
||||||
) -> Self::Future {
|
) -> Self::Future {
|
||||||
let mut connect_extensions = Extensions::new();
|
let on_connect_data =
|
||||||
|
OnConnectData::from_io(&io, self.on_connect_ext.as_deref());
|
||||||
if let Some(ref handler) = self.on_connect_ext {
|
|
||||||
handler(&io, &mut connect_extensions);
|
|
||||||
}
|
|
||||||
|
|
||||||
match proto {
|
match proto {
|
||||||
Protocol::Http2 => HttpServiceHandlerResponse {
|
Protocol::Http2 => HttpServiceHandlerResponse {
|
||||||
state: State::H2Handshake(Some((
|
state: State::H2Handshake(Some((
|
||||||
server::handshake(io),
|
server::handshake(io),
|
||||||
self.cfg.clone(),
|
self.cfg.clone(),
|
||||||
self.srv.clone(),
|
self.flow.clone(),
|
||||||
connect_extensions,
|
on_connect_data,
|
||||||
peer_addr,
|
peer_addr,
|
||||||
))),
|
))),
|
||||||
},
|
},
|
||||||
|
@ -564,13 +574,13 @@ where
|
||||||
state: State::H1(h1::Dispatcher::new(
|
state: State::H1(h1::Dispatcher::new(
|
||||||
io,
|
io,
|
||||||
self.cfg.clone(),
|
self.cfg.clone(),
|
||||||
self.srv.clone(),
|
self.flow.clone(),
|
||||||
self.expect.clone(),
|
on_connect_data,
|
||||||
self.upgrade.clone(),
|
|
||||||
connect_extensions,
|
|
||||||
peer_addr,
|
peer_addr,
|
||||||
)),
|
)),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
proto => unimplemented!("Unsupported HTTP version: {:?}.", proto),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -589,13 +599,13 @@ where
|
||||||
U::Error: fmt::Display,
|
U::Error: fmt::Display,
|
||||||
{
|
{
|
||||||
H1(#[pin] h1::Dispatcher<T, S, B, X, U>),
|
H1(#[pin] h1::Dispatcher<T, S, B, X, U>),
|
||||||
H2(#[pin] Dispatcher<T, S, B>),
|
H2(#[pin] Dispatcher<T, S, B, X, U>),
|
||||||
H2Handshake(
|
H2Handshake(
|
||||||
Option<(
|
Option<(
|
||||||
Handshake<T, Bytes>,
|
Handshake<T, Bytes>,
|
||||||
ServiceConfig,
|
ServiceConfig,
|
||||||
CloneableService<S>,
|
Rc<RefCell<HttpFlow<S, X, U>>>,
|
||||||
Extensions,
|
OnConnectData,
|
||||||
Option<net::SocketAddr>,
|
Option<net::SocketAddr>,
|
||||||
)>,
|
)>,
|
||||||
),
|
),
|
||||||
|
@ -634,53 +644,30 @@ where
|
||||||
{
|
{
|
||||||
type Output = Result<(), DispatchError>;
|
type Output = Result<(), DispatchError>;
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
self.project().state.poll(cx)
|
match self.as_mut().project().state.project() {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, S, B, X, U> State<T, S, B, X, U>
|
|
||||||
where
|
|
||||||
T: AsyncRead + AsyncWrite + Unpin,
|
|
||||||
S: Service<Request>,
|
|
||||||
S::Error: Into<Error> + 'static,
|
|
||||||
S::Response: Into<Response<B>> + 'static,
|
|
||||||
B: MessageBody + 'static,
|
|
||||||
X: Service<Request, Response = Request>,
|
|
||||||
X::Error: Into<Error>,
|
|
||||||
U: Service<(Request, Framed<T, h1::Codec>), Response = ()>,
|
|
||||||
U::Error: fmt::Display,
|
|
||||||
{
|
|
||||||
fn poll(
|
|
||||||
mut self: Pin<&mut Self>,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
) -> Poll<Result<(), DispatchError>> {
|
|
||||||
match self.as_mut().project() {
|
|
||||||
StateProj::H1(disp) => disp.poll(cx),
|
StateProj::H1(disp) => disp.poll(cx),
|
||||||
StateProj::H2(disp) => disp.poll(cx),
|
StateProj::H2(disp) => disp.poll(cx),
|
||||||
StateProj::H2Handshake(ref mut data) => {
|
StateProj::H2Handshake(data) => {
|
||||||
let conn = if let Some(ref mut item) = data {
|
match ready!(Pin::new(&mut data.as_mut().unwrap().0).poll(cx)) {
|
||||||
match Pin::new(&mut item.0).poll(cx) {
|
Ok(conn) => {
|
||||||
Poll::Ready(Ok(conn)) => conn,
|
let (_, cfg, srv, on_connect_data, peer_addr) =
|
||||||
Poll::Ready(Err(err)) => {
|
data.take().unwrap();
|
||||||
trace!("H2 handshake error: {}", err);
|
self.as_mut().project().state.set(State::H2(Dispatcher::new(
|
||||||
return Poll::Ready(Err(err.into()));
|
srv,
|
||||||
}
|
conn,
|
||||||
Poll::Pending => return Poll::Pending,
|
on_connect_data,
|
||||||
|
cfg,
|
||||||
|
None,
|
||||||
|
peer_addr,
|
||||||
|
)));
|
||||||
|
self.poll(cx)
|
||||||
}
|
}
|
||||||
} else {
|
Err(err) => {
|
||||||
panic!()
|
trace!("H2 handshake error: {}", err);
|
||||||
};
|
Poll::Ready(Err(err.into()))
|
||||||
let (_, cfg, srv, on_connect_data, peer_addr) = data.take().unwrap();
|
}
|
||||||
self.set(State::H2(Dispatcher::new(
|
}
|
||||||
srv,
|
|
||||||
conn,
|
|
||||||
on_connect_data,
|
|
||||||
cfg,
|
|
||||||
None,
|
|
||||||
peer_addr,
|
|
||||||
)));
|
|
||||||
self.poll(cx)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use std::convert::{From, Into};
|
use std::convert::{From, Into};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use self::OpCode::*;
|
|
||||||
/// Operation codes as part of RFC6455.
|
/// Operation codes as part of RFC6455.
|
||||||
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
|
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
|
||||||
pub enum OpCode {
|
pub enum OpCode {
|
||||||
|
@ -29,6 +28,7 @@ pub enum OpCode {
|
||||||
|
|
||||||
impl fmt::Display for OpCode {
|
impl fmt::Display for OpCode {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
use self::OpCode::*;
|
||||||
match *self {
|
match *self {
|
||||||
Continue => write!(f, "CONTINUE"),
|
Continue => write!(f, "CONTINUE"),
|
||||||
Text => write!(f, "TEXT"),
|
Text => write!(f, "TEXT"),
|
||||||
|
@ -41,9 +41,10 @@ impl fmt::Display for OpCode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<u8> for OpCode {
|
impl From<OpCode> for u8 {
|
||||||
fn into(self) -> u8 {
|
fn from(op: OpCode) -> u8 {
|
||||||
match self {
|
use self::OpCode::*;
|
||||||
|
match op {
|
||||||
Continue => 0,
|
Continue => 0,
|
||||||
Text => 1,
|
Text => 1,
|
||||||
Binary => 2,
|
Binary => 2,
|
||||||
|
@ -60,6 +61,7 @@ impl Into<u8> for OpCode {
|
||||||
|
|
||||||
impl From<u8> for OpCode {
|
impl From<u8> for OpCode {
|
||||||
fn from(byte: u8) -> OpCode {
|
fn from(byte: u8) -> OpCode {
|
||||||
|
use self::OpCode::*;
|
||||||
match byte {
|
match byte {
|
||||||
0 => Continue,
|
0 => Continue,
|
||||||
1 => Text,
|
1 => Text,
|
||||||
|
@ -72,7 +74,6 @@ impl From<u8> for OpCode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use self::CloseCode::*;
|
|
||||||
/// Status code used to indicate why an endpoint is closing the `WebSocket`
|
/// Status code used to indicate why an endpoint is closing the `WebSocket`
|
||||||
/// connection.
|
/// connection.
|
||||||
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
|
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
|
||||||
|
@ -138,9 +139,10 @@ pub enum CloseCode {
|
||||||
Other(u16),
|
Other(u16),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<u16> for CloseCode {
|
impl From<CloseCode> for u16 {
|
||||||
fn into(self) -> u16 {
|
fn from(code: CloseCode) -> u16 {
|
||||||
match self {
|
use self::CloseCode::*;
|
||||||
|
match code {
|
||||||
Normal => 1000,
|
Normal => 1000,
|
||||||
Away => 1001,
|
Away => 1001,
|
||||||
Protocol => 1002,
|
Protocol => 1002,
|
||||||
|
@ -161,6 +163,7 @@ impl Into<u16> for CloseCode {
|
||||||
|
|
||||||
impl From<u16> for CloseCode {
|
impl From<u16> for CloseCode {
|
||||||
fn from(code: u16) -> CloseCode {
|
fn from(code: u16) -> CloseCode {
|
||||||
|
use self::CloseCode::*;
|
||||||
match code {
|
match code {
|
||||||
1000 => Normal,
|
1000 => Normal,
|
||||||
1001 => Away,
|
1001 => Away,
|
||||||
|
@ -185,6 +188,7 @@ impl From<u16> for CloseCode {
|
||||||
pub struct CloseReason {
|
pub struct CloseReason {
|
||||||
/// Exit code
|
/// Exit code
|
||||||
pub code: CloseCode,
|
pub code: CloseCode,
|
||||||
|
|
||||||
/// Optional description of the exit code
|
/// Optional description of the exit code
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2021-xx-xx
|
## Unreleased - 2021-xx-xx
|
||||||
* Fix multipart consuming payload before header checks #1513
|
|
||||||
|
|
||||||
|
## 0.4.0-beta.1 - 2021-01-07
|
||||||
|
* Fix multipart consuming payload before header checks. [#1513]
|
||||||
* Update `bytes` to `1.0`. [#1813]
|
* Update `bytes` to `1.0`. [#1813]
|
||||||
|
|
||||||
[#1813]: https://github.com/actix/actix-web/pull/1813
|
[#1813]: https://github.com/actix/actix-web/pull/1813
|
||||||
|
[#1513]: https://github.com/actix/actix-web/pull/1513
|
||||||
|
|
||||||
|
|
||||||
## 3.0.0 - 2020-09-11
|
## 0.3.0 - 2020-09-11
|
||||||
* No significant changes from `3.0.0-beta.2`.
|
* No significant changes from `0.3.0-beta.2`.
|
||||||
|
|
||||||
|
|
||||||
## 3.0.0-beta.2 - 2020-09-10
|
## 0.3.0-beta.2 - 2020-09-10
|
||||||
* Update `actix-*` dependencies to latest versions.
|
* Update `actix-*` dependencies to latest versions.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "actix-multipart"
|
name = "actix-multipart"
|
||||||
version = "0.3.0"
|
version = "0.4.0-beta.1"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Multipart support for actix web framework."
|
description = "Multipart support for actix web framework."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
@ -16,11 +16,11 @@ name = "actix_multipart"
|
||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-web = { version = "3.0.0", default-features = false }
|
actix-web = { version = "4.0.0-beta.1", default-features = false }
|
||||||
actix-utils = "3.0.0-beta.1"
|
actix-utils = "3.0.0-beta.1"
|
||||||
|
|
||||||
bytes = "1"
|
bytes = "1"
|
||||||
derive_more = "0.99.2"
|
derive_more = "0.99.5"
|
||||||
httparse = "1.3"
|
httparse = "1.3"
|
||||||
futures-util = { version = "0.3.7", default-features = false }
|
futures-util = { version = "0.3.7", default-features = false }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
@ -29,4 +29,4 @@ twoway = "0.2"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-rt = "2.0.0-beta.1"
|
actix-rt = "2.0.0-beta.1"
|
||||||
actix-http = "2.0.0"
|
actix-http = "3.0.0-beta.1"
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2021-xx-xx
|
## Unreleased - 2021-xx-xx
|
||||||
|
|
||||||
|
|
||||||
|
## 4.0.0-beta.1 - 2021-01-07
|
||||||
* Update `pin-project` to `1.0`.
|
* Update `pin-project` to `1.0`.
|
||||||
* Update `bytes` to `1.0`. [#1813]
|
* Update `bytes` to `1.0`. [#1813]
|
||||||
* `WebsocketContext::text` now takes an `Into<bytestring::ByteString>`. [#1864]
|
* `WebsocketContext::text` now takes an `Into<bytestring::ByteString>`. [#1864]
|
||||||
|
@ -8,6 +11,7 @@
|
||||||
[#1813]: https://github.com/actix/actix-web/pull/1813
|
[#1813]: https://github.com/actix/actix-web/pull/1813
|
||||||
[#1864]: https://github.com/actix/actix-web/pull/1864
|
[#1864]: https://github.com/actix/actix-web/pull/1864
|
||||||
|
|
||||||
|
|
||||||
## 3.0.0 - 2020-09-11
|
## 3.0.0 - 2020-09-11
|
||||||
* No significant changes from `3.0.0-beta.2`.
|
* No significant changes from `3.0.0-beta.2`.
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "actix-web-actors"
|
name = "actix-web-actors"
|
||||||
version = "3.0.0"
|
version = "4.0.0-beta.1"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Actix actors support for actix web framework."
|
description = "Actix actors support for actix web framework."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
@ -18,8 +18,8 @@ path = "src/lib.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix = "0.11.0-beta.1"
|
actix = "0.11.0-beta.1"
|
||||||
actix-codec = "0.4.0-beta.1"
|
actix-codec = "0.4.0-beta.1"
|
||||||
actix-http = "2.0.0"
|
actix-http = "3.0.0-beta.1"
|
||||||
actix-web = { version = "3.0.0", default-features = false }
|
actix-web = { version = "4.0.0-beta.1", default-features = false }
|
||||||
|
|
||||||
bytes = "1"
|
bytes = "1"
|
||||||
bytestring = "1"
|
bytestring = "1"
|
||||||
|
|
|
@ -20,7 +20,7 @@ proc-macro2 = "1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-rt = "2.0.0-beta.1"
|
actix-rt = "2.0.0-beta.1"
|
||||||
actix-web = "3.0.0"
|
actix-web = "4.0.0-beta.1"
|
||||||
futures-util = { version = "0.3.7", default-features = false }
|
futures-util = { version = "0.3.7", default-features = false }
|
||||||
trybuild = "1"
|
trybuild = "1"
|
||||||
rustversion = "1"
|
rustversion = "1"
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2021-xx-xx
|
## Unreleased - 2021-xx-xx
|
||||||
|
|
||||||
|
|
||||||
|
## 3.0.0-beta.1 - 2021-01-07
|
||||||
### Changed
|
### Changed
|
||||||
* Update `rand` to `0.8`
|
* Update `rand` to `0.8`
|
||||||
* Update `bytes` to `1.0`. [#1813]
|
* Update `bytes` to `1.0`. [#1813]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "awc"
|
name = "awc"
|
||||||
version = "2.0.3"
|
version = "3.0.0-beta.1"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Async HTTP and WebSocket client library built on the Actix ecosystem"
|
description = "Async HTTP and WebSocket client library built on the Actix ecosystem"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
@ -39,13 +39,13 @@ compress = ["actix-http/compress"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-codec = "0.4.0-beta.1"
|
actix-codec = "0.4.0-beta.1"
|
||||||
actix-service = "2.0.0-beta.2"
|
actix-service = "2.0.0-beta.2"
|
||||||
actix-http = "2.2.0"
|
actix-http = "3.0.0-beta.1"
|
||||||
actix-rt = "2.0.0-beta.1"
|
actix-rt = "2.0.0-beta.1"
|
||||||
|
|
||||||
base64 = "0.13"
|
base64 = "0.13"
|
||||||
bytes = "1"
|
bytes = "1"
|
||||||
cfg-if = "1.0"
|
cfg-if = "1.0"
|
||||||
derive_more = "0.99.2"
|
derive_more = "0.99.5"
|
||||||
futures-core = { version = "0.3.7", default-features = false }
|
futures-core = { version = "0.3.7", default-features = false }
|
||||||
log =" 0.4"
|
log =" 0.4"
|
||||||
mime = "0.3"
|
mime = "0.3"
|
||||||
|
@ -61,9 +61,9 @@ rust-tls = { version = "0.19.0", package = "rustls", optional = true, features =
|
||||||
# TODO: actix is temporary added as dev dep for actix-macro reason.
|
# TODO: actix is temporary added as dev dep for actix-macro reason.
|
||||||
# Can be removed when it does not impact tests.
|
# Can be removed when it does not impact tests.
|
||||||
actix = "0.11.0-beta.1"
|
actix = "0.11.0-beta.1"
|
||||||
actix-web = { version = "3.0.0", features = ["openssl"] }
|
actix-web = { version = "4.0.0-beta.1", features = ["openssl"] }
|
||||||
actix-http = { version = "2.0.0", features = ["openssl"] }
|
actix-http = { version = "3.0.0-beta.1", features = ["openssl"] }
|
||||||
actix-http-test = { version = "2.0.0", features = ["openssl"] }
|
actix-http-test = { version = "3.0.0-beta.1", features = ["openssl"] }
|
||||||
actix-utils = "3.0.0-beta.1"
|
actix-utils = "3.0.0-beta.1"
|
||||||
actix-server = "2.0.0-beta.2"
|
actix-server = "2.0.0-beta.2"
|
||||||
actix-tls = { version = "3.0.0-beta.2", features = ["openssl", "rustls"] }
|
actix-tls = { version = "3.0.0-beta.2", features = ["openssl", "rustls"] }
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//!
|
//!
|
||||||
//! ## Making a GET request
|
//! ## Making a GET request
|
||||||
//!
|
//!
|
||||||
//! ```rust
|
//! ```no_run
|
||||||
//! # #[actix_rt::main]
|
//! # #[actix_rt::main]
|
||||||
//! # async fn main() -> Result<(), awc::error::SendRequestError> {
|
//! # async fn main() -> Result<(), awc::error::SendRequestError> {
|
||||||
//! let mut client = awc::Client::default();
|
//! let mut client = awc::Client::default();
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
//!
|
//!
|
||||||
//! ### Raw body contents
|
//! ### Raw body contents
|
||||||
//!
|
//!
|
||||||
//! ```rust
|
//! ```no_run
|
||||||
//! # #[actix_rt::main]
|
//! # #[actix_rt::main]
|
||||||
//! # async fn main() -> Result<(), awc::error::SendRequestError> {
|
//! # async fn main() -> Result<(), awc::error::SendRequestError> {
|
||||||
//! let mut client = awc::Client::default();
|
//! let mut client = awc::Client::default();
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
//!
|
//!
|
||||||
//! ### Forms
|
//! ### Forms
|
||||||
//!
|
//!
|
||||||
//! ```rust
|
//! ```no_run
|
||||||
//! # #[actix_rt::main]
|
//! # #[actix_rt::main]
|
||||||
//! # async fn main() -> Result<(), awc::error::SendRequestError> {
|
//! # async fn main() -> Result<(), awc::error::SendRequestError> {
|
||||||
//! let params = [("foo", "bar"), ("baz", "quux")];
|
//! let params = [("foo", "bar"), ("baz", "quux")];
|
||||||
|
@ -48,7 +48,7 @@
|
||||||
//!
|
//!
|
||||||
//! ### JSON
|
//! ### JSON
|
||||||
//!
|
//!
|
||||||
//! ```rust
|
//! ```no_run
|
||||||
//! # #[actix_rt::main]
|
//! # #[actix_rt::main]
|
||||||
//! # async fn main() -> Result<(), awc::error::SendRequestError> {
|
//! # async fn main() -> Result<(), awc::error::SendRequestError> {
|
||||||
//! let request = serde_json::json!({
|
//! let request = serde_json::json!({
|
||||||
|
@ -66,7 +66,7 @@
|
||||||
//!
|
//!
|
||||||
//! ## WebSocket support
|
//! ## WebSocket support
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```no_run
|
||||||
//! # #[actix_rt::main]
|
//! # #[actix_rt::main]
|
||||||
//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
//! use futures_util::{sink::SinkExt, stream::StreamExt};
|
//! use futures_util::{sink::SinkExt, stream::StreamExt};
|
||||||
|
|
|
@ -33,18 +33,18 @@ pub(crate) enum PrepForSendingError {
|
||||||
Http(HttpError),
|
Http(HttpError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<FreezeRequestError> for PrepForSendingError {
|
impl From<PrepForSendingError> for FreezeRequestError {
|
||||||
fn into(self) -> FreezeRequestError {
|
fn from(err: PrepForSendingError) -> FreezeRequestError {
|
||||||
match self {
|
match err {
|
||||||
PrepForSendingError::Url(e) => FreezeRequestError::Url(e),
|
PrepForSendingError::Url(e) => FreezeRequestError::Url(e),
|
||||||
PrepForSendingError::Http(e) => FreezeRequestError::Http(e),
|
PrepForSendingError::Http(e) => FreezeRequestError::Http(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<SendRequestError> for PrepForSendingError {
|
impl From<PrepForSendingError> for SendRequestError {
|
||||||
fn into(self) -> SendRequestError {
|
fn from(err: PrepForSendingError) -> SendRequestError {
|
||||||
match self {
|
match err {
|
||||||
PrepForSendingError::Url(e) => SendRequestError::Url(e),
|
PrepForSendingError::Url(e) => SendRequestError::Url(e),
|
||||||
PrepForSendingError::Http(e) => SendRequestError::Http(e),
|
PrepForSendingError::Http(e) => SendRequestError::Http(e),
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
//!
|
//!
|
||||||
//! # Example
|
//! # Example
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```no_run
|
||||||
//! use awc::{Client, ws};
|
//! use awc::{Client, ws};
|
||||||
//! use futures_util::{sink::SinkExt, stream::StreamExt};
|
//! use futures_util::{sink::SinkExt, stream::StreamExt};
|
||||||
//!
|
//!
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
//! For an example of extracting a client TLS certificate, see:
|
//! For an example of extracting a client TLS certificate, see:
|
||||||
//! <https://github.com/actix/examples/tree/HEAD/rustls-client-cert>
|
//! <https://github.com/actix/examples/tree/HEAD/rustls-client-cert>
|
||||||
|
|
||||||
use std::{any::Any, env, io, net::SocketAddr};
|
use std::{any::Any, io, net::SocketAddr};
|
||||||
|
|
||||||
use actix_web::{dev::Extensions, rt::net::TcpStream, web, App, HttpServer};
|
use actix_web::{dev::Extensions, rt::net::TcpStream, web, App, HttpServer};
|
||||||
|
|
||||||
|
@ -36,11 +36,7 @@ fn get_conn_info(connection: &dyn Any, data: &mut Extensions) {
|
||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
async fn main() -> io::Result<()> {
|
async fn main() -> io::Result<()> {
|
||||||
if env::var("RUST_LOG").is_err() {
|
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
||||||
env::set_var("RUST_LOG", "info");
|
|
||||||
}
|
|
||||||
|
|
||||||
env_logger::init();
|
|
||||||
|
|
||||||
HttpServer::new(|| App::new().default_service(web::to(route_whoami)))
|
HttpServer::new(|| App::new().default_service(web::to(route_whoami)))
|
||||||
.on_connect(get_conn_info)
|
.on_connect(get_conn_info)
|
||||||
|
|
|
@ -22,8 +22,7 @@ async fn no_params() -> &'static str {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
std::env::set_var("RUST_LOG", "actix_server=info,actix_web=info");
|
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
||||||
env_logger::init();
|
|
||||||
|
|
||||||
HttpServer::new(|| {
|
HttpServer::new(|| {
|
||||||
App::new()
|
App::new()
|
||||||
|
|
|
@ -416,9 +416,9 @@ impl<B> ServiceResponse<B> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> Into<Response<B>> for ServiceResponse<B> {
|
impl<B> From<ServiceResponse<B>> for Response<B> {
|
||||||
fn into(self) -> Response<B> {
|
fn from(res: ServiceResponse<B>) -> Response<B> {
|
||||||
self.response
|
res.response
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,13 +121,13 @@ pub enum EitherExtractError<A, B> {
|
||||||
Extract(A, B),
|
Extract(A, B),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Into<Error> for EitherExtractError<A, B>
|
impl<A, B> From<EitherExtractError<A, B>> for Error
|
||||||
where
|
where
|
||||||
A: Into<Error>,
|
A: Into<Error>,
|
||||||
B: Into<Error>,
|
B: Into<Error>,
|
||||||
{
|
{
|
||||||
fn into(self) -> Error {
|
fn from(err: EitherExtractError<A, B>) -> Error {
|
||||||
match self {
|
match err {
|
||||||
EitherExtractError::Bytes(err) => err,
|
EitherExtractError::Bytes(err) => err,
|
||||||
EitherExtractError::Extract(a_err, _b_err) => a_err.into(),
|
EitherExtractError::Extract(a_err, _b_err) => a_err.into(),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue