音視頻流媒體開(kāi)發(fā)【五十四】HLS流媒體6-HTTP協(xié)議分析

音視頻流媒體開(kāi)發(fā)-目錄
iOS知識(shí)點(diǎn)-目錄
Android-目錄
Flutter-目錄
數(shù)據(jù)結(jié)構(gòu)與算法-目錄
uni-pp-目錄

進(jìn)?步參考?檔:

《HTTP協(xié)議》
《圖解HTTP》

報(bào)?結(jié)構(gòu)

你也許對(duì) TCP/UDP 的報(bào)?格式有所了解,拿 TCP 報(bào)?來(lái)舉例摩泪,它在實(shí)際要傳輸?shù)臄?shù)據(jù)之前附加了?個(gè)20 字節(jié)的頭部數(shù)據(jù)濒生,存儲(chǔ) TCP 協(xié)議必須的額外信息火架,例如發(fā)送?的端?號(hào)闻牡、接收?的端?號(hào)、包序號(hào)、標(biāo)志位等等。

有了這個(gè)附加的 TCP 頭袭厂,數(shù)據(jù)包才能夠正確傳輸,到了?的地后把頭部去掉饭入,就可以拿到真正的數(shù)據(jù)嵌器。

HTTP 協(xié)議也是與 TCP/UDP 類似肛真,同樣也需要在實(shí)際傳輸?shù)臄?shù)據(jù)前附加?些頭數(shù)據(jù)谐丢,不過(guò)與 TCP/UDP不同的是,它是?個(gè)“純?本”的協(xié)議蚓让,所以頭數(shù)據(jù)都是 ASCII 碼的?本乾忱,可以很容易地??眼閱讀,不?借助程序解析也能夠看懂历极。

HTTP 協(xié)議的請(qǐng)求報(bào)?和響應(yīng)報(bào)?的結(jié)構(gòu)基本相同窄瘟,由三?部分組成:

  • 起始?(start line):描述請(qǐng)求或響應(yīng)的基本信息;
  • 頭部字段集合(header):使? key-value 形式更詳細(xì)地說(shuō)明報(bào)?趟卸;
  • 消息正?(entity):實(shí)際傳輸?shù)臄?shù)據(jù)蹄葱,它不?定是純?本氏义,可以是圖?、視頻等?進(jìn)制數(shù)據(jù)图云。

這其中前兩部分起始?和頭部字段經(jīng)常?合稱為“請(qǐng)求頭”或“響應(yīng)頭”惯悠,消息正??稱為“實(shí)體”,但與“header”對(duì)應(yīng)竣况,很多時(shí)候就直接稱為“body”克婶。

HTTP 協(xié)議規(guī)定報(bào)?必須有 header,但可以沒(méi)有 body丹泉,?且在 header 之后必須要有?個(gè)“空?”情萤,也就是“CRLF”,?六進(jìn)制的“0D0A”摹恨。

所以筋岛,?個(gè)完整的 HTTP 報(bào)?就像是下圖的這個(gè)樣?,注意在 header 和 body 之間有?個(gè)“空?”晒哄。

看?下我們之前? Wireshark 抓的包泉蝌。

在這個(gè)瀏覽器發(fā)出的請(qǐng)求報(bào)??。

第??“GET / HTTP/1.1”就是請(qǐng)求?揩晴,?后?的“Host”“Connection”等等都屬于 header勋陪,報(bào)?的最后是?個(gè)空??結(jié)束,沒(méi)有 body硫兰。

在很多時(shí)候诅愚,特別是瀏覽器發(fā)送 GET 請(qǐng)求的時(shí)候都是這樣,HTTP 報(bào)?經(jīng)常是只有 header ?沒(méi) body劫映。

請(qǐng)求?

了解了 HTTP 報(bào)?的基本結(jié)構(gòu)后违孝,我們來(lái)看看請(qǐng)求報(bào)??的起始?也就是請(qǐng)求?(request line),它簡(jiǎn)要地描述了客戶端想要如何操作服務(wù)器端的資源泳赋。

