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