websockets-0.13.0.0: A sensible and clean way to write WebSocket-capable servers in Haskell.

Safe Haskell | None
Language | Haskell2010

Network.WebSockets.Connection

Description

This module exposes connection internals

Synopsis

- data PendingConnection = PendingConnection {
  - pendingOptions :: !ConnectionOptions
  - pendingRequest :: !RequestHead
  - pendingOnAccept :: !(Connection -> IO ())
  - pendingStream :: !Stream
  }
- acceptRequest :: PendingConnection -> IO Connection
- data AcceptRequest = AcceptRequest {
  - acceptSubprotocol :: !(Maybe ByteString)
  - acceptHeaders :: !Headers
  }
- defaultAcceptRequest :: AcceptRequest
- acceptRequestWith :: PendingConnection -> AcceptRequest -> IO Connection
- rejectRequest :: PendingConnection -> ByteString -> IO ()
- data RejectRequest = RejectRequest {
  - rejectCode :: !Int
  - rejectMessage :: !ByteString
  - rejectHeaders :: Headers
  - rejectBody :: !ByteString
  }
- defaultRejectRequest :: RejectRequest
- rejectRequestWith :: PendingConnection -> RejectRequest -> IO ()
- data Connection = Connection {
  - connectionOptions :: !ConnectionOptions
  - connectionType :: !ConnectionType
  - connectionProtocol :: !Protocol
  - connectionHeartbeat :: !(MVar ())
  - connectionParse :: !(IO (Maybe Message))
  - connectionWrite :: !([Message] -> IO ())
  - connectionSentClose :: !(IORef Bool)
  }
- data ConnectionOptions = ConnectionOptions {
  - connectionOnPong :: !(IO ())
  - connectionTimeout :: !Int
  - connectionCompressionOptions :: !CompressionOptions
  - connectionStrictUnicode :: !Bool
  - connectionFramePayloadSizeLimit :: !SizeLimit
  - connectionMessageDataSizeLimit :: !SizeLimit
  }
- defaultConnectionOptions :: ConnectionOptions
- receive :: Connection -> IO Message
- receiveDataMessage :: Connection -> IO DataMessage
- receiveData :: WebSocketsData a => Connection -> IO a
- send :: Connection -> Message -> IO ()
- sendDataMessage :: Connection -> DataMessage -> IO ()
- sendDataMessages :: Connection -> [DataMessage] -> IO ()
- sendTextData :: WebSocketsData a => Connection -> a -> IO ()
- sendTextDatas :: WebSocketsData a => Connection -> [a] -> IO ()
- sendBinaryData :: WebSocketsData a => Connection -> a -> IO ()
- sendBinaryDatas :: WebSocketsData a => Connection -> [a] -> IO ()
- sendClose :: WebSocketsData a => Connection -> a -> IO ()
- sendCloseCode :: WebSocketsData a => Connection -> Word16 -> a -> IO ()
- sendPing :: WebSocketsData a => Connection -> a -> IO ()
- sendPong :: WebSocketsData a => Connection -> a -> IO ()
- withPingThread :: Connection -> Int -> IO () -> IO a -> IO a
- forkPingThread :: Connection -> Int -> IO ()
- pingThread :: Connection -> Int -> IO () -> IO ()
- data CompressionOptions
  - = NoCompression
  - | PermessageDeflateCompression PermessageDeflate
- data PermessageDeflate = PermessageDeflate {
  - serverNoContextTakeover :: Bool
  - clientNoContextTakeover :: Bool
  - serverMaxWindowBits :: Int
  - clientMaxWindowBits :: Int
  - pdCompressionLevel :: Int
  }
- defaultPermessageDeflate :: PermessageDeflate
- data SizeLimit
  - = NoSizeLimit
  - | SizeLimit !Int64

# Documentation

data PendingConnection #

A new client connected to the server. We haven't accepted the connection yet, though.

Constructors

PendingConnection |

Fields

