diff --git a/servant-server/test/Servant/ServerSpec.hs b/servant-server/test/Servant/ServerSpec.hs index eaf25de3..17c2f7d1 100644 --- a/servant-server/test/Servant/ServerSpec.hs +++ b/servant-server/test/Servant/ServerSpec.hs @@ -173,7 +173,7 @@ verbSpec = describe "Servant.API.Verb" $ do it "sets the Content-Type header" $ do response <- THW.request method "" [] "" liftIO $ simpleHeaders response `shouldContain` - [("Content-Type", "application/json")] + [("Content-Type", "application/json;charset=utf-8")] test "GET 200" get200 methodGet 200 test "POST 210" post210 methodPost 210 diff --git a/servant/CHANGELOG.md b/servant/CHANGELOG.md index f7f7988b..4c089f42 100644 --- a/servant/CHANGELOG.md +++ b/servant/CHANGELOG.md @@ -12,6 +12,12 @@ ([#345](https://github.com/haskell-servant/servant/pull/345)) ([#305](https://github.com/haskell-servant/servant/issues/305)) +* Default JSON content type change to `application/json;charset=utf-8`. + ([#263](https://github.com/haskell-servant/servant/issues/263)) + Related browser bugs: + [Chromium](https://bugs.chromium.org/p/chromium/issues/detail?id=438464) and + [Firefox](https://bugzilla.mozilla.org/show_bug.cgi?id=918742) + 0.9.1 ------ diff --git a/servant/src/Servant/API/ContentTypes.hs b/servant/src/Servant/API/ContentTypes.hs index 504fd397..d13d9951 100644 --- a/servant/src/Servant/API/ContentTypes.hs +++ b/servant/src/Servant/API/ContentTypes.hs @@ -130,7 +130,9 @@ class Accept ctype where -- | @application/json@ instance Accept JSON where - contentType _ = "application" M.// "json" + contentTypes _ = + "application" M.// "json" M./: ("charset", "utf-8") NE.:| + [ "application" M.// "json" ] -- | @application/x-www-form-urlencoded@ instance Accept FormUrlEncoded where diff --git a/servant/test/Servant/API/ContentTypesSpec.hs b/servant/test/Servant/API/ContentTypesSpec.hs index 07fb5438..74bc09c5 100644 --- a/servant/test/Servant/API/ContentTypesSpec.hs +++ b/servant/test/Servant/API/ContentTypesSpec.hs @@ -115,21 +115,21 @@ spec = describe "Servant.API.ContentTypes" $ do it "returns the Content-Type as the first element of the tuple" $ do handleAcceptH (Proxy :: Proxy '[JSON]) "*/*" (3 :: Int) - `shouldSatisfy` ((== "application/json") . fst . fromJust) + `shouldSatisfy` ((== "application/json;charset=utf-8") . fst . fromJust) handleAcceptH (Proxy :: Proxy '[PlainText, JSON]) "application/json" (3 :: Int) - `shouldSatisfy` ((== "application/json") . fst . fromJust) + `shouldSatisfy` ((== "application/json;charset=utf-8") . fst . fromJust) handleAcceptH (Proxy :: Proxy '[PlainText, JSON, OctetStream]) "application/octet-stream" ("content" :: ByteString) `shouldSatisfy` ((== "application/octet-stream") . fst . fromJust) it "returns the appropriately serialized representation" $ do property $ \x -> handleAcceptH (Proxy :: Proxy '[JSON]) "*/*" (x :: SomeData) - == Just ("application/json", encode x) + == Just ("application/json;charset=utf-8", encode x) it "respects the Accept spec ordering" $ do let highest a b c = maximumBy (compare `on` snd) [ ("application/octet-stream", a) - , ("application/json", b) + , ("application/json;charset=utf-8", b) , ("text/plain;charset=utf-8", c) ] let acceptH a b c = addToAccept (Proxy :: Proxy OctetStream) a $