diff options
| author | Lars Ingebrigtsen | 2018-05-01 14:26:27 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2018-05-01 14:26:38 +0200 |
| commit | e859acb11cacd0c661b730d43151f77281e17d7d (patch) | |
| tree | eec19287beb514c9a923febd835b46d671257d0b | |
| parent | 539f5889207157ddd864f228b126197573404dd9 (diff) | |
| download | emacs-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.el | 45 | ||||
| -rw-r--r-- | test/lisp/url/url-util-tests.el | 12 |
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. |
| 639 | not contain a registered name." | 636 | Return 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 |