Class: Rack::Directory
- Inherits:
-
Object
- Object
- Rack::Directory
- Defined in:
- rack/rack/directory.rb
Overview
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.
Constant Summary
- 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> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <style type='text/css'> table { width:100%%; } .name { text-align:left; } .size, .mtime { text-align:right; } .type { width:11em; } .mtime { width:15em; } </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
- F =
::File
- FILESIZE_FORMAT =
Stolen from Ramaze
[ ['%.1fT', 1 << 40], ['%.1fG', 1 << 30], ['%.1fM', 1 << 20], ['%.1fK', 1 << 10], ]
Instance Attribute Summary (collapse)
-
- (void) files
readonly
Returns the value of attribute files.
-
- (void) path
Returns the value of attribute path.
-
- (void) root
Returns the value of attribute root.
Instance Method Summary (collapse)
- - (void) _call(env)
- - (void) call(env)
- - (void) check_forbidden
- - (void) each
- - (void) entity_not_found
- - (void) filesize_format(int)
-
- (Directory) initialize(root, app = nil)
constructor
A new instance of Directory.
- - (void) list_directory
-
- (void) list_path
TODO: add correct response if not readable, not sure if 404 is the best option.
- - (void) stat(node, max = 10)
Constructor Details
- (Directory) initialize(root, app = nil)
Returns a new instance of Directory
45 46 47 48 |
# File 'rack/rack/directory.rb', line 45 def initialize(root, app=nil) @root = F.(root) @app = app || Rack::File.new(@root) end |
Instance Attribute Details
- (void) files (readonly)
Returns the value of attribute files
42 43 44 |
# File 'rack/rack/directory.rb', line 42 def files @files end |
- (void) path
Returns the value of attribute path
43 44 45 |
# File 'rack/rack/directory.rb', line 43 def path @path end |
- (void) root
Returns the value of attribute root
43 44 45 |
# File 'rack/rack/directory.rb', line 43 def root @root end |
Instance Method Details
- (void) _call(env)
56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'rack/rack/directory.rb', line 56 def _call(env) @env = env @script_name = env['SCRIPT_NAME'] @path_info = Utils.unescape(env['PATH_INFO']) if forbidden = check_forbidden forbidden else @path = F.join(@root, @path_info) list_path end end |
- (void) call(env)
50 51 52 |
# File 'rack/rack/directory.rb', line 50 def call(env) dup._call(env) end |
- (void) check_forbidden
69 70 71 72 73 74 75 76 77 |
# File 'rack/rack/directory.rb', line 69 def check_forbidden return unless @path_info.include? ".." body = "Forbidden\n" size = Rack::Utils.bytesize(body) return [403, {"Content-Type" => "text/plain", "Content-Length" => size.to_s, "X-Cascade" => "pass"}, [body]] end |
- (void) each
137 138 139 140 141 142 |
# File 'rack/rack/directory.rb', line 137 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 |
- (void) entity_not_found
129 130 131 132 133 134 135 |
# File 'rack/rack/directory.rb', line 129 def entity_not_found body = "Entity not found: #{@path_info}\n" size = Rack::Utils.bytesize(body) return [404, {"Content-Type" => "text/plain", "Content-Length" => size.to_s, "X-Cascade" => "pass"}, [body]] end |
- (void) filesize_format(int)
153 154 155 156 157 158 159 |
# File 'rack/rack/directory.rb', line 153 def filesize_format(int) FILESIZE_FORMAT.each do |format, size| return format % (int.to_f / size) if int >= size end int.to_s + 'B' end |
- (void) list_directory
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'rack/rack/directory.rb', line 79 def list_directory @files = [['../','Parent Directory','','','']] glob = F.join(@path, '*') url_head = (@script_name.split('/') + @path_info.split('/')).map do |part| Rack::Utils.escape part end Dir[glob].sort.each do |node| stat = stat(node) next unless stat basename = F.basename(node) ext = F.extname(node) url = F.join(*url_head + [Rack::Utils.escape(basename)]) size = stat.size type = stat.directory? ? 'directory' : Mime.mime_type(ext) size = stat.directory? ? '-' : filesize_format(size) mtime = stat.mtime.httpdate url << '/' if stat.directory? basename << '/' if stat.directory? @files << [ url, basename, size, type, mtime ] end return [ 200, {'Content-Type'=>'text/html; charset=utf-8'}, self ] end |
- (void) list_path
TODO: add correct response if not readable, not sure if 404 is the best option
115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'rack/rack/directory.rb', line 115 def list_path @stat = F.stat(@path) if @stat.readable? return @app.call(@env) if @stat.file? return list_directory if @stat.directory? else raise Errno::ENOENT, 'No such file or directory' end rescue Errno::ENOENT, Errno::ELOOP return entity_not_found end |
- (void) stat(node, max = 10)
107 108 109 110 111 |
# File 'rack/rack/directory.rb', line 107 def stat(node, max = 10) F.stat(node) rescue Errno::ENOENT, Errno::ELOOP return nil end |