This commit is contained in:
Jan Bartel 2016-10-13 15:06:47 +11:00
parent 407111a796
commit 37ec4160bb
2 changed files with 143 additions and 5 deletions

View File

@ -109,6 +109,7 @@ public class ServletHandler extends ScopedHandler
private boolean _startWithUnavailable=false;
private boolean _ensureDefaultServlet=true;
private IdentityService _identityService;
private boolean _allowDuplicateMappings=false;
private ServletHolder[] _servlets=new ServletHolder[0];
private ServletMapping[] _servletMappings;
@ -825,6 +826,22 @@ public class ServletHandler extends ScopedHandler
_startWithUnavailable=start;
}
/**
* @return the allowDuplicateMappings
*/
public boolean isAllowDuplicateMappings()
{
return _allowDuplicateMappings;
}
/**
* @param allowDuplicateMappings the allowDuplicateMappings to set
*/
public void setAllowDuplicateMappings(boolean allowDuplicateMappings)
{
_allowDuplicateMappings = allowDuplicateMappings;
}
/* ------------------------------------------------------------ */
/**
* @return True if this handler will start with unavailable servlets
@ -1452,7 +1469,7 @@ public class ServletHandler extends ScopedHandler
Map<String,ServletMapping> servletPathMappings = new HashMap<String,ServletMapping>();
//create a map of paths to set of ServletMappings that define that mapping
HashMap<String, Set<ServletMapping>> sms = new HashMap<String, Set<ServletMapping>>();
HashMap<String, List<ServletMapping>> sms = new HashMap<String, List<ServletMapping>>();
for (ServletMapping servletMapping : _servletMappings)
{
String[] pathSpecs = servletMapping.getPathSpecs();
@ -1460,10 +1477,10 @@ public class ServletHandler extends ScopedHandler
{
for (String pathSpec : pathSpecs)
{
Set<ServletMapping> mappings = sms.get(pathSpec);
List<ServletMapping> mappings = sms.get(pathSpec);
if (mappings == null)
{
mappings = new HashSet<ServletMapping>();
mappings = new ArrayList<ServletMapping>();
sms.put(pathSpec, mappings);
}
mappings.add(servletMapping);
@ -1476,7 +1493,7 @@ public class ServletHandler extends ScopedHandler
{
//for each path, look at the mappings where it is referenced
//if a mapping is for a servlet that is not enabled, skip it
Set<ServletMapping> mappings = sms.get(pathSpec);
List<ServletMapping> mappings = sms.get(pathSpec);
ServletMapping finalMapping = null;
for (ServletMapping mapping : mappings)
@ -1494,9 +1511,15 @@ public class ServletHandler extends ScopedHandler
finalMapping = mapping;
else
{
//already have a candidate - only accept another one if the candidate is a default
//already have a candidate - only accept another one
//if the candidate is a default, or we're allowing duplicate mappings
if (finalMapping.isDefault())
finalMapping = mapping;
else if (isAllowDuplicateMappings())
{
LOG.warn("Multiple servlets map to path: "+pathSpec+": "+finalMapping.getServletName()+","+mapping.getServletName());
finalMapping = mapping;
}
else
{
//existing candidate isn't a default, if the one we're looking at isn't a default either, then its an error

View File

@ -26,6 +26,7 @@ import java.util.EnumSet;
import javax.servlet.DispatcherType;
import org.eclipse.jetty.http.PathMap;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.servlet.BaseHolder.Source;
import org.junit.Before;
@ -49,6 +50,15 @@ public class ServletHandlerTest
FilterMapping fm5 = new FilterMapping();
ServletHolder sh1 = new ServletHolder(Source.DESCRIPTOR);
ServletMapping sm1 = new ServletMapping();
ServletHolder sh2 = new ServletHolder(Source.DESCRIPTOR);
ServletMapping sm2 = new ServletMapping();
ServletHolder sh3 = new ServletHolder(Source.DESCRIPTOR);
ServletMapping sm3 = new ServletMapping();
@Before
public void initMappings()
@ -72,6 +82,111 @@ public class ServletHandlerTest
fh5.setName("fh5");
fm5.setPathSpec("/*");
fm5.setFilterHolder(fh5);
sh1.setName("s1");
sm1.setDefault(false);
sm1.setPathSpec("/foo/*");
sm1.setServletName("s1");
sh2.setName("s2");
sm2.setDefault(false);
sm2.setPathSpec("/foo/*");
sm2.setServletName("s2");
sh3.setName("s3");
sm3.setDefault(true);
sm3.setPathSpec("/foo/*");
sm3.setServletName("s3");
}
@Test
public void testDuplicateMappingsForbidden() throws Exception
{
ServletHandler handler = new ServletHandler();
handler.setAllowDuplicateMappings(false);
handler.addServlet(sh1);
handler.addServlet(sh2);
handler.updateNameMappings();
handler.addServletMapping(sm1);
handler.addServletMapping(sm2);
try
{
handler.updateMappings();
}
catch (IllegalStateException e)
{
//expected error
}
}
@Test
public void testDuplicateMappingsWithDefaults() throws Exception
{
ServletHandler handler = new ServletHandler();
handler.setAllowDuplicateMappings(false);
handler.addServlet(sh1);
handler.addServlet(sh3);
handler.updateNameMappings();
handler.addServletMapping(sm3);
handler.addServletMapping(sm1);
handler.updateMappings();
PathMap.MappedEntry<ServletHolder> entry=handler.getHolderEntry("/foo/*");
assertNotNull(entry);
assertEquals("s1", entry.getValue().getName());
}
@Test
public void testDuplicateMappingsSameServlet() throws Exception
{
ServletHolder sh4 = new ServletHolder();
sh4.setName("s1");
ServletMapping sm4 = new ServletMapping();
sm4.setPathSpec("/foo/*");
sm4.setServletName("s1");
ServletHandler handler = new ServletHandler();
handler.setAllowDuplicateMappings(true);
handler.addServlet(sh1);
handler.addServlet(sh4);
handler.updateNameMappings();
handler.addServletMapping(sm1);
handler.addServletMapping(sm4);
handler.updateMappings();
}
@Test
public void testDuplicateMappingsAllowed() throws Exception
{
ServletHandler handler = new ServletHandler();
handler.setAllowDuplicateMappings(true);
handler.addServlet(sh1);
handler.addServlet(sh2);
handler.updateNameMappings();
handler.addServletMapping(sm1);
handler.addServletMapping(sm2);
handler.updateMappings();
PathMap.MappedEntry<ServletHolder> entry=handler.getHolderEntry("/foo/*");
assertNotNull(entry);
assertEquals("s2", entry.getValue().getName());
}
@Test