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