package io.vertx.test.core; import java.util.concurrent.CountDownLatch; import org.junit.Test; import io.vertx.core.Handler; import io.vertx.core.http.HttpClient; import io.vertx.core.http.HttpClientOptions; import io.vertx.core.http.HttpClientResponse; import io.vertx.core.logging.Logger; import io.vertx.core.logging.LoggerFactory; import io.vertx.core.net.ProxyOptions; import io.vertx.core.net.ProxyType; import io.vertx.test.core.HttpProxy; import io.vertx.test.core.VertxTestBase; /** * Test all kinds of errors raised by the proxy * * @author <a href="http://oss.lehmann.cx/">Alexander Lehmann</a> * */ public class ProxyErrorTest extends VertxTestBase { private static final Logger log = LoggerFactory.getLogger(ProxyErrorTest.class); private HttpProxy proxy = null; // we don't start http/https servers, due to the error, they will not be queried private void startProxy(int error, String username) throws InterruptedException { CountDownLatch latch = new CountDownLatch(1); proxy = new HttpProxy(username); proxy.setError(error); proxy.start(vertx, v -> latch.countDown()); latch.await(); } @Override public void tearDown() throws Exception { super.tearDown(); if (proxy!=null) { proxy.stop(); } } @Test public void testProxyHttpsError() throws Exception { expectProxyException(403, null, "https://localhost/"); } @Test public void testProxyHttpsAuthFail() throws Exception { expectProxyException(0, "user", "https://localhost/"); } @Test public void testProxyHttpsHostUnknown() throws Exception { expectProxyException(0, null, "https://unknown.hostname/"); } @Test public void testProxyError() throws Exception { expectStatusError(403, 403, null, "http://localhost/"); } @Test public void testProxyAuthFail() throws Exception { expectStatusError(0, 407, "user", "http://localhost/"); } @Test public void testProxyHostUnknown() throws Exception { expectStatusError(0, 504, null, "http://unknown.hostname/"); } // we expect the request to fail with a ProxyConnectException if we use https // so we fail the test when it succeeds private void expectProxyException(int error, String username, String url) throws Exception { proxyTest(error, username, url, resp -> { log.info("request is supposed to fail but response is " + resp.statusCode() + " " + resp.statusMessage()); fail("request is supposed to fail"); }, true); } // we expect the request to fail with a http status error if we use http (behaviour is similar to Squid) private void expectStatusError(int error, int responseStatus, String username, String url) throws Exception { proxyTest(error, username, url, resp -> { assertEquals(responseStatus, resp.statusCode()); testComplete(); }, false); } private void proxyTest(int error, String username, String url, Handler<HttpClientResponse> assertResponse, boolean completeOnException) throws Exception { startProxy(error, username); final HttpClientOptions options = new HttpClientOptions() .setSsl(url.startsWith("https")) .setProxyOptions(new ProxyOptions() .setType(ProxyType.HTTP) .setHost("localhost") .setPort(proxy.getPort())); HttpClient client = vertx.createHttpClient(options); client.getAbs(url, assertResponse) .exceptionHandler(e -> { if (completeOnException) { testComplete(); } else { fail(e); } }) .end(); await(); } }