首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Tomcat 8.0.36 請求匹配流程深度解析與已知 Bug 避坑指南

     編輯:Java 綜合教學

Tomcat 8.0.36 請求匹配流程深度解析與已知 Bug 避坑指南

理解 Tomcat 如何將 HTTP 請求路由到具體 Servlet,對排查 404、多 Host 配置、反向代理轉發至關重要。本文基於 Tomcat 8.0.36 源碼邏輯,梳理完整匹配鏈路,並揭示該版本兩個關鍵 Bug 及規避方案。

一、請求匹配完整流程圖解

HTTP Request
    │
    ▼
Connector (端口、協議、線程池)
    │
    ▼
ProtocolHandler (Http11NioProtocol 等)
    │
    ▼
Adapter (CoyoteAdapter) --> 將 Request 轉為 ServletRequest
    │
    ▼
Mapper (MapperListener) 核心路由邏輯
    │
    ├── 1. 選擇 Service (通常唯一)
    ├── 2. 選擇 Engine (通常唯一)
    ├── 3. 【關鍵】匹配 Host (域名/虛擬主機)
    │       └─ server.xml 中  / 
    ├── 4. 匹配 Context (Web 應用路徑 /app1, /app2)
    │       └─ docBase、path、web.xml、Servlet 映射
    └── 5. 匹配 Wrapper (Servlet 定義)
            └─ url-pattern: /api/*, *.do, /exact/path

Wrapper --> Filter Chain --> Servlet.service()
    │
    ▼
Response 返回

二、核心組件職責

組件職責配置位置
Connector監聽端口、解析 HTTP 協議、管理 I/O 線程server.xml
Mapper**核心路由器**,按 Host → Context → Wrapper 層級匹配內部組件,由 MapperListener 維護映射表
Host虛擬主機容器,綁定域名,持有多個 Contextserver.xml
Context單個 Web 應用,管理 Servlet、Filter、Listener、資源server.xml 或 META-INF/context.xml
Wrapper單個 Servlet 定義,持有 url-pattern 集合web.xml 或 @WebServlet

三、Tomcat 8.0.36 兩大已知 Bug

Bug 1:Cookie Header 解析異常 (CVE-2017-5647 / Bug 60718)

  • 現象:請求攜帶特定格式 Cookie(如包含未轉義的分號、等號、換行)時,Request.getCookies() 返回 null 或拋 IllegalArgumentException,導致 Session 失效、登錄態異常。
  • 影響版本:8.0.36、8.5.0-8.5.11、9.0.0.M1-9.0.0.M17
  • 修復版本:8.0.37+、8.5.12+、9.0.0.M18+
  • 規避方案:
    1. 升級 Tomcat(最徹底)
    2. Nginx/Apache 前置過濾異常 Cookie Header
    3. 自定義 Valve 或 Filter 捕獲異常並降級處理

Bug 2:TRACE 方法默認禁用配置陷阱

  • 現象:Connector 屬性 allowTrace="true" 才允許 TRACE 請求,默認 false 返回 405。此非 Bug 但常被誤以為故障。
  • 安全建議:生產環境**嚴禁開啟 TRACE**,防範 XST (Cross-Site Tracing) 攻擊。

四、Host 匹配進階:無泛域名支持的應對

Tomcat **不支持泛域名匹配**(如 *.example.com),Host.name 必須是確切域名或 localhost。

方案對比

方案適用場景實現方式
默認 Host 兜底域名少、固定、無需隔離,所有未匹配域名落入默認 Host,應用內再按域名分流
Nginx 域名路由 + 統一 Host域名多、需 SSL 卸載、靜態資源分離Nginx server_name 匹配 → proxy_pass 統一上游 Tomcat Host
動態 Host 註冊 (代碼侵入)SaaS 多租戶、運行時新增域名實現 LifecycleListener,運行時調用 engine.addChild(new StandardHost())
修改 Tomcat 源碼極少見、強定制需求修改 Mapper.map() 邏輯支持通配符,維護成本極高

五、調試技巧:如何驗證匹配路徑

  1. 開啟 Access Log Valve:server.xml 添加 <Valve className="org.apache.catalina.valves.AccessLogValve" pattern="%h %t %r %s %b %{Host}i %{X-Forwarded-For}i" />
  2. 查看日誌中的 Host Header 與實際路由的 Context Path
  3. JMX 監控 Catalina:type=Mapper,host=*,context=* 觀察映射表實時變化
  4. 斷點調試 CoyoteAdapter.postParseRequest() → Mapper.map()

六、總結

Tomcat 請求匹配遵循 **Connector → Mapper (Host → Context → Wrapper) → Servlet** 鏈路。8.0.36 存在**嚴重 Cookie 解析 Bug**,生產環境**必須升級至 8.0.37+**。泛域名需求請在 **Nginx 層解決**,勿強行改造 Tomcat。掌握 Mapper 邏輯與 Access Log 分析,能快速定位 99% 的 404、Session 丟失、多域名路由錯誤問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved