@@ -3,9 +3,7 @@ use std::task::{Context, Poll};
33use http:: { Request , Response } ;
44use http_body:: Body ;
55use tower:: { Layer , Service } ;
6- use tower_http:: decompression:: {
7- Decompression as TowerDecompression , DecompressionBody , ResponseFuture ,
8- } ;
6+ use tower_http:: decompression:: { self , DecompressionBody , ResponseFuture } ;
97
108use super :: AcceptEncoding ;
119use crate :: { client:: layer:: config:: RequestAcceptEncoding , core:: ext:: RequestConfig } ;
@@ -20,7 +18,7 @@ pub struct DecompressionLayer {
2018}
2119
2220impl DecompressionLayer {
23- /// Creates a new `DecompressionLayer` with the specified `Accepts `.
21+ /// Creates a new `DecompressionLayer` with the specified `AcceptEncoding `.
2422 pub const fn new ( accept : AcceptEncoding ) -> Self {
2523 Self { accept }
2624 }
@@ -30,9 +28,11 @@ impl<S> Layer<S> for DecompressionLayer {
3028 type Service = Decompression < S > ;
3129
3230 fn layer ( & self , service : S ) -> Self :: Service {
33- let decoder = TowerDecompression :: new ( service) ;
34- let decoder = Decompression :: < S > :: accept ( decoder, & self . accept ) ;
35- Decompression { decoder }
31+ let decoder = decompression:: Decompression :: new ( service) ;
32+ let decoder = Decompression :: < S > :: accept_in_place ( decoder, & self . accept ) ;
33+ Decompression {
34+ decoder : Some ( decoder) ,
35+ }
3636 }
3737}
3838
@@ -42,14 +42,15 @@ impl<S> Layer<S> for DecompressionLayer {
4242/// bodies based on the `Content-Encoding` header.
4343#[ derive( Clone ) ]
4444pub struct Decompression < S > {
45- decoder : TowerDecompression < S > ,
45+ decoder : Option < decompression :: Decompression < S > > ,
4646}
4747
4848impl < S > Decompression < S > {
49- fn accept (
50- mut decoder : TowerDecompression < S > ,
49+ // replaces the current decoder with a new one based on the `AcceptEncoding`.
50+ fn accept_in_place (
51+ mut decoder : decompression:: Decompression < S > ,
5152 accept : & AcceptEncoding ,
52- ) -> TowerDecompression < S > {
53+ ) -> decompression :: Decompression < S > {
5354 #[ cfg( feature = "gzip" ) ]
5455 {
5556 decoder = decoder. gzip ( accept. gzip ) ;
@@ -86,16 +87,33 @@ where
8687
8788 #[ inline( always) ]
8889 fn poll_ready ( & mut self , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) , Self :: Error > > {
89- self . decoder . poll_ready ( cx)
90+ match self . decoder . as_mut ( ) {
91+ Some ( decoder) => decoder. poll_ready ( cx) ,
92+ None => unreachable ! ( "Decompression service is not initialized" ) ,
93+ }
9094 }
9195
9296 fn call ( & mut self , req : Request < ReqBody > ) -> Self :: Future {
97+ // If the accept encoding is set, we need to update the decoder
98+ // to handle the specified encodings.
9399 if let Some ( accept) = RequestConfig :: < RequestAcceptEncoding > :: get ( req. extensions ( ) ) {
94- let mut decoder = self . decoder . clone ( ) ;
95- decoder = Decompression :: accept ( decoder, accept) ;
96- std:: mem:: swap ( & mut self . decoder , & mut decoder) ;
100+ if let Some ( mut decoder) = self . decoder . take ( ) {
101+ decoder = Decompression :: accept_in_place ( decoder, accept) ;
102+ self . decoder = Some ( decoder) ;
103+ }
97104 }
98105
99- self . decoder . call ( req)
106+ // Call the underlying service with the request
107+ match self . decoder . as_mut ( ) {
108+ Some ( decoder) => decoder. call ( req) ,
109+ None => {
110+ // This branch should never be reached: decoder is always initialized in
111+ // DecompressionLayer::layer(). If this panic occurs, it indicates a
112+ // bug in the service setup or unexpected internal state.
113+ unreachable ! (
114+ "Decompression service was not initialized; this indicates a bug in service setup"
115+ ) ;
116+ }
117+ }
100118 }
101119}
0 commit comments