Skip to content

Commit

Permalink
Fix charset=utf-8 appending to binary output
Browse files Browse the repository at this point in the history
  • Loading branch information
steve-chavez committed Oct 29, 2020
1 parent a6696f3 commit 2798ced
Show file tree
Hide file tree
Showing 6 changed files with 16 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- #1094, Fix expired JWTs starting an empty transaction on the db - @steve-chavez
- #1162, Fix location header for POST request with select= without PK - @wolfgangwalther
- #1585, Fix error messages on connection failure for localized postgres on Windows - @wolfgangwalther
- #1636, Fix `application/octet-stream` appending `charset=utf-8` - @steve-chavez

### Changed

Expand Down
2 changes: 1 addition & 1 deletion src/PostgREST/ApiRequest.hs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ userApiRequest confSchemas rootSpec dbStructure req reqBody
(CTTextCSV, _) -> do
json <- csvToJson <$> CSV.decodeByName reqBody
note "All lines must have same number of fields" $ payloadAttributes (JSON.encode json) json
(CTOther "application/x-www-form-urlencoded", _) ->
(CTUrlEncoded, _) ->
let json = paramsFromList . map (toS *** toS) . parseSimpleQuery $ toS reqBody
keys = S.fromList $ M.keys json in
Right $ ProcessedJSON (JSON.encode json) keys
Expand Down
11 changes: 9 additions & 2 deletions src/PostgREST/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,17 @@ import Protolude.Conv (toS)
-- | Enumeration of currently supported response content types
data ContentType = CTApplicationJSON | CTSingularJSON
| CTTextCSV | CTTextPlain
| CTOpenAPI | CTOctetStream
| CTOpenAPI | CTUrlEncoded | CTOctetStream
| CTAny | CTOther ByteString deriving (Show, Eq)

-- | Convert from ContentType to a full HTTP Header
toHeader :: ContentType -> Header
toHeader ct = (hContentType, toMime ct <> "; charset=utf-8")
toHeader ct = (hContentType, toMime ct <> charset)
where
charset = case ct of
CTOctetStream -> mempty
CTOther _ -> mempty
_ -> "; charset=utf-8"

-- | Convert from ContentType to a ByteString representing the mime type
toMime :: ContentType -> ByteString
Expand All @@ -45,6 +50,7 @@ toMime CTTextCSV = "text/csv"
toMime CTTextPlain = "text/plain"
toMime CTOpenAPI = "application/openapi+json"
toMime CTSingularJSON = "application/vnd.pgrst.object+json"
toMime CTUrlEncoded = "application/x-www-form-urlencoded"
toMime CTOctetStream = "application/octet-stream"
toMime CTAny = "*/*"
toMime (CTOther ct) = ct
Expand All @@ -58,6 +64,7 @@ decodeContentType ct = case BS.takeWhile (/= BS.c2w ';') ct of
"application/openapi+json" -> CTOpenAPI
"application/vnd.pgrst.object+json" -> CTSingularJSON
"application/vnd.pgrst.object" -> CTSingularJSON
"application/x-www-form-urlencoded" -> CTUrlEncoded
"application/octet-stream" -> CTOctetStream
"*/*" -> CTAny
ct' -> CTOther ct'
Expand Down
2 changes: 1 addition & 1 deletion test/Feature/HtmlRawOutputSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ spec = describe "When raw-media-types is set to \"text/html\"" $
|</html>
|]
{ matchStatus = 200
, matchHeaders = ["Content-Type" <:> "text/html; charset=utf-8"]
, matchHeaders = ["Content-Type" <:> "text/html"]
}
4 changes: 2 additions & 2 deletions test/Feature/QuerySpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ spec actualPgVersion = do
request methodGet "/images_base64?select=img&name=eq.A.png" (acceptHdrs "application/octet-stream") ""
`shouldRespondWith` "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEUAAAD/AAAb/40iAAAAP0lEQVQI12NgwAbYG2AE/wEYwQMiZB4ACQkQYZEAIgqAhAGIKLCAEQ8kgMT/P1CCEUwc4IMSzA3sUIIdCHECAGSQEkeOTUyCAAAAAElFTkSuQmCC"
{ matchStatus = 200
, matchHeaders = ["Content-Type" <:> "application/octet-stream; charset=utf-8"]
, matchHeaders = ["Content-Type" <:> "application/octet-stream"]
}

it "can get raw output with Accept: text/plain" $
Expand All @@ -817,7 +817,7 @@ spec actualPgVersion = do
request methodGet "/images_base64?select=img&name=in.(A.png,B.png)" (acceptHdrs "application/octet-stream") ""
`shouldRespondWith` "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEUAAAD/AAAb/40iAAAAP0lEQVQI12NgwAbYG2AE/wEYwQMiZB4ACQkQYZEAIgqAhAGIKLCAEQ8kgMT/P1CCEUwc4IMSzA3sUIIdCHECAGSQEkeOTUyCAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEX///8AAP94wDzzAAAAL0lEQVQIW2NgwAb+HwARH0DEDyDxwAZEyGAhLODqHmBRzAcn5GAS///A1IF14AAA5/Adbiiz/0gAAAAASUVORK5CYII="
{ matchStatus = 200
, matchHeaders = ["Content-Type" <:> "application/octet-stream; charset=utf-8"]
, matchHeaders = ["Content-Type" <:> "application/octet-stream"]
}

describe "values with quotes in IN and NOT IN" $ do
Expand Down
4 changes: 2 additions & 2 deletions test/Feature/RpcSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ spec actualPgVersion =
request methodPost "/rpc/ret_base64_bin" (acceptHdrs "application/octet-stream") ""
`shouldRespondWith` "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEUAAAD/AAAb/40iAAAAP0lEQVQI12NgwAbYG2AE/wEYwQMiZB4ACQkQYZEAIgqAhAGIKLCAEQ8kgMT/P1CCEUwc4IMSzA3sUIIdCHECAGSQEkeOTUyCAAAAAElFTkSuQmCC"
{ matchStatus = 200
, matchHeaders = ["Content-Type" <:> "application/octet-stream; charset=utf-8"]
, matchHeaders = ["Content-Type" <:> "application/octet-stream"]
}

it "can get raw output with Accept: text/plain" $
Expand All @@ -744,7 +744,7 @@ spec actualPgVersion =
request methodPost "/rpc/ret_rows_with_base64_bin?select=img" (acceptHdrs "application/octet-stream") ""
`shouldRespondWith` "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEUAAAD/AAAb/40iAAAAP0lEQVQI12NgwAbYG2AE/wEYwQMiZB4ACQkQYZEAIgqAhAGIKLCAEQ8kgMT/P1CCEUwc4IMSzA3sUIIdCHECAGSQEkeOTUyCAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEX///8AAP94wDzzAAAAL0lEQVQIW2NgwAb+HwARH0DEDyDxwAZEyGAhLODqHmBRzAcn5GAS///A1IF14AAA5/Adbiiz/0gAAAAASUVORK5CYII="
{ matchStatus = 200
, matchHeaders = ["Content-Type" <:> "application/octet-stream; charset=utf-8"]
, matchHeaders = ["Content-Type" <:> "application/octet-stream"]
}

it "fails if a single column is not selected" $
Expand Down

0 comments on commit 2798ced

Please sign in to comment.