Class: Rack::File

Inherits:
Object show all
Defined in:
lib/gems/rack-0.4.0/lib/rack/file.rb

Overview

Rack::File serves files below the root given, according to the path info of the Rack request.

Handlers can detect if bodies are a Rack::File, and use mechanisms like sendfile on the path.

Constant Summary collapse

F =
::File
MIME_TYPES =

:stopdoc: From WEBrick with some additions.

{
  "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",
  "mp3"   => "audio/mpeg",
  "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",
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root) ⇒ File

Returns a new instance of File.



14
15
16
# File 'lib/gems/rack-0.4.0/lib/rack/file.rb', line 14

def initialize(root)
  @root = root
end

Instance Attribute Details

#pathObject

Returns the value of attribute path.



12
13
14
# File 'lib/gems/rack-0.4.0/lib/rack/file.rb', line 12

def path
  @path
end

#rootObject

Returns the value of attribute root.



11
12
13
# File 'lib/gems/rack-0.4.0/lib/rack/file.rb', line 11

def root
  @root
end

Instance Method Details

#_call(env) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/gems/rack-0.4.0/lib/rack/file.rb', line 24

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"]))
  ext = F.extname(@path)[1..-1]

  if F.file?(@path) && F.readable?(@path)
    [200, {
       "Last-Modified"  => F.mtime(@path).httpdate,
       "Content-Type"   => MIME_TYPES[ext] || "text/plain",
       "Content-Length" => F.size(@path).to_s
     }, self]
  else
    body = "File not found: #{env["PATH_INFO"]}\n"
    size = body.respond_to?(:bytesize) ? body.bytesize : body.size
    [404, {"Content-Type" => "text/plain", "Content-Length" => size.to_s}, [body]]
  end
end

#call(env) ⇒ Object



18
19
20
# File 'lib/gems/rack-0.4.0/lib/rack/file.rb', line 18

def call(env)
  dup._call(env)
end

#eachObject



47
48
49
50
51
52
53
# File 'lib/gems/rack-0.4.0/lib/rack/file.rb', line 47

def each
  F.open(@path, "rb") { |file|
    while part = file.read(8192)
      yield part
    end
  }
end