Class: Cybertrain::Response
- Inherits:
-
Object
- Object
- Cybertrain::Response
- Defined in:
- cybertrain/http/response.rb
Overview
The response a request builds up on its way through the stack; the Server serializes it with #to_http. Headers keep the case they were set with, and Set-Cookie values live in their own list because one response may carry several.
Controller#response in an action. Controller#render,
Controller#redirect_to and Controller#head set the status and body;
use this object for headers and cookies. Content-Length is always
computed, and Content-Type defaults to text/html; charset=utf-8.
Instance Attribute Summary collapse
-
#body ⇒ String
The body,
""until set. -
#cookies ⇒ Array<String>
readonly
The Set-Cookie values added so far.
-
#headers ⇒ Hash{String => String}
readonly
The headers set so far, in the case they were set with; change them through #set_header and #drop_header.
-
#status ⇒ Integer
The status code, 200 until set.
Instance Method Summary collapse
-
#add_cookie(set_cookie_value) ⇒ Object
Adds a Set-Cookie header; build the value with Cookies.serialize.
-
#content_type=(value) ⇒ Object
-
#drop_header(name) ⇒ nil
Removes the header of that name, whatever its case (every spelling when several were stored); a missing one is not an error.
-
#header(name) ⇒ String?
-
#set_header(name, value) ⇒ Object
Replaces any existing header of the same name, whatever its case, keeping its position in the output.
Instance Attribute Details
#body ⇒ String
The body, "" until set.
36 37 38 |
# File 'cybertrain/http/response.rb', line 36 def body @body end |
#cookies ⇒ Array<String> (readonly)
The Set-Cookie values added so far.
47 48 49 |
# File 'cybertrain/http/response.rb', line 47 def @cookies end |
#headers ⇒ Hash{String => String} (readonly)
The headers set so far, in the case they were set with; change them through #set_header and #drop_header.
42 43 44 |
# File 'cybertrain/http/response.rb', line 42 def headers @headers end |
#status ⇒ Integer
The status code, 200 until set. A code missing from STATUS_TEXT (401, 409, …) is sent with the reason phrase “Unknown”.
31 32 33 |
# File 'cybertrain/http/response.rb', line 31 def status @status end |
Instance Method Details
#add_cookie(set_cookie_value) ⇒ Object
Adds a Set-Cookie header; build the value with Cookies.serialize. Raises ArgumentError when the value contains CR or LF.
150 151 152 153 |
# File 'cybertrain/http/response.rb', line 150 def () reject_crlf!("Set-Cookie", ) @cookies << end |
#content_type=(value) ⇒ Object
142 143 144 |
# File 'cybertrain/http/response.rb', line 142 def content_type=(value) set_header("Content-Type", value) end |
#drop_header(name) ⇒ nil
Removes the header of that name, whatever its case (every spelling
when several were stored); a missing one is not an error. Returns nil
(NOTES rules 10/34: one return type for the name). Edits @headers in
place: headers is a public reader, so a Hash a before_action or
middleware took earlier must still be the live one afterwards. The
matching keys are collected first (never delete while iterating) and
removed with Hash#delete; no block-taking Hash method is needed.
125 126 127 128 129 130 |
# File 'cybertrain/http/response.rb', line 125 def drop_header(name) gone = [] @headers.keys.each { |k| gone << k if HeaderName.same?(k, name) } gone.each { |k| @headers.delete(k) } nil end |
#header(name) ⇒ String?
135 136 137 138 |
# File 'cybertrain/http/response.rb', line 135 def header(name) key = header_key(name) key.nil? ? nil : @headers[key] end |
#set_header(name, value) ⇒ Object
Replaces any existing header of the same name, whatever its case, keeping its position in the output. Raises ArgumentError when the name or value contains CR or LF (header injection / response splitting).
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'cybertrain/http/response.rb', line 94 def set_header(name, value) reject_crlf!(name, name) reject_crlf!(name, value) existing = header_key(name) if existing.nil? || existing == name @headers[name] = value else # Rebuilt in place (clear, then put back in order): `headers` is a # public reader, so a Hash a before_action or middleware kept must # stay the live one. names = [] values = [] @headers.each do |k, v| names << (k == existing ? name : k) values << v end @headers.clear names.each_with_index { |k, i| @headers[k] = k == name ? value : values[i] } end end |