README.md in truemail-2.1.0 vs README.md in truemail-2.2.0

- old
+ new

@@ -38,10 +38,11 @@ - [With custom regex pattern](#with-custom-regex-pattern) - [DNS (MX) validation](#mx-validation) - [RFC MX lookup flow](#rfc-mx-lookup-flow) - [Not RFC MX lookup flow](#not-rfc-mx-lookup-flow) - [SMTP validation](#smtp-validation) + - [SMTP fail fast enabled](#smtp-fail-fast-enabled) - [SMTP safe check disabled](#smtp-safe-check-disabled) - [SMTP safe check enabled](#smtp-safe-check-enabled) - [Host audit features](#host-audit-features) - [IP audit](#ip-audit) - [DNS audit](#dns-audit) @@ -80,14 +81,16 @@ - Configurable validator, validate only what you need - Minimal runtime dependencies - Supporting of internationalized emails ([EAI](https://en.wikipedia.org/wiki/Email_address#Internationalization)) - Whitelist/blacklist validation layers +- Ability to configure different MX/SMTP validation flows - Simple SMTP debugger - Event logger - Host auditor tools (helps to detect common host problems interfering to proper email verification) - JSON serializers +- Ability to use the library as independent stateless microservice ([Truemail Server](https://truemail-rb.org/truemail-rack)) ## Requirements Ruby MRI 2.5.0+ @@ -127,10 +130,12 @@ - default validation type - validation type for domains - whitelisted domains - whitelist validation - blacklisted domains +- RFC MX lookup flow +- SMTP fail fast - SMTP safe check - event logger - JSON serializer #### Setting global configuration @@ -199,10 +204,17 @@ # Optional parameter. This option will provide to use not RFC MX lookup flow. # It means that MX and Null MX records will be cheked on the DNS validation layer only. # By default this option is disabled. config.not_rfc_mx_lookup_flow = true + # Optional parameter. This option will provide to use smtp fail fast behaviour. When + # smtp_fail_fast = true it means that truemail ends smtp validation session after first + # attempt on the first mx server in any fail cases (network connection/timeout error, + # smtp validation error). This feature helps to reduce total time of SMTP validation + # session up to 1 second. By default this option is disabled. + config.smtp_fail_fast = true + # Optional parameter. This option will be parse bodies of SMTP errors. It will be helpful # if SMTP server does not return an exact answer that the email does not exist # By default this option is disabled, available for SMTP validation only. config.smtp_safe_check = true @@ -231,10 +243,11 @@ @whitelist_validation=true, @blacklisted_domains=[], @verifier_domain="somedomain.com", @verifier_email="verifier@example.com", @not_rfc_mx_lookup_flow=true, + @smtp_fail_fast=true, @smtp_safe_check=true, @logger=#<Truemail::Logger:0x0000557f837450b0 @event=:all, @file="/home/app/log/truemail.log", @stdout=true>> ``` @@ -260,10 +273,11 @@ @whitelist_validation=true, @blacklisted_domains=[], @verifier_domain="somedomain.com", @verifier_email="verifier@example.com", @not_rfc_mx_lookup_flow=true, + @smtp_fail_fast=true, @smtp_safe_check=true, @logger=#<Truemail::Logger:0x0000557f837450b0 @event=:all, @file="/home/app/log/truemail.log", @stdout=true>> ``` @@ -292,11 +306,10 @@ Truemail.host_audit('email@example.com', custom_configuration: custom_configuration) ``` Please note, you should have global or custom configuration for use Truemail gem. - ### Validation features #### Whitelist/Blacklist check Whitelist/Blacklist check is zero validation level. You can define white and black list domains. It means that validation of email which contains whitelisted domain always will return `true`, and for blacklisted domain will return `false`. @@ -344,10 +357,11 @@ @default_validation_type=:smtp, @email_pattern=/(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-|\.|\+]*)@((?i-mx:[\p{L}0-9]+([\-\.]{1}[\p{L}0-9]+)*\.[\p{L}]{2,63}))\z)/, @response_timeout=2, @smtp_error_body_pattern=/(?=.*550)(?=.*(user|account|customer|mailbox)).*/i, @not_rfc_mx_lookup_flow=false, + @smtp_fail_fast=false, @smtp_safe_check=false, @validation_type_by_domain={"somedomain.com"=>:mx}, @verifier_domain="example.com", @verifier_email="verifier@example.com", @whitelist_validation=false, @@ -390,10 +404,11 @@ @default_validation_type=:smtp, @email_pattern=/(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-|\.|\+]*)@((?i-mx:[\p{L}0-9]+([\-\.]{1}[\p{L}0-9]+)*\.[\p{L}]{2,63}))\z)/, @response_timeout=2, @smtp_error_body_pattern=/(?=.*550)(?=.*(user|account|customer|mailbox)).*/i, @not_rfc_mx_lookup_flow=false, + @smtp_fail_fast=false, @smtp_safe_check=false, @validation_type_by_domain={}, @verifier_domain="example.com", @verifier_email="verifier@example.com", @whitelist_validation=true, @@ -422,10 +437,11 @@ @default_validation_type=:smtp, @email_pattern=/(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-|\.|\+]*)@((?i-mx:[\p{L}0-9]+([\-\.]{1}[\p{L}0-9]+)*\.[\p{L}]{2,63}))\z)/, @response_timeout=2, @smtp_error_body_pattern=/(?=.*550)(?=.*(user|account|customer|mailbox)).*/i, @not_rfc_mx_lookup_flow=false, + @smtp_fail_fast=false, @smtp_safe_check=false, @validation_type_by_domain={}, @verifier_domain="example.com", @verifier_email="verifier@example.com", @whitelist_validation=true, @@ -456,10 +472,11 @@ @default_validation_type=:smtp, @email_pattern=/(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-|\.|\+]*)@((?i-mx:[\p{L}0-9]+([\-\.]{1}[\p{L}0-9]+)*\.[\p{L}]{2,63}))\z)/, @response_timeout=2, @smtp_error_body_pattern=/(?=.*550)(?=.*(user|account|customer|mailbox)).*/i, @not_rfc_mx_lookup_flow=false, + @smtp_fail_fast=false, @smtp_safe_check=false, @validation_type_by_domain={}, @verifier_domain="example.com", @verifier_email="verifier@example.com", @whitelist_validation=true, @@ -490,10 +507,11 @@ @default_validation_type=:smtp, @email_pattern=/(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-|\.|\+]*)@((?i-mx:[\p{L}0-9]+([\-\.]{1}[\p{L}0-9]+)*\.[\p{L}]{2,63}))\z)/, @response_timeout=2, @smtp_error_body_pattern=/(?=.*550)(?=.*(user|account|customer|mailbox)).*/i, @not_rfc_mx_lookup_flow=false, + @smtp_fail_fast=false, @smtp_safe_check=false, @validation_type_by_domain={}, @verifier_domain="example.com", @verifier_email="verifier@example.com", @whitelist_validation=true, @@ -540,10 +558,11 @@ @default_validation_type=:smtp, @email_pattern=/(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-|\.|\+]*)@((?i-mx:[\p{L}0-9]+([\-\.]{1}[\p{L}0-9]+)*\.[\p{L}]{2,63}))\z)/, @response_timeout=2, @smtp_error_body_pattern=/(?=.*550)(?=.*(user|account|customer|mailbox)).*/i, @not_rfc_mx_lookup_flow=false, + @smtp_fail_fast=false, @smtp_safe_check=false, @validation_type_by_domain={}, @verifier_domain="example.com", @verifier_email="verifier@example.com", @whitelist_validation=false, @@ -582,10 +601,11 @@ @default_validation_type=:smtp, @email_pattern=/regex_pattern/, @response_timeout=2, @smtp_error_body_pattern=/(?=.*550)(?=.*(user|account|customer|mailbox)).*/i, @not_rfc_mx_lookup_flow=false, + @smtp_fail_fast=false, @smtp_safe_check=false, @validation_type_by_domain={}, @verifier_domain="example.com", @verifier_email="verifier@example.com", @whitelist_validation=false, @@ -635,10 +655,11 @@ @default_validation_type=:smtp, @email_pattern=/(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-|\.|\+]*)@((?i-mx:[\p{L}0-9]+([\-\.]{1}[\p{L}0-9]+)*\.[\p{L}]{2,63}))\z)/, @response_timeout=2, @smtp_error_body_pattern=/(?=.*550)(?=.*(user|account|customer|mailbox)).*/i, @not_rfc_mx_lookup_flow=false, + @smtp_fail_fast=false, @smtp_safe_check=false, @validation_type_by_domain={}, @verifier_domain="example.com", @verifier_email="verifier@example.com", @whitelist_validation=false, @@ -679,10 +700,11 @@ @default_validation_type=:smtp, @email_pattern=/(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-|\.|\+]*)@((?i-mx:[\p{L}0-9]+([\-\.]{1}[\p{L}0-9]+)*\.[\p{L}]{2,63}))\z)/, @response_timeout=2, @smtp_error_body_pattern=/(?=.*550)(?=.*(user|account|customer|mailbox)).*/i, @not_rfc_mx_lookup_flow=true, + @smtp_fail_fast=false, @smtp_safe_check=false, @validation_type_by_domain={}, @verifier_domain="example.com", @verifier_email="verifier@example.com", @whitelist_validation=false, @@ -700,10 +722,72 @@ If total count of MX servers is equal to one, `Truemail::Smtp` validator will use value from `Truemail.configuration.connection_attempts` as connection attempts. By default it's equal `2`. By default, you don't need pass with-parameter to use it. Example of usage is specified below: +##### SMTP fail fast enabled + +Truemail can use fail fast behaviour for SMTP validation layer. When `smtp_fail_fast = true` it means that `truemail` ends smtp validation session after first attempt on the first mx server in any fail cases (network connection/timeout error, smtp validation error). This feature helps to reduce total time of SMTP validation session up to 1 second. + +```ruby +require 'truemail' + +Truemail.configure do |config| + config.verifier_email = 'verifier@example.com' + config.smtp_fail_fast = true +end + +Truemail.validate('email@example.com') + +# SMTP validation failed, smtp fail fast validation scenario +=> #<Truemail::Validator:0x00007fdc4504f460 + @result= + #<struct Truemail::Validator::Result + success=false, + email="email@example.com", + domain="example.com", + mail_servers=["127.0.1.1", "127.0.1.2", "127.0.1.3"], # there are 3 mail servers in a row + errors={:smtp=>"smtp error"}, + smtp_debug= + [#<Truemail::Validate::Smtp::Request:0x00007fdc43150b90 # but iteration has been stopped after the first failure + @attempts=nil, + @configuration= + #<Truemail::Validate::Smtp::Request::Configuration:0x00007fdc43150b18 + @connection_timeout=2, + @response_timeout=2, + @verifier_domain="example.com", + @verifier_email="verifier@example.com">, + @email="email@example.com", + @host="127.0.1.1", + @response= + #<struct Truemail::Validate::Smtp::Response + port_opened=false, + connection=nil, + helo=nil, + mailfrom=nil, + rcptto=nil, + errors={}>>], + configuration= + #<Truemail::Configuration:0x00007fdc4504f5c8 + @blacklisted_domains=[], + @connection_attempts=2, + @connection_timeout=2, + @default_validation_type=:smtp, + @email_pattern=/(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-.+]*)@((?i-mx:[\p{L}0-9]+([\-.]{1}[\p{L}0-9]+)*\.\p{L}{2,63}))\z)/, + @not_rfc_mx_lookup_flow=false, + @response_timeout=2, + @smtp_error_body_pattern=/(?=.*550)(?=.*(user|account|customer|mailbox)).*/i, + @smtp_fail_fast=true, + @smtp_safe_check=false, + @validation_type_by_domain={}, + @verifier_domain="example.com", + @verifier_email="verifier@example.com", + @whitelist_validation=false, + @whitelisted_domains=[]>>, + @validation_type=:smtp> +``` + ##### SMTP safe check disabled With `smtp_safe_check = false` ```ruby @@ -733,10 +817,11 @@ @default_validation_type=:smtp, @email_pattern=/(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-|\.|\+]*)@((?i-mx:[\p{L}0-9]+([\-\.]{1}[\p{L}0-9]+)*\.[\p{L}]{2,63}))\z)/, @response_timeout=2, @smtp_error_body_pattern=/(?=.*550)(?=.*(user|account|customer|mailbox)).*/i, @not_rfc_mx_lookup_flow=false, + @smtp_fail_fast=false, @smtp_safe_check=false, @validation_type_by_domain={}, @verifier_domain="example.com", @verifier_email="verifier@example.com", @whitelist_validation=false, @@ -782,10 +867,11 @@ @default_validation_type=:smtp, @email_pattern=/(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-|\.|\+]*)@((?i-mx:[\p{L}0-9]+([\-\.]{1}[\p{L}0-9]+)*\.[\p{L}]{2,63}))\z)/, @response_timeout=2, @smtp_error_body_pattern=/(?=.*550)(?=.*(user|account|customer|mailbox)).*/i, @not_rfc_mx_lookup_flow=false, + @smtp_fail_fast=false, @smtp_safe_check=false, @validation_type_by_domain={}, @verifier_domain="example.com", @verifier_email="verifier@example.com", @whitelist_validation=false, @@ -843,10 +929,11 @@ @default_validation_type=:smtp, @email_pattern=/(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-|\.|\+]*)@((?i-mx:[\p{L}0-9]+([\-\.]{1}[\p{L}0-9]+)*\.[\p{L}]{2,63}))\z)/, @response_timeout=2, @smtp_error_body_pattern=/(?=.*550)(?=.*(user|account|customer|mailbox)).*/i, @not_rfc_mx_lookup_flow=false, + @smtp_fail_fast=false, @smtp_safe_check=false, @validation_type_by_domain={}, @verifier_domain="example.com", @verifier_email="verifier@example.com", @whitelist_validation=false, @@ -889,10 +976,11 @@ @default_validation_type=:smtp, @email_pattern=/(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-|\.|\+]*)@((?i-mx:[\p{L}0-9]+([\-\.]{1}[\p{L}0-9]+)*\.[\p{L}]{2,63}))\z)/, @response_timeout=2, @smtp_error_body_pattern=/(?=.*550)(?=.*(user|account|customer|mailbox)).*/i, @not_rfc_mx_lookup_flow=false, + @smtp_fail_fast=false, @smtp_safe_check=false, @validation_type_by_domain={}, @verifier_domain="example.com", @verifier_email="verifier@example.com", @whitelist_validation=false, @@ -936,10 +1024,11 @@ @default_validation_type=:smtp, @email_pattern=/(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-|\.|\+]*)@((?i-mx:[\p{L}0-9]+([\-\.]{1}[\p{L}0-9]+)*\.[\p{L}]{2,63}))\z)/, @response_timeout=2, @smtp_error_body_pattern=/(?=.*550)(?=.*(user|account|customer|mailbox)).*/i, @not_rfc_mx_lookup_flow=false, + @smtp_fail_fast=false, @smtp_safe_check=false, @validation_type_by_domain={}, @verifier_domain="example.com", @verifier_email="verifier@example.com", @whitelist_validation=false, @@ -962,10 +1051,11 @@ @default_validation_type=:smtp, @email_pattern=/(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-|\.|\+]*)@((?i-mx:[\p{L}0-9]+([\-\.]{1}[\p{L}0-9]+)*\.[\p{L}]{2,63}))\z)/, @response_timeout=2, @smtp_error_body_pattern=/(?=.*550)(?=.*(user|account|customer|mailbox)).*/i, @not_rfc_mx_lookup_flow=false, + @smtp_fail_fast=false, @smtp_safe_check=false, @validation_type_by_domain={}, @verifier_domain="example.com", @verifier_email="verifier@example.com", @whitelist_validation=false, @@ -1010,10 +1100,11 @@ "validation_type_by_domain": null, "whitelist_validation": false, "whitelisted_domains": null, "blacklisted_domains": null, "not_rfc_mx_lookup_flow": false, + "smtp_fail_fast": false, "smtp_safe_check": false, "email_pattern": "default gem value", "smtp_error_body_pattern": "default gem value" } } @@ -1048,10 +1139,11 @@ "validation_type_by_domain": null, "whitelist_validation": false, "whitelisted_domains": null, "blacklisted_domains": null, "not_rfc_mx_lookup_flow": false, + "smtp_fail_fast": false, "smtp_safe_check": false, "email_pattern": "default gem value", "smtp_error_body_pattern": "default gem value" } } @@ -1088,10 +1180,11 @@ "validation_type_by_domain": null, "whitelist_validation": false, "whitelisted_domains": null, "blacklisted_domains": null, "not_rfc_mx_lookup_flow": false, + "smtp_fail_fast": false, "smtp_safe_check": false, "email_pattern": "default gem value", "smtp_error_body_pattern": "default gem value" } } @@ -1123,9 +1216,10 @@ "validation_type_by_domain": null, "whitelist_validation": false, "whitelisted_domains": null, "blacklisted_domains": null, "not_rfc_mx_lookup_flow": false, + "smtp_fail_fast": false, "smtp_safe_check": false, "email_pattern": "default gem value", "smtp_error_body_pattern": "default gem value" } }