@@ -10,6 +10,7 @@ use futures::{Stream, StreamExt};
10
10
use bytes:: Buf ;
11
11
use uuid:: Uuid ;
12
12
use http_body:: Body ;
13
+ use std:: convert:: Infallible ;
13
14
14
15
type HttpClient = hyper:: Client < hyper:: client:: HttpConnector > ;
15
16
@@ -19,6 +20,7 @@ pub struct Request {
19
20
status : u16 ,
20
21
is_replay : bool ,
21
22
path : String ,
23
+ query : Option < String > ,
22
24
method : Method ,
23
25
headers : HashMap < String , Vec < String > > ,
24
26
body_data : Vec < u8 > ,
@@ -28,6 +30,16 @@ pub struct Request {
28
30
completed : chrono:: NaiveDateTime ,
29
31
}
30
32
33
+ impl Request {
34
+ pub fn path_and_query ( & self ) -> String {
35
+ if let Some ( query) = self . query . as_ref ( ) {
36
+ format ! ( "{}?{}" , self . path, query)
37
+ } else {
38
+ self . path . clone ( )
39
+ }
40
+ }
41
+ }
42
+
31
43
impl Request {
32
44
pub fn elapsed ( & self ) -> String {
33
45
let duration = self . completed - self . started ;
@@ -72,6 +84,7 @@ pub fn start_introspection_server(config: Config) -> IntrospectionAddrs {
72
84
. and ( warp:: any ( ) . map ( move || local_addr. clone ( ) ) )
73
85
. and ( warp:: method ( ) )
74
86
. and ( warp:: path:: full ( ) )
87
+ . and ( opt_raw_query ( ) )
75
88
. and ( warp:: header:: headers_cloned ( ) )
76
89
. and ( warp:: body:: stream ( ) )
77
90
. and ( get_client ( ) )
@@ -124,6 +137,7 @@ pub fn start_introspection_server(config: Config) -> IntrospectionAddrs {
124
137
async fn forward ( local_addr : String ,
125
138
method : Method ,
126
139
path : FullPath ,
140
+ query : Option < String > ,
127
141
headers : HeaderMap ,
128
142
mut body : impl Stream < Item = Result < impl Buf , warp:: Error > > + Send + Sync + Unpin + ' static ,
129
143
client : HttpClient ) -> Result < Box < dyn warp:: Reply > , warp:: reject:: Rejection >
@@ -147,7 +161,14 @@ async fn forward(local_addr: String,
147
161
collected. extend_from_slice ( chunk. as_ref ( ) )
148
162
}
149
163
150
- let url = format ! ( "http://{}{}" , local_addr, path. as_str( ) ) ;
164
+ let query_str = if let Some ( query) = query. as_ref ( ) {
165
+ format ! ( "?{}" , query)
166
+ } else {
167
+ String :: new ( )
168
+ } ;
169
+
170
+ let url = format ! ( "http://{}{}{}" , local_addr, path. as_str( ) , query_str) ;
171
+ log:: debug!( "forwarding to: {}" , & url) ;
151
172
152
173
let mut request = hyper:: Request :: builder ( )
153
174
. method ( method. clone ( ) )
@@ -196,6 +217,7 @@ async fn forward(local_addr: String,
196
217
id : Uuid :: new_v4 ( ) . to_string ( ) ,
197
218
status : parts. status . as_u16 ( ) ,
198
219
path : path. as_str ( ) . to_owned ( ) ,
220
+ query,
199
221
method,
200
222
headers : request_headers,
201
223
body_data : collected,
@@ -294,7 +316,13 @@ async fn replay_request(rid: String, client: HttpClient, addr: SocketAddr) -> Re
294
316
None => return Err ( warp:: reject:: not_found ( ) )
295
317
} ;
296
318
297
- let url = format ! ( "http://localhost:{}{}" , addr. port( ) , & request. path) ;
319
+ let query_str = if let Some ( query) = request. query . as_ref ( ) {
320
+ format ! ( "?{}" , query)
321
+ } else {
322
+ String :: new ( )
323
+ } ;
324
+
325
+ let url = format ! ( "http://localhost:{}{}{}" , addr. port( ) , & request. path, query_str) ;
298
326
299
327
let mut new_request = hyper:: Request :: builder ( )
300
328
. method ( request. method )
@@ -339,4 +367,10 @@ impl <T> warp::reply::Reply for Page<T> where T:askama::Template + Send + 'stati
339
367
"text/html" ,
340
368
) . body ( res. into ( ) ) . unwrap ( )
341
369
}
370
+ }
371
+
372
+ fn opt_raw_query ( ) -> impl Filter < Extract = ( Option < String > , ) , Error = Infallible > + Copy {
373
+ warp:: filters:: query:: raw ( ) . map ( |q| Some ( q) )
374
+ . or ( warp:: any ( ) . map ( || None ) )
375
+ . unify ( )
342
376
}
0 commit comments