{-# OPTIONS_GHC -fno-warn-orphans #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeOperators #-} module Main where import Control.Concurrent.Async (mapConcurrently) import qualified Data.ByteString.Char8 as ByteString import Data.ByteString.Lazy (fromStrict, toStrict) import Data.Default.Class (def) import Data.Text (Text) import qualified Data.Text as Text import Data.Text.Encoding as Encoding import Data.Proxy import Network.HTTP2.Client import Network.HTTP2.Client.Servant import qualified Network.TLS as TLS import qualified Network.TLS.Extra.Cipher as TLS import Servant.API import Servant.Client.Core data RawText instance Accept RawText where contentType _ = "text/plain" instance MimeRender RawText Text where mimeRender _ = fromStrict . Encoding.encodeUtf8 instance MimeUnrender RawText Text where mimeUnrender _ = pure . Encoding.decodeUtf8 . toStrict instance MimeUnrender OctetStream Text where mimeUnrender _ = pure . Encoding.decodeUtf8 . toStrict type Http2Golang = "reqinfo" :> Get '[RawText] Text :<|> "goroutines" :> StreamGet NewlineFraming RawText (ResultStream Text) :<|> "ECHO" :> ReqBody '[RawText] Text :> Put '[OctetStream] Text myApi :: Proxy Http2Golang myApi = Proxy getExample :: H2ClientM Text getGoroutines :: H2ClientM (ResultStream Text) capitalize :: Text -> H2ClientM Text getExample :<|> getGoroutines :<|> capitalize = h2client myApi main :: IO () main = do frameConn <- newHttp2FrameConnection "http2.golang.org" 443 (Just tlsParams) client <- newHttp2Client frameConn 8192 8192 [] defaultGoAwayHandler ignoreFallbackHandler let env = H2ClientEnv "http2.golang.org" client runH2ClientM getExample env >>= print runH2ClientM (capitalize "shout me something back") env >>= print mapConcurrently (\c -> runH2ClientM (capitalize $ Text.singleton c) env) ['a'..'z'] >>= print runH2ClientM getGoroutines env >>= go _close client where go :: Either ServantError (ResultStream Text) -> IO () go (Left err) = print err go (Right (ResultStream k)) = k $ \getResult -> let loop = do r <- getResult case r of Nothing -> return () Just x -> print x >> loop in loop tlsParams = TLS.ClientParams { TLS.clientWantSessionResume = Nothing , TLS.clientUseMaxFragmentLength = Nothing , TLS.clientServerIdentification = ("http2.golang.org", ByteString.pack "443") , TLS.clientUseServerNameIndication = True , TLS.clientShared = def , TLS.clientHooks = def { TLS.onServerCertificate = \_ _ _ _ -> return [] } , TLS.clientSupported = def { TLS.supportedCiphers = TLS.ciphersuite_default } , TLS.clientDebug = def }