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