-- 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>
--   
--   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.8.1.1

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 ()) -> InputStream ByteString -> OutputStream Builder -> 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 stream
pendingIn :: PendingConnection -> InputStream ByteString

-- | Output stream
pendingOut :: PendingConnection -> OutputStream Builder
acceptRequest :: PendingConnection -> IO Connection
rejectRequest :: PendingConnection -> ByteString -> IO ()
data Connection
Connection :: ConnectionOptions -> ConnectionType -> Protocol -> InputStream Message -> OutputStream Message -> Connection
connectionOptions :: Connection -> ConnectionOptions
connectionType :: Connection -> ConnectionType
connectionProtocol :: Connection -> Protocol
connectionIn :: Connection -> InputStream Message
connectionOut :: Connection -> OutputStream Message
data ConnectionOptions
ConnectionOptions :: IO () -> ConnectionOptions
connectionOnPong :: ConnectionOptions -> IO ()
defaultConnectionOptions :: ConnectionOptions
receive :: Connection -> IO Message

-- | Receive an application message. Automatically respond to control
--   messages.
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>
sendDataMessage :: Connection -> DataMessage -> IO ()

-- | Send a message as text
sendTextData :: WebSocketsData a => Connection -> a -> IO ()

-- | Send a message as binary data
sendBinaryData :: WebSocketsData a => Connection -> a -> IO ()

-- | Send a friendly close message
sendClose :: WebSocketsData a => Connection -> a -> IO ()

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

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
acceptRequest :: PendingConnection -> IO Connection
rejectRequest :: PendingConnection -> ByteString -> IO ()
data Connection
data ConnectionOptions
ConnectionOptions :: IO () -> ConnectionOptions
connectionOnPong :: ConnectionOptions -> IO ()
defaultConnectionOptions :: ConnectionOptions
receive :: Connection -> IO Message

-- | Receive an application message. Automatically respond to control
--   messages.
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>
sendDataMessage :: Connection -> DataMessage -> IO ()

-- | Send a message as text
sendTextData :: WebSocketsData a => Connection -> a -> IO ()

-- | Send a message as binary data
sendBinaryData :: WebSocketsData a => Connection -> a -> IO ()

-- | Send a friendly close message
sendClose :: WebSocketsData a => Connection -> 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

-- | 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
DataMessage :: DataMessage -> Message

-- | Different control messages
data ControlMessage
Close :: 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.
data DataMessage
Text :: ByteString -> DataMessage
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
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.
--   <a>unknown path</a>)
RequestRejected :: Request -> String -> HandshakeException

-- | for example <a>EOF came too early</a> (which is actually a parse
--   error) or for your own errors. (like <a>unknown path</a>?)
OtherHandshakeException :: String -> HandshakeException

-- | The connection couldn't be established or broke down unexpectedly.
--   thrown as an iteratee exception.
data ConnectionException

-- | the client unexpectedly closed the connection while we were trying to
--   receive some data.
--   
--   todo: Also want this for sending.
ConnectionClosed :: 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 standalone applications, for
--   real applications, you should use a real server.
runServer :: String -> Int -> ServerApp -> IO ()

-- | A version of <a>runServer</a> which allows you to customize some
--   options.
runServerWith :: String -> Int -> ConnectionOptions -> ServerApp -> IO ()

-- | 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 :: (InputStream ByteString, OutputStream ByteString) -> String -> String -> ConnectionOptions -> Headers -> ClientApp a -> IO a
