class Middleware < Protocol::HTTP::Middleware
- Inherits from
Protocol::HTTP::Middleware- Includes
Localization::Resolver
A middleware which serves static files from the specified root directory.
Definitions
def initialize(app, root: Utopia::default_root, types: MIME_TYPES[:default], cache_control: DEFAULT_CACHE_CONTROL)
Implementation
def initialize(app, root: Utopia::default_root, types: MIME_TYPES[:default], cache_control: DEFAULT_CACHE_CONTROL)
super(app)
@root = File.expand_path(root)
@extensions = MimeTypeLoader.extensions_for(types)
@cache_control = cache_control
end
def freeze
Freeze this object and its internal state.
Signature
-
returns
self This object.
Implementation
def freeze
return self if frozen?
@root.freeze
@extensions.freeze
@cache_control.freeze
super
end
def response_headers_for(file, content_type)
Build response headers for the given file.
Signature
-
parameter
fileLocalFile The file.
-
parameter
content_typeString The content type.
-
returns
Hash(String, String) The response headers.
Implementation
def response_headers_for(file, content_type)
if @cache_control.respond_to?(:call)
cache_control = @cache_control.call(file)
else
cache_control = @cache_control
end
{
LAST_MODIFIED => file.mtime_date,
CONTENT_TYPE => content_type,
CACHE_CONTROL => cache_control,
ETAG => file.etag,
ACCEPT_RANGES => "bytes"
}
end
def respond(request, path, extension, content_type, localization: request.localization)
Respond.
Signature
-
parameter
requestUtopia::Request The request.
-
parameter
pathProtocol::URL::Path The request path to serve.
-
parameter
extensionString The file extension.
-
parameter
content_typeString The file media type.
-
parameter
localizationUtopia::Localization::Preferences | Nil The selected localization.
-
returns
Protocol::HTTP::Response The response.
Implementation
def respond(request, path, extension, content_type, localization: request.localization)
local_path = path.local_path(@root)
if locale = localization&.locale
local_path = local_path.delete_suffix(extension) + ".#{locale}#{extension}"
end
if file = fetch_file(local_path)
response_headers = self.response_headers_for(file, content_type)
if file.modified?(request)
return file.serve(request, response_headers)
else
return Response[304, response_headers, []]
end
end
end
def call(request)
Serve a recognized static file or pass the request to the next middleware.
Signature
-
parameter
requestUtopia::Request The request.
-
returns
Protocol::HTTP::Response The static-file or downstream response.
Implementation
def call(request)
case request.method
when Protocol::HTTP::Methods::GET, Protocol::HTTP::Methods::HEAD
else
return @delegate.call(request)
end
path = request.url.path
extension = File.extname(path.basename)
if content_type = @extensions[extension.downcase]
response = resolve_localized(request) do |localization|
self.respond(request, path, extension, content_type, localization: localization)
end
if response
return response
end
end
# else if no file was found:
return @delegate.call(request)
end