问题描述
我正在尝试将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”或等效名称结尾。