borderless_runtime/
http.rs1use bytes::Bytes;
2use http::request::Parts;
3use http::{header::CONTENT_TYPE, HeaderValue, StatusCode};
4use mime::{APPLICATION_JSON, TEXT_PLAIN_UTF_8};
5use serde::de::DeserializeOwned;
6use serde::Serialize;
7pub use tower::Service;
8
9#[cfg(feature = "contracts")]
10pub mod contract;
11
12#[cfg(feature = "agents")]
13pub mod agent;
14
15#[cfg(feature = "contracts")]
16pub mod ledger;
17
18pub type Request<T = Bytes> = http::Request<T>;
19pub type Response<T = Bytes> = http::Response<T>;
20
21pub fn reject_404() -> Response {
22 let mut resp = Response::new(Bytes::new());
23 *resp.status_mut() = StatusCode::NOT_FOUND;
24 resp
25}
26
27pub fn method_not_allowed() -> Response {
28 let mut resp = Response::new(Bytes::new());
29 *resp.status_mut() = StatusCode::METHOD_NOT_ALLOWED;
30 resp
31}
32
33pub fn unsupported_media_type() -> Response {
34 let mut resp = Response::new(Bytes::new());
35 *resp.status_mut() = StatusCode::UNSUPPORTED_MEDIA_TYPE;
36 resp
37}
38
39#[derive(Serialize)]
40struct ErrBody {
41 status: String,
42 error: String,
43}
44
45pub fn bad_request(err: String) -> Response {
46 err_response(StatusCode::BAD_REQUEST, err)
47}
48
49pub fn err_response(status: StatusCode, err_msg: String) -> Response {
50 let body = ErrBody {
51 status: status.to_string(),
52 error: err_msg,
53 };
54 let mut resp = json_response(&body);
55 *resp.status_mut() = status;
56 resp
57}
58
59pub fn json_response<S: Serialize>(value: &S) -> Response<Bytes> {
60 let bytes = serde_json::to_vec(value).unwrap_or_default();
61 json_body(bytes)
62}
63
64pub fn json_body(bytes: Vec<u8>) -> Response<Bytes> {
65 let mut resp = Response::new(bytes.into());
66 resp.headers_mut().insert(
67 CONTENT_TYPE,
68 HeaderValue::from_static(APPLICATION_JSON.as_ref()),
69 );
70 resp
71}
72
73pub(crate) fn json_response_nested<S: Serialize + DeserializeOwned>(
74 value: S,
75 truncated_path: &str,
76) -> Response<Bytes> {
77 use borderless::__private::storage_traits::ToPayload;
78 match value.to_payload(truncated_path) {
79 Ok(Some(s)) => json_body(s.into_bytes()),
80 Ok(None) => json_response(&None::<()>),
81 Err(e) => into_server_error(e),
82 }
83}
84
85pub fn check_json_content(parts: &Parts) -> bool {
86 if let Some(content_type) = parts.headers.get(CONTENT_TYPE) {
87 content_type.as_bytes() == APPLICATION_JSON.as_ref().as_bytes()
88 } else {
89 false
90 }
91}
92
93pub fn into_server_error<E: ToString>(error: E) -> Response {
98 let mut resp = Response::new(error.to_string().into_bytes().into());
99 resp.headers_mut().append(
100 CONTENT_TYPE,
101 HeaderValue::from_static(TEXT_PLAIN_UTF_8.as_ref()),
102 );
103 *resp.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
104 resp
105}