-- | Version of 'runWebSockets' which allows you to specify custom options
runWebSocketsWith :: forall p a. Protocol p
                  => WebSocketsOptions
                  -> RequestHttpPart
                  -> (Request -> WebSockets p a)
                  -> Iteratee ByteString IO ()
                  -> Iteratee ByteString IO a
runWebSocketsWith opts httpReq goWs outIter = E.catchError ok $ \e -> do
    -- If handshake went bad, send response
    forM_ (fromException e) $ \he ->
        let builder = encodeResponse $ responseError (undefined :: p) he
        in liftIO $ makeBuilderSender outIter builder
    -- Re-throw error
    E.throwError e
  where
    -- Perform handshake, call runWebSocketsWith'
    ok = do
        (rq, p) <- handshake httpReq
        runWebSocketsWith' opts p (goWs rq) outIter
runWebSocketsWith :: forall p a. Protocol p
                  => WebSocketsOptions
                  -> RequestHttpPart
                  -> (Request -> WebSockets p a)
                  -> Iteratee ByteString IO ()
                  -> Iteratee ByteString IO a
runWebSocketsWith opts httpReq goWs outIter = E.catchError ok $ \e -> do
    -- If handshake went bad, send response
    forM_ (fromException e) $ \he ->
        let builder = encodeResponse $ responseError (undefined :: p) he
        in liftIO $ makeBuilderSender outIter builder
    -- Re-throw error
    E.throwError e
  where
    -- Perform handshake, call runWebSocketsWith'
    ok = do
        (rq, p) <- handshake httpReq
        runWebSocketsWith' opts p (goWs rq) outIter
runWebSocketsWith opts httpReq goWs outIter = E.catchError ok $ \e -> do
    -- If handshake went bad, send response
    forM_ (fromException e) $ \he ->
        let builder = encodeResponse $ responseError (undefined :: p) he
        in liftIO $ makeBuilderSender outIter builder
    -- Re-throw error
    E.throwError e
  where
    -- Perform handshake, call runWebSocketsWith'
    ok = do
        (rq, p) <- handshake httpReq
        runWebSocketsWith' opts p (goWs rq) outIter