Merge pull request #1991 from acelaya-forks/feature/remove-league-uri

Feature/remove league uri
This commit is contained in:
Alejandro Celaya 2024-02-05 23:12:17 +01:00 committed by GitHub
commit deef938e97
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 30 additions and 32 deletions

View file

@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
### Changed ### Changed
* [#1935](https://github.com/shlinkio/shlink/issues/1935) Replace dependency on abandoned `php-middleware/request-id` with userland simple middleware. * [#1935](https://github.com/shlinkio/shlink/issues/1935) Replace dependency on abandoned `php-middleware/request-id` with userland simple middleware.
* [#1988](https://github.com/shlinkio/shlink/issues/1988) Remove dependency on `league\uri` package.
### Deprecated ### Deprecated
* *Nothing* * *Nothing*

View file

@ -33,7 +33,6 @@
"laminas/laminas-inputfilter": "^2.27", "laminas/laminas-inputfilter": "^2.27",
"laminas/laminas-servicemanager": "^3.21", "laminas/laminas-servicemanager": "^3.21",
"laminas/laminas-stdlib": "^3.17", "laminas/laminas-stdlib": "^3.17",
"league/uri": "^6.8",
"matomo/matomo-php-tracker": "^3.2", "matomo/matomo-php-tracker": "^3.2",
"mezzio/mezzio": "^3.17", "mezzio/mezzio": "^3.17",
"mezzio/mezzio-fastroute": "^3.11", "mezzio/mezzio-fastroute": "^3.11",

View file

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Config; namespace Shlinkio\Shlink\Core\Config;
use League\Uri\Exceptions\SyntaxError; use Laminas\Diactoros\Exception\InvalidArgumentException;
use League\Uri\Uri; use Laminas\Diactoros\Uri;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UriInterface; use Psr\Http\Message\UriInterface;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
@ -51,8 +51,8 @@ class NotFoundRedirectResolver implements NotFoundRedirectResolverInterface
private function resolvePlaceholders(UriInterface $currentUri, string $redirectUrl): string private function resolvePlaceholders(UriInterface $currentUri, string $redirectUrl): string
{ {
try { try {
$redirectUri = Uri::createFromString($redirectUrl); $redirectUri = new Uri($redirectUrl);
} catch (SyntaxError $e) { } catch (InvalidArgumentException $e) {
$this->logger->warning('It was not possible to parse "{url}" as a valid URL: {e}', [ $this->logger->warning('It was not possible to parse "{url}" as a valid URL: {e}', [
'e' => $e, 'e' => $e,
'url' => $redirectUrl, 'url' => $redirectUrl,
@ -63,26 +63,22 @@ class NotFoundRedirectResolver implements NotFoundRedirectResolverInterface
$path = $currentUri->getPath(); $path = $currentUri->getPath();
$domain = $currentUri->getAuthority(); $domain = $currentUri->getAuthority();
$replacePlaceholderForPattern = static fn (string $pattern, string $replace, ?string $value): string|null =>
$value === null ? null : str_replace($pattern, $replace, $value);
$replacePlaceholders = static function ( $replacePlaceholders = static function (
callable $modifier, callable $modifier,
?string $value, string $value,
) use ( ) use (
$replacePlaceholderForPattern,
$path, $path,
$domain, $domain,
): string|null { ): string {
$value = $replacePlaceholderForPattern($modifier(self::DOMAIN_PLACEHOLDER), $modifier($domain), $value); $value = str_replace(urlencode(self::DOMAIN_PLACEHOLDER), $modifier($domain), $value);
return $replacePlaceholderForPattern($modifier(self::ORIGINAL_PATH_PLACEHOLDER), $modifier($path), $value); return str_replace(urlencode(self::ORIGINAL_PATH_PLACEHOLDER), $modifier($path), $value);
}; };
$replacePlaceholdersInPath = static function (string $path) use ($replacePlaceholders): string { $replacePlaceholdersInPath = static function (string $path) use ($replacePlaceholders): string {
$result = $replacePlaceholders(static fn (mixed $v) => $v, $path); $result = $replacePlaceholders(static fn (mixed $v) => $v, $path);
return str_replace('//', '/', $result ?? ''); return str_replace('//', '/', $result);
}; };
$replacePlaceholdersInQuery = static fn (?string $query): string|null => $replacePlaceholders( $replacePlaceholdersInQuery = static fn (string $query): string => $replacePlaceholders(
urlencode(...), urlencode(...),
$query, $query,
); );

View file

@ -5,8 +5,8 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\ShortUrl\Helper; namespace Shlinkio\Shlink\Core\ShortUrl\Helper;
use GuzzleHttp\Psr7\Query; use GuzzleHttp\Psr7\Query;
use Laminas\Diactoros\Uri;
use Laminas\Stdlib\ArrayUtils; use Laminas\Stdlib\ArrayUtils;
use League\Uri\Uri;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Shlinkio\Shlink\Core\Model\DeviceType; use Shlinkio\Shlink\Core\Model\DeviceType;
use Shlinkio\Shlink\Core\Options\TrackingOptions; use Shlinkio\Shlink\Core\Options\TrackingOptions;
@ -27,7 +27,7 @@ class ShortUrlRedirectionBuilder implements ShortUrlRedirectionBuilderInterface
): string { ): string {
$currentQuery = $request->getQueryParams(); $currentQuery = $request->getQueryParams();
$device = DeviceType::matchFromUserAgent($request->getHeaderLine('User-Agent')); $device = DeviceType::matchFromUserAgent($request->getHeaderLine('User-Agent'));
$uri = Uri::createFromString($shortUrl->longUrlForDevice($device)); $uri = new Uri($shortUrl->longUrlForDevice($device));
$shouldForwardQuery = $shortUrl->forwardQuery(); $shouldForwardQuery = $shortUrl->forwardQuery();
return $uri return $uri
@ -36,9 +36,9 @@ class ShortUrlRedirectionBuilder implements ShortUrlRedirectionBuilderInterface
->__toString(); ->__toString();
} }
private function resolveQuery(Uri $uri, array $currentQuery): ?string private function resolveQuery(Uri $uri, array $currentQuery): string
{ {
$hardcodedQuery = Query::parse($uri->getQuery() ?? ''); $hardcodedQuery = Query::parse($uri->getQuery());
$disableTrackParam = $this->trackingOptions->disableTrackParam; $disableTrackParam = $this->trackingOptions->disableTrackParam;
if ($disableTrackParam !== null) { if ($disableTrackParam !== null) {
@ -48,7 +48,7 @@ class ShortUrlRedirectionBuilder implements ShortUrlRedirectionBuilderInterface
// We want to merge preserving numeric keys, as some params might be numbers // We want to merge preserving numeric keys, as some params might be numbers
$mergedQuery = ArrayUtils::merge($hardcodedQuery, $currentQuery, true); $mergedQuery = ArrayUtils::merge($hardcodedQuery, $currentQuery, true);
return empty($mergedQuery) ? null : Query::build($mergedQuery); return Query::build($mergedQuery);
} }
private function resolvePath(Uri $uri, ?string $extraPath): string private function resolvePath(Uri $uri, ?string $extraPath): string

View file

@ -18,6 +18,8 @@ class RedirectTest extends ApiTestCase
public function properRedirectHappensBasedOnUserAgent(?string $userAgent, string $expectedRedirect): void public function properRedirectHappensBasedOnUserAgent(?string $userAgent, string $expectedRedirect): void
{ {
$response = $this->callShortUrl('def456', $userAgent); $response = $this->callShortUrl('def456', $userAgent);
self::assertEquals(302, $response->getStatusCode());
self::assertEquals($expectedRedirect, $response->getHeaderLine('Location')); self::assertEquals($expectedRedirect, $response->getHeaderLine('Location'));
} }

View file

@ -57,8 +57,14 @@ class NotFoundRedirectResolverTest extends TestCase
yield 'base URL with trailing slash' => [ yield 'base URL with trailing slash' => [
$uri = new Uri('/'), $uri = new Uri('/'),
self::notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)), self::notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)),
new NotFoundRedirectOptions(baseUrl: 'baseUrl'), new NotFoundRedirectOptions(baseUrl: 'https://example.com/baseUrl'),
'baseUrl', 'https://example.com/baseUrl',
];
yield 'base URL without trailing slash' => [
$uri = new Uri(''),
self::notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)),
new NotFoundRedirectOptions(baseUrl: 'https://example.com/baseUrl'),
'https://example.com/baseUrl',
]; ];
yield 'base URL with domain placeholder' => [ yield 'base URL with domain placeholder' => [
$uri = new Uri('https://s.test'), $uri = new Uri('https://s.test'),
@ -72,17 +78,11 @@ class NotFoundRedirectResolverTest extends TestCase
new NotFoundRedirectOptions(baseUrl: 'https://redirect-here.com/?domain={DOMAIN}'), new NotFoundRedirectOptions(baseUrl: 'https://redirect-here.com/?domain={DOMAIN}'),
'https://redirect-here.com/?domain=s.test', 'https://redirect-here.com/?domain=s.test',
]; ];
yield 'base URL without trailing slash' => [
$uri = new Uri(''),
self::notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)),
new NotFoundRedirectOptions(baseUrl: 'baseUrl'),
'baseUrl',
];
yield 'regular 404' => [ yield 'regular 404' => [
$uri = new Uri('/foo/bar'), $uri = new Uri('/foo/bar'),
self::notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)), self::notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)),
new NotFoundRedirectOptions(regular404: 'regular404'), new NotFoundRedirectOptions(regular404: 'https://example.com/regular404'),
'regular404', 'https://example.com/regular404',
]; ];
yield 'regular 404 with path placeholder in query' => [ yield 'regular 404 with path placeholder in query' => [
$uri = new Uri('/foo/bar'), $uri = new Uri('/foo/bar'),
@ -101,8 +101,8 @@ class NotFoundRedirectResolverTest extends TestCase
yield 'invalid short URL' => [ yield 'invalid short URL' => [
new Uri('/foo'), new Uri('/foo'),
self::notFoundType(self::requestForRoute(RedirectAction::class)), self::notFoundType(self::requestForRoute(RedirectAction::class)),
new NotFoundRedirectOptions(invalidShortUrl: 'invalidShortUrl'), new NotFoundRedirectOptions(invalidShortUrl: 'https://example.com/invalidShortUrl'),
'invalidShortUrl', 'https://example.com/invalidShortUrl',
]; ];
yield 'invalid short URL with path placeholder' => [ yield 'invalid short URL with path placeholder' => [
new Uri('/foo'), new Uri('/foo'),