feat(middleware): add request logger and static file server

This commit is contained in:
dualfroz committed 2026-08-26 17:00:00 +02:00
1 parent a00dd619c1
commit 514e8fada8
2 files changed
+63

No files matched your search

+18
View File
@@ -0,0 +1,18 @@
module Prism
module Middleware
class Logger
def initialize(app, io: $stderr)
@app = app
@io = io
end
def call(env)
started = Time.now
status, headers, body = @app.call(env)
elapsed = ((Time.now - started) * 1000).round(2)
@io.puts(format('%s %s -> %d (%.2f ms)', env['REQUEST_METHOD'], env['PATH_INFO'], status, elapsed))
[status, headers, body]
end
end
end
end
+45
View File
@@ -0,0 +1,45 @@
module Prism
module Middleware
class Static
ContentTypes = {
'.html' => 'text/html;charset=utf-8', '.htm' => 'text/html;charset=utf-8',
'.css' => 'text/css', '.js' => 'application/javascript', '.json' => 'application/json',
'.png' => 'image/png', '.jpg' => 'image/jpeg', '.jpeg' => 'image/jpeg', '.gif' => 'image/gif',
'.svg' => 'image/svg+xml', '.ico' => 'image/x-icon', '.txt' => 'text/plain', '.pdf' => 'application/pdf'
}.freeze
def initialize(app, root:)
@app = app
@root = File.expand_path(root)
end
def call(env)
method = env['REQUEST_METHOD']
return @app.call(env) unless %w[GET HEAD].include?(method)
file = resolve(env['PATH_INFO'])
return @app.call(env) unless file
serve(file)
end
private
def resolve(path_info)
return nil if path_info.nil? || path_info.include?("\0")
decoded = CGI.unescape(path_info)
candidate = File.expand_path(File.join(@root, decoded))
return nil unless candidate.start_with?("#{@root}#{File::SEPARATOR}") || candidate == @root
return File.join(candidate, 'index.html') if File.directory?(candidate) && File.file?(File.join(candidate, 'index.html'))
return nil unless File.file?(candidate)
candidate
end
def serve(file)
body = File.binread(file)
type = ContentTypes.fetch(File.extname(file).downcase, 'application/octet-stream')
[200, { 'Content-Type' => type, 'Content-Length' => body.bytesize.to_s }, [body]]
end
end
end
end