add: add "Vary" header to responses
Co-authored-by: Steve Chavez <stevechavezast@gmail.com>
This commit is contained in:
committed by
Steve Chavez
co-authored by
Steve Chavez
parent
d5df12c9c2
commit
1f54e2accc
@@ -13,9 +13,12 @@ All notable changes to this project will be documented in this file. From versio
|
|||||||
- Optimize requests with `Prefer: count=exact` that do not use ranges or `db-max-rows` by @laurenceisla in #3957
|
- Optimize requests with `Prefer: count=exact` that do not use ranges or `db-max-rows` by @laurenceisla in #3957
|
||||||
+ Removed unnecessary double count when building the `Content-Range`.
|
+ Removed unnecessary double count when building the `Content-Range`.
|
||||||
- Add config `client_error_verbosity` to customize error verbosity by @taimoorzaeem in #4088, #3980, #3824
|
- Add config `client_error_verbosity` to customize error verbosity by @taimoorzaeem in #4088, #3980, #3824
|
||||||
|
- Add `Vary` header to responses by @develop7 in #4609
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
- All responses now include a `Vary` header by @develop7 in #4609
|
||||||
|
|
||||||
- Log error when `db-schemas` config contains schema `pg_catalog` or `information_schema` by @taimoorzaeem in #4359
|
- Log error when `db-schemas` config contains schema `pg_catalog` or `information_schema` by @taimoorzaeem in #4359
|
||||||
+ Now fails at startup. Prior to this, it failed with `PGRST205` on requests related to these schemas.
|
+ Now fails at startup. Prior to this, it failed with `PGRST205` on requests related to these schemas.
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ BOM
|
|||||||
Bytea
|
Bytea
|
||||||
Cardano
|
Cardano
|
||||||
cd
|
cd
|
||||||
|
CDNs
|
||||||
centric
|
centric
|
||||||
CLI
|
CLI
|
||||||
CMS
|
CMS
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ PostgREST exposes three database objects of a schema as resources: tables, views
|
|||||||
api/aggregate_functions.rst
|
api/aggregate_functions.rst
|
||||||
api/openapi.rst
|
api/openapi.rst
|
||||||
api/preferences.rst
|
api/preferences.rst
|
||||||
|
api/vary_header.rst
|
||||||
api/*
|
api/*
|
||||||
|
|
||||||
.. raw:: html
|
.. raw:: html
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
.. _vary_header:
|
||||||
|
|
||||||
|
Vary Header
|
||||||
|
===========
|
||||||
|
|
||||||
|
In order to assist caching proxies and CDNs, PostgREST includes a ``Vary`` header of value
|
||||||
|
``Accept, Prefer, Range`` in its responses which should fit most of the bills. As any other
|
||||||
|
response header, it's available for override
|
||||||
|
by updating ``response.headers`` GUC variable accordingly, for example:
|
||||||
|
|
||||||
|
.. code-block:: postgres
|
||||||
|
|
||||||
|
-- Override the Vary header to include Accept, Prefer and X-Test-Vary headers
|
||||||
|
perform set_config('response.headers', '[{"Vary": "Accept, Prefer, X-Test-Vary"}]', true);
|
||||||
|
|
||||||
|
In this case PostgREST will use provided value verbatim.
|
||||||
+21
-10
@@ -60,15 +60,16 @@ import PostgREST.SchemaCache (SchemaCache (..))
|
|||||||
import PostgREST.TimeIt (timeItT)
|
import PostgREST.TimeIt (timeItT)
|
||||||
import PostgREST.Version (docsVersion, prettyVersion)
|
import PostgREST.Version (docsVersion, prettyVersion)
|
||||||
|
|
||||||
import qualified Data.ByteString.Char8 as BS
|
import qualified Data.ByteString.Char8 as BS
|
||||||
import qualified Data.List as L
|
import qualified Data.List as L
|
||||||
import Data.Streaming.Network (bindPortTCP,
|
import Data.Streaming.Network (bindPortTCP,
|
||||||
bindRandomPortTCP)
|
bindRandomPortTCP)
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Network.HTTP.Types as HTTP
|
import qualified Network.HTTP.Types as HTTP
|
||||||
import qualified Network.Socket as NS
|
import qualified Network.HTTP.Types.Header as HTTP (hVary)
|
||||||
import PostgREST.Unix (createAndBindDomainSocket)
|
import qualified Network.Socket as NS
|
||||||
import Protolude hiding (Handler)
|
import PostgREST.Unix (createAndBindDomainSocket)
|
||||||
|
import Protolude hiding (Handler)
|
||||||
|
|
||||||
type Handler = ExceptT Error
|
type Handler = ExceptT Error
|
||||||
|
|
||||||
@@ -208,7 +209,17 @@ postgrestResponse appState conf@AppConfig{..} maybeSchemaCache authResult@AuthRe
|
|||||||
|
|
||||||
where
|
where
|
||||||
toWaiResponse :: ServerTiming -> Response.PgrstResponse -> Wai.Response
|
toWaiResponse :: ServerTiming -> Response.PgrstResponse -> Wai.Response
|
||||||
toWaiResponse timing (Response.PgrstResponse st hdrs bod) = Wai.responseLBS st (hdrs ++ ([serverTimingHeader timing | configServerTimingEnabled])) bod
|
toWaiResponse timing (Response.PgrstResponse st hdrs bod) =
|
||||||
|
Wai.responseLBS st (hdrs ++ serverTimingHeaders timing ++ [varyHeader | not $ varyHeaderPresent hdrs]) bod
|
||||||
|
|
||||||
|
serverTimingHeaders :: ServerTiming -> [HTTP.Header]
|
||||||
|
serverTimingHeaders timing = [serverTimingHeader timing | configServerTimingEnabled]
|
||||||
|
|
||||||
|
varyHeader :: HTTP.Header
|
||||||
|
varyHeader = (HTTP.hVary, "Accept, Prefer, Range")
|
||||||
|
|
||||||
|
varyHeaderPresent :: [HTTP.Header] -> Bool
|
||||||
|
varyHeaderPresent = any (\(h, _v) -> h == HTTP.hVary)
|
||||||
|
|
||||||
withTiming :: Handler IO a -> Handler IO (Maybe Double, a)
|
withTiming :: Handler IO a -> Handler IO (Maybe Double, a)
|
||||||
withTiming f = if configServerTimingEnabled
|
withTiming f = if configServerTimingEnabled
|
||||||
|
|||||||
@@ -196,6 +196,23 @@
|
|||||||
pdSchema: public
|
pdSchema: public
|
||||||
pdVolatility: Volatile
|
pdVolatility: Volatile
|
||||||
|
|
||||||
|
- - qiName: custom_vary_hdr
|
||||||
|
qiSchema: public
|
||||||
|
- - pdDescription: null
|
||||||
|
pdFuncSettings: []
|
||||||
|
pdHasVariadic: false
|
||||||
|
pdName: custom_vary_hdr
|
||||||
|
pdParams: []
|
||||||
|
pdReturnType:
|
||||||
|
contents:
|
||||||
|
contents:
|
||||||
|
qiName: void
|
||||||
|
qiSchema: pg_catalog
|
||||||
|
tag: Scalar
|
||||||
|
tag: Single
|
||||||
|
pdSchema: public
|
||||||
|
pdVolatility: Volatile
|
||||||
|
|
||||||
- - qiName: get_postgres_version
|
- - qiName: get_postgres_version
|
||||||
qiSchema: public
|
qiSchema: public
|
||||||
- - pdDescription: null
|
- - pdDescription: null
|
||||||
|
|||||||
@@ -258,3 +258,10 @@ $_$ language sql;
|
|||||||
create or replace function notify_pgrst() returns void as $$
|
create or replace function notify_pgrst() returns void as $$
|
||||||
notify pgrst;
|
notify pgrst;
|
||||||
$$ language sql;
|
$$ language sql;
|
||||||
|
|
||||||
|
|
||||||
|
create or replace function custom_vary_hdr() returns void as $$
|
||||||
|
begin
|
||||||
|
perform set_config('response.headers', '[{"Vary": "X-Test-Accept"}]', false);
|
||||||
|
end
|
||||||
|
$$ language plpgsql;
|
||||||
|
|||||||
@@ -1811,3 +1811,23 @@ def test_client_error_verbosity_config(defaultenv):
|
|||||||
"details": None,
|
"details": None,
|
||||||
"hint": "Perhaps you meant the table 'public.items'",
|
"hint": "Perhaps you meant the table 'public.items'",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_vary_custom_header_set(defaultenv):
|
||||||
|
"Test default Vary header value is overridden in pre-request database function"
|
||||||
|
|
||||||
|
env = {**defaultenv, "PGRST_DB_PRE_REQUEST": "custom_vary_hdr"}
|
||||||
|
|
||||||
|
with run(env=env) as postgrest:
|
||||||
|
response = postgrest.session.get("/projects")
|
||||||
|
|
||||||
|
assert response.headers["Vary"] == "X-Test-Accept"
|
||||||
|
|
||||||
|
|
||||||
|
def test_vary_default_header_set(defaultenv):
|
||||||
|
"Test default Vary header value matches default one"
|
||||||
|
|
||||||
|
with run(env=defaultenv) as postgrest:
|
||||||
|
response = postgrest.session.get("/projects")
|
||||||
|
|
||||||
|
assert response.headers["Vary"] == "Accept, Prefer, Range"
|
||||||
|
|||||||
Reference in New Issue
Block a user