Tuesday, February 26, 2013

reverse proxies: put my thing down, flip it and reverse it

The other day I realize the web page I made to test my mockup RESTful server wouldn't allow me to make the same requests against the real server because of cross-site scripting blocks. I figured I had 4 options:
  1. Some kind of JSONP Solution, which probably wasn't going to happen, since it would require changing the server.
  2. Putting the testing web page on that server, which was also a bit unlikely.
  3. Forget testing from webpage, use curl instead.
  4. Some kind of proxy, so the webpage could hit the remote server while thinking it was talking to the same server and port it was served off of.
So 4 was the most promising solution. It turns out this is called a "reverse proxy"- that means not only is the request to a server passed on to a different server, but when the response comes back, headers are munged so that the response looks like it came from that "server in the middle" (or else the web browser would get balky.)

There is a node.js Reverse Proxy system available, but to be honest I am not yet fluent enough in node to safely know I could get the thing working in a timely way.

A better solution seemed to be using the Apache webserver that comes built in (but not on by default) with Macs.

Even though I wasn't setting up the proxy to talk to a Tomcat server, this page had one of the more concise descriptions of how to set up the reverse proxy. The only problem I had with it was I had to use more wildcards for my service to work...

(A note, I had to use "sudo" for a lot of these editing and server starting operations, since I was using protected files and ports.)

Anyway, on a mac the main config file for Apache is /etc/apache2/httpd.conf . The first few lines of code listed (the LoadModule) on that Tomcat page were already taken care of, and I added the following near the end:

# mod_proxy setup.
ProxyRequests Off
ProxyPass /myapp/
ProxyPassReverse /myapp/

<Location "/myapp/*">
  # Configurations specific to this location. Add what you need.
  # For instance, you can add mod_proxy_html directives to fix
  # links in the HTML code. See link at end of this page about using 
  # mod_proxy_html.

  # Allow access to this proxied URL location for everyone. 
  Order allow,deny
  Allow from all

So I had to specify the IP address and port, add in my own app name, but then the Location needed to be a wildcard, so the actual calls could work.

The document root for the default OSX Apache server was /Library/WebServer/Documents/  (and I had to change some permissions so I could easily work in that folder.) That's where I put my little web client page.

Finally, the best way of starting/restarting/stopping the server was apachectl, e.g.
sudo apachectl start
BAM! Proxy Reversed!

For what it's worth, it seems like "reverse proxy" is a misleading name. Personally it feels more like a "masked proxy"-- still passing on requests to a remote server, but then hiding over the fact that the information isn't coming from the local server.

No comments:

Post a Comment