請(qǐng)求?由三部分構(gòu)成:
1. 請(qǐng)求?法:是?個(gè)動(dòng)詞雌桑,如 GET/POST,表示對(duì)資源的操作祖今;
2. 請(qǐng)求?標(biāo):通常是?個(gè) URI校坑,標(biāo)記了請(qǐng)求?法要操作的資源;
3. 版本號(hào):表示報(bào)?使?的 HTTP 協(xié)議版本千诬。

這三個(gè)部分通常使?空格(space)來(lái)分隔耍目,最后要? CRLF 換?表示結(jié)束。(圖示SP代表空格)

還是? Wireshark 抓包的數(shù)據(jù)來(lái)舉例:

GET / HTTP/1.1\r\n
GET /live/livestream.m3u8 HTTP/1.1\r\n

在這個(gè)請(qǐng)求??徐绑,“GET”是請(qǐng)求?法邪驮,“/”是請(qǐng)求?標(biāo),“HTTP/1.1”是版本號(hào)傲茄,把這三部分連起來(lái)毅访,意思就是“服務(wù)器你好沮榜,我想獲取?站根?錄下的默認(rèn)?件,我?的協(xié)議版本號(hào)是 1.1喻粹,請(qǐng)不要? 1.0 或者 2.0回復(fù)我敞映。”

別看請(qǐng)求?就??磷斧,貌似很簡(jiǎn)單振愿,其實(shí)這??的“講究”是?常多的,尤其是前?的請(qǐng)求?法和請(qǐng)求?標(biāo)弛饭,組合起來(lái)變化多端冕末,后?我還會(huì)詳細(xì)介紹。

狀態(tài)?

看完了請(qǐng)求?侣颂,我們?cè)倏错憫?yīng)報(bào)??的起始?档桃,在這?它不叫“響應(yīng)?”,?是叫“狀態(tài)?”(status line)憔晒,意思是服務(wù)器響應(yīng)的狀態(tài)藻肄。

?起請(qǐng)求?來(lái)說(shuō),狀態(tài)?要簡(jiǎn)單?些拒担,同樣也是由三部分構(gòu)成:

  • 版本號(hào):表示報(bào)?使?的 HTTP 協(xié)議版本嘹屯;
  • 狀態(tài)碼:?個(gè)三位數(shù),?代碼的形式表示處理的結(jié)果从撼,?如 200 是成功州弟,500 是服務(wù)器錯(cuò)誤;
  • 原因:作為數(shù)字狀態(tài)碼補(bǔ)充低零,是更詳細(xì)的解釋?字婆翔,幫助?理解原因。

看?下上?講? Wireshark 抓包?的響應(yīng)報(bào)?掏婶,狀態(tài)?是:

HTTP/1.1 200 OK\r\n

意思就是:“瀏覽器你好啃奴,我已經(jīng)處理完了你的請(qǐng)求,這個(gè)報(bào)?使?的協(xié)議版本號(hào)是 1.1雄妥,狀態(tài)碼是 200最蕾,?切 OK【グ牛”

?另?個(gè)“GET /favicon.ico HTTP/1.1”的響應(yīng)報(bào)?狀態(tài)?是:

HTTP/1.1 404 Not Found

翻譯成?話就是:“抱歉啊瀏覽器揖膜,剛才你的請(qǐng)求收到了誓沸,但我沒(méi)找到你要的資源梅桩,錯(cuò)誤代碼是 404,接下來(lái)的事情你就看著辦吧拜隧∷薨伲”

頭部字段

請(qǐng)求?或狀態(tài)?再加上頭部字段集合就構(gòu)成了 HTTP 報(bào)??完整的請(qǐng)求頭或響應(yīng)頭趁仙,我畫了兩個(gè)示意圖,你可以看?下垦页。

請(qǐng)求頭和響應(yīng)頭的結(jié)構(gòu)是基本?樣的雀费,唯?的區(qū)別是起始?,所以我把請(qǐng)求頭和響應(yīng)頭?的字段放在?起介紹痊焊。

頭部字段是 key-value 的形式盏袄,key 和 value 之間?“:”分隔,最后? CRLF 換?表示字段結(jié)束薄啥。?如在“Host: 127.0.0.1”這??? key 就是“Host”辕羽,value 就是“127.0.0.1”。

HTTP 頭字段?常靈活垄惧,不僅可以使?標(biāo)準(zhǔn)?的 Host刁愿、Connection 等已有頭,也可以任意添加?定義頭到逊,這就給 HTTP 協(xié)議帶來(lái)了?限的擴(kuò)展可能铣口。

