HTTP2StateOpen = 1,
HTTP2StateReserved = 2,
HTTP2StateDataClient = 3,
- HTTP2StateDataServer = 4,
- HTTP2StateHalfClosedClient = 5,
+ HTTP2StateHalfClosedClient = 4,
+ HTTP2StateDataServer = 5,
HTTP2StateHalfClosedServer = 6,
HTTP2StateClosed = 7,
//not a RFC-defined state, used for stream 0 frames appyling to the global connection
HTTP2FrameTypeData::HEADERS(_) | HTTP2FrameTypeData::DATA => {
if header.flags & parser::HTTP2_FLAG_HEADER_EOS != 0 {
match self.state {
- HTTP2TransactionState::HTTP2StateHalfClosedClient => {
+ HTTP2TransactionState::HTTP2StateHalfClosedClient
+ | HTTP2TransactionState::HTTP2StateDataServer => {
if dir == STREAM_TOCLIENT {
self.state = HTTP2TransactionState::HTTP2StateClosed;
}
self.state = HTTP2TransactionState::HTTP2StateClosed;
}
}
- // do not revert back to a hald closed state
+ // do not revert back to a half closed state
HTTP2TransactionState::HTTP2StateClosed => {}
HTTP2TransactionState::HTTP2StateGlobal => {}
_ => {
} else if header.ftype == parser::HTTP2FrameType::DATA as u8 {
//not end of stream
if dir == STREAM_TOSERVER {
- self.state = HTTP2TransactionState::HTTP2StateDataClient;
+ if self.state < HTTP2TransactionState::HTTP2StateDataClient {
+ self.state = HTTP2TransactionState::HTTP2StateDataClient;
+ }
} else {
- self.state = HTTP2TransactionState::HTTP2StateDataServer;
+ if self.state < HTTP2TransactionState::HTTP2StateDataServer {
+ self.state = HTTP2TransactionState::HTTP2StateDataServer;
+ }
}
}
}
return None;
}
- fn find_tx_index(&mut self, sid: u32) -> usize {
+ fn find_tx_index(&mut self, sid: u32, header: &parser::HTTP2FrameHeader) -> usize {
for i in 0..self.transactions.len() {
//reverse order should be faster
let idx = self.transactions.len() - 1 - i;
if sid == self.transactions[idx].stream_id {
if self.transactions[idx].state == HTTP2TransactionState::HTTP2StateClosed {
- self.set_event(HTTP2Event::StreamIdReuse);
- return 0;
+ //these frames can be received in this state for a short period
+ if header.ftype != parser::HTTP2FrameType::RSTSTREAM as u8
+ && header.ftype != parser::HTTP2FrameType::WINDOWUPDATE as u8
+ && header.ftype != parser::HTTP2FrameType::PRIORITY as u8
+ {
+ self.set_event(HTTP2Event::StreamIdReuse);
+ }
}
return idx + 1;
}
}
_ => header.stream_id,
};
- let index = self.find_tx_index(sid);
+ let index = self.find_tx_index(sid, header);
if index > 0 {
return &mut self.transactions[index - 1];
} else {