From fe5a2286a42055130107f1e0b1fb59e8e456d2be Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Fri, 1 Jan 2021 20:12:02 +0100 Subject: [PATCH] Update cache handling --- src/pretix/presale/forms/checkout.py | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/pretix/presale/forms/checkout.py b/src/pretix/presale/forms/checkout.py index ec2dd3a042..7968cb2634 100644 --- a/src/pretix/presale/forms/checkout.py +++ b/src/pretix/presale/forms/checkout.py @@ -20,12 +20,16 @@ from pretix.base.validators import EmailBanlistValidator from pretix.presale.signals import contact_form_fields -class EmailDNSValidator(): +class EmailDNSValidator: + msg = _('Please check your email domain, it does not look like "%(value)s" is able to receive emails.') + def __call__(self, value): domain = value.split('@')[-1] works = cache.get(f"mail_domain_exists_{domain}") - if works: + if works == "true": return value + if works == "false": + raise ValidationError(self.msg, code='dns', params={'value': domain}) resolver = dns.resolver.Resolver() resolver.lifetime = 0.5 @@ -36,13 +40,20 @@ class EmailDNSValidator(): if len(resolver.query(domain, record_type)): cache.set(f"mail_domain_exists_{domain}", "true", 3600 * 24 * 7) return value - except: + except (dns.resolver.NoAnswer, dns.resolver.NXDOMAIN, dns.resolver.YXDOMAIN): + # These errors represent a non-existing domain or entry, we want to continue with the + # other types of records and if all fail, we'll report an error. continue - raise ValidationError( - _('Please check your email domain, it does not look like "%(value)s" is able to receive emails.'), - code='dns', - params={'value': domain}, - ) + except: + # Timeout, IO errors, etc.: We don't know what's happening! Let's not stop the user + # from buying and just not validate this. Let's cache this result for a short while + # to prevent issues during peak load + cache.set(f"mail_domain_exists_{domain}", "false", 60) + return value + # No valid record found, even though the requests did not fail. This domain will not receive email. + # Cache this result for a short time. + cache.set(f"mail_domain_exists_{domain}", "false", 300) + raise ValidationError(self.msg, code='dns', params={'value': domain}) class ContactForm(forms.Form):