Skip to content

Commit 134c78b

Browse files
Add HEAD support to feeds
1 parent cbf1e32 commit 134c78b

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

.DS_Store

0 Bytes
Binary file not shown.

www/index.php

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ function delete_audio(array $args)
145145
$main->redirect('/feed?id=' . $item['feed_id']);
146146
}
147147

148-
#[Route('/rss', 'GET')]
148+
#[Route('/rss', ['GET', 'HEAD'])]
149149
function rss(array $args)
150150
{
151151
global $main;
@@ -173,6 +173,36 @@ function rss(array $args)
173173
return;
174174
}
175175

176+
// Set proper Content-Type for RSS feeds
177+
header('Content-Type: application/rss+xml; charset=utf-8');
178+
179+
// Add Last-Modified header based on feed update time
180+
$lastModified = strtotime($feed['last_update']);
181+
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastModified) . ' GMT');
182+
183+
// Generate ETag based on feed content
184+
$etag = '"' . md5($feed['id'] . $feed['last_update'] . count($items)) . '"';
185+
header('ETag: ' . $etag);
186+
187+
// Add cache headers
188+
header('Cache-Control: public, max-age=300'); // 5 minutes
189+
190+
// Handle conditional requests
191+
$headers = $main->getHeaders();
192+
$ifNoneMatch = $headers['If-None-Match'] ?? null;
193+
$ifModifiedSince = $headers['If-Modified-Since'] ?? null;
194+
195+
if ($ifNoneMatch === $etag ||
196+
($ifModifiedSince && strtotime($ifModifiedSince) >= $lastModified)) {
197+
$main->setResponseCode(304); // Not Modified
198+
return;
199+
}
200+
201+
// Handle HEAD requests - return headers only
202+
if ($main->getMethod() === 'HEAD') {
203+
return;
204+
}
205+
176206
Template::renderXml($main, 'rss', $vars);
177207
}
178208

@@ -194,7 +224,7 @@ function opml(array $args)
194224
Template::renderXml($main, 'opml', $vars);
195225
}
196226

197-
#[Route('/file', 'GET')]
227+
#[Route('/file', ['GET', 'HEAD'])]
198228
function file_cache(array $args): ?string
199229
{
200230
global $main;
@@ -206,6 +236,7 @@ function file_cache(array $args): ?string
206236

207237
} else {
208238
$main->setResponseCode(404);
239+
return null;
209240
}
210241

211242
if (empty($file_data)) {
@@ -244,8 +275,22 @@ function file_cache(array $args): ?string
244275
// Add ETag for cache validation
245276
$etag = '"' . md5($file_data['url'] . $file_data['cached']) . '"';
246277
header('ETag: ' . $etag);
278+
279+
// Add Last-Modified header
280+
$lastModified = strtotime($file_data['cached']);
281+
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastModified) . ' GMT');
247282

248283
$headers = $main->getHeaders();
284+
285+
// Handle conditional requests for caching
286+
$ifNoneMatch = $headers['If-None-Match'] ?? null;
287+
$ifModifiedSince = $headers['If-Modified-Since'] ?? null;
288+
289+
if ($ifNoneMatch === $etag ||
290+
($ifModifiedSince && strtotime($ifModifiedSince) >= $lastModified)) {
291+
$main->setResponseCode(304); // Not Modified
292+
return null;
293+
}
249294

250295
$range = $headers['Range'] ?? null;
251296
$data = $file_data['data'];
@@ -287,7 +332,7 @@ function file_cache(array $args): ?string
287332
return null;
288333
}
289334

290-
#[Route('/audio', 'GET')]
335+
#[Route('/audio', ['GET', 'HEAD'])]
291336
function audio_cache(array $args)
292337
{
293338
global $main;
@@ -310,7 +355,7 @@ function audio_cache(array $args)
310355
file_cache(['file_id' => $file_id]);
311356
}
312357

313-
#[Route('/image', 'GET')]
358+
#[Route('/image', ['GET', 'HEAD'])]
314359
function image_cache(array $args)
315360
{
316361
global $main;

0 commit comments

Comments
 (0)