-- 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:
--   <a>https://github.com/jaspervdj/websockets/blob/master/example/server.lhs</a>
--   
--   An example client:
--   <a>https://github.com/jaspervdj/websockets/blob/master/example/client.hs</a>
--   
--   This package only supports insecure (<tt>ws://...</tt>) WebSockets. If
--   you need secure (<tt>wss://...</tt>) websockets, consider using Wuss:
--   <a>https://hackage.haskell.org/package/wuss</a>
--   
--   See also:
--   
--   <ul>
--   <li>The specification of the WebSocket protocol:
--   <a>http://www.whatwg.org/specs/web-socket-protocol/</a></li>
--   <li>The JavaScript API for dealing with WebSockets:
--   <a>http://www.w3.org/TR/websockets/</a></li>
--   </ul>
@package websockets
@version 0.13.0.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:
--   
--   <ul>
--   <li>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.</li>
--   <li>Reading from or writing to a closed <a>Stream</a> will always
--   throw an exception, even if the underlying "receive" and "send"
--   functions do not (we do the bookkeeping).</li>
--   <li>Streams should always be closed.</li>
--   </ul>
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 <tt>Connection</tt>.
--   
--   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
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 <a>Connection</a>
[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 <a>Connection</a>.
acceptRequest :: PendingConnection -> IO Connection

-- | This datatype allows you to set options for <a>acceptRequestWith</a>.
--   It is strongly recommended to use <a>defaultAcceptRequest</a> 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
--   <tt>pendingSubprotcols</tt> is non-empty, <a>acceptSubprotocol</a>
--   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 <a>acceptRequest</a> but allows you to set
--   custom options using the <a>AcceptRequest</a> datatype.
acceptRequestWith :: PendingConnection -> AcceptRequest -> IO Connection

-- | Requires calling <a>pendingStream</a> and <a>close</a>.
rejectRequest :: PendingConnection -> ByteString -> IO ()

-- | Parameters that allow you to tweak how a request is rejected. Please
--   use <a>defaultRejectRequest</a> 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 -> !MVar () -> !IO (Maybe Message) -> ![Message] -> IO () -> !IORef Bool -> Connection
[connectionOptions] :: Connection -> !ConnectionOptions
[connectionType] :: Connection -> !ConnectionType
[connectionProtocol] :: Connection -> !Protocol

-- | This MVar is filled whenever a pong is received. This is used by
--   <tt>withPingPong</tt> to timeout the connection if a pong is not
--   received.
[connectionHeartbeat] :: Connection -> !MVar ()
[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 <tt>Connection</tt>. Please do not use this
--   constructor directly, but rather use <a>defaultConnectionOptions</a>
--   and then set the fields you want, e.g.:
--   
--   <pre>
--   myOptions = defaultConnectionOptions {connectionStrictUnicode = True}
--   </pre>
--   
--   This way your code does not break if the library introduces new
--   fields.
data ConnectionOptions
ConnectionOptions :: !IO () -> !Int -> !CompressionOptions -> !Bool -> !SizeLimit -> !SizeLimit -> ConnectionOptions

-- | Whenever a <tt>pong</tt> is received, this IO action is executed. It
--   can be used to tickle connections or fire missiles.
[connectionOnPong] :: ConnectionOptions -> !IO ()

-- | Timeout for connection establishment in seconds. Only used in the
--   client.
[connectionTimeout] :: ConnectionOptions -> !Int

-- | Enable <a>PermessageDeflate</a>.
[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
--   <tt>UnicodeException</tt> 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 <tt>ParseException</tt> is thrown.
[connectionFramePayloadSizeLimit] :: ConnectionOptions -> !SizeLimit

-- | <tt>connectionFrameSizeLimit</tt> 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 <tt>ParseException</tt> 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:
--   
--   <ul>
--   <li>Nothing happens when a pong is received.</li>
--   <li>Compression is disabled.</li>
--   <li>Lenient unicode decoding.</li>
--   <li>30 second timeout for connection establishment.</li>
--   </ul>
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
--   <a>CloseRequest</a> 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 <a>CloseRequest</a>
--   exception will be thrown. The RFC specifies that the server is
--   responsible for closing the TCP connection, which should happen after
--   receiving the <a>CloseRequest</a> exception from this function.
--   
--   This will throw <a>ConnectionClosed</a> 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 <a>DataMessage</a>. This allows you send both human-readable
--   text and binary data. This is a slightly more low-level interface than
--   <a>sendTextData</a> or <a>sendBinaryData</a>.
sendDataMessage :: Connection -> DataMessage -> IO ()

-- | Send a collection of <a>DataMessage</a>s. This is more efficient than
--   calling <a>sendDataMessage</a> 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
--   <a>sendTextData</a> 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
--   <a>sendBinaryData</a> many times.
sendBinaryDatas :: WebSocketsData a => Connection -> [a] -> IO ()

-- | Send a friendly close message. Note that after sending this message,
--   you should still continue calling <a>receiveDataMessage</a> to process
--   any in-flight messages. The peer will eventually respond with a close
--   control message of its own which will cause <a>receiveDataMessage</a>
--   to throw the <a>CloseRequest</a> 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
--   <a>sendClose</a>, you should continue calling
--   <a>receiveDataMessage</a> until you receive a <a>CloseRequest</a>
--   exception.
--   
--   See <a>http://tools.ietf.org/html/rfc6455#section-7.4</a> for a list
--   of close codes.
sendCloseCode :: WebSocketsData a => Connection -> Word16 -> a -> IO ()

-- | Send a ping
sendPing :: WebSocketsData a => Connection -> a -> IO ()

-- | Send a pong
sendPong :: WebSocketsData a => Connection -> a -> IO ()

-- | Forks a ping thread, sending a ping message every <tt>n</tt> seconds
--   over the connection. The thread is killed when the inner IO action is
--   finished.
--   
--   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.
--   
--   Note that usually you want to use <a>withPingPong</a> to timeout the
--   connection if a pong is not received.
withPingThread :: Connection -> Int -> IO () -> IO a -> IO a

-- | DEPRECATED: Use <a>withPingThread</a> instead.
--   
--   Forks a ping thread, sending a ping message every <tt>n</tt> 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.

-- | <i>Deprecated: Use <a>withPingThread</a> instead</i>
forkPingThread :: Connection -> Int -> IO ()

-- | Use this if you want to run the ping thread yourself.
--   
--   See also <a>withPingThread</a>.
pingThread :: Connection -> Int -> IO () -> IO ()
data CompressionOptions
NoCompression :: CompressionOptions
PermessageDeflateCompression :: PermessageDeflate -> CompressionOptions

-- | Four extension parameters are defined for "permessage-deflate" to help
--   endpoints manage per-connection resource usage.
--   
--   <ul>
--   <li>"server_no_context_takeover"</li>
--   <li>"client_no_context_takeover"</li>
--   <li>"server_max_window_bits"</li>
--   <li>"client_max_window_bits"</li>
--   </ul>
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 <a>Monoid</a> instance takes the minimum
--   limit.
data SizeLimit
NoSizeLimit :: SizeLimit
SizeLimit :: !Int64 -> SizeLimit

module Network.WebSockets.Connection.PingPong

-- | Run an application with ping-pong enabled. Raises PongTimeout if a
--   pong is not received.
--   
--   Can used with Client and Server connections.
withPingPong :: PingPongOptions -> Connection -> (Connection -> IO ()) -> IO ()

-- | Options for ping-pong
--   
--   Make sure that the ping interval is less than the pong timeout, for
--   example N/2.
data PingPongOptions
PingPongOptions :: Int -> Int -> IO () -> PingPongOptions

-- | Interval in seconds
[pingInterval] :: PingPongOptions -> Int

-- | Timeout in seconds
[pongTimeout] :: PingPongOptions -> Int

-- | Action to perform after sending a ping
[pingAction] :: PingPongOptions -> IO ()

-- | Exception type used to kill connections if there is a pong timeout.
data PongTimeout
PongTimeout :: PongTimeout

-- | Default options for ping-pong
--   
--   Ping every 15 seconds, timeout after 30 seconds
defaultPingPongOptions :: PingPongOptions
instance GHC.Internal.Exception.Type.Exception Network.WebSockets.Connection.PingPong.PongTimeout
instance GHC.Internal.Show.Show Network.WebSockets.Connection.PingPong.PongTimeout


-- | This part of the library provides you with utilities to create
--   WebSockets clients (in addition to servers).
module Network.WebSockets.Client

-- | A client application interacting with a single server. Once this
--   <a>IO</a> 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 <a>Connection</a> from the client's point of view.
--   
--   <i>WARNING</i>: Be sure to call <a>close</a> on the given
--   <a>Stream</a> after you are done using the <a>Connection</a> in order
--   to properly close the communication channel.
--   <a>runClientWithStream</a> handles this for you, prefer to use it when
--   possible.
newClientConnection :: Stream -> String -> String -> ConnectionOptions -> Headers -> IO Connection
createRequest :: Protocol -> ByteString -> ByteString -> Bool -> Headers -> IO RequestHead
data Protocol
Hybi13 :: Protocol
defaultProtocol :: Protocol

-- | Check the response from the server. Throws
--   <a>OtherHandshakeException</a> on failure
checkServerResponse :: Stream -> RequestHead -> IO ()

-- | Build a <a>Connection</a> from a pre-established stream with already
--   finished handshake.
--   
--   <i>NB</i>: this will not perform any handshaking.
streamToClientConnection :: Stream -> ConnectionOptions -> IO Connection

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 <a>Connection</a>.
acceptRequest :: PendingConnection -> IO Connection

-- | This datatype allows you to set options for <a>acceptRequestWith</a>.
--   It is strongly recommended to use <a>defaultAcceptRequest</a> 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
--   <tt>pendingSubprotcols</tt> is non-empty, <a>acceptSubprotocol</a>
--   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 <a>acceptRequest</a> but allows you to set
--   custom options using the <a>AcceptRequest</a> datatype.
acceptRequestWith :: PendingConnection -> AcceptRequest -> IO Connection

-- | Requires calling <a>pendingStream</a> and <a>close</a>.
rejectRequest :: PendingConnection -> ByteString -> IO ()

-- | Parameters that allow you to tweak how a request is rejected. Please
--   use <a>defaultRejectRequest</a> 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 <tt>Connection</tt>. Please do not use this
--   constructor directly, but rather use <a>defaultConnectionOptions</a>
--   and then set the fields you want, e.g.:
--   
--   <pre>
--   myOptions = defaultConnectionOptions {connectionStrictUnicode = True}
--   </pre>
--   
--   This way your code does not break if the library introduces new
--   fields.
data ConnectionOptions
ConnectionOptions :: !IO () -> !Int -> !CompressionOptions -> !Bool -> !SizeLimit -> !SizeLimit -> ConnectionOptions

-- | Whenever a <tt>pong</tt> is received, this IO action is executed. It
--   can be used to tickle connections or fire missiles.
[connectionOnPong] :: ConnectionOptions -> !IO ()

-- | Timeout for connection establishment in seconds. Only used in the
--   client.
[connectionTimeout] :: ConnectionOptions -> !Int

-- | Enable <a>PermessageDeflate</a>.
[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
--   <tt>UnicodeException</tt> 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 <tt>ParseException</tt> is thrown.
[connectionFramePayloadSizeLimit] :: ConnectionOptions -> !SizeLimit

-- | <tt>connectionFrameSizeLimit</tt> 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 <tt>ParseException</tt> 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:
--   
--   <ul>
--   <li>Nothing happens when a pong is received.</li>
--   <li>Compression is disabled.</li>
--   <li>Lenient unicode decoding.</li>
--   <li>30 second timeout for connection establishment.</li>
--   </ul>
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.
--   
--   <ul>
--   <li>"server_no_context_takeover"</li>
--   <li>"client_no_context_takeover"</li>
--   <li>"server_max_window_bits"</li>
--   <li>"client_max_window_bits"</li>
--   </ul>
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 <a>Monoid</a> 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
--   <a>CloseRequest</a> 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 <a>CloseRequest</a>
--   exception will be thrown. The RFC specifies that the server is
--   responsible for closing the TCP connection, which should happen after
--   receiving the <a>CloseRequest</a> exception from this function.
--   
--   This will throw <a>ConnectionClosed</a> 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 <a>DataMessage</a>. This allows you send both human-readable
--   text and binary data. This is a slightly more low-level interface than
--   <a>sendTextData</a> or <a>sendBinaryData</a>.
sendDataMessage :: Connection -> DataMessage -> IO ()

-- | Send a collection of <a>DataMessage</a>s. This is more efficient than
--   calling <a>sendDataMessage</a> 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
--   <a>sendTextData</a> 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
--   <a>sendBinaryData</a> many times.
sendBinaryDatas :: WebSocketsData a => Connection -> [a] -> IO ()

-- | Send a friendly close message. Note that after sending this message,
--   you should still continue calling <a>receiveDataMessage</a> to process
--   any in-flight messages. The peer will eventually respond with a close
--   control message of its own which will cause <a>receiveDataMessage</a>
--   to throw the <a>CloseRequest</a> 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
--   <a>sendClose</a>, you should continue calling
--   <a>receiveDataMessage</a> until you receive a <a>CloseRequest</a>
--   exception.
--   
--   See <a>http://tools.ietf.org/html/rfc6455#section-7.4</a> 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 <tt>Frame</tt>s 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:
--   
--   <ul>
--   <li>Textual UTF-8 encoded data. This corresponds roughly to sending a
--   String in JavaScript.</li>
--   <li>Binary data. This corresponds roughly to send an ArrayBuffer in
--   JavaScript.</li>
--   </ul>
data DataMessage

-- | A textual message. The second field <i>might</i> 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:
--   
--   <ul>
--   <li>Natively, everything is represented as a <a>ByteString</a>, so
--   this is the fastest instance</li>
--   <li>You should only use the <a>Text</a> or the <a>Text</a> instance
--   when you are sure that the data is UTF-8 encoded (which is the case
--   for <a>Text</a> messages).</li>
--   <li>Messages can be very large. If this is the case, it might be
--   inefficient to use the strict <a>ByteString</a> and <a>Text</a>
--   instances.</li>
--   </ul>
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
--   <a>Exception</a>.
--   
--   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 :: RequestHead -> ResponseHead -> HandshakeException

-- | The connection timed out
ConnectionTimeout :: 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 <a>http://tools.ietf.org/html/rfc6455#section-7.4</a> 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
--   <a>IO</a> 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:
--   
--   <ul>
--   <li>Performance is reasonable under load, but:</li>
--   <li>No protection against DoS attacks is provided.</li>
--   <li>No logging is performed.</li>
--   <li>...</li>
--   </ul>
--   
--   Glue for using this package with real servers is provided by:
--   
--   <ul>
--   <li><a>https://hackage.haskell.org/package/wai-websockets</a></li>
--   <li><a>https://hackage.haskell.org/package/websockets-snap</a></li>
--   </ul>
runServer :: String -> Int -> ServerApp -> IO ()

-- | A version of <a>runServer</a> which allows you to customize some
--   options.

-- | <i>Deprecated: Use <a>runServerWithOptions</a> instead</i>
runServerWith :: String -> Int -> ConnectionOptions -> ServerApp -> IO ()
data ServerOptions
ServerOptions :: String -> Int -> ConnectionOptions -> ServerOptions
[serverHost] :: ServerOptions -> String
[serverPort] :: ServerOptions -> Int
[serverConnectionOptions] :: ServerOptions -> ConnectionOptions
defaultServerOptions :: ServerOptions

-- | Customizable version of <a>runServer</a>. Never returns until killed.
--   
--   Please use the <a>defaultServerOptions</a> combined with record
--   updates to set the fields you want. This way your code is unlikely to
--   break on future changes.
runServerWithOptions :: ServerOptions -> ServerApp -> IO a

-- | 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 <a>withSocketsDo</a>.
makeListenSocket :: String -> Int -> IO Socket

-- | Turns a socket, connected to some client, into a
--   <a>PendingConnection</a>. The <a>PendingConnection</a> should be
--   closed using <a>pendingStream</a> and <a>close</a> later.
makePendingConnection :: Socket -> ConnectionOptions -> IO PendingConnection

-- | More general version of <a>makePendingConnection</a> for <a>Stream</a>
--   instead of a <a>Socket</a>.
makePendingConnectionFromStream :: Stream -> ConnectionOptions -> IO PendingConnection

-- | A client application interacting with a single server. Once this
--   <a>IO</a> 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 <a>Connection</a> from the client's point of view.
--   
--   <i>WARNING</i>: Be sure to call <a>close</a> on the given
--   <a>Stream</a> after you are done using the <a>Connection</a> in order
--   to properly close the communication channel.
--   <a>runClientWithStream</a> handles this for you, prefer to use it when
--   possible.
newClientConnection :: Stream -> String -> String -> ConnectionOptions -> Headers -> IO Connection

-- | Options for ping-pong
--   
--   Make sure that the ping interval is less than the pong timeout, for
--   example N/2.
data PingPongOptions
PingPongOptions :: Int -> Int -> IO () -> PingPongOptions

-- | Interval in seconds
[pingInterval] :: PingPongOptions -> Int

-- | Timeout in seconds
[pongTimeout] :: PingPongOptions -> Int

-- | Action to perform after sending a ping
[pingAction] :: PingPongOptions -> IO ()

-- | Default options for ping-pong
--   
--   Ping every 15 seconds, timeout after 30 seconds
defaultPingPongOptions :: PingPongOptions

-- | Run an application with ping-pong enabled. Raises PongTimeout if a
--   pong is not received.
--   
--   Can used with Client and Server connections.
withPingPong :: PingPongOptions -> Connection -> (Connection -> IO ()) -> IO ()

-- | Forks a ping thread, sending a ping message every <tt>n</tt> seconds
--   over the connection. The thread is killed when the inner IO action is
--   finished.
--   
--   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.
--   
--   Note that usually you want to use <a>withPingPong</a> to timeout the
--   connection if a pong is not received.
withPingThread :: Connection -> Int -> IO () -> IO a -> IO a

-- | DEPRECATED: Use <a>withPingThread</a> instead.
--   
--   Forks a ping thread, sending a ping message every <tt>n</tt> 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.

-- | <i>Deprecated: Use <a>withPingThread</a> instead</i>
forkPingThread :: Connection -> Int -> IO ()
