HTTP 1.0和1.1 協議基礎概念複習

HTTP 協議基礎概念複習

回顧一下發現本科學的東西都忘了,網絡好像是那個說髒話的愛爾蘭人教的,總之腦子裏全是烤羊腿和老雪。這裏重新整理一下。

內容:

  1. 介紹
  2. http在TCP/IP協議棧中的位置
  3. HTTP的請求響應模型
  4. 工作流程
  5. 抓包
  6. Http 報文格式
  7. Http/1.0 和Http/1.1 的區別
  8. Cookie和Session
  9. 緩存的實現原理
  10. 斷點續傳和多線程下載的實現原理
  11. HTTPS 原理簡介

1. 介紹

HTTP是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫。它的發展是萬維網協會(World Wide Web Consortium)和Internet工作小組IETF(Internet Engineering Task Force)合作的結果,(他們)最終發佈了一系列的RFC,RFC 1945定義了HTTP/1.0版本。其中最著名的就是RFC 2616。RFC (Request for Comments) 2616定義了今天普遍使用的一個版本——HTTP 1.1。 http/1.0 和 http/1.1 還是有很明顯的區別的。後面再說

HTTP協議(HyperText Transfer Protocol,超文本傳輸協議)是用於從WWW服務器傳輸超文本到本地瀏覽器的傳送協議。它可以使瀏覽器更加高效,使網絡傳輸減少。它不僅保證計算機正確快速地傳輸超文本文檔,還確定傳輸文檔中的哪一部分,以及哪部分內容首先顯示(如文本先於圖形)等。(和網頁的內容的表現形式有關,圖片是通過url來定位的,文字先加載,圖片再一次http請求,加載得到之後再加載)

HTTP是一個應用層協議,由請求和響應構成,是一個標準的客戶端服務器模型。HTTP是一個無狀態的協議。(<mark>無狀態指的是狀態無記錄,通過session或者cooki這種東西來實現有狀態</mark>)

2. http在TCP/IP協議棧中的位置

HTTP協議通常承載於TCP協議之上,有時也承載於TLS或SSL協議層之上,這個時候,就成了我們常說的HTTPS。如下圖所示:

https

<mark>默認HTTP的端口號爲80,HTTPS的端口號爲443</mark>.

3. HTTP的請求響應模型

HTTP協議永遠都是客戶端發起請求,服務器回送響應。見下圖:

http-client-server-model

這樣就限制了使用HTTP協議,無法實現在客戶端沒有發起請求的時候,服務器將消息推送給客戶端。

HTTP協議是一個無狀態的協議,同一個客戶端的這次請求和上次請求是沒有對應關係。

4. 工作流程

一次HTTP操作稱爲一個事務,其工作過程可分爲四步:

  1. 首先客戶機與服務器需要建立連接。只要單擊某個超級鏈接,HTTP的工作開始。
  2. 建立連接後,客戶機發送一個請求給服務器,請求方式的格式爲:統一資源標識符(URL)、協議版本號,後邊是MIME (Multipurpose Internet Mail Extensions) 信息, 包括請求修飾符、客戶機信息和可能的內容。
  3. 服務器接到請求後,給予相應的響應信息,其格式爲一個狀態行,包括信息的協議版本號、一個成功或錯誤的代碼,後邊是MIME信息, 包括服務器信息、實體信息和可能的內容。
  4. 客戶端接收服務器所返回的信息通過瀏覽器顯示在用戶的顯示屏上,然後客戶機與服務器斷開連接。
    如果在以上過程中的某一步出現錯誤,那麼產生錯誤的信息將返回到客戶端,有顯示屏輸出。對於用戶來說,這些過程是由HTTP自己完成的,用戶只要用鼠標點擊,等待信息顯示就可以了。

5. 抓包

Mac 使用 Charles 等

Windows 使用 Wireshark 等

6. Http 報文格式

6.1 請求報文

一個HTTP請求報文由請求行(request line)請求頭部(header)空行請求數據4個部分組成,下圖給出了請求報文的一般格式。

