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
-
#status=(code) ⇒ Object
Set 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, 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 = || 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 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.
173 174 175 |
# File 'lib/hanami/action/response.rb', line 173 def [](key) @exposures.fetch(key) end |
#[]=(key, value) ⇒ Object
Sets an exposure value for the given key.
186 187 188 |
# File 'lib/hanami/action/response.rb', line 186 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.
433 434 435 436 437 438 439 440 441 442 443 444 445 |
# File 'lib/hanami/action/response.rb', line 433 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.
415 416 417 418 419 |
# File 'lib/hanami/action/response.rb', line 415 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.
333 334 335 336 |
# File 'lib/hanami/action/response.rb', line 333 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.
236 237 238 |
# File 'lib/hanami/action/response.rb', line 236 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.
362 363 364 365 |
# File 'lib/hanami/action/response.rb', line 362 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.
222 223 224 225 226 227 228 |
# File 'lib/hanami/action/response.rb', line 222 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.
124 125 126 |
# File 'lib/hanami/action/response.rb', line 124 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.
155 156 157 158 159 160 161 |
# File 'lib/hanami/action/response.rb', line 155 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.
389 390 391 392 393 394 395 396 397 |
# File 'lib/hanami/action/response.rb', line 389 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.
427 428 429 |
# File 'lib/hanami/action/response.rb', line 427 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.
247 248 249 250 251 252 |
# File 'lib/hanami/action/response.rb', line 247 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
108 109 110 |
# File 'lib/hanami/action/response.rb', line 108 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.
407 408 409 410 411 |
# File 'lib/hanami/action/response.rb', line 407 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)
272 273 274 275 276 |
# File 'lib/hanami/action/response.rb', line 272 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.
202 203 204 205 206 207 208 |
# File 'lib/hanami/action/response.rb', line 202 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.
401 402 403 |
# File 'lib/hanami/action/response.rb', line 401 def set_format(value) # rubocop:disable Naming/AccessorMethodName @format = value end |
#status=(code) ⇒ Object
Set the response status
101 102 103 |
# File 'lib/hanami/action/response.rb', line 101 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.
288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/hanami/action/response.rb', line 288 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 |