LoginSignup
2
1

More than 5 years have passed since last update.

Haskell Servant 入門 (HTTPS対応)

Posted at

Https in Haskell with Servant

Servant を TLS(HTTPS) に対応させる方法を紹介します。
本記事のソースコードは以下のリポジトリにおいてあります。
http://github.com/algas/haskell-servant-cookbook
クライアントとサーバをそれぞれ HTTPS で扱えるようにします。
(サーバ側はリバースプロキシで対応することの方が多いと思いますが)

Client

http-client-tls を使います。
tlsManagerSettingsdefaultManagerSettings の代わりに用います。

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

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1