Accept empty string as empty json body when calling an rpc (#832)
This commit is contained in:
committed by
Joe Nelson
parent
0b486ccf44
commit
9b4b45671c
@@ -13,6 +13,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
- #827, Avoid Warp reaper, extend socket timeout to 1 hour - @majorcode
|
- #827, Avoid Warp reaper, extend socket timeout to 1 hour - @majorcode
|
||||||
- #791, malformed nested JSON error - @diogob
|
- #791, malformed nested JSON error - @diogob
|
||||||
- Resource embedding in views referencing tables in public schema - @fab1an
|
- Resource embedding in views referencing tables in public schema - @fab1an
|
||||||
|
- #777, Empty body is allowed when calling a non-parameterized RPC - @koulakis
|
||||||
- #831, Fix proc resource embedding issue with search_path - @steve-chavez
|
- #831, Fix proc resource embedding issue with search_path - @steve-chavez
|
||||||
|
|
||||||
## [0.4.0.0] - 2017-01-19
|
## [0.4.0.0] - 2017-01-19
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ module PostgREST.ApiRequest ( ApiRequest(..)
|
|||||||
|
|
||||||
import Protolude
|
import Protolude
|
||||||
import qualified Data.Aeson as JSON
|
import qualified Data.Aeson as JSON
|
||||||
|
import Data.Aeson.Types (emptyObject)
|
||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
import qualified Data.ByteString.Internal as BS (c2w)
|
import qualified Data.ByteString.Internal as BS (c2w)
|
||||||
import qualified Data.ByteString.Lazy as BL
|
import qualified Data.ByteString.Lazy as BL
|
||||||
@@ -124,13 +125,13 @@ userApiRequest schema req reqBody
|
|||||||
payload =
|
payload =
|
||||||
case decodeContentType . fromMaybe "application/json" $ lookupHeader "content-type" of
|
case decodeContentType . fromMaybe "application/json" $ lookupHeader "content-type" of
|
||||||
CTApplicationJSON ->
|
CTApplicationJSON ->
|
||||||
either Left (\val -> case ensureUniform (pluralize val) of
|
note "All object keys must match" . ensureUniform . pluralize
|
||||||
Nothing -> Left "All object keys must match"
|
=<< if BL.null reqBody && isTargetingProc
|
||||||
Just json -> Right json) (JSON.eitherDecode reqBody)
|
then Right emptyObject
|
||||||
|
else JSON.eitherDecode reqBody
|
||||||
CTTextCSV ->
|
CTTextCSV ->
|
||||||
either Left (\val -> case ensureUniform (csvToJson val) of
|
note "All lines must have same number of fields" . ensureUniform . csvToJson
|
||||||
Nothing -> Left "All lines must have same number of fields"
|
=<< CSV.decodeByName reqBody
|
||||||
Just json -> Right json) (CSV.decodeByName reqBody)
|
|
||||||
CTOther "application/x-www-form-urlencoded" ->
|
CTOther "application/x-www-form-urlencoded" ->
|
||||||
Right . PayloadJSON . V.singleton . M.fromList
|
Right . PayloadJSON . V.singleton . M.fromList
|
||||||
. map (toS *** JSON.String . toS) . parseSimpleQuery
|
. map (toS *** JSON.String . toS) . parseSimpleQuery
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import Test.Hspec.Wai
|
|||||||
import Test.Hspec.Wai.JSON
|
import Test.Hspec.Wai.JSON
|
||||||
import Network.HTTP.Types
|
import Network.HTTP.Types
|
||||||
import Network.Wai.Test (SResponse(simpleHeaders,simpleStatus,simpleBody))
|
import Network.Wai.Test (SResponse(simpleHeaders,simpleStatus,simpleBody))
|
||||||
|
import qualified Data.ByteString.Lazy as BL (empty)
|
||||||
|
|
||||||
import SpecHelper
|
import SpecHelper
|
||||||
import Text.Heredoc
|
import Text.Heredoc
|
||||||
@@ -481,7 +482,6 @@ spec = do
|
|||||||
, matchHeaders = ["Content-Range" <:> "0-0/2"]
|
, matchHeaders = ["Content-Range" <:> "0-0/2"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
it "returns proper json" $
|
it "returns proper json" $
|
||||||
post "/rpc/getitemrange" [json| { "min": 2, "max": 4 } |] `shouldRespondWith`
|
post "/rpc/getitemrange" [json| { "min": 2, "max": 4 } |] `shouldRespondWith`
|
||||||
[json| [ {"id": 3}, {"id":4} ] |]
|
[json| [ {"id": 3}, {"id":4} ] |]
|
||||||
@@ -640,6 +640,12 @@ spec = do
|
|||||||
, "boolean":"false", "date":"1900-01-01", "money":"$3.99", "enum":"foo" } |]
|
, "boolean":"false", "date":"1900-01-01", "money":"$3.99", "enum":"foo" } |]
|
||||||
{ matchHeaders = [matchContentTypeJson] }
|
{ matchHeaders = [matchContentTypeJson] }
|
||||||
|
|
||||||
|
context "a proc that receives no parameters" $
|
||||||
|
it "interprets empty string as empty json object on a post request" $
|
||||||
|
post "/rpc/noparamsproc" BL.empty `shouldRespondWith`
|
||||||
|
[json| "Return value of no parameters procedure." |]
|
||||||
|
{ matchHeaders = [matchContentTypeJson] }
|
||||||
|
|
||||||
describe "weird requests" $ do
|
describe "weird requests" $ do
|
||||||
it "can query as normal" $ do
|
it "can query as normal" $ do
|
||||||
get "/Escap3e;" `shouldRespondWith`
|
get "/Escap3e;" `shouldRespondWith`
|
||||||
|
|||||||
Vendored
+9
@@ -173,6 +173,15 @@ CREATE FUNCTION getitemrange(min bigint, max bigint) RETURNS SETOF items
|
|||||||
SELECT * FROM test.items WHERE id > $1 AND id <= $2;
|
SELECT * FROM test.items WHERE id > $1 AND id <= $2;
|
||||||
$_$;
|
$_$;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: version(); Type: FUNCTION; Schema: test; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE FUNCTION noparamsproc() RETURNS text
|
||||||
|
LANGUAGE sql
|
||||||
|
AS $$
|
||||||
|
SELECT a FROM (VALUES ('Return value of no parameters procedure.')) s(a);
|
||||||
|
$$;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: insert_insertable_view_with_join(); Type: FUNCTION; Schema: test; Owner: -
|
-- Name: insert_insertable_view_with_join(); Type: FUNCTION; Schema: test; Owner: -
|
||||||
|
|||||||
Reference in New Issue
Block a user