- pendingOptions :: !ConnectionOptions

  Options, passed as-is to the `Connection`

- pendingRequest :: !RequestHead

  Useful for e.g. inspecting the request path.

- pendingOnAccept :: !(Connection -> IO ())

  One-shot callback fired when a connection is accepted, i.e., *after* the accepting response is sent to the client.

- pendingStream :: !Stream

  Input/output stream

acceptRequest :: PendingConnection -> IO Connection #

Accept a pending connection, turning it into a `Connection`.

data AcceptRequest #

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.

Constructors

AcceptRequest |

Fields

- acceptSubprotocol :: !(Maybe ByteString)

  The subprotocol to speak with the client. If `pendingSubprotcols` is non-empty, `acceptSubprotocol` must be one of the subprotocols from the list.

- acceptHeaders :: !Headers

  Extra headers to send with the response.

defaultAcceptRequest :: AcceptRequest #

acceptRequestWith :: PendingConnection -> AcceptRequest -> IO Connection #

This function is like `acceptRequest` but allows you to set custom options using the `AcceptRequest` datatype.

rejectRequest #

Arguments

:: PendingConnection | Connection to reject
-> ByteString | Rejection response body
-> IO () |

Requires calling `pendingStream` and `close`.

data RejectRequest #

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.

Constructors

RejectRequest |

Fields

- rejectCode :: !Int

  The status code, 400 by default.

- rejectMessage :: !ByteString

  The message, "Bad Request" by default

- rejectHeaders :: Headers

  Extra headers to be sent with the response.

- rejectBody :: !ByteString

  Reponse body of the rejection.

defaultRejectRequest :: RejectRequest #

rejectRequestWith #

Arguments

:: PendingConnection | Connection to reject
-> RejectRequest | Params on how to reject the request
-> IO () |

data Connection #

Constructors

Connection |

Fields

- connectionOptions :: !ConnectionOptions
- connectionType :: !ConnectionType
- connectionProtocol :: !Protocol
- connectionHeartbeat :: !(MVar ())

  This MVar is filled whenever a pong is received. This is used by `withPingPong` to timeout the connection if a pong is not received.

- connectionParse :: !(IO (Maybe Message))
- connectionWrite :: !([Message] -> IO ())
- connectionSentClose :: !(IORef Bool)

  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.

data ConnectionOptions #

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.

Constructors

ConnectionOptions |

Fields

- connectionOnPong :: !(IO ())

  Whenever a `pong` is received, this IO action is executed. It can be used to tickle connections or fire missiles.

- connectionTimeout :: !Int

  Timeout for connection establishment in seconds. Only used in the client.

- connectionCompressionOptions :: !CompressionOptions

  Enable `PermessageDeflate`.

- connectionStrictUnicode :: !Bool

  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.

- connectionFramePayloadSizeLimit :: !SizeLimit

  The maximum size for incoming frame payload size in bytes. If a frame exceeds this limit, a `ParseException` is thrown.

- connectionMessageDataSizeLimit :: !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.

defaultConnectionOptions :: ConnectionOptions #

The default connection options:

- Nothing happens when a pong is received.
- Compression is disabled.
- Lenient unicode decoding.
- 30 second timeout for connection establishment.

receive :: Connection -> IO Message #

receiveDataMessage :: Connection -> IO DataMessage #

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.

receiveData :: WebSocketsData a => Connection -> IO a #

Receive a message, converting it to whatever format is needed.

send :: Connection -> Message -> IO () #

