- System > This installation > Address has a field and a link to the other spelling (with or without www), like the WordPress address. It writes SITE_ORIGIN to .env through Environment::write and takes effect on the next request. With SITE_ORIGIN from the server environment there is no field, and a POST is refused. - Before saving, OriginCheck requests /.well-known/kantsites-origin under the new address; it has to return an HMAC of APP_SECRET that only this installation knows. Switching to www without DNS or certificate would otherwise send every page, the administration included, nowhere. "Save anyway" appears only after a refusal. The probe also answers during maintenance. - The message says when the administration changes host and needs a new sign-in, since the session cookie belongs to one spelling. Tests: 584 PHPUnit on PHP 8.2 and 8.4, 35 node, test:editor and test:browser green (test:browser reports only the known editor colour contrast on /grundlagen). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
55 lines
2.1 KiB
PHP
55 lines
2.1 KiB
PHP
<?php
|
|
|
|
namespace App\EventSubscriber;
|
|
|
|
use App\Ops\Updater;
|
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\HttpKernel\Event\RequestEvent;
|
|
use Symfony\Component\HttpKernel\KernelEvents;
|
|
use Twig\Environment;
|
|
|
|
/**
|
|
* While an update runs, the website answers with 503 and the administration stays open.
|
|
*
|
|
* 503 and not 200 with a notice: a search engine reads 503 with Retry-After as "come back later"
|
|
* and keeps the page in its index, while a 200 would teach it that the page now contains an
|
|
* excuse. The administration has to stay reachable, because otherwise nobody could finish or
|
|
* undo the update.
|
|
*/
|
|
final class MaintenanceSubscriber implements EventSubscriberInterface
|
|
{
|
|
public function __construct(private Environment $twig, private string $projectDir, private string $adminPath)
|
|
{
|
|
}
|
|
|
|
public static function getSubscribedEvents(): array
|
|
{
|
|
// Before the router: during maintenance no controller should run at all.
|
|
return [KernelEvents::REQUEST => ['onRequest', 40]];
|
|
}
|
|
|
|
public function onRequest(RequestEvent $event): void
|
|
{
|
|
if (!$event->isMainRequest() || !is_file($this->projectDir.'/'.Updater::MAINTENANCE_FILE)) {
|
|
return;
|
|
}
|
|
$path = $event->getRequest()->getPathInfo();
|
|
if (preg_match('#^/('.preg_quote($this->adminPath, '#').'|assets/|media/|favicon|\.well-known/kantsites-origin)#', $path)) {
|
|
return;
|
|
}
|
|
$since = @file_get_contents($this->projectDir.'/'.Updater::MAINTENANCE_FILE);
|
|
$response = new Response(
|
|
$this->twig->render('maintenance.html.twig', ['since' => trim((string) $since)]),
|
|
Response::HTTP_SERVICE_UNAVAILABLE,
|
|
[
|
|
'Retry-After' => '600',
|
|
'Cache-Control' => 'no-store',
|
|
'Content-Type' => 'text/html; charset=UTF-8',
|
|
'Content-Security-Policy' => "default-src 'self'; script-src 'none'; style-src 'self'; img-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'",
|
|
],
|
|
);
|
|
$event->setResponse($response);
|
|
}
|
|
}
|