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-Controlheader. -
#cookies ⇒ CookieJar
Returns the set of cookies to be included in the response.
-
#expires(amount, *values) ⇒ Object
Sets the
Expiresheader andCache-Control/max-agedirective 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
etagand/orlast_modifiedheaders on the response and halts with a ‘304 Not Modified` response if the request is still fresh according to theIfNoneMatchandIfModifiedSincerequest headers. - #head? ⇒ Boolean private
-
#initialize(request:, config:, content_type: nil, env: {}, headers: {}, view_options: nil, sessions_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, **options) ⇒ Object
private
This is NOT RELEASED with 2.0.0.
- #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.
- #set_format(value) ⇒ Object private
-
#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, sessions_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, sessions_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 @sessions_enabled = sessions_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.
152 153 154 |
# File 'lib/hanami/action/response.rb', line 152 def [](key) @exposures.fetch(key) end |
#[]=(key, value) ⇒ Object
Sets an exposure value for the given key.
165 166 167 |
# File 'lib/hanami/action/response.rb', line 165 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.
412 413 414 415 416 417 418 419 420 421 422 423 424 |
# File 'lib/hanami/action/response.rb', line 412 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.
394 395 396 397 398 |
# File 'lib/hanami/action/response.rb', line 394 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 |
# File 'lib/hanami/action/response.rb', line 72 def body=(str) @length = 0 @body = EMPTY_BODY.dup # FIXME: there could be a bug that prevents Content-Length to be sent for files if str.is_a?(::Rack::File::Iterator) @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.
312 313 314 315 |
# File 'lib/hanami/action/response.rb', line 312 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.
215 216 217 |
# File 'lib/hanami/action/response.rb', line 215 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.
341 342 343 344 |
# File 'lib/hanami/action/response.rb', line 341 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.
201 202 203 204 205 206 207 |
# File 'lib/hanami/action/response.rb', line 201 def flash unless @sessions_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.
103 104 105 |
# File 'lib/hanami/action/response.rb', line 103 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.
134 135 136 137 138 139 140 |
# File 'lib/hanami/action/response.rb', line 134 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.
368 369 370 371 372 373 374 375 376 |
# File 'lib/hanami/action/response.rb', line 368 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.
406 407 408 |
# File 'lib/hanami/action/response.rb', line 406 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.
226 227 228 229 230 231 |
# File 'lib/hanami/action/response.rb', line 226 def redirect_to(url, status: 302) return unless allow_redirect? redirect(::String.new(url), status) Halt.call(status) end |
#render(view, **options) ⇒ 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.
This is NOT RELEASED with 2.0.0
87 88 89 |
# File 'lib/hanami/action/response.rb', line 87 def render(view, **) self.body = view.(**.(request, self), **exposures.merge()).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.
386 387 388 389 390 |
# File 'lib/hanami/action/response.rb', line 386 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-TypeandContent-Lengthheaders -
File Not Found responses (returns a 404)
-
Conditional GET (via
If-Modified-Sinceheader) -
Range requests (via
Rangeheader)
251 252 253 254 255 |
# File 'lib/hanami/action/response.rb', line 251 def send_file(path) _send_file( 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.
181 182 183 184 185 186 187 |
# File 'lib/hanami/action/response.rb', line 181 def session unless @sessions_enabled raise Hanami::Action::MissingSessionError.new("Hanami::Action::Response#session") end request.session 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.
380 381 382 |
# File 'lib/hanami/action/response.rb', line 380 def set_format(value) # rubocop:disable Naming/AccessorMethodName @format = value 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.
267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/hanami/action/response.rb', line 267 def unsafe_send_file(path) directory = if Pathname.new(path).relative? @config.root_directory else FILE_SYSTEM_ROOT end _send_file( Rack::File.new(path, directory).call(env) ) end |