不過(guò)使?頭字段需要注意下??點(diǎn):

  • 字段名不區(qū)分??寫,例如“Host”也可以寫成“host”觉壶,但?字??寫的可讀性更好脑题;
  • 字段名?不允許出現(xiàn)空格,可以使?連字符“-”铜靶,但不能使?下劃線“_”旭蠕。例如,“test-name”是合法的字段名旷坦,?“test name”“test_name”是不正確的字段名掏熬;
  • 字段名后?必須緊接著“:”,不能有空格秒梅,?“:”后的字段值前可以有多個(gè)空格旗芬;
  • 字段的順序是沒(méi)有意義的,可以任意排列不影響語(yǔ)義捆蜀;
  • 字段原則上不能重復(fù)疮丛,除?這個(gè)字段本身的語(yǔ)義允許,例如 Set-Cookie辆它。
?wireshark抓包的分析
請(qǐng)求
image.png
響應(yīng)

常?頭字段

HTTP 協(xié)議規(guī)定了?常多的頭部字段誊薄,實(shí)現(xiàn)各種各樣的功能,但基本上可以分為四?類:

  • 通?字段:在請(qǐng)求頭和響應(yīng)頭?都可以出現(xiàn)锰茉;
  • 請(qǐng)求字段:僅能出現(xiàn)在請(qǐng)求頭?呢蔫,進(jìn)?步說(shuō)明請(qǐng)求信息或者額外的附加條件;
  • 響應(yīng)字段:僅能出現(xiàn)在響應(yīng)頭?飒筑,補(bǔ)充說(shuō)明響應(yīng)報(bào)?的信息片吊;
  • 實(shí)體字段:它實(shí)際上屬于通?字段绽昏,但專?描述 body 的額外信息。

對(duì) HTTP 報(bào)?的解析和處理實(shí)際上主要就是對(duì)頭字段的處理俏脊,理解了頭字段也就理解了 HTTP 報(bào)?全谤。

這?主要講?個(gè)最基本的頭,看完了它們你就應(yīng)該能夠讀懂?多數(shù) HTTP 報(bào)?了爷贫。

User-Agent

User-Agent是請(qǐng)求字段认然,只出現(xiàn)在請(qǐng)求頭?。它使??個(gè)字符串來(lái)描述發(fā)起 HTTP 請(qǐng)求的客戶端漫萄,服務(wù)器可以依據(jù)它來(lái)返回最合適此瀏覽器顯示的??季眷。

但由于歷史的原因,User-Agent ?尘砜瑁混亂子刮,每個(gè)瀏覽器都?稱是“Mozilla”“Chrome”“Safari”,企圖使?這個(gè)字段來(lái)互相“偽裝”窑睁,導(dǎo)致 User-Agent 變得越來(lái)越?挺峡,最終變得毫?意義。

不過(guò)有的?較“誠(chéng)實(shí)”的爬?會(huì)在 User-Agent ??“spider”標(biāo)明??是爬?担钮,所以可以利?這個(gè)字段實(shí)現(xiàn)簡(jiǎn)單的反爬?策略橱赠。

Accept

Accept是請(qǐng)求字段,代表客戶端希望接受的數(shù)據(jù)類型箫津。?如Accept:text/xml(application/json);代表客戶端希望接受的數(shù)據(jù)類型是xml(json )類型狭姨;?如Accept: /則說(shuō)明客戶端接收所有類型的數(shù)據(jù)。

Host

?先要說(shuō)的是Host字段苏遥,它屬于請(qǐng)求字段饼拍,只能出現(xiàn)在請(qǐng)求頭?,它同時(shí)也是唯??個(gè) HTTP/1.1 規(guī)范?要求必須出現(xiàn)的字段田炭,也就是說(shuō)师抄,如果請(qǐng)求頭?沒(méi)有 Host,那這就是?個(gè)錯(cuò)誤的報(bào)?教硫。

