本文已於 2019.01.05 發佈至 www.jianshu.com/p/97519d170…算法
據我我的瞭解,不少工做好久的開發者對HTTP的理解很是的片面甚至有些誤差,常常把HTTP和TCP混淆,因此我認爲我有必要將這兩個概念進行澄清,前兩篇文章咱們描述了傳輸層協議TCP、UDP以及對應的Socket編程,從這篇文章咱們開始轉戰應用層,我將會連續推出關於應用層的幾篇文章,包括應用層協議HTTP、HTTPS以及基於HTTP的網絡請求框架的使用和源碼解析。編程
HTTP全稱是HyperText Transfer Protocol,譯成中文是超文本傳輸協議
,當時理解這個命名的時候我是有點崩潰的,這也是爲何不少開發者將TCP和HTTP進行混淆的緣由,HTTP不是應用層協議嗎?幹嗎說它是超文本傳輸
協議,其實我我的認爲這個命名是真的有點誤導人,簡單說它就是基於TCP的應用層協議,HTTP負責把數據按照協議進行封裝而後由TCP進行傳輸,HTTP嚴謹的譯名應該是超文本轉移協議
,命名就是這麼回事,那HTTP的做用究竟是什麼呢?前面咱們也說了,HTTP是徹底基於TCP進行傳輸的,TCP是面向字節流的傳輸協議,接收方收到的全是字節,因此說若是發送方和接受方不約定一套協議解析這些字節,即便接收方收到數據那麼他也看不懂,而HTTP就屬於雙方約定的這種協議,Client和Server必須同時嚴格遵照。 我這描述的夠白話了吧 (゜-゜),相信聰明的你確定能理解HTTP存在的意義以及與TCP的區別,另外,應用層協議並不僅有HTTP,好有不少,好比:FTP、SMTP等等。緩存
HTTP報文分爲請求報文
和響應報文
安全
請求報文可分爲三大部分,分別是報文首部、空行、報文主體。而報文首部又可細分爲兩部分,分別是請求行、請求頭字段,我繪製了一張草圖來表示HTTP請求報文,如圖1-1 bash
裏面一些專業的詞彙我會在文章後面詳細講解,在此你們只須要了解HTTP報文結構便可服務器
- 請求行:包含三部份內容,請求方法、Uri路徑、HTTP版本
- 請求頭字段:頭字段能夠爲0個或多個
- 空行:換行符(CR+LF),用於區分報文首部和報文主體
- 主體:須要發送的數據
報文第一行是請求行,位於空行和請求行之間爲請求頭字段,空行後面爲請求主體。 請求報文實際結構如圖1-2,該圖摘自這篇文章 cookie
請求報文也分爲三大部分,分別是報文首部、空行、報文主體。而報文首部也可細分爲兩部分,分別是狀態行、響應頭字段,結構和請求報文基本相同因此就再也不用圖來表示(畫圖是真的費勁- -)。網絡
- 狀態行:包含三部份內容,HTTP版本、狀態碼、描述信息
- 響應頭字段:頭字段能夠爲0個或多個
- 空行:換行符(CR+LF),用於區分報文首部和報文主體
- 主體:須要響應的數據
報文第一行是狀態行,位於空行和狀態行之間爲響應頭字段,空行後面爲響應主體框架
上滿咱們講到HTTP報文分爲首部和實體,首部又可分爲請求/狀態行和頭字段,請求/狀態行就是一些HTTP版本請求方法之類的只佔用一行,而頭字段能夠爲0個或多個。 頭字段由關鍵字/值對組成,每行一對,關鍵字和值用英文冒號「:」分隔,是用來封裝請求或響應一些基本信息,下滿我列舉一些比較常見的頭字段:ui
Accept:客戶端可接受的MIME類型。 Accept-Charset:客戶端可接受的字符集。 Accept-Encoding:客戶端可以進行解碼的數據編碼方式,好比gzip。 Accept-Language:客戶端所但願的語言種類,當服務器可以提供一種以上的語言版本時要用到。 Authorization:受權信息,一般出如今對服務器發送的WWW-Authenticate頭的應答中。 Connection:容許客戶端和服務器指定請求/響應鏈接有關的選項。 Content-Length:表示請求消息正文的長度。 Cookie:設置cookie,這是最重要的請求頭信息之一 From:請求發送者的email地址,由一些特殊的客戶端程序使用
HTTP頭字段有不少個,就不一一列舉,感興趣的同窗可自行了解。同時頭字段也可分爲請求頭字段、響應頭字段、通用頭字段、實體頭字段。
狀態碼是客戶端對服務器進行請求時,服務器用來描述的一個請求結果。經過對狀態碼的分析,客戶端能夠獲取到請求的一個情況。
狀態碼分類:
- 1xx:類別爲Informational(信息性狀態碼),表明請求正在處理
- 2xx:表明請求成功,最多見的就是200 OK
- 3xx:表明重定向,提示客戶端請求耳朵URI已發生變化
- 4xx:表明客戶端錯誤,提示客戶端錯誤發生在你這
- 5xx:服務器錯誤,提示客戶端錯誤發生在服務器
狀態碼這一塊沒啥難的,基本不用思考就能理解,因此我就不挨個將狀態碼列舉講解,感興趣的同窗可自行了解。
HTTP每次請求都要創建一個鏈接同時請求結束後會斷開鏈接,若是連續請求同一資源,須要屢次創建和斷開鏈接,這樣實際上是不必的,因此HTTP也具有緩存功能,必定程度上提高了請求效率。 HTTP緩存能夠大體可分爲兩種:強制緩存和對比緩存
Expires
:客戶端第一次進行請求的時候服務器會返回一個頭字段爲Expires
的頭信息,表明有效日期,客戶端要對該日期進行保存,下一次請求該資源的時候會判斷當前日期是否超過有效日期,沒有就直接從緩存中獲取。超過就再次從服務器獲取,Expires
日期格式以下:
Expires:Thu, 16 Mar 2018 12:31 GMT
複製代碼
Cache-Control
:經過Expires
進行緩存是存在安全隱患,若是客戶端與服務器日期不一致就可能出現BUG,因此在HTTP1.1後推出了另外一種緩存策略Cache-Control
來代替Expires
。Cache-Control
有以下幾種取值:
private:客戶端能夠緩存,爲默認取值。 public:客戶端和代理服務器均可以緩存。 max-age:xxx:緩存內容將在xxx秒後失效,指定了age後默認爲private。 no-cache:使用對比緩存來驗證緩存數據。 no-store:不進行任何緩存,
Cache-Control
返回格式以下:
Cache-Control: public ,max-age=31536000
複製代碼
在HTTP1.1以前,Expires
和Cache-Control
同時存在時Expires
會覆蓋掉Cache-Control
,而在HTTP1.1以後正好與之相反
與強制緩存不一樣,對比緩存經過服務器來決定是否須要緩存,也就是說須要對服務器進行請求,在這有的同窗可能會有疑問:"你都對服務器進行請求了,緩存還有意義嗎?",是這樣的,若是服務器判斷緩存有效只返回一個響應首部不返回響應體,這就比如我背10塊磚頭上2樓跟背100塊磚頭上2樓用的時間確定不同。下滿咱們來看一下對比緩存的具體流程: Last-Modified/If-Modified-Since
:
- Last-Modified:客戶端在進行第一次請求的時候服務器會返回一個頭字段名稱爲Last-Modified的日期表明服務器對該資源最後修改時間,客戶端須要對該日期進行保存。
- If-Modified-Since:客戶端在以後的請求中會在請求頭中加入頭字段If-Modified-Since,其內容爲服務器返回的Last-Modified,服務器收到後會判斷緩存是否有效,若是有效返回304告訴客戶端從本身本地緩存讀取數據,不然返回200並攜帶新的響應體同時更新Last-Modified,客戶端收到響應後從新保存Last-Modified和數據。
Etag/If-None-Match
:
Etag是資源的一個標識,當資源修改後Etag值會改變,Etag是由服務器生成,
Etag/If-None-Match
判斷過程和Last-Modified/If-Modified-Since
基本一致,惟一區別是緩存有效即服務器返回304時前者會在響應頭中加入Etag
,然後者不會再響應頭中加入Last-Modified
.
Last-Modified/If-Modified-Since
和 Etag/If-None-Match
判斷方式基本類似那麼兩者同時存在的意義是什麼呢?大概有三點:
Last-Modified/If-Modified-Since
時間單位是精確到秒的,因此沒法保證精度在秒以內的的正確性。通常來講對比緩存要配合強制緩存使用,Expires
和Cache-Control
優先級最高,其次是Etag/If-None-Match
,最後是Last-Modified/If-Modified-Since
,下面我來用一張圖來表示經過對比緩存配合強制緩存實現HTTP緩存的流程,如圖1-5
畫圖真的是能要了個人親命,該圖摘自這篇文章
HTTPS全稱爲Hyper Text Transfer Protocol over Secure Socket Layer(HTTP安全套接字),HTTPS使HTTP傳輸變得更加安全,下面我羅列幾點HTTP存在的安全隱患:
- 竊取:HTTP爲明文傳輸,假如HTTP中存在銀行卡及密碼,不法分子很容易就能竊取
- 假裝:假如客戶端正在與服務器進行通訊,不法分子能夠從中間假裝成客戶端與服務器通訊。
- 篡改:假如正在進行網絡轉帳,不法分子能夠將收錢的銀行卡號篡改成本身的銀行卡號。
以上三點就是HTTP面臨的主要威脅,而經過HTTPS基本能夠避免這三種隱患,HTTPS是如何作到安全傳輸呢?網絡結構自己就很複雜,因此想作到數據不被中間者攔截是不可能的,可是能夠對數據進行加密,即便中間者攔截到數據他也看不懂,因此HTTPS是經過對數據各類加密來實現安全傳輸。
在描述對稱加密前我先普及一下加密算法和祕鑰的概念,由於有些同窗對加密算法和祕鑰的概念容易混淆,打個比方,加密算法至關於鎖內的構造,而祕鑰就至關於鑰匙,代碼中的體現:
public String encryption(String content0,int key){
...
...
...
return content1;
}
複製代碼
encryption(String content0,int key)就是加密算法,content0是準備加密的內容,key就是祕鑰,算法經過key科技將content0加密成別人看不懂的content1.,解密同理。
對稱加密:
採用單鑰密碼系統的加密方法,同一個密鑰能夠同時用做信息的加密和解密,這種加密方法稱爲對稱加密,也稱爲單密鑰加密。
簡單說就是客戶的和服務器共享一套算法和祕鑰,在傳輸數據前經過共享祕鑰將數據進行加密,而後再進行發送,接收方收到數據後經過共享祕鑰對數據進行解析。
優勢:簡單、直接、效率高。 缺點:祕鑰不適合在網絡上傳輸,由於拿到祕鑰後一些算法是可能被pojie(中文的提示我違規不給發~~~)
的,因此每一個客戶端都要有一個惟一的共享祕鑰,而且服務器要保存全部客戶端的共享祕鑰,也增長了服務器的壓力。
咱們來看一下非對稱加密的官方解釋:
非對稱加密算法須要兩個密鑰:公開密鑰(publickey)和私有密鑰(privatekey)。公開密鑰與私有密鑰是一對,若是用公開密鑰對數據進行加密,只有用對應的私有密鑰才能解密;若是用私有密鑰對數據進行加密,那麼只有用對應的公開密鑰才能解密。由於加密和解密使用的是兩個不一樣的密鑰,因此這種算法叫做非對稱加密算法。 非對稱加密算法實現機密信息交換的基本過程是:甲方生成一對密鑰並將其中的一把做爲公用密鑰向其它方公開;獲得該公用密鑰的乙方使用該密鑰對機密信息進行加密後再發送給甲方;甲方再用本身保存的另外一把專用密鑰對加密後的信息進行解密。
優勢:由於存在公鑰和私鑰,祕鑰能夠在網絡上傳輸,因此靈活性較高 缺點:算法複雜度高,因此加密解密耗時較長
對稱加密和非對稱加密都有各自的優缺點,那能不能將兩者優勢相結合來進行一次安全傳輸呢?是能夠的,下面我來講一下對稱加密結合非對稱加密額使用流程:
- 客戶端請求服務器,服務器返回一個公鑰
- 客戶端生成一個對稱加密祕鑰,經過公鑰進行加密傳給服務器
- 服務器收到對稱加密祕鑰經過私鑰進行解密
通過上面的三步服務器和客戶端就能夠肯定一個祕鑰,在此後的傳輸經過該祕鑰進行加解密就能夠保證數據不被竊取。這種加密方式就摒除了對稱加密密鑰不可在網絡傳輸的弊端和非對稱加密加密效率低下的問題,實際場景中基本也是經過該方式對數據進行加密。
在網絡傳輸中經過數字簽名能夠保證數據的完整性,具體流程以下: (假設客戶端和服務器已經完成對稱加密祕鑰的肯定)
- 服務器在發送數據前先對數據進行一次hash運算獲得一個數值,而後經過祕鑰對該數據進行加密
- 客戶端收到數據後對數據進行解密,對數據進行hash運算,而後再對服務器生生地hash值進行解密,最後比較兩個hash值是否相同,若是不相同證實數據在網絡傳輸中被進行了篡改
CA的全稱是Certificate Authority(證書頒發機構),它能夠爲企業頒發數字證書確認這些企業的身份,同時也能夠吊銷數字證書。在HTTPS中須要一個SSL證書,該證書也屬於數字證書的一種由CA進行頒發,內容包括公鑰
+申請者與頒發者信息
+簽名
.
具體的證書驗證過程:
- 客戶端請求服務器
- 服務器將證書和數字簽名經過私鑰加密攜帶着公鑰一同傳遞給客戶端
- 客戶端收到後首先拿着公鑰解密證書,拿着證書去CA機構進行認證是否合法
- 若是證書合法就對證書進行hash運算,再將數字簽名解密,對比兩個hash值,若是一致表明證書沒有被冒充。
另外,進行CA認證通常是要收費的
重頭戲要來了...... SSL全稱爲Secure Sockets Layer(安全套接層),沒錯,它就是HTTPS的核心,換句話說就是HTTPS就是HTTP+SSL,經過SSL能夠實現HTTP安全傳輸,實現原理就是基於上面幾個小結所講的對稱加密、非對稱加密、CA認證,下面我先用一張圖來表明SSL整個流程,如圖2-1:
我用文字敘述一下整個流程:
- 客戶端請求服務器,並攜帶支持的加密算法
- 服務器選定加密算法,將確認的加密算法+公鑰+證書一併返回給客戶端
- 客戶端收到會拿着公鑰去進行CA認證,若是認證成功就生成一個對稱祕鑰用公鑰加密並返回給服務器,不然就視爲服務器爲非法服務器。
- 服務器拿到對稱祕鑰後經過私鑰進行解密並保存,此後客戶端和服務器就能夠經過該祕鑰對數據進行加密傳輸
- 服務器發送數據前須要對數據進行一次hash運算獲得一個hash值,對數據和hash值加密後傳輸給客戶端
- 客戶端收到數據後對數據進行解密,而後對數據進行一次hash運算獲得一個hash值,並解密服務器傳來的hash值,將兩個hash值進行比較,若是不相同可視爲數據中途被篡改
以上就是SSL加密流程,SSL實際是位於應用層和傳輸層之間的,因此SSL並不僅屬於HTTP,它也能夠幫助其餘應用層協議實現安全傳輸。HTTPS內容大概就是這些
本篇文章描述了HTTP和HTTPS,HTTP內容內容相對來講較爲簡單,都是一些概念性的知識,記住就好了,而HTTPS就是在HTTP和TCP之間加入了SSL,經過SSL能夠實現數據安全傳輸,切記,SSL也能夠應用到其餘的應用層協議中。本篇文章對HTTP的描述到此爲止。