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 = || 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 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.format_from_media_type(r.content_type), config) end end |
Instance Method Details
#[](key) ⇒ Object
Returns the exposure value for the given key.
185 186 187 |
# File 'lib/hanami/action/response.rb', line 185 def [](key) @exposures.fetch(key) end |
#[]=(key, value) ⇒ Object
Sets an exposure value for the given key.
198 199 200 |
# File 'lib/hanami/action/response.rb', line 198 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.
457 458 459 460 461 462 463 464 465 466 467 468 469 |
# File 'lib/hanami/action/response.rb', line 457 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.
439 440 441 442 443 |
# File 'lib/hanami/action/response.rb', line 439 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 82 83 84 |
# File 'lib/hanami/action/response.rb', line 72 def body=(str) @length = 0 @body = EMPTY_BODY.dup return if str.nil? || str == EMPTY_BODY if str.is_a?(::Rack::Files::BaseIterator) @body = str buffered_body! # Ensure appropriate content-length is set else write(str) 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.
357 358 359 360 |
# File 'lib/hanami/action/response.rb', line 357 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.
258 259 260 |
# File 'lib/hanami/action/response.rb', line 258 def ||= 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.
386 387 388 389 |
# File 'lib/hanami/action/response.rb', line 386 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.
244 245 246 247 248 249 250 |
# File 'lib/hanami/action/response.rb', line 244 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`.
136 137 138 |
# File 'lib/hanami/action/response.rb', line 136 def format @format ||= Mime.format_from_media_type(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.
167 168 169 170 171 172 173 |
# File 'lib/hanami/action/response.rb', line 167 def format=(value) format, content_type = Mime.format_and_media_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.
413 414 415 416 417 418 419 420 421 |
# File 'lib/hanami/action/response.rb', line 413 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.
451 452 453 |
# File 'lib/hanami/action/response.rb', line 451 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.
269 270 271 272 273 274 |
# File 'lib/hanami/action/response.rb', line 269 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.
114 115 116 117 118 119 120 121 122 |
# File 'lib/hanami/action/response.rb', line 114 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.
431 432 433 434 435 |
# File 'lib/hanami/action/response.rb', line 431 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)
295 296 297 298 299 |
# File 'lib/hanami/action/response.rb', line 295 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.
224 225 226 227 228 229 230 |
# File 'lib/hanami/action/response.rb', line 224 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.
208 209 210 |
# File 'lib/hanami/action/response.rb', line 208 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.
425 426 427 |
# File 'lib/hanami/action/response.rb', line 425 def set_format(value) # rubocop:disable Naming/AccessorMethodName @format = value end |
#status=(code) ⇒ Object
Sets the response status.
103 104 105 |
# File 'lib/hanami/action/response.rb', line 103 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.
312 313 314 315 316 317 318 319 320 321 322 |
# File 'lib/hanami/action/response.rb', line 312 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 |