From 4cf0894616508d53f43d5f357f37eefc78031e11 Mon Sep 17 00:00:00 2001 From: Guy Halse Date: Wed, 30 Apr 2025 10:19:12 +0200 Subject: [PATCH] Force refetching source if our cached copy will expire If we set the `expiresAfter` option in metarefresh's config, we effectively alter the inbound metadata. Thus when we're conditionally GETting, we need to be aware that we've introduced a validUntil attribute that the remote server may not know about. That means we might need to force a refresh of the source even if the remote server does not think it has been modified. --- src/MetaLoader.php | 18 ++++++++++++++++++ src/MetaRefresh.php | 7 ++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/MetaLoader.php b/src/MetaLoader.php index e7faf30..2fbfdaf 100644 --- a/src/MetaLoader.php +++ b/src/MetaLoader.php @@ -4,6 +4,7 @@ namespace SimpleSAML\Module\metarefresh; +use DateTimeImmutable; use Exception; use SimpleSAML\Configuration; use SimpleSAML\Logger; @@ -388,6 +389,23 @@ private function createContext(array $source): array if (array_key_exists($source['src'], $this->state)) { $sourceState = $this->state[$source['src']]; + /* + * If an expireAfter value exists, we effectively altered the metadata's validUntil ourselves + * so we may need to refresh the metadata even if the source indicates it has not changed. + */ + if (isset($source['expireAfter']) && isset($sourceState['requested_at'])) { + $requestedAt = (new DateTimeImmutable($sourceState['requested_at']))->getTimestamp(); + if ($requestedAt + $source['expireAfter'] <= time() - 3600) { // 1 hour based on default cron tags + Logger::info(sprintf( + 'Cached metadata for %s expires soon - forcing refresh even if not changed', + $source['src'], + )); + unset($sourceState['last-modified']); + unset($sourceState['etag']); + $rawheader .= 'Cache-Control: max-age=0' . "\r\n"; + } + } + if (isset($sourceState['last-modified'])) { $rawheader .= 'If-Modified-Since: ' . $sourceState['last-modified'] . "\r\n"; } diff --git a/src/MetaRefresh.php b/src/MetaRefresh.php index 86770f1..bea5a0b 100644 --- a/src/MetaRefresh.php +++ b/src/MetaRefresh.php @@ -111,7 +111,7 @@ public function runRefresh(string $crontag = null): void $source['whitelist'] = $whitelist; } - # Merge global and src specific attributewhitelists: cannot use array_unique for multi-dim. + // Merge global and src specific attributewhitelists: cannot use array_unique for multi-dim. if (isset($source['attributewhitelist'])) { $source['attributewhitelist'] = array_merge($source['attributewhitelist'], $attributewhitelist); } else { @@ -123,6 +123,11 @@ public function runRefresh(string $crontag = null): void $source['conditionalGET'] = $conditionalGET; } + // make our cache expiry available to the loader if we're conditionally GETting + if ($source['conditionalGET'] && isset($expireAfter)) { + $source['expireAfter'] = $expireAfter; + } + Logger::debug('[metarefresh]: In set [' . $setkey . '] loading source [' . $source['src'] . ']'); $metaloader->loadSource($source); }