{-# LANGUAGE OverloadedStrings #-} module Backend.Https (forkHttpsBackend, httpsDefaultSettings) where import Backend.Http import Config import Control.Concurrent.MVar (MVar) import Data.Text () -- we only need the isString instance to generate literals import qualified Network.Wai as Wai import qualified Network.Wai.Handler.Warp as HTTP import qualified Network.Wai.Handler.WarpTLS as HTTPS import Toml (TomlCodec, (.=)) import qualified Toml type HttpsConfiguration = (HttpConfiguration, TLSConfiguration) data TLSConfiguration = TLSConfiguration { certFile :: FilePath, certChain :: [FilePath], keyFile :: FilePath } tlsDefaultSetting :: TLSConfiguration tlsDefaultSetting = TLSConfiguration "certificate.pem" [] "key.pem" httpsDefaultSetting :: HttpsConfiguration httpsDefaultSetting = (httpDefaultSetting, tlsDefaultSetting) httpsDefaultSettings :: [HttpsConfiguration] httpsDefaultSettings = [httpsDefaultSetting] httpsConfigCodec' :: TomlCodec TLSConfiguration httpsConfigCodec' = TLSConfiguration <$> Toml.string "Certificate" .= certFile <*> Toml.arrayOf Toml._String "CertChain" .= certChain <*> Toml.string "KeyFile" .= keyFile httpsConfigCodec :: TomlCodec HttpsConfiguration httpsConfigCodec = Toml.pair httpConfigCodec httpsConfigCodec' httpsConfigsCodec :: TomlCodec [HttpsConfiguration] httpsConfigsCodec = Toml.list httpsConfigCodec "https" forkHttpsBackend :: Wai.Application -> FilePath -> IO [MVar ()] forkHttpsBackend app configFile = forkWithConfigs (backend app) httpsConfigsCodec configFile httpsToWarpTLSConfig :: HttpsConfiguration -> HTTPS.TLSSettings httpsToWarpTLSConfig (_, tlsConfig) = HTTPS.tlsSettingsChain (certFile tlsConfig) (certChain tlsConfig) (keyFile tlsConfig) httpsToWarpConfig :: HttpsConfiguration -> HTTP.Settings httpsToWarpConfig = httpToWarpConfig . fst backend :: Wai.Application -> HttpsConfiguration -> IO () backend app conf = HTTPS.runTLS (httpsToWarpTLSConfig conf) (httpsToWarpConfig conf) app