Greetings I'm running tomcat v9.0.105 with a CXF based SOAP service (you know, the old school JAXWS services). Within that service, I had a need to retrieve a specific http header and i've been running into some inconsistent results. The tomcat server is sitting behind a nginx proxy if that matters. Sometimes the header was there, sometimes it wasn't. It was more consistent if I send the header twice with different casing. x-forwarded-for vs X-Forwarded-For. (issue 1)
In order to troubleshoot the inconsistency, i wrote a little routine to simple get the servlet request, get the header names, enumerate them and print all the keys and values to the log file for troubleshooting. Then i ran into an even stranger problem... sometimes, but not always, I'm getting a NPE being thrown from tomcat code and I honestly have no idea why (issue 2) First the stack trace for (issue 2)... at org.apache.tomcat.util.http.ValuesEnumerator.findNext(MimeHeaders.java:509) [tomcat-coyote.jar:9.0.105] at org.apache.tomcat.util.http. ValuesEnumerator.nextElement(MimeHeaders.java:525) [tomcat-coyote.jar:9.0.105] at org.apache.tomcat.util.http. ValuesEnumerator.nextElement(MimeHeaders.java:490) [tomcat-coyote.jar:9.0.105] at org.apache.cxf.transport.http.HttpServletRequestSnapshot.getHeader(HttpServletRequestSnapshot.java:124) [cxf-rt-transports-http-3.5.5.jar] Now checking that specific line number in the source code...yields something odd... https://github.com/apache/tomcat/blob/9.0.x/java/org/apache/tomcat/util/http/MimeHeaders.java#L509 and it's @Override line... so i dug a bit further and decompiled the jar in order to understand what's going on here. (issue 3) private void findNext() { this.next=null; for (; this.pos < this.size; this.pos++) { MessageBytes n1 = this.headers.getName(this.pos); //fails here! if (n1.equalsIgnoreCase(this.name)) { this.next = this.headers.getValue(this.pos); break; } } this.pos++; } Apologies for the formatting as i had to retype this by hand. This would seem to imply that there's an extra 9 lines or so of code in the jar i'm using, which was from a docker public container tomcat:9.0-jdk11 Additional info: I did wireshark this and was able to see the message before going to tomcat and it looks ok. Headers all appeared to be there and were well formed, nothing out of the ordinary. Questions/issue summary (1) apparent inconsistent access to a specific http header in tomcat with behind a proxy. Sometimes it's there, something it isn't. (2) NPE being thrown when enumerating headers. Any idea why am i getting a NPE in this case? (3) should be concerned that the git repo's source line numbers do not align with what the jar is reporting? Hoping this isn't some kind of supply chain attack Some theories I've cooked up on questions (1, 2) Since it's a CXF JAXWS SOAP service with springboot servlet, i'm pretty sure the only way to get http headers is via @Resource WebServiceContext injection and then dig down to get the servlet request. I was always under the impression that this should be thread safe, but if it isn't, it's possible that the MimeHeaders class, at least according to the javadocs may have recycled before i got it to, thus making the 'headers' variable be cleared out. Or it could be a bug in cxf (it is an older version but I'm stuck until we can update JREs) or maybe a tomcat bug. I did note that someone reporting this issue many years ago on stack overflow, specifically here: https://stackoverflow.com/questions/37493552 but as i said, the request looks ok and no different than any other setup. The only other thing that might be a factor was that we recently renewed the server certificate key pair. Seems unlikely though. Pretty sure I'm not using the tomcat native libraries for anything related to TLS Anyhow, a long one but hopefully someone will have an idea. TIA