aboutsummaryrefslogtreecommitdiff
path: root/middlewares
diff options
context:
space:
mode:
authorGravatar Dag <me@dvikan.no> 2024-09-01 21:48:14 +0200
committerGravatar GitHub <noreply@github.com> 2024-09-01 21:48:14 +0200
commita6bdc322b01de91b7a9e27243b30a65caf2d3c5a (patch)
tree7bcfa9d74912856df81f0d8f2a3345d0e15a3f11 /middlewares
parent36fd72c87e5e96923a61bc79aeff8cc97b950423 (diff)
downloadrss-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.php59
-rw-r--r--middlewares/ExceptionMiddleware.php24
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