Host 字段告訴服務(wù)器這個(gè)請(qǐng)求應(yīng)該由哪個(gè)主機(jī)來(lái)處理叨吮,當(dāng)?臺(tái)計(jì)算機(jī)上托管了多個(gè)虛擬主機(jī)的時(shí)候,服務(wù)器端就需要? Host 字段來(lái)選擇瞬矩,有點(diǎn)像是?個(gè)簡(jiǎn)單的“路由重定向”茶鉴。

例如我們的試驗(yàn)環(huán)境,在 127.0.0.1 上有三個(gè)虛擬主機(jī):“www.chrono.com”“www.metroid.net”和“origin.io”景用。那么當(dāng)使?域名的?式訪問(wèn)時(shí)涵叮,就必須要?Host 字段來(lái)區(qū)分這三個(gè) IP 相同但域名不同的?站,否則服務(wù)器就會(huì)找不到合適的虛擬主機(jī),?法處理围肥。

Range

Range是請(qǐng)求字段剿干。

?如Range: bytes=5001-10000 對(duì)于只需獲資源的范圍請(qǐng)求蜂怎,包含?部字段 Range 即可告知服務(wù)器資源的指定范圍穆刻。上?的示例表示請(qǐng)求獲取從第 5001 字節(jié)到第 10000 字節(jié)的資源。

?如Range: bytes=0- 則是請(qǐng)求所有的數(shù)據(jù)杠步。

接收到附帶 Range ?部字段請(qǐng)求的服務(wù)器氢伟,會(huì)在處理請(qǐng)求之后返回狀態(tài)碼為 206 Partial Content 的響應(yīng)。?法處理該范圍請(qǐng)求時(shí)幽歼,則會(huì)返回狀態(tài)碼 200 OK 的響應(yīng)及全部資源朵锣。

Connection

管理持久連接

①: close 斷開(kāi)連接

Connection: close

HTTP/1.1版本的默認(rèn)連接都是持久連接。為此甸私,客戶端會(huì)在持久連接上連續(xù)發(fā)送請(qǐng)求诚些。當(dāng)服務(wù)器端想明確斷開(kāi)連接時(shí),則指定 Connection ?部字段的值為 close 皇型。

②: Keep-Alive 保持連接

Connection: keep-alive

HTTP/1.1 之前的版本的默認(rèn)連接都是?持久連接诬烹。為此,如果想在舊版本的HTTP協(xié)議上維持持續(xù)連接弃鸦,則需要指定 Connection ?部字段的值為 keep-alive 绞吁。

在客戶單發(fā)送請(qǐng)求給服務(wù)器時(shí),攜帶此參數(shù)和值唬格,服務(wù)器也會(huì)加上字段和值進(jìn)?返回響應(yīng)家破。

http是?個(gè)?狀態(tài)的?向連接的協(xié)議。

http?狀態(tài):?狀態(tài)協(xié)議是指http協(xié)議本身對(duì)于事務(wù)處理沒(méi)有記憶功能购岗,服務(wù)器不知道瀏覽器的狀態(tài)汰聋。通俗的即使你登錄了,去訪問(wèn)同?個(gè)?站的不同??喊积,服務(wù)器都不會(huì)知道你是誰(shuí)马僻,如果需要記錄登錄?戶的信息,?戶操作注服,?戶?為等數(shù)據(jù)需要使?cookie或session來(lái)存儲(chǔ)韭邓。

keep-alive:從HTTP/1.1起,瀏覽器默認(rèn)都開(kāi)啟了Keep-Alive溶弟,保持連接特性女淑,客戶端和服務(wù)器都能選擇隨時(shí)關(guān)閉連接,則請(qǐng)求頭中為connection:close辜御。簡(jiǎn)單地說(shuō)鸭你,當(dāng)?個(gè)??打開(kāi)完成后,客戶端和服務(wù)器之間?于傳輸HTTP數(shù)據(jù)的TCP連接不會(huì)關(guān)閉,如果客戶端再次訪問(wèn)這個(gè)服務(wù)器上的??袱巨,會(huì)繼續(xù)使?這?條已經(jīng)建?的TCP連接阁谆。但是Keep-Alive不會(huì)永久保持連接,它有?個(gè)保持時(shí)間愉老,可以在不同的服務(wù)器軟件(如Apache)中設(shè)定這個(gè)時(shí)間场绿。

