You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Christopher Schultz <ch...@christopherschultz.net> on 2015/07/03 19:40:03 UTC

Tomcat not properly fully-qualifying redirect URLs

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

All,

Running Tomcat 8.0.x trunk as of 1688887 (slightly old) on jdk1.8.0_45
on Mac OS X, I'm having intermittent problems with Tomcat appearing
not to change a relative URL into a fully-qualified URL for
redirection purposes.

Since it's intermittent, it's hard to catch. But I just found a case.

I have an HttpServletResponseWrapper that logs calls to sendRedirect()
by dumping-out the URL that was passed-into the sendRedirect method.

I have anonymized the URLs somewhat. I hope I haven't removed any
URL-escapes or anything like that to break the URLs... I can assure
you that they are correct. These are things that have been working for
years and years in production and other environments. This *only seems
to be a problem on my localhost environment*.

Here's what I just got:

2015-07-03 13:24:11,388 [catalina-exec-79] INFO  redirect-
sendRedirect:
location=/context/path/to/action.do?id=7734&returnURL=%2Fpath%2Fto%2Fano
ther%2Faction.do%3Fid%3D1045&cancelReturnURL=%2Fpath%2Fto%2Fanother%2Fac
tion.do%3Fid%3D1045

This is what the browser saw (care of LiveHttpHeaders):

(Request, then response)

http://localhost/context/path/to/action.do?id=7734&returnURL=%2Fpath%2Ft
o%2Faction.do%3Fid%3D1045&cancelReturnURL=%2Fpath%2Fto%2Faction.do%3Fid%
3D1045&submit=action%C2%A0%C2%A0%C2%BB

GET
/context/path/to/action.do?id=7734&returnURL=%2Fpath%2Fto%2Faction.do%3F
id%3D1045&cancelReturnURL=%2Fpath%2Fto%2Faction.do%3Fid%3D1045&submit=ac
tion%C2%A0%C2%A0%C2%BB
HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:38.0)
Gecko/20100101 Firefox/38.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer:
http://localhost/context/path/to/resume.do?id=7734&returnURL=%2Fpath%2Ft
o%2Faction.do%3Fid%3D1045&cancelReturnURL=%2Fpath%2Fto%2Faction.do%3Fid%
3D1045
Cookie: JSESSIONID=A96FC368FB3E1D132CE3EAEFB697A43A.myworker
Connection: keep-alive

HTTP/1.1 302 Found
Date: Fri, 03 Jul 2015 17:30:58 GMT
Server: Apache/2.4.10 (Unix) OpenSSL/0.9.8zd mod_jk/1.2.41-dev
Location:
http://context/path/to/questions.do?id=7734&u=14e54f8a677&returnURL=%2Fp
ath%2Fto%2Faction.do%3Fid%3D1045&cancelReturnURL=%2Fpath%2Fto%2Faction.d
o%3Fid%3D1045
Content-Type: text/html;charset=UTF-8
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
- ----------------------------------------------------------

Note the "Location" header in the response. It looks like Tomcat took
the URL passed-into sendRedirect and then just added "http:/" to the
beginning of it.

I'm proxying through httpd 2.4.10 using mod_proxy_ajp. Here is my
<Connector>:

    <Connector port="8215"
       redirectPort="443"
           protocol="org.apache.coyote.ajp.AjpNioProtocol"
        URIEncoding="UTF-8"
         packetSize="65536"
           executor="tomcatThreadPool" />

I have a fairly standard ProxyPass handling requests to /context

ProxyPass /context/ ajp://localhost:8215/context/
ProxyPassReverse /context/ ajp://localhost:8215/context/

Note that we don't use mod_proxy_ajp in production; we use mod_jk
instead. I also haven't instrumented the connection between Tomcat and
httpd. This could definitely be a mod_proxy_ajp problem.

Any ideas?

Thanks,
- -chris
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - http://gpgtools.org

