SSLConnection.java revision 16749:38e5d6e8a291
11556Srgrimes/* 21556Srgrimes * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. 31556Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 41556Srgrimes * 51556Srgrimes * This code is free software; you can redistribute it and/or modify it 61556Srgrimes * under the terms of the GNU General Public License version 2 only, as 71556Srgrimes * published by the Free Software Foundation. Oracle designates this 81556Srgrimes * particular file as subject to the "Classpath" exception as provided 91556Srgrimes * by Oracle in the LICENSE file that accompanied this code. 101556Srgrimes * 111556Srgrimes * This code is distributed in the hope that it will be useful, but WITHOUT 121556Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 131556Srgrimes * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 141556Srgrimes * version 2 for more details (a copy is included in the LICENSE file that 151556Srgrimes * accompanied this code). 161556Srgrimes * 171556Srgrimes * You should have received a copy of the GNU General Public License version 181556Srgrimes * 2 along with this work; if not, write to the Free Software Foundation, 191556Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 201556Srgrimes * 211556Srgrimes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 221556Srgrimes * or visit www.oracle.com if you need additional information or have any 231556Srgrimes * questions. 241556Srgrimes */ 251556Srgrimes 261556Srgrimespackage jdk.incubator.http; 271556Srgrimes 281556Srgrimesimport java.io.IOException; 291556Srgrimesimport java.net.InetSocketAddress; 301556Srgrimesimport java.nio.ByteBuffer; 311556Srgrimesimport java.nio.channels.SocketChannel; 321556Srgrimesimport java.util.concurrent.CompletableFuture; 331556Srgrimesimport javax.net.ssl.SSLEngineResult.Status; 341556Srgrimesimport javax.net.ssl.SSLParameters; 353044Sdgimport jdk.incubator.http.SSLDelegate.WrapperResult; 3617987Speter 371556Srgrimesimport jdk.incubator.http.internal.common.ByteBufferReference; 381556Srgrimesimport jdk.incubator.http.internal.common.MinimalFuture; 391556Srgrimesimport jdk.incubator.http.internal.common.Utils; 401556Srgrimes 411556Srgrimes/** 421556Srgrimes * An SSL connection built on a Plain TCP connection. 431556Srgrimes */ 441556Srgrimesclass SSLConnection extends HttpConnection { 451556Srgrimes 4617987Speter PlainHttpConnection delegate; 471556Srgrimes SSLDelegate sslDelegate; 481556Srgrimes final String[] alpn; 491556Srgrimes 501556Srgrimes @Override 511556Srgrimes public CompletableFuture<Void> connectAsync() { 521556Srgrimes return delegate.connectAsync() 531556Srgrimes .thenCompose((Void v) -> 5417987Speter MinimalFuture.supply( () -> { 551556Srgrimes this.sslDelegate = new SSLDelegate(delegate.channel(), client, alpn); 561556Srgrimes return null; 571556Srgrimes })); 581556Srgrimes } 591556Srgrimes 601556Srgrimes @Override 611556Srgrimes public void connect() throws IOException { 621556Srgrimes delegate.connect(); 631556Srgrimes this.sslDelegate = new SSLDelegate(delegate.channel(), client, alpn); 641556Srgrimes } 6517987Speter 6617987Speter SSLConnection(InetSocketAddress addr, HttpClientImpl client, String[] ap) { 6717987Speter super(addr, client); 6817987Speter this.alpn = ap; 6917987Speter delegate = new PlainHttpConnection(addr, client); 7017987Speter } 7117987Speter 7217987Speter @Override 7317987Speter SSLParameters sslParameters() { 7417987Speter return sslDelegate.getSSLParameters(); 7517987Speter } 7617987Speter 7717987Speter @Override 7817987Speter public String toString() { 7917987Speter return "SSLConnection: " + super.toString(); 801556Srgrimes } 811556Srgrimes 821556Srgrimes private static long countBytes(ByteBuffer[] buffers, int start, int length) { 831556Srgrimes long c = 0; 841556Srgrimes for (int i=0; i<length; i++) { 851556Srgrimes c+= buffers[start+i].remaining(); 861556Srgrimes } 871556Srgrimes return c; 8817987Speter } 8917987Speter 9017987Speter @Override 9117987Speter ConnectionPool.CacheKey cacheKey() { 9217987Speter return ConnectionPool.cacheKey(address, null); 9317987Speter } 941556Srgrimes 951556Srgrimes @Override 9617987Speter long write(ByteBuffer[] buffers, int start, int number) throws IOException { 971556Srgrimes //debugPrint("Send", buffers, start, number); 981556Srgrimes long l = countBytes(buffers, start, number); 991556Srgrimes WrapperResult r = sslDelegate.sendData(buffers, start, number); 1001556Srgrimes if (r.result.getStatus() == Status.CLOSED) { 1011556Srgrimes if (l > 0) { 1021556Srgrimes throw new IOException("SSLHttpConnection closed"); 10317987Speter } 10417987Speter } 10517987Speter return l; 10617987Speter } 10717987Speter 10817987Speter @Override 10917987Speter long write(ByteBuffer buffer) throws IOException { 1101556Srgrimes //debugPrint("Send", buffer); 11117987Speter long l = buffer.remaining(); 11217987Speter WrapperResult r = sslDelegate.sendData(buffer); 11317987Speter if (r.result.getStatus() == Status.CLOSED) { 11417987Speter if (l > 0) { 11517987Speter throw new IOException("SSLHttpConnection closed"); 11617987Speter } 1171556Srgrimes } 11817987Speter return l; 11917987Speter } 12017987Speter 12117987Speter @Override 12217987Speter void writeAsync(ByteBufferReference[] buffers) throws IOException { 1231556Srgrimes write(ByteBufferReference.toBuffers(buffers), 0, buffers.length); 1241556Srgrimes } 1251556Srgrimes 1261556Srgrimes @Override 1271556Srgrimes void writeAsyncUnordered(ByteBufferReference[] buffers) throws IOException { 1281556Srgrimes write(ByteBufferReference.toBuffers(buffers), 0, buffers.length); 1291556Srgrimes } 1301556Srgrimes 1311556Srgrimes @Override 1321556Srgrimes void flushAsync() throws IOException { 1331556Srgrimes // nothing to do 1341556Srgrimes } 1351556Srgrimes 1361556Srgrimes @Override 1371556Srgrimes public void close() { 1381556Srgrimes Utils.close(delegate.channel()); 1391556Srgrimes } 1401556Srgrimes 1411556Srgrimes @Override 1421556Srgrimes void shutdownInput() throws IOException { 1431556Srgrimes delegate.channel().shutdownInput(); 1441556Srgrimes } 1451556Srgrimes 1461556Srgrimes @Override 1471556Srgrimes void shutdownOutput() throws IOException { 1481556Srgrimes delegate.channel().shutdownOutput(); 1491556Srgrimes } 1501556Srgrimes 1511556Srgrimes @Override 1521556Srgrimes protected ByteBuffer readImpl() throws IOException { 1531556Srgrimes ByteBuffer dst = ByteBuffer.allocate(8192); 1541556Srgrimes int n = readImpl(dst); 1551556Srgrimes if (n > 0) { 1561556Srgrimes return dst; 1571556Srgrimes } else if (n == 0) { 1581556Srgrimes return Utils.EMPTY_BYTEBUFFER; 1591556Srgrimes } else { 1601556Srgrimes return null; 1611556Srgrimes } 1621556Srgrimes } 1631556Srgrimes 1641556Srgrimes @Override 1651556Srgrimes protected int readImpl(ByteBuffer buf) throws IOException { 1661556Srgrimes // TODO: need to ensure that buf is big enough for application data 1671556Srgrimes WrapperResult r = sslDelegate.recvData(buf); 1681556Srgrimes // TODO: check for closure 16917525Sache String s = "Receive) "; 1701556Srgrimes //debugPrint(s, r.buf); 1711556Srgrimes if (r.result.bytesProduced() > 0) { 1721556Srgrimes assert buf == r.buf; 1731556Srgrimes } 1741556Srgrimes return r.result.bytesProduced(); 1751556Srgrimes } 1761556Srgrimes 17717987Speter @Override 1781556Srgrimes boolean connected() { 1791556Srgrimes return delegate.connected(); 1801556Srgrimes } 1811556Srgrimes 1821556Srgrimes @Override 1831556Srgrimes SocketChannel channel() { 1841556Srgrimes return delegate.channel(); 1851556Srgrimes } 18617987Speter 1871556Srgrimes @Override 1881556Srgrimes CompletableFuture<Void> whenReceivingResponse() { 1891556Srgrimes return delegate.whenReceivingResponse(); 1901556Srgrimes } 1911556Srgrimes 1921556Srgrimes @Override 1931556Srgrimes boolean isSecure() { 1941556Srgrimes return true; 1951556Srgrimes } 1961556Srgrimes 1971556Srgrimes @Override 1981556Srgrimes boolean isProxied() { 1991556Srgrimes return false; 2001556Srgrimes } 2011556Srgrimes 2021556Srgrimes} 2031556Srgrimes