Reputation: 13751
The example code listed here shows how to make warp listen only on specific hosts.
Furtheremore, this post shows some basics on how to use unix domain sockets in Haskell.
How can I combine those two approaches in order to make warp listen on (i.e. bind to) a specific unix domain socket (say, warp.sock
)?
Note: This question intentionally shows no research effort as it was answered Q&A-Style.
Upvotes: 10
Views: 1220
Reputation: 12123
FWIW: If one wants to use http-client to use that UNIX socket:
{-# LANGUAGE OverloadedStrings #-}
import Network.HTTP.Client
import Network.HTTP.Client.Internal (Connection, openSocketConnection, makeConnection)
import Network.Socket.ByteString (sendAll, recv)
import qualified Control.Exception as E
import qualified Network.Socket as NS
main :: IO ()
main = do
mgr <- newManager defaultManagerSettings {
managerRawConnection = createUnixConnection
}
-- This changes in http-client-0.5, use parseUrlThrow
req <- parseUrl "http://localhost/whatever"
res <- httpLbs req mgr
print (responseBody res)
createUnixConnection :: IO (Maybe NS.HostAddress -> String -> Int -> IO Connection)
createUnixConnection = return $ \_ _ _ -> openUnixConnection "warp.sock"
openUnixConnection :: String -> IO Connection
openUnixConnection addr = E.bracketOnError
(NS.socket NS.AF_UNIX NS.Stream NS.defaultProtocol)
(NS.close)
$ \sock -> do
NS.connect sock sockAddr
socketConnection sock chunksize
where
sockAddr = NS.SockAddrUnix addr
chunksize = 8192
-------------------------------------------------------------------------------
-- Copied from http-client
-------------------------------------------------------------------------------
socketConnection :: NS.Socket -> Int -> IO Connection
socketConnection socket chunksize = makeConnection
(recv socket chunksize)
(sendAll socket)
(NS.close socket)
Upvotes: 2
Reputation: 13751
You can use runSettingsSocket
with a AF_UNIX
socket:
{-# LANGUAGE OverloadedStrings #-}
import Network.Wai (responseLBS)
import Network.Wai.Handler.Warp
import Network.Socket
import Network.HTTP.Types (status200)
import Network.HTTP.Types.Header (hContentType)
main = do
let port = 3000
-- Open the socket
sock <- socket AF_UNIX Stream 0
bind sock $ SockAddrUnix "warp.sock"
listen sock maxListenQueue
-- Run the server
let settings = defaultSettings { settingsPort = port }
runSettingsSocket settings sock app
-- Cleanup: Close socket
close sock
app req f = f $
responseLBS status200 [(hContentType, "text/plain")] "Hello world!"
Note that this will obviously only work on unixoid platforms.
Upvotes: 13