Class: Async::HTTP::Protocol::HTTP2::Response
- Inherits:
-
Protocol::Response
- Object
- Protocol::Response
- Async::HTTP::Protocol::HTTP2::Response
- Defined in:
- lib/async/http/protocol/http2/response.rb
Overview
Typically used on the client side for writing a request and reading the incoming response.
Defined Under Namespace
Classes: Stream
Instance Attribute Summary collapse
-
#request ⇒ Object
readonly
Returns the value of attribute request.
-
#stream ⇒ Object
readonly
Returns the value of attribute stream.
Instance Method Summary collapse
-
#build_request(headers) ⇒ Object
Build a request object from push promise headers.
-
#close(error = nil) ⇒ Object
Close this response as quickly as possible.
- #connection ⇒ Object
- #head? ⇒ Boolean
-
#initialize(stream) ⇒ Response
constructor
Initialize the response from an HTTP/2 stream.
-
#pool=(pool) ⇒ Object
Assign the connection pool, releasing the connection when the stream is closed.
-
#send_request(request) ⇒ Object
Send a request and read it into this response.
- #valid? ⇒ Boolean
-
#wait ⇒ Object
Wait for the response headers to be received.
Constructor Details
#initialize(stream) ⇒ Response
Initialize the response from an HTTP/2 stream.
141 142 143 144 145 146 |
# File 'lib/async/http/protocol/http2/response.rb', line 141 def initialize(stream) super(stream.connection.version, nil, nil) @stream = stream @request = nil end |
Instance Attribute Details
#request ⇒ Object (readonly)
Returns the value of attribute request.
149 150 151 |
# File 'lib/async/http/protocol/http2/response.rb', line 149 def request @request end |
#stream ⇒ Object (readonly)
Returns the value of attribute stream.
148 149 150 |
# File 'lib/async/http/protocol/http2/response.rb', line 148 def stream @stream end |
Instance Method Details
#build_request(headers) ⇒ Object
Build a request object from push promise headers.
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/async/http/protocol/http2/response.rb', line 197 def build_request(headers) request = ::Protocol::HTTP::Request.new request.headers = ::Protocol::HTTP::Headers.new headers.each do |key, value| if key == SCHEME raise ::Protocol::HTTP2::HeaderError, "Request scheme already specified!" if request.scheme request.scheme = value elsif key == AUTHORITY raise ::Protocol::HTTP2::HeaderError, "Request authority already specified!" if request. request. = value elsif key == METHOD raise ::Protocol::HTTP2::HeaderError, "Request method already specified!" if request.method request.method = value elsif key == PATH raise ::Protocol::HTTP2::HeaderError, "Request path is empty!" if value.empty? raise ::Protocol::HTTP2::HeaderError, "Request path already specified!" if request.path request.path = value elsif key.start_with? ":" raise ::Protocol::HTTP2::HeaderError, "Invalid pseudo-header #{key}!" else request.headers[key] = value end end @request = request end |
#close(error = nil) ⇒ Object
Close this response as quickly as possible. If the response body is still active, cancel the HTTP/2 exchange rather than draining it.
175 176 177 178 179 180 181 182 |
# File 'lib/async/http/protocol/http2/response.rb', line 175 def close(error = nil) if @body && !@stream.closed? code = error ? ::Protocol::HTTP2::Error::INTERNAL_ERROR : ::Protocol::HTTP2::Error::CANCEL @stream.send_reset_stream(code) end super end |
#connection ⇒ Object
164 165 166 |
# File 'lib/async/http/protocol/http2/response.rb', line 164 def connection @stream.connection end |
#head? ⇒ Boolean
185 186 187 |
# File 'lib/async/http/protocol/http2/response.rb', line 185 def head? @request&.head? end |
#pool=(pool) ⇒ Object
Assign the connection pool, releasing the connection when the stream is closed.
153 154 155 156 157 158 159 160 161 |
# File 'lib/async/http/protocol/http2/response.rb', line 153 def pool=(pool) # If we are already closed, the stream can be released now: if @stream.closed? pool.release(@stream.connection) else # Otherwise, we will release the stream when it is closed: @stream.pool = pool end end |
#send_request(request) ⇒ Object
Send a request and read it into this response.
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/async/http/protocol/http2/response.rb', line 230 def send_request(request) @request = request # https://http2.github.io/http2-spec/#rfc.section.8.1.2.3 # All HTTP/2 requests MUST include exactly one valid value for the :method, :scheme, and :path pseudo-header fields, unless it is a CONNECT request (Section 8.3). An HTTP request that omits mandatory pseudo-header fields is malformed (Section 8.1.2.6). pseudo_headers = [ [SCHEME, request.scheme], [METHOD, request.method], ] if path = request.path pseudo_headers << [PATH, path] end # To ensure that the HTTP/1.1 request line can be reproduced accurately, this pseudo-header field MUST be omitted when translating from an HTTP/1.1 request that has a request target in origin or asterisk form (see [RFC7230], Section 5.3). Clients that generate HTTP/2 requests directly SHOULD use the :authority pseudo-header field instead of the Host header field. if = request. pseudo_headers << [AUTHORITY, ] end if protocol = request.protocol pseudo_headers << [PROTOCOL, protocol] end headers = ::Protocol::HTTP::Headers::Merged.new( pseudo_headers, request.headers.header ) if request.body.nil? @stream.send_headers(headers, ::Protocol::HTTP2::END_STREAM) else if length = request.body.length # This puts it at the end of the pseudo-headers: pseudo_headers << [CONTENT_LENGTH, length] end # This function informs the headers object that any subsequent headers are going to be trailer. Therefore, it must be called *before* sending the headers, to avoid any race conditions. trailer = request.headers.trailer! begin @stream.send_headers(headers) rescue raise ::Protocol::HTTP::RefusedError end @stream.send_body(request.body, trailer) end end |
#valid? ⇒ Boolean
190 191 192 |
# File 'lib/async/http/protocol/http2/response.rb', line 190 def valid? !!@status end |
#wait ⇒ Object
Wait for the response headers to be received.
169 170 171 |
# File 'lib/async/http/protocol/http2/response.rb', line 169 def wait @stream.wait end |