以前在項目中遇到一個關於http協議header部分最大長度限制的問題,我的以爲頗有意思,因而寫下這篇文章記錄這個問題。html
http協議,超文本傳輸協議,HyperText Transfer Protocol,是互聯網上應用最爲普遍的一種網絡協議,全部的WWW文件都遵照這個標準。關於http協議消息的格式,你們能夠網上自行搜索,這裏再也不贅述。本文關注的是其header部分,以下圖所示(紅框標註部分):java
問題原型node
有一個web application提供web service,這個web application基於java開發,部署在tomcat容器上。問題是:當客戶端發送一個GET請求,結果獲得400的response,意思是說bad request。檢查了這個request的代碼實現邏輯,並無相關input validation的邏輯,而且檢查server端日誌發現,request請求彷佛並無到達咱們本身代碼實現邏輯部分。這是爲何呢?git
問題解釋github
遇到這個問題時,第一步就是查看server端日誌,可是以爲很tricky的是,最開始並無發現相關的日誌,只是發現request並無到達咱們本身代碼實現邏輯部分。後來,mina同窗眼神很好,發現了以下日誌:golang
經過日誌note信息發現,該條日誌在info級別下只會打印一次,以後都會是debug級別纔打印,難怪以前沒有注意到這條日誌。web
從日誌信息可知,request的header部分太大,超過了tomcat容許的最大值。默認狀況下,tomcat(8.0版本)容許的http請求header的最大值是8024個字節(8KB)。那爲何以前沒有出現這個問題呢?緣由是,項目遷移到SCP平臺上以後,改爲JWT token作權限校驗,這個JWT token會被添加到request的header,然而JWT token通常來講都很大(平均有6k個字節左右),因此說在增長了JWT token這個header以及其餘一些相關的headers以後,整個request的header部分就超過8024個字節,因而就出現了這個問題。apache
那麼如何解決這個問題呢?能夠從兩個方面考慮:tomcat
1.增長tomcat容許http header最大值。這個配置參數maxHttpHeaderSize能夠設置tomcat容許的http header最大值。服務器
2.減小header的size,好比不要添加無關的header到request。
擴展
在研究這個問題的過程當中,其實還有一些其餘疑問。首先,一個request的轉發流程大體以下:
那麼,在這個流程中,爲何request在前面的部分沒有出現這個問題,而這個問題出如今最後一個技術棧是java/tomcat的component呢?
緣由是,每一個web服務器的http header最大長度的默認值不同,同時隨語言、版本不一樣也會不同。舉個例子tomcat 5的http header size的默認值是4K。
我找到了其餘component中對於http header size的默認值的定義:
以上兩個默認值都要遠遠大於8KB,這也就解釋了沒什麼問題出在最後一個component。
References
https://baike.baidu.com/item/http/243074?fromtitle=HTTP%E5%8D%8F%E8%AE%AE&fromid=1276942&fr=aladdin
http://grokbase.com/t/gg/golang-nuts/15aqc8qc9k/go-nuts-max-size-for-http-headers
https://stackoverflow.com/questions/24167656/nodejs-max-header-size-in-http-request