@@ -92,6 +92,13 @@ const ENV_ASYNC_INIT_DEPRECATED: &str = "ASYNC_INIT";
9292// Lambda runtime environment variable
9393const ENV_LAMBDA_RUNTIME_API : & str = "AWS_LAMBDA_RUNTIME_API" ;
9494
95+ // Captures the original AWS_LAMBDA_RUNTIME_API value before apply_runtime_proxy_config()
96+ // overwrites it with the proxy address. Extension registration uses the original so it
97+ // reaches the real Lambda Runtime API directly, bypassing the proxy.
98+ // Outer Option distinguishes "not yet captured" (None) from "captured but env was unset"
99+ // (Some(None)).
100+ static ORIGINAL_LAMBDA_RUNTIME_API : OnceLock < Option < String > > = OnceLock :: new ( ) ;
101+
95102use http:: {
96103 header:: { HeaderName , HeaderValue } ,
97104 Method , StatusCode ,
@@ -114,7 +121,7 @@ use std::{
114121 pin:: Pin ,
115122 sync:: {
116123 atomic:: { AtomicBool , Ordering } ,
117- Arc ,
124+ Arc , OnceLock ,
118125 } ,
119126 time:: Duration ,
120127} ;
@@ -652,8 +659,12 @@ impl Adapter<HttpConnector, Body> {
652659 /// Registers with the Lambda Extensions API and waits for the next event.
653660 /// This keeps the extension alive for the duration of the Lambda instance.
654661 async fn register_extension_internal ( ) -> Result < ( ) , Error > {
655- let aws_lambda_runtime_api: String =
656- env:: var ( ENV_LAMBDA_RUNTIME_API ) . unwrap_or_else ( |_| "127.0.0.1:9001" . to_string ( ) ) ;
662+ // Prefer the original (pre-proxy) value if apply_runtime_proxy_config() captured one.
663+ // Otherwise fall back to the current env var.
664+ let aws_lambda_runtime_api: String = match ORIGINAL_LAMBDA_RUNTIME_API . get ( ) {
665+ Some ( captured) => captured. clone ( ) . unwrap_or_else ( || "127.0.0.1:9001" . to_string ( ) ) ,
666+ None => env:: var ( ENV_LAMBDA_RUNTIME_API ) . unwrap_or_else ( |_| "127.0.0.1:9001" . to_string ( ) ) ,
667+ } ;
657668 let client = Client :: builder ( hyper_util:: rt:: TokioExecutor :: new ( ) ) . build ( HttpConnector :: new ( ) ) ;
658669
659670 let register_req = hyper:: Request :: builder ( )
@@ -868,6 +879,11 @@ impl Adapter<HttpConnector, Body> {
868879 /// ```
869880 pub fn apply_runtime_proxy_config ( ) {
870881 if let Ok ( runtime_proxy) = env:: var ( ENV_LAMBDA_RUNTIME_API_PROXY ) {
882+ // Capture the original value before we overwrite it, so extension
883+ // registration can still reach the real Lambda Runtime API.
884+ let original = env:: var ( ENV_LAMBDA_RUNTIME_API ) . ok ( ) ;
885+ let _ = ORIGINAL_LAMBDA_RUNTIME_API . set ( original) ;
886+
871887 // We need to overwrite the env variable because lambda_http::run()
872888 // calls lambda_runtime::run() which doesn't allow changing the client URI.
873889 //
@@ -1243,22 +1259,31 @@ mod tests {
12431259 assert ! ( codes. is_empty( ) ) ;
12441260 }
12451261
1262+ // Combined into one test because ORIGINAL_LAMBDA_RUNTIME_API is a process-wide
1263+ // OnceLock that can only be set once — separate tests would race on it.
12461264 #[ test]
1247- fn test_apply_runtime_proxy_config_sets_env ( ) {
1248- // Clean up first
1265+ fn test_apply_runtime_proxy_config ( ) {
1266+ // Cleanup
12491267 env:: remove_var ( ENV_LAMBDA_RUNTIME_API_PROXY ) ;
12501268 env:: remove_var ( ENV_LAMBDA_RUNTIME_API ) ;
12511269
1252- // When proxy is not set, runtime API should not be changed
1270+ // Case 1: proxy unset → no overwrite, no capture
12531271 Adapter :: apply_runtime_proxy_config ( ) ;
12541272 assert ! ( env:: var( ENV_LAMBDA_RUNTIME_API ) . is_err( ) ) ;
1273+ assert ! ( ORIGINAL_LAMBDA_RUNTIME_API . get( ) . is_none( ) ) ;
12551274
1256- // When proxy is set, runtime API should be overwritten
1275+ // Case 2: proxy set with a real original → original captured, env overwritten
1276+ env:: set_var ( ENV_LAMBDA_RUNTIME_API , "real-api:9001" ) ;
12571277 env:: set_var ( ENV_LAMBDA_RUNTIME_API_PROXY , "127.0.0.1:9002" ) ;
12581278 Adapter :: apply_runtime_proxy_config ( ) ;
12591279 assert_eq ! ( env:: var( ENV_LAMBDA_RUNTIME_API ) . unwrap( ) , "127.0.0.1:9002" ) ;
1280+ assert_eq ! (
1281+ ORIGINAL_LAMBDA_RUNTIME_API . get( ) ,
1282+ Some ( & Some ( "real-api:9001" . to_string( ) ) ) ,
1283+ "extension registration should see the pre-proxy Runtime API"
1284+ ) ;
12601285
1261- // Clean up
1286+ // Cleanup
12621287 env:: remove_var ( ENV_LAMBDA_RUNTIME_API_PROXY ) ;
12631288 env:: remove_var ( ENV_LAMBDA_RUNTIME_API ) ;
12641289 }
0 commit comments