Move range validation to userApiRequest.
This commit is contained in:
@@ -15,6 +15,7 @@ module PostgREST.ApiRequest ( ApiRequest(..)
|
|||||||
) where
|
) where
|
||||||
|
|
||||||
import Protolude
|
import Protolude
|
||||||
|
import Data.Ranged.Ranges (emptyRange)
|
||||||
|
|
||||||
import qualified Data.Aeson as JSON
|
import qualified Data.Aeson as JSON
|
||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
@@ -62,7 +63,10 @@ data PreferRepresentation = Full | HeadersOnly | None deriving Eq
|
|||||||
data ContentType = CTApplicationJSON | CTTextCSV | CTOpenAPI
|
data ContentType = CTApplicationJSON | CTTextCSV | CTOpenAPI
|
||||||
| CTAny | CTOther BS.ByteString deriving Eq
|
| CTAny | CTOther BS.ByteString deriving Eq
|
||||||
|
|
||||||
data ApiRequestError = ErrorActionInappropriate | ErrorInvalidBody ByteString deriving (Show, Eq)
|
data ApiRequestError = ErrorActionInappropriate
|
||||||
|
| ErrorInvalidBody ByteString
|
||||||
|
| ErrorInvalidRange
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
-- | Convert from ContentType to a full HTTP Header
|
-- | Convert from ContentType to a full HTTP Header
|
||||||
toHeader :: ContentType -> Header
|
toHeader :: ContentType -> Header
|
||||||
@@ -118,6 +122,7 @@ data ApiRequest = ApiRequest {
|
|||||||
userApiRequest :: Schema -> Request -> RequestBody -> Either ApiRequestError ApiRequest
|
userApiRequest :: Schema -> Request -> RequestBody -> Either ApiRequestError ApiRequest
|
||||||
userApiRequest schema req reqBody
|
userApiRequest schema req reqBody
|
||||||
| isTargetingProc && method /= "POST" = Left ErrorActionInappropriate
|
| isTargetingProc && method /= "POST" = Left ErrorActionInappropriate
|
||||||
|
| topLevelRange == emptyRange = Left $ ErrorInvalidRange
|
||||||
| isError = Left $ ErrorInvalidBody payloadError
|
| isError = Left $ ErrorInvalidBody payloadError
|
||||||
| otherwise = Right ApiRequest {
|
| otherwise = Right ApiRequest {
|
||||||
iAction = action
|
iAction = action
|
||||||
@@ -168,6 +173,7 @@ userApiRequest schema req reqBody
|
|||||||
$ toS reqBody
|
$ toS reqBody
|
||||||
ct ->
|
ct ->
|
||||||
PayloadParseError $ "Content-Type not acceptable: " <> toMime ct
|
PayloadParseError $ "Content-Type not acceptable: " <> toMime ct
|
||||||
|
topLevelRange = fromMaybe allRange $ M.lookup "limit" ranges
|
||||||
action =
|
action =
|
||||||
if isTargetingProc
|
if isTargetingProc
|
||||||
then ActionInvoke
|
then ActionInvoke
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import qualified Data.ByteString.Char8 as BS
|
|||||||
import Data.IORef (IORef, readIORef)
|
import Data.IORef (IORef, readIORef)
|
||||||
import Data.List (delete, lookup)
|
import Data.List (delete, lookup)
|
||||||
import Data.Maybe (fromJust)
|
import Data.Maybe (fromJust)
|
||||||
import Data.Ranged.Ranges (emptyRange)
|
|
||||||
import Data.Text (replace, strip, isInfixOf, dropWhile, drop, intercalate)
|
import Data.Text (replace, strip, isInfixOf, dropWhile, drop, intercalate)
|
||||||
import Data.Time.Clock.POSIX (POSIXTime)
|
import Data.Time.Clock.POSIX (POSIXTime)
|
||||||
import Data.Tree
|
import Data.Tree
|
||||||
@@ -99,6 +98,7 @@ postgrest conf refDbStructure pool getTime =
|
|||||||
case err of
|
case err of
|
||||||
ErrorActionInappropriate -> errResponse status405 "Bad Request"
|
ErrorActionInappropriate -> errResponse status405 "Bad Request"
|
||||||
ErrorInvalidBody errorMessage -> errResponse status400 $ toS errorMessage
|
ErrorInvalidBody errorMessage -> errResponse status400 $ toS errorMessage
|
||||||
|
ErrorInvalidRange -> errResponse status416 "HTTP Range error"
|
||||||
|
|
||||||
transactionMode :: Action -> H.Mode
|
transactionMode :: Action -> H.Mode
|
||||||
transactionMode ActionRead = HT.Read
|
transactionMode ActionRead = HT.Read
|
||||||
@@ -115,7 +115,7 @@ app dbStructure conf apiRequest =
|
|||||||
(ActionRead, TargetIdent qi, Nothing) ->
|
(ActionRead, TargetIdent qi, Nothing) ->
|
||||||
case readSqlParts of
|
case readSqlParts of
|
||||||
Left errorResponse -> return errorResponse
|
Left errorResponse -> return errorResponse
|
||||||
Right (q, cq) -> respondToRange $ do
|
Right (q, cq) -> do
|
||||||
let singular = iPreferSingular apiRequest
|
let singular = iPreferSingular apiRequest
|
||||||
stm = createReadStatement q cq singular shouldCount (contentType == CTTextCSV)
|
stm = createReadStatement q cq singular shouldCount (contentType == CTTextCSV)
|
||||||
row <- H.query () stm
|
row <- H.query () stm
|
||||||
@@ -219,7 +219,7 @@ app dbStructure conf apiRequest =
|
|||||||
(ActionInvoke, TargetProc qi, Just (PayloadJSON (UniformObjects payload))) ->
|
(ActionInvoke, TargetProc qi, Just (PayloadJSON (UniformObjects payload))) ->
|
||||||
case readSqlParts of
|
case readSqlParts of
|
||||||
Left errorResponse -> return errorResponse
|
Left errorResponse -> return errorResponse
|
||||||
Right (q, cq) -> respondToRange $ do
|
Right (q, cq) -> do
|
||||||
let p = V.head payload
|
let p = V.head payload
|
||||||
singular = iPreferSingular apiRequest
|
singular = iPreferSingular apiRequest
|
||||||
paramsAsSingleObject = iPreferSingleObjectParameter apiRequest
|
paramsAsSingleObject = iPreferSingleObjectParameter apiRequest
|
||||||
@@ -276,10 +276,6 @@ app dbStructure conf apiRequest =
|
|||||||
countQuery = requestToCountQuery schema <$> readDbRequest
|
countQuery = requestToCountQuery schema <$> readDbRequest
|
||||||
readSqlParts = (,) <$> selectQuery <*> countQuery
|
readSqlParts = (,) <$> selectQuery <*> countQuery
|
||||||
mutateSqlParts = (,) <$> selectQuery <*> mutateQuery
|
mutateSqlParts = (,) <$> selectQuery <*> mutateQuery
|
||||||
respondToRange response =
|
|
||||||
if topLevelRange == emptyRange
|
|
||||||
then return $ errResponse status416 "HTTP Range error"
|
|
||||||
else response
|
|
||||||
|
|
||||||
responseContentTypeOrError :: [ContentType] -> Action -> Either Response ContentType
|
responseContentTypeOrError :: [ContentType] -> Action -> Either Response ContentType
|
||||||
responseContentTypeOrError accepts action = serves contentTypesForRequest accepts
|
responseContentTypeOrError accepts action = serves contentTypesForRequest accepts
|
||||||
|
|||||||
Reference in New Issue
Block a user