Skip to content

Commit b77ee51

Browse files
authored
Fixes #5555 NPE if Filter of named servlet (#5556)
Fixed #5555 NPE if there is a filter with a servlet name mapping, but a request is received for a servlet without a name match. Added more simple tests for servlet and filter mappings
1 parent f21c606 commit b77ee51

File tree

2 files changed

+125
-3
lines changed

2 files changed

+125
-3
lines changed

jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java

+7-3
Original file line numberDiff line numberDiff line change
@@ -614,10 +614,14 @@ protected FilterChain getFilterChain(Request baseRequest, String pathInContext,
614614
for (FilterMapping mapping : _wildFilterNameMappings)
615615
chain = newFilterChain(mapping.getFilterHolder(), chain == null ? new ChainEnd(servletHolder) : chain);
616616

617-
for (FilterMapping mapping : _filterNameMappings.get(servletHolder.getName()))
617+
List<FilterMapping> nameMappings = _filterNameMappings.get(servletHolder.getName());
618+
if (nameMappings != null)
618619
{
619-
if (mapping.appliesTo(dispatch))
620-
chain = newFilterChain(mapping.getFilterHolder(), chain == null ? new ChainEnd(servletHolder) : chain);
620+
for (FilterMapping mapping : nameMappings)
621+
{
622+
if (mapping.appliesTo(dispatch))
623+
chain = newFilterChain(mapping.getFilterHolder(), chain == null ? new ChainEnd(servletHolder) : chain);
624+
}
621625
}
622626
}
623627

jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletHandlerTest.java

+118
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,29 @@
1818

1919
package org.eclipse.jetty.servlet;
2020

21+
import java.io.IOException;
2122
import java.util.ArrayList;
2223
import java.util.EnumSet;
2324
import java.util.List;
2425
import javax.servlet.DispatcherType;
26+
import javax.servlet.Filter;
27+
import javax.servlet.FilterConfig;
28+
import javax.servlet.ServletException;
29+
import javax.servlet.http.HttpServlet;
30+
import javax.servlet.http.HttpServletRequest;
31+
import javax.servlet.http.HttpServletResponse;
2532
import javax.servlet.http.HttpSessionEvent;
2633
import javax.servlet.http.HttpSessionListener;
2734

2835
import org.eclipse.jetty.http.pathmap.MappedResource;
36+
import org.eclipse.jetty.server.LocalConnector;
37+
import org.eclipse.jetty.server.Server;
2938
import org.eclipse.jetty.util.component.Container;
3039
import org.junit.jupiter.api.BeforeEach;
3140
import org.junit.jupiter.api.Test;
3241

42+
import static org.hamcrest.MatcherAssert.assertThat;
43+
import static org.hamcrest.Matchers.containsString;
3344
import static org.junit.jupiter.api.Assertions.assertEquals;
3445
import static org.junit.jupiter.api.Assertions.assertFalse;
3546
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -730,4 +741,111 @@ public void sessionCreated(HttpSessionEvent se)
730741
assertTrue(removeResults.contains(sh1));
731742
assertTrue(removeResults.contains(lh1));
732743
}
744+
745+
@Test
746+
public void testServletMappings() throws Exception
747+
{
748+
Server server = new Server();
749+
ServletHandler handler = new ServletHandler();
750+
server.setHandler(handler);
751+
for (final String mapping : new String[] {"/", "/foo", "/bar/*", "*.bob"})
752+
{
753+
handler.addServletWithMapping(new ServletHolder(new HttpServlet()
754+
{
755+
@Override
756+
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
757+
{
758+
resp.getOutputStream().println("mapping='" + mapping + "'");
759+
}
760+
}), mapping);
761+
}
762+
// add servlet with no mapping
763+
handler.addServlet(new ServletHolder(new HttpServlet() {}));
764+
765+
LocalConnector connector = new LocalConnector(server);
766+
server.addConnector(connector);
767+
768+
server.start();
769+
770+
assertThat(connector.getResponse("GET /default HTTP/1.0\r\n\r\n"), containsString("mapping='/'"));
771+
assertThat(connector.getResponse("GET /foo HTTP/1.0\r\n\r\n"), containsString("mapping='/foo'"));
772+
assertThat(connector.getResponse("GET /bar HTTP/1.0\r\n\r\n"), containsString("mapping='/bar/*'"));
773+
assertThat(connector.getResponse("GET /bar/bob HTTP/1.0\r\n\r\n"), containsString("mapping='/bar/*'"));
774+
assertThat(connector.getResponse("GET /bar/foo.bob HTTP/1.0\r\n\r\n"), containsString("mapping='/bar/*'"));
775+
assertThat(connector.getResponse("GET /other/foo.bob HTTP/1.0\r\n\r\n"), containsString("mapping='*.bob'"));
776+
}
777+
778+
@Test
779+
public void testFilterMappings() throws Exception
780+
{
781+
Server server = new Server();
782+
ServletHandler handler = new ServletHandler();
783+
server.setHandler(handler);
784+
785+
ServletHolder foo = new ServletHolder(new HttpServlet()
786+
{
787+
@Override
788+
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
789+
{
790+
resp.getOutputStream().println("FOO");
791+
}
792+
});
793+
foo.setName("foo");
794+
handler.addServletWithMapping(foo, "/foo/*");
795+
796+
ServletHolder def = new ServletHolder(new HttpServlet()
797+
{
798+
@Override
799+
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
800+
{
801+
resp.getOutputStream().println("default");
802+
}
803+
});
804+
def.setName("default");
805+
handler.addServletWithMapping(def, "/");
806+
807+
for (final String mapping : new String[]{"/*", "/foo", "/bar/*", "*.bob"})
808+
{
809+
handler.addFilterWithMapping(new FilterHolder((TestFilter)(request, response, chain) ->
810+
{
811+
response.getOutputStream().print("path-" + mapping + "-");
812+
chain.doFilter(request, response);
813+
}), mapping, EnumSet.of(DispatcherType.REQUEST));
814+
}
815+
816+
FilterHolder fooFilter = new FilterHolder((TestFilter)(request, response, chain) ->
817+
{
818+
response.getOutputStream().print("name-foo-");
819+
chain.doFilter(request, response);
820+
});
821+
fooFilter.setName("fooFilter");
822+
FilterMapping named = new FilterMapping();
823+
named.setFilterHolder(fooFilter);
824+
named.setServletName("foo");
825+
handler.addFilter(fooFilter, named);
826+
827+
LocalConnector connector = new LocalConnector(server);
828+
server.addConnector(connector);
829+
830+
server.start();
831+
832+
assertThat(connector.getResponse("GET /default HTTP/1.0\r\n\r\n"), containsString("path-/*-default"));
833+
assertThat(connector.getResponse("GET /foo HTTP/1.0\r\n\r\n"), containsString("path-/*-path-/foo-name-foo-FOO"));
834+
assertThat(connector.getResponse("GET /foo/bar HTTP/1.0\r\n\r\n"), containsString("path-/*-name-foo-FOO"));
835+
assertThat(connector.getResponse("GET /foo/bar.bob HTTP/1.0\r\n\r\n"), containsString("path-/*-path-*.bob-name-foo-FOO"));
836+
assertThat(connector.getResponse("GET /other.bob HTTP/1.0\r\n\r\n"), containsString("path-/*-path-*.bob-default"));
837+
}
838+
839+
private interface TestFilter extends Filter
840+
{
841+
default void init(FilterConfig filterConfig) throws ServletException
842+
{
843+
}
844+
845+
@Override
846+
default void destroy()
847+
{
848+
}
849+
}
850+
733851
}

0 commit comments

Comments
 (0)