From a9a53a96523c0e22d4b28aa97037728ff723e5c7 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Mon, 6 Apr 2020 20:52:33 +0200 Subject: [PATCH 01/10] Ensured entities metadata cache is cleared during installation and docker start-up --- CHANGELOG.md | 23 +++++++++++++++++++++++ composer.json | 4 ++-- docker/docker-entrypoint.sh | 3 +++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e7d5ea1..6730bef1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,29 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com), and this project adheres to [Semantic Versioning](https://semver.org). +## [Unreleased] + +#### Added + +* *Nothing* + +#### Changed + +* *Nothing* + +#### Deprecated + +* *Nothing* + +#### Removed + +* *Nothing* + +#### Fixed + +* [#712](https://github.com/shlinkio/shlink/issues/712) Fixed app set-up not clearing entities metadata cache. + + ## 2.1.2 - 2020-03-29 #### Added diff --git a/composer.json b/composer.json index 7094757d..d2c9d467 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,7 @@ "shlinkio/shlink-common": "^3.0", "shlinkio/shlink-config": "^1.0", "shlinkio/shlink-event-dispatcher": "^1.4", - "shlinkio/shlink-installer": "^4.3.1", + "shlinkio/shlink-installer": "4.3.2", "shlinkio/shlink-ip-geolocation": "^1.4", "symfony/console": "^5.0", "symfony/filesystem": "^5.0", @@ -65,7 +65,7 @@ "eaglewu/swoole-ide-helper": "dev-master", "infection/infection": "^0.16.1", "phpstan/phpstan": "^0.12.18", - "phpunit/phpunit": "^9.0.1", + "phpunit/phpunit": "~9.0.1", "roave/security-advisories": "dev-master", "shlinkio/php-coding-standard": "~2.1.0", "shlinkio/shlink-test-utils": "^1.4", diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index 7f924057..055e315f 100644 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -12,6 +12,9 @@ php bin/cli db:migrate -n -q echo "Generating proxies..." php vendor/doctrine/orm/bin/doctrine.php orm:generate-proxies -n -q +echo "Clearing entities cache..." +php vendor/doctrine/orm/bin/doctrine.php orm:clear-cache:metadata -n -q + # When restarting the container, swoole might think it is already in execution # This forces the app to be started every second until the exit code is 0 until php vendor/mezzio/mezzio-swoole/bin/mezzio-swoole start; do sleep 1 ; done From fa9ace83ad92cfd4054bf131e7dce6679c7d510c Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Mon, 6 Apr 2020 20:59:10 +0200 Subject: [PATCH 02/10] Fixed incorrect use of tilde --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index d2c9d467..cd0d699a 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,7 @@ "shlinkio/shlink-common": "^3.0", "shlinkio/shlink-config": "^1.0", "shlinkio/shlink-event-dispatcher": "^1.4", - "shlinkio/shlink-installer": "4.3.2", + "shlinkio/shlink-installer": "^4.3.2", "shlinkio/shlink-ip-geolocation": "^1.4", "symfony/console": "^5.0", "symfony/filesystem": "^5.0", From ec8cbf82e5fcfe1cc3e060ad0c77427163338821 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Wed, 8 Apr 2020 17:27:26 +0200 Subject: [PATCH 03/10] Added HEAD request implicit handling --- .../autoload/middleware-pipeline.global.php | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/config/autoload/middleware-pipeline.global.php b/config/autoload/middleware-pipeline.global.php index 45abf30e..a0cf44e2 100644 --- a/config/autoload/middleware-pipeline.global.php +++ b/config/autoload/middleware-pipeline.global.php @@ -5,8 +5,9 @@ declare(strict_types=1); namespace Shlinkio\Shlink; use Laminas\Stratigility\Middleware\ErrorHandler; -use Mezzio; +use Mezzio\Helper; use Mezzio\ProblemDetails; +use Mezzio\Router; use PhpMiddleware\RequestId\RequestIdMiddleware; return [ @@ -14,7 +15,7 @@ return [ 'middleware_pipeline' => [ 'error-handler' => [ 'middleware' => [ - Mezzio\Helper\ContentLengthMiddleware::class, + Helper\ContentLengthMiddleware::class, ErrorHandler::class, ], ], @@ -35,14 +36,15 @@ return [ 'routing' => [ 'middleware' => [ - Mezzio\Router\Middleware\RouteMiddleware::class, + Router\Middleware\RouteMiddleware::class, + Router\Middleware\ImplicitHeadMiddleware::class, ], ], 'rest' => [ 'path' => '/rest', 'middleware' => [ - Mezzio\Router\Middleware\ImplicitOptionsMiddleware::class, + Router\Middleware\ImplicitOptionsMiddleware::class, Rest\Middleware\BodyParserMiddleware::class, Rest\Middleware\AuthenticationMiddleware::class, ], @@ -50,7 +52,7 @@ return [ 'dispatch' => [ 'middleware' => [ - Mezzio\Router\Middleware\DispatchMiddleware::class, + Router\Middleware\DispatchMiddleware::class, ], ], @@ -67,4 +69,11 @@ return [ ], ], ], + + 'dependencies' => [ + 'factories' => [ + Router\Middleware\ImplicitHeadMiddleware::class => Router\Middleware\ImplicitHeadMiddlewareFactory::class, + ], + ], + ]; From 1980d35691b2f8626a344bc29635eb4b4a4ba562 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Wed, 8 Apr 2020 23:51:57 +0200 Subject: [PATCH 04/10] Ensured redirect requests are not tracked when request is performed using method HEAD --- .../src/Action/AbstractTrackingAction.php | 23 ++++++++++++++----- .../Core/test/Action/RedirectActionTest.php | 21 +++++++++++++++++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/module/Core/src/Action/AbstractTrackingAction.php b/module/Core/src/Action/AbstractTrackingAction.php index 436810e6..4d883794 100644 --- a/module/Core/src/Action/AbstractTrackingAction.php +++ b/module/Core/src/Action/AbstractTrackingAction.php @@ -4,7 +4,9 @@ declare(strict_types=1); namespace Shlinkio\Shlink\Core\Action; +use Fig\Http\Message\RequestMethodInterface; use Laminas\Diactoros\Uri; +use Mezzio\Router\Middleware\ImplicitHeadMiddleware; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; @@ -24,7 +26,7 @@ use function array_merge; use function GuzzleHttp\Psr7\build_query; use function GuzzleHttp\Psr7\parse_query; -abstract class AbstractTrackingAction implements MiddlewareInterface +abstract class AbstractTrackingAction implements MiddlewareInterface, RequestMethodInterface { private ShortUrlResolverInterface $urlResolver; private VisitsTrackerInterface $visitTracker; @@ -50,14 +52,13 @@ abstract class AbstractTrackingAction implements MiddlewareInterface $disableTrackParam = $this->appOptions->getDisableTrackParam(); try { - $url = $this->urlResolver->resolveEnabledShortUrl($identifier); + $shortUrl = $this->urlResolver->resolveEnabledShortUrl($identifier); - // Track visit to this short code - if ($disableTrackParam === null || ! array_key_exists($disableTrackParam, $query)) { - $this->visitTracker->track($url, Visitor::fromRequest($request)); + if ($this->shouldTrackRequest($request, $query, $disableTrackParam)) { + $this->visitTracker->track($shortUrl, Visitor::fromRequest($request)); } - return $this->createSuccessResp($this->buildUrlToRedirectTo($url, $query, $disableTrackParam)); + return $this->createSuccessResp($this->buildUrlToRedirectTo($shortUrl, $query, $disableTrackParam)); } catch (ShortUrlNotFoundException $e) { $this->logger->warning('An error occurred while tracking short code. {e}', ['e' => $e]); return $this->createErrorResp($request, $handler); @@ -76,6 +77,16 @@ abstract class AbstractTrackingAction implements MiddlewareInterface return (string) $uri->withQuery(build_query($mergedQuery)); } + private function shouldTrackRequest(ServerRequestInterface $request, array $query, ?string $disableTrackParam): bool + { + $forwardedMethod = $request->getAttribute(ImplicitHeadMiddleware::FORWARDED_HTTP_METHOD_ATTRIBUTE); + if ($forwardedMethod === self::METHOD_HEAD) { + return false; + } + + return $disableTrackParam === null || ! array_key_exists($disableTrackParam, $query); + } + abstract protected function createSuccessResp(string $longUrl): ResponseInterface; abstract protected function createErrorResp( diff --git a/module/Core/test/Action/RedirectActionTest.php b/module/Core/test/Action/RedirectActionTest.php index 8d28f21c..f4de05c5 100644 --- a/module/Core/test/Action/RedirectActionTest.php +++ b/module/Core/test/Action/RedirectActionTest.php @@ -4,8 +4,10 @@ declare(strict_types=1); namespace ShlinkioTest\Shlink\Core\Action; +use Fig\Http\Message\RequestMethodInterface; use Laminas\Diactoros\Response; use Laminas\Diactoros\ServerRequest; +use Mezzio\Router\Middleware\ImplicitHeadMiddleware; use PHPUnit\Framework\TestCase; use Prophecy\Argument; use Prophecy\Prophecy\ObjectProphecy; @@ -89,4 +91,23 @@ class RedirectActionTest extends TestCase $handle->shouldHaveBeenCalledOnce(); } + + /** @test */ + public function trackingIsDisabledWhenRequestIsForwardedFromHead(): void + { + $shortCode = 'abc123'; + $shortUrl = new ShortUrl('http://domain.com/foo/bar?some=thing'); + $this->urlResolver->resolveEnabledShortUrl(new ShortUrlIdentifier($shortCode, ''))->willReturn($shortUrl); + $track = $this->visitTracker->track(Argument::cetera())->will(function (): void { + }); + + $request = (new ServerRequest())->withAttribute('shortCode', $shortCode) + ->withAttribute( + ImplicitHeadMiddleware::FORWARDED_HTTP_METHOD_ATTRIBUTE, + RequestMethodInterface::METHOD_HEAD, + ); + $this->action->process($request, $this->prophesize(RequestHandlerInterface::class)->reveal()); + + $track->shouldNotHaveBeenCalled(); + } } From ec9f874bb9bd99ecd619f4ce3310736ef248018b Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Wed, 8 Apr 2020 23:53:23 +0200 Subject: [PATCH 05/10] Updated changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6730bef1..8993377f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this #### Fixed * [#712](https://github.com/shlinkio/shlink/issues/712) Fixed app set-up not clearing entities metadata cache. +* [#711](https://github.com/shlinkio/shlink/issues/711) Fixed `HEAD` requests returning a duplicated `Content-Length` header. +* [#716](https://github.com/shlinkio/shlink/issues/716) Fixed Twitter not properly displaying preview for final long URL. ## 2.1.2 - 2020-03-29 From 34c7b870a7f14ba7cd23628d09f9fda432b7b85a Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Wed, 8 Apr 2020 23:56:39 +0200 Subject: [PATCH 06/10] Removed unnecessary service registration, as it comes preregistered from third party config provider --- config/autoload/middleware-pipeline.global.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/config/autoload/middleware-pipeline.global.php b/config/autoload/middleware-pipeline.global.php index a0cf44e2..9f8cc729 100644 --- a/config/autoload/middleware-pipeline.global.php +++ b/config/autoload/middleware-pipeline.global.php @@ -70,10 +70,4 @@ return [ ], ], - 'dependencies' => [ - 'factories' => [ - Router\Middleware\ImplicitHeadMiddleware::class => Router\Middleware\ImplicitHeadMiddlewareFactory::class, - ], - ], - ]; From 28e0fb049b6c681dc71b13871aa4ed01bcb876b3 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Thu, 9 Apr 2020 11:54:54 +0200 Subject: [PATCH 07/10] Added check to ensure DB connection is gracefully recovered on swoole task workers --- .../EventDispatcher/LocateShortUrlVisit.php | 38 +++++++++++++------ .../LocateShortUrlVisitTest.php | 5 +++ 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/module/Core/src/EventDispatcher/LocateShortUrlVisit.php b/module/Core/src/EventDispatcher/LocateShortUrlVisit.php index 6abbe02b..ff382770 100644 --- a/module/Core/src/EventDispatcher/LocateShortUrlVisit.php +++ b/module/Core/src/EventDispatcher/LocateShortUrlVisit.php @@ -9,6 +9,7 @@ use Psr\EventDispatcher\EventDispatcherInterface; use Psr\Log\LoggerInterface; use Shlinkio\Shlink\CLI\Exception\GeolocationDbUpdateFailedException; use Shlinkio\Shlink\CLI\Util\GeolocationDbUpdaterInterface; +use Shlinkio\Shlink\Common\Doctrine\ReopeningEntityManager; use Shlinkio\Shlink\Core\Entity\Visit; use Shlinkio\Shlink\Core\Entity\VisitLocation; use Shlinkio\Shlink\IpGeolocation\Exception\WrongIpException; @@ -41,22 +42,35 @@ class LocateShortUrlVisit public function __invoke(ShortUrlVisited $shortUrlVisited): void { + // FIXME Temporarily handling DB connection reset here to fix https://github.com/shlinkio/shlink/issues/717 + // Remove when https://github.com/shlinkio/shlink-event-dispatcher/issues/23 is implemented + if ($this->em instanceof ReopeningEntityManager) { + $this->em->open(); + } + $visitId = $shortUrlVisited->visitId(); - /** @var Visit|null $visit */ - $visit = $this->em->find(Visit::class, $visitId); - if ($visit === null) { - $this->logger->warning('Tried to locate visit with id "{visitId}", but it does not exist.', [ - 'visitId' => $visitId, - ]); - return; - } + try { + /** @var Visit|null $visit */ + $visit = $this->em->find(Visit::class, $visitId); + if ($visit === null) { + $this->logger->warning('Tried to locate visit with id "{visitId}", but it does not exist.', [ + 'visitId' => $visitId, + ]); + return; + } - if ($this->downloadOrUpdateGeoLiteDb($visitId)) { - $this->locateVisit($visitId, $shortUrlVisited->originalIpAddress(), $visit); - } + if ($this->downloadOrUpdateGeoLiteDb($visitId)) { + $this->locateVisit($visitId, $shortUrlVisited->originalIpAddress(), $visit); + } - $this->eventDispatcher->dispatch(new VisitLocated($visitId)); + $this->eventDispatcher->dispatch(new VisitLocated($visitId)); + } finally { + // FIXME Temporarily handling DB connection reset here to fix https://github.com/shlinkio/shlink/issues/717 + // Remove when https://github.com/shlinkio/shlink-event-dispatcher/issues/23 is implemented + $this->em->getConnection()->close(); + $this->em->clear(); + } } private function downloadOrUpdateGeoLiteDb(string $visitId): bool diff --git a/module/Core/test/EventDispatcher/LocateShortUrlVisitTest.php b/module/Core/test/EventDispatcher/LocateShortUrlVisitTest.php index 087c0e0b..e35e7921 100644 --- a/module/Core/test/EventDispatcher/LocateShortUrlVisitTest.php +++ b/module/Core/test/EventDispatcher/LocateShortUrlVisitTest.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace ShlinkioTest\Shlink\Core\EventDispatcher; +use Doctrine\DBAL\Connection; use Doctrine\ORM\EntityManagerInterface; use PHPUnit\Framework\TestCase; use Prophecy\Argument; @@ -37,6 +38,10 @@ class LocateShortUrlVisitTest extends TestCase { $this->ipLocationResolver = $this->prophesize(IpLocationResolverInterface::class); $this->em = $this->prophesize(EntityManagerInterface::class); + $conn = $this->prophesize(Connection::class); + $this->em->getConnection()->willReturn($conn->reveal()); + $this->em->clear()->will(function (): void { + }); $this->logger = $this->prophesize(LoggerInterface::class); $this->dbUpdater = $this->prophesize(GeolocationDbUpdaterInterface::class); $this->eventDispatcher = $this->prophesize(EventDispatcherInterface::class); From 4c83ae2b22df7499ac9dfe1d38f87ab6a6e95203 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Thu, 9 Apr 2020 11:55:47 +0200 Subject: [PATCH 08/10] Updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8993377f..1313b73a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this * [#712](https://github.com/shlinkio/shlink/issues/712) Fixed app set-up not clearing entities metadata cache. * [#711](https://github.com/shlinkio/shlink/issues/711) Fixed `HEAD` requests returning a duplicated `Content-Length` header. * [#716](https://github.com/shlinkio/shlink/issues/716) Fixed Twitter not properly displaying preview for final long URL. +* [#717](https://github.com/shlinkio/shlink/issues/717) Fixed DB connection expiring on task workers when using swoole. ## 2.1.2 - 2020-03-29 From 551368c30d662b864f0551eb8a8c61519b3516ea Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Thu, 9 Apr 2020 12:31:03 +0200 Subject: [PATCH 09/10] Ensured QR code action respects configured domain --- module/Core/config/dependencies.config.php | 8 +-- module/Core/config/routes.config.php | 2 - module/Core/src/Action/QrCodeAction.php | 19 +++---- .../src/Middleware/QrCodeCacheMiddleware.php | 50 ----------------- module/Core/test/Action/QrCodeActionTest.php | 2 +- .../Middleware/QrCodeCacheMiddlewareTest.php | 55 ------------------- 6 files changed, 9 insertions(+), 127 deletions(-) delete mode 100644 module/Core/src/Middleware/QrCodeCacheMiddleware.php delete mode 100644 module/Core/test/Middleware/QrCodeCacheMiddlewareTest.php diff --git a/module/Core/config/dependencies.config.php b/module/Core/config/dependencies.config.php index 13a74c36..a055e34b 100644 --- a/module/Core/config/dependencies.config.php +++ b/module/Core/config/dependencies.config.php @@ -4,9 +4,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\Core; -use Doctrine\Common\Cache\Cache; use Laminas\ServiceManager\AbstractFactory\ConfigAbstractFactory; -use Mezzio\Router\RouterInterface; use Mezzio\Template\TemplateRendererInterface; use Psr\EventDispatcher\EventDispatcherInterface; use Shlinkio\Shlink\Core\Domain\Resolver; @@ -39,8 +37,6 @@ return [ Action\PixelAction::class => ConfigAbstractFactory::class, Action\QrCodeAction::class => ConfigAbstractFactory::class, - Middleware\QrCodeCacheMiddleware::class => ConfigAbstractFactory::class, - Resolver\PersistenceDomainResolver::class => ConfigAbstractFactory::class, ], ], @@ -81,13 +77,11 @@ return [ 'Logger_Shlink', ], Action\QrCodeAction::class => [ - RouterInterface::class, Service\ShortUrl\ShortUrlResolver::class, + 'config.url_shortener.domain', 'Logger_Shlink', ], - Middleware\QrCodeCacheMiddleware::class => [Cache::class], - Resolver\PersistenceDomainResolver::class => ['em'], ], diff --git a/module/Core/config/routes.config.php b/module/Core/config/routes.config.php index d636ed23..82abef30 100644 --- a/module/Core/config/routes.config.php +++ b/module/Core/config/routes.config.php @@ -5,7 +5,6 @@ declare(strict_types=1); use Fig\Http\Message\RequestMethodInterface as RequestMethod; use RKA\Middleware\IpAddress; use Shlinkio\Shlink\Core\Action; -use Shlinkio\Shlink\Core\Middleware; return [ @@ -32,7 +31,6 @@ return [ 'name' => Action\QrCodeAction::class, 'path' => '/{shortCode}/qr-code[/{size:[0-9]+}]', 'middleware' => [ - Middleware\QrCodeCacheMiddleware::class, Action\QrCodeAction::class, ], 'allowed_methods' => [RequestMethod::METHOD_GET], diff --git a/module/Core/src/Action/QrCodeAction.php b/module/Core/src/Action/QrCodeAction.php index 7a07f2a1..979e34fe 100644 --- a/module/Core/src/Action/QrCodeAction.php +++ b/module/Core/src/Action/QrCodeAction.php @@ -5,7 +5,6 @@ declare(strict_types=1); namespace Shlinkio\Shlink\Core\Action; use Endroid\QrCode\QrCode; -use Mezzio\Router\RouterInterface; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Server\MiddlewareInterface; @@ -23,17 +22,17 @@ class QrCodeAction implements MiddlewareInterface private const MIN_SIZE = 50; private const MAX_SIZE = 1000; - private RouterInterface $router; private ShortUrlResolverInterface $urlResolver; + private array $domainConfig; private LoggerInterface $logger; public function __construct( - RouterInterface $router, ShortUrlResolverInterface $urlResolver, + array $domainConfig, ?LoggerInterface $logger = null ) { - $this->router = $router; $this->urlResolver = $urlResolver; + $this->domainConfig = $domainConfig; $this->logger = $logger ?: new NullLogger(); } @@ -42,23 +41,19 @@ class QrCodeAction implements MiddlewareInterface $identifier = ShortUrlIdentifier::fromRedirectRequest($request); try { - $this->urlResolver->resolveEnabledShortUrl($identifier); + $shortUrl = $this->urlResolver->resolveEnabledShortUrl($identifier); } catch (ShortUrlNotFoundException $e) { $this->logger->warning('An error occurred while creating QR code. {e}', ['e' => $e]); return $handler->handle($request); } - $path = $this->router->generateUri(RedirectAction::class, ['shortCode' => $identifier->shortCode()]); - $size = $this->getSizeParam($request); - - $qrCode = new QrCode((string) $request->getUri()->withPath($path)->withQuery('')); - $qrCode->setSize($size); + $qrCode = new QrCode($shortUrl->toString($this->domainConfig)); + $qrCode->setSize($this->getSizeParam($request)); $qrCode->setMargin(0); + return new QrCodeResponse($qrCode); } - /** - */ private function getSizeParam(Request $request): int { $size = (int) $request->getAttribute('size', self::DEFAULT_SIZE); diff --git a/module/Core/src/Middleware/QrCodeCacheMiddleware.php b/module/Core/src/Middleware/QrCodeCacheMiddleware.php deleted file mode 100644 index 79101ae5..00000000 --- a/module/Core/src/Middleware/QrCodeCacheMiddleware.php +++ /dev/null @@ -1,50 +0,0 @@ -cache = $cache; - } - - /** - * Process an incoming server request and return a response, optionally delegating - * to the next middleware component to create the response. - * - * - */ - public function process(Request $request, RequestHandlerInterface $handler): Response - { - $cacheKey = $request->getUri()->getPath(); - - // If this QR code is already cached, just return it - if ($this->cache->contains($cacheKey)) { - $qrData = $this->cache->fetch($cacheKey); - $response = new DiactResp(); - $response->getBody()->write($qrData['body']); - return $response->withHeader('Content-Type', $qrData['content-type']); - } - - // If not, call the next middleware and cache it - /** @var Response $resp */ - $resp = $handler->handle($request); - $this->cache->save($cacheKey, [ - 'body' => $resp->getBody()->__toString(), - 'content-type' => $resp->getHeaderLine('Content-Type'), - ]); - return $resp; - } -} diff --git a/module/Core/test/Action/QrCodeActionTest.php b/module/Core/test/Action/QrCodeActionTest.php index 2a4d1a19..eb68f0e1 100644 --- a/module/Core/test/Action/QrCodeActionTest.php +++ b/module/Core/test/Action/QrCodeActionTest.php @@ -30,7 +30,7 @@ class QrCodeActionTest extends TestCase $this->urlResolver = $this->prophesize(ShortUrlResolverInterface::class); - $this->action = new QrCodeAction($router->reveal(), $this->urlResolver->reveal()); + $this->action = new QrCodeAction($this->urlResolver->reveal(), ['domain' => 'doma.in']); } /** @test */ diff --git a/module/Core/test/Middleware/QrCodeCacheMiddlewareTest.php b/module/Core/test/Middleware/QrCodeCacheMiddlewareTest.php deleted file mode 100644 index e2d73266..00000000 --- a/module/Core/test/Middleware/QrCodeCacheMiddlewareTest.php +++ /dev/null @@ -1,55 +0,0 @@ -cache = new ArrayCache(); - $this->middleware = new QrCodeCacheMiddleware($this->cache); - } - - /** @test */ - public function noCachedPathFallsBackToNextMiddleware(): void - { - $delegate = $this->prophesize(RequestHandlerInterface::class); - $delegate->handle(Argument::any())->willReturn(new Response())->shouldBeCalledOnce(); - - $this->middleware->process((new ServerRequest())->withUri(new Uri('/foo/bar')), $delegate->reveal()); - - $this->assertTrue($this->cache->contains('/foo/bar')); - } - - /** @test */ - public function cachedPathReturnsCacheContent(): void - { - $isCalled = false; - $uri = (new Uri())->withPath('/foo'); - $this->cache->save('/foo', ['body' => 'the body', 'content-type' => 'image/png']); - $delegate = $this->prophesize(RequestHandlerInterface::class); - - $resp = $this->middleware->process((new ServerRequest())->withUri($uri), $delegate->reveal()); - - $this->assertFalse($isCalled); - $resp->getBody()->rewind(); - $this->assertEquals('the body', $resp->getBody()->getContents()); - $this->assertEquals('image/png', $resp->getHeaderLine('Content-Type')); - $delegate->handle(Argument::any())->shouldHaveBeenCalledTimes(0); - } -} From 832a24e4c7ba82e4ab6b3cd7fda31be268fb0b2f Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Thu, 9 Apr 2020 12:33:00 +0200 Subject: [PATCH 10/10] Updated changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1313b73a..af2297d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com), and this project adheres to [Semantic Versioning](https://semver.org). -## [Unreleased] +## 2.1.3 - 2020-04-09 #### Added @@ -28,6 +28,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this * [#711](https://github.com/shlinkio/shlink/issues/711) Fixed `HEAD` requests returning a duplicated `Content-Length` header. * [#716](https://github.com/shlinkio/shlink/issues/716) Fixed Twitter not properly displaying preview for final long URL. * [#717](https://github.com/shlinkio/shlink/issues/717) Fixed DB connection expiring on task workers when using swoole. +* [#705](https://github.com/shlinkio/shlink/issues/705) Fixed how the short URL domain is inferred when generating QR codes, making sure the configured domain is respected even if the request is performed using a different one, and only when a custom domain is used, then that one is used instead. ## 2.1.2 - 2020-03-29