Skip to content

Commit 3bde5cb

Browse files
authored
Merge branch 'main' into fabisev/release-changelog-and-github-releases
2 parents cf830ff + f26d75a commit 3bde5cb

2 files changed

Lines changed: 88 additions & 4 deletions

File tree

aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/runtimeapi/LambdaRuntimeApiClientImpl.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import java.io.OutputStream;
1515
import java.net.HttpURLConnection;
1616
import java.net.MalformedURLException;
17+
import java.net.Proxy;
1718
import java.net.URL;
1819
import java.util.HashMap;
1920
import java.util.Map;
@@ -175,8 +176,7 @@ void reportLambdaError(String endpoint, LambdaError error, int maxXrayHeaderSize
175176
private int doPost(String endpoint,
176177
Map<String, String> headers,
177178
byte[] payload) throws IOException {
178-
URL url = createUrl(endpoint);
179-
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
179+
HttpURLConnection conn = createConnection(endpoint);
180180
conn.setRequestMethod("POST");
181181
conn.setRequestProperty("Content-Type", DEFAULT_CONTENT_TYPE);
182182
conn.setRequestProperty("User-Agent", USER_AGENT);
@@ -201,8 +201,7 @@ private int doPost(String endpoint,
201201
}
202202

203203
private int doGet(String endpoint) throws IOException {
204-
URL url = createUrl(endpoint);
205-
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
204+
HttpURLConnection conn = createConnection(endpoint);
206205
conn.setRequestMethod("GET");
207206
conn.setRequestProperty("User-Agent", USER_AGENT);
208207

@@ -212,6 +211,15 @@ private int doGet(String endpoint) throws IOException {
212211
return responseCode;
213212
}
214213

214+
/**
215+
* Opens a direct connection to the given endpoint, bypassing any
216+
* customer-configured proxy.
217+
*/
218+
private HttpURLConnection createConnection(String endpoint) throws IOException {
219+
URL url = createUrl(endpoint);
220+
return (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
221+
}
222+
215223
private URL createUrl(String endpoint) {
216224
try {
217225
return new URL(endpoint);

aws-lambda-java-runtime-interface-client/src/test/java/com/amazonaws/services/lambda/runtime/api/client/runtimeapi/LambdaRuntimeApiClientImplTest.java

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import org.junit.jupiter.api.Test;
1010
import org.junit.jupiter.api.condition.DisabledOnOs;
1111
import org.junit.jupiter.api.condition.OS;
12+
import org.junit.jupiter.api.parallel.ResourceLock;
13+
import org.junit.jupiter.api.parallel.Resources;
1214

1315
import static org.junit.jupiter.api.Assertions.assertTrue;
1416
import static org.junit.jupiter.api.Assertions.assertNull;
@@ -22,12 +24,17 @@
2224
import com.amazonaws.services.lambda.runtime.api.client.runtimeapi.dto.XRayErrorCause;
2325
import com.amazonaws.services.lambda.runtime.api.client.runtimeapi.dto.XRayException;
2426

27+
import java.net.Inet4Address;
28+
import java.net.InetAddress;
29+
import java.net.NetworkInterface;
2530
import java.util.ArrayList;
31+
import java.util.Enumeration;
2632
import java.util.List;
2733
import java.util.function.Function;
2834
import java.util.function.Supplier;
2935

3036
import static org.junit.jupiter.api.Assertions.fail;
37+
import static org.junit.jupiter.api.Assumptions.assumeTrue;
3138
import static org.mockito.ArgumentMatchers.any;
3239
import static org.mockito.ArgumentMatchers.anyString;
3340
import static org.mockito.ArgumentMatchers.eq;
@@ -533,6 +540,75 @@ public void reportInvocationErrorWithInvocationIdTest() {
533540
}
534541
}
535542

543+
@Test
544+
@ResourceLock(Resources.SYSTEM_PROPERTIES)
545+
public void connectionBypassesConfiguredProxy() throws Exception {
546+
// Bind RAPID mock to a non-loopback IPv4 so Java's ProxySelector doesn't
547+
// auto-exempt it. On loopback (127.0.0.1), the JVM skips proxy regardless.
548+
InetAddress nonLoopback = findNonLoopbackIPv4();
549+
assumeTrue(nonLoopback != null, "No non-loopback IPv4 address available for proxy-bypass test");
550+
551+
MockWebServer nonLoopbackServer = new MockWebServer();
552+
nonLoopbackServer.start(nonLoopback, 0);
553+
554+
MockWebServer fakeProxy = new MockWebServer();
555+
fakeProxy.start();
556+
// Enqueue a response so if proxy is used, the test fails fast instead of hanging indefinitely.
557+
fakeProxy.enqueue(new MockResponse().setResponseCode(HTTP_ACCEPTED));
558+
559+
String previousProxyHost = System.getProperty("http.proxyHost");
560+
String previousProxyPort = System.getProperty("http.proxyPort");
561+
562+
System.setProperty("http.proxyHost", fakeProxy.getHostName());
563+
System.setProperty("http.proxyPort", String.valueOf(fakeProxy.getPort()));
564+
565+
try {
566+
MockResponse mockResponse = new MockResponse();
567+
mockResponse.setResponseCode(HTTP_ACCEPTED);
568+
nonLoopbackServer.enqueue(mockResponse);
569+
570+
String endpoint = "http://" + nonLoopback.getHostAddress() + ":" + nonLoopbackServer.getPort();
571+
LambdaError lambdaError = new LambdaError(errorRequest, RapidErrorType.AfterRestoreError);
572+
lambdaRuntimeApiClientImpl.reportLambdaError(endpoint, lambdaError, 1024 * 1024, null);
573+
574+
// Request arrived at RAPID mock directly
575+
assertEquals(1, nonLoopbackServer.getRequestCount());
576+
// Nothing went to the fake proxy
577+
assertEquals(0, fakeProxy.getRequestCount());
578+
} finally {
579+
if (previousProxyHost != null) {
580+
System.setProperty("http.proxyHost", previousProxyHost);
581+
} else {
582+
System.clearProperty("http.proxyHost");
583+
}
584+
if (previousProxyPort != null) {
585+
System.setProperty("http.proxyPort", previousProxyPort);
586+
} else {
587+
System.clearProperty("http.proxyPort");
588+
}
589+
nonLoopbackServer.shutdown();
590+
fakeProxy.shutdown();
591+
}
592+
}
593+
594+
private InetAddress findNonLoopbackIPv4() throws Exception {
595+
Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
596+
while (ifaces.hasMoreElements()) {
597+
NetworkInterface iface = ifaces.nextElement();
598+
if (!iface.isUp() || iface.isLoopback() || iface.isVirtual()) {
599+
continue;
600+
}
601+
Enumeration<InetAddress> addrs = iface.getInetAddresses();
602+
while (addrs.hasMoreElements()) {
603+
InetAddress addr = addrs.nextElement();
604+
if (addr instanceof Inet4Address && !addr.isLoopbackAddress() && !addr.isLinkLocalAddress()) {
605+
return addr;
606+
}
607+
}
608+
}
609+
return null;
610+
}
611+
536612
private String getHostnamePort() {
537613
return mockWebServer.getHostName() + ":" + mockWebServer.getPort();
538614
}

0 commit comments

Comments
 (0)