mirror of
https://github.com/shlinkio/shlink.git
synced 2024-11-26 14:53:48 +03:00
Merge pull request #1991 from acelaya-forks/feature/remove-league-uri
Feature/remove league uri
This commit is contained in:
commit
deef938e97
6 changed files with 30 additions and 32 deletions
|
@ -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*
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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,
|
||||||
);
|
);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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'),
|
||||||
|
|
Loading…
Reference in a new issue