Skip to main content

object_storage_proxy/utils/
response.rs

1use bytes::Bytes;
2use http::StatusCode;
3use pingora::Result;
4use pingora::http::ResponseHeader;
5use pingora::proxy::Session;
6use tracing::debug;
7
8const DEFAULT_SERVER_NAME: &str = "<osp⚡>";
9
10/// Write a plain-text HTTP error response to the downstream client.
11///
12/// Sets `Content-Type: text/plain`, `X-Content-Type-Options: nosniff`, and a
13/// custom `Server` header before sending `msg` as the response body.
14///
15/// Always returns `Ok(true)` so callers can do
16/// `return write_error_response_with_header(…).await?;`
17/// from within a `request_filter` implementation.
18pub async fn write_error_response_with_header(
19    session: &mut Session,
20    status_code: StatusCode,
21    msg: String,
22) -> Result<bool> {
23    let mut hdr = ResponseHeader::build(status_code, None)?;
24    hdr.insert_header("Content-Type", "text/plain")?;
25    hdr.insert_header("Server", DEFAULT_SERVER_NAME)?;
26    hdr.insert_header("X-Content-Type-Options", "nosniff")?;
27
28    session.write_response_header(Box::new(hdr), false).await?;
29
30    session
31        .write_response_body(Some(Bytes::copy_from_slice(msg.as_bytes())), false)
32        .await?;
33
34    session
35        .respond_error_with_body(status_code.as_u16(), msg.clone().into())
36        .await?;
37    debug!(status = status_code.as_u16(), msg, "wrote error response");
38    Ok(true)
39}