https

 

  • 請求行 請求行分爲三個部分:請求方法、請求地址 和 協議版本.

    請求方法:
    HTTP/1.1 定義的請求方法有8種:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE。
    最常的兩種GET和POST,如果是RESTful接口的話一般會用到GET、POST、DELETE、PUT。HTTP/1.0 只定義了三種 GET, HEAD, POST

    請求地址:
    URL:統一資源定位符,是一種自願位置的抽象唯一識別方法。
    組成:<協議>://<主機>:<端口>/<路徑>
    端口和路徑有時可以省略(HTTP默認端口號是80)
    如下例:

    https

    協議版本:
    協議版本的格式爲:HTTP/主版本號.次版本號,常用的有HTTP/1.0和HTTP/1.1

  • 請求頭部

    請求頭部爲請求報文添加了一些附加信息,由“名/值”對組成,每行一對,名和值之間使用冒號分隔。
    常見請求頭如下:

    https

    請求頭部的最後會有一個空行,表示請求頭部結束,接下來爲請求數據,這一行非常重要,必不可少。

  • 請求數據

    可選部分,比如GET請求一般就沒有請求數據。

    下面是一個POST方法的請求報文:

POST  /index.php HTTP/1.1    請求行
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2  請求頭
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer:http://localhost/
Content-Length:25
Content-Type:application/x-www-form-urlencoded
  //空行//
username=aa&password=1234  請求數據

6.2 響應報文

HTTP響應報文由狀態行響應頭部空行以及響應數據組成。

https

 

  • 狀態行

    由3部分組成,分別爲:協議版本,狀態碼,狀態碼描述 三個。
    其中協議版本與請求報文一致,狀態碼描述是對狀態碼的簡單描述。

    -狀態碼:
    狀態代碼爲3位數字。

1xx:指示信息——表示請求已接收,繼續處理。

2xx:成功——表示請求已被成功接收、理解、接受。

3xx:重定向——要完成請求必須進行更進一步的操作。

4xx:客戶端錯誤——請求有語法錯誤或請求無法實現。

5xx:服務器端錯誤——服務器未能實現合法的請求。

-協議版本:
協議版本的格式爲:HTTP/主版本號.次版本號,常用的有HTTP/1.0和HTTP/1.1

據兩個例子:

HTTP/1.1 200 OK
HTTP/1.1 200 Connection established
  • 響應頭部

    與請求頭部類似,爲響應報文添加了一些附加信息

    常見響應頭部如下:

    常見響應頭

    請求頭部的最後會有一個空行,表示請求頭部結束,接下來爲請求數據,這一行非常重要,必不可少。

  • 響應數據

    用於存放需要返回給客戶端的數據信息。
    下面是一個響應報文的實例:

HTTP/1.1 200 OK    狀態行
Server: Tengine/2.0.2     響應頭部
Date: Thu, 13 Sep 2018 11:17:28 GMT
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
X-ASEN: SEN-9877428
Cache-Control: no-cache, must-revalidate
Expires: Thu, 01 Jan 1970 00:00:00 GMT
X-Confluence-Request-Time: 1536837448721
X-Seraph-LoginReason: OK
X-AUSERNAME: zhangyu02_sx
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self'
Proxy-Connection: keep-alive
-----空行-----  
<!DOCTYPE html>      響應數據
<html>
   .......  
</html>

6.3 HTTP 首部字段根據實際用途被分爲以下 4 種類型。

通用首部字段(General Header Fields)
請求報文和響應報文兩方都會使用的首部。

請求首部字段(Request Header Fields)
從客戶端向服務器端發送請求報文時使用的首部。補充了請求的附加內容、客戶端信息、響應內容相關優先級等信息。

響應首部字段(Response Header Fields)
從服務器端向客戶端返回響應報文時使用的首部。補充了響應的附加內容,也會要求客戶端附加額外的內容信息。

實體首部字段(Entity Header Fields)
針對請求報文和響應報文的實體部分使用的首部。補充了資源內容更新時間等與實體有關的信息。

  • 通用首部字段

Cache-Control |控制緩存的行爲
Connection |逐跳首部、連接的管理
Date |創建報文的日期時間
Pragma |報文指令
Trailer |報文末端的首部一覽
Transfer-Encoding| 指定報文主體的傳輸編碼方式
Upgrade |升級爲其他協議
Via |代理服務器的相關信息
Warning |錯誤通知

  • 請求首部字段...

  • 響應首部字段...

  • 實體首部字段

    首部字段名 |說明
    ---------|------
    Allow |資源可支持的HTTP方法
    Content-Encoding| 實體主體適用的編碼方式
    Content-Language| 實體主體的自然語言
    Content-Length |實體主體的大小(單位:字節)
    Content-Location| 替代對應資源的URI
    Content-MD5 |實體主體的報文摘要
    Content-Range |實體主體的位置範圍
    Content-Type |實體主體的媒體類型
    Expires |實體主體過期的日期時間
    Last-Modified |資源的最後修改日期時間

