Support forced HTTPS redirects #39

This commit is contained in:
spikecodes 2021-01-16 22:04:03 -08:00
parent ef9bc791e1
commit 6127f2a90c
4 changed files with 37 additions and 6 deletions

13
Cargo.lock generated
View File

@ -684,6 +684,7 @@ checksum = "da9052a1a50244d8d5aa9bf55cbc2fb6f357c86cc52e46c62ed390a7180cf150"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
@ -706,6 +707,17 @@ version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79e5145dde8da7d1b3892dad07a9c98fc04bc39892b1ecc9692cf53e2b780a65"
[[package]]
name = "futures-executor"
version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9e59fdc009a4b3096bf94f740a0f2424c082521f20a9b08c5c07c48d90fd9b9"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.12"
@ -988,6 +1000,7 @@ dependencies = [
"askama",
"async-recursion",
"base64 0.13.0",
"futures",
"regex",
"serde",
"serde_json",

View File

@ -10,6 +10,7 @@ edition = "2018"
[dependencies]
base64 = "0.13.0"
actix-web = { version = "3.3.2", features = ["rustls"] }
futures = "0.3"
askama = "0.10.5"
ureq = "2.0.1"
serde = { version = "1.0.118", default_features = false, features = ["derive"] }

View File

@ -190,6 +190,8 @@ Specify a custom address for the server by passing the `-a` or `--address` argum
libreddit --address=0.0.0.0:8111
```
Given you have a TLS certificate, you can pass the `-r` or `--redirect-https` arguments to force HTTPS.
## Building
```

View File

@ -1,5 +1,6 @@
// Import Crates
use actix_web::{middleware, web, App, HttpResponse, HttpServer}; // dev::Service
use actix_web::{App, HttpResponse, HttpServer, dev::{Service, ServiceResponse}, middleware, web};
use futures::future::FutureExt;
// Reference local files
mod post;
@ -30,12 +31,12 @@ async fn favicon() -> HttpResponse {
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let mut address = "0.0.0.0:8080".to_string();
// let mut https = false;
let mut force_https = false;
for arg in std::env::args().collect::<Vec<String>>() {
match arg.split('=').collect::<Vec<&str>>()[0] {
"--address" | "-a" => address = arg.split('=').collect::<Vec<&str>>()[1].to_string(),
// "--redirect-https" | "-r" => https = true,
"--redirect-https" | "-r" => force_https = true,
_ => (),
}
}
@ -43,10 +44,24 @@ async fn main() -> std::io::Result<()> {
// start http server
println!("Running Libreddit v{} on {}!", env!("CARGO_PKG_VERSION"), &address);
HttpServer::new(|| {
HttpServer::new(move || {
App::new()
// Redirect to HTTPS
// .wrap_fn(|req, srv| { let fut = srv.call(req); async { let mut res = fut.await?; if https {} Ok(res) } })
// Redirect to HTTPS if "--redirect-https" enabled
.wrap_fn(move |req, srv| {
let secure = req.connection_info().scheme() == "https";
let https_url = format!("https://{}{}", req.connection_info().host(), req.uri().to_string());
srv.call(req).map(move |res: Result<ServiceResponse, _> | {
if force_https && !secure {
let redirect: ServiceResponse<actix_web::dev::Body> = ServiceResponse::new(
res.unwrap().request().clone(),
HttpResponse::Found().header("Location", https_url).finish()
);
Ok(redirect)
} else {
res
}
})
})
// Append trailing slash and remove double slashes
.wrap(middleware::NormalizePath::default())
// Default service in case no routes match