Getting Out of a Jam with Object.extend
A Rails project I’m currently working on is hosted on an array of virtual machines running Passenger behind a Big IP load balancer. One of the interesting features of Big IP is that it can be configured with an SSL certificate allowing it to encrypt HTTP traffic for a domain and eliminating the need to configure each web server with its own SSL certificate. This is great because it not only saves money (since you only have to purchase one certificate), but also cuts down on server maintenance.
In this configuration, communication between the browser and the website is encrypted by Big IP, but communication between the load balancer and the application servers is not. To the Rails application, all of the traffic looks like plain HTTP. Unfortunately, this means that any calls to redirect_to will cause the browser to leave the security of the HTTPS protocol. This is because redirect_to examines the request.protocol parameter, which will always be "http://". What’s needed in this scenario is a way to fool Rails into thinking the request protocol is really "https://".
One surreptitious way to accomplish this goal is to override the request.protocol method. By creating a module with a protocol method that always returns "https://" and extending the request object with this module, we can make sure that redirections will always keep the browser on a secure channel. The code follows:
You may have also noticed the Object.extend trick being used to add application-specific configuration to the built-in Rails::Configuration class. If you need lots of application-specific configuration there are better ways to expose it, but for our little protocol hack Object.extend gets the job done with minimal fuss.