7. Http/1.0 和Http/1.1 的區別

7.1 RFC1945定義了HTTP/1.0版本,RFC2616定義了HTTP/1.1版本。

7.2 建立連接方面

HTTP/1.0 每次請求都需要建立新的TCP連接,連接不能複用。HTTP/1.1 新的請求可以在上次請求建立的TCP連接之上發送,連接可以複用。優點是減少重複進行TCP三次握手的開銷,提高效率。

<mark>注意:在同一個TCP連接中,新的請求需要等上次請求收到響應後,才能發送。</mark>

這是因爲,
在http1.1,request和reponse頭中都有可能出現一個connection的頭,此header的含義是當client和server通信時對於長鏈接如何進行處理。

在http1.1中,client和server都是默認對方支持長鏈接的, 如果client使用http1.1協議,但又不希望使用長鏈接,則需要在header中指明connection的值爲close;如果server方也不想支持長鏈接,則在response中也需要明確說明connection的值爲close。不論request還是response的header中包含了值爲close的connection,都表明當前正在使用的tcp鏈接在當前請求處理完畢後會被斷掉。以後client再進行新的請求時就必須創建新的tcp鏈接了。

7.3 Host域

HTTP1.1在Request消息頭裏頭多了一個Host域, HTTP1.0則沒有這個域。

Eg.:

    GET /pub/WWW/TheProject.html HTTP/1.1
    Host: www.w3.org

可能HTTP1.0的時候認爲,建立TCP連接的時候已經指定了IP地址,這個IP地址上只有一個host。

7.4 日期時間戳

(接收方向)

無論是HTTP1.0還是HTTP1.1,都要能解析下面三種date/time stamp:

Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 

Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036

Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format

(發送方向)

HTTP1.0要求不能生成第三種asctime格式的date/time stamp;

HTTP1.1則要求只生成RFC 1123(第一種)格式的date/time stamp。

7.5 狀態響應碼

狀態響應碼100 (Continue) 狀態代碼的使用,允許客戶端在發request消息body之前先用request header試探一下server,看server要不要接收request body,再決定要不要發request body。
客戶端在Request頭部中包含

Expect: 100-continue

Server看到之後呢如果回100 (Continue) 這個狀態代碼,客戶端就繼續發request body。這個是HTTP1.1纔有的。
另外在HTTP/1.1中還增加了101、203、205等等性狀態響應碼

7.6 請求方法,上面提到過

HTTP1.1增加了OPTIONS, PUT, DELETE, TRACE, CONNECT這些Request方法

8. Cookie和Session

Cookie和Session都爲了用來保存狀態信息,都是保存客戶端狀態的機制,它們都是爲了解決HTTP無狀態的問題而所做的努力。

Session可以用Cookie來實現,也可以用URL回寫的機制來實現。用Cookie來實現的Session可以認爲是對Cookie更高級的應用。

8.1 兩者比較

Cookie和Session有以下明顯的不同點:

1)Cookie將狀態保存在客戶端,Session將狀態 保存在服務器端;

2)Cookies是服務器在 本地機器上存儲的小段文本 並隨每一個請求發送至同一個服務器。

Cookie最早在RFC2109中實現,後續RFC2965做了增強。網絡服務器用HTTP頭向客戶端發送cookies,在客戶終端,瀏覽器解析這些cookies並將它們保存爲一個本地文件,它會自動將同一服務器的任何請求縛上這些cookies。Session並沒有在HTTP的協議中定義;

3)Session是針對每一個用戶的,變量的值保存在服務器上,用一個sessionID來區分是哪個用戶session變量,這個值是通過用戶的瀏覽器在訪問的時候返回給服務器,當客戶禁用cookie時,這個值也可能設置爲由get來返回給服務器;

4)就安全性來說:當你訪問一個使用session 的站點,同時在自己機子上建立一個cookie,建議在服務器端的SESSION機制更安全些.因爲它不會任意讀取客戶存儲的信息。

8.2 Session機制

Session機制是一種服務器端的機制,服務器使用一種類似於散列表的結構(也可能就是使用散列表)來保存信息。

