Tomcat 9: header line does not conform to RFC 7230

Solution 1:

What's the difference between 8 and 9 Tomcat versions that my request works in 8 but in 9 do not?

I think the difference is that Tomcat 9.x has tightened up on what should be permitted to be unencoded within a URL, so from a technical perspective there is no problem with Tomcat 9.x; the issue lies with earlier Tomcat releases, and browsers not strictly following specifications.

That said, I couldn't identify any specific fix that has triggered this issue for you, nor could I see anything in the Release Notes.

I add relaxedQueryChars parameter to Tomcat Connector with colon (though colon is allowed symbol)...and it still fails.

From the Tomcat 9.0 documentation for relaxedQueryChars:

The HTTP/1.1 specification requires that certain characters are %nn encoded when used in URI query strings. Unfortunately, many user agents including all the major browsers are not compliant with this specification and use these characters in unencoded form. To prevent Tomcat rejecting such requests, this attribute may be used to specify the additional characters to allow. If not specified, no additional characters will be allowed. The value may be any combination of the following characters: " < > [ \ ] ^ ` { | } . Any other characters present in the value will be ignored.

Note the last two sentences. The colon character is not mentioned, so it "will be ignored".

Is there anything I can do in Tomcat to make this request work?

I don't think so, but the real problem is that you are not encoding colons within your parameters, and you have already mentioned that this resolves the issue. See this SO answer, and in particular the final sentence:

There are reserved characters, that have a reserved meanings, those are delimiters — :/?#[]@ — and subdelimiters — !$&'()*+,;=

There is also a set of characters called unreserved characters — alphanumerics and -._~ — which are not to be encoded.

That means, that anything that doesn't belong to unreserved characters set is supposed to be %-encoded, when they do not have special meaning (e.g. when passed as a part of GET parameter).

The colon is a reserved character with a special meaning, and therefore it must be encoded within your parameters.

Notes:

  • Also see Bug 62273 - Add support for alternate URL specification. Although it doesn't specifically address your issue with the colon character, there is an interesting discussion on how browsers have not been adhering to RFC 3986 (Uniform Resource Identifier (URI): Generic Syntax).

  • The error message you are getting from Tomcat is vague, and could probably be improved. Perhaps raise a bug report with them?