GROOVY-8294: Return 404 for non-existing paths in TemplateServlet when running from .war (closes #588)
- When TemplateServlet was used in application servers that don't unpack a war (i.e. when the real path of resources could not be retrieved), an internal server error was returned upon trying to retrieve a non-existing template file. Now, a 404 is returned. - When running from a unpacked war, this had already worked before. Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/49ff8b20 Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/49ff8b20 Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/49ff8b20 Branch: refs/heads/GROOVY_2_5_X Commit: 49ff8b203a44f8052b32874820e36f6973f46f62 Parents: 3ffaf66 Author: Thomas Reifenberger <[email protected]> Authored: Thu Aug 17 23:11:30 2017 +0200 Committer: John Wagenleitner <[email protected]> Committed: Thu Aug 24 18:33:10 2017 -0700 ---------------------------------------------------------------------- .../java/groovy/servlet/TemplateServlet.java | 4 + .../groovy/servlet/TemplateServletTest.groovy | 97 ++++++++++++++++++++ 2 files changed, 101 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/49ff8b20/subprojects/groovy-servlet/src/main/java/groovy/servlet/TemplateServlet.java ---------------------------------------------------------------------- diff --git a/subprojects/groovy-servlet/src/main/java/groovy/servlet/TemplateServlet.java b/subprojects/groovy-servlet/src/main/java/groovy/servlet/TemplateServlet.java index 4c3e8be..553ed3c 100644 --- a/subprojects/groovy-servlet/src/main/java/groovy/servlet/TemplateServlet.java +++ b/subprojects/groovy-servlet/src/main/java/groovy/servlet/TemplateServlet.java @@ -441,6 +441,10 @@ public class TemplateServlet extends AbstractHttpServlet { } else { name = getScriptUri(request); URL url = servletContext.getResource(name); + if (url == null) { + response.sendError(HttpServletResponse.SC_NOT_FOUND); + return; + } getMillis = System.currentTimeMillis(); template = getTemplate(url); getMillis = System.currentTimeMillis() - getMillis; http://git-wip-us.apache.org/repos/asf/groovy/blob/49ff8b20/subprojects/groovy-servlet/src/test/groovy/groovy/servlet/TemplateServletTest.groovy ---------------------------------------------------------------------- diff --git a/subprojects/groovy-servlet/src/test/groovy/groovy/servlet/TemplateServletTest.groovy b/subprojects/groovy-servlet/src/test/groovy/groovy/servlet/TemplateServletTest.groovy new file mode 100644 index 0000000..ae05e6d --- /dev/null +++ b/subprojects/groovy-servlet/src/test/groovy/groovy/servlet/TemplateServletTest.groovy @@ -0,0 +1,97 @@ +package groovy.servlet + +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TemporaryFolder + +import javax.servlet.ServletConfig +import javax.servlet.ServletContext +import javax.servlet.http.HttpServletRequest +import javax.servlet.http.HttpServletResponse + +class TemplateServletTest { + + TemplateServlet servlet + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder() + + @Before + void setUp() { + servlet = new TemplateServlet() + } + + @Test + void test_service_for_existing_resource() { + def templateFile = temporaryFolder.newFile('template.gsp') + def url = templateFile.toURI().toURL() + def servletConfig = mockServletConfigForUrlResource(url) + HttpServletRequest request = mockRequest() + def (HttpServletResponse response, responseData) = mockResponse() + servlet.init(servletConfig) + + servlet.service(request, response) + + assert responseData.error == null + assert responseData.writer.toString() != '' + assert responseData.status == HttpServletResponse.SC_OK + } + + @Test + void test_service_for_missing_resource() { + def url = null + def servletConfig = mockServletConfigForUrlResource(url) + HttpServletRequest request = mockRequest() + def (HttpServletResponse response, responseData) = mockResponse() + servlet.init(servletConfig) + + servlet.service(request, response) + + assert responseData.error == HttpServletResponse.SC_NOT_FOUND + assert responseData.writer.toString() == '' + assert responseData.status == null + } + + private mockRequest() { + return [ + getAttribute : { null }, + getPathInfo : { 'pathInfo' }, + getScriptUri : 'scriptUri', + getServletPath : { 'servletPath' }, + getSession : { null }, + getParameterNames: { new Vector().elements() }, + getHeaderNames : { new Vector().elements() }, + ] as HttpServletRequest + } + + private mockResponse() { + def data = [ + writer: new StringWriter(), + status: null, + error : null, + ] + def mock = [ + getWriter : { new PrintWriter(data.writer) }, + sendError : { error -> data.error = error }, + setContentType: { contentType -> }, + setStatus : { status -> data.status = status }, + flushBuffer : { -> }, + ] as HttpServletResponse + return [mock, data] + } + + private mockServletConfigForUrlResource(URL mockedResourceUrl) { + def servletContext = [ + getRealPath: { arg -> null }, + getResource: { arg -> mockedResourceUrl }, + log : { msg -> }, + ] as ServletContext + [ + getServletName : { 'name' }, + getServletContext: { servletContext }, + getInitParameter : { null }, + ] as ServletConfig + } + +}
