mirror of
https://github.com/shlinkio/shlink.git
synced 2024-12-22 15:13:59 -06:00
Added support to serve redirects with status 301 and Cache-Control
This commit is contained in:
parent
186168b26c
commit
68db52679b
@ -2,6 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use const Shlinkio\Shlink\Core\DEFAULT_REDIRECT_STATUS_CODE;
|
||||
use const Shlinkio\Shlink\Core\DEFAULT_SHORT_CODES_LENGTH;
|
||||
|
||||
return [
|
||||
@ -15,6 +16,8 @@ return [
|
||||
'anonymize_remote_addr' => true,
|
||||
'visits_webhooks' => [],
|
||||
'default_short_codes_length' => DEFAULT_SHORT_CODES_LENGTH,
|
||||
'redirect_status_code' => DEFAULT_REDIRECT_STATUS_CODE,
|
||||
'redirect_cache_lifetime' => 30,
|
||||
],
|
||||
|
||||
];
|
||||
|
@ -4,11 +4,10 @@ declare(strict_types=1);
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\Tools\Console\ConsoleRunner;
|
||||
use Laminas\ServiceManager\ServiceManager;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
return (function () {
|
||||
/** @var ContainerInterface|ServiceManager $container */
|
||||
/** @var ContainerInterface $container */
|
||||
$container = include __DIR__ . '/container.php';
|
||||
$em = $container->get(EntityManager::class);
|
||||
|
||||
|
@ -76,6 +76,7 @@ return [
|
||||
Service\ShortUrl\ShortUrlResolver::class,
|
||||
Service\VisitsTracker::class,
|
||||
Options\AppOptions::class,
|
||||
Options\UrlShortenerOptions::class,
|
||||
'Logger_Shlink',
|
||||
],
|
||||
Action\PixelAction::class => [
|
||||
|
@ -6,12 +6,15 @@ namespace Shlinkio\Shlink\Core;
|
||||
|
||||
use Cake\Chronos\Chronos;
|
||||
use DateTimeInterface;
|
||||
use Fig\Http\Message\StatusCodeInterface;
|
||||
use PUGX\Shortid\Factory as ShortIdFactory;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
const DEFAULT_SHORT_CODES_LENGTH = 5;
|
||||
const MIN_SHORT_CODES_LENGTH = 4;
|
||||
const DEFAULT_REDIRECT_STATUS_CODE = StatusCodeInterface::STATUS_FOUND;
|
||||
const DEFAULT_REDIRECT_CACHE_LIFETIME = 30;
|
||||
const LOCAL_LOCK_FACTORY = 'Shlinkio\Shlink\LocalLockFactory';
|
||||
|
||||
function generateRandomShortCode(int $length): string
|
||||
|
@ -4,18 +4,40 @@ declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Core\Action;
|
||||
|
||||
use Fig\Http\Message\StatusCodeInterface;
|
||||
use Laminas\Diactoros\Response\RedirectResponse;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Shlinkio\Shlink\Core\Options;
|
||||
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortUrlResolverInterface;
|
||||
use Shlinkio\Shlink\Core\Service\VisitsTrackerInterface;
|
||||
use function sprintf;
|
||||
|
||||
class RedirectAction extends AbstractTrackingAction
|
||||
class RedirectAction extends AbstractTrackingAction implements StatusCodeInterface
|
||||
{
|
||||
private Options\UrlShortenerOptions $urlShortenerOptions;
|
||||
|
||||
public function __construct(
|
||||
ShortUrlResolverInterface $urlResolver,
|
||||
VisitsTrackerInterface $visitTracker,
|
||||
Options\AppOptions $appOptions,
|
||||
Options\UrlShortenerOptions $urlShortenerOptions,
|
||||
?LoggerInterface $logger = null
|
||||
) {
|
||||
parent::__construct($urlResolver, $visitTracker, $appOptions, $logger);
|
||||
$this->urlShortenerOptions = $urlShortenerOptions;
|
||||
}
|
||||
|
||||
protected function createSuccessResp(string $longUrl): Response
|
||||
{
|
||||
// Return a redirect response to the long URL.
|
||||
// Use a temporary redirect to make sure browsers always hit the server for analytics purposes
|
||||
return new RedirectResponse($longUrl);
|
||||
$statusCode = $this->urlShortenerOptions->redirectStatusCode();
|
||||
$headers = $statusCode === self::STATUS_FOUND ? [] : [
|
||||
'Cache-Control' => sprintf('private,max-age=%s', $this->urlShortenerOptions->redirectCacheLifetime()),
|
||||
];
|
||||
|
||||
return new RedirectResponse($longUrl, $statusCode, $headers);
|
||||
}
|
||||
|
||||
protected function createErrorResp(ServerRequestInterface $request, RequestHandlerInterface $handler): Response
|
||||
|
@ -6,20 +6,50 @@ namespace Shlinkio\Shlink\Core\Options;
|
||||
|
||||
use Laminas\Stdlib\AbstractOptions;
|
||||
|
||||
use function Functional\contains;
|
||||
|
||||
use const Shlinkio\Shlink\Core\DEFAULT_REDIRECT_STATUS_CODE;
|
||||
|
||||
class UrlShortenerOptions extends AbstractOptions
|
||||
{
|
||||
protected $__strictMode__ = false; // phpcs:ignore
|
||||
|
||||
private bool $validateUrl = true;
|
||||
private int $redirectStatusCode = DEFAULT_REDIRECT_STATUS_CODE;
|
||||
private int $redirectCacheLifetime = 30;
|
||||
|
||||
public function isUrlValidationEnabled(): bool
|
||||
{
|
||||
return $this->validateUrl;
|
||||
}
|
||||
|
||||
protected function setValidateUrl(bool $validateUrl): self
|
||||
protected function setValidateUrl(bool $validateUrl): void
|
||||
{
|
||||
$this->validateUrl = $validateUrl;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function redirectStatusCode(): int
|
||||
{
|
||||
return $this->redirectStatusCode;
|
||||
}
|
||||
|
||||
protected function setRedirectStatusCode(int $redirectStatusCode): void
|
||||
{
|
||||
$this->redirectStatusCode = $this->normalizeRedirectStatusCode($redirectStatusCode);
|
||||
}
|
||||
|
||||
private function normalizeRedirectStatusCode(int $statusCode): int
|
||||
{
|
||||
return contains([301, 302], $statusCode) ? $statusCode : 302;
|
||||
}
|
||||
|
||||
public function redirectCacheLifetime(): int
|
||||
{
|
||||
return $this->redirectCacheLifetime;
|
||||
}
|
||||
|
||||
protected function setRedirectCacheLifetime(int $redirectCacheLifetime): void
|
||||
{
|
||||
$this->redirectCacheLifetime = $redirectCacheLifetime;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user