1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.server.handler;
15
16 import java.io.File;
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.net.MalformedURLException;
20 import java.net.URL;
21 import java.net.URLClassLoader;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Collections;
25 import java.util.Enumeration;
26 import java.util.EventListener;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.List;
30 import java.util.Locale;
31 import java.util.Map;
32 import java.util.Set;
33
34 import javax.servlet.RequestDispatcher;
35 import javax.servlet.Servlet;
36 import javax.servlet.ServletContext;
37 import javax.servlet.ServletContextAttributeEvent;
38 import javax.servlet.ServletContextAttributeListener;
39 import javax.servlet.ServletContextEvent;
40 import javax.servlet.ServletContextListener;
41 import javax.servlet.ServletException;
42 import javax.servlet.ServletRequestAttributeListener;
43 import javax.servlet.ServletRequestEvent;
44 import javax.servlet.ServletRequestListener;
45 import javax.servlet.http.HttpServletRequest;
46 import javax.servlet.http.HttpServletResponse;
47
48 import org.eclipse.jetty.http.HttpException;
49 import org.eclipse.jetty.http.MimeTypes;
50 import org.eclipse.jetty.io.Buffer;
51 import org.eclipse.jetty.server.Dispatcher;
52 import org.eclipse.jetty.server.DispatcherType;
53 import org.eclipse.jetty.server.Handler;
54 import org.eclipse.jetty.server.HandlerContainer;
55 import org.eclipse.jetty.server.HttpConnection;
56 import org.eclipse.jetty.server.Request;
57 import org.eclipse.jetty.server.Server;
58 import org.eclipse.jetty.util.Attributes;
59 import org.eclipse.jetty.util.AttributesMap;
60 import org.eclipse.jetty.util.LazyList;
61 import org.eclipse.jetty.util.Loader;
62 import org.eclipse.jetty.util.TypeUtil;
63 import org.eclipse.jetty.util.URIUtil;
64 import org.eclipse.jetty.util.component.AggregateLifeCycle;
65 import org.eclipse.jetty.util.component.Dumpable;
66 import org.eclipse.jetty.util.log.Log;
67 import org.eclipse.jetty.util.log.Logger;
68 import org.eclipse.jetty.util.resource.Resource;
69
70
71
72
73
74
75
76
77
78
79
80
81
82 public class ContextHandler extends ScopedHandler implements Attributes, Server.Graceful
83 {
84 private static final ThreadLocal<Context> __context = new ThreadLocal<Context>();
85
86
87
88
89
90
91 public static final String MANAGED_ATTRIBUTES = "org.eclipse.jetty.server.context.ManagedAttributes";
92
93
94
95
96
97
98
99 public static Context getCurrentContext()
100 {
101 return __context.get();
102 }
103
104 protected Context _scontext;
105
106 private final AttributesMap _attributes;
107 private final AttributesMap _contextAttributes;
108 private final Map<String, String> _initParams;
109 private ClassLoader _classLoader;
110 private String _contextPath = "/";
111 private String _displayName;
112 private Resource _baseResource;
113 private MimeTypes _mimeTypes;
114 private Map<String, String> _localeEncodingMap;
115 private String[] _welcomeFiles;
116 private ErrorHandler _errorHandler;
117 private String[] _vhosts;
118 private Set<String> _connectors;
119 private EventListener[] _eventListeners;
120 private Logger _logger;
121 private boolean _allowNullPathInfo;
122 private int _maxFormContentSize = Integer.getInteger("org.eclipse.jetty.server.Request.maxFormContentSize",200000).intValue();
123 private boolean _compactPath = false;
124 private boolean _aliases = false;
125
126 private Object _contextListeners;
127 private Object _contextAttributeListeners;
128 private Object _requestListeners;
129 private Object _requestAttributeListeners;
130 private Map<String, Object> _managedAttributes;
131
132 private boolean _shutdown = false;
133 private boolean _available = true;
134 private volatile int _availability;
135
136 private final static int __STOPPED = 0, __AVAILABLE = 1, __SHUTDOWN = 2, __UNAVAILABLE = 3;
137
138
139
140
141
142 public ContextHandler()
143 {
144 super();
145 _scontext = new Context();
146 _attributes = new AttributesMap();
147 _contextAttributes = new AttributesMap();
148 _initParams = new HashMap<String, String>();
149 }
150
151
152
153
154
155 protected ContextHandler(Context context)
156 {
157 super();
158 _scontext = context;
159 _attributes = new AttributesMap();
160 _contextAttributes = new AttributesMap();
161 _initParams = new HashMap<String, String>();
162 }
163
164
165
166
167
168 public ContextHandler(String contextPath)
169 {
170 this();
171 setContextPath(contextPath);
172 }
173
174
175
176
177
178 public ContextHandler(HandlerContainer parent, String contextPath)
179 {
180 this();
181 setContextPath(contextPath);
182 if (parent instanceof HandlerWrapper)
183 ((HandlerWrapper)parent).setHandler(this);
184 else if (parent instanceof HandlerCollection)
185 ((HandlerCollection)parent).addHandler(this);
186 }
187
188
189 @Override
190 public void dump(Appendable out, String indent) throws IOException
191 {
192 dumpThis(out);
193 dump(out,indent,Collections.singletonList(new CLDump(getClassLoader())),TypeUtil.asList(getHandlers()),getBeans(),_initParams.entrySet(),
194 _attributes.getAttributeEntrySet(),_contextAttributes.getAttributeEntrySet());
195 }
196
197
198 public Context getServletContext()
199 {
200 return _scontext;
201 }
202
203
204
205
206
207 public boolean getAllowNullPathInfo()
208 {
209 return _allowNullPathInfo;
210 }
211
212
213
214
215
216
217 public void setAllowNullPathInfo(boolean allowNullPathInfo)
218 {
219 _allowNullPathInfo = allowNullPathInfo;
220 }
221
222
223 @Override
224 public void setServer(Server server)
225 {
226 if (_errorHandler != null)
227 {
228 Server old_server = getServer();
229 if (old_server != null && old_server != server)
230 old_server.getContainer().update(this,_errorHandler,null,"error",true);
231 super.setServer(server);
232 if (server != null && server != old_server)
233 server.getContainer().update(this,null,_errorHandler,"error",true);
234 _errorHandler.setServer(server);
235 }
236 else
237 super.setServer(server);
238 }
239
240
241
242
243
244
245
246
247
248
249
250 public void setVirtualHosts(String[] vhosts)
251 {
252 if (vhosts == null)
253 {
254 _vhosts = vhosts;
255 }
256 else
257 {
258 _vhosts = new String[vhosts.length];
259 for (int i = 0; i < vhosts.length; i++)
260 _vhosts[i] = normalizeHostname(vhosts[i]);
261 }
262 }
263
264
265
266
267
268
269
270
271
272
273 public String[] getVirtualHosts()
274 {
275 return _vhosts;
276 }
277
278
279
280
281
282 public String[] getConnectorNames()
283 {
284 if (_connectors == null || _connectors.size() == 0)
285 return null;
286
287 return _connectors.toArray(new String[_connectors.size()]);
288 }
289
290
291
292
293
294
295
296
297
298
299 public void setConnectorNames(String[] connectors)
300 {
301 if (connectors == null || connectors.length == 0)
302 _connectors = null;
303 else
304 _connectors = new HashSet<String>(Arrays.asList(connectors));
305 }
306
307
308
309
310
311 public Object getAttribute(String name)
312 {
313 return _attributes.getAttribute(name);
314 }
315
316
317
318
319
320 @SuppressWarnings("unchecked")
321 public Enumeration getAttributeNames()
322 {
323 return AttributesMap.getAttributeNamesCopy(_attributes);
324 }
325
326
327
328
329
330 public Attributes getAttributes()
331 {
332 return _attributes;
333 }
334
335
336
337
338
339 public ClassLoader getClassLoader()
340 {
341 return _classLoader;
342 }
343
344
345
346
347
348
349
350 public String getClassPath()
351 {
352 if (_classLoader == null || !(_classLoader instanceof URLClassLoader))
353 return null;
354 URLClassLoader loader = (URLClassLoader)_classLoader;
355 URL[] urls = loader.getURLs();
356 StringBuilder classpath = new StringBuilder();
357 for (int i = 0; i < urls.length; i++)
358 {
359 try
360 {
361 Resource resource = newResource(urls[i]);
362 File file = resource.getFile();
363 if (file != null && file.exists())
364 {
365 if (classpath.length() > 0)
366 classpath.append(File.pathSeparatorChar);
367 classpath.append(file.getAbsolutePath());
368 }
369 }
370 catch (IOException e)
371 {
372 Log.debug(e);
373 }
374 }
375 if (classpath.length() == 0)
376 return null;
377 return classpath.toString();
378 }
379
380
381
382
383
384 public String getContextPath()
385 {
386 return _contextPath;
387 }
388
389
390
391
392
393 public String getInitParameter(String name)
394 {
395 return _initParams.get(name);
396 }
397
398
399
400
401 public String setInitParameter(String name, String value)
402 {
403 return _initParams.put(name,value);
404 }
405
406
407
408
409
410 @SuppressWarnings("rawtypes")
411 public Enumeration getInitParameterNames()
412 {
413 return Collections.enumeration(_initParams.keySet());
414 }
415
416
417
418
419
420 public Map<String, String> getInitParams()
421 {
422 return _initParams;
423 }
424
425
426
427
428
429 public String getDisplayName()
430 {
431 return _displayName;
432 }
433
434
435 public EventListener[] getEventListeners()
436 {
437 return _eventListeners;
438 }
439
440
441
442
443
444
445
446
447
448
449
450
451 public void setEventListeners(EventListener[] eventListeners)
452 {
453 _contextListeners = null;
454 _contextAttributeListeners = null;
455 _requestListeners = null;
456 _requestAttributeListeners = null;
457
458 _eventListeners = eventListeners;
459
460 for (int i = 0; eventListeners != null && i < eventListeners.length; i++)
461 {
462 EventListener listener = _eventListeners[i];
463
464 if (listener instanceof ServletContextListener)
465 _contextListeners = LazyList.add(_contextListeners,listener);
466
467 if (listener instanceof ServletContextAttributeListener)
468 _contextAttributeListeners = LazyList.add(_contextAttributeListeners,listener);
469
470 if (listener instanceof ServletRequestListener)
471 _requestListeners = LazyList.add(_requestListeners,listener);
472
473 if (listener instanceof ServletRequestAttributeListener)
474 _requestAttributeListeners = LazyList.add(_requestAttributeListeners,listener);
475 }
476 }
477
478
479
480
481
482
483
484
485
486
487 public void addEventListener(EventListener listener)
488 {
489 setEventListeners((EventListener[])LazyList.addToArray(getEventListeners(),listener,EventListener.class));
490 }
491
492
493
494
495
496 public boolean isShutdown()
497 {
498 return !_shutdown;
499 }
500
501
502
503
504
505
506
507
508
509 public void setShutdown(boolean shutdown)
510 {
511 synchronized (this)
512 {
513 _shutdown = shutdown;
514 _availability = isRunning()?(_shutdown?__SHUTDOWN:_available?__AVAILABLE:__UNAVAILABLE):__STOPPED;
515 }
516 }
517
518
519
520
521
522 public boolean isAvailable()
523 {
524 return _available;
525 }
526
527
528
529
530
531 public void setAvailable(boolean available)
532 {
533 synchronized (this)
534 {
535 _available = available;
536 _availability = isRunning()?(_shutdown?__SHUTDOWN:_available?__AVAILABLE:__UNAVAILABLE):__STOPPED;
537 }
538 }
539
540
541 public Logger getLogger()
542 {
543 return _logger;
544 }
545
546
547 public void setLogger(Logger logger)
548 {
549 _logger = logger;
550 }
551
552
553
554
555
556 @Override
557 protected void doStart() throws Exception
558 {
559 _availability = __STOPPED;
560
561 if (_contextPath == null)
562 throw new IllegalStateException("Null contextPath");
563
564 _logger = Log.getLogger(getDisplayName() == null?getContextPath():getDisplayName());
565 ClassLoader old_classloader = null;
566 Thread current_thread = null;
567 Context old_context = null;
568
569 try
570 {
571
572 if (_classLoader != null)
573 {
574 current_thread = Thread.currentThread();
575 old_classloader = current_thread.getContextClassLoader();
576 current_thread.setContextClassLoader(_classLoader);
577 }
578
579 if (_mimeTypes == null)
580 _mimeTypes = new MimeTypes();
581
582 old_context = __context.get();
583 __context.set(_scontext);
584
585
586 startContext();
587
588 _availability = _shutdown?__SHUTDOWN:_available?__AVAILABLE:__UNAVAILABLE;
589 }
590 finally
591 {
592 __context.set(old_context);
593
594
595 if (_classLoader != null)
596 {
597 current_thread.setContextClassLoader(old_classloader);
598 }
599
600 }
601 }
602
603
604
605
606
607
608
609
610 protected void startContext() throws Exception
611 {
612 String managedAttributes = _initParams.get(MANAGED_ATTRIBUTES);
613 if (managedAttributes != null)
614 {
615 _managedAttributes = new HashMap<String, Object>();
616 String[] attributes = managedAttributes.split(",");
617 for (String attribute : attributes)
618 _managedAttributes.put(attribute,null);
619
620 Enumeration e = _scontext.getAttributeNames();
621 while (e.hasMoreElements())
622 {
623 String name = (String)e.nextElement();
624 Object value = _scontext.getAttribute(name);
625 checkManagedAttribute(name,value);
626 }
627 }
628
629 super.doStart();
630
631 if (_errorHandler != null)
632 _errorHandler.start();
633
634
635 if (_contextListeners != null)
636 {
637 ServletContextEvent event = new ServletContextEvent(_scontext);
638 for (int i = 0; i < LazyList.size(_contextListeners); i++)
639 {
640 ((ServletContextListener)LazyList.get(_contextListeners,i)).contextInitialized(event);
641 }
642 }
643
644 Log.info("started {}",this);
645 }
646
647
648
649
650
651 @Override
652 protected void doStop() throws Exception
653 {
654 _availability = __STOPPED;
655
656 ClassLoader old_classloader = null;
657 Thread current_thread = null;
658
659 Context old_context = __context.get();
660 __context.set(_scontext);
661 try
662 {
663
664 if (_classLoader != null)
665 {
666 current_thread = Thread.currentThread();
667 old_classloader = current_thread.getContextClassLoader();
668 current_thread.setContextClassLoader(_classLoader);
669 }
670
671 super.doStop();
672
673
674 if (_contextListeners != null)
675 {
676 ServletContextEvent event = new ServletContextEvent(_scontext);
677 for (int i = LazyList.size(_contextListeners); i-- > 0;)
678 {
679 ((ServletContextListener)LazyList.get(_contextListeners,i)).contextDestroyed(event);
680 }
681 }
682
683 if (_errorHandler != null)
684 _errorHandler.stop();
685
686 Enumeration e = _scontext.getAttributeNames();
687 while (e.hasMoreElements())
688 {
689 String name = (String)e.nextElement();
690 checkManagedAttribute(name,null);
691 }
692 }
693 finally
694 {
695 Log.info("stopped {}",this);
696 __context.set(old_context);
697
698 if (_classLoader != null)
699 current_thread.setContextClassLoader(old_classloader);
700 }
701
702 _contextAttributes.clearAttributes();
703 }
704
705
706
707
708
709 public boolean checkContext(final String target, final Request baseRequest, final HttpServletResponse response) throws IOException, ServletException
710 {
711 DispatcherType dispatch = baseRequest.getDispatcherType();
712
713 switch (_availability)
714 {
715 case __STOPPED:
716 case __SHUTDOWN:
717 return false;
718 case __UNAVAILABLE:
719 baseRequest.setHandled(true);
720 response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
721 return false;
722 default:
723 if ((DispatcherType.REQUEST.equals(dispatch) && baseRequest.isHandled()))
724 return false;
725 }
726
727
728 if (_vhosts != null && _vhosts.length > 0)
729 {
730 String vhost = normalizeHostname(baseRequest.getServerName());
731
732 boolean match = false;
733
734
735 for (int i = 0; !match && i < _vhosts.length; i++)
736 {
737 String contextVhost = _vhosts[i];
738 if (contextVhost == null)
739 continue;
740 if (contextVhost.startsWith("*."))
741 {
742
743 match = contextVhost.regionMatches(true,2,vhost,vhost.indexOf(".") + 1,contextVhost.length() - 2);
744 }
745 else
746 match = contextVhost.equalsIgnoreCase(vhost);
747 }
748 if (!match)
749 return false;
750 }
751
752
753 if (_connectors != null && _connectors.size() > 0)
754 {
755 String connector = HttpConnection.getCurrentConnection().getConnector().getName();
756 if (connector == null || !_connectors.contains(connector))
757 return false;
758 }
759
760
761 if (_contextPath.length() > 1)
762 {
763
764 if (!target.startsWith(_contextPath))
765 return false;
766 if (target.length() > _contextPath.length() && target.charAt(_contextPath.length()) != '/')
767 return false;
768
769
770 if (!_allowNullPathInfo && _contextPath.length() == target.length())
771 {
772
773 baseRequest.setHandled(true);
774 if (baseRequest.getQueryString() != null)
775 response.sendRedirect(URIUtil.addPaths(baseRequest.getRequestURI(),URIUtil.SLASH) + "?" + baseRequest.getQueryString());
776 else
777 response.sendRedirect(URIUtil.addPaths(baseRequest.getRequestURI(),URIUtil.SLASH));
778 return false;
779 }
780 }
781
782 return true;
783 }
784
785
786
787
788
789
790 @Override
791 public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
792 {
793 Log.debug("scope {} @ {}",baseRequest.getContextPath() + "|" + baseRequest.getServletPath() + "|" + baseRequest.getPathInfo(),this);
794
795 Context old_context = null;
796 String old_context_path = null;
797 String old_servlet_path = null;
798 String old_path_info = null;
799 ClassLoader old_classloader = null;
800 Thread current_thread = null;
801 String pathInfo = null;
802
803 DispatcherType dispatch = baseRequest.getDispatcherType();
804
805 old_context = baseRequest.getContext();
806
807
808 if (old_context != _scontext)
809 {
810
811 if (DispatcherType.REQUEST.equals(dispatch) || DispatcherType.ASYNC.equals(dispatch))
812 {
813 if (_compactPath)
814 target = URIUtil.compactPath(target);
815 if (!checkContext(target,baseRequest,response))
816 return;
817
818 if (target.length() > _contextPath.length())
819 {
820 if (_contextPath.length() > 1)
821 target = target.substring(_contextPath.length());
822 pathInfo = target;
823 }
824 else if (_contextPath.length() == 1)
825 {
826 target = URIUtil.SLASH;
827 pathInfo = URIUtil.SLASH;
828 }
829 else
830 {
831 target = URIUtil.SLASH;
832 pathInfo = null;
833 }
834 }
835
836
837 if (_classLoader != null)
838 {
839 current_thread = Thread.currentThread();
840 old_classloader = current_thread.getContextClassLoader();
841 current_thread.setContextClassLoader(_classLoader);
842 }
843 }
844
845 try
846 {
847 old_context_path = baseRequest.getContextPath();
848 old_servlet_path = baseRequest.getServletPath();
849 old_path_info = baseRequest.getPathInfo();
850
851
852 baseRequest.setContext(_scontext);
853 __context.set(_scontext);
854 if (!DispatcherType.INCLUDE.equals(dispatch) && target.startsWith("/"))
855 {
856 if (_contextPath.length() == 1)
857 baseRequest.setContextPath("");
858 else
859 baseRequest.setContextPath(_contextPath);
860 baseRequest.setServletPath(null);
861 baseRequest.setPathInfo(pathInfo);
862 }
863
864 if (Log.isDebugEnabled())
865 Log.debug("context={} @ {}",baseRequest.getContextPath() + "|" + baseRequest.getServletPath() + "|" + baseRequest.getPathInfo(),this);
866
867
868 if (never())
869 nextScope(target,baseRequest,request,response);
870 else if (_nextScope != null)
871 _nextScope.doScope(target,baseRequest,request,response);
872 else if (_outerScope != null)
873 _outerScope.doHandle(target,baseRequest,request,response);
874 else
875 doHandle(target,baseRequest,request,response);
876
877 }
878 finally
879 {
880 if (old_context != _scontext)
881 {
882
883 if (_classLoader != null)
884 {
885 current_thread.setContextClassLoader(old_classloader);
886 }
887
888
889 baseRequest.setContext(old_context);
890 __context.set(old_context);
891 baseRequest.setContextPath(old_context_path);
892 baseRequest.setServletPath(old_servlet_path);
893 baseRequest.setPathInfo(old_path_info);
894 }
895 }
896 }
897
898
899
900
901
902
903 @Override
904 public void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
905 {
906 final DispatcherType dispatch = baseRequest.getDispatcherType();
907 final boolean new_context = baseRequest.takeNewContext();
908 try
909 {
910 if (new_context)
911 {
912
913 if (_requestAttributeListeners != null)
914 {
915 final int s = LazyList.size(_requestAttributeListeners);
916 for (int i = 0; i < s; i++)
917 baseRequest.addEventListener(((EventListener)LazyList.get(_requestAttributeListeners,i)));
918 }
919
920 if (_requestListeners != null)
921 {
922 final int s = LazyList.size(_requestListeners);
923 final ServletRequestEvent sre = new ServletRequestEvent(_scontext,request);
924 for (int i = 0; i < s; i++)
925 ((ServletRequestListener)LazyList.get(_requestListeners,i)).requestInitialized(sre);
926 }
927 }
928
929 if (DispatcherType.REQUEST.equals(dispatch) && isProtectedTarget(target))
930 throw new HttpException(HttpServletResponse.SC_NOT_FOUND);
931
932
933
934 if (never())
935 nextHandle(target,baseRequest,request,response);
936 else if (_nextScope != null && _nextScope == _handler)
937 _nextScope.doHandle(target,baseRequest,request,response);
938 else if (_handler != null)
939 _handler.handle(target,baseRequest,request,response);
940
941 }
942 catch (HttpException e)
943 {
944 Log.debug(e);
945 baseRequest.setHandled(true);
946 response.sendError(e.getStatus(),e.getReason());
947 }
948 finally
949 {
950
951 if (new_context)
952 {
953 if (_requestListeners != null)
954 {
955 final ServletRequestEvent sre = new ServletRequestEvent(_scontext,request);
956 for (int i = LazyList.size(_requestListeners); i-- > 0;)
957 ((ServletRequestListener)LazyList.get(_requestListeners,i)).requestDestroyed(sre);
958 }
959
960 if (_requestAttributeListeners != null)
961 {
962 for (int i = LazyList.size(_requestAttributeListeners); i-- > 0;)
963 baseRequest.removeEventListener(((EventListener)LazyList.get(_requestAttributeListeners,i)));
964 }
965 }
966 }
967 }
968
969
970
971
972
973 public void handle(Runnable runnable)
974 {
975 ClassLoader old_classloader = null;
976 Thread current_thread = null;
977 Context old_context = null;
978 try
979 {
980 old_context = __context.get();
981 __context.set(_scontext);
982
983
984 if (_classLoader != null)
985 {
986 current_thread = Thread.currentThread();
987 old_classloader = current_thread.getContextClassLoader();
988 current_thread.setContextClassLoader(_classLoader);
989 }
990
991 runnable.run();
992 }
993 finally
994 {
995 __context.set(old_context);
996 if (old_classloader != null)
997 {
998 current_thread.setContextClassLoader(old_classloader);
999 }
1000 }
1001 }
1002
1003
1004
1005
1006
1007
1008
1009 protected boolean isProtectedTarget(String target)
1010 {
1011 return false;
1012 }
1013
1014
1015
1016
1017
1018 public void removeAttribute(String name)
1019 {
1020 checkManagedAttribute(name,null);
1021 _attributes.removeAttribute(name);
1022 }
1023
1024
1025
1026
1027
1028
1029
1030
1031 public void setAttribute(String name, Object value)
1032 {
1033 checkManagedAttribute(name,value);
1034 _attributes.setAttribute(name,value);
1035 }
1036
1037
1038
1039
1040
1041
1042 public void setAttributes(Attributes attributes)
1043 {
1044 _attributes.clearAttributes();
1045 _attributes.addAll(attributes);
1046 Enumeration e = _attributes.getAttributeNames();
1047 while (e.hasMoreElements())
1048 {
1049 String name = (String)e.nextElement();
1050 checkManagedAttribute(name,attributes.getAttribute(name));
1051 }
1052 }
1053
1054
1055 public void clearAttributes()
1056 {
1057 Enumeration e = _attributes.getAttributeNames();
1058 while (e.hasMoreElements())
1059 {
1060 String name = (String)e.nextElement();
1061 checkManagedAttribute(name,null);
1062 }
1063 _attributes.clearAttributes();
1064 }
1065
1066
1067 public void checkManagedAttribute(String name, Object value)
1068 {
1069 if (_managedAttributes != null && _managedAttributes.containsKey(name))
1070 {
1071 setManagedAttribute(name,value);
1072 }
1073 }
1074
1075
1076 public void setManagedAttribute(String name, Object value)
1077 {
1078 Object old = _managedAttributes.put(name,value);
1079 getServer().getContainer().update(this,old,value,name,true);
1080 }
1081
1082
1083
1084
1085
1086
1087 public void setClassLoader(ClassLoader classLoader)
1088 {
1089 _classLoader = classLoader;
1090 }
1091
1092
1093
1094
1095
1096
1097 public void setContextPath(String contextPath)
1098 {
1099 if (contextPath != null && contextPath.length() > 1 && contextPath.endsWith("/"))
1100 throw new IllegalArgumentException("ends with /");
1101 _contextPath = contextPath;
1102
1103 if (getServer() != null && (getServer().isStarting() || getServer().isStarted()))
1104 {
1105 Handler[] contextCollections = getServer().getChildHandlersByClass(ContextHandlerCollection.class);
1106 for (int h = 0; contextCollections != null && h < contextCollections.length; h++)
1107 ((ContextHandlerCollection)contextCollections[h]).mapContexts();
1108 }
1109 }
1110
1111
1112
1113
1114
1115
1116 public void setDisplayName(String servletContextName)
1117 {
1118 _displayName = servletContextName;
1119 }
1120
1121
1122
1123
1124
1125 public Resource getBaseResource()
1126 {
1127 if (_baseResource == null)
1128 return null;
1129 return _baseResource;
1130 }
1131
1132
1133
1134
1135
1136 public String getResourceBase()
1137 {
1138 if (_baseResource == null)
1139 return null;
1140 return _baseResource.toString();
1141 }
1142
1143
1144
1145
1146
1147
1148 public void setBaseResource(Resource base)
1149 {
1150 _baseResource = base;
1151 }
1152
1153
1154
1155
1156
1157
1158 public void setResourceBase(String resourceBase)
1159 {
1160 try
1161 {
1162 setBaseResource(newResource(resourceBase));
1163 }
1164 catch (Exception e)
1165 {
1166 Log.warn(e.toString());
1167 Log.debug(e);
1168 throw new IllegalArgumentException(resourceBase);
1169 }
1170 }
1171
1172
1173
1174
1175
1176 public boolean isAliases()
1177 {
1178 return _aliases;
1179 }
1180
1181
1182
1183
1184
1185
1186 public void setAliases(boolean aliases)
1187 {
1188 _aliases = aliases;
1189 }
1190
1191
1192
1193
1194
1195 public MimeTypes getMimeTypes()
1196 {
1197 if (_mimeTypes == null)
1198 _mimeTypes = new MimeTypes();
1199 return _mimeTypes;
1200 }
1201
1202
1203
1204
1205
1206
1207 public void setMimeTypes(MimeTypes mimeTypes)
1208 {
1209 _mimeTypes = mimeTypes;
1210 }
1211
1212
1213
1214
1215 public void setWelcomeFiles(String[] files)
1216 {
1217 _welcomeFiles = files;
1218 }
1219
1220
1221
1222
1223
1224
1225
1226 public String[] getWelcomeFiles()
1227 {
1228 return _welcomeFiles;
1229 }
1230
1231
1232
1233
1234
1235 public ErrorHandler getErrorHandler()
1236 {
1237 return _errorHandler;
1238 }
1239
1240
1241
1242
1243
1244
1245 public void setErrorHandler(ErrorHandler errorHandler)
1246 {
1247 if (errorHandler != null)
1248 errorHandler.setServer(getServer());
1249 if (getServer() != null)
1250 getServer().getContainer().update(this,_errorHandler,errorHandler,"errorHandler",true);
1251 _errorHandler = errorHandler;
1252 }
1253
1254
1255 public int getMaxFormContentSize()
1256 {
1257 return _maxFormContentSize;
1258 }
1259
1260
1261 public void setMaxFormContentSize(int maxSize)
1262 {
1263 _maxFormContentSize = maxSize;
1264 }
1265
1266
1267
1268
1269
1270 public boolean isCompactPath()
1271 {
1272 return _compactPath;
1273 }
1274
1275
1276
1277
1278
1279
1280 public void setCompactPath(boolean compactPath)
1281 {
1282 _compactPath = compactPath;
1283 }
1284
1285
1286 @Override
1287 public String toString()
1288 {
1289 String[] vhosts = getVirtualHosts();
1290
1291 StringBuilder b = new StringBuilder();
1292
1293 String p = getClass().getPackage().getName();
1294 if (p != null && p.length() > 0)
1295 {
1296 String[] ss = p.split("\\.");
1297 for (String s : ss)
1298 b.append(s.charAt(0)).append('.');
1299 }
1300
1301 b.append(getClass().getSimpleName());
1302 b.append('{').append(getContextPath()).append(',').append(getBaseResource());
1303
1304 if (vhosts != null && vhosts.length > 0)
1305 b.append(',').append(vhosts[0]);
1306 b.append('}');
1307
1308 return b.toString();
1309 }
1310
1311
1312 public synchronized Class<?> loadClass(String className) throws ClassNotFoundException
1313 {
1314 if (className == null)
1315 return null;
1316
1317 if (_classLoader == null)
1318 return Loader.loadClass(this.getClass(),className);
1319
1320 return _classLoader.loadClass(className);
1321 }
1322
1323
1324 public void addLocaleEncoding(String locale, String encoding)
1325 {
1326 if (_localeEncodingMap == null)
1327 _localeEncodingMap = new HashMap<String, String>();
1328 _localeEncodingMap.put(locale,encoding);
1329 }
1330
1331 public String getLocaleEncoding(String locale)
1332 {
1333 if (_localeEncodingMap == null)
1334 return null;
1335 String encoding = _localeEncodingMap.get(locale);
1336 return encoding;
1337 }
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348 public String getLocaleEncoding(Locale locale)
1349 {
1350 if (_localeEncodingMap == null)
1351 return null;
1352 String encoding = _localeEncodingMap.get(locale.toString());
1353 if (encoding == null)
1354 encoding = _localeEncodingMap.get(locale.getLanguage());
1355 return encoding;
1356 }
1357
1358
1359
1360
1361 public Resource getResource(String path) throws MalformedURLException
1362 {
1363 if (path == null || !path.startsWith(URIUtil.SLASH))
1364 throw new MalformedURLException(path);
1365
1366 if (_baseResource == null)
1367 return null;
1368
1369 try
1370 {
1371 path = URIUtil.canonicalPath(path);
1372 Resource resource = _baseResource.addPath(path);
1373
1374 if (!_aliases && resource.getAlias() != null)
1375 {
1376 if (resource.exists())
1377 Log.warn("Aliased resource: " + resource + "~=" + resource.getAlias());
1378 else if (path.endsWith("/") && resource.getAlias().toString().endsWith(path))
1379 return resource;
1380 else if (Log.isDebugEnabled())
1381 Log.debug("Aliased resource: " + resource + "~=" + resource.getAlias());
1382 return null;
1383 }
1384
1385 return resource;
1386 }
1387 catch (Exception e)
1388 {
1389 Log.ignore(e);
1390 }
1391
1392 return null;
1393 }
1394
1395
1396
1397
1398
1399 public Resource newResource(URL url) throws IOException
1400 {
1401 return Resource.newResource(url);
1402 }
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414 public Resource newResource(String urlOrPath) throws IOException
1415 {
1416 return Resource.newResource(urlOrPath);
1417 }
1418
1419
1420
1421
1422 public Set<String> getResourcePaths(String path)
1423 {
1424 try
1425 {
1426 path = URIUtil.canonicalPath(path);
1427 Resource resource = getResource(path);
1428
1429 if (resource != null && resource.exists())
1430 {
1431 if (!path.endsWith(URIUtil.SLASH))
1432 path = path + URIUtil.SLASH;
1433
1434 String[] l = resource.list();
1435 if (l != null)
1436 {
1437 HashSet<String> set = new HashSet<String>();
1438 for (int i = 0; i < l.length; i++)
1439 set.add(path + l[i]);
1440 return set;
1441 }
1442 }
1443 }
1444 catch (Exception e)
1445 {
1446 Log.ignore(e);
1447 }
1448 return Collections.emptySet();
1449 }
1450
1451
1452 private String normalizeHostname(String host)
1453 {
1454 if (host == null)
1455 return null;
1456
1457 if (host.endsWith("."))
1458 return host.substring(0,host.length() - 1);
1459
1460 return host;
1461 }
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472 public class Context implements ServletContext
1473 {
1474
1475 protected Context()
1476 {
1477 }
1478
1479
1480 public ContextHandler getContextHandler()
1481 {
1482
1483 return ContextHandler.this;
1484 }
1485
1486
1487
1488
1489
1490 public ServletContext getContext(String uripath)
1491 {
1492 List<ContextHandler> contexts = new ArrayList<ContextHandler>();
1493 Handler[] handlers = getServer().getChildHandlersByClass(ContextHandler.class);
1494 String matched_path = null;
1495
1496 for (Handler handler : handlers)
1497 {
1498 if (handler == null)
1499 continue;
1500 ContextHandler ch = (ContextHandler)handler;
1501 String context_path = ch.getContextPath();
1502
1503 if (uripath.equals(context_path) || (uripath.startsWith(context_path) && uripath.charAt(context_path.length()) == '/')
1504 || "/".equals(context_path))
1505 {
1506
1507 if (getVirtualHosts() != null && getVirtualHosts().length > 0)
1508 {
1509 if (ch.getVirtualHosts() != null && ch.getVirtualHosts().length > 0)
1510 {
1511 for (String h1 : getVirtualHosts())
1512 for (String h2 : ch.getVirtualHosts())
1513 if (h1.equals(h2))
1514 {
1515 if (matched_path == null || context_path.length() > matched_path.length())
1516 {
1517 contexts.clear();
1518 matched_path = context_path;
1519 }
1520
1521 if (matched_path.equals(context_path))
1522 contexts.add(ch);
1523 }
1524 }
1525 }
1526 else
1527 {
1528 if (matched_path == null || context_path.length() > matched_path.length())
1529 {
1530 contexts.clear();
1531 matched_path = context_path;
1532 }
1533
1534 if (matched_path.equals(context_path))
1535 contexts.add(ch);
1536 }
1537 }
1538 }
1539
1540 if (contexts.size() > 0)
1541 return contexts.get(0)._scontext;
1542
1543
1544 matched_path = null;
1545 for (Handler handler : handlers)
1546 {
1547 if (handler == null)
1548 continue;
1549 ContextHandler ch = (ContextHandler)handler;
1550 String context_path = ch.getContextPath();
1551
1552 if (uripath.equals(context_path) || (uripath.startsWith(context_path) && uripath.charAt(context_path.length()) == '/')
1553 || "/".equals(context_path))
1554 {
1555 if (matched_path == null || context_path.length() > matched_path.length())
1556 {
1557 contexts.clear();
1558 matched_path = context_path;
1559 }
1560
1561 if (matched_path.equals(context_path))
1562 contexts.add(ch);
1563 }
1564 }
1565
1566 if (contexts.size() > 0)
1567 return contexts.get(0)._scontext;
1568 return null;
1569 }
1570
1571
1572
1573
1574
1575 public int getMajorVersion()
1576 {
1577 return 2;
1578 }
1579
1580
1581
1582
1583
1584 public String getMimeType(String file)
1585 {
1586 if (_mimeTypes == null)
1587 return null;
1588 Buffer mime = _mimeTypes.getMimeByExtension(file);
1589 if (mime != null)
1590 return mime.toString();
1591 return null;
1592 }
1593
1594
1595
1596
1597
1598 public int getMinorVersion()
1599 {
1600 return 5;
1601 }
1602
1603
1604
1605
1606
1607 public RequestDispatcher getNamedDispatcher(String name)
1608 {
1609 return null;
1610 }
1611
1612
1613
1614
1615
1616 public RequestDispatcher getRequestDispatcher(String uriInContext)
1617 {
1618 if (uriInContext == null)
1619 return null;
1620
1621 if (!uriInContext.startsWith("/"))
1622 return null;
1623
1624 try
1625 {
1626 String query = null;
1627 int q = 0;
1628 if ((q = uriInContext.indexOf('?')) > 0)
1629 {
1630 query = uriInContext.substring(q + 1);
1631 uriInContext = uriInContext.substring(0,q);
1632 }
1633 if ((q = uriInContext.indexOf(';')) > 0)
1634 uriInContext = uriInContext.substring(0,q);
1635
1636 String pathInContext = URIUtil.canonicalPath(URIUtil.decodePath(uriInContext));
1637 String uri = URIUtil.addPaths(getContextPath(),uriInContext);
1638 ContextHandler context = ContextHandler.this;
1639 return new Dispatcher(context,uri,pathInContext,query);
1640 }
1641 catch (Exception e)
1642 {
1643 Log.ignore(e);
1644 }
1645 return null;
1646 }
1647
1648
1649
1650
1651
1652 public String getRealPath(String path)
1653 {
1654 if (path == null)
1655 return null;
1656 if (path.length() == 0)
1657 path = URIUtil.SLASH;
1658 else if (path.charAt(0) != '/')
1659 path = URIUtil.SLASH + path;
1660
1661 try
1662 {
1663 Resource resource = ContextHandler.this.getResource(path);
1664 if (resource != null)
1665 {
1666 File file = resource.getFile();
1667 if (file != null)
1668 return file.getCanonicalPath();
1669 }
1670 }
1671 catch (Exception e)
1672 {
1673 Log.ignore(e);
1674 }
1675
1676 return null;
1677 }
1678
1679
1680 public URL getResource(String path) throws MalformedURLException
1681 {
1682 Resource resource = ContextHandler.this.getResource(path);
1683 if (resource != null && resource.exists())
1684 return resource.getURL();
1685 return null;
1686 }
1687
1688
1689
1690
1691
1692 public InputStream getResourceAsStream(String path)
1693 {
1694 try
1695 {
1696 URL url = getResource(path);
1697 if (url == null)
1698 return null;
1699 return url.openStream();
1700 }
1701 catch (Exception e)
1702 {
1703 Log.ignore(e);
1704 return null;
1705 }
1706 }
1707
1708
1709
1710
1711
1712 public Set getResourcePaths(String path)
1713 {
1714 return ContextHandler.this.getResourcePaths(path);
1715 }
1716
1717
1718
1719
1720
1721 public String getServerInfo()
1722 {
1723 return "jetty/" + Server.getVersion();
1724 }
1725
1726
1727
1728
1729
1730 public Servlet getServlet(String name) throws ServletException
1731 {
1732 return null;
1733 }
1734
1735
1736
1737
1738
1739 @SuppressWarnings("unchecked")
1740 public Enumeration getServletNames()
1741 {
1742 return Collections.enumeration(Collections.EMPTY_LIST);
1743 }
1744
1745
1746
1747
1748
1749 @SuppressWarnings("unchecked")
1750 public Enumeration getServlets()
1751 {
1752 return Collections.enumeration(Collections.EMPTY_LIST);
1753 }
1754
1755
1756
1757
1758
1759 public void log(Exception exception, String msg)
1760 {
1761 _logger.warn(msg,exception);
1762 }
1763
1764
1765
1766
1767
1768 public void log(String msg)
1769 {
1770 _logger.info(msg);
1771 }
1772
1773
1774
1775
1776
1777 public void log(String message, Throwable throwable)
1778 {
1779 _logger.warn(message,throwable);
1780 }
1781
1782
1783
1784
1785
1786 public String getInitParameter(String name)
1787 {
1788 return ContextHandler.this.getInitParameter(name);
1789 }
1790
1791
1792
1793
1794
1795 @SuppressWarnings("unchecked")
1796 public Enumeration getInitParameterNames()
1797 {
1798 return ContextHandler.this.getInitParameterNames();
1799 }
1800
1801
1802
1803
1804
1805 public synchronized Object getAttribute(String name)
1806 {
1807 Object o = ContextHandler.this.getAttribute(name);
1808 if (o == null && _contextAttributes != null)
1809 o = _contextAttributes.getAttribute(name);
1810 return o;
1811 }
1812
1813
1814
1815
1816
1817 @SuppressWarnings("unchecked")
1818 public synchronized Enumeration getAttributeNames()
1819 {
1820 HashSet<String> set = new HashSet<String>();
1821 if (_contextAttributes != null)
1822 {
1823 Enumeration<String> e = _contextAttributes.getAttributeNames();
1824 while (e.hasMoreElements())
1825 set.add(e.nextElement());
1826 }
1827 Enumeration<String> e = _attributes.getAttributeNames();
1828 while (e.hasMoreElements())
1829 set.add(e.nextElement());
1830
1831 return Collections.enumeration(set);
1832 }
1833
1834
1835
1836
1837
1838 public synchronized void setAttribute(String name, Object value)
1839 {
1840 checkManagedAttribute(name,value);
1841 Object old_value = _contextAttributes.getAttribute(name);
1842
1843 if (value == null)
1844 _contextAttributes.removeAttribute(name);
1845 else
1846 _contextAttributes.setAttribute(name,value);
1847
1848 if (_contextAttributeListeners != null)
1849 {
1850 ServletContextAttributeEvent event = new ServletContextAttributeEvent(_scontext,name,old_value == null?value:old_value);
1851
1852 for (int i = 0; i < LazyList.size(_contextAttributeListeners); i++)
1853 {
1854 ServletContextAttributeListener l = (ServletContextAttributeListener)LazyList.get(_contextAttributeListeners,i);
1855
1856 if (old_value == null)
1857 l.attributeAdded(event);
1858 else if (value == null)
1859 l.attributeRemoved(event);
1860 else
1861 l.attributeReplaced(event);
1862 }
1863 }
1864 }
1865
1866
1867
1868
1869
1870 public synchronized void removeAttribute(String name)
1871 {
1872 checkManagedAttribute(name,null);
1873
1874 if (_contextAttributes == null)
1875 {
1876
1877 _attributes.removeAttribute(name);
1878 return;
1879 }
1880
1881 Object old_value = _contextAttributes.getAttribute(name);
1882 _contextAttributes.removeAttribute(name);
1883 if (old_value != null)
1884 {
1885 if (_contextAttributeListeners != null)
1886 {
1887 ServletContextAttributeEvent event = new ServletContextAttributeEvent(_scontext,name,old_value);
1888
1889 for (int i = 0; i < LazyList.size(_contextAttributeListeners); i++)
1890 ((ServletContextAttributeListener)LazyList.get(_contextAttributeListeners,i)).attributeRemoved(event);
1891 }
1892 }
1893 }
1894
1895
1896
1897
1898
1899 public String getServletContextName()
1900 {
1901 String name = ContextHandler.this.getDisplayName();
1902 if (name == null)
1903 name = ContextHandler.this.getContextPath();
1904 return name;
1905 }
1906
1907
1908 public String getContextPath()
1909 {
1910 if ((_contextPath != null) && _contextPath.equals(URIUtil.SLASH))
1911 return "";
1912
1913 return _contextPath;
1914 }
1915
1916
1917 @Override
1918 public String toString()
1919 {
1920 return "ServletContext@" + ContextHandler.this.toString();
1921 }
1922
1923
1924 public boolean setInitParameter(String name, String value)
1925 {
1926 if (ContextHandler.this.getInitParameter(name) != null)
1927 return false;
1928 ContextHandler.this.getInitParams().put(name,value);
1929 return true;
1930 }
1931
1932 }
1933
1934 private static class CLDump implements Dumpable
1935 {
1936 final ClassLoader _loader;
1937
1938 CLDump(ClassLoader loader)
1939 {
1940 _loader = loader;
1941 }
1942
1943 public String dump()
1944 {
1945 return AggregateLifeCycle.dump(this);
1946 }
1947
1948 public void dump(Appendable out, String indent) throws IOException
1949 {
1950 out.append(String.valueOf(_loader)).append("\n");
1951
1952 if (_loader != null)
1953 {
1954 Object parent = _loader.getParent();
1955 if (parent != null)
1956 {
1957 if (!(parent instanceof Dumpable))
1958 parent = new CLDump((ClassLoader)parent);
1959
1960 if (_loader instanceof URLClassLoader)
1961 AggregateLifeCycle.dump(out,indent,TypeUtil.asList(((URLClassLoader)_loader).getURLs()),Collections.singleton(parent));
1962 else
1963 AggregateLifeCycle.dump(out,indent,Collections.singleton(parent));
1964 }
1965 }
1966 }
1967
1968 }
1969 }