001/* 002 * ==================================================================== 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, 014 * software distributed under the License is distributed on an 015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 016 * KIND, either express or implied. See the License for the 017 * specific language governing permissions and limitations 018 * under the License. 019 * ==================================================================== 020 * 021 * This software consists of voluntary contributions made by many 022 * individuals on behalf of the Apache Software Foundation. For more 023 * information on the Apache Software Foundation, please see 024 * <http://www.apache.org/>. 025 * 026 */ 027 028package org.apache.http.impl.nio.reactor; 029 030import java.io.IOException; 031 032import org.apache.http.nio.reactor.IOEventDispatch; 033import org.apache.http.nio.reactor.IOSession; 034import org.apache.http.nio.reactor.ssl.SSLIOSession; 035import org.apache.http.util.Asserts; 036 037/** 038 * Abstract {@link IOEventDispatch} implementation that supports both plain (non-encrypted) 039 * and SSL encrypted HTTP connections. 040 * 041 * @param <T> the connection type. 042 * @since 4.2 043 */ 044public abstract class AbstractIODispatch<T> implements IOEventDispatch { 045 046 protected abstract T createConnection(IOSession session); 047 048 protected abstract void onConnected(T conn); 049 050 protected abstract void onClosed(T conn); 051 052 protected abstract void onException(T conn, IOException ex); 053 054 protected abstract void onInputReady(T conn); 055 056 protected abstract void onOutputReady(T conn); 057 058 protected abstract void onTimeout(T conn); 059 060 private void ensureNotNull(final T conn) { 061 Asserts.notNull(conn, "HTTP connection"); 062 } 063 064 @Override 065 public void connected(final IOSession session) { 066 @SuppressWarnings("unchecked") 067 T conn = (T) session.getAttribute(IOEventDispatch.CONNECTION_KEY); 068 try { 069 if (conn == null) { 070 conn = createConnection(session); 071 session.setAttribute(IOEventDispatch.CONNECTION_KEY, conn); 072 } 073 onConnected(conn); 074 final SSLIOSession ssliosession = (SSLIOSession) session.getAttribute( 075 SSLIOSession.SESSION_KEY); 076 if (ssliosession != null) { 077 try { 078 synchronized (ssliosession) { 079 if (!ssliosession.isInitialized()) { 080 ssliosession.initialize(); 081 } 082 } 083 } catch (final IOException ex) { 084 onException(conn, ex); 085 ssliosession.shutdown(); 086 } 087 } 088 } catch (final RuntimeException ex) { 089 session.shutdown(); 090 throw ex; 091 } 092 } 093 094 @Override 095 public void disconnected(final IOSession session) { 096 @SuppressWarnings("unchecked") 097 final 098 T conn = (T) session.getAttribute(IOEventDispatch.CONNECTION_KEY); 099 if (conn != null) { 100 onClosed(conn); 101 } 102 } 103 104 @Override 105 public void inputReady(final IOSession session) { 106 @SuppressWarnings("unchecked") 107 final 108 T conn = (T) session.getAttribute(IOEventDispatch.CONNECTION_KEY); 109 try { 110 ensureNotNull(conn); 111 final SSLIOSession ssliosession = (SSLIOSession) session.getAttribute( 112 SSLIOSession.SESSION_KEY); 113 if (ssliosession == null) { 114 onInputReady(conn); 115 } else { 116 try { 117 if (!ssliosession.isInitialized()) { 118 ssliosession.initialize(); 119 } 120 if (ssliosession.isAppInputReady()) { 121 onInputReady(conn); 122 } 123 ssliosession.inboundTransport(); 124 } catch (final IOException ex) { 125 onException(conn, ex); 126 ssliosession.shutdown(); 127 } 128 } 129 } catch (final RuntimeException ex) { 130 session.shutdown(); 131 throw ex; 132 } 133 } 134 135 @Override 136 public void outputReady(final IOSession session) { 137 @SuppressWarnings("unchecked") 138 final 139 T conn = (T) session.getAttribute(IOEventDispatch.CONNECTION_KEY); 140 try { 141 ensureNotNull(conn); 142 final SSLIOSession ssliosession = (SSLIOSession) session.getAttribute( 143 SSLIOSession.SESSION_KEY); 144 if (ssliosession == null) { 145 onOutputReady(conn); 146 } else { 147 try { 148 if (!ssliosession.isInitialized()) { 149 ssliosession.initialize(); 150 } 151 if (ssliosession.isAppOutputReady()) { 152 onOutputReady(conn); 153 } 154 ssliosession.outboundTransport(); 155 } catch (final IOException ex) { 156 onException(conn, ex); 157 ssliosession.shutdown(); 158 } 159 } 160 } catch (final RuntimeException ex) { 161 session.shutdown(); 162 throw ex; 163 } 164 } 165 166 @Override 167 public void timeout(final IOSession session) { 168 @SuppressWarnings("unchecked") 169 final 170 T conn = (T) session.getAttribute(IOEventDispatch.CONNECTION_KEY); 171 try { 172 final SSLIOSession ssliosession = (SSLIOSession) session.getAttribute( 173 SSLIOSession.SESSION_KEY); 174 ensureNotNull(conn); 175 onTimeout(conn); 176 if (ssliosession != null) { 177 synchronized (ssliosession) { 178 if (ssliosession.isOutboundDone() && !ssliosession.isInboundDone()) { 179 // The session failed to terminate cleanly 180 ssliosession.shutdown(); 181 } 182 } 183 } 184 } catch (final RuntimeException ex) { 185 session.shutdown(); 186 throw ex; 187 } 188 } 189 190}