Teapot \ HttpException (410)
The timetable more than a week ago is no longer available. Teapot\HttpException thrown with message "The timetable more than a week ago is no longer available." Stacktrace: #5 Teapot\HttpException in /var/www/gbtt.uk/src/Controllers/ScheduleController.php:90 #4 Metroapps\NationalRailTimetable\Controllers\ScheduleController:run in /var/www/gbtt.uk/vendor/miklcct/thin_php_app/src/Controller/Application.php:48 #3 Psr\Http\Server\RequestHandlerInterface@anonymous/var/www/gbtt.uk/vendor/miklcct/thin_php_app/src/Controller/Application.php:42$13:handle in /var/www/gbtt.uk/src/Middlewares/CacheMiddleware.php:20 #2 Metroapps\NationalRailTimetable\Middlewares\CacheMiddleware:process in /var/www/gbtt.uk/vendor/miklcct/thin_php_app/src/Controller/MiddlewareApplication.php:44 #1 Miklcct\ThinPhpApp\Controller\MiddlewareApplication:handle in /var/www/gbtt.uk/vendor/miklcct/thin_php_app/src/Controller/Application.php:54 #0 Miklcct\ThinPhpApp\Controller\Application:handle in /var/www/gbtt.uk/public_html/timetable.php:10
Stack frames (6)
5
Teapot\HttpException
/src/Controllers/ScheduleController.php90
4
Metroapps\NationalRailTimetable\Controllers\ScheduleController run
/vendor/miklcct/thin_php_app/src/Controller/Application.php48
3
Psr\Http\Server\RequestHandlerInterface@anonymous/var/www/gbtt.uk/vendor/miklcct/thin_php_app/src/Controller/Application.php:42$13 handle
/src/Middlewares/CacheMiddleware.php20
2
Metroapps\NationalRailTimetable\Middlewares\CacheMiddleware process
/vendor/miklcct/thin_php_app/src/Controller/MiddlewareApplication.php44
1
Miklcct\ThinPhpApp\Controller\MiddlewareApplication handle
/vendor/miklcct/thin_php_app/src/Controller/Application.php54
0
Miklcct\ThinPhpApp\Controller\Application handle
/public_html/timetable.php10
            return $this->createEmptyFormResponse($e);
        }
 
        $canonical_url = $this->query->getUrl(static::URL);
        if ($request->getServerParams()['REQUEST_URI'] !== $canonical_url) {
            return new Response(
                Http::PERMANENT_REDIRECT
                , ['Location' => $canonical_url]
            );
        }
 
        $this->cacheMiddleware->query = $this->query;
        if ($this->query->station === null) {
            return $this->createEmptyFormResponse(null);
        }
 
 
        $date = $this->query->date ?? Date::today();
        if ($date->toDateTimeImmutable()->getTimestamp() < time() - 7 * 24 * 60 * 60) {
            throw new HttpException('The timetable more than a week ago is no longer available.', Http::GONE);
        }
        $service_repository = ($this->serviceRepositoryFactory)($this->query->permanentOnly);
        return ($this->viewResponseFactory)(
            new ScheduleView(
                $this->streamFactory
                , $this->locationRepository->getAllStations()
                , $date
                , $this->query
                , $this->getFixedLinks()
                , $service_repository->getGeneratedDate()
                , $this->config->siteName
                , $this->getInnerView()
            )
        );
    }
 
    protected function getFixedLinks() : array {
        $station = $this->query->station;
        if (!$station instanceof Station) {
            return [];
    /**
     * Handle a request and return a response.
     *
     * The application will first pass the request through the defined middlewares sequentially.
     * The {@link run()} method is only called from the innermost middleware.
     *
     * @param ServerRequestInterface $request
     * @return ResponseInterface
     */
    public function handle(ServerRequestInterface $request) : ResponseInterface {
        $handle = Closure::fromCallable([$this, 'run']);
        return MiddlewareApplication::bindMultiple(
            $this->getMiddlewares()
            , new class($handle) implements RequestHandlerInterface {
                public function __construct(callable $handle) {
                    $this->handle = $handle;
                }
 
                public function handle(ServerRequestInterface $request) : ResponseInterface {
                    return ($this->handle)($request);
                }
 
                /** @var callable */
                private $handle;
            }
        )->handle($request);
    }
 
    /**
     * Process the request after passed through the middlewares
     *
     * This the main controller. The request processed by the middlewares before it reaches this method,
     * and the response is processed by the middlewares before it is send out.
     *
     * @param ServerRequestInterface $request
     * @return ResponseInterface
     */
    abstract protected function run(ServerRequestInterface $request) : ResponseInterface;
 
    /**
<?php
declare(strict_types=1);
 
namespace Metroapps\NationalRailTimetable\Middlewares;
 
use DateTimeZone;
use Metroapps\NationalRailTimetable\Controllers\BoardQuery;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Safe\DateTimeImmutable as SafeDateTimeImmutable;
use Teapot\StatusCode\Http;
use function str_replace;
 
class CacheMiddleware implements MiddlewareInterface {
    public ?BoardQuery $query = null;
 
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface {
        return $this->addCacheHeader($handler->handle($request));
    }
 
    public function addCacheHeader(ResponseInterface $response) : ResponseInterface {
        if ($this->query === null || $response->getStatusCode() !== Http::OK) {
            return $response;
        }
        $response = $response->withAddedHeader('Cache-Control', 'public')->withAddedHeader('Cache-Control', 'max-age=7200');
        return $this->query->station !== null && $this->query->date === null
            ? $response->withAddedHeader('Cache-Control', 'public')->withAddedHeader(
                'Expires',
                str_replace(
                    '+0000',
                    'GMT',
                    (new SafeDateTimeImmutable('tomorrow'))->setTimezone(new DateTimeZone('UTC'))->format('r')
                )
            )
            : $response;
    }
}
            , function (RequestHandlerInterface $carry, MiddlewareInterface $middleware) : RequestHandlerInterface {
                return new static($middleware, $carry);
            }
            , $application
        );
    }
 
    /**
     * Bind a middleware on top of an application
     *
     * @param MiddlewareInterface $middleware
     * @param RequestHandlerInterface $application
     */
    public final function __construct(MiddlewareInterface $middleware, RequestHandlerInterface $application) {
        $this->middleware = $middleware;
        $this->application = $application;
    }
 
    public function handle(ServerRequestInterface $request) : ResponseInterface {
        return $this->middleware->process($request, $this->application);
    }
 
    /** @var MiddlewareInterface */
    private $middleware;
    /** @var RequestHandlerInterface */
    private $application;
}
     * @param ServerRequestInterface $request
     * @return ResponseInterface
     */
    public function handle(ServerRequestInterface $request) : ResponseInterface {
        $handle = Closure::fromCallable([$this, 'run']);
        return MiddlewareApplication::bindMultiple(
            $this->getMiddlewares()
            , new class($handle) implements RequestHandlerInterface {
                public function __construct(callable $handle) {
                    $this->handle = $handle;
                }
 
                public function handle(ServerRequestInterface $request) : ResponseInterface {
                    return ($this->handle)($request);
                }
 
                /** @var callable */
                private $handle;
            }
        )->handle($request);
    }
 
    /**
     * Process the request after passed through the middlewares
     *
     * This the main controller. The request processed by the middlewares before it reaches this method,
     * and the response is processed by the middlewares before it is send out.
     *
     * @param ServerRequestInterface $request
     * @return ResponseInterface
     */
    abstract protected function run(ServerRequestInterface $request) : ResponseInterface;
 
    /**
     * Get the middlewares for this application.
     *
     * The middlewares must be sorted from the outermost to the innermost order, i.e. the beginning middleware
     * will process the initial request and create the final response.
     *
     * To disable middlewares of an existing application, override this method to return an empty array.
<?php
declare(strict_types=1);
 
use GuzzleHttp\Psr7\ServerRequest;
use Metroapps\NationalRailTimetable\Controllers\TimetableController;
use function Http\Response\send;
 
require_once __DIR__ . '/../initialise.php';
 
send(get_container()->get(TimetableController::class)->handle(ServerRequest::fromGlobals()));

Environment & details:

Key Value
connecting_time 2023-03-20T22:29
connecting_toc LO
empty
empty
empty
empty
Key Value
REDIRECT_HTTPS on
REDIRECT_SSL_TLS_SNI gbtt.uk
REDIRECT_STATUS 200
HTTPS on
SSL_TLS_SNI gbtt.uk
HTTP_ACCEPT */*
HTTP_USER_AGENT claudebot
HTTP_HOST gbtt.uk
PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
SERVER_SIGNATURE <address>Apache/2.4.59 (Debian) Server at gbtt.uk Port 443</address>
SERVER_SOFTWARE Apache/2.4.59 (Debian)
SERVER_NAME gbtt.uk
SERVER_ADDR 107.155.122.66
SERVER_PORT 443
REMOTE_ADDR 18.118.9.146
DOCUMENT_ROOT /var/www/gbtt.uk/public_html
REQUEST_SCHEME https
CONTEXT_PREFIX
CONTEXT_DOCUMENT_ROOT /var/www/gbtt.uk/public_html
SERVER_ADMIN [no address given]
SCRIPT_FILENAME /var/www/gbtt.uk/public_html/timetable.php
REMOTE_PORT 51879
REDIRECT_URL /timetable/HKW/2023-03-20
REDIRECT_QUERY_STRING connecting_time=2023-03-20T22%3A29&connecting_toc=LO
GATEWAY_INTERFACE CGI/1.1
SERVER_PROTOCOL HTTP/1.1
REQUEST_METHOD GET
QUERY_STRING connecting_time=2023-03-20T22%3A29&connecting_toc=LO
REQUEST_URI /timetable/HKW/2023-03-20?connecting_time=2023-03-20T22%3A29&connecting_toc=LO
SCRIPT_NAME /timetable.php
PATH_INFO /HKW/2023-03-20
PATH_TRANSLATED /var/www/gbtt.uk/public_html/HKW/2023-03-20
PHP_SELF /timetable.php/HKW/2023-03-20
REQUEST_TIME_FLOAT 1713458975.1399
REQUEST_TIME 1713458975
empty
0. Whoops\Handler\PrettyPageHandler
1. Whoops\Handler\Handler@anonymous/var/www/gbtt.uk/initialise.php:102$0