1 /* 2 * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.incubator.http; 27 28 import java.io.IOException; 29 import java.lang.System.Logger.Level; 30 import java.net.InetSocketAddress; 31 import java.nio.channels.SocketChannel; 32 import java.util.concurrent.CompletableFuture; 33 import jdk.incubator.http.internal.common.SSLTube; 34 import jdk.incubator.http.internal.common.Utils; 35 36 /** 37 * An SSL tunnel built on a Plain (CONNECT) TCP tunnel. 38 */ 39 class AsyncSSLTunnelConnection extends AbstractAsyncSSLConnection { 40 41 final PlainTunnelingConnection plainConnection; 42 final PlainHttpPublisher writePublisher; 43 volatile SSLTube flow; 44 45 AsyncSSLTunnelConnection(InetSocketAddress addr, 46 HttpClientImpl client, 47 String[] alpn, 48 InetSocketAddress proxy) 49 { 50 super(addr, client, Utils.getServerName(addr), alpn); 51 this.plainConnection = new PlainTunnelingConnection(addr, proxy, client); 52 this.writePublisher = new PlainHttpPublisher(); 53 } 54 55 @Override 56 public CompletableFuture<Void> connectAsync() { 57 debug.log(Level.DEBUG, "Connecting plain tunnel connection"); 58 // This will connect the PlainHttpConnection flow, so that 59 // its HttpSubscriber and HttpPublisher are subscribed to the 60 // SocketTube 61 return plainConnection 62 .connectAsync() 63 .thenApply( unused -> { 64 debug.log(Level.DEBUG, "creating SSLTube"); 65 // create the SSLTube wrapping the SocketTube, with the given engine 66 flow = new SSLTube(engine, 67 client().theExecutor(), 68 plainConnection.getConnectionFlow()); 69 return null;} ); 70 } 71 72 @Override 73 boolean connected() { 74 return plainConnection.connected(); // && sslDelegate.connected(); 75 } 76 77 @Override 78 HttpPublisher publisher() { return writePublisher; } 79 80 @Override 81 public String toString() { 82 return "AsyncSSLTunnelConnection: " + super.toString(); 83 } 84 85 @Override 86 PlainTunnelingConnection plainConnection() { 87 return plainConnection; 88 } 89 90 @Override 91 ConnectionPool.CacheKey cacheKey() { 92 return ConnectionPool.cacheKey(address, plainConnection.proxyAddr); 93 } 94 95 @Override 96 public void close() { 97 plainConnection.close(); 98 } 99 100 @Override 101 void shutdownInput() throws IOException { 102 plainConnection.channel().shutdownInput(); 103 } 104 105 @Override 106 void shutdownOutput() throws IOException { 107 plainConnection.channel().shutdownOutput(); 108 } 109 110 @Override 111 SocketChannel channel() { 112 return plainConnection.channel(); 113 } 114 115 @Override 116 boolean isProxied() { 117 return true; 118 } 119 120 @Override 121 SSLTube getConnectionFlow() { 122 return flow; 123 } 124 }