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
-
#filename ⇒ String
(also: #to_path)
readonly
Filename attribute.
Instance Method Summary collapse
-
#each {|String| ... } ⇒ Object
Support using self as a response body.
-
#finish ⇒ Array
Present the final response for rack.
-
#found? ⇒ Boolean
Was the file in the system and ready to be served?.
-
#initialize(env, filename, content_type = nil) ⇒ FileResponse
constructor
A new instance of FileResponse.
Constructor Details
#initialize(env, filename, content_type = nil) ⇒ FileResponse
Returns 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
#filename ⇒ String (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| ... } ⇒ Object
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 |
#finish ⇒ Array
Present the final response for rack.
84 85 86 |
# File 'lib/closure/file_response.rb', line 84 def finish [@status, @headers, @body] end |
#found? ⇒ Boolean
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 |