Https in Haskell with Servant
Servant を TLS(HTTPS) に対応させる方法を紹介します。
本記事のソースコードは以下のリポジトリにおいてあります。
http://github.com/algas/haskell-servant-cookbook
クライアントとサーバをそれぞれ HTTPS で扱えるようにします。
(サーバ側はリバースプロキシで対応することの方が多いと思いますが)
Client
http-client-tls を使います。
tlsManagerSettings
を defaultManagerSettings
の代わりに用います。
https-client/Main.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Monad.Trans.Except (ExceptT, runExceptT)
import Data.Proxy
import Data.Text (Text)
import qualified Data.Text as T
import HelloApi
import Network.HTTP.Client (Manager, newManager)
import Network.HTTP.Client.TLS (tlsManagerSettings)
import Servant.API
import Servant.Client
type SimpleAPI = Get '[PlainText] Text
simpleApi :: Proxy SimpleAPI
simpleApi = Proxy
simple = client simpleApi
queries :: Manager -> BaseUrl -> ExceptT ServantError IO (Text)
queries manager baseurl = do
h <- simple manager baseurl
return h
main :: IO ()
main = do
manager <- newManager tlsManagerSettings
let baseUrl = BaseUrl Https "localhost" 8080 ""
res <- runExceptT $ queries manager baseUrl
case res of
Left err -> putStrLn $ "Error: " ++ show err
Right p -> do
print p
Server
warp-tls を使います。
runTLS
, tlsSettings
を用います。
https-server/Main.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.Text (Text)
import Network.Wai
import Network.Wai.Handler.Warp
import Network.Wai.Handler.WarpTLS
import Servant
import Servant.API
type SimpleAPI = Get '[PlainText] Text
simpleApi :: Proxy SimpleAPI
simpleApi = Proxy
server :: Server SimpleAPI
server = return "Simple"
app :: Application
app = serve simpleApi server
main :: IO ()
main = do
runTLS (tlsSettings "server.crt" "server.key") (setPort 8080 defaultSettings) app
Dependencies
haskell-servant-cookbook.cabal
executable https-client
hs-source-dirs: https-client
main-is: Main.hs
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, text
, aeson
, http-client
, http-client-tls
, transformers
, servant
, servant-client
, haskell-servant-cookbook
default-language: Haskell2010
executable https-server
hs-source-dirs: https-server
main-is: Main.hs
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, text
, aeson
, wai
, warp
, warp-tls
, servant
, servant-server
, haskell-servant-cookbook
default-language: Haskell2010
参考文献
https://hackage.haskell.org/package/scotty-tls
http://d.hatena.ne.jp/ozuma/20130511/1368284304