diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/http/TestWebServer.java b/jib-core/src/test/java/com/google/cloud/tools/jib/http/TestWebServer.java index 3633b33302..8fee967e83 100644 --- a/jib-core/src/test/java/com/google/cloud/tools/jib/http/TestWebServer.java +++ b/jib-core/src/test/java/com/google/cloud/tools/jib/http/TestWebServer.java @@ -31,6 +31,8 @@ import java.nio.file.Paths; import java.security.GeneralSecurityException; import java.security.KeyStore; +import java.util.Arrays; +import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; @@ -47,14 +49,26 @@ public class TestWebServer implements Closeable { private final Semaphore threadStarted = new Semaphore(0); private final StringBuilder inputRead = new StringBuilder(); + private final List responses; + public TestWebServer(boolean https) throws IOException, InterruptedException, GeneralSecurityException, URISyntaxException { + this(https, Arrays.asList("HTTP/1.1 200 OK\nContent-Length:12\n\nHello World!")); + } + + public TestWebServer(boolean https, List responses) + throws IOException, InterruptedException, GeneralSecurityException, URISyntaxException { this.https = https; - serverSocket = createServerSocket(https); - ignoreReturn(executorService.submit(this::serve200)); + this.responses = responses; + serverSocket = https ? createHttpsServerSocket() : new ServerSocket(0); + ignoreReturn(executorService.submit(this::serveResponses)); threadStarted.acquire(); } + public int getLocalPort() { + return serverSocket.getLocalPort(); + } + public String getEndpoint() { String host = serverSocket.getInetAddress().getHostAddress(); return (https ? "https" : "http") + "://" + host + ":" + serverSocket.getLocalPort(); @@ -66,47 +80,45 @@ public void close() throws IOException { executorService.shutdown(); } - private ServerSocket createServerSocket(boolean https) + private ServerSocket createHttpsServerSocket() throws IOException, GeneralSecurityException, URISyntaxException { - if (https) { - KeyStore keyStore = KeyStore.getInstance("JKS"); - // generated with: keytool -genkey -keyalg RSA -keystore ./TestWebServer-keystore - Path keyStoreFile = Paths.get(Resources.getResource("core/TestWebServer-keystore").toURI()); - try (InputStream in = Files.newInputStream(keyStoreFile)) { - keyStore.load(in, "password".toCharArray()); - } + KeyStore keyStore = KeyStore.getInstance("JKS"); + // generated with: keytool -genkey -keyalg RSA -keystore ./TestWebServer-keystore + Path keyStoreFile = Paths.get(Resources.getResource("core/TestWebServer-keystore").toURI()); + try (InputStream in = Files.newInputStream(keyStoreFile)) { + keyStore.load(in, "password".toCharArray()); + } - KeyManagerFactory keyManagerFactory = - KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - keyManagerFactory.init(keyStore, "password".toCharArray()); + KeyManagerFactory keyManagerFactory = + KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + keyManagerFactory.init(keyStore, "password".toCharArray()); - SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(keyManagerFactory.getKeyManagers(), null, null); - return sslContext.getServerSocketFactory().createServerSocket(0); - } else { - return new ServerSocket(0); - } + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(keyManagerFactory.getKeyManagers(), null, null); + return sslContext.getServerSocketFactory().createServerSocket(0); } - private Void serve200() throws IOException { + private Void serveResponses() throws IOException { threadStarted.release(); try (Socket socket = serverSocket.accept()) { - InputStream in = socket.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8)); - for (String line = reader.readLine(); - line != null && !line.isEmpty(); // An empty line marks the end of an HTTP request. - line = reader.readLine()) { - inputRead.append(line + "\n"); - } - String response = "HTTP/1.1 200 OK\nContent-Length:12\n\nHello World!"; - socket.getOutputStream().write(response.getBytes(StandardCharsets.UTF_8)); - socket.getOutputStream().flush(); + for (String response : responses) { + for (String line = reader.readLine(); + line != null && !line.isEmpty(); // An empty line marks the end of an HTTP request. + line = reader.readLine()) { + inputRead.append(line + "\n"); + } + socket.getOutputStream().write(response.getBytes(StandardCharsets.UTF_8)); + socket.getOutputStream().flush(); + } } return null; } + // For use to ignore (i.e., accept and do nothing) a return value from ExecutionService.submit(). + // Without "consuming" the return value this way, Error Prone will complain to use it. private void ignoreReturn(Future future) { // do nothing; to make Error Prone happy } diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/http/WithServerConnectionTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/http/WithServerConnectionTest.java index 52dd89eb78..678b92ff53 100644 --- a/jib-core/src/test/java/com/google/cloud/tools/jib/http/WithServerConnectionTest.java +++ b/jib-core/src/test/java/com/google/cloud/tools/jib/http/WithServerConnectionTest.java @@ -22,7 +22,9 @@ import java.net.URL; import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; +import java.util.Arrays; import javax.net.ssl.SSLException; +import org.hamcrest.CoreMatchers; import org.junit.Assert; import org.junit.Test; @@ -89,4 +91,36 @@ public void testInsecureConnection() ByteStreams.toByteArray(response.getBody())); } } + + @Test + public void testProxyCredentialProperties() + throws IOException, InterruptedException, GeneralSecurityException, URISyntaxException { + String proxyResponse = + "HTTP/1.1 407 Proxy Authentication Required\n" + + "Proxy-Authenticate: BASIC realm=\"some-realm\"\n" + + "Cache-Control: no-cache\n" + + "Pragma: no-cache\n" + + "Content-Length: 0\n\n"; + String targetServerResponse = "HTTP/1.1 200 OK\nContent-Length:12\n\nHello World!"; + + try (TestWebServer server = + new TestWebServer(false, Arrays.asList(proxyResponse, targetServerResponse))) { + System.setProperty("http.proxyHost", "localhost"); + System.setProperty("http.proxyPort", String.valueOf(server.getLocalPort())); + System.setProperty("http.proxyUser", "user_sys_prop"); + System.setProperty("http.proxyPassword", "pass_sys_prop"); + + try (Connection connection = + Connection.getConnectionFactory().apply(new URL("http://does.not.matter"))) { + Response response = connection.send("GET", new Request.Builder().build()); + Assert.assertThat( + server.getInputRead(), + CoreMatchers.containsString( + "Proxy-Authorization: Basic dXNlcl9zeXNfcHJvcDpwYXNzX3N5c19wcm9w")); + Assert.assertArrayEquals( + "Hello World!".getBytes(StandardCharsets.UTF_8), + ByteStreams.toByteArray(response.getBody())); + } + } + } }