Skip to content
Snippets Groups Projects
Commit 1e99d1ba authored by Jean-Paul Calderone's avatar Jean-Paul Calderone
Browse files

Support either HTTP or HTTPS

parent 5afdba98
No related branches found
No related tags found
1 merge request!27Switch to running on TLS
...@@ -19,12 +19,13 @@ import Data.Default ...@@ -19,12 +19,13 @@ import Data.Default
( def ( def
) )
import Network.Wai.Handler.Warp import Network.Wai.Handler.Warp
( defaultSettings ( Port
, defaultSettings
, setPort , setPort
, run
) )
import Network.Wai.Handler.WarpTLS import Network.Wai.Handler.WarpTLS
( TLSSettings ( runTLS
, runTLS
, tlsSettingsChain , tlsSettingsChain
) )
import Network.Wai import Network.Wai
...@@ -66,6 +67,7 @@ import Options.Applicative ...@@ -66,6 +67,7 @@ import Options.Applicative
, progDesc , progDesc
, header , header
, (<**>) , (<**>)
, (<|>)
) )
import System.Exit import System.Exit
( exitFailure ( exitFailure
...@@ -87,13 +89,55 @@ data ServerConfig = ServerConfig ...@@ -87,13 +89,55 @@ data ServerConfig = ServerConfig
, signingKey :: Maybe Text , signingKey :: Maybe Text
, database :: Database , database :: Database
, databasePath :: Maybe Text , databasePath :: Maybe Text
, httpPortNumber :: Int , endpoint :: Endpoint
, certificatePath :: String
, chainPath :: Maybe String
, keyPath :: String
} }
deriving (Show, Eq) deriving (Show, Eq)
-- | An Endpoint represents the configuration for a socket's IP address.
-- There are some layering violations here. I'm just copying Twisted
-- endpoints at the moment. At some point it would be great to implement a
-- general purpose endpoint library outside of PaymentServer and without the
-- layering violations.
data Endpoint =
-- | A TCPEndpoint represents a bare TCP/IP socket address.
TCPEndpoint
{ portNumber :: Port
}
|
-- | A TLSEndpoint represents a TCP/IP socket address which will have TLS
-- used over it.
TLSEndpoint
{ portNumber :: Port
, certificatePath :: FilePath
, chainPath :: Maybe FilePath
, keyPath :: FilePath
}
deriving (Show, Eq)
http :: Parser Endpoint
http = TCPEndpoint
<$> option auto
( long "http-port"
<> help "Port number on which to accept HTTP connections."
)
https :: Parser Endpoint
https = TLSEndpoint
<$> option auto
( long "https-port"
<> help "Port number on which to accept HTTPS connections." )
<*> strOption
( long "https-certificate-path"
<> help "Filesystem path to the TLS certificate to use for HTTPS." )
<*> optional
( strOption
( long "https-certificate-chain-path"
<> help "Filesystem path to the TLS certificate chain to use for HTTPS." ) )
<*> strOption
( long "https-key-path"
<> help "Filesystem path to the TLS private key to use for HTTPS." )
sample :: Parser ServerConfig sample :: Parser ServerConfig
sample = ServerConfig sample = ServerConfig
<$> option auto <$> option auto
...@@ -114,20 +158,7 @@ sample = ServerConfig ...@@ -114,20 +158,7 @@ sample = ServerConfig
( long "database-path" ( long "database-path"
<> help "Path to on-disk database (sqlite3 only)" <> help "Path to on-disk database (sqlite3 only)"
<> showDefault ) ) <> showDefault ) )
<*> option auto <*> (http <|> https)
( long "https-port"
<> help "Port number on which to accept HTTPS connections."
<> showDefault
<> value 443 )
<*> strOption
( long "https-certificate-path"
<> help "Filesystem path to the TLS certificate to use for HTTPS." )
<*> optional ( strOption
( long "https-certificate-chain-path"
<> help "Filesystem path to the TLS certificate chain to use for HTTPS." ) )
<*> strOption
( long "https-key-path"
<> help "Filesystem path to the TLS private key to use for HTTPS." )
opts :: ParserInfo ServerConfig opts :: ParserInfo ServerConfig
...@@ -140,15 +171,30 @@ opts = info (sample <**> helper) ...@@ -140,15 +171,30 @@ opts = info (sample <**> helper)
main :: IO () main :: IO ()
main = do main = do
config <- execParser opts config <- execParser opts
let port = httpPortNumber config
app <- getApp config app <- getApp config
tlsSettings <- getTlsSettings config let run = getRunner (endpoint config)
putStrLn (printf "Accepting HTTPS connections on %d" port :: String) logEndpoint (endpoint config)
runTLS tlsSettings (setPort port defaultSettings) app run app
getRunner :: Endpoint -> (Application -> IO ())
getRunner endpoint =
case endpoint of
(TCPEndpoint portNumber) ->
run portNumber
(TLSEndpoint portNumber certificatePath chainPath keyPath) ->
let
tlsSettings = tlsSettingsChain certificatePath (maybeToList chainPath) keyPath
settings = setPort portNumber defaultSettings
in
runTLS tlsSettings settings
getTlsSettings :: ServerConfig -> IO TLSSettings logEndpoint :: Endpoint -> IO ()
getTlsSettings ServerConfig{ certificatePath, chainPath, keyPath } = logEndpoint endpoint =
return $ tlsSettingsChain certificatePath (maybeToList chainPath) keyPath case endpoint of
TCPEndpoint { portNumber } ->
putStrLn (printf "Accepting HTTP connections on %d" portNumber :: String)
TLSEndpoint { portNumber } ->
putStrLn (printf "Accepting HTTPS connections on %d" portNumber :: String)
getApp :: ServerConfig -> IO Application getApp :: ServerConfig -> IO Application
getApp config = getApp config =
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment