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.ManagedObject;
42 import org.eclipse.jetty.util.annotation.Name;
43 import org.eclipse.jetty.util.ssl.SslContextFactory;
44 import org.eclipse.jetty.util.thread.Scheduler;
45
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 @ManagedObject("HTTP connector using NIO ByteChannels and Selectors")
79 public class ServerConnector extends AbstractNetworkConnector
80 {
81 private final SelectorManager _manager;
82 private volatile ServerSocketChannel _acceptChannel;
83 private volatile boolean _inheritChannel = false;
84 private volatile int _localPort = -1;
85 private volatile int _acceptQueueSize = 128;
86 private volatile boolean _reuseAddress = true;
87 private volatile int _lingerTime = -1;
88
89
90 public ServerConnector(
91 @Name("server") Server server)
92 {
93 this(server,null,null,null,0,0,new HttpConnectionFactory());
94 }
95
96 public ServerConnector(
97 @Name("server") Server server,
98 @Name("factories") ConnectionFactory... factories)
99 {
100 this(server,null,null,null,0,0,factories);
101 }
102
103 public ServerConnector(
104 @Name("server") Server server,
105 @Name("sslContextFactory") SslContextFactory sslContextFactory)
106 {
107 this(server,null,null,null,0,0,AbstractConnectionFactory.getFactories(sslContextFactory,new HttpConnectionFactory()));
108 }
109
110 public ServerConnector(
111 @Name("server") Server server,
112 @Name("sslContextFactory") SslContextFactory sslContextFactory,
113 @Name("factories") ConnectionFactory... factories)
114 {
115 this(server,null,null,null,0,0,AbstractConnectionFactory.getFactories(sslContextFactory,factories));
116 }
117
118
119
120
121
122
123
124
125
126 public ServerConnector(
127 @Name("server") Server server,
128 @Name("executor") Executor executor,
129 @Name("scheduler") Scheduler scheduler,
130 @Name("bufferPool") ByteBufferPool pool,
131 @Name("acceptors") int acceptors,
132 @Name("selectors") int selectors,
133 @Name("factories") ConnectionFactory... factories)
134 {
135 super(server,executor,scheduler,pool,acceptors,factories);
136 _manager = new ServerConnectorManager(getExecutor(), getScheduler(), selectors > 0 ? selectors : Runtime.getRuntime().availableProcessors());
137 addBean(_manager, true);
138 }
139
140 @Override
141 public boolean isOpen()
142 {
143 ServerSocketChannel channel = _acceptChannel;
144 return channel!=null && channel.isOpen();
145 }
146
147
148
149
150
151 public boolean isInheritChannel()
152 {
153 return _inheritChannel;
154 }
155
156
157
158
159
160
161
162
163
164
165
166
167 public void setInheritChannel(boolean inheritChannel)
168 {
169 _inheritChannel = inheritChannel;
170 }
171
172 @Override
173 public void open() throws IOException
174 {
175 if (_acceptChannel == null)
176 {
177 ServerSocketChannel serverChannel = null;
178 if (isInheritChannel())
179 {
180 Channel channel = System.inheritedChannel();
181 if (channel instanceof ServerSocketChannel)
182 serverChannel = (ServerSocketChannel)channel;
183 else
184 LOG.warn("Unable to use System.inheritedChannel() [{}]. Trying a new ServerSocketChannel at {}:{}", channel, getHost(), getPort());
185 }
186
187 if (serverChannel == null)
188 {
189 serverChannel = ServerSocketChannel.open();
190
191 InetSocketAddress bindAddress = getHost() == null ? new InetSocketAddress(getPort()) : new InetSocketAddress(getHost(), getPort());
192 serverChannel.socket().bind(bindAddress, getAcceptQueueSize());
193 serverChannel.socket().setReuseAddress(getReuseAddress());
194
195 _localPort = serverChannel.socket().getLocalPort();
196 if (_localPort <= 0)
197 throw new IOException("Server channel not bound");
198
199 addBean(serverChannel);
200 }
201
202 serverChannel.configureBlocking(true);
203 addBean(serverChannel);
204
205 _acceptChannel = serverChannel;
206 }
207 }
208
209 @Override
210 public <C> Future<C> shutdown(C c)
211 {
212
213 return super.shutdown(c);
214 }
215
216 @Override
217 public void close()
218 {
219 ServerSocketChannel serverChannel = _acceptChannel;
220 _acceptChannel = null;
221
222 if (serverChannel != null)
223 {
224 removeBean(serverChannel);
225
226
227 if (serverChannel.isOpen())
228 {
229 try
230 {
231 serverChannel.close();
232 }
233 catch (IOException e)
234 {
235 LOG.warn(e);
236 }
237 }
238 }
239
240 _localPort = -2;
241 }
242
243 @Override
244 public void accept(int acceptorID) throws IOException
245 {
246 ServerSocketChannel serverChannel = _acceptChannel;
247 if (serverChannel != null && serverChannel.isOpen())
248 {
249 SocketChannel channel = serverChannel.accept();
250 channel.configureBlocking(false);
251 Socket socket = channel.socket();
252 configure(socket);
253 _manager.accept(channel);
254 }
255 }
256
257 protected void configure(Socket socket)
258 {
259 try
260 {
261 socket.setTcpNoDelay(true);
262 if (_lingerTime >= 0)
263 socket.setSoLinger(true, _lingerTime / 1000);
264 else
265 socket.setSoLinger(false, 0);
266 }
267 catch (SocketException e)
268 {
269 LOG.ignore(e);
270 }
271 }
272
273 public SelectorManager getSelectorManager()
274 {
275 return _manager;
276 }
277
278 @Override
279 public Object getTransport()
280 {
281 return _acceptChannel;
282 }
283
284 @Override
285 public int getLocalPort()
286 {
287 return _localPort;
288 }
289
290 protected SelectChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException
291 {
292 return new SelectChannelEndPoint(channel, selectSet, key, getScheduler(), getIdleTimeout());
293 }
294
295
296
297
298
299 public int getLingerTime()
300 {
301 return _lingerTime;
302 }
303
304
305
306
307
308 public void setSoLingerTime(int lingerTime)
309 {
310 _lingerTime = lingerTime;
311 }
312
313
314
315
316 public int getAcceptQueueSize()
317 {
318 return _acceptQueueSize;
319 }
320
321
322
323
324 public void setAcceptQueueSize(int acceptQueueSize)
325 {
326 _acceptQueueSize = acceptQueueSize;
327 }
328
329
330
331
332
333 public boolean getReuseAddress()
334 {
335 return _reuseAddress;
336 }
337
338
339
340
341
342 public void setReuseAddress(boolean reuseAddress)
343 {
344 _reuseAddress = reuseAddress;
345 }
346
347 private final class ServerConnectorManager extends SelectorManager
348 {
349 private ServerConnectorManager(Executor executor, Scheduler scheduler, int selectors)
350 {
351 super(executor, scheduler, selectors);
352 }
353
354 @Override
355 protected SelectChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey selectionKey) throws IOException
356 {
357 return ServerConnector.this.newEndPoint(channel, selectSet, selectionKey);
358 }
359
360 @Override
361 public Connection newConnection(SocketChannel channel, EndPoint endpoint, Object attachment) throws IOException
362 {
363 return getDefaultConnectionFactory().newConnection(ServerConnector.this, endpoint);
364 }
365 }
366 }