8 -- |Type class for things behaves like a 'So.Socket'.
9 module Network.HTTP.Lucu.SocketLike
14 import Control.Exception
16 import qualified Network.Socket as So
17 import Network.HTTP.Lucu.HandleLike
19 import qualified OpenSSL.Session as SSL
20 import Prelude hiding (catch)
21 import Prelude.Unicode
23 import qualified System.IO as I
25 class (HandleLike (Handle s)) ⇒ SocketLike s where
27 accept ∷ s → IO (Handle s, So.SockAddr)
28 socketPort ∷ s → IO So.PortNumber
30 instance SocketLike So.Socket where
31 type Handle So.Socket = I.Handle
34 = do (soPeer, addr) ← So.accept soSelf
35 hPeer ← So.socketToHandle soPeer I.ReadWriteMode
38 socketPort = So.socketPort
41 instance SocketLike (SSL.SSLContext, So.Socket) where
42 type Handle (SSL.SSLContext, So.Socket) = SSL.SSL
45 = do (soPeer, addr) ← So.accept soSelf
46 ssl ← SSL.connection ctx soPeer
47 handshake ssl addr `catch` next ssl addr
49 handshake ∷ SSL.SSL → So.SockAddr → IO (SSL.SSL, So.SockAddr)
56 → SSL.SomeSSLException
57 → IO (SSL.SSL, So.SockAddr)
59 = do I.hPutStrLn I.stderr
60 $ "Lucu: failed to accept an SSL connection from "
65 SSL.shutdown ssl SSL.Bidirectional
68 socketPort = So.socketPort ∘ snd