Class: Mongrel::DirHandler
- Inherits:
-
HttpHandler
- Object
- HttpHandler
- Mongrel::DirHandler
- Defined in:
- lib/mongrel/handlers.rb
Overview
Serves the contents of a directory. You give it the path to the root where the files are located, and it tries to find the files based on the PATH_INFO inside the directory. If the requested path is a directory then it returns a simple directory listing.
It does a simple protection against going outside it’s root path by converting all paths to an absolute expanded path, and then making sure that the final expanded path includes the root path. If it doesn’t than it simply gives a 404.
Constant Summary collapse
- MIME_TYPES =
{ ".css" => "text/css", ".gif" => "image/gif", ".htm" => "text/html", ".html" => "text/html", ".jpeg" => "image/jpeg", ".jpg" => "image/jpeg", ".js" => "text/javascript", ".png" => "image/png", ".swf" => "application/x-shockwave-flash", ".txt" => "text/plain" }
Instance Attribute Summary collapse
-
#path ⇒ Object
readonly
Returns the value of attribute path.
Class Method Summary collapse
-
.add_mime_type(extension, type) ⇒ Object
There is a small number of default mime types for extensions, but this lets you add any others you’ll need when serving content.
Instance Method Summary collapse
-
#can_serve(path_info) ⇒ Object
Checks if the given path can be served and returns the full path (or nil if not).
-
#initialize(path, listing_allowed = true, index_html = "index.html") ⇒ DirHandler
constructor
You give it the path to the directory root and an (optional).
-
#process(request, response) ⇒ Object
Process the request to either serve a file or a directory listing if allowed (based on the listing_allowed paramter to the constructor).
-
#send_dir_listing(base, dir, response) ⇒ Object
Returns a simplistic directory listing if they’re enabled, otherwise a 403.
-
#send_file(req, response) ⇒ Object
Sends the contents of a file back to the user.
Constructor Details
#initialize(path, listing_allowed = true, index_html = "index.html") ⇒ DirHandler
You give it the path to the directory root and an (optional)
60 61 62 63 64 |
# File 'lib/mongrel/handlers.rb', line 60 def initialize(path, listing_allowed=true, index_html="index.html") @path = File.(path) @listing_allowed=listing_allowed @index_html = index_html end |
Instance Attribute Details
#path ⇒ Object (readonly)
Returns the value of attribute path.
57 58 59 |
# File 'lib/mongrel/handlers.rb', line 57 def path @path end |
Class Method Details
.add_mime_type(extension, type) ⇒ Object
There is a small number of default mime types for extensions, but this lets you add any others you’ll need when serving content.
175 176 177 |
# File 'lib/mongrel/handlers.rb', line 175 def DirHandler::add_mime_type(extension, type) MIME_TYPES[extension] = type end |
Instance Method Details
#can_serve(path_info) ⇒ Object
Checks if the given path can be served and returns the full path (or nil if not).
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/mongrel/handlers.rb', line 67 def can_serve(path_info) req = File.(File.join(@path,path_info), @path) if req.index(@path) == 0 and File.exist? req # it exists and it's in the right location if File.directory? req # the request is for a directory index = File.join(req, @index_html) if File.exist? index # serve the index return index elsif @listing_allowed # serve the directory req else # do not serve anything return nil end else # it's a file and it's there return req end else # does not exist or isn't in the right spot return nil end end |
#process(request, response) ⇒ Object
Process the request to either serve a file or a directory listing if allowed (based on the listing_allowed paramter to the constructor).
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/mongrel/handlers.rb', line 149 def process(request, response) req = can_serve request.params['PATH_INFO'] if not req # not found, return a 404 response.start(404) do |head,out| out << "File not found" end else begin if File.directory? req send_dir_listing(request.params["REQUEST_URI"],req, response) else send_file(req, response) end rescue => details response.reset response.start(403) do |head,out| out << "Error accessing file: #{details}" out << details.backtrace.join("\n") end end end end |
#send_dir_listing(base, dir, response) ⇒ Object
Returns a simplistic directory listing if they’re enabled, otherwise a 403. Base is the base URI from the REQUEST_URI, dir is the directory to serve on the file system (comes from can_serve()), and response is the HttpResponse object to send the results on.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/mongrel/handlers.rb', line 100 def send_dir_listing(base, dir, response) # take off any trailing / so the links come out right base.chop! if base[-1] == "/"[-1] if @listing_allowed response.start(200) do |head,out| head['Content-Type'] = "text/html" out << "<html><head><title>Directory Listing</title></head><body>" Dir.entries(dir).each do |child| next if child == "." if child == ".." out << "<a href=\"#{base}/#{child}\">Up to parent..</a><br/>" else out << "<a href=\"#{base}/#{child}\">#{child}</a><br/>" end end out << "</body></html>" end else response.start(403) do |head,out| out.write("Directory listings not allowed") end end end |
#send_file(req, response) ⇒ Object
Sends the contents of a file back to the user. Not terribly efficient since it’s opening and closing the file for each read.
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/mongrel/handlers.rb', line 129 def send_file(req, response) response.start(200) do |head,out| # set the mime type from our map based on the ending dot_at = req.rindex(".") if dot_at ext = req[dot_at .. -1] if MIME_TYPES[ext] head['Content-Type'] = MIME_TYPES[ext] end end open(req, "rb") do |f| out.write(f.read) end end end |