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.nio.channels.SelectionKey;
32  import java.nio.channels.SocketChannel;
33  
34  import org.apache.hc.core5.io.CloseMode;
35  import org.apache.hc.core5.io.Closer;
36  import org.apache.hc.core5.io.SocketTimeoutExceptionFactory;
37  import org.apache.hc.core5.util.Timeout;
38  
39  final class InternalConnectChannel extends InternalChannel {
40  
41      private final SelectionKey key;
42      private final SocketChannel socketChannel;
43      private final IOSessionRequest sessionRequest;
44      private final long creationTimeMillis;
45      private final InternalDataChannelFactory dataChannelFactory;
46  
47      InternalConnectChannel(
48              final SelectionKey key,
49              final SocketChannel socketChannel,
50              final IOSessionRequest sessionRequest,
51              final InternalDataChannelFactory dataChannelFactory) {
52          super();
53          this.key = key;
54          this.socketChannel = socketChannel;
55          this.sessionRequest = sessionRequest;
56          this.creationTimeMillis = System.currentTimeMillis();
57          this.dataChannelFactory = dataChannelFactory;
58      }
59  
60      @Override
61      void onIOEvent(final int readyOps) throws IOException {
62          if ((readyOps & SelectionKey.OP_CONNECT) != 0) {
63              if (socketChannel.isConnectionPending()) {
64                  socketChannel.finishConnect();
65              }
66              //check out connectTimeout
67              final long now = System.currentTimeMillis();
68              if (checkTimeout(now)) {
69                  final InternalDataChannel dataChannel = dataChannelFactory.create(
70                          key,
71                          socketChannel,
72                          sessionRequest.remoteEndpoint,
73                          sessionRequest.attachment);
74                  key.attach(dataChannel);
75                  sessionRequest.completed(dataChannel);
76                  dataChannel.handleIOEvent(SelectionKey.OP_CONNECT);
77              }
78          }
79      }
80  
81      @Override
82      Timeout getTimeout() {
83          return sessionRequest.timeout;
84      }
85  
86      @Override
87      long getLastEventTime() {
88          return creationTimeMillis;
89      }
90  
91      @Override
92      void onTimeout(final Timeout timeout) throws IOException {
93          sessionRequest.failed(SocketTimeoutExceptionFactory.create(timeout));
94          close();
95      }
96  
97      @Override
98      void onException(final Exception cause) {
99          sessionRequest.failed(cause);
100     }
101 
102     @Override
103     public void close() throws IOException {
104         key.cancel();
105         socketChannel.close();
106     }
107 
108     @Override
109     public void close(final CloseMode closeMode) {
110         key.cancel();
111         Closer.closeQuietly(socketChannel);
112     }
113 
114     @Override
115     public String toString() {
116         return sessionRequest.toString();
117     }
118 
119 }