Copy the attached static.war into $CATALINA_HOME/webapps. Then start the server and paste this HTTP request in netcat: GET /static/name%20with%20spaces HTTP/1.1 User-Agent: Jakarta Commons-HttpClient/3.0 Host: localhost:8080 Tomcat will answer with the following HTTP redirect: HTTP/1.1 302 Moved Temporarily Server: Apache-Coyote/1.1 Location: http://localhost:8080/static/name with spaces/ Transfer-Encoding: chunked Date: Tue, 20 Nov 2007 13:46:12 GMT Observe the Location: header. It has raw unencoded spaces in the URL which is in clear violation of the HTTP specification.
Created attachment 21160 [details] minimal webapp that demonstrates the problem
Created attachment 21161 [details] simple fix I have no idea what the preferred internal Tomcat method for encoding URLs is, I just copied the URLEncoder stuff from DefaultServlet.
I have been through RFC2616 and can't see anywhere that states that the location header for a 302 must be encoded. Please provide reference(s) to the section(s) that require this.
Section 14.30 of RFC2616 specifies the Location header as: Location = "Location" ":" absoluteURI Then, in section 3.2.1 it specifies the definition of absoluteURI: For definitive information on URL syntax and semantics, see "Uniform Resource Identifiers (URI): Generic Syntax and Semantics," RFC 2396 [42] (which replaces RFCs 1738 [4] and RFC 1808 [11]). This specification adopts the definitions of "URI-reference", "absoluteURI", "relativeURI", "port", "host","abs_path", "rel_path", and "authority" from that specification. Moving on to RFC2396, in section 3 you can find the start of the absoluteURI BNF. If you follow the production you will eventually see that the basic characters of the individual path components come down to this: pchar = unreserved | escaped | ":" | "@" | "&" | "=" | "+" | "$" | "," Basically, the above says it can only contain unreserved characters and the characters explicitly specified, all the rest must be escaped. Look into sections 2.3 and 2.4.1 for the exact definitions of "unreserved" and "escaped", and you will see that none of them include the space character, which means "pchar" doesn't include it, which in turn means "absoluteURI" doesn't include it, which means eventually that the Location header can't include it either. Same goes for many other special characters not explicitly covered by "pchar", not just space.
Thanks for the pointer. That makes perfect sense. I have applied your patch to trunk and proposed it for 6.0.x and 5.5.x
Fixed in Tomcat 6.0.x.
Fixed in 5.5.x and will be included in 5.5.26 onwards.