aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller/vendor/rack-0.4.0/rack/directory.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_controller/vendor/rack-0.4.0/rack/directory.rb')
-rw-r--r--actionpack/lib/action_controller/vendor/rack-0.4.0/rack/directory.rb158
1 files changed, 158 insertions, 0 deletions
diff --git a/actionpack/lib/action_controller/vendor/rack-0.4.0/rack/directory.rb b/actionpack/lib/action_controller/vendor/rack-0.4.0/rack/directory.rb
new file mode 100644
index 0000000000..31e0db8449
--- /dev/null
+++ b/actionpack/lib/action_controller/vendor/rack-0.4.0/rack/directory.rb
@@ -0,0 +1,158 @@
+require 'time'
+
+module Rack
+ # Rack::Directory serves entries below the +root+ given, according to the
+ # path info of the Rack request. If a directory is found, the file's contents
+ # will be presented in an html based index. If a file is found, the env will
+ # be passed to the specified +app+.
+ #
+ # If +app+ is not specified, a Rack::File of the same +root+ will be used.
+
+ class Directory
+ DIR_FILE = "<tr><td class='name'><a href='%s'>%s</a></td><td class='size'>%s</td><td class='type'>%s</td><td class='mtime'>%s</td></tr>"
+ DIR_PAGE = <<-PAGE
+<html><head>
+ <title>%s</title>
+ <style type='text/css'>
+table { width:100%%; }
+.name { text-align:left; }
+.size, .mtime { text-align:right; }
+ </style>
+</head><body>
+<h1>%s</h1>
+<hr />
+<table>
+ <tr>
+ <th class='name'>Name</th>
+ <th class='size'>Size</th>
+ <th class='type'>Type</th>
+ <th class='mtime'>Last Modified</th>
+ </tr>
+%s
+</table>
+<hr />
+</body></html>
+ PAGE
+
+ attr_reader :files
+ attr_accessor :root, :path
+
+ def initialize(root, app=nil)
+ @root = root
+ @app = app
+ unless defined? @app
+ @app = Rack::File.new(@root)
+ end
+ end
+
+ def call(env)
+ dup._call(env)
+ end
+
+ F = ::File
+
+ def _call(env)
+ if env["PATH_INFO"].include? ".."
+ body = "Forbidden\n"
+ size = body.respond_to?(:bytesize) ? body.bytesize : body.size
+ return [403, {"Content-Type" => "text/plain","Content-Length" => size.to_s}, [body]]
+ end
+
+ @path = F.join(@root, Utils.unescape(env['PATH_INFO']))
+
+ if F.exist?(@path) and F.readable?(@path)
+ if F.file?(@path)
+ return @app.call(env)
+ elsif F.directory?(@path)
+ @files = [['../','Parent Directory','','','']]
+ sName, pInfo = env.values_at('SCRIPT_NAME', 'PATH_INFO')
+ Dir.entries(@path).sort.each do |file|
+ next if file[0] == ?.
+ fl = F.join(@path, file)
+ sz = F.size(fl)
+ url = F.join(sName, pInfo, file)
+ type = F.directory?(fl) ? 'directory' :
+ MIME_TYPES.fetch(F.extname(file)[1..-1],'unknown')
+ size = (type!='directory' ? (sz<10240 ? "#{sz}B" : "#{sz/1024}KB") : '-')
+ mtime = F.mtime(fl).httpdate
+ @files << [ url, file, size, type, mtime ]
+ end
+ return [ 200, {'Content-Type'=>'text/html'}, self ]
+ end
+ end
+
+ body = "Entity not found: #{env["PATH_INFO"]}\n"
+ size = body.respond_to?(:bytesize) ? body.bytesize : body.size
+ return [404, {"Content-Type" => "text/plain", "Content-Length" => size.to_s}, [body]]
+ end
+
+ def each
+ show_path = @path.sub(/^#{@root}/,'')
+ files = @files.map{|f| DIR_FILE % f }*"\n"
+ page = DIR_PAGE % [ show_path, show_path , files ]
+ page.each_line{|l| yield l }
+ end
+
+ def each_entry
+ @files.each{|e| yield e }
+ end
+
+ # From WEBrick.
+ MIME_TYPES = {
+ "ai" => "application/postscript",
+ "asc" => "text/plain",
+ "avi" => "video/x-msvideo",
+ "bin" => "application/octet-stream",
+ "bmp" => "image/bmp",
+ "class" => "application/octet-stream",
+ "cer" => "application/pkix-cert",
+ "crl" => "application/pkix-crl",
+ "crt" => "application/x-x509-ca-cert",
+ #"crl" => "application/x-pkcs7-crl",
+ "css" => "text/css",
+ "dms" => "application/octet-stream",
+ "doc" => "application/msword",
+ "dvi" => "application/x-dvi",
+ "eps" => "application/postscript",
+ "etx" => "text/x-setext",
+ "exe" => "application/octet-stream",
+ "gif" => "image/gif",
+ "htm" => "text/html",
+ "html" => "text/html",
+ "jpe" => "image/jpeg",
+ "jpeg" => "image/jpeg",
+ "jpg" => "image/jpeg",
+ "js" => "text/javascript",
+ "lha" => "application/octet-stream",
+ "lzh" => "application/octet-stream",
+ "mov" => "video/quicktime",
+ "mpe" => "video/mpeg",
+ "mpeg" => "video/mpeg",
+ "mpg" => "video/mpeg",
+ "pbm" => "image/x-portable-bitmap",
+ "pdf" => "application/pdf",
+ "pgm" => "image/x-portable-graymap",
+ "png" => "image/png",
+ "pnm" => "image/x-portable-anymap",
+ "ppm" => "image/x-portable-pixmap",
+ "ppt" => "application/vnd.ms-powerpoint",
+ "ps" => "application/postscript",
+ "qt" => "video/quicktime",
+ "ras" => "image/x-cmu-raster",
+ "rb" => "text/plain",
+ "rd" => "text/plain",
+ "rtf" => "application/rtf",
+ "sgm" => "text/sgml",
+ "sgml" => "text/sgml",
+ "tif" => "image/tiff",
+ "tiff" => "image/tiff",
+ "txt" => "text/plain",
+ "xbm" => "image/x-xbitmap",
+ "xls" => "application/vnd.ms-excel",
+ "xml" => "text/xml",
+ "xpm" => "image/x-xpixmap",
+ "xwd" => "image/x-xwindowdump",
+ "zip" => "application/zip",
+ }
+ end
+end