This page looks best with JavaScript enabled

What Is Http

 ·  ☕ 3 min read

HTTP 們

HTTP

https://notfalse.net/39/http-message-format
HyperText Transfer Protocol
一種應用層的通訊協定
簡單來說就是應用程式之間的一種溝通規範,規定好大家資料格式長什麼樣子,互相該如何來回訊息。如果大家都依照這種統一規範來做自己的東西,那麼在銜接上就會很容易

http 通常使用 tcp 協定 (http3 是 udp)

建立 tcp 連線 3 way handshake

基於 tcp 的 http 們,一開始要過三次的訊息交換來建立連線
詳細請參考 https://notfalse.net/7/three-way-handshake
注意這時傳送的訊息跟應用程式實際溝通時的 request 和 response 不一樣
note: ack 回應時不單是seq+1,而是 seq+(整個header+data的長度)

Stateless

每個 request 都不會預設 server 知道自己之前做過什麼
Request 要依靠自己提供完整的資訊,或提供線索讓 server 知道去哪裡找到資訊 (在 header 帶著 cookie 之類的)

Request, Response

Request 長相如下 (Ref: https://documentation.help/DogeTool-HTTP-Requests-vt/http_request.htm)

Response

各代 http

不同代的 http 都有一些問題,下面簡單舉幾個例子

HTTP/1.0

預設不使用 keep-alive (然後好像大家真的都沒用XD)
這樣的話每次request都要建立一個TCP連線,想法是為了避免 client 佔著 server 太久,所以做完一件事情就關掉
如果開一個網頁要讀取很多東西 -> 建立很多連線(3 way) -> 耗費資源

HTTP/1.1

預設持久連線,重複使用同一個TCP連線
要馬上關閉的話要特別在 header 裡面的 Connection 寫
有 head of line blocking 的問題

http1.1 有 pipeline 功能嘗試解決這個問題
但似乎規定 server 需要依照收到 request 的順序回給 client,代表每個 req 都要多帶一些資訊,且應用程式都必須特別處理這一部分,複雜度太高,且很多 proxy 根本不是你能控制的,所以都沒人在用。
HOLB 還是存在

比起 1.0 還多了一些 header etag 之類的東西
cache: https://blog.techbridge.cc/2017/06/17/cache-introduction/

可以對 body 的部分進行編碼順便壓縮,常見的像是 gzip

https://crypto.stackexchange.com/questions/40215/encoding-vs-compression-vs-encryption


HTTP/2.0

也是基於 tcp,http2 許多東西都與 http1.1相容,像是 methods、status code 那些
然後優化了其他東西
主要有下面幾個變動

  1. 可以 server push (主動丟東西給 client),在之前的 http 中,都需要 client 先發 request 後 server 才可回應

  2. header 壓縮 (hpack),可以壓縮到剩下幾 byte,原本的可能數十甚至數百

  3. 上面提過的 holb 問題解決了(解決了應用層的,但 tcp 本身網路層就有 holb,http3 才會試著用 udp 來解決),一條 tcp 連線裡面可以有多個 stream
    例如一個 request 會有一個 stream id x,request 可以被拆成 frame 們,到目的地再組起來,不同 request 的一堆 frame 們都可以不照順序傳輸。
    其實長得還滿像 tcp packet 的 XD

  4. Binary protocol
    這條不得不說從字面上看起來真的很看不懂XDD
    後來查到這篇 https://stackoverflow.com/questions/58498116/why-is-it-said-that-http2-is-a-binary-protocol 才比較了解一點
    大意就是,原本基於文字的 http,接收的人看到資料就是一串 character,需要一個個字去讀出來解析,找到 newline character 之類的,速度超慢。
    且在傳輸上,一個 request 或是 response 都必須一次傳送到達目的地,在這之前其他人都不能用這條連線(與第三點相關)。
    而 http2 的每個 frame 都很有結構(https://tools.ietf.org/html/rfc7540#section-4.1),譬如前面 n 個 bit 代表 frame 長度,接下來 m 個 bit 代表什麼什麼,內容多長等等的,都可以預先知道,在解析上就可以非常容易

http3.0

tcp 接收資料時會確保資料封包是連續的,才會依照順序把資料拿給應用程式
譬如有 1 2 3 4 5個封包
如果傳送中 1 3 正確到達但 2 掉了,tcp 就只能等到 2 到達後才把 3 也一起拿來用(即使 1 3 這兩個封包在應用層上都可以直接使用,但 tcp 並不瞭解應用層的事情)
且在此同時 sliding window 也可能被卡住,傳送端或線路上即使空閒也不會繼續傳送後面的封包,造成 holb 的問題

http3 就用 udp + QUIC 來解決這個問題
QUIC 也是一種傳輸層的協議,提供可靠傳輸
至於細節還沒研究 XD
現在還沒有被很廣泛的使用


下一篇可能會拿 websocket 和 http2 比較看看,因為現在其實很多瀏覽器都支援 http2 了,http2 又有 server push 的功能,感覺和 websocket 還滿像的 ?? GRPC???

Share on

Marko Peng
WRITTEN BY
Marko Peng
Good man