1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.server;
20
21 import java.io.IOException;
22 import java.net.InetSocketAddress;
23 import java.net.ServerSocket;
24 import java.net.Socket;
25 import java.net.SocketException;
26 import java.nio.channels.Channel;
27 import java.nio.channels.SelectionKey;
28 import java.nio.channels.Selector;
29 import java.nio.channels.ServerSocketChannel;
30 import java.nio.channels.SocketChannel;
31 import java.util.concurrent.Executor;
32 import java.util.concurrent.Future;
33
34 import org.eclipse.jetty.io.ByteBufferPool;
35 import org.eclipse.jetty.io.Connection;
36 import org.eclipse.jetty.io.EndPoint;
37 import org.eclipse.jetty.io.SelectChannelEndPoint;
38 import org.eclipse.jetty.io.SelectorManager;
39 import org.eclipse.jetty.io.SelectorManager.ManagedSelector;
40 import org.eclipse.jetty.util.Callback;
41 import org.eclipse.jetty.util.annotation.ManagedAttribute;
42 import org.eclipse.jetty.util.annotation.ManagedObject;
43 import org.eclipse.jetty.util.annotation.Name;
44 import org.eclipse.jetty.util.ssl.SslContextFactory;
45 import org.eclipse.jetty.util.thread.Scheduler;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 @ManagedObject("HTTP connector using NIO ByteChannels and Selectors")
80 public class ServerConnector extends AbstractNetworkConnector
81 {
82 private final SelectorManager _manager;
83 private volatile ServerSocketChannel _acceptChannel;
84 private volatile boolean _inheritChannel = false;
85 private volatile int _localPort = -1;
86 private volatile int _acceptQueueSize = 0;
87 private volatile boolean _reuseAddress = true;
88 private volatile int _lingerTime = -1;
89
90
91
92
93
94
95
96 public ServerConnector(
97 @Name("server") Server server)
98 {
99 this(server,null,null,null,-1,-1,new HttpConnectionFactory());
100 }
101
102
103
104
105
106
107
108
109
110
111
112 public ServerConnector(
113 @Name("server") Server server,
114 @Name("acceptors") int acceptors,
115 @Name("selectors") int selectors)
116 {
117 this(server,null,null,null,acceptors,selectors,new HttpConnectionFactory());
118 }
119
120
121
122
123
124
125
126 public ServerConnector(
127 @Name("server") Server server,
128 @Name("factories") ConnectionFactory... factories)
129 {
130 this(server,null,null,null,-1,-1,factories);
131 }
132
133
134
135
136
137
138
139
140 public ServerConnector(
141 @Name("server") Server server,
142 @Name("sslContextFactory") SslContextFactory sslContextFactory)
143 {
144 this(server,null,null,null,-1,-1,AbstractConnectionFactory.getFactories(sslContextFactory,new HttpConnectionFactory()));
145 }
146
147
148
149
150
151
152
153
154
155
156
157
158
159 public ServerConnector(
160 @Name("server") Server server,
161 @Name("acceptors") int acceptors,
162 @Name("selectors") int selectors,
163 @Name("sslContextFactory") SslContextFactory sslContextFactory)
164 {
165 this(server,null,null,null,acceptors,selectors,AbstractConnectionFactory.getFactories(sslContextFactory,new HttpConnectionFactory()));
166 }
167
168
169
170
171
172
173
174
175 public ServerConnector(
176 @Name("server") Server server,
177 @Name("sslContextFactory") SslContextFactory sslContextFactory,
178 @Name("factories") ConnectionFactory... factories)
179 {
180 this(server,null,null,null,-1,-1,AbstractConnectionFactory.getFactories(sslContextFactory,factories));
181 }
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201 public ServerConnector(
202 @Name("server") Server server,
203 @Name("executor") Executor executor,
204 @Name("scheduler") Scheduler scheduler,
205 @Name("bufferPool") ByteBufferPool bufferPool,
206 @Name("acceptors") int acceptors,
207 @Name("selectors") int selectors,
208 @Name("factories") ConnectionFactory... factories)
209 {
210 super(server,executor,scheduler,bufferPool,acceptors,factories);
211 _manager = new ServerConnectorManager(getExecutor(), getScheduler(), selectors >= 0 ? selectors : Runtime.getRuntime().availableProcessors());
212 addBean(_manager, true);
213 }
214
215 @Override
216 protected void doStart() throws Exception
217 {
218 super.doStart();
219
220 if (getAcceptors()==0)
221 {
222 _acceptChannel.configureBlocking(false);
223 _manager.acceptor(_acceptChannel);
224 }
225 }
226
227 @Override
228 public boolean isOpen()
229 {
230 ServerSocketChannel channel = _acceptChannel;
231 return channel!=null && channel.isOpen();
232 }
233
234
235
236
237
238 public boolean isInheritChannel()
239 {
240 return _inheritChannel;
241 }
242
243
244
245
246
247
248
249
250
251
252
253
254 public void setInheritChannel(boolean inheritChannel)
255 {
256 _inheritChannel = inheritChannel;
257 }
258
259 @Override
260 public void open() throws IOException
261 {
262 if (_acceptChannel == null)
263 {
264 ServerSocketChannel serverChannel = null;
265 if (isInheritChannel())
266 {
267 Channel channel = System.inheritedChannel();
268 if (channel instanceof ServerSocketChannel)
269 serverChannel = (ServerSocketChannel)channel;
270 else
271 LOG.warn("Unable to use System.inheritedChannel() [{}]. Trying a new ServerSocketChannel at {}:{}", channel, getHost(), getPort());
272 }
273
274 if (serverChannel == null)
275 {
276 serverChannel = ServerSocketChannel.open();
277
278 InetSocketAddress bindAddress = getHost() == null ? new InetSocketAddress(getPort()) : new InetSocketAddress(getHost(), getPort());
279 serverChannel.socket().bind(bindAddress, getAcceptQueueSize());
280 serverChannel.socket().setReuseAddress(getReuseAddress());
281
282 _localPort = serverChannel.socket().getLocalPort();
283 if (_localPort <= 0)
284 throw new IOException("Server channel not bound");
285
286 addBean(serverChannel);
287 }
288
289 serverChannel.configureBlocking(true);
290 addBean(serverChannel);
291
292 _acceptChannel = serverChannel;
293 }
294 }
295
296 @Override
297 public Future<Void> shutdown()
298 {
299
300 return super.shutdown();
301 }
302
303 @Override
304 public void close()
305 {
306 ServerSocketChannel serverChannel = _acceptChannel;
307 _acceptChannel = null;
308
309 if (serverChannel != null)
310 {
311 removeBean(serverChannel);
312
313
314 if (serverChannel.isOpen())
315 {
316 try
317 {
318 serverChannel.close();
319 }
320 catch (IOException e)
321 {
322 LOG.warn(e);
323 }
324 }
325 }
326
327 _localPort = -2;
328 }
329
330 @Override
331 public void accept(int acceptorID) throws IOException
332 {
333 ServerSocketChannel serverChannel = _acceptChannel;
334 if (serverChannel != null && serverChannel.isOpen())
335 {
336 SocketChannel channel = serverChannel.accept();
337 accepted(channel);
338 }
339 }
340
341 private void accepted(SocketChannel channel) throws IOException
342 {
343 channel.configureBlocking(false);
344 Socket socket = channel.socket();
345 configure(socket);
346 _manager.accept(channel);
347 }
348
349 protected void configure(Socket socket)
350 {
351 try
352 {
353 socket.setTcpNoDelay(true);
354 if (_lingerTime >= 0)
355 socket.setSoLinger(true, _lingerTime / 1000);
356 else
357 socket.setSoLinger(false, 0);
358 }
359 catch (SocketException e)
360 {
361 LOG.ignore(e);
362 }
363 }
364
365 public SelectorManager getSelectorManager()
366 {
367 return _manager;
368 }
369
370 @Override
371 public Object getTransport()
372 {
373 return _acceptChannel;
374 }
375
376 @Override
377 @ManagedAttribute("local port")
378 public int getLocalPort()
379 {
380 return _localPort;
381 }
382
383 protected SelectChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException
384 {
385 return new SelectChannelEndPoint(channel, selectSet, key, getScheduler(), getIdleTimeout());
386 }
387
388
389
390
391
392 @ManagedAttribute("TCP/IP solinger time or -1 to disable")
393 public int getSoLingerTime()
394 {
395 return _lingerTime;
396 }
397
398
399
400
401
402 public void setSoLingerTime(int lingerTime)
403 {
404 _lingerTime = lingerTime;
405 }
406
407
408
409
410 @ManagedAttribute("Accept Queue size")
411 public int getAcceptQueueSize()
412 {
413 return _acceptQueueSize;
414 }
415
416
417
418
419 public void setAcceptQueueSize(int acceptQueueSize)
420 {
421 _acceptQueueSize = acceptQueueSize;
422 }
423
424
425
426
427
428 public boolean getReuseAddress()
429 {
430 return _reuseAddress;
431 }
432
433
434
435
436
437 public void setReuseAddress(boolean reuseAddress)
438 {
439 _reuseAddress = reuseAddress;
440 }
441
442 private final class ServerConnectorManager extends SelectorManager
443 {
444 private ServerConnectorManager(Executor executor, Scheduler scheduler, int selectors)
445 {
446 super(executor, scheduler, selectors);
447 }
448
449 @Override
450 protected void accepted(SocketChannel channel) throws IOException
451 {
452 ServerConnector.this.accepted(channel);
453 }
454
455 @Override
456 protected SelectChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey selectionKey) throws IOException
457 {
458 return ServerConnector.this.newEndPoint(channel, selectSet, selectionKey);
459 }
460
461 @Override
462 public Connection newConnection(SocketChannel channel, EndPoint endpoint, Object attachment) throws IOException
463 {
464 return getDefaultConnectionFactory().newConnection(ServerConnector.this, endpoint);
465 }
466
467 @Override
468 protected void endPointOpened(EndPoint endpoint)
469 {
470 super.endPointOpened(endpoint);
471 onEndPointOpened(endpoint);
472 }
473
474 @Override
475 protected void endPointClosed(EndPoint endpoint)
476 {
477 onEndPointClosed(endpoint);
478 super.endPointClosed(endpoint);
479 }
480
481
482 }
483 }