lib/roda/plugins/public.rb in roda-3.32.0 vs lib/roda/plugins/public.rb in roda-3.33.0
- old
+ new
@@ -40,20 +40,23 @@
# Use options given to setup a Rack::File instance for serving files. Options:
# :default_mime :: The default mime type to use if the mime type is not recognized.
# :gzip :: Whether to serve already gzipped files with a .gz extension for clients
# supporting gzipped transfer encoding.
+ # :brotli :: Whether to serve already brotli-compressed files with a .br extension
+ # for clients supporting brotli transfer encoding.
# :headers :: A hash of headers to use for statically served files
# :root :: Use this option for the root of the public directory (default: "public")
def self.configure(app, opts={})
if opts[:root]
app.opts[:public_root] = app.expand_path(opts[:root])
elsif !app.opts[:public_root]
app.opts[:public_root] = app.expand_path("public")
end
app.opts[:public_server] = ::Rack::File.new(app.opts[:public_root], opts[:headers]||{}, opts[:default_mime] || 'text/plain')
app.opts[:public_gzip] = opts[:gzip]
+ app.opts[:public_brotli] = opts[:brotli]
end
module RequestMethods
# Serve files from the public directory if the file exists and this is a GET request.
def public
@@ -63,28 +66,13 @@
roda_opts = roda_class.opts
server = roda_opts[:public_server]
path = ::File.join(server.root, *public_path_segments(path))
- if roda_opts[:public_gzip] && env['HTTP_ACCEPT_ENCODING'] =~ /\bgzip\b/
- gzip_path = path + '.gz'
+ public_serve_compressed(server, path, '.br', 'br') if roda_opts[:public_brotli]
+ public_serve_compressed(server, path, '.gz', 'gzip') if roda_opts[:public_gzip]
- if public_file_readable?(gzip_path)
- res = public_serve(server, gzip_path)
- headers = res[1]
-
- unless res[0] == 304
- if mime_type = ::Rack::Mime.mime_type(::File.extname(path), 'text/plain')
- headers['Content-Type'] = mime_type
- end
- headers['Content-Encoding'] = 'gzip'
- end
-
- halt res
- end
- end
-
if public_file_readable?(path)
halt public_serve(server, path)
end
end
end
@@ -109,9 +97,29 @@
::File.file?(path) && ::File.readable?(path)
rescue SystemCallError
# :nocov:
false
# :nocov:
+ end
+
+ def public_serve_compressed(server, path, suffix, encoding)
+ if env['HTTP_ACCEPT_ENCODING'] =~ /\b#{encoding}\b/
+ compressed_path = path + suffix
+
+ if public_file_readable?(compressed_path)
+ res = public_serve(server, compressed_path)
+ headers = res[1]
+
+ unless res[0] == 304
+ if mime_type = ::Rack::Mime.mime_type(::File.extname(path), 'text/plain')
+ headers['Content-Type'] = mime_type
+ end
+ headers['Content-Encoding'] = encoding
+ end
+
+ halt res
+ end
+ end
end
if ::Rack.release > '2'
# Serve the given path using the given Rack::File server.
def public_serve(server, path)