Skip to content

Commit

Permalink
Issue #10084 - Implementing fix for ee9
Browse files Browse the repository at this point in the history
  • Loading branch information
joakime committed Jul 7, 2023
1 parent 8e4da80 commit e9e0780
Show file tree
Hide file tree
Showing 11 changed files with 266 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1568,15 +1568,18 @@ public Set<String> getResourcePaths(String path)
Resource resource = getResource(path);

if (!path.endsWith("/"))
path = path + "/";
path = path + '/';

HashSet<String> set = new HashSet<>();

for (Resource r: resource)
{
for (Resource item: r.list())
{
set.add(path + item.getFileName());
String entry = path + item.getFileName();
if (item.isDirectory())
entry = entry + '/';
set.add(entry);
}
}
return set;
Expand Down
2 changes: 2 additions & 0 deletions jetty-ee9/jetty-ee9-webapp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
<configuration>
<argLine>
@{argLine} ${jetty.surefire.argLine}
--add-exports org.eclipse.jetty.ee9.webapp/org.acme.webapp=org.eclipse.jetty.ee9.servlet
--add-exports org.eclipse.jetty.ee9.webapp/org.acme.webapp=org.eclipse.jetty.ee9.nested
</argLine>
<useManifestOnlyJar>false</useManifestOnlyJar>
<additionalClasspathElements>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.acme.webapp;

import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.Set;

import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class GetRealPathsServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException
{
collectResourcePaths("/").stream()
.map(p -> getServletContext().getRealPath(p))
.forEach(resp.getWriter()::println);
resp.getWriter().flush();
}

