diff --git a/CHANGELOG.md b/CHANGELOG.md index 1790da7e5..f54a18345 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - #2899, Fix `application/vnd.pgrst.array` not accepted as a valid mediatype - @taimoorzaeem - #2524, Fix schema cache and configuration reloading with `NOTIFY` not working on Windows - @diogob, @laurenceisla + - #2915, Fix duplicate headers in response - @taimoorzaeem ## [11.2.0] - 2023-08-10 diff --git a/src/PostgREST/Response.hs b/src/PostgREST/Response.hs index 160cb1834..36374fb59 100644 --- a/src/PostgREST/Response.hs +++ b/src/PostgREST/Response.hs @@ -297,11 +297,36 @@ optionalRollback AppConfig{..} ApiRequest{iPreferences=Preferences{..}} resp = d | otherwise = identity --- | Add headers not already included to allow the user to override them instead of duplicating them +-- | Add headers not already included to allow the user to override them instead of duplicating them. The exception here is the Preference-Applied header, which will be duplicated here, but later get combined into a single header +-- +-- >>> :{ +-- addHeadersIfNotIncluded +-- [("Content-Type","application/json"), +-- ("Preference-Applied","tx=commit"), +-- ("Content-Range","*/*")] +-- [("Content-Type","custom/type"), +-- ("Preference-Applied","return=representation")] +-- :} +-- [("Preference-Applied","tx=commit"),("Content-Range","*/*"),("Content-Type","custom/type"),("Preference-Applied","return=representation")] +-- +-- | Hmm, below seems like a problem, however this won't happen practically +-- because preferRepresentation is only added once in the request processing +-- pipeline. Thus, no need to add an extra filter. In case this becomes a +-- problem in the future, we can always change this +-- +-- >>> :{ +-- addHeadersIfNotIncluded +-- [("Preference-Applied","return=minimal")] +-- [("Preference-Applied","return=representation")] +-- :} +-- [("Preference-Applied","return=minimal"),("Preference-Applied","return=representation")] + addHeadersIfNotIncluded :: [HTTP.Header] -> [HTTP.Header] -> [HTTP.Header] addHeadersIfNotIncluded newHeaders initialHeaders = - filter (\(nk, nv) -> isNothing $ find (\(ik, iv) -> ik == nk && nv == iv) initialHeaders) newHeaders ++ - initialHeaders + filter (keyNotSameOrPrefApp . fst) newHeaders ++ initialHeaders + where + keyNotSameOrPrefApp k = isNothing (find ((== k) . fst) initialHeaders) || + (k == HTTP.hPreferenceApplied) -- | Filters out multiple Preference-Applied Headers from the list and concatenate them into a single Preference-Applied header: --