-
Notifications
You must be signed in to change notification settings - Fork 0
/
Web.hs
56 lines (48 loc) · 1.66 KB
/
Web.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Web
( WebHandler,
run,
WebsocketHandler,
websocketsOr,
withPingThread,
sourceAddress,
)
where
import Data.List (find)
import qualified Network.Wai as Wai
import qualified Network.Wai.Handler.Warp as Warp
import qualified Network.Wai.Handler.WebSockets as Wai
import qualified Network.WebSockets as WebSockets
import RIO
type WebHandler m = Wai.Request -> (Wai.Response -> m Wai.ResponseReceived) -> m Wai.ResponseReceived
run :: MonadUnliftIO m => Warp.Port -> WebHandler m -> m ()
run port app = withRunInIO $ \runInIO ->
Warp.run port (\req respond -> runInIO (app req (liftIO . respond)))
type WebsocketHandler m = WebSockets.PendingConnection -> m ()
websocketsOr ::
MonadUnliftIO m =>
WebSockets.ConnectionOptions ->
WebsocketHandler m ->
WebHandler m ->
WebHandler m
websocketsOr connectionOptions app backup =
\req respond -> withRunInIO $ \runInIO ->
Wai.websocketsOr
connectionOptions
(\conn -> runInIO $ app conn)
(\req1 respond1 -> runInIO $ backup req1 (liftIO . respond1))
req
(runInIO . respond)
withPingThread :: MonadUnliftIO m => WebSockets.Connection -> Int -> m a -> m a
withPingThread conn interval action = withRunInIO $ \runInIO ->
WebSockets.withPingThread conn interval (return ()) (runInIO action)
sourceAddress :: Wai.Request -> Utf8Builder
sourceAddress req = fromMaybe socketAddr headerAddr
where
headerAddr =
displayBytesUtf8 . snd
<$> find
(\x -> fst x `elem` ["x-real-ip", "x-forwarded-for"])
(Wai.requestHeaders req)
socketAddr = displayShow . Wai.remoteHost $ req