true, 'now' => date('c')]; publishToMercure(MERCURE_TOPIC, $payload); header('Content-Type: application/json'); echo json_encode($payload); return; } http_response_code(404); header('Content-Type: application/json'); echo json_encode(['error' => 'not found', 'path' => $path]); function publishToMercure(string $topic, array $data): void { $body = http_build_query([ 'topic' => $topic, 'data' => json_encode($data), ]); $ch = curl_init(MERCURE_HUB); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => $body, CURLOPT_HTTPHEADER => [ 'Content-Type: application/x-www-form-urlencoded', 'Authorization: Bearer ' . mintPublisherJwt(), ], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5, ]); $resp = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); error_log("mercure publish topic=$topic http=$code body=" . ($resp === false ? 'false' : (string) $resp)); } function mintPublisherJwt(): string { $header = ['alg' => 'HS256', 'typ' => 'JWT']; $payload = ['mercure' => ['publish' => ['*']]]; $h = b64url(json_encode($header)); $p = b64url(json_encode($payload)); $s = b64url(hash_hmac('sha256', "$h.$p", MERCURE_KEY, true)); return "$h.$p.$s"; } function b64url(string $bytes): string { return rtrim(strtr(base64_encode($bytes), '+/', '-_'), '='); }