iQIcBAEBCAAGBQJVlsjzAAoJEBzwKT+lPKRYRogQALXQ5Dn1zss9d7VDXNRv41zr
fNjqe06ri2LdoB7TiItRvX5m2wlWWkG4yI5aaRAhB+bbZdK5bOjAh7Ak2onxOGKs
9z/hAEyzEXuGWc789hm4y8aGyn2SFPCh/qn/IhJZ/jfEnYGxk2H+DQT3VzJ6UZnm
MhDMJdsve4QKDGFxwrg94qaZOttxsIpabHX7OtNTxsQm+nW59KIg0CgPRR3f93Yz
iruOHopZzOmiZLzb/+CHOTdP3zb1tYrzwk+DlWC/k5hHOhI+mVP8pBNmnA4xgapd
jF4b/aSb4c47cbhl0LnePMOh9WSZ+S1aty5XKsOMt9tM/v51V5UhmMp3/LCHq3Ty
fdMSnMdPohXNkS78Xd9LNIDat8cNW+UHCuGFohvb7HtLgvz7KmNZvMmWTAsAm/M0
k9QhL47XZCpfBWZhbBK4+ovqQW8bjFQtoaaFmsN9Mkea8UKn0mgpLQij0irp3XaA
qehyd6VyHFO9F6c3JH+L1r9mOZ+1TcGSgHNFSrdt14n1kEVKjmz313ygT3+qJZI9
BGRzAxiHstfw7vYwI4SD2mlZHABYHrZha6UouIxaIFv0+qrTsE6GJA0SomAgOgLq
limsu2ji8RJ61Hr5j1YDM+U7r8YCTdDMb2SYOnnAhMJEGPaEzV1ppkfCZsHqSeog
n/6o+XdHzpMp/v7E1zRC
=EOoE
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Tomcat returning context path with extra leading slash

Posted by Christopher Schultz <ch...@christopherschultz.net>.
Konstantin,

