page caching urls with space characters broken in webrick and mongrel

Page caching of urls with spaces in them using WEBrick and Mongrel is broken in Edge Rails (and Rails 1.1.6, where I started). This is due to the dispatch flow of control in both servers converting '+' in requested paths into ' ' chars, whereas the page caching system writes cache files for URLs with spaces in them out as encoded '+' characters

This issue does *not* occur with lighttpd, as the lighttpd.conf url rewriting to look for <name>.html does not convert '+' to ' ' when it looks for the file on the local filesystem to serve up.

I claim that we should fix WEBrick/Mongrel to also not convert '+' to ' ' when looking for a file on the local filesystem.

Dissenters or those who know more than I before I go down the ticket/patch/test path? Also, if I'm incorrect thinking this is the right place to discuss this pre-ticket let me know.

I only hesitate on the proposed fix as one assumes the culprit line in webrick_server.rb (detail below) was added for a reason, but it's not clear to me what specific scenario would have one wanting to serve up a local file with ' ' in its name via a request specified as '+'. And putting an actual space in filenames is so declasse.

More detail:

While investigating why using caches_page() to cache urls that have a space in them encoded as either '+' or '%20' doesn't work (the cache files are generated but never used, and continually regenerated on page reload) led me to this line in webrick_server.rb handle_file():

      path.gsub!('+', ' ') # Unescape + since FileHandler doesn't do so.

Commenting this line out restores page caching to proper functionality, as the filename is written to disk with '+' (and '%20' is also normalized to a '+' in the cache file filename), but this code converts them to an actual space character which then means the cache files are always incorrectly overlooked.

Similar line in mongrel's handlers.rb can_serve():

      req_path = File.expand_path(File.join(@path,HttpRequest.unescape(path_info)), @path)

where unescaping the path turns the '+' into a ' '.

- Walter Korman -- http://www.lemurware.com