1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.webapp;
20
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.EnumSet;
24 import java.util.EventListener;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.ListIterator;
30 import java.util.Locale;
31 import java.util.Map;
32 import java.util.Set;
33
34 import javax.servlet.DispatcherType;
35 import javax.servlet.MultipartConfigElement;
36 import javax.servlet.ServletException;
37 import javax.servlet.SessionTrackingMode;
38
39 import org.eclipse.jetty.security.ConstraintAware;
40 import org.eclipse.jetty.security.ConstraintMapping;
41 import org.eclipse.jetty.security.authentication.FormAuthenticator;
42 import org.eclipse.jetty.servlet.BaseHolder.Source;
43 import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
44 import org.eclipse.jetty.servlet.FilterHolder;
45 import org.eclipse.jetty.servlet.FilterMapping;
46 import org.eclipse.jetty.servlet.ListenerHolder;
47 import org.eclipse.jetty.servlet.ServletContextHandler.JspConfig;
48 import org.eclipse.jetty.servlet.ServletContextHandler.JspPropertyGroup;
49 import org.eclipse.jetty.servlet.ServletContextHandler.TagLib;
50 import org.eclipse.jetty.servlet.ServletHolder;
51 import org.eclipse.jetty.servlet.ServletMapping;
52 import org.eclipse.jetty.util.ArrayUtil;
53 import org.eclipse.jetty.util.Loader;
54 import org.eclipse.jetty.util.log.Log;
55 import org.eclipse.jetty.util.log.Logger;
56 import org.eclipse.jetty.util.security.Constraint;
57 import org.eclipse.jetty.xml.XmlParser;
58 import org.eclipse.jetty.xml.XmlParser.Node;
59
60
61
62
63
64
65 public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
66 {
67 private static final Logger LOG = Log.getLogger(StandardDescriptorProcessor.class);
68
69 public static final String STANDARD_PROCESSOR = "org.eclipse.jetty.standardDescriptorProcessor";
70
71 final Map<String,FilterHolder> _filterHolderMap = new HashMap<>();
72 final List<FilterHolder> _filterHolders = new ArrayList<>();
73 final List<FilterMapping> _filterMappings = new ArrayList<>();
74 final Map<String,ServletHolder> _servletHolderMap = new HashMap<>();
75 final List<ServletHolder> _servletHolders = new ArrayList<>();
76 final List<ServletMapping> _servletMappings = new ArrayList<>();
77
78 public StandardDescriptorProcessor ()
79 {
80 try
81 {
82 registerVisitor("context-param", this.getClass().getMethod("visitContextParam", __signature));
83 registerVisitor("display-name", this.getClass().getMethod("visitDisplayName", __signature));
84 registerVisitor("servlet", this.getClass().getMethod("visitServlet", __signature));
85 registerVisitor("servlet-mapping", this.getClass().getMethod("visitServletMapping", __signature));
86 registerVisitor("session-config", this.getClass().getMethod("visitSessionConfig", __signature));
87 registerVisitor("mime-mapping", this.getClass().getMethod("visitMimeMapping", __signature));
88 registerVisitor("welcome-file-list", this.getClass().getMethod("visitWelcomeFileList", __signature));
89 registerVisitor("locale-encoding-mapping-list", this.getClass().getMethod("visitLocaleEncodingList", __signature));
90 registerVisitor("error-page", this.getClass().getMethod("visitErrorPage", __signature));
91 registerVisitor("taglib", this.getClass().getMethod("visitTagLib", __signature));
92 registerVisitor("jsp-config", this.getClass().getMethod("visitJspConfig", __signature));
93 registerVisitor("security-constraint", this.getClass().getMethod("visitSecurityConstraint", __signature));
94 registerVisitor("login-config", this.getClass().getMethod("visitLoginConfig", __signature));
95 registerVisitor("security-role", this.getClass().getMethod("visitSecurityRole", __signature));
96 registerVisitor("filter", this.getClass().getMethod("visitFilter", __signature));
97 registerVisitor("filter-mapping", this.getClass().getMethod("visitFilterMapping", __signature));
98 registerVisitor("listener", this.getClass().getMethod("visitListener", __signature));
99 registerVisitor("distributable", this.getClass().getMethod("visitDistributable", __signature));
100 registerVisitor("deny-uncovered-http-methods", this.getClass().getMethod("visitDenyUncoveredHttpMethods", __signature));
101 }
102 catch (Exception e)
103 {
104 throw new IllegalStateException(e);
105 }
106 }
107
108
109
110
111
112
113 public void start(WebAppContext context, Descriptor descriptor)
114 {
115 for (FilterHolder h : context.getServletHandler().getFilters())
116 {
117 _filterHolderMap.put(h.getName(),h);
118 _filterHolders.add(h);
119 }
120 if (context.getServletHandler().getFilterMappings()!=null)
121 _filterMappings.addAll(Arrays.asList(context.getServletHandler().getFilterMappings()));
122 for (ServletHolder h : context.getServletHandler().getServlets())
123 {
124 _servletHolderMap.put(h.getName(),h);
125 _servletHolders.add(h);
126 }
127 if (context.getServletHandler().getServletMappings()!=null)
128 _servletMappings.addAll(Arrays.asList(context.getServletHandler().getServletMappings()));
129 }
130
131
132
133
134
135 public void end(WebAppContext context, Descriptor descriptor)
136 {
137 context.getServletHandler().setFilters(_filterHolders.toArray(new FilterHolder[_filterHolderMap.size()]));
138 context.getServletHandler().setServlets(_servletHolders.toArray(new ServletHolder[_servletHolderMap.size()]));
139
140 context.getServletHandler().setFilterMappings(_filterMappings.toArray(new FilterMapping[_filterMappings.size()]));
141 context.getServletHandler().setServletMappings(_servletMappings.toArray(new ServletMapping[_servletMappings.size()]));
142
143 _filterHolderMap.clear();
144 _filterHolders.clear();
145 _filterMappings.clear();
146 _servletHolderMap.clear();
147 _servletHolders.clear();
148 _servletMappings.clear();
149 }
150
151
152
153
154
155
156 public void visitContextParam (WebAppContext context, Descriptor descriptor, XmlParser.Node node)
157 {
158 String name = node.getString("param-name", false, true);
159 String value = node.getString("param-value", false, true);
160 switch (context.getMetaData().getOrigin("context-param."+name))
161 {
162 case NotSet:
163 {
164
165 context.getInitParams().put(name, value);
166 context.getMetaData().setOrigin("context-param."+name, descriptor);
167 break;
168 }
169 case WebXml:
170 case WebDefaults:
171 case WebOverride:
172 {
173
174 if (!(descriptor instanceof FragmentDescriptor))
175 {
176 context.getInitParams().put(name, value);
177 context.getMetaData().setOrigin("context-param."+name, descriptor);
178 }
179 break;
180 }
181 case WebFragment:
182 {
183
184 if (descriptor instanceof FragmentDescriptor)
185 {
186 if (!((String)context.getInitParams().get(name)).equals(value))
187 throw new IllegalStateException("Conflicting context-param "+name+"="+value+" in "+descriptor.getResource());
188 }
189 break;
190 }
191 default:
192 LOG.warn(new Throwable());
193 }
194 if (LOG.isDebugEnabled())
195 LOG.debug("ContextParam: " + name + "=" + value);
196
197 }
198
199
200
201
202
203
204
205
206 public void visitDisplayName(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
207 {
208
209 if (!(descriptor instanceof FragmentDescriptor))
210 {
211 context.setDisplayName(node.toString(false, true));
212 context.getMetaData().setOrigin("display-name", descriptor);
213 }
214 }
215
216
217
218
219
220
221
222 public void visitServlet(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
223 {
224 String id = node.getAttribute("id");
225
226
227 String name = node.getString("servlet-name", false, true);
228 ServletHolder holder = _servletHolderMap.get(name);
229
230
231 if (holder == null)
232 {
233 holder = context.getServletHandler().newServletHolder(Source.DESCRIPTOR);
234 holder.setName(name);
235 _servletHolderMap.put(name,holder);
236 _servletHolders.add(holder);
237 }
238
239
240 Iterator<?> iParamsIter = node.iterator("init-param");
241 while (iParamsIter.hasNext())
242 {
243 XmlParser.Node paramNode = (XmlParser.Node) iParamsIter.next();
244 String pname = paramNode.getString("param-name", false, true);
245 String pvalue = paramNode.getString("param-value", false, true);
246 String originName = name+".servlet.init-param."+pname;
247
248 Descriptor originDescriptor = context.getMetaData().getOriginDescriptor(originName);
249 switch (context.getMetaData().getOrigin(originName))
250 {
251 case NotSet:
252 {
253
254 holder.setInitParameter(pname, pvalue);
255 context.getMetaData().setOrigin(originName, descriptor);
256 break;
257 }
258 case WebXml:
259 case WebDefaults:
260 case WebOverride:
261 {
262
263
264
265 if (!(descriptor instanceof FragmentDescriptor) && (descriptor!=originDescriptor))
266 {
267 holder.setInitParameter(pname, pvalue);
268 context.getMetaData().setOrigin(originName, descriptor);
269 }
270 break;
271 }
272 case WebFragment:
273 {
274
275 if ((descriptor != originDescriptor) && !holder.getInitParameter(pname).equals(pvalue))
276 throw new IllegalStateException("Mismatching init-param "+pname+"="+pvalue+" in "+descriptor.getResource());
277 break;
278 }
279 default:
280 LOG.warn(new Throwable());
281 }
282 }
283
284 String servlet_class = node.getString("servlet-class", false, true);
285 if ("".equals(servlet_class))
286 servlet_class = null;
287
288
289 if (id != null && id.equals("jsp") && servlet_class != null)
290 {
291 try
292 {
293 Loader.loadClass(this.getClass(), servlet_class);
294 }
295 catch (ClassNotFoundException e)
296 {
297 LOG.info("NO JSP Support for {}, did not find {}", context.getContextPath(), servlet_class);
298 servlet_class = "org.eclipse.jetty.servlet.NoJspServlet";
299 }
300 }
301
302
303
304 if (servlet_class != null)
305 {
306 ((WebDescriptor)descriptor).addClassName(servlet_class);
307 switch (context.getMetaData().getOrigin(name+".servlet.servlet-class"))
308 {
309 case NotSet:
310 {
311
312 holder.setClassName(servlet_class);
313 context.getMetaData().setOrigin(name+".servlet.servlet-class", descriptor);
314 break;
315 }
316 case WebXml:
317 case WebDefaults:
318 case WebOverride:
319 {
320
321 if (!(descriptor instanceof FragmentDescriptor))
322 {
323 holder.setClassName(servlet_class);
324 context.getMetaData().setOrigin(name+".servlet.servlet-class", descriptor);
325 }
326 break;
327 }
328 case WebFragment:
329 {
330
331 if (!servlet_class.equals(holder.getClassName()))
332 throw new IllegalStateException("Conflicting servlet-class "+servlet_class+" in "+descriptor.getResource());
333 break;
334 }
335 default:
336 LOG.warn(new Throwable());
337 }
338 }
339
340
341 String jsp_file = node.getString("jsp-file", false, true);
342 if (jsp_file != null)
343 holder.setForcedPath(jsp_file);
344
345
346 XmlParser.Node startup = node.get("load-on-startup");
347 if (startup != null)
348 {
349 String s = startup.toString(false, true).toLowerCase(Locale.ENGLISH);
350 int order = 0;
351 if (s.startsWith("t"))
352 {
353 LOG.warn("Deprecated boolean load-on-startup. Please use integer");
354 order = 1;
355 }
356 else
357 {
358 try
359 {
360 if (s != null && s.trim().length() > 0) order = Integer.parseInt(s);
361 }
362 catch (Exception e)
363 {
364 LOG.warn("Cannot parse load-on-startup " + s + ". Please use integer");
365 LOG.ignore(e);
366 }
367 }
368
369 switch (context.getMetaData().getOrigin(name+".servlet.load-on-startup"))
370 {
371 case NotSet:
372 {
373
374 holder.setInitOrder(order);
375 context.getMetaData().setOrigin(name+".servlet.load-on-startup", descriptor);
376 break;
377 }
378 case WebXml:
379 case WebDefaults:
380 case WebOverride:
381 {
382
383 if (!(descriptor instanceof FragmentDescriptor))
384 {
385 holder.setInitOrder(order);
386 context.getMetaData().setOrigin(name+".servlet.load-on-startup", descriptor);
387 }
388 break;
389 }
390 case WebFragment:
391 {
392
393 if (order != holder.getInitOrder())
394 throw new IllegalStateException("Conflicting load-on-startup value in "+descriptor.getResource());
395 break;
396 }
397 default:
398 LOG.warn(new Throwable());
399 }
400 }
401
402 Iterator<Node> sRefsIter = node.iterator("security-role-ref");
403 while (sRefsIter.hasNext())
404 {
405 XmlParser.Node securityRef = (XmlParser.Node) sRefsIter.next();
406 String roleName = securityRef.getString("role-name", false, true);
407 String roleLink = securityRef.getString("role-link", false, true);
408 if (roleName != null && roleName.length() > 0 && roleLink != null && roleLink.length() > 0)
409 {
410 if (LOG.isDebugEnabled()) LOG.debug("link role " + roleName + " to " + roleLink + " for " + this);
411 switch (context.getMetaData().getOrigin(name+".servlet.role-name."+roleName))
412 {
413 case NotSet:
414 {
415
416 holder.setUserRoleLink(roleName, roleLink);
417 context.getMetaData().setOrigin(name+".servlet.role-name."+roleName, descriptor);
418 break;
419 }
420 case WebXml:
421 case WebDefaults:
422 case WebOverride:
423 {
424
425 if (!(descriptor instanceof FragmentDescriptor))
426 {
427 holder.setUserRoleLink(roleName, roleLink);
428 context.getMetaData().setOrigin(name+".servlet.role-name."+roleName, descriptor);
429 }
430 break;
431 }
432 case WebFragment:
433 {
434 if (!holder.getUserRoleLink(roleName).equals(roleLink))
435 throw new IllegalStateException("Conflicting role-link for role-name "+roleName+" for servlet "+name+" in "+descriptor.getResource());
436 break;
437 }
438 default:
439 LOG.warn(new Throwable());
440 }
441 }
442 else
443 {
444 LOG.warn("Ignored invalid security-role-ref element: " + "servlet-name=" + holder.getName() + ", " + securityRef);
445 }
446 }
447
448
449 XmlParser.Node run_as = node.get("run-as");
450 if (run_as != null)
451 {
452 String roleName = run_as.getString("role-name", false, true);
453
454 if (roleName != null)
455 {
456 switch (context.getMetaData().getOrigin(name+".servlet.run-as"))
457 {
458 case NotSet:
459 {
460
461 holder.setRunAsRole(roleName);
462 context.getMetaData().setOrigin(name+".servlet.run-as", descriptor);
463 break;
464 }
465 case WebXml:
466 case WebDefaults:
467 case WebOverride:
468 {
469
470 if (!(descriptor instanceof FragmentDescriptor))
471 {
472 holder.setRunAsRole(roleName);
473 context.getMetaData().setOrigin(name+".servlet.run-as", descriptor);
474 }
475 break;
476 }
477 case WebFragment:
478 {
479
480 if (!holder.getRunAsRole().equals(roleName))
481 throw new IllegalStateException("Conflicting run-as role "+roleName+" for servlet "+name+" in "+descriptor.getResource());
482 break;
483 }
484 default:
485 LOG.warn(new Throwable());
486 }
487 }
488 }
489
490 String async=node.getString("async-supported",false,true);
491 if (async!=null)
492 {
493 boolean val = async.length()==0||Boolean.valueOf(async);
494 switch (context.getMetaData().getOrigin(name+".servlet.async-supported"))
495 {
496 case NotSet:
497 {
498
499 holder.setAsyncSupported(val);
500 context.getMetaData().setOrigin(name+".servlet.async-supported", descriptor);
501 break;
502 }
503 case WebXml:
504 case WebDefaults:
505 case WebOverride:
506 {
507
508 if (!(descriptor instanceof FragmentDescriptor))
509 {
510 holder.setAsyncSupported(val);
511 context.getMetaData().setOrigin(name+".servlet.async-supported", descriptor);
512 }
513 break;
514 }
515 case WebFragment:
516 {
517
518 if (holder.isAsyncSupported() != val)
519 throw new IllegalStateException("Conflicting async-supported="+async+" for servlet "+name+" in "+descriptor.getResource());
520 break;
521 }
522 default:
523 LOG.warn(new Throwable());
524 }
525 }
526
527 String enabled = node.getString("enabled", false, true);
528 if (enabled!=null)
529 {
530 boolean is_enabled = enabled.length()==0||Boolean.valueOf(enabled);
531 switch (context.getMetaData().getOrigin(name+".servlet.enabled"))
532 {
533 case NotSet:
534 {
535
536 holder.setEnabled(is_enabled);
537 context.getMetaData().setOrigin(name+".servlet.enabled", descriptor);
538 break;
539 }
540 case WebXml:
541 case WebDefaults:
542 case WebOverride:
543 {
544
545 if (!(descriptor instanceof FragmentDescriptor))
546 {
547 holder.setEnabled(is_enabled);
548 context.getMetaData().setOrigin(name+".servlet.enabled", descriptor);
549 }
550 break;
551 }
552 case WebFragment:
553 {
554
555 if (holder.isEnabled() != is_enabled)
556 throw new IllegalStateException("Conflicting value of servlet enabled for servlet "+name+" in "+descriptor.getResource());
557 break;
558 }
559 default:
560 LOG.warn(new Throwable());
561 }
562 }
563
564
565
566
567
568
569 XmlParser.Node multipart = node.get("multipart-config");
570 if (multipart != null)
571 {
572 String location = multipart.getString("location", false, true);
573 String maxFile = multipart.getString("max-file-size", false, true);
574 String maxRequest = multipart.getString("max-request-size", false, true);
575 String threshold = multipart.getString("file-size-threshold",false,true);
576 MultipartConfigElement element = new MultipartConfigElement(location,
577 (maxFile==null||"".equals(maxFile)?-1L:Long.parseLong(maxFile)),
578 (maxRequest==null||"".equals(maxRequest)?-1L:Long.parseLong(maxRequest)),
579 (threshold==null||"".equals(threshold)?0:Integer.parseInt(threshold)));
580
581 switch (context.getMetaData().getOrigin(name+".servlet.multipart-config"))
582 {
583 case NotSet:
584 {
585
586 holder.getRegistration().setMultipartConfig(element);
587 context.getMetaData().setOrigin(name+".servlet.multipart-config", descriptor);
588 break;
589 }
590 case WebXml:
591 case WebDefaults:
592 case WebOverride:
593 {
594
595 if (!(descriptor instanceof FragmentDescriptor))
596 {
597 holder.getRegistration().setMultipartConfig(element);
598 context.getMetaData().setOrigin(name+".servlet.multipart-config", descriptor);
599 }
600 break;
601 }
602 case WebFragment:
603 {
604
605 MultipartConfigElement cfg = ((ServletHolder.Registration)holder.getRegistration()).getMultipartConfig();
606
607 if (cfg.getMaxFileSize() != element.getMaxFileSize())
608 throw new IllegalStateException("Conflicting multipart-config max-file-size for servlet "+name+" in "+descriptor.getResource());
609 if (cfg.getMaxRequestSize() != element.getMaxRequestSize())
610 throw new IllegalStateException("Conflicting multipart-config max-request-size for servlet "+name+" in "+descriptor.getResource());
611 if (cfg.getFileSizeThreshold() != element.getFileSizeThreshold())
612 throw new IllegalStateException("Conflicting multipart-config file-size-threshold for servlet "+name+" in "+descriptor.getResource());
613 if ((cfg.getLocation() != null && (element.getLocation() == null || element.getLocation().length()==0))
614 || (cfg.getLocation() == null && (element.getLocation()!=null || element.getLocation().length() > 0)))
615 throw new IllegalStateException("Conflicting multipart-config location for servlet "+name+" in "+descriptor.getResource());
616 break;
617 }
618 default:
619 LOG.warn(new Throwable());
620 }
621 }
622 }
623
624
625
626
627
628
629
630
631 public void visitServletMapping(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
632 {
633
634
635
636
637
638
639 String servlet_name = node.getString("servlet-name", false, true);
640 switch (context.getMetaData().getOrigin(servlet_name+".servlet.mappings"))
641 {
642 case NotSet:
643 {
644
645 context.getMetaData().setOrigin(servlet_name+".servlet.mappings", descriptor);
646 addServletMapping(servlet_name, node, context, descriptor);
647 break;
648 }
649 case WebDefaults:
650 case WebXml:
651 case WebOverride:
652 {
653
654
655 if (!(descriptor instanceof FragmentDescriptor))
656 {
657 addServletMapping(servlet_name, node, context, descriptor);
658 }
659 break;
660 }
661 case WebFragment:
662 {
663
664 addServletMapping(servlet_name, node, context, descriptor);
665 break;
666 }
667 default:
668 LOG.warn(new Throwable());
669 }
670 }
671
672
673
674
675
676
677
678 public void visitSessionConfig(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
679 {
680 XmlParser.Node tNode = node.get("session-timeout");
681 if (tNode != null)
682 {
683 int timeout = Integer.parseInt(tNode.toString(false, true));
684 context.getSessionHandler().getSessionManager().setMaxInactiveInterval(timeout * 60);
685 }
686
687
688
689
690 Iterator<Node> iter = node.iterator("tracking-mode");
691 if (iter.hasNext())
692 {
693 Set<SessionTrackingMode> modes = null;
694 Origin o = context.getMetaData().getOrigin("session.tracking-mode");
695 switch (o)
696 {
697 case NotSet:
698 case WebDefaults:
699 {
700
701 modes = new HashSet<SessionTrackingMode>();
702 context.getMetaData().setOrigin("session.tracking-mode", descriptor);
703 break;
704 }
705 case WebXml:
706 case WebFragment:
707 case WebOverride:
708 {
709
710 if (descriptor instanceof OverrideDescriptor)
711 modes = new HashSet<SessionTrackingMode>();
712 else
713 modes = new HashSet<SessionTrackingMode>(context.getSessionHandler().getSessionManager().getEffectiveSessionTrackingModes());
714 context.getMetaData().setOrigin("session.tracking-mode", descriptor);
715 break;
716 }
717 default:
718 LOG.warn(new Throwable());
719 }
720
721 while (iter.hasNext())
722 {
723 XmlParser.Node mNode = (XmlParser.Node) iter.next();
724 String trackMode = mNode.toString(false, true);
725 modes.add(SessionTrackingMode.valueOf(trackMode));
726 }
727 context.getSessionHandler().getSessionManager().setSessionTrackingModes(modes);
728 }
729
730
731
732
733 XmlParser.Node cookieConfig = node.get("cookie-config");
734 if (cookieConfig != null)
735 {
736
737 String name = cookieConfig.getString("name", false, true);
738 if (name != null)
739 {
740 switch (context.getMetaData().getOrigin("cookie-config.name"))
741 {
742 case NotSet:
743 {
744
745 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setName(name);
746 context.getMetaData().setOrigin("cookie-config.name", descriptor);
747 break;
748 }
749 case WebXml:
750 case WebDefaults:
751 case WebOverride:
752 {
753
754 if (!(descriptor instanceof FragmentDescriptor))
755 {
756 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setName(name);
757 context.getMetaData().setOrigin("cookie-config.name", descriptor);
758 }
759 break;
760 }
761 case WebFragment:
762 {
763
764 if (!context.getSessionHandler().getSessionManager().getSessionCookieConfig().getName().equals(name))
765 throw new IllegalStateException("Conflicting cookie-config name "+name+" in "+descriptor.getResource());
766 break;
767 }
768 default:
769 LOG.warn(new Throwable());
770 }
771 }
772
773
774 String domain = cookieConfig.getString("domain", false, true);
775 if (domain != null)
776 {
777 switch (context.getMetaData().getOrigin("cookie-config.domain"))
778 {
779 case NotSet:
780 {
781
782 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setDomain(domain);
783 context.getMetaData().setOrigin("cookie-config.domain", descriptor);
784 break;
785 }
786 case WebXml:
787 case WebDefaults:
788 case WebOverride:
789 {
790
791 if (!(descriptor instanceof FragmentDescriptor))
792 {
793 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setDomain(domain);
794 context.getMetaData().setOrigin("cookie-config.domain", descriptor);
795 }
796 break;
797 }
798 case WebFragment:
799 {
800
801 if (!context.getSessionHandler().getSessionManager().getSessionCookieConfig().getDomain().equals(domain))
802 throw new IllegalStateException("Conflicting cookie-config domain "+domain+" in "+descriptor.getResource());
803 break;
804 }
805 default:
806 LOG.warn(new Throwable());
807 }
808 }
809
810
811 String path = cookieConfig.getString("path", false, true);
812 if (path != null)
813 {
814 switch (context.getMetaData().getOrigin("cookie-config.path"))
815 {
816 case NotSet:
817 {
818
819 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setPath(path);
820 context.getMetaData().setOrigin("cookie-config.path", descriptor);
821 break;
822 }
823 case WebXml:
824 case WebDefaults:
825 case WebOverride:
826 {
827
828 if (!(descriptor instanceof FragmentDescriptor))
829 {
830 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setPath(path);
831 context.getMetaData().setOrigin("cookie-config.path", descriptor);
832 }
833 break;
834 }
835 case WebFragment:
836 {
837
838 if (!context.getSessionHandler().getSessionManager().getSessionCookieConfig().getPath().equals(path))
839 throw new IllegalStateException("Conflicting cookie-config path "+path+" in "+descriptor.getResource());
840 break;
841 }
842 default:
843 LOG.warn(new Throwable());
844 }
845 }
846
847
848 String comment = cookieConfig.getString("comment", false, true);
849 if (comment != null)
850 {
851 switch (context.getMetaData().getOrigin("cookie-config.comment"))
852 {
853 case NotSet:
854 {
855
856 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setComment(comment);
857 context.getMetaData().setOrigin("cookie-config.comment", descriptor);
858 break;
859 }
860 case WebXml:
861 case WebDefaults:
862 case WebOverride:
863 {
864
865 if (!(descriptor instanceof FragmentDescriptor))
866 {
867 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setComment(comment);
868 context.getMetaData().setOrigin("cookie-config.comment", descriptor);
869 }
870 break;
871 }
872 case WebFragment:
873 {
874
875 if (!context.getSessionHandler().getSessionManager().getSessionCookieConfig().getComment().equals(comment))
876 throw new IllegalStateException("Conflicting cookie-config comment "+comment+" in "+descriptor.getResource());
877 break;
878 }
879 default:
880 LOG.warn(new Throwable());
881 }
882 }
883
884
885 tNode = cookieConfig.get("http-only");
886 if (tNode != null)
887 {
888 boolean httpOnly = Boolean.parseBoolean(tNode.toString(false,true));
889 switch (context.getMetaData().getOrigin("cookie-config.http-only"))
890 {
891 case NotSet:
892 {
893
894 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setHttpOnly(httpOnly);
895 context.getMetaData().setOrigin("cookie-config.http-only", descriptor);
896 break;
897 }
898 case WebXml:
899 case WebDefaults:
900 case WebOverride:
901 {
902
903 if (!(descriptor instanceof FragmentDescriptor))
904 {
905 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setHttpOnly(httpOnly);
906 context.getMetaData().setOrigin("cookie-config.http-only", descriptor);
907 }
908 break;
909 }
910 case WebFragment:
911 {
912
913 if (context.getSessionHandler().getSessionManager().getSessionCookieConfig().isHttpOnly() != httpOnly)
914 throw new IllegalStateException("Conflicting cookie-config http-only "+httpOnly+" in "+descriptor.getResource());
915 break;
916 }
917 default:
918 LOG.warn(new Throwable());
919 }
920 }
921
922
923 tNode = cookieConfig.get("secure");
924 if (tNode != null)
925 {
926 boolean secure = Boolean.parseBoolean(tNode.toString(false,true));
927 switch (context.getMetaData().getOrigin("cookie-config.secure"))
928 {
929 case NotSet:
930 {
931
932 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setSecure(secure);
933 context.getMetaData().setOrigin("cookie-config.secure", descriptor);
934 break;
935 }
936 case WebXml:
937 case WebDefaults:
938 case WebOverride:
939 {
940
941 if (!(descriptor instanceof FragmentDescriptor))
942 {
943 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setSecure(secure);
944 context.getMetaData().setOrigin("cookie-config.secure", descriptor);
945 }
946 break;
947 }
948 case WebFragment:
949 {
950
951 if (context.getSessionHandler().getSessionManager().getSessionCookieConfig().isSecure() != secure)
952 throw new IllegalStateException("Conflicting cookie-config secure "+secure+" in "+descriptor.getResource());
953 break;
954 }
955 default:
956 LOG.warn(new Throwable());
957 }
958 }
959
960
961 tNode = cookieConfig.get("max-age");
962 if (tNode != null)
963 {
964 int maxAge = Integer.parseInt(tNode.toString(false,true));
965 switch (context.getMetaData().getOrigin("cookie-config.max-age"))
966 {
967 case NotSet:
968 {
969
970 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setMaxAge(maxAge);
971 context.getMetaData().setOrigin("cookie-config.max-age", descriptor);
972 break;
973 }
974 case WebXml:
975 case WebDefaults:
976 case WebOverride:
977 {
978
979 if (!(descriptor instanceof FragmentDescriptor))
980 {
981 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setMaxAge(maxAge);
982 context.getMetaData().setOrigin("cookie-config.max-age", descriptor);
983 }
984 break;
985 }
986 case WebFragment:
987 {
988
989 if (context.getSessionHandler().getSessionManager().getSessionCookieConfig().getMaxAge() != maxAge)
990 throw new IllegalStateException("Conflicting cookie-config max-age "+maxAge+" in "+descriptor.getResource());
991 break;
992 }
993 default:
994 LOG.warn(new Throwable());
995 }
996 }
997 }
998 }
999
1000
1001
1002
1003
1004
1005
1006
1007 public void visitMimeMapping(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1008 {
1009 String extension = node.getString("extension", false, true);
1010 if (extension != null && extension.startsWith("."))
1011 extension = extension.substring(1);
1012 String mimeType = node.getString("mime-type", false, true);
1013 if (extension != null)
1014 {
1015 switch (context.getMetaData().getOrigin("extension."+extension))
1016 {
1017 case NotSet:
1018 {
1019
1020 context.getMimeTypes().addMimeMapping(extension, mimeType);
1021 context.getMetaData().setOrigin("extension."+extension, descriptor);
1022 break;
1023 }
1024 case WebXml:
1025 case WebDefaults:
1026 case WebOverride:
1027 {
1028
1029 if (!(descriptor instanceof FragmentDescriptor))
1030 {
1031 context.getMimeTypes().addMimeMapping(extension, mimeType);
1032 context.getMetaData().setOrigin("extension."+extension, descriptor);
1033 }
1034 break;
1035 }
1036 case WebFragment:
1037 {
1038
1039 if (!context.getMimeTypes().getMimeByExtension("."+extension).equals(mimeType))
1040 throw new IllegalStateException("Conflicting mime-type "+mimeType+" for extension "+extension+" in "+descriptor.getResource());
1041 break;
1042 }
1043 default:
1044 LOG.warn(new Throwable());
1045 }
1046 }
1047 }
1048
1049
1050
1051
1052
1053
1054 public void visitWelcomeFileList(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1055 {
1056 switch (context.getMetaData().getOrigin("welcome-file-list"))
1057 {
1058 case NotSet:
1059 {
1060 context.getMetaData().setOrigin("welcome-file-list", descriptor);
1061 addWelcomeFiles(context,node);
1062 break;
1063 }
1064 case WebXml:
1065 {
1066
1067 addWelcomeFiles(context,node);
1068 break;
1069 }
1070 case WebDefaults:
1071 {
1072
1073
1074 if (!(descriptor instanceof DefaultsDescriptor) && !(descriptor instanceof OverrideDescriptor) && !(descriptor instanceof FragmentDescriptor))
1075 {
1076 context.setWelcomeFiles(new String[0]);
1077 }
1078 addWelcomeFiles(context,node);
1079 break;
1080 }
1081 case WebOverride:
1082 {
1083
1084 addWelcomeFiles(context,node);
1085 break;
1086 }
1087 case WebFragment:
1088 {
1089
1090 addWelcomeFiles(context,node);
1091 break;
1092 }
1093 default:
1094 LOG.warn(new Throwable());
1095 }
1096 }
1097
1098
1099
1100
1101
1102
1103 public void visitLocaleEncodingList(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1104 {
1105 Iterator<XmlParser.Node> iter = node.iterator("locale-encoding-mapping");
1106 while (iter.hasNext())
1107 {
1108 XmlParser.Node mapping = iter.next();
1109 String locale = mapping.getString("locale", false, true);
1110 String encoding = mapping.getString("encoding", false, true);
1111
1112 if (encoding != null)
1113 {
1114 switch (context.getMetaData().getOrigin("locale-encoding."+locale))
1115 {
1116 case NotSet:
1117 {
1118
1119 context.addLocaleEncoding(locale, encoding);
1120 context.getMetaData().setOrigin("locale-encoding."+locale, descriptor);
1121 break;
1122 }
1123 case WebXml:
1124 case WebDefaults:
1125 case WebOverride:
1126 {
1127
1128 if (!(descriptor instanceof FragmentDescriptor))
1129 {
1130 context.addLocaleEncoding(locale, encoding);
1131 context.getMetaData().setOrigin("locale-encoding."+locale, descriptor);
1132 }
1133 break;
1134 }
1135 case WebFragment:
1136 {
1137
1138 if (!encoding.equals(context.getLocaleEncoding(locale)))
1139 throw new IllegalStateException("Conflicting loacle-encoding mapping for locale "+locale+" in "+descriptor.getResource());
1140 break;
1141 }
1142 default:
1143 LOG.warn(new Throwable());
1144 }
1145 }
1146 }
1147 }
1148
1149
1150
1151
1152
1153
1154 public void visitErrorPage(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1155 {
1156 String error = node.getString("error-code", false, true);
1157 int code=0;
1158 if (error == null || error.length() == 0)
1159 {
1160 error = node.getString("exception-type", false, true);
1161 if (error == null || error.length() == 0)
1162 error = ErrorPageErrorHandler.GLOBAL_ERROR_PAGE;
1163 }
1164 else
1165 code=Integer.valueOf(error);
1166
1167 String location = node.getString("location", false, true);
1168 ErrorPageErrorHandler handler = (ErrorPageErrorHandler)context.getErrorHandler();
1169
1170 switch (context.getMetaData().getOrigin("error."+error))
1171 {
1172 case NotSet:
1173 {
1174
1175 if (code>0)
1176 handler.addErrorPage(code,location);
1177 else
1178 handler.addErrorPage(error,location);
1179 context.getMetaData().setOrigin("error."+error, descriptor);
1180 break;
1181 }
1182 case WebXml:
1183 case WebDefaults:
1184 case WebOverride:
1185 {
1186
1187 if (!(descriptor instanceof FragmentDescriptor))
1188 {
1189 if (descriptor instanceof OverrideDescriptor || descriptor instanceof DefaultsDescriptor)
1190 {
1191 if (code>0)
1192 handler.addErrorPage(code,location);
1193 else
1194 handler.addErrorPage(error,location);
1195 context.getMetaData().setOrigin("error."+error, descriptor);
1196 }
1197 else
1198 throw new IllegalStateException("Duplicate global error-page "+location);
1199 }
1200 break;
1201 }
1202 case WebFragment:
1203 {
1204
1205 if (!handler.getErrorPages().get(error).equals(location))
1206 throw new IllegalStateException("Conflicting error-code or exception-type "+error+" in "+descriptor.getResource());
1207 break;
1208 }
1209 default:
1210 LOG.warn(new Throwable());
1211 }
1212
1213 }
1214
1215
1216
1217
1218
1219 public void addWelcomeFiles(WebAppContext context, XmlParser.Node node)
1220 {
1221 Iterator<XmlParser.Node> iter = node.iterator("welcome-file");
1222 while (iter.hasNext())
1223 {
1224 XmlParser.Node indexNode = (XmlParser.Node) iter.next();
1225 String welcome = indexNode.toString(false, true);
1226
1227
1228 if (welcome != null && welcome.trim().length() > 0)
1229 context.setWelcomeFiles((String[])ArrayUtil.addToArray(context.getWelcomeFiles(),welcome,String.class));
1230 }
1231 }
1232
1233
1234
1235
1236
1237
1238
1239 public ServletMapping addServletMapping (String servletName, XmlParser.Node node, WebAppContext context, Descriptor descriptor)
1240 {
1241 ServletMapping mapping = new ServletMapping();
1242 mapping.setServletName(servletName);
1243 mapping.setDefault(descriptor instanceof DefaultsDescriptor);
1244
1245 List<String> paths = new ArrayList<String>();
1246 Iterator<XmlParser.Node> iter = node.iterator("url-pattern");
1247 while (iter.hasNext())
1248 {
1249 String p = iter.next().toString(false, true);
1250 p = normalizePattern(p);
1251
1252
1253
1254 ListIterator<ServletMapping> listItor = _servletMappings.listIterator();
1255 boolean found = false;
1256 while (listItor.hasNext() && !found)
1257 {
1258 ServletMapping sm = listItor.next();
1259 if (sm.getPathSpecs() != null)
1260 {
1261 for (String ps:sm.getPathSpecs())
1262 {
1263 if (p.equals(ps) && sm.isDefault())
1264 {
1265 if (LOG.isDebugEnabled()) LOG.debug("{} in mapping {} from defaults descriptor is overridden by ",ps,sm,servletName);
1266
1267
1268 String[] updatedPaths = ArrayUtil.removeFromArray(sm.getPathSpecs(), ps);
1269 if (updatedPaths == null || updatedPaths.length == 0)
1270 {
1271 if (LOG.isDebugEnabled()) LOG.debug("Removed mapping {} from defaults descriptor",sm);
1272 listItor.remove();
1273 }
1274 else
1275 {
1276 sm.setPathSpecs(updatedPaths);
1277 if (LOG.isDebugEnabled()) LOG.debug("Removed path {} from mapping {} from defaults descriptor ", p,sm);
1278 }
1279 found = true;
1280 break;
1281 }
1282 }
1283 }
1284 }
1285
1286 paths.add(p);
1287 context.getMetaData().setOrigin(servletName+".servlet.mapping."+p, descriptor);
1288 }
1289 mapping.setPathSpecs((String[]) paths.toArray(new String[paths.size()]));
1290 if (LOG.isDebugEnabled()) LOG.debug("Added mapping {} ",mapping);
1291
1292
1293
1294 _servletMappings.add(mapping);
1295 return mapping;
1296 }
1297
1298
1299
1300
1301
1302
1303 public void addFilterMapping (String filterName, XmlParser.Node node, WebAppContext context, Descriptor descriptor)
1304 {
1305 FilterMapping mapping = new FilterMapping();
1306 mapping.setFilterName(filterName);
1307
1308 List<String> paths = new ArrayList<String>();
1309 Iterator<XmlParser.Node> iter = node.iterator("url-pattern");
1310 while (iter.hasNext())
1311 {
1312 String p = iter.next().toString(false, true);
1313 p = normalizePattern(p);
1314 paths.add(p);
1315 context.getMetaData().setOrigin(filterName+".filter.mapping."+p, descriptor);
1316 }
1317 mapping.setPathSpecs((String[]) paths.toArray(new String[paths.size()]));
1318
1319 List<String> names = new ArrayList<String>();
1320 iter = node.iterator("servlet-name");
1321 while (iter.hasNext())
1322 {
1323 String n = ((XmlParser.Node) iter.next()).toString(false, true);
1324 names.add(n);
1325 }
1326 mapping.setServletNames((String[]) names.toArray(new String[names.size()]));
1327
1328
1329 List<DispatcherType> dispatches = new ArrayList<DispatcherType>();
1330 iter=node.iterator("dispatcher");
1331 while(iter.hasNext())
1332 {
1333 String d=((XmlParser.Node)iter.next()).toString(false,true);
1334 dispatches.add(FilterMapping.dispatch(d));
1335 }
1336
1337 if (dispatches.size()>0)
1338 mapping.setDispatcherTypes(EnumSet.copyOf(dispatches));
1339
1340 _filterMappings.add(mapping);
1341 }
1342
1343
1344
1345
1346
1347
1348
1349 public void visitTagLib(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1350 {
1351
1352 String uri = node.getString("taglib-uri", false, true);
1353 String location = node.getString("taglib-location", false, true);
1354
1355 context.setResourceAlias(uri, location);
1356
1357 JspConfig config = (JspConfig)context.getServletContext().getJspConfigDescriptor();
1358 if (config == null)
1359 {
1360 config = new JspConfig();
1361 context.getServletContext().setJspConfigDescriptor(config);
1362 }
1363
1364 TagLib tl = new TagLib();
1365 tl.setTaglibLocation(location);
1366 tl.setTaglibURI(uri);
1367 config.addTaglibDescriptor(tl);
1368 }
1369
1370
1371
1372
1373
1374
1375 public void visitJspConfig(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1376 {
1377
1378 JspConfig config = (JspConfig)context.getServletContext().getJspConfigDescriptor();
1379 if (config == null)
1380 {
1381 config = new JspConfig();
1382 context.getServletContext().setJspConfigDescriptor(config);
1383 }
1384
1385
1386 for (int i = 0; i < node.size(); i++)
1387 {
1388 Object o = node.get(i);
1389 if (o instanceof XmlParser.Node && "taglib".equals(((XmlParser.Node) o).getTag()))
1390 visitTagLib(context,descriptor, (XmlParser.Node) o);
1391 }
1392
1393
1394
1395 Iterator<XmlParser.Node> iter = node.iterator("jsp-property-group");
1396 List<String> paths = new ArrayList<String>();
1397 while (iter.hasNext())
1398 {
1399
1400 JspPropertyGroup jpg = new JspPropertyGroup();
1401 config.addJspPropertyGroup(jpg);
1402 XmlParser.Node group = iter.next();
1403
1404 Iterator<XmlParser.Node> iter2 = group.iterator("url-pattern");
1405 while (iter2.hasNext())
1406 {
1407 String url = iter2.next().toString(false, true);
1408 url = normalizePattern(url);
1409 paths.add( url);
1410 jpg.addUrlPattern(url);
1411 }
1412
1413 jpg.setElIgnored(group.getString("el-ignored", false, true));
1414 jpg.setPageEncoding(group.getString("page-encoding", false, true));
1415 jpg.setScriptingInvalid(group.getString("scripting-invalid", false, true));
1416 jpg.setIsXml(group.getString("is-xml", false, true));
1417 jpg.setDeferredSyntaxAllowedAsLiteral(group.getString("deferred-syntax-allowed-as-literal", false, true));
1418 jpg.setTrimDirectiveWhitespaces(group.getString("trim-directive-whitespaces", false, true));
1419 jpg.setDefaultContentType(group.getString("default-content-type", false, true));
1420 jpg.setBuffer(group.getString("buffer", false, true));
1421 jpg.setErrorOnUndeclaredNamespace(group.getString("error-on-undeclared-namespace", false, true));
1422
1423
1424 Iterator<XmlParser.Node> preludes = group.iterator("include-prelude");
1425 while (preludes.hasNext())
1426 {
1427 String prelude = preludes.next().toString(false, true);
1428 jpg.addIncludePrelude(prelude);
1429 }
1430
1431 Iterator<XmlParser.Node> codas = group.iterator("include-coda");
1432 while (codas.hasNext())
1433 {
1434 String coda = codas.next().toString(false, true);
1435 jpg.addIncludeCoda(coda);
1436 }
1437
1438 if (LOG.isDebugEnabled()) LOG.debug(config.toString());
1439 }
1440
1441
1442 if (paths.size() > 0)
1443 {
1444 ServletMapping mapping = new ServletMapping();
1445 mapping.setServletName("jsp");
1446 mapping.setPathSpecs(paths.toArray(new String[paths.size()]));
1447 _servletMappings.add(mapping);
1448 }
1449 }
1450
1451
1452
1453
1454
1455
1456 public void visitSecurityConstraint(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1457 {
1458 Constraint scBase = new Constraint();
1459
1460
1461
1462
1463
1464 try
1465 {
1466 XmlParser.Node auths = node.get("auth-constraint");
1467
1468 if (auths != null)
1469 {
1470 scBase.setAuthenticate(true);
1471
1472 Iterator<XmlParser.Node> iter = auths.iterator("role-name");
1473 List<String> roles = new ArrayList<String>();
1474 while (iter.hasNext())
1475 {
1476 String role = iter.next().toString(false, true);
1477 roles.add(role);
1478 }
1479 scBase.setRoles(roles.toArray(new String[roles.size()]));
1480 }
1481
1482 XmlParser.Node data = node.get("user-data-constraint");
1483 if (data != null)
1484 {
1485 data = data.get("transport-guarantee");
1486 String guarantee = data.toString(false, true).toUpperCase(Locale.ENGLISH);
1487 if (guarantee == null || guarantee.length() == 0 || "NONE".equals(guarantee))
1488 scBase.setDataConstraint(Constraint.DC_NONE);
1489 else if ("INTEGRAL".equals(guarantee))
1490 scBase.setDataConstraint(Constraint.DC_INTEGRAL);
1491 else if ("CONFIDENTIAL".equals(guarantee))
1492 scBase.setDataConstraint(Constraint.DC_CONFIDENTIAL);
1493 else
1494 {
1495 LOG.warn("Unknown user-data-constraint:" + guarantee);
1496 scBase.setDataConstraint(Constraint.DC_CONFIDENTIAL);
1497 }
1498 }
1499 Iterator<XmlParser.Node> iter = node.iterator("web-resource-collection");
1500 while (iter.hasNext())
1501 {
1502 XmlParser.Node collection = iter.next();
1503 String name = collection.getString("web-resource-name", false, true);
1504 Constraint sc = (Constraint) scBase.clone();
1505 sc.setName(name);
1506
1507 Iterator<XmlParser.Node> iter2 = collection.iterator("url-pattern");
1508 while (iter2.hasNext())
1509 {
1510 String url = iter2.next().toString(false, true);
1511 url = normalizePattern(url);
1512
1513 context.getMetaData().setOrigin("constraint.url."+url, descriptor);
1514
1515 Iterator<XmlParser.Node> methods = collection.iterator("http-method");
1516 Iterator<XmlParser.Node> ommissions = collection.iterator("http-method-omission");
1517
1518 if (methods.hasNext())
1519 {
1520 if (ommissions.hasNext())
1521 throw new IllegalStateException ("web-resource-collection cannot contain both http-method and http-method-omission");
1522
1523
1524 while (methods.hasNext())
1525 {
1526 String method = ((XmlParser.Node) methods.next()).toString(false, true);
1527 ConstraintMapping mapping = new ConstraintMapping();
1528 mapping.setMethod(method);
1529 mapping.setPathSpec(url);
1530 mapping.setConstraint(sc);
1531 ((ConstraintAware)context.getSecurityHandler()).addConstraintMapping(mapping);
1532 }
1533 }
1534 else if (ommissions.hasNext())
1535 {
1536
1537
1538 while (ommissions.hasNext())
1539 {
1540 String method = ((XmlParser.Node)ommissions.next()).toString(false, true);
1541 ConstraintMapping mapping = new ConstraintMapping();
1542 mapping.setMethodOmissions(new String[]{method});
1543 mapping.setPathSpec(url);
1544 mapping.setConstraint(sc);
1545 ((ConstraintAware)context.getSecurityHandler()).addConstraintMapping(mapping);
1546 }
1547 }
1548 else
1549 {
1550
1551 ConstraintMapping mapping = new ConstraintMapping();
1552 mapping.setPathSpec(url);
1553 mapping.setConstraint(sc);
1554 ((ConstraintAware)context.getSecurityHandler()).addConstraintMapping(mapping);
1555 }
1556 }
1557 }
1558 }
1559 catch (CloneNotSupportedException e)
1560 {
1561 LOG.warn(e);
1562 }
1563 }
1564
1565
1566
1567
1568
1569
1570
1571 public void visitLoginConfig(WebAppContext context, Descriptor descriptor, XmlParser.Node node) throws Exception
1572 {
1573
1574
1575
1576 XmlParser.Node method = node.get("auth-method");
1577 if (method != null)
1578 {
1579
1580 switch (context.getMetaData().getOrigin("auth-method"))
1581 {
1582 case NotSet:
1583 {
1584
1585 context.getSecurityHandler().setAuthMethod(method.toString(false, true));
1586 context.getMetaData().setOrigin("auth-method", descriptor);
1587 break;
1588 }
1589 case WebXml:
1590 case WebDefaults:
1591 case WebOverride:
1592 {
1593
1594 if (!(descriptor instanceof FragmentDescriptor))
1595 {
1596 context.getSecurityHandler().setAuthMethod(method.toString(false, true));
1597 context.getMetaData().setOrigin("auth-method", descriptor);
1598 }
1599 break;
1600 }
1601 case WebFragment:
1602 {
1603
1604 if (!context.getSecurityHandler().getAuthMethod().equals(method.toString(false, true)))
1605 throw new IllegalStateException("Conflicting auth-method value in "+descriptor.getResource());
1606 break;
1607 }
1608 default:
1609 LOG.warn(new Throwable());
1610 }
1611
1612
1613 XmlParser.Node name = node.get("realm-name");
1614 String nameStr = (name == null ? "default" : name.toString(false, true));
1615 switch (context.getMetaData().getOrigin("realm-name"))
1616 {
1617 case NotSet:
1618 {
1619
1620 context.getSecurityHandler().setRealmName(nameStr);
1621 context.getMetaData().setOrigin("realm-name", descriptor);
1622 break;
1623 }
1624 case WebXml:
1625 case WebDefaults:
1626 case WebOverride:
1627 {
1628
1629 if (!(descriptor instanceof FragmentDescriptor))
1630 {
1631 context.getSecurityHandler().setRealmName(nameStr);
1632 context.getMetaData().setOrigin("realm-name", descriptor);
1633 }
1634 break;
1635 }
1636 case WebFragment:
1637 {
1638
1639 if (!context.getSecurityHandler().getRealmName().equals(nameStr))
1640 throw new IllegalStateException("Conflicting realm-name value in "+descriptor.getResource());
1641 break;
1642 }
1643 default:
1644 LOG.warn(new Throwable());
1645 }
1646
1647 if (Constraint.__FORM_AUTH.equalsIgnoreCase(context.getSecurityHandler().getAuthMethod()))
1648 {
1649 XmlParser.Node formConfig = node.get("form-login-config");
1650 if (formConfig != null)
1651 {
1652 String loginPageName = null;
1653 XmlParser.Node loginPage = formConfig.get("form-login-page");
1654 if (loginPage != null)
1655 loginPageName = loginPage.toString(false, true);
1656 String errorPageName = null;
1657 XmlParser.Node errorPage = formConfig.get("form-error-page");
1658 if (errorPage != null)
1659 errorPageName = errorPage.toString(false, true);
1660
1661
1662 switch (context.getMetaData().getOrigin("form-login-page"))
1663 {
1664 case NotSet:
1665 {
1666
1667 context.getSecurityHandler().setInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE,loginPageName);
1668 context.getMetaData().setOrigin("form-login-page",descriptor);
1669 break;
1670 }
1671 case WebXml:
1672 case WebDefaults:
1673 case WebOverride:
1674 {
1675
1676 if (!(descriptor instanceof FragmentDescriptor))
1677 {
1678 context.getSecurityHandler().setInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE,loginPageName);
1679 context.getMetaData().setOrigin("form-login-page",descriptor);
1680 }
1681 break;
1682 }
1683 case WebFragment:
1684 {
1685
1686 if (!context.getSecurityHandler().getInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE).equals(loginPageName))
1687 throw new IllegalStateException("Conflicting form-login-page value in "+descriptor.getResource());
1688 break;
1689 }
1690 default:
1691 LOG.warn(new Throwable());
1692 }
1693
1694
1695 switch (context.getMetaData().getOrigin("form-error-page"))
1696 {
1697 case NotSet:
1698 {
1699
1700 context.getSecurityHandler().setInitParameter(FormAuthenticator.__FORM_ERROR_PAGE,errorPageName);
1701 context.getMetaData().setOrigin("form-error-page",descriptor);
1702 break;
1703 }
1704 case WebXml:
1705 case WebDefaults:
1706 case WebOverride:
1707 {
1708
1709 if (!(descriptor instanceof FragmentDescriptor))
1710 {
1711 context.getSecurityHandler().setInitParameter(FormAuthenticator.__FORM_ERROR_PAGE,errorPageName);
1712 context.getMetaData().setOrigin("form-error-page",descriptor);
1713 }
1714 break;
1715 }
1716 case WebFragment:
1717 {
1718
1719 if (!context.getSecurityHandler().getInitParameter(FormAuthenticator.__FORM_ERROR_PAGE).equals(errorPageName))
1720 throw new IllegalStateException("Conflicting form-error-page value in "+descriptor.getResource());
1721 break;
1722 }
1723 default:
1724 LOG.warn(new Throwable());
1725 }
1726 }
1727 else
1728 {
1729 throw new IllegalStateException("!form-login-config");
1730 }
1731 }
1732 }
1733 }
1734
1735
1736
1737
1738
1739
1740 public void visitSecurityRole(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1741 {
1742
1743 XmlParser.Node roleNode = node.get("role-name");
1744 String role = roleNode.toString(false, true);
1745 ((ConstraintAware)context.getSecurityHandler()).addRole(role);
1746 }
1747
1748
1749
1750
1751
1752
1753
1754 public void visitFilter(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1755 {
1756 String name = node.getString("filter-name", false, true);
1757 FilterHolder holder = _filterHolderMap.get(name);
1758 if (holder == null)
1759 {
1760 holder = context.getServletHandler().newFilterHolder(Source.DESCRIPTOR);
1761 holder.setName(name);
1762 _filterHolderMap.put(name,holder);
1763 _filterHolders.add(holder);
1764 }
1765
1766 String filter_class = node.getString("filter-class", false, true);
1767 if (filter_class != null)
1768 {
1769 ((WebDescriptor)descriptor).addClassName(filter_class);
1770
1771 switch (context.getMetaData().getOrigin(name+".filter.filter-class"))
1772 {
1773 case NotSet:
1774 {
1775
1776 holder.setClassName(filter_class);
1777 context.getMetaData().setOrigin(name+".filter.filter-class", descriptor);
1778 break;
1779 }
1780 case WebXml:
1781 case WebDefaults:
1782 case WebOverride:
1783 {
1784
1785 if (!(descriptor instanceof FragmentDescriptor))
1786 {
1787 holder.setClassName(filter_class);
1788 context.getMetaData().setOrigin(name+".filter.filter-class", descriptor);
1789 }
1790 break;
1791 }
1792 case WebFragment:
1793 {
1794
1795 if (!holder.getClassName().equals(filter_class))
1796 throw new IllegalStateException("Conflicting filter-class for filter "+name+" in "+descriptor.getResource());
1797 break;
1798 }
1799 default:
1800 LOG.warn(new Throwable());
1801 }
1802 }
1803
1804 Iterator<XmlParser.Node> iter = node.iterator("init-param");
1805 while (iter.hasNext())
1806 {
1807 XmlParser.Node paramNode = iter.next();
1808 String pname = paramNode.getString("param-name", false, true);
1809 String pvalue = paramNode.getString("param-value", false, true);
1810
1811 switch (context.getMetaData().getOrigin(name+".filter.init-param."+pname))
1812 {
1813 case NotSet:
1814 {
1815
1816 holder.setInitParameter(pname, pvalue);
1817 context.getMetaData().setOrigin(name+".filter.init-param."+pname, descriptor);
1818 break;
1819 }
1820 case WebXml:
1821 case WebDefaults:
1822 case WebOverride:
1823 {
1824
1825
1826 if (!(descriptor instanceof FragmentDescriptor))
1827 {
1828 holder.setInitParameter(pname, pvalue);
1829 context.getMetaData().setOrigin(name+".filter.init-param."+pname, descriptor);
1830 }
1831 break;
1832 }
1833 case WebFragment:
1834 {
1835
1836 if (!holder.getInitParameter(pname).equals(pvalue))
1837 throw new IllegalStateException("Mismatching init-param "+pname+"="+pvalue+" in "+descriptor.getResource());
1838 break;
1839 }
1840 default:
1841 LOG.warn(new Throwable());
1842 }
1843 }
1844
1845 String async=node.getString("async-supported",false,true);
1846 if (async!=null)
1847 holder.setAsyncSupported(async.length()==0||Boolean.valueOf(async));
1848 if (async!=null)
1849 {
1850 boolean val = async.length()==0||Boolean.valueOf(async);
1851 switch (context.getMetaData().getOrigin(name+".filter.async-supported"))
1852 {
1853 case NotSet:
1854 {
1855
1856 holder.setAsyncSupported(val);
1857 context.getMetaData().setOrigin(name+".filter.async-supported", descriptor);
1858 break;
1859 }
1860 case WebXml:
1861 case WebDefaults:
1862 case WebOverride:
1863 {
1864
1865 if (!(descriptor instanceof FragmentDescriptor))
1866 {
1867 holder.setAsyncSupported(val);
1868 context.getMetaData().setOrigin(name+".filter.async-supported", descriptor);
1869 }
1870 break;
1871 }
1872 case WebFragment:
1873 {
1874
1875 if (holder.isAsyncSupported() != val)
1876 throw new IllegalStateException("Conflicting async-supported="+async+" for filter "+name+" in "+descriptor.getResource());
1877 break;
1878 }
1879 default:
1880 LOG.warn(new Throwable());
1881 }
1882 }
1883 }
1884
1885
1886
1887
1888
1889
1890 public void visitFilterMapping(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1891 {
1892
1893
1894
1895
1896 String filter_name = node.getString("filter-name", false, true);
1897 switch (context.getMetaData().getOrigin(filter_name+".filter.mappings"))
1898 {
1899 case NotSet:
1900 {
1901
1902 context.getMetaData().setOrigin(filter_name+".filter.mappings", descriptor);
1903 addFilterMapping(filter_name, node, context, descriptor);
1904 break;
1905 }
1906 case WebDefaults:
1907 case WebOverride:
1908 case WebXml:
1909 {
1910
1911 if (!(descriptor instanceof FragmentDescriptor))
1912 {
1913 addFilterMapping(filter_name, node, context, descriptor);
1914 }
1915 break;
1916 }
1917 case WebFragment:
1918 {
1919
1920 addFilterMapping(filter_name, node, context, descriptor);
1921 break;
1922 }
1923 default:
1924 LOG.warn(new Throwable());
1925 }
1926 }
1927
1928
1929
1930
1931
1932
1933
1934 public void visitListener(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1935 {
1936 String className = node.getString("listener-class", false, true);
1937 EventListener listener = null;
1938 try
1939 {
1940 if (className != null && className.length()> 0)
1941 {
1942
1943
1944 EventListener[] listeners=context.getEventListeners();
1945 if (listeners!=null)
1946 {
1947 for (EventListener l : listeners)
1948 {
1949 if (l.getClass().getName().equals(className))
1950 return;
1951 }
1952 }
1953
1954 ((WebDescriptor)descriptor).addClassName(className);
1955
1956 Class<? extends EventListener> listenerClass = (Class<? extends EventListener>)context.loadClass(className);
1957 listener = newListenerInstance(context,listenerClass);
1958 if (!(listener instanceof EventListener))
1959 {
1960 LOG.warn("Not an EventListener: " + listener);
1961 return;
1962 }
1963 context.addEventListener(listener);
1964 context.getMetaData().setOrigin(className+".listener", descriptor);
1965
1966 }
1967 }
1968 catch (Exception e)
1969 {
1970 LOG.warn("Could not instantiate listener " + className, e);
1971 return;
1972 }
1973 }
1974
1975
1976
1977
1978
1979
1980 public void visitDistributable(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1981 {
1982
1983
1984
1985 ((WebDescriptor)descriptor).setDistributable(true);
1986 }
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998 public void visitDenyUncoveredHttpMethods(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1999 {
2000 ((ConstraintAware)context.getSecurityHandler()).setDenyUncoveredHttpMethods(true);
2001 }
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011 public EventListener newListenerInstance(WebAppContext context,Class<? extends EventListener> clazz) throws Exception
2012 {
2013 ListenerHolder h = context.getServletHandler().newListenerHolder(Source.DESCRIPTOR);
2014 EventListener l = context.getServletContext().createInstance(clazz);
2015 h.setListener(l);
2016 context.getServletHandler().addListener(h);
2017 return l;
2018
2019 }
2020
2021
2022
2023
2024
2025 public String normalizePattern(String p)
2026 {
2027 if (p != null && p.length() > 0 && !p.startsWith("/") && !p.startsWith("*")) return "/" + p;
2028 return p;
2029 }
2030
2031
2032 }