Class: Utopia::Middleware::Static::LocalFile
- Defined in:
- lib/utopia/middleware/static.rb
Instance Attribute Summary collapse
-
#etag ⇒ Object
readonly
Returns the value of attribute etag.
-
#path ⇒ Object
readonly
Returns the value of attribute path.
-
#range ⇒ Object
readonly
Returns the value of attribute range.
-
#root ⇒ Object
readonly
Returns the value of attribute root.
Instance Method Summary collapse
- #each ⇒ Object
- #full_path ⇒ Object
-
#initialize(root, path) ⇒ LocalFile
constructor
A new instance of LocalFile.
- #modified?(env) ⇒ Boolean
- #mtime_date ⇒ Object
- #serve(env, response_headers) ⇒ Object
- #size ⇒ Object
-
#to_path ⇒ Object
Fit in with Rack::Sendfile.
Constructor Details
Instance Attribute Details
#etag ⇒ Object (readonly)
Returns the value of attribute etag.
63 64 65 |
# File 'lib/utopia/middleware/static.rb', line 63 def etag @etag end |
#path ⇒ Object (readonly)
Returns the value of attribute path.
62 63 64 |
# File 'lib/utopia/middleware/static.rb', line 62 def path @path end |
#range ⇒ Object (readonly)
Returns the value of attribute range.
64 65 66 |
# File 'lib/utopia/middleware/static.rb', line 64 def range @range end |
Instance Method Details
#each ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/utopia/middleware/static.rb', line 83 def each File.open(full_path, "rb") do |file| file.seek(@range.begin) remaining = @range.end - @range.begin+1 while remaining > 0 break unless part = file.read([8192, remaining].min) remaining -= part.length yield part end end end |
#full_path ⇒ Object
71 72 73 |
# File 'lib/utopia/middleware/static.rb', line 71 def full_path File.join(@root, @path.components) end |
#modified?(env) ⇒ Boolean
98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/utopia/middleware/static.rb', line 98 def modified?(env) if modified_since = env['HTTP_IF_MODIFIED_SINCE'] return false if File.mtime(full_path) <= Time.parse(modified_since) end if = env['HTTP_IF_NONE_MATCH'] = .split(/\s*,\s*/) return false if .include?(etag) || .include?('*') end return true end |
#mtime_date ⇒ Object
75 76 77 |
# File 'lib/utopia/middleware/static.rb', line 75 def mtime_date File.mtime(full_path).httpdate end |
#serve(env, response_headers) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/utopia/middleware/static.rb', line 111 def serve(env, response_headers) ranges = Rack::Utils.byte_ranges(env, size) response = [200, response_headers, self] # LOG.info("Requesting ranges: #{ranges.inspect} (#{size})") if ranges.nil? || ranges.length > 1 # No ranges, or multiple ranges (which we don't support): # TODO: Support multiple byte-ranges response[0] = 200 response[1]["Content-Length"] = size.to_s @range = 0..size-1 elsif ranges.empty? # Unsatisfiable. Return error, and file size: response = Middleware::failure(416, "Invalid range specified.") response[1]["Content-Range"] = "bytes */#{size}" return response else # Partial content: @range = ranges[0] response[0] = 206 response[1]["Content-Range"] = "bytes #{@range.begin}-#{@range.end}/#{size}" response[1]["Content-Length"] = (@range.end - @range.begin+1).to_s size = @range.end - @range.begin + 1 end # LOG.info("Response for #{self.full_path}: #{response.inspect}") LOG.info "Serving file #{full_path.inspect}, range #{@range.inspect}" return response end |
#size ⇒ Object
79 80 81 |
# File 'lib/utopia/middleware/static.rb', line 79 def size File.size(full_path) end |
#to_path ⇒ Object
Fit in with Rack::Sendfile
67 68 69 |
# File 'lib/utopia/middleware/static.rb', line 67 def to_path full_path end |