6#include "validatordomain_p.h"
19 const QString &defValKey)
20 :
ValidatorRule(*new ValidatorDomainPrivate(field, checkDNS, messages, defValKey))
29 QString *extractedValue)
36 bool hasRootDot =
false;
37 if (_v.endsWith(u
'.')) {
43 const QString v = QString::fromLatin1(QUrl::toAce(_v)).toLower();
46 const QStringList nonAceParts = _v.split(QLatin1Char(
'.'));
47 if (!nonAceParts.empty()) {
48 const QString tld = nonAceParts.last();
54 for (
const QChar &ch : tld) {
55 const ushort &uc = ch.unicode();
56 if (((uc >= ValidatorRulePrivate::ascii_0) &&
57 (uc <= ValidatorRulePrivate::ascii_9)) ||
58 (uc == ValidatorRulePrivate::ascii_dash)) {
68 if (v.length() <= ValidatorDomainPrivate::maxDnsNameWithLastDot) {
69 const QStringList parts = v.split(QLatin1Char(
'.'), Qt::KeepEmptyParts);
71 if (parts.size() > 1) {
73 if (parts.last().length() > 1) {
74 for (
int i = 0; i < parts.size(); ++i) {
76 const QString &part = parts.at(i);
77 if (!part.isEmpty()) {
80 ValidatorDomainPrivate::maxDnsLabelLength) {
81 bool isTld = (i == (parts.size() - 1));
82 bool isPunyCode = part.startsWith(u
"xn--");
83 for (
int j = 0; j < part.size(); ++j) {
84 const ushort &uc = part.at(j).unicode();
86 ((uc >= ValidatorRulePrivate::ascii_0) &&
87 (uc <= ValidatorRulePrivate::ascii_9));
89 (uc == ValidatorRulePrivate::ascii_dash);
92 if ((j == 0) && (isDash || isDigit)) {
98 if ((j == (part.size() - 1)) && isDash) {
104 ((uc >= ValidatorRulePrivate::ascii_a) &&
105 (uc <= ValidatorRulePrivate::ascii_z));
109 if (!(isDigit || isDash || isChar)) {
116 if (!(isDigit || isDash || isChar)) {
170 if (valid && checkDNS) {
171 QDnsLookup alookup(QDnsLookup::A, v);
173 QObject::connect(&alookup, &QDnsLookup::finished, &aloop, &QEventLoop::quit);
174 QTimer::singleShot(ValidatorDomainPrivate::dnsLookupTimeout, &alookup, &QDnsLookup::abort);
178 if (((alookup.error() != QDnsLookup::NoError) &&
179 (alookup.error() != QDnsLookup::OperationCancelledError)) ||
180 alookup.hostAddressRecords().empty()) {
181 QDnsLookup aaaaLookup(QDnsLookup::AAAA, v);
183 QObject::connect(&aaaaLookup, &QDnsLookup::finished, &aaaaLoop, &QEventLoop::quit);
185 ValidatorDomainPrivate::dnsLookupTimeout, &aaaaLookup, &QDnsLookup::abort);
189 if (((aaaaLookup.error() != QDnsLookup::NoError) &&
190 (aaaaLookup.error() != QDnsLookup::OperationCancelledError)) ||
191 aaaaLookup.hostAddressRecords().empty()) {
194 }
else if (aaaaLookup.error() == QDnsLookup::OperationCancelledError) {
198 }
else if (alookup.error() == QDnsLookup::OperationCancelledError) {
208 if (valid && extractedValue) {
210 *extractedValue = v + QLatin1Char(
'.');
221 if (
label.isEmpty()) {
226 return c->
qtTrId(
"cutelyst-valdomain-diag-missingdns");
229 return c->
qtTrId(
"cutelyst-valdomain-diag-invalidchars");
235 return c->
qtTrId(
"cutelyst-valdomain-diag-labeltoolong");
240 return c->
qtTrId(
"cutelyst-valdomain-diag-toolong");
244 return c->
qtTrId(
"cutelyst-valdomain-diag-invalidlabelcount");
248 return c->
qtTrId(
"cutelyst-valdomain-diag-emptylabel");
252 return c->
qtTrId(
"cutelyst-valdomain-diag-invalidtld");
255 return c->
qtTrId(
"cutelyst-valdomain-diag-dashstart");
258 return c->
qtTrId(
"cutelyst-valdomain-diag-dashend");
261 return c->
qtTrId(
"cutelyst-valdomain-diag-digitstart");
264 return c->
qtTrId(
"cutelyst-valdomain-diag-valid");
267 return c->
qtTrId(
"cutelyst-valdomain-diag-dnstimeout");
269 Q_ASSERT_X(
false,
"domain validation diagnose",
"invalid diagnose");
277 return c->
qtTrId(
"cutelyst-valdomain-diag-missingdns-label").arg(
label);
280 return c->
qtTrId(
"cutelyst-valdomain-diag-invalidchars-label").arg(
label);
287 return c->
qtTrId(
"cutelyst-valdomain-diag-labeltoolong-label").arg(
label);
292 return c->
qtTrId(
"cutelyst-valdomain-diag-toolong-label").arg(
label);
296 return c->
qtTrId(
"cutelyst-valdomain-diag-invalidlabelcount-label").arg(
label);
301 return c->
qtTrId(
"cutelyst-valdomain-diag-emptylabel-label").arg(
label);
305 return c->
qtTrId(
"cutelyst-valdomain-diag-invalidtld-label").arg(
label);
309 return c->
qtTrId(
"cutelyst-valdomain-diag-dashstart-label").arg(
label);
313 return c->
qtTrId(
"cutelyst-valdomain-diag-dashend-label").arg(
label);
317 return c->
qtTrId(
"cutelyst-valdomain-diag-digitstart-label").arg(
label);
320 return c->
qtTrId(
"cutelyst-valdomain-diag-valid-label").arg(
label);
324 return c->
qtTrId(
"cutelyst-valdomain-diag-dnstimeout-label").arg(
label);
326 Q_ASSERT_X(
false,
"domain validation diagnose",
"invalid diagnose");
336 const QString &v =
value(params);
343 result.
value.setValue(exVal);
346 if (C_VALIDATOR().isDebugEnabled()) {
351 qCDebug(C_VALIDATOR).noquote()
352 <<
debugString(c) <<
"Can not find valid DNS entry for" << v;
355 qCDebug(C_VALIDATOR).noquote()
357 <<
"The domain name contains characters that are not allowed";
360 qCDebug(C_VALIDATOR).noquote()
362 <<
"At least on of the domain name labels exceeds the maximum" <<
"size of"
363 << ValidatorDomainPrivate::maxDnsLabelLength <<
"characters";
366 qCDebug(C_VALIDATOR).noquote()
367 <<
debugString(c) <<
"The domain name exceeds the maximum size of"
368 << ValidatorDomainPrivate::maxDnsNameWithLastDot <<
"characters";
371 qCDebug(C_VALIDATOR).noquote()
372 <<
debugString(c) <<
"Invalid label count. Either no labels or only TLD";
375 qCDebug(C_VALIDATOR).noquote()
376 <<
debugString(c) <<
"At least one of the domain name labels is empty";
379 qCDebug(C_VALIDATOR).noquote()
381 <<
"The TLD label contains characters that are not allowed";
384 qCDebug(C_VALIDATOR).noquote()
385 <<
debugString(c) <<
"At least one label starts with a dash";
388 qCDebug(C_VALIDATOR).noquote()
389 <<
debugString(c) <<
"At least one label ends with a dash";
392 qCDebug(C_VALIDATOR).noquote()
393 <<
debugString(c) <<
"At least one label starts with a digit";
396 qCDebug(C_VALIDATOR).noquote()
397 <<
debugString(c) <<
"The DNS lookup exceeds the timeout of"
398#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
399 << ValidatorDomainPrivate::dnsLookupTimeout;
401 << ValidatorDomainPrivate::dnsLookupTimeout.count() <<
"milliseconds";
418#include "moc_validatordomain.cpp"
QString qtTrId(const char *id, int n=-1) const
Checks if the value of the input field contains a FQDN according to RFC 1035.
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error message if validation failed.
static QString diagnoseString(Context *c, Diagnose diagnose, const QString &label=QString())
ValidatorDomain(const QString &field, bool checkDNS=false, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey=QString())
Constructs a new ValidatorDomain object with the given parameters.
~ValidatorDomain() override
Diagnose
Possible diagnose information for the checked domain.
Base class for all validator rules.
QString validationError(Context *c, const QVariant &errorData={}) const
QString label(Context *c) const
void defaultValue(Context *c, ValidatorReturnType *result) const
QString value(const ParamsMultiMap ¶ms) const
QString debugString(Context *c) const
QMultiMap< QString, QString > ParamsMultiMap
static bool validate(const QString &value, bool checkDNS, Diagnose *diagnose=nullptr, QString *extractedValue=nullptr)
Returns true if value is a valid fully qualified domain name.
The Cutelyst namespace holds all public Cutelyst API.
Stores custom error messages and the input field label.
Contains the result of a single input parameter validation.