/** * To make an HTTPS connection over an HTTP proxy, send an unencrypted CONNECT request to create * the proxy connection. This may need to be retried if the proxy requires authorization. */ private void makeTunnel(TunnelRequest tunnelRequest) throws IOException { HttpConnection tunnelConnection = new HttpConnection(pool, this, socket); Request request = tunnelRequest.getRequest(); String requestLine = tunnelRequest.requestLine(); while (true) { tunnelConnection.writeRequest(request.headers(), requestLine); tunnelConnection.flush(); Response response = tunnelConnection.readResponse().request(request).build(); tunnelConnection.emptyResponseBody(); switch (response.code()) { case HTTP_OK: // Assume the server won't send a TLS ServerHello until we send a TLS ClientHello. If that // happens, then we will have buffered bytes that are needed by the SSLSocket! if (tunnelConnection.bufferSize() > 0) { throw new IOException("TLS tunnel buffered too many bytes!"); } return; case HTTP_PROXY_AUTH: request = HttpAuthenticator.processAuthHeader( route.address.authenticator, response, route.proxy); if (request != null) continue; throw new IOException("Failed to authenticate with proxy"); default: throw new IOException("Unexpected response code for CONNECT: " + response.code()); } } }
/** * Returns true if we are confident that we can read data from this connection. This is more * expensive and more accurate than {@link #isAlive()}; callers should check {@link #isAlive()} * first. */ public boolean isReadable() { if (httpConnection != null) return httpConnection.isReadable(); return true; // SPDY connections, and connections before connect() are both optimistic. }