1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.servlet;
15
16 import java.io.IOException;
17 import java.util.ArrayList;
18 import java.util.Arrays;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.concurrent.ConcurrentHashMap;
24
25 import javax.servlet.Filter;
26 import javax.servlet.FilterChain;
27 import javax.servlet.RequestDispatcher;
28 import javax.servlet.Servlet;
29 import javax.servlet.ServletContext;
30 import javax.servlet.ServletException;
31 import javax.servlet.ServletRequest;
32 import javax.servlet.ServletResponse;
33 import javax.servlet.UnavailableException;
34 import javax.servlet.http.HttpServletRequest;
35 import javax.servlet.http.HttpServletResponse;
36
37 import org.eclipse.jetty.continuation.ContinuationThrowable;
38 import org.eclipse.jetty.http.HttpException;
39 import org.eclipse.jetty.http.PathMap;
40 import org.eclipse.jetty.io.EofException;
41 import org.eclipse.jetty.io.RuntimeIOException;
42 import org.eclipse.jetty.security.IdentityService;
43 import org.eclipse.jetty.security.SecurityHandler;
44 import org.eclipse.jetty.server.Dispatcher;
45 import org.eclipse.jetty.server.DispatcherType;
46 import org.eclipse.jetty.server.HttpConnection;
47 import org.eclipse.jetty.server.Request;
48 import org.eclipse.jetty.server.Server;
49 import org.eclipse.jetty.server.UserIdentity;
50 import org.eclipse.jetty.server.handler.ContextHandler;
51 import org.eclipse.jetty.server.handler.ScopedHandler;
52 import org.eclipse.jetty.util.LazyList;
53 import org.eclipse.jetty.util.MultiException;
54 import org.eclipse.jetty.util.MultiMap;
55 import org.eclipse.jetty.util.URIUtil;
56 import org.eclipse.jetty.util.log.Log;
57
58
59
60
61
62
63
64
65
66
67
68
69
70 public class ServletHandler extends ScopedHandler
71 {
72
73 public static final String __DEFAULT_SERVLET="default";
74
75
76 private ContextHandler _contextHandler;
77 private ContextHandler.Context _servletContext;
78 private FilterHolder[] _filters;
79 private FilterMapping[] _filterMappings;
80 private boolean _filterChainsCached=true;
81 private int _maxFilterChainsCacheSize=1000;
82 private boolean _startWithUnavailable=true;
83 private IdentityService _identityService;
84
85 private ServletHolder[] _servlets;
86 private ServletMapping[] _servletMappings;
87
88 private transient Map<String,FilterHolder> _filterNameMap= new HashMap<String,FilterHolder>();
89 private transient List<FilterMapping> _filterPathMappings;
90 private transient MultiMap<String> _filterNameMappings;
91
92 private transient Map<String,ServletHolder> _servletNameMap=new HashMap();
93 private transient PathMap _servletPathMap;
94
95 protected transient ConcurrentHashMap _chainCache[];
96
97
98
99
100
101 public ServletHandler()
102 {
103 }
104
105
106
107
108
109 public void setServer(Server server)
110 {
111 if (getServer()!=null && getServer()!=server)
112 {
113 getServer().getContainer().update(this, _filters, null, "filter",true);
114 getServer().getContainer().update(this, _filterMappings, null, "filterMapping",true);
115 getServer().getContainer().update(this, _servlets, null, "servlet",true);
116 getServer().getContainer().update(this, _servletMappings, null, "servletMapping",true);
117 }
118 if (server!=null && getServer()!=server)
119 {
120 server.getContainer().update(this, null, _filters, "filter",true);
121 server.getContainer().update(this, null, _filterMappings, "filterMapping",true);
122 server.getContainer().update(this, null, _servlets, "servlet",true);
123 server.getContainer().update(this, null, _servletMappings, "servletMapping",true);
124 }
125 super.setServer(server);
126 }
127
128
129 protected synchronized void doStart()
130 throws Exception
131 {
132 _servletContext=ContextHandler.getCurrentContext();
133 _contextHandler=_servletContext==null?null:_servletContext.getContextHandler();
134
135 if (_contextHandler!=null)
136 {
137 SecurityHandler security_handler = (SecurityHandler)_contextHandler.getChildHandlerByClass(SecurityHandler.class);
138 if (security_handler!=null)
139 _identityService=security_handler.getIdentityService();
140 }
141
142 updateNameMappings();
143 updateMappings();
144
145 if(_filterChainsCached)
146 _chainCache= new ConcurrentHashMap[]{null,new ConcurrentHashMap(),new ConcurrentHashMap(),null,new ConcurrentHashMap(),null,null,null,new ConcurrentHashMap(),null,null,null,null,null,null,null,new ConcurrentHashMap()};
147
148 super.doStart();
149
150 if (_contextHandler==null || !(_contextHandler instanceof ServletContextHandler))
151 initialize();
152 }
153
154
155 protected synchronized void doStop()
156 throws Exception
157 {
158 super.doStop();
159
160
161 if (_filters!=null)
162 {
163 for (int i=_filters.length; i-->0;)
164 {
165 try { _filters[i].stop(); }catch(Exception e){Log.warn(Log.EXCEPTION,e);}
166 }
167 }
168
169
170 if (_servlets!=null)
171 {
172 for (int i=_servlets.length; i-->0;)
173 {
174 try { _servlets[i].stop(); }catch(Exception e){Log.warn(Log.EXCEPTION,e);}
175 }
176 }
177
178 _filterPathMappings=null;
179 _filterNameMappings=null;
180
181 _servletPathMap=null;
182 _chainCache=null;
183 }
184
185
186 IdentityService getIdentityService()
187 {
188 return _identityService;
189 }
190
191
192
193
194
195 public Object getContextLog()
196 {
197 return null;
198 }
199
200
201
202
203
204 public FilterMapping[] getFilterMappings()
205 {
206 return _filterMappings;
207 }
208
209
210
211
212
213 public FilterHolder[] getFilters()
214 {
215 return _filters;
216 }
217
218
219
220
221
222
223 public PathMap.Entry getHolderEntry(String pathInContext)
224 {
225 if (_servletPathMap==null)
226 return null;
227 return _servletPathMap.getMatch(pathInContext);
228 }
229
230
231
232
233
234
235
236 public RequestDispatcher getRequestDispatcher(String uriInContext)
237 {
238 if (uriInContext == null)
239 return null;
240
241 if (!uriInContext.startsWith("/"))
242 return null;
243
244 try
245 {
246 String query=null;
247 int q;
248 if ((q=uriInContext.indexOf('?'))>0)
249 {
250 query=uriInContext.substring(q+1);
251 uriInContext=uriInContext.substring(0,q);
252 }
253 if ((q=uriInContext.indexOf(';'))>0)
254 uriInContext=uriInContext.substring(0,q);
255
256 String pathInContext=URIUtil.canonicalPath(URIUtil.decodePath(uriInContext));
257 String uri=URIUtil.addPaths(_contextHandler.getContextPath(), uriInContext);
258 return new Dispatcher(_contextHandler, uri, pathInContext, query);
259 }
260 catch(Exception e)
261 {
262 Log.ignore(e);
263 }
264 return null;
265 }
266
267
268 public ServletContext getServletContext()
269 {
270 return _servletContext;
271 }
272
273
274
275
276 public ServletMapping[] getServletMappings()
277 {
278 return _servletMappings;
279 }
280
281
282
283
284
285 public ServletHolder[] getServlets()
286 {
287 return _servlets;
288 }
289
290
291 public ServletHolder getServlet(String name)
292 {
293 return (ServletHolder)_servletNameMap.get(name);
294 }
295
296
297 @Override
298 public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
299 {
300
301 final String old_servlet_path=baseRequest.getServletPath();
302 final String old_path_info=baseRequest.getPathInfo();
303
304 DispatcherType type = baseRequest.getDispatcherType();
305
306 ServletHolder servlet_holder=null;
307 UserIdentity.Scope old_scope=null;
308
309
310 if (target.startsWith("/"))
311 {
312
313 PathMap.Entry entry=getHolderEntry(target);
314 if (entry!=null)
315 {
316 servlet_holder=(ServletHolder)entry.getValue();
317
318 if(Log.isDebugEnabled())Log.debug("servlet="+servlet_holder);
319
320 String servlet_path_spec=(String)entry.getKey();
321 String servlet_path=entry.getMapped()!=null?entry.getMapped():PathMap.pathMatch(servlet_path_spec,target);
322 String path_info=PathMap.pathInfo(servlet_path_spec,target);
323
324 if (DispatcherType.INCLUDE.equals(type))
325 {
326 baseRequest.setAttribute(Dispatcher.INCLUDE_SERVLET_PATH,servlet_path);
327 baseRequest.setAttribute(Dispatcher.INCLUDE_PATH_INFO, path_info);
328 }
329 else
330 {
331 baseRequest.setServletPath(servlet_path);
332 baseRequest.setPathInfo(path_info);
333 }
334 }
335 }
336 else
337 {
338
339 servlet_holder=(ServletHolder)_servletNameMap.get(target);
340 }
341
342 Log.debug("servlet holder=",servlet_holder);
343
344 try
345 {
346
347 if (servlet_holder!=null)
348 {
349 old_scope=baseRequest.getUserIdentityScope();
350 baseRequest.setUserIdentityScope(servlet_holder);
351
352
353 if (false)
354 nextScope(target,baseRequest,request,response);
355 else if (_nextScope!=null)
356 _nextScope.doScope(target,baseRequest,request, response);
357 else if (_outerScope!=null)
358 _outerScope.doHandle(target,baseRequest,request, response);
359 else
360 doHandle(target,baseRequest,request, response);
361
362 }
363 }
364 finally
365 {
366 if (old_scope!=null)
367 baseRequest.setUserIdentityScope(old_scope);
368
369 if (!(DispatcherType.INCLUDE.equals(type)))
370 {
371 baseRequest.setServletPath(old_servlet_path);
372 baseRequest.setPathInfo(old_path_info);
373 }
374 }
375
376 }
377
378
379
380
381
382 public void doHandle(String target, Request baseRequest,HttpServletRequest request, HttpServletResponse response)
383 throws IOException, ServletException
384 {
385 DispatcherType type = baseRequest.getDispatcherType();
386
387 ServletHolder servlet_holder=(ServletHolder) baseRequest.getUserIdentityScope();
388 FilterChain chain=null;
389
390
391 if (target.startsWith("/"))
392 {
393 if (servlet_holder!=null && _filterMappings!=null && _filterMappings.length>0)
394 chain=getFilterChain(baseRequest, target, servlet_holder);
395 }
396 else
397 {
398 if (servlet_holder!=null)
399 {
400 if (_filterMappings!=null && _filterMappings.length>0)
401 {
402 chain=getFilterChain(baseRequest, null,servlet_holder);
403 }
404 }
405 }
406
407 Log.debug("chain=",chain);
408
409 try
410 {
411
412 if (servlet_holder==null)
413 {
414 notFound(request, response);
415 }
416 else
417 {
418 baseRequest.setHandled(true);
419
420 if (chain!=null)
421 chain.doFilter(request, response);
422 else
423 servlet_holder.handle(baseRequest,request,response);
424 }
425 }
426 catch(EofException e)
427 {
428 throw e;
429 }
430 catch(RuntimeIOException e)
431 {
432 throw e;
433 }
434 catch(ContinuationThrowable e)
435 {
436 throw e;
437 }
438 catch(Exception e)
439 {
440 if (!(DispatcherType.REQUEST.equals(type) || DispatcherType.ASYNC.equals(type)))
441 {
442 if (e instanceof IOException)
443 throw (IOException)e;
444 if (e instanceof RuntimeException)
445 throw (RuntimeException)e;
446 if (e instanceof ServletException)
447 throw (ServletException)e;
448 }
449
450
451 Throwable th=e;
452 if (th instanceof UnavailableException)
453 {
454 Log.debug(th);
455 }
456 else if (th instanceof ServletException)
457 {
458 Log.debug(th);
459 Throwable cause=((ServletException)th).getRootCause();
460 if (cause!=null)
461 th=cause;
462 }
463 else if (th instanceof RuntimeIOException)
464 {
465 Log.debug(th);
466 Throwable cause=(IOException)((RuntimeIOException)th).getCause();
467 if (cause!=null)
468 th=cause;
469 }
470
471
472 if (th instanceof HttpException)
473 throw (HttpException)th;
474 else if (th instanceof RuntimeIOException)
475 throw (RuntimeIOException)th;
476 else if (th instanceof EofException)
477 throw (EofException)th;
478
479 else if (Log.isDebugEnabled())
480 {
481 Log.warn(request.getRequestURI(), th);
482 Log.debug(request.toString());
483 }
484 else if (th instanceof IOException || th instanceof UnavailableException)
485 {
486 Log.debug(request.getRequestURI(),th);
487 }
488 else
489 {
490 Log.warn(request.getRequestURI(),th);
491 }
492
493 if (!response.isCommitted())
494 {
495 request.setAttribute(Dispatcher.ERROR_EXCEPTION_TYPE,th.getClass());
496 request.setAttribute(Dispatcher.ERROR_EXCEPTION,th);
497 if (th instanceof UnavailableException)
498 {
499 UnavailableException ue = (UnavailableException)th;
500 if (ue.isPermanent())
501 response.sendError(HttpServletResponse.SC_NOT_FOUND,th.getMessage());
502 else
503 response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,th.getMessage());
504 }
505 else
506 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,th.getMessage());
507 }
508 else
509 Log.debug("Response already committed for handling "+th);
510 }
511 catch(Error e)
512 {
513 if (!(DispatcherType.REQUEST.equals(type) || DispatcherType.ASYNC.equals(type)))
514 throw e;
515 Log.warn("Error for "+request.getRequestURI(),e);
516 if(Log.isDebugEnabled())Log.debug(request.toString());
517
518
519 if (!response.isCommitted())
520 {
521 request.setAttribute(Dispatcher.ERROR_EXCEPTION_TYPE,e.getClass());
522 request.setAttribute(Dispatcher.ERROR_EXCEPTION,e);
523 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,e.getMessage());
524 }
525 else
526 Log.debug("Response already committed for handling ",e);
527 }
528 }
529
530
531 private FilterChain getFilterChain(Request baseRequest, String pathInContext, ServletHolder servletHolder)
532 {
533 String key=pathInContext==null?servletHolder.getName():pathInContext;
534 int dispatch = FilterMapping.dispatch(baseRequest.getDispatcherType());
535
536 if (_filterChainsCached && _chainCache!=null)
537 {
538 FilterChain chain = (FilterChain)_chainCache[dispatch].get(key);
539 if (chain!=null)
540 return chain;
541 }
542
543
544 Object filters= null;
545
546 if (pathInContext!=null && _filterPathMappings!=null)
547 {
548 for (int i= 0; i < _filterPathMappings.size(); i++)
549 {
550 FilterMapping mapping = (FilterMapping)_filterPathMappings.get(i);
551 if (mapping.appliesTo(pathInContext, dispatch))
552 filters= LazyList.add(filters, mapping.getFilterHolder());
553 }
554 }
555
556
557 if (servletHolder != null && _filterNameMappings!=null && _filterNameMappings.size() > 0)
558 {
559
560 if (_filterNameMappings.size() > 0)
561 {
562 Object o= _filterNameMappings.get(servletHolder.getName());
563 for (int i=0; i<LazyList.size(o);i++)
564 {
565 FilterMapping mapping = (FilterMapping)LazyList.get(o,i);
566 if (mapping.appliesTo(dispatch))
567 filters=LazyList.add(filters,mapping.getFilterHolder());
568 }
569
570 o= _filterNameMappings.get("*");
571 for (int i=0; i<LazyList.size(o);i++)
572 {
573 FilterMapping mapping = (FilterMapping)LazyList.get(o,i);
574 if (mapping.appliesTo(dispatch))
575 filters=LazyList.add(filters,mapping.getFilterHolder());
576 }
577 }
578 }
579
580 if (filters==null)
581 return null;
582
583 FilterChain chain = null;
584 if (_filterChainsCached)
585 {
586 if (LazyList.size(filters) > 0)
587 chain= new CachedChain(filters, servletHolder);
588 if (_maxFilterChainsCacheSize>0 && _chainCache[dispatch].size()>_maxFilterChainsCacheSize)
589 _chainCache[dispatch].clear();
590 _chainCache[dispatch].put(key,chain);
591 }
592 else if (LazyList.size(filters) > 0)
593 chain = new Chain(baseRequest,filters, servletHolder);
594
595 return chain;
596 }
597
598
599
600
601
602
603 public boolean isInitializeAtStart()
604 {
605 return false;
606 }
607
608
609
610
611
612
613 public void setInitializeAtStart(boolean initializeAtStart)
614 {
615 }
616
617
618
619
620
621 public boolean isAvailable()
622 {
623 if (!isStarted())
624 return false;
625 ServletHolder[] holders = getServlets();
626 for (int i=0;i<holders.length;i++)
627 {
628 ServletHolder holder = holders[i];
629 if (holder!=null && !holder.isAvailable())
630 return false;
631 }
632 return true;
633 }
634
635
636
637
638
639 public void setStartWithUnavailable(boolean start)
640 {
641 _startWithUnavailable=start;
642 }
643
644
645
646
647
648 public boolean isStartWithUnavailable()
649 {
650 return _startWithUnavailable;
651 }
652
653
654
655
656
657
658
659 public void initialize()
660 throws Exception
661 {
662 MultiException mx = new MultiException();
663
664
665 if (_filters!=null)
666 {
667 for (int i=0;i<_filters.length; i++)
668 _filters[i].start();
669 }
670
671 if (_servlets!=null)
672 {
673
674 ServletHolder[] servlets = (ServletHolder[])_servlets.clone();
675 Arrays.sort(servlets);
676 for (int i=0; i<servlets.length; i++)
677 {
678 try
679 {
680 if (servlets[i].getClassName()==null && servlets[i].getForcedPath()!=null)
681 {
682 ServletHolder forced_holder = (ServletHolder)_servletPathMap.match(servlets[i].getForcedPath());
683 if (forced_holder==null || forced_holder.getClassName()==null)
684 {
685 mx.add(new IllegalStateException("No forced path servlet for "+servlets[i].getForcedPath()));
686 continue;
687 }
688 servlets[i].setClassName(forced_holder.getClassName());
689 }
690
691 servlets[i].start();
692 }
693 catch(Throwable e)
694 {
695 Log.debug(Log.EXCEPTION,e);
696 mx.add(e);
697 }
698 }
699 mx.ifExceptionThrow();
700 }
701 }
702
703
704
705
706
707 public boolean isFilterChainsCached()
708 {
709 return _filterChainsCached;
710 }
711
712
713
714
715
716 public ServletHolder newServletHolder()
717 {
718 return new ServletHolder();
719 }
720
721
722 public ServletHolder newServletHolder(Class servlet)
723 {
724 return new ServletHolder(servlet);
725 }
726
727
728
729
730
731 public ServletHolder addServletWithMapping (String className,String pathSpec)
732 {
733 ServletHolder holder = newServletHolder(null);
734 holder.setName(className+"-"+holder.hashCode());
735 holder.setClassName(className);
736
737 addServletWithMapping(holder,pathSpec);
738
739 return holder;
740 }
741
742
743
744
745
746 public ServletHolder addServletWithMapping (Class<? extends Servlet> servlet,String pathSpec)
747 {
748 ServletHolder holder = newServletHolder(servlet);
749 setServlets((ServletHolder[])LazyList.addToArray(getServlets(), holder, ServletHolder.class));
750
751 addServletWithMapping(holder,pathSpec);
752
753 return holder;
754 }
755
756
757
758
759
760
761 public void addServletWithMapping (ServletHolder servlet,String pathSpec)
762 {
763 ServletHolder[] holders=getServlets();
764 if (holders!=null)
765 holders = holders.clone();
766
767 try
768 {
769 setServlets((ServletHolder[])LazyList.addToArray(holders, servlet, ServletHolder.class));
770
771 ServletMapping mapping = new ServletMapping();
772 mapping.setServletName(servlet.getName());
773 mapping.setPathSpec(pathSpec);
774 setServletMappings((ServletMapping[])LazyList.addToArray(getServletMappings(), mapping, ServletMapping.class));
775 }
776 catch (Exception e)
777 {
778 setServlets(holders);
779 if (e instanceof RuntimeException)
780 throw (RuntimeException)e;
781 throw new RuntimeException(e);
782 }
783 }
784
785
786
787
788
789
790
791
792 public ServletHolder addServlet (String className, String pathSpec)
793 {
794 return addServletWithMapping (className, pathSpec);
795 }
796
797
798
799
800
801
802 public void addServlet(ServletHolder holder)
803 {
804 setServlets((ServletHolder[])LazyList.addToArray(getServlets(), holder, ServletHolder.class));
805 }
806
807
808
809
810
811 public void addServletMapping (ServletMapping mapping)
812 {
813 setServletMappings((ServletMapping[])LazyList.addToArray(getServletMappings(), mapping, ServletMapping.class));
814 }
815
816
817 public FilterHolder newFilterHolder(Class<? extends Filter> filter)
818 {
819 return new FilterHolder(filter);
820 }
821
822
823
824
825
826 public FilterHolder newFilterHolder()
827 {
828 return new FilterHolder();
829 }
830
831
832 public FilterHolder getFilter(String name)
833 {
834 return (FilterHolder)_filterNameMap.get(name);
835 }
836
837
838
839
840
841
842
843
844 public FilterHolder addFilterWithMapping (Class<? extends Filter> filter,String pathSpec,int dispatches)
845 {
846 FilterHolder holder = newFilterHolder(filter);
847 addFilterWithMapping(holder,pathSpec,dispatches);
848
849 return holder;
850 }
851
852
853
854
855
856
857
858
859 public FilterHolder addFilterWithMapping (String className,String pathSpec,int dispatches)
860 {
861 FilterHolder holder = newFilterHolder(null);
862 holder.setName(className+"-"+holder.hashCode());
863 holder.setClassName(className);
864
865 addFilterWithMapping(holder,pathSpec,dispatches);
866 return holder;
867 }
868
869
870
871
872
873
874
875 public void addFilterWithMapping (FilterHolder holder,String pathSpec,int dispatches)
876 {
877 FilterHolder[] holders = getFilters();
878 if (holders!=null)
879 holders = (FilterHolder[])holders.clone();
880
881 try
882 {
883 setFilters((FilterHolder[])LazyList.addToArray(holders, holder, FilterHolder.class));
884
885 FilterMapping mapping = new FilterMapping();
886 mapping.setFilterName(holder.getName());
887 mapping.setPathSpec(pathSpec);
888 mapping.setDispatches(dispatches);
889 setFilterMappings((FilterMapping[])LazyList.addToArray(getFilterMappings(), mapping, FilterMapping.class));
890 }
891 catch (RuntimeException e)
892 {
893 setFilters(holders);
894 throw e;
895 }
896 catch (Error e)
897 {
898 setFilters(holders);
899 throw e;
900 }
901
902 }
903
904
905
906
907
908
909
910
911
912 public FilterHolder addFilter (String className,String pathSpec,int dispatches)
913 {
914 return addFilterWithMapping(className, pathSpec, dispatches);
915 }
916
917
918
919
920
921
922
923 public void addFilter (FilterHolder filter, FilterMapping filterMapping)
924 {
925 if (filter != null)
926 setFilters((FilterHolder[])LazyList.addToArray(getFilters(), filter, FilterHolder.class));
927 if (filterMapping != null)
928 setFilterMappings((FilterMapping[])LazyList.addToArray(getFilterMappings(), filterMapping, FilterMapping.class));
929 }
930
931
932
933
934
935 public void addFilter (FilterHolder filter)
936 {
937 if (filter != null)
938 setFilters((FilterHolder[])LazyList.addToArray(getFilters(), filter, FilterHolder.class));
939 }
940
941
942
943
944
945 public void addFilterMapping (FilterMapping mapping)
946 {
947 if (mapping != null)
948 setFilterMappings((FilterMapping[])LazyList.addToArray(getFilterMappings(), mapping, FilterMapping.class));
949 }
950
951
952
953
954
955 public void prependFilterMapping (FilterMapping mapping)
956 {
957 if (mapping != null)
958 {
959 FilterMapping[] mappings =getFilterMappings();
960 if (mappings==null || mappings.length==0)
961 setFilterMappings(new FilterMapping[] {mapping});
962 else
963 {
964
965 FilterMapping[] new_mappings=new FilterMapping[mappings.length+1];
966 System.arraycopy(mappings,0,new_mappings,1,mappings.length);
967 new_mappings[0]=mapping;
968 setFilterMappings(new_mappings);
969 }
970 }
971 }
972
973
974 protected synchronized void updateNameMappings()
975 {
976
977 _filterNameMap.clear();
978 if (_filters!=null)
979 {
980 for (int i=0;i<_filters.length;i++)
981 {
982 _filterNameMap.put(_filters[i].getName(),_filters[i]);
983 _filters[i].setServletHandler(this);
984 }
985 }
986
987
988 _servletNameMap.clear();
989 if (_servlets!=null)
990 {
991
992 for (int i=0;i<_servlets.length;i++)
993 {
994 _servletNameMap.put(_servlets[i].getName(),_servlets[i]);
995 _servlets[i].setServletHandler(this);
996 }
997 }
998 }
999
1000
1001 protected synchronized void updateMappings()
1002 {
1003
1004 if (_filterMappings==null)
1005 {
1006 _filterPathMappings=null;
1007 _filterNameMappings=null;
1008 }
1009 else
1010 {
1011 _filterPathMappings=new ArrayList();
1012 _filterNameMappings=new MultiMap();
1013 for (int i=0;i<_filterMappings.length;i++)
1014 {
1015 FilterHolder filter_holder = (FilterHolder)_filterNameMap.get(_filterMappings[i].getFilterName());
1016 if (filter_holder==null)
1017 throw new IllegalStateException("No filter named "+_filterMappings[i].getFilterName());
1018 _filterMappings[i].setFilterHolder(filter_holder);
1019 if (_filterMappings[i].getPathSpecs()!=null)
1020 _filterPathMappings.add(_filterMappings[i]);
1021
1022 if (_filterMappings[i].getServletNames()!=null)
1023 {
1024 String[] names=_filterMappings[i].getServletNames();
1025 for (int j=0;j<names.length;j++)
1026 {
1027 if (names[j]!=null)
1028 _filterNameMappings.add(names[j], _filterMappings[i]);
1029 }
1030 }
1031 }
1032 }
1033
1034
1035 if (_servletMappings==null || _servletNameMap==null)
1036 {
1037 _servletPathMap=null;
1038 }
1039 else
1040 {
1041 PathMap pm = new PathMap();
1042
1043
1044 for (int i=0;i<_servletMappings.length;i++)
1045 {
1046 ServletHolder servlet_holder = (ServletHolder)_servletNameMap.get(_servletMappings[i].getServletName());
1047 if (servlet_holder==null)
1048 throw new IllegalStateException("No such servlet: "+_servletMappings[i].getServletName());
1049 else if (_servletMappings[i].getPathSpecs()!=null)
1050 {
1051 String[] pathSpecs = _servletMappings[i].getPathSpecs();
1052 for (int j=0;j<pathSpecs.length;j++)
1053 if (pathSpecs[j]!=null)
1054 pm.put(pathSpecs[j],servlet_holder);
1055 }
1056 }
1057
1058 _servletPathMap=pm;
1059 }
1060
1061
1062 if (_chainCache!=null)
1063 {
1064 for (int i=_chainCache.length;i-->0;)
1065 {
1066 if (_chainCache[i]!=null)
1067 _chainCache[i].clear();
1068 }
1069 }
1070
1071 if (Log.isDebugEnabled())
1072 {
1073 Log.debug("filterNameMap="+_filterNameMap);
1074 Log.debug("pathFilters="+_filterPathMappings);
1075 Log.debug("servletFilterMap="+_filterNameMappings);
1076 Log.debug("servletPathMap="+_servletPathMap);
1077 Log.debug("servletNameMap="+_servletNameMap);
1078 }
1079
1080 try
1081 {
1082 if (isStarted())
1083 initialize();
1084 }
1085 catch (Exception e)
1086 {
1087 throw new RuntimeException(e);
1088 }
1089 }
1090
1091
1092 protected void notFound(HttpServletRequest request,
1093 HttpServletResponse response)
1094 throws IOException
1095 {
1096 if(Log.isDebugEnabled())Log.debug("Not Found "+request.getRequestURI());
1097 response.sendError(HttpServletResponse.SC_NOT_FOUND);
1098 }
1099
1100
1101
1102
1103
1104 public void setFilterChainsCached(boolean filterChainsCached)
1105 {
1106 _filterChainsCached = filterChainsCached;
1107 }
1108
1109
1110
1111
1112
1113 public void setFilterMappings(FilterMapping[] filterMappings)
1114 {
1115 if (getServer()!=null)
1116 getServer().getContainer().update(this,_filterMappings,filterMappings,"filterMapping",true);
1117 _filterMappings = filterMappings;
1118 updateMappings();
1119 }
1120
1121
1122 public synchronized void setFilters(FilterHolder[] holders)
1123 {
1124 if (getServer()!=null)
1125 getServer().getContainer().update(this,_filters,holders,"filter",true);
1126 _filters=holders;
1127 updateNameMappings();
1128 }
1129
1130
1131
1132
1133
1134 public void setServletMappings(ServletMapping[] servletMappings)
1135 {
1136 if (getServer()!=null)
1137 getServer().getContainer().update(this,_servletMappings,servletMappings,"servletMapping",true);
1138 _servletMappings = servletMappings;
1139 updateMappings();
1140 }
1141
1142
1143
1144
1145
1146 public synchronized void setServlets(ServletHolder[] holders)
1147 {
1148 if (getServer()!=null)
1149 getServer().getContainer().update(this,_servlets,holders,"servlet",true);
1150 _servlets=holders;
1151 updateNameMappings();
1152 }
1153
1154
1155
1156
1157 private class CachedChain implements FilterChain
1158 {
1159 FilterHolder _filterHolder;
1160 CachedChain _next;
1161 ServletHolder _servletHolder;
1162
1163
1164 CachedChain(Object filters, ServletHolder servletHolder)
1165 {
1166 if (LazyList.size(filters)>0)
1167 {
1168 _filterHolder=(FilterHolder)LazyList.get(filters, 0);
1169 filters=LazyList.remove(filters,0);
1170 _next=new CachedChain(filters,servletHolder);
1171 }
1172 else
1173 _servletHolder=servletHolder;
1174 }
1175
1176
1177 public void doFilter(ServletRequest request, ServletResponse response)
1178 throws IOException, ServletException
1179 {
1180
1181 if (_filterHolder!=null)
1182 {
1183 if (Log.isDebugEnabled())
1184 Log.debug("call filter " + _filterHolder);
1185 Filter filter= _filterHolder.getFilter();
1186 if (_filterHolder.isAsyncSupported())
1187 filter.doFilter(request, response, _next);
1188 else
1189 {
1190 final Request baseRequest=(request instanceof Request)?((Request)request):HttpConnection.getCurrentConnection().getRequest();
1191 final boolean suspendable=baseRequest.isAsyncSupported();
1192 if (suspendable)
1193 {
1194 try
1195 {
1196 baseRequest.setAsyncSupported(false);
1197 filter.doFilter(request, response, _next);
1198 }
1199 finally
1200 {
1201 baseRequest.setAsyncSupported(true);
1202 }
1203 }
1204 else
1205 filter.doFilter(request, response, _next);
1206 }
1207 return;
1208 }
1209
1210
1211 if (_servletHolder != null)
1212 {
1213 if (Log.isDebugEnabled())
1214 Log.debug("call servlet " + _servletHolder);
1215 final Request baseRequest=(request instanceof Request)?((Request)request):HttpConnection.getCurrentConnection().getRequest();
1216 _servletHolder.handle(baseRequest,request, response);
1217 }
1218 else
1219 notFound((HttpServletRequest)request, (HttpServletResponse)response);
1220 }
1221
1222 public String toString()
1223 {
1224 if (_filterHolder!=null)
1225 return _filterHolder+"->"+_next.toString();
1226 if (_servletHolder!=null)
1227 return _servletHolder.toString();
1228 return "null";
1229 }
1230 }
1231
1232
1233
1234 private class Chain implements FilterChain
1235 {
1236 final Request _baseRequest;
1237 final Object _chain;
1238 final ServletHolder _servletHolder;
1239 int _filter= 0;
1240
1241
1242 Chain(Request baseRequest, Object filters, ServletHolder servletHolder)
1243 {
1244 _baseRequest=baseRequest;
1245 _chain= filters;
1246 _servletHolder= servletHolder;
1247 }
1248
1249
1250 public void doFilter(ServletRequest request, ServletResponse response)
1251 throws IOException, ServletException
1252 {
1253 if (Log.isDebugEnabled()) Log.debug("doFilter " + _filter);
1254
1255
1256 if (_filter < LazyList.size(_chain))
1257 {
1258 FilterHolder holder= (FilterHolder)LazyList.get(_chain, _filter++);
1259 if (Log.isDebugEnabled()) Log.debug("call filter " + holder);
1260 Filter filter= holder.getFilter();
1261
1262 if (holder.isAsyncSupported() || !_baseRequest.isAsyncSupported())
1263 {
1264 filter.doFilter(request, response, this);
1265 }
1266 else
1267 {
1268 try
1269 {
1270 _baseRequest.setAsyncSupported(false);
1271 filter.doFilter(request, response, this);
1272 }
1273 finally
1274 {
1275 _baseRequest.setAsyncSupported(true);
1276 }
1277 }
1278
1279 return;
1280 }
1281
1282
1283 if (_servletHolder != null)
1284 {
1285 if (Log.isDebugEnabled()) Log.debug("call servlet " + _servletHolder);
1286 _servletHolder.handle(_baseRequest,request, response);
1287 }
1288 else
1289 notFound((HttpServletRequest)request, (HttpServletResponse)response);
1290 }
1291
1292
1293 public String toString()
1294 {
1295 StringBuilder b = new StringBuilder();
1296 for (int i=0; i<LazyList.size(_chain);i++)
1297 {
1298 Object o=LazyList.get(_chain, i);
1299 b.append(o.toString());
1300 b.append("->");
1301 }
1302 b.append(_servletHolder);
1303 return b.toString();
1304 }
1305 }
1306
1307
1308
1309
1310
1311 public int getMaxFilterChainsCacheSize()
1312 {
1313 return _maxFilterChainsCacheSize;
1314 }
1315
1316
1317
1318
1319
1320
1321
1322
1323 public void setMaxFilterChainsCacheSize(int maxFilterChainsCacheSize)
1324 {
1325 _maxFilterChainsCacheSize = maxFilterChainsCacheSize;
1326 }
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339 public Servlet customizeServlet (Servlet servlet)
1340 throws Exception
1341 {
1342 return servlet;
1343 }
1344
1345
1346 public Servlet customizeServletDestroy (Servlet servlet)
1347 throws Exception
1348 {
1349 return servlet;
1350 }
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364 public Filter customizeFilter (Filter filter)
1365 throws Exception
1366 {
1367 return filter;
1368 }
1369
1370
1371 public Filter customizeFilterDestroy (Filter filter)
1372 throws Exception
1373 {
1374 return filter;
1375 }
1376
1377
1378
1379
1380 protected void dump(StringBuilder b,String indent)
1381 {
1382 super.dump(b,indent);
1383
1384 if (getFilterMappings()!=null)
1385 {
1386 for (FilterMapping f : getFilterMappings())
1387 {
1388 b.append(indent);
1389 b.append(" +-");
1390 b.append(f);
1391 b.append('\n');
1392 }
1393 }
1394 HashSet<String> servlets = new HashSet<String>();
1395 if (getServletMappings()!=null)
1396 {
1397 for (ServletMapping m : getServletMappings())
1398 {
1399 servlets.add(m.getServletName());
1400 b.append(indent);
1401 b.append(" +-");
1402 b.append(m);
1403 b.append('\n');
1404 }
1405 }
1406
1407 if (getServlets()!=null)
1408 {
1409 for (ServletHolder h : getServlets())
1410 {
1411 if (servlets.contains(h.getName()))
1412 continue;
1413 b.append(indent);
1414 b.append(" +-[]==>");
1415 b.append(h.getName());
1416 b.append('\n');
1417 }
1418 }
1419
1420 }
1421
1422
1423 }