|
|
|
|
@ -566,6 +566,17 @@ impl HTTP2Transaction {
|
|
|
|
|
&mut stream_tx.progress_tc
|
|
|
|
|
};
|
|
|
|
|
match data {
|
|
|
|
|
HTTP2FrameTypeData::CONTINUATION(c) => {
|
|
|
|
|
if c.end_stream && *state < HTTP2TxProgress::HTTP2ProgClosed {
|
|
|
|
|
*state = HTTP2TxProgress::HTTP2ProgClosed;
|
|
|
|
|
if stream_tx.progress_ts == HTTP2TxProgress::HTTP2ProgClosed
|
|
|
|
|
&& stream_tx.progress_tc == HTTP2TxProgress::HTTP2ProgClosed
|
|
|
|
|
{
|
|
|
|
|
stream_tx.progress_ts = HTTP2TxProgress::HTTP2ProgComplete;
|
|
|
|
|
stream_tx.progress_tc = HTTP2TxProgress::HTTP2ProgComplete;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
HTTP2FrameTypeData::HEADERS(_) => {
|
|
|
|
|
if header.flags & parser::HTTP2_FLAG_HEADER_EOS != 0
|
|
|
|
|
&& header.flags & parser::HTTP2_FLAG_HEADER_END_HEADERS != 0
|
|
|
|
|
@ -730,6 +741,7 @@ impl HTTP2DynTable {
|
|
|
|
|
struct HTTP2HeaderReassemblyBuffer {
|
|
|
|
|
data: Vec<u8>,
|
|
|
|
|
stream_id: u32,
|
|
|
|
|
end_stream: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct HTTP2State {
|
|
|
|
|
@ -1243,7 +1255,10 @@ impl HTTP2State {
|
|
|
|
|
*reass_limit_reached = true;
|
|
|
|
|
}
|
|
|
|
|
if head.flags & parser::HTTP2_FLAG_HEADER_END_HEADERS == 0 {
|
|
|
|
|
let hs = parser::HTTP2FrameContinuation { blocks: Vec::new() };
|
|
|
|
|
let hs = parser::HTTP2FrameContinuation {
|
|
|
|
|
blocks: Vec::new(),
|
|
|
|
|
end_stream: false,
|
|
|
|
|
};
|
|
|
|
|
return (HTTP2FrameTypeData::CONTINUATION(hs), events);
|
|
|
|
|
}
|
|
|
|
|
} // else try to parse anyways
|
|
|
|
|
@ -1259,11 +1274,16 @@ impl HTTP2State {
|
|
|
|
|
&mut self.dynamic_headers_ts
|
|
|
|
|
};
|
|
|
|
|
match parser::http2_parse_frame_continuation(input_reass, dyn_headers) {
|
|
|
|
|
Ok((_, hs)) => {
|
|
|
|
|
if head.stream_id == buf.stream_id {
|
|
|
|
|
Ok((_, mut hs)) => {
|
|
|
|
|
let same = head.stream_id == buf.stream_id;
|
|
|
|
|
if same {
|
|
|
|
|
buf.stream_id = 0;
|
|
|
|
|
buf.data.clear();
|
|
|
|
|
}
|
|
|
|
|
hs.end_stream = buf.end_stream;
|
|
|
|
|
if same {
|
|
|
|
|
buf.end_stream = false;
|
|
|
|
|
}
|
|
|
|
|
events.extend(self.process_headers(&hs.blocks, dir));
|
|
|
|
|
return (HTTP2FrameTypeData::CONTINUATION(hs), events);
|
|
|
|
|
}
|
|
|
|
|
@ -1271,6 +1291,7 @@ impl HTTP2State {
|
|
|
|
|
if head.stream_id == buf.stream_id {
|
|
|
|
|
buf.stream_id = 0;
|
|
|
|
|
buf.data.clear();
|
|
|
|
|
buf.end_stream = false;
|
|
|
|
|
}
|
|
|
|
|
if complete {
|
|
|
|
|
events.push(HTTP2Event::InvalidFrameData);
|
|
|
|
|
@ -1293,6 +1314,7 @@ impl HTTP2State {
|
|
|
|
|
if head.stream_id == buf.stream_id {
|
|
|
|
|
buf.stream_id = 0;
|
|
|
|
|
buf.data.clear();
|
|
|
|
|
buf.end_stream = false;
|
|
|
|
|
}
|
|
|
|
|
events.push(HTTP2Event::InvalidFrameData);
|
|
|
|
|
return (
|
|
|
|
|
@ -1312,6 +1334,7 @@ impl HTTP2State {
|
|
|
|
|
&mut self.c2s_buf
|
|
|
|
|
};
|
|
|
|
|
buf.data.clear();
|
|
|
|
|
buf.end_stream = head.flags & parser::HTTP2_FLAG_HEADER_EOS != 0;
|
|
|
|
|
if let Ok((rem_hpack, hs)) = parser::get_frame_headers_hpack(input, hflags) {
|
|
|
|
|
// store only the HPACK fragment: skip Pad Length, Priority, and trailing padding
|
|
|
|
|
buf.data.extend(rem_hpack);
|
|
|
|
|
|