-
-
Notifications
You must be signed in to change notification settings - Fork 283
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
…#494) * Expose methods for explicit certificate renewal * Notes * Style fixes * Use struct return from issue cert to prevent mixing up priv and pub keys * update examples --------- Co-authored-by: andrew <> Co-authored-by: Sunli <[email protected]> Co-authored-by: Sunli <[email protected]>
- Loading branch information
1 parent
a04b7e7
commit 5d8048c
Showing
9 changed files
with
298 additions
and
94 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[package] | ||
name = "example-acme-expanded-http-01" | ||
version = "0.1.0" | ||
edition = "2021" | ||
publish = false | ||
|
||
[dependencies] | ||
poem = { path = "../../../poem", features = ["acme"] } | ||
tokio = { version = "1.12.0", features = ["rt-multi-thread", "macros"] } | ||
tracing-subscriber = { version = "0.3.9", features = ["env-filter"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
//! If you want to manage certificates yourself (sharing between servers, | ||
//! sending over the network, etc) you can use this expanded ACME | ||
//! certificate generation process which gives you access to the | ||
//! generated certificates. | ||
use std::{sync::Arc, time::Duration}; | ||
|
||
use poem::{ | ||
get, handler, | ||
listener::{ | ||
acme::{ | ||
issue_cert, seconds_until_expiry, AcmeClient, ChallengeType, Http01Endpoint, | ||
Http01TokensMap, ResolveServerCert, ResolvedCertListener, LETS_ENCRYPT_PRODUCTION, | ||
}, | ||
Listener, TcpListener, | ||
}, | ||
middleware::Tracing, | ||
web::Path, | ||
EndpointExt, Route, RouteScheme, Server, | ||
}; | ||
use tokio::{spawn, time::sleep}; | ||
|
||
#[handler] | ||
fn hello(Path(name): Path<String>) -> String { | ||
format!("hello: {}", name) | ||
} | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), std::io::Error> { | ||
if std::env::var_os("RUST_LOG").is_none() { | ||
std::env::set_var("RUST_LOG", "poem=debug"); | ||
} | ||
tracing_subscriber::fmt::init(); | ||
|
||
let mut acme_client = | ||
AcmeClient::try_new(&LETS_ENCRYPT_PRODUCTION.parse().unwrap(), vec![]).await?; | ||
let cert_resolver = Arc::new(ResolveServerCert::default()); | ||
let challenge = ChallengeType::Http01; | ||
let keys_for_http_challenge = Http01TokensMap::new(); | ||
|
||
{ | ||
let domains = vec!["poem.rs".to_string()]; | ||
let keys_for_http_challenge = keys_for_http_challenge.clone(); | ||
let cert_resolver = Arc::downgrade(&cert_resolver); | ||
spawn(async move { | ||
loop { | ||
let sleep_duration; | ||
if let Some(cert_resolver) = cert_resolver.upgrade() { | ||
let cert = match issue_cert( | ||
&mut acme_client, | ||
&cert_resolver, | ||
&domains, | ||
challenge, | ||
Some(&keys_for_http_challenge), | ||
) | ||
.await | ||
{ | ||
Ok(result) => result.rustls_key, | ||
Err(err) => { | ||
eprintln!("failed to issue certificate: {}", err); | ||
sleep(Duration::from_secs(60 * 5)).await; | ||
continue; | ||
} | ||
}; | ||
sleep_duration = seconds_until_expiry(&cert) - 12 * 60 * 60; | ||
*cert_resolver.cert.write() = Some(cert); | ||
} else { | ||
break; | ||
} | ||
sleep(Duration::from_secs(sleep_duration as u64)).await; | ||
} | ||
}); | ||
} | ||
|
||
let app = RouteScheme::new() | ||
.https(Route::new().at("/hello/:name", get(hello))) | ||
.http(Http01Endpoint { | ||
keys: keys_for_http_challenge, | ||
}) | ||
.with(Tracing); | ||
|
||
Server::new( | ||
ResolvedCertListener::new( | ||
TcpListener::bind("0.0.0.0:443"), | ||
cert_resolver, | ||
ChallengeType::Http01, | ||
) | ||
.combine(TcpListener::bind("0.0.0.0:80")), | ||
) | ||
.name("hello-world") | ||
.run(app) | ||
.await | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.