Domani connects your domain to whatever you want to host on it, all with no account needed
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.
 
 
 
 
domani/src/service/http/tasks.rs

109 lines
3.5 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;
// only used for logging
let listen_host = service
.interface_domain
.clone()
.map_or(addr.ip().to_string(), |ref d| d.as_str().to_string());
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://{}:{}", listen_host, addr.port(),);
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();
// only used for logging
let listen_host = service
.interface_domain
.clone()
.map_or(addr.ip().to_string(), |ref d| d.as_str().to_string());
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://{}:{}", listen_host, addr.port());
let server = hyper::Server::builder(incoming).serve(make_service);
let graceful = server.with_graceful_shutdown(async {
canceller.cancelled().await;
});
graceful.await.or_unexpected()
}