diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PushCacheFilterTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PushCacheFilterTest.java index 53a0c8e67c4..5258127bb48 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PushCacheFilterTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PushCacheFilterTest.java @@ -418,7 +418,8 @@ public class PushCacheFilterTest extends AbstractTest public void testRecursivePush() throws Exception { final String primaryResource = "/primary.html"; - final String secondaryResource = "/secondary.css"; + final String secondaryResource1 = "/secondary1.css"; + final String secondaryResource2 = "/secondary2.js"; final String tertiaryResource = "/tertiary.png"; start(new HttpServlet() { @@ -429,8 +430,10 @@ public class PushCacheFilterTest extends AbstractTest final ServletOutputStream output = response.getOutputStream(); if (requestURI.endsWith(primaryResource)) output.print("
PRIMARY"); - else if (requestURI.endsWith(secondaryResource)) + else if (requestURI.endsWith(secondaryResource1)) output.print("body { background-image: url(\"" + tertiaryResource + "\"); }"); + else if (requestURI.endsWith(secondaryResource2)) + output.print("(function() { window.alert('HTTP/2'); })()"); if (requestURI.endsWith(tertiaryResource)) output.write("TERTIARY".getBytes(StandardCharsets.UTF_8)); } @@ -442,7 +445,7 @@ public class PushCacheFilterTest extends AbstractTest final String primaryURI = "http://localhost:" + connector.getLocalPort() + servletPath + primaryResource; HttpFields primaryFields = new HttpFields(); MetaData.Request primaryRequest = newRequest("GET", primaryResource, primaryFields); - final CountDownLatch warmupLatch = new CountDownLatch(1); + final CountDownLatch warmupLatch = new CountDownLatch(2); session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter() { @Override @@ -451,12 +454,12 @@ public class PushCacheFilterTest extends AbstractTest callback.succeeded(); if (frame.isEndStream()) { - // Request for the secondary resource. - final String secondaryURI = "http://localhost:" + connector.getLocalPort() + servletPath + secondaryResource; - HttpFields secondaryFields = new HttpFields(); - secondaryFields.put(HttpHeader.REFERER, primaryURI); - MetaData.Request secondaryRequest = newRequest("GET", secondaryResource, secondaryFields); - session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter() + // Request for the secondary resources. + String secondaryURI1 = "http://localhost:" + connector.getLocalPort() + servletPath + secondaryResource1; + HttpFields secondaryFields1 = new HttpFields(); + secondaryFields1.put(HttpHeader.REFERER, primaryURI); + MetaData.Request secondaryRequest1 = newRequest("GET", secondaryResource1, secondaryFields1); + session.newStream(new HeadersFrame(secondaryRequest1, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter() { @Override public void onData(Stream stream, DataFrame frame, Callback callback) @@ -466,13 +469,14 @@ public class PushCacheFilterTest extends AbstractTest { // Request for the tertiary resource. HttpFields tertiaryFields = new HttpFields(); - tertiaryFields.put(HttpHeader.REFERER, secondaryURI); + tertiaryFields.put(HttpHeader.REFERER, secondaryURI1); MetaData.Request tertiaryRequest = newRequest("GET", tertiaryResource, tertiaryFields); session.newStream(new HeadersFrame(tertiaryRequest, null, true), new Promise.Adapter<>(), new Adapter() { @Override public void onData(Stream stream, DataFrame frame, Callback callback) { + callback.succeeded(); if (frame.isEndStream()) warmupLatch.countDown(); } @@ -480,6 +484,20 @@ public class PushCacheFilterTest extends AbstractTest } } }); + + HttpFields secondaryFields2 = new HttpFields(); + secondaryFields2.put(HttpHeader.REFERER, primaryURI); + MetaData.Request secondaryRequest2 = newRequest("GET", secondaryResource2, secondaryFields2); + session.newStream(new HeadersFrame(secondaryRequest2, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter() + { + @Override + public void onData(Stream stream, DataFrame frame, Callback callback) + { + callback.succeeded(); + if (frame.isEndStream()) + warmupLatch.countDown(); + } + }); } } }); @@ -487,19 +505,73 @@ public class PushCacheFilterTest extends AbstractTest Thread.sleep(1000); - // Request again the primary resource, we should get the secondary and tertiary resource pushed. + // Request again the primary resource, we should get the secondary and tertiary resources pushed. primaryRequest = newRequest("GET", primaryResource, primaryFields); final CountDownLatch primaryResponseLatch = new CountDownLatch(1); - final CountDownLatch pushLatch = new CountDownLatch(2); + final CountDownLatch primaryPushesLatch = new CountDownLatch(3); + final CountDownLatch recursiveLatch = new CountDownLatch(1); session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter() { @Override public void onData(Stream stream, DataFrame frame, Callback callback) { + callback.succeeded(); if (frame.isEndStream()) primaryResponseLatch.countDown(); } + @Override + public Stream.Listener onPush(Stream stream, PushPromiseFrame frame) + { + // The stream id of the PUSH_PROMISE must + // always be a client stream and therefore odd. + Assert.assertEquals(1, frame.getStreamId() & 1); + return new Adapter() + { + @Override + public void onData(Stream stream, DataFrame frame, Callback callback) + { + callback.succeeded(); + if (frame.isEndStream()) + primaryPushesLatch.countDown(); + } + + @Override + public Stream.Listener onPush(Stream stream, PushPromiseFrame frame) + { + return new Adapter() + { + @Override + public void onData(Stream stream, DataFrame frame, Callback callback) + { + callback.succeeded(); + if (frame.isEndStream()) + recursiveLatch.countDown(); + } + }; + } + }; + } + }); + + Assert.assertTrue(primaryPushesLatch.await(5, TimeUnit.SECONDS)); + Assert.assertFalse(recursiveLatch.await(1, TimeUnit.SECONDS)); + Assert.assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS)); + + // Make sure that explicitly requesting a secondary resource, we get the tertiary pushed. + CountDownLatch secondaryResponseLatch = new CountDownLatch(1); + CountDownLatch secondaryPushLatch = new CountDownLatch(1); + MetaData.Request secondaryRequest = newRequest("GET", secondaryResource1, new HttpFields()); + session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter() + { + @Override + public void onData(Stream stream, DataFrame frame, Callback callback) + { + callback.succeeded(); + if (frame.isEndStream()) + secondaryResponseLatch.countDown(); + } + @Override public Stream.Listener onPush(Stream stream, PushPromiseFrame frame) { @@ -510,19 +582,14 @@ public class PushCacheFilterTest extends AbstractTest { callback.succeeded(); if (frame.isEndStream()) - pushLatch.countDown(); - } - - @Override - public Stream.Listener onPush(Stream stream, PushPromiseFrame frame) - { - return this; + secondaryPushLatch.countDown(); } }; } }); - Assert.assertTrue(pushLatch.await(5, TimeUnit.SECONDS)); - Assert.assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS)); + + Assert.assertTrue(secondaryPushLatch.await(5, TimeUnit.SECONDS)); + Assert.assertTrue(secondaryResponseLatch.await(5, TimeUnit.SECONDS)); } @Test diff --git a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/AttributeNormalizer.java b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/AttributeNormalizer.java index aae4361f6fe..8e550f66269 100644 --- a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/AttributeNormalizer.java +++ b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/AttributeNormalizer.java @@ -123,6 +123,11 @@ public class AttributeNormalizer return 1; } + if( (o1.path == null) && (o2.path == null) ) + { + return 0; + } + // Different lengths? int diff = o2.path.getNameCount() - o1.path.getNameCount(); if(diff != 0) @@ -142,14 +147,19 @@ public class AttributeNormalizer } } + private URI warURI; private List
+ * Eg: on fedora /etc/init.d is a symlink to /etc/rc.d/init.d
+ */
+ private static String toSystemPath(String rawpath)
+ {
+ Path path = FileSystems.getDefault().getPath(rawpath);
+ if (Files.exists(path))
+ {
+ // It exists, resolve it to the real path
+ try
+ {
+ path = path.toRealPath();
+ }
+ catch (IOException e)
+ {
+ // something prevented us from resolving to real path, fallback to
+ // absolute path resolution (not as accurate)
+ path = path.toAbsolutePath();
+ e.printStackTrace();
+ }
+ }
+ else
+ {
+ // File doesn't exist, resolve to absolute path
+ // We can't rely on File.toCanonicalPath() here
+ path = path.toAbsolutePath();
+ }
+ return path.toString();
+ }
+
+ private static String origJettyBase;
+ private static String origJettyHome;
+ private static String origUserHome;
+ private static String origUserDir;
+
+ @BeforeClass
+ public static void initProperties()
+ {
+ origJettyBase = System.getProperty("jetty.base");
+ origJettyHome = System.getProperty("jetty.home");
+ origUserHome = System.getProperty("user.home");
+ origUserDir = System.getProperty("user.dir");
+
+ System.setProperty("jetty.home","/opt/jetty-distro");
+ System.setProperty("jetty.base","/opt/jetty-distro/demo.base");
+ System.setProperty("user.home","/home/user");
+ System.setProperty("user.dir","/etc/init.d");
+ }
+
+ @AfterClass
+ public static void restoreProperties()
+ {
+ if(origJettyBase != null) System.setProperty("jetty.base",origJettyBase);
+ if(origJettyHome != null) System.setProperty("jetty.home",origJettyHome);
+ if(origUserHome != null) System.setProperty("user.home",origUserHome);
+ if(origUserDir != null) System.setProperty("user.dir",origUserDir);
+ }
+
+ @Parameter(0)
+ public String key;
+
+ @Parameter(1)
+ public String path;
+
+ private AttributeNormalizer normalizer;
+
+ public AttributeNormalizerPathTest() throws MalformedURLException
+ {
+ normalizer = new AttributeNormalizer(Resource.newResource("/opt/jetty-distro/demo.base/webapps/root"));
+ }
+
+ @Test
+ public void testEqual()
+ {
+ assertThat(normalizer.normalize("file:" + path), is("file:${" + key + "}"));
+ }
+
+ @Test
+ public void testEqualsSlash()
+ {
+ assertThat(normalizer.normalize("file:" + path + "/"), is("file:${" + key + "}"));
+ }
+
+ @Test
+ public void testEqualsSlashFile()
+ {
+ assertThat(normalizer.normalize("file:" + path + "/file"), is("file:${" + key + "}/file"));
+ }
+
+ @Test
+ public void testURIEquals() throws URISyntaxException
+ {
+ assertThat(normalizer.normalize(new URI("file:" + path)), is("file:${" + key + "}"));
+ }
+
+ @Test
+ public void testURIEqualsSlash() throws URISyntaxException
+ {
+ assertThat(normalizer.normalize(new URI("file:" + path + "/")), is("file:${" + key + "}"));
+ }
+
+ @Test
+ public void testURIEqualsSlashFile() throws URISyntaxException
+ {
+ assertThat(normalizer.normalize(new URI("file:" + path + "/file")), is("file:${" + key + "}/file"));
+ }
+
+ @Test
+ public void testURLEquals() throws MalformedURLException
+ {
+ assertThat(normalizer.normalize(new URL("file:" + path)), is("file:${" + key + "}"));
+ }
+
+ @Test
+ public void testURLEqualsSlash() throws MalformedURLException
+ {
+ assertThat(normalizer.normalize(new URL("file:" + path + "/")), is("file:${" + key + "}"));
+ }
+
+ @Test
+ public void testURLEqualsSlashFile() throws MalformedURLException
+ {
+ assertThat(normalizer.normalize(new URL("file:" + path + "/file")), is("file:${" + key + "}/file"));
+ }
+
+ @Test
+ public void testJarFileEquals_BangFile()
+ {
+ assertThat(normalizer.normalize("jar:file:" + path + "!/file"), is("jar:file:${" + key + "}!/file"));
+ }
+
+ @Test
+ public void testJarFileEquals_SlashBangFile()
+ {
+ assertThat(normalizer.normalize("jar:file:" + path + "/!/file"), is("jar:file:${" + key + "}!/file"));
+ }
+
+ @Test
+ public void testJarFileEquals_FileBangFile()
+ {
+ assertThat(normalizer.normalize("jar:file:" + path + "/file!/file"), is("jar:file:${" + key + "}/file!/file"));
+ }
+
+ @Test
+ public void testJarFileEquals_URIBangFile() throws URISyntaxException
+ {
+ assertThat(normalizer.normalize(new URI("jar:file:" + path + "!/file")), is("jar:file:${" + key + "}!/file"));
+ }
+
+ @Test
+ public void testJarFileEquals_URISlashBangFile() throws URISyntaxException
+ {
+ assertThat(normalizer.normalize(new URI("jar:file:" + path + "/!/file")), is("jar:file:${" + key + "}!/file"));
+ }
+
+ @Test
+ public void testJarFileEquals_URIFileBangFile() throws URISyntaxException
+ {
+ assertThat(normalizer.normalize(new URI("jar:file:" + path + "/file!/file")), is("jar:file:${" + key + "}/file!/file"));
+ }
+
+ @Test
+ public void testJarFileEquals_URLBangFile() throws MalformedURLException
+ {
+ assertThat(normalizer.normalize(new URL("jar:file:" + path + "!/file")), is("jar:file:${" + key + "}!/file"));
+ }
+
+ @Test
+ public void testJarFileEquals_URLSlashBangFile() throws MalformedURLException
+ {
+ assertThat(normalizer.normalize(new URL("jar:file:" + path + "/!/file")), is("jar:file:${" + key + "}!/file"));
+ }
+
+ @Test
+ public void testJarFileEquals_URLFileBangFile() throws MalformedURLException
+ {
+ assertThat(normalizer.normalize(new URL("jar:file:" + path + "/file!/file")), is("jar:file:${" + key + "}/file!/file"));
+ }
+}
diff --git a/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/AttributeNormalizerTest.java b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/AttributeNormalizerTest.java
index e0bec424b7b..b9c6f1e8c87 100644
--- a/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/AttributeNormalizerTest.java
+++ b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/AttributeNormalizerTest.java
@@ -1,4 +1,4 @@
- //
+//
// ========================================================================
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
@@ -18,226 +18,29 @@
package org.eclipse.jetty.quickstart;
+import java.net.MalformedURLException;
+import java.net.URI;
+
+import org.eclipse.jetty.util.resource.Resource;
+import org.junit.Test;
+
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.nio.file.FileSystems;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.List;
-
-import org.eclipse.jetty.util.resource.Resource;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
public class AttributeNormalizerTest
{
- @Parameters(name="{0} = {1}")
- public static List
- * Eg: on fedora /etc/init.d is a symlink to /etc/rc.d/init.d
- */
- private static String toSystemPath(String rawpath)
- {
- Path path = FileSystems.getDefault().getPath(rawpath);
- if (Files.exists(path))
- {
- // It exists, resolve it to the real path
- try
- {
- path = path.toRealPath();
- }
- catch (IOException e)
- {
- // something prevented us from resolving to real path, fallback to
- // absolute path resolution (not as accurate)
- path = path.toAbsolutePath();
- e.printStackTrace();
- }
- }
- else
- {
- // File doesn't exist, resolve to absolute path
- // We can't rely on File.toCanonicalPath() here
- path = path.toAbsolutePath();
- }
- return path.toString();
- }
-
- private static String origJettyBase;
- private static String origJettyHome;
- private static String origUserHome;
- private static String origUserDir;
-
- @BeforeClass
- public static void initProperties()
- {
- origJettyBase = System.getProperty("jetty.base");
- origJettyHome = System.getProperty("jetty.home");
- origUserHome = System.getProperty("user.home");
- origUserDir = System.getProperty("user.dir");
-
- System.setProperty("jetty.home","/opt/jetty-distro");
- System.setProperty("jetty.base","/opt/jetty-distro/demo.base");
- System.setProperty("user.home","/home/user");
- System.setProperty("user.dir","/etc/init.d");
- }
-
- @AfterClass
- public static void restoreProperties()
- {
- if(origJettyBase != null) System.setProperty("jetty.base",origJettyBase);
- if(origJettyHome != null) System.setProperty("jetty.home",origJettyHome);
- if(origUserHome != null) System.setProperty("user.home",origUserHome);
- if(origUserDir != null) System.setProperty("user.dir",origUserDir);
- }
-
- @Parameter(0)
- public String key;
-
- @Parameter(1)
- public String path;
-
- private AttributeNormalizer normalizer;
-
- public AttributeNormalizerTest() throws MalformedURLException
- {
- normalizer = new AttributeNormalizer(Resource.newResource("/opt/jetty-distro/demo.base/webapps/root"));
- }
-
@Test
- public void testEqual()
+ public void testNormalizeWAR() throws MalformedURLException
{
- assertThat(normalizer.normalize("file:" + path), is("file:${" + key + "}"));
- }
+ String webref = "http://localhost/resource/webapps/root";
+ Resource webresource = Resource.newResource(webref);
+ AttributeNormalizer normalizer = new AttributeNormalizer(webresource);
+ String result = null;
- @Test
- public void testEqualsSlash()
- {
- assertThat(normalizer.normalize("file:" + path + "/"), is("file:${" + key + "}"));
- }
+ result = normalizer.normalize(URI.create(webref));
+ assertThat(result, is("${WAR}"));
- @Test
- public void testEqualsSlashFile()
- {
- assertThat(normalizer.normalize("file:" + path + "/file"), is("file:${" + key + "}/file"));
- }
-
- @Test
- public void testURIEquals() throws URISyntaxException
- {
- assertThat(normalizer.normalize(new URI("file:" + path)), is("file:${" + key + "}"));
- }
-
- @Test
- public void testURIEqualsSlash() throws URISyntaxException
- {
- assertThat(normalizer.normalize(new URI("file:" + path + "/")), is("file:${" + key + "}"));
- }
-
- @Test
- public void testURIEqualsSlashFile() throws URISyntaxException
- {
- assertThat(normalizer.normalize(new URI("file:" + path + "/file")), is("file:${" + key + "}/file"));
- }
-
- @Test
- public void testURLEquals() throws MalformedURLException
- {
- assertThat(normalizer.normalize(new URL("file:" + path)), is("file:${" + key + "}"));
- }
-
- @Test
- public void testURLEqualsSlash() throws MalformedURLException
- {
- assertThat(normalizer.normalize(new URL("file:" + path + "/")), is("file:${" + key + "}"));
- }
-
- @Test
- public void testURLEqualsSlashFile() throws MalformedURLException
- {
- assertThat(normalizer.normalize(new URL("file:" + path + "/file")), is("file:${" + key + "}/file"));
- }
-
- @Test
- public void testJarFileEquals_BangFile()
- {
- assertThat(normalizer.normalize("jar:file:" + path + "!/file"), is("jar:file:${" + key + "}!/file"));
- }
-
- @Test
- public void testJarFileEquals_SlashBangFile()
- {
- assertThat(normalizer.normalize("jar:file:" + path + "/!/file"), is("jar:file:${" + key + "}!/file"));
- }
-
- @Test
- public void testJarFileEquals_FileBangFile()
- {
- assertThat(normalizer.normalize("jar:file:" + path + "/file!/file"), is("jar:file:${" + key + "}/file!/file"));
- }
-
- @Test
- public void testJarFileEquals_URIBangFile() throws URISyntaxException
- {
- assertThat(normalizer.normalize(new URI("jar:file:" + path + "!/file")), is("jar:file:${" + key + "}!/file"));
- }
-
- @Test
- public void testJarFileEquals_URISlashBangFile() throws URISyntaxException
- {
- assertThat(normalizer.normalize(new URI("jar:file:" + path + "/!/file")), is("jar:file:${" + key + "}!/file"));
- }
-
- @Test
- public void testJarFileEquals_URIFileBangFile() throws URISyntaxException
- {
- assertThat(normalizer.normalize(new URI("jar:file:" + path + "/file!/file")), is("jar:file:${" + key + "}/file!/file"));
- }
-
- @Test
- public void testJarFileEquals_URLBangFile() throws MalformedURLException
- {
- assertThat(normalizer.normalize(new URL("jar:file:" + path + "!/file")), is("jar:file:${" + key + "}!/file"));
- }
-
- @Test
- public void testJarFileEquals_URLSlashBangFile() throws MalformedURLException
- {
- assertThat(normalizer.normalize(new URL("jar:file:" + path + "/!/file")), is("jar:file:${" + key + "}!/file"));
- }
-
- @Test
- public void testJarFileEquals_URLFileBangFile() throws MalformedURLException
- {
- assertThat(normalizer.normalize(new URL("jar:file:" + path + "/file!/file")), is("jar:file:${" + key + "}/file!/file"));
+ result = normalizer.normalize(URI.create(webref + "/deep/ref"));
+ assertThat(result, is("${WAR}/deep/ref"));
}
}