誤解:?狀態(tài)不代表HTTP不能保持TCP連接,更不能代表HTTP使?的是UDP協(xié)議(?連接)嫉入。即使http在?狀態(tài)下焰盗,只要客戶端和服務(wù)器的頭部信息connection:keep-alive,則在有效期內(nèi)他們使?同?條TCP連接咒林。

Date

Date字段是?個(gè)通?字段熬拒,但通常出現(xiàn)在響應(yīng)頭?,表示 HTTP 報(bào)?創(chuàng)建的時(shí)間垫竞,客戶端可以使?這個(gè)時(shí)間再搭配其他字段決定緩存策略澎粟。

Server

Server字段是響應(yīng)字段,只能出現(xiàn)在響應(yīng)頭?欢瞪。它告訴客戶端當(dāng)前正在提供 Web 服務(wù)的軟件名稱和版本號(hào)活烙, Server 字段也不是必須要出現(xiàn)的,因?yàn)檫@會(huì)把服務(wù)器的?部分信息暴露給外界引有,如果這個(gè)版本恰好存在 bug瓣颅,那么?客就有可能利? bug 攻陷服務(wù)器。所以譬正,有的?站響應(yīng)頭?要么沒(méi)有這個(gè)字段宫补,要么就給出?個(gè)完全?關(guān)的描述信息。

?如 GitHub曾我,它的 Server 字段?就看不出是使?了 Apache 還是 Nginx粉怕,只是顯示為“GitHub.com”。

再?如srs流媒體服務(wù)器的響應(yīng) Server:SRS/3.0.141(OuXuli)\r\n

Content-Type

Content-Type是實(shí)體字段抒巢,表發(fā)送端(客戶端|服務(wù)器)發(fā)送的實(shí)體數(shù)據(jù)的數(shù)據(jù)類型贫贝。?如:ContentType:text/html(application/json) ; 代表發(fā)送端發(fā)送的數(shù)據(jù)格式是html(json)。

Content-Length

實(shí)體字段?要說(shuō)的?個(gè)是Content-Length蛉谜,它表示報(bào)?? body 的?度稚晚,也就是請(qǐng)求頭或響應(yīng)頭空?后?數(shù)據(jù)的?度。服務(wù)器看到這個(gè)字段型诚,就知道了后續(xù)有多少數(shù)據(jù)客燕,可以直接接收。如果沒(méi)有這個(gè)字段狰贯,那么 body 就是不定?的也搓,需要使? chunked ?式分段傳輸赏廓。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市傍妒,隨后出現(xiàn)的幾起案子幔摸,更是在濱河造成了極大的恐慌,老刑警劉巖颤练,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件既忆,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡昔案,警方通過(guò)查閱死者的電腦和手機(jī)尿贫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門电媳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)踏揣,“玉大人,你說(shuō)我怎么就攤上這事匾乓±谈澹” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵拼缝,是天一觀的道長(zhǎng)娱局。 經(jīng)常有香客問(wèn)我,道長(zhǎng)咧七,這世上最難降的妖魔是什么衰齐? 我笑而不...
    開(kāi)封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮继阻,結(jié)果婚禮上耻涛,老公的妹妹穿的比我還像新娘。我一直安慰自己瘟檩,他們只是感情好抹缕,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著墨辛,像睡著了一般卓研。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上睹簇,一...
    開(kāi)封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天奏赘,我揣著相機(jī)與錄音,去河邊找鬼太惠。 笑死磨淌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的垛叨。 我是一名探鬼主播伦糯,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼柜某,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了敛纲?” 一聲冷哼從身側(cè)響起喂击,我...
    開(kāi)封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎淤翔,沒(méi)想到半個(gè)月后翰绊,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡旁壮,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年监嗜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抡谐。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡裁奇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出麦撵,到底是詐尸還是另有隱情刽肠,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布免胃,位于F島的核電站音五,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏羔沙。R本人自食惡果不足惜躺涝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望扼雏。 院中可真熱鬧坚嗜,春花似錦、人聲如沸呢蛤。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)其障。三九已至银室,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間励翼,已是汗流浹背蜈敢。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留汽抚,地道東北人抓狭。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像造烁,于是被迫代替她去往敵國(guó)和親否过。 傳聞我的和親對(duì)象是個(gè)殘疾皇子午笛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容