From 82a7a63e81728e0c0dfc4dd8edd0471aefa27e5f Mon Sep 17 00:00:00 2001 From: Wolfgang Meier Date: Mon, 23 May 2022 14:56:31 +0100 Subject: [PATCH] Add configuration parameter to disable caching (ignore If-Modified-Since header) --- Dockerfile | 3 +- modules/config.xqm | 14 +++++- modules/lib/api/caching.xql | 72 ++++++++++++++++-------------- templates/basic/modules/config.xqm | 12 +++++ 4 files changed, 65 insertions(+), 36 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0bd60fc13..a3fe914dd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -89,6 +89,7 @@ ARG HTTPS_PORT=8443 ENV NER_ENDPOINT=http://localhost:8001 ENV CONTEXT_PATH=auto +ENV PROXY_CACHING=false ENV JAVA_OPTS \ -Djetty.port=${HTTP_PORT} \ @@ -108,4 +109,4 @@ RUN if [ "${ADMIN_PASS}" != "none" ]; then bin/client.sh -l --no-gui --xpath "sm EXPOSE ${HTTP_PORT} -ENTRYPOINT JAVA_OPTS="${JAVA_OPTS} -Dteipublisher.ner-endpoint=${NER_ENDPOINT} -Dteipublisher.context-path=${CONTEXT_PATH}" /exist/bin/startup.sh \ No newline at end of file +ENTRYPOINT JAVA_OPTS="${JAVA_OPTS} -Dteipublisher.ner-endpoint=${NER_ENDPOINT} -Dteipublisher.context-path=${CONTEXT_PATH} -Dteipublisher.proxy-caching=${PROXY_CACHING}" /exist/bin/startup.sh \ No newline at end of file diff --git a/modules/config.xqm b/modules/config.xqm index fa5f6041f..ccaaec97c 100644 --- a/modules/config.xqm +++ b/modules/config.xqm @@ -29,7 +29,19 @@ declare variable $config:origin-whitelist := ( "https?://teipublisher.onrender.com" ); -(:~~ +(:~ + : Set to true to allow caching: if the browser sends an If-Modified-Since header, + : TEI Publisher will respond with a 304 if the resource has not changed since last + : access. However, this does *not* take into account changes to ODD or other auxiliary + : files, so don't use it during development. + :) +declare variable $config:enable-proxy-caching := + let $prop := util:system-property("teipublisher.proxy-caching") + return + exists($prop) and lower-case($prop) = 'true' +; + +(:~ : The version of the pb-components webcomponents library to be used by this app. : Should either point to a version published on npm, : or be set to 'local' or 'dev'. diff --git a/modules/lib/api/caching.xql b/modules/lib/api/caching.xql index 7753864dd..6606fc5d2 100644 --- a/modules/lib/api/caching.xql +++ b/modules/lib/api/caching.xql @@ -3,42 +3,46 @@ xquery version "3.1"; module namespace cutil="http://teipublisher.com/api/cache"; import module namespace router="http://exist-db.org/xquery/router"; +import module namespace config="http://www.tei-c.org/tei-simple/config" at "../../config.xqm"; declare function cutil:check-last-modified($request as map(*), $nodes as node()*, $callback as function(*)) { - util:log('INFO', 'If-Modified-Since: ' || $request?parameters?If-Modified-Since), - let $ifModifiedSince := - if (map:contains($request?parameters, 'If-Modified-Since')) then - $request?parameters?If-Modified-Since => parse-ietf-date() - else - () - let $lastModified := - for $node in $nodes - let $modified := - xmldb:last-modified(util:collection-name($node), util:document-name($node)) - order by $modified descending - return - $modified - let $shouldReturn304 := - if (exists($ifModifiedSince)) then - $ifModifiedSince ge - $lastModified - (: For the purpose of comparing the resource's last modified date with the If-Modified-Since - : header supplied by the client, we must truncate any milliseconds from the last modified date. - : This is because HTTP-date is only specific to the second. - : @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1 :) - => format-dateTime("[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01][Z]") - => xs:dateTime() - else - () - return ( - if(string-length($lastModified) >0) - then (response:set-header("Last-Modified", cutil:format-http-date(head($lastModified)))) - else (), - if ($shouldReturn304) then - router:response(304, "", "") - else - $callback($request, $nodes) - ) + if ($config:enable-proxy-caching) then ( + util:log('INFO', 'If-Modified-Since: ' || $request?parameters?If-Modified-Since), + let $ifModifiedSince := + if (map:contains($request?parameters, 'If-Modified-Since')) then + $request?parameters?If-Modified-Since => parse-ietf-date() + else + () + let $lastModified := + for $node in $nodes + let $modified := + xmldb:last-modified(util:collection-name($node), util:document-name($node)) + order by $modified descending + return + $modified + let $shouldReturn304 := + if (exists($ifModifiedSince)) then + $ifModifiedSince ge + $lastModified + (: For the purpose of comparing the resource's last modified date with the If-Modified-Since + : header supplied by the client, we must truncate any milliseconds from the last modified date. + : This is because HTTP-date is only specific to the second. + : @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1 :) + => format-dateTime("[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01][Z]") + => xs:dateTime() + else + () + return ( + if(string-length($lastModified) >0) + then (response:set-header("Last-Modified", cutil:format-http-date(head($lastModified)))) + else (), + if ($shouldReturn304) then + router:response(304, "", "") + else + $callback($request, $nodes) + ) + ) else + $callback($request, $nodes) }; declare function cutil:format-http-date($dateTime as xs:dateTime) as xs:string { diff --git a/templates/basic/modules/config.xqm b/templates/basic/modules/config.xqm index eb81b8562..0821fe417 100644 --- a/templates/basic/modules/config.xqm +++ b/templates/basic/modules/config.xqm @@ -52,6 +52,18 @@ declare variable $config:origin-whitelist := ( "(?:https?://localhost:.*|https?://127.0.0.1:.*)" ); +(:~ + : Set to true to allow caching: if the browser sends an If-Modified-Since header, + : TEI Publisher will respond with a 304 if the resource has not changed since last + : access. However, this does *not* take into account changes to ODD or other auxiliary + : files, so don't use it during development. + :) +declare variable $config:enable-proxy-caching := + let $prop := util:system-property("teipublisher.proxy-caching") + return + exists($prop) and lower-case($prop) = 'true' +; + (:~ : Should documents be located by xml:id or filename? :)