Return Location header only when using Prefer: return=header-only

This commit is contained in:
Laurence Isla
2022-06-24 12:53:27 -05:00
committed by GitHub
parent f7745e1569
commit 169547aee6
4 changed files with 39 additions and 30 deletions
+1
View File
@@ -71,6 +71,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
+ For migrating, clients must be updated to the embedding form of `/view?select=*,other_view!column(*)`.
- #1959, A full table PATCH(without filters) is now restricted, it requires a `limit` parameter - @steve-chavez
+ A `PATCH /tbl` will now result in 0 rows updated, unless `PATCH /tbl?limit=10&order=<pkcol>` is done
- #2312, Using `Prefer: return=representation` no longer returns a `Location` header - @laurenceisla
## [9.0.1] - 2022-06-03
+1 -1
View File
@@ -63,7 +63,7 @@ createWriteStatement selectQuery mutateQuery wantSingle isInsert asCsv asGeoJson
"FROM (" <> selectF <> ") _postgrest_t"
locF =
if isInsert && rep /= None
if isInsert && rep == HeadersOnly
then BS.unwords [
"CASE WHEN pg_catalog.count(_postgrest_t) = 1",
"THEN coalesce(" <> locationF pKeys <> ", " <> noLocationF <> ")",
+1 -1
View File
@@ -155,7 +155,7 @@ instance ToAppliedHeader PreferResolution
--
-- From https://tools.ietf.org/html/rfc7240#section-4.2
data PreferRepresentation
= Full -- ^ Return the body plus the Location header(in case of POST).
= Full -- ^ Return the body.
| HeadersOnly -- ^ Return the Location header(in case of POST). This needs a SELECT privilege on the pk.
| None -- ^ Return nothing from the mutated data.
deriving Eq
+36 -28
View File
@@ -96,7 +96,7 @@ spec actualPgVersion = do
[json|{"id":6,"name":"New Project","client_id":2}|] `shouldRespondWith` [json|[{"id":6,"name":"New Project","clients":{"id":2,"name":"Apple"}}]|]
{ matchStatus = 201
, matchHeaders = [ matchContentTypeJson
, "Location" <:> "/projects?id=eq.6"
, matchHeaderAbsent hLocation
, "Content-Range" <:> "*/1" ]
}
@@ -107,7 +107,7 @@ spec actualPgVersion = do
[json|[{"pId":"7","pName":"New Project","cId":"2"}]|]
{ matchStatus = 201
, matchHeaders = [ matchContentTypeJson
, "Location" <:> "/projects?id=eq.7"
, matchHeaderAbsent hLocation
, "Content-Range" <:> "*/*" ]
}
@@ -117,7 +117,7 @@ spec actualPgVersion = do
[json|[{"name":"New Project","client_id":2}]|]
{ matchStatus = 201
, matchHeaders = [ matchContentTypeJson
, "Location" <:> "/projects?id=eq.10"
, matchHeaderAbsent hLocation
, "Content-Range" <:> "*/*" ]
}
@@ -254,7 +254,7 @@ spec actualPgVersion = do
`shouldRespondWith`
[json|[ { "k1":12, "k2":"Rock & R+ll", "extra": null } ]|]
{ matchStatus = 201
, matchHeaders = [ "Location" <:> "/compound_pk?k1=eq.12&k2=eq.Rock%20%26%20R%2Bll" ]
, matchHeaders = [ matchHeaderAbsent hLocation ]
}
context "with bulk insert" $
@@ -436,6 +436,37 @@ spec actualPgVersion = do
, matchHeaders = []
}
context "with unicode values" $ do
it "succeeds and returns full representation" $
request methodPost "/simple_pk2?select=extra,k"
[("Prefer", "return=representation")]
[json| { "k":"圍棋", "extra":"" } |]
`shouldRespondWith`
[json|[ { "k":"圍棋", "extra":"" } ]|]
{ matchStatus = 201 }
it "succeeds and returns usable location header" $ do
p <- request methodPost "/simple_pk2?select=extra,k"
[("Prefer", "tx=commit"), ("Prefer", "return=headers-only")]
[json| { "k":"圍棋", "extra":"" } |]
pure p `shouldRespondWith`
""
{ matchStatus = 201 }
Just location <- pure $ lookup hLocation $ simpleHeaders p
get location
`shouldRespondWith`
[json|[ { "k":"圍棋", "extra":"" } ]|]
request methodDelete location
[("Prefer", "tx=commit")]
""
`shouldRespondWith`
""
{ matchStatus = 204
, matchHeaders = [matchHeaderAbsent hContentType]
}
describe "CSV insert" $ do
context "disparate csv types" $
it "succeeds with multipart response" $ do
@@ -489,29 +520,6 @@ spec actualPgVersion = do
, matchHeaders = [matchContentTypeJson]
}
context "with unicode values" $
it "succeeds and returns usable location header" $ do
p <- request methodPost "/simple_pk2?select=extra,k"
[("Prefer", "tx=commit"), ("Prefer", "return=representation")]
[json| { "k":"圍棋", "extra":"" } |]
pure p `shouldRespondWith`
[json|[ { "k":"圍棋", "extra":"" } ]|]
{ matchStatus = 201 }
Just location <- pure $ lookup hLocation $ simpleHeaders p
get location
`shouldRespondWith`
[json|[ { "k":"圍棋", "extra":"" } ]|]
request methodDelete location
[("Prefer", "tx=commit")]
""
`shouldRespondWith`
""
{ matchStatus = 204
, matchHeaders = [matchHeaderAbsent hContentType]
}
describe "Row level permission" $
it "set user_id when inserting rows" $ do
request methodPost "/authors_only"
@@ -537,7 +545,7 @@ spec actualPgVersion = do
`shouldRespondWith`
[json|[{"id":6,"name":"wot","parent_content":{"name":"wut"}}]|]
{ matchStatus = 201
, matchHeaders = [ matchContentTypeJson , "Location" <:> "/web_content?id=eq.6" ]
, matchHeaders = [ matchContentTypeJson , matchHeaderAbsent hLocation ]
}
context "table with limited privileges" $ do