2

Little bit of a newb when it comes to configuring httpd but here's my situation:

I'm trying to proxy an application (let's call it catsapp) that I have no control over with httpd.

catsapp, an html/javascript application, has httpd running in front of it as well. But I can't mess with that configuration, I can only control the top-level httpd config.

Turns out that inside of the index.html of catsapp, there is a javascript call:

window.location="viewer.html"

Which is meant to load the viewer page.

Normally, writing the ProxyPass directive is easy enough and this is what I have currently:

ProxyPass /catsapp http://catsapp-server timeout=600
ProxyPassReverse /catsapp http://catsapp-server timeout=600

This does not work however. If I navigate to example.com/catsapp I get a 200 OK followed immediately by 404 Not Found because the browser tries to load example.com/viewer.html instead of example.com/catsapp/viewer.html.

Is there some way to configure the root httpd server so that when catsapp calls window.location="viewer.html" it resolves to example.com/catsapp/viewer.html?

Andrew Schulman
  • 8,811
  • 21
  • 32
  • 47
FGreg
  • 530
  • 3
  • 10

2 Answers2

1

I guess that there are multiple resources that need to be loaded from your application, so example.com/catsapp should look a subdirectory. Without a trailing slash, browsers see example.com/catsapp as a file-like resource, not a folder-like resource. Following the link viewer.html relative to example.com/catsapp leads to example.com/viewer.html. However, resolving viewer.html relative to example.com/catsapp/ (notice the trailing slash) resolves to example.com/catsapp/viewer.html.

I would suggest redirecting example.com/catsapp to example.com/catsapp/ (not internally but via HTTP 3xx) and editing your ProxyPass rule to also include the trailing slash. For example:

Redirect permanent /catsapp /catsapp/
ProxyPass /catsapp/ http://catsapp-server/ timeout=600
ProxyPassReverse /catsapp/ http://catsapp-server/ timeout=600
FGreg
  • 530
  • 3
  • 10
Felix
  • 46
  • 10
  • 1
    Interesting. If I remove my rewrite rule and alter my Proxy/ProxyPass to: `ProxyPass /catsapp http://catsapp/ timeout=600` and `ProxyPassReverse /catsapp http://catsapp/ timeout=600`; when I request `http://example.com/catsapp` it still incorrectly resolves to `http://example.com/viewer.html` **but** if I request `http://example.com/catsapp/` is does redirect correctly to `http://example.com/catsapp/viewer.html` – FGreg Jan 29 '18 at 21:57
  • Keep in mind that it mind that it's the browser who does the relative resolving. The browser is instructed to go to `viewer.html`, so it resolves that relative to what it sees as the current address. Therefor, you must make sure that the browser never gets to `example.com/catsapp`, but only to `example.com/catsapp/`. – Felix Jan 30 '18 at 12:05
  • I just noticed my description may be misleading. You mustn't redirect the request to `example.com/catsapp` *internally* to `example.com/catsapp/`, but instruct the browser via HTTP 3xx to go visit that address instead. If the browser however requests the page with the slash (or any subresource), ProxyPass the request to the application server. – Felix Jan 30 '18 at 12:09
  • Aha! That makes much more sense now. I've implemented rules as you suggest and everything works. I've edited my working configuration into your answer. – FGreg Jan 30 '18 at 19:36
0

After some more digging it looks like what I want to do is not "easily" possible. I now understand that the problem is this:

  1. Browser requests example.com/catsapp
  2. Root httpd server intercepts request and forwards to http://catsapp-server/
  3. catsapp-server httpd receives requests and returns index.html
  4. Root httpd server returns response to client
  5. Browser receives index.html
  6. Browser changes location to example.com/viewer.html (because the javascript told it to)

So the erroneous URL is being decided client-side after httpd is out of the picture. What it seems I would have to do is use something like mod_substitute to alter the response being sent back to the client in step #4 to insert my custom /catsapp path before viewer.html. Sounds ugly and prone to error.


What I decided to do instead seems to be a little more robust but still pretty specific to this use case. I noticed that index.html exists only to redirect the client to viewer.html. So why don't I just do that automatically during step #2 above? I tried that by adding a RewriteRule to the root httpd server.

RewriteRule (.*/catsapp) https://%{HTTP_HOST}%{REQUEST_URI}/viewer.html [R,L]

And it seems to be working just fine. I don't think there are other areas of the application that try changing location like index.html does and this solution wouldn't work for any cases where that happens... so here's hoping it works out.

FGreg
  • 530
  • 3
  • 10
  • Even though I settled on a workaround, I want to leave this question open in case I'm wrong or missing something. Please comment or add an answer if you disagree with my analysis/approach. – FGreg Jan 25 '18 at 22:12