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