我正在使用Scotty开发一个应用程序,当然还有WAI。我希望能够限制请求的大小,包括正文长度和标题。我怎样才能做到这一点?是否可以使用普通的 WAI 中间件来做到这一点?
问问题
551 次
3 回答
4
我不知道 Scotty 的详细信息,但当然可以设置一个 WAI 中间件来查看requestBodyLength,如果它太大,则返回适当的 413 状态代码页。您需要处理的一件事是上传正文是否使用分块编码发送,在这种情况下不存在内容长度。但这并不常见。您可以选择拒绝这些请求,或者添加代码来包装请求正文并在结果太大时返回错误(这就是 Yesod 所做的)。
于 2015-04-15T09:58:08.610 回答
1
标记的解决方案指向正确的方向,但如果您像我一样,您可能仍然难以明确地导出所需的完整代码。这是一个实现(感谢有经验的 Haskell 朋友的帮助):
import qualified Network.HTTP.Types as Http
import qualified Network.Wai as Wai
limitRequestSize :: Wai.Middleware
limitRequestSize app req respond = do
case Wai.requestBodyLength req of
Wai.KnownLength len -> do
if len > maxLen
then respond $ Wai.responseBuilder Http.status413 [] mempty
else app req respond
Wai.ChunkedBody ->
respond $ Wai.responseBuilder Http.status411 [] mempty
where
maxLen = 50*1000 -- 50kB
然后中间件就像这样在 scotty 的 do 块中运行
import Network.Wai.Middleware.RequestLogger (logStdout)
main :: IO ()
main = do
scotty 3000 $ do
middleware logStdout
middleware limitRequestSize
get "/alive" $ do
status Http.status200
-- ...
如果您对如何推导出它感到好奇(或者为什么我发现这不是太琐碎),请考虑这Middleware
是
Application -> Application
其中Application
本身是一个别名
Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived
因此,即使解决方案非常简洁,也有很多(精神上)解包的论据。
于 2019-09-09T11:35:47.863 回答
1
从wai-extra-3.1.1开始,上述代码已添加到Network.Wai.Middleware.RequestSizeLimit模块中,因此可以将其作为依赖项引入。
于 2021-10-19T13:34:50.520 回答