feature #23076 [Validator] Adds support to check specific DNS record type for URL (iisisrael)
This PR was merged into the 3.4 branch.
Discussion
----------
[Validator] Adds support to check specific DNS record type for URL
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
URL validation with the `checkDNS` option can time out for some international registrars or for reasons unknown. When the `URL` constraint is implemented, the context may logically allow for a single DNS record type to be checked, which is less prone to timing out. This updates the `checkDNS` option value to be one of any valid for the underlying `checkdnsrr()` method with backwards compatibility for the original boolean value.
Commits
-------
e66d8f1bef
[Validator] Adds support to check specific DNS record type for URL
This commit is contained in:
commit
1f6330a9b9
@ -6,6 +6,7 @@ CHANGELOG
|
||||
|
||||
* not setting the `strict` option of the `Choice` constraint to `true` is
|
||||
deprecated and will throw an exception in Symfony 4.0
|
||||
* setting the `checkDNS` option of the `Url` constraint to `true` is deprecated in favor of constant values and will throw an exception in Symfony 4.0
|
||||
|
||||
3.3.0
|
||||
-----
|
||||
|
@ -21,6 +21,20 @@ use Symfony\Component\Validator\Constraint;
|
||||
*/
|
||||
class Url extends Constraint
|
||||
{
|
||||
const CHECK_DNS_TYPE_ANY = 'ANY';
|
||||
const CHECK_DNS_TYPE_NONE = false;
|
||||
const CHECK_DNS_TYPE_A = 'A';
|
||||
const CHECK_DNS_TYPE_A6 = 'A6';
|
||||
const CHECK_DNS_TYPE_AAAA = 'AAAA';
|
||||
const CHECK_DNS_TYPE_CNAME = 'CNAME';
|
||||
const CHECK_DNS_TYPE_MX = 'MX';
|
||||
const CHECK_DNS_TYPE_NAPTR = 'NAPTR';
|
||||
const CHECK_DNS_TYPE_NS = 'NS';
|
||||
const CHECK_DNS_TYPE_PTR = 'PTR';
|
||||
const CHECK_DNS_TYPE_SOA = 'SOA';
|
||||
const CHECK_DNS_TYPE_SRV = 'SRV';
|
||||
const CHECK_DNS_TYPE_TXT = 'TXT';
|
||||
|
||||
const INVALID_URL_ERROR = '57c2f299-1154-4870-89bb-ef3b1f5ad229';
|
||||
|
||||
protected static $errorNames = array(
|
||||
@ -30,5 +44,5 @@ class Url extends Constraint
|
||||
public $message = 'This value is not a valid URL.';
|
||||
public $dnsMessage = 'The host could not be resolved.';
|
||||
public $protocols = array('http', 'https');
|
||||
public $checkDNS = false;
|
||||
public $checkDNS = self::CHECK_DNS_TYPE_NONE;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\Validator\Constraints;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidator;
|
||||
use Symfony\Component\Validator\Exception\InvalidOptionsException;
|
||||
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
|
||||
/**
|
||||
@ -72,9 +73,32 @@ class UrlValidator extends ConstraintValidator
|
||||
}
|
||||
|
||||
if ($constraint->checkDNS) {
|
||||
// backwards compatibility
|
||||
if ($constraint->checkDNS === true) {
|
||||
$constraint->checkDNS = Url::CHECK_DNS_TYPE_ANY;
|
||||
@trigger_error(sprintf('Use of the boolean TRUE for the "checkDNS" option in %s is deprecated. Use Url::CHECK_DNS_TYPE_ANY instead.', Url::class), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if (!in_array($constraint->checkDNS, array(
|
||||
Url::CHECK_DNS_TYPE_ANY,
|
||||
Url::CHECK_DNS_TYPE_A,
|
||||
Url::CHECK_DNS_TYPE_A6,
|
||||
Url::CHECK_DNS_TYPE_AAAA,
|
||||
Url::CHECK_DNS_TYPE_CNAME,
|
||||
Url::CHECK_DNS_TYPE_MX,
|
||||
Url::CHECK_DNS_TYPE_NAPTR,
|
||||
Url::CHECK_DNS_TYPE_NS,
|
||||
Url::CHECK_DNS_TYPE_PTR,
|
||||
Url::CHECK_DNS_TYPE_SOA,
|
||||
Url::CHECK_DNS_TYPE_SRV,
|
||||
Url::CHECK_DNS_TYPE_TXT,
|
||||
))) {
|
||||
throw new InvalidOptionsException(sprintf('Invalid value for option "checkDNS" in constraint %s', get_class($constraint)), array('checkDNS'));
|
||||
}
|
||||
|
||||
$host = parse_url($value, PHP_URL_HOST);
|
||||
|
||||
if (!is_string($host) || !checkdnsrr($host, 'ANY')) {
|
||||
if (!is_string($host) || !checkdnsrr($host, $constraint->checkDNS)) {
|
||||
$this->context->buildViolation($constraint->dnsMessage)
|
||||
->setParameter('{{ value }}', $this->formatValue($host))
|
||||
->setCode(Url::INVALID_URL_ERROR)
|
||||
|
@ -203,7 +203,7 @@ class UrlValidatorTest extends ConstraintValidatorTestCase
|
||||
DnsMock::withMockedHosts(array('example.com' => array(array('type' => $violation ? '' : 'A'))));
|
||||
|
||||
$constraint = new Url(array(
|
||||
'checkDNS' => true,
|
||||
'checkDNS' => 'ANY',
|
||||
'dnsMessage' => 'myMessage',
|
||||
));
|
||||
|
||||
@ -223,6 +223,75 @@ class UrlValidatorTest extends ConstraintValidatorTestCase
|
||||
{
|
||||
return array(array(true), array(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getCheckDnsTypes
|
||||
* @requires function Symfony\Bridge\PhpUnit\DnsMock::withMockedHosts
|
||||
*/
|
||||
public function testCheckDnsByType($type)
|
||||
{
|
||||
DnsMock::withMockedHosts(array('example.com' => array(array('type' => $type))));
|
||||
|
||||
$constraint = new Url(array(
|
||||
'checkDNS' => $type,
|
||||
'dnsMessage' => 'myMessage',
|
||||
));
|
||||
|
||||
$this->validator->validate('http://example.com', $constraint);
|
||||
|
||||
$this->assertNoViolation();
|
||||
}
|
||||
|
||||
public function getCheckDnsTypes()
|
||||
{
|
||||
return array(
|
||||
array('ANY'),
|
||||
array('A'),
|
||||
array('A6'),
|
||||
array('AAAA'),
|
||||
array('CNAME'),
|
||||
array('MX'),
|
||||
array('NAPTR'),
|
||||
array('NS'),
|
||||
array('PTR'),
|
||||
array('SOA'),
|
||||
array('SRV'),
|
||||
array('TXT'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testCheckDnsWithBoolean()
|
||||
{
|
||||
DnsMock::withMockedHosts(array('example.com' => array(array('type' => 'A'))));
|
||||
|
||||
$constraint = new Url(array(
|
||||
'checkDNS' => true,
|
||||
'dnsMessage' => 'myMessage',
|
||||
));
|
||||
|
||||
$this->validator->validate('http://example.com', $constraint);
|
||||
|
||||
$this->assertNoViolation();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Validator\Exception\InvalidOptionsException
|
||||
* @requires function Symfony\Bridge\PhpUnit\DnsMock::withMockedHosts
|
||||
*/
|
||||
public function testCheckDnsWithInvalidType()
|
||||
{
|
||||
DnsMock::withMockedHosts(array('example.com' => array(array('type' => 'A'))));
|
||||
|
||||
$constraint = new Url(array(
|
||||
'checkDNS' => 'BOGUS',
|
||||
'dnsMessage' => 'myMessage',
|
||||
));
|
||||
|
||||
$this->validator->validate('http://example.com', $constraint);
|
||||
}
|
||||
}
|
||||
|
||||
class EmailProvider
|
||||
|
Reference in New Issue
Block a user