6 # Rack::File serves files below the +root+ given, according to the
7 # path info of the Rack request.
9 # Handlers can detect if bodies are a Rack::File, and use mechanisms
10 # like sendfile on the +path+.
29 @path_info = Utils
.unescape(env["PATH_INFO"])
30 return forbidden
if @path_info.include? ".."
32 @path = F
.join(@root, @path_info)
35 if F
.file
?(@path) && F
.readable
?(@path)
40 rescue SystemCallError
47 [403, {"Content-Type" => "text/plain",
48 "Content-Length" => body
.size
.to_s
},
53 # We check via File::size? whether this file provides size info
54 # via stat (e.g. /proc files often don't), otherwise we have to
55 # figure it out by reading the whole file into memory. And while
56 # we're at it we also use this as body then.
59 if size
= F
.size
?(@path)
62 body
= [F
.read(@path)]
63 size
= Utils
.bytesize(body
.first
)
67 "Last-Modified" => F
.mtime(@path).httpdate
,
68 "Content-Type" => Mime
.mime_type(F
.extname(@path), 'text/plain'),
69 "Content-Length" => size
.to_s
74 body
= "File not found: #{@path_info}\n"
75 [404, {"Content-Type" => "text/plain",
76 "Content-Length" => body
.size
.to_s
},
81 F
.open(@path, "rb") { |file
|
82 while part
= file
.read(8192)