haskellunix-sockethaskell-warp

Warp: Binding to Unix Domain Sockets


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.


Solution

  • 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.