Class: WEBrick::HTTPReverseProxyServer

Inherits:
HTTPServer
  • Object
show all
Defined in:
lib/webrick/httpreverseproxyserver.rb,
lib/webrick/httpreverseproxyserver/version.rb

Overview

Use case

You have several services running as different users for security purposes (they might even be chrooted). In production we use apache but for testing I prefer to use webrick because I find it more flexible for unit testing.

Configuration

The proxy mapping is modelled on the ProxyPass directive of apache. For example:

original URL              proxies  private URL
------------------------    ==>   --------------------------
/marmalade/index.html             localhost:8081/index.html
/apps/vegemite?id=123             localhost:8082/apps/someservlet?id=123

Its not designed to be mod_rewrite (eg. query_string cannot be transformed), but you can specify proxy rules that match a fragment of the original URL and replace it with something else while also sending the new URL to the proxied host and port. So the rules in that example are specified thus:

serverConfig = {
  :Port => 80,
  :ProxyRules => [
    WEBrick::ProxyRule.new('^/marmalade/', 'localhost', 8081, '/'),
    WEBrick::ProxyRule.new('vegemite', 'localhost', 8082, 'someservlet')
  ]
}
server = WEBrick::HTTPReverseProxyServer.new(serverConfig)

ProxyRules is an array so the order is important - the first match is used! If no matches are found then the URL is handled by the local web server normally.

Running a server

You may start a server, just like any WEBrick server.

To get started using RubyGems, use the following example:

require 'rubygems'
require 'webrick/httpreverseproxyserver'

# create a configuration and a server instance
serverConfig = {
  :Port => 8080,
  :ProxyRules => [WEBrick::ProxyRule.new('/', 'www.example.com', 80, '/')]
}
server = WEBrick::HTTPReverseProxyServer.new(serverConfig)

# catch ^C to quit cleanly
trap("INT") { server.shutdown }

# start request-response-loop
server.start

Advanced inspection

In order to better analyse an HTTP stream, you may easily subclass HTTPReverseProxyServer to add advanced request/response inspection.

The following example implements basic Cookie logging:

class CookieLoggingProxy < WEBrick::HTTPReverseProxyServer
  def service(request, response)
    super.tap do
      puts
      puts request.request_line
      print_cookie_headers request.header
      puts response.status_line
      print_cookie_headers response.header
    end
  end

  def print_cookie_headers(headers)
    headers.each do |key, val|
      puts "#{key}: #{val}" if key =~ /cookie/i
    end
  end
end

Constant Summary

VERSION =
'0.1.2'

Instance Method Summary (collapse)

Instance Method Details

- (Object) service(request, response)



96
97
98
99
100
101
102
103
# File 'lib/webrick/httpreverseproxyserver.rb', line 96

def service(request, response)
  rule = first_matching_proxy_rule(request)
  if rule.nil?
    super(request, response)
  else
    service_proxy(request, response, rule)
  end
end