Merge pull request #515 from acelaya-forks/feature/host-and-port

Feature/host and port
This commit is contained in:
Alejandro Celaya 2019-10-20 11:14:44 +02:00 committed by GitHub
commit c4ca59dcb0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 13 deletions

View File

@ -29,6 +29,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
#### Fixed #### Fixed
* [#507](https://github.com/shlinkio/shlink/issues/507) Fixed error with too long original URLs by increasing size to the maximum value (2048) based on [the standard](https://stackoverflow.com/a/417184). * [#507](https://github.com/shlinkio/shlink/issues/507) Fixed error with too long original URLs by increasing size to the maximum value (2048) based on [the standard](https://stackoverflow.com/a/417184).
* [#502](https://github.com/shlinkio/shlink/issues/502) Fixed error when providing the port as part of the domain on short URLs.
## 1.19.0 - 2019-10-05 ## 1.19.0 - 2019-10-05

View File

@ -50,9 +50,7 @@ class ShortUrlMetaInputFilter extends InputFilter
$this->add($this->createBooleanInput(self::FIND_IF_EXISTS, false)); $this->add($this->createBooleanInput(self::FIND_IF_EXISTS, false));
$domain = $this->createInput(self::DOMAIN, false); $domain = $this->createInput(self::DOMAIN, false);
$domain->getValidatorChain()->attach(new Validator\Hostname([ $domain->getValidatorChain()->attach(new Validation\HostAndPortValidator());
'allow' => Validator\Hostname::ALLOW_DNS | Validator\Hostname::ALLOW_LOCAL,
]));
$this->add($domain); $this->add($domain);
} }
} }

View File

@ -7,6 +7,7 @@ namespace Shlinkio\Shlink\Rest\Action\ShortUrl;
use Cake\Chronos\Chronos; use Cake\Chronos\Chronos;
use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Core\Exception\InvalidArgumentException; use Shlinkio\Shlink\Core\Exception\InvalidArgumentException;
use Shlinkio\Shlink\Core\Exception\ValidationException;
use Shlinkio\Shlink\Core\Model\CreateShortUrlData; use Shlinkio\Shlink\Core\Model\CreateShortUrlData;
use Shlinkio\Shlink\Core\Model\ShortUrlMeta; use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
use Zend\Diactoros\Uri; use Zend\Diactoros\Uri;
@ -29,18 +30,20 @@ class CreateShortUrlAction extends AbstractCreateShortUrlAction
throw new InvalidArgumentException('A URL was not provided'); throw new InvalidArgumentException('A URL was not provided');
} }
return new CreateShortUrlData( try {
new Uri($postData['longUrl']), $meta = ShortUrlMeta::createFromParams(
(array) ($postData['tags'] ?? []),
ShortUrlMeta::createFromParams(
$this->getOptionalDate($postData, 'validSince'), $this->getOptionalDate($postData, 'validSince'),
$this->getOptionalDate($postData, 'validUntil'), $this->getOptionalDate($postData, 'validUntil'),
$postData['customSlug'] ?? null, $postData['customSlug'] ?? null,
$postData['maxVisits'] ?? null, $postData['maxVisits'] ?? null,
$postData['findIfExists'] ?? null, $postData['findIfExists'] ?? null,
$postData['domain'] ?? null $postData['domain'] ?? null
) );
);
return new CreateShortUrlData(new Uri($postData['longUrl']), (array) ($postData['tags'] ?? []), $meta);
} catch (ValidationException $e) {
throw new InvalidArgumentException('Provided meta data is not valid', -1, $e);
}
} }
private function getOptionalDate(array $postData, string $fieldName): ?Chronos private function getOptionalDate(array $postData, string $fieldName): ?Chronos

View File

@ -15,6 +15,7 @@ use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
use Shlinkio\Shlink\Core\Service\UrlShortener; use Shlinkio\Shlink\Core\Service\UrlShortener;
use Shlinkio\Shlink\Rest\Action\ShortUrl\CreateShortUrlAction; use Shlinkio\Shlink\Rest\Action\ShortUrl\CreateShortUrlAction;
use Shlinkio\Shlink\Rest\Util\RestUtils; use Shlinkio\Shlink\Rest\Util\RestUtils;
use Zend\Diactoros\Response\JsonResponse;
use Zend\Diactoros\ServerRequest; use Zend\Diactoros\ServerRequest;
use Zend\Diactoros\Uri; use Zend\Diactoros\Uri;
@ -50,8 +51,8 @@ class CreateShortUrlActionTest extends TestCase
{ {
$shortUrl = new ShortUrl(''); $shortUrl = new ShortUrl('');
$this->urlShortener->urlToShortCode(Argument::type(Uri::class), Argument::type('array'), Argument::cetera()) $this->urlShortener->urlToShortCode(Argument::type(Uri::class), Argument::type('array'), Argument::cetera())
->willReturn($shortUrl) ->willReturn($shortUrl)
->shouldBeCalledOnce(); ->shouldBeCalledOnce();
$request = (new ServerRequest())->withParsedBody([ $request = (new ServerRequest())->withParsedBody([
'longUrl' => 'http://www.domain.com/foo/bar', 'longUrl' => 'http://www.domain.com/foo/bar',
@ -65,8 +66,8 @@ class CreateShortUrlActionTest extends TestCase
public function anInvalidUrlReturnsError(): void public function anInvalidUrlReturnsError(): void
{ {
$this->urlShortener->urlToShortCode(Argument::type(Uri::class), Argument::type('array'), Argument::cetera()) $this->urlShortener->urlToShortCode(Argument::type(Uri::class), Argument::type('array'), Argument::cetera())
->willThrow(InvalidUrlException::class) ->willThrow(InvalidUrlException::class)
->shouldBeCalledOnce(); ->shouldBeCalledOnce();
$request = (new ServerRequest())->withParsedBody([ $request = (new ServerRequest())->withParsedBody([
'longUrl' => 'http://www.domain.com/foo/bar', 'longUrl' => 'http://www.domain.com/foo/bar',
@ -76,6 +77,35 @@ class CreateShortUrlActionTest extends TestCase
$this->assertTrue(strpos($response->getBody()->getContents(), RestUtils::INVALID_URL_ERROR) > 0); $this->assertTrue(strpos($response->getBody()->getContents(), RestUtils::INVALID_URL_ERROR) > 0);
} }
/**
* @test
* @dataProvider provideInvalidDomains
*/
public function anInvalidDomainReturnsError(string $domain): void
{
$shortUrl = new ShortUrl('');
$urlToShortCode = $this->urlShortener->urlToShortCode(Argument::cetera())->willReturn($shortUrl);
$request = (new ServerRequest())->withParsedBody([
'longUrl' => 'http://www.domain.com/foo/bar',
'domain' => $domain,
]);
/** @var JsonResponse $response */
$response = $this->action->handle($request);
$payload = $response->getPayload();
$this->assertEquals(400, $response->getStatusCode());
$this->assertEquals(RestUtils::INVALID_ARGUMENT_ERROR, $payload['error']);
$urlToShortCode->shouldNotHaveBeenCalled();
}
public function provideInvalidDomains(): iterable
{
yield ['localhost:80000'];
yield ['127.0.0.1'];
yield ['???/&%$&'];
}
/** @test */ /** @test */
public function nonUniqueSlugReturnsError(): void public function nonUniqueSlugReturnsError(): void
{ {