From 92c546a2c5fd529e067e4647a228412c2feaa95b Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 10 Jan 2024 16:50:01 -0600 Subject: [PATCH 1/4] Updating poms --- embedded/deploying/pom.xml | 10 +++++----- embedded/form-post/pom.xml | 6 +++--- embedded/http-config/pom.xml | 6 +++--- embedded/jndi/pom.xml | 6 +++--- embedded/redirect/pom.xml | 8 ++++---- embedded/rewrite/pom.xml | 10 +++++----- embedded/xml/pom.xml | 4 ++-- 7 files changed, 25 insertions(+), 25 deletions(-) diff --git a/embedded/deploying/pom.xml b/embedded/deploying/pom.xml index f7b8565..6dd1b72 100644 --- a/embedded/deploying/pom.xml +++ b/embedded/deploying/pom.xml @@ -12,27 +12,27 @@ Jetty Examples :: Jetty 9.4.x :: Embedded :: Deploying + org.eclipse.jetty - jetty-server + jetty-deploy ${jetty.version} - org.eclipse.jetty - jetty-deploy + jetty-server ${jetty.version} org.eclipse.jetty - jetty-xml + jetty-servlet ${jetty.version} org.eclipse.jetty - jetty-servlet + jetty-xml ${jetty.version} diff --git a/embedded/form-post/pom.xml b/embedded/form-post/pom.xml index 29ee0b2..4a50f9c 100644 --- a/embedded/form-post/pom.xml +++ b/embedded/form-post/pom.xml @@ -12,15 +12,15 @@ Jetty Examples :: Jetty 9.4.x :: Embedded :: HTML Form POST + org.eclipse.jetty - jetty-server + jetty-client ${jetty.version} - org.eclipse.jetty - jetty-client + jetty-server ${jetty.version} diff --git a/embedded/http-config/pom.xml b/embedded/http-config/pom.xml index c736f71..692f717 100644 --- a/embedded/http-config/pom.xml +++ b/embedded/http-config/pom.xml @@ -12,15 +12,15 @@ Jetty Examples :: Jetty 9.4.x :: Embedded :: HTTP Configuration + org.eclipse.jetty - jetty-server + jetty-client ${jetty.version} - org.eclipse.jetty - jetty-client + jetty-server ${jetty.version} diff --git a/embedded/jndi/pom.xml b/embedded/jndi/pom.xml index 1fdd31c..1987963 100644 --- a/embedded/jndi/pom.xml +++ b/embedded/jndi/pom.xml @@ -12,15 +12,15 @@ Jetty Examples :: Jetty 9.4.x :: Embedded :: JNDI + org.eclipse.jetty - jetty-server + jetty-plus ${jetty.version} - org.eclipse.jetty - jetty-plus + jetty-server ${jetty.version} diff --git a/embedded/redirect/pom.xml b/embedded/redirect/pom.xml index 3de2e62..a278875 100644 --- a/embedded/redirect/pom.xml +++ b/embedded/redirect/pom.xml @@ -12,16 +12,16 @@ Jetty Examples :: Jetty 9.4.x :: Embedded :: Redirect + org.eclipse.jetty - jetty-server + jetty-http ${jetty.version} + tests - org.eclipse.jetty - jetty-http - tests + jetty-server ${jetty.version} diff --git a/embedded/rewrite/pom.xml b/embedded/rewrite/pom.xml index 5cc5e0d..b6f7297 100644 --- a/embedded/rewrite/pom.xml +++ b/embedded/rewrite/pom.xml @@ -12,22 +12,22 @@ Jetty Examples :: Jetty 9.4.x :: Embedded :: Rewrite + org.eclipse.jetty - jetty-server + jetty-http ${jetty.version} + tests org.eclipse.jetty - jetty-http - tests + jetty-rewrite ${jetty.version} - org.eclipse.jetty - jetty-rewrite + jetty-server ${jetty.version} diff --git a/embedded/xml/pom.xml b/embedded/xml/pom.xml index 64e7d76..c7a0980 100644 --- a/embedded/xml/pom.xml +++ b/embedded/xml/pom.xml @@ -20,13 +20,13 @@ org.eclipse.jetty - jetty-xml + jetty-servlet ${jetty.version} org.eclipse.jetty - jetty-servlet + jetty-xml ${jetty.version} From 6f340cfb228581e0db3676beb6130b3f289b54dd Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 10 Jan 2024 16:50:29 -0600 Subject: [PATCH 2/4] Updating ci.yml --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3b8b1fe..9f76c69 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,6 +4,8 @@ on: push: branches: - 'jetty-9.4.x' + - 'jetty-10.0.x' + - 'jetty-11.0.x' pull_request: jobs: From 6cccd73ae1bc6815d80f93e7e01acd63485afefe Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 10 Jan 2024 17:11:55 -0600 Subject: [PATCH 3/4] Updating CI branch names --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9f76c69..a310c55 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,9 +3,9 @@ name: CI on: push: branches: - - 'jetty-9.4.x' - - 'jetty-10.0.x' - - 'jetty-11.0.x' + - '9.4.x' + - '10.0.x' + - '11.0.x' pull_request: jobs: From c568d13f5e3d9468d931099f0f7b42a72db5cd1a Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Thu, 1 Feb 2024 15:14:44 -0600 Subject: [PATCH 4/4] Adding tests for file-server demo + 2MB and 2GB tests --- embedded/file-server/pom.xml | 7 ++ .../ResourceHandlerFromClasspath.java | 18 ++- .../ResourceHandlerFromFileSystem.java | 17 ++- .../ServletFileServerMultipleLocations.java | 39 +++--- .../ServletFileServerSingleLocation.java | 23 ++-- .../examples/ByteCountingOutputStream.java | 44 +++++++ .../ResourceHandlerFromFileSystemTest.java | 109 +++++++++++++++++ ...ervletFileServerMultipleLocationsTest.java | 112 ++++++++++++++++++ .../src/test/java/examples/StaticFileGen.java | 98 +++++++++++++++ 9 files changed, 433 insertions(+), 34 deletions(-) create mode 100644 embedded/file-server/src/test/java/examples/ByteCountingOutputStream.java create mode 100644 embedded/file-server/src/test/java/examples/ResourceHandlerFromFileSystemTest.java create mode 100644 embedded/file-server/src/test/java/examples/ServletFileServerMultipleLocationsTest.java create mode 100644 embedded/file-server/src/test/java/examples/StaticFileGen.java diff --git a/embedded/file-server/pom.xml b/embedded/file-server/pom.xml index 4dd4dd4..5a20ac5 100644 --- a/embedded/file-server/pom.xml +++ b/embedded/file-server/pom.xml @@ -23,6 +23,13 @@ jetty-webapp ${jetty.version} + + + org.eclipse.jetty.toolchain + jetty-test-helper + ${jetty-test-helper.version} + test + diff --git a/embedded/file-server/src/main/java/examples/ResourceHandlerFromClasspath.java b/embedded/file-server/src/main/java/examples/ResourceHandlerFromClasspath.java index 96f3687..3d105ea 100644 --- a/embedded/file-server/src/main/java/examples/ResourceHandlerFromClasspath.java +++ b/embedded/file-server/src/main/java/examples/ResourceHandlerFromClasspath.java @@ -13,6 +13,7 @@ package examples; +import java.net.MalformedURLException; import java.net.URI; import java.net.URL; @@ -24,8 +25,6 @@ public class ResourceHandlerFromClasspath { public static void main(String[] args) throws Exception { - Server server = new Server(8080); - // Figure out what path to serve content from ClassLoader cl = ResourceHandlerFromClasspath.class.getClassLoader(); // We look for a file, as ClassLoader.getResource() is not @@ -40,13 +39,20 @@ public static void main(String[] args) throws Exception URI webRootUri = f.toURI().resolve("./").normalize(); System.err.println("WebRoot is " + webRootUri); + Server server = ResourceHandlerFromClasspath.newServer(8080, webRootUri); + server.start(); + server.join(); + } + + public static Server newServer(int port, URI resourcesRoot) throws MalformedURLException + { + Server server = new Server(port); + ResourceHandler handler = new ResourceHandler(); - handler.setBaseResource(Resource.newResource(webRootUri)); + handler.setBaseResource(Resource.newResource(resourcesRoot)); handler.setDirectoriesListed(true); server.setHandler(handler); - - server.start(); - server.join(); + return server; } } diff --git a/embedded/file-server/src/main/java/examples/ResourceHandlerFromFileSystem.java b/embedded/file-server/src/main/java/examples/ResourceHandlerFromFileSystem.java index dc094c4..d2eafbe 100644 --- a/embedded/file-server/src/main/java/examples/ResourceHandlerFromFileSystem.java +++ b/embedded/file-server/src/main/java/examples/ResourceHandlerFromFileSystem.java @@ -25,8 +25,6 @@ public class ResourceHandlerFromFileSystem { public static void main(String[] args) throws Exception { - Server server = new Server(8080); - Path webRootPath = Paths.get("webapps/alt-root/").toAbsolutePath().normalize(); if (!Files.isDirectory(webRootPath)) { @@ -35,13 +33,20 @@ public static void main(String[] args) throws Exception } System.err.println("WebRoot is " + webRootPath); + Server server = ResourceHandlerFromFileSystem.newServer(8080, webRootPath); + server.start(); + server.join(); + } + + public static Server newServer(int port, Path resourcesRoot) + { + Server server = new Server(port); + ResourceHandler handler = new ResourceHandler(); - handler.setBaseResource(new PathResource(webRootPath)); + handler.setBaseResource(new PathResource(resourcesRoot)); handler.setDirectoriesListed(true); server.setHandler(handler); - - server.start(); - server.join(); + return server; } } diff --git a/embedded/file-server/src/main/java/examples/ServletFileServerMultipleLocations.java b/embedded/file-server/src/main/java/examples/ServletFileServerMultipleLocations.java index 0fc8731..eaf67b9 100644 --- a/embedded/file-server/src/main/java/examples/ServletFileServerMultipleLocations.java +++ b/embedded/file-server/src/main/java/examples/ServletFileServerMultipleLocations.java @@ -13,8 +13,9 @@ package examples; -import java.io.File; +import java.net.MalformedURLException; import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; @@ -41,11 +42,19 @@ public class ServletFileServerMultipleLocations { public static void main(String[] args) throws Exception { - Server server = new Server(); - ServerConnector connector = new ServerConnector(server); - connector.setPort(8080); - server.addConnector(connector); + URI webRootUri = findDefaultBaseResource(); + System.err.println("Default Base Resource is " + webRootUri); + + Path altPath = Paths.get("webapps/alt-root").toRealPath(); + System.err.println("Alt Base Resource is " + altPath); + Server server = ServletFileServerMultipleLocations.newServer(8080, webRootUri, altPath); + server.start(); + server.join(); + } + + public static URI findDefaultBaseResource() throws URISyntaxException + { // Figure out what path to serve content from ClassLoader cl = ServletFileServerMultipleLocations.class.getClassLoader(); // We look for a file, as ClassLoader.getResource() is not @@ -57,21 +66,24 @@ public static void main(String[] args) throws Exception } // Resolve file to directory - URI webRootUri = f.toURI().resolve("./").normalize(); - System.err.println("Main Base Resource is " + webRootUri); + return f.toURI().resolve("./").normalize(); + } + + public static Server newServer(int port, URI mainResourceBase, Path altPath) throws MalformedURLException + { + Server server = new Server(); + ServerConnector connector = new ServerConnector(server); + connector.setPort(port); + server.addConnector(connector); // Setup the basic application "context" for this application at "/" // This is also known as the handler tree (in jetty speak) ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); - context.setBaseResource(Resource.newResource(webRootUri)); + context.setBaseResource(Resource.newResource(mainResourceBase)); context.setWelcomeFiles(new String[]{"index.html", "index.htm", "alt-index.html"}); server.setHandler(context); - // Find altPath - Path altPath = Paths.get("webapps/alt-root").toRealPath(); - System.err.println("Alt Base Resource is " + altPath); - // add special pathspec of "/alt/" content mapped to the altPath ServletHolder holderAlt = new ServletHolder("static-alt", DefaultServlet.class); holderAlt.setInitParameter("resourceBase", altPath.toUri().toASCIIString()); @@ -85,7 +97,6 @@ public static void main(String[] args) throws Exception holderDef.setInitParameter("dirAllowed", "true"); context.addServlet(holderDef, "/"); - server.start(); - server.join(); + return server; } } diff --git a/embedded/file-server/src/main/java/examples/ServletFileServerSingleLocation.java b/embedded/file-server/src/main/java/examples/ServletFileServerSingleLocation.java index b7747c7..5540d3d 100644 --- a/embedded/file-server/src/main/java/examples/ServletFileServerSingleLocation.java +++ b/embedded/file-server/src/main/java/examples/ServletFileServerSingleLocation.java @@ -13,6 +13,7 @@ package examples; +import java.net.MalformedURLException; import java.net.URI; import java.net.URL; @@ -30,11 +31,6 @@ public class ServletFileServerSingleLocation { public static void main(String[] args) throws Exception { - Server server = new Server(); - ServerConnector connector = new ServerConnector(server); - connector.setPort(8080); - server.addConnector(connector); - // Figure out what path to serve content from ClassLoader cl = ServletFileServerSingleLocation.class.getClassLoader(); // We look for a file, as ClassLoader.getResource() is not @@ -49,16 +45,27 @@ public static void main(String[] args) throws Exception URI webRootUri = f.toURI().resolve("./").normalize(); System.err.println("WebRoot is " + webRootUri); + Server server = ServletFileServerSingleLocation.newServer(8080, webRootUri); + server.start(); + server.join(); + } + + public static Server newServer(int port, URI resourcesRoot) throws MalformedURLException + { + Server server = new Server(); + ServerConnector connector = new ServerConnector(server); + connector.setPort(port); + server.addConnector(connector); + ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); - context.setBaseResource(Resource.newResource(webRootUri)); + context.setBaseResource(Resource.newResource(resourcesRoot)); server.setHandler(context); ServletHolder holderPwd = new ServletHolder("default", DefaultServlet.class); holderPwd.setInitParameter("dirAllowed", "true"); context.addServlet(holderPwd, "/"); - server.start(); - server.join(); + return server; } } diff --git a/embedded/file-server/src/test/java/examples/ByteCountingOutputStream.java b/embedded/file-server/src/test/java/examples/ByteCountingOutputStream.java new file mode 100644 index 0000000..53be4b1 --- /dev/null +++ b/embedded/file-server/src/test/java/examples/ByteCountingOutputStream.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// 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 examples; + +import java.io.OutputStream; + +public class ByteCountingOutputStream extends OutputStream +{ + private long count = 0; + + public long getCount() + { + return count; + } + + @Override + public void write(int b) + { + count++; + } + + @Override + public void write(byte[] b) + { + count += b.length; + } + + @Override + public void write(byte[] b, int off, int len) + { + count += len; + } +} diff --git a/embedded/file-server/src/test/java/examples/ResourceHandlerFromFileSystemTest.java b/embedded/file-server/src/test/java/examples/ResourceHandlerFromFileSystemTest.java new file mode 100644 index 0000000..24db30d --- /dev/null +++ b/embedded/file-server/src/test/java/examples/ResourceHandlerFromFileSystemTest.java @@ -0,0 +1,109 @@ +// +// ======================================================================== +// 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 examples; + +import java.net.HttpURLConnection; +import java.nio.file.Path; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.toolchain.test.FS; +import org.eclipse.jetty.toolchain.test.MavenPaths; +import org.eclipse.jetty.util.component.LifeCycle; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static examples.StaticFileGen.GB; +import static examples.StaticFileGen.MB; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +public class ResourceHandlerFromFileSystemTest +{ + private final long exampleSize = 2 * MB; + private final long largeSize = 2 * GB; + private Server server; + private String exampleSha; + private String largeSha; + + @BeforeEach + public void startServer() throws Exception + { + Path resourcesRoot = MavenPaths.targetTestDir(ResourceHandlerFromFileSystemTest.class.getSimpleName()); + FS.ensureDirExists(resourcesRoot); + + exampleSha = StaticFileGen.generate(resourcesRoot.resolve("example.png"), exampleSize); + largeSha = StaticFileGen.generate(resourcesRoot.resolve("large.mkv"), largeSize); + + server = ResourceHandlerFromFileSystem.newServer(0, resourcesRoot); + server.start(); + } + + @AfterEach + public void stopServer() + { + LifeCycle.stop(server); + } + + /** + * Get small file + */ + @Test + public void testGetSmall() throws Exception + { + HttpURLConnection http = (HttpURLConnection)server.getURI().resolve("/example.png").toURL().openConnection(); + http.connect(); + dumpRequestResponse(http); + assertEquals(HttpURLConnection.HTTP_OK, http.getResponseCode()); + String contentLengthResponse = http.getHeaderField("Content-Length"); + assertNotNull(contentLengthResponse); + long contentLengthLong = Long.parseLong(contentLengthResponse); + assertEquals(2 * MB, contentLengthLong); + assertEquals("image/png", http.getHeaderField("Content-Type")); + + StaticFileGen.verify(http.getInputStream(), exampleSize, exampleSha); + } + + /** + * Get large file + */ + @Test + public void testGetLarge() throws Exception + { + HttpURLConnection http = (HttpURLConnection)server.getURI().resolve("/large.mkv").toURL().openConnection(); + http.connect(); + dumpRequestResponse(http); + assertEquals(HttpURLConnection.HTTP_OK, http.getResponseCode()); + String contentLengthResponse = http.getHeaderField("Content-Length"); + assertNotNull(contentLengthResponse); + long contentLengthLong = Long.parseLong(contentLengthResponse); + assertEquals(2 * GB, contentLengthLong); + assertNull(http.getHeaderField("Content-Type"), "Not a recognized mime-type by Jetty"); + + StaticFileGen.verify(http.getInputStream(), largeSize, largeSha); + } + + private static void dumpRequestResponse(HttpURLConnection http) + { + System.out.println(); + System.out.println("----"); + System.out.printf("%s %s HTTP/1.1%n", http.getRequestMethod(), http.getURL()); + System.out.println("----"); + System.out.printf("%s%n", http.getHeaderField(null)); + http.getHeaderFields().entrySet().stream() + .filter(entry -> entry.getKey() != null) + .forEach((entry) -> System.out.printf("%s: %s%n", entry.getKey(), http.getHeaderField(entry.getKey()))); + } +} diff --git a/embedded/file-server/src/test/java/examples/ServletFileServerMultipleLocationsTest.java b/embedded/file-server/src/test/java/examples/ServletFileServerMultipleLocationsTest.java new file mode 100644 index 0000000..bc3b9a2 --- /dev/null +++ b/embedded/file-server/src/test/java/examples/ServletFileServerMultipleLocationsTest.java @@ -0,0 +1,112 @@ +// +// ======================================================================== +// 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 examples; + +import java.net.HttpURLConnection; +import java.net.URI; +import java.nio.file.Path; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.toolchain.test.FS; +import org.eclipse.jetty.toolchain.test.MavenPaths; +import org.eclipse.jetty.util.component.LifeCycle; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static examples.StaticFileGen.GB; +import static examples.StaticFileGen.MB; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +public class ServletFileServerMultipleLocationsTest +{ + private final long exampleSize = 2 * MB; + private final long largeSize = 2 * GB; + private Server server; + private String exampleSha; + private String largeSha; + + @BeforeEach + public void startServer() throws Exception + { + Path resourcesRoot = MavenPaths.targetTestDir(ServletFileServerMultipleLocations.class.getSimpleName()); + FS.ensureDirExists(resourcesRoot); + + exampleSha = StaticFileGen.generate(resourcesRoot.resolve("example.png"), exampleSize); + largeSha = StaticFileGen.generate(resourcesRoot.resolve("large.mkv"), largeSize); + + URI defaultBaseResource = ServletFileServerMultipleLocations.findDefaultBaseResource(); + + server = ServletFileServerMultipleLocations.newServer(0, defaultBaseResource, resourcesRoot); + server.start(); + } + + @AfterEach + public void stopServer() + { + LifeCycle.stop(server); + } + + /** + * Get small file + */ + @Test + public void testGetSmall() throws Exception + { + HttpURLConnection http = (HttpURLConnection)server.getURI().resolve("/alt/example.png").toURL().openConnection(); + http.connect(); + dumpRequestResponse(http); + assertEquals(HttpURLConnection.HTTP_OK, http.getResponseCode()); + String contentLengthResponse = http.getHeaderField("Content-Length"); + assertNotNull(contentLengthResponse); + long contentLengthLong = Long.parseLong(contentLengthResponse); + assertEquals(2 * MB, contentLengthLong); + assertEquals("image/png", http.getHeaderField("Content-Type")); + + StaticFileGen.verify(http.getInputStream(), exampleSize, exampleSha); + } + + /** + * Get large file + */ + @Test + public void testGetLarge() throws Exception + { + HttpURLConnection http = (HttpURLConnection)server.getURI().resolve("/alt/large.mkv").toURL().openConnection(); + http.connect(); + dumpRequestResponse(http); + assertEquals(HttpURLConnection.HTTP_OK, http.getResponseCode()); + String contentLengthResponse = http.getHeaderField("Content-Length"); + assertNotNull(contentLengthResponse); + long contentLengthLong = Long.parseLong(contentLengthResponse); + assertEquals(2 * GB, contentLengthLong); + assertNull(http.getHeaderField("Content-Type"), "Not a recognized mime-type by Jetty"); + + StaticFileGen.verify(http.getInputStream(), largeSize, largeSha); + } + + private static void dumpRequestResponse(HttpURLConnection http) + { + System.out.println(); + System.out.println("----"); + System.out.printf("%s %s HTTP/1.1%n", http.getRequestMethod(), http.getURL()); + System.out.println("----"); + System.out.printf("%s%n", http.getHeaderField(null)); + http.getHeaderFields().entrySet().stream() + .filter(entry -> entry.getKey() != null) + .forEach((entry) -> System.out.printf("%s: %s%n", entry.getKey(), http.getHeaderField(entry.getKey()))); + } +} diff --git a/embedded/file-server/src/test/java/examples/StaticFileGen.java b/embedded/file-server/src/test/java/examples/StaticFileGen.java new file mode 100644 index 0000000..f01286d --- /dev/null +++ b/embedded/file-server/src/test/java/examples/StaticFileGen.java @@ -0,0 +1,98 @@ +// +// ======================================================================== +// 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 examples; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.nio.channels.SeekableByteChannel; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.security.DigestOutputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; + +import org.eclipse.jetty.toolchain.test.Hex; +import org.eclipse.jetty.toolchain.test.Sha1Sum; +import org.eclipse.jetty.util.IO; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class StaticFileGen +{ + public static final long KB = 1024; + public static final long MB = 1024 * KB; + public static final long GB = 1024 * MB; + + /** + * Generate a static file. + * + * @param staticFile the path of the file to create + * @param size the size of the file to create + * @return the SHA1 hash of the static file + * @throws IOException if unable to create the file + * @throws NoSuchAlgorithmException if unable to find the SHA1 algorithm + */ + public static String generate(Path staticFile, long size) throws IOException, NoSuchAlgorithmException + { + byte[] buf = new byte[(int)MB]; + Arrays.fill(buf, (byte)'x'); + ByteBuffer src = ByteBuffer.wrap(buf); + + if (Files.exists(staticFile) && Files.size(staticFile) == size) + { + // all done, nothing left to do. + System.err.printf("File Exists Already: %s (%,d bytes)%n", staticFile, Files.size(staticFile)); + return Sha1Sum.calculate(staticFile); + } + + System.err.printf("Creating %,d byte file: %s ...%n", size, staticFile); + try (SeekableByteChannel channel = Files.newByteChannel(staticFile, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) + { + long remaining = size; + while (remaining > 0) + { + ByteBuffer slice = src.slice(); + int len = buf.length; + if (remaining < Integer.MAX_VALUE) + { + len = Math.min(buf.length, (int)remaining); + slice.limit(len); + } + + channel.write(slice); + remaining -= len; + } + } + System.err.println(" Done"); + return Sha1Sum.calculate(staticFile); + } + + public static void verify(InputStream inputStream, long expectedSize, String expectedSha1) throws NoSuchAlgorithmException, IOException + { + MessageDigest digest = MessageDigest.getInstance("SHA1"); + try(ByteCountingOutputStream byteCountingOutputStream = new ByteCountingOutputStream(); + DigestOutputStream digestOut = new DigestOutputStream(byteCountingOutputStream, digest)) + { + IO.copy(inputStream, digestOut); + String actualSha1 = Hex.asHex(digestOut.getMessageDigest().digest()); + assertEquals(expectedSha1, actualSha1); + + long actualSize = byteCountingOutputStream.getCount(); + assertEquals(expectedSize, actualSize); + } + } +}