@@ -93,18 +93,7 @@ impl AppTrait for App {
9393 payjoin:: bitcoin:: consensus:: encode:: serialize_hex( & fallback_tx)
9494 ) ;
9595
96- let expected_length = response
97- . headers ( )
98- . get ( "Content-Length" )
99- . and_then ( |val| val. to_str ( ) . ok ( ) )
100- . and_then ( |s| s. parse :: < usize > ( ) . ok ( ) )
101- . unwrap_or ( MAX_CONTENT_LENGTH ) ;
102-
103- if expected_length > MAX_CONTENT_LENGTH {
104- return Err ( anyhow ! ( "Response body is too large: {} bytes" , expected_length) ) ;
105- }
106-
107- let body = read_limited_body ( response. bytes_stream ( ) , expected_length) . await ?;
96+ let body = read_limited_body ( & response. headers ( ) . clone ( ) , response. bytes_stream ( ) ) . await ?;
10897
10998 let psbt = ctx. process_response ( & body) . map_err ( |e| {
11099 log:: debug!( "Error processing response: {e:?}" ) ;
@@ -312,26 +301,11 @@ impl App {
312301 req : Request < Incoming > ,
313302 ) -> Result < Response < BoxBody < Bytes , hyper:: Error > > , ReplyableError > {
314303 let ( parts, body) = req. into_parts ( ) ;
315- let headers = Headers ( & parts. headers ) ;
316-
317- let expected_length = headers
318- . 0
319- . get ( "Content-Length" )
320- . and_then ( |val| val. to_str ( ) . ok ( ) )
321- . and_then ( |s| s. parse :: < usize > ( ) . ok ( ) )
322- . unwrap_or ( MAX_CONTENT_LENGTH ) ;
323-
324- if expected_length > MAX_CONTENT_LENGTH {
325- log:: error!( "Error: Content length exceeds max allowed" ) ;
326- return Err ( Implementation ( ImplementationError :: from (
327- anyhow ! ( "Content length too large: {expected_length}" ) . into_boxed_dyn_error ( ) ,
328- ) ) ) ;
329- }
330-
331- let body = read_limited_body ( body. into_data_stream ( ) , expected_length)
304+ let body = read_limited_body ( & parts. headers , body. into_data_stream ( ) )
332305 . await
333306 . map_err ( |e| Implementation ( ImplementationError :: from ( e. into_boxed_dyn_error ( ) ) ) ) ?;
334307
308+ let headers = Headers ( & parts. headers ) ;
335309 let query_string = parts. uri . query ( ) . unwrap_or ( "" ) ;
336310 let proposal = UncheckedProposal :: from_request ( & body, query_string, headers) ?;
337311
@@ -407,11 +381,22 @@ impl App {
407381 }
408382}
409383
410- pub async fn read_limited_body < S , E > ( mut stream : S , expected_len : usize ) -> Result < Vec < u8 > >
384+ pub async fn read_limited_body < S , E > ( headers : & hyper :: HeaderMap , mut stream : S ) -> Result < Vec < u8 > >
411385where
412386 S : Stream < Item = Result < Bytes , E > > + Unpin ,
413387 E : std:: error:: Error + Send + Sync + ' static ,
414388{
389+ let expected_len = headers
390+ . get ( "Content-Length" )
391+ . and_then ( |val| val. to_str ( ) . ok ( ) )
392+ . and_then ( |s| s. parse :: < usize > ( ) . ok ( ) )
393+ . unwrap_or ( MAX_CONTENT_LENGTH ) ;
394+
395+ if expected_len > MAX_CONTENT_LENGTH {
396+ log:: error!( "Header-defined Content-Length exceeds max allowed: {expected_len}" ) ;
397+ return Err ( anyhow ! ( "Header-defined Content-Length exceeds max allowed: {expected_len}" ) ) ;
398+ }
399+
415400 let mut body = Vec :: with_capacity ( expected_len) ;
416401
417402 while let Some ( chunk) = stream. next ( ) . await {
0 commit comments