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

Method rcv_continuation_frame

src/proxy/http2/Http2ConnectionState.cc:1011–1138  ·  view source on GitHub ↗

* [RFC 7540] 6.10 CONTINUATION * * NOTE: Logically, the CONTINUATION frames are part of the HEADERS frame. ([RFC *7540] 6.2 HEADERS) * */

Source from the content-addressed store, hash-verified

1009 *
1010 */
1011Http2Error
1012Http2ConnectionState::rcv_continuation_frame(const Http2Frame &frame)
1013{
1014 const Http2StreamId stream_id = frame.header().streamid;
1015 const uint32_t payload_length = frame.header().length;
1016
1017 Http2StreamDebug(this->session, stream_id, "Received CONTINUATION frame");
1018
1019 if (!http2_is_client_streamid(stream_id)) {
1020 return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_PROTOCOL_ERROR,
1021 "continuation bad client id");
1022 }
1023
1024 if (payload_length == 0 && (frame.header().flags & HTTP2_FLAGS_HEADERS_END_HEADERS) == 0x0) {
1025 this->increment_received_empty_frame_count();
1026 if (configured_max_empty_frames_per_minute >= 0 &&
1027 this->get_received_empty_frame_count() > static_cast<uint32_t>(configured_max_empty_frames_per_minute)) {
1028 Metrics::Counter::increment(http2_rsb.max_empty_frames_per_minute_exceeded);
1029 Http2StreamDebug(this->session, stream_id, "Observed too many empty CONTINUATION frames: %u within the last minute",
1030 this->get_received_empty_frame_count());
1031 return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_ENHANCE_YOUR_CALM,
1032 "recv continuation too frequent empty frame");
1033 }
1034 }
1035
1036 // Find opened stream
1037 // CONTINUATION frames MUST be associated with a stream. If a
1038 // CONTINUATION frame is received whose stream identifier field is 0x0,
1039 // the recipient MUST respond with a connection error ([RFC 7540] Section
1040 // 5.4.1) of type PROTOCOL_ERROR.
1041 Http2Stream *stream = this->find_stream(stream_id);
1042 if (stream == nullptr) {
1043 if (this->is_valid_streamid(stream_id)) {
1044 return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_STREAM_CLOSED,
1045 "continuation stream freed with valid id");
1046 } else {
1047 return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_PROTOCOL_ERROR,
1048 "continuation stream freed with invalid id");
1049 }
1050 } else {
1051 switch (stream->get_state()) {
1052 case Http2StreamState::HTTP2_STREAM_STATE_HALF_CLOSED_REMOTE:
1053 return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_STREAM_CLOSED,
1054 "continuation half close remote");
1055 case Http2StreamState::HTTP2_STREAM_STATE_IDLE:
1056 break;
1057 default:
1058 return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_PROTOCOL_ERROR,
1059 "continuation bad state");
1060 }
1061 }
1062
1063 // Update CONTINUATION frame count per minute.
1064 this->increment_received_continuation_frame_count();
1065 // Close this connection if its CONTINUATION frame count exceeds a limit.
1066 if (configured_max_continuation_frames_per_minute != 0 &&
1067 this->get_received_continuation_frame_count() > static_cast<uint32_t>(configured_max_continuation_frames_per_minute)) {
1068 Metrics::Counter::increment(http2_rsb.max_continuation_frames_per_minute_exceeded);

Callers

nothing calls this directly

Calls 15

find_streamMethod · 0.95
is_valid_streamidMethod · 0.95
http2_is_client_streamidFunction · 0.85
Http2ErrorClass · 0.85
incrementFunction · 0.85
ats_reallocFunction · 0.85
this_ethreadFunction · 0.85

Tested by

no test coverage detected