hpack_decoder = &session_data->hpack_decoder[source_id];
}
-
-Http2HeadersFrame::~Http2HeadersFrame()
-{
- hpack_decoder->cleanup();
-}
-
void Http2HeadersFrame::clear()
{
if (session_data->abort_flow[source_id] || stream->get_state(source_id) == STREAM_ERROR)
session_data->hi->clear(&dummy_pkt);
}
+bool Http2HeadersFrame::decode_headers(Http2StartLine* start_line_generator, bool trailers)
+{
+ const uint32_t encoded_headers_length = (data.length() > hpack_headers_offset) ?
+ data.length() - hpack_headers_offset : 0;
+ if (!hpack_decoder->decode_headers((data.start() + hpack_headers_offset),
+ encoded_headers_length, start_line_generator, trailers))
+ {
+ if (!(*session_data->infractions[source_id] & INF_TRUNCATED_HEADER_LINE))
+ {
+ session_data->abort_flow[source_id] = true;
+ session_data->events[source_id]->create_event(EVENT_MISFORMATTED_HTTP2);
+ http1_header.set(STAT_PROBLEMATIC);
+ hpack_decoder->cleanup();
+ return false;
+ }
+ }
+ hpack_decoder->set_decoded_headers(http1_header);
+ return true;
+}
+
void Http2HeadersFrame::process_decoded_headers(HttpFlowData* http_flow, SourceId hi_source_id)
{
- if (session_data->abort_flow[source_id])
+ if (session_data->abort_flow[source_id] or http1_header.length() < 0)
return;
- hpack_decoder->set_decoded_headers(http1_header);
+ if (http1_header.length() <= 0 and !session_data->is_processing_partial_header())
+ {
+ // This shouldn't happen because well-formatted empty frames have crlf written to the
+ // decoded headers buffer
+ assert(false);
+ return;
+ }
+
StreamBuffer stream_buf;
// http_inspect scan() of headers
// be empty. Don't call scan on the empty buffer because it will create a cutter and the check
// for this condition in HI::finish() will fail. Truncated headers with non-empty http1_header
// buffers are still sent to HI::scan().
- assert ((http1_header.length() > 0) or session_data->is_processing_partial_header());
if (http1_header.length() > 0)
{
uint32_t flush_offset;
class Http2HeadersFrame : public Http2Frame
{
public:
- ~Http2HeadersFrame() override;
void clear() override;
const Field& get_buf(unsigned id) override;
Http2HeadersFrame(const uint8_t* header_buffer, const uint32_t header_len,
const uint8_t* data_buffer, const uint32_t data_len, Http2FlowData* ssn_data,
HttpCommon::SourceId src_id, Http2Stream* stream);
+ bool decode_headers(Http2StartLine* start_line_generator, bool trailers);
void process_decoded_headers(HttpFlowData* http_flow, HttpCommon::SourceId hi_source_id);
uint8_t get_flags_mask() const override;
start_line_generator = new Http2StatusLine(session_data->events[source_id],
session_data->infractions[source_id]);
- // Decode headers
- const uint32_t encoded_headers_length = (data.length() > hpack_headers_offset) ?
- data.length() - hpack_headers_offset : 0;
- if (!hpack_decoder->decode_headers((data.start() + hpack_headers_offset),
- encoded_headers_length, start_line_generator, false))
+ if (decode_headers(start_line_generator, false))
{
- if (!(*session_data->infractions[source_id] & INF_TRUNCATED_HEADER_LINE))
+ // process start line
+ if (!start_line_generator->generate_start_line(start_line, are_pseudo_headers_complete()))
{
- session_data->abort_flow[source_id] = true;
- session_data->events[source_id]->create_event(EVENT_MISFORMATTED_HTTP2);
- return;
+ stream->set_state(source_id, STREAM_ERROR);
}
}
-
- // process start line
- if (!start_line_generator->generate_start_line(start_line, are_pseudo_headers_complete()))
- {
- stream->set_state(source_id, STREAM_ERROR);
- }
}
bool Http2HeadersFrameHeader::valid_sequence(Http2Enums::StreamState state)
*session_data->infractions[source_id] += INF_TRAILERS_NOT_END;
session_data->events[source_id]->create_event(EVENT_TRAILERS_NOT_END);
}
-
- // Decode trailers
- const uint32_t encoded_headers_length = (data.length() > hpack_headers_offset) ?
- data.length() - hpack_headers_offset : 0;
- if (!hpack_decoder->decode_headers((data.start() + hpack_headers_offset),
- encoded_headers_length, nullptr, true))
- {
- if (!(*session_data->infractions[source_id] & INF_TRUNCATED_HEADER_LINE))
- {
- session_data->abort_flow[source_id] = true;
- session_data->events[source_id]->create_event(EVENT_MISFORMATTED_HTTP2);
- }
- }
+ decode_headers(nullptr, true);
}
bool Http2HeadersFrameTrailer::valid_sequence(Http2Enums::StreamState state)
void Http2HpackDecoder::cleanup()
{
- if (decoded_headers)
- {
- // get_decoded_headers() was never called because we encountered some error during
- // processing. We must clean up the buffer.
- delete[] decoded_headers;
- decoded_headers = nullptr;
- decoded_headers_size = 0;
- }
+ delete[] decoded_headers;
+ decoded_headers = nullptr;
+ decoded_headers_size = 0;
}
hpack_headers_offset += PROMISED_ID_LENGTH;
- // Decode headers
- if (!hpack_decoder->decode_headers((data.start() + hpack_headers_offset), data.length() -
- hpack_headers_offset, start_line_generator, false))
- {
- if (!(*session_data->infractions[source_id] & INF_TRUNCATED_HEADER_LINE))
- {
- session_data->abort_flow[source_id] = true;
- session_data->events[source_id]->create_event(EVENT_MISFORMATTED_HTTP2);
- }
- }
+ decode_headers(start_line_generator, false);
}
bool Http2PushPromiseFrame::valid_sequence(Http2Enums::StreamState)