comparison src/org/eclipse/jetty/io/nio/ChannelEndPoint.java @ 802:3428c60d7cfc

replace jetty jars with source
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 07 Sep 2016 21:15:48 -0600
parents
children 8e9db0bbf4f9
comparison
equal deleted inserted replaced
801:6a21393191c1 802:3428c60d7cfc
1 //
2 // ========================================================================
3 // Copyright (c) 1995-2014 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.nio;
20
21 import java.io.IOException;
22 import java.net.InetSocketAddress;
23 import java.net.Socket;
24 import java.net.SocketException;
25 import java.nio.ByteBuffer;
26 import java.nio.channels.ByteChannel;
27 import java.nio.channels.GatheringByteChannel;
28 import java.nio.channels.SelectableChannel;
29 import java.nio.channels.SocketChannel;
30
31 import org.eclipse.jetty.io.Buffer;
32 import org.eclipse.jetty.io.EndPoint;
33 import org.eclipse.jetty.util.StringUtil;
34 import org.eclipse.jetty.util.log.Log;
35 import org.eclipse.jetty.util.log.Logger;
36
37 /**
38 * Channel End Point.
39 * <p>Holds the channel and socket for an NIO endpoint.
40 *
41 */
42 public class ChannelEndPoint implements EndPoint
43 {
44 private static final Logger LOG = Log.getLogger(ChannelEndPoint.class);
45
46 protected final ByteChannel _channel;
47 protected final ByteBuffer[] _gather2=new ByteBuffer[2];
48 protected final Socket _socket;
49 protected final InetSocketAddress _local;
50 protected final InetSocketAddress _remote;
51 protected volatile int _maxIdleTime;
52 private volatile boolean _ishut;
53 private volatile boolean _oshut;
54
55 public ChannelEndPoint(ByteChannel channel) throws IOException
56 {
57 super();
58 this._channel = channel;
59 _socket=(channel instanceof SocketChannel)?((SocketChannel)channel).socket():null;
60 if (_socket!=null)
61 {
62 _local=(InetSocketAddress)_socket.getLocalSocketAddress();
63 _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
64 _maxIdleTime=_socket.getSoTimeout();
65 }
66 else
67 {
68 _local=_remote=null;
69 }
70 }
71
72 protected ChannelEndPoint(ByteChannel channel, int maxIdleTime) throws IOException
73 {
74 this._channel = channel;
75 _maxIdleTime=maxIdleTime;
76 _socket=(channel instanceof SocketChannel)?((SocketChannel)channel).socket():null;
77 if (_socket!=null)
78 {
79 _local=(InetSocketAddress)_socket.getLocalSocketAddress();
80 _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
81 _socket.setSoTimeout(_maxIdleTime);
82 }
83 else
84 {
85 _local=_remote=null;
86 }
87 }
88
89 public boolean isBlocking()
90 {
91 return !(_channel instanceof SelectableChannel) || ((SelectableChannel)_channel).isBlocking();
92 }
93
94 public boolean blockReadable(long millisecs) throws IOException
95 {
96 return true;
97 }
98
99 public boolean blockWritable(long millisecs) throws IOException
100 {
101 return true;
102 }
103
104 /*
105 * @see org.eclipse.io.EndPoint#isOpen()
106 */
107 public boolean isOpen()
108 {
109 return _channel.isOpen();
110 }
111
112 /** Shutdown the channel Input.
113 * Cannot be overridden. To override, see {@link #shutdownInput()}
114 * @throws IOException
115 */
116 protected final void shutdownChannelInput() throws IOException
117 {
118 LOG.debug("ishut {}", this);
119 _ishut = true;
120 if (_channel.isOpen())
121 {
122 if (_socket != null)
123 {
124 try
125 {
126 if (!_socket.isInputShutdown())
127 {
128 _socket.shutdownInput();
129 }
130 }
131 catch (SocketException e)
132 {
133 LOG.debug(e.toString());
134 LOG.ignore(e);
135 }
136 finally
137 {
138 if (_oshut)
139 {
140 close();
141 }
142 }
143 }
144 }
145 }
146
147 /* (non-Javadoc)
148 * @see org.eclipse.io.EndPoint#close()
149 */
150 public void shutdownInput() throws IOException
151 {
152 shutdownChannelInput();
153 }
154
155 protected final void shutdownChannelOutput() throws IOException
156 {
157 LOG.debug("oshut {}",this);
158 _oshut = true;
159 if (_channel.isOpen())
160 {
161 if (_socket != null)
162 {
163 try
164 {
165 if (!_socket.isOutputShutdown())
166 {
167 _socket.shutdownOutput();
168 }
169 }
170 catch (SocketException e)
171 {
172 LOG.debug(e.toString());
173 LOG.ignore(e);
174 }
175 finally
176 {
177 if (_ishut)
178 {
179 close();
180 }
181 }
182 }
183 }
184 }
185
186 /* (non-Javadoc)
187 * @see org.eclipse.io.EndPoint#close()
188 */
189 public void shutdownOutput() throws IOException
190 {
191 shutdownChannelOutput();
192 }
193
194 public boolean isOutputShutdown()
195 {
196 return _oshut || !_channel.isOpen() || _socket != null && _socket.isOutputShutdown();
197 }
198
199 public boolean isInputShutdown()
200 {
201 return _ishut || !_channel.isOpen() || _socket != null && _socket.isInputShutdown();
202 }
203
204 /* (non-Javadoc)
205 * @see org.eclipse.io.EndPoint#close()
206 */
207 public void close() throws IOException
208 {
209 LOG.debug("close {}",this);
210 _channel.close();
211 }
212
213 /* (non-Javadoc)
214 * @see org.eclipse.io.EndPoint#fill(org.eclipse.io.Buffer)
215 */
216 public int fill(Buffer buffer) throws IOException
217 {
218 if (_ishut)
219 return -1;
220 Buffer buf = buffer.buffer();
221 int len=0;
222 if (buf instanceof NIOBuffer)
223 {
224 final NIOBuffer nbuf = (NIOBuffer)buf;
225 final ByteBuffer bbuf=nbuf.getByteBuffer();
226
227 //noinspection SynchronizationOnLocalVariableOrMethodParameter
228 try
229 {
230 synchronized(bbuf)
231 {
232 try
233 {
234 bbuf.position(buffer.putIndex());
235 len=_channel.read(bbuf);
236 }
237 finally
238 {
239 buffer.setPutIndex(bbuf.position());
240 bbuf.position(0);
241 }
242 }
243
244 if (len<0 && isOpen())
245 {
246 if (!isInputShutdown())
247 shutdownInput();
248 if (isOutputShutdown())
249 _channel.close();
250 }
251 }
252 catch (IOException x)
253 {
254 LOG.debug("Exception while filling", x);
255 try
256 {
257 if (_channel.isOpen())
258 _channel.close();
259 }
260 catch (Exception xx)
261 {
262 LOG.ignore(xx);
263 }
264
265 if (len>0)
266 throw x;
267 len=-1;
268 }
269 }
270 else
271 {
272 throw new IOException("Not Implemented");
273 }
274
275 return len;
276 }
277
278 /* (non-Javadoc)
279 * @see org.eclipse.io.EndPoint#flush(org.eclipse.io.Buffer)
280 */
281 public int flush(Buffer buffer) throws IOException
282 {
283 Buffer buf = buffer.buffer();
284 int len=0;
285 if (buf instanceof NIOBuffer)
286 {
287 final NIOBuffer nbuf = (NIOBuffer)buf;
288 final ByteBuffer bbuf=nbuf.getByteBuffer().asReadOnlyBuffer();
289 try
290 {
291 bbuf.position(buffer.getIndex());
292 bbuf.limit(buffer.putIndex());
293 len=_channel.write(bbuf);
294 }
295 finally
296 {
297 if (len>0)
298 buffer.skip(len);
299 }
300 }
301 else if (buf instanceof RandomAccessFileBuffer)
302 {
303 len = ((RandomAccessFileBuffer)buf).writeTo(_channel,buffer.getIndex(),buffer.length());
304 if (len>0)
305 buffer.skip(len);
306 }
307 else if (buffer.array()!=null)
308 {
309 ByteBuffer b = ByteBuffer.wrap(buffer.array(), buffer.getIndex(), buffer.length());
310 len=_channel.write(b);
311 if (len>0)
312 buffer.skip(len);
313 }
314 else
315 {
316 throw new IOException("Not Implemented");
317 }
318 return len;
319 }
320
321 /* (non-Javadoc)
322 * @see org.eclipse.io.EndPoint#flush(org.eclipse.io.Buffer, org.eclipse.io.Buffer, org.eclipse.io.Buffer)
323 */
324 public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException
325 {
326 int length=0;
327
328 Buffer buf0 = header==null?null:header.buffer();
329 Buffer buf1 = buffer==null?null:buffer.buffer();
330
331 if (_channel instanceof GatheringByteChannel &&
332 header!=null && header.length()!=0 && buf0 instanceof NIOBuffer &&
333 buffer!=null && buffer.length()!=0 && buf1 instanceof NIOBuffer)
334 {
335 length = gatheringFlush(header,((NIOBuffer)buf0).getByteBuffer(),buffer,((NIOBuffer)buf1).getByteBuffer());
336 }
337 else
338 {
339 // flush header
340 if (header!=null && header.length()>0)
341 length=flush(header);
342
343 // flush buffer
344 if ((header==null || header.length()==0) &&
345 buffer!=null && buffer.length()>0)
346 length+=flush(buffer);
347
348 // flush trailer
349 if ((header==null || header.length()==0) &&
350 (buffer==null || buffer.length()==0) &&
351 trailer!=null && trailer.length()>0)
352 length+=flush(trailer);
353 }
354
355 return length;
356 }
357
358 protected int gatheringFlush(Buffer header, ByteBuffer bbuf0, Buffer buffer, ByteBuffer bbuf1) throws IOException
359 {
360 int length;
361
362 synchronized(this)
363 {
364 // Adjust position indexs of buf0 and buf1
365 bbuf0=bbuf0.asReadOnlyBuffer();
366 bbuf0.position(header.getIndex());
367 bbuf0.limit(header.putIndex());
368 bbuf1=bbuf1.asReadOnlyBuffer();
369 bbuf1.position(buffer.getIndex());
370 bbuf1.limit(buffer.putIndex());
371
372 _gather2[0]=bbuf0;
373 _gather2[1]=bbuf1;
374
375 // do the gathering write.
376 length=(int)((GatheringByteChannel)_channel).write(_gather2);
377
378 int hl=header.length();
379 if (length>hl)
380 {
381 header.clear();
382 buffer.skip(length-hl);
383 }
384 else if (length>0)
385 {
386 header.skip(length);
387 }
388 }
389 return length;
390 }
391
392 /* ------------------------------------------------------------ */
393 /**
394 * @return Returns the channel.
395 */
396 public ByteChannel getChannel()
397 {
398 return _channel;
399 }
400
401
402 /* ------------------------------------------------------------ */
403 /*
404 * @see org.eclipse.io.EndPoint#getLocalAddr()
405 */
406 public String getLocalAddr()
407 {
408 if (_socket==null)
409 return null;
410 if (_local==null || _local.getAddress()==null || _local.getAddress().isAnyLocalAddress())
411 return StringUtil.ALL_INTERFACES;
412 return _local.getAddress().getHostAddress();
413 }
414
415 /* ------------------------------------------------------------ */
416 /*
417 * @see org.eclipse.io.EndPoint#getLocalHost()
418 */
419 public String getLocalHost()
420 {
421 if (_socket==null)
422 return null;
423 if (_local==null || _local.getAddress()==null || _local.getAddress().isAnyLocalAddress())
424 return StringUtil.ALL_INTERFACES;
425 return _local.getAddress().getCanonicalHostName();
426 }
427
428 /* ------------------------------------------------------------ */
429 /*
430 * @see org.eclipse.io.EndPoint#getLocalPort()
431 */
432 public int getLocalPort()
433 {
434 if (_socket==null)
435 return 0;
436 if (_local==null)
437 return -1;
438 return _local.getPort();
439 }
440
441 /* ------------------------------------------------------------ */
442 /*
443 * @see org.eclipse.io.EndPoint#getRemoteAddr()
444 */
445 public String getRemoteAddr()
446 {
447 if (_socket==null)
448 return null;
449 if (_remote==null)
450 return null;
451 return _remote.getAddress().getHostAddress();
452 }
453
454 /* ------------------------------------------------------------ */
455 /*
456 * @see org.eclipse.io.EndPoint#getRemoteHost()
457 */
458 public String getRemoteHost()
459 {
460 if (_socket==null)
461 return null;
462 if (_remote==null)
463 return null;
464 return _remote.getAddress().getCanonicalHostName();
465 }
466
467 /* ------------------------------------------------------------ */
468 /*
469 * @see org.eclipse.io.EndPoint#getRemotePort()
470 */
471 public int getRemotePort()
472 {
473 if (_socket==null)
474 return 0;
475 return _remote==null?-1:_remote.getPort();
476 }
477
478 /* ------------------------------------------------------------ */
479 /*
480 * @see org.eclipse.io.EndPoint#getConnection()
481 */
482 public Object getTransport()
483 {
484 return _channel;
485 }
486
487 /* ------------------------------------------------------------ */
488 public void flush()
489 throws IOException
490 {
491 }
492
493 /* ------------------------------------------------------------ */
494 public int getMaxIdleTime()
495 {
496 return _maxIdleTime;
497 }
498
499 /* ------------------------------------------------------------ */
500 /**
501 * @see org.eclipse.jetty.io.bio.StreamEndPoint#setMaxIdleTime(int)
502 */
503 public void setMaxIdleTime(int timeMs) throws IOException
504 {
505 if (_socket!=null && timeMs!=_maxIdleTime)
506 _socket.setSoTimeout(timeMs>0?timeMs:0);
507 _maxIdleTime=timeMs;
508 }
509 }