如何限制WAI中请求正文和标题的大小?

时间:2015-04-15 07:25:54

标签: haskell scotty haskell-wai

我正在使用Scotty开发一个应用程序,当然还有WAI。我希望能够限制请求的大小,包括体长和标题。我怎样才能做到这一点?是否可以使用普通的WAI中间件来实现?

2 个答案:

答案 0 :(得分:3)

我不知道Scotty的详细信息,但是当然可以设置一个WAI中间件来查看requestBodyLength,如果它太大,则会返回一个合适的413状态代码页。您需要处理的一件事是上传主体是否使用分块编码发送,在这种情况下,不存在内容长度。但这并不常见。您可以选择拒绝这些请求,或添加代码来包装请求正文,如果结果太大(that's what Yesod does)则返回错误。

答案 1 :(得分:0)

标记的解决方案指向正确的方向,但是如果您像我一样,可能仍然很难显式地导出所需的完整代码。这是一个实现(由于有经验的Haskell朋友的帮助):

ni

中间件然后像这样在scotty的do块中运行

someFunc()

如果您对如何推导它感到好奇(或者为什么我发现这不太琐碎),请考虑Middleware

的别名。
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

其中Application本身是

的别名
import Network.Wai.Middleware.RequestLogger (logStdout)

main :: IO ()
main = do
    scotty 3000 $ do
        middleware logStdout
        middleware limitRequestSize

        get "/alive" $ do
            status Http.status200

        -- ...

因此,即使解决方案很简洁,也有很多参数(在思想上)可以解压缩。