Google Guava與網絡操作相關的類

1.介紹

InternetDomainName是用於解析和操作域名的有用工具。它可以用作驗證器、組件提取器以及用作以類型安全的方式傳遞域名的值類型。

然而,InternetDomainName行爲的某些方面可能令人吃驚,並且可能導致調用代碼中的錯誤。本文檔解決了這些問題。

2.細節

2.1公共後綴和私有域名

根據相關的RFC規範,可以保證InternetDomainName對象在語法上是有效的,但不能保證它與Internet上的實際可尋址域相對應。如果不對域進行網絡查找並嘗試與它聯繫,就不可能做到這一點,對於大多數常見情況而言,這是不可接受的開銷。

儘管如此,確定給定域名是否可以代表Internet上的實際域名通常非常有用。爲此,我們使用來自公共後綴列表(Public Suffix List (PSL))的數據,該列表由Mozilla Foundation維護。InternetDomainName上有一些方法可以確定給定域名與PSL的關係。用最基本的術語來說,如果domain.hasPublicSuffix()返回true,則該域可能對應於一個真實的Internet地址;否則,幾乎可以肯定不會。

在這一點上,我們需要備份並定義一些術語。有四個興趣條款:

  • 頂級域名(Top-Level Domain (TLD)):沒有子域的單標籤域,例如comau
  • 註冊表後綴:由域名註冊機構(例如Verisign for com)控制的域名(例如comco.uk),人們可以在該域名下通過域名註冊機構(例如Namecheap)註冊子域名。此類域名註冊受互聯網監管機構(如ICANN)的法律保護。
  • 公共後綴:此類別是註冊表後綴的超集,另外還包括不受註冊表控制但允許公衆註冊子域的後綴(例如blogspot.com)。在幾種常見情況下,更適合按公共後綴而不是註冊表後綴對域進行分類。例如,永遠不要在公共後綴上設置cookie。
  • 有效的頂級域:“公共後綴”的已棄用同義詞。

在繼續之前值得仔細閱讀鏈接中的文章。

造成混淆的一個主要原因是人們說“ TLD”是指“註冊後綴”還是“公共後綴”。所有這三個都是獨立的概念。例如:

  • com是這三個部分:一個TLD,一個註冊後綴和一個公共後綴
  • au是TLD,但不是註冊表後綴或公共後綴
  • com.au是註冊表後綴和公共後綴,但不是TLD
  • blogspot.com是公共後綴,但既不是註冊表後綴也不是TLD
  • squerf不是這三個中的任何一個

這種混淆尤其危險,因爲TLD和註冊後綴具有明確的正式定義,而公共後綴則沒有。最後,一個可靠的消息來源要求PSL維護者將公共後綴添加到列表中。可信來源包括ICANN和國家/地區域管理者,但還包括提供服務的私營公司,這些服務具有(模糊地)定義了公共後綴的特徵——獨立的子域和超級cookie抑制。例如,PSL中包含許多Google擁有的域(例如blogspot.com)。

回到InternetDomainName,只要我們限制使用hasPublicSuffix()來驗證該域是一個合理的Internet域,一切都很好。這種危險來自識別或提取“頂級私有域”的方法。從技術角度來看,頂級私有域只是公共後綴之前最右邊的超級域。因此,例如,www.foo.co.uk的後綴爲co.uk,頂級私人域爲foo.co.uk

正如有關isUnderPublicSuffix()isTopPrivateDomain()topPrivateDomain()的文檔所述,這些方法(大多數)唯一可靠的是確定可以在哪裏設置Cookie。但是,許多人實際上想做的是從子域中找到“真實”域或“所有者”域。例如,他們希望在mail.google.com中將google.com標識爲所有者域。所以他們寫

InternetDomainName owner =
    InternetDomainName.from("mail.google.com").topPrivateDomain();

…當然,所有者最終以google.com域爲域名。事實上,這種習語(以及類似的習語)在很多時候都起作用。它看起來很直觀,“公共後綴下的域”在語義上應等效於“所有者域”。

但這不是問題所在。考慮出現在PSL中的blogspot.com。儘管它具有公共後綴的特徵——人們可以在其下注冊域名(用於其博客),並且不應該在它上面設置cookie(以防止跨博客cookie惡作劇),它本身是Internet上的一個可尋址域(在撰寫本文時,該域恰好重定向到blogger.com,但這很容易更改)。

因此,如果在foo.blogspot.com上使用上述習語,所有者將是相同的域foo.blogspot.com。對於許多常見應用程序來說,這是cookie設置的正確答案,但是對於許多人來說,這顯然是令人驚訝的。

對於那些實際上旨在確定從註冊表購買的域名的稀有應用程序,正確的抽象不是公共後綴,而是註冊表後綴。如果我們更改上面的代碼以對註冊表後綴使用並行方法:

InternetDomainName owner =
    InternetDomainName.from("foo.blogspot.com").topDomainUnderRegistrySuffix();

…然後我們最終將所有者設置爲blogspot.com

這張表格方便的總結了各種後綴類型之間的區別:

InternetDomainName publicSuffix() topPrivateDomain() registrySuffix() topDomainUnderRegistrySuffix()
google.com com google.com com google.com
co.uk co.uk N/A co.uk N/A
www.google.co.uk co.uk google.co.uk co.uk google.co.uk
foo.blogspot.com blogspot.com foo.blogspot.com com blogspot.com
google.invalid N/A N/A N/A N/A

這裏的主要經驗是:

  • TLD、註冊表後綴和公共後綴不是一回事。
  • 公共後綴是由人類定義的,用於嚴格限制的目的(主要是域驗證和超級cookie預防),並且變化是不可預測的。
  • 給定域與公共後綴的關係,該域對Web請求的響應能力以及該域的“所有權”之間沒有定義映射。
  • 從ICANN風格的域名註冊的角度來看,註冊後綴可以幫助你確定域名的“所有權”;但是對於大多數應用程序,此信息不如公共後綴適用。
  • 你可以使用InternetDomainName來確定給定的字符串是否代表Internet上的合理可尋址域,並確定域的哪一部分可能允許設置cookie。
  • 你不能使用InternetDomainName來確定在Internet上是否存在作爲可尋址主機的域。

請記住,如果你不聽從這個建議,你的代碼似乎可以在各種各樣的輸入上工作…但是失敗案例都是等待發生的所有錯誤,隨着PSL更新被合併到InternetDomainName基礎代碼中,失敗案例的集合將發生變化。

本文參考:
InternetDomainNameExplained
guava-tests-net

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章