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