module Ganeti.Utils.Http
( httpConfFromOpts
, error404
, plainJSON
) where
import Control.Monad (liftM)
import Data.ByteString.Char8 (pack)
import Data.Map ((!))
import Data.Maybe (fromMaybe)
import Network.BSD (getServicePortNumber)
import qualified Network.Socket as Socket
import Snap.Core (Snap, writeBS, modifyResponse, setResponseStatus)
import Snap.Http.Server.Config ( Config, ConfigLog(ConfigFileLog), emptyConfig
, setAccessLog, setErrorLog, setCompression
, setVerbose, setPort, setBind )
import qualified Text.JSON as J
import Ganeti.BasicTypes (GenericResult(..))
import qualified Ganeti.Constants as C
import Ganeti.Daemon (DaemonOptions(..))
import Ganeti.Runtime ( GanetiDaemon, daemonName
, daemonsExtraLogFile, ExtraLogReason(..))
import qualified Ganeti.Ssconf as Ssconf
import Ganeti.Utils (withDefaultOnIOError)
defaultHttpConf :: FilePath -> FilePath -> Config Snap ()
defaultHttpConf accessLog errorLog =
setAccessLog (ConfigFileLog accessLog) .
setCompression False .
setErrorLog (ConfigFileLog errorLog) $
setVerbose False
emptyConfig
httpConfFromOpts :: GanetiDaemon -> DaemonOptions -> IO (Config Snap ())
httpConfFromOpts daemon opts = do
accessLog <- daemonsExtraLogFile daemon AccessLog
errorLog <- daemonsExtraLogFile daemon ErrorLog
let name = daemonName daemon
standardPort = snd $ C.daemonsPorts ! name
defaultPort <- withDefaultOnIOError standardPort
. liftM fromIntegral
$ getServicePortNumber name
defaultFamily <- Ssconf.getPrimaryIPFamily Nothing
let defaultBind = if defaultFamily == Ok Socket.AF_INET6 then "::" else "*"
return .
setPort (maybe defaultPort fromIntegral (optPort opts)) .
setBind (pack . fromMaybe defaultBind $ optBindAddress opts)
$ defaultHttpConf accessLog errorLog
error404 :: Snap ()
error404 = do
modifyResponse $ setResponseStatus 404 "Not found"
writeBS "Resource not found"
plainJSON :: J.JSON a => a -> Snap ()
plainJSON = writeBS . pack . J.encode