Https server
In this section, we implement a simple https server that returns a constant string message.
TODO: Modify this to firstly implement a http server (not implementing https from the start)
HTTP is an acronym for Hyper Text Transfer Protocol. It defines the way how files transfer through the internet from/to server to/from client (your browser). We use this daily since every web site use this protocol to display the contents on its server. For example, you can see the hidden http word in Google’s site https://www.google.com.
However, HTTP does not provide (defines) the way to authorize the server and secure the file transportation network: you may be accessing to a fake server without leagal authentication and it is easy for others to see what you are getting/posting through the internet, which may lead to severe security issues. Therefore, we usually use HTTPS, Secure HTTP, which authorize the server and encrypt the file transportation. Notice that Google’s site https://www.google.com also uses HTTPS instead of HTTP (Google also provides http://www.google.com but you will be redirected to the HTTPS site even if you access this).
To enable HTTPS, we firstly need to authenticate the server. It is common to use letsencrypt in the production level (you may use this if you want in this hands-on). However since we are going to develop software locally, it is enough to authorize locally. To do this, we use mkcert in this tutorial.
Create a new project
cargo new wiki-rs create a new rust project named wiki-rs
cd wiki-rs
Enable CA
See https://github.com/actix/examples/tree/master/https-tls/openssl and follow the instructions on README.md to enable CA. We will be using mkcert.
-
use local CA
mkcert -install
-
generate own cert/private key
mkcert 127.0.0.1
rename the
127.0.0.1-key.pem
file withkey.pem
and the127.0.0.1.pem
file withcert.pem
.
Add dependency
See https://github.com/actix/examples/tree/master/https-tls/openssl and add dependency
Cargo.toml
# Cargo.toml
[package]
name = "wiki-rs" # The name of the project
version = "0.1.0" # The version of the project
edition = "2021" # The version of the rust we will be using
# Add the following dependency
[dependencies]
actix-web = { version = "4", features = ["openssl"] } # Use actix-web to implement a backend server
env_logger = "0.9" # for logging
openssl = "0.10" # for TLS
Implement with actix-web
Implement src/main.rs
following https://github.com/actix/examples/blob/master/https-tls/openssl/src/main.rs.
// src/main.rs
use std::io;
use actix_web::{middleware, web, App, Error, HttpRequest, HttpResponse, HttpServer};
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
/// simple handle
async fn index(req: HttpRequest) -> Result<HttpResponse, Error> {
println!("{:?}", req);
Ok(HttpResponse::Ok()
.content_type("text/plain")
.body("Welcome!"))
}
#[actix_web::main]
async fn main() -> io::Result<()> {
std::env::set_var("RUST_LOG", "actix_web=debug");
env_logger::init();
println!("Started http server: 127.0.0.1:8443");
// load TLS keys
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
builder
.set_private_key_file("key.pem", SslFiletype::PEM)
.unwrap();
builder.set_certificate_chain_file("cert.pem").unwrap();
// Start http(s) server
HttpServer::new(|| {
App::new()
// enable logger
.wrap(middleware::Logger::default())
// register simple handler, handle all methods
.service(web::resource("/index.html").to(index))
// with path parameters
.service(web::resource("/").route(web::get().to(|| async {
HttpResponse::Found()
.append_header(("LOCATION", "/index.html"))
.finish()
})))
})
.bind_openssl("127.0.0.1:8443", builder)?
.run()
.await
}
Run the backend and access
cargo run
and
curl https://127.0.0.1:8443/index.html
with the other terminal.
or access https://127.0.0.1:8443/index.html on browser.
You will get Welcome!
if it goes fine.