aboutsummaryrefslogtreecommitdiffstats
path: root/api/guestbook-recent.php
blob: c4ef59e03bcbcf9a6fd996549b1a7b026b62f67c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<?php
/**
 * Guestbook recent comments — JSON proxy for homepage inline display.
 * Fetches from guestbook.sillylaird.ca/api.php (server-to-server, no CORS).
 */
require_once __DIR__ . '/../partials/proxy_helpers.php';

header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: public, max-age=90');

$limit = min(max((int)($_GET['limit'] ?? 8), 1), 25);

$cacheDir  = sys_get_temp_dir() . '/sillylaird_guestbook';
if (!is_dir($cacheDir)) {
    @mkdir($cacheDir, 0700, true);
}
$cacheFile = $cacheDir . '/recent_' . $limit . '.json';
$freshTtl  = 90;
$staleTtl  = 3600;

$emit = static function (string $json, int $code = 200): void {
    http_response_code($code);
    echo $json;
    exit;
};

if (is_file($cacheFile) && (time() - filemtime($cacheFile)) < $freshTtl) {
    $emit((string)file_get_contents($cacheFile));
}

if (!proxy_rate_limit('guestbook_recent', 40, 60)) {
    if (is_file($cacheFile) && (time() - filemtime($cacheFile)) < $staleTtl) {
        $emit((string)file_get_contents($cacheFile));
    }
    $emit(json_encode(['error' => true, 'message' => 'rate limited']), 429);
}

$url = 'https://guestbook.sillylaird.ca/api.php?limit=' . $limit;
$ctx = stream_context_create([
    'http' => [
        'timeout'     => 8,
        'user_agent'  => 'SillyLaird-GuestbookProxy/1.0',
        'ignore_errors' => true,
    ],
    'ssl' => [
        'verify_peer'      => true,
        'verify_peer_name' => true,
    ],
]);

$raw = @file_get_contents($url, false, $ctx);
if ($raw === false) {
    if (is_file($cacheFile)) {
        $emit((string)file_get_contents($cacheFile));
    }
    $emit(json_encode(['error' => true, 'message' => 'upstream unavailable']), 502);
}

$data = json_decode($raw, true);
if (!is_array($data) || !isset($data['entries']) || !is_array($data['entries'])) {
    if (is_file($cacheFile)) {
        $emit((string)file_get_contents($cacheFile));
    }
    $emit(json_encode(['error' => true, 'message' => 'invalid upstream response']), 502);
}

$out = json_encode([
    'entries' => array_slice($data['entries'], 0, $limit),
    'total'   => (int)($data['total'] ?? count($data['entries'])),
    'fetched' => time(),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

$tmp = $cacheFile . '.tmp';
if (@file_put_contents($tmp, $out, LOCK_EX) !== false) {
    @rename($tmp, $cacheFile);
}

$emit($out);