概念
簡介
HTTP是一個屬於應用層的面向對象的協議,目前使用最為廣泛的是HTTP1.1協議。當然,許多網站已經開始支持HTTP2.0,HTTP2復雜度高於HTTP1.1,我們先從HTTP1.1說起。
HTTP於1990 年提出,經過幾年的使用與發展,得到不斷地完善和擴展。主要有以下特點:
- 支持客戶/服務器模式
- ASCII碼傳輸,人能直接讀懂
- 參數靈活
- *無連接/無狀態(僅針對HTTP2以前的版本)
兩個重要的網站
主要存儲RFC標准文檔
2.https://zh.wikipedia.org/zh-cn/超文本傳輸協議
這個地址是關於HTTP的詳細介紹
關於RFC
RFC:Request For Comments(RFC),是一系列以編號排定的文件。文件收集了有關互聯網相關信息,以及UNIX和互聯網社區的軟件文件。RFC文件是由Internet Society(ISOC)贊助發行。基本的互聯網通信協議都有在RFC文件內詳細說明。RFC文件還額外加入許多在標准內的論題,例如對於互聯網新開發的協議及發展中所有的記錄。因此幾乎所有的互聯網標准都有收錄在RFC文件之中。(來自百度百科)
RFC2026將標准定義位4個階段:因特網草案、建議標准、草案標准、因特網標准。更多的過程可以看看這些文件:
- RFC 2223 "Instructions to RFC Authors"。
- RFC 2026 "The Internet Standards Process -- Revision 3"。
瀏覽器輸入某個網站地址並按下回車后發生了什么
假設我們在瀏覽器鍾輸入www.abc.com,這個網站的IP地址是11.22.33.44,當回車按下后計算機將做如下工作:
1.首先檢查本地的各種緩存,比如DNS緩存、網站內容緩存等,如果有並且規則表明不需在服務器查找則直接展示內容出來
2.檢查本地的hosts配置,如果輸入的網站域名在本機有配置則加載本機配置的IP地址,比如我們直接配置了一條hosts如下:
11.22.33.44 www.abc.com
那么計算機將會直接向11.22.33.44這個地址發送數據,而不會做DNS查詢。
3.如果本機什么都沒有則進行DNS查詢,DNS和本機的hosts類似,即傳入www.abc.com,然后DNS服務器返回給機器11.22.33.44,這個DNS服務器即我們在TCP/IP里面填寫的服務器地址,它使用的是UDP傳輸。
4.使用IP建立連接,需要記住的是在互聯網世界里面只有IP地址才是唯一地址,而網站域名只是一種別名,在連接服務器的過程中也是使用IP地址進行連接。
5.發送客戶端請求的數據。
6.接收服務端響應的數據。
當然,實際情形下遠不止以上幾步這么簡單,以上的每一步也可以拆分位許多小步,甚至形成一篇新的文章,但是基本流程就是這樣。
怎么觀察HTTP協議內容
如上文所說,HTTP協議是基於應用層的協議,那么計算機網絡抓包過后的應用層數據即包含HTTP協議的內容,在windows里面我們可以采用大名鼎鼎的wireshark進行數據報文的抓取,然后篩選HTTP協議進行觀察,也可以使用smartsniff這樣小而精的軟件專門抓取應用層內容,在Linux里面直接使用tcpdump進行抓取即可,然后將抓取的結果使用相關的軟件打開觀察,也可以導入到wireshark進行觀察。一個實際抓取的較為典型的HTTP內容如下:
客戶端請求:
POST /devices HTTP/1.1
Host: www.abc.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
a=b&c=d
服務器響應:
HTTP/1.1 200 OK
Date: Tue, 27 Oct 2020 02:13:39 GMT
Content-Type: application/json
Content-Length: 5
Connection: keep-alive
Server: nginx
Pragma: no-cache
Hello
協議詳解
HTTP之URL
HTTP URL格式如下:
http://host[":"port][abs_path]
host 表示合法的 Internet 主機域名或者 IP 地址
port 指定一個端口號,為空則使用缺省端口 80
abs_path 指定請求資源的 URI
舉幾個例子:
http://www.abc.com
http://www.abc.com:8080
http://www.abc.com/devices
http://www.abc.com:8080/devices/data
http://11.22.33.44/devices/data
http://11.22.33.44:8080/devices/data
以上均符合HTTP URL的定義,我們可以簡單地將其理解位我們在瀏覽器里面輸入的網站域名
HTTP之請求
請求組成部分
http請求由三部分組成,分別是:請求行、消息報頭、請求正文
關於請求行
請求行以一個方法符號開頭,以空格分開,后面跟着請求的URI和協議的版本,即
Method Request-URI HTTP-Version CRLF
針對Method有以下定義,並且必須使用以下定義的內容,如果填入其他的數據那么就不是標准的HTTP協議(雖然一部分服務器能自動糾錯)
- GET 請求獲取 Request-URI 所標識的資源
- POST 在 Request-URI 所標識的資源后附加新的數據
- HEAD 請求獲取由 Request-URI 所標識的資源的響應消息報頭
- PUT 請求服務器存儲一個資源,並用 Request-URI 作為其標識
- DELETE 請求服務器刪除 Request-URI 所標識的資源
- TRACE 請求服務器回送收到的請求信息,主要用於測試或診斷
- CONNECT 保留將來使用
- OPTIONS 請求查詢服務器的性能,或者查詢與資源相關的選項和需求
常用的Method只有GET以及POST,如果有涉及到協議轉換,比如HTTP1轉換到HTTP2、HTTP轉換到HTTPS或者轉換為websocket,可能回使用OPTIONS方法先詢問。至於其他的方法通常不怎么用,值得注意的是標准的restful接口業務會在GET和POST基礎上還有PUT和DELETE方法。
針對Request-URI則是我們在瀏覽器輸入的域名和端后后面的內容,比如/devices,如果是根目錄,比如www.abc.com,實際上Request-URI是“/”,即默認都是“/”開始,這樣的目錄結構和Linux的目錄結構類似,而實際上也是來源於它。
HTTP-Version我們常用的是HTTP/1.1,當然,現在也有部分網站使用HTTP/2
第一節的客戶端請求里面第一行則是請求行的內容,具體如下:
POST /devices HTTP/1.1
關於消息報頭
在第一節關於HTTP抓包的請求實例中,除了a=b&c=d這一個內容外其余的全是消息報頭,即
Host: www.abc.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
這里面也是HTTP核心東西之一,它以key: value的形式成對出現,除了上述內容外,我們常說的cookie、session等通常情況下也是放在消息報頭中進行傳輸
我們也常說HTTP Header,直接將消息報頭理解為HEADER里面的所有東西也是沒什么問題的。
關於請求正文
上述例子中,“a=b&c=d”即是請求正文,請求正文通常情況下有按照form形式、按照json形式進行傳輸,但是也可以自由發揮填充任意東西,只要服務端能去解析即可。
關於form形式除了最簡單的a=b&c=d外還有mutiform等形式,也是在請求頭中進行定義,然后請求正文使用相應的格式進行數據填充。
具體請求例子
具體的例子里面我們將以最小的報文頭進行展示而展示無關的信息
- 打開www.abc.com網站首頁
GET / HTTP/1.1
Host: www.abc.com
- 以GET形式傳入username為haha以及password為hehe到www.abc.com網站的登錄接口(假設為/login)
GET /login?username=haha&password=hehe HTTP/1.1
Host: www.abc.com
- 以POST標准FORM形式傳入username為haha以及password為hehe到www.abc.com網站的登錄接口(假設為/login)
POST /login HTTP/1.1
Host: www.abc.com
username=haha&password=hehe
- 以POST標准json形式傳入username為haha以及password為hehe到www.abc.com網站的登錄接口(假設為/login)
POST /login HTTP/1.1
Host: www.abc.com
{"username":"haha","password":"hehe"}
- 查詢www.abc.com網站的設備列表,並帶上cookie為123456(假設為/devicelist)
GET /devicelist HTTP/1.1
Host: www.abc.com
Cookie: 123456
- 查詢www.abc.com網站的設備列表,並帶上cookie為123456,要求服務端保持連接(假設為/devicelist)
GET /devicelist HTTP/1.1
Host: www.abc.com
Cookie: 123456
Connection: keep-alive
總結和后續計划
本文主要講解了HTTP一些基本概念以及請求相關的報文。
接下來第二篇將講解HTTP響應、HTTP2簡介以及當下主流的HTTPS簡單交互過程,最后將模擬請求一次網站並進行抓包演示。