aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ingebrigtsen2018-05-01 14:26:27 +0200
committerLars Ingebrigtsen2018-05-01 14:26:38 +0200
commite859acb11cacd0c661b730d43151f77281e17d7d (patch)
treeeec19287beb514c9a923febd835b46d671257d0b
parent539f5889207157ddd864f228b126197573404dd9 (diff)
downloademacs-e859acb11cacd0c661b730d43151f77281e17d7d.tar.gz
emacs-e859acb11cacd0c661b730d43151f77281e17d7d.zip
Rewrite `url-domain' to avoid network traffic
* lisp/url/url-util.el (url-domain): Don't talk DNS to determine the domain, because this is slow. * test/lisp/url/url-util-tests.el (url-domain-tests): Add tests for `url-domain'.
-rw-r--r--lisp/url/url-util.el45
-rw-r--r--test/lisp/url/url-util-tests.el12
2 files changed, 32 insertions, 25 deletions
diff --git a/lisp/url/url-util.el b/lisp/url/url-util.el
index 51c56249697..9bfbca65d9a 100644
--- a/lisp/url/url-util.el
+++ b/lisp/url/url-util.el
@@ -628,34 +628,29 @@ Creates FILE and its parent directories if they do not exist."
628 (set-file-modes file #o0600)))) 628 (set-file-modes file #o0600))))
629 629
630(autoload 'puny-encode-domain "puny") 630(autoload 'puny-encode-domain "puny")
631(autoload 'dns-query "dns") 631(autoload 'url-domsuf-cookie-allowed-p "url-domsuf")
632
633(defvar url--domain-cache (make-hash-table :test 'equal :size 17)
634 "Cache to minimize dns lookups.")
635 632
636;;;###autoload 633;;;###autoload
637(defun url-domain (url) 634(defun url-domain (url)
638 "Return the domain of the host of the url, or nil if url does 635 "Return the domain of the host of the url.
639not contain a registered name." 636Return nil if this can't be determined."
640 ;; Determining the domain of a name can not be done with simple 637 (let* ((host (puny-encode-domain (url-host url)))
641 ;; textual manipulations. a.b.c is either host a in domain b.c 638 (parts (nreverse (split-string host "\\.")))
642 ;; (www.google.com), or domain a.b.c with no separate host 639 (candidate (pop parts))
643 ;; (bbc.co.uk). Instead of guessing based on tld (which in any case 640 found)
644 ;; may be inaccurate in the face of subdelegations), we look for 641 ;; IP addresses aren't domains.
645 ;; domain delegations in DNS. 642 (when (string-match "\\`[0-9.]+\\'" host)
646 ;; 643 (setq parts nil))
647 ;; Domain delegations change rarely enough that we won't bother with 644 ;; We assume that the top-level domain is never an appropriate
648 ;; cache invalidation, I think. 645 ;; thing as "the domain", so we start at the next one (eg.
649 (let* ((host-parts (split-string (puny-encode-domain (url-host url)) "\\.")) 646 ;; "fsf.org").
650 (result (gethash host-parts url--domain-cache 'not-found))) 647 (while (and parts
651 (when (eq result 'not-found) 648 (not (setq found
652 (setq result 649 (url-domsuf-cookie-allowed-p
653 (cl-loop for parts on host-parts 650 (setq candidate (concat (pop parts) "."
654 for dom = (mapconcat #'identity parts ".") 651 candidate))))))
655 when (dns-query dom 'SOA) 652 )
656 return dom)) 653 (and found candidate)))
657 (puthash host-parts result url--domain-cache))
658 result))
659 654
660(provide 'url-util) 655(provide 'url-util)
661 656
diff --git a/test/lisp/url/url-util-tests.el b/test/lisp/url/url-util-tests.el
index ee97d97dd34..2e2875a196b 100644
--- a/test/lisp/url/url-util-tests.el
+++ b/test/lisp/url/url-util-tests.el
@@ -46,6 +46,18 @@
46 ("key2" "val2") 46 ("key2" "val2")
47 ("key1" "val1"))))) 47 ("key1" "val1")))))
48 48
49(ert-deftest url-domain-tests ()
50 (should (equal (url-domain (url-generic-parse-url "http://www.fsf.co.uk"))
51 "fsf.co.uk"))
52 (should (equal (url-domain (url-generic-parse-url "http://fsf.co.uk"))
53 "fsf.co.uk"))
54 (should (equal (url-domain (url-generic-parse-url "http://co.uk"))
55 nil))
56 (should (equal (url-domain (url-generic-parse-url "http://www.fsf.com"))
57 "fsf.com"))
58 (should (equal (url-domain (url-generic-parse-url "http://192.168.0.1"))
59 nil)))
60
49(provide 'url-util-tests) 61(provide 'url-util-tests)
50 62
51;;; url-util-tests.el ends here 63;;; url-util-tests.el ends here