http2: update progress after continuation frame ended stream

Ticket: 9217
pull/16497/head
Philippe Antoine 2 weeks ago committed by Victor Julien
parent ef7184012a
commit 620dff6759

@ -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);

@ -680,13 +680,23 @@ pub fn http2_parse_frame_push_promise<'a>(
#[derive(Clone, Debug)]
pub struct HTTP2FrameContinuation {
pub blocks: Vec<HTTP2FrameHeaderBlock>,
// not in the contination frame itself,
// but inherited from parent headers frame,
// so as to update progress
pub end_stream: bool,
}
pub fn http2_parse_frame_continuation<'a>(
input: &'a [u8], dyn_headers: &mut HTTP2DynTable,
) -> IResult<&'a [u8], HTTP2FrameContinuation> {
let (i3, blocks) = http2_parse_headers_blocks(input, dyn_headers)?;
return Ok((i3, HTTP2FrameContinuation { blocks }));
return Ok((
i3,
HTTP2FrameContinuation {
blocks,
end_stream: false,
},
));
}
#[repr(u16)]

Loading…
Cancel
Save