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