frame_length = data_len = frame_len;
padding_len = data_bytes_read = padding_read = 0;
frame_flags = flags;
- frame_bytes_seen = cur_data_offset = FRAME_HEADER_LENGTH;
- *flush_offset = FRAME_HEADER_LENGTH;
- data_state = ((frame_flags & PADDED) !=0) ? PADDING_LENGTH : DATA;
+ *flush_offset = frame_bytes_seen = FRAME_HEADER_LENGTH;
+
+ if (frame_length == 0)
+ data_state = FULL_FRAME;
+ else if ((frame_flags & PADDED) !=0)
+ data_state = PADDING_LENGTH;
+ else
+ data_state = DATA;
}
uint32_t cur_pos = data_offset + leftover_bytes;
session_data->events[source_id]->create_event(EVENT_PADDING_LEN);
return false;
}
- // FIXIT temporary - till multiple data frames sent to http
- if (data_len == (padding_len + 1))
- return false;
data_len -= (padding_len + 1);
- data_state = DATA;
+
+ if (data_len)
+ data_state = DATA;
+ else if (padding_len)
+ data_state = PADDING;
+ else
+ data_state = FULL_FRAME;
cur_pos++;
cur_data_offset++;
break;
if (frame_flags & END_STREAM)
{
finish_msg_body(session_data, source_id);
+ session_data->data_processing[source_id] = false;
return StreamSplitter::FLUSH;
}
else
reassemble_frame_flags = get_frame_flags(session_data->frame_header[source_id]+
session_data->frame_header_offset[source_id]);
cur_data_offset = cur_pos;
- reassemble_state = ((reassemble_frame_flags & PADDED) !=0) ? GET_PADDING_LEN :
- SEND_DATA;
session_data->frame_header_offset[source_id] += FRAME_HEADER_LENGTH;
+
+ if (reassemble_data_len == 0)
+ reassemble_state = CLEANUP;
+ else if ((reassemble_frame_flags & PADDED) !=0)
+ reassemble_state = GET_PADDING_LEN;
+ else
+ reassemble_state = SEND_DATA;
}
break;
reassemble_data_len -= (reassemble_padding_len + 1);
cur_pos++;
cur_data_offset++;
- reassemble_state = SEND_DATA;
+ if (reassemble_data_len)
+ reassemble_state = SEND_DATA;
+ else if (reassemble_padding_len)
+ reassemble_state = SKIP_PADDING;
+ else
+ reassemble_state = CLEANUP;
break;
case SEND_DATA:
{
if (stream && stream->abort_on_data_is_set(source_id))
return StreamSplitter::ABORT;
- HttpFlowData* http_flow = nullptr;
- if (stream)
- http_flow = (HttpFlowData*)stream->get_hi_flow_data();
+ if (!stream || stream->end_stream_is_set(source_id))
+ {
+ *session_data->infractions[source_id] += INF_FRAME_SEQUENCE;
+ session_data->events[source_id]->create_event(EVENT_FRAME_SEQUENCE);
+ return StreamSplitter::ABORT;
+ }
- if (!stream || !http_flow || stream->end_stream_is_set(source_id) ||
- (frame_length > 0 and (http_flow->get_type_expected(source_id) != HttpEnums::SEC_BODY_H2)))
+ HttpFlowData* const http_flow = (HttpFlowData*)stream->get_hi_flow_data();
+ if (http_flow == nullptr)
{
*session_data->infractions[source_id] += INF_FRAME_SEQUENCE;
session_data->events[source_id]->create_event(EVENT_FRAME_SEQUENCE);
return StreamSplitter::ABORT;
}
- if (frame_length == 0 or frame_length > MAX_OCTETS)
+ if (http_flow->get_type_expected(source_id) != HttpEnums::SEC_BODY_H2)
+ {
+ // If 0 length frame and http isn't expecting body, flush without involving http
+ if (frame_length == 0)
+ {
+ *flush_offset = data_offset;
+ return StreamSplitter::FLUSH;
+ }
+
+ *session_data->infractions[source_id] += INF_FRAME_SEQUENCE;
+ session_data->events[source_id]->create_event(EVENT_FRAME_SEQUENCE);
+ return StreamSplitter::ABORT;
+ }
+
+ if (frame_length > MAX_OCTETS)
return StreamSplitter::ABORT;
Http2DataCutter* data_cutter = stream->get_data_cutter(source_id);
{
session_data->current_stream[source_id] = old_stream;
session_data->frame_type[source_id] = FT_DATA;
- finish_msg_body(session_data, source_id);
+ Http2Stream* const stream = session_data->find_stream(
+ session_data->current_stream[source_id]);
+ Http2DataCutter* const data_cutter = stream->get_data_cutter(source_id);
+ if (data_cutter->is_flush_required())
+ finish_msg_body(session_data, source_id);
+ session_data->data_processing[source_id] = false;
*flush_offset = FRAME_HEADER_LENGTH;
session_data->flushing_data[source_id] = true;
memcpy(session_data->leftover_hdr[source_id],
session_data->scan_frame_header[source_id], FRAME_HEADER_LENGTH);
session_data->num_frame_headers[source_id] -= 1;
- Http2Stream* const stream = session_data->find_stream(
- session_data->current_stream[source_id]);
stream->set_abort_on_data(source_id);
}