/* * Copyright (c) 2016 AsyncHttpClient Project. All rights reserved. * * This program is licensed to you under the Apache License Version 2.0, * and you may not use this file except in compliance with the Apache License Version 2.0. * You may obtain a copy of the Apache License Version 2.0 at * http://www.apache.org/licenses/LICENSE-2.0. * * Unless required by applicable law or agreed to in writing, * software distributed under the Apache License Version 2.0 is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under. */ package org.asynchttpclient; import static io.netty.handler.codec.http.HttpHeaderNames.*; import static org.asynchttpclient.Dsl.*; import static org.asynchttpclient.test.TestUtils.*; import java.io.IOException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.asynchttpclient.Realm.AuthScheme; import org.asynchttpclient.test.EchoHandler; import org.eclipse.jetty.proxy.ConnectHandler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; /** * Test that validates that when having an HTTP proxy and trying to access an HTTPS through the proxy the proxy credentials should be passed during the CONNECT request. */ public class BasicHttpProxyToHttpsTest { private static final Logger LOGGER = LoggerFactory.getLogger(BasicHttpProxyToHttpsTest.class); private int httpPort; private int proxyPort; private Server httpServer; private Server proxy; @BeforeClass(alwaysRun = true) public void setUpGlobal() throws Exception { // HTTP server httpServer = new Server(); ServerConnector connector1 = addHttpsConnector(httpServer); httpServer.setHandler(new EchoHandler()); httpServer.start(); httpPort = connector1.getLocalPort(); // proxy proxy = new Server(); ServerConnector connector2 = addHttpConnector(proxy); ConnectHandler connectHandler = new ConnectHandler() { @Override protected boolean handleAuthentication(HttpServletRequest request, HttpServletResponse response, String address) { String authorization = request.getHeader(PROXY_AUTHORIZATION.toString()); if (authorization == null) { response.setStatus(HttpServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED); response.setHeader(PROXY_AUTHENTICATE.toString(), "Basic realm=\"Fake Realm\""); return false; } else if (authorization.equals("Basic am9obmRvZTpwYXNz")) { return true; } response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return false; } }; proxy.setHandler(connectHandler); proxy.start(); proxyPort = connector2.getLocalPort(); LOGGER.info("Local HTTP Server (" + httpPort + "), Proxy (" + proxyPort + ") started successfully"); } @AfterClass(alwaysRun = true) public void tearDownGlobal() throws Exception { httpServer.stop(); proxy.stop(); } @Test public void nonPreemptiveProxyAuthWithHttpsTarget() throws IOException, InterruptedException, ExecutionException { try (AsyncHttpClient client = asyncHttpClient(config().setUseInsecureTrustManager(true))) { String targetUrl = "https://localhost:" + httpPort + "/foo/bar"; Request request = get(targetUrl)// .setProxyServer(proxyServer("127.0.0.1", proxyPort).setRealm(realm(AuthScheme.BASIC, "johndoe", "pass")))// // .setRealm(realm(AuthScheme.BASIC, "user", "passwd"))// .build(); Future<Response> responseFuture = client.executeRequest(request); Response response = responseFuture.get(); Assert.assertEquals(response.getStatusCode(), HttpServletResponse.SC_OK); Assert.assertEquals("/foo/bar", response.getHeader("X-pathInfo")); } } }