module Middleman::CoreExtensions::Request::InstanceMethods

Methods to be mixed-in to Middleman::Application

Attributes

current_path[R]

Accessor for current path @return [String]

env[RW]

Rack env

req[RW]

Rack request @return [Rack::Request]

request[R]

Backwards-compatibility with old request.path signature

res[RW]

Rack response @return [Rack::Response]

Public Instance Methods

call(env) click to toggle source
# File lib/middleman-core/core_extensions/request.rb, line 187
def call(env)
  dup.call!(env)
end
call!(env) click to toggle source

Rack Interface

@param env Rack environment

# File lib/middleman-core/core_extensions/request.rb, line 194
def call!(env)
  self.env = env
  # Store environment, request and response for later
  self.req = req = ::Rack::Request.new(env)
  self.res = 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
content_type(res, type, params={}) click to toggle source

Set the content type for the current request

@param [String] type Content type @param [Hash] params @return [void]

# File lib/middleman-core/core_extensions/request.rb, line 314
def content_type(res, type, params={})
  return unless type
  default = params.delete :default
  mime_type = mime_type(type) || default
  throw "Unknown media type: %p" % type if mime_type.nil?
  mime_type = mime_type.dup
  unless params.include? :charset
    params[:charset] = params.delete('charset') || "utf-8"
  end
  params.delete :charset if mime_type.include? 'charset'
  unless params.empty?
    mime_type << (mime_type.include?(';') ? ', ' : ';')
    mime_type << params.map { |kv| kv.join('=') }.join(', ')
  end
  res['Content-Type'] = mime_type
end
current_path=(path) click to toggle source

Set the current path

@param [String] path The new current path @return [void]

# File lib/middleman-core/core_extensions/request.rb, line 165
def current_path=(path)
  @current_path = path
  @request = ::Thor::CoreExt::HashWithIndifferentAccess.new({
    :path   => path,
    :params => req ? ::Thor::CoreExt::HashWithIndifferentAccess.new(req.params) : {}
  })
end
halt(response) click to toggle source

Halt the current request and return a response

@param [String] response Response value

# File lib/middleman-core/core_extensions/request.rb, line 215
def halt(response)
  throw :halt, response
end
map(*args, &block) click to toggle source
# File lib/middleman-core/core_extensions/request.rb, line 174
def map(*args, &block); self.class.map(*args, &block); end
mime_type(type, value=nil) click to toggle source

Add a new mime-type for a specific extension

@param [Symbol] type File extension @param [String] value Mime type @return [void]

# File lib/middleman-core/core_extensions/request.rb, line 278
def mime_type(type, value=nil)
  return type if type.nil? || type.to_s.include?('/')
  return ::Rack::Mime.mime_type('.txt') if type.empty?
  type = ".#{type}" unless type.to_s[0] == ?.
  return ::Rack::Mime.mime_type(type, nil) unless value
  ::Rack::Mime::MIME_TYPES[type] = value
end
not_found(res, path) click to toggle source

Halt request and return 404

# File lib/middleman-core/core_extensions/request.rb, line 287
def not_found(res, path)
  res.status == 404
  res.write "<html><body><h1>File Not Found</h1><p>#{path}</p></body>"
  res.finish
end
process_request(env, req, res) click to toggle source

Core response method. We process the request, check with the sitemap, and return the correct file, response or status message.

@param env @param [Rack::Request] req @param [Rack::Response] res

# File lib/middleman-core/core_extensions/request.rb, line 226
def process_request(env, req, res)
  start_time = Time.now
  @current_path = nil

  request_path = URI.decode(env["PATH_INFO"].dup)
  if request_path.respond_to? :force_encoding
    request_path.force_encoding('UTF-8')
  end
  request_path = full_path(request_path)

  # Run before callbacks
  run_hook :before

  # Get the resource object for this path
  resource = sitemap.find_resource_by_destination_path(request_path)

  # Return 404 if not in sitemap
  return not_found(res, request_path) unless resource && !resource.ignored?

  # If this path is a binary file, send it immediately
  return send_file(resource.source_file, env, res) if resource.binary?

  current_path = resource.destination_path

  # Set a HTTP content type based on the request's extensions
  content_type(res, mime_type(resource.ext))

  begin
    # Write out the contents of the page
    output = resource.render do
      self.req = req
      self.current_path = current_path
    end

    res.write output
    # Valid content is a 200 status
    res.status = 200
  rescue Middleman::CoreExtensions::Rendering::TemplateNotFound => e
    res.write "Error: #{e.message}"
    res.status = 500
  end

  # End the request
  logger.debug "== Finishing Request: #{current_path} (#{(Time.now - start_time).round(2)}s)"
  halt res.finish
end
send_file(path, env, res) click to toggle source

Immediately send static file

@param [String] path File to send

# File lib/middleman-core/core_extensions/request.rb, line 296
def send_file(path, env, res)
  extension = File.extname(path)
  matched_mime = mime_type(extension)
  matched_mime = "application/octet-stream" if matched_mime.nil?
  content_type res, matched_mime

  file      = ::Rack::File.new nil
  file.path = path
  response = file.serving(env)
  response[1]['Content-Encoding'] = 'gzip' if %w(.svgz).include?(extension)
  halt response
end
use(*args, &block) click to toggle source
# File lib/middleman-core/core_extensions/request.rb, line 173
def use(*args, &block); self.class.use(*args, &block); end