http與https代理中的差別及細節

前提:

HTTP/1.1中,默認開啓長鏈接,如客戶端不須要,須要加上請求首部connection:close告知服務器。如服務器不支持長鏈接,則須要加上響應首部connection:close告知客戶端,不然須要加上響應首部connection:keep-alive
HTTP/1.0中,默認不開啓長鏈接,如客戶端須要,須要加上請求首部connection:keep-alive告知服務器。如服務器不支持長鏈接,則須要加上響應首部connection:close告知客戶端,不然須要加上響應首部connection:keep-alive

所謂鏈接並非一個水管鏈接起來,而是人們想象出來的東西。

傳統的短鏈接只是在發送真正的數據包前,加了一個發送握手數據包的過程。而在發送完數據包以後,加了一個揮手數據包的過程。

而長鏈接也只是在發送完數據包後,不着急發送揮手數據包,繼續發送數據包。

請注意,長鏈接是tcp/ip層面的東西,http應用只是根據connection首部去控制tcp/ip層數據包而已,這一點很是重要。

在HTTP中代理要用什麼方式去鏈接server,代理說了算。客戶端能控制的只是本身與代理之間的鏈接。

HTTP代理

首先看普通的CS模型服務器

 

 

而後來看一下中間有代理的tcp

 

有區別的地方我用紅框標出來了,第一個紅框不難理解,先解釋第二個紅框吧

代理服務多種多樣,有聰明的即能完整作到http協議的,也有笨的只能作到一部分http協議的,咱們稱之爲盲中繼。

在http協議中,代理層是不容許轉發connection首部,而盲中繼則會轉發connection首部
若是轉發了connection首部,意味着客戶端能夠控制代理層與server之間的鏈接,讓咱們來看看問題ui

以上圖爲例,盲中繼會將connection首部進行轉發,而且每每在響應和請求時都只支持http1.0
 
帶來的結果是:服務器認爲本身在進行長鏈接,客戶端也認爲本身在進行長鏈接,但代理層根本不知道什麼長鏈接
 
因而代理層認爲server應該關閉鏈接,因而該鏈接掛起。與此同時客戶端認爲本身在進行長鏈接,因而繼續發送http事物給代理,代理層則忽略客戶端發來的任何請求,因而一直在打圈,在超時後,鏈接斷開。
 
這種問題咱們是不想看到的,雖然咱們規定了代理層不容許轉發connection首部,但咱們又不能要求全部人都不使用盲中繼,因而就有了上面的那種解決方案:
 
當代理層理解http事物時,他將請求頭改爲了connection:keep-alive發送給Server。 
 
 
盲中繼則是繼續無腦轉發,而proxy-connection只被服務器當成了一個普通首部而不會影響
 
 
注意上面幾張圖http協議版本號的轉化
 
最後說說第三個框,squid代理中,響應請求使用的是http1.0,發送請求時使用的是http1.1,具體爲何,多是由於個人squid版本比較老形成的,咱們要知道,發請求遠比處理請求簡單的多。聽說squid3.0能夠完美支持http1.1響應了。
 
最後咱們在命令行中證實一下上面的結論。
 
不通過代理 
 
 
使用squid代理

 

HTTPS代理
 
HTTPS只是在http與tcp之間加了一個ssl層,
 
重要的是,在客戶端與代理創建鏈接後,客戶端發往代理的http事務數據是通過加密的,請看下圖
 
注意加密的只是http事務數據,tcp/ip的數據包是不會被加密的,不然路由器理解不了,這一點在以後理解長鏈接短鏈接很是重要。
 
 
在http中經過代理時,應將數據發往誰,是在http首部中定義的,如
而在https中,代理收到的http請求全是加密的,所以代理不知道該發往誰
 
 
因此代理層是這麼處理的:客戶端在發送真正數據包以前,以明文方式告訴代理應將報文發往誰便可,請看下圖。 
 
 
 
也就是說,客戶端先使用connect方法讓代理與server事先創建好一個鏈接,代理收到同一客戶端的後續請求,只需使用事先創建好的鏈接便可。
所以https代理必須支持connect方法
 
最後在命令行中驗證一下 
 
telnet 實現
 
 
因爲代理層收到的都是加密的http報文,所以代理能作到的僅僅是無腦轉發http報文,這種行爲咱們叫作隧道。
 
可是注意只是http報文被加密了,tcp/ip報文依然是明文的,若是連tcp/ip報文都被加密,路由器就沒法理解了,也就沒法傳遞了。
 
而tcp長短鏈接,是在tcp/ip報文中控制的。
 
在http中,client和server能夠根據connection首部來判斷後發送相應的tcp/ip報文。
 
因爲代理沒法理解http行爲,所以也沒法在http層面上根據connection頭來控制長鏈接。
 
所以長短鏈接均由cilent和server的connection控制,這點是與http有決定性不一樣的
 
所以若是一條鏈接發生了斷開請求,另外一端必定會馬上開始斷開,能夠說,https中代理的兩側鏈接是同步的,來看一下。
 
HTTP代理:因爲代理層能夠理解http報文,則可能出現客戶端與代理通訊是短鏈接,而代理與服務器間通訊是長鏈接的狀況。
 
 
HTTPS代理:因爲代理詞只能收到加密的http報文,沒法根據connection首部判斷髮送相應的tcp/ip報文,只能根據client或者server的tcp/ip報文來轉發,所以兩側的鏈接狀態是相同的。 
 
 
最後,一樣因爲https代理是沒法添加http首部的,因此server沒法得到client的ip,而http中是能夠的。
 
over 
相關文章
相關標籤/搜索