Fix empty headers being added on POST/PATCH/DELETE (#1458)

This commit is contained in:
Steve Chavez
2020-03-13 11:02:38 -05:00
committed by GitHub
parent 5b5945e427
commit 0f8838623b
5 changed files with 57 additions and 13 deletions
+18 -12
View File
@@ -168,17 +168,19 @@ app dbStructure proc cols conf apiRequest =
Left _ -> return . errorResponseFor $ GucHeadersError
Right ghdrs -> do
let
(ctHeader, rBody) = if iPreferRepresentation apiRequest == Full then (toHeader contentType, toS body) else (mempty, mempty)
headers = addHeadersIfNotIncluded [
(ctHeader, rBody) = if iPreferRepresentation apiRequest == Full
then (Just $ toHeader contentType, toS body)
else (Nothing, mempty)
headers = addHeadersIfNotIncluded (catMaybes [
if null fields
then mempty
else locationH tName fields
then Nothing
else Just $ locationH tName fields
, ctHeader
, contentRangeH 1 0 $ if shouldCount then Just queryTotal else Nothing
, Just $ contentRangeH 1 0 $ if shouldCount then Just queryTotal else Nothing
, if null pkCols && isNothing (iOnConflict apiRequest)
then mempty
else maybe mempty (\x -> ("Preference-Applied", show x)) $ iPreferResolution apiRequest
] (unwrapGucHeader <$> ghdrs)
then Nothing
else (\x -> ("Preference-Applied", show x)) <$> iPreferResolution apiRequest
]) (unwrapGucHeader <$> ghdrs)
if contentType == CTSingularJSON && queryTotal /= 1
then do
HT.condemn
@@ -204,8 +206,10 @@ app dbStructure proc cols conf apiRequest =
| iPreferRepresentation apiRequest == Full = status200
| otherwise = status204
contentRangeHeader = contentRangeH 0 (queryTotal - 1) $ if shouldCount then Just queryTotal else Nothing
(ctHeader, rBody) = if iPreferRepresentation apiRequest == Full then (toHeader contentType, toS body) else (mempty, mempty)
headers = addHeadersIfNotIncluded [contentRangeHeader, ctHeader] (unwrapGucHeader <$> ghdrs)
(ctHeader, rBody) = if iPreferRepresentation apiRequest == Full
then (Just $ toHeader contentType, toS body)
else (Nothing, mempty)
headers = addHeadersIfNotIncluded (catMaybes [Just contentRangeHeader, ctHeader]) (unwrapGucHeader <$> ghdrs)
if contentType == CTSingularJSON && queryTotal /= 1
then do
HT.condemn
@@ -263,8 +267,10 @@ app dbStructure proc cols conf apiRequest =
let
status = if iPreferRepresentation apiRequest == Full then status200 else status204
contentRangeHeader = contentRangeH 1 0 $ if shouldCount then Just queryTotal else Nothing
(ctHeader, rBody) = if iPreferRepresentation apiRequest == Full then (toHeader contentType, toS body) else (mempty, mempty)
headers = addHeadersIfNotIncluded [contentRangeHeader, ctHeader] (unwrapGucHeader <$> ghdrs)
(ctHeader, rBody) = if iPreferRepresentation apiRequest == Full
then (Just $ toHeader contentType, toS body)
else (Nothing, mempty)
headers = addHeadersIfNotIncluded (catMaybes [Just contentRangeHeader, ctHeader]) (unwrapGucHeader <$> ghdrs)
if contentType == CTSingularJSON
&& queryTotal /= 1
then do
+29
View File
@@ -2,6 +2,7 @@ module Feature.PgVersion96Spec where
import Network.HTTP.Types
import Network.Wai (Application)
import Network.Wai.Test (SResponse (simpleHeaders))
import Test.Hspec
import Test.Hspec.Wai
@@ -132,6 +133,34 @@ spec =
, matchHeaders = ["Location" <:> "/stuff?id=eq.1&overriden=true"]
}
-- On https://github.com/PostgREST/postgrest/issues/1427#issuecomment-595907535
-- it was reported that blank headers ` : ` where added and that cause proxies to fail the requests.
-- These tests are to ensure no blank headers are added.
context "Blank headers bug" $ do
it "shouldn't add blank headers on POST" $ do
r <- request methodPost "/loc_test" [] [json|{"id": "1", "c": "c1"}|]
liftIO $ do
let respHeaders = simpleHeaders r
respHeaders `shouldSatisfy` noBlankHeader
it "shouldn't add blank headers on PATCH" $ do
r <- request methodPatch "/loc_test?id=eq.1" [] [json|{"c": "c2"}|]
liftIO $ do
let respHeaders = simpleHeaders r
respHeaders `shouldSatisfy` noBlankHeader
it "shouldn't add blank headers on GET" $ do
r <- request methodGet "/loc_test" [] ""
liftIO $ do
let respHeaders = simpleHeaders r
respHeaders `shouldSatisfy` noBlankHeader
it "shouldn't add blank headers on DELETE" $ do
r <- request methodDelete "/loc_test?id=eq.1" [] ""
liftIO $ do
let respHeaders = simpleHeaders r
respHeaders `shouldSatisfy` noBlankHeader
context "Use of the phraseto_tsquery function" $ do
it "finds matches" $
get "/tsearch?text_search_vector=phfts.The%20Fat%20Cats" `shouldRespondWith`
+3
View File
@@ -178,6 +178,9 @@ matchHeader :: CI BS.ByteString -> BS.ByteString -> [Header] -> Bool
matchHeader name valRegex headers =
maybe False (=~ valRegex) $ lookup name headers
noBlankHeader :: [Header] -> Bool
noBlankHeader = notElem mempty
authHeaderBasic :: BS.ByteString -> BS.ByteString -> Header
authHeaderBasic u p =
(hAuthorization, "Basic " <> (toS . B64.encode . toS $ u <> ":" <> p))
+1
View File
@@ -121,6 +121,7 @@ GRANT ALL ON TABLE
, activities
, unit_workdays
, stuff
, loc_test
TO postgrest_test_anonymous;
GRANT INSERT ON TABLE insertonly TO postgrest_test_anonymous;
+6 -1
View File
@@ -1681,10 +1681,15 @@ begin
perform set_config(
'response.headers'
, format('[{"Location": "/%s?id=eq.%s&overriden=true"}]', tg_table_name, new.id)
, false
, true
);
end if;
return new;
end
$$ language plpgsql security definer;
create trigger location_for_stuff instead of insert on test.stuff for each row execute procedure test.location_for_stuff();
create table loc_test (
id int primary key
, c text
);