Move handle_request onto service as a method
This commit is contained in:
parent
506037dcd0
commit
43f4b98b38
@ -328,7 +328,7 @@ impl<'svc> Service {
|
||||
self.render_page("/domain_sync.html", response)
|
||||
}
|
||||
|
||||
pub fn domains(&self) -> SvcResponse {
|
||||
fn domains(&self) -> SvcResponse {
|
||||
#[derive(Serialize)]
|
||||
struct Response {
|
||||
domains: Vec<String>,
|
||||
@ -350,15 +350,88 @@ impl<'svc> Service {
|
||||
|
||||
self.render_page("/domains.html", Response { domains })
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn handle_request(
|
||||
svc: sync::Arc<Service>,
|
||||
req: Request<Body>,
|
||||
) -> Result<Response<Body>, Infallible> {
|
||||
match handle_request_inner(svc, req).await {
|
||||
Ok(res) => Ok(res),
|
||||
Err(err) => panic!("unexpected error {err}"),
|
||||
async fn handle_request_inner(&self, req: Request<Body>) -> SvcResponse {
|
||||
let maybe_host = match (
|
||||
req.headers()
|
||||
.get("Host")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.map(strip_port),
|
||||
req.uri().host().map(strip_port),
|
||||
) {
|
||||
(Some(h), _) if h != self.http_domain.as_str() => Some(h),
|
||||
(_, Some(h)) if h != self.http_domain.as_str() => Some(h),
|
||||
_ => None,
|
||||
}
|
||||
.and_then(|h| domain::Name::from_str(h).ok());
|
||||
|
||||
let method = req.method();
|
||||
let path = req.uri().path();
|
||||
|
||||
// Serving acme challenges always takes priority. We serve them from the same store no matter
|
||||
// the domain, presumably they are cryptographically random enough that it doesn't matter.
|
||||
if method == Method::GET && path.starts_with("/.well-known/acme-challenge/") {
|
||||
let token = path.trim_start_matches("/.well-known/acme-challenge/");
|
||||
|
||||
if let Ok(key) = self.domain_manager.get_acme_http01_challenge_key(token) {
|
||||
let body: hyper::Body = key.into();
|
||||
return match Response::builder().status(200).body(body) {
|
||||
Ok(res) => Ok(res),
|
||||
Err(err) => Err(format!(
|
||||
"failed to write acme http-01 challenge key: {}",
|
||||
err
|
||||
)),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// If a managed domain was given then serve that from its origin
|
||||
if let Some(domain) = maybe_host {
|
||||
return self.serve_origin(domain, req.uri().path());
|
||||
}
|
||||
|
||||
// Serve main domiply site
|
||||
|
||||
if method == Method::GET && path.starts_with("/static/") {
|
||||
return self.render(200, path, ());
|
||||
}
|
||||
|
||||
match (method, path) {
|
||||
(&Method::GET, "/") | (&Method::GET, "/index.html") => {
|
||||
self.render_page("/index.html", ())
|
||||
}
|
||||
(&Method::GET, "/domain.html") => {
|
||||
self.with_query_req(&req, |args: DomainGetArgs| async { self.domain_get(args) })
|
||||
.await
|
||||
}
|
||||
(&Method::GET, "/domain_init.html") => {
|
||||
self.with_query_req(&req, |args: DomainInitArgs| async {
|
||||
self.with_query_req(&req, |config: service::util::FlatConfig| async {
|
||||
self.domain_init(args, config)
|
||||
})
|
||||
.await
|
||||
})
|
||||
.await
|
||||
}
|
||||
(&Method::GET, "/domain_sync.html") => {
|
||||
self.with_query_req(&req, |args: DomainSyncArgs| async {
|
||||
self.with_query_req(&req, |config: service::util::FlatConfig| async {
|
||||
self.domain_sync(args, config).await
|
||||
})
|
||||
.await
|
||||
})
|
||||
.await
|
||||
}
|
||||
(&Method::GET, "/domains.html") => self.domains(),
|
||||
_ => self.render_error_page(404, "Page not found!"),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn handle_request(&self, req: Request<Body>) -> Result<Response<Body>, Infallible> {
|
||||
match self.handle_request_inner(req).await {
|
||||
Ok(res) => Ok(res),
|
||||
Err(err) => panic!("unexpected error {err}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -368,77 +441,3 @@ fn strip_port(host: &str) -> &str {
|
||||
Some(i) => &host[..i],
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn handle_request_inner(svc: sync::Arc<Service>, req: Request<Body>) -> SvcResponse {
|
||||
let maybe_host = match (
|
||||
req.headers()
|
||||
.get("Host")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.map(strip_port),
|
||||
req.uri().host().map(strip_port),
|
||||
) {
|
||||
(Some(h), _) if h != svc.http_domain.as_str() => Some(h),
|
||||
(_, Some(h)) if h != svc.http_domain.as_str() => Some(h),
|
||||
_ => None,
|
||||
}
|
||||
.and_then(|h| domain::Name::from_str(h).ok());
|
||||
|
||||
let method = req.method();
|
||||
let path = req.uri().path();
|
||||
|
||||
// Serving acme challenges always takes priority. We serve them from the same store no matter
|
||||
// the domain, presumably they are cryptographically random enough that it doesn't matter.
|
||||
if method == Method::GET && path.starts_with("/.well-known/acme-challenge/") {
|
||||
let token = path.trim_start_matches("/.well-known/acme-challenge/");
|
||||
|
||||
if let Ok(key) = svc.domain_manager.get_acme_http01_challenge_key(token) {
|
||||
let body: hyper::Body = key.into();
|
||||
return match Response::builder().status(200).body(body) {
|
||||
Ok(res) => Ok(res),
|
||||
Err(err) => Err(format!(
|
||||
"failed to write acme http-01 challenge key: {}",
|
||||
err
|
||||
)),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// If a managed domain was given then serve that from its origin
|
||||
if let Some(domain) = maybe_host {
|
||||
return svc.serve_origin(domain, req.uri().path());
|
||||
}
|
||||
|
||||
// Serve main domiply site
|
||||
|
||||
if method == Method::GET && path.starts_with("/static/") {
|
||||
return svc.render(200, path, ());
|
||||
}
|
||||
|
||||
match (method, path) {
|
||||
(&Method::GET, "/") | (&Method::GET, "/index.html") => svc.render_page("/index.html", ()),
|
||||
(&Method::GET, "/domain.html") => {
|
||||
svc.with_query_req(&req, |args: DomainGetArgs| async { svc.domain_get(args) })
|
||||
.await
|
||||
}
|
||||
(&Method::GET, "/domain_init.html") => {
|
||||
svc.with_query_req(&req, |args: DomainInitArgs| async {
|
||||
svc.with_query_req(&req, |config: service::util::FlatConfig| async {
|
||||
svc.domain_init(args, config)
|
||||
})
|
||||
.await
|
||||
})
|
||||
.await
|
||||
}
|
||||
(&Method::GET, "/domain_sync.html") => {
|
||||
svc.with_query_req(&req, |args: DomainSyncArgs| async {
|
||||
svc.with_query_req(&req, |config: service::util::FlatConfig| async {
|
||||
svc.domain_sync(args, config).await
|
||||
})
|
||||
.await
|
||||
})
|
||||
.await
|
||||
}
|
||||
(&Method::GET, "/domains.html") => svc.domains(),
|
||||
_ => svc.render_error_page(404, "Page not found!"),
|
||||
}
|
||||
}
|
||||
|
@ -11,19 +11,20 @@ pub fn listen_http(
|
||||
addr: net::SocketAddr,
|
||||
domain: domain::Name,
|
||||
) -> tokio::task::JoinHandle<()> {
|
||||
let make_service = hyper::service::make_service_fn(move |_| {
|
||||
let service = service.clone();
|
||||
tokio::spawn(async move {
|
||||
let make_service = hyper::service::make_service_fn(move |_| {
|
||||
let service = service.clone();
|
||||
|
||||
// Create a `Service` for responding to the request.
|
||||
let hyper_service = hyper::service::service_fn(move |req| {
|
||||
service::http::handle_request(service.clone(), req)
|
||||
// Create a `Service` for responding to the request.
|
||||
let hyper_service = hyper::service::service_fn(move |req| {
|
||||
let service = service.clone();
|
||||
async move { service.handle_request(req).await }
|
||||
});
|
||||
|
||||
// Return the service to hyper.
|
||||
async move { Ok::<_, convert::Infallible>(hyper_service) }
|
||||
});
|
||||
|
||||
// Return the service to hyper.
|
||||
async move { Ok::<_, convert::Infallible>(hyper_service) }
|
||||
});
|
||||
|
||||
tokio::spawn(async move {
|
||||
log::info!("Listening on http://{}:{}", domain.as_str(), addr.port());
|
||||
let server = hyper::Server::bind(&addr).serve(make_service);
|
||||
|
||||
@ -44,19 +45,20 @@ pub fn listen_https(
|
||||
addr: net::SocketAddr,
|
||||
domain: domain::Name,
|
||||
) -> tokio::task::JoinHandle<()> {
|
||||
let make_service = hyper::service::make_service_fn(move |_| {
|
||||
let service = service.clone();
|
||||
tokio::spawn(async move {
|
||||
let make_service = hyper::service::make_service_fn(move |_| {
|
||||
let service = service.clone();
|
||||
|
||||
// Create a `Service` for responding to the request.
|
||||
let hyper_service = hyper::service::service_fn(move |req| {
|
||||
service::http::handle_request(service.clone(), req)
|
||||
// Create a `Service` for responding to the request.
|
||||
let hyper_service = hyper::service::service_fn(move |req| {
|
||||
let service = service.clone();
|
||||
async move { service.handle_request(req).await }
|
||||
});
|
||||
|
||||
// Return the service to hyper.
|
||||
async move { Ok::<_, convert::Infallible>(hyper_service) }
|
||||
});
|
||||
|
||||
// Return the service to hyper.
|
||||
async move { Ok::<_, convert::Infallible>(hyper_service) }
|
||||
});
|
||||
|
||||
tokio::spawn(async move {
|
||||
let server_config: tokio_rustls::TlsAcceptor = sync::Arc::new(
|
||||
rustls::server::ServerConfig::builder()
|
||||
.with_safe_defaults()
|
||||
|
Loading…
Reference in New Issue
Block a user