Class: Hanami::Action::Response Private
- Inherits:
-
Rack::Response
- Object
- Rack::Response
- Hanami::Action::Response
- Defined in:
- lib/hanami/action/response.rb
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
The HTTP response for an action, given to #handle.
Inherits from ‘Rack::Response`, providing compatibility with Rack functionality.
Constant Summary collapse
- DEFAULT_VIEW_OPTIONS =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
-> (*) { {} }.freeze
- EMPTY_BODY =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
[].freeze
- FILE_SYSTEM_ROOT =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Pathname.new("/").freeze
Instance Attribute Summary collapse
- #charset ⇒ Object private
- #env ⇒ Object readonly private
- #exposures ⇒ Object readonly private
- #request ⇒ Object readonly private
- #view_options ⇒ Object readonly private
Class Method Summary collapse
- .build(status, env) ⇒ Object private
Instance Method Summary collapse
-
#[](key) ⇒ Object
Returns the exposure value for the given key.
-
#[]=(key, value) ⇒ Object
Sets an exposure value for the given key.
- #_send_file(send_file_response) ⇒ Object private
- #allow_redirect? ⇒ Boolean private
-
#body=(str) ⇒ Object
Sets the response body.
-
#cache_control(*values) ⇒ Object
Specifies the response freshness policy for HTTP caches using the ‘Cache-Control` header.
-
#cookies ⇒ CookieJar
Returns the set of cookies to be included in the response.
-
#expires(amount, *values) ⇒ Object
Sets the ‘Expires` header and `Cache-Control`/`max-age` directive for the response.
-
#flash ⇒ Flash
Returns the flash for the request.
-
#format ⇒ Symbol?
Returns the format for the response.
-
#format=(value) ⇒ Object
Sets the format and associated content type for the response.
-
#fresh(options) ⇒ Object
Sets the ‘etag` and/or `last_modified` headers on the response and halts with a `304 Not Modified` response if the request is still fresh according to the `IfNoneMatch` and `IfModifiedSince` request headers.
- #head? ⇒ Boolean private
-
#initialize(request:, config:, content_type: nil, env: {}, headers: {}, view_options: nil, session_enabled: false) ⇒ Response
constructor
private
A new instance of Response.
-
#redirect_to(url, status: 302) ⇒ Object
Sets the response to redirect to the given URL and halts further handling.
-
#render(view, **input) ⇒ Object
Sets the response body from the rendered view.
- #renderable? ⇒ Boolean private
-
#send_file(path) ⇒ void
Sends the file at the given path as the response, for any file within the configured ‘public_directory`.
-
#session ⇒ Hash
Returns the session for the response.
-
#session_enabled? ⇒ Boolean
Returns true if the session is enabled for the request.
- #set_format(value) ⇒ Object private
-
#status=(code) ⇒ Object
Sets the response status.
-
#unsafe_send_file(path) ⇒ void
Send the file at the given path as the response, for a file anywhere in the file system.
Constructor Details
#initialize(request:, config:, content_type: nil, env: {}, headers: {}, view_options: nil, session_enabled: false) ⇒ Response
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of Response.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/hanami/action/response.rb', line 51 def initialize(request:, config:, content_type: nil, env: {}, headers: {}, view_options: nil, session_enabled: false) # rubocop:disable Layout/LineLength, Metrics/ParameterLists super([], 200, headers.dup) self.content_type = content_type if content_type @request = request @config = config @charset = ::Rack::MediaType.params(content_type).fetch("charset", nil) @exposures = {} @env = env @view_options = || DEFAULT_VIEW_OPTIONS @session_enabled = session_enabled @sending_file = false end |
Instance Attribute Details
#charset ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
37 38 39 |
# File 'lib/hanami/action/response.rb', line 37 def charset @charset end |
#env ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
33 34 35 |
# File 'lib/hanami/action/response.rb', line 33 def env @env end |
#exposures ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
33 34 35 |
# File 'lib/hanami/action/response.rb', line 33 def exposures @exposures end |
#request ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
33 34 35 |
# File 'lib/hanami/action/response.rb', line 33 def request @request end |
#view_options ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
33 34 35 |
# File 'lib/hanami/action/response.rb', line 33 def @view_options end |
Class Method Details
.build(status, env) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
41 42 43 44 45 46 47 |
# File 'lib/hanami/action/response.rb', line 41 def self.build(status, env) new(config: Action.config.dup, content_type: Mime.best_q_match(env[Action::HTTP_ACCEPT]), env: env).tap do |r| r.status = status r.body = Http::Status.(status) r.set_format(Mime.detect_format(r.content_type), config) end end |
Instance Method Details
#[](key) ⇒ Object
Returns the exposure value for the given key.
182 183 184 |
# File 'lib/hanami/action/response.rb', line 182 def [](key) @exposures.fetch(key) end |
#[]=(key, value) ⇒ Object
Sets an exposure value for the given key.
195 196 197 |
# File 'lib/hanami/action/response.rb', line 195 def []=(key, value) @exposures[key] = value end |
#_send_file(send_file_response) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
454 455 456 457 458 459 460 461 462 463 464 465 466 |
# File 'lib/hanami/action/response.rb', line 454 def _send_file(send_file_response) headers.merge!(send_file_response[Action::RESPONSE_HEADERS]) if send_file_response[Action::RESPONSE_CODE] == Action::NOT_FOUND headers.delete(Action::X_CASCADE) headers.delete(Action::CONTENT_LENGTH) Halt.call(Action::NOT_FOUND) else self.status = send_file_response[Action::RESPONSE_CODE] self.body = send_file_response[Action::RESPONSE_BODY] @sending_file = true end end |
#allow_redirect? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
436 437 438 439 440 |
# File 'lib/hanami/action/response.rb', line 436 def allow_redirect? return body.empty? if body.respond_to?(:empty?) !@sending_file end |
#body=(str) ⇒ Object
Sets the response body.
72 73 74 75 76 77 78 79 80 81 |
# File 'lib/hanami/action/response.rb', line 72 def body=(str) @length = 0 @body = EMPTY_BODY.dup if str.is_a?(::Rack::Files::BaseIterator) @body = str else write(str) unless str.nil? || str == EMPTY_BODY end end |
#cache_control(*values) ⇒ Object
Specifies the response freshness policy for HTTP caches using the ‘Cache-Control` header.
Any number of non-value directives (‘:public`, `:private`, `:no_cache`, `:no_store`, `:must_revalidate`, `:proxy_revalidate`) may be passed along with a Hash of value directives (`:max_age`, `:min_stale`, `:s_max_age`).
See [RFC 2616 / 14.9](tools.ietf.org/html/rfc2616#section-14.9.1) for more on standard cache control directives.
354 355 356 357 |
# File 'lib/hanami/action/response.rb', line 354 def cache_control(*values) directives = Cache::CacheControl::Directives.new(*values) headers.merge!(directives.headers) end |
#cookies ⇒ CookieJar
Returns the set of cookies to be included in the response.
255 256 257 |
# File 'lib/hanami/action/response.rb', line 255 def @cookies ||= CookieJar.new(env.dup, headers, @config.) end |
#expires(amount, *values) ⇒ Object
Sets the ‘Expires` header and `Cache-Control`/`max-age` directive for the response.
You can provide an integer number of seconds in the future, or a Time object indicating when the response should be considered “stale”. The remaining arguments are passed to #cache_control.
383 384 385 386 |
# File 'lib/hanami/action/response.rb', line 383 def expires(amount, *values) directives = Cache::Expires::Directives.new(amount, *values) headers.merge!(directives.headers) end |
#flash ⇒ Flash
Returns the flash for the request.
This is the same flash object as the Hanami::Action::Request.
241 242 243 244 245 246 247 |
# File 'lib/hanami/action/response.rb', line 241 def flash unless session_enabled? raise Hanami::Action::MissingSessionError.new("Hanami::Action::Response#flash") end request.flash end |
#format ⇒ Symbol?
Returns the format for the response.
Returns nil if a format has not been assigned and also cannot be determined from the response’s ‘#content_type`.
133 134 135 |
# File 'lib/hanami/action/response.rb', line 133 def format @format ||= Mime.detect_format(content_type, @config) end |
#format=(value) ⇒ Object
Sets the format and associated content type for the response.
Either a format name (‘:json`) or a MIME type (`“application/json”`) may be given. In either case, the format or content type will be derived from the given value, and both will be set.
Providing an unknown format name will raise an UnknownFormatError.
Providing an unknown MIME type will set the content type and set the format as nil.
164 165 166 167 168 169 170 |
# File 'lib/hanami/action/response.rb', line 164 def format=(value) format, content_type = Mime.detect_format_and_content_type(value, @config) self.content_type = Mime.content_type_with_charset(content_type, charset) @format = format end |
#fresh(options) ⇒ Object
Sets the ‘etag` and/or `last_modified` headers on the response and halts with a `304 Not Modified` response if the request is still fresh according to the `IfNoneMatch` and `IfModifiedSince` request headers.
410 411 412 413 414 415 416 417 418 |
# File 'lib/hanami/action/response.rb', line 410 def fresh() conditional_get = Cache::ConditionalGet.new(env, ) headers.merge!(conditional_get.headers) conditional_get.fresh? do Halt.call(304) end end |
#head? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
448 449 450 |
# File 'lib/hanami/action/response.rb', line 448 def head? env[Action::REQUEST_METHOD] == Action::HEAD end |
#redirect_to(url, status: 302) ⇒ Object
Sets the response to redirect to the given URL and halts further handling.
266 267 268 269 270 271 |
# File 'lib/hanami/action/response.rb', line 266 def redirect_to(url, status: 302) return unless allow_redirect? redirect(::String.new(url), status) Halt.call(status) end |
#render(view, **input) ⇒ Object
Sets the response body from the rendered view.
111 112 113 114 115 116 117 118 119 |
# File 'lib/hanami/action/response.rb', line 111 def render(view, **input) view_input = { **.call(request, self), **exposures, **input } self.body = view.call(**view_input).to_str end |
#renderable? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
428 429 430 431 432 |
# File 'lib/hanami/action/response.rb', line 428 def renderable? return !head? && body.empty? if body.respond_to?(:empty?) !@sending_file && !head? end |
#send_file(path) ⇒ void
This method returns an undefined value.
Sends the file at the given path as the response, for any file within the configured ‘public_directory`.
Handles the following aspects for file responses:
-
Setting ‘Content-Type` and `Content-Length` headers
-
File Not Found responses (returns a 404)
-
Conditional GET (via ‘If-Modified-Since` header)
-
Range requests (via ‘Range` header)
292 293 294 295 296 |
# File 'lib/hanami/action/response.rb', line 292 def send_file(path) _send_file( Action::Rack::File.new(path, @config.public_directory).call(env) ) end |
#session ⇒ Hash
Returns the session for the response.
This is the same session object as the Hanami::Action::Request.
221 222 223 224 225 226 227 |
# File 'lib/hanami/action/response.rb', line 221 def session unless session_enabled? raise Hanami::Action::MissingSessionError.new("Hanami::Action::Response#session") end request.session end |
#session_enabled? ⇒ Boolean
Returns true if the session is enabled for the request.
205 206 207 |
# File 'lib/hanami/action/response.rb', line 205 def session_enabled? @session_enabled end |
#set_format(value) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
422 423 424 |
# File 'lib/hanami/action/response.rb', line 422 def set_format(value) # rubocop:disable Naming/AccessorMethodName @format = value end |
#status=(code) ⇒ Object
Sets the response status.
100 101 102 |
# File 'lib/hanami/action/response.rb', line 100 def status=(code) super(Http::Status.lookup(code)) end |
#unsafe_send_file(path) ⇒ void
This method returns an undefined value.
Send the file at the given path as the response, for a file anywhere in the file system.
309 310 311 312 313 314 315 316 317 318 319 |
# File 'lib/hanami/action/response.rb', line 309 def unsafe_send_file(path) directory = if Pathname.new(path).relative? @config.root_directory else FILE_SYSTEM_ROOT end _send_file( Action::Rack::File.new(path, directory).call(env) ) end |