předmluva
HTTP protokol je jedním z nejdůležitějších protokolů na internetu, i když se zdá jednoduchý, v praxi často naráží na problémy, s nimiž jsme se setkali několikrát. Jsou zde dlouhé spoje a parsování paketů. O HTTP protokolu nemůžete nic vědět, musíte mu důkladně rozumět. Proto jsem napsal tuto sérii, abych sdílel problémy a zkušenosti s HTTP protokolem.
HTTP protokol má hlavičku i tělo pro pakety požadavku i odpovědi a tělo je zdroj, který chcete získat, například html stránku, jpeg obrázek, a hlavička slouží k vytvoření určitých konvencí. Například klient a server se dohodnou na některých formátech přenosu, klient nejprve získá hlavičku, zná nějaké informace o formátu a pak začne číst hlavní část.
Klient: Accept-Encoding:gzip (komprimuj to pro mě, používám provoz, nejdřív to stáhni a pak pomalu rozbaluj)
Server 1: Content-Encoding: null (Žádná hlavička Content-Enkódování.) Nedávám kompresi, CPU není volný, chceš ho)
Server 2: Content-Encoding:gzip (ušetří vám provoz, komprimuje ho) Klient: Připojení: keep-alive (Velký brácho, konečně jsme vytvořili TCP připojení, příště ho použijeme)
Server 1: Připojení: udržuj naživu (není to snadné, pokračuj v použití)
Server 2: Připojení: uzavřené (Kdo ho s vámi bude dál využít, náš TCP je jednorázový a příště se budeme muset znovu připojit) HTTP protokol nemá tři handshake a když klient požádá o zdroje ze serveru, zvítězí serverová strana. Existují také některé hlavičky, které nemají vyjednávací proces, ale server přímo říká klientovi, co má dělat. Například výše uvedený obsah a délka je to, co server klientovi sděluje, jak velké je těleso. Ale! Server vám možná nebude schopen předem přesně říct, jak velké je tělo. Server musí nejdřív napsat hlavičku a pak tělo, pokud chcete napsat tělo do hlavičky, musíte předem znát velikost těla. Pokud je tělo generováno dynamicky, server dokončí a začne psát hlavičku, což vyžaduje hodně dodatečné režie, takže v hlavičce nemusí být délka obsahu.
Jak tedy klient pozná velikost těla? Server vám to řekne třemi způsoby.
1. Server už zná velikost zdroje a sdělí vám to přes hlavičku délky obsahu.
Content-Length:1076(body的大小是1076B,你读取1076B就可以完成任务了)
Transfer-Encoding: null
2. Server nemůže předem znát velikost zdroje nebo není ochoten investovat zdroje do výpočtu jeho velikosti předem, takže přidá hlavičku k http odpovědi nazvanou Transfer-Encoding:chunked, což znamená blokový přenos. Každý blok používá pevný formát, s velikostí bloku na začátku, daty za ním a nakonec posledním blokem o velikosti 0. Tímto způsobem musí klient při parsování věnovat pozornost odstranění některých zbytečných polí.
Content-Length:null
Transfer-Encoding:chunked (接下来的body我要一块一块的传,每一块开始是这一块的大小,等我传到大小为0的块时,就没了)
3. Server nezná velikost zdroje a nepodporuje režim přenosu s částmi, takže neexistuje ani hlavička délky obsahu, ani hlavička pro přenosové kódování. V tuto chvíli musí být hlavička vrácená serverem blízko.
Content-Length:null
Transfer-Encoding:null
Connection:close(我不知道大小,我也用不了chunked,啥时候我关了tcp连接,就说明传输结束了)
|