0

I have several web applications hosted on an AWS server on different ports, e.g.

app1: http://x.x.x.x:8080
app2: http://x.x.x.x:9000
...

I would like to a proxy in front of these apps (apache, nginix etc.) so that all of them can be accessed using port 80. I could think of two aproaches:

  • Put each app on a different sub-domain and forward based on the sub-domain, e.g

    http://app1.mydomain.com --> http://x.x.x.x:8080
    http://app2.mydomain.com --> http://x.x.x.x:9000
    

However in my case, I do not control the creation of subdomains. I have been given on sub-domain and I have to live with that. So this approach does not work.

  • Use a seperate URL for each app and then rewrite the URL, e.g.

    http://mysubdomain.mydomain.com/app1 --> http://x.x.x.x:8080
    http://mysubdomain.mydomain.com/app2 --> http://x.x.x.x:9000
    

However, I am running into an issue with this approach. For example, http://mysubdomain.mydomain.com/app1 correctly returns index.html from the app1, but then that index.html asks for js and css files without the app1 prefix, e.g. it asks for http://mysubdomain.mydomain.com/js/main.js instead of http://mysubdomain.mydomain.com/app1/js/main.js. As you can see, the forwarding rule no longer works. Even more confusing is that if my initial request terminates with a slash (http://mysubdomain.mydomain.com/app1/), then the requests for js and css files is formatted correctly (http://mysubdomain.mydomain.com/app1/js/main.js). I don't understand this behavior!

Is there any other approach that you can think of? I have heard of host header mapping, but couldn't figure out how it works. I can't imagine that this problem has not been solved!

Edits based on suggestion from @stoned

I have a Web application served from http://x.x.x.x:8080. This URL serves the index.html file which pulls in bunch of CSS and JavaScript files.

Here's my attempt to reverse proxy this app using Apache running at http://www.example.com:

# Reverse proxy requests for /app1 to http://x.x.x.x:8080
ProxyRequests off
ProxyPass /app1 http://x.x.x.x:8080
ProxyPassReverse /app1 http://x.x.x.x:8080

This does not work when I type http://www.example.com/app1 in my browser (note no slash at the end).

  • index.html is served correctly
  • However index.html asks for css and js with lines like this:

    <link rel="stylesheet" href="vendor/bootstrap.min.css"/> 
    <script src="vendor/angular.min.js"></script>
    
  • This translates to requests like this with no app1 imbedded in the URL:

    http://www.example.com/vendor/bootstrap.min.css
    http://www.example.com/vendor/angular.min.js
    
  • Obviously, the reverse proxy does not know what to do with these!

  • However, if I add a slash at the end of the URL (http://www.example.com/app1/), then the requests are translated correctly:

    http://www.example.com/app1/vendor/bootstrap.min.css
    http://www.example.com/app1/vendor/angular.min.js
    

I don't understand how adding a slash at the end makes the browser behave differently! Anyway, the important point is that I can't expect my users to type a slash at the end. Any thoughts on how to solve this problem?

Solved - Finally!

After bunch of googling I found that a trailing slash is used to indicate that the requested resource is a directory. In such cases the "default" resource from the directory is returned (usually index.html). If a user wrongly requests a directory without a trailing slash, mod_dir (which is normally loaded in Apache installations) adds a trailing slash and does a client-side redirect, fixing the problem.

In my case, http://www.example.com/app1 was not redirecting to http://www.example.com/app1/ (with a trailing slash) because /app1 is not a real directory on the apache server - mod_dir was not detecting this. Hence this URL was being proxied to http://x.x.x.x:8080 as is. While this was correctly returning the index.html, but the subsequent requests were relative to http://www.example.com and not http://www.example.com/app1. To fix the problem, I added a rewrite rule to redirect http://www.example.com/app1 to http://www.example.com/app1/ (with a slash). I also changed my reverse proxy rules to only match if I find a trailing slash. See below:

# Fix any request for /app1 to /app1/
RewriteEngine on
RewriteRule ^/app1$  /app1/  [R]

# Reverse proxy requests for /app1/ to http://x.x.x.x:8080/
ProxyRequests off
ProxyPass /app1/ http://x.x.x.x:8080/
ProxyPassReverse /app1/ http://x.x.x.x:8080/
Naresh
  • 103
  • 2

1 Answers1

0

With Apache you can do that with a reverse proxy. In your case with Apache you could use this kind of approach in the configuration file:

ProxyRequests off
ProxyPass /app1 http://x.x.x.x:8080
ProxyPassReverse /app1 http://x.x.x.x:8080
ProxyPass /app2 http://x.x.x.x:9000
ProxyPassReverse /app2 http://x.x.x.x:9000

(Of course you should have mod_proxy_http enabled and loaded in your Apache) If your application makes use of cookies, you might also have to properly set the ProxyPassReverseCookieDomain and ProxyPassReverseCookiePath directives. You can read the related documentation here.

Also, you forgot to mention which application server you're running, even if I see you're using some java application server. Mind that often application servers won't like at all if you change the application's context, which you should keep even on the proxy to stay on the safe side.

Finally, regarding your url rewriting, I'm sorry but if you don't post your exact configuration I guess that no one would be able to help you. Mind that anyway slashes do actually make a difference to web/application servers. Some add them automatically, others won't.

stoned
  • 808
  • 5
  • 10
  • Thanks @stoned. My app server is Node.js which is serving up a web app and a RESTful API both on port 8080. Based on your suggestion, I have now front-ended this server with Apache running a reverse proxy. Please see my edits for details. Still running into problems if my URL does not end with a slash. – Naresh Sep 07 '14 at 23:21
  • I finally figured out the issue with trailing slashes - see my 2nd edit. I am marking your answer as correct because it really is, the trailing slash problem was a sepearte one! – Naresh Sep 08 '14 at 02:28
  • Nice to know that you solved your problem @Naresh. I don't know about Node.js, but the problem with slashes is typical with many Application Servers... had that kind of problems with Jetty too, I solved that everytime with mod_rewrite too. – stoned Sep 08 '14 at 10:19