當程序需要爲某個客戶端的請求創建一個session的時候,服務器首先檢查這個客戶端的請求裏是否已包含了一個session標識 - 稱爲 session id,如果已包含一個session id, 則說明以前已經爲此客戶端創建過session,服務器就按照session id 把這個 session 檢索出來使用(如果檢索不到,可能會新建一個),如果客戶端請求不包含session id,則爲此客戶端創建一個session並且生成一個與此session相關聯的session id,session id的值應該是一個既不會重複,又不容易被找到規律以仿造的字符串,這個 session id將被在本次響應中返回給客戶端保存。

8.3 Session的實現方式

  • 使用Cookie來實現

    服務器給每個Session分配一個唯一的JSESSIONID,並通過Cookie發送給客戶端。
    當客戶端發起新的請求的時候,將在Cookie頭中攜帶這個JSESSIONID。這樣服務器能夠找到這個客戶端對應的Session。
    流程如下圖所示:

    使用cooki實現session

  • 使用URL回顯來實現

    URL回寫是指服務器在發送給瀏覽器頁面的所有鏈接中都攜帶JSESSIONID的參數,這樣客戶端點擊任何一個鏈接都會把JSESSIONID帶會服務器。
    如果直接在瀏覽器輸入服務端資源的url來請求該資源,那麼Session是匹配不到的。
    Tomcat對Session的實現,是一開始同時使用Cookie和URL回寫機制,如果發現客戶端支持Cookie,就繼續使用Cookie,停止使用URL回寫。如果發現Cookie被禁用,就一直使用URL回寫。jsp開發處理到Session的時候,對頁面中的鏈接最好使用response.encodeURL(),原因你懂的。

8.4 與Cookie相關的HTTP擴展頭

    1. Cookie:客戶端將服務器設置的Cookie返回到服務器;
    1. Set-Cookie:服務器向客戶端設置Cookie;
    1. Cookie2 (RFC2965)):客戶端指示服務器支持Cookie的版本;
    1. Set-Cookie2 (RFC2965):服務器向客戶端設置Cookie。

8.5 Cookie的流程

服務器在響應消息中用Set-Cookie頭將Cookie的內容回送給客戶端,客戶端在新的請求中將相同的內容攜帶在Cookie頭中發送給服務器。從而實現會話的保持。
流程如下圖所示:

cooki的流程

9. 緩存的實現原理

9.1 緩存的優點

  • 減少相應延遲:因爲請求從緩存服務器(離客戶端更近)而不是源服務器被相應,這個過程耗時更少,讓web服務器看上去相應更快。
  • 減少網絡帶寬消耗:當副本被重用時會減低客戶端的帶寬消耗;客戶可以節省帶寬費用,控制帶寬的需求的增長並更易於管理。

9.2 與緩存相關的HTTP擴展消息頭

  • Expires:指示響應內容過期的時間,格林威治時間GMT
  • Cache-Control:更細緻的控制緩存的內容
  • Last-Modified:響應中資源最後一次修改的時間
  • ETag:響應中資源的校驗值,在服務器上某個時段是唯一標識的。
  • Date:服務器的時間
  • If-Modified-Since:客戶端存取的該資源最後一次修改的時間,同Last-Modified。
  • If-None-Match:客戶端存取的該資源的檢驗值,同ETag。

9.3 客戶端緩存生效的常見流程

服務器收到請求時,會在200OK中回送該資源的Last-Modified和ETag頭,客戶端將該資源保存在cache中,並記錄這兩個屬性。當客戶端需要發送相同的請求時,會在請求中攜帶If-Modified-Since和If-None-Match兩個頭。兩個頭的值分別是響應中Last-Modified和ETag頭的值。服務器通過這兩個頭判斷本地資源未發生變化,客戶端不需要重新下載,返回304響應。常見流程如下圖所示:

客戶端緩存生效常見流程

9.4 緩存機制

HTTP/1.1中緩存的目的是爲了在很多情況下減少發送請求,同時在許多情況下可以不需要發送完整響應。前者減少了網絡迴路的數量;HTTP利用一個“過期(expiration)”機制來爲此目的。後者減少了網絡應用的帶寬;HTTP用“驗證(validation)”機制來爲此目的。

HTTP定義了3種緩存機制:

