Class: Middleman::Rack
- Inherits:
-
Object
- Object
- Middleman::Rack
- Extended by:
- Forwardable
- Defined in:
- lib/middleman-core/rack.rb
Instance Method Summary collapse
-
#call(env) ⇒ Object
Rack Interface.
-
#halt(response) ⇒ Object
Halt the current request and return a response.
-
#initialize(middleman) ⇒ Rack
constructor
A new instance of Rack.
-
#not_found(res, path) ⇒ Object
Halt request and return 404.
-
#process_request(env, req, res) ⇒ Object
Core response method.
-
#send_file(resource, env) ⇒ Object
Immediately send static file.
- #to_app ⇒ Object
Constructor Details
#initialize(middleman) ⇒ Rack
Returns a new instance of Rack.
50 51 52 |
# File 'lib/middleman-core/rack.rb', line 50 def initialize(middleman) @middleman = middleman end |
Instance Method Details
#call(env) ⇒ Object
Rack Interface
57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/middleman-core/rack.rb', line 57 def call(env) # Store environment, request and response for later req = ::Rack::Request.new(env) res = ::Rack::Response.new logger.debug "== Request: #{env['PATH_INFO']}" # Catch :halt exceptions and use that response if given catch(:halt) do process_request(env, req, res) res.status = 404 res.finish end end |
#halt(response) ⇒ Object
Halt the current request and return a response
75 76 77 |
# File 'lib/middleman-core/rack.rb', line 75 def halt(response) throw :halt, response end |
#not_found(res, path) ⇒ Object
Halt request and return 404
127 128 129 130 131 132 |
# File 'lib/middleman-core/rack.rb', line 127 def not_found(res, path) path = ::Rack::Utils.escape_html(path) res.status = 404 res.write "<html><head></head><body><h1>File Not Found</h1><p>#{path}</p></body></html>" res.finish end |
#process_request(env, req, res) ⇒ Object
Core response method. We process the request, check with the sitemap, and return the correct file, response or status message.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/middleman-core/rack.rb', line 86 def process_request(env, req, res) start_time = Time.now request_path = URI.decode(env['PATH_INFO'].dup) if request_path.respond_to? :force_encoding request_path.force_encoding('UTF-8') end request_path = ::Middleman::Util.full_path(request_path, @middleman) full_request_path = File.join(env['SCRIPT_NAME'], request_path) # Path including rack mount # Run before callbacks @middleman.execute_callbacks(:before) # Get the resource object for this path resource = @middleman.sitemap.find_resource_by_destination_path(request_path.gsub(' ', '%20')) # Return 404 if not in sitemap return not_found(res, full_request_path) unless resource && !resource.ignored? # If this path is a binary file, send it immediately return send_file(resource, env) if resource.binary? res['Content-Type'] = resource.content_type || 'text/plain' begin # Write out the contents of the page res.write resource.render({}, rack: { request: req }) # Valid content is a 200 status res.status = 200 rescue Middleman::TemplateRenderer::TemplateNotFound => e res.write "Error: #{e.}" res.status = 500 end # End the request logger.debug "== Finishing Request: #{resource.destination_path} (#{(Time.now - start_time).round(2)}s)" halt res.finish end |
#send_file(resource, env) ⇒ Object
Immediately send static file
135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/middleman-core/rack.rb', line 135 def send_file(resource, env) file = ::Rack::File.new nil file.path = resource.file_descriptor[:full_path] response = file.serving(env) status = response[0] response[1]['Content-Encoding'] = 'gzip' if %w(.svgz .gz).include?(resource.ext) # Do not set Content-Type if status is 1xx, 204, 205 or 304, otherwise # Rack will throw an error (500) if !(100..199).cover?(status) && ![204, 205, 304].include?(status) response[1]['Content-Type'] = resource.content_type || 'application/octet-stream' end halt response end |
#to_app ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/middleman-core/rack.rb', line 28 def to_app app = ::Rack::Builder.new app.use ::Rack::Lint app.use ::Rack::Head @middleman.middleware.each do |middleware| app.use(middleware[:class], *middleware[:options], &middleware[:block]) end inner_app = self app.map('/') { run inner_app } @middleman.mappings.each do |mapping| app.map(mapping[:path], &mapping[:block]) end app end |