iT邦幫忙

2026 iThome 鐵人賽

DAY 27
0
JavaScript

Learn HTTP With JS(2)系列 第 27

為何 response header 會出現 Nncoection 這個怪異拼法?從 TCP Checksum 到 F5 BIG-IP 架構,一步步破解

  • 分享至 

  • xImage
  •  

前言

某天在逛一個網站時,看到 response header 有 Nncoection: close

Nncoection: close

當下立即想到是拼錯的 Connection: close,但又覺得沒有這麼簡單,於是就趁這個機會來研究看看

推測1:後端工程師手殘打錯字

以 Node.js http.Server 為例,需要這樣設定

res.setHeader("Nncoection", "close");

但實務上,我們在 Application Server 寫的都是 Layer 7 之上的商業邏輯,基本上不會碰到 TCP 連線池的管理,都是交給程式語言本身的 http, net 模組來處理,所以這個 "後端工程師手殘打錯字" 的推測,機率感覺非常低

推測2:某個 proxy 加的

從瀏覽器的 F12 > Network 可以觀察到這是 HTTP/2 的請求

HTTP/2 廢棄了 Connection header,參考 RFC 9113 Section 8.2.2 的描述

HTTP/2 does not use the Connection header field (Section 7.6.1 of [HTTP]) to indicate connection-specific header fields

現代很多 Application 的架構,都是 client > Frontend 走 HTTP/2,Frontend > Backend 走 HTTP/1.1

client-frontend-to-backend

也就是說,Nncoection: close 可能是在 response 階段的某個節點加的

client-frontend-backend-nncoection-close

Google Search

如果在 Google 查詢 "Nncoection" 的話,會看到有蠻多篇討論的,大多數都集中在 2010 ~ 2011 年

大致上有提到幾個關鍵字

  • TCP Checksum
  • Citrix NetScaler, F5 BIG-IP

這個領域,對於一般接觸 Layer 7 為主的軟體工程師來講,會很不熟悉。我查了很多資料,總結以下:

  • F5:一間美國的公司
  • BIG-IP:F5 公司的旗下的一個產品系列
  • Citrix NetScaler ADC:對標 F5 BIG-IP,Citrix 公司旗下 NetScaler 的一款產品 ADC,全名為 Application Delivery Controller

平常我們常接觸的 Nginx 是運作在 Layer 7 的 load balancer,每秒能處理的請求數量有限,但對於中小型企業來說很夠用

但如果是金融產業等大型企業,每秒百萬級別的請求,則需要更強大的解決方案,這時候就會需要上述兩種產品(運作在 Layer 7 以下)

最終結論

從上面的各種線索,我推敲出以下結論

client-f5-big-ip-nncoection

至於為何不直接把 Connection: close 這行刪掉,或是改成 Connection: keep-alive 呢?原因也是效能優化:

  • Connection 改成 NncoectionTCP Checksum 是一樣的,且 bytes 長度也相同,不會發生位移
  • 所以在 TCP 這層可以邊發邊改,不需要把整個 HTTP response header buffer 在緩衝區

另外,若同樣的請求,用 HTTP/1.1 重發一次的話,也可以間接驗證我上述的結論

curl --http1.1 https://REDACTED/ecapp/Index.do -v

< HTTP/1.1 500 Internal Server Error
< Server: Apache
< Content-Encoding: gzip
< Strict-Transport-Security: max-age=15768000
< X-Frame-Options: SAMEORIGIN
< X-e: bg237 bg160 bg237
< Content-Length: 480
< nnCoection: close
< Content-Type: text/html;charset=BIG5
< Connection: keep-alive

同時可以看到

  • Frontend (F5 BIG-IP) 修改過的 nnCoection: close
  • Frontend (F5 BIG-IP) 把 Connection: keep-alive 加到 respone header 最後面

小結

這次的研究過程,其實是一個典型的技術偵探故事:從一個看似手殘打字的 header 開始,透過觀察 HTTP/2 廢棄 Connection header 的規範、Google 搜尋歷史文章、以及用 curl --http1.1 重現驗證,最終拼湊出 F5 BIG-IP 為了效能而 inplace 修改 header 的完整故事。這也提醒了我們,任何「看起來像 bug」的現象,背後都可能藏著值得深挖的架構知識。

參考資料


上一篇
Expect: 100-continue 解析:用途、Node.js 實作與 curl 行為
下一篇
介紹 ALPN 如何讓 client 與 server 在 TLS 階段協商 HTTP/1.1 或 HTTP/2,並以 curl、Node.js 實例解析
系列文
Learn HTTP With JS(2)29
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言