| 294 | } |
| 295 | |
| 296 | void |
| 297 | Http2Stream::send_headers(Http2ConnectionState & /* cstate ATS_UNUSED */) |
| 298 | { |
| 299 | if (closed) { |
| 300 | return; |
| 301 | } |
| 302 | REMEMBER(NO_EVENT, this->reentrancy_count); |
| 303 | |
| 304 | // Convert header to HTTP/1.1 format. Trailing headers need no conversion |
| 305 | // because they, by definition, do not contain pseudo headers. |
| 306 | if (this->trailing_header_is_possible()) { |
| 307 | Http2StreamDebug("trailing header: Skipping send_headers initialization."); |
| 308 | } else { |
| 309 | if (http2_convert_header_from_2_to_1_1(&_receive_header) == PARSE_RESULT_ERROR) { |
| 310 | Http2StreamDebug("Error converting HTTP/2 headers to HTTP/1.1."); |
| 311 | if (_receive_header.type_get() == HTTP_TYPE_REQUEST) { |
| 312 | // There's no way to cause Bad Request directly at this time. |
| 313 | // Set an invalid method so it causes an error later. |
| 314 | _receive_header.method_set("\xffVOID", 1); |
| 315 | } |
| 316 | } |
| 317 | |
| 318 | if (_receive_header.type_get() == HTTP_TYPE_REQUEST) { |
| 319 | // Check whether the request uses CONNECT method |
| 320 | int method_len; |
| 321 | const char *method = _receive_header.method_get(&method_len); |
| 322 | if (method_len == HTTP_LEN_CONNECT && strncmp(method, HTTP_METHOD_CONNECT, HTTP_LEN_CONNECT) == 0) { |
| 323 | this->_is_tunneling = true; |
| 324 | } |
| 325 | } |
| 326 | ink_release_assert(this->_sm != nullptr); |
| 327 | this->_http_sm_id = this->_sm->sm_id; |
| 328 | } |
| 329 | |
| 330 | // Write header to a buffer. Borrowing logic from HttpSM::write_header_into_buffer. |
| 331 | // Seems like a function like this ought to be in HTTPHdr directly |
| 332 | int bufindex; |
| 333 | int dumpoffset = 0; |
| 334 | // The name dumpoffset is used here for parity with |
| 335 | // HttpSM::write_header_into_buffer, but create an alias for clarity in the |
| 336 | // use of this variable below this loop. |
| 337 | int &num_header_bytes = dumpoffset; |
| 338 | int done, tmp; |
| 339 | do { |
| 340 | bufindex = 0; |
| 341 | tmp = dumpoffset; |
| 342 | IOBufferBlock *block = this->_receive_buffer.get_current_block(); |
| 343 | if (!block) { |
| 344 | this->_receive_buffer.add_block(); |
| 345 | block = this->_receive_buffer.get_current_block(); |
| 346 | } |
| 347 | done = _receive_header.print(block->end(), block->write_avail(), &bufindex, &tmp); |
| 348 | dumpoffset += bufindex; |
| 349 | this->_receive_buffer.fill(bufindex); |
| 350 | if (!done) { |
| 351 | this->_receive_buffer.add_block(); |
| 352 | } |
| 353 | } while (!done); |
no test coverage detected