View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.hc.core5.reactor;
29  
30  import java.io.IOException;
31  import java.net.SocketTimeoutException;
32  import java.nio.channels.SelectionKey;
33  import java.nio.channels.SocketChannel;
34  
35  import org.apache.hc.core5.io.ShutdownType;
36  
37  final class InternalConnectChannel extends InternalChannel {
38  
39      private final SelectionKey key;
40      private final SocketChannel socketChannel;
41      private final IOSessionRequest sessionRequest;
42      private final long creationTime;
43      private final InternalDataChannelFactory dataChannelFactory;
44  
45      InternalConnectChannel(
46              final SelectionKey key,
47              final SocketChannel socketChannel,
48              final IOSessionRequest sessionRequest,
49              final InternalDataChannelFactory dataChannelFactory) {
50          super();
51          this.key = key;
52          this.socketChannel = socketChannel;
53          this.sessionRequest = sessionRequest;
54          this.creationTime = System.currentTimeMillis();
55          this.dataChannelFactory = dataChannelFactory;
56      }
57  
58      @Override
59      void onIOEvent(final int readyOps) throws IOException {
60          if ((readyOps & SelectionKey.OP_CONNECT) != 0) {
61              if (socketChannel.isConnectionPending()) {
62                  socketChannel.finishConnect();
63              }
64              //check out connectTimeout
65              final long now = System.currentTimeMillis();
66              if (checkTimeout(now)) {
67                  final InternalDataChannel dataChannel = dataChannelFactory.create(
68                          key,
69                          socketChannel,
70                          sessionRequest.remoteEndpoint,
71                          sessionRequest.attachment);
72                  key.attach(dataChannel);
73                  sessionRequest.completed(dataChannel);
74                  dataChannel.handleIOEvent(SelectionKey.OP_CONNECT);
75              }
76          }
77      }
78  
79      @Override
80      int getTimeout() {
81          return sessionRequest.timeout.toMillisIntBound();
82      }
83  
84      @Override
85      long getLastReadTime() {
86          return creationTime;
87      }
88  
89      @Override
90      void onTimeout() throws IOException {
91          sessionRequest.failed(new SocketTimeoutException());
92          close();
93      }
94  
95      @Override
96      void onException(final Exception cause) {
97          sessionRequest.failed(cause);
98      }
99  
100     @Override
101     public void close() throws IOException {
102         key.cancel();
103         socketChannel.close();
104     }
105 
106     @Override
107     public void shutdown(final ShutdownType shutdownType) {
108         try {
109             close();
110         } catch (final IOException ignore) {
111         }
112     }
113 }