1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.io.nio;
15
16 import java.io.IOException;
17 import java.net.InetSocketAddress;
18 import java.net.Socket;
19 import java.nio.ByteBuffer;
20 import java.nio.channels.ByteChannel;
21 import java.nio.channels.GatheringByteChannel;
22 import java.nio.channels.SelectableChannel;
23 import java.nio.channels.SocketChannel;
24
25 import org.eclipse.jetty.io.Buffer;
26 import org.eclipse.jetty.io.EndPoint;
27 import org.eclipse.jetty.util.StringUtil;
28 import org.eclipse.jetty.util.log.Log;
29
30
31
32
33
34
35
36
37 public class ChannelEndPoint implements EndPoint
38 {
39 protected final ByteChannel _channel;
40 protected final ByteBuffer[] _gather2=new ByteBuffer[2];
41 protected Socket _socket;
42 protected InetSocketAddress _local;
43 protected InetSocketAddress _remote;
44
45
46
47
48 public ChannelEndPoint(ByteChannel channel)
49 {
50 super();
51 this._channel = channel;
52 if (channel instanceof SocketChannel)
53 _socket=((SocketChannel)channel).socket();
54 }
55
56 public boolean isBlocking()
57 {
58 return !(_channel instanceof SelectableChannel) || ((SelectableChannel)_channel).isBlocking();
59 }
60
61 public boolean blockReadable(long millisecs) throws IOException
62 {
63 return true;
64 }
65
66 public boolean blockWritable(long millisecs) throws IOException
67 {
68 return true;
69 }
70
71
72
73
74 public boolean isOpen()
75 {
76 return _channel.isOpen();
77 }
78
79
80
81
82 public void close() throws IOException
83 {
84 if (_channel.isOpen())
85 {
86 try
87 {
88 if (_channel instanceof SocketChannel)
89 {
90
91 Socket socket= ((SocketChannel)_channel).socket();
92 if (!socket.isClosed()&&!socket.isOutputShutdown())
93 socket.shutdownOutput();
94 }
95 }
96 catch(IOException e)
97 {
98 Log.ignore(e);
99 }
100 catch(UnsupportedOperationException e)
101 {
102 Log.ignore(e);
103 }
104 finally
105 {
106 _channel.close();
107 }
108 }
109 }
110
111
112
113
114 public int fill(Buffer buffer) throws IOException
115 {
116 Buffer buf = buffer.buffer();
117 int len=0;
118 if (buf instanceof NIOBuffer)
119 {
120 final NIOBuffer nbuf = (NIOBuffer)buf;
121 final ByteBuffer bbuf=nbuf.getByteBuffer();
122
123 synchronized(bbuf)
124 {
125 try
126 {
127 bbuf.position(buffer.putIndex());
128 len=_channel.read(bbuf);
129 if (len<0)
130 _channel.close();
131 }
132 finally
133 {
134 buffer.setPutIndex(bbuf.position());
135 bbuf.position(0);
136 }
137 }
138 }
139 else
140 {
141 throw new IOException("Not Implemented");
142 }
143
144 return len;
145 }
146
147
148
149
150 public int flush(Buffer buffer) throws IOException
151 {
152 Buffer buf = buffer.buffer();
153 int len=0;
154 if (buf instanceof NIOBuffer)
155 {
156 final NIOBuffer nbuf = (NIOBuffer)buf;
157 final ByteBuffer bbuf=nbuf.getByteBuffer();
158
159
160 synchronized(bbuf)
161 {
162 try
163 {
164 bbuf.position(buffer.getIndex());
165 bbuf.limit(buffer.putIndex());
166 len=_channel.write(bbuf);
167 }
168 finally
169 {
170 if (len>0)
171 buffer.skip(len);
172 bbuf.position(0);
173 bbuf.limit(bbuf.capacity());
174 }
175 }
176 }
177 else if (buf instanceof RandomAccessFileBuffer)
178 {
179 len = buffer.length();
180 ((RandomAccessFileBuffer)buf).writeTo(_channel,buffer.getIndex(),buffer.length());
181 if (len>0)
182 buffer.skip(len);
183 }
184 else if (buffer.array()!=null)
185 {
186 ByteBuffer b = ByteBuffer.wrap(buffer.array(), buffer.getIndex(), buffer.length());
187 len=_channel.write(b);
188 if (len>0)
189 buffer.skip(len);
190 }
191 else
192 {
193 throw new IOException("Not Implemented");
194 }
195 return len;
196 }
197
198
199
200
201 public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException
202 {
203 int length=0;
204
205 Buffer buf0 = header==null?null:header.buffer();
206 Buffer buf1 = buffer==null?null:buffer.buffer();
207
208 if (_channel instanceof GatheringByteChannel &&
209 header!=null && header.length()!=0 && buf0 instanceof NIOBuffer &&
210 buffer!=null && buffer.length()!=0 && buf1 instanceof NIOBuffer)
211 {
212 final NIOBuffer nbuf0 = (NIOBuffer)buf0;
213 final ByteBuffer bbuf0=nbuf0.getByteBuffer();
214 final NIOBuffer nbuf1 = (NIOBuffer)buf1;
215 final ByteBuffer bbuf1=nbuf1.getByteBuffer();
216
217 synchronized(this)
218 {
219
220
221 synchronized(bbuf0)
222 {
223
224 synchronized(bbuf1)
225 {
226 try
227 {
228
229 bbuf0.position(header.getIndex());
230 bbuf0.limit(header.putIndex());
231 bbuf1.position(buffer.getIndex());
232 bbuf1.limit(buffer.putIndex());
233
234 _gather2[0]=bbuf0;
235 _gather2[1]=bbuf1;
236
237
238 length=(int)((GatheringByteChannel)_channel).write(_gather2);
239
240 int hl=header.length();
241 if (length>hl)
242 {
243 header.clear();
244 buffer.skip(length-hl);
245 }
246 else if (length>0)
247 {
248 header.skip(length);
249 }
250
251 }
252 finally
253 {
254
255 if (!header.isImmutable())
256 header.setGetIndex(bbuf0.position());
257 if (!buffer.isImmutable())
258 buffer.setGetIndex(bbuf1.position());
259
260 bbuf0.position(0);
261 bbuf1.position(0);
262 bbuf0.limit(bbuf0.capacity());
263 bbuf1.limit(bbuf1.capacity());
264 }
265 }
266 }
267 }
268 }
269 else
270 {
271
272
273
274 if (header!=null && header.length()>0)
275 length=flush(header);
276
277
278 if ((header==null || header.length()==0) &&
279 buffer!=null && buffer.length()>0)
280 length+=flush(buffer);
281
282
283 if ((header==null || header.length()==0) &&
284 (buffer==null || buffer.length()==0) &&
285 trailer!=null && trailer.length()>0)
286 length+=flush(trailer);
287 }
288
289 return length;
290 }
291
292
293
294
295 public ByteChannel getChannel()
296 {
297 return _channel;
298 }
299
300
301
302
303
304
305 public String getLocalAddr()
306 {
307 if (_socket==null)
308 return null;
309
310 if (_local==null)
311 _local=(InetSocketAddress)_socket.getLocalSocketAddress();
312
313 if (_local==null || _local.getAddress()==null || _local.getAddress().isAnyLocalAddress())
314 return StringUtil.ALL_INTERFACES;
315
316 return _local.getAddress().getHostAddress();
317 }
318
319
320
321
322
323 public String getLocalHost()
324 {
325 if (_socket==null)
326 return null;
327
328 if (_local==null)
329 _local=(InetSocketAddress)_socket.getLocalSocketAddress();
330
331 if (_local==null || _local.getAddress()==null || _local.getAddress().isAnyLocalAddress())
332 return StringUtil.ALL_INTERFACES;
333
334 return _local.getAddress().getCanonicalHostName();
335 }
336
337
338
339
340
341 public int getLocalPort()
342 {
343 if (_socket==null)
344 return 0;
345
346 if (_local==null)
347 _local=(InetSocketAddress)_socket.getLocalSocketAddress();
348 if (_local==null)
349 return -1;
350 return _local.getPort();
351 }
352
353
354
355
356
357 public String getRemoteAddr()
358 {
359 if (_socket==null)
360 return null;
361
362 if (_remote==null)
363 _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
364
365 if (_remote==null)
366 return null;
367 return _remote.getAddress().getHostAddress();
368 }
369
370
371
372
373
374 public String getRemoteHost()
375 {
376 if (_socket==null)
377 return null;
378
379 if (_remote==null)
380 _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
381
382 if (_remote==null)
383 return null;
384 return _remote.getAddress().getCanonicalHostName();
385 }
386
387
388
389
390
391 public int getRemotePort()
392 {
393 if (_socket==null)
394 return 0;
395
396 if (_remote==null)
397 _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
398
399 return _remote==null?-1:_remote.getPort();
400 }
401
402
403
404
405
406 public Object getTransport()
407 {
408 return _channel;
409 }
410
411
412 public void flush()
413 throws IOException
414 {
415 }
416
417
418 public boolean isBufferingInput()
419 {
420 return false;
421 }
422
423
424 public boolean isBufferingOutput()
425 {
426 return false;
427 }
428
429
430 public boolean isBufferred()
431 {
432 return false;
433 }
434 }