mongrel and feedtools


In case anyone's wondering why the feedreader plugin involves a patch to feedtools, here's the scoop. Mongrel monkey patches Kernel and IO, adding modifying their open methods (you can find this in debug.rb). Feedtools relies on htree which when parsing something as xml will attempt to open the object if it supports being opened. Now opening a String is generally not possible (open is private), but with the modification open in Kernel the method is suddenly available. Unfortunately, the monkey patched implementation of open only adds a logging/diagnostic facility onto open calls and then passes the call onto the class's original open method. Since String doesn't have an open method by default, this fails badly.

lib/mongrel/debug.rb:121:in `initialize' lib/mongrel/debug.rb:121:in `orig_open' lib/mongrel/debug.rb:121:in `open' lib/feed_tools/vendor/htree/parse.rb:65:in `parse_as' lib/feed_tools/vendor/htree/parse.rb:51:in `parse_xml' lib/feed_tools/vendor/htree/fstr.rb:11:in `with_frozen_string_hash' lib/feed_tools/vendor/htree/parse.rb:50:in `parse_xml' lib/feed_tools/helpers/html_helper.rb:300:in `sanitize_html' lib/feed_tools/helpers/html_helper.rb:564:in `process_text_construct' lib/feed_tools/feed_item.rb:220:in `title'

Here's the mongrel trouble-maker:

module Kernel
  alias_method :orig_open, :open

  def open(*arg, &blk)
    $open_files[self] = arg[0]
    orig_open(*arg,&blk)
  end

  def log_open_files
    open_counts = {}
    $open_files.each do |f,args|
      open_counts[args] ||= 0
      open_counts[args] += 1
    end
    MongrelDbg::trace(:files, open_counts.to_yaml)
  end
end  
 

Here's the original duck-typing based parse.rb snippet from htree:


    elsif (input.respond_to? :open)  # Pathname, URI with open-uri
      input.open {|f|
        input = f.read.untaint
        input_charset = f.charset if f.respond_to? :charset
      }     

I'd say this pretty much illustrates the problems that can be caused by monkey patching. I'm pretty sure the solution is pretty simple on the mongrel side, probably a switch over to monkey patching based on a flag .