module Wuss
( runSecureClient
, runSecureClientWith
, Config(..)
, defaultConfig
, runSecureClientWithConfig
) where
import qualified Control.Applicative as Applicative
import qualified Control.Exception as Exception
import qualified Data.Bool as Bool
import qualified Data.ByteString as StrictBytes
import qualified Data.ByteString.Lazy as LazyBytes
import qualified Data.Maybe as Maybe
import qualified Data.String as String
import qualified Network.Connection as Connection
import qualified Network.Socket as Socket
import qualified Network.WebSockets as WebSockets
import qualified Network.WebSockets.Stream as Stream
import qualified System.IO as IO
import qualified System.IO.Error as IO.Error
runSecureClient
:: Socket.HostName
-> Socket.PortNumber
-> String.String
-> WebSockets.ClientApp a
-> IO.IO a
runSecureClient host port path app = do
let options = WebSockets.defaultConnectionOptions
let headers = []
runSecureClientWith host port path options headers app
runSecureClientWith
:: Socket.HostName
-> Socket.PortNumber
-> String.String
-> WebSockets.ConnectionOptions
-> WebSockets.Headers
-> WebSockets.ClientApp a
-> IO.IO a
runSecureClientWith host port path options headers app = do
let config = defaultConfig
runSecureClientWithConfig host port path config options headers app
data Config = Config
{ connectionGet :: Connection.Connection -> IO.IO StrictBytes.ByteString
}
defaultConfig
:: Config
defaultConfig = do
Config
{ connectionGet = Connection.connectionGetChunk
}
runSecureClientWithConfig
:: Socket.HostName
-> Socket.PortNumber
-> String.String
-> Config
-> WebSockets.ConnectionOptions
-> WebSockets.Headers
-> WebSockets.ClientApp a
-> IO.IO a
runSecureClientWithConfig host port path config options headers app = do
context <- Connection.initConnectionContext
Exception.bracket
(Connection.connectTo context (connectionParams host port))
Connection.connectionClose
(\connection -> do
stream <-
Stream.makeStream (reader config connection) (writer connection)
WebSockets.runClientWithStream stream host path options headers app)
connectionParams
:: Socket.HostName
-> Socket.PortNumber
-> Connection.ConnectionParams
connectionParams host port = do
Connection.ConnectionParams
{ Connection.connectionHostname = host
, Connection.connectionPort = port
, Connection.connectionUseSecure = Maybe.Just tlsSettings
, Connection.connectionUseSocks = Maybe.Nothing
}
tlsSettings
:: Connection.TLSSettings
tlsSettings = do
Connection.TLSSettingsSimple
{ Connection.settingDisableCertificateValidation = Bool.False
, Connection.settingDisableSession = Bool.False
, Connection.settingUseServerName = Bool.False
}
reader
:: Config
-> Connection.Connection
-> IO.IO (Maybe.Maybe StrictBytes.ByteString)
reader config connection =
IO.Error.catchIOError (do
chunk <- (connectionGet config) connection
Applicative.pure (Maybe.Just chunk))
(\e ->
if IO.Error.isEOFError e
then Applicative.pure Maybe.Nothing
else Exception.throwIO e)
writer
:: Connection.Connection
-> Maybe.Maybe LazyBytes.ByteString
-> IO.IO ()
writer connection maybeBytes = do
case maybeBytes of
Maybe.Nothing -> do
Applicative.pure ()
Maybe.Just bytes -> do
Connection.connectionPut connection (LazyBytes.toStrict bytes)