public RouteSelector(Address paramAddress, URI paramURI, OkHttpClient paramOkHttpClient, Request paramRequest) { this.address = paramAddress; this.uri = paramURI; this.client = paramOkHttpClient; this.pool = paramOkHttpClient.connectionPool; this.routeDatabase = Internal.instance.routeDatabase(paramOkHttpClient); this.network = Internal.instance.network(paramOkHttpClient); this.request = paramRequest; Proxy localProxy = paramAddress.proxy; if (localProxy != null) { this.proxies = Collections.singletonList(localProxy); } for (;;) { this.nextProxyIndex = 0; return; this.proxies = new ArrayList(); List localList = this.client.proxySelector.select(paramURI); if (localList != null) { this.proxies.addAll(localList); } this.proxies.removeAll(Collections.singleton(Proxy.NO_PROXY)); this.proxies.add(Proxy.NO_PROXY); } }
@Test public void singleRoute() throws Exception { Address address = new Address(uriHost, uriPort, socketFactory, null, null, authenticator, null, protocols); RouteSelector routeSelector = new RouteSelector(address, uri, proxySelector, pool, dns, new RouteDatabase()); assertTrue(routeSelector.hasNext()); dns.inetAddresses = makeFakeAddresses(255, 1); assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[0], uriPort, false); dns.assertRequests(uriHost); assertFalse(routeSelector.hasNext()); try { routeSelector.next("GET"); fail(); } catch (NoSuchElementException expected) { } }
@Test public void singleRouteReturnsFailedRoute() throws Exception { Address address = new Address(uriHost, uriPort, socketFactory, null, null, authenticator, null, protocols); RouteSelector routeSelector = new RouteSelector(address, uri, proxySelector, pool, dns, new RouteDatabase()); assertTrue(routeSelector.hasNext()); dns.inetAddresses = makeFakeAddresses(255, 1); Connection connection = routeSelector.next("GET"); RouteDatabase routeDatabase = new RouteDatabase(); routeDatabase.failed(connection.getRoute()); routeSelector = new RouteSelector(address, uri, proxySelector, pool, dns, routeDatabase); assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[0], uriPort, false); assertFalse(routeSelector.hasNext()); try { routeSelector.next("GET"); fail(); } catch (NoSuchElementException expected) { } }
@Test public void explicitProxyTriesThatProxiesAddressesOnly() throws Exception { Address address = new Address(uriHost, uriPort, socketFactory, null, null, authenticator, proxyA, protocols); RouteSelector routeSelector = new RouteSelector(address, uri, proxySelector, pool, dns, new RouteDatabase()); assertTrue(routeSelector.hasNext()); dns.inetAddresses = makeFakeAddresses(255, 2); assertConnection(routeSelector.next("GET"), address, proxyA, dns.inetAddresses[0], proxyAPort, false); assertConnection(routeSelector.next("GET"), address, proxyA, dns.inetAddresses[1], proxyAPort, false); assertFalse(routeSelector.hasNext()); dns.assertRequests(proxyAHost); proxySelector.assertRequests(); // No proxy selector requests! }
@Test public void explicitDirectProxy() throws Exception { Address address = new Address(uriHost, uriPort, socketFactory, null, null, authenticator, NO_PROXY, protocols); RouteSelector routeSelector = new RouteSelector(address, uri, proxySelector, pool, dns, new RouteDatabase()); assertTrue(routeSelector.hasNext()); dns.inetAddresses = makeFakeAddresses(255, 2); assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[0], uriPort, false); assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[1], uriPort, false); assertFalse(routeSelector.hasNext()); dns.assertRequests(uri.getHost()); proxySelector.assertRequests(); // No proxy selector requests! }
@Test public void proxySelectorReturnsNull() throws Exception { Address address = new Address(uriHost, uriPort, socketFactory, null, null, authenticator, null, protocols); proxySelector.proxies = null; RouteSelector routeSelector = new RouteSelector(address, uri, proxySelector, pool, dns, new RouteDatabase()); proxySelector.assertRequests(uri); assertTrue(routeSelector.hasNext()); dns.inetAddresses = makeFakeAddresses(255, 1); assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[0], uriPort, false); dns.assertRequests(uriHost); assertFalse(routeSelector.hasNext()); }
@Test public void proxySelectorReturnsNoProxies() throws Exception { Address address = new Address(uriHost, uriPort, socketFactory, null, null, authenticator, null, protocols); RouteSelector routeSelector = new RouteSelector(address, uri, proxySelector, pool, dns, new RouteDatabase()); assertTrue(routeSelector.hasNext()); dns.inetAddresses = makeFakeAddresses(255, 2); assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[0], uriPort, false); assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[1], uriPort, false); assertFalse(routeSelector.hasNext()); dns.assertRequests(uri.getHost()); proxySelector.assertRequests(uri); }
@Test public void proxySelectorDirectConnectionsAreSkipped() throws Exception { Address address = new Address(uriHost, uriPort, socketFactory, null, null, authenticator, null, protocols); proxySelector.proxies.add(NO_PROXY); RouteSelector routeSelector = new RouteSelector(address, uri, proxySelector, pool, dns, new RouteDatabase()); proxySelector.assertRequests(uri); // Only the origin server will be attempted. assertTrue(routeSelector.hasNext()); dns.inetAddresses = makeFakeAddresses(255, 1); assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[0], uriPort, false); dns.assertRequests(uriHost); assertFalse(routeSelector.hasNext()); }
private static Address createAddress(OkHttpClient client, Request request) { SSLSocketFactory sslSocketFactory = null; HostnameVerifier hostnameVerifier = null; CertificatePinner certificatePinner = null; if (request.isHttps()) { sslSocketFactory = client.getSslSocketFactory(); hostnameVerifier = client.getHostnameVerifier(); certificatePinner = client.getCertificatePinner(); } return new Address(request.httpUrl().host(), request.httpUrl().port(), client.getDns(), client.getSocketFactory(), sslSocketFactory, hostnameVerifier, certificatePinner, client.getAuthenticator(), client.getProxy(), client.getProtocols(), client.getConnectionSpecs(), client.getProxySelector()); }
public RouteSelector(Address address, URI uri, ProxySelector proxySelector, ConnectionPool pool, Dns dns, RouteDatabase routeDatabase) { this.address = address; this.uri = uri; this.proxySelector = proxySelector; this.pool = pool; this.dns = dns; this.routeDatabase = routeDatabase; this.postponedRoutes = new LinkedList<Route>(); resetNextProxy(uri, address.getProxy()); }
/** Connect to the origin server either directly or via a proxy. */ protected final void connect() throws IOException { if (connection != null) { return; } if (routeSelector == null) { String uriHost = uri.getHost(); if (uriHost == null) { throw new UnknownHostException(uri.toString()); } SSLSocketFactory sslSocketFactory = null; HostnameVerifier hostnameVerifier = null; if (uri.getScheme().equalsIgnoreCase("https")) { sslSocketFactory = client.getSslSocketFactory(); hostnameVerifier = client.getHostnameVerifier(); } Address address = new Address(uriHost, getEffectivePort(uri), sslSocketFactory, hostnameVerifier, client.getAuthenticator(), client.getProxy(), client.getTransports()); routeSelector = new RouteSelector(address, uri, client.getProxySelector(), client.getConnectionPool(), Dns.DEFAULT, client.getRoutesDatabase()); } connection = routeSelector.next(method); if (!connection.isConnected()) { connection.connect(client.getConnectTimeout(), client.getReadTimeout(), getTunnelConfig()); client.getConnectionPool().maybeShare(connection); client.getRoutesDatabase().connected(connection.getRoute()); } else if (!connection.isSpdy()) { connection.updateReadTimeout(client.getReadTimeout()); } connected(connection); if (connection.getRoute().getProxy() != client.getProxy()) { // Update the request line if the proxy changed; it may need a host name. requestHeaders.getHeaders().setRequestLine(getRequestLine()); } }
public final Response proceed(Request paramRequest) throws IOException { this.calls = (1 + this.calls); if (this.index > 0) { Interceptor localInterceptor2 = (Interceptor)HttpEngine.this.client.networkInterceptors.get(-1 + this.index); Address localAddress = HttpEngine.this.connection.route.address; if ((!paramRequest.url().getHost().equals(localAddress.uriHost)) || (Util.getEffectivePort(paramRequest.url()) != localAddress.uriPort)) { throw new IllegalStateException("network interceptor " + localInterceptor2 + " must retain the same host and port"); } if (this.calls > 1) { throw new IllegalStateException("network interceptor " + localInterceptor2 + " must call proceed() exactly once"); } } Response localResponse; if (this.index < HttpEngine.this.client.networkInterceptors.size()) { NetworkInterceptorChain localNetworkInterceptorChain = new NetworkInterceptorChain(HttpEngine.this, 1 + this.index, paramRequest); Interceptor localInterceptor1 = (Interceptor)HttpEngine.this.client.networkInterceptors.get(this.index); localResponse = localInterceptor1.intercept(localNetworkInterceptorChain); if (localNetworkInterceptorChain.calls != 1) { throw new IllegalStateException("network interceptor " + localInterceptor1 + " must call proceed() exactly once"); } } else { HttpEngine.this.transport.writeRequestHeaders(paramRequest); if ((HttpEngine.this.permitsRequestBody()) && (paramRequest.body != null)) { BufferedSink localBufferedSink = Okio.buffer(HttpEngine.this.transport.createRequestBody(paramRequest, paramRequest.body.contentLength())); paramRequest.body.writeTo(localBufferedSink); localBufferedSink.close(); } localResponse = HttpEngine.this.readNetworkResponse(); } return localResponse; }