module Hanami::Action::Rack
Rack
integration API
@since 0.1.0
Constants
- CONTENT_LENGTH
The Content-Length HTTP header
@since 1.0.0 @api private
- DEFAULT_REQUEST_ID_LENGTH
The default HTTP
Request
ID length@since 0.3.0 @api private
- DEFAULT_RESPONSE_BODY
The default
Rack
response body@since 0.1.0 @api private
- DEFAULT_RESPONSE_CODE
The default HTTP response code
@since 0.1.0 @api private
- FILE_SYSTEM_ROOT
This is the root directory for `#unsafe_send_file`
@since 1.3.3 @api private
@see
unsafe_send_file
- HEAD
HEAD
request@since 0.3.2 @api private
- NOT_FOUND
Not Found
@since 1.0.0 @api private
- REQUEST_METHOD
The request method
@since 0.3.2 @api private
- RESPONSE_BODY
Rack
SPEC response body@since 1.0.0 @api private
- RESPONSE_CODE
Rack
SPEC response code@since 1.0.0 @api private
- RESPONSE_HEADERS
Rack
SPEC response headers@since 1.0.0 @api private
- ROUTER_PARSED_BODY
The key that returns router parsed body from the
Rack
env- X_CASCADE
The non-standard HTTP header to pass the control over when a resource cannot be found by the current endpoint
@since 1.0.0 @api private
Public Class Methods
Override Ruby's hook for modules. It includes basic Hanami::Action
modules to the given class.
@param base [Class] the target action
@since 0.1.0 @api private
@see www.ruby-doc.org/core-2.1.2/Module.html#method-i-included
# File lib/hanami/action/rack.rb, line 103 def self.included(base) base.class_eval do extend ClassMethods prepend InstanceMethods end end
Protected Instance Methods
Gets the headers from the response
@return [Hash] the HTTP headers from the response
@since 0.1.0
@example
require 'hanami/controller' class Show include Hanami::Action def call(params) # ... self.headers # => { ... } self.headers.merge!({'X-Custom' => 'OK'}) end end
# File lib/hanami/action/rack.rb, line 204 def headers @headers end
Return parsed request body
@deprecated
# File lib/hanami/action/rack.rb, line 259 def parsed_request_body Hanami::Utils::Deprecation.new('#parsed_request_body is deprecated and it will be removed in future versions') @_env.fetch(ROUTER_PARSED_BODY, nil) end
Returns a Hanami
specialized rack request
@return [Hanami::Action::Request] The request
@since 0.3.1
@example
require 'hanami/controller' class Create include Hanami::Action def call(params) ip = request.ip secure = request.ssl? end end
# File lib/hanami/action/rack.rb, line 252 def request @request ||= ::Hanami::Action::Request.new(@_env) end
Calculates an unique ID for the current request
@return [String] The unique ID
@since 0.3.0
# File lib/hanami/action/rack.rb, line 230 def request_id # FIXME make this number configurable and document the probabilities of clashes @request_id ||= SecureRandom.hex(DEFAULT_REQUEST_ID_LENGTH) end
Returns a serialized Rack
response (Array), according to the current
status code, headers, and body.
@return [Array] the serialized response
@since 0.1.0 @api private
@see Hanami::Action::Rack::DEFAULT_RESPONSE_CODE
@see Hanami::Action::Rack::DEFAULT_RESPONSE_BODY
@see Hanami::Action::Rack#status=
@see Hanami::Action::Rack#headers
@see Hanami::Action::Rack#body=
# File lib/hanami/action/rack.rb, line 221 def response [ @_status || DEFAULT_RESPONSE_CODE, headers, @_body || DEFAULT_RESPONSE_BODY.dup ] end
Private Instance Methods
@since 1.0.0 @api private
# File lib/hanami/action/rack.rb, line 394 def _send_file(response) headers.merge!(response[RESPONSE_HEADERS]) if response[RESPONSE_CODE] == NOT_FOUND headers.delete(X_CASCADE) headers.delete(CONTENT_LENGTH) halt NOT_FOUND else # FIXME: this is a fix for https://github.com/hanami/controller/issues/240 # It's here to maintain the backward compat with 1.1, as we can't remove `#halt` # We should review the workflow for 2.0, because I don't like callbacks to be referenced from here. _run_after_callbacks(params) halt response[RESPONSE_CODE], response[RESPONSE_BODY] end end
Sets the body of the response
@param body [String] the body of the response @return [void]
@since 0.1.0
@example
require 'hanami/controller' class Show include Hanami::Action def call(params) # ... self.body = 'Hi!' end end
# File lib/hanami/action/rack.rb, line 306 def body=(body) body = Array(body) unless body.respond_to?(:each) @_body = body end
Check if the current request is a HEAD
@return [TrueClass,FalseClass] the result of the check
@since 0.3.2
# File lib/hanami/action/rack.rb, line 380 def head? request_method == HEAD end
NOTE: Hanami::Action::CSRFProtection
(hanamirb
gem) depends on this.
@api private @since 0.4.4
# File lib/hanami/action/rack.rb, line 388 def request_method @_env[REQUEST_METHOD] end
Send a file as response.
<tt>This method only sends files from the public directory</tt>
It automatically handle the following cases:
* <tt>Content-Type</tt> and <tt>Content-Length</tt> * File Not found (returns a 404) * Conditional GET (via <tt>If-Modified-Since</tt> header) * Range requests (via <tt>Range</tt> header)
@param path [String, Pathname] the body of the response @return [void]
@since 0.4.3
@example
require 'hanami/controller' class Show include Hanami::Action def call(params) # ... send_file Pathname.new('path/to/file') end end
# File lib/hanami/action/rack.rb, line 337 def send_file(path) _send_file( File.new(path, self.class.configuration.public_directory).call(@_env) ) end
Sets the HTTP status code for the response
@param status [Fixnum] an HTTP status code @return [void]
@since 0.1.0
@example
require 'hanami/controller' class Create include Hanami::Action def call(params) # ... self.status = 201 end end
# File lib/hanami/action/rack.rb, line 284 def status=(status) @_status = status end
Send a file as response from anywhere in the file system.
@see Hanami::Action::Rack#send_file
@param path [String, Pathname] path to the file to be sent @return [void]
@since 1.0.0
@example
require 'hanami/controller' class Show include Hanami::Action def call(params) # ... unsafe_send_file Pathname.new('/tmp/path/to/file') end end
# File lib/hanami/action/rack.rb, line 363 def unsafe_send_file(path) directory = if Pathname.new(path).relative? self.class.configuration.root_directory else FILE_SYSTEM_ROOT end _send_file( File.new(path, directory).call(@_env) ) end