Class: Async::HTTP::Protocol::HTTP2::Response
- Inherits:
-
Response
- Object
- Protocol::HTTP::Response
- 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.
- #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.
Methods inherited from Response
#hijack?, #inspect, #peer, #remote_address
Constructor Details
#initialize(stream) ⇒ Response
Initialize the response from an HTTP/2 stream.
144 145 146 147 148 149 |
# File 'lib/async/http/protocol/http2/response.rb', line 144 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.
152 153 154 |
# File 'lib/async/http/protocol/http2/response.rb', line 152 def request @request end |
#stream ⇒ Object (readonly)
Returns the value of attribute stream.
151 152 153 |
# File 'lib/async/http/protocol/http2/response.rb', line 151 def stream @stream end |
Instance Method Details
#build_request(headers) ⇒ Object
Build a request object from push promise headers.
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/async/http/protocol/http2/response.rb', line 189 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 |
#connection ⇒ Object
167 168 169 |
# File 'lib/async/http/protocol/http2/response.rb', line 167 def connection @stream.connection end |
#head? ⇒ Boolean
177 178 179 |
# File 'lib/async/http/protocol/http2/response.rb', line 177 def head? @request&.head? end |
#pool=(pool) ⇒ Object
Assign the connection pool, releasing the connection when the stream is closed.
156 157 158 159 160 161 162 163 164 |
# File 'lib/async/http/protocol/http2/response.rb', line 156 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.
222 223 224 225 226 227 228 229 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 |
# File 'lib/async/http/protocol/http2/response.rb', line 222 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
182 183 184 |
# File 'lib/async/http/protocol/http2/response.rb', line 182 def valid? !!@status end |
#wait ⇒ Object
Wait for the response headers to be received.
172 173 174 |
# File 'lib/async/http/protocol/http2/response.rb', line 172 def wait @stream.wait end |