mirror of
https://github.com/actix/actix-web.git
synced 2024-12-30 12:00:38 +00:00
remove unpin from body types (#2152)
This commit is contained in:
parent
ce50cc9523
commit
edd9f14752
19 changed files with 241 additions and 194 deletions
|
@ -1,6 +1,14 @@
|
|||
# Changes
|
||||
|
||||
## Unreleased - 2021-xx-xx
|
||||
### Added
|
||||
* `impl<T: MessageBody> MessageBody for Pin<Box<T>>`. [#2152]
|
||||
|
||||
### Changes
|
||||
* The type parameter of `Response` no longer has a default. [#2152]
|
||||
* The `Message` variant of `body::Body` is now `Pin<Box<dyn MessageBody>>`. [#2152]
|
||||
* `BodyStream` and `SizedStream` are no longer restricted to Unpin types. [#2152]
|
||||
|
||||
### Removed
|
||||
* `cookies` feature flag. [#2065]
|
||||
* Top-level `cookies` mod (re-export). [#2065]
|
||||
|
@ -13,6 +21,7 @@
|
|||
|
||||
[#2065]: https://github.com/actix/actix-web/pull/2065
|
||||
[#2148]: https://github.com/actix/actix-web/pull/2148
|
||||
[#2152]: https://github.com/actix/actix-web/pull/2152
|
||||
|
||||
|
||||
## 3.0.0-beta.5 - 2021-04-02
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use std::{env, io};
|
||||
|
||||
use actix_http::http::HeaderValue;
|
||||
use actix_http::{body::Body, http::HeaderValue};
|
||||
use actix_http::{Error, HttpService, Request, Response};
|
||||
use actix_server::Server;
|
||||
use bytes::BytesMut;
|
||||
use futures_util::StreamExt as _;
|
||||
use log::info;
|
||||
|
||||
async fn handle_request(mut req: Request) -> Result<Response, Error> {
|
||||
async fn handle_request(mut req: Request) -> Result<Response<Body>, Error> {
|
||||
let mut body = BytesMut::new();
|
||||
while let Some(item) = req.payload().next().await {
|
||||
body.extend_from_slice(&item?)
|
||||
|
|
|
@ -12,15 +12,19 @@ use crate::error::Error;
|
|||
use super::{BodySize, BodyStream, MessageBody, SizedStream};
|
||||
|
||||
/// Represents various types of HTTP message body.
|
||||
// #[deprecated(since = "4.0.0", note = "Use body types directly.")]
|
||||
pub enum Body {
|
||||
/// Empty response. `Content-Length` header is not set.
|
||||
None,
|
||||
|
||||
/// Zero sized response body. `Content-Length` header is set to `0`.
|
||||
Empty,
|
||||
|
||||
/// Specific response body.
|
||||
Bytes(Bytes),
|
||||
|
||||
/// Generic message body.
|
||||
Message(Box<dyn MessageBody + Unpin>),
|
||||
Message(Pin<Box<dyn MessageBody>>),
|
||||
}
|
||||
|
||||
impl Body {
|
||||
|
@ -30,8 +34,8 @@ impl Body {
|
|||
}
|
||||
|
||||
/// Create body from generic message body.
|
||||
pub fn from_message<B: MessageBody + Unpin + 'static>(body: B) -> Body {
|
||||
Body::Message(Box::new(body))
|
||||
pub fn from_message<B: MessageBody + 'static>(body: B) -> Body {
|
||||
Body::Message(Box::pin(body))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,7 +64,7 @@ impl MessageBody for Body {
|
|||
Poll::Ready(Some(Ok(mem::take(bin))))
|
||||
}
|
||||
}
|
||||
Body::Message(body) => Pin::new(&mut **body).poll_next(cx),
|
||||
Body::Message(body) => body.as_mut().poll_next(cx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -134,7 +138,7 @@ impl From<BytesMut> for Body {
|
|||
|
||||
impl<S> From<SizedStream<S>> for Body
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, Error>> + Unpin + 'static,
|
||||
S: Stream<Item = Result<Bytes, Error>> + 'static,
|
||||
{
|
||||
fn from(s: SizedStream<S>) -> Body {
|
||||
Body::from_message(s)
|
||||
|
@ -143,7 +147,7 @@ where
|
|||
|
||||
impl<S, E> From<BodyStream<S>> for Body
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, E>> + Unpin + 'static,
|
||||
S: Stream<Item = Result<Bytes, E>> + 'static,
|
||||
E: Into<Error> + 'static,
|
||||
{
|
||||
fn from(s: BodyStream<S>) -> Body {
|
||||
|
|
|
@ -5,21 +5,25 @@ use std::{
|
|||
|
||||
use bytes::Bytes;
|
||||
use futures_core::{ready, Stream};
|
||||
use pin_project_lite::pin_project;
|
||||
|
||||
use crate::error::Error;
|
||||
|
||||
use super::{BodySize, MessageBody};
|
||||
|
||||
/// Streaming response wrapper.
|
||||
///
|
||||
/// Response does not contain `Content-Length` header and appropriate transfer encoding is used.
|
||||
pub struct BodyStream<S: Unpin> {
|
||||
stream: S,
|
||||
pin_project! {
|
||||
/// Streaming response wrapper.
|
||||
///
|
||||
/// Response does not contain `Content-Length` header and appropriate transfer encoding is used.
|
||||
pub struct BodyStream<S> {
|
||||
#[pin]
|
||||
stream: S,
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, E> BodyStream<S>
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, E>> + Unpin,
|
||||
S: Stream<Item = Result<Bytes, E>>,
|
||||
E: Into<Error>,
|
||||
{
|
||||
pub fn new(stream: S) -> Self {
|
||||
|
@ -29,7 +33,7 @@ where
|
|||
|
||||
impl<S, E> MessageBody for BodyStream<S>
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, E>> + Unpin,
|
||||
S: Stream<Item = Result<Bytes, E>>,
|
||||
E: Into<Error>,
|
||||
{
|
||||
fn size(&self) -> BodySize {
|
||||
|
@ -46,9 +50,9 @@ where
|
|||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
loop {
|
||||
let stream = &mut self.as_mut().stream;
|
||||
let stream = self.as_mut().project().stream;
|
||||
|
||||
let chunk = match ready!(Pin::new(stream).poll_next(cx)) {
|
||||
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)),
|
||||
};
|
||||
|
|
|
@ -52,6 +52,19 @@ impl<T: MessageBody + Unpin> MessageBody for Box<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: MessageBody> MessageBody for Pin<Box<T>> {
|
||||
fn size(&self) -> BodySize {
|
||||
self.as_ref().size()
|
||||
}
|
||||
|
||||
fn poll_next(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
self.as_mut().poll_next(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl MessageBody for Bytes {
|
||||
fn size(&self) -> BodySize {
|
||||
BodySize::Sized(self.len() as u64)
|
||||
|
|
|
@ -5,23 +5,27 @@ use std::{
|
|||
|
||||
use bytes::Bytes;
|
||||
use futures_core::{ready, Stream};
|
||||
use pin_project_lite::pin_project;
|
||||
|
||||
use crate::error::Error;
|
||||
|
||||
use super::{BodySize, MessageBody};
|
||||
|
||||
/// 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.
|
||||
pub struct SizedStream<S: Unpin> {
|
||||
size: u64,
|
||||
stream: S,
|
||||
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.
|
||||
pub struct SizedStream<S> {
|
||||
size: u64,
|
||||
#[pin]
|
||||
stream: S,
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> SizedStream<S>
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, Error>> + Unpin,
|
||||
S: Stream<Item = Result<Bytes, Error>>,
|
||||
{
|
||||
pub fn new(size: u64, stream: S) -> Self {
|
||||
SizedStream { size, stream }
|
||||
|
@ -30,7 +34,7 @@ where
|
|||
|
||||
impl<S> MessageBody for SizedStream<S>
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, Error>> + Unpin,
|
||||
S: Stream<Item = Result<Bytes, Error>>,
|
||||
{
|
||||
fn size(&self) -> BodySize {
|
||||
BodySize::Sized(self.size as u64)
|
||||
|
@ -46,9 +50,9 @@ where
|
|||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
loop {
|
||||
let stream = &mut self.as_mut().stream;
|
||||
let stream = self.as_mut().project().stream;
|
||||
|
||||
let chunk = match ready!(Pin::new(stream).poll_next(cx)) {
|
||||
let chunk = match ready!(stream.poll_next(cx)) {
|
||||
Some(Ok(ref bytes)) if bytes.is_empty() => continue,
|
||||
val => val,
|
||||
};
|
||||
|
|
|
@ -92,7 +92,7 @@ impl<B: MessageBody> Encoder<B> {
|
|||
enum EncoderBody<B> {
|
||||
Bytes(Bytes),
|
||||
Stream(#[pin] B),
|
||||
BoxedStream(Box<dyn MessageBody + Unpin>),
|
||||
BoxedStream(Pin<Box<dyn MessageBody>>),
|
||||
}
|
||||
|
||||
impl<B: MessageBody> MessageBody for EncoderBody<B> {
|
||||
|
@ -117,9 +117,7 @@ impl<B: MessageBody> MessageBody for EncoderBody<B> {
|
|||
}
|
||||
}
|
||||
EncoderBodyProj::Stream(b) => b.poll_next(cx),
|
||||
EncoderBodyProj::BoxedStream(ref mut b) => {
|
||||
Pin::new(b.as_mut()).poll_next(cx)
|
||||
}
|
||||
EncoderBodyProj::BoxedStream(ref mut b) => b.as_mut().poll_next(cx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ pub trait ResponseError: fmt::Debug + fmt::Display {
|
|||
/// Create response for error
|
||||
///
|
||||
/// Internal server error is generated by default.
|
||||
fn error_response(&self) -> Response {
|
||||
fn error_response(&self) -> Response<Body> {
|
||||
let mut resp = Response::new(self.status_code());
|
||||
let mut buf = BytesMut::new();
|
||||
let _ = write!(Writer(&mut buf), "{}", self);
|
||||
|
@ -111,7 +111,7 @@ impl From<std::convert::Infallible> for Error {
|
|||
}
|
||||
|
||||
/// Convert `Error` to a `Response` instance
|
||||
impl From<Error> for Response {
|
||||
impl From<Error> for Response<Body> {
|
||||
fn from(err: Error) -> Self {
|
||||
Response::from_error(err)
|
||||
}
|
||||
|
@ -127,8 +127,8 @@ impl<T: ResponseError + 'static> From<T> for Error {
|
|||
}
|
||||
|
||||
/// Convert Response to a Error
|
||||
impl From<Response> for Error {
|
||||
fn from(res: Response) -> Error {
|
||||
impl From<Response<Body>> for Error {
|
||||
fn from(res: Response<Body>) -> Error {
|
||||
InternalError::from_response("", res).into()
|
||||
}
|
||||
}
|
||||
|
@ -454,7 +454,7 @@ pub struct InternalError<T> {
|
|||
|
||||
enum InternalErrorType {
|
||||
Status(StatusCode),
|
||||
Response(RefCell<Option<Response>>),
|
||||
Response(RefCell<Option<Response<Body>>>),
|
||||
}
|
||||
|
||||
impl<T> InternalError<T> {
|
||||
|
@ -467,7 +467,7 @@ impl<T> InternalError<T> {
|
|||
}
|
||||
|
||||
/// Create `InternalError` with predefined `Response`.
|
||||
pub fn from_response(cause: T, response: Response) -> Self {
|
||||
pub fn from_response(cause: T, response: Response<Body>) -> Self {
|
||||
InternalError {
|
||||
cause,
|
||||
status: InternalErrorType::Response(RefCell::new(Some(response))),
|
||||
|
@ -510,7 +510,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn error_response(&self) -> Response {
|
||||
fn error_response(&self) -> Response<Body> {
|
||||
match self.status {
|
||||
InternalErrorType::Status(st) => {
|
||||
let mut res = Response::new(st);
|
||||
|
@ -931,11 +931,11 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_into_response() {
|
||||
let resp: Response = ParseError::Incomplete.error_response();
|
||||
let resp: Response<Body> = ParseError::Incomplete.error_response();
|
||||
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||
|
||||
let err: HttpError = StatusCode::from_u16(10000).err().unwrap().into();
|
||||
let resp: Response = err.error_response();
|
||||
let resp: Response<Body> = err.error_response();
|
||||
assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
|
@ -966,7 +966,7 @@ mod tests {
|
|||
fn test_error_http_response() {
|
||||
let orig = io::Error::new(io::ErrorKind::Other, "other");
|
||||
let e = Error::from(orig);
|
||||
let resp: Response = e.into();
|
||||
let resp: Response<Body> = e.into();
|
||||
assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
|
@ -1023,7 +1023,7 @@ mod tests {
|
|||
fn test_internal_error() {
|
||||
let err =
|
||||
InternalError::from_response(ParseError::Method, Response::Ok().into());
|
||||
let resp: Response = err.error_response();
|
||||
let resp: Response<Body> = err.error_response();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
|
@ -1039,121 +1039,121 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_error_helpers() {
|
||||
let r: Response = ErrorBadRequest("err").into();
|
||||
assert_eq!(r.status(), StatusCode::BAD_REQUEST);
|
||||
let res: Response<Body> = ErrorBadRequest("err").into();
|
||||
assert_eq!(res.status(), StatusCode::BAD_REQUEST);
|
||||
|
||||
let r: Response = ErrorUnauthorized("err").into();
|
||||
assert_eq!(r.status(), StatusCode::UNAUTHORIZED);
|
||||
let res: Response<Body> = ErrorUnauthorized("err").into();
|
||||
assert_eq!(res.status(), StatusCode::UNAUTHORIZED);
|
||||
|
||||
let r: Response = ErrorPaymentRequired("err").into();
|
||||
assert_eq!(r.status(), StatusCode::PAYMENT_REQUIRED);
|
||||
let res: Response<Body> = ErrorPaymentRequired("err").into();
|
||||
assert_eq!(res.status(), StatusCode::PAYMENT_REQUIRED);
|
||||
|
||||
let r: Response = ErrorForbidden("err").into();
|
||||
assert_eq!(r.status(), StatusCode::FORBIDDEN);
|
||||
let res: Response<Body> = ErrorForbidden("err").into();
|
||||
assert_eq!(res.status(), StatusCode::FORBIDDEN);
|
||||
|
||||
let r: Response = ErrorNotFound("err").into();
|
||||
assert_eq!(r.status(), StatusCode::NOT_FOUND);
|
||||
let res: Response<Body> = ErrorNotFound("err").into();
|
||||
assert_eq!(res.status(), StatusCode::NOT_FOUND);
|
||||
|
||||
let r: Response = ErrorMethodNotAllowed("err").into();
|
||||
assert_eq!(r.status(), StatusCode::METHOD_NOT_ALLOWED);
|
||||
let res: Response<Body> = ErrorMethodNotAllowed("err").into();
|
||||
assert_eq!(res.status(), StatusCode::METHOD_NOT_ALLOWED);
|
||||
|
||||
let r: Response = ErrorNotAcceptable("err").into();
|
||||
assert_eq!(r.status(), StatusCode::NOT_ACCEPTABLE);
|
||||
let res: Response<Body> = ErrorNotAcceptable("err").into();
|
||||
assert_eq!(res.status(), StatusCode::NOT_ACCEPTABLE);
|
||||
|
||||
let r: Response = ErrorProxyAuthenticationRequired("err").into();
|
||||
assert_eq!(r.status(), StatusCode::PROXY_AUTHENTICATION_REQUIRED);
|
||||
let res: Response<Body> = ErrorProxyAuthenticationRequired("err").into();
|
||||
assert_eq!(res.status(), StatusCode::PROXY_AUTHENTICATION_REQUIRED);
|
||||
|
||||
let r: Response = ErrorRequestTimeout("err").into();
|
||||
assert_eq!(r.status(), StatusCode::REQUEST_TIMEOUT);
|
||||
let res: Response<Body> = ErrorRequestTimeout("err").into();
|
||||
assert_eq!(res.status(), StatusCode::REQUEST_TIMEOUT);
|
||||
|
||||
let r: Response = ErrorConflict("err").into();
|
||||
assert_eq!(r.status(), StatusCode::CONFLICT);
|
||||
let res: Response<Body> = ErrorConflict("err").into();
|
||||
assert_eq!(res.status(), StatusCode::CONFLICT);
|
||||
|
||||
let r: Response = ErrorGone("err").into();
|
||||
assert_eq!(r.status(), StatusCode::GONE);
|
||||
let res: Response<Body> = ErrorGone("err").into();
|
||||
assert_eq!(res.status(), StatusCode::GONE);
|
||||
|
||||
let r: Response = ErrorLengthRequired("err").into();
|
||||
assert_eq!(r.status(), StatusCode::LENGTH_REQUIRED);
|
||||
let res: Response<Body> = ErrorLengthRequired("err").into();
|
||||
assert_eq!(res.status(), StatusCode::LENGTH_REQUIRED);
|
||||
|
||||
let r: Response = ErrorPreconditionFailed("err").into();
|
||||
assert_eq!(r.status(), StatusCode::PRECONDITION_FAILED);
|
||||
let res: Response<Body> = ErrorPreconditionFailed("err").into();
|
||||
assert_eq!(res.status(), StatusCode::PRECONDITION_FAILED);
|
||||
|
||||
let r: Response = ErrorPayloadTooLarge("err").into();
|
||||
assert_eq!(r.status(), StatusCode::PAYLOAD_TOO_LARGE);
|
||||
let res: Response<Body> = ErrorPayloadTooLarge("err").into();
|
||||
assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE);
|
||||
|
||||
let r: Response = ErrorUriTooLong("err").into();
|
||||
assert_eq!(r.status(), StatusCode::URI_TOO_LONG);
|
||||
let res: Response<Body> = ErrorUriTooLong("err").into();
|
||||
assert_eq!(res.status(), StatusCode::URI_TOO_LONG);
|
||||
|
||||
let r: Response = ErrorUnsupportedMediaType("err").into();
|
||||
assert_eq!(r.status(), StatusCode::UNSUPPORTED_MEDIA_TYPE);
|
||||
let res: Response<Body> = ErrorUnsupportedMediaType("err").into();
|
||||
assert_eq!(res.status(), StatusCode::UNSUPPORTED_MEDIA_TYPE);
|
||||
|
||||
let r: Response = ErrorRangeNotSatisfiable("err").into();
|
||||
assert_eq!(r.status(), StatusCode::RANGE_NOT_SATISFIABLE);
|
||||
let res: Response<Body> = ErrorRangeNotSatisfiable("err").into();
|
||||
assert_eq!(res.status(), StatusCode::RANGE_NOT_SATISFIABLE);
|
||||
|
||||
let r: Response = ErrorExpectationFailed("err").into();
|
||||
assert_eq!(r.status(), StatusCode::EXPECTATION_FAILED);
|
||||
let res: Response<Body> = ErrorExpectationFailed("err").into();
|
||||
assert_eq!(res.status(), StatusCode::EXPECTATION_FAILED);
|
||||
|
||||
let r: Response = ErrorImATeapot("err").into();
|
||||
assert_eq!(r.status(), StatusCode::IM_A_TEAPOT);
|
||||
let res: Response<Body> = ErrorImATeapot("err").into();
|
||||
assert_eq!(res.status(), StatusCode::IM_A_TEAPOT);
|
||||
|
||||
let r: Response = ErrorMisdirectedRequest("err").into();
|
||||
assert_eq!(r.status(), StatusCode::MISDIRECTED_REQUEST);
|
||||
let res: Response<Body> = ErrorMisdirectedRequest("err").into();
|
||||
assert_eq!(res.status(), StatusCode::MISDIRECTED_REQUEST);
|
||||
|
||||
let r: Response = ErrorUnprocessableEntity("err").into();
|
||||
assert_eq!(r.status(), StatusCode::UNPROCESSABLE_ENTITY);
|
||||
let res: Response<Body> = ErrorUnprocessableEntity("err").into();
|
||||
assert_eq!(res.status(), StatusCode::UNPROCESSABLE_ENTITY);
|
||||
|
||||
let r: Response = ErrorLocked("err").into();
|
||||
assert_eq!(r.status(), StatusCode::LOCKED);
|
||||
let res: Response<Body> = ErrorLocked("err").into();
|
||||
assert_eq!(res.status(), StatusCode::LOCKED);
|
||||
|
||||
let r: Response = ErrorFailedDependency("err").into();
|
||||
assert_eq!(r.status(), StatusCode::FAILED_DEPENDENCY);
|
||||
let res: Response<Body> = ErrorFailedDependency("err").into();
|
||||
assert_eq!(res.status(), StatusCode::FAILED_DEPENDENCY);
|
||||
|
||||
let r: Response = ErrorUpgradeRequired("err").into();
|
||||
assert_eq!(r.status(), StatusCode::UPGRADE_REQUIRED);
|
||||
let res: Response<Body> = ErrorUpgradeRequired("err").into();
|
||||
assert_eq!(res.status(), StatusCode::UPGRADE_REQUIRED);
|
||||
|
||||
let r: Response = ErrorPreconditionRequired("err").into();
|
||||
assert_eq!(r.status(), StatusCode::PRECONDITION_REQUIRED);
|
||||
let res: Response<Body> = ErrorPreconditionRequired("err").into();
|
||||
assert_eq!(res.status(), StatusCode::PRECONDITION_REQUIRED);
|
||||
|
||||
let r: Response = ErrorTooManyRequests("err").into();
|
||||
assert_eq!(r.status(), StatusCode::TOO_MANY_REQUESTS);
|
||||
let res: Response<Body> = ErrorTooManyRequests("err").into();
|
||||
assert_eq!(res.status(), StatusCode::TOO_MANY_REQUESTS);
|
||||
|
||||
let r: Response = ErrorRequestHeaderFieldsTooLarge("err").into();
|
||||
assert_eq!(r.status(), StatusCode::REQUEST_HEADER_FIELDS_TOO_LARGE);
|
||||
let res: Response<Body> = ErrorRequestHeaderFieldsTooLarge("err").into();
|
||||
assert_eq!(res.status(), StatusCode::REQUEST_HEADER_FIELDS_TOO_LARGE);
|
||||
|
||||
let r: Response = ErrorUnavailableForLegalReasons("err").into();
|
||||
assert_eq!(r.status(), StatusCode::UNAVAILABLE_FOR_LEGAL_REASONS);
|
||||
let res: Response<Body> = ErrorUnavailableForLegalReasons("err").into();
|
||||
assert_eq!(res.status(), StatusCode::UNAVAILABLE_FOR_LEGAL_REASONS);
|
||||
|
||||
let r: Response = ErrorInternalServerError("err").into();
|
||||
assert_eq!(r.status(), StatusCode::INTERNAL_SERVER_ERROR);
|
||||
let res: Response<Body> = ErrorInternalServerError("err").into();
|
||||
assert_eq!(res.status(), StatusCode::INTERNAL_SERVER_ERROR);
|
||||
|
||||
let r: Response = ErrorNotImplemented("err").into();
|
||||
assert_eq!(r.status(), StatusCode::NOT_IMPLEMENTED);
|
||||
let res: Response<Body> = ErrorNotImplemented("err").into();
|
||||
assert_eq!(res.status(), StatusCode::NOT_IMPLEMENTED);
|
||||
|
||||
let r: Response = ErrorBadGateway("err").into();
|
||||
assert_eq!(r.status(), StatusCode::BAD_GATEWAY);
|
||||
let res: Response<Body> = ErrorBadGateway("err").into();
|
||||
assert_eq!(res.status(), StatusCode::BAD_GATEWAY);
|
||||
|
||||
let r: Response = ErrorServiceUnavailable("err").into();
|
||||
assert_eq!(r.status(), StatusCode::SERVICE_UNAVAILABLE);
|
||||
let res: Response<Body> = ErrorServiceUnavailable("err").into();
|
||||
assert_eq!(res.status(), StatusCode::SERVICE_UNAVAILABLE);
|
||||
|
||||
let r: Response = ErrorGatewayTimeout("err").into();
|
||||
assert_eq!(r.status(), StatusCode::GATEWAY_TIMEOUT);
|
||||
let res: Response<Body> = ErrorGatewayTimeout("err").into();
|
||||
assert_eq!(res.status(), StatusCode::GATEWAY_TIMEOUT);
|
||||
|
||||
let r: Response = ErrorHttpVersionNotSupported("err").into();
|
||||
assert_eq!(r.status(), StatusCode::HTTP_VERSION_NOT_SUPPORTED);
|
||||
let res: Response<Body> = ErrorHttpVersionNotSupported("err").into();
|
||||
assert_eq!(res.status(), StatusCode::HTTP_VERSION_NOT_SUPPORTED);
|
||||
|
||||
let r: Response = ErrorVariantAlsoNegotiates("err").into();
|
||||
assert_eq!(r.status(), StatusCode::VARIANT_ALSO_NEGOTIATES);
|
||||
let res: Response<Body> = ErrorVariantAlsoNegotiates("err").into();
|
||||
assert_eq!(res.status(), StatusCode::VARIANT_ALSO_NEGOTIATES);
|
||||
|
||||
let r: Response = ErrorInsufficientStorage("err").into();
|
||||
assert_eq!(r.status(), StatusCode::INSUFFICIENT_STORAGE);
|
||||
let res: Response<Body> = ErrorInsufficientStorage("err").into();
|
||||
assert_eq!(res.status(), StatusCode::INSUFFICIENT_STORAGE);
|
||||
|
||||
let r: Response = ErrorLoopDetected("err").into();
|
||||
assert_eq!(r.status(), StatusCode::LOOP_DETECTED);
|
||||
let res: Response<Body> = ErrorLoopDetected("err").into();
|
||||
assert_eq!(res.status(), StatusCode::LOOP_DETECTED);
|
||||
|
||||
let r: Response = ErrorNotExtended("err").into();
|
||||
assert_eq!(r.status(), StatusCode::NOT_EXTENDED);
|
||||
let res: Response<Body> = ErrorNotExtended("err").into();
|
||||
assert_eq!(res.status(), StatusCode::NOT_EXTENDED);
|
||||
|
||||
let r: Response = ErrorNetworkAuthenticationRequired("err").into();
|
||||
assert_eq!(r.status(), StatusCode::NETWORK_AUTHENTICATION_REQUIRED);
|
||||
let res: Response<Body> = ErrorNetworkAuthenticationRequired("err").into();
|
||||
assert_eq!(res.status(), StatusCode::NETWORK_AUTHENTICATION_REQUIRED);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -407,7 +407,7 @@ where
|
|||
}
|
||||
// send expect error as response
|
||||
Poll::Ready(Err(err)) => {
|
||||
let res: Response = err.into().into();
|
||||
let res = Response::from_error(err.into());
|
||||
let (res, body) = res.replace_body(());
|
||||
self.as_mut().send_response(res, body.into_body())?;
|
||||
}
|
||||
|
@ -456,8 +456,7 @@ where
|
|||
// to notify the dispatcher a new state is set and the outer loop
|
||||
// should be continue.
|
||||
Poll::Ready(Err(err)) => {
|
||||
let err = err.into();
|
||||
let res: Response = err.into();
|
||||
let res = Response::from_error(err.into());
|
||||
let (res, body) = res.replace_body(());
|
||||
return self.send_response(res, body.into_body());
|
||||
}
|
||||
|
@ -477,7 +476,7 @@ where
|
|||
Poll::Pending => Ok(()),
|
||||
// see the comment on ExpectCall state branch's Ready(Err(err)).
|
||||
Poll::Ready(Err(err)) => {
|
||||
let res: Response = err.into().into();
|
||||
let res = Response::from_error(err.into());
|
||||
let (res, body) = res.replace_body(());
|
||||
self.send_response(res, body.into_body())
|
||||
}
|
||||
|
@ -979,19 +978,20 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
fn ok_service() -> impl Service<Request, Response = Response, Error = Error> {
|
||||
fn ok_service() -> impl Service<Request, Response = Response<Body>, Error = Error> {
|
||||
fn_service(|_req: Request| ready(Ok::<_, Error>(Response::Ok().finish())))
|
||||
}
|
||||
|
||||
fn echo_path_service() -> impl Service<Request, Response = Response, Error = Error> {
|
||||
fn echo_path_service(
|
||||
) -> impl Service<Request, Response = Response<Body>, Error = Error> {
|
||||
fn_service(|req: Request| {
|
||||
let path = req.path().as_bytes();
|
||||
ready(Ok::<_, Error>(Response::Ok().body(Body::from_slice(path))))
|
||||
})
|
||||
}
|
||||
|
||||
fn echo_payload_service() -> impl Service<Request, Response = Response, Error = Error>
|
||||
{
|
||||
fn echo_payload_service(
|
||||
) -> impl Service<Request, Response = Response<Body>, Error = Error> {
|
||||
fn_service(|mut req: Request| {
|
||||
Box::pin(async move {
|
||||
use futures_util::stream::StreamExt as _;
|
||||
|
|
|
@ -252,8 +252,8 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
Err(e) => {
|
||||
let res: Response = e.into().into();
|
||||
Err(err) => {
|
||||
let res = Response::from_error(err.into());
|
||||
let (res, body) = res.replace_body(());
|
||||
|
||||
let mut send = send.take().unwrap();
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
|
||||
use http::StatusCode;
|
||||
|
||||
use crate::response::{Response, ResponseBuilder};
|
||||
use crate::{
|
||||
body::Body,
|
||||
response::{Response, ResponseBuilder},
|
||||
};
|
||||
|
||||
macro_rules! static_resp {
|
||||
($name:ident, $status:expr) => {
|
||||
|
@ -15,7 +18,7 @@ macro_rules! static_resp {
|
|||
};
|
||||
}
|
||||
|
||||
impl Response {
|
||||
impl Response<Body> {
|
||||
static_resp!(Continue, StatusCode::CONTINUE);
|
||||
static_resp!(SwitchingProtocols, StatusCode::SWITCHING_PROTOCOLS);
|
||||
static_resp!(Processing, StatusCode::PROCESSING);
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
//! | `openssl` | TLS support via [OpenSSL]. |
|
||||
//! | `rustls` | TLS support via [rustls]. |
|
||||
//! | `compress` | Payload compression support. (Deflate, Gzip & Brotli) |
|
||||
//! | `secure-cookies` | Adds for secure cookies. Enables `cookies` feature. |
|
||||
//! | `trust-dns` | Use [trust-dns] as the client DNS resolver. |
|
||||
//!
|
||||
//! [OpenSSL]: https://crates.io/crates/openssl
|
||||
|
|
|
@ -22,7 +22,7 @@ use crate::{
|
|||
};
|
||||
|
||||
/// An HTTP Response
|
||||
pub struct Response<B = Body> {
|
||||
pub struct Response<B> {
|
||||
head: BoxedResponseHead,
|
||||
body: ResponseBody<B>,
|
||||
error: Option<Error>,
|
||||
|
@ -43,7 +43,7 @@ impl Response<Body> {
|
|||
|
||||
/// Constructs a response
|
||||
#[inline]
|
||||
pub fn new(status: StatusCode) -> Response {
|
||||
pub fn new(status: StatusCode) -> Response<Body> {
|
||||
Response {
|
||||
head: BoxedResponseHead::new(status),
|
||||
body: ResponseBody::Body(Body::Empty),
|
||||
|
@ -53,7 +53,7 @@ impl Response<Body> {
|
|||
|
||||
/// Constructs an error response
|
||||
#[inline]
|
||||
pub fn from_error(error: Error) -> Response {
|
||||
pub fn from_error(error: Error) -> Response<Body> {
|
||||
let mut resp = error.as_response_error().error_response();
|
||||
if resp.head.status == StatusCode::INTERNAL_SERVER_ERROR {
|
||||
error!("Internal Server Error: {:?}", error);
|
||||
|
@ -238,8 +238,8 @@ impl<B: MessageBody> fmt::Debug for Response<B> {
|
|||
}
|
||||
}
|
||||
|
||||
impl Future for Response {
|
||||
type Output = Result<Response, Error>;
|
||||
impl<B: Unpin> Future for Response<B> {
|
||||
type Output = Result<Response<B>, Error>;
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
Poll::Ready(Ok(Response {
|
||||
|
@ -421,7 +421,7 @@ impl ResponseBuilder {
|
|||
///
|
||||
/// `ResponseBuilder` can not be used after this call.
|
||||
#[inline]
|
||||
pub fn body<B: Into<Body>>(&mut self, body: B) -> Response {
|
||||
pub fn body<B: Into<Body>>(&mut self, body: B) -> Response<Body> {
|
||||
self.message_body(body.into())
|
||||
}
|
||||
|
||||
|
@ -446,7 +446,7 @@ impl ResponseBuilder {
|
|||
///
|
||||
/// `ResponseBuilder` can not be used after this call.
|
||||
#[inline]
|
||||
pub fn streaming<S, E>(&mut self, stream: S) -> Response
|
||||
pub fn streaming<S, E>(&mut self, stream: S) -> Response<Body>
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, E>> + Unpin + 'static,
|
||||
E: Into<Error> + 'static,
|
||||
|
@ -458,7 +458,7 @@ impl ResponseBuilder {
|
|||
///
|
||||
/// `ResponseBuilder` can not be used after this call.
|
||||
#[inline]
|
||||
pub fn finish(&mut self) -> Response {
|
||||
pub fn finish(&mut self) -> Response<Body> {
|
||||
self.body(Body::Empty)
|
||||
}
|
||||
|
||||
|
@ -513,7 +513,7 @@ impl<'a> From<&'a ResponseHead> for ResponseBuilder {
|
|||
}
|
||||
|
||||
impl Future for ResponseBuilder {
|
||||
type Output = Result<Response, Error>;
|
||||
type Output = Result<Response<Body>, Error>;
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
Poll::Ready(Ok(self.finish()))
|
||||
|
@ -540,7 +540,7 @@ impl fmt::Debug for ResponseBuilder {
|
|||
}
|
||||
|
||||
/// Helper converters
|
||||
impl<I: Into<Response>, E: Into<Error>> From<Result<I, E>> for Response {
|
||||
impl<I: Into<Response<Body>>, E: Into<Error>> From<Result<I, E>> for Response<Body> {
|
||||
fn from(res: Result<I, E>) -> Self {
|
||||
match res {
|
||||
Ok(val) => val.into(),
|
||||
|
@ -549,13 +549,13 @@ impl<I: Into<Response>, E: Into<Error>> From<Result<I, E>> for Response {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<ResponseBuilder> for Response {
|
||||
impl From<ResponseBuilder> for Response<Body> {
|
||||
fn from(mut builder: ResponseBuilder) -> Self {
|
||||
builder.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&'static str> for Response {
|
||||
impl From<&'static str> for Response<Body> {
|
||||
fn from(val: &'static str) -> Self {
|
||||
Response::Ok()
|
||||
.content_type(mime::TEXT_PLAIN_UTF_8)
|
||||
|
@ -563,7 +563,7 @@ impl From<&'static str> for Response {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<&'static [u8]> for Response {
|
||||
impl From<&'static [u8]> for Response<Body> {
|
||||
fn from(val: &'static [u8]) -> Self {
|
||||
Response::Ok()
|
||||
.content_type(mime::APPLICATION_OCTET_STREAM)
|
||||
|
@ -571,7 +571,7 @@ impl From<&'static [u8]> for Response {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<String> for Response {
|
||||
impl From<String> for Response<Body> {
|
||||
fn from(val: String) -> Self {
|
||||
Response::Ok()
|
||||
.content_type(mime::TEXT_PLAIN_UTF_8)
|
||||
|
@ -579,7 +579,7 @@ impl From<String> for Response {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a String> for Response {
|
||||
impl<'a> From<&'a String> for Response<Body> {
|
||||
fn from(val: &'a String) -> Self {
|
||||
Response::Ok()
|
||||
.content_type(mime::TEXT_PLAIN_UTF_8)
|
||||
|
@ -587,7 +587,7 @@ impl<'a> From<&'a String> for Response {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<Bytes> for Response {
|
||||
impl From<Bytes> for Response<Body> {
|
||||
fn from(val: Bytes) -> Self {
|
||||
Response::Ok()
|
||||
.content_type(mime::APPLICATION_OCTET_STREAM)
|
||||
|
@ -595,7 +595,7 @@ impl From<Bytes> for Response {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<BytesMut> for Response {
|
||||
impl From<BytesMut> for Response<Body> {
|
||||
fn from(val: BytesMut) -> Self {
|
||||
Response::Ok()
|
||||
.content_type(mime::APPLICATION_OCTET_STREAM)
|
||||
|
@ -653,7 +653,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_into_response() {
|
||||
let resp: Response = "test".into();
|
||||
let resp: Response<Body> = "test".into();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
assert_eq!(
|
||||
resp.headers().get(CONTENT_TYPE).unwrap(),
|
||||
|
@ -662,7 +662,7 @@ mod tests {
|
|||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
assert_eq!(resp.body().get_ref(), b"test");
|
||||
|
||||
let resp: Response = b"test".as_ref().into();
|
||||
let resp: Response<Body> = b"test".as_ref().into();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
assert_eq!(
|
||||
resp.headers().get(CONTENT_TYPE).unwrap(),
|
||||
|
@ -671,7 +671,7 @@ mod tests {
|
|||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
assert_eq!(resp.body().get_ref(), b"test");
|
||||
|
||||
let resp: Response = "test".to_owned().into();
|
||||
let resp: Response<Body> = "test".to_owned().into();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
assert_eq!(
|
||||
resp.headers().get(CONTENT_TYPE).unwrap(),
|
||||
|
@ -680,7 +680,7 @@ mod tests {
|
|||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
assert_eq!(resp.body().get_ref(), b"test");
|
||||
|
||||
let resp: Response = (&"test".to_owned()).into();
|
||||
let resp: Response<Body> = (&"test".to_owned()).into();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
assert_eq!(
|
||||
resp.headers().get(CONTENT_TYPE).unwrap(),
|
||||
|
@ -690,7 +690,7 @@ mod tests {
|
|||
assert_eq!(resp.body().get_ref(), b"test");
|
||||
|
||||
let b = Bytes::from_static(b"test");
|
||||
let resp: Response = b.into();
|
||||
let resp: Response<Body> = b.into();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
assert_eq!(
|
||||
resp.headers().get(CONTENT_TYPE).unwrap(),
|
||||
|
@ -700,7 +700,7 @@ mod tests {
|
|||
assert_eq!(resp.body().get_ref(), b"test");
|
||||
|
||||
let b = Bytes::from_static(b"test");
|
||||
let resp: Response = b.into();
|
||||
let resp: Response<Body> = b.into();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
assert_eq!(
|
||||
resp.headers().get(CONTENT_TYPE).unwrap(),
|
||||
|
@ -710,7 +710,7 @@ mod tests {
|
|||
assert_eq!(resp.body().get_ref(), b"test");
|
||||
|
||||
let b = BytesMut::from("test");
|
||||
let resp: Response = b.into();
|
||||
let resp: Response<Body> = b.into();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
assert_eq!(
|
||||
resp.headers().get(CONTENT_TYPE).unwrap(),
|
||||
|
@ -723,7 +723,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_into_builder() {
|
||||
let mut resp: Response = "test".into();
|
||||
let mut resp: Response<Body> = "test".into();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
|
||||
resp.headers_mut().insert(
|
||||
|
|
|
@ -9,8 +9,8 @@ use derive_more::{Display, Error, From};
|
|||
use http::{header, Method, StatusCode};
|
||||
|
||||
use crate::{
|
||||
error::ResponseError, header::HeaderValue, message::RequestHead, response::Response,
|
||||
ResponseBuilder,
|
||||
body::Body, error::ResponseError, header::HeaderValue, message::RequestHead,
|
||||
response::Response, ResponseBuilder,
|
||||
};
|
||||
|
||||
mod codec;
|
||||
|
@ -99,7 +99,7 @@ pub enum HandshakeError {
|
|||
}
|
||||
|
||||
impl ResponseError for HandshakeError {
|
||||
fn error_response(&self) -> Response {
|
||||
fn error_response(&self) -> Response<Body> {
|
||||
match self {
|
||||
HandshakeError::GetMethodRequired => Response::MethodNotAllowed()
|
||||
.insert_header((header::ALLOW, "GET"))
|
||||
|
@ -320,17 +320,17 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_wserror_http_response() {
|
||||
let resp: Response = HandshakeError::GetMethodRequired.error_response();
|
||||
let resp = HandshakeError::GetMethodRequired.error_response();
|
||||
assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
|
||||
let resp: Response = HandshakeError::NoWebsocketUpgrade.error_response();
|
||||
let resp = HandshakeError::NoWebsocketUpgrade.error_response();
|
||||
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||
let resp: Response = HandshakeError::NoConnectionUpgrade.error_response();
|
||||
let resp = HandshakeError::NoConnectionUpgrade.error_response();
|
||||
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||
let resp: Response = HandshakeError::NoVersionHeader.error_response();
|
||||
let resp = HandshakeError::NoVersionHeader.error_response();
|
||||
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||
let resp: Response = HandshakeError::UnsupportedVersion.error_response();
|
||||
let resp = HandshakeError::UnsupportedVersion.error_response();
|
||||
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||
let resp: Response = HandshakeError::BadWebsocketKey.error_response();
|
||||
let resp = HandshakeError::BadWebsocketKey.error_response();
|
||||
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,11 +4,15 @@ extern crate tls_openssl as openssl;
|
|||
|
||||
use std::io;
|
||||
|
||||
use actix_http::error::{ErrorBadRequest, PayloadError};
|
||||
use actix_http::http::header::{self, HeaderName, HeaderValue};
|
||||
use actix_http::http::{Method, StatusCode, Version};
|
||||
use actix_http::HttpMessage;
|
||||
use actix_http::{body, Error, HttpService, Request, Response};
|
||||
use actix_http::{
|
||||
body::{Body, SizedStream},
|
||||
error::{ErrorBadRequest, PayloadError},
|
||||
http::{
|
||||
header::{self, HeaderName, HeaderValue},
|
||||
Method, StatusCode, Version,
|
||||
},
|
||||
Error, HttpMessage, HttpService, Request, Response,
|
||||
};
|
||||
use actix_http_test::test_server;
|
||||
use actix_service::{fn_service, ServiceFactoryExt};
|
||||
use actix_utils::future::{err, ok, ready};
|
||||
|
@ -328,7 +332,7 @@ async fn test_h2_body_length() {
|
|||
.h2(|_| {
|
||||
let body = once(ok(Bytes::from_static(STR.as_ref())));
|
||||
ok::<_, ()>(
|
||||
Response::Ok().body(body::SizedStream::new(STR.len() as u64, body)),
|
||||
Response::Ok().body(SizedStream::new(STR.len() as u64, body)),
|
||||
)
|
||||
})
|
||||
.openssl(tls_config())
|
||||
|
@ -401,7 +405,7 @@ async fn test_h2_response_http_error_handling() {
|
|||
async fn test_h2_service_error() {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|_| err::<Response, Error>(ErrorBadRequest("error")))
|
||||
.h2(|_| err::<Response<Body>, Error>(ErrorBadRequest("error")))
|
||||
.openssl(tls_config())
|
||||
.map_err(|_| ())
|
||||
})
|
||||
|
|
|
@ -2,10 +2,15 @@
|
|||
|
||||
extern crate tls_rustls as rustls;
|
||||
|
||||
use actix_http::error::PayloadError;
|
||||
use actix_http::http::header::{self, HeaderName, HeaderValue};
|
||||
use actix_http::http::{Method, StatusCode, Version};
|
||||
use actix_http::{body, error, Error, HttpService, Request, Response};
|
||||
use actix_http::{
|
||||
body::{Body, SizedStream},
|
||||
error::{self, PayloadError},
|
||||
http::{
|
||||
header::{self, HeaderName, HeaderValue},
|
||||
Method, StatusCode, Version,
|
||||
},
|
||||
Error, HttpService, Request, Response,
|
||||
};
|
||||
use actix_http_test::test_server;
|
||||
use actix_service::{fn_factory_with_config, fn_service};
|
||||
use actix_utils::future::{err, ok};
|
||||
|
@ -344,7 +349,7 @@ async fn test_h2_body_length() {
|
|||
.h2(|_| {
|
||||
let body = once(ok(Bytes::from_static(STR.as_ref())));
|
||||
ok::<_, ()>(
|
||||
Response::Ok().body(body::SizedStream::new(STR.len() as u64, body)),
|
||||
Response::Ok().body(SizedStream::new(STR.len() as u64, body)),
|
||||
)
|
||||
})
|
||||
.rustls(tls_config())
|
||||
|
@ -416,7 +421,7 @@ async fn test_h2_response_http_error_handling() {
|
|||
async fn test_h2_service_error() {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h2(|_| err::<Response, Error>(error::ErrorBadRequest("error")))
|
||||
.h2(|_| err::<Response<Body>, Error>(error::ErrorBadRequest("error")))
|
||||
.rustls(tls_config())
|
||||
})
|
||||
.await;
|
||||
|
@ -433,7 +438,7 @@ async fn test_h2_service_error() {
|
|||
async fn test_h1_service_error() {
|
||||
let mut srv = test_server(move || {
|
||||
HttpService::build()
|
||||
.h1(|_| err::<Response, Error>(error::ErrorBadRequest("error")))
|
||||
.h1(|_| err::<Response<Body>, Error>(error::ErrorBadRequest("error")))
|
||||
.rustls(tls_config())
|
||||
})
|
||||
.await;
|
||||
|
|
|
@ -13,7 +13,10 @@ use regex::Regex;
|
|||
|
||||
use actix_http::HttpMessage;
|
||||
use actix_http::{
|
||||
body, error, http, http::header, Error, HttpService, KeepAlive, Request, Response,
|
||||
body::{Body, SizedStream},
|
||||
error, http,
|
||||
http::header,
|
||||
Error, HttpService, KeepAlive, Request, Response,
|
||||
};
|
||||
|
||||
#[actix_rt::test]
|
||||
|
@ -539,7 +542,7 @@ async fn test_h1_body_length() {
|
|||
.h1(|_| {
|
||||
let body = once(ok(Bytes::from_static(STR.as_ref())));
|
||||
ok::<_, ()>(
|
||||
Response::Ok().body(body::SizedStream::new(STR.len() as u64, body)),
|
||||
Response::Ok().body(SizedStream::new(STR.len() as u64, body)),
|
||||
)
|
||||
})
|
||||
.tcp()
|
||||
|
@ -646,7 +649,7 @@ async fn test_h1_response_http_error_handling() {
|
|||
async fn test_h1_service_error() {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.h1(|_| err::<Response, _>(error::ErrorBadRequest("error")))
|
||||
.h1(|_| err::<Response<Body>, _>(error::ErrorBadRequest("error")))
|
||||
.tcp()
|
||||
})
|
||||
.await;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::fmt;
|
||||
|
||||
use actix_http::{
|
||||
body::Body,
|
||||
error::InternalError,
|
||||
http::{header::IntoHeaderPair, Error as HttpError, HeaderMap, StatusCode},
|
||||
};
|
||||
|
@ -65,7 +66,7 @@ impl Responder for HttpResponse {
|
|||
}
|
||||
}
|
||||
|
||||
impl Responder for actix_http::Response {
|
||||
impl Responder for actix_http::Response<Body> {
|
||||
#[inline]
|
||||
fn respond_to(self, _: &HttpRequest) -> HttpResponse {
|
||||
HttpResponse::from(self)
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::{
|
|||
convert::TryInto,
|
||||
fmt,
|
||||
future::Future,
|
||||
mem,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
@ -287,18 +288,17 @@ impl<B> From<HttpResponse<B>> for Response<B> {
|
|||
}
|
||||
|
||||
impl Future for HttpResponse {
|
||||
type Output = Result<Response, Error>;
|
||||
type Output = Result<Response<Body>, Error>;
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
if let Some(err) = self.error.take() {
|
||||
eprintln!("httpresponse future error");
|
||||
return Poll::Ready(Ok(Response::from_error(err).into_body()));
|
||||
}
|
||||
|
||||
let res = &mut self.res;
|
||||
actix_rt::pin!(res);
|
||||
|
||||
res.poll(cx)
|
||||
Poll::Ready(Ok(mem::replace(
|
||||
&mut self.res,
|
||||
Response::new(StatusCode::default()),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -680,7 +680,7 @@ impl From<HttpResponseBuilder> for HttpResponse {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<HttpResponseBuilder> for Response {
|
||||
impl From<HttpResponseBuilder> for Response<Body> {
|
||||
fn from(mut builder: HttpResponseBuilder) -> Self {
|
||||
builder.finish().into()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue