aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-02-12 10:15:03 +0100
committermetamuffin <metamuffin@disroot.org>2023-02-12 10:15:03 +0100
commit1f6ade88e4f7b8fdb48ad040b469e33292faaf74 (patch)
treef5fa84348dfa84b38753dbe92e60ef2ebcbe5cf5 /src
parentf7d989c8785bb83bfd02a0fa7287b8bf4e383ac6 (diff)
downloadgnix-1f6ade88e4f7b8fdb48ad040b469e33292faaf74.tar
gnix-1f6ade88e4f7b8fdb48ad040b469e33292faaf74.tar.bz2
gnix-1f6ade88e4f7b8fdb48ad040b469e33292faaf74.tar.zst
doc + error handling
Diffstat (limited to 'src')
-rw-r--r--src/main.rs47
1 files changed, 27 insertions, 20 deletions
diff --git a/src/main.rs b/src/main.rs
index f507ed5..7f6ec88 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,12 +5,12 @@ use anyhow::{anyhow, bail, Context, Result};
use http_body_util::{combinators::BoxBody, BodyExt};
use hyper::{
body::Incoming,
- header::UPGRADE,
+ header::{HOST, UPGRADE},
http::{uri::PathAndQuery, HeaderValue},
server::conn::http1,
service::service_fn,
upgrade::OnUpgrade,
- Request, Response, Uri,
+ Request, Response, StatusCode, Uri,
};
use log::{debug, error, info, warn};
use std::{fs::File, io::BufReader, path::Path, sync::Arc};
@@ -20,6 +20,16 @@ use tokio::{
};
use tokio_rustls::TlsAcceptor;
+#[derive(Debug, thiserror::Error)]
+enum ServiceError {
+ #[error("hyper error")]
+ Hyper(hyper::Error),
+ #[error("unknown host")]
+ NoHost,
+ #[error("can't connect to the backend")]
+ CantConnect,
+}
+
#[tokio::main]
async fn main() -> anyhow::Result<()> {
env_logger::init_from_env("LOG");
@@ -61,10 +71,7 @@ async fn serve_https(config: Arc<Config>) -> Result<()> {
.with_safe_defaults()
.with_no_client_auth()
.with_single_cert(certs, key)?;
- cfg.alpn_protocols = vec![
- // b"h2".to_vec(),
- b"http/1.1".to_vec(),
- ];
+ cfg.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
Arc::new(cfg)
};
let listener = TcpListener::bind(https_config.bind).await?;
@@ -74,8 +81,10 @@ async fn serve_https(config: Arc<Config>) -> Result<()> {
loop {
let (stream, addr) = listener.accept().await.context("accepting connection")?;
debug!("connection from {addr}");
- let stream = tls_acceptor.accept(stream).await.context("accepting tls")?;
- serve_stream(config.clone(), stream)
+ match tls_acceptor.accept(stream).await {
+ Ok(stream) => serve_stream(config.clone(), stream),
+ Err(e) => warn!("error accepting tls: {e}"),
+ };
}
}
@@ -93,9 +102,13 @@ pub fn serve_stream<T: AsyncRead + AsyncWrite + Unpin + Send + 'static>(
match service(config, req).await {
Ok(r) => Ok(r),
Err(ServiceError::Hyper(e)) => Err(e),
- Err(other) => Ok(Response::new(format!(
- "the reverse proxy encountered an error: gnix-{other:?}"
- ))
+ Err(error) => Ok({
+ let mut resp = Response::new(format!(
+ "the reverse proxy encountered an issue: {error}"
+ ));
+ *resp.status_mut() = StatusCode::BAD_REQUEST;
+ resp
+ }
.map(|b| b.map_err(|e| match e {}).boxed())),
}
}
@@ -103,7 +116,7 @@ pub fn serve_stream<T: AsyncRead + AsyncWrite + Unpin + Send + 'static>(
)
.with_upgrades();
if let Err(err) = conn.await {
- error!("error: {:?}", err);
+ warn!("error: {:?}", err);
}
});
}
@@ -123,17 +136,11 @@ fn load_private_key(path: &Path) -> anyhow::Result<rustls::PrivateKey> {
Ok(rustls::PrivateKey(keys[0].clone()))
}
-#[derive(Debug)]
-enum ServiceError {
- Hyper(hyper::Error),
- NoHost,
- CantConnect,
-}
-
async fn service(
config: Arc<Config>,
mut req: Request<Incoming>,
) -> Result<hyper::Response<BoxBody<bytes::Bytes, hyper::Error>>, ServiceError> {
+ debug!("<- {:?} {}", req.headers().get(HOST), req.uri());
*req.uri_mut() = Uri::builder()
.scheme("http")
.authority("backend")
@@ -151,7 +158,7 @@ async fn service(
.hosts
.get(remove_port(
&req.headers()
- .get("host")
+ .get(HOST)
.and_then(|e| e.to_str().ok())
.map(String::from)
.unwrap_or(String::from("")),