Class: Above::MiddleWare::Static
- Inherits:
-
Object
- Object
- Above::MiddleWare::Static
- Defined in:
- lib/above/middleware/static.rb
Overview
Middleware to serve static files
Instance Method Summary collapse
- #call(env:) ⇒ Object
- #format_response(maybe_incomplete_triplet:, env:) ⇒ Object
-
#initialize(app:) ⇒ Static
constructor
A new instance of Static.
- #read_file(request:, env:, again: false) ⇒ Object
- #response(env:) ⇒ Object
- #try_index(request:, env:, index:) ⇒ Object
Constructor Details
#initialize(app:) ⇒ Static
Returns a new instance of Static.
7 8 9 |
# File 'lib/above/middleware/static.rb', line 7 def initialize(app:) @app = app # who you gonna call end |
Instance Method Details
#call(env:) ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/above/middleware/static.rb', line 11 def call(env:) # env is {socket:, request:, config:, server:, valid:} status, header, body_arr = @app.call(env:) unless @app.nil? # usually nothing to call from here # If redirect or cache fired we wouldn't get to here in the default arrangemnet. Usually wouldn't have any # other middleware to call after this one. If indeed we don't, or if that didn't create a response, try to get the file requested if status.nil? response(env:) else [status, header, body_arr] end end |
#format_response(maybe_incomplete_triplet:, env:) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/above/middleware/static.rb', line 25 def format_response(maybe_incomplete_triplet:, env:) lang = env[:config]["Above::MiddleWare::Static"]["lang"] status, header, content_arr = maybe_incomplete_triplet if status < 20 || status > 59 # TODO: input requests (from some other middleware?) not currently handled [42, Status::CODE[42], []] elsif status > 39 # Ensure errors have some header text header = Status::CODE[status] if header.nil? [status, header, content_arr] elsif header.start_with?("text/") # TODO: multipart, streaming etc # header here is the mime_type, from #read_file content = content_arr.first.encode(Encoding.find("UTF-8"), invalid: :replace, undef: :replace, replace: "") [status, "#{header}; charset=utf-8; lang=#{lang}; size=#{content.length}", [content]] else [status, "#{header}; size=#{content_arr.first.length}", content_arr] end end |
#read_file(request:, env:, again: false) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/above/middleware/static.rb', line 45 def read_file(request:, env:, again: false) config = env[:config]["Above::MiddleWare::Static"] path = File.join(File.(config["docroot"]), request.path) mime_type = Mime.type(path:) # TODO - maybe replace marcel, this reads files twice... content = File.read(path) # Maybe TODO: multi part, streaming etc # nb header is incomplete at this point [20, mime_type, [content]] rescue Errno::EISDIR if !again try_index(request:, env:, index: config["index"]) else [51, Status::CODE[51], []] end rescue Errno::ENOENT [51, Status::CODE[51], []] end |
#response(env:) ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/above/middleware/static.rb', line 63 def response(env:) host = env[:server]["domain"] request = env[:request] response = if !env[:valid] # Bad request caught earlier [59, Status::CODE[59], []] elsif request.to_s.length > 1024 # Request longer than maximum length [59, Status::CODE[59], []] elsif request.scheme != "gemini" || request.host != host # Currently - refuse proxy requests for different protocols or servers, maybe TODO [53, Status::CODE[53], []] else maybe_incomplete_triplet = read_file(request:, env:) format_response(maybe_incomplete_triplet:, env:) end rescue NoMethodError # eg trying to encode nil content response = [40, Status::CODE[40], []] rescue # Bad uri, no scheme etc that got this far response = [59, Status::CODE[59], []] ensure response end |
#try_index(request:, env:, index:) ⇒ Object
89 90 91 92 93 |
# File 'lib/above/middleware/static.rb', line 89 def try_index(request:, env:, index:) new_request = request.dup new_request.path = File.join(request.path, index) read_file(request: new_request, env:, again: true) end |