This commit is contained in:
Maximilian Tagher 2019-11-29 10:43:11 -05:00
parent 0025226af6
commit 42d41f77de
4 changed files with 21 additions and 5 deletions

View File

@ -1,5 +1,9 @@
# ChangeLog for yesod-core # ChangeLog for yesod-core
## 1.6.17
Adds `contentTypeIsJson` [#1646](https://github.com/yesodweb/yesod/pull/1646)
## 1.6.16.1 ## 1.6.16.1
* Compiles with GHC 8.8.1 * Compiles with GHC 8.8.1

View File

@ -32,6 +32,9 @@ module Yesod.Core.Json
, jsonOrRedirect , jsonOrRedirect
, jsonEncodingOrRedirect , jsonEncodingOrRedirect
, acceptsJson , acceptsJson
-- * Checking if data is JSON
, contentTypeHeaderIsJson
) where ) where
import Yesod.Core.Handler (HandlerFor, getRequest, invalidArgs, redirect, selectRep, provideRep, rawRequestBody, ProvidedRep, lookupHeader) import Yesod.Core.Handler (HandlerFor, getRequest, invalidArgs, redirect, selectRep, provideRep, rawRequestBody, ProvidedRep, lookupHeader)
@ -134,8 +137,8 @@ parseInsecureJsonBody = do
parseCheckJsonBody :: (MonadHandler m, J.FromJSON a) => m (J.Result a) parseCheckJsonBody :: (MonadHandler m, J.FromJSON a) => m (J.Result a)
parseCheckJsonBody = do parseCheckJsonBody = do
mct <- lookupHeader "content-type" mct <- lookupHeader "content-type"
case fmap (B8.takeWhile (/= ';')) mct of case fmap contentTypeHeaderIsJson mct of
Just "application/json" -> parseInsecureJsonBody Just True -> parseInsecureJsonBody
_ -> return $ J.Error $ "Non-JSON content type: " ++ show mct _ -> return $ J.Error $ "Non-JSON content type: " ++ show mct
-- | Same as 'parseInsecureJsonBody', but return an invalid args response on a parse -- | Same as 'parseInsecureJsonBody', but return an invalid args response on a parse
@ -219,3 +222,11 @@ acceptsJson = (maybe False ((== "application/json") . B8.takeWhile (/= ';'))
. reqAccept) . reqAccept)
`liftM` getRequest `liftM` getRequest
-- | Given the @Content-Type@ header, returns if it is JSON.
--
-- This function is currently a simple check for @application/json@, but in the future may check for
-- alternative representations such as @<https://tools.ietf.org/html/rfc6839#section-3.1 xxx/yyy+json>@.
--
-- @since 1.6.17
contentTypeHeaderIsJson :: B8.ByteString -> Bool
contentTypeHeaderIsJson bs = B8.takeWhile (/= ';') bs == "application/json"

View File

@ -1,5 +1,5 @@
name: yesod-core name: yesod-core
version: 1.6.16.1 version: 1.6.17
license: MIT license: MIT
license-file: LICENSE license-file: LICENSE
author: Michael Snoyman <michael@snoyman.com> author: Michael Snoyman <michael@snoyman.com>

View File

@ -171,6 +171,7 @@ import System.IO
import Yesod.Core.Unsafe (runFakeHandler) import Yesod.Core.Unsafe (runFakeHandler)
import Yesod.Test.TransversingCSS import Yesod.Test.TransversingCSS
import Yesod.Core import Yesod.Core
import Yesod.Core.Json (contentTypeHeaderIsJson)
import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy as TL
import Data.Text.Lazy.Encoding (encodeUtf8, decodeUtf8, decodeUtf8With) import Data.Text.Lazy.Encoding (encodeUtf8, decodeUtf8, decodeUtf8With)
import Text.XML.Cursor hiding (element) import Text.XML.Cursor hiding (element)
@ -604,7 +605,7 @@ htmlCount query count = do
-- | Parses the response body from JSON into a Haskell value, throwing an error if parsing fails. -- | Parses the response body from JSON into a Haskell value, throwing an error if parsing fails.
-- --
-- This function also checks that the @Content-Type@ of the response is @application/json@. -- This function also checks that the @Content-Type@ of the response is @application\/json@.
-- --
-- ==== __Examples__ -- ==== __Examples__
-- --
@ -619,7 +620,7 @@ requireJSONResponse :: (HasCallStack, FromJSON a) => YesodExample site a
requireJSONResponse = do requireJSONResponse = do
withResponse $ \(SResponse _status headers body) -> do withResponse $ \(SResponse _status headers body) -> do
let mContentType = lookup hContentType headers let mContentType = lookup hContentType headers
isJSONContentType = maybe False (\contentType -> BS8.takeWhile (/= ';') contentType == "application/json") mContentType isJSONContentType = maybe False contentTypeHeaderIsJson mContentType
unless unless
isJSONContentType isJSONContentType
(failure $ T.pack $ "Expected `Content-Type: application/json` in the headers, got: " ++ show headers) (failure $ T.pack $ "Expected `Content-Type: application/json` in the headers, got: " ++ show headers)