Class: Closure::FileResponse
- Inherits:
-
Object
- Object
- Closure::FileResponse
- Defined in:
- lib/closure/file_response.rb
Overview
Can be used as a Rack::Response. Provides advanced cache control.
Instance Attribute Summary (collapse)
-
- (String) filename
(also: #to_path)
readonly
Filename attribute.
Instance Method Summary (collapse)
-
- each {|String| ... }
Support using self as a response body.
-
- (Array) finish
Present the final response for rack.
-
- (Boolean) found?
Was the file in the system and ready to be served?.
-
- (FileResponse) initialize(env, filename, content_type = nil)
constructor
A new instance of FileResponse.
Constructor Details
- (FileResponse) initialize(env, filename, content_type = nil)
A new instance of FileResponse
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/closure/file_response.rb', line 22 def initialize(env, filename, content_type = nil) @env = env @filename = filename @status = 200 @headers = {} @body = [] begin raise Errno::EPERM unless File.file?(filename) and File.readable?(filename) rescue SystemCallError @body = ["404 Not Found\n"] @headers["Content-Length"] = @body.first.size.to_s @headers["Content-Type"] = "text/plain" @headers["X-Cascade"] = "pass" @status = 404 return end # Caching strategy mod_since = Time.httpdate(env['HTTP_IF_MODIFIED_SINCE']) rescue nil last_modified = File.mtime(filename) @status = 304 and return if last_modified == mod_since @headers["Last-Modified"] = last_modified.httpdate if env['QUERY_STRING'] =~ /^[0-9]{9,10}$/ and last_modified == Time.at(env['QUERY_STRING'].to_i) @headers["Cache-Control"] = 'max-age=86400, public' # one day else @headers["Cache-Control"] = 'max-age=0, private, must-revalidate' end # Sending the file or reading an unknown length stream to send @body = self unless size = File.size?(filename) @body = [File.read(filename)] size = @body.first.respond_to?(:bytesize) ? @body.first.bytesize : @body.first.size end @headers["Content-Length"] = size.to_s @headers["Content-Type"] = content_type || Rack::Mime.mime_type(File.extname(filename), 'text/plain') end |
Instance Attribute Details
- (String) filename (readonly) Also known as: to_path
Filename attribute. Alias is used by some rack servers to detach from Ruby early.
74 75 76 |
# File 'lib/closure/file_response.rb', line 74 def filename @filename end |
Instance Method Details
- each {|String| ... }
Support using self as a response body.
63 64 65 66 67 68 69 |
# File 'lib/closure/file_response.rb', line 63 def each File.open(@filename, "rb") do |file| while part = file.read(8192) yield part end end end |
- (Array) finish
Present the final response for rack.
84 85 86 |
# File 'lib/closure/file_response.rb', line 84 def finish [@status, @headers, @body] end |
- (Boolean) found?
Was the file in the system and ready to be served?
78 79 80 |
# File 'lib/closure/file_response.rb', line 78 def found? @status == 200 or @status == 304 end |