On 10/23/15 6:32 AM, Konstantin Kolinko wrote:
> 2015-10-22 20:55 GMT+03:00 Christopher Schultz <ch...@christopherschultz.net>:
>> All,
>>
>> On 10/14/15 11:03 PM, Christopher Schultz wrote:
>>> All,
>>>
>>> On 7/3/15 1:40 PM, Christopher Schultz wrote:
>>>> Running Tomcat 8.0.x trunk as of 1688887 (slightly old) on
>>>> jdk1.8.0_45 on Mac OS X, I'm having intermittent problems with
>>>> Tomcat appearing not to change a relative URL into a
>>>> fully-qualified URL for redirection purposes.
>>>
>>>> Since it's intermittent, it's hard to catch. But I just found a
>>>> case.
>>>
>>>> I have an HttpServletResponseWrapper that logs calls to
>>>> sendRedirect() by dumping-out the URL that was passed-into the
>>>> sendRedirect method.
>>>
>>>> [snip]
>>>
>>>> [HttpServletResponse.sendRedirect or similar is ruining my redirect
>>>>  URL, so the hostname is being obliterated and I get
>>>> http://context/path/to/page instead of
>>>> http://localhost/context/path/to/page]
>>>
>>> I'm having this problem, again. This time with an updated 8.0.x trunk
>>> (pretty much 8.0.27).
>>>
>>> It might be a problem with securityfilter, which is trying to do this:
>>>
>>> // redirect to login page
>>> response.sendRedirect(response.encodeRedirectURL(request.getContextPath(
>>> )
>>> + loginPage));
>>>
> <...>
>>
>> Any idea what might be causing Tomcat to return "/" + context path when
>> ServletContext.getContextPath() is called?
> 
> It seems that you are confusing two different methods,
> 
> (1) HttpServletRequest.getContextPath()
> (2) ServletContext.getContextPath(), @since Servlet 2.5
> 
> (1) returns the actual value from client's request, as is
> (2) returns "canonical" value
> 
> (2) is always the same, (1) varies

Aah, I didn't realize that they were different.

I'll look into why HttpServletRequest.getContextPath is returning the
"extra" slash -- probably because of something that has happened
previously in the workflow.

Thanks,
-chris

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Tomcat returning context path with extra leading slash (was: Re: Tomcat not properly fully-qualifying redirect URLs)

Posted by Konstantin Kolinko <kn...@gmail.com>.
2015-10-22 20:55 GMT+03:00 Christopher Schultz <ch...@christopherschultz.net>:
> All,
>
> On 10/14/15 11:03 PM, Christopher Schultz wrote:
>> All,
>>
>> On 7/3/15 1:40 PM, Christopher Schultz wrote:
>>> Running Tomcat 8.0.x trunk as of 1688887 (slightly old) on
>>> jdk1.8.0_45 on Mac OS X, I'm having intermittent problems with
>>> Tomcat appearing not to change a relative URL into a
>>> fully-qualified URL for redirection purposes.
>>
>>> Since it's intermittent, it's hard to catch. But I just found a
>>> case.
>>
>>> I have an HttpServletResponseWrapper that logs calls to
>>> sendRedirect() by dumping-out the URL that was passed-into the
>>> sendRedirect method.
>>
>>> [snip]
>>
>>> [HttpServletResponse.sendRedirect or similar is ruining my redirect
>>>  URL, so the hostname is being obliterated and I get
>>> http://context/path/to/page instead of
>>> http://localhost/context/path/to/page]
>>
>> I'm having this problem, again. This time with an updated 8.0.x trunk
>> (pretty much 8.0.27).
>>
>> It might be a problem with securityfilter, which is trying to do this:
>>
>> // redirect to login page
>> response.sendRedirect(response.encodeRedirectURL(request.getContextPath(
>> )
>> + loginPage));
>>
<...>
>
> Any idea what might be causing Tomcat to return "/" + context path when
> ServletContext.getContextPath() is called?

It seems that you are confusing two different methods,

(1) HttpServletRequest.getContextPath()
(2) ServletContext.getContextPath(), @since Servlet 2.5

(1) returns the actual value from client's request, as is
(2) returns "canonical" value

(2) is always the same, (1) varies

Best regards,
Konstantin Kolinko

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Tomcat returning context path with extra leading slash (was: Re: Tomcat not properly fully-qualifying redirect URLs)

Posted by Christopher Schultz <ch...@christopherschultz.net>.
All,

On 10/14/15 11:03 PM, Christopher Schultz wrote:
> All,
> 
> On 7/3/15 1:40 PM, Christopher Schultz wrote:
>> Running Tomcat 8.0.x trunk as of 1688887 (slightly old) on
>> jdk1.8.0_45 on Mac OS X, I'm having intermittent problems with
>> Tomcat appearing not to change a relative URL into a
>> fully-qualified URL for redirection purposes.
> 
>> Since it's intermittent, it's hard to catch. But I just found a
>> case.
> 
>> I have an HttpServletResponseWrapper that logs calls to
>> sendRedirect() by dumping-out the URL that was passed-into the
>> sendRedirect method.
> 
>> [snip]
> 
>> [HttpServletResponse.sendRedirect or similar is ruining my redirect
>>  URL, so the hostname is being obliterated and I get 
>> http://context/path/to/page instead of 
>> http://localhost/context/path/to/page]
> 
> I'm having this problem, again. This time with an updated 8.0.x trunk
> (pretty much 8.0.27).
> 
> It might be a problem with securityfilter, which is trying to do this:
> 
> // redirect to login page
> response.sendRedirect(response.encodeRedirectURL(request.getContextPath(
> )
> + loginPage));
> 
> The "loginPage" variable starts with a "/" and the final URL *should*
> be something like "/context/loginPage", but by the time it gets to
> HttpServletResponse.sendRedirect, it's been changed to
> "//context/loginPage". This ruins everything, of course.
> 
> I haven't stepped-through the code in a debugger, yet, but all the
> code in both securityfilter and Tomcat looks okay at first glance.
> 
> The good news is that HttpServletResponse.sendRedirect isn't making a
> bad decision. It's either securityfilter itself, or some weird
> combination of a few components, since
> o.a.c.connector.Response.encodeRedirectURL doesn't mutate the URL in a
> way that could add leading slashes.

Okay, I caught this happening again.

I have this class wrapping the request object in a Filter that does
other things -- I just re-purposed it in order to catch this problem:

    static class RequestWrapper
        extends HttpServletRequestWrapper
    {
        RequestWrapper(HttpServletRequest request)
        {
            super(request);
        }

        public String getContextPath()
        {
            String contextPath = super.getContextPath();

org.apache.log4j.Logger.getLogger("redirect").info("contextPath=" +
contextPath);
            return contextPath;
        }
    }

I got an error with the redirect, and this is what I have in my log file:

2015-10-22 13:47:33,367 [catalina-exec-6] INFO  redirect-
contextPath=//mycontext

(Note the // prefix.)

My application is deployed into an exploded WAR directory with a
META-INF/context.xml file that (correctly) declares neither a docBase
nor a path.

Later, when the redirect actually happens, the sendRedirect method
observes this:

2015-10-22 13:47:33,367 [catalina-exec-6] INFO  redirect-
encodeRedirectURL before encoding url=//mycontext/somepath&parameters


2015-10-22 13:47:33,367 [catalina-exec-6] INFO  redirect-
encodeRedirectURL after encoding url=//mycontext/somepath&parameters

2015-10-22 13:47:33,367 [catalina-exec-6] INFO  redirect- sendRedirect:
location=//mycontext/somepath&parameters

Any idea what might be causing Tomcat to return "/" + context path when
ServletContext.getContextPath() is called?

-chris

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Tomcat not properly fully-qualifying redirect URLs

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

All,

On 7/3/15 1:40 PM, Christopher Schultz wrote:
> Running Tomcat 8.0.x trunk as of 1688887 (slightly old) on
> jdk1.8.0_45 on Mac OS X, I'm having intermittent problems with
> Tomcat appearing not to change a relative URL into a
> fully-qualified URL for redirection purposes.
> 
> Since it's intermittent, it's hard to catch. But I just found a
> case.
> 
> I have an HttpServletResponseWrapper that logs calls to
> sendRedirect() by dumping-out the URL that was passed-into the
> sendRedirect method.
> 
> [snip]
> 
> [HttpServletResponse.sendRedirect or similar is ruining my redirect
>  URL, so the hostname is being obliterated and I get 
> http://context/path/to/page instead of 
> http://localhost/context/path/to/page]

I'm having this problem, again. This time with an updated 8.0.x trunk
(pretty much 8.0.27).

It might be a problem with securityfilter, which is trying to do this:

// redirect to login page
response.sendRedirect(response.encodeRedirectURL(request.getContextPath(
)
+ loginPage));

The "loginPage" variable starts with a "/" and the final URL *should*
be something like "/context/loginPage", but by the time it gets to
HttpServletResponse.sendRedirect, it's been changed to
"//context/loginPage". This ruins everything, of course.

I haven't stepped-through the code in a debugger, yet, but all the
code in both securityfilter and Tomcat looks okay at first glance.

The good news is that HttpServletResponse.sendRedirect isn't making a
bad decision. It's either securityfilter itself, or some weird
combination of a few components, since
o.a.c.connector.Response.encodeRedirectURL doesn't mutate the URL in a
way that could add leading slashes.

- -chris
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - http://gpgtools.org

iQIcBAEBCAAGBQJWHxeWAAoJEBzwKT+lPKRYAQMQAKXjLuWehajKAc1OpoN4YJyo
+YBXN9xUGrYUJOKRIrEveaI/RrgU7OzfgA1n3A4wSIIu4NFzxwJYZnBGpCgCLo75
7qmoc+ikHUd5OxYkTsQ2SD03e9A3bZQDUeNwt6FvfUeMTBNHwsrRRmBW7PLyJNwN
FSFIroI1kURBm2SEn+uXlJ3WdQtAJC0XzIxa4lfiq6rU8Hwnx/aGAr/tkcQmXIi1
iWefdR2iYpvG5PqADbwqmLxzt3dWqJH6RCLeFRrtnqjK4gB0sDpoFNTj8if8RYkT
8L90k0ZcPzM4WJJWSJPZdnDAjHWUGEycbZkHk87AXl4xZkvQ/pmYQSAqWF+w1/hx
sVvgrbTonv0gK8jFNdm/RVp5C6dI44/EZloHmKkeuVj+geMbejo0xKA4hi1CUalU
nLb/NysBq9cfFU4foc/dpYn21Mixro+SLNStbQgwVq/jncHsLu80uKoP9QAkMjvY
OGuGQilYL+q3Hk6No5dRhDEdK2fAQ0Oi0SFb7LK4qS+6RQdBw9TDsOlOMFRPYAFW
slbstyHnevx9u2YgJw9P6BCc4dcxPcgJkjAal8uuPNBRuBWknoV7BQ4Tc/kFvpRP
eGnb0pVf9fXVb89majicQzNSf4aec8zTYxyToPj4jW6hlpjjxnZLhbHwHnNZvWaW
lDsyARINmf2kuKkX4gJj
=oRAf
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org