@Test public void testAuthDefaultHttpsPortWhenProxy() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/stuff"); this.target = new HttpHost("localhost", -1, "https"); final HttpRoute route = new HttpRoute( new HttpHost("localhost", 443, "https"), null, new HttpHost("localhost", 8888), true, TunnelType.TUNNELLED, LayerType.LAYERED); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry); final HttpRequestInterceptor interceptor = new RequestAddCookies(); interceptor.process(request, context); final CookieOrigin cookieOrigin = context.getCookieOrigin(); Assert.assertNotNull(cookieOrigin); Assert.assertEquals(this.target.getHostName(), cookieOrigin.getHost()); Assert.assertEquals(443, cookieOrigin.getPort()); Assert.assertEquals("/stuff", cookieOrigin.getPath()); Assert.assertTrue(cookieOrigin.isSecure()); }
@Test public void testConnectionKeepAliveForTunneledRequests() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpClientContext context = HttpClientContext.create(); final HttpHost target = new HttpHost("localhost", 443, "https"); final HttpHost proxy = new HttpHost("localhost", 8080); final HttpRoute route = new HttpRoute(target, null, proxy, true, TunnelType.TUNNELLED, LayerType.LAYERED); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); final HttpRequestInterceptor interceptor = new RequestClientConnControl(); interceptor.process(request, context); final Header header1 = request.getFirstHeader(HTTP.CONN_DIRECTIVE); Assert.assertNotNull(header1); Assert.assertEquals(HTTP.CONN_KEEP_ALIVE, header1.getValue()); final Header header2 = request.getFirstHeader("Proxy-Connection"); Assert.assertNull(header2); }
@Test public void testProxyConnectionKeepAliveForRequestsOverProxy() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpClientContext context = HttpClientContext.create(); final HttpHost target = new HttpHost("localhost", 80, "http"); final HttpHost proxy = new HttpHost("localhost", 8080); final HttpRoute route = new HttpRoute(target, null, proxy, false, TunnelType.PLAIN, LayerType.PLAIN); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); final HttpRequestInterceptor interceptor = new RequestClientConnControl(); interceptor.process(request, context); final Header header1 = request.getFirstHeader("Proxy-Connection"); Assert.assertNotNull(header1); Assert.assertEquals(HTTP.CONN_KEEP_ALIVE, header1.getValue()); final Header header2 = request.getFirstHeader(HTTP.CONN_DIRECTIVE); Assert.assertNull(header2); }
@Test public void testPreserveCustomConnectionHeader() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); request.addHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE); final HttpClientContext context = HttpClientContext.create(); final HttpHost target = new HttpHost("localhost", 443, "https"); final HttpHost proxy = new HttpHost("localhost", 8080); final HttpRoute route = new HttpRoute(target, null, proxy, true, TunnelType.TUNNELLED, LayerType.LAYERED); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); final HttpRequestInterceptor interceptor = new RequestClientConnControl(); interceptor.process(request, context); final Header header1 = request.getFirstHeader(HTTP.CONN_DIRECTIVE); Assert.assertNotNull(header1); Assert.assertEquals(HTTP.CONN_CLOSE, header1.getValue()); final Header header2 = request.getFirstHeader("Proxy-Connection"); Assert.assertNull(header2); }
@Test public void testPreserveCustomProxyConnectionHeader() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); request.addHeader("Proxy-Connection", HTTP.CONN_CLOSE); final HttpClientContext context = HttpClientContext.create(); final HttpHost target = new HttpHost("localhost", 80, "http"); final HttpHost proxy = new HttpHost("localhost", 8080); final HttpRoute route = new HttpRoute(target, null, proxy, false, TunnelType.PLAIN, LayerType.PLAIN); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); final HttpRequestInterceptor interceptor = new RequestClientConnControl(); interceptor.process(request, context); final Header header1 = request.getFirstHeader("Proxy-Connection"); Assert.assertNotNull(header1); Assert.assertEquals(HTTP.CONN_CLOSE, header1.getValue()); }
@SuppressWarnings("unused") @Test public void testCstr4() { // test convenience constructor with 4 arguments HttpRoute route = new HttpRoute(TARGET2, null, PROXY2, false); HttpRoute should = new HttpRoute (TARGET2, null, new HttpHost[]{ PROXY2 }, false, TunnelType.PLAIN, LayerType.PLAIN); Assert.assertEquals("bad convenience route 4/insecure", route, should); route = new HttpRoute(TARGET2, LOCAL42, PROXY1, true); should = new HttpRoute (TARGET2, LOCAL42, new HttpHost[]{ PROXY1 }, true, TunnelType.TUNNELLED, LayerType.LAYERED); Assert.assertEquals("bad convenience route 4/secure", route, should); // this constructor REQUIRES a proxy to be specified try { new HttpRoute(TARGET1, LOCAL61, null, false); Assert.fail("missing proxy not detected"); } catch (final IllegalArgumentException iax) { // expected } }
@Test public void testCstr6() { // test convenience constructor with 6 arguments HttpRoute route = new HttpRoute (TARGET2, null, PROXY2, true, TunnelType.TUNNELLED, LayerType.PLAIN); HttpRoute should = new HttpRoute (TARGET2, null, new HttpHost[]{ PROXY2 }, true, TunnelType.TUNNELLED, LayerType.PLAIN); Assert.assertEquals("bad convenience route 6/proxied", route, should); route = new HttpRoute (TARGET2, null, (HttpHost) null, true, TunnelType.PLAIN, LayerType.LAYERED); should = new HttpRoute (TARGET2, null, (HttpHost[]) null, true, TunnelType.PLAIN, LayerType.LAYERED); Assert.assertEquals("bad convenience route 6/direct", route, should); // handling of null vs. empty chain is checked in the equals tests }
@Test public void testImmutable() throws CloneNotSupportedException { final HttpHost[] proxies = new HttpHost[]{ PROXY1, PROXY2, PROXY3 }; final HttpRoute route1 = new HttpRoute(TARGET1, null, proxies, false, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route2 = (HttpRoute) route1.clone(); final HttpRoute route3 = new HttpRoute(TARGET1, null, proxies.clone(), false, TunnelType.PLAIN, LayerType.PLAIN); // modify the array that was passed to the constructor of route1 proxies[1] = PROXY3; proxies[2] = PROXY2; Assert.assertEquals("route differs from clone", route2, route1); Assert.assertEquals("route was modified", route3, route1); }
/** Helper to check the status of the four flags. */ public final static void checkCTLS(final RouteTracker rt, final boolean c, final boolean t, final boolean l, final boolean s) { final String rts = rt.toString(); Assert.assertEquals("wrong flag connected: " + rts, c, rt.isConnected()); Assert.assertEquals("wrong flag tunnelled: " + rts, t, rt.isTunnelled()); Assert.assertEquals("wrong enum tunnelled: " + rts, t ? TunnelType.TUNNELLED : TunnelType.PLAIN, rt.getTunnelType()); Assert.assertEquals("wrong flag layered: " + rts, l, rt.isLayered()); Assert.assertEquals("wrong enum layered: " + rts, l ? LayerType.LAYERED : LayerType.PLAIN, rt.getLayerType()); Assert.assertEquals("wrong flag secure: " + rts, s, rt.isSecure()); }
@Test public void testCstrFullRoute() { // create a route with all arguments and check the details final HttpHost[] chain3 = { PROXY1, PROXY2, PROXY3 }; final HttpRoute route = new HttpRoute(TARGET1, LOCAL41, chain3, false, TunnelType.PLAIN, LayerType.PLAIN); Assert.assertEquals("wrong target", TARGET1, route.getTargetHost()); Assert.assertEquals("wrong local address", LOCAL41, route.getLocalAddress()); Assert.assertEquals("wrong proxy host", PROXY1, route.getProxyHost()); Assert.assertEquals("wrong hop count", 4, route.getHopCount()); Assert.assertEquals("wrong hop 0", PROXY1, route.getHopTarget(0)); Assert.assertEquals("wrong hop 1", PROXY2, route.getHopTarget(1)); Assert.assertEquals("wrong hop 2", PROXY3, route.getHopTarget(2)); Assert.assertEquals("wrong hop 3", TARGET1, route.getHopTarget(3)); Assert.assertFalse("wrong flag: secured", route.isSecure()); Assert.assertFalse("wrong flag: tunnelled", route.isTunnelled()); Assert.assertFalse("wrong flag: layered", route.isLayered()); final String routestr = route.toString(); Assert.assertTrue("missing target in toString", routestr.contains(TARGET1.getHostName())); Assert.assertTrue("missing local address in toString", routestr.contains(LOCAL41.toString())); Assert.assertTrue("missing proxy 1 in toString", routestr.contains(PROXY1.getHostName())); Assert.assertTrue("missing proxy 2 in toString", routestr.contains(PROXY2.getHostName())); Assert.assertTrue("missing proxy 3 in toString", routestr.contains(PROXY3.getHostName())); }
@Test public void testNullEnums() { // tests the default values for the enum parameters // also covers the accessors for the enum attributes final HttpRoute route = new HttpRoute(TARGET1, null, PROXY1, false, null, null); // here are defaults Assert.assertFalse("default tunnelling", route.isTunnelled()); Assert.assertEquals("untunnelled", TunnelType.PLAIN, route.getTunnelType()); Assert.assertFalse("default layering", route.isLayered()); Assert.assertEquals("unlayered", LayerType.PLAIN, route.getLayerType()); }
@Test public void testCstr1() { final HttpRoute route = new HttpRoute(TARGET2); final HttpRoute should = new HttpRoute (TARGET2, null, (HttpHost[]) null, false, TunnelType.PLAIN, LayerType.PLAIN); Assert.assertEquals("bad convenience route", route, should); }
@Test public void testCstr3() { // test convenience constructor with 3 arguments HttpRoute route = new HttpRoute(TARGET2, LOCAL61, false); HttpRoute should = new HttpRoute (TARGET2, LOCAL61, (HttpHost[]) null, false, TunnelType.PLAIN, LayerType.PLAIN); Assert.assertEquals("bad convenience route 3/insecure", route, should); route = new HttpRoute(TARGET2, null, true); should = new HttpRoute(TARGET2, null, (HttpHost[]) null, true, TunnelType.PLAIN, LayerType.PLAIN); Assert.assertEquals("bad convenience route 3/secure", route, should); }
@Test public void testProxyRoutes() { final HttpRouteDirector rd = new BasicRouteDirector(); HttpRoute r = new HttpRoute(TARGET2, null, PROXY1, false); RouteTracker rt = new RouteTracker(r); boolean complete = checkVia(rt, r, rd, 2); Assert.assertTrue("incomplete route 1", complete); // tunnelled, but neither secure nor layered r = new HttpRoute(TARGET1, LOCAL61, PROXY3, false, TunnelType.TUNNELLED, LayerType.PLAIN); rt = new RouteTracker(r); complete = checkVia(rt, r, rd, 3); Assert.assertTrue("incomplete route 2", complete); // tunnelled, layered, but not secure r = new HttpRoute(TARGET1, LOCAL61, PROXY3, false, TunnelType.TUNNELLED, LayerType.LAYERED); rt = new RouteTracker(r); complete = checkVia(rt, r, rd, 4); Assert.assertTrue("incomplete route 3", complete); // tunnelled, layered, secure r = new HttpRoute(TARGET1, LOCAL61, PROXY3, true); rt = new RouteTracker(r); complete = checkVia(rt, r, rd, 4); Assert.assertTrue("incomplete route 4", complete); }
@Test public void testProxyChainRoutes() { final HttpRouteDirector rd = new BasicRouteDirector(); HttpHost[] proxies = { PROXY1, PROXY2 }; HttpRoute r = new HttpRoute(TARGET2, LOCAL42, proxies, false, TunnelType.PLAIN, LayerType.PLAIN); RouteTracker rt = new RouteTracker(r); boolean complete = checkVia(rt, r, rd, 3); Assert.assertTrue("incomplete route 1", complete); // tunnelled, but neither secure nor layered proxies = new HttpHost[]{ PROXY3, PROXY2 }; r = new HttpRoute(TARGET1, null, proxies, false, TunnelType.TUNNELLED, LayerType.PLAIN); rt = new RouteTracker(r); complete = checkVia(rt, r, rd, 4); Assert.assertTrue("incomplete route 2", complete); // tunnelled, layered, but not secure proxies = new HttpHost[]{ PROXY3, PROXY2, PROXY1 }; r = new HttpRoute(TARGET2, LOCAL61, proxies, false, TunnelType.TUNNELLED, LayerType.LAYERED); rt = new RouteTracker(r); complete = checkVia(rt, r, rd, 6); Assert.assertTrue("incomplete route 3", complete); // tunnelled, layered, secure proxies = new HttpHost[]{ PROXY1, PROXY3 }; r = new HttpRoute(TARGET1, LOCAL61, proxies, true, TunnelType.TUNNELLED, LayerType.LAYERED); rt = new RouteTracker(r); complete = checkVia(rt, r, rd, 5); Assert.assertTrue("incomplete route 4", complete); }
public HttpRoute determineRoute(HttpHost target, HttpRequest request, HttpContext context) throws HttpException { if (request == null) { throw new IllegalStateException("Request must not be null."); } // If we have a forced route, we can do without a target. HttpRoute route = ConnRouteParams.getForcedRoute(request.getParams()); if (route != null) { return route; } // If we get here, there is no forced route. // So we need a target to compute a route. if (target == null) { throw new IllegalStateException("Target host must not be null."); } final InetAddress local = ConnRouteParams.getLocalAddress(request.getParams()); final Scheme schm = schemeRegistry.getScheme(target.getSchemeName()); // as it is typically used for TLS/SSL, we assume that // a layered scheme implies a secure connection final boolean secure = schm.isLayered(); if (proxyChain == null || proxyChain.length == 0) { route = new HttpRoute(target, local, secure); } else { TunnelType tunnelType = secure ? TunnelType.TUNNELLED : TunnelType.PLAIN; LayerType layereType = secure ? LayerType.LAYERED : LayerType.PLAIN; return new HttpRoute(target, null, proxyChain, secure, tunnelType, layereType); } return route; }
@Test public void testProxyChain() { final HttpHost[] chainA = { PROXY1 }; final HttpHost[] chainB = { PROXY1, PROXY2 }; final HttpHost[] chainC = { PROXY2, PROXY1 }; final HttpRouteDirector rowdy = new BasicRouteDirector(); final HttpRoute route1cA = new HttpRoute(TARGET1, null, chainA, false, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route1cB = new HttpRoute(TARGET1, null, chainB, false, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route1cC = new HttpRoute(TARGET1, null, chainC, false, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route1cD = new HttpRoute(TARGET1, null, chainC, false, TunnelType.PLAIN, LayerType.PLAIN); int step = rowdy.nextStep(route1cA, null); Assert.assertEquals("wrong step to route1cA", HttpRouteDirector.CONNECT_PROXY, step); step = rowdy.nextStep(route1cB, null); Assert.assertEquals("wrong step to route1cB", HttpRouteDirector.CONNECT_PROXY, step); step = rowdy.nextStep(route1cC, null); Assert.assertEquals("wrong step to route1cC", HttpRouteDirector.CONNECT_PROXY, step); step = rowdy.nextStep(route1cD, null); Assert.assertEquals("wrong step to route1cD", HttpRouteDirector.CONNECT_PROXY, step); step = rowdy.nextStep(route1cB, route1cA); Assert.assertEquals("wrong step to route 1cB from 1cA", HttpRouteDirector.TUNNEL_PROXY, step); step = rowdy.nextStep(route1cB, route1cB); Assert.assertEquals("complete route 1cB not detected", HttpRouteDirector.COMPLETE, step); step = rowdy.nextStep(route1cB, route1cC); Assert.assertEquals("unreachable route 1cB from 1cC not detected", HttpRouteDirector.UNREACHABLE, step); step = rowdy.nextStep(route1cB, route1cD); Assert.assertEquals("unreachable route 1cB from 1cD not detected", HttpRouteDirector.UNREACHABLE, step); step = rowdy.nextStep(route1cA, route1cB); Assert.assertEquals("unreachable route 1cA from 1cB not detected", HttpRouteDirector.UNREACHABLE, step); }