{-# LANGUAGE CPP #-}
module Happstack.Server.Internal.Socket
( acceptLite
, sockAddrToPeer
) where
import Data.List (intersperse)
import Data.Word (Word32)
import qualified Network.Socket as S
( Socket
, PortNumber()
, SockAddr(..)
, HostName
, accept
)
import Numeric (showHex)
type HostAddress = Word32
type HostAddress6 = (Word32, Word32, Word32, Word32)
showHostAddress :: HostAddress -> String
showHostAddress :: Word32 -> String
showHostAddress Word32
num = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [forall a. Show a => a -> String
show Word32
q1, String
".", forall a. Show a => a -> String
show Word32
q2, String
".", forall a. Show a => a -> String
show Word32
q3, String
".", forall a. Show a => a -> String
show Word32
q4]
where (Word32
num',Word32
q1) = Word32
num forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
256
(Word32
num'',Word32
q2) = Word32
num' forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
256
(Word32
num''',Word32
q3) = Word32
num'' forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
256
(Word32
_,Word32
q4) = Word32
num''' forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
256
showHostAddress6 :: HostAddress6 -> String
showHostAddress6 :: HostAddress6 -> String
showHostAddress6 (Word32
a,Word32
b,Word32
c,Word32
d) =
(forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a] -> [a]
intersperse String
":" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. (Integral a, Show a) => a -> ShowS
showHex String
""))
[Word32
p1,Word32
p2,Word32
p3,Word32
p4,Word32
p5,Word32
p6,Word32
p7,Word32
p8]
where (Word32
a',Word32
p2) = Word32
a forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
65536
(Word32
_,Word32
p1) = Word32
a' forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
65536
(Word32
b',Word32
p4) = Word32
b forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
65536
(Word32
_,Word32
p3) = Word32
b' forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
65536
(Word32
c',Word32
p6) = Word32
c forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
65536
(Word32
_,Word32
p5) = Word32
c' forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
65536
(Word32
d',Word32
p8) = Word32
d forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
65536
(Word32
_,Word32
p7) = Word32
d' forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
65536
acceptLite :: S.Socket -> IO (S.Socket, S.HostName, S.PortNumber)
acceptLite :: Socket -> IO (Socket, String, PortNumber)
acceptLite Socket
sock = do
(Socket
sock', SockAddr
addr) <- Socket -> IO (Socket, SockAddr)
S.accept Socket
sock
let (String
peer, PortNumber
port) = SockAddr -> (String, PortNumber)
sockAddrToPeer SockAddr
addr
forall (m :: * -> *) a. Monad m => a -> m a
return (Socket
sock', String
peer, PortNumber
port)
sockAddrToPeer :: S.SockAddr -> (S.HostName, S.PortNumber)
sockAddrToPeer :: SockAddr -> (String, PortNumber)
sockAddrToPeer SockAddr
addr =
case SockAddr
addr of
(S.SockAddrInet PortNumber
p Word32
ha) -> (Word32 -> String
showHostAddress Word32
ha, PortNumber
p)
(S.SockAddrInet6 PortNumber
p Word32
_ HostAddress6
ha Word32
_) -> (HostAddress6 -> String
showHostAddress6 HostAddress6
ha, PortNumber
p)
SockAddr
_ -> forall a. HasCallStack => String -> a
error String
"sockAddrToPeer: Unsupported socket type"