diff options
author | 2024-09-01 21:48:14 +0200 | |
---|---|---|
committer | 2024-09-01 21:48:14 +0200 | |
commit | a6bdc322b01de91b7a9e27243b30a65caf2d3c5a (patch) | |
tree | 7bcfa9d74912856df81f0d8f2a3345d0e15a3f11 /middlewares | |
parent | 36fd72c87e5e96923a61bc79aeff8cc97b950423 (diff) | |
download | rss-bridge-a6bdc322b01de91b7a9e27243b30a65caf2d3c5a.tar.gz rss-bridge-a6bdc322b01de91b7a9e27243b30a65caf2d3c5a.tar.zst rss-bridge-a6bdc322b01de91b7a9e27243b30a65caf2d3c5a.zip |
refactor: extract exception and cache middleware (#4248)
Diffstat (limited to 'middlewares')
-rw-r--r-- | middlewares/CacheMiddleware.php | 59 | ||||
-rw-r--r-- | middlewares/ExceptionMiddleware.php | 24 |
2 files changed, 83 insertions, 0 deletions
diff --git a/middlewares/CacheMiddleware.php b/middlewares/CacheMiddleware.php new file mode 100644 index 00000000..ae0d0d33 --- /dev/null +++ b/middlewares/CacheMiddleware.php @@ -0,0 +1,59 @@ +<?php + +declare(strict_types=1); + +class CacheMiddleware implements Middleware +{ + private CacheInterface $cache; + + public function __construct(CacheInterface $cache) + { + $this->cache = $cache; + } + + public function __invoke(Request $request, $next): Response + { + $action = $request->attribute('action'); + + if ($action !== 'DisplayAction') { + // We only cache DisplayAction (for now) + return $next($request); + } + + // TODO: might want to remove som params from query + $cacheKey = 'http_' . json_encode($request->toArray()); + $cachedResponse = $this->cache->get($cacheKey); + + if ($cachedResponse) { + $ifModifiedSince = $request->server('HTTP_IF_MODIFIED_SINCE'); + $lastModified = $cachedResponse->getHeader('last-modified'); + if ($ifModifiedSince && $lastModified) { + $lastModified = new \DateTimeImmutable($lastModified); + $lastModifiedTimestamp = $lastModified->getTimestamp(); + $modifiedSince = strtotime($ifModifiedSince); + // TODO: \DateTimeImmutable can be compared directly + if ($lastModifiedTimestamp <= $modifiedSince) { + $modificationTimeGMT = gmdate('D, d M Y H:i:s ', $lastModifiedTimestamp); + return new Response('', 304, ['last-modified' => $modificationTimeGMT . 'GMT']); + } + } + return $cachedResponse; + } + + /** @var Response $response */ + $response = $next($request); + + if (in_array($response->getCode(), [403, 429, 500, 503])) { + // Cache these responses for about ~20 mins on average + $this->cache->set($cacheKey, $response, 60 * 15 + rand(1, 60 * 10)); + } + + // For 1% of requests, prune cache + if (rand(1, 100) === 1) { + // This might be resource intensive! + $this->cache->prune(); + } + + return $response; + } +}
\ No newline at end of file diff --git a/middlewares/ExceptionMiddleware.php b/middlewares/ExceptionMiddleware.php new file mode 100644 index 00000000..8bb74713 --- /dev/null +++ b/middlewares/ExceptionMiddleware.php @@ -0,0 +1,24 @@ +<?php + +declare(strict_types=1); + +class ExceptionMiddleware implements Middleware +{ + private Logger $logger; + + public function __construct(Logger $logger) + { + $this->logger = $logger; + } + + public function __invoke(Request $request, $next): Response + { + try { + return $next($request); + } catch (\Throwable $e) { + $this->logger->error('Exception in ExceptionMiddleware', ['e' => $e]); + + return new Response(render(__DIR__ . '/../templates/exception.html.php', ['e' => $e]), 500); + } + } +}
\ No newline at end of file |