Tomcat version: 9.0.37 Operating system: windows 11 JDK version: OpenJDK 1.8 Problem Description: During the debugging process, it was found that in the prepareRequest stage when Tomcat parses the HTTP request headers, the X-Forwarded-For field is lost, and at the same time, there are duplicate Host fields. The original request stream (from inputBuffer): -------------------------------------------------- GET /v1/webapi/server/current_time? t=1774661427160 HTTP/1.1 isdisplaypage:true tenantid: groupid: unity-access-token:f7e20127-1b55-4e1e-a0e2-d15b2caa112ee devicetype: user-agent:HolliView accept:application/json, text/plain, */* content-type:application/json token:f7e20127-1b55-4e1e-a0e2-d15b2caa112e projectid: Referer: http://12.52.41.10:8080/hv-visio/display.html? ... accept-encoding:gzip, deflate accept-language:zh-CN forwarded:proto=http; host="12.52.41.10:8080"; for="12.52.41.20:56611" x-forwarded-for: 12.52.41.200 x-forwarded-proto:http x-forwarded-prefix:/hv-data x-forwarded-port:8080 x-forwarded-host: 12.52.41.10:8080 host: 127.0.0.1:80011 content-length:0 --------------------------------------------------
Actual parsing result (MimeHeaders): - X-Forwarded-For field: Missing (does not exist) - Host field: Appears twice (repeated) headers=@MimeHeaderField[][ @MimeHeaderField[ nameB=@MessageBytes[isdisplaypage], valueB=@MessageBytes[true], ], @MimeHeaderField[ nameB=@MessageBytes[tenantid], valueB=@MessageBytes[], ], @MimeHeaderField[ nameB=@MessageBytes[accept], valueB=@MessageBytes[application/json, text/plain, */*], ], @MimeHeaderField[ nameB=@MessageBytes[unity-access-token], valueB=@MessageBytes[f7e20127-1b55-4e1e-a0e2-d15b2caa112e], ], @MimeHeaderField[ nameB=@MessageBytes[devicetype], valueB=@MessageBytes[], ], @MimeHeaderField[ nameB=@MessageBytes[user-agent], valueB=@MessageBytes[HolliView], ], @MimeHeaderField[ nameB=@MessageBytes[accept], valueB=@MessageBytes[application/json, text/plain, */*], ], @MimeHeaderField[ nameB=@MessageBytes[content-type], valueB=@MessageBytes[application/json], ], @MimeHeaderField[ nameB=@MessageBytes[token], valueB=@MessageBytes[f7e20127-1b55-4e1e-a0e2-d15b2caa112e], ], @MimeHeaderField[ nameB=@MessageBytes[projectid], valueB=@MessageBytes[], ], @MimeHeaderField[ nameB=@MessageBytes[referer], valueB=@MessageBytes[http://12.52.41.10:8080/hv-visio/display.html?tag=displays/%E7%AC%AC%E5%9B%9B%E5%87%80%E5%8C%96%E5%8E%82%E6%B5%81%E7%A8%8B%E5%9B%BE/%E8%84%B1%E7%A1%AB%E8%84%B1%E6%B0%B4%E8%A3%85%E7%BD%AE2/%E8%84%B1%E6%B0%B4%E8%A3%85%E7%BD%AE.json], ], @MimeHeaderField[ nameB=@MessageBytes[accept-encoding], valueB=@MessageBytes[gzip, deflate], ], @MimeHeaderField[ nameB=@MessageBytes[accept-language], valueB=@MessageBytes[zh-CN], ], @MimeHeaderField[ nameB=@MessageBytes[forwarded], valueB=@MessageBytes[proto=http;host="12.52.41.10:8080";for="12.52.41.20:56611"], ], @MimeHeaderField[ nameB=@MessageBytes[host], valueB=@MessageBytes[127.0.0.1:8001], ], @MimeHeaderField[ nameB=@MessageBytes[x-forwarded-proto], valueB=@MessageBytes[http], ], @MimeHeaderField[ nameB=@MessageBytes[x-forwarded-prefix], valueB=@MessageBytes[/hv-data], ], @MimeHeaderField[ nameB=@MessageBytes[x-forwarded-port], valueB=@MessageBytes[8080], ], @MimeHeaderField[ nameB=@MessageBytes[x-forwarded-host], valueB=@MessageBytes[12.52.41.10:8080], ], @MimeHeaderField[ nameB=@MessageBytes[host], valueB=@MessageBytes[127.0.0.1:8001], ], @MimeHeaderField[ nameB=@MessageBytes[content-length], valueB=@MessageBytes[0], ] ], Key observations: 1. The original request contains x-forwarded-for: 12.52.41.200. 2. The original request has host: 127.0.0.1:8001 only once. 3. However, after parsing, X-Forwarded-For is lost and Host becomes two. 4. It doesn't occur every time. 5.The Tomcat that is embedded within the Spring Boot 6. Trigger badRequest("http11processor.request.multipleHosts"); 7.There are no other additional configurations. Investigations completed: - Confirmed that the header is included in the request flow before it reaches Tomcat. - Configured with RemoteIpValve, but the issue occurred during the parsing stage. 1. Is this a known parsing issue? 2. Are there any configuration items that would affect the header parsing behavior? 3. How can we further determine whether it is a parsing logic issue or caused by pre-processing? Thank you! 扛起一片天!✨ [email protected]
