mirror of https://github.com/fafhrd91/actix-web
change stream type errors
This commit is contained in:
parent
18106170ce
commit
ea6f0cd49a
|
@ -11,6 +11,7 @@
|
|||
* `ServiceResponse::take_body`. [#2201]
|
||||
* `ServiceResponse::map_body` closure receives and returns `B` instead of `ResponseBody<B>` types. [#2201]
|
||||
* All error trait bounds in server service builders have changed from `Into<Error>` to `Into<Response<AnyBody>>`. [#2224]
|
||||
* All error trait bounds in message body and stream impls changed from `Into<Error>` to `Into<Box<dyn std::error::Error>>`. [#2224]
|
||||
|
||||
### Removed
|
||||
* `HttpResponse::take_body` and old `HttpResponse::into_body` method that casted body type. [#2201]
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
### Changed
|
||||
* The `MessageBody` trait now has an associated `Error` type. [#2183]
|
||||
* All error trait bounds in server service builders have changed from `Into<Error>` to `Into<Response<AnyBody>>`. [#2224]
|
||||
* All error trait bounds in message body and stream impls changed from `Into<Error>` to `Into<Box<dyn std::error::Error>>`. [#2224]
|
||||
* Places in `Response` where `ResponseBody<B>` was received or returned now simply use `B`. [#2201]
|
||||
* `header` mod is now public. [#2171]
|
||||
* `uri` mod is now public. [#2171]
|
||||
|
|
|
@ -174,7 +174,7 @@ where
|
|||
impl<S, E> From<BodyStream<S>> for AnyBody
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, E>> + 'static,
|
||||
E: Into<Error> + 'static,
|
||||
E: Into<Box<dyn StdError>> + 'static,
|
||||
{
|
||||
fn from(s: BodyStream<S>) -> Body {
|
||||
AnyBody::from_message(s)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::{
|
||||
error::Error as StdError,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
@ -7,8 +8,6 @@ use bytes::Bytes;
|
|||
use futures_core::{ready, Stream};
|
||||
use pin_project_lite::pin_project;
|
||||
|
||||
use crate::error::Error;
|
||||
|
||||
use super::{BodySize, MessageBody};
|
||||
|
||||
pin_project! {
|
||||
|
@ -24,7 +23,7 @@ pin_project! {
|
|||
impl<S, E> BodyStream<S>
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, E>>,
|
||||
E: Into<Error>,
|
||||
E: Into<Box<dyn StdError>> + 'static,
|
||||
{
|
||||
pub fn new(stream: S) -> Self {
|
||||
BodyStream { stream }
|
||||
|
@ -34,9 +33,9 @@ where
|
|||
impl<S, E> MessageBody for BodyStream<S>
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, E>>,
|
||||
E: Into<Error>,
|
||||
E: Into<Box<dyn StdError>> + 'static,
|
||||
{
|
||||
type Error = Error;
|
||||
type Error = E;
|
||||
|
||||
fn size(&self) -> BodySize {
|
||||
BodySize::Stream
|
||||
|
@ -56,7 +55,7 @@ where
|
|||
|
||||
let chunk = match ready!(stream.poll_next(cx)) {
|
||||
Some(Ok(ref bytes)) if bytes.is_empty() => continue,
|
||||
opt => opt.map(|res| res.map_err(Into::into)),
|
||||
opt => opt,
|
||||
};
|
||||
|
||||
return Poll::Ready(chunk);
|
||||
|
@ -66,6 +65,8 @@ where
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::convert::Infallible;
|
||||
|
||||
use actix_rt::pin;
|
||||
use actix_utils::future::poll_fn;
|
||||
use futures_util::stream;
|
||||
|
@ -78,7 +79,7 @@ mod tests {
|
|||
let body = BodyStream::new(stream::iter(
|
||||
["1", "", "2"]
|
||||
.iter()
|
||||
.map(|&v| Ok(Bytes::from(v)) as Result<Bytes, ()>),
|
||||
.map(|&v| Ok::<_, Infallible>(Bytes::from(v))),
|
||||
));
|
||||
pin!(body);
|
||||
|
||||
|
@ -103,7 +104,7 @@ mod tests {
|
|||
let body = BodyStream::new(stream::iter(
|
||||
["1", "", "2"]
|
||||
.iter()
|
||||
.map(|&v| Ok(Bytes::from(v)) as Result<Bytes, ()>),
|
||||
.map(|&v| Ok::<_, Infallible>(Bytes::from(v))),
|
||||
));
|
||||
|
||||
assert_eq!(to_bytes(body).await.ok(), Some(Bytes::from("12")));
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::{
|
||||
error::Error as StdError,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
@ -7,15 +8,13 @@ use bytes::Bytes;
|
|||
use futures_core::{ready, Stream};
|
||||
use pin_project_lite::pin_project;
|
||||
|
||||
use crate::error::Error;
|
||||
|
||||
use super::{BodySize, MessageBody};
|
||||
|
||||
pin_project! {
|
||||
/// Known sized streaming response wrapper.
|
||||
///
|
||||
/// This body implementation should be used if total size of stream is known. Data get sent as is
|
||||
/// without using transfer encoding.
|
||||
/// This body implementation should be used if total size of stream is known. Data is sent as-is
|
||||
/// without using chunked transfer encoding.
|
||||
pub struct SizedStream<S> {
|
||||
size: u64,
|
||||
#[pin]
|
||||
|
@ -23,20 +22,22 @@ pin_project! {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S> SizedStream<S>
|
||||
impl<S, E> SizedStream<S>
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, Error>>,
|
||||
S: Stream<Item = Result<Bytes, E>>,
|
||||
E: Into<Box<dyn StdError>> + 'static,
|
||||
{
|
||||
pub fn new(size: u64, stream: S) -> Self {
|
||||
SizedStream { size, stream }
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> MessageBody for SizedStream<S>
|
||||
impl<S, E> MessageBody for SizedStream<S>
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, Error>>,
|
||||
S: Stream<Item = Result<Bytes, E>>,
|
||||
E: Into<Box<dyn StdError>> + 'static,
|
||||
{
|
||||
type Error = Error;
|
||||
type Error = E;
|
||||
|
||||
fn size(&self) -> BodySize {
|
||||
BodySize::Sized(self.size as u64)
|
||||
|
@ -66,6 +67,8 @@ where
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::convert::Infallible;
|
||||
|
||||
use actix_rt::pin;
|
||||
use actix_utils::future::poll_fn;
|
||||
use futures_util::stream;
|
||||
|
@ -77,7 +80,11 @@ mod tests {
|
|||
async fn skips_empty_chunks() {
|
||||
let body = SizedStream::new(
|
||||
2,
|
||||
stream::iter(["1", "", "2"].iter().map(|&v| Ok(Bytes::from(v)))),
|
||||
stream::iter(
|
||||
["1", "", "2"]
|
||||
.iter()
|
||||
.map(|&v| Ok::<_, Infallible>(Bytes::from(v))),
|
||||
),
|
||||
);
|
||||
|
||||
pin!(body);
|
||||
|
@ -103,7 +110,11 @@ mod tests {
|
|||
async fn read_to_bytes() {
|
||||
let body = SizedStream::new(
|
||||
2,
|
||||
stream::iter(["1", "", "2"].iter().map(|&v| Ok(Bytes::from(v)))),
|
||||
stream::iter(
|
||||
["1", "", "2"]
|
||||
.iter()
|
||||
.map(|&v| Ok::<_, Infallible>(Bytes::from(v))),
|
||||
),
|
||||
);
|
||||
|
||||
assert_eq!(to_bytes(body).await.ok(), Some(Bytes::from("12")));
|
||||
|
|
|
@ -90,7 +90,7 @@ impl fmt::Debug for Error {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {
|
||||
impl StdError for Error {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use std::{
|
||||
cell::{Ref, RefMut},
|
||||
error::Error as StdError,
|
||||
fmt,
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
|
@ -259,7 +260,7 @@ impl ResponseBuilder {
|
|||
pub fn streaming<S, E>(&mut self, stream: S) -> Response<Body>
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, E>> + 'static,
|
||||
E: Into<Error> + 'static,
|
||||
E: Into<Box<dyn StdError>> + 'static,
|
||||
{
|
||||
self.body(Body::from_message(BodyStream::new(stream)))
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
extern crate tls_openssl as openssl;
|
||||
|
||||
use std::io;
|
||||
use std::{convert::Infallible, io};
|
||||
|
||||
use actix_http::{
|
||||
body::{AnyBody, Body, SizedStream},
|
||||
|
@ -330,9 +330,12 @@ async fn test_h2_head_binary2() {
|
|||
async fn test_h2_body_length() {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|_| {
|
||||
let body = once(ok(Bytes::from_static(STR.as_ref())));
|
||||
ok::<_, ()>(
|
||||
.h2(|_| async {
|
||||
let body = once(async {
|
||||
Ok::<_, Infallible>(Bytes::from_static(STR.as_ref()))
|
||||
});
|
||||
|
||||
Ok::<_, Infallible>(
|
||||
Response::ok().set_body(SizedStream::new(STR.len() as u64, body)),
|
||||
)
|
||||
})
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
|
||||
extern crate tls_rustls as rustls;
|
||||
|
||||
use std::{
|
||||
convert::Infallible,
|
||||
io::{self, BufReader},
|
||||
};
|
||||
|
||||
use actix_http::{
|
||||
body::{AnyBody, Body, SizedStream},
|
||||
error::PayloadError,
|
||||
|
@ -23,8 +28,6 @@ use rustls::{
|
|||
NoClientAuth, ServerConfig as RustlsServerConfig,
|
||||
};
|
||||
|
||||
use std::io::{self, BufReader};
|
||||
|
||||
async fn load_body<S>(mut stream: S) -> Result<BytesMut, PayloadError>
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, PayloadError>> + Unpin,
|
||||
|
@ -347,7 +350,7 @@ async fn test_h2_body_length() {
|
|||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|_| {
|
||||
let body = once(ok(Bytes::from_static(STR.as_ref())));
|
||||
let body = once(ok::<_, Infallible>(Bytes::from_static(STR.as_ref())));
|
||||
ok::<_, ()>(
|
||||
Response::ok().set_body(SizedStream::new(STR.len() as u64, body)),
|
||||
)
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
use std::io::{Read, Write};
|
||||
use std::time::Duration;
|
||||
use std::{net, thread};
|
||||
use std::{
|
||||
convert::Infallible,
|
||||
io::{Read, Write},
|
||||
net, thread,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use actix_http::{
|
||||
body::{AnyBody, Body, SizedStream},
|
||||
|
@ -557,7 +560,7 @@ async fn test_h1_body_length() {
|
|||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.h1(|_| {
|
||||
let body = once(ok(Bytes::from_static(STR.as_ref())));
|
||||
let body = once(ok::<_, Infallible>(Bytes::from_static(STR.as_ref())));
|
||||
ok::<_, ()>(
|
||||
Response::ok().set_body(SizedStream::new(STR.len() as u64, body)),
|
||||
)
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
use std::convert::TryFrom;
|
||||
use std::net;
|
||||
use std::rc::Rc;
|
||||
use std::time::Duration;
|
||||
use std::{convert::TryFrom, error::Error as StdError, net, rc::Rc, time::Duration};
|
||||
|
||||
use bytes::Bytes;
|
||||
use futures_core::Stream;
|
||||
use serde::Serialize;
|
||||
|
||||
use actix_http::body::Body;
|
||||
use actix_http::http::header::IntoHeaderValue;
|
||||
use actix_http::http::{Error as HttpError, HeaderMap, HeaderName, Method, Uri};
|
||||
use actix_http::{Error, RequestHead};
|
||||
use actix_http::{
|
||||
body::Body,
|
||||
http::{header::IntoHeaderValue, Error as HttpError, HeaderMap, HeaderName, Method, Uri},
|
||||
RequestHead,
|
||||
};
|
||||
|
||||
use crate::sender::{RequestSender, SendClientRequest};
|
||||
use crate::ClientConfig;
|
||||
use crate::{
|
||||
sender::{RequestSender, SendClientRequest},
|
||||
ClientConfig,
|
||||
};
|
||||
|
||||
/// `FrozenClientRequest` struct represents clonable client request.
|
||||
/// `FrozenClientRequest` struct represents cloneable client request.
|
||||
/// It could be used to send same request multiple times.
|
||||
#[derive(Clone)]
|
||||
pub struct FrozenClientRequest {
|
||||
|
@ -82,7 +82,7 @@ impl FrozenClientRequest {
|
|||
pub fn send_stream<S, E>(&self, stream: S) -> SendClientRequest
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, E>> + Unpin + 'static,
|
||||
E: Into<Error> + 'static,
|
||||
E: Into<Box<dyn StdError>> + 'static,
|
||||
{
|
||||
RequestSender::Rc(self.head.clone(), None).send_stream(
|
||||
self.addr,
|
||||
|
@ -207,7 +207,7 @@ impl FrozenSendBuilder {
|
|||
pub fn send_stream<S, E>(self, stream: S) -> SendClientRequest
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, E>> + Unpin + 'static,
|
||||
E: Into<Error> + 'static,
|
||||
E: Into<Box<dyn StdError>> + 'static,
|
||||
{
|
||||
if let Some(e) = self.err {
|
||||
return e.into();
|
||||
|
|
|
@ -1,25 +1,26 @@
|
|||
use std::convert::TryFrom;
|
||||
use std::rc::Rc;
|
||||
use std::time::Duration;
|
||||
use std::{fmt, net};
|
||||
use std::{convert::TryFrom, error::Error as StdError, fmt, net, rc::Rc, time::Duration};
|
||||
|
||||
use bytes::Bytes;
|
||||
use futures_core::Stream;
|
||||
use serde::Serialize;
|
||||
|
||||
use actix_http::body::Body;
|
||||
use actix_http::http::header::{self, IntoHeaderPair};
|
||||
use actix_http::http::{
|
||||
use actix_http::{
|
||||
body::Body,
|
||||
http::{
|
||||
header::{self, IntoHeaderPair},
|
||||
uri, ConnectionType, Error as HttpError, HeaderMap, HeaderValue, Method, Uri, Version,
|
||||
},
|
||||
RequestHead,
|
||||
};
|
||||
use actix_http::{Error, RequestHead};
|
||||
|
||||
#[cfg(feature = "cookies")]
|
||||
use crate::cookie::{Cookie, CookieJar};
|
||||
use crate::error::{FreezeRequestError, InvalidUrl};
|
||||
use crate::frozen::FrozenClientRequest;
|
||||
use crate::sender::{PrepForSendingError, RequestSender, SendClientRequest};
|
||||
use crate::ClientConfig;
|
||||
use crate::{
|
||||
error::{FreezeRequestError, InvalidUrl},
|
||||
frozen::FrozenClientRequest,
|
||||
sender::{PrepForSendingError, RequestSender, SendClientRequest},
|
||||
ClientConfig,
|
||||
};
|
||||
|
||||
#[cfg(feature = "compress")]
|
||||
const HTTPS_ENCODING: &str = "br, gzip, deflate";
|
||||
|
@ -408,7 +409,7 @@ impl ClientRequest {
|
|||
pub fn send_stream<S, E>(self, stream: S) -> SendClientRequest
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, E>> + Unpin + 'static,
|
||||
E: Into<Error> + 'static,
|
||||
E: Into<Box<dyn StdError>> + 'static,
|
||||
{
|
||||
let slf = match self.prep_for_sending() {
|
||||
Ok(slf) => slf,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::{
|
||||
error::Error as StdError,
|
||||
future::Future,
|
||||
io, net,
|
||||
pin::Pin,
|
||||
|
@ -266,7 +267,7 @@ impl RequestSender {
|
|||
) -> SendClientRequest
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, E>> + Unpin + 'static,
|
||||
E: Into<Error> + 'static,
|
||||
E: Into<Box<dyn StdError>> + 'static,
|
||||
{
|
||||
self.send_body(
|
||||
addr,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::{
|
||||
cell::{Ref, RefMut},
|
||||
convert::TryInto,
|
||||
error::Error as StdError,
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
|
@ -354,7 +355,7 @@ impl HttpResponseBuilder {
|
|||
pub fn streaming<S, E>(&mut self, stream: S) -> HttpResponse
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, E>> + Unpin + 'static,
|
||||
E: Into<Error> + 'static,
|
||||
E: Into<Box<dyn StdError>> + 'static,
|
||||
{
|
||||
self.body(Body::from_message(BodyStream::new(stream)))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue