Recipe: HTTPS and HTTP redirect

Goal: Bind TLS and optionally force HTTPS.

open System
open System.Security.Cryptography.X509Certificates
open Suave
open Suave.Filters
open Suave.Operators
open Suave.Successful
open Suave.Redirection

let cert = new X509Certificate2("certificate.p12", "password")
let http  = HttpBinding.createSimple HTTP "0.0.0.0" 8080
let https = HttpBinding.createSimple (HTTPS cert) "0.0.0.0" 8443

let redirectToSsl (allow : WebPart) : WebPart =
  context (fun c ->
    if c.request.binding.scheme.secure then allow
    else
      let b = UriBuilder(Scheme = Uri.UriSchemeHttps, Host = c.request.host, Path = c.request.path)
      redirect (b.Uri.ToString()))

let cfg = { defaultConfig with bindings = [ http; https ] }
let app = redirectToSsl (OK "Secure hello")

startWebServer cfg app

Behind nginx, you may check x-forwarded-proto instead of scheme.secure. See Bindings.