module Hanami::Action::Head

Ensures to not send body or headers for HEAD requests and/or for status codes that doesn't allow them.

@since 0.3.2

@see www.ietf.org/rfc/rfc2616.txt

Constants

ENTITY_HEADERS

Entity headers allowed in blank body responses, according to RFC 2616 - Section 10 (HTTP 1.1).

“The response MAY include new or updated metainformation in the form

of entity-headers".

@since 0.4.0 @api private

@see www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.5 @see www.w3.org/Protocols/rfc2616/rfc2616-sec7.html

HTTP_STATUSES_WITHOUT_BODY

Status codes that by RFC must not include a message body

@since 0.3.2 @api private

Public Instance Methods

finish() click to toggle source

Ensures to not send body or headers for HEAD requests and/or for status codes that doesn't allow them.

@since 0.3.2 @api private

@see Hanami::Action#finish

Calls superclass method
# File lib/hanami/action/head.rb, line 48
def finish
  super

  if _requires_no_body?
    @_body = nil
    @headers.reject! {|header,_| !keep_response_header?(header) }
  end
end

Protected Instance Methods

_requires_no_body?() click to toggle source

@since 0.3.2 @api private

# File lib/hanami/action/head.rb, line 60
def _requires_no_body?
  HTTP_STATUSES_WITHOUT_BODY.include?(@_status) || head?
end

Private Instance Methods

keep_response_header?(header) click to toggle source

According to RFC 2616, when a response MUST have an empty body, it only allows Entity Headers.

For instance, a 204 doesn't allow Content-Type or any other custom header.

This restriction is enforced by Hanami::Action::Head#finish.

However, there are cases that demand to bypass this rule to set meta informations via headers.

An example is a DELETE request for a JSON API application. It returns a 204 but still wants to specify the rate limit quota via X-Rate-Limit.

@since 0.5.0

@see Hanami::Action::HEAD#finish

@example

require 'hanami/controller'

module Books
  class Destroy
    include Hanami::Action

    def call(params)
      # ...
      self.headers.merge!(
        'Last-Modified' => 'Fri, 27 Nov 2015 13:32:36 GMT',
        'X-Rate-Limit'  => '4000',
        'Content-Type'  => 'application/json',
        'X-No-Pass'     => 'true'
      )

      self.status = 204
    end

    private

    def keep_response_header?(header)
      super || header == 'X-Rate-Limit'
    end
  end
end

# Only the following headers will be sent:
#  * Last-Modified - because we used `super' in the method that respects the HTTP RFC
#  * X-Rate-Limit  - because we explicitely allow it

# Both Content-Type and X-No-Pass are removed because they're not allowed
# File lib/hanami/action/head.rb, line 116
def keep_response_header?(header)
  ENTITY_HEADERS.include?(header)
end