use http::header;
use pingora::{http::ResponseHeader, proxy::Session};
use super::https_proxy::RouterContext;
pub async fn respond(
session: &mut Session,
ctx: &mut RouterContext,
mut response: ResponseHeader,
) -> pingora::Result<()> {
response_blocks(session, &mut response, ctx).await;
session.write_response_header(Box::new(response), true).await
}
async fn response_blocks(
session: &mut Session,
response: &mut ResponseHeader,
ctx: &mut RouterContext,
) {
if let Some(location) = ctx.route_container.clone() {
location.blocks.response(session, response, ctx).await;
}
crate::rules::response(session, response, ctx).await;
}
pub async fn respond_error(
session: &mut Session,
ctx: &mut RouterContext,
code: u16,
) -> pingora::Result<()> {
session.set_keepalive(None);
if session
.response_written()
.is_some_and(|written| !written.status.is_informational() || written.status == 101)
{
return Ok(());
}
respond(session, ctx, error_response(code)?).await
}
fn error_response(code: u16) -> pingora::Result<ResponseHeader> {
let mut response = ResponseHeader::build(code, Some(2))?;
response.insert_header(header::CONTENT_LENGTH, "0")?;
response.insert_header(header::CACHE_CONTROL, "private, no-store")?;
Ok(response)
}
pub async fn respond_with_body(
session: &mut Session,
ctx: &mut RouterContext,
mut response: ResponseHeader,
body: bytes::Bytes,
) -> pingora::Result<()> {
response_blocks(session, &mut response, ctx).await;
response.insert_header(header::CONTENT_LENGTH, body.len())?;
let end = body.is_empty();
session.write_response_header(Box::new(response), end).await?;
if !end {
session.write_response_body(Some(body), true).await?;
}
Ok(())
}