@@ -175,6 +175,9 @@ use tokio::io::AsyncReadExt;
175175use tokio:: io:: AsyncWrite ;
176176use tokio:: io:: AsyncWriteExt ;
177177
178+ use miniz_oxide:: { DataFormat , MZFlush } ;
179+ use miniz_oxide:: inflate:: stream:: { InflateState , inflate} ;
180+
178181pub use crate :: close:: CloseCode ;
179182pub use crate :: error:: WebSocketError ;
180183pub use crate :: fragment:: FragmentCollector ;
@@ -681,7 +684,11 @@ impl ReadHalf {
681684 let rsv2 = self . buffer [ 0 ] & 0b00100000 != 0 ;
682685 let rsv3 = self . buffer [ 0 ] & 0b00010000 != 0 ;
683686
684- if rsv1 || rsv2 || rsv3 {
687+ let mut compressed = false ;
688+
689+ if rsv1 && !rsv2 && !rsv3 {
690+ compressed = true ;
691+ } else if rsv1 || rsv2 || rsv3 {
685692 return Err ( WebSocketError :: ReservedBitsNotZero ) ;
686693 }
687694
@@ -743,8 +750,13 @@ impl ReadHalf {
743750 }
744751
745752 // if we read too much it will stay in the buffer, for the next call to this method
746- let payload = self . buffer . split_to ( payload_len) ;
753+ let mut payload = self . buffer . split_to ( payload_len) ;
754+ if compressed {
755+ payload = BytesMut :: from ( inflate_payload ( & payload. to_vec ( ) ) ?. as_slice ( ) ) ;
756+ }
757+
747758 let frame = Frame :: new ( fin, opcode, mask, Payload :: Bytes ( payload) ) ;
759+
748760 Ok ( frame)
749761 }
750762}
@@ -820,3 +832,25 @@ mod tests {
820832 assert_unsync :: < WebSocket < tokio:: net:: TcpStream > > ( ) ;
821833 } ;
822834}
835+
836+ fn inflate_payload (
837+ payload : & Vec < u8 >
838+ ) -> Result < Vec < u8 > , WebSocketError >
839+ {
840+ let max_output_size = usize:: max_value ( ) ;
841+ let mut out: Vec < u8 > = vec ! [ 0 ; payload. len( ) . saturating_mul( 2 ) . min( max_output_size) ] ;
842+ let mut state = InflateState :: new_boxed ( DataFormat :: Raw ) ;
843+
844+ let payload = [ payload. as_slice ( ) , [ 0x00 , 0x00 , 0xff , 0xff ] . as_slice ( ) ] . concat ( ) ;
845+ let res = inflate ( & mut state, & payload, & mut out, MZFlush :: Partial ) ;
846+
847+ match res. status {
848+ Ok ( _) => {
849+ out. truncate ( res. bytes_written ) ;
850+ Ok ( out)
851+ }
852+ Err ( _) => {
853+ Err ( WebSocketError :: InvalidEncoding )
854+ }
855+ }
856+ }
0 commit comments