WebKit中的URL解析

Python部落(python.freelycode.com)組織翻譯,禁止轉載,歡迎轉發。

數十年以來人們一直在使用URL。如果你認為同一個URL在不同的軟件中的行為是一致的,那你就錯了。

一致性

快速瀏覽URL構造一致性的測試(http://w3c-test.org/url/url-constructor.html),你就會發現現代URL規範的一致性非常差。沒有一個主流瀏覽器能夠通過2/3以上的測試,且不包含對於一些極端情況的測試。Safari技術預覽中包含的WebKit Trunk 是目前所有主流瀏覽器引擎中最標準、最統一的URL解析器。

瀏覽器作為互聯網基礎結構中最基本的組成部分,不同瀏覽器間的一致性極為重要,並且瀏覽器間的差異會以微妙的方式干擾網絡應用程序的正常運行。例如 <code>new URL("file:afc")/<code>在不同的瀏覽器中就有不同的行為。

在 Safari 10 中,其被規範化為 file://afc

在 Firefox 49 中,其被規範化為 file:///afc

在 Chrome 53 中,其在Windows上被規範化為 file://afc/,在macOS上被規範化為 file:///afc

在 Edge 38 中,它會拋出一個 JavaScript 異常。

但願沒有人寄希望於這些格式不一致的URL有一致的表現,但是瀏覽器中像這樣的差異是非常多的。不幸的是,網絡開發者目前的解決方法是避免使用這些在不同瀏覽器中表現迥異的URL。這是大家都不願看到的情況。

那麼什麼是“正確”的行為呢?一個佔據市場份額的URL工具(URL implementation)表現出一種特定的行為,那麼這個行為就會成為實際上的標準,但是互聯網上存在各種各樣的市場。比如你運營著一個跨國在線服務。如果你的服務通過瀏覽器進行,那麼你會最關注市場佔有率最高的瀏覽器。如果有人通過移動設備使用你的服務,那麼你會更關注移動設備瀏覽器的市場份額。如果你有本地應用程序使用操作系統的URL工具,你可能要研究操作系統的特殊之處,並且系統的任何一點改變都可能導致你的應用程序無法運行。

不幸的是如果改變URL的行為,可能導致依賴於原有特徵的應用程序崩潰。例如,你可能想通過刪除URL中一些不必要的字符來減小服務器的帶寬壓力。如果你嘗試檢查向地址為 https://example.org/ 的主機發送請求的用戶代理,你可能會對基於WebKit的用戶代理使用<code>而不是<code>的語句。此後,隨著WebKit變得更加符合規範,你的鏈接將會失效。原本指向<code>https://webkit.org/<code>的鏈接將會指向符合Chrome、Firefox特徵和URL規範的<code>https://example.org/webkit.org/<code>。如果你使用這種方法進行用戶代理的檢測,你的網絡應用是十分脆弱的,因為其可能隨著瀏覽器的升級而崩潰。

安全

瀏覽器不是唯一使用URL的程序。廣泛使用的URL解析器工具有很多,比如WebKit,Chromium,Gecko,cURL,PHP,libsoup等等,還包括很多閉源工具。理想的情況是每一個解析URL的程序對於通用性和謹慎處理非法操作有一致的表現。

HTTP服務器通常不會看到客戶端發來的完整的URL。服務器只會接收在HTTP請求第一行的路徑和查詢(query),通常看起來像這樣 "<code>GET /index.html?id=5 HTTP/1.1/<code>"。服務器通常會有各種各樣只負責解析路徑和查詢的解析器。服務器需要尤其注意不要錯誤地假設請求中不會出現像 "<code>GET ../password.txt HTTP/1.1/<code>" 或 "<code>GET %2e%2e/password.txt HTTP/1.1/<code>"的路徑,嘗試獲取文件夾外的文件,如果將這個路徑直接交由文件系統處理,可能使黑客能夠訪問私有文件。服務器還需要注意惡意客戶端發來的非ASCII字符。

如果你的網絡應用使用了內容安全策略,並且你對同一個主機地址使用了不同的寫法,你可能會遇到出乎意料的加載失敗。例如,"<code>http://example.com/<code>"和"<code>http://ex%61mple.com/<code>" 就是相同的地址使用了不同的寫法; "<code>http://[::0:abcd]/<code>"和"<code>http://[::abcd]/<code>"則是相同的的IPv6地址。主機的解析不一致可能有意外的安全影響。

性能

URL解釋器的性能是一個重要的考慮因素。在很多程序中URL解析不是最慢的操作,但是卻有很多操作涉及到URL的解析,所以讓URL解析變得更快,很多的操作的速度都會略有提升。理想的衡量標準是測試其解析主流網站實際使用的URL時的性能。但是公佈這樣一個基準測試存在問題,因為URL中通常會包含敏感的個人身份信息,比如<code>https://example.org/?user_id=57483/<code>。在上述基準測試中,Trunk WebKit URL解析器比Safari 10 中的WebKit快20%。在實踐中,大多數時間花費在解析最長且包含信息最多的 URL的路徑和查詢,以及最需要編碼的域名。由於不同瀏覽器對於URL的處理行為大相徑庭,因此不同瀏覽器之間無法進行完全相同的URL解析速度測試。

總結

瀏覽器及其他地方使用的URL工具應該變得更一致、更安全。網站開發者則需要適應這樣的改變。如有任何問題,請與我聯繫,我們可以討論並解決問題。如果這些改變造成了原有程序出現問題,我們不應抱怨,而更應該著眼於互聯網的未來。每個人都將會受益於一致的網絡標準。

若有任何問題或建議請聯繫本文作者 @alexfchr,或Jonathan Davis, Apple’s Web Technologies Evangelist, at @jonathandavis or [email protected].

英文原文:https://webkit.org/blog/7086/url-parsing-in-webkit/
譯者:panlining


分享到:


相關文章: