src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLConnection.java
branchhttp-client-branch
changeset 55763 634d8e14c172
parent 47216 71c04702a3d5
child 55795 074bb951658a
equal deleted inserted replaced
55762:e947a3a50a95 55763:634d8e14c172
    24  */
    24  */
    25 
    25 
    26 package jdk.incubator.http;
    26 package jdk.incubator.http;
    27 
    27 
    28 import java.io.IOException;
    28 import java.io.IOException;
       
    29 import java.lang.System.Logger.Level;
    29 import java.net.InetSocketAddress;
    30 import java.net.InetSocketAddress;
    30 import java.nio.ByteBuffer;
       
    31 import java.nio.channels.SocketChannel;
    31 import java.nio.channels.SocketChannel;
    32 import java.util.concurrent.CompletableFuture;
    32 import java.util.concurrent.CompletableFuture;
    33 import java.util.function.Consumer;
    33 import jdk.incubator.http.internal.common.ByteBufferReference;
    34 import java.util.function.Supplier;
    34 import jdk.incubator.http.internal.common.SSLTube;
    35 import javax.net.ssl.SSLEngine;
    35 import jdk.incubator.http.internal.common.Utils;
    36 
    36 
    37 import jdk.incubator.http.internal.common.ByteBufferReference;
       
    38 import jdk.incubator.http.internal.common.Utils;
       
    39 
    37 
    40 /**
    38 /**
    41  * Asynchronous version of SSLConnection.
    39  * Asynchronous version of SSLConnection.
    42  */
    40  */
    43 class AsyncSSLConnection extends AbstractAsyncSSLConnection {
    41 class AsyncSSLConnection extends AbstractAsyncSSLConnection {
    44 
    42 
    45     final AsyncSSLDelegate sslDelegate;
       
    46     final PlainHttpConnection plainConnection;
    43     final PlainHttpConnection plainConnection;
    47     final String serverName;
    44     final PlainHttpPublisher writePublisher;
       
    45     private volatile SSLTube flow;
    48 
    46 
    49     AsyncSSLConnection(InetSocketAddress addr, HttpClientImpl client, String[] ap) {
    47     AsyncSSLConnection(InetSocketAddress addr,
    50         super(addr, client);
    48                        HttpClientImpl client,
       
    49                        String[] alpn) {
       
    50         super(addr, client, Utils.getServerName(addr), alpn);
    51         plainConnection = new PlainHttpConnection(addr, client);
    51         plainConnection = new PlainHttpConnection(addr, client);
    52         serverName = Utils.getServerName(addr);
    52         writePublisher = new PlainHttpPublisher();
    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     }
    53     }
    61 
    54 
    62     @Override
    55     @Override
    63     PlainHttpConnection plainConnection() {
    56     PlainHttpConnection plainConnection() {
    64         return plainConnection;
    57         return plainConnection;
    65     }
    58     }
    66 
    59 
    67     @Override
    60     @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() {
    61     public CompletableFuture<Void> connectAsync() {
    82         // not used currently
    62         return plainConnection
    83         throw new InternalError();
    63                 .connectAsync()
       
    64                 .thenApply( unused -> {
       
    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; } );
    84     }
    70     }
    85 
    71 
    86     @Override
    72     @Override
    87     boolean connected() {
    73     boolean connected() {
    88         return plainConnection.connected() && sslDelegate.connected();
    74         return plainConnection.connected();
    89     }
    75     }
       
    76 
       
    77     @Override
       
    78     HttpPublisher publisher() { return writePublisher; }
    90 
    79 
    91     @Override
    80     @Override
    92     boolean isProxied() {
    81     boolean isProxied() {
    93         return false;
    82         return false;
    94     }
    83     }
    97     SocketChannel channel() {
    86     SocketChannel channel() {
    98         return plainConnection.channel();
    87         return plainConnection.channel();
    99     }
    88     }
   100 
    89 
   101     @Override
    90     @Override
   102     public void enableCallback() {
       
   103         sslDelegate.enableCallback();
       
   104     }
       
   105 
       
   106     @Override
       
   107     ConnectionPool.CacheKey cacheKey() {
    91     ConnectionPool.CacheKey cacheKey() {
   108         return ConnectionPool.cacheKey(address, null);
    92         return ConnectionPool.cacheKey(address, null);
   109     }
    93     }
   110 
    94 
   111     @Override
    95     @Override
   112     long write(ByteBuffer[] buffers, int start, int number)
    96     public void writeAsync(ByteBufferReference[] buffers) throws IOException {
   113         throws IOException
    97         writePublisher.writeAsync(buffers);
   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     }
    98     }
   129 
    99 
   130     @Override
   100     @Override
   131     public void writeAsyncUnordered(ByteBufferReference[] buffers) throws IOException {
   101     public void writeAsyncUnordered(ByteBufferReference[] buffers) throws IOException {
   132         assert getMode() == Mode.ASYNC;
   102         writePublisher.writeAsyncUnordered(buffers);
   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     }
   103     }
   141 
   104 
   142     @Override
   105     @Override
   143     public void flushAsync() throws IOException {
   106     public void flushAsync() throws IOException {
   144         sslDelegate.flushAsync();
   107         writePublisher.flushAsync();
   145     }
   108     }
   146 
   109 
   147     @Override
   110     @Override
   148     public void closeExceptionally(Throwable cause) {
   111     public void closeExceptionally(Throwable cause) {
   149         Utils.close(cause, sslDelegate, plainConnection.channel());
   112         debug.log(Level.DEBUG, () -> "closing: " + cause);
       
   113         plainConnection.close();
   150     }
   114     }
   151 
   115 
   152     @Override
   116     @Override
   153     public void close() {
   117     public void close() {
   154         Utils.close(sslDelegate, plainConnection.channel());
   118         plainConnection.close();
   155     }
   119     }
   156 
   120 
   157     @Override
   121     @Override
   158     void shutdownInput() throws IOException {
   122     void shutdownInput() throws IOException {
       
   123         debug.log(Level.DEBUG, "plainConnection.channel().shutdownInput()");
   159         plainConnection.channel().shutdownInput();
   124         plainConnection.channel().shutdownInput();
   160     }
   125     }
   161 
   126 
   162     @Override
   127     @Override
   163     void shutdownOutput() throws IOException {
   128     void shutdownOutput() throws IOException {
       
   129         debug.log(Level.DEBUG, "plainConnection.channel().shutdownOutput()");
   164         plainConnection.channel().shutdownOutput();
   130         plainConnection.channel().shutdownOutput();
   165     }
   131     }
   166 
   132 
   167     @Override
   133    @Override
   168     SSLEngine getEngine() {
   134    SSLTube getConnectionFlow() {
   169         return sslDelegate.getEngine();
   135        return flow;
   170     }
   136    }
   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 }
   137 }