sendDataMessage :: Connection -> DataMessage -> 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`.

sendDataMessages :: Connection -> [DataMessage] -> IO () #

Send a collection of `DataMessage`s. This is more efficient than calling `sendDataMessage` many times.

sendTextData :: WebSocketsData a => Connection -> a -> 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.

sendTextDatas :: WebSocketsData a => Connection -> [a] -> IO () #

Send a number of textual messages. This is more efficient than calling `sendTextData` many times.

sendBinaryData :: WebSocketsData a => Connection -> a -> IO () #

Send a binary message. This is useful for sending binary blobs, e.g. images, data encoded with MessagePack, images...

sendBinaryDatas :: WebSocketsData a => Connection -> [a] -> IO () #

Send a number of binary messages. This is more efficient than calling `sendBinaryData` many times.

sendClose :: 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.

sendCloseCode :: WebSocketsData a => Connection -> Word16 -> 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.

sendPing :: WebSocketsData a => Connection -> a -> IO () #

Send a ping

sendPong :: WebSocketsData a => Connection -> a -> IO () #

Send a pong

withPingThread #

Arguments

:: Connection |
-> Int | Second interval in which pings should be sent.
-> IO () | Repeat this after sending a ping.
-> IO a | Application to wrap with a ping thread.
-> IO a | Executes application and kills ping thread when done.

Forks a ping thread, sending a ping message every `n` 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 `withPingPong` to timeout the connection if a pong is not received.

forkPingThread :: Connection -> Int -> IO () #

Deprecated: Use `withPingThread` instead

DEPRECATED: Use `withPingThread` instead.

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.

pingThread :: Connection -> Int -> IO () -> IO () #

Use this if you want to run the ping thread yourself.

See also `withPingThread`.

data CompressionOptions #

Constructors

NoCompression |
PermessageDeflateCompression PermessageDeflate |

#### Instances

Instances details

Show CompressionOptions # |
Instance details Defined in Network.WebSockets.Connection.Options Methods showsPrec :: Int -> CompressionOptions -> ShowS # show :: CompressionOptions -> String # showList :: [CompressionOptions] -> ShowS #
Eq CompressionOptions # |
Instance details Defined in Network.WebSockets.Connection.Options Methods (==) :: CompressionOptions -> CompressionOptions -> Bool # (/=) :: CompressionOptions -> CompressionOptions -> Bool #

data PermessageDeflate #

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"

Constructors

PermessageDeflate |

Fields

- serverNoContextTakeover :: Bool
- clientNoContextTakeover :: Bool
- serverMaxWindowBits :: Int
- clientMaxWindowBits :: Int
- pdCompressionLevel :: Int

#### Instances

Instances details

Show PermessageDeflate # |
Instance details Defined in Network.WebSockets.Connection.Options Methods showsPrec :: Int -> PermessageDeflate -> ShowS # show :: PermessageDeflate -> String # showList :: [PermessageDeflate] -> ShowS #
Eq PermessageDeflate # |
Instance details Defined in Network.WebSockets.Connection.Options Methods (==) :: PermessageDeflate -> PermessageDeflate -> Bool # (/=) :: PermessageDeflate -> PermessageDeflate -> Bool #

defaultPermessageDeflate :: PermessageDeflate #

data SizeLimit #

A size limit, in bytes. The `Monoid` instance takes the minimum limit.

Constructors

NoSizeLimit |
SizeLimit !Int64 |

#### Instances

Instances details

Monoid SizeLimit # |
Instance details Defined in Network.WebSockets.Connection.Options Methods mempty :: SizeLimit # mappend :: SizeLimit -> SizeLimit -> SizeLimit # mconcat :: [SizeLimit] -> SizeLimit #
Semigroup SizeLimit # |
Instance details Defined in Network.WebSockets.Connection.Options Methods (<>) :: SizeLimit -> SizeLimit -> SizeLimit # sconcat :: NonEmpty SizeLimit -> SizeLimit # stimes :: Integral b => b -> SizeLimit -> SizeLimit #
Show SizeLimit # |
Instance details Defined in Network.WebSockets.Connection.Options Methods showsPrec :: Int -> SizeLimit -> ShowS # show :: SizeLimit -> String # showList :: [SizeLimit] -> ShowS #
Eq SizeLimit # |
Instance details Defined in Network.WebSockets.Connection.Options Methods (==) :: SizeLimit -> SizeLimit -> Bool # (/=) :: SizeLimit -> SizeLimit -> Bool #