Fix for serving static files with Mongrel using Camping
Last night, at our Ruby hack night, I had some assistance debugging a known issue with Why’s magic framework, Camping. Ok, let me be honest; Nathaniel fixed the issue while I sat and observed.
The issue occurs when you try to serve static content like images and style sheets using Mongrel. You can use Why’s example to spin up a controller to handle the static content using X-SendFile like this:
module Camping::Controllers
class Static < R '/static/(.+)'
MIME_TYPES = {'.css' => 'text/css', '.js' => 'text/javascript', '.jpg' => 'image/jpeg'}
PATH = File.expand_path(File.dirname(__FILE__))
def get(path)
@headers['Content-Type'] = MIME_TYPES[path[/\.\w+$/, 0]] || "text/plain"
unless path.include? ".." # prevent directory traversal attacks
@headers['X-Sendfile'] = "#{PATH}/static/#{path}"
else
@status = "403"
"403 - Invalid path"
end
end
end
end
This code should allow Mongrel to serve any file under the “static” directory. This works as expected on non-Win32 platforms.
To correct this issue on Windows, a change has to be made to the Camping handler in Mongrel. Here is a diff that depicts the fix:
--- camping.rb.orig 2007-10-04 20:36:01.000000000 -0400
+++ camping.rb 2007-10-04 21:31:42.000000000 -0400
@@ -38,7 +38,7 @@
@@file_only_methods = ["GET","HEAD"]
def initialize(klass)
- @files = Mongrel::DirHandler.new("/",false)
+ @files = Mongrel::DirHandler.new(File.dirname(klass.instance_eval{@script}),false)
@guard = Mutex.new
@klass = klass
end
This change will impact the “path” parameter that is passed into the controller. Subsequently, the controller should be modified to take advantage of this change:
module Camping::Controllers
class Static < R '/static/(.+)'
MIME_TYPES = {'.css' => 'text/css', '.js' => 'text/javascript', '.jpg' => 'image/jpeg'}
def get(path)
@headers['Content-Type'] = MIME_TYPES[path[/\.\w+$/, 0]] || "text/plain"
unless path.include? ".." # prevent directory traversal attacks
@headers['X-Sendfile'] = path
else
@status = "403"
"403 - Invalid path"
end
end
end
end
As you may have guessed, this will break the contract with non-Win32 platforms, which is why I have not suggested this change to the Mongrel group. But, I hope you find it useful.
Hi decent little post right right right here, was just wondering if i could quote some of it in the post im executing (I will credit and hyperlink back again below!). Drop me a message if thats not ok. you’ll be able to quote any of my stuff as prolonged as you hyperlink back again to it 🙂 Also fantastic template you use below would you thoughts telling me where by by you got it :D. Sorry for my english 🙂
Joseph Briggeman
June 13, 2010 at 11:59 am