1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.server;
15
16 import java.io.IOException;
17 import java.net.InetSocketAddress;
18 import java.util.Enumeration;
19
20 import javax.servlet.ServletException;
21 import javax.servlet.http.HttpServletRequest;
22 import javax.servlet.http.HttpServletResponse;
23
24 import org.eclipse.jetty.http.HttpGenerator;
25 import org.eclipse.jetty.http.HttpURI;
26 import org.eclipse.jetty.server.handler.HandlerWrapper;
27 import org.eclipse.jetty.server.nio.SelectChannelConnector;
28 import org.eclipse.jetty.util.Attributes;
29 import org.eclipse.jetty.util.AttributesMap;
30 import org.eclipse.jetty.util.LazyList;
31 import org.eclipse.jetty.util.MultiException;
32 import org.eclipse.jetty.util.TypeUtil;
33 import org.eclipse.jetty.util.URIUtil;
34 import org.eclipse.jetty.util.component.Container;
35 import org.eclipse.jetty.util.component.Destroyable;
36 import org.eclipse.jetty.util.component.LifeCycle;
37 import org.eclipse.jetty.util.log.Log;
38 import org.eclipse.jetty.util.thread.QueuedThreadPool;
39 import org.eclipse.jetty.util.thread.ShutdownThread;
40 import org.eclipse.jetty.util.thread.ThreadPool;
41
42
43
44
45
46
47
48
49
50
51 public class Server extends HandlerWrapper implements Attributes
52 {
53 private static final String _version;
54 static
55 {
56 if (Server.class.getPackage()!=null && Server.class.getPackage().getImplementationVersion()!=null)
57 _version=Server.class.getPackage().getImplementationVersion();
58 else
59 _version=System.getProperty("jetty.version","7.x.y-SNAPSHOT");
60 }
61 private final Container _container=new Container();
62 private final AttributesMap _attributes = new AttributesMap();
63 private ThreadPool _threadPool;
64 private Connector[] _connectors;
65 private SessionIdManager _sessionIdManager;
66 private boolean _sendServerVersion = true;
67 private boolean _sendDateHeader = false;
68 private int _graceful=0;
69 private boolean _stopAtShutdown;
70 private int _maxCookieVersion=1;
71 private boolean _dumpAfterStart=false;
72 private boolean _dumpBeforeStop=false;
73
74
75
76 public Server()
77 {
78 setServer(this);
79 }
80
81
82
83
84
85 public Server(int port)
86 {
87 setServer(this);
88
89 Connector connector=new SelectChannelConnector();
90 connector.setPort(port);
91 setConnectors(new Connector[]{connector});
92 }
93
94
95
96
97
98 public Server(InetSocketAddress addr)
99 {
100 setServer(this);
101
102 Connector connector=new SelectChannelConnector();
103 connector.setHost(addr.getHostName());
104 connector.setPort(addr.getPort());
105 setConnectors(new Connector[]{connector});
106 }
107
108
109
110 public static String getVersion()
111 {
112 return _version;
113 }
114
115
116
117
118
119 public Container getContainer()
120 {
121 return _container;
122 }
123
124
125 public boolean getStopAtShutdown()
126 {
127 return _stopAtShutdown;
128 }
129
130
131 public void setStopAtShutdown(boolean stop)
132 {
133 _stopAtShutdown=stop;
134 if (stop)
135 ShutdownThread.register(this);
136 else
137 ShutdownThread.deregister(this);
138 }
139
140
141
142
143
144 public Connector[] getConnectors()
145 {
146 return _connectors;
147 }
148
149
150 public void addConnector(Connector connector)
151 {
152 setConnectors((Connector[])LazyList.addToArray(getConnectors(), connector, Connector.class));
153 }
154
155
156
157
158
159
160
161 public void removeConnector(Connector connector) {
162 setConnectors((Connector[])LazyList.removeFromArray (getConnectors(), connector));
163 }
164
165
166
167
168
169
170 public void setConnectors(Connector[] connectors)
171 {
172 if (connectors!=null)
173 {
174 for (int i=0;i<connectors.length;i++)
175 connectors[i].setServer(this);
176 }
177
178 _container.update(this, _connectors, connectors, "connector");
179 _connectors = connectors;
180 }
181
182
183
184
185
186 public ThreadPool getThreadPool()
187 {
188 return _threadPool;
189 }
190
191
192
193
194
195 public void setThreadPool(ThreadPool threadPool)
196 {
197 if (_threadPool!=null)
198 removeBean(_threadPool);
199 _container.update(this, _threadPool, threadPool, "threadpool",false);
200 _threadPool = threadPool;
201 if (_threadPool!=null)
202 addBean(_threadPool);
203 }
204
205
206
207
208 public boolean isDumpAfterStart()
209 {
210 return _dumpAfterStart;
211 }
212
213
214
215
216 public void setDumpAfterStart(boolean dumpAfterStart)
217 {
218 _dumpAfterStart = dumpAfterStart;
219 }
220
221
222
223
224 public boolean isDumpBeforeStop()
225 {
226 return _dumpBeforeStop;
227 }
228
229
230
231
232 public void setDumpBeforeStop(boolean dumpBeforeStop)
233 {
234 _dumpBeforeStop = dumpBeforeStop;
235 }
236
237
238 @Override
239 protected void doStart() throws Exception
240 {
241 if (getStopAtShutdown())
242 ShutdownThread.register(this);
243
244 Log.info("jetty-"+_version);
245 HttpGenerator.setServerVersion(_version);
246 MultiException mex=new MultiException();
247
248 if (_threadPool==null)
249 setThreadPool(new QueuedThreadPool());
250
251 try
252 {
253 super.doStart();
254 }
255 catch(Throwable e)
256 {
257 Log.warn("Error starting handlers",e);
258 }
259
260 if (_connectors!=null)
261 {
262 for (int i=0;i<_connectors.length;i++)
263 {
264 try{_connectors[i].start();}
265 catch(Throwable e)
266 {
267 mex.add(e);
268 }
269 }
270 }
271
272 if (isDumpAfterStart())
273 dumpStdErr();
274
275 mex.ifExceptionThrow();
276 }
277
278
279 @Override
280 protected void doStop() throws Exception
281 {
282 if (isDumpBeforeStop())
283 dumpStdErr();
284
285 MultiException mex=new MultiException();
286
287 if (_graceful>0)
288 {
289 if (_connectors!=null)
290 {
291 for (int i=_connectors.length;i-->0;)
292 {
293 Log.info("Graceful shutdown {}",_connectors[i]);
294 try{_connectors[i].close();}catch(Throwable e){mex.add(e);}
295 }
296 }
297
298 Handler[] contexts = getChildHandlersByClass(Graceful.class);
299 for (int c=0;c<contexts.length;c++)
300 {
301 Graceful context=(Graceful)contexts[c];
302 Log.info("Graceful shutdown {}",context);
303 context.setShutdown(true);
304 }
305 Thread.sleep(_graceful);
306 }
307
308 if (_connectors!=null)
309 {
310 for (int i=_connectors.length;i-->0;)
311 try{_connectors[i].stop();}catch(Throwable e){mex.add(e);}
312 }
313
314 try {super.doStop(); } catch(Throwable e) { mex.add(e);}
315
316 mex.ifExceptionThrow();
317
318 if (getStopAtShutdown())
319 ShutdownThread.deregister(this);
320 }
321
322
323
324
325
326
327
328 public void handle(HttpConnection connection) throws IOException, ServletException
329 {
330 final String target=connection.getRequest().getPathInfo();
331 final Request request=connection.getRequest();
332 final Response response=connection.getResponse();
333
334 if (Log.isDebugEnabled())
335 {
336 Log.debug("REQUEST "+target+" on "+connection);
337 handle(target, request, request, response);
338 Log.debug("RESPONSE "+target+" "+connection.getResponse().getStatus());
339 }
340 else
341 handle(target, request, request, response);
342 }
343
344
345
346
347
348
349
350 public void handleAsync(HttpConnection connection) throws IOException, ServletException
351 {
352 final AsyncContinuation async = connection.getRequest().getAsyncContinuation();
353 final AsyncContinuation.AsyncEventState state = async.getAsyncEventState();
354
355 final Request baseRequest=connection.getRequest();
356 final String path=state.getPath();
357
358 if (path!=null)
359 {
360
361 baseRequest.setAttribute(AsyncContext.ASYNC_REQUEST_URI,baseRequest.getRequestURI());
362 baseRequest.setAttribute(AsyncContext.ASYNC_QUERY_STRING,baseRequest.getQueryString());
363
364 baseRequest.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH,state.getSuspendedContext().getContextPath());
365
366 final String contextPath=state.getServletContext().getContextPath();
367 HttpURI uri = new HttpURI(URIUtil.addPaths(contextPath,path));
368 baseRequest.setUri(uri);
369 baseRequest.setRequestURI(null);
370 baseRequest.setPathInfo(baseRequest.getRequestURI());
371 if (uri.getQuery()!=null)
372 baseRequest.mergeQueryString(uri.getQuery());
373 }
374
375 final String target=baseRequest.getPathInfo();
376 final HttpServletRequest request=(HttpServletRequest)async.getRequest();
377 final HttpServletResponse response=(HttpServletResponse)async.getResponse();
378
379 if (Log.isDebugEnabled())
380 {
381 Log.debug("REQUEST "+target+" on "+connection);
382 handle(target, baseRequest, request, response);
383 Log.debug("RESPONSE "+target+" "+connection.getResponse().getStatus());
384 }
385 else
386 handle(target, baseRequest, request, response);
387
388 }
389
390
391
392 public void join() throws InterruptedException
393 {
394 getThreadPool().join();
395 }
396
397
398
399
400
401
402 public SessionIdManager getSessionIdManager()
403 {
404 return _sessionIdManager;
405 }
406
407
408
409
410
411
412 public void setSessionIdManager(SessionIdManager sessionIdManager)
413 {
414 if (_sessionIdManager!=null)
415 removeBean(_sessionIdManager);
416 _container.update(this, _sessionIdManager, sessionIdManager, "sessionIdManager",false);
417 _sessionIdManager = sessionIdManager;
418 if (_sessionIdManager!=null)
419 addBean(_sessionIdManager);
420 }
421
422
423 public void setSendServerVersion (boolean sendServerVersion)
424 {
425 _sendServerVersion = sendServerVersion;
426 }
427
428
429 public boolean getSendServerVersion()
430 {
431 return _sendServerVersion;
432 }
433
434
435
436
437
438 public void setSendDateHeader(boolean sendDateHeader)
439 {
440 _sendDateHeader = sendDateHeader;
441 }
442
443
444 public boolean getSendDateHeader()
445 {
446 return _sendDateHeader;
447 }
448
449
450
451
452
453 public int getMaxCookieVersion()
454 {
455 return _maxCookieVersion;
456 }
457
458
459
460
461
462 public void setMaxCookieVersion(int maxCookieVersion)
463 {
464 _maxCookieVersion = maxCookieVersion;
465 }
466
467
468
469
470
471
472
473
474 @Deprecated
475 public void addLifeCycle (LifeCycle c)
476 {
477 addBean(c);
478 }
479
480
481
482
483
484
485
486
487
488
489 @Override
490 public boolean addBean(Object o)
491 {
492 if (super.addBean(o))
493 {
494 _container.addBean(o);
495 return true;
496 }
497 return false;
498 }
499
500
501
502
503
504
505 @Deprecated
506 public void removeLifeCycle (LifeCycle c)
507 {
508 removeBean(c);
509 }
510
511
512
513
514
515 @Override
516 public boolean removeBean (Object o)
517 {
518 if (super.removeBean(o))
519 {
520 _container.removeBean(o);
521 return true;
522 }
523 return false;
524 }
525
526
527
528
529
530 public void clearAttributes()
531 {
532 _attributes.clearAttributes();
533 }
534
535
536
537
538
539 public Object getAttribute(String name)
540 {
541 return _attributes.getAttribute(name);
542 }
543
544
545
546
547
548 public Enumeration getAttributeNames()
549 {
550 return AttributesMap.getAttributeNamesCopy(_attributes);
551 }
552
553
554
555
556
557 public void removeAttribute(String name)
558 {
559 _attributes.removeAttribute(name);
560 }
561
562
563
564
565
566 public void setAttribute(String name, Object attribute)
567 {
568 _attributes.setAttribute(name, attribute);
569 }
570
571
572
573
574
575 public int getGracefulShutdown()
576 {
577 return _graceful;
578 }
579
580
581
582
583
584
585
586
587
588
589
590 public void setGracefulShutdown(int timeoutMS)
591 {
592 _graceful=timeoutMS;
593 }
594
595
596 @Override
597 public String toString()
598 {
599 return this.getClass().getName()+"@"+Integer.toHexString(hashCode());
600 }
601
602
603 @Override
604 public void dump(Appendable out,String indent) throws IOException
605 {
606 dumpThis(out);
607 dump(out,indent,TypeUtil.asList(getHandlers()),getBeans(),TypeUtil.asList(_connectors));
608 }
609
610
611
612
613
614
615 public interface Graceful extends Handler
616 {
617 public void setShutdown(boolean shutdown);
618 }
619
620
621 public static void main(String...args) throws Exception
622 {
623 System.err.println(getVersion());
624 }
625 }