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.http.impl.nio.reactor;
29  
30  import java.io.IOException;
31  
32  import org.apache.http.annotation.Immutable;
33  import org.apache.http.nio.reactor.IOEventDispatch;
34  import org.apache.http.nio.reactor.IOSession;
35  import org.apache.http.nio.reactor.ssl.SSLIOSession;
36  
37  /**
38   * Abstract {@link IOEventDispatch} implementation that supports both plain (non-encrypted)
39   * and SSL encrypted HTTP connections.
40   *
41   * @param <T> the connection type.
42   * @since 4.2
43   */
44  @Immutable // provided injected dependencies are immutable
45  public abstract class AbstractIODispatch<T> implements IOEventDispatch {
46  
47      protected abstract T createConnection(IOSession session);
48  
49      protected abstract void onConnected(T conn);
50  
51      protected abstract void onClosed(T conn);
52  
53      protected abstract void onException(T conn, IOException ex);
54  
55      protected abstract void onInputReady(T conn);
56  
57      protected abstract void onOutputReady(T conn);
58  
59      protected abstract void onTimeout(T conn);
60  
61      private void ensureNotNull(final T conn) {
62          if (conn == null) {
63              throw new IllegalStateException("HTTP connection is null");
64          }
65      }
66  
67      public void connected(final IOSession session) {
68          @SuppressWarnings("unchecked")
69          T conn = (T) session.getAttribute(IOEventDispatch.CONNECTION_KEY);
70          try {
71              if (conn == null) {
72                  conn = createConnection(session);
73                  session.setAttribute(IOEventDispatch.CONNECTION_KEY, conn);
74              }
75              onConnected(conn);
76              SSLIOSession ssliosession = (SSLIOSession) session.getAttribute(
77                      SSLIOSession.SESSION_KEY);
78              if (ssliosession != null) {
79                  try {
80                      synchronized (ssliosession) {
81                          if (!ssliosession.isInitialized()) {
82                              ssliosession.initialize();
83                          }
84                      }
85                  } catch (IOException ex) {
86                      onException(conn, ex);
87                      ssliosession.shutdown();
88                  }
89              }
90          } catch (RuntimeException ex) {
91              session.shutdown();
92              throw ex;
93          }
94      }
95  
96      public void disconnected(final IOSession session) {
97          @SuppressWarnings("unchecked")
98          T conn = (T) session.getAttribute(IOEventDispatch.CONNECTION_KEY);
99          if (conn != null) {
100             onClosed(conn);
101         }
102     }
103 
104     public void inputReady(final IOSession session) {
105         @SuppressWarnings("unchecked")
106         T conn = (T) session.getAttribute(IOEventDispatch.CONNECTION_KEY);
107         try {
108             ensureNotNull(conn);
109             SSLIOSession ssliosession = (SSLIOSession) session.getAttribute(
110                     SSLIOSession.SESSION_KEY);
111             if (ssliosession == null) {
112                 onInputReady(conn);
113             } else {
114                 try {
115                     if (!ssliosession.isInitialized()) {
116                         ssliosession.initialize();
117                     }
118                     if (ssliosession.isAppInputReady()) {
119                         onInputReady(conn);
120                     }
121                     ssliosession.inboundTransport();
122                 } catch (IOException ex) {
123                     onException(conn, ex);
124                     ssliosession.shutdown();
125                 }
126             }
127         } catch (RuntimeException ex) {
128             session.shutdown();
129             throw ex;
130         }
131     }
132 
133     public void outputReady(final IOSession session) {
134         @SuppressWarnings("unchecked")
135         T conn = (T) session.getAttribute(IOEventDispatch.CONNECTION_KEY);
136         try {
137             ensureNotNull(conn);
138             SSLIOSession ssliosession = (SSLIOSession) session.getAttribute(
139                     SSLIOSession.SESSION_KEY);
140             if (ssliosession == null) {
141                 onOutputReady(conn);
142             } else {
143                 try {
144                     if (!ssliosession.isInitialized()) {
145                         ssliosession.initialize();
146                     }
147                     if (ssliosession.isAppOutputReady()) {
148                         onOutputReady(conn);
149                     }
150                     ssliosession.outboundTransport();
151                 } catch (IOException ex) {
152                     onException(conn, ex);
153                     ssliosession.shutdown();
154                 }
155             }
156         } catch (RuntimeException ex) {
157             session.shutdown();
158             throw ex;
159         }
160     }
161 
162     public void timeout(final IOSession session) {
163         @SuppressWarnings("unchecked")
164         T conn = (T) session.getAttribute(IOEventDispatch.CONNECTION_KEY);
165         try {
166             SSLIOSession ssliosession = (SSLIOSession) session.getAttribute(
167                     SSLIOSession.SESSION_KEY);
168             ensureNotNull(conn);
169             onTimeout(conn);
170             if (ssliosession != null) {
171                 synchronized (ssliosession) {
172                     if (ssliosession.isOutboundDone() && !ssliosession.isInboundDone()) {
173                         // The session failed to terminate cleanly
174                         ssliosession.shutdown();
175                     }
176                 }
177             }
178         } catch (RuntimeException ex) {
179             session.shutdown();
180             throw ex;
181         }
182     }
183 
184 }