将yesod应用程序用作快速CGI

问题描述

我正在尝试将yesod应用程序作为CGI(或FastCGI)程序提供,但是Apache向我显示500错误

[Mon Sep 21 17:35:41.425565 2020] [http:error] [pid 2758] [client 10.0.2.2:43872] AH02429:响应标头名称'21 / Sep / 2020'包含无效字符,正在中止请求

从带有stack new project yesodweb/sqlite新模板开始,我尝试通过更改src/Application.hs将其转换为CGI程序。

我已将Wai CGI库导入到

import Network.Wai.Handler.CGI              (run)

并将appMain的最后一行更改为run app

-- | The @main@ function for an executable running this site.
appMain :: IO ()
appMain = do 
    -- Get the settings from all relevant sources
    settings <- loadYamlSettingsArgs
        -- fall back to compile-time values,set to [] to require values at runtime
        [configSettingsYmlValue]
 
        -- allow environment variables to override
        useEnv
 
    -- Generate the foundation from the settings
    foundation <- makeFoundation settings
 
    -- Generate a WAI Application from the foundation
    app <- makeApplication foundation
                                             
    -- Run the application with Warp
    --runSettings (warpSettings foundation) app
    run app

我认为这是将其用作CGI程序的最小更改,但显然不起作用。

我已经看过yesod的书chapter on deploying your Webapp,因为它很容易编写适当的Apache配置,因此服务器可以运行该应用程序。对于我认为问题出在哪里的应用程序代码的必要更改,它什么也没说。

我也检查了此stackoverflow question,但这是距今大约8年前的事,所以现在已经过时了。

解决方法

问题在于默认的makeFoundation记录到标准输出,这也是CGI程序应该发送其响应的位置,因此您将响应标头与日志输出混合在一起,而Apache试图将日志行解析为HTTP标头等。

如果将newStdoutLoggerSet替换为newStderrLoggerSet,它应该可以工作,并且日志输出将以Apache的“ error.log”或等效名称结尾。