diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f4ef358..12c68daa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this ## [Unreleased] ### Added +* [#1221](https://github.com/shlinkio/shlink/issues/1221) Added experimental support to run Shlink with [RoadRunner](https://roadrunner.dev) instead of openswoole. +* [#1531](https://github.com/shlinkio/shlink/issues/1531) and [#1090](https://github.com/shlinkio/shlink/issues/1090) Added support for trailing slashes in short URLs. * [#1406](https://github.com/shlinkio/shlink/issues/1406) Added new REST API version 3. When making requests to the REST API with `/rest/v3/...` and an error occurs, all error types will be different, with the next correlation: @@ -28,7 +30,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this Non-error responses are not affected. * [#1513](https://github.com/shlinkio/shlink/issues/1513) Added publishing of the docker image in GHCR. -* [#1221](https://github.com/shlinkio/shlink/issues/1221) Added experimental support to run Shlink with [RoadRunner](https://roadrunner.dev) instead of openswoole. ### Changed * [#1339](https://github.com/shlinkio/shlink/issues/1339) Added new test suite for CLI E2E tests. diff --git a/composer.json b/composer.json index d8b2874f..99e6cb21 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,7 @@ "shlinkio/shlink-config": "dev-main#33004e6 as 2.1", "shlinkio/shlink-event-dispatcher": "dev-main#48c0137 as 2.6", "shlinkio/shlink-importer": "^4.0", - "shlinkio/shlink-installer": "^8.1", + "shlinkio/shlink-installer": "dev-develop#f1cc5c7 as 8.2", "shlinkio/shlink-ip-geolocation": "^3.0", "spiral/roadrunner": "^2.11", "spiral/roadrunner-jobs": "^2.3", diff --git a/config/autoload/installer.global.php b/config/autoload/installer.global.php index 2e120e35..a7a4c97a 100644 --- a/config/autoload/installer.global.php +++ b/config/autoload/installer.global.php @@ -44,6 +44,7 @@ return [ Option\UrlShortener\AutoResolveTitlesConfigOption::class, Option\UrlShortener\AppendExtraPathConfigOption::class, Option\UrlShortener\EnableMultiSegmentSlugsConfigOption::class, + Option\UrlShortener\EnableTrailingSlashConfigOption::class, Option\Tracking\IpAnonymizationConfigOption::class, Option\Tracking\OrphanVisitsTrackingConfigOption::class, Option\Tracking\DisableTrackParamConfigOption::class, diff --git a/config/autoload/routes.config.php b/config/autoload/routes.config.php index 298b9349..b36c4b78 100644 --- a/config/autoload/routes.config.php +++ b/config/autoload/routes.config.php @@ -7,15 +7,19 @@ namespace Shlinkio\Shlink; use Fig\Http\Message\RequestMethodInterface; use RKA\Middleware\IpAddress; use Shlinkio\Shlink\Core\Action as CoreAction; +use Shlinkio\Shlink\Core\Config\EnvVars; use Shlinkio\Shlink\Rest\Action; use Shlinkio\Shlink\Rest\ConfigProvider; use Shlinkio\Shlink\Rest\Middleware; use Shlinkio\Shlink\Rest\Middleware\Mercure\NotConfiguredMercureErrorHandler; +use function sprintf; + return (static function (): array { $contentNegotiationMiddleware = Middleware\ShortUrl\CreateShortUrlContentNegotiationMiddleware::class; $dropDomainMiddleware = Middleware\ShortUrl\DropDefaultDomainFromRequestMiddleware::class; $overrideDomainMiddleware = Middleware\ShortUrl\OverrideDomainMiddleware::class; + $shortUrlRouteSuffix = EnvVars::SHORT_URL_TRAILING_SLASH->loadFromEnv(false) ? '[/]' : ''; return [ @@ -90,7 +94,7 @@ return (static function (): array { ], [ 'name' => CoreAction\RedirectAction::class, - 'path' => '/{shortCode}', + 'path' => sprintf('/{shortCode}%s', $shortUrlRouteSuffix), 'middleware' => [ IpAddress::class, CoreAction\RedirectAction::class, diff --git a/module/Core/src/Config/EnvVars.php b/module/Core/src/Config/EnvVars.php index ae93e4da..7cbd0af4 100644 --- a/module/Core/src/Config/EnvVars.php +++ b/module/Core/src/Config/EnvVars.php @@ -43,6 +43,7 @@ enum EnvVars: string case REDIRECT_STATUS_CODE = 'REDIRECT_STATUS_CODE'; case REDIRECT_CACHE_LIFETIME = 'REDIRECT_CACHE_LIFETIME'; case BASE_PATH = 'BASE_PATH'; + case SHORT_URL_TRAILING_SLASH = 'SHORT_URL_TRAILING_SLASH'; case PORT = 'PORT'; case TASK_WORKER_NUM = 'TASK_WORKER_NUM'; case WEB_WORKER_NUM = 'WEB_WORKER_NUM';