break: remove binary field logic, raw-media-types

BREAKING CHANGE

Can be done later with custom media types
This commit is contained in:
steve-chavez
2023-10-26 09:04:02 -05:00
committed by Steve Chavez
parent 6920a88dc0
commit 14d030b96c
26 changed files with 54 additions and 121 deletions
+7
View File
@@ -86,6 +86,13 @@ This project adheres to [Semantic Versioning](http://semver.org/).
+ The `/table?select=*,other!fk(*)` must be used to disambiguate + The `/table?select=*,other!fk(*)` must be used to disambiguate
+ The server aids in choosing the `!fk` by sending a `hint` on the error whenever an ambiguous request happens. + The server aids in choosing the `!fk` by sending a `hint` on the error whenever an ambiguous request happens.
### Changed
- #1462, #1548, Removed [raw-media-types config](https://postgrest.org/en/v11.1/references/configuration.html#raw-media-types) - @steve-chavez
+ Can be replaced with custom media types
- #1462, #1548, Removed `application/octet-stream`, `text/plain`, `text/xml` [builtin support for scalar results](https://postgrest.org/en/v11.1/references/api/resource_representation.html#scalar-function-response-format) - @steve-chavez
+ Can be replaced with custom media types
## [11.1.0] - 2023-06-07 ## [11.1.0] - 2023-06-07
### Added ### Added
-3
View File
@@ -218,9 +218,6 @@ exampleConfigFile =
|## Base url for the OpenAPI output |## Base url for the OpenAPI output
|openapi-server-proxy-uri = "" |openapi-server-proxy-uri = ""
| |
|## Content types to produce raw output
|# raw-media-types="image/png, image/jpg"
|
|## Configurable CORS origins |## Configurable CORS origins
|# server-cors-allowed-origins = "" |# server-cors-allowed-origins = ""
| |
-4
View File
@@ -61,7 +61,6 @@ import PostgREST.Config.JSPath (JSPath, JSPathExp (..),
dumpJSPath, pRoleClaimKey) dumpJSPath, pRoleClaimKey)
import PostgREST.Config.Proxy (Proxy (..), import PostgREST.Config.Proxy (Proxy (..),
isMalformedProxyUri, toURI) isMalformedProxyUri, toURI)
import PostgREST.MediaType (MediaType (..), toMime)
import PostgREST.SchemaCache.Identifiers (QualifiedIdentifier, dumpQi, import PostgREST.SchemaCache.Identifiers (QualifiedIdentifier, dumpQi,
toQi) toQi)
@@ -102,7 +101,6 @@ data AppConfig = AppConfig
, configOpenApiMode :: OpenAPIMode , configOpenApiMode :: OpenAPIMode
, configOpenApiSecurityActive :: Bool , configOpenApiSecurityActive :: Bool
, configOpenApiServerProxyUri :: Maybe Text , configOpenApiServerProxyUri :: Maybe Text
, configRawMediaTypes :: [MediaType]
, configServerCorsAllowedOrigins :: Maybe [Text] , configServerCorsAllowedOrigins :: Maybe [Text]
, configServerHost :: Text , configServerHost :: Text
, configServerPort :: Int , configServerPort :: Int
@@ -169,7 +167,6 @@ toText conf =
,("openapi-mode", q . dumpOpenApiMode . configOpenApiMode) ,("openapi-mode", q . dumpOpenApiMode . configOpenApiMode)
,("openapi-security-active", T.toLower . show . configOpenApiSecurityActive) ,("openapi-security-active", T.toLower . show . configOpenApiSecurityActive)
,("openapi-server-proxy-uri", q . fromMaybe mempty . configOpenApiServerProxyUri) ,("openapi-server-proxy-uri", q . fromMaybe mempty . configOpenApiServerProxyUri)
,("raw-media-types", q . T.decodeUtf8 . BS.intercalate "," . fmap toMime . configRawMediaTypes)
,("server-cors-allowed-origins", q . maybe "" (T.intercalate ",") . configServerCorsAllowedOrigins) ,("server-cors-allowed-origins", q . maybe "" (T.intercalate ",") . configServerCorsAllowedOrigins)
,("server-host", q . configServerHost) ,("server-host", q . configServerHost)
,("server-port", show . configServerPort) ,("server-port", show . configServerPort)
@@ -274,7 +271,6 @@ parser optPath env dbSettings roleSettings roleIsolationLvl =
<*> parseOpenAPIMode "openapi-mode" <*> parseOpenAPIMode "openapi-mode"
<*> (fromMaybe False <$> optBool "openapi-security-active") <*> (fromMaybe False <$> optBool "openapi-security-active")
<*> parseOpenAPIServerProxyURI "openapi-server-proxy-uri" <*> parseOpenAPIServerProxyURI "openapi-server-proxy-uri"
<*> (maybe [] (fmap (MTOther . encodeUtf8) . splitOnCommas) <$> optValue "raw-media-types")
<*> (fmap splitOnCommas <$> optValue "server-cors-allowed-origins") <*> (fmap splitOnCommas <$> optValue "server-cors-allowed-origins")
<*> (fromMaybe "!4" <$> optString "server-host") <*> (fromMaybe "!4" <$> optString "server-host")
<*> (fromMaybe 3000 <$> optInt "server-port") <*> (fromMaybe 3000 <$> optInt "server-port")
+8 -50
View File
@@ -124,18 +124,16 @@ wrappedReadPlan :: QualifiedIdentifier -> AppConfig -> SchemaCache -> ApiRequest
wrappedReadPlan identifier conf sCache apiRequest@ApiRequest{iPreferences=Preferences{..},..} = do wrappedReadPlan identifier conf sCache apiRequest@ApiRequest{iPreferences=Preferences{..},..} = do
rPlan <- readPlan identifier conf sCache apiRequest rPlan <- readPlan identifier conf sCache apiRequest
mediaType <- mapLeft ApiRequestError $ negotiateContent conf iAction iPathInfo iAcceptMediaType mediaType <- mapLeft ApiRequestError $ negotiateContent conf iAction iPathInfo iAcceptMediaType
binField <- mapLeft ApiRequestError $ binaryField conf mediaType Nothing rPlan
if not (null invalidPrefs) && preferHandling == Just Strict then Left $ ApiRequestError $ InvalidPreferences invalidPrefs else Right () if not (null invalidPrefs) && preferHandling == Just Strict then Left $ ApiRequestError $ InvalidPreferences invalidPrefs else Right ()
return $ WrappedReadPlan rPlan SQL.Read (mediaToAggregate mediaType binField apiRequest) mediaType return $ WrappedReadPlan rPlan SQL.Read (mediaToAggregate mediaType apiRequest) mediaType
mutateReadPlan :: Mutation -> ApiRequest -> QualifiedIdentifier -> AppConfig -> SchemaCache -> Either Error MutateReadPlan mutateReadPlan :: Mutation -> ApiRequest -> QualifiedIdentifier -> AppConfig -> SchemaCache -> Either Error MutateReadPlan
mutateReadPlan mutation apiRequest@ApiRequest{iPreferences=Preferences{..},..} identifier conf sCache = do mutateReadPlan mutation apiRequest@ApiRequest{iPreferences=Preferences{..},..} identifier conf sCache = do
rPlan <- readPlan identifier conf sCache apiRequest rPlan <- readPlan identifier conf sCache apiRequest
mPlan <- mutatePlan mutation identifier apiRequest sCache rPlan mPlan <- mutatePlan mutation identifier apiRequest sCache rPlan
mediaType <- mapLeft ApiRequestError $ negotiateContent conf iAction iPathInfo iAcceptMediaType mediaType <- mapLeft ApiRequestError $ negotiateContent conf iAction iPathInfo iAcceptMediaType
binField <- mapLeft ApiRequestError $ binaryField conf mediaType Nothing rPlan
if not (null invalidPrefs) && preferHandling == Just Strict then Left $ ApiRequestError $ InvalidPreferences invalidPrefs else Right () if not (null invalidPrefs) && preferHandling == Just Strict then Left $ ApiRequestError $ InvalidPreferences invalidPrefs else Right ()
return $ MutateReadPlan rPlan mPlan SQL.Write (mediaToAggregate mediaType binField apiRequest) mediaType return $ MutateReadPlan rPlan mPlan SQL.Write (mediaToAggregate mediaType apiRequest) mediaType
callReadPlan :: QualifiedIdentifier -> AppConfig -> SchemaCache -> ApiRequest -> InvokeMethod -> Either Error CallReadPlan callReadPlan :: QualifiedIdentifier -> AppConfig -> SchemaCache -> ApiRequest -> InvokeMethod -> Either Error CallReadPlan
callReadPlan identifier conf sCache apiRequest@ApiRequest{iPreferences=Preferences{..},..} invMethod = do callReadPlan identifier conf sCache apiRequest@ApiRequest{iPreferences=Preferences{..},..} invMethod = do
@@ -160,9 +158,8 @@ callReadPlan identifier conf sCache apiRequest@ApiRequest{iPreferences=Preferenc
(InvPost, Routine.Volatile) -> SQL.Write (InvPost, Routine.Volatile) -> SQL.Write
cPlan = callPlan proc apiRequest paramKeys args rPlan cPlan = callPlan proc apiRequest paramKeys args rPlan
mediaType <- mapLeft ApiRequestError $ negotiateContent conf iAction iPathInfo iAcceptMediaType mediaType <- mapLeft ApiRequestError $ negotiateContent conf iAction iPathInfo iAcceptMediaType
binField <- mapLeft ApiRequestError $ binaryField conf mediaType (Just proc) rPlan
if not (null invalidPrefs) && preferHandling == Just Strict then Left $ ApiRequestError $ InvalidPreferences invalidPrefs else Right () if not (null invalidPrefs) && preferHandling == Just Strict then Left $ ApiRequestError $ InvalidPreferences invalidPrefs else Right ()
return $ CallReadPlan rPlan cPlan txMode proc (mediaToAggregate mediaType binField apiRequest) mediaType return $ CallReadPlan rPlan cPlan txMode proc (mediaToAggregate mediaType apiRequest) mediaType
where where
qsParams' = QueryParams.qsParams iQueryParams qsParams' = QueryParams.qsParams iQueryParams
@@ -828,40 +825,8 @@ inferColsEmbedNeeds (Node ReadPlan{select} forest) pkCols
addFilterToLogicForest :: CoercibleFilter -> [CoercibleLogicTree] -> [CoercibleLogicTree] addFilterToLogicForest :: CoercibleFilter -> [CoercibleLogicTree] -> [CoercibleLogicTree]
addFilterToLogicForest flt lf = CoercibleStmnt flt : lf addFilterToLogicForest flt lf = CoercibleStmnt flt : lf
-- | If raw(binary) output is requested, check that MediaType is one of the mediaToAggregate :: MediaType -> ApiRequest -> ResultAggregate
-- admitted rawMediaTypes and that`?select=...` contains only one field other mediaToAggregate mt apiReq@ApiRequest{iAction=act, iPreferences=Preferences{preferRepresentation=rep}} =
-- than `*`
binaryField :: AppConfig -> MediaType -> Maybe Routine -> ReadPlanTree -> Either ApiRequestError (Maybe FieldName)
binaryField AppConfig{configRawMediaTypes} acceptMediaType proc rpTree
| isRawMediaType =
if (funcReturnsScalar <$> proc) == Just True ||
(funcReturnsSetOfScalar <$> proc) == Just True
then Right $ Just "pgrst_scalar"
else
let
fieldName = fstFieldName rpTree
in
case fieldName of
Just fld -> Right $ Just fld
Nothing -> Left $ BinaryFieldError acceptMediaType
| otherwise =
Right Nothing
where
isRawMediaType = acceptMediaType `elem` configRawMediaTypes `L.union` [MTOctetStream, MTTextPlain, MTTextXML] || isRawPlan acceptMediaType
isRawPlan mt = case mt of
MTPlan MTOctetStream _ _ -> True
MTPlan MTTextPlain _ _ -> True
MTPlan MTTextXML _ _ -> True
_ -> False
fstFieldName :: ReadPlanTree -> Maybe FieldName
fstFieldName (Node ReadPlan{select=(CoercibleField{cfName="*", cfJsonPath=[]}, _, _):_} []) = Nothing
fstFieldName (Node ReadPlan{select=[(CoercibleField{cfName=fld, cfJsonPath=[]}, _, _)]} []) = Just fld
fstFieldName _ = Nothing
mediaToAggregate :: MediaType -> Maybe FieldName -> ApiRequest -> ResultAggregate
mediaToAggregate mt binField apiReq@ApiRequest{iAction=act, iPreferences=Preferences{preferRepresentation=rep}} =
if noAgg then NoAgg if noAgg then NoAgg
else case mt of else case mt of
MTApplicationJSON -> BuiltinAggJson MTApplicationJSON -> BuiltinAggJson
@@ -873,16 +838,11 @@ mediaToAggregate mt binField apiReq@ApiRequest{iAction=act, iPreferences=Prefere
MTOpenAPI -> BuiltinAggJson MTOpenAPI -> BuiltinAggJson
MTUrlEncoded -> NoAgg -- TODO: unreachable since a previous step (producedMediaTypes) whitelists the media types that can become aggregates. MTUrlEncoded -> NoAgg -- TODO: unreachable since a previous step (producedMediaTypes) whitelists the media types that can become aggregates.
-- binary types
MTTextPlain -> BuiltinAggBinary binField
MTTextXML -> BuiltinAggXml binField
MTOctetStream -> BuiltinAggBinary binField
MTOther _ -> BuiltinAggBinary binField
-- Doing `Accept: application/vnd.pgrst.plan; for="application/vnd.pgrst.plan"` doesn't make sense, so we just empty the body. -- Doing `Accept: application/vnd.pgrst.plan; for="application/vnd.pgrst.plan"` doesn't make sense, so we just empty the body.
-- TODO: fail instead to be more strict -- TODO: fail instead to be more strict
MTPlan (MTPlan{}) _ _ -> NoAgg MTPlan (MTPlan{}) _ _ -> NoAgg
MTPlan media _ _ -> mediaToAggregate media binField apiReq MTPlan media _ _ -> mediaToAggregate media apiReq
_ -> NoAgg
where where
noAgg = case act of noAgg = case act of
ActionMutate _ -> rep == Just HeadersOnly || rep == Just None || isNothing rep ActionMutate _ -> rep == Just HeadersOnly || rep == Just None || isNothing rep
@@ -904,7 +864,7 @@ negotiateContent conf action path accepts =
producedMediaTypes :: AppConfig -> Action -> PathInfo -> [MediaType] producedMediaTypes :: AppConfig -> Action -> PathInfo -> [MediaType]
producedMediaTypes conf action path = producedMediaTypes conf action path =
case action of case action of
ActionRead _ -> defaultMediaTypes ++ rawMediaTypes ActionRead _ -> defaultMediaTypes
ActionInvoke _ -> invokeMediaTypes ActionInvoke _ -> invokeMediaTypes
ActionInfo -> defaultMediaTypes ActionInfo -> defaultMediaTypes
ActionMutate _ -> defaultMediaTypes ActionMutate _ -> defaultMediaTypes
@@ -913,9 +873,7 @@ producedMediaTypes conf action path =
inspectMediaTypes = [MTOpenAPI, MTApplicationJSON, MTArrayJSONStrip, MTAny] inspectMediaTypes = [MTOpenAPI, MTApplicationJSON, MTArrayJSONStrip, MTAny]
invokeMediaTypes = invokeMediaTypes =
defaultMediaTypes defaultMediaTypes
++ rawMediaTypes
++ [MTOpenAPI | pathIsRootSpec path] ++ [MTOpenAPI | pathIsRootSpec path]
defaultMediaTypes = defaultMediaTypes =
[MTApplicationJSON, MTArrayJSONStrip, MTSingularJSON True, MTSingularJSON False, MTGeoJSON, MTTextCSV] ++ [MTApplicationJSON, MTArrayJSONStrip, MTSingularJSON True, MTSingularJSON False, MTGeoJSON, MTTextCSV] ++
[MTPlan MTApplicationJSON PlanText mempty | configDbPlanEnabled conf] ++ [MTAny] [MTPlan MTApplicationJSON PlanText mempty | configDbPlanEnabled conf] ++ [MTAny]
rawMediaTypes = configRawMediaTypes conf `L.union` [MTOctetStream, MTTextPlain, MTTextXML]
+2 -2
View File
@@ -66,7 +66,7 @@ import Protolude hiding (Handler)
type DbHandler = ExceptT Error SQL.Transaction type DbHandler = ExceptT Error SQL.Transaction
readQuery :: WrappedReadPlan -> AppConfig -> ApiRequest -> DbHandler ResultSet readQuery :: WrappedReadPlan -> AppConfig -> ApiRequest -> DbHandler ResultSet
readQuery WrappedReadPlan{wrReadPlan, wrMedia, wrResAgg} conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} = do readQuery WrappedReadPlan{..} conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} = do
let countQuery = QueryBuilder.readPlanToCountQuery wrReadPlan let countQuery = QueryBuilder.readPlanToCountQuery wrReadPlan
resultSet <- resultSet <-
lift . SQL.statement mempty $ lift . SQL.statement mempty $
@@ -151,7 +151,7 @@ deleteQuery mrPlan@MutateReadPlan{mrMedia} apiReq@ApiRequest{..} conf = do
pure resultSet pure resultSet
invokeQuery :: Routine -> CallReadPlan -> ApiRequest -> AppConfig -> PgVersion -> DbHandler ResultSet invokeQuery :: Routine -> CallReadPlan -> ApiRequest -> AppConfig -> PgVersion -> DbHandler ResultSet
invokeQuery rout CallReadPlan{crReadPlan, crCallPlan, crResAgg, crMedia} apiReq@ApiRequest{iPreferences=Preferences{..}} conf@AppConfig{..} pgVer = do invokeQuery rout CallReadPlan{..} apiReq@ApiRequest{iPreferences=Preferences{..}} conf@AppConfig{..} pgVer = do
resultSet <- resultSet <-
lift . SQL.statement mempty $ lift . SQL.statement mempty $
Statements.prepareCall Statements.prepareCall
-13
View File
@@ -209,20 +209,9 @@ asJsonF rout strip
Just r -> (funcReturnsSingleComposite r, funcReturnsScalar r, funcReturnsSetOfScalar r) Just r -> (funcReturnsSingleComposite r, funcReturnsScalar r, funcReturnsSetOfScalar r)
Nothing -> (False, False, False) Nothing -> (False, False, False)
asXmlF :: Maybe FieldName -> SQL.Snippet
asXmlF (Just fieldName) = "coalesce(xmlagg(_postgrest_t." <> pgFmtIdent fieldName <> "), '')"
-- TODO unreachable because a previous step(binaryField) will validate that there's a field. This will be cleared once custom media types are implemented.
asXmlF Nothing = "coalesce(xmlagg(_postgrest_t), '')"
asGeoJsonF :: SQL.Snippet asGeoJsonF :: SQL.Snippet
asGeoJsonF = "json_build_object('type', 'FeatureCollection', 'features', coalesce(json_agg(ST_AsGeoJSON(_postgrest_t)::json), '[]'))" asGeoJsonF = "json_build_object('type', 'FeatureCollection', 'features', coalesce(json_agg(ST_AsGeoJSON(_postgrest_t)::json), '[]'))"
asBinaryF :: Maybe FieldName -> SQL.Snippet
asBinaryF (Just fieldName) = "coalesce(string_agg(_postgrest_t." <> pgFmtIdent fieldName <> ", ''), '')"
-- TODO unreachable because a previous step(binaryField) will validate that there's a field. This will be cleared once custom media types are implemented.
asBinaryF Nothing = "coalesce(string_agg(_postgrest_t, ''), '')"
locationF :: [Text] -> SQL.Snippet locationF :: [Text] -> SQL.Snippet
locationF pKeys = [qc|( locationF pKeys = [qc|(
WITH data AS (SELECT row_to_json(_) AS row FROM {sourceCTEName} AS _ LIMIT 1) WITH data AS (SELECT row_to_json(_) AS row FROM {sourceCTEName} AS _ LIMIT 1)
@@ -504,6 +493,4 @@ aggF rout = \case
BuiltinAggSingleJson strip -> asJsonSingleF rout strip BuiltinAggSingleJson strip -> asJsonSingleF rout strip
BuiltinAggGeoJson -> asGeoJsonF BuiltinAggGeoJson -> asGeoJsonF
BuiltinAggCsv -> asCsvF BuiltinAggCsv -> asCsvF
BuiltinAggXml bField -> asXmlF bField
BuiltinAggBinary bField -> asBinaryF bField
NoAgg -> "''::text" NoAgg -> "''::text"
+1 -4
View File
@@ -23,8 +23,7 @@ import qualified Data.Aeson as JSON
import qualified Data.HashMap.Strict as HM import qualified Data.HashMap.Strict as HM
import qualified Hasql.Transaction.Sessions as SQL import qualified Hasql.Transaction.Sessions as SQL
import PostgREST.SchemaCache.Identifiers (FieldName, import PostgREST.SchemaCache.Identifiers (QualifiedIdentifier (..),
QualifiedIdentifier (..),
Schema, TableName) Schema, TableName)
import Protolude import Protolude
@@ -95,8 +94,6 @@ data ResultAggregate
| BuiltinAggArrayJsonStrip | BuiltinAggArrayJsonStrip
| BuiltinAggGeoJson | BuiltinAggGeoJson
| BuiltinAggCsv | BuiltinAggCsv
| BuiltinAggXml (Maybe FieldName)
| BuiltinAggBinary (Maybe FieldName)
| NoAgg | NoAgg
deriving (Eq, Show) deriving (Eq, Show)
-1
View File
@@ -27,7 +27,6 @@ log-level = "error"
openapi-mode = "follow-privileges" openapi-mode = "follow-privileges"
openapi-security-active = false openapi-security-active = false
openapi-server-proxy-uri = "" openapi-server-proxy-uri = ""
raw-media-types = ""
server-cors-allowed-origins = "" server-cors-allowed-origins = ""
server-host = "!4" server-host = "!4"
server-port = 3000 server-port = 3000
@@ -27,7 +27,6 @@ log-level = "error"
openapi-mode = "follow-privileges" openapi-mode = "follow-privileges"
openapi-security-active = false openapi-security-active = false
openapi-server-proxy-uri = "" openapi-server-proxy-uri = ""
raw-media-types = ""
server-cors-allowed-origins = "" server-cors-allowed-origins = ""
server-host = "!4" server-host = "!4"
server-port = 3000 server-port = 3000
@@ -27,7 +27,6 @@ log-level = "error"
openapi-mode = "follow-privileges" openapi-mode = "follow-privileges"
openapi-security-active = false openapi-security-active = false
openapi-server-proxy-uri = "" openapi-server-proxy-uri = ""
raw-media-types = ""
server-cors-allowed-origins = "" server-cors-allowed-origins = ""
server-host = "!4" server-host = "!4"
server-port = 3000 server-port = 3000
-1
View File
@@ -27,7 +27,6 @@ log-level = "error"
openapi-mode = "follow-privileges" openapi-mode = "follow-privileges"
openapi-security-active = false openapi-security-active = false
openapi-server-proxy-uri = "" openapi-server-proxy-uri = ""
raw-media-types = ""
server-cors-allowed-origins = "" server-cors-allowed-origins = ""
server-host = "!4" server-host = "!4"
server-port = 3000 server-port = 3000
@@ -27,7 +27,6 @@ log-level = "info"
openapi-mode = "disabled" openapi-mode = "disabled"
openapi-security-active = false openapi-security-active = false
openapi-server-proxy-uri = "https://otherexample.org/api" openapi-server-proxy-uri = "https://otherexample.org/api"
raw-media-types = "application/vnd.pgrst.other-db-config"
server-cors-allowed-origins = "http://example.com" server-cors-allowed-origins = "http://example.com"
server-host = "0.0.0.0" server-host = "0.0.0.0"
server-port = 80 server-port = 80
@@ -27,7 +27,6 @@ log-level = "info"
openapi-mode = "ignore-privileges" openapi-mode = "ignore-privileges"
openapi-security-active = true openapi-security-active = true
openapi-server-proxy-uri = "https://example.org/api" openapi-server-proxy-uri = "https://example.org/api"
raw-media-types = "application/vnd.pgrst.db-config"
server-cors-allowed-origins = "http://example.com" server-cors-allowed-origins = "http://example.com"
server-host = "0.0.0.0" server-host = "0.0.0.0"
server-port = 80 server-port = 80
@@ -27,7 +27,6 @@ log-level = "info"
openapi-mode = "ignore-privileges" openapi-mode = "ignore-privileges"
openapi-security-active = true openapi-security-active = true
openapi-server-proxy-uri = "https://postgrest.org" openapi-server-proxy-uri = "https://postgrest.org"
raw-media-types = "application/vnd.pgrst.config"
server-cors-allowed-origins = "http://example.com" server-cors-allowed-origins = "http://example.com"
server-host = "0.0.0.0" server-host = "0.0.0.0"
server-port = 80 server-port = 80
-1
View File
@@ -27,7 +27,6 @@ log-level = "error"
openapi-mode = "follow-privileges" openapi-mode = "follow-privileges"
openapi-security-active = false openapi-security-active = false
openapi-server-proxy-uri = "" openapi-server-proxy-uri = ""
raw-media-types = ""
server-cors-allowed-origins = "" server-cors-allowed-origins = ""
server-host = "!4" server-host = "!4"
server-port = 3000 server-port = 3000
-1
View File
@@ -29,7 +29,6 @@ PGRST_LOG_LEVEL: info
PGRST_OPENAPI_MODE: 'ignore-privileges' PGRST_OPENAPI_MODE: 'ignore-privileges'
PGRST_OPENAPI_SECURITY_ACTIVE: true PGRST_OPENAPI_SECURITY_ACTIVE: true
PGRST_OPENAPI_SERVER_PROXY_URI: 'https://postgrest.org' PGRST_OPENAPI_SERVER_PROXY_URI: 'https://postgrest.org'
PGRST_RAW_MEDIA_TYPES: application/vnd.pgrst.config
PGRST_SERVER_CORS_ALLOWED_ORIGINS: "http://example.com" PGRST_SERVER_CORS_ALLOWED_ORIGINS: "http://example.com"
PGRST_SERVER_HOST: 0.0.0.0 PGRST_SERVER_HOST: 0.0.0.0
PGRST_SERVER_PORT: 80 PGRST_SERVER_PORT: 80
-1
View File
@@ -27,7 +27,6 @@ log-level = "info"
openapi-mode = "ignore-privileges" openapi-mode = "ignore-privileges"
openapi-security-active = true openapi-security-active = true
openapi-server-proxy-uri = "https://postgrest.org" openapi-server-proxy-uri = "https://postgrest.org"
raw-media-types = "application/vnd.pgrst.config"
server-cors-allowed-origins = "http://example.com" server-cors-allowed-origins = "http://example.com"
server-host = "0.0.0.0" server-host = "0.0.0.0"
server-port = 80 server-port = 80
-3
View File
@@ -8,6 +8,3 @@ db-channel-enabled = 13
# expects integer or string # expects integer or string
db-max-rows = true db-max-rows = true
# expects string
raw-media-types = true
-2
View File
@@ -3,7 +3,6 @@ CREATE ROLE db_config_authenticator LOGIN NOINHERIT;
-- reloadable config options -- reloadable config options
ALTER ROLE db_config_authenticator SET pgrst.jwt_aud = 'https://example.org'; ALTER ROLE db_config_authenticator SET pgrst.jwt_aud = 'https://example.org';
ALTER ROLE db_config_authenticator SET pgrst.openapi_server_proxy_uri = 'https://example.org/api'; ALTER ROLE db_config_authenticator SET pgrst.openapi_server_proxy_uri = 'https://example.org/api';
ALTER ROLE db_config_authenticator SET pgrst.raw_media_types = 'application/vnd.pgrst.db-config';
ALTER ROLE db_config_authenticator SET pgrst.jwt_secret = 'REALLY=REALLY=REALLY=REALLY=VERY=SAFE'; ALTER ROLE db_config_authenticator SET pgrst.jwt_secret = 'REALLY=REALLY=REALLY=REALLY=VERY=SAFE';
ALTER ROLE db_config_authenticator SET pgrst.jwt_secret_is_base64 = 'false'; ALTER ROLE db_config_authenticator SET pgrst.jwt_secret_is_base64 = 'false';
ALTER ROLE db_config_authenticator SET pgrst.jwt_role_claim_key = '."a"."role"'; ALTER ROLE db_config_authenticator SET pgrst.jwt_role_claim_key = '."a"."role"';
@@ -51,7 +50,6 @@ ALTER ROLE db_config_authenticator SET pgrst.db_config = 'true';
CREATE ROLE other_authenticator LOGIN NOINHERIT; CREATE ROLE other_authenticator LOGIN NOINHERIT;
ALTER ROLE other_authenticator SET pgrst.jwt_aud = 'https://otherexample.org'; ALTER ROLE other_authenticator SET pgrst.jwt_aud = 'https://otherexample.org';
ALTER ROLE other_authenticator SET pgrst.openapi_server_proxy_uri = 'https://otherexample.org/api'; ALTER ROLE other_authenticator SET pgrst.openapi_server_proxy_uri = 'https://otherexample.org/api';
ALTER ROLE other_authenticator SET pgrst.raw_media_types = 'application/vnd.pgrst.other-db-config';
ALTER ROLE other_authenticator SET pgrst.jwt_secret = 'ODERREALLYREALLYREALLYREALLYVERYSAFE'; ALTER ROLE other_authenticator SET pgrst.jwt_secret = 'ODERREALLYREALLYREALLYREALLYVERYSAFE';
ALTER ROLE other_authenticator SET pgrst.jwt_secret_is_base64 = 'true'; ALTER ROLE other_authenticator SET pgrst.jwt_secret_is_base64 = 'true';
ALTER ROLE other_authenticator SET pgrst.db_schemas = 'test, other_tenant1, other_tenant2'; ALTER ROLE other_authenticator SET pgrst.db_schemas = 'test, other_tenant1, other_tenant2';
-5
View File
@@ -119,11 +119,6 @@ cli:
use_defaultenv: true use_defaultenv: true
env: env:
PGRST_DB_TX_END: rollback PGRST_DB_TX_END: rollback
- name: raw-media-types list
expect: 'raw-media-types = "image/png,image/jpeg"'
use_defaultenv: true
env:
PGRST_RAW_MEDIA_TYPES: ' image/png , image/jpeg '
roleclaims: roleclaims:
- key: '.postgrest.a_role' - key: '.postgrest.a_role'
+2 -1
View File
@@ -12,7 +12,8 @@ import SpecHelper (acceptHdrs)
spec :: SpecWith ((), Application) spec :: SpecWith ((), Application)
spec = describe "When raw-media-types is set to \"text/html\"" $ spec = describe "When raw-media-types is set to \"text/html\"" $
it "can get raw output with Accept: text/html" $ it "can get raw output with Accept: text/html" $ do
pendingWith "TBD"
request methodGet "/rpc/welcome.html" (acceptHdrs "text/html") "" request methodGet "/rpc/welcome.html" (acceptHdrs "text/html") ""
`shouldRespondWith` `shouldRespondWith`
[str| [str|
+1
View File
@@ -276,6 +276,7 @@ spec actualPgVersion = do
totalCost `shouldBe` 68.56 totalCost `shouldBe` 68.56
it "outputs the plan for text/xml" $ do it "outputs the plan for text/xml" $ do
pendingWith "TBD"
r <- request methodGet "/rpc/return_scalar_xml" r <- request methodGet "/rpc/return_scalar_xml"
(acceptHdrs "application/vnd.pgrst.plan+json; for=\"text/xml\"; options=verbose") "" (acceptHdrs "application/vnd.pgrst.plan+json; for=\"text/xml\"; options=verbose") ""
+9 -4
View File
@@ -1043,21 +1043,24 @@ spec actualPgVersion = do
{ matchHeaders = [matchContentTypeJson] } { matchHeaders = [matchContentTypeJson] }
context "binary output" $ do context "binary output" $ do
it "can query if a single column is selected" $ it "can query if a single column is selected" $ do
pendingWith "TBD"
request methodGet "/images_base64?select=img&name=eq.A.png" (acceptHdrs "application/octet-stream") "" request methodGet "/images_base64?select=img&name=eq.A.png" (acceptHdrs "application/octet-stream") ""
`shouldRespondWith` "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEUAAAD/AAAb/40iAAAAP0lEQVQI12NgwAbYG2AE/wEYwQMiZB4ACQkQYZEAIgqAhAGIKLCAEQ8kgMT/P1CCEUwc4IMSzA3sUIIdCHECAGSQEkeOTUyCAAAAAElFTkSuQmCC" `shouldRespondWith` "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEUAAAD/AAAb/40iAAAAP0lEQVQI12NgwAbYG2AE/wEYwQMiZB4ACQkQYZEAIgqAhAGIKLCAEQ8kgMT/P1CCEUwc4IMSzA3sUIIdCHECAGSQEkeOTUyCAAAAAElFTkSuQmCC"
{ matchStatus = 200 { matchStatus = 200
, matchHeaders = ["Content-Type" <:> "application/octet-stream"] , matchHeaders = ["Content-Type" <:> "application/octet-stream"]
} }
it "can get raw output with Accept: text/plain" $ it "can get raw output with Accept: text/plain" $ do
pendingWith "TBD"
request methodGet "/projects?select=name&id=eq.1" (acceptHdrs "text/plain") "" request methodGet "/projects?select=name&id=eq.1" (acceptHdrs "text/plain") ""
`shouldRespondWith` "Windows 7" `shouldRespondWith` "Windows 7"
{ matchStatus = 200 { matchStatus = 200
, matchHeaders = ["Content-Type" <:> "text/plain; charset=utf-8"] , matchHeaders = ["Content-Type" <:> "text/plain; charset=utf-8"]
} }
it "can get raw xml output with Accept: text/xml" $ it "can get raw xml output with Accept: text/xml" $ do
pendingWith "TBD"
request methodGet "/xmltest?select=xml" (acceptHdrs "text/xml") "" request methodGet "/xmltest?select=xml" (acceptHdrs "text/xml") ""
`shouldRespondWith` `shouldRespondWith`
"<myxml>foo</myxml>bar<foobar><baz/></foobar>" "<myxml>foo</myxml>bar<foobar><baz/></foobar>"
@@ -1066,6 +1069,7 @@ spec actualPgVersion = do
} }
it "fails if a single column is not selected" $ do it "fails if a single column is not selected" $ do
pendingWith "TBD"
request methodGet "/images?select=img,name&name=eq.A.png" (acceptHdrs "application/octet-stream") "" request methodGet "/images?select=img,name&name=eq.A.png" (acceptHdrs "application/octet-stream") ""
`shouldRespondWith` `shouldRespondWith`
[json| {"message":"application/octet-stream requested but more than one column was selected","code":"PGRST113","details":null,"hint":null} |] [json| {"message":"application/octet-stream requested but more than one column was selected","code":"PGRST113","details":null,"hint":null} |]
@@ -1085,7 +1089,8 @@ spec actualPgVersion = do
[json| {"message":"application/octet-stream requested but more than one column was selected","code":"PGRST113","details":null,"hint":null} |] [json| {"message":"application/octet-stream requested but more than one column was selected","code":"PGRST113","details":null,"hint":null} |]
{ matchStatus = 406 } { matchStatus = 406 }
it "concatenates results if more than one row is returned" $ it "concatenates results if more than one row is returned" $ do
pendingWith "TBD"
request methodGet "/images_base64?select=img&name=in.(A.png,B.png)" (acceptHdrs "application/octet-stream") "" request methodGet "/images_base64?select=img&name=in.(A.png,B.png)" (acceptHdrs "application/octet-stream") ""
`shouldRespondWith` "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEUAAAD/AAAb/40iAAAAP0lEQVQI12NgwAbYG2AE/wEYwQMiZB4ACQkQYZEAIgqAhAGIKLCAEQ8kgMT/P1CCEUwc4IMSzA3sUIIdCHECAGSQEkeOTUyCAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEX///8AAP94wDzzAAAAL0lEQVQIW2NgwAb+HwARH0DEDyDxwAZEyGAhLODqHmBRzAcn5GAS///A1IF14AAA5/Adbiiz/0gAAAAASUVORK5CYII=" `shouldRespondWith` "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEUAAAD/AAAb/40iAAAAP0lEQVQI12NgwAbYG2AE/wEYwQMiZB4ACQkQYZEAIgqAhAGIKLCAEQ8kgMT/P1CCEUwc4IMSzA3sUIIdCHECAGSQEkeOTUyCAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEX///8AAP94wDzzAAAAL0lEQVQIW2NgwAb+HwARH0DEDyDxwAZEyGAhLODqHmBRzAcn5GAS///A1IF14AAA5/Adbiiz/0gAAAAASUVORK5CYII="
{ matchStatus = 200 { matchStatus = 200
+23 -10
View File
@@ -1079,21 +1079,24 @@ spec actualPgVersion =
context "binary output" $ do context "binary output" $ do
context "Proc that returns scalar" $ do context "Proc that returns scalar" $ do
it "can query without selecting column" $ it "can query without selecting column" $ do
pendingWith "TBD"
request methodPost "/rpc/ret_base64_bin" (acceptHdrs "application/octet-stream") "" request methodPost "/rpc/ret_base64_bin" (acceptHdrs "application/octet-stream") ""
`shouldRespondWith` "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEUAAAD/AAAb/40iAAAAP0lEQVQI12NgwAbYG2AE/wEYwQMiZB4ACQkQYZEAIgqAhAGIKLCAEQ8kgMT/P1CCEUwc4IMSzA3sUIIdCHECAGSQEkeOTUyCAAAAAElFTkSuQmCC" `shouldRespondWith` "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEUAAAD/AAAb/40iAAAAP0lEQVQI12NgwAbYG2AE/wEYwQMiZB4ACQkQYZEAIgqAhAGIKLCAEQ8kgMT/P1CCEUwc4IMSzA3sUIIdCHECAGSQEkeOTUyCAAAAAElFTkSuQmCC"
{ matchStatus = 200 { matchStatus = 200
, matchHeaders = ["Content-Type" <:> "application/octet-stream"] , matchHeaders = ["Content-Type" <:> "application/octet-stream"]
} }
it "can get raw output with Accept: text/plain" $ it "can get raw output with Accept: text/plain" $ do
pendingWith "TBD"
request methodGet "/rpc/welcome" (acceptHdrs "text/plain") "" request methodGet "/rpc/welcome" (acceptHdrs "text/plain") ""
`shouldRespondWith` "Welcome to PostgREST" `shouldRespondWith` "Welcome to PostgREST"
{ matchStatus = 200 { matchStatus = 200
, matchHeaders = ["Content-Type" <:> "text/plain; charset=utf-8"] , matchHeaders = ["Content-Type" <:> "text/plain; charset=utf-8"]
} }
it "can get raw xml output with Accept: text/xml" $ it "can get raw xml output with Accept: text/xml" $ do
pendingWith "TBD"
request methodGet "/rpc/return_scalar_xml" (acceptHdrs "text/xml") "" request methodGet "/rpc/return_scalar_xml" (acceptHdrs "text/xml") ""
`shouldRespondWith` `shouldRespondWith`
"<my-xml-tag/>" "<my-xml-tag/>"
@@ -1101,7 +1104,8 @@ spec actualPgVersion =
, matchHeaders = ["Content-Type" <:> "text/xml; charset=utf-8"] , matchHeaders = ["Content-Type" <:> "text/xml; charset=utf-8"]
} }
it "can get raw xml output with Accept: text/xml" $ it "can get raw xml output with Accept: text/xml" $ do
pendingWith "TBD"
request methodGet "/rpc/welcome.xml" (acceptHdrs "text/xml") "" request methodGet "/rpc/welcome.xml" (acceptHdrs "text/xml") ""
`shouldRespondWith` `shouldRespondWith`
"<html>\n <head>\n <title>PostgREST</title>\n </head>\n <body>\n <h1>Welcome to PostgREST</h1>\n </body>\n</html>" "<html>\n <head>\n <title>PostgREST</title>\n </head>\n <body>\n <h1>Welcome to PostgREST</h1>\n </body>\n</html>"
@@ -1109,7 +1113,8 @@ spec actualPgVersion =
, matchHeaders = ["Content-Type" <:> "text/xml; charset=utf-8"] , matchHeaders = ["Content-Type" <:> "text/xml; charset=utf-8"]
} }
it "should fail with function returning text and Accept: text/xml" $ it "should fail with function returning text and Accept: text/xml" $ do
pendingWith "TBD"
request methodGet "/rpc/welcome" (acceptHdrs "text/xml") "" request methodGet "/rpc/welcome" (acceptHdrs "text/xml") ""
`shouldRespondWith` `shouldRespondWith`
[json| [json|
@@ -1125,7 +1130,8 @@ spec actualPgVersion =
} }
context "Proc that returns set of scalars" $ context "Proc that returns set of scalars" $
it "can query without selecting column" $ it "can query without selecting column" $ do
pendingWith "TBD"
request methodGet "/rpc/welcome_twice" request methodGet "/rpc/welcome_twice"
(acceptHdrs "text/plain") (acceptHdrs "text/plain")
"" ""
@@ -1136,14 +1142,16 @@ spec actualPgVersion =
} }
context "Proc that returns rows" $ do context "Proc that returns rows" $ do
it "can query if a single column is selected" $ it "can query if a single column is selected" $ do
pendingWith "TBD"
request methodPost "/rpc/ret_rows_with_base64_bin?select=img" (acceptHdrs "application/octet-stream") "" request methodPost "/rpc/ret_rows_with_base64_bin?select=img" (acceptHdrs "application/octet-stream") ""
`shouldRespondWith` "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEUAAAD/AAAb/40iAAAAP0lEQVQI12NgwAbYG2AE/wEYwQMiZB4ACQkQYZEAIgqAhAGIKLCAEQ8kgMT/P1CCEUwc4IMSzA3sUIIdCHECAGSQEkeOTUyCAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEX///8AAP94wDzzAAAAL0lEQVQIW2NgwAb+HwARH0DEDyDxwAZEyGAhLODqHmBRzAcn5GAS///A1IF14AAA5/Adbiiz/0gAAAAASUVORK5CYII=" `shouldRespondWith` "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEUAAAD/AAAb/40iAAAAP0lEQVQI12NgwAbYG2AE/wEYwQMiZB4ACQkQYZEAIgqAhAGIKLCAEQ8kgMT/P1CCEUwc4IMSzA3sUIIdCHECAGSQEkeOTUyCAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEX///8AAP94wDzzAAAAL0lEQVQIW2NgwAb+HwARH0DEDyDxwAZEyGAhLODqHmBRzAcn5GAS///A1IF14AAA5/Adbiiz/0gAAAAASUVORK5CYII="
{ matchStatus = 200 { matchStatus = 200
, matchHeaders = ["Content-Type" <:> "application/octet-stream"] , matchHeaders = ["Content-Type" <:> "application/octet-stream"]
} }
it "fails if a single column is not selected" $ it "fails if a single column is not selected" $ do
pendingWith "TBD"
request methodPost "/rpc/ret_rows_with_base64_bin" request methodPost "/rpc/ret_rows_with_base64_bin"
(acceptHdrs "application/octet-stream") "" (acceptHdrs "application/octet-stream") ""
`shouldRespondWith` `shouldRespondWith`
@@ -1318,14 +1326,16 @@ spec actualPgVersion =
`shouldRespondWith` `shouldRespondWith`
[json|{"A": 1, "B": 2, "C": 3}|] [json|{"A": 1, "B": 2, "C": 3}|]
it "can insert text directly" $ it "can insert text directly" $ do
pendingWith "TBD"
request methodPost "/rpc/unnamed_text_param" request methodPost "/rpc/unnamed_text_param"
[("Content-Type", "text/plain"), ("Accept", "text/plain")] [("Content-Type", "text/plain"), ("Accept", "text/plain")]
[str|unnamed text arg|] [str|unnamed text arg|]
`shouldRespondWith` `shouldRespondWith`
[str|unnamed text arg|] [str|unnamed text arg|]
it "can insert xml directly" $ it "can insert xml directly" $ do
pendingWith "TBD"
request methodPost "/rpc/unnamed_xml_param" request methodPost "/rpc/unnamed_xml_param"
[("Content-Type", "text/xml"), ("Accept", "text/xml")] [("Content-Type", "text/xml"), ("Accept", "text/xml")]
[str|<note><from>John</from><to>Jane</to><message>Remember me</message></note>|] [str|<note><from>John</from><to>Jane</to><message>Remember me</message></note>|]
@@ -1333,6 +1343,7 @@ spec actualPgVersion =
[str|<note><from>John</from><to>Jane</to><message>Remember me</message></note>|] [str|<note><from>John</from><to>Jane</to><message>Remember me</message></note>|]
it "can insert bytea directly" $ do it "can insert bytea directly" $ do
pendingWith "TBD"
let file = unsafePerformIO $ BL.readFile "test/spec/fixtures/image.png" let file = unsafePerformIO $ BL.readFile "test/spec/fixtures/image.png"
r <- request methodPost "/rpc/unnamed_bytea_param" r <- request methodPost "/rpc/unnamed_bytea_param"
[("Content-Type", "application/octet-stream"), ("Accept", "application/octet-stream")] [("Content-Type", "application/octet-stream"), ("Accept", "application/octet-stream")]
@@ -1418,6 +1429,7 @@ spec actualPgVersion =
} }
it "should be able to fallback to the single unnamed parameter function when other overloaded functions are not found" $ do it "should be able to fallback to the single unnamed parameter function when other overloaded functions are not found" $ do
pendingWith "TBD"
request methodPost "/rpc/overloaded_unnamed_param" request methodPost "/rpc/overloaded_unnamed_param"
[("Content-Type", "application/json")] [("Content-Type", "application/json")]
[json|{"A": 1, "B": 2, "C": 3}|] [json|{"A": 1, "B": 2, "C": 3}|]
@@ -1476,6 +1488,7 @@ spec actualPgVersion =
} }
it "should fail on /rpc/unnamed_xml_param when posting invalid xml" $ do it "should fail on /rpc/unnamed_xml_param when posting invalid xml" $ do
pendingWith "TBD"
request methodPost "/rpc/unnamed_xml_param" request methodPost "/rpc/unnamed_xml_param"
[("Content-Type", "text/xml"), ("Accept", "text/xml")] [("Content-Type", "text/xml"), ("Accept", "text/xml")]
[str|<|] [str|<|]
+1 -5
View File
@@ -103,7 +103,6 @@ main = do
asymJwkApp = app testCfgAsymJWK asymJwkApp = app testCfgAsymJWK
asymJwkSetApp = app testCfgAsymJWKSet asymJwkSetApp = app testCfgAsymJWKSet
rootSpecApp = app testCfgRootSpec rootSpecApp = app testCfgRootSpec
htmlRawOutputApp = app testCfgHtmlRawOutput
responseHeadersApp = app testCfgResponseHeaders responseHeadersApp = app testCfgResponseHeaders
disallowRollbackApp = app testCfgDisallowRollback disallowRollbackApp = app testCfgDisallowRollback
forceRollbackApp = app testCfgForceRollback forceRollbackApp = app testCfgForceRollback
@@ -150,6 +149,7 @@ main = do
, ("Feature.Query.ComputedRelsSpec" , Feature.Query.ComputedRelsSpec.spec) , ("Feature.Query.ComputedRelsSpec" , Feature.Query.ComputedRelsSpec.spec)
, ("Feature.Query.RelatedQueriesSpec" , Feature.Query.RelatedQueriesSpec.spec) , ("Feature.Query.RelatedQueriesSpec" , Feature.Query.RelatedQueriesSpec.spec)
, ("Feature.Query.SpreadQueriesSpec" , Feature.Query.SpreadQueriesSpec.spec) , ("Feature.Query.SpreadQueriesSpec" , Feature.Query.SpreadQueriesSpec.spec)
, ("Feature.Query.HtmlRawOutputSpec" , Feature.Query.HtmlRawOutputSpec.spec)
, ("Feature.NoSuperuserSpec" , Feature.NoSuperuserSpec.spec) , ("Feature.NoSuperuserSpec" , Feature.NoSuperuserSpec.spec)
] ]
@@ -160,10 +160,6 @@ main = do
parallel $ beforeAll_ analyze . before withApp $ parallel $ beforeAll_ analyze . before withApp $
describe "Feature.Query.RangeSpec" Feature.Query.RangeSpec.spec describe "Feature.Query.RangeSpec" Feature.Query.RangeSpec.spec
-- this test runs with a raw-output-media-types set to text/html
parallel $ before htmlRawOutputApp $
describe "Feature.Query.HtmlRawOutputSpec" Feature.Query.HtmlRawOutputSpec.spec
-- this test runs with a different server flag -- this test runs with a different server flag
parallel $ before maxRowsApp $ parallel $ before maxRowsApp $
describe "Feature.Query.QueryLimitedSpec" Feature.Query.QueryLimitedSpec.spec describe "Feature.Query.QueryLimitedSpec" Feature.Query.QueryLimitedSpec.spec
-5
View File
@@ -31,7 +31,6 @@ import PostgREST.Config (AppConfig (..),
LogLevel (..), LogLevel (..),
OpenAPIMode (..), OpenAPIMode (..),
parseSecret) parseSecret)
import PostgREST.MediaType (MediaType (..))
import PostgREST.SchemaCache.Identifiers (QualifiedIdentifier (..)) import PostgREST.SchemaCache.Identifiers (QualifiedIdentifier (..))
import Protolude hiding (get, toS) import Protolude hiding (get, toS)
import Protolude.Conv (toS) import Protolude.Conv (toS)
@@ -128,7 +127,6 @@ baseCfg = let secret = Just $ encodeUtf8 "reallyreallyreallyreallyverysafe" in
, configOpenApiMode = OAFollowPriv , configOpenApiMode = OAFollowPriv
, configOpenApiSecurityActive = False , configOpenApiSecurityActive = False
, configOpenApiServerProxyUri = Nothing , configOpenApiServerProxyUri = Nothing
, configRawMediaTypes = []
, configServerCorsAllowedOrigins = Nothing , configServerCorsAllowedOrigins = Nothing
, configServerHost = "localhost" , configServerHost = "localhost"
, configServerPort = 3000 , configServerPort = 3000
@@ -221,9 +219,6 @@ testCfgExtraSearchPath = baseCfg { configDbExtraSearchPath = ["public", "extensi
testCfgRootSpec :: AppConfig testCfgRootSpec :: AppConfig
testCfgRootSpec = baseCfg { configDbRootSpec = Just $ QualifiedIdentifier mempty "root"} testCfgRootSpec = baseCfg { configDbRootSpec = Just $ QualifiedIdentifier mempty "root"}
testCfgHtmlRawOutput :: AppConfig
testCfgHtmlRawOutput = baseCfg { configRawMediaTypes = [MTOther "text/html"] }
testCfgResponseHeaders :: AppConfig testCfgResponseHeaders :: AppConfig
testCfgResponseHeaders = baseCfg { configDbPreRequest = Just $ QualifiedIdentifier mempty "custom_headers" } testCfgResponseHeaders = baseCfg { configDbPreRequest = Just $ QualifiedIdentifier mempty "custom_headers" }