Class: Rack::Response
- Includes:
- Helpers
- Defined in:
- vendor/bundler/ruby/3.4.0/bundler/gems/rack-40d68f842b5f/lib/rack/response.rb
Overview
Rack::Response provides a convenient interface to create a Rack response.
It allows setting of headers and cookies, and provides useful defaults (an OK response with empty headers and body).
You can use Response#write to iteratively generate your response, but note that this is buffered by Rack::Response until you call +finish+. +finish+ however can take a block inside which calls to +write+ are synchronous with the Rack response.
Your application's +call+ should end returning Response#finish.
Direct Known Subclasses
Defined Under Namespace
Constant Summary collapse
- CHUNKED =
'chunked'
- STATUS_WITH_NO_ENTITY_BODY =
Utils::STATUS_WITH_NO_ENTITY_BODY
Instance Attribute Summary collapse
-
#body ⇒ Object
Returns the value of attribute body.
-
#headers ⇒ Object
readonly
Returns the value of attribute headers.
-
#length ⇒ Object
Returns the value of attribute length.
-
#status ⇒ Object
Returns the value of attribute status.
Class Method Summary collapse
Instance Method Summary collapse
- #chunked? ⇒ Boolean
- #close ⇒ Object
- #delete_header(key) ⇒ Object
- #each(&callback) ⇒ Object
- #empty? ⇒ Boolean
-
#finish(&block) ⇒ Array
(also: #to_a)
Generate a response array consistent with the requirements of the SPEC.
- #get_header(key) ⇒ Object (also: #[])
- #has_header?(key) ⇒ Boolean
-
#initialize(body = nil, status = 200, headers = {}) {|_self| ... } ⇒ Response
constructor
Initialize the response object with the specified +body+, +status+ and +headers+.
- #no_entity_body? ⇒ Boolean
- #redirect(target, status = 302) ⇒ Object
- #set_header(key, value) ⇒ Object (also: #[]=)
-
#write(chunk) ⇒ Object
Append a chunk to the response body.
Methods included from Helpers
#accepted?, #add_header, #append, #bad_request?, #buffered_body!, #cache!, #cache_control, #cache_control=, #client_error?, #content_length, #content_type, #content_type=, #created?, #delete_cookie, #do_not_cache!, #etag, #etag=, #forbidden?, #include?, #informational?, #invalid?, #location, #location=, #media_type, #media_type_params, #method_not_allowed?, #moved_permanently?, #no_content?, #not_acceptable?, #not_found?, #ok?, #precondition_failed?, #redirect?, #redirection?, #request_timeout?, #server_error?, #set_cookie, #set_cookie_header, #set_cookie_header=, #successful?, #unauthorized?, #unprocessable?
Constructor Details
#initialize(body = nil, status = 200, headers = {}) {|_self| ... } ⇒ Response
Initialize the response object with the specified +body+, +status+ and +headers+.
If the +body+ is +nil+, construct an empty response object with internal buffering.
If the +body+ responds to +to_str+, assume it's a string-like object and construct a buffered response object containing using that string as the initial contents of the buffer.
Otherwise it is expected +body+ conforms to the normal requirements of a Rack response body, typically implementing one of +each+ (enumerable body) or +call+ (streaming body).
The +status+ defaults to +200+ which is the "OK" HTTP status code. You can provide any other valid status code.
The +headers+ must be a +Hash+ of key-value header pairs which conform to the Rack specification for response headers. The key must be a +String+ instance and the value can be either a +String+ or +Array+ instance.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'vendor/bundler/ruby/3.4.0/bundler/gems/rack-40d68f842b5f/lib/rack/response.rb', line 54 def initialize(body = nil, status = 200, headers = {}) @status = status.to_i unless headers.is_a?(Hash) raise ArgumentError, "Headers must be a Hash!" end @headers = Headers.new # Convert headers input to a plain hash with lowercase keys. headers.each do |k, v| @headers[k] = v end @writer = self.method(:append) @block = nil # Keep track of whether we have expanded the user supplied body. if body.nil? @body = [] @buffered = true # Body is unspecified - it may be a buffered response, or it may be a HEAD response. @length = nil elsif body.respond_to?(:to_str) @body = [body] @buffered = true @length = body.to_str.bytesize else @body = body @buffered = nil # undetermined as of yet. @length = nil end yield self if block_given? end |
Instance Attribute Details
#body ⇒ Object
Returns the value of attribute body.
31 32 33 |
# File 'vendor/bundler/ruby/3.4.0/bundler/gems/rack-40d68f842b5f/lib/rack/response.rb', line 31 def body @body end |
#headers ⇒ Object (readonly)
Returns the value of attribute headers.
32 33 34 |
# File 'vendor/bundler/ruby/3.4.0/bundler/gems/rack-40d68f842b5f/lib/rack/response.rb', line 32 def headers @headers end |
#length ⇒ Object
Returns the value of attribute length.
31 32 33 |
# File 'vendor/bundler/ruby/3.4.0/bundler/gems/rack-40d68f842b5f/lib/rack/response.rb', line 31 def length @length end |
#status ⇒ Object
Returns the value of attribute status.
31 32 33 |
# File 'vendor/bundler/ruby/3.4.0/bundler/gems/rack-40d68f842b5f/lib/rack/response.rb', line 31 def status @status end |
Class Method Details
.[](status, headers, body) ⇒ Object
24 25 26 |
# File 'vendor/bundler/ruby/3.4.0/bundler/gems/rack-40d68f842b5f/lib/rack/response.rb', line 24 def self.[](status, headers, body) self.new(body, status, headers) end |
Instance Method Details
#chunked? ⇒ Boolean
95 96 97 |
# File 'vendor/bundler/ruby/3.4.0/bundler/gems/rack-40d68f842b5f/lib/rack/response.rb', line 95 def chunked? CHUNKED == get_header(TRANSFER_ENCODING) end |
#close ⇒ Object
152 153 154 |
# File 'vendor/bundler/ruby/3.4.0/bundler/gems/rack-40d68f842b5f/lib/rack/response.rb', line 152 def close @body.close if @body.respond_to?(:close) end |
#delete_header(key) ⇒ Object
172 173 174 175 |
# File 'vendor/bundler/ruby/3.4.0/bundler/gems/rack-40d68f842b5f/lib/rack/response.rb', line 172 def delete_header(key) raise ArgumentError unless key.is_a?(String) @headers.delete key end |
#each(&callback) ⇒ Object
130 131 132 133 134 135 136 137 138 |
# File 'vendor/bundler/ruby/3.4.0/bundler/gems/rack-40d68f842b5f/lib/rack/response.rb', line 130 def each(&callback) @body.each(&callback) @buffered = true if @block @writer = callback @block.call(self) end end |
#empty? ⇒ Boolean
156 157 158 |
# File 'vendor/bundler/ruby/3.4.0/bundler/gems/rack-40d68f842b5f/lib/rack/response.rb', line 156 def empty? @block == nil && @body.empty? end |
#finish(&block) ⇒ Array Also known as: to_a
Generate a response array consistent with the requirements of the SPEC.
which is suitable to be returned from the middleware #call(env)
method.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'vendor/bundler/ruby/3.4.0/bundler/gems/rack-40d68f842b5f/lib/rack/response.rb', line 107 def finish(&block) if no_entity_body? delete_header CONTENT_TYPE delete_header CONTENT_LENGTH close return [@status, @headers, []] else if block_given? # We don't add the content-length here as the user has provided a block that can #write additional chunks to the body. @block = block return [@status, @headers, self] else # If we know the length of the body, set the content-length header... except if we are chunked? which is a legacy special case where the body might already be encoded and thus the actual encoded body length and the content-length are likely to be different. if @length && !chunked? @headers[CONTENT_LENGTH] = @length.to_s end return [@status, @headers, @body] end end end |
#get_header(key) ⇒ Object Also known as: []
164 165 166 167 |
# File 'vendor/bundler/ruby/3.4.0/bundler/gems/rack-40d68f842b5f/lib/rack/response.rb', line 164 def get_header(key) raise ArgumentError unless key.is_a?(String) @headers[key] end |
#has_header?(key) ⇒ Boolean
160 161 162 163 |
# File 'vendor/bundler/ruby/3.4.0/bundler/gems/rack-40d68f842b5f/lib/rack/response.rb', line 160 def has_header?(key) raise ArgumentError unless key.is_a?(String) @headers.key?(key) end |
#no_entity_body? ⇒ Boolean
99 100 101 102 |
# File 'vendor/bundler/ruby/3.4.0/bundler/gems/rack-40d68f842b5f/lib/rack/response.rb', line 99 def no_entity_body? # The response body is an enumerable body and it is not allowed to have an entity body. @body.respond_to?(:each) && STATUS_WITH_NO_ENTITY_BODY[@status] end |
#redirect(target, status = 302) ⇒ Object
90 91 92 93 |
# File 'vendor/bundler/ruby/3.4.0/bundler/gems/rack-40d68f842b5f/lib/rack/response.rb', line 90 def redirect(target, status = 302) self.status = status self.location = target end |
#set_header(key, value) ⇒ Object Also known as: []=
168 169 170 171 |
# File 'vendor/bundler/ruby/3.4.0/bundler/gems/rack-40d68f842b5f/lib/rack/response.rb', line 168 def set_header(key, value) raise ArgumentError unless key.is_a?(String) @headers[key] = value end |
#write(chunk) ⇒ Object
Append a chunk to the response body.
Converts the response into a buffered response if it wasn't already.
NOTE: Do not mix #write and direct #body access!
146 147 148 149 150 |
# File 'vendor/bundler/ruby/3.4.0/bundler/gems/rack-40d68f842b5f/lib/rack/response.rb', line 146 def write(chunk) buffered_body! @writer.call(chunk.to_s) end |