示例#1
0
  /**
   * 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());
      }
    }
  }