1pub mod admin;
2mod cache_control;
3pub mod config;
4mod crypto;
5mod encoding;
6pub mod events;
7mod glob;
8pub mod goals;
9pub mod hoops;
10pub mod observability;
11mod placeholder;
12pub mod plugin;
13pub mod proxy;
14pub mod router;
15pub mod runtime;
16pub mod salvo_service;
17pub mod sd_notify;
18pub mod server;
19pub mod storage;
20pub mod stream;
21pub mod tls;
22pub mod ttl_cache;
23mod websocket;
24
25use bytes::Bytes;
26use http_body_util::BodyExt;
27use http_body_util::combinators::BoxBody;
28
29pub type Body = BoxBody<Bytes, BoxError>;
32
33pub type BoxError = Box<dyn std::error::Error + Send + Sync>;
35
36pub fn empty_body() -> Body {
38 use http_body_util::Empty;
39 BoxBody::new(
40 Empty::new().map_err(|never: std::convert::Infallible| -> BoxError { match never {} }),
41 )
42}
43
44pub fn full_body(data: impl Into<Bytes>) -> Body {
46 use http_body_util::Full;
47 BoxBody::new(
48 Full::new(data.into())
49 .map_err(|never: std::convert::Infallible| -> BoxError { match never {} }),
50 )
51}
52
53#[derive(Debug, thiserror::Error)]
55pub enum ProxyError {
56 #[error("hyper error: {0}")]
57 Hyper(#[from] hyper::Error),
58
59 #[error("HTTP error: {0}")]
60 Http(#[from] http::Error),
61
62 #[error("hyper-util client error: {0}")]
63 Client(#[from] hyper_util::client::legacy::Error),
64
65 #[error("IO error: {0}")]
66 Io(#[from] std::io::Error),
67
68 #[error("config error: {0}")]
69 Config(#[from] config::ConfigError),
70
71 #[error("no upstream available")]
72 NoUpstream,
73
74 #[error("bad request: {0}")]
75 BadRequest(String),
76
77 #[error("{0}")]
78 Internal(String),
79}
80
81impl ProxyError {
82 pub fn into_response(self) -> http::Response<Body> {
84 let status = match &self {
85 ProxyError::BadRequest(_) => http::StatusCode::BAD_REQUEST,
86 ProxyError::NoUpstream => http::StatusCode::BAD_GATEWAY,
87 _ => http::StatusCode::INTERNAL_SERVER_ERROR,
88 };
89 let body = full_body(self.to_string());
90 http::Response::builder().status(status).body(body).unwrap()
91 }
92}