mirror of https://github.com/fafhrd91/actix-web
relax bound on MessageBody::Error to Debug
This commit is contained in:
parent
44b7302845
commit
35d279e594
|
@ -1,5 +1,5 @@
|
||||||
use std::{
|
use std::{
|
||||||
error::Error as StdError,
|
fmt,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
};
|
};
|
||||||
|
@ -25,7 +25,7 @@ pin_project! {
|
||||||
impl<S, E> BodyStream<S>
|
impl<S, E> BodyStream<S>
|
||||||
where
|
where
|
||||||
S: Stream<Item = Result<Bytes, E>>,
|
S: Stream<Item = Result<Bytes, E>>,
|
||||||
E: Into<Box<dyn StdError>> + 'static,
|
E: fmt::Debug + 'static,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(stream: S) -> Self {
|
pub fn new(stream: S) -> Self {
|
||||||
|
@ -36,7 +36,7 @@ where
|
||||||
impl<S, E> MessageBody for BodyStream<S>
|
impl<S, E> MessageBody for BodyStream<S>
|
||||||
where
|
where
|
||||||
S: Stream<Item = Result<Bytes, E>>,
|
S: Stream<Item = Result<Bytes, E>>,
|
||||||
E: Into<Box<dyn StdError>> + 'static,
|
E: fmt::Debug + 'static,
|
||||||
{
|
{
|
||||||
type Error = E;
|
type Error = E;
|
||||||
|
|
||||||
|
@ -150,21 +150,6 @@ mod tests {
|
||||||
assert!(matches!(to_bytes(body).await, Err("stringy error")));
|
assert!(matches!(to_bytes(body).await, Err("stringy error")));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
|
||||||
async fn stream_boxed_error() {
|
|
||||||
// `Box<dyn Error>` does not impl `Error`
|
|
||||||
// but it does impl `Into<Box<dyn Error>>`
|
|
||||||
|
|
||||||
let body = BodyStream::new(stream::once(async {
|
|
||||||
Err(Box::<dyn StdError>::from("stringy error"))
|
|
||||||
}));
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
to_bytes(body).await.unwrap_err().to_string(),
|
|
||||||
"stringy error"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn stream_delayed_error() {
|
async fn stream_delayed_error() {
|
||||||
let body = BodyStream::new(stream::iter(vec![Ok(Bytes::from("1")), Err(StreamErr)]));
|
let body = BodyStream::new(stream::iter(vec![Ok(Bytes::from("1")), Err(StreamErr)]));
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use std::{
|
use std::{
|
||||||
error::Error as StdError,
|
|
||||||
fmt,
|
fmt,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
|
@ -8,23 +7,28 @@ use std::{
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
|
||||||
use super::{BodySize, MessageBody, MessageBodyMapErr};
|
use super::{BodySize, MessageBody, MessageBodyMapErr};
|
||||||
use crate::Error;
|
|
||||||
|
|
||||||
/// A boxed message body with boxed errors.
|
/// A boxed message body with boxed errors.
|
||||||
pub struct BoxBody(Pin<Box<dyn MessageBody<Error = Box<dyn StdError>>>>);
|
pub struct BoxBody(Pin<Box<dyn MessageBody<Error = Box<dyn fmt::Debug>>>>);
|
||||||
|
|
||||||
impl BoxBody {
|
impl BoxBody {
|
||||||
/// Boxes a `MessageBody` and any errors it generates.
|
/// Boxes a `MessageBody` and any errors it generates.
|
||||||
|
#[inline]
|
||||||
pub fn new<B>(body: B) -> Self
|
pub fn new<B>(body: B) -> Self
|
||||||
where
|
where
|
||||||
B: MessageBody + 'static,
|
B: MessageBody + 'static,
|
||||||
{
|
{
|
||||||
let body = MessageBodyMapErr::new(body, Into::into);
|
fn box_it<T: fmt::Debug + 'static>(it: T) -> Box<dyn fmt::Debug> {
|
||||||
|
Box::new(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
let body = MessageBodyMapErr::new(body, box_it);
|
||||||
Self(Box::pin(body))
|
Self(Box::pin(body))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a mutable pinned reference to the inner message body type.
|
/// Returns a mutable pinned reference to the inner message body type.
|
||||||
pub fn as_pin_mut(&mut self) -> Pin<&mut (dyn MessageBody<Error = Box<dyn StdError>>)> {
|
#[inline]
|
||||||
|
pub fn as_pin_mut(&mut self) -> Pin<&mut (dyn MessageBody<Error = Box<dyn fmt::Debug>>)> {
|
||||||
self.0.as_mut()
|
self.0.as_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,22 +40,22 @@ impl fmt::Debug for BoxBody {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MessageBody for BoxBody {
|
impl MessageBody for BoxBody {
|
||||||
type Error = Error;
|
type Error = Box<dyn fmt::Debug>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn size(&self) -> BodySize {
|
fn size(&self) -> BodySize {
|
||||||
self.0.size()
|
self.0.size()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn poll_next(
|
fn poll_next(
|
||||||
mut self: Pin<&mut Self>,
|
mut self: Pin<&mut Self>,
|
||||||
cx: &mut Context<'_>,
|
cx: &mut Context<'_>,
|
||||||
) -> Poll<Option<Result<Bytes, Self::Error>>> {
|
) -> Poll<Option<Result<Bytes, Self::Error>>> {
|
||||||
self.0
|
self.0.as_mut().poll_next(cx)
|
||||||
.as_mut()
|
|
||||||
.poll_next(cx)
|
|
||||||
.map_err(|err| Error::new_body().with_cause(err))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn is_complete_body(&self) -> bool {
|
fn is_complete_body(&self) -> bool {
|
||||||
self.0.is_complete_body()
|
self.0.is_complete_body()
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,10 +66,10 @@ where
|
||||||
match self.project() {
|
match self.project() {
|
||||||
EitherBodyProj::Left { body } => body
|
EitherBodyProj::Left { body } => body
|
||||||
.poll_next(cx)
|
.poll_next(cx)
|
||||||
.map_err(|err| Error::new_body().with_cause(err)),
|
.map_err(|err| Error::new_body().with_cause(format!("{:?}", err))),
|
||||||
EitherBodyProj::Right { body } => body
|
EitherBodyProj::Right { body } => body
|
||||||
.poll_next(cx)
|
.poll_next(cx)
|
||||||
.map_err(|err| Error::new_body().with_cause(err)),
|
.map_err(|err| Error::new_body().with_cause(format!("{:?}", err))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
convert::Infallible,
|
convert::Infallible,
|
||||||
error::Error as StdError,
|
fmt, mem,
|
||||||
mem,
|
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
};
|
};
|
||||||
|
@ -17,9 +16,11 @@ use super::BodySize;
|
||||||
/// An interface types that can converted to bytes and used as response bodies.
|
/// An interface types that can converted to bytes and used as response bodies.
|
||||||
// TODO: examples
|
// TODO: examples
|
||||||
pub trait MessageBody {
|
pub trait MessageBody {
|
||||||
// TODO: consider this bound to only fmt::Display since the error type is not really used
|
/// The type of error that will be returned if streaming response fails.
|
||||||
// and there is an impl for Into<Box<StdError>> on String
|
///
|
||||||
type Error: Into<Box<dyn StdError>>;
|
/// Since it is not appropriate to generate a response mid-stream, it only requires `Debug` for
|
||||||
|
/// internal logging.
|
||||||
|
type Error: fmt::Debug + 'static;
|
||||||
|
|
||||||
/// Body size hint.
|
/// Body size hint.
|
||||||
fn size(&self) -> BodySize;
|
fn size(&self) -> BodySize;
|
||||||
|
@ -450,7 +451,7 @@ impl<B, F, E> MessageBody for MessageBodyMapErr<B, F>
|
||||||
where
|
where
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
F: FnOnce(B::Error) -> E,
|
F: FnOnce(B::Error) -> E,
|
||||||
E: Into<Box<dyn StdError>>,
|
E: fmt::Debug + 'static,
|
||||||
{
|
{
|
||||||
type Error = E;
|
type Error = E;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use std::{
|
use std::{
|
||||||
error::Error as StdError,
|
fmt,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
};
|
};
|
||||||
|
@ -25,7 +25,7 @@ pin_project! {
|
||||||
impl<S, E> SizedStream<S>
|
impl<S, E> SizedStream<S>
|
||||||
where
|
where
|
||||||
S: Stream<Item = Result<Bytes, E>>,
|
S: Stream<Item = Result<Bytes, E>>,
|
||||||
E: Into<Box<dyn StdError>> + 'static,
|
E: fmt::Debug + 'static,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(size: u64, stream: S) -> Self {
|
pub fn new(size: u64, stream: S) -> Self {
|
||||||
|
@ -38,7 +38,7 @@ where
|
||||||
impl<S, E> MessageBody for SizedStream<S>
|
impl<S, E> MessageBody for SizedStream<S>
|
||||||
where
|
where
|
||||||
S: Stream<Item = Result<Bytes, E>>,
|
S: Stream<Item = Result<Bytes, E>>,
|
||||||
E: Into<Box<dyn StdError>> + 'static,
|
E: fmt::Debug + 'static,
|
||||||
{
|
{
|
||||||
type Error = E;
|
type Error = E;
|
||||||
|
|
||||||
|
@ -147,25 +147,4 @@ mod tests {
|
||||||
let body = SizedStream::new(1, stream::once(async { Err("stringy error") }));
|
let body = SizedStream::new(1, stream::once(async { Err("stringy error") }));
|
||||||
assert!(matches!(to_bytes(body).await, Err("stringy error")));
|
assert!(matches!(to_bytes(body).await, Err("stringy error")));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
|
||||||
async fn stream_boxed_error() {
|
|
||||||
// `Box<dyn Error>` does not impl `Error`
|
|
||||||
// but it does impl `Into<Box<dyn Error>>`
|
|
||||||
|
|
||||||
let body = SizedStream::new(
|
|
||||||
0,
|
|
||||||
stream::once(async { Err(Box::<dyn StdError>::from("stringy error")) }),
|
|
||||||
);
|
|
||||||
assert_eq!(to_bytes(body).await.unwrap(), Bytes::new());
|
|
||||||
|
|
||||||
let body = SizedStream::new(
|
|
||||||
1,
|
|
||||||
stream::once(async { Err(Box::<dyn StdError>::from("stringy error")) }),
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
to_bytes(body).await.unwrap_err().to_string(),
|
|
||||||
"stringy error"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,7 +129,7 @@ where
|
||||||
}
|
}
|
||||||
EncoderBodyProj::Stream { body } => body
|
EncoderBodyProj::Stream { body } => body
|
||||||
.poll_next(cx)
|
.poll_next(cx)
|
||||||
.map_err(|err| EncoderError::Body(err.into())),
|
.map_err(|err| EncoderError::Body(format!("{:?}", err).into())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -335,28 +335,27 @@ impl From<PayloadError> for Error {
|
||||||
#[derive(Debug, Display, Error, From)]
|
#[derive(Debug, Display, Error, From)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum DispatchError {
|
pub enum DispatchError {
|
||||||
/// Service error
|
/// Service error.
|
||||||
// FIXME: display and error type
|
// FIXME: display and error type
|
||||||
#[display(fmt = "Service Error")]
|
#[display(fmt = "Service Error")]
|
||||||
Service(#[error(not(source))] Response<BoxBody>),
|
Service(#[error(not(source))] Response<BoxBody>),
|
||||||
|
|
||||||
/// Body error
|
/// Body error.
|
||||||
// FIXME: display and error type
|
|
||||||
#[display(fmt = "Body Error")]
|
#[display(fmt = "Body Error")]
|
||||||
Body(#[error(not(source))] Box<dyn StdError>),
|
ResponseBody(#[error(not(source))] Box<dyn fmt::Debug>),
|
||||||
|
|
||||||
/// Upgrade service error
|
/// Upgrade service error.
|
||||||
Upgrade,
|
Upgrade,
|
||||||
|
|
||||||
/// An `io::Error` that occurred while trying to read or write to a network stream.
|
/// An `io::Error` that occurred while trying to read or write to a network stream.
|
||||||
#[display(fmt = "IO error: {}", _0)]
|
#[display(fmt = "IO error")]
|
||||||
Io(io::Error),
|
Io(io::Error),
|
||||||
|
|
||||||
/// Http request parse error.
|
/// Request parse error.
|
||||||
#[display(fmt = "Parse error: {}", _0)]
|
#[display(fmt = "Request parse error")]
|
||||||
Parse(ParseError),
|
Parse(ParseError),
|
||||||
|
|
||||||
/// Http/2 error
|
/// HTTP/2 error.
|
||||||
#[display(fmt = "{}", _0)]
|
#[display(fmt = "{}", _0)]
|
||||||
H2(h2::Error),
|
H2(h2::Error),
|
||||||
|
|
||||||
|
@ -364,23 +363,23 @@ pub enum DispatchError {
|
||||||
#[display(fmt = "The first request did not complete within the specified timeout")]
|
#[display(fmt = "The first request did not complete within the specified timeout")]
|
||||||
SlowRequestTimeout,
|
SlowRequestTimeout,
|
||||||
|
|
||||||
/// Disconnect timeout. Makes sense for ssl streams.
|
/// Disconnect timeout. Makes sense for TLS streams.
|
||||||
#[display(fmt = "Connection shutdown timeout")]
|
#[display(fmt = "Connection shutdown timeout")]
|
||||||
DisconnectTimeout,
|
DisconnectTimeout,
|
||||||
|
|
||||||
/// Payload is not consumed
|
/// Payload is not consumed.
|
||||||
#[display(fmt = "Task is completed but request's payload is not consumed")]
|
#[display(fmt = "Task is completed but request's payload is not consumed")]
|
||||||
PayloadIsNotConsumed,
|
PayloadIsNotConsumed,
|
||||||
|
|
||||||
/// Malformed request
|
/// Malformed request.
|
||||||
#[display(fmt = "Malformed request")]
|
#[display(fmt = "Malformed request")]
|
||||||
MalformedRequest,
|
MalformedRequest,
|
||||||
|
|
||||||
/// Internal error
|
/// Internal error.
|
||||||
#[display(fmt = "Internal error")]
|
#[display(fmt = "Internal error")]
|
||||||
InternalError,
|
InternalError,
|
||||||
|
|
||||||
/// Unknown error
|
/// Unknown error.
|
||||||
#[display(fmt = "Unknown error")]
|
#[display(fmt = "Unknown error")]
|
||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
|
@ -426,7 +426,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
Poll::Ready(Some(Err(err))) => {
|
Poll::Ready(Some(Err(err))) => {
|
||||||
return Err(DispatchError::Body(err.into()))
|
return Err(DispatchError::ResponseBody(Box::new(err)))
|
||||||
}
|
}
|
||||||
|
|
||||||
Poll::Pending => return Ok(PollResponse::DoNothing),
|
Poll::Pending => return Ok(PollResponse::DoNothing),
|
||||||
|
@ -458,7 +458,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
Poll::Ready(Some(Err(err))) => {
|
Poll::Ready(Some(Err(err))) => {
|
||||||
return Err(DispatchError::Service(err.into()))
|
return Err(DispatchError::ResponseBody(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
Poll::Pending => return Ok(PollResponse::DoNothing),
|
Poll::Pending => return Ok(PollResponse::DoNothing),
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use std::{
|
use std::{
|
||||||
cmp,
|
cmp, fmt,
|
||||||
error::Error as StdError,
|
|
||||||
future::Future,
|
future::Future,
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
net,
|
net,
|
||||||
|
@ -14,6 +13,7 @@ use actix_rt::time::{sleep, Sleep};
|
||||||
use actix_service::Service;
|
use actix_service::Service;
|
||||||
use actix_utils::future::poll_fn;
|
use actix_utils::future::poll_fn;
|
||||||
use bytes::{Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
|
use derive_more::{Display, Error};
|
||||||
use futures_core::ready;
|
use futures_core::ready;
|
||||||
use h2::{
|
use h2::{
|
||||||
server::{Connection, SendResponse},
|
server::{Connection, SendResponse},
|
||||||
|
@ -187,10 +187,25 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Display, Error)]
|
||||||
enum DispatchError {
|
enum DispatchError {
|
||||||
|
/// Send response head failed.
|
||||||
|
#[display(fmt = "Send response head failed")]
|
||||||
SendResponse(h2::Error),
|
SendResponse(h2::Error),
|
||||||
|
|
||||||
|
/// Send response data failed.
|
||||||
|
#[display(fmt = "Send response data failed")]
|
||||||
SendData(h2::Error),
|
SendData(h2::Error),
|
||||||
ResponseBody(Box<dyn StdError>),
|
|
||||||
|
/// Receiving body chunk failed.
|
||||||
|
#[display(fmt = "Receiving body chunk failed")]
|
||||||
|
ResponseBody(#[error(not(source))] Box<dyn fmt::Debug>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DispatchError {
|
||||||
|
fn response_body<E: fmt::Debug + 'static>(err: E) -> Self {
|
||||||
|
Self::ResponseBody(Box::new(err))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_response<B>(
|
async fn handle_response<B>(
|
||||||
|
@ -221,7 +236,7 @@ where
|
||||||
actix_rt::pin!(body);
|
actix_rt::pin!(body);
|
||||||
|
|
||||||
while let Some(res) = poll_fn(|cx| body.as_mut().poll_next(cx)).await {
|
while let Some(res) = poll_fn(|cx| body.as_mut().poll_next(cx)).await {
|
||||||
let mut chunk = res.map_err(|err| DispatchError::ResponseBody(err.into()))?;
|
let mut chunk = res.map_err(DispatchError::response_body)?;
|
||||||
|
|
||||||
'send: loop {
|
'send: loop {
|
||||||
let chunk_size = cmp::min(chunk.len(), CHUNK_SIZE);
|
let chunk_size = cmp::min(chunk.len(), CHUNK_SIZE);
|
||||||
|
|
|
@ -11,8 +11,6 @@ use pin_project_lite::pin_project;
|
||||||
|
|
||||||
use actix_http::body::{BodySize, BodyStream, BoxBody, MessageBody, SizedStream};
|
use actix_http::body::{BodySize, BodyStream, BoxBody, MessageBody, SizedStream};
|
||||||
|
|
||||||
use crate::BoxError;
|
|
||||||
|
|
||||||
pin_project! {
|
pin_project! {
|
||||||
/// Represents various types of HTTP message body.
|
/// Represents various types of HTTP message body.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -117,7 +115,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AnyBodyProj::Body { body } => body.poll_next(cx).map_err(|err| err.into()),
|
AnyBodyProj::Body { body } => body
|
||||||
|
.poll_next(cx)
|
||||||
|
.map_err(|err| format!("{:?}", err).into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,7 @@ impl<B> From<BytesMut> for AnyBody<B> {
|
||||||
impl<S, E> From<SizedStream<S>> for AnyBody
|
impl<S, E> From<SizedStream<S>> for AnyBody
|
||||||
where
|
where
|
||||||
S: Stream<Item = Result<Bytes, E>> + 'static,
|
S: Stream<Item = Result<Bytes, E>> + 'static,
|
||||||
E: Into<BoxError> + 'static,
|
E: fmt::Debug + 'static,
|
||||||
{
|
{
|
||||||
fn from(stream: SizedStream<S>) -> Self {
|
fn from(stream: SizedStream<S>) -> Self {
|
||||||
AnyBody::new_boxed(stream)
|
AnyBody::new_boxed(stream)
|
||||||
|
@ -223,7 +223,7 @@ where
|
||||||
impl<S, E> From<BodyStream<S>> for AnyBody
|
impl<S, E> From<BodyStream<S>> for AnyBody
|
||||||
where
|
where
|
||||||
S: Stream<Item = Result<Bytes, E>> + 'static,
|
S: Stream<Item = Result<Bytes, E>> + 'static,
|
||||||
E: Into<BoxError> + 'static,
|
E: fmt::Debug + 'static,
|
||||||
{
|
{
|
||||||
fn from(stream: BodyStream<S>) -> Self {
|
fn from(stream: BodyStream<S>) -> Self {
|
||||||
AnyBody::new_boxed(stream)
|
AnyBody::new_boxed(stream)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{convert::TryFrom, net, rc::Rc, time::Duration};
|
use std::{convert::TryFrom, fmt, net, rc::Rc, time::Duration};
|
||||||
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use futures_core::Stream;
|
use futures_core::Stream;
|
||||||
|
@ -13,7 +13,7 @@ use actix_http::{
|
||||||
use crate::{
|
use crate::{
|
||||||
any_body::AnyBody,
|
any_body::AnyBody,
|
||||||
sender::{RequestSender, SendClientRequest},
|
sender::{RequestSender, SendClientRequest},
|
||||||
BoxError, ClientConfig,
|
ClientConfig,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// `FrozenClientRequest` struct represents cloneable client request.
|
/// `FrozenClientRequest` struct represents cloneable client request.
|
||||||
|
@ -83,7 +83,7 @@ impl FrozenClientRequest {
|
||||||
pub fn send_stream<S, E>(&self, stream: S) -> SendClientRequest
|
pub fn send_stream<S, E>(&self, stream: S) -> SendClientRequest
|
||||||
where
|
where
|
||||||
S: Stream<Item = Result<Bytes, E>> + Unpin + 'static,
|
S: Stream<Item = Result<Bytes, E>> + Unpin + 'static,
|
||||||
E: Into<BoxError> + 'static,
|
E: fmt::Debug + 'static,
|
||||||
{
|
{
|
||||||
RequestSender::Rc(self.head.clone(), None).send_stream(
|
RequestSender::Rc(self.head.clone(), None).send_stream(
|
||||||
self.addr,
|
self.addr,
|
||||||
|
@ -208,7 +208,7 @@ impl FrozenSendBuilder {
|
||||||
pub fn send_stream<S, E>(self, stream: S) -> SendClientRequest
|
pub fn send_stream<S, E>(self, stream: S) -> SendClientRequest
|
||||||
where
|
where
|
||||||
S: Stream<Item = Result<Bytes, E>> + Unpin + 'static,
|
S: Stream<Item = Result<Bytes, E>> + Unpin + 'static,
|
||||||
E: Into<BoxError> + 'static,
|
E: fmt::Debug + 'static,
|
||||||
{
|
{
|
||||||
if let Some(e) = self.err {
|
if let Some(e) = self.err {
|
||||||
return e.into();
|
return e.into();
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::{
|
||||||
error::{FreezeRequestError, InvalidUrl},
|
error::{FreezeRequestError, InvalidUrl},
|
||||||
frozen::FrozenClientRequest,
|
frozen::FrozenClientRequest,
|
||||||
sender::{PrepForSendingError, RequestSender, SendClientRequest},
|
sender::{PrepForSendingError, RequestSender, SendClientRequest},
|
||||||
BoxError, ClientConfig,
|
ClientConfig,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "cookies")]
|
#[cfg(feature = "cookies")]
|
||||||
|
@ -394,7 +394,7 @@ impl ClientRequest {
|
||||||
pub fn send_stream<S, E>(self, stream: S) -> SendClientRequest
|
pub fn send_stream<S, E>(self, stream: S) -> SendClientRequest
|
||||||
where
|
where
|
||||||
S: Stream<Item = Result<Bytes, E>> + Unpin + 'static,
|
S: Stream<Item = Result<Bytes, E>> + Unpin + 'static,
|
||||||
E: Into<BoxError> + 'static,
|
E: fmt::Debug + 'static,
|
||||||
{
|
{
|
||||||
let slf = match self.prep_for_sending() {
|
let slf = match self.prep_for_sending() {
|
||||||
Ok(slf) => slf,
|
Ok(slf) => slf,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use std::{
|
use std::{
|
||||||
|
fmt,
|
||||||
future::Future,
|
future::Future,
|
||||||
net,
|
net,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
|
@ -25,7 +26,7 @@ use actix_http::{encoding::Decoder, header::ContentEncoding, Payload, PayloadStr
|
||||||
use crate::{
|
use crate::{
|
||||||
any_body::AnyBody,
|
any_body::AnyBody,
|
||||||
error::{FreezeRequestError, InvalidUrl, SendRequestError},
|
error::{FreezeRequestError, InvalidUrl, SendRequestError},
|
||||||
BoxError, ClientConfig, ClientResponse, ConnectRequest, ConnectResponse,
|
ClientConfig, ClientResponse, ConnectRequest, ConnectResponse,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, From)]
|
#[derive(Debug, From)]
|
||||||
|
@ -275,7 +276,7 @@ impl RequestSender {
|
||||||
) -> SendClientRequest
|
) -> SendClientRequest
|
||||||
where
|
where
|
||||||
S: Stream<Item = Result<Bytes, E>> + Unpin + 'static,
|
S: Stream<Item = Result<Bytes, E>> + Unpin + 'static,
|
||||||
E: Into<BoxError> + 'static,
|
E: fmt::Debug + 'static,
|
||||||
{
|
{
|
||||||
self.send_body(
|
self.send_body(
|
||||||
addr,
|
addr,
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
//! Most users will not have to interact with the types in this module, but it is useful for those
|
//! Most users will not have to interact with the types in this module, but it is useful for those
|
||||||
//! writing extractors, middleware, libraries, or interacting with the service API directly.
|
//! writing extractors, middleware, libraries, or interacting with the service API directly.
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
pub use crate::config::{AppConfig, AppService};
|
pub use crate::config::{AppConfig, AppService};
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub use crate::handler::Handler;
|
pub use crate::handler::Handler;
|
||||||
|
@ -114,7 +116,7 @@ pub(crate) enum AnyBody {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::body::MessageBody for AnyBody {
|
impl crate::body::MessageBody for AnyBody {
|
||||||
type Error = crate::BoxError;
|
type Error = Box<dyn fmt::Debug>;
|
||||||
|
|
||||||
/// Body size hint.
|
/// Body size hint.
|
||||||
fn size(&self) -> crate::body::BodySize {
|
fn size(&self) -> crate::body::BodySize {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use std::future::Future;
|
use std::{fmt, future::Future};
|
||||||
|
|
||||||
use actix_service::{boxed, fn_service};
|
use actix_service::{boxed, fn_service};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
body::MessageBody,
|
body::MessageBody,
|
||||||
service::{BoxedHttpServiceFactory, ServiceRequest, ServiceResponse},
|
service::{BoxedHttpServiceFactory, ServiceRequest, ServiceResponse},
|
||||||
BoxError, FromRequest, HttpResponse, Responder,
|
FromRequest, HttpResponse, Responder,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A request handler is an async function that accepts zero or more parameters that can be
|
/// A request handler is an async function that accepts zero or more parameters that can be
|
||||||
|
@ -31,7 +31,7 @@ where
|
||||||
R: Future,
|
R: Future,
|
||||||
R::Output: Responder,
|
R::Output: Responder,
|
||||||
<R::Output as Responder>::Body: MessageBody,
|
<R::Output as Responder>::Body: MessageBody,
|
||||||
<<R::Output as Responder>::Body as MessageBody>::Error: Into<BoxError>,
|
<<R::Output as Responder>::Body as MessageBody>::Error: fmt::Debug,
|
||||||
{
|
{
|
||||||
boxed::factory(fn_service(move |req: ServiceRequest| {
|
boxed::factory(fn_service(move |req: ServiceRequest| {
|
||||||
let handler = handler.clone();
|
let handler = handler.clone();
|
||||||
|
|
|
@ -113,5 +113,3 @@ pub use crate::route::Route;
|
||||||
pub use crate::scope::Scope;
|
pub use crate::scope::Scope;
|
||||||
pub use crate::server::HttpServer;
|
pub use crate::server::HttpServer;
|
||||||
pub use crate::types::Either;
|
pub use crate::types::Either;
|
||||||
|
|
||||||
pub(crate) type BoxError = Box<dyn std::error::Error>;
|
|
||||||
|
|
|
@ -325,9 +325,8 @@ pin_project! {
|
||||||
impl<B> MessageBody for StreamLog<B>
|
impl<B> MessageBody for StreamLog<B>
|
||||||
where
|
where
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
B::Error: Into<Error>,
|
|
||||||
{
|
{
|
||||||
type Error = Error;
|
type Error = B::Error;
|
||||||
|
|
||||||
fn size(&self) -> BodySize {
|
fn size(&self) -> BodySize {
|
||||||
self.body.size()
|
self.body.size()
|
||||||
|
@ -344,7 +343,7 @@ where
|
||||||
*this.size += chunk.len();
|
*this.size += chunk.len();
|
||||||
Poll::Ready(Some(Ok(chunk)))
|
Poll::Ready(Some(Ok(chunk)))
|
||||||
}
|
}
|
||||||
Some(Err(err)) => Poll::Ready(Some(Err(err.into()))),
|
Some(Err(err)) => Poll::Ready(Some(Err(err))),
|
||||||
None => Poll::Ready(None),
|
None => Poll::Ready(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ use crate::{
|
||||||
BoxedHttpService, BoxedHttpServiceFactory, HttpServiceFactory, ServiceRequest,
|
BoxedHttpService, BoxedHttpServiceFactory, HttpServiceFactory, ServiceRequest,
|
||||||
ServiceResponse,
|
ServiceResponse,
|
||||||
},
|
},
|
||||||
BoxError, Error, FromRequest, HttpResponse, Responder,
|
Error, FromRequest, HttpResponse, Responder,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// *Resource* is an entry in resources table which corresponds to requested URL.
|
/// *Resource* is an entry in resources table which corresponds to requested URL.
|
||||||
|
@ -239,7 +239,7 @@ where
|
||||||
R: Future + 'static,
|
R: Future + 'static,
|
||||||
R::Output: Responder + 'static,
|
R::Output: Responder + 'static,
|
||||||
<R::Output as Responder>::Body: MessageBody,
|
<R::Output as Responder>::Body: MessageBody,
|
||||||
<<R::Output as Responder>::Body as MessageBody>::Error: Into<BoxError>,
|
<<R::Output as Responder>::Body as MessageBody>::Error: fmt::Debug,
|
||||||
{
|
{
|
||||||
self.routes.push(Route::new().to(handler));
|
self.routes.push(Route::new().to(handler));
|
||||||
self
|
self
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use std::{
|
use std::{
|
||||||
cell::{Ref, RefMut},
|
cell::{Ref, RefMut},
|
||||||
convert::TryInto,
|
convert::TryInto,
|
||||||
|
fmt,
|
||||||
future::Future,
|
future::Future,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
|
@ -23,7 +24,7 @@ use cookie::{Cookie, CookieJar};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{Error, JsonPayloadError},
|
error::{Error, JsonPayloadError},
|
||||||
BoxError, HttpResponse,
|
HttpResponse,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An HTTP response builder.
|
/// An HTTP response builder.
|
||||||
|
@ -349,7 +350,7 @@ impl HttpResponseBuilder {
|
||||||
pub fn streaming<S, E>(&mut self, stream: S) -> HttpResponse
|
pub fn streaming<S, E>(&mut self, stream: S) -> HttpResponse
|
||||||
where
|
where
|
||||||
S: Stream<Item = Result<Bytes, E>> + 'static,
|
S: Stream<Item = Result<Bytes, E>> + 'static,
|
||||||
E: Into<BoxError> + 'static,
|
E: fmt::Debug + 'static,
|
||||||
{
|
{
|
||||||
self.body(BodyStream::new(stream))
|
self.body(BodyStream::new(stream))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
use actix_http::{
|
use actix_http::{
|
||||||
body::{EitherBody, MessageBody},
|
body::{EitherBody, MessageBody},
|
||||||
error::HttpError,
|
error::HttpError,
|
||||||
|
@ -6,7 +8,7 @@ use actix_http::{
|
||||||
StatusCode,
|
StatusCode,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{BoxError, HttpRequest, HttpResponse, Responder};
|
use crate::{HttpRequest, HttpResponse, Responder};
|
||||||
|
|
||||||
/// Allows overriding status code and headers for a [`Responder`].
|
/// Allows overriding status code and headers for a [`Responder`].
|
||||||
///
|
///
|
||||||
|
@ -143,7 +145,7 @@ impl<R: Responder> CustomizeResponder<R> {
|
||||||
impl<T> Responder for CustomizeResponder<T>
|
impl<T> Responder for CustomizeResponder<T>
|
||||||
where
|
where
|
||||||
T: Responder,
|
T: Responder,
|
||||||
<T::Body as MessageBody>::Error: Into<BoxError>,
|
<T::Body as MessageBody>::Error: fmt::Debug,
|
||||||
{
|
{
|
||||||
type Body = EitherBody<T::Body>;
|
type Body = EitherBody<T::Body>;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::borrow::Cow;
|
use std::{borrow::Cow, fmt};
|
||||||
|
|
||||||
use actix_http::{
|
use actix_http::{
|
||||||
body::{BoxBody, EitherBody, MessageBody},
|
body::{BoxBody, EitherBody, MessageBody},
|
||||||
|
@ -7,7 +7,7 @@ use actix_http::{
|
||||||
};
|
};
|
||||||
use bytes::{Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
|
|
||||||
use crate::{BoxError, Error, HttpRequest, HttpResponse, HttpResponseBuilder};
|
use crate::{Error, HttpRequest, HttpResponse, HttpResponseBuilder};
|
||||||
|
|
||||||
use super::CustomizeResponder;
|
use super::CustomizeResponder;
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ impl Responder for actix_http::ResponseBuilder {
|
||||||
impl<T> Responder for Option<T>
|
impl<T> Responder for Option<T>
|
||||||
where
|
where
|
||||||
T: Responder,
|
T: Responder,
|
||||||
<T::Body as MessageBody>::Error: Into<BoxError>,
|
<T::Body as MessageBody>::Error: fmt::Debug,
|
||||||
{
|
{
|
||||||
type Body = EitherBody<T::Body>;
|
type Body = EitherBody<T::Body>;
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ where
|
||||||
impl<T, E> Responder for Result<T, E>
|
impl<T, E> Responder for Result<T, E>
|
||||||
where
|
where
|
||||||
T: Responder,
|
T: Responder,
|
||||||
<T::Body as MessageBody>::Error: Into<BoxError>,
|
<T::Body as MessageBody>::Error: fmt::Debug,
|
||||||
E: Into<Error>,
|
E: Into<Error>,
|
||||||
{
|
{
|
||||||
type Body = EitherBody<T::Body>;
|
type Body = EitherBody<T::Body>;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{future::Future, mem, rc::Rc};
|
use std::{fmt, future::Future, mem, rc::Rc};
|
||||||
|
|
||||||
use actix_http::Method;
|
use actix_http::Method;
|
||||||
use actix_service::{
|
use actix_service::{
|
||||||
|
@ -12,7 +12,7 @@ use crate::{
|
||||||
guard::{self, Guard},
|
guard::{self, Guard},
|
||||||
handler::{handler_service, Handler},
|
handler::{handler_service, Handler},
|
||||||
service::{BoxedHttpServiceFactory, ServiceRequest, ServiceResponse},
|
service::{BoxedHttpServiceFactory, ServiceRequest, ServiceResponse},
|
||||||
BoxError, Error, FromRequest, HttpResponse, Responder,
|
Error, FromRequest, HttpResponse, Responder,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Resource route definition
|
/// Resource route definition
|
||||||
|
@ -183,7 +183,7 @@ impl Route {
|
||||||
R: Future + 'static,
|
R: Future + 'static,
|
||||||
R::Output: Responder + 'static,
|
R::Output: Responder + 'static,
|
||||||
<R::Output as Responder>::Body: MessageBody,
|
<R::Output as Responder>::Body: MessageBody,
|
||||||
<<R::Output as Responder>::Body as MessageBody>::Error: Into<BoxError>,
|
<<R::Output as Responder>::Body as MessageBody>::Error: fmt::Debug,
|
||||||
{
|
{
|
||||||
self.service = handler_service(handler);
|
self.service = handler_service(handler);
|
||||||
self
|
self
|
||||||
|
|
|
@ -470,7 +470,6 @@ impl<B> From<ServiceResponse<B>> for Response<B> {
|
||||||
impl<B> fmt::Debug for ServiceResponse<B>
|
impl<B> fmt::Debug for ServiceResponse<B>
|
||||||
where
|
where
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
B::Error: Into<Error>,
|
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let res = writeln!(
|
let res = writeln!(
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Essentials helper functions and types for application registration.
|
//! Essentials helper functions and types for application registration.
|
||||||
|
|
||||||
use std::{error::Error as StdError, future::Future};
|
use std::{fmt, future::Future};
|
||||||
|
|
||||||
use actix_http::Method;
|
use actix_http::Method;
|
||||||
use actix_router::IntoPatterns;
|
use actix_router::IntoPatterns;
|
||||||
|
@ -146,7 +146,7 @@ where
|
||||||
R: Future + 'static,
|
R: Future + 'static,
|
||||||
R::Output: Responder + 'static,
|
R::Output: Responder + 'static,
|
||||||
<R::Output as Responder>::Body: MessageBody + 'static,
|
<R::Output as Responder>::Body: MessageBody + 'static,
|
||||||
<<R::Output as Responder>::Body as MessageBody>::Error: Into<Box<dyn StdError + 'static>>,
|
<<R::Output as Responder>::Body as MessageBody>::Error: fmt::Debug,
|
||||||
{
|
{
|
||||||
Route::new().to(handler)
|
Route::new().to(handler)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue