@@ -2685,10 +2685,9 @@ impl DomainFronter {
26852685 let app_body = self
26862686 . send_prebuilt_payload_through_relay ( outer_payload)
26872687 . await ?;
2688-
2689- // exit-node's JSON envelope: {s: u16, h: {...}, b: "<base64>"} on
2690- // success, {e: "..."} on its own internal error.
2691- parse_exit_node_response ( & app_body)
2688+
2689+ let result = parse_exit_node_response ( & app_body) ;
2690+ result
26922691 }
26932692
26942693 /// Build the inner-layer payload that the exit node will execute.
@@ -3031,7 +3030,7 @@ impl DomainFronter {
30313030 let start = text. find ( '{' ) . ok_or_else ( || {
30323031 FronterError :: BadResponse ( format ! (
30333032 "no json in tunnel response: {}" ,
3034- & text[ ..text . len ( ) . min ( 200 ) ]
3033+ & text. chars ( ) . take ( 200 ) . collect :: < String > ( )
30353034 ) )
30363035 } ) ?;
30373036 let end = text. rfind ( '}' ) . ok_or_else ( || {
@@ -3199,7 +3198,7 @@ impl DomainFronter {
31993198 let start = text. find ( '{' ) . ok_or_else ( || {
32003199 FronterError :: BadResponse ( format ! (
32013200 "no json in batch response: {}" ,
3202- & text[ ..text . len ( ) . min ( 200 ) ]
3201+ & text. chars ( ) . take ( 200 ) . collect :: < String > ( )
32033202 ) )
32043203 } ) ?;
32053204 let end = text. rfind ( '}' ) . ok_or_else ( || {
@@ -3961,11 +3960,17 @@ fn unix_to_ymd_utc(secs: u64) -> (i64, u32, u32) {
39613960/// MITM TLS write-back path sees the same shape it gets from the regular
39623961/// Apps Script relay (status line + headers + body).
39633962fn parse_exit_node_response ( body : & [ u8 ] ) -> Result < Vec < u8 > , FronterError > {
3964- let v: Value = serde_json:: from_slice ( body) . map_err ( |e| {
3963+ let json_start = body
3964+ . windows ( 4 )
3965+ . position ( |w| w == b"\r \n \r \n " )
3966+ . map ( |i| i + 4 )
3967+ . unwrap_or ( 0 ) ;
3968+ let json_bytes = & body[ json_start..] ;
3969+ let v: Value = serde_json:: from_slice ( json_bytes) . map_err ( |e| {
39653970 FronterError :: Relay ( format ! (
39663971 "exit-node response not valid JSON ({}): {}" ,
39673972 e,
3968- String :: from_utf8_lossy( & body [ ..body . len( ) . min( 200 ) ] )
3973+ String :: from_utf8_lossy( & json_bytes [ ..json_bytes . len( ) . min( 200 ) ] )
39693974 ) )
39703975 } ) ?;
39713976
@@ -4001,6 +4006,7 @@ fn parse_exit_node_response(body: &[u8]) -> Result<Vec<u8>, FronterError> {
40014006 "transfer-encoding" ,
40024007 "connection" ,
40034008 "keep-alive" ,
4009+ "content-encoding" , // exit node's fetch() auto-decompresses; header is stale
40044010 ] ;
40054011
40064012 let mut out = Vec :: with_capacity ( body_bytes. len ( ) + 256 ) ;
@@ -4565,13 +4571,13 @@ fn parse_relay_json(body: &[u8]) -> Result<Vec<u8>, FronterError> {
45654571 let start = text. find ( '{' ) . ok_or_else ( || {
45664572 FronterError :: BadResponse ( format ! (
45674573 "no json in: {}" ,
4568- & text[ ..text . len ( ) . min ( 200 ) ]
4574+ & text. chars ( ) . take ( 200 ) . collect :: < String > ( )
45694575 ) )
45704576 } ) ?;
45714577 let end = text. rfind ( '}' ) . ok_or_else ( || {
45724578 FronterError :: BadResponse ( format ! (
45734579 "no json end in: {}" ,
4574- & text[ ..text . len ( ) . min ( 200 ) ]
4580+ & text. chars ( ) . take ( 200 ) . collect :: < String > ( )
45754581 ) )
45764582 } ) ?;
45774583 serde_json:: from_str ( & text[ start..=end] ) ?
0 commit comments