Bug 55734 - Manager using absolute URLs
Summary: Manager using absolute URLs
Status: RESOLVED WONTFIX
Alias: None
Product: Tomcat 7
Classification: Unclassified
Component: Manager (show other bugs)
Version: 7.0.42
Hardware: PC Linux
: P2 enhancement (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-11-01 20:02 UTC by Milo Hyson
Modified: 2013-11-04 20:01 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Milo Hyson 2013-11-01 20:02:42 UTC
The manager application seems to be using absolute URLs on its pages for internal references. For instance, if deployed with a context-path of /manager, all images and hyperlinks in /manager/html are prefixed with /manager. This can be a problem if Tomcat is running behind a proxy. The following httpd config, for example, breaks the links:

ProxyPass /some/other/path/ http://localhost:8080/manager/
Comment 1 Mark Thomas 2013-11-01 20:07:02 UTC
If a proxy modifies the context path of a web application then it is the proxy's responsibility to clean up the mess (cookie paths, redirects, links in pages, anywhere else the path might appear) that results.
Comment 2 Milo Hyson 2013-11-01 20:23:04 UTC
Why is it the admin's responsibility? The developer initiated the mess by making a faulty assumption.
Comment 3 Mark Thomas 2013-11-01 20:35:03 UTC
The developer is doing exactly what they should do - using request.getContextPath() to correctly construct the URL.

The breakage occurs in the proxy because the proxy is changing the path and the application has no way of knowing the path has been changed. Changing the context path in the proxy is something pretty much guaranteed to break all but the most trivial of web applications. If an sys admin decides to change the path in the proxy then they need to change it for both inbound and outbound traffic.

The simplest solution is to change the context path in the back-end server to match the context path used by the proxy. In your example renaming $CATALINA_BASE/webapps/manager to $CATALINA_BASE/webapps/some#other#path is the change required.

The complex solution is to use mod_proxy, mod_headers and mod_substitute (or equivalent) to fix the headers and the content.

If the manager app generates URLs that start with "/manager" when deployed under a different path that would be a valid bug.
Comment 4 Milo Hyson 2013-11-01 20:52:49 UTC
Having reviewed the source I think I see the problem. As a general rule, developers should NOT be using request.getContextPath() as you suggest. That just binds application content to a deployment-time concern. In this particular instance, however, the manager application appears to be a quick-and-dirty implementation with no separation of concerns. It's generating HTML in-code of all things. Given that approach, producing relative URLs is not likely to be trivial.

Sorry for wasting your time.
Comment 5 Mark Thomas 2013-11-01 21:29:37 UTC
The Manager app is certainly not a model application in many respects but it does get the handling of the context path right.

Consider session cookies. The application is required to set the cookie path. That is set to the context path. If a proxy changes the the context path neither the application nor the container has any visibility that the path has changed. However for correct, secure operation the session cookie path needs to be changed to match the context path set in the proxy. The only component with the knowledge that the session cookie path needs to be changed and the knowledge of what it needs to be changed to is the proxy. The proxy changes the path and it has to take responsibility for the knock-on effects of that.

302 redirects are another example. The location header is required to be an absolute URI. Again, the proxy is the only place with the knowledge that this needs to be changed and what it should be changed to.

Various popular libraries also set custom http headers that include absolute URIs. These too need to be changed. Again, the proxy is the only place that this can be done.

Applications should be (and it is treated as a bug if any of the Tomcat provided apps are not) agnostic to the context path they are deployed to in the container. Applications can not be agnostic to changes in the context path introduced by a proxy. Cookie paths and location headers for 302 redirects to are some of the many things that make this impossible.

Changing the context path in the proxy is rarely trivial. The more complex the application, the more complex the process of ensuring that it works correctly. By far the simplest approach is to change the context path in the container to match the path used by the proxy.
Comment 6 Milo Hyson 2013-11-01 21:49:51 UTC
Cookies and redirects are easy with the directives provided by mod_proxy. At issue is HTML content. I see no reason why an application should, as a matter of general practice, bake the context-path into internal references. /manager/html, for example, has a link that reads /manager/images/asf-logo.gif when it could read images/asf-logo.gif. Granted, given the particular architecture that's not necessarily easy to do, but in other cases it is.
Comment 7 Christopher Schultz 2013-11-01 22:06:42 UTC
(In reply to Milo Hyson from comment #4)
> As a general rule, developers should NOT be using request.getContextPath() as you suggest.

I disagree. Relative links fail in all sorts of bad ways, which is why all JSP tag libraries, tools, etc. automatically insert the context-path at the beginning of all their URLs /by default/. It's not even clear to me that you can disable this kind of thing in JSTL for example.

> That just binds application content to a deployment-time concern.

Again, I disagree: in fact it frees the application from deployment-time concerns. If you re-name the context, the web application continues to work properly. If the page you are accessing was due to a "forward", the links continue to work even if the browser's URL resolution would otherwise create bad links.

> Given [this] approach, producing relative URLs is not likely to be trivial.

It would be trivial yet irrelevant.

If you want to use a different context-path, don't play proxying games: just rename the context so it has the deployment path you want it to have.
Comment 8 Milo Hyson 2013-11-01 22:43:17 UTC
(In reply to Christopher Schultz from comment #7)
> Relative links fail in all sorts of bad ways ...

Maybe I've just been lucky, but I've been using relative links in applications for years with no issue. Can you elaborate on these bad ways?
Comment 9 Chuck Caldarale 2013-11-02 00:12:45 UTC
(In reply to Milo Hyson from comment #8)
> Maybe I've just been lucky, but I've been using relative links in
> applications for years with no issue. Can you elaborate on these bad ways?

Here's a start:
http://yoast.com/relative-urls-issues/
Comment 10 Milo Hyson 2013-11-02 02:41:04 UTC
I came across that same article when I Googled the issue. The problem is it seems to be describing generally bad practices that are not specific to the use of relative URLs.
Comment 11 Christopher Schultz 2013-11-02 13:45:39 UTC
(In reply to Milo Hyson from comment #10)
> I came across that same article when I Googled the issue. The problem is it
> seems to be describing generally bad practices that are not specific to the
> use of relative URLs.

I'm sorry for launching a discussion in BZ. This really belongs on the users' list. I'd be happy to expand upon my assertions there.
Comment 12 Milo Hyson 2013-11-04 19:02:41 UTC
(In reply to Christopher Schultz from comment #11)
> I'm sorry for launching a discussion in BZ. This really belongs on the
> users' list. I'd be happy to expand upon my assertions there.

Please do. I'd like to know if I'm making a big mistake, and if so why it hasn't bitten me.
Comment 13 Konstantin Kolinko 2013-11-04 20:01:46 UTC
Note that some places (e.g. the 404 and 403 pages) respond to various URLs. It is so much easier and safer to use absolute URLs in all those responses.

The "list" page is one of those places. That is what is shown by default regardless of what command was invoked on the Manager.

If one wants to improve that, consider proposing a patch.


Note that the manager application does not need to be named "manager". It can be deployed at some/other/path as easily and should work as well.

mv manager some#other#path

http://tomcat.apache.org/tomcat-7.0-doc/config/context.html#Naming