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