Mongrel, SSL, and Apache 1.3
So, you’ve heard all about this mongrel thing that has Rails programmers everywhere talking. You’re anxious to give the whole setup a try, but…
You’re stuck on Apache 1.3, and you’ve got certain actions in your app that require SSL support.
This happened to me recently. Parts of my app require SSL, and other parts do not. The general solution, if you are using Apache 2, is to set the X-FORWARDED-PROTO request header to “https” before proxying the (decrypted) request to mongrel. Unfortunately, Apache 1.3 has no mechanism for setting request headers!
Here’s how I worked around it. I changed my vhost setting thus:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<VirtualHost a.b.c.d> ServerName foo.bar.com ProxyPass / http://localhost:3000/ ProxyPassReverse / http://localhost:3000/ </VirtualHost> <VirtualHost a.b.c.d:443> ServerName foo.bar.com ProxyPass / http://localhost:3000/ssl/ ProxyPassReverse / http://localhost:3000/ssl/ ... </VirtualHost> |
In the first block, I define the proxy to just forward the request to port 3000, unaltered. (I’ve got a pen process running on port 3000, which then balances requests across multiple mongrel instances.) In the second block, however, I configure the proxy to forward to the same port, but I append the path /ssl/
to it. This, then, gives me a way to differentiate SSL requests from non-SSL requests in my app.
I then make two tweaks to my app. For the first tweak, I add a new route:
1 2 3 4 |
ActionController::Routing::Routes.draw do |map| # ... map.connect "ssl/*suburi", :controller => "ssl_proxy", :action => "reprocess" end |
Then, I add a new controller, which will process (and forward) SSL requests:
1 2 3 4 5 6 7 8 9 10 11 |
class SslProxyController < ActionController::Base def reprocess request.env["REQUEST_URI"] = "/#{params[:suburi]}" request.env["HTTPS"] = "on" controller = ActionController::Routing::Routes.recognize(request) controller.process(request, response) @performed_render = true end end |
This just sets the REQUEST_URI
and HTTPS
environment variables appropriately, requests routing to recognize the new path, and has the resulting controller process the request. I then tell Rails that a render was performed, just to prevent it from trying to render the non-existant reprocess.rhtml
template.
Now, this may or may not work for every situation, but it works well enough for what I need. Eventually I’ll be moving to Apache 2 and can throw this stop-gap code away, but it at least lets me get up and running with mongrel sooner, rather than later.
Reader Comments
3 Oct 2006
3 Oct 2006
4 Oct 2006
4 Oct 2006