-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | A sensible and clean way to write WebSocket-capable servers in Haskell.
--
-- This library allows you to write WebSocket-capable servers.
--
-- An example server:
-- https://github.com/jaspervdj/websockets/blob/master/example/server.lhs
--
-- An example client:
-- https://github.com/jaspervdj/websockets/blob/master/example/client.hs
--
-- See also:
--
--
@package websockets
@version 0.12.5.0
-- | Lightweight abstraction over an input/output stream.
module Network.WebSockets.Stream
-- | Lightweight abstraction over an input/output stream.
data Stream
-- | Create a stream from a "receive" and "send" action. The following
-- properties apply:
--
--
-- - Regardless of the provided "receive" and "send" functions, reading
-- and writing from the stream will be thread-safe, i.e. this function
-- will create a receive and write lock to be used internally.
-- - Reading from or writing or to a closed Stream will always
-- throw an exception, even if the underlying "receive" and "send"
-- functions do not (we do the bookkeeping).
-- - Streams should always be closed.
--
makeStream :: IO (Maybe ByteString) -> (Maybe ByteString -> IO ()) -> IO Stream
makeSocketStream :: Socket -> IO Stream
makeEchoStream :: IO Stream
parse :: Stream -> Parser a -> IO (Maybe a)
parseBin :: Stream -> Get a -> IO (Maybe a)
write :: Stream -> ByteString -> IO ()
close :: Stream -> IO ()
module Network.WebSockets.Extensions
data ExtensionDescription
ExtensionDescription :: !ByteString -> ![ExtensionParam] -> ExtensionDescription
[extName] :: ExtensionDescription -> !ByteString
[extParams] :: ExtensionDescription -> ![ExtensionParam]
type ExtensionDescriptions = [ExtensionDescription]
parseExtensionDescriptions :: ByteString -> Either String ExtensionDescriptions
type NegotiateExtension = ExtensionDescriptions -> Either String Extension
-- | An extension is currently allowed to set extra headers and transform
-- the parse/write functions of Connection.
--
-- This type is very likely to change as other extensions are introduced.
data Extension
Extension :: Headers -> (IO (Maybe Message) -> IO (IO (Maybe Message))) -> (([Message] -> IO ()) -> IO ([Message] -> IO ())) -> Extension
[extHeaders] :: Extension -> Headers
[extParse] :: Extension -> IO (Maybe Message) -> IO (IO (Maybe Message))
[extWrite] :: Extension -> ([Message] -> IO ()) -> IO ([Message] -> IO ())
-- | This module exposes connection internals and should only be used if
-- you really know what you are doing.
module Network.WebSockets.Connection
-- | A new client connected to the server. We haven't accepted the
-- connection yet, though.
data PendingConnection
PendingConnection :: !ConnectionOptions -> !RequestHead -> !(Connection -> IO ()) -> !Stream -> PendingConnection
-- | Options, passed as-is to the Connection
[pendingOptions] :: PendingConnection -> !ConnectionOptions
-- | Useful for e.g. inspecting the request path.
[pendingRequest] :: PendingConnection -> !RequestHead
-- | One-shot callback fired when a connection is accepted, i.e., *after*
-- the accepting response is sent to the client.
[pendingOnAccept] :: PendingConnection -> !(Connection -> IO ())
-- | Input/output stream
[pendingStream] :: PendingConnection -> !Stream
-- | Accept a pending connection, turning it into a Connection.
acceptRequest :: PendingConnection -> IO Connection
-- | This datatype allows you to set options for acceptRequestWith.
-- It is strongly recommended to use defaultAcceptRequest and then
-- modify the various fields, that way new fields introduced in the
-- library do not break your code.
data AcceptRequest
AcceptRequest :: !(Maybe ByteString) -> !Headers -> AcceptRequest
-- | The subprotocol to speak with the client. If
-- pendingSubprotcols is non-empty, acceptSubprotocol
-- must be one of the subprotocols from the list.
[acceptSubprotocol] :: AcceptRequest -> !(Maybe ByteString)
-- | Extra headers to send with the response.
[acceptHeaders] :: AcceptRequest -> !Headers
defaultAcceptRequest :: AcceptRequest
-- | This function is like acceptRequest but allows you to set
-- custom options using the AcceptRequest datatype.
acceptRequestWith :: PendingConnection -> AcceptRequest -> IO Connection
rejectRequest :: PendingConnection -> ByteString -> IO ()
-- | Parameters that allow you to tweak how a request is rejected. Please
-- use defaultRejectRequest and modify fields using record syntax
-- so your code will not break when new fields are added.
data RejectRequest
RejectRequest :: !Int -> !ByteString -> Headers -> !ByteString -> RejectRequest
-- | The status code, 400 by default.
[rejectCode] :: RejectRequest -> !Int
-- | The message, "Bad Request" by default
[rejectMessage] :: RejectRequest -> !ByteString
-- | Extra headers to be sent with the response.
[rejectHeaders] :: RejectRequest -> Headers
-- | Reponse body of the rejection.
[rejectBody] :: RejectRequest -> !ByteString
defaultRejectRequest :: RejectRequest
rejectRequestWith :: PendingConnection -> RejectRequest -> IO ()
data Connection
Connection :: !ConnectionOptions -> !ConnectionType -> !Protocol -> !(IO (Maybe Message)) -> !([Message] -> IO ()) -> !(IORef Bool) -> Connection
[connectionOptions] :: Connection -> !ConnectionOptions
[connectionType] :: Connection -> !ConnectionType
[connectionProtocol] :: Connection -> !Protocol
[connectionParse] :: Connection -> !(IO (Maybe Message))
[connectionWrite] :: Connection -> !([Message] -> IO ())
-- | According to the RFC, both the client and the server MUST send a close
-- control message to each other. Either party can initiate the first
-- close message but then the other party must respond. Finally, the
-- server is in charge of closing the TCP connection. This IORef tracks
-- if we have sent a close message and are waiting for the peer to
-- respond.
[connectionSentClose] :: Connection -> !(IORef Bool)
-- | Set options for a Connection. Please do not use this
-- constructor directly, but rather use defaultConnectionOptions
-- and then set the fields you want, e.g.:
--
--
-- myOptions = defaultConnectionOptions {connectionStrictUnicode = True}
--
--
-- This way your code does not break if the library introduces new
-- fields.
data ConnectionOptions
ConnectionOptions :: !(IO ()) -> !CompressionOptions -> !Bool -> !SizeLimit -> !SizeLimit -> ConnectionOptions
-- | Whenever a pong is received, this IO action is executed. It
-- can be used to tickle connections or fire missiles.
[connectionOnPong] :: ConnectionOptions -> !(IO ())
-- | Enable PermessageDeflate.
[connectionCompressionOptions] :: ConnectionOptions -> !CompressionOptions
-- | Enable strict unicode on the connection. This means that if a client
-- (or server) sends invalid UTF-8, we will throw a
-- UnicodeException rather than replacing it by the unicode
-- replacement character U+FFFD.
[connectionStrictUnicode] :: ConnectionOptions -> !Bool
-- | The maximum size for incoming frame payload size in bytes. If a frame
-- exceeds this limit, a ParseException is thrown.
[connectionFramePayloadSizeLimit] :: ConnectionOptions -> !SizeLimit
-- | connectionFrameSizeLimit is often not enough since a
-- malicious client can send many small frames to create a huge message.
-- This limit allows you to protect from that. If a message exceeds this
-- limit, a ParseException is thrown.
--
-- Note that, if compression is enabled, we check the size of the
-- compressed messages, as well as the size of the uncompressed messages
-- as we are deflating them to ensure we don't use too much memory in any
-- case.
[connectionMessageDataSizeLimit] :: ConnectionOptions -> !SizeLimit
-- | The default connection options:
--
--
-- - Nothing happens when a pong is received.
-- - Compression is disabled.
-- - Lenient unicode decoding.
--
defaultConnectionOptions :: ConnectionOptions
receive :: Connection -> IO Message
-- | Receive an application message. Automatically respond to control
-- messages.
--
-- When the peer sends a close control message, an exception of type
-- CloseRequest is thrown. The peer can send a close control
-- message either to initiate a close or in response to a close message
-- we have sent to the peer. In either case the CloseRequest
-- exception will be thrown. The RFC specifies that the server is
-- responsible for closing the TCP connection, which should happen after
-- receiving the CloseRequest exception from this function.
--
-- This will throw ConnectionClosed if the TCP connection dies
-- unexpectedly.
receiveDataMessage :: Connection -> IO DataMessage
-- | Receive a message, converting it to whatever format is needed.
receiveData :: WebSocketsData a => Connection -> IO a
send :: Connection -> Message -> IO ()
-- | Send a DataMessage. This allows you send both human-readable
-- text and binary data. This is a slightly more low-level interface than
-- sendTextData or sendBinaryData.
sendDataMessage :: Connection -> DataMessage -> IO ()
-- | Send a collection of DataMessages. This is more efficient than
-- calling sendDataMessage many times.
sendDataMessages :: Connection -> [DataMessage] -> IO ()
-- | Send a textual message. The message will be encoded as UTF-8. This
-- should be the default choice for human-readable text-based protocols
-- such as JSON.
sendTextData :: WebSocketsData a => Connection -> a -> IO ()
-- | Send a number of textual messages. This is more efficient than calling
-- sendTextData many times.
sendTextDatas :: WebSocketsData a => Connection -> [a] -> IO ()
-- | Send a binary message. This is useful for sending binary blobs, e.g.
-- images, data encoded with MessagePack, images...
sendBinaryData :: WebSocketsData a => Connection -> a -> IO ()
-- | Send a number of binary messages. This is more efficient than calling
-- sendBinaryData many times.
sendBinaryDatas :: WebSocketsData a => Connection -> [a] -> IO ()
-- | Send a friendly close message. Note that after sending this message,
-- you should still continue calling receiveDataMessage to process
-- any in-flight messages. The peer will eventually respond with a close
-- control message of its own which will cause receiveDataMessage
-- to throw the CloseRequest exception. This exception is when you
-- can finally consider the connection closed.
sendClose :: WebSocketsData a => Connection -> a -> IO ()
-- | Send a friendly close message and close code. Similar to
-- sendClose, you should continue calling
-- receiveDataMessage until you receive a CloseRequest
-- exception.
--
-- See http://tools.ietf.org/html/rfc6455#section-7.4 for a list
-- of close codes.
sendCloseCode :: WebSocketsData a => Connection -> Word16 -> a -> IO ()
-- | Send a ping
sendPing :: WebSocketsData a => Connection -> a -> IO ()
-- | Forks a ping thread, sending a ping message every n seconds
-- over the connection. The thread dies silently if the connection
-- crashes or is closed.
--
-- This is useful to keep idle connections open through proxies and
-- whatnot. Many (but not all) proxies have a 60 second default timeout,
-- so based on that sending a ping every 30 seconds is a good idea.
forkPingThread :: Connection -> Int -> IO ()
data CompressionOptions
NoCompression :: CompressionOptions
PermessageDeflateCompression :: PermessageDeflate -> CompressionOptions
-- | Four extension parameters are defined for "permessage-deflate" to help
-- endpoints manage per-connection resource usage.
--
--
-- - "server_no_context_takeover"
-- - "client_no_context_takeover"
-- - "server_max_window_bits"
-- - "client_max_window_bits"
--
data PermessageDeflate
PermessageDeflate :: Bool -> Bool -> Int -> Int -> Int -> PermessageDeflate
[serverNoContextTakeover] :: PermessageDeflate -> Bool
[clientNoContextTakeover] :: PermessageDeflate -> Bool
[serverMaxWindowBits] :: PermessageDeflate -> Int
[clientMaxWindowBits] :: PermessageDeflate -> Int
[pdCompressionLevel] :: PermessageDeflate -> Int
defaultPermessageDeflate :: PermessageDeflate
-- | A size limit, in bytes. The Monoid instance takes the minimum
-- limit.
data SizeLimit
NoSizeLimit :: SizeLimit
SizeLimit :: !Int64 -> SizeLimit
module Network.WebSockets
-- | A new client connected to the server. We haven't accepted the
-- connection yet, though.
data PendingConnection
-- | Useful for e.g. inspecting the request path.
pendingRequest :: PendingConnection -> RequestHead
-- | Accept a pending connection, turning it into a Connection.
acceptRequest :: PendingConnection -> IO Connection
-- | This datatype allows you to set options for acceptRequestWith.
-- It is strongly recommended to use defaultAcceptRequest and then
-- modify the various fields, that way new fields introduced in the
-- library do not break your code.
data AcceptRequest
AcceptRequest :: !(Maybe ByteString) -> !Headers -> AcceptRequest
-- | The subprotocol to speak with the client. If
-- pendingSubprotcols is non-empty, acceptSubprotocol
-- must be one of the subprotocols from the list.
[acceptSubprotocol] :: AcceptRequest -> !(Maybe ByteString)
-- | Extra headers to send with the response.
[acceptHeaders] :: AcceptRequest -> !Headers
defaultAcceptRequest :: AcceptRequest
-- | This function is like acceptRequest but allows you to set
-- custom options using the AcceptRequest datatype.
acceptRequestWith :: PendingConnection -> AcceptRequest -> IO Connection
rejectRequest :: PendingConnection -> ByteString -> IO ()
-- | Parameters that allow you to tweak how a request is rejected. Please
-- use defaultRejectRequest and modify fields using record syntax
-- so your code will not break when new fields are added.
data RejectRequest
RejectRequest :: !Int -> !ByteString -> Headers -> !ByteString -> RejectRequest
-- | The status code, 400 by default.
[rejectCode] :: RejectRequest -> !Int
-- | The message, "Bad Request" by default
[rejectMessage] :: RejectRequest -> !ByteString
-- | Extra headers to be sent with the response.
[rejectHeaders] :: RejectRequest -> Headers
-- | Reponse body of the rejection.
[rejectBody] :: RejectRequest -> !ByteString
defaultRejectRequest :: RejectRequest
rejectRequestWith :: PendingConnection -> RejectRequest -> IO ()
data Connection
-- | Set options for a Connection. Please do not use this
-- constructor directly, but rather use defaultConnectionOptions
-- and then set the fields you want, e.g.:
--
--
-- myOptions = defaultConnectionOptions {connectionStrictUnicode = True}
--
--
-- This way your code does not break if the library introduces new
-- fields.
data ConnectionOptions
ConnectionOptions :: !(IO ()) -> !CompressionOptions -> !Bool -> !SizeLimit -> !SizeLimit -> ConnectionOptions
-- | Whenever a pong is received, this IO action is executed. It
-- can be used to tickle connections or fire missiles.
[connectionOnPong] :: ConnectionOptions -> !(IO ())
-- | Enable PermessageDeflate.
[connectionCompressionOptions] :: ConnectionOptions -> !CompressionOptions
-- | Enable strict unicode on the connection. This means that if a client
-- (or server) sends invalid UTF-8, we will throw a
-- UnicodeException rather than replacing it by the unicode
-- replacement character U+FFFD.
[connectionStrictUnicode] :: ConnectionOptions -> !Bool
-- | The maximum size for incoming frame payload size in bytes. If a frame
-- exceeds this limit, a ParseException is thrown.
[connectionFramePayloadSizeLimit] :: ConnectionOptions -> !SizeLimit
-- | connectionFrameSizeLimit is often not enough since a
-- malicious client can send many small frames to create a huge message.
-- This limit allows you to protect from that. If a message exceeds this
-- limit, a ParseException is thrown.
--
-- Note that, if compression is enabled, we check the size of the
-- compressed messages, as well as the size of the uncompressed messages
-- as we are deflating them to ensure we don't use too much memory in any
-- case.
[connectionMessageDataSizeLimit] :: ConnectionOptions -> !SizeLimit
-- | The default connection options:
--
--
-- - Nothing happens when a pong is received.
-- - Compression is disabled.
-- - Lenient unicode decoding.
--
defaultConnectionOptions :: ConnectionOptions
data CompressionOptions
NoCompression :: CompressionOptions
PermessageDeflateCompression :: PermessageDeflate -> CompressionOptions
-- | Four extension parameters are defined for "permessage-deflate" to help
-- endpoints manage per-connection resource usage.
--
--
-- - "server_no_context_takeover"
-- - "client_no_context_takeover"
-- - "server_max_window_bits"
-- - "client_max_window_bits"
--
data PermessageDeflate
PermessageDeflate :: Bool -> Bool -> Int -> Int -> Int -> PermessageDeflate
[serverNoContextTakeover] :: PermessageDeflate -> Bool
[clientNoContextTakeover] :: PermessageDeflate -> Bool
[serverMaxWindowBits] :: PermessageDeflate -> Int
[clientMaxWindowBits] :: PermessageDeflate -> Int
[pdCompressionLevel] :: PermessageDeflate -> Int
defaultPermessageDeflate :: PermessageDeflate
-- | A size limit, in bytes. The Monoid instance takes the minimum
-- limit.
data SizeLimit
NoSizeLimit :: SizeLimit
SizeLimit :: !Int64 -> SizeLimit
receive :: Connection -> IO Message
-- | Receive an application message. Automatically respond to control
-- messages.
--
-- When the peer sends a close control message, an exception of type
-- CloseRequest is thrown. The peer can send a close control
-- message either to initiate a close or in response to a close message
-- we have sent to the peer. In either case the CloseRequest
-- exception will be thrown. The RFC specifies that the server is
-- responsible for closing the TCP connection, which should happen after
-- receiving the CloseRequest exception from this function.
--
-- This will throw ConnectionClosed if the TCP connection dies
-- unexpectedly.
receiveDataMessage :: Connection -> IO DataMessage
-- | Receive a message, converting it to whatever format is needed.
receiveData :: WebSocketsData a => Connection -> IO a
send :: Connection -> Message -> IO ()
-- | Send a DataMessage. This allows you send both human-readable
-- text and binary data. This is a slightly more low-level interface than
-- sendTextData or sendBinaryData.
sendDataMessage :: Connection -> DataMessage -> IO ()
-- | Send a collection of DataMessages. This is more efficient than
-- calling sendDataMessage many times.
sendDataMessages :: Connection -> [DataMessage] -> IO ()
-- | Send a textual message. The message will be encoded as UTF-8. This
-- should be the default choice for human-readable text-based protocols
-- such as JSON.
sendTextData :: WebSocketsData a => Connection -> a -> IO ()
-- | Send a number of textual messages. This is more efficient than calling
-- sendTextData many times.
sendTextDatas :: WebSocketsData a => Connection -> [a] -> IO ()
-- | Send a binary message. This is useful for sending binary blobs, e.g.
-- images, data encoded with MessagePack, images...
sendBinaryData :: WebSocketsData a => Connection -> a -> IO ()
-- | Send a number of binary messages. This is more efficient than calling
-- sendBinaryData many times.
sendBinaryDatas :: WebSocketsData a => Connection -> [a] -> IO ()
-- | Send a friendly close message. Note that after sending this message,
-- you should still continue calling receiveDataMessage to process
-- any in-flight messages. The peer will eventually respond with a close
-- control message of its own which will cause receiveDataMessage
-- to throw the CloseRequest exception. This exception is when you
-- can finally consider the connection closed.
sendClose :: WebSocketsData a => Connection -> a -> IO ()
-- | Send a friendly close message and close code. Similar to
-- sendClose, you should continue calling
-- receiveDataMessage until you receive a CloseRequest
-- exception.
--
-- See http://tools.ietf.org/html/rfc6455#section-7.4 for a list
-- of close codes.
sendCloseCode :: WebSocketsData a => Connection -> Word16 -> a -> IO ()
-- | Send a ping
sendPing :: WebSocketsData a => Connection -> a -> IO ()
-- | Request headers
type Headers = [(CI ByteString, ByteString)]
-- | A request with a body
data Request
Request :: RequestHead -> ByteString -> Request
-- | An HTTP request. The request body is not yet read.
data RequestHead
RequestHead :: !ByteString -> Headers -> Bool -> RequestHead
[requestPath] :: RequestHead -> !ByteString
[requestHeaders] :: RequestHead -> Headers
[requestSecure] :: RequestHead -> Bool
-- | List of subprotocols specified by the client, in order of preference.
-- If the client did not specify a list of subprotocols, this will be the
-- empty list.
getRequestSubprotocols :: RequestHead -> [ByteString]
-- | A response including a body
data Response
Response :: ResponseHead -> ByteString -> Response
-- | HTTP response, without body.
data ResponseHead
ResponseHead :: !Int -> !ByteString -> Headers -> ResponseHead
[responseCode] :: ResponseHead -> !Int
[responseMessage] :: ResponseHead -> !ByteString
[responseHeaders] :: ResponseHead -> Headers
-- | The kind of message a server application typically deals with
data Message
ControlMessage :: ControlMessage -> Message
-- | Reserved bits, actual message
DataMessage :: Bool -> Bool -> Bool -> DataMessage -> Message
-- | Different control messages
data ControlMessage
Close :: Word16 -> ByteString -> ControlMessage
Ping :: ByteString -> ControlMessage
Pong :: ByteString -> ControlMessage
-- | For an end-user of this library, dealing with Frames would be
-- a bit low-level. This is why define another type on top of it, which
-- represents data for the application layer.
--
-- There are currently two kinds of data messages supported by the
-- WebSockets protocol:
--
--
-- - Textual UTF-8 encoded data. This corresponds roughly to sending a
-- String in JavaScript.
-- - Binary data. This corresponds roughly to send an ArrayBuffer in
-- JavaScript.
--
data DataMessage
-- | A textual message. The second field might contain the decoded
-- UTF-8 text for caching reasons. This field is computed lazily so if
-- it's not accessed, it should have no performance impact.
Text :: ByteString -> (Maybe Text) -> DataMessage
-- | A binary message.
Binary :: ByteString -> DataMessage
-- | In order to have an even more high-level API, we define a typeclass
-- for values the user can receive from and send to the socket. A few
-- warnings apply:
--
--
-- - Natively, everything is represented as a ByteString, so
-- this is the fastest instance
-- - You should only use the Text or the Text instance
-- when you are sure that the data is UTF-8 encoded (which is the case
-- for Text messages).
-- - Messages can be very large. If this is the case, it might be
-- inefficient to use the strict ByteString and Text
-- instances.
--
class WebSocketsData a
fromDataMessage :: WebSocketsData a => DataMessage -> a
fromLazyByteString :: WebSocketsData a => ByteString -> a
toLazyByteString :: WebSocketsData a => a -> ByteString
-- | Error in case of failed handshake. Will be thrown as an
-- Exception.
--
-- TODO: This should probably be in the Handshake module, and is solely
-- here to prevent a cyclic dependency.
data HandshakeException
-- | We don't have a match for the protocol requested by the client. todo:
-- version parameter
NotSupported :: HandshakeException
-- | The request was somehow invalid (missing headers or wrong security
-- token)
MalformedRequest :: RequestHead -> String -> HandshakeException
-- | The servers response was somehow invalid (missing headers or wrong
-- security token)
MalformedResponse :: ResponseHead -> String -> HandshakeException
-- | The request was well-formed, but the library user rejected it. (e.g.
-- "unknown path")
RequestRejected :: Request -> String -> HandshakeException
-- | for example "EOF came too early" (which is actually a parse error) or
-- for your own errors. (like "unknown path"?)
OtherHandshakeException :: String -> HandshakeException
-- | Various exceptions that can occur while receiving or transmitting
-- messages
data ConnectionException
-- | The peer has requested that the connection be closed, and included a
-- close code and a reason for closing. When receiving this exception, no
-- more messages can be sent. Also, the server is responsible for closing
-- the TCP connection once this exception is received.
--
-- See http://tools.ietf.org/html/rfc6455#section-7.4 for a list
-- of close codes.
CloseRequest :: Word16 -> ByteString -> ConnectionException
-- | The peer unexpectedly closed the connection while we were trying to
-- receive some data. This is a violation of the websocket RFC since the
-- TCP connection should only be closed after sending and receiving close
-- control messages.
ConnectionClosed :: ConnectionException
-- | The client sent garbage, i.e. we could not parse the WebSockets
-- stream.
ParseException :: String -> ConnectionException
-- | The client sent invalid UTF-8. Note that this exception will only be
-- thrown if strict decoding is set in the connection options.
UnicodeException :: String -> ConnectionException
-- | WebSockets application that can be ran by a server. Once this
-- IO action finishes, the underlying socket is closed
-- automatically.
type ServerApp = PendingConnection -> IO ()
-- | Provides a simple server. This function blocks forever. Note that this
-- is merely provided for quick-and-dirty or internal applications, but
-- for real applications, you should use a real server.
--
-- For example:
--
--
-- - Performance is reasonable under load, but:
-- - No protection against DoS attacks is provided.
-- - No logging is performed.
-- - ...
--
--
-- Glue for using this package with real servers is provided by:
--
--
runServer :: String -> Int -> ServerApp -> IO ()
-- | A version of runServer which allows you to customize some
-- options.
runServerWith :: String -> Int -> ConnectionOptions -> ServerApp -> IO ()
-- | Create a standardized socket on which you can listen for incomming
-- connections. Should only be used for a quick and dirty solution!
-- Should be preceded by the call withSocketsDo.
makeListenSocket :: String -> Int -> IO Socket
-- | Turns a socket, connected to some client, into a
-- PendingConnection. The PendingConnection should be
-- closed using close later.
makePendingConnection :: Socket -> ConnectionOptions -> IO PendingConnection
-- | More general version of makePendingConnection for Stream
-- instead of a Socket.
makePendingConnectionFromStream :: Stream -> ConnectionOptions -> IO PendingConnection
-- | A client application interacting with a single server. Once this
-- IO action finished, the underlying socket is closed
-- automatically.
type ClientApp a = Connection -> IO a
runClient :: String -> Int -> String -> ClientApp a -> IO a
runClientWith :: String -> Int -> String -> ConnectionOptions -> Headers -> ClientApp a -> IO a
runClientWithSocket :: Socket -> String -> String -> ConnectionOptions -> Headers -> ClientApp a -> IO a
runClientWithStream :: Stream -> String -> String -> ConnectionOptions -> Headers -> ClientApp a -> IO a
-- | Build a new Connection from the client's point of view.
--
-- WARNING: Be sure to call close on the given
-- Stream after you are done using the Connection in order
-- to properly close the communication channel.
-- runClientWithStream handles this for you, prefer to use it when
-- possible.
newClientConnection :: Stream -> String -> String -> ConnectionOptions -> Headers -> IO Connection
-- | Forks a ping thread, sending a ping message every n seconds
-- over the connection. The thread dies silently if the connection
-- crashes or is closed.
--
-- This is useful to keep idle connections open through proxies and
-- whatnot. Many (but not all) proxies have a 60 second default timeout,
-- so based on that sending a ping every 30 seconds is a good idea.
forkPingThread :: Connection -> Int -> IO ()