Sometimes you don't really want to handle a request, but you want to be able to modify the results coming in or going out of the server dynamically. Mongrel's HttpHandler classes can do this since they by default act in a chain. In this situation you are ostensibly writing a "filter," which is really just a handler that modifies its results.
This brings up another point: handlers don't have to do any processing. It's perfectly legal for them to make a decision and do nothing, allowing the remaining handlers do their thing instead.
For our first filter we're going to write a class that removes any HTTP_USER_AGENT headers coming in, and then another filter that deflate compresses (deflates) its output. First the UserAgentRemover:
class UserAgentRemover < Mongrel::HttpHandler def process(req, resp) if req.params.delete "HTTP_USER_AGENT" STDERR.puts "Removed a user agent" end end end uri "/dumped", :handler => UserAgentRemover.new, :in_front => true
Pretty simple, we just delete it from the params hash and log a simple message. If you need to do simple logging then use STDERR since this is written to the log/mongrel.log file or the console and isn't hijacked by the framework. If you need to do serious logging then use Ruby's Logger.
The above code assumes that you put this in the mongrel.conf after the first uri call. This is why this block of code as a :in_front parameter, which tells the Configurator that you want this handler moved to the front of the chain.
Run your mongrel_rails again and hit the /dumped URI to see that HTTP_USER_AGENT is actually removed.
This ability to modify requests as they come in with simple handler chains means that you can perform security checks, clean up requests, do file processing, and other tasks prior to Rails or another framework getting the results. We'll now write another handler that does nearly the same thing but it takes results and translates them into deflate form. Add this next block to your mongrel.conf file:
Obviously this handler is more involved, but it's a good example of doing something useful with HttpHandlers as filters. Let's walk through it:
This filter isn't put on the handler chain with :in_front so it will happen after ParamDumper. If we were to draw a picture of this setup it'd look like Figure 6.2, even though in the mongrel.conf we added them in a different order. This is necessary since, if you need to put a filter in front of say RailsHandler, then :in_front lets you do that.
Figure 6.2. Handler Chain Processing