{-# LANGUAGE CPP #-}
-- | Only allow local connections.
--
module Network.Wai.Middleware.Local
    ( local
    ) where

import Network.Wai (Middleware,remoteHost, Response)
import Network.Socket (SockAddr(..))

-- | This middleware rejects non-local connections with a specific response. 
--   It is useful when supporting web-based local applications, which would
--   typically want to reject external connections.

local :: Response -> Middleware
local :: Response -> Middleware
local Response
resp Application
f Request
r Response -> IO ResponseReceived
k = case Request -> SockAddr
remoteHost Request
r of
                   SockAddrInet PortNumber
_  HostAddress
h | HostAddress
h HostAddress -> HostAddress -> Bool
forall a. Eq a => a -> a -> Bool
== Integer -> HostAddress
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
home
                                    -> Application
f Request
r Response -> IO ResponseReceived
k
#if !defined(mingw32_HOST_OS) && !defined(_WIN32)
                   SockAddrUnix String
_   -> Application
f Request
r Response -> IO ResponseReceived
k
#endif
                   SockAddr
_                ->  Response -> IO ResponseReceived
k (Response -> IO ResponseReceived)
-> Response -> IO ResponseReceived
forall a b. (a -> b) -> a -> b
$ Response
resp
 where
        home :: Integer
        home :: Integer
home = Integer
127 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ (Integer
256 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
256 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
256) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1