Updated to router v3.
This commit is contained in:
parent
a8359af2e3
commit
6e177caaf8
6 changed files with 181 additions and 206 deletions
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"require": {
|
||||
"flashwave/index": "^0.2410",
|
||||
"flashwave/index": "^0.2503",
|
||||
"sentry/sdk": "^4.0"
|
||||
},
|
||||
"autoload": {
|
||||
|
|
210
composer.lock
generated
210
composer.lock
generated
|
@ -4,25 +4,27 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "023574a93f076ef7a987151cdbfdb33e",
|
||||
"content-hash": "ca6ae2c3d6229791acf93914e055bf41",
|
||||
"packages": [
|
||||
{
|
||||
"name": "flashwave/index",
|
||||
"version": "v0.2410.830205",
|
||||
"version": "v0.2503.201929",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://patchii.net/flash/index.git",
|
||||
"reference": "416c716b2efab9619d14be02a20cd6540e18a83f"
|
||||
"reference": "1ba9e8fa34fbd30c84c23b2a9b6beb2152ca54f0"
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": ">=8.3",
|
||||
"twig/html-extra": "^3.13",
|
||||
"twig/twig": "^3.14"
|
||||
"php": ">=8.4",
|
||||
"psr/http-message": "^2.0",
|
||||
"psr/http-server-handler": "^1.0",
|
||||
"twig/html-extra": "^3.20",
|
||||
"twig/twig": "^3.20"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^2.0",
|
||||
"phpunit/phpunit": "^11.4"
|
||||
"phpstan/phpstan": "^2.1",
|
||||
"phpunit/phpunit": "^12.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-memcache": "Support for the Index\\Cache\\Memcached namespace (only if you can't use ext-memcached for some reason).",
|
||||
|
@ -59,7 +61,7 @@
|
|||
],
|
||||
"description": "Composer package for the common library for my projects.",
|
||||
"homepage": "https://railgun.sh/index",
|
||||
"time": "2024-12-22T02:05:46+00:00"
|
||||
"time": "2025-03-20T19:29:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/psr7",
|
||||
|
@ -179,16 +181,16 @@
|
|||
},
|
||||
{
|
||||
"name": "jean85/pretty-package-versions",
|
||||
"version": "2.1.0",
|
||||
"version": "2.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Jean85/pretty-package-versions.git",
|
||||
"reference": "3c4e5f62ba8d7de1734312e4fff32f67a8daaf10"
|
||||
"reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/3c4e5f62ba8d7de1734312e4fff32f67a8daaf10",
|
||||
"reference": "3c4e5f62ba8d7de1734312e4fff32f67a8daaf10",
|
||||
"url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/4d7aa5dab42e2a76d99559706022885de0e18e1a",
|
||||
"reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -198,8 +200,9 @@
|
|||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.2",
|
||||
"jean85/composer-provided-replaced-stub-package": "^1.0",
|
||||
"phpstan/phpstan": "^1.4",
|
||||
"phpstan/phpstan": "^2.0",
|
||||
"phpunit/phpunit": "^7.5|^8.5|^9.6",
|
||||
"rector/rector": "^2.0",
|
||||
"vimeo/psalm": "^4.3 || ^5.0"
|
||||
},
|
||||
"type": "library",
|
||||
|
@ -232,9 +235,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Jean85/pretty-package-versions/issues",
|
||||
"source": "https://github.com/Jean85/pretty-package-versions/tree/2.1.0"
|
||||
"source": "https://github.com/Jean85/pretty-package-versions/tree/2.1.1"
|
||||
},
|
||||
"time": "2024-11-18T16:19:46+00:00"
|
||||
"time": "2025-03-19T14:43:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-factory",
|
||||
|
@ -344,6 +347,62 @@
|
|||
},
|
||||
"time": "2023-04-04T09:54:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-server-handler",
|
||||
"version": "1.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-server-handler.git",
|
||||
"reference": "84c4fb66179be4caaf8e97bd239203245302e7d4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/84c4fb66179be4caaf8e97bd239203245302e7d4",
|
||||
"reference": "84c4fb66179be4caaf8e97bd239203245302e7d4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0",
|
||||
"psr/http-message": "^1.0 || ^2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Http\\Server\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for HTTP server-side request handler",
|
||||
"keywords": [
|
||||
"handler",
|
||||
"http",
|
||||
"http-interop",
|
||||
"psr",
|
||||
"psr-15",
|
||||
"psr-7",
|
||||
"request",
|
||||
"response",
|
||||
"server"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/http-server-handler/tree/1.0.2"
|
||||
},
|
||||
"time": "2023-04-10T20:06:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
"version": "3.0.2",
|
||||
|
@ -651,16 +710,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/mime",
|
||||
"version": "v7.2.1",
|
||||
"version": "v7.2.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/mime.git",
|
||||
"reference": "7f9617fcf15cb61be30f8b252695ed5e2bfac283"
|
||||
"reference": "87ca22046b78c3feaff04b337f33b38510fd686b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/mime/zipball/7f9617fcf15cb61be30f8b252695ed5e2bfac283",
|
||||
"reference": "7f9617fcf15cb61be30f8b252695ed5e2bfac283",
|
||||
"url": "https://api.github.com/repos/symfony/mime/zipball/87ca22046b78c3feaff04b337f33b38510fd686b",
|
||||
"reference": "87ca22046b78c3feaff04b337f33b38510fd686b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -715,7 +774,7 @@
|
|||
"mime-type"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/mime/tree/v7.2.1"
|
||||
"source": "https://github.com/symfony/mime/tree/v7.2.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -731,7 +790,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-07T08:50:44+00:00"
|
||||
"time": "2025-02-19T08:51:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
|
@ -1123,98 +1182,22 @@
|
|||
],
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php81",
|
||||
"version": "v1.31.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php81.git",
|
||||
"reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
|
||||
"reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php81\\": ""
|
||||
},
|
||||
"classmap": [
|
||||
"Resources/stubs"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "twig/html-extra",
|
||||
"version": "v3.18.0",
|
||||
"version": "v3.20.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/html-extra.git",
|
||||
"reference": "c63b28e192c1b7c15bb60f81d2e48b140846239a"
|
||||
"reference": "f7d54d4de1b64182af745cfb66777f699b599734"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/html-extra/zipball/c63b28e192c1b7c15bb60f81d2e48b140846239a",
|
||||
"reference": "c63b28e192c1b7c15bb60f81d2e48b140846239a",
|
||||
"url": "https://api.github.com/repos/twigphp/html-extra/zipball/f7d54d4de1b64182af745cfb66777f699b599734",
|
||||
"reference": "f7d54d4de1b64182af745cfb66777f699b599734",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.2",
|
||||
"php": ">=8.1.0",
|
||||
"symfony/deprecation-contracts": "^2.5|^3",
|
||||
"symfony/mime": "^5.4|^6.4|^7.0",
|
||||
"twig/twig": "^3.13|^4.0"
|
||||
|
@ -1253,7 +1236,7 @@
|
|||
"twig"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/twigphp/html-extra/tree/v3.18.0"
|
||||
"source": "https://github.com/twigphp/html-extra/tree/v3.20.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1265,28 +1248,27 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-29T10:29:59+00:00"
|
||||
"time": "2025-01-31T20:45:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v3.18.0",
|
||||
"version": "v3.20.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "acffa88cc2b40dbe42eaf3a5025d6c0d4600cc50"
|
||||
"reference": "3468920399451a384bef53cf7996965f7cd40183"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/acffa88cc2b40dbe42eaf3a5025d6c0d4600cc50",
|
||||
"reference": "acffa88cc2b40dbe42eaf3a5025d6c0d4600cc50",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/3468920399451a384bef53cf7996965f7cd40183",
|
||||
"reference": "3468920399451a384bef53cf7996965f7cd40183",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.2",
|
||||
"php": ">=8.1.0",
|
||||
"symfony/deprecation-contracts": "^2.5|^3",
|
||||
"symfony/polyfill-ctype": "^1.8",
|
||||
"symfony/polyfill-mbstring": "^1.3",
|
||||
"symfony/polyfill-php81": "^1.29"
|
||||
"symfony/polyfill-mbstring": "^1.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^2.0",
|
||||
|
@ -1333,7 +1315,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/twigphp/Twig/issues",
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.18.0"
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.20.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1345,7 +1327,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-29T10:51:50+00:00"
|
||||
"time": "2025-02-13T08:34:43+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
|
|
|
@ -17,11 +17,15 @@ use Uiharu\Lookup\NicoNicoLookupResult;
|
|||
use Index\MediaType;
|
||||
use Index\Cache\CacheProvider;
|
||||
use Index\Colour\{Colour,ColourRgb};
|
||||
use Index\Http\Routing\{HttpGet,HttpPost,RouteHandlerTrait};
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Routing\RouteHandlerCommon;
|
||||
use Index\Http\Routing\AccessControl\AccessControl;
|
||||
use Index\Http\Routing\Routes\ExactRoute;
|
||||
use Index\Http\Streams\Stream;
|
||||
use Index\Performance\Stopwatch;
|
||||
|
||||
final class v1_0 implements \Uiharu\IApi {
|
||||
use RouteHandlerTrait;
|
||||
use RouteHandlerCommon;
|
||||
|
||||
private UihContext $ctx;
|
||||
private CacheProvider $cache;
|
||||
|
@ -35,8 +39,9 @@ final class v1_0 implements \Uiharu\IApi {
|
|||
return !str_starts_with($url, '/v');
|
||||
}
|
||||
|
||||
#[HttpGet('/metadata/thumb/audio')]
|
||||
public function getThumbAudio($response, $request) {
|
||||
#[AccessControl]
|
||||
#[ExactRoute('GET', '/metadata/thumb/audio')]
|
||||
public function getThumbAudio(HttpResponseBuilder $response, HttpRequest $request) {
|
||||
$targetUrl = (string)$request->getParam('url');
|
||||
|
||||
if(empty($targetUrl))
|
||||
|
@ -53,11 +58,12 @@ final class v1_0 implements \Uiharu\IApi {
|
|||
|
||||
$response->setContentType('image/png');
|
||||
$response->setCacheControl('public', 'max-age=31536000', 'immutable');
|
||||
$response->setContent(FFMPEG::grabFirstAudioCover($parsedUrl));
|
||||
$response->body = Stream::createStream(FFMPEG::grabFirstAudioCover($parsedUrl));
|
||||
}
|
||||
|
||||
#[HttpGet('/metadata/thumb/video')]
|
||||
public function getThumbVideo($response, $request) {
|
||||
#[AccessControl]
|
||||
#[ExactRoute('GET', '/metadata/thumb/video')]
|
||||
public function getThumbVideo(HttpResponseBuilder $response, HttpRequest $request) {
|
||||
$targetUrl = (string)$request->getParam('url');
|
||||
|
||||
if(empty($targetUrl))
|
||||
|
@ -74,55 +80,37 @@ final class v1_0 implements \Uiharu\IApi {
|
|||
|
||||
$response->setContentType('image/png');
|
||||
$response->setCacheControl('public', 'max-age=31536000', 'immutable');
|
||||
$response->setContent(FFMPEG::grabFirstVideoFrame($parsedUrl));
|
||||
$response->body = Stream::createStream(FFMPEG::grabFirstVideoFrame($parsedUrl));
|
||||
}
|
||||
|
||||
#[HttpGet('/metadata')]
|
||||
public function getMetadata($response, $request) {
|
||||
if($request->getMethod() === 'HEAD') {
|
||||
$response->setTypeJson();
|
||||
return;
|
||||
}
|
||||
|
||||
#[AccessControl]
|
||||
#[ExactRoute('GET', '/metadata')]
|
||||
public function getMetadata(HttpResponseBuilder $response, HttpRequest $request) {
|
||||
return $this->handleMetadata(
|
||||
$response, $request,
|
||||
(string)$request->getParam('url')
|
||||
);
|
||||
}
|
||||
|
||||
#[HttpPost('/metadata')]
|
||||
public function postMetadata($response, $request) {
|
||||
if(!$request->isStringContent())
|
||||
return 400;
|
||||
|
||||
#[AccessControl]
|
||||
#[ExactRoute('POST', '/metadata')]
|
||||
public function postMetadata(HttpResponseBuilder $response, HttpRequest $request) {
|
||||
return $this->handleMetadata(
|
||||
$response, $request,
|
||||
(string)$request->getContent()
|
||||
(string)$request->getBody()
|
||||
);
|
||||
}
|
||||
|
||||
#[HttpGet('/metadata/batch')]
|
||||
public function getMetadataBatch($response, $request) {
|
||||
if($request->getMethod() === 'HEAD') {
|
||||
$response->setTypeJson();
|
||||
return;
|
||||
}
|
||||
|
||||
return $this->handleMetadataBatch(
|
||||
$response, $request,
|
||||
$request->getParam('url', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY)
|
||||
);
|
||||
#[AccessControl]
|
||||
#[ExactRoute('GET', '/metadata/batch')]
|
||||
public function getMetadataBatch(): int {
|
||||
return 410;
|
||||
}
|
||||
|
||||
#[HttpPost('/metadata/batch')]
|
||||
public function postMetadataBatch($response, $request) {
|
||||
if(!$request->isFormContent())
|
||||
return 400;
|
||||
|
||||
return $this->handleMetadataBatch(
|
||||
$response, $request,
|
||||
$request->getContent()->getParam('url', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY)
|
||||
);
|
||||
#[AccessControl]
|
||||
#[ExactRoute('POST', '/metadata/batch')]
|
||||
public function postMetadataBatch(): int {
|
||||
return 410;
|
||||
}
|
||||
|
||||
private function metadataLookup(string $targetUrl) {
|
||||
|
@ -172,11 +160,11 @@ final class v1_0 implements \Uiharu\IApi {
|
|||
$resp->content_type = MediaTypeExts::toV1($result->getMediaType());
|
||||
if($result->hasColour()) {
|
||||
$colour = $result->getColour();
|
||||
if($colour->getAlpha() < 1.0)
|
||||
if($colour->alpha < 1.0)
|
||||
$colour = new ColourRgb(
|
||||
$colour->getRed(),
|
||||
$colour->getGreen(),
|
||||
$colour->getBlue()
|
||||
$colour->red,
|
||||
$colour->green,
|
||||
$colour->blue,
|
||||
);
|
||||
|
||||
$resp->color = (string)$colour;
|
||||
|
@ -278,7 +266,7 @@ final class v1_0 implements \Uiharu\IApi {
|
|||
}
|
||||
|
||||
$sw->stop();
|
||||
$resp->took = $sw->getElapsedTime() / 1000;
|
||||
$resp->took = $sw->elapsedTime / 1000;
|
||||
$respJson = json_encode($resp);
|
||||
|
||||
$this->cache->set($cacheKey, $respJson, 10 * 60);
|
||||
|
@ -290,7 +278,7 @@ final class v1_0 implements \Uiharu\IApi {
|
|||
return $resp;
|
||||
}
|
||||
|
||||
private function handleMetadata($response, $request, string $targetUrl) {
|
||||
private function handleMetadata(HttpResponseBuilder $response, HttpRequest $request, string $targetUrl) {
|
||||
$result = $this->metadataLookup($targetUrl);
|
||||
if(is_int($result))
|
||||
return $result;
|
||||
|
@ -305,7 +293,7 @@ final class v1_0 implements \Uiharu\IApi {
|
|||
return $result;
|
||||
}
|
||||
|
||||
private function handleMetadataBatch($response, $request, array $urls) {
|
||||
private function handleMetadataBatch(HttpResponseBuilder $response, HttpRequest $request, array $urls) {
|
||||
$sw = Stopwatch::startNew();
|
||||
|
||||
if(count($urls) > 20)
|
||||
|
|
|
@ -7,14 +7,14 @@ final class MediaTypeExts {
|
|||
public static function toV1(MediaType $mediaType): array {
|
||||
$parts = [
|
||||
'string' => (string)$mediaType,
|
||||
'type' => $mediaType->getCategory(),
|
||||
'subtype' => $mediaType->getKind(),
|
||||
'type' => $mediaType->category,
|
||||
'subtype' => $mediaType->kind,
|
||||
];
|
||||
|
||||
if(!empty($suffix = $mediaType->getSuffix()))
|
||||
if(!empty($suffix = $mediaType->suffix))
|
||||
$parts['suffix'] = $suffix;
|
||||
|
||||
if(!empty($params = $mediaType->getParams()))
|
||||
if(!empty($params = $mediaType->params))
|
||||
$parts['params'] = $params;
|
||||
|
||||
return $parts;
|
||||
|
|
|
@ -3,12 +3,15 @@ namespace Uiharu;
|
|||
|
||||
use Index\Cache\CacheProvider;
|
||||
use Index\Config\Config;
|
||||
use Index\Http\Routing\HttpRouter;
|
||||
use Index\Http\HttpResponseBuilder;
|
||||
use Index\Http\Routing\{Router,RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Filters\PrefixFilter;
|
||||
use Index\Http\Routing\Routes\ExactRoute;
|
||||
|
||||
final class UihContext {
|
||||
private CacheProvider $cache;
|
||||
private Config $config;
|
||||
private HttpRouter $router;
|
||||
private Router $router;
|
||||
private array $apis = [];
|
||||
private array $lookups = [];
|
||||
|
||||
|
@ -21,52 +24,28 @@ final class UihContext {
|
|||
return $this->cache;
|
||||
}
|
||||
|
||||
public function getRouter(): HttpRouter {
|
||||
public function getRouter(): Router {
|
||||
return $this->router;
|
||||
}
|
||||
|
||||
public function isOriginAllowed(string $origin): bool {
|
||||
$origin = mb_strtolower(parse_url($origin, PHP_URL_HOST));
|
||||
|
||||
if($origin === $_SERVER['HTTP_HOST'])
|
||||
return true;
|
||||
|
||||
$allowed = $this->config->getArray('cors:origins');
|
||||
if(empty($allowed))
|
||||
return true;
|
||||
|
||||
return in_array($origin, $allowed);
|
||||
}
|
||||
|
||||
public function setupHttp(): void {
|
||||
$this->router = new HttpRouter;
|
||||
$this->router->use('/', function($response) {
|
||||
$response->setPoweredBy('Uiharu');
|
||||
});
|
||||
$this->router = new Router(
|
||||
accessControlHandler: new UiharuAccessControlHandler($this->config->getArray('cors:origins')),
|
||||
);
|
||||
$this->router->register(new class implements RouteHandler {
|
||||
use RouteHandlerCommon;
|
||||
|
||||
$this->router->use('/', function($response, $request) {
|
||||
$origin = $request->getHeaderLine('Origin');
|
||||
|
||||
if(!empty($origin)) {
|
||||
if(!$this->isOriginAllowed($origin))
|
||||
return 403;
|
||||
|
||||
$response->setHeader('Access-Control-Allow-Origin', $origin);
|
||||
$response->setHeader('Vary', 'Origin');
|
||||
#[PrefixFilter('/')]
|
||||
public function filterPoweredBy(HttpResponseBuilder $response): void {
|
||||
$response->setPoweredBy('Uiharu');
|
||||
}
|
||||
});
|
||||
|
||||
$this->router->use('/', function($response, $request) {
|
||||
if($request->getMethod() === 'OPTIONS') {
|
||||
$response->setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET, POST');
|
||||
return 204;
|
||||
#[ExactRoute('GET', '/')]
|
||||
public function getIndex(HttpResponseBuilder $response): void {
|
||||
$response->accelRedirect('/index.html');
|
||||
$response->setContentType('text/html; charset=utf-8');
|
||||
}
|
||||
});
|
||||
|
||||
$this->router->get('/', function($response) {
|
||||
$response->accelRedirect('/index.html');
|
||||
$response->setContentType('text/html; charset=utf-8');
|
||||
});
|
||||
}
|
||||
|
||||
public function dispatchHttp(): void {
|
||||
|
|
26
src/UiharuAccessControlHandler.php
Normal file
26
src/UiharuAccessControlHandler.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
namespace Uiharu;
|
||||
|
||||
use Index\Http\HttpUri;
|
||||
use Index\Http\Routing\HandlerContext;
|
||||
use Index\Http\Routing\Routes\RouteInfo;
|
||||
use Index\Http\Routing\AccessControl\{AccessControl,SimpleAccessControlHandler};
|
||||
|
||||
class UiharuAccessControlHandler extends SimpleAccessControlHandler {
|
||||
public function __construct(
|
||||
private array $origins,
|
||||
) {}
|
||||
|
||||
#[\Override]
|
||||
public function checkAccess(
|
||||
HandlerContext $context,
|
||||
AccessControl $accessControl,
|
||||
HttpUri $origin,
|
||||
?RouteInfo $routeInfo = null,
|
||||
): string|bool {
|
||||
if(!in_array($origin->host, $this->origins))
|
||||
return false;
|
||||
|
||||
return $accessControl->credentials ? (string)$origin : true;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue