Skip to content

Commit

Permalink
Give more detail in the error message for too large request bodies.
Browse files Browse the repository at this point in the history
* Just to be helpful to developers, give the maximum body length and their body length
* Also point developers to the function to change that value

(I don't think this leaks any sensitive info, because you can always binary search with different request body sizes to find the maximum allowable)
  • Loading branch information
MaxGabriel committed Jan 19, 2018
1 parent e2b0a5c commit 6b22a0b
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 6 deletions.
4 changes: 4 additions & 0 deletions yesod-core/ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.4.37.3

* Improve error message when request body is too large [#1477](https://github.com/yesodweb/yesod/pull/1477)

## 1.4.37.2

* Improve error messages for the CSRF checking functions [#1455](https://github.com/yesodweb/yesod/issues/1455)
Expand Down
15 changes: 11 additions & 4 deletions yesod-core/Yesod/Core/Internal/Request.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import qualified Network.Wai as W
import Web.Cookie (parseCookiesText)
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as S8
import qualified Data.ByteString.Lazy.Char8 as LS8
import Data.Text (Text, pack)
import Network.HTTP.Types (queryToQueryText, Status (Status))
import Data.Maybe (fromMaybe, catMaybes)
Expand Down Expand Up @@ -60,17 +61,23 @@ limitRequestBody maxLen req = do
let len = fromIntegral $ S8.length bs
remaining' = remaining - len
if remaining < len
then throwIO $ HCWai tooLargeResponse
then throwIO $ HCWai $ tooLargeResponse maxLen len
else do
writeIORef ref remaining'
return bs
}

tooLargeResponse :: W.Response
tooLargeResponse = W.responseLBS
tooLargeResponse :: Word64 -> Word64 -> W.Response
tooLargeResponse maxLen bodyLen = W.responseLBS
(Status 413 "Too Large")
[("Content-Type", "text/plain")]
"Request body too large to be processed."
(L.concat
[ "Request body too large to be processed. The maximum size is "
, (LS8.pack (show maxLen))
, " bytes; your request body was "
, (LS8.pack (show bodyLen))
, " bytes. If you're the developer of this site, you can configure the maximum length with the `maximumContentLength` function on the Yesod typeclass."
])

parseWaiRequest :: W.Request
-> SessionMap
Expand Down
2 changes: 1 addition & 1 deletion yesod-core/Yesod/Core/Internal/Run.hs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ yesodRunner :: (ToTypedContent res, Yesod site)
-> Maybe (Route site)
-> Application
yesodRunner handler' YesodRunnerEnv {..} route req sendResponse
| Just maxLen <- mmaxLen, KnownLength len <- requestBodyLength req, maxLen < len = sendResponse tooLargeResponse
| Just maxLen <- mmaxLen, KnownLength len <- requestBodyLength req, maxLen < len = sendResponse (tooLargeResponse maxLen len)
| otherwise = do
let dontSaveSession _ = return []
(session, saveSession) <- liftIO $
Expand Down
2 changes: 1 addition & 1 deletion yesod-core/yesod-core.cabal
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: yesod-core
version: 1.4.37.2
version: 1.4.37.3
license: MIT
license-file: LICENSE
author: Michael Snoyman <michael@snoyman.com>
Expand Down

0 comments on commit 6b22a0b

Please sign in to comment.