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

Method send_a_data_frame

src/proxy/http2/Http2ConnectionState.cc:2262–2357  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2260}
2261
2262Http2SendDataFrameResult
2263Http2ConnectionState::send_a_data_frame(Http2Stream *stream, size_t &payload_length)
2264{
2265 const ssize_t window_size = std::min(this->get_peer_rwnd(), stream->get_peer_rwnd());
2266 const size_t buf_len = BUFFER_SIZE_FOR_INDEX(buffer_size_index[HTTP2_FRAME_TYPE_DATA]);
2267 const size_t write_available_size = std::min(buf_len, static_cast<size_t>(window_size));
2268 payload_length = 0;
2269
2270 uint8_t flags = 0x00;
2271 IOBufferReader *resp_reader = stream->get_data_reader_for_send();
2272
2273 SCOPED_MUTEX_LOCK(stream_lock, stream->mutex, this_ethread());
2274
2275 if (!resp_reader) {
2276 Http2StreamDebug(this->session, stream->get_id(), "couldn't get data reader");
2277 return Http2SendDataFrameResult::ERROR;
2278 }
2279
2280 // Select appropriate payload length
2281 if (resp_reader->is_read_avail_more_than(0)) {
2282 // We only need to check for window size when there is a payload
2283 if (window_size <= 0) {
2284 if (session->is_outbound()) {
2285 ip_port_text_buffer ipb;
2286 const char *server_ip = ats_ip_ntop(session->get_proxy_session()->get_remote_addr(), ipb, sizeof(ipb));
2287 // Warn the user to give them visibility that their server-side
2288 // connection is being limited by their server's flow control. Maybe
2289 // they can make adjustments.
2290 Warning("No window server_ip=%s session_wnd=%zd stream_wnd=%zd peer_initial_window=%u", server_ip, get_peer_rwnd(),
2291 stream->get_peer_rwnd(), this->peer_settings.get(HTTP2_SETTINGS_INITIAL_WINDOW_SIZE));
2292 }
2293 Http2StreamDebug(this->session, stream->get_id(), "No window session_wnd=%zd stream_wnd=%zd peer_initial_window=%u",
2294 get_peer_rwnd(), stream->get_peer_rwnd(), this->peer_settings.get(HTTP2_SETTINGS_INITIAL_WINDOW_SIZE));
2295 this->session->flush();
2296 return Http2SendDataFrameResult::NO_WINDOW;
2297 }
2298
2299 if (resp_reader->is_read_avail_more_than(write_available_size)) {
2300 payload_length = write_available_size;
2301 } else {
2302 payload_length = resp_reader->read_avail();
2303 }
2304 } else {
2305 payload_length = 0;
2306 }
2307
2308 // For HTTP/2 sessions, is_write_high_water() returning true correlates to
2309 // our write buffer exceeding HTTP2_SETTINGS_MAX_FRAME_SIZE. Thus we will
2310 // hold off on processing the payload until the write buffer is drained.
2311 if (payload_length > 0 && this->session->is_write_high_water()) {
2312 Http2StreamDebug(this->session, stream->get_id(), "Not write avail, payload_length=%zu", payload_length);
2313 this->session->flush();
2314 return Http2SendDataFrameResult::NOT_WRITE_AVAIL;
2315 }
2316
2317 stream->update_sent_count(payload_length);
2318
2319 // Are we at the end?

Callers

nothing calls this directly

Calls 15

get_peer_rwndMethod · 0.95
decrement_peer_rwndMethod · 0.95
this_ethreadFunction · 0.85
is_write_high_waterMethod · 0.80
update_sent_countMethod · 0.80
is_write_vio_doneMethod · 0.80
xmitMethod · 0.80
is_tunnelingMethod · 0.80
change_stateMethod · 0.80
ats_ip_ntopFunction · 0.50

Tested by

no test coverage detected