diff --git a/rule.go b/rule.go index bd88b35..e7dfd7a 100644 --- a/rule.go +++ b/rule.go @@ -1,6 +1,7 @@ package validate import ( + "context" "fmt" "net" "net/http" @@ -162,15 +163,23 @@ var NotRegex CheckFunc = func(r *http.Request, param string, o Options) error { // MXEmail looks up the MX Records on a domain to check if a record exists. If // an MX record exists, it is likely that the email address is real. This is // smarter than just checking if an email address fits a certain format. -var MXEmail CheckFunc = func(r *http.Request, param string, _ Options) error { +var MXEmail CheckFunc = func(r *http.Request, param string, o Options) error { if err := Email(r, param, nil); err != nil { return err } + timeout, ok := o["timeout"].(int) + if !ok { + timeout = 5 + } + parts := strings.Split(r.Form.Get(param), "@") domain := parts[len(parts)-1] - records, err := net.LookupMX(domain) + rsv := net.Resolver{} + ctx, cancel := context.WithTimeout(r.Context(), time.Duration(timeout)*time.Second) + defer cancel() + records, err := rsv.LookupMX(ctx, domain) if err != nil { return fmt.Errorf("failed to look up MX records for %s", param) } diff --git a/rule_test.go b/rule_test.go index 963ded3..ee69fc2 100644 --- a/rule_test.go +++ b/rule_test.go @@ -75,7 +75,14 @@ func TestRules(t *testing.T) { MXEmail, []string{"me@tomm.us", "lucyduggleby@hotmail.co.uk"}, []string{"me@something@addasadsdn2343567hgbf.com", "juststring", "me@space@tomm.us"}, - nil, + Options{"timeout": 10}, + }, + { + // MXEmail, but with a short timeout. + MXEmail, + []string{}, // No `passable` values, as these should all time out. + []string{"me@something@addasadsdn2343567hgbf.com", "juststring", "me@space@tomm.us"}, + Options{"timeout": 1}, }, { RFC3339,