| 12 | |
| 13 | #[actix_web::main] |
| 14 | async fn main() -> std::io::Result<()> { |
| 15 | env_logger::init_from_env(env_logger::Env::new().default_filter_or("info")); |
| 16 | |
| 17 | rustls::crypto::aws_lc_rs::default_provider() |
| 18 | .install_default() |
| 19 | .unwrap(); |
| 20 | |
| 21 | let cert_chain = CertificateDer::pem_file_iter("cert.pem") |
| 22 | .unwrap() |
| 23 | .flatten() |
| 24 | .collect(); |
| 25 | |
| 26 | let key_der = |
| 27 | PrivateKeyDer::from_pem_file("key.pem").expect("Could not locate PKCS 8 private keys."); |
| 28 | |
| 29 | let config = ServerConfig::builder() |
| 30 | .with_no_client_auth() |
| 31 | .with_single_cert(cert_chain, key_der) |
| 32 | .unwrap(); |
| 33 | |
| 34 | log::info!( |
| 35 | "starting HTTP server at http://localhost:80 and HTTPS server on http://localhost:443" |
| 36 | ); |
| 37 | |
| 38 | HttpServer::new(|| { |
| 39 | App::new() |
| 40 | .wrap_fn(|sreq, srv| { |
| 41 | let host = sreq.connection_info().host().to_owned(); |
| 42 | let uri = sreq.uri().to_owned(); |
| 43 | let url = format!("https://{host}{uri}"); |
| 44 | |
| 45 | // If the scheme is "https" then it will let other services below this wrap_fn |
| 46 | // handle the request and if it's "http" then a response with redirect status code |
| 47 | // will be sent whose "location" header will be same as before, with just "http" |
| 48 | // changed to "https" |
| 49 | |
| 50 | if sreq.connection_info().scheme() == "https" { |
| 51 | Either::Left(srv.call(sreq).map(|res| res)) |
| 52 | } else { |
| 53 | println!("An http request has arrived here, i will redirect it to use https"); |
| 54 | Either::Right(future::ready(Ok(sreq.into_response( |
| 55 | HttpResponse::MovedPermanently() |
| 56 | .append_header((http::header::LOCATION, url)) |
| 57 | .finish(), |
| 58 | )))) |
| 59 | } |
| 60 | }) |
| 61 | .service(index) |
| 62 | }) |
| 63 | .bind(("127.0.0.1", 80))? // HTTP port |
| 64 | .bind_rustls_0_23(("127.0.0.1", 443), config)? // HTTPS port |
| 65 | .run() |
| 66 | .await |
| 67 | } |