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.net.InetSocketAddress; 30 import java.nio.ByteBuffer; 31 import java.nio.channels.SocketChannel; 32 import java.util.concurrent.CompletableFuture; 33 import java.util.function.Consumer; 34 import java.util.function.Supplier; 35 import javax.net.ssl.SSLEngine; 36 37 import jdk.incubator.http.internal.common.ByteBufferReference; 38 import jdk.incubator.http.internal.common.Utils; 39 40 /** 41 * Asynchronous version of SSLConnection. 42 */ 43 class AsyncSSLConnection extends AbstractAsyncSSLConnection { 44 45 final AsyncSSLDelegate sslDelegate; 46 final PlainHttpConnection plainConnection; 47 final String serverName; 48 49 AsyncSSLConnection(InetSocketAddress addr, HttpClientImpl client, String[] ap) { 50 super(addr, client); 51 plainConnection = new PlainHttpConnection(addr, client); 52 serverName = Utils.getServerName(addr); 53 sslDelegate = new AsyncSSLDelegate(plainConnection, client, ap, serverName); 54 } 55 56 @Override 57 synchronized void configureMode(Mode mode) throws IOException { 58 super.configureMode(mode); 59 plainConnection.configureMode(mode); 60 } 61 62 @Override 63 PlainHttpConnection plainConnection() { 64 return plainConnection; 65 } 66 67 @Override 68 AsyncSSLDelegate sslDelegate() { 69 return sslDelegate; 70 } 71 72 @Override 73 public void connect() throws IOException, InterruptedException { 74 plainConnection.connect(); 75 configureMode(Mode.ASYNC); 76 startReading(); 77 sslDelegate.connect(); 78 } 79 80 @Override 81 public CompletableFuture<Void> connectAsync() { 82 // not used currently 83 throw new InternalError(); 84 } 85 86 @Override 87 boolean connected() { 88 return plainConnection.connected() && sslDelegate.connected(); 89 } 90 91 @Override 92 boolean isProxied() { 93 return false; 94 } 95 96 @Override 97 SocketChannel channel() { 98 return plainConnection.channel(); 99 } 100 101 @Override 102 public void enableCallback() { 103 sslDelegate.enableCallback(); 104 } 105 106 @Override 107 ConnectionPool.CacheKey cacheKey() { 108 return ConnectionPool.cacheKey(address, null); 109 } 110 111 @Override 112 long write(ByteBuffer[] buffers, int start, int number) 113 throws IOException 114 { 115 ByteBuffer[] bufs = Utils.reduce(buffers, start, number); 116 long n = Utils.remaining(bufs); 117 sslDelegate.writeAsync(ByteBufferReference.toReferences(bufs)); 118 sslDelegate.flushAsync(); 119 return n; 120 } 121 122 @Override 123 long write(ByteBuffer buffer) throws IOException { 124 long n = buffer.remaining(); 125 sslDelegate.writeAsync(ByteBufferReference.toReferences(buffer)); 126 sslDelegate.flushAsync(); 127 return n; 128 } 129 130 @Override 131 public void writeAsyncUnordered(ByteBufferReference[] buffers) throws IOException { 132 assert getMode() == Mode.ASYNC; 133 sslDelegate.writeAsyncUnordered(buffers); 134 } 135 136 @Override 137 public void writeAsync(ByteBufferReference[] buffers) throws IOException { 138 assert getMode() == Mode.ASYNC; 139 sslDelegate.writeAsync(buffers); 140 } 141 142 @Override 143 public void flushAsync() throws IOException { 144 sslDelegate.flushAsync(); 145 } 146 147 @Override 148 public void closeExceptionally(Throwable cause) { 149 Utils.close(cause, sslDelegate, plainConnection.channel()); 150 } 151 152 @Override 153 public void close() { 154 Utils.close(sslDelegate, plainConnection.channel()); 155 } 156 157 @Override 158 void shutdownInput() throws IOException { 159 plainConnection.channel().shutdownInput(); 160 } 161 162 @Override 163 void shutdownOutput() throws IOException { 164 plainConnection.channel().shutdownOutput(); 165 } 166 167 @Override 168 SSLEngine getEngine() { 169 return sslDelegate.getEngine(); 170 } 171 172 @Override 173 public void setAsyncCallbacks(Consumer<ByteBufferReference> asyncReceiver, 174 Consumer<Throwable> errorReceiver, 175 Supplier<ByteBufferReference> readBufferSupplier) { 176 sslDelegate.setAsyncCallbacks(asyncReceiver, errorReceiver, readBufferSupplier); 177 plainConnection.setAsyncCallbacks(sslDelegate::asyncReceive, errorReceiver, sslDelegate::getNetBuffer); 178 } 179 180 @Override 181 public void startReading() { 182 plainConnection.startReading(); 183 sslDelegate.startReading(); 184 } 185 186 @Override 187 public void stopAsyncReading() { 188 plainConnection.stopAsyncReading(); 189 } 190 191 @Override 192 SSLConnection downgrade() { 193 return new SSLConnection(this); 194 } 195 }