Esempio n. 1
0
  /** Create an {@code SSLSocket} and perform the TLS handshake and certificate validation. */
  private void upgradeToTls(TunnelRequest tunnelRequest) throws IOException {
    Platform platform = Platform.get();

    // Make an SSL Tunnel on the first message pair of each SSL + proxy connection.
    if (requiresTunnel()) {
      makeTunnel(tunnelRequest);
    }

    // Create the wrapper over connected socket.
    socket =
        route.address.sslSocketFactory.createSocket(
            socket, route.address.uriHost, route.address.uriPort, true /* autoClose */);
    SSLSocket sslSocket = (SSLSocket) socket;
    if (route.modernTls) {
      platform.enableTlsExtensions(sslSocket, route.address.uriHost);
    } else {
      platform.supportTlsIntolerantServer(sslSocket);
    }

    boolean useNpn = route.modernTls && route.address.transports.contains("spdy/3");
    if (useNpn) {
      platform.setNpnProtocols(sslSocket, NPN_PROTOCOLS);
    }

    // Force handshake. This can throw!
    sslSocket.startHandshake();

    // Verify that the socket's certificates are acceptable for the target host.
    if (!route.address.hostnameVerifier.verify(route.address.uriHost, sslSocket.getSession())) {
      throw new IOException("Hostname '" + route.address.uriHost + "' was not verified");
    }

    out = sslSocket.getOutputStream();
    in = sslSocket.getInputStream();

    byte[] selectedProtocol;
    if (useNpn && (selectedProtocol = platform.getNpnSelectedProtocol(sslSocket)) != null) {
      if (Arrays.equals(selectedProtocol, SPDY3)) {
        sslSocket.setSoTimeout(0); // SPDY timeouts are set per-stream.
        spdyConnection =
            new SpdyConnection.Builder(route.address.getUriHost(), true, in, out).build();
        spdyConnection.sendConnectionHeader();
      } else if (!Arrays.equals(selectedProtocol, HTTP_11)) {
        throw new IOException(
            "Unexpected NPN transport " + new String(selectedProtocol, "ISO-8859-1"));
      }
    }
  }
Esempio n. 2
0
  /** Create an {@code SSLSocket} and perform the TLS handshake and certificate validation. */
  private void upgradeToTls(TunnelRequest tunnelRequest) throws IOException {
    Platform platform = Platform.get();

    // Make an SSL Tunnel on the first message pair of each SSL + proxy connection.
    if (requiresTunnel()) {
      makeTunnel(tunnelRequest);
    }

    // Create the wrapper over connected socket.
    socket =
        route.address.sslSocketFactory.createSocket(
            socket, route.address.uriHost, route.address.uriPort, true /* autoClose */);
    SSLSocket sslSocket = (SSLSocket) socket;
    if (route.modernTls) {
      platform.enableTlsExtensions(sslSocket, route.address.uriHost);
    } else {
      platform.supportTlsIntolerantServer(sslSocket);
    }

    boolean useNpn =
        route.modernTls
            && ( // Contains a spdy variant.
            route.address.protocols.contains(Protocol.HTTP_2)
                || route.address.protocols.contains(Protocol.SPDY_3));

    if (useNpn) {
      if (route.address.protocols.contains(Protocol.HTTP_2) // Contains both spdy variants.
          && route.address.protocols.contains(Protocol.SPDY_3)) {
        platform.setNpnProtocols(sslSocket, Protocol.HTTP2_SPDY3_AND_HTTP);
      } else if (route.address.protocols.contains(Protocol.HTTP_2)) {
        platform.setNpnProtocols(sslSocket, Protocol.HTTP2_AND_HTTP_11);
      } else {
        platform.setNpnProtocols(sslSocket, Protocol.SPDY3_AND_HTTP11);
      }
    }

    // Force handshake. This can throw!
    sslSocket.startHandshake();

    // Verify that the socket's certificates are acceptable for the target host.
    if (!route.address.hostnameVerifier.verify(route.address.uriHost, sslSocket.getSession())) {
      throw new IOException("Hostname '" + route.address.uriHost + "' was not verified");
    }

    out = sslSocket.getOutputStream();
    in = sslSocket.getInputStream();
    handshake = Handshake.get(sslSocket.getSession());
    streamWrapper();

    ByteString maybeProtocol;
    if (useNpn && (maybeProtocol = platform.getNpnSelectedProtocol(sslSocket)) != null) {
      Protocol selectedProtocol = Protocol.find(maybeProtocol); // Throws IOE on unknown.
      if (selectedProtocol.spdyVariant) {
        sslSocket.setSoTimeout(0); // SPDY timeouts are set per-stream.
        spdyConnection =
            new SpdyConnection.Builder(route.address.getUriHost(), true, in, out)
                .protocol(selectedProtocol)
                .build();
        spdyConnection.sendConnectionHeader();
      }
    }
  }