Class: StaticRails::FileHandler
- Inherits:
-
Object
- Object
- StaticRails::FileHandler
- Defined in:
- lib/static-rails/file_handler.rb
Overview
This class was extracted from Ruby on Rails:
- actionpack/lib/action_dispatch/middleware/static.rb
Copyright © 2005-2020 David Heinemeier Hansson, Ryan Edward Hall, Jeremy Daer
License here: github.com/rails/rails/blob/master/MIT-LICENSE
This endpoint serves static files from disk using Rack::File.
URL paths are matched with static files according to expected conventions: path
, path
.html, path
/index.html.
Precompressed versions of these files are checked first. Brotli (.br) and gzip (.gz) files are supported. If path
.br exists, this endpoint returns that file with a Content-Encoding: br header.
If no matching file is found, this endpoint responds 404 Not Found.
Pass the root
directory to search for matching files, an optional index: “index” to change the default path
/index.html, and optional additional response headers.
Constant Summary collapse
- PRECOMPRESSED =
Accept-Encoding value -> file extension
{ "br" => ".br", "gzip" => ".gz", "identity" => nil }
Instance Method Summary collapse
- #attempt(env) ⇒ Object
- #call(env) ⇒ Object
-
#find_file(path_info, accept_encoding:) ⇒ Object
Match a URI path to a static file to be served.
-
#initialize(root, index: "index", headers: {}, precompressed: %i[br gzip],, compressible_content_types: /\A(?:text\/|application\/javascript)/) ⇒ FileHandler
constructor
A new instance of FileHandler.
- #serve(request, filepath, content_headers) ⇒ Object
Constructor Details
#initialize(root, index: "index", headers: {}, precompressed: %i[br gzip],, compressible_content_types: /\A(?:text\/|application\/javascript)/) ⇒ FileHandler
Returns a new instance of FileHandler.
32 33 34 35 36 37 38 39 40 |
# File 'lib/static-rails/file_handler.rb', line 32 def initialize(root, index: "index", headers: {}, precompressed: %i[br gzip], compressible_content_types: /\A(?:text\/|application\/javascript)/) @root = root.chomp("/").b @index = index @precompressed = Array(precompressed).map(&:to_s) | %w[identity] @compressible_content_types = compressible_content_types @file_server = ::Rack::File.new(@root, headers) end |
Instance Method Details
#attempt(env) ⇒ Object
46 47 48 49 50 51 52 53 54 |
# File 'lib/static-rails/file_handler.rb', line 46 def attempt(env) request = Rack::Request.new env if request.get? || request.head? if (found = find_file(request.path_info, accept_encoding: request.accept_encoding)) serve request, *found end end end |
#call(env) ⇒ Object
42 43 44 |
# File 'lib/static-rails/file_handler.rb', line 42 def call(env) attempt(env) || @file_server.call(env) end |
#find_file(path_info, accept_encoding:) ⇒ Object
Match a URI path to a static file to be served.
Used by the Static
class to negotiate a servable file in the public/
directory (see Static#call).
Checks for path
, path
.html, and path
/index.html files, in that order, including .br and .gzip compressed extensions.
If a matching file is found, the path and necessary response headers (Content-Type, Content-Encoding) are returned.
79 80 81 82 83 84 85 |
# File 'lib/static-rails/file_handler.rb', line 79 def find_file(path_info, accept_encoding:) each_candidate_filepath(path_info) do |filepath, content_type| if (response = try_files(filepath, content_type, accept_encoding: accept_encoding)) return response end end end |
#serve(request, filepath, content_headers) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/static-rails/file_handler.rb', line 56 def serve(request, filepath, content_headers) original, request.path_info = request.path_info, ::Rack::Utils.escape_path(filepath).b @file_server.call(request.env).tap do |status, headers, body| # Omit Content-Encoding/Type/etc headers for 304 Not Modified if status != 304 headers.update(content_headers) end end ensure request.path_info = original end |