1)Freshness:允許一個迴應消息可以在源服務器不被重新檢查,並且可以由服務器和客戶端來控制。例如,Expires迴應頭給了一個文檔不可用的時間。Cache-Control中的max-age標識指明瞭緩存的最長時間;

2)Validation:用來檢查以一個緩存的迴應是否仍然可用。例如,如果一個迴應有一個Last-Modified迴應頭,緩存能夠使用If-Modified-Since來判斷是否已改變,以便判斷根據情況發送請求;

3)Invalidation: 在另一個請求通過緩存的時候,常常有一個副作用。例如,如果一個URL關聯到一個緩存迴應,但是其後跟着POST、PUT和DELETE的請求的話,緩存就會過期。

10 斷點續傳和多線程下載的實現原理

  • HTTP協議的GET方法,支持只請求某個資源的某一部分;
  • 206 Partial Content 部分內容響應;
  • Range 請求的資源範圍;
  • Content-Range 響應的資源範圍;
  • 在連接斷開重連時,客戶端只請求該資源未下載的部分,而不是重新請求整個資源,來實現斷點續傳。

分塊請求資源實例:

E.g.1:Range: bytes=306302- :請求這個資源從306302個字節到末尾的部分;

E.g.2:Content-Range: bytes 306302-604047/604048: 響應中指示攜帶的是該資源的第306302-604047的字節,該資源共604048個字節;

客戶端通過併發的請求相同資源的不同片段,來實現對某個資源的併發分塊下載。從而達到快速下載的目的。目前流行的FlashGet和迅雷基本都是這個原理。

多線程下載的原理:

  • 下載工具開啓多個發出HTTP請求的線程;
  • 每個http請求只請求資源文件的一部分:Content-Range: bytes 20000-40000/47000;
  • 合併每個線程下載的文件。

11 HTTPS 原理簡介

  1. 客戶端發起HTTPS請求

    這個沒什麼好說的,就是用戶在瀏覽器裏輸入一個https網址,然後連接到server的443端口。

  2. 服務端的配置

    採用HTTPS協議的服務器必須要有一套數字證書,可以自己製作,也可以向組織申請。區別就是自己頒發的證書需要客戶端驗證通過,纔可以繼續訪問,而使用受信任的公司申請的證書則不會彈出提示頁面(startssl就是個不錯的選擇,有1年的免費服務)。這套證書其實就是一對公鑰和私鑰。如果對公鑰和私鑰不太理解,可以想象成一把鑰匙和一個鎖頭,只是全世界只有你一個人有這把鑰匙,你可以把鎖頭給別人,別人可以用這個鎖把重要的東西鎖起來,然後發給你,因爲只有你一個人有這把鑰匙,所以只有你才能看到被這把鎖鎖起來的東西。

  3. 傳送證書

    這個證書其實就是公鑰,只是包含了很多信息,如證書的頒發機構,過期時間等等。

  4. 客戶端解析證書

    這部分工作是有客戶端的TLS來完成的,首先會驗證公鑰是否有效,比如頒發機構,過期時間等等,如果發現異常,則會彈出一個警告框,提示證書存在問題。如果證書沒有問題,那麼就生成一個隨即值。然後用證書對該隨機值進行加密。就好像上面說的,把隨機值用鎖頭鎖起來,這樣除非有鑰匙,不然看不到被鎖住的內容。

  5. 傳送加密信息

    這部分傳送的是用證書加密後的隨機值,目的就是讓服務端得到這個隨機值,以後客戶端和服務端的通信就可以通過這個隨機值來進行加密解密了。

  6. 服務端加密信息

    服務端用私鑰解密後,得到了客戶端傳過來的隨機值(私鑰),然後把內容通過該值進行對稱加密。所謂對稱加密就是,將信息和私鑰通過某種算法混合在一起,這樣除非知道私鑰,不然無法獲取內容,而正好客戶端和服務端都知道這個私鑰,所以只要加密算法夠彪悍,私鑰夠複雜,數據就夠安全。

  7. 傳輸加密後的信息

    這部分信息是服務段用私鑰加密後的信息,可以在客戶端被還原

  8. 客戶端解密信息

    客戶端用之前生成的私鑰解密服務段傳過來的信息,於是獲取瞭解密後的內容。

    給一張圖:

    https過程

     

整個過程第三方即使監聽到了數據,也束手無策。


微信掃一掃

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