Skip to content

Commit 5647274

Browse files
authored
Force refetching source if our cached copy will expire (#44)
* 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. * Use only DateTime objects
1 parent 308c61a commit 5647274

2 files changed

Lines changed: 28 additions & 1 deletion

File tree

src/MetaLoader.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace SimpleSAML\Module\metarefresh;
66

7+
use DateInterval;
8+
use DateTimeImmutable;
79
use Exception;
810
use SimpleSAML\Configuration;
911
use SimpleSAML\Logger;
@@ -393,6 +395,26 @@ private function createContext(array $source): array
393395
if (array_key_exists($source['src'], $this->state)) {
394396
$sourceState = $this->state[$source['src']];
395397

398+
/*
399+
* If an expireAfter value exists, we effectively altered the metadata's validUntil ourselves
400+
* so we may need to refresh the metadata even if the source indicates it has not changed.
401+
*/
402+
if (isset($source['expireAfter']) && isset($sourceState['requested_at'])) {
403+
$requestedAt = new DateTimeImmutable($sourceState['requested_at']);
404+
$expiresAt = $requestedAt->add(new DateInterval('PT' . $source['expireAfter'] . 'S'));
405+
$refreshThreshold = $expiresAt->sub(new DateInterval('PT1H')); // 1 hour based on default cron tags
406+
$now = new DateTimeImmutable();
407+
if ($now >= $refreshThreshold) {
408+
Logger::info(sprintf(
409+
'Cached metadata for %s expires soon - forcing refresh even if not changed',
410+
$source['src'],
411+
));
412+
unset($sourceState['last-modified']);
413+
unset($sourceState['etag']);
414+
$rawheader .= 'Cache-Control: max-age=0' . "\r\n";
415+
}
416+
}
417+
396418
if (isset($sourceState['last-modified'])) {
397419
$headers['If-Modified-Since'] = $sourceState['last-modified'];
398420
}

src/MetaRefresh.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public function runRefresh(?string $crontag = null): void
113113
$source['whitelist'] = $whitelist;
114114
}
115115

116-
# Merge global and src specific attributewhitelists: cannot use array_unique for multi-dim.
116+
// Merge global and src specific attributewhitelists: cannot use array_unique for multi-dim.
117117
if (isset($source['attributewhitelist'])) {
118118
$source['attributewhitelist'] = array_merge($source['attributewhitelist'], $attributewhitelist);
119119
} else {
@@ -125,6 +125,11 @@ public function runRefresh(?string $crontag = null): void
125125
$source['conditionalGET'] = $conditionalGET;
126126
}
127127

128+
// make our cache expiry available to the loader if we're conditionally GETting
129+
if ($source['conditionalGET'] && isset($expireAfter)) {
130+
$source['expireAfter'] = $expireAfter;
131+
}
132+
128133
Logger::debug('[metarefresh]: In set [' . $setkey . '] loading source [' . $source['src'] . ']');
129134
$metaloader->loadSource($source);
130135
}

0 commit comments

Comments
 (0)