MCPcopy Create free account
hub / github.com/apache/trafficserver / send_headers_frame

Method send_headers_frame

src/proxy/http2/Http2ConnectionState.cc:2413–2524  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2411}
2412
2413void
2414Http2ConnectionState::send_headers_frame(Http2Stream *stream)
2415{
2416 uint32_t header_blocks_size = 0;
2417 int payload_length = 0;
2418 uint8_t flags = 0x00;
2419
2420 // For outbound streams, set the ID if it has not yet already been set
2421 // Need to defer setting the stream ID to avoid another later created stream
2422 // sending out first. This may cause the peer to issue a stream or connection
2423 // error (new stream less that the greatest we have seen so far)
2424 this->set_stream_id(stream);
2425
2426 // Keep this debug below set_stream_id so that the id is correct.
2427 Http2StreamDebug(session, stream->get_id(), "Send HEADERS frame");
2428
2429 HTTPHdr *send_hdr = stream->get_send_header();
2430 if (stream->expect_send_trailer()) {
2431 // Which is a no-op conversion
2432 } else {
2433 http2_convert_header_from_1_1_to_2(send_hdr);
2434 }
2435
2436 uint32_t buf_len = send_hdr->length_get() * 2; // Make it double just in case
2437 ts::LocalBuffer local_buffer(buf_len);
2438 uint8_t *buf = local_buffer.data();
2439
2440 stream->mark_milestone(Http2StreamMilestone::START_ENCODE_HEADERS);
2441 Http2ErrorCode result = http2_encode_header_blocks(send_hdr, buf, buf_len, &header_blocks_size, *(this->peer_hpack_handle),
2442 peer_settings.get(HTTP2_SETTINGS_HEADER_TABLE_SIZE));
2443 if (result != Http2ErrorCode::HTTP2_ERROR_NO_ERROR) {
2444 return;
2445 }
2446
2447 // Send a HEADERS frame
2448 if (header_blocks_size <= static_cast<uint32_t>(BUFFER_SIZE_FOR_INDEX(buffer_size_index[HTTP2_FRAME_TYPE_HEADERS]))) {
2449 payload_length = header_blocks_size;
2450 flags |= HTTP2_FLAGS_HEADERS_END_HEADERS;
2451 if (stream->is_outbound_connection()) { // Will be sending a request_header
2452 int method = send_hdr->method_get_wksidx();
2453
2454 // Set END_STREAM on request headers for POST, etc. methods combined with
2455 // an explicit length 0. Some origins RST on request headers with
2456 // explicit zero length and no end stream flag, causing the request to
2457 // fail. We emulate chromium behaviour here prevent such RSTs. Transfer-encoding
2458 // implies there’s a body, regardless of whether it is chunked or not.
2459 bool content_method = method == HTTP_WKSIDX_POST || method == HTTP_WKSIDX_PUSH || method == HTTP_WKSIDX_PUT;
2460 bool is_transfer_encoded = send_hdr->presence(MIME_PRESENCE_TRANSFER_ENCODING);
2461 bool has_content_header = send_hdr->presence(MIME_PRESENCE_CONTENT_LENGTH);
2462 bool explicit_zero_length = has_content_header && send_hdr->get_content_length() == 0;
2463 int64_t content_length = has_content_header ? send_hdr->get_content_length() : 0L;
2464 bool is_chunked =
2465 is_transfer_encoded && send_hdr->value_get(MIME_FIELD_TRANSFER_ENCODING) == std::string_view(HTTP_VALUE_CHUNKED);
2466
2467 bool expect_content_stream =
2468 is_transfer_encoded || // transfer encoded content length is unknown
2469 (!content_method && has_content_header && !explicit_zero_length) || // nonzero content with GET,etc
2470 (content_method && !explicit_zero_length) || // content-length >0 or empty with POST etc

Callers 1

update_write_requestMethod · 0.80

Calls 15

set_stream_idMethod · 0.95
send_goaway_frameMethod · 0.95
this_ethreadFunction · 0.85
get_send_headerMethod · 0.80
mark_milestoneMethod · 0.80
method_get_wksidxMethod · 0.80
presenceMethod · 0.80
get_content_lengthMethod · 0.80
get_ua_txnMethod · 0.80

Tested by

no test coverage detected