Web代理(Web proxy)服務器是網絡的中間實體。代理位於客戶端和服務器之間,扮演"中間人"的角色,在各端點之間來回傳送HTTP報文。Web上的代理服務器是表明客戶端完成事務處理的中間人。若是沒有Web代理,Web客戶端就要直接與Web服務器進行對話。有了Web代理,客戶端就能夠與代理進行對話,而後由代理表明客戶端與服務器進行交流。客戶端仍然會完成對事務的處理,但它是經過代理服務器提供的優質服務來實現的。HTTP的代理服務器既是Web服務器又是Web客戶端。Web客戶端會向代理髮送請求報文,代理服務器必須像Web服務器同樣,正確地處理請求和鏈接,而後返回響應。同時,代理自身要向服務器發送請求,這樣,其行爲就必須像正確的Web客戶端同樣,要發送請求並接收響應。若是要建立本身的Web代理,就要認真地遵循爲Web客戶端和Web服務器制定的規則。
算法
代理服務器能夠是某個客戶端專用的,也能夠是不少客戶端共享的。單個客戶端專用的代理被稱爲私有代理。衆多客戶端共享的代理被稱爲公共代理。
數據庫
嚴格來講,代理鏈接的是兩個或多個使用相同協議的應用程序,而網關鏈接的則是兩個或多個使用不一樣協議的端點。網關扮演的是"協議轉換器"的角色,即便客戶端和服務器使用的是不一樣的協議,客戶端也能夠經過它完成與服務器之間的事務處理。實際上,代理和網關之間的區別很模糊。因爲瀏覽器和服務器實現的是不一樣版本的HTTP,代理也常常要作一些協議轉換工做。而商業化的代理服務器也會實現網關的功能來支持SSL安全協議、SOCKS防火牆、FTP訪問,以及基於Web的應用程序。
瀏覽器
代理服務器能夠實現各類時髦且有用的功能。它們能夠改善安全性,提升性能,節省費用。代理服務器能夠看到並接觸到全部流過的HTTP流量,因此代理能夠監視流量並對其進行修改,以實現不少有用的增值Web服務。
緩存
匿名者:匿名者代理會主動從HTTP報文中刪除身份特性(好比客戶端IP地址、From首部、Referer首部、cookie、URI的會話 ID),從而提供高度的私密性和匿名性。安全
能夠根據其目標用途,將代理放在任意位置。
服務器
能夠經過代理層次結構(proxy hierarchy)將代理級聯起來。在代理的層次結構中,會將報文從一個代理傳給另外一個代理,直到最終抵達原始服務器爲止(而後經過代理傳回給客戶端)。代理層次結構中的代理服務器被賦予了父(parent)和子(child)的關係。下一個入口(inbound)代理(靠近服務器)被稱爲父代理,下一個出口(outbound)代理(靠近客戶端)被稱爲子代理。
cookie
代理服務器能夠根據衆多因素,將報文轉發給一個不斷變化的代理服務器和原始服務器集。訪問代理會根據不一樣的狀況將報文轉發給父代理或原始服務器。
網絡
客戶端一般會直接與Web服務器進行通訊,有四種常見方式可使客戶端流量流向代理。
app
全部現代的Web瀏覽器都容許用戶對代理的使用進行配置。實際上,不少瀏覽器都提供了多種配置代理的方式,其中包括如下幾種。
負載均衡
PAC文件是一些小型的JavaScript程序,能夠在運行過程當中計算代理設置,所以,是一種更動態的代理配置解決方案。訪問每一個文檔時,JavaScript函數都會選擇恰當的代理服務器。要使用PAC文件,就要用JavaScript PAC文件的URI來配置瀏覽器[配置方式與手工配置相似,但要在"automatic configuration"(自動配置)框中提供一個URI]。瀏覽器會從這個URI上獲取PAC文件,並用JavaScript邏輯爲每次訪問計算恰當的代理服務器。PAC文件的後綴一般是".pac",MIME類型一般是"application/x-ns- proxy-autoconfig"。每一個PAC文件都必須定義一個名爲"FindProxyForURL(url,host)"的函數,用來計算訪問URI時使用的適當的代理服務器。
代理自動配置腳本的返回值:
"FindProxyForURL(url,host)"的返回值 | 描述 |
---|---|
DIRECT | 不通過任何代理,直接進行鏈接 |
PROXY host:port | 應該使用指定的代理 |
SOCKS host:port | 應該使用指定的SOCKS服務器 |
實現 WPAD 協議的客戶端須要:
當前的 WPAD 協議規範按順序定義了下列技術:
除了一點以外,Web服務器報文和Web代理報文的語法是同樣的。客戶端向服務器而不是代理髮送請求時,HTTP請求報文中的URI會有所不一樣。客戶端向Web服務器發送請求時,請求行中只包含部分URI(沒有方案、主機或端口)。但當客戶端向代理髮送請求時,請求行中則包含完整的URI。</p>
<p>爲何會有兩種不一樣的請求格式,一種用於代理,另外一種用於服務器呢?在原始的HTTP設計中,客戶端會直接與單個服務器進行對話。不存在虛擬主機,也沒有爲代理制定什麼規則。單個的服務器都知道本身的主機名和端口,因此,爲了不發送冗餘信息,客戶端只需發送部分URI便可,無需發送方案和主機(以及端口)。代理出現以後,使用部分URI就有問題了。代理須要知道目標服務器的名稱,這樣它們才能創建本身與服務器的鏈接。基於代理的網關要知道URI的方案才能鏈接到FTP資源和其餘方案上去。"HTTP/1.0"要求代理請求發送完整的URI,解決了這個問題,但它爲服務器請求保留部分URI的形式(已經有至關多的服務器都改成支持完整URI了)。所以,咱們要將部分URI發送給服務器,將完整URI發送給代理。在顯式地配置客戶端代理設置的狀況下,客戶端就知道要發佈哪一種類型的請求了。
代理"缺乏方案/主機/端口"的問題與虛擬主機Web服務器面臨的問題相同。虛擬主機Web服務器會在不少Web站點間共享同一個物理Web服務器。包含部分URI的請求到達時,虛擬主機Web服務器須要知道目的Web站點的主機名。
儘管它們出現的問題類似,但解決方法卻有所不一樣:
只要客戶端正確地實現了HTTP,它們就會在請求中包含完整的URI,發送給通過顯式配置的代理。這樣解決了部分問題,但還有一個問題:客戶端並不老是知道它是在和代理進行對話,由於有些代理對客戶端多是不可見的。即便沒有將客戶端配置爲使用代理,客戶端的流量也可能會通過替代物或攔截代理。在這兩種狀況下,客戶端都會認爲它在與Web服務器進行對話,不會發送完整的URI。
因爲將流量重定向到代理服務器的方式有所不一樣,通用的代理服務器既應該支持請求報文中的完整URI,也應該支持部分URI。若是是顯式的代理請求,代理就應該使用完整URI,若是是Web服務器請求,就應該使用部分URI和虛擬Host首部。
使用完整和部分URI的規則以下所示。
若是提供的是部分URI,並且沒有Host首部,就要用其餘方法來肯定原始服務器:
代理服務器要在轉發報文時修改請求URI的話,須要特別當心。對URI的微小修改,甚至是看起來無害的修改,均可能給下游服務器帶來一些互操做性問題。尤爲是,如今已知有些代理會在將URI轉發給下一跳節點以前將URI"規範"爲標準格式。有些看起來無害的轉換行爲,好比用顯式的":80"來取代默認的HTTP端口,或者用適當的換碼轉義符來取代非法的保留字符以校訂URI,就可能形成互操做性問題。總之,代理服務器要儘可能寬容一些。它們的目標不是成爲強制實現嚴格協議一致性的"協議警察",由於這樣可能會嚴重破壞以前能正常工做的服務。特別是,HTTP規範禁止通常的攔截代理在轉發URI時重寫其絕對路徑部分。惟一的例外是能夠用"/"來取代空路徑。
根據是否有代理,瀏覽器對請求URI的解析會有所不一樣。沒有代理時,瀏覽器會獲取你輸入的URI,嘗試着尋找相應的IP地址。若是找到了主機名,瀏覽器會嘗試相應的IP地址直到得到成功的鏈接爲止。可是,若是沒有找到主機,不少瀏覽器都會嘗試着提供某種主機名自動「擴展」機制,以防用戶輸入的是主機「簡短」的縮寫形式。
如今,在將Web請求從客戶端傳送到服務器的路徑上,通過兩個或多個代理是很常見的。好比,出於安全和節省費用的考慮,不少公司都會用緩存代理服務器來訪問因特網,並且不少大型ISP都會使用代理緩存來提升性能並實現各類特性。如今,有至關比例的Web請求都是經過代理轉發的。同時,出於性能緣由,把內容複製到遍及全球的替代物緩存庫中的情形也愈來愈常見了。代理是由不一樣廠商開發的。它們有不一樣的特性和缺陷,由各類不一樣的組織負責管理。隨着代理的逐漸流行,咱們要可以追蹤通過代理的報文流,以檢測出各類問題,其重要性就跟追蹤通過不一樣交換機和路由器傳輸的IP分組流同樣。
Via首部字段列出了與報文途經的每一箇中間節點(代理或網關)有關的信息。報文每通過一個節點,都必須將這個中間節點添加到Via列表的末尾。Via首部字段用於記錄報文的轉發,診斷報文循環,標識請求/響應鏈上全部發送者的協議能力。代理也能夠用Via首部來檢測網絡中的路由循環。代理應該在發送一條請求以前,在Via首部插入一個與其自身有關的獨特字符串,並在輸入的請求中查找這個字符串,以檢測網絡中是否存在路由循環。
Via的語法:Via首部字段包含一個由逗號分隔的路標(waypoint)。每一個路標都表示一個獨立的代理服務器或網關,且包含與那個中間節點的協議和地址有關的信息。
每一個Via路標中最多包含4個組件:一個可選的協議名(默認爲HTTP)、一個必選的協議版本、一個必選的節點名和一個可選的描述性註釋。
代理服務器能夠在轉發報文時對其進行修改。能夠添加、修改或刪除首部,也能夠將主體部分轉換成不一樣的格式。代理變得愈來愈複雜,開發代理產品的廠商也愈來愈多,互操做性問題也開始逐漸顯現。爲了便於對代理網絡進行診斷,咱們須要有一種便捷的方式來觀察在經過HTTP代理網絡逐跳轉發報文的過程當中,報文是怎樣變化的。經過"HTTP/1.1"的TRACE方法,用戶能夠跟蹤經代理鏈傳輸的請求報文,觀察報文通過了哪些代理,以及每一個代理是如何對請求報文進行修改的。TRACE對代理流的調試很是有用。當TRACE請求到達目的服務器時,整條請求報文都會被封裝在一條HTTP響應的主體中回送給發送端。當TRACE響應到達時,客戶端能夠檢查服務器收到的確切報文,以及它所通過的代理列表(在Via首部)。TRACE響應的Content-Type爲message/http,狀態爲"200 OK"。</p>
<p>Max-Forwards:一般,無論中間插入了多少代理,TRACE報文都會沿着整條路徑傳到目的服務器上。可使用Max-Forwards(最大轉發次數)首部來限制TRACE和OPTIONS請求所通過的代理跳數,在測試代理鏈是不是在無限循環中轉發報文,或者查看鏈中特定代理服務器的效果時,它是頗有用的。Max-Forwards也能夠限制OPTIONS報文的轉發。Max-Forwards請求首部字段包含了一個整數,用來講明這條請求報文還能夠被轉發的次數。若是Max-Forwards的值爲零(Max-Forwards:0),那麼即便接收者不是原始服務器,它也必須將TRACE報文回送給客戶端,而不該該繼續轉發。若是收到的Max-Forwards值大於零,轉發的報文中就必須包含一個更新了的Max-Forwards字段,其值會被減一。全部的代理和網關都應該支持Max-Forwards。能夠用Max-Forwards來查看在代理鏈的任意一跳上接收到的請求。
代理能夠做爲訪問控制設備使用。HTTP定義了一種名爲代理認證(proxy authentication)的機制,這種機制能夠阻止對內容的請求,直到用戶向代理提供了有效的訪問權限證書爲止。若傳輸鏈路中有多個代理,且每一個代理都要進行認證時,代理認證一般沒法很好地工做。
客戶端、服務器和代理是由不一樣廠商構建的,實現的是不一樣版本的HTTP規範。它們支持的特性各不相同,也存在着不一樣的問題。代理服務器位於客戶端和服務器設備之間,這些設備實現的協議可能有所不一樣,可能存在着很棘手的問題。
代理服務器可能沒法理解全部經其傳輸的首部字段。有些首部可能比代理自身還要新;其餘首部多是特定應用程序獨有的定製首部。代理必須對不認識的首部字段進行轉發,並且必須維持同名首部字段的相對順序。相似地,若是代理不熟悉某個方法,那麼只要可能,就應該嘗試着將報文轉發到下一跳節點上去。
經過OPTIONS方法,客戶端(或代理)能夠發現Web服務器或者其上某個特定資源所支持的功能(好比,它們所支持的方法)。經過使用OPTIONS,客戶端能夠在與服務器進行交互以前,肯定服務器的能力,這樣它就能夠更方便地與具有不一樣特性的代理和服務器進行互操做了。若是OPTIONS請求的URI是個"*"(星號),請求的就是整個服務器所支持的功能。若是URI是個實際資源地址,OPTIONS請求就是在查詢那個特定資源的可用特性。若是成功,OPTIONS方法就會返回一個包含了各類首部字段的"200 OK"響應,這些 字段描述了服務器所支持的,或資源可用的各類可選特性。"HTTP/1.1"在響應中惟一指定的首部字段是Allow首部,這個首部用於描述服務器所支持的各類方法(或者服務器上的特定資源)。OPTIONS容許在可選的響應主體中包含更多的信息,但並無對這種用法進行定義。
Allow實體首部字段列出了請求URI標識的資源所支持的方法列表,若是請求URI爲"*"(星號)的話,列出的就是整個服務器所支持的方法列表。能夠將Allow首部做爲請求首部,建議在新的資源上支持某些方法。並不要求服務器支持這些方法,但應該在相應的響應中包含一個Allow首部,列出它實際支持的方法。由於客戶端可能已經經過其餘途徑與原始服務器進行了交流,因此即便代理沒法理解指定的全部方法,也不能對Allow首部字段進行修改。