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