private Set<String> collectResourcePaths(String path)
{
Set<String> allResourcePaths = new LinkedHashSet<>();
Set<String> pathsForPath = getServletContext().getResourcePaths(path);
if (pathsForPath != null)
{
for (String resourcePath : pathsForPath)
{
allResourcePaths.add(resourcePath);
allResourcePaths.addAll(collectResourcePaths(resourcePath));
}
}
return allResourcePaths;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.acme.webapp;

import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.Set;

import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class GetResourcePathsServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException
{
collectResourcePaths("/").forEach(resp.getWriter()::println);
resp.getWriter().flush();
}

private Set<String> collectResourcePaths(String path)
{
Set<String> allResourcePaths = new LinkedHashSet<>();
Set<String> pathsForPath = getServletContext().getResourcePaths(path);
if (pathsForPath != null)
{
for (String resourcePath : pathsForPath)
{
allResourcePaths.add(resourcePath);
allResourcePaths.addAll(collectResourcePaths(resourcePath));
}
}
return allResourcePaths;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand Down Expand Up @@ -68,8 +69,12 @@

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
Expand Down Expand Up @@ -546,6 +551,132 @@ public void testBaseResourceAbsolutePath() throws Exception
assertTrue(context.isAvailable(), "WebAppContext should be available");
}

@Test
public void testGetResourceFromCollection() throws Exception
{
Server server = newServer();

WebAppContext context = new WebAppContext();
context.setContextPath("/");
context.setBaseResource(ResourceFactory.combine(
ResourceFactory.root().newResource(MavenTestingUtils.getTestResourcePath("wars/layer0/")),
ResourceFactory.root().newResource(MavenTestingUtils.getTestResourcePath("wars/layer1/"))));
server.setHandler(context);
server.start();

ServletContext servletContext = context.getServletContext();
assertThat(servletContext.getResource("/WEB-INF/zero.xml"), notNullValue());
assertThat(servletContext.getResource("/WEB-INF/one.xml"), notNullValue());
}

@Test
public void testGetResourcePathsFromCollection() throws Exception
{
Server server = newServer();

WebAppContext context = new WebAppContext();
context.setContextPath("/");
context.setBaseResource(ResourceFactory.combine(
ResourceFactory.root().newResource(MavenTestingUtils.getTestResourcePath("wars/layer0/")),
ResourceFactory.root().newResource(MavenTestingUtils.getTestResourcePath("wars/layer1/"))));
server.setHandler(context);
server.start();

ServletContext servletContext = context.getServletContext();
assertThat(servletContext.getResourcePaths("/WEB-INF/"), containsInAnyOrder("/WEB-INF/zero.xml", "/WEB-INF/one.xml"));
}

@Test
public void testGetResourcePathsWithDirsFromCollection() throws Exception
{
Server server = newServer();

WebAppContext context = new WebAppContext();
context.setContextPath("/");
context.setBaseResource(ResourceFactory.combine(
ResourceFactory.root().newResource(MavenTestingUtils.getTestResourcePath("wars/layer0/")),
ResourceFactory.root().newResource(MavenTestingUtils.getTestResourcePath("wars/layer1/")),
ResourceFactory.root().newResource(MavenTestingUtils.getTestResourcePath("wars/with_dirs/"))
));
server.setHandler(context);
server.start();

ServletContext servletContext = context.getServletContext();
Set<String> results = servletContext.getResourcePaths("/WEB-INF/");
String[] expected = {
"/WEB-INF/zero.xml",
"/WEB-INF/one.xml",
"/WEB-INF/bar/",
"/WEB-INF/foo/"
};
assertThat(results, containsInAnyOrder(expected));
}

@Test
@Disabled("getRealPath() not working yet")
public void testGetResourcePaths() throws Exception
{
Server server = newServer();
LocalConnector connector = new LocalConnector(server);
server.addConnector(connector);

Path warRoot = MavenPaths.projectBase().resolve("src/test/webapp-with-resources");
assertTrue(Files.isDirectory(warRoot), "Unable to find directory: " + warRoot);
WebAppContext context = new WebAppContext();
Resource warResource = context.getResourceFactory().newResource(warRoot);
context.setWarResource(warResource);
context.setContextPath("/");
server.setHandler(context);
server.start();

ServletContext servletContext = context.getServletContext();

Set<String> resourcePaths = servletContext.getResourcePaths("/");
String[] expected = {
"/WEB-INF/",
"/nested-reserved-!#\\\\$%&()*+,:=?@[]-meta-inf-resource.txt",
};
assertThat(resourcePaths.size(), is(2));
assertThat(resourcePaths, containsInAnyOrder(expected));

String realPath = servletContext.getRealPath("/");
assertThat(realPath, notNullValue());
assertThat(servletContext.getRealPath("/WEB-INF/"), endsWith("/WEB-INF/"));
// TODO the following assertion fails because of a bug in the JDK (see JDK-8311079 and MountedPathResourceTest.testJarFileResourceAccessBackSlash())
//assertThat(servletContext.getRealPath(resourcePaths.get(1)), endsWith("/nested-reserved-!#\\\\$%&()*+,:=?@[]-meta-inf-resource.txt"));

assertThat(servletContext.getResource("/WEB-INF/"), notNullValue());
// TODO the following assertion fails because of a bug in the JDK (see JDK-8311079 and MountedPathResourceTest.testJarFileResourceAccessBackSlash())
//assertThat(servletContext.getResource("/nested-reserved-!#\\\\$%&()*+,:=?@[]-meta-inf-resource.txt"), notNullValue());

HttpTester.Response response1 = HttpTester.parseResponse(connector.getResponse("""
GET /resource HTTP/1.1\r
Host: local\r
Connection: close\r
\r
"""));

assertThat(response1.getStatus(), is(HttpStatus.OK_200));
assertThat(response1.getContent(), containsString("/WEB-INF"));
assertThat(response1.getContent(), containsString("/WEB-INF/lib"));
assertThat(response1.getContent(), containsString("/WEB-INF/lib/odd-resource.jar"));
assertThat(response1.getContent(), containsString("/nested-reserved-!#\\\\$%&()*+,:=?@[]-meta-inf-resource.txt"));

HttpTester.Response response2 = HttpTester.parseResponse(connector.getResponse("""
GET /real HTTP/1.1\r
Host: local\r
Connection: close\r
\r
"""));

assertThat(response2.getStatus(), is(HttpStatus.OK_200));
assertThat(response2.getContent(), containsString("/WEB-INF"));
assertThat(response2.getContent(), containsString("/WEB-INF/lib"));
assertThat(response2.getContent(), containsString("/WEB-INF/lib/odd-resource.jar"));
// TODO the following assertion fails because of a bug in the JDK (see JDK-8311079 and MountedPathResourceTest.testJarFileResourceAccessBackSlash())
//assertThat(response2.getContent(), containsString("/nested-reserved-!#\\\\$%&()*+,:=?@[]-meta-inf-resource.txt"));
}

public static Stream<Arguments> extraClasspathGlob()
{
List<Arguments> references = new ArrayList<>();
Expand Down
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is the "main.txt" in the /bar/ directory for war "with_dirs"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is the "alt.txt" in the /foo/ directory for war "with_dirs"
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
metadata-complete="false"
version="6.0">

<servlet>
<servlet-name>GetResourcePathsServlet</servlet-name>
<servlet-class>org.acme.webapp.GetResourcePathsServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>GetRealPathsServlet</servlet-name>
<servlet-class>org.acme.webapp.GetRealPathsServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>GetResourcePathsServlet</servlet-name>
<url-pattern>/resource/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>GetRealPathsServlet</servlet-name>
<url-pattern>/real/*</url-pattern>
</servlet-mapping>
</web-app>


0 comments on commit e9e0780

Please sign in to comment.