You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
3.1 KiB
97 lines
3.1 KiB
use crate::error::unexpected::{self, Mappable};
|
|
use crate::service;
|
|
|
|
use std::{convert, future, sync};
|
|
|
|
use futures::StreamExt;
|
|
use hyper::server::conn::AddrStream;
|
|
use tokio_rustls::server::TlsStream;
|
|
use tokio_util::sync::CancellationToken;
|
|
|
|
pub async fn listen_http(
|
|
service: sync::Arc<service::http::Service>,
|
|
canceller: CancellationToken,
|
|
) -> Result<(), unexpected::Error> {
|
|
let addr = service.config.http.http_addr;
|
|
|
|
let make_service = hyper::service::make_service_fn(move |conn: &AddrStream| {
|
|
let service = service.clone();
|
|
let client_ip = conn.remote_addr().ip();
|
|
|
|
// Create a `Service` for responding to the request.
|
|
let hyper_service = hyper::service::service_fn(move |req| {
|
|
let service = service.clone();
|
|
async move {
|
|
Ok::<_, convert::Infallible>(service.handle_request(client_ip, req, false).await)
|
|
}
|
|
});
|
|
|
|
// Return the service to hyper.
|
|
async move { Ok::<_, convert::Infallible>(hyper_service) }
|
|
});
|
|
|
|
log::info!("Listening on http://{}", &addr);
|
|
let server = hyper::Server::bind(&addr).serve(make_service);
|
|
|
|
let graceful = server.with_graceful_shutdown(async {
|
|
canceller.cancelled().await;
|
|
});
|
|
|
|
graceful.await.or_unexpected()
|
|
}
|
|
|
|
pub async fn listen_https(
|
|
service: sync::Arc<service::http::Service>,
|
|
canceller: CancellationToken,
|
|
) -> Result<(), unexpected::Error> {
|
|
let cert_resolver = service.cert_resolver.clone();
|
|
let addr = service.config.http.https_addr.unwrap();
|
|
|
|
let make_service = hyper::service::make_service_fn(move |conn: &TlsStream<AddrStream>| {
|
|
let service = service.clone();
|
|
let client_ip = conn.get_ref().0.remote_addr().ip();
|
|
|
|
// Create a `Service` for responding to the request.
|
|
let hyper_service = hyper::service::service_fn(move |req| {
|
|
let service = service.clone();
|
|
async move {
|
|
Ok::<_, convert::Infallible>(service.handle_request(client_ip, req, true).await)
|
|
}
|
|
});
|
|
|
|
// Return the service to hyper.
|
|
async move { Ok::<_, convert::Infallible>(hyper_service) }
|
|
});
|
|
|
|
let server_config: tokio_rustls::TlsAcceptor = sync::Arc::new(
|
|
rustls::server::ServerConfig::builder()
|
|
.with_safe_defaults()
|
|
.with_no_client_auth()
|
|
.with_cert_resolver(cert_resolver),
|
|
)
|
|
.into();
|
|
|
|
let addr_incoming = hyper::server::conn::AddrIncoming::bind(&addr)
|
|
.expect("https listen socket creation failed");
|
|
|
|
let incoming = tls_listener::TlsListener::new(server_config, addr_incoming).filter(|conn| {
|
|
if let Err(err) = conn {
|
|
log::error!("Error accepting TLS connection: {:?}", err);
|
|
future::ready(false)
|
|
} else {
|
|
future::ready(true)
|
|
}
|
|
});
|
|
|
|
let incoming = hyper::server::accept::from_stream(incoming);
|
|
|
|
log::info!("Listening on https://{}", addr);
|
|
|
|
let server = hyper::Server::builder(incoming).serve(make_service);
|
|
|
|
let graceful = server.with_graceful_shutdown(async {
|
|
canceller.cancelled().await;
|
|
});
|
|
|
|
graceful.await.or_unexpected()
|
|
}
|
|
|