1 // 2 // ======================================================================== 3 // Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. 4 // ------------------------------------------------------------------------ 5 // All rights reserved. This program and the accompanying materials 6 // are made available under the terms of the Eclipse Public License v1.0 7 // and Apache License v2.0 which accompanies this distribution. 8 // 9 // The Eclipse Public License is available at 10 // http://www.eclipse.org/legal/epl-v10.html 11 // 12 // The Apache License v2.0 is available at 13 // http://www.opensource.org/licenses/apache2.0.php 14 // 15 // You may elect to redistribute this code under either of these licenses. 16 // ======================================================================== 17 // 18 19 package org.eclipse.jetty.io; 20 21 import java.io.Closeable; 22 import java.io.IOException; 23 import java.net.InetSocketAddress; 24 import java.nio.ByteBuffer; 25 import java.nio.channels.ReadPendingException; 26 import java.nio.channels.WritePendingException; 27 28 import org.eclipse.jetty.util.Callback; 29 import org.eclipse.jetty.util.FutureCallback; 30 import org.eclipse.jetty.util.IteratingCallback; 31 32 /** 33 * 34 * A transport EndPoint 35 * 36 * <h3>Asynchronous Methods</h3> 37 * <p>The asynchronous scheduling methods of {@link EndPoint} 38 * has been influenced by NIO.2 Futures and Completion 39 * handlers, but does not use those actual interfaces because they have 40 * some inefficiencies.</p> 41 * <p>This class will frequently be used in conjunction with some of the utility 42 * implementations of {@link Callback}, such as {@link FutureCallback} and 43 * {@link IteratingCallback}. Examples are:</p> 44 * 45 * <h3>Blocking Read</h3> 46 * <p>A FutureCallback can be used to block until an endpoint is ready to be filled 47 * from:</p> 48 * <blockquote><pre> 49 * FutureCallback<String> future = new FutureCallback<>(); 50 * endpoint.fillInterested("ContextObj",future); 51 * ... 52 * String context = future.get(); // This blocks 53 * int filled=endpoint.fill(mybuffer); 54 * </pre></blockquote> 55 * 56 * <h3>Dispatched Read</h3> 57 * <p>By using a different callback, the read can be done asynchronously in its own dispatched thread:</p> 58 * <blockquote><pre> 59 * endpoint.fillInterested("ContextObj",new ExecutorCallback<String>(executor) 60 * { 61 * public void onCompleted(String context) 62 * { 63 * int filled=endpoint.fill(mybuffer); 64 * ... 65 * } 66 * public void onFailed(String context,Throwable cause) {...} 67 * }); 68 * </pre></blockquote> 69 * <p>The executor callback can also be customized to not dispatch in some circumstances when 70 * it knows it can use the callback thread and does not need to dispatch.</p> 71 * 72 * <h3>Blocking Write</h3> 73 * <p>The write contract is that the callback complete is not called until all data has been 74 * written or there is a failure. For blocking this looks like:</p> 75 * <blockquote><pre> 76 * FutureCallback<String> future = new FutureCallback<>(); 77 * endpoint.write("ContextObj",future,headerBuffer,contentBuffer); 78 * String context = future.get(); // This blocks 79 * </pre></blockquote> 80 * 81 * <h3>Dispatched Write</h3> 82 * <p>Note also that multiple buffers may be passed in write so that gather writes 83 * can be done:</p> 84 * <blockquote><pre> 85 * endpoint.write("ContextObj",new ExecutorCallback<String>(executor) 86 * { 87 * public void onCompleted(String context) 88 * { 89 * int filled=endpoint.fill(mybuffer); 90 * ... 91 * } 92 * public void onFailed(String context,Throwable cause) {...} 93 * },headerBuffer,contentBuffer); 94 * </pre></blockquote> 95 */ 96 public interface EndPoint extends Closeable 97 { 98 /* ------------------------------------------------------------ */ 99 /** 100 * @return The local Inet address to which this <code>EndPoint</code> is bound, or <code>null</code> 101 * if this <code>EndPoint</code> does not represent a network connection. 102 */ 103 InetSocketAddress getLocalAddress(); 104 105 /* ------------------------------------------------------------ */ 106 /** 107 * @return The remote Inet address to which this <code>EndPoint</code> is bound, or <code>null</code> 108 * if this <code>EndPoint</code> does not represent a network connection. 109 */ 110 InetSocketAddress getRemoteAddress(); 111 112 /* ------------------------------------------------------------ */ 113 boolean isOpen(); 114 115 /* ------------------------------------------------------------ */ 116 long getCreatedTimeStamp(); 117 118 /* ------------------------------------------------------------ */ 119 /** Shutdown the output. 120 * <p>This call indicates that no more data will be sent on this endpoint that 121 * that the remote end should read an EOF once all previously sent data has been 122 * consumed. Shutdown may be done either at the TCP/IP level, as a protocol exchange (Eg 123 * TLS close handshake) or both. 124 * <p> 125 * If the endpoint has {@link #isInputShutdown()} true, then this call has the same effect 126 * as {@link #close()}. 127 */ 128 void shutdownOutput(); 129 130 /* ------------------------------------------------------------ */ 131 /** Test if output is shutdown. 132 * The output is shutdown by a call to {@link #shutdownOutput()} 133 * or {@link #close()}. 134 * @return true if the output is shutdown or the endpoint is closed. 135 */ 136 boolean isOutputShutdown(); 137 138 /* ------------------------------------------------------------ */ 139 /** Test if the input is shutdown. 140 * The input is shutdown if an EOF has been read while doing 141 * a {@link #fill(ByteBuffer)}. Once the input is shutdown, all calls to 142 * {@link #fill(ByteBuffer)} will return -1, until such time as the 143 * end point is close, when they will return {@link EofException}. 144 * @return True if the input is shutdown or the endpoint is closed. 145 */ 146 boolean isInputShutdown(); 147 148 /** 149 * Close any backing stream associated with the endpoint 150 */ 151 @Override 152 void close(); 153 154 /** 155 * Fill the passed buffer with data from this endpoint. The bytes are appended to any 156 * data already in the buffer by writing from the buffers limit up to it's capacity. 157 * The limit is updated to include the filled bytes. 158 * 159 * @param buffer The buffer to fill. The position and limit are modified during the fill. After the 160 * operation, the position is unchanged and the limit is increased to reflect the new data filled. 161 * @return an <code>int</code> value indicating the number of bytes 162 * filled or -1 if EOF is read or the input is shutdown. 163 * @throws IOException if the endpoint is closed. 164 */ 165 int fill(ByteBuffer buffer) throws IOException; 166 167 168 /** 169 * Flush data from the passed header/buffer to this endpoint. As many bytes as can be consumed 170 * are taken from the header/buffer position up until the buffer limit. The header/buffers position 171 * is updated to indicate how many bytes have been consumed. 172 * @param buffer the buffers to flush 173 * @return True IFF all the buffers have been consumed and the endpoint has flushed the data to its 174 * destination (ie is not buffering any data). 175 * @throws IOException If the endpoint is closed or output is shutdown. 176 */ 177 boolean flush(ByteBuffer... buffer) throws IOException; 178 179 /* ------------------------------------------------------------ */ 180 /** 181 * @return The underlying transport object (socket, channel, etc.) 182 */ 183 Object getTransport(); 184 185 /* ------------------------------------------------------------ */ 186 /** Get the max idle time in ms. 187 * <p>The max idle time is the time the endpoint can be idle before 188 * extraordinary handling takes place. 189 * @return the max idle time in ms or if ms <= 0 implies an infinite timeout 190 */ 191 long getIdleTimeout(); 192 193 /* ------------------------------------------------------------ */ 194 /** Set the idle timeout. 195 * @param idleTimeout the idle timeout in MS. Timeout <= 0 implies an infinite timeout 196 */ 197 void setIdleTimeout(long idleTimeout); 198 199 200 /** 201 * <p>Requests callback methods to be invoked when a call to {@link #fill(ByteBuffer)} would return data or EOF.</p> 202 * 203 * @param callback the callback to call when an error occurs or we are readable. 204 * @throws ReadPendingException if another read operation is concurrent. 205 */ 206 void fillInterested(Callback callback) throws ReadPendingException; 207 208 /** 209 * @return whether {@link #fillInterested(Callback)} has been called, but {@link #fill(ByteBuffer)} has not yet 210 * been called 211 */ 212 boolean isFillInterested(); 213 214 /** 215 * <p>Writes the given buffers via {@link #flush(ByteBuffer...)} and invokes callback methods when either 216 * all the data has been flushed or an error occurs.</p> 217 * 218 * @param callback the callback to call when an error occurs or the write completed. 219 * @param buffers one or more {@link ByteBuffer}s that will be flushed. 220 * @throws WritePendingException if another write operation is concurrent. 221 */ 222 void write(Callback callback, ByteBuffer... buffers) throws WritePendingException; 223 224 /** 225 * @return the {@link Connection} associated with this {@link EndPoint} 226 * @see #setConnection(Connection) 227 */ 228 Connection getConnection(); 229 230 /** 231 * @param connection the {@link Connection} associated with this {@link EndPoint} 232 * @see #getConnection() 233 * @see #upgrade(Connection) 234 */ 235 void setConnection(Connection connection); 236 237 /** 238 * <p>Callback method invoked when this {@link EndPoint} is opened.</p> 239 * @see #onClose() 240 */ 241 void onOpen(); 242 243 /** 244 * <p>Callback method invoked when this {@link EndPoint} is close.</p> 245 * @see #onOpen() 246 */ 247 void onClose(); 248 249 /** Is the endpoint optimized for DirectBuffer usage 250 * @return True if direct buffers can be used optimally. 251 */ 252 boolean isOptimizedForDirectBuffers(); 253 254 255 /** Upgrade connections. 256 * Close the old connection, update the endpoint and open the new connection. 257 * If the oldConnection is an instance of {@link Connection.UpgradeFrom} then 258 * a prefilled buffer is requested and passed to the newConnection if it is an instance 259 * of {@link Connection.UpgradeTo} 260 * @param newConnection The connection to upgrade to 261 */ 262 public void upgrade(Connection newConnection); 263 }