LCOV - code coverage report
Current view: top level - proxy/src/serverless - http_util.rs (source / functions) Coverage Total Hit
Test: 49aa928ec5b4b510172d8b5c6d154da28e70a46c.info Lines: 0.0 % 71 0
Test Date: 2024-11-13 18:23:39 Functions: 0.0 % 11 0

            Line data    Source code
       1              : //! Things stolen from `libs/utils/src/http` to add hyper 1.0 compatibility
       2              : //! Will merge back in at some point in the future.
       3              : 
       4              : use anyhow::Context;
       5              : use bytes::Bytes;
       6              : use http::{Response, StatusCode};
       7              : use http_body_util::combinators::BoxBody;
       8              : use http_body_util::{BodyExt, Full};
       9              : use serde::Serialize;
      10              : use utils::http::error::ApiError;
      11              : 
      12              : /// Like [`ApiError::into_response`]
      13            0 : pub(crate) fn api_error_into_response(this: ApiError) -> Response<BoxBody<Bytes, hyper::Error>> {
      14            0 :     match this {
      15            0 :         ApiError::BadRequest(err) => HttpErrorBody::response_from_msg_and_status(
      16            0 :             format!("{err:#?}"), // use debug printing so that we give the cause
      17            0 :             StatusCode::BAD_REQUEST,
      18            0 :         ),
      19              :         ApiError::Forbidden(_) => {
      20            0 :             HttpErrorBody::response_from_msg_and_status(this.to_string(), StatusCode::FORBIDDEN)
      21              :         }
      22              :         ApiError::Unauthorized(_) => {
      23            0 :             HttpErrorBody::response_from_msg_and_status(this.to_string(), StatusCode::UNAUTHORIZED)
      24              :         }
      25              :         ApiError::NotFound(_) => {
      26            0 :             HttpErrorBody::response_from_msg_and_status(this.to_string(), StatusCode::NOT_FOUND)
      27              :         }
      28              :         ApiError::Conflict(_) => {
      29            0 :             HttpErrorBody::response_from_msg_and_status(this.to_string(), StatusCode::CONFLICT)
      30              :         }
      31            0 :         ApiError::PreconditionFailed(_) => HttpErrorBody::response_from_msg_and_status(
      32            0 :             this.to_string(),
      33            0 :             StatusCode::PRECONDITION_FAILED,
      34            0 :         ),
      35            0 :         ApiError::ShuttingDown => HttpErrorBody::response_from_msg_and_status(
      36            0 :             "Shutting down".to_string(),
      37            0 :             StatusCode::SERVICE_UNAVAILABLE,
      38            0 :         ),
      39            0 :         ApiError::ResourceUnavailable(err) => HttpErrorBody::response_from_msg_and_status(
      40            0 :             err.to_string(),
      41            0 :             StatusCode::SERVICE_UNAVAILABLE,
      42            0 :         ),
      43            0 :         ApiError::TooManyRequests(err) => HttpErrorBody::response_from_msg_and_status(
      44            0 :             err.to_string(),
      45            0 :             StatusCode::TOO_MANY_REQUESTS,
      46            0 :         ),
      47            0 :         ApiError::Timeout(err) => HttpErrorBody::response_from_msg_and_status(
      48            0 :             err.to_string(),
      49            0 :             StatusCode::REQUEST_TIMEOUT,
      50            0 :         ),
      51            0 :         ApiError::Cancelled => HttpErrorBody::response_from_msg_and_status(
      52            0 :             this.to_string(),
      53            0 :             StatusCode::INTERNAL_SERVER_ERROR,
      54            0 :         ),
      55            0 :         ApiError::InternalServerError(err) => HttpErrorBody::response_from_msg_and_status(
      56            0 :             err.to_string(),
      57            0 :             StatusCode::INTERNAL_SERVER_ERROR,
      58            0 :         ),
      59              :     }
      60            0 : }
      61              : 
      62              : /// Same as [`utils::http::error::HttpErrorBody`]
      63              : #[derive(Serialize)]
      64              : struct HttpErrorBody {
      65              :     pub(crate) msg: String,
      66              : }
      67              : 
      68              : impl HttpErrorBody {
      69              :     /// Same as [`utils::http::error::HttpErrorBody::response_from_msg_and_status`]
      70            0 :     fn response_from_msg_and_status(
      71            0 :         msg: String,
      72            0 :         status: StatusCode,
      73            0 :     ) -> Response<BoxBody<Bytes, hyper::Error>> {
      74            0 :         HttpErrorBody { msg }.to_response(status)
      75            0 :     }
      76              : 
      77              :     /// Same as [`utils::http::error::HttpErrorBody::to_response`]
      78            0 :     fn to_response(&self, status: StatusCode) -> Response<BoxBody<Bytes, hyper::Error>> {
      79            0 :         Response::builder()
      80            0 :             .status(status)
      81            0 :             .header(http::header::CONTENT_TYPE, "application/json")
      82            0 :             // we do not have nested maps with non string keys so serialization shouldn't fail
      83            0 :             .body(
      84            0 :                 Full::new(Bytes::from(serde_json::to_string(self).unwrap()))
      85            0 :                     .map_err(|x| match x {})
      86            0 :                     .boxed(),
      87            0 :             )
      88            0 :             .unwrap()
      89            0 :     }
      90              : }
      91              : 
      92              : /// Same as [`utils::http::json::json_response`]
      93            0 : pub(crate) fn json_response<T: Serialize>(
      94            0 :     status: StatusCode,
      95            0 :     data: T,
      96            0 : ) -> Result<Response<BoxBody<Bytes, hyper::Error>>, ApiError> {
      97            0 :     let json = serde_json::to_string(&data)
      98            0 :         .context("Failed to serialize JSON response")
      99            0 :         .map_err(ApiError::InternalServerError)?;
     100            0 :     let response = Response::builder()
     101            0 :         .status(status)
     102            0 :         .header(http::header::CONTENT_TYPE, "application/json")
     103            0 :         .body(Full::new(Bytes::from(json)).map_err(|x| match x {}).boxed())
     104            0 :         .map_err(|e| ApiError::InternalServerError(e.into()))?;
     105            0 :     Ok(response)
     106            0 : }
        

Generated by: LCOV version 2.1-beta