use super::{
super::{
super::{
std::{error::*, immutable::*},
transcoding::*,
},
headers::*,
},
body::*,
};
use {http::*, http_body::*};
pub trait IntoTranscodingResponse<BodyT>
where
Self: Sized,
BodyT: Body,
BodyT::Error: Into<CapturedError>,
{
fn with_transcoding_body_passthrough(self) -> Response<TranscodingBody<BodyT>> {
self.with_transcoding_body_passthrough_with_first_bytes(None)
}
fn with_transcoding_body_passthrough_with_first_bytes(
self,
first_bytes: Option<ImmutableBytes>,
) -> Response<TranscodingBody<BodyT>>;
fn with_transcoding_body(
self,
encoding: &Encoding,
encodable_by_default: bool,
) -> Response<TranscodingBody<BodyT>> {
self.with_transcoding_body_with_first_bytes(None, encoding, encodable_by_default)
}
fn with_transcoding_body_with_first_bytes(
self,
first_bytes: Option<ImmutableBytes>,
encoding: &Encoding,
encodable_by_default: bool,
) -> Response<TranscodingBody<BodyT>>;
}
impl<BodyT> IntoTranscodingResponse<BodyT> for Response<BodyT>
where
BodyT: Body,
BodyT::Error: Into<CapturedError>,
{
fn with_transcoding_body_passthrough_with_first_bytes(
self,
first_bytes: Option<ImmutableBytes>,
) -> Response<TranscodingBody<BodyT>> {
let (mut parts, body) = self.into_parts();
parts.headers.remove(XX_ENCODE);
parts.headers.remove(XX_CACHE);
Response::from_parts(parts, body.into_transcoding_passthrough_with_first_bytes(first_bytes))
}
fn with_transcoding_body_with_first_bytes(
self,
first_bytes: Option<ImmutableBytes>,
encoding: &Encoding,
encodable_by_default: bool,
) -> Response<TranscodingBody<BodyT>> {
if *encoding == Encoding::Identity {
return self.with_transcoding_body_passthrough_with_first_bytes(first_bytes);
}
let (mut parts, body) = self.into_parts();
let encode = parts.headers.xx_encode(encodable_by_default);
parts.headers.remove(XX_CACHE);
parts.headers.remove(XX_ENCODE);
if !encode {
tracing::debug!("not encoding to {} ({}=false)", encoding, XX_ENCODE);
return Response::from_parts(parts, body.into_transcoding_passthrough_with_first_bytes(first_bytes));
}
let current_encoding = parts.headers.content_encoding().into();
if *encoding == current_encoding {
tracing::debug!("already encoded as {}", encoding);
return Response::from_parts(parts, body.into_transcoding_passthrough_with_first_bytes(first_bytes));
}
if current_encoding != Encoding::Identity {
tracing::debug!("not reencoding from {} to {})", current_encoding, encoding);
return Response::from_parts(parts, body.into_transcoding_passthrough_with_first_bytes(first_bytes));
}
parts.headers.set_into_header_value(CONTENT_ENCODING, encoding.clone());
parts.headers.remove(CONTENT_LENGTH);
parts.headers.remove(CONTENT_DIGEST);
Response::from_parts(parts, body.into_encoding_with_first_bytes(first_bytes, encoding))
}
}
pub fn error_transcoding_response<BodyT>() -> Response<TranscodingBody<BodyT>>
where
BodyT: Body + From<ImmutableBytes>,
BodyT::Error: Into<CapturedError>,
{
let mut response =
Response::new(ImmutableBytes::default().into()).with_transcoding_body_passthrough_with_first_bytes(None);
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
response
}
pub fn not_modified_transcoding_response<BodyT>() -> Response<TranscodingBody<BodyT>>
where
BodyT: Body + From<ImmutableBytes>,
BodyT::Error: Into<CapturedError>,
{
let mut response =
Response::new(ImmutableBytes::default().into()).with_transcoding_body_passthrough_with_first_bytes(None);
*response.status_mut() = StatusCode::NOT_MODIFIED;
response
}