Merged branch 'jetty-9.4.x' into 'jetty-10.0.x'.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
Simone Bordet 2019-02-12 11:23:56 +01:00
commit 5ce3d1bd61
15 changed files with 1002 additions and 16 deletions

View File

@ -400,8 +400,7 @@ public class CrossOriginFilter implements Filter
{
response.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, origin);
//W3C CORS spec http://www.w3.org/TR/cors/#resource-implementation
if (!anyOriginAllowed)
response.addHeader("Vary", ORIGIN_HEADER);
response.addHeader("Vary", ORIGIN_HEADER);
if (allowCredentials)
response.setHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, "true");
if (!exposedHeaders.isEmpty())

View File

@ -135,7 +135,7 @@ public class CrossOriginFilterTest
Set<String> fieldNames = response.getFieldNamesCollection();
assertThat(response.toString(), CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, isIn(fieldNames));
assertThat(response.toString(), CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, isIn(fieldNames));
assertThat(response.toString(), "Vary", not(isIn(fieldNames)));
assertThat(response.toString(), "Vary", isIn(fieldNames));
assertTrue(latch.await(1, TimeUnit.SECONDS));
}

View File

@ -36,7 +36,8 @@
<tycho-version>1.2.0</tycho-version>
<cbi-plugins.version>1.1.5</cbi-plugins.version>
<junit.version>5.3.1</junit.version>
<maven.version>3.5.0</maven.version>
<maven.version>3.6.0</maven.version>
<maven.resolver.version>1.3.1</maven.resolver.version>
<weld.version>2.4.5.Final</weld.version>
<jetty.perf-helper.version>1.0.5</jetty.perf-helper.version>
<unix.socket.tmp></unix.socket.tmp>

View File

@ -68,5 +68,6 @@
<module>test-quickstart</module>
<module>test-jmx</module>
<module>test-http-client-transport</module>
<module>test-distribution</module>
</modules>
</project>

View File

@ -0,0 +1,100 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>tests-parent</artifactId>
<version>10.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>test-distribution</artifactId>
<packaging>jar</packaging>
<properties>
<bundle-symbolic-name>${project.groupId}.tests.distribution</bundle-symbolic-name>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-resolver-provider</artifactId>
<version>${maven.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-connector-basic</artifactId>
<version>${maven.resolver.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-transport-file</artifactId>
<version>${maven.resolver.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-transport-http</artifactId>
<version>${maven.resolver.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-distribution</artifactId>
<version>${project.version}</version>
<type>zip</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-http-client-transport</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-simple-webapp</artifactId>
<version>${project.version}</version>
<type>war</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<mavenRepoPath>${settings.localRepository}</mavenRepoPath>
<jettyVersion>${project.version}</jettyVersion>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,601 @@
//
// ========================================================================
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.tests.distribution;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.codehaus.plexus.util.IOUtil;
import org.eclipse.aether.AbstractRepositoryListener;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositoryEvent;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
import org.eclipse.aether.impl.DefaultServiceLocator;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.ArtifactRequest;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
import org.eclipse.aether.transfer.AbstractTransferListener;
import org.eclipse.aether.transport.file.FileTransporterFactory;
import org.eclipse.aether.transport.http.HttpTransporterFactory;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* <p>Helper class to test the Jetty Distribution</p>.
* <p>API can change without any further notice.</p>
* <p>Usage:</p>
* <pre>
* // Create the distribution.
* String jettyVersion = "9.4.14.v20181114";
* DistributionTester distribution = DistributionTester.Builder.newInstance()
* .jettyVersion(jettyVersion)
* .jettyBase(Paths.get("demo-base"))
* .build();
*
* // The first run initializes the Jetty Base.
* try (DistributionTester.Run run1 = distribution.start("--create-startd", "--add-to-start=http2c,jsp,deploy"))
* {
* assertTrue(run1.awaitFor(5, TimeUnit.SECONDS));
* assertEquals(0, run1.getExitValue());
*
* // Install a web application.
* File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + jettyVersion);
* distribution.installWarFile(war, "test");
*
* // The second run starts the distribution.
* int port = 9090;
* try (DistributionTester.Run run = distribution.start("jetty.http.port=" + port))
* {
* // Wait for Jetty to be fully started.
* assertTrue(run1.awaitConsoleLogsFor("Started @", 20, TimeUnit.SECONDS));
*
* // Make a HTTP request to the web application.
* HttpClient client = new HttpClient();
* client.start();
* ContentResponse response = client.GET("http://localhost:" + port + "/test/index.jsp");
* assertEquals(HttpStatus.OK_200, response.getStatus());
* }
* }
* </pre>
*/
public class DistributionTester
{
private static final Logger LOGGER = Log.getLogger(DistributionTester.class);
private Config config;
private DistributionTester(Config config)
{
this.config = config;
}
/**
* Starts the distribution with the given arguments
*
* @param args arguments to use to start the distribution
*/
public DistributionTester.Run start(String... args) throws Exception
{
return start(Arrays.asList(args));
}
/**
* Start the distribution with the arguments
*
* @param args arguments to use to start the distribution
*/
public DistributionTester.Run start(List<String> args) throws Exception
{
List<String> commands = new ArrayList<>();
commands.add(getJavaExecutable());
commands.add("-jar");
commands.add(config.jettyHome.toAbsolutePath() + "/start.jar");
commands.addAll(args);
File workingDir = config.jettyBase.toFile();
LOGGER.info("Executing: {}", commands);
LOGGER.info("Working Dir: {}", workingDir.getAbsolutePath());
ProcessBuilder pbCmd = new ProcessBuilder(commands);
pbCmd.directory(workingDir);
Process process = pbCmd.start();
return new Run(process);
}
/**
* @return a free port chosen by the OS that can be used to listen to
* @throws IOException if a free port is not available
*/
public int freePort() throws IOException
{
try (ServerSocket server = new ServerSocket())
{
server.setReuseAddress(true);
server.bind(new InetSocketAddress("localhost", 0));
return server.getLocalPort();
}
}
/**
* Installs in {@code ${jetty.base}/webapps} the given war file under the given context path.
*
* @param warFile the war file to install
* @param context the context path
* @throws IOException if the installation fails
*/
public void installWarFile(File warFile, String context) throws IOException
{
//webapps
Path webapps = Paths.get(config.jettyBase.toString(), "webapps", context);
if (!Files.exists(webapps))
Files.createDirectories(webapps);
unzip(warFile, webapps.toFile());
}
/**
* Resolves an artifact given its Maven coordinates.
*
* @param coordinates <groupId>:<artifactId>[:<extension>[:<classifier>]]:<version>
* @return the artifact
* @see #installWarFile(File, String)
*/
public File resolveArtifact(String coordinates) throws ArtifactResolutionException
{
RepositorySystem repositorySystem = newRepositorySystem();
Artifact artifact = new DefaultArtifact(coordinates);
RepositorySystemSession session = newRepositorySystemSession(repositorySystem);
ArtifactRequest artifactRequest = new ArtifactRequest();
artifactRequest.setArtifact(artifact);
artifactRequest.setRepositories(newRepositories());
ArtifactResult artifactResult = repositorySystem.resolveArtifact(session, artifactRequest);
artifact = artifactResult.getArtifact();
return artifact.getFile();
}
private void init() throws Exception
{
if (config.jettyHome == null)
config.jettyHome = resolveDistribution(config.jettyVersion);
if (config.jettyBase == null)
{
config.jettyBase = Files.createTempDirectory("jetty_base_");
}
else
{
if (!config.jettyBase.isAbsolute())
config.jettyBase = config.jettyHome.resolve(config.jettyBase);
}
}
private String getJavaExecutable()
{
String[] javaExecutables = new String[]{"java", "java.exe"};
File javaHomeDir = new File(System.getProperty("java.home"));
for (String javaExecutable : javaExecutables)
{
File javaFile = new File(javaHomeDir, "bin" + File.separator + javaExecutable);
if (javaFile.exists() && javaFile.isFile())
return javaFile.getAbsolutePath();
}
return "java";
}
private void unzip(File zipFile, File output) throws IOException
{
try (InputStream fileInputStream = Files.newInputStream(zipFile.toPath());
ZipInputStream zipInputStream = new ZipInputStream(fileInputStream))
{
ZipEntry entry = zipInputStream.getNextEntry();
while (entry != null)
{
if (entry.isDirectory())
{
File dir = new File(output, entry.getName());
if (!Files.exists(dir.toPath()))
{
Files.createDirectories(dir.toPath());
}
}
else
{
// Read zipEntry and write to a file.
File file = new File(output, entry.getName());
if (!Files.exists(file.getParentFile().toPath()))
{
Files.createDirectories(file.getParentFile().toPath());
}
try (OutputStream outputStream = Files.newOutputStream(file.toPath()))
{
IOUtil.copy(zipInputStream, outputStream);
}
}
// Get next entry
entry = zipInputStream.getNextEntry();
}
}
}
private Path resolveDistribution(String version) throws Exception
{
File artifactFile = resolveArtifact("org.eclipse.jetty:jetty-distribution:zip:" + version);
// create tmp directory to unzip distribution
Path tmp = Files.createTempDirectory("jetty_home_");
File tmpFile = tmp.toFile();
unzip(artifactFile, tmpFile);
return tmp.resolve("jetty-distribution-" + version);
}
private RepositorySystem newRepositorySystem()
{
DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
locator.addService(TransporterFactory.class, FileTransporterFactory.class);
locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
locator.setErrorHandler(new DefaultServiceLocator.ErrorHandler()
{
@Override
public void serviceCreationFailed(Class<?> type, Class<?> impl, Throwable exception)
{
LOGGER.warn("Service creation failed for {} implementation {}: {}",
type, impl, exception.getMessage(), exception);
}
});
return locator.getService(RepositorySystem.class);
}
private List<RemoteRepository> newRepositories()
{
List<RemoteRepository> remoteRepositories = new ArrayList<>(config.mavenRemoteRepositories.size() + 1);
config.mavenRemoteRepositories.forEach((key, value) -> remoteRepositories.add(new RemoteRepository.Builder(key, "default", value).build()));
remoteRepositories.add(newCentralRepository());
return remoteRepositories;
}
private static RemoteRepository newCentralRepository()
{
return new RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2/").build();
}
private DefaultRepositorySystemSession newRepositorySystemSession(RepositorySystem system)
{
DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
LocalRepository localRepo = new LocalRepository(config.mavenLocalRepository);
session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));
session.setTransferListener(new LogTransferListener());
session.setRepositoryListener(new LogRepositoryListener());
return session;
}
private static class Config
{
private Path jettyBase;
private Path jettyHome;
private String jettyVersion;
private String mavenLocalRepository = System.getProperty("user.home") + "/.m2/repository";
private Map<String, String> mavenRemoteRepositories = new HashMap<>();
@Override
public String toString()
{
return String.format("%s@%x{jettyBase=%s, jettyHome=%s, jettyVersion=%s, mavenLocalRepository=%s, mavenRemoteRepositories=%s}",
getClass().getSimpleName(),
hashCode(),
jettyBase,
jettyHome,
jettyVersion,
mavenLocalRepository,
mavenRemoteRepositories);
}
}
private static class LogTransferListener extends AbstractTransferListener
{
// no op
}
private static class LogRepositoryListener extends AbstractRepositoryListener
{
@Override
public void artifactDownloaded(RepositoryEvent event)
{
LOGGER.debug("distribution downloaded to {}", event.getFile());
}
@Override
public void artifactResolved(RepositoryEvent event)
{
LOGGER.debug("distribution resolved to {}", event.getFile());
}
}
/**
* A distribution run wraps the process that started the Jetty distribution.
*/
public static class Run implements Closeable
{
private final Process process;
private final List<ConsoleStreamer> consoleStreamers = new ArrayList<>();
private final List<String> logs = new ArrayList<>();
private Run(Process process)
{
this.process = process;
consoleStreamers.add(startPump("STDOUT", process.getInputStream()));
consoleStreamers.add(startPump("STDERR", process.getErrorStream()));
}
private ConsoleStreamer startPump(String mode, InputStream stream)
{
ConsoleStreamer pump = new ConsoleStreamer(stream);
Thread thread = new Thread(pump, "ConsoleStreamer/" + mode);
thread.start();
return pump;
}
/**
* Waits for the given time for the distribution process to stop.
*
* @param time the time to wait
* @param unit the unit of time
* @return true if the distribution process is terminated, false if the timeout elapsed
* @throws InterruptedException if the wait is interrupted
*/
public boolean awaitFor(long time, TimeUnit unit) throws InterruptedException
{
boolean result = process.waitFor(time, unit);
if (result)
stopConsoleStreamers();
return result;
}
/**
* @return the distribution process exit value
* @throws IllegalThreadStateException if the distribution process is not terminated yet
*/
public int getExitValue() throws IllegalThreadStateException
{
return process.exitValue();
}
/**
* Stops the distribution process.
*
* @see #awaitFor(long, TimeUnit)
*/
public void stop()
{
process.destroy();
stopConsoleStreamers();
}
/**
* Forcibly destroys the distribution process.
*/
public void destroy()
{
process.destroyForcibly();
stopConsoleStreamers();
}
private void stopConsoleStreamers()
{
consoleStreamers.forEach(ConsoleStreamer::stop);
}
/**
* @see #destroy()
*/
@Override
public void close()
{
destroy();
}
/**
* Awaits the console logs to contain the given text, for the given amount of time.
*
* @param txt the text that must be present in the console logs
* @param time the time to wait
* @param unit the unit of time
* @return true if the text was found, false if the timeout elapsed
* @throws InterruptedException if the wait is interrupted
*/
public boolean awaitConsoleLogsFor(String txt, long time, TimeUnit unit) throws InterruptedException
{
long end = System.nanoTime() + unit.toNanos(time);
while (System.nanoTime() < end)
{
boolean result = logs.stream().anyMatch(s -> s.contains(txt));
if (result)
return true;
Thread.sleep(250);
}
return false;
}
/**
* Simple streamer for the console output from a Process
*/
private class ConsoleStreamer implements Runnable
{
private final BufferedReader reader;
private volatile boolean stop;
public ConsoleStreamer(InputStream stream)
{
this.reader = new BufferedReader(new InputStreamReader(stream));
}
@Override
public void run()
{
try
{
String line;
while ((line = reader.readLine()) != null && !stop)
{
LOGGER.info("{}", line);
logs.add(line);
}
}
catch (IOException ignore)
{
// ignore
}
finally
{
IO.close(reader);
}
}
public void stop()
{
stop = true;
IO.close(reader);
}
}
}
public static class Builder
{
private Config config = new Config();
private Builder()
{
}
/**
* @param jettyVersion the version to use (format: 9.4.14.v20181114 9.4.15-SNAPSHOT).
* The distribution will be downloaded from local repository or remote
* @return the {@link Builder}
*/
public Builder jettyVersion(String jettyVersion)
{
config.jettyVersion = jettyVersion;
return this;
}
/**
* @param jettyHome Path to the local exploded jetty distribution
* if configured the jettyVersion parameter will not be used
* @return the {@link Builder}
*/
public Builder jettyHome(Path jettyHome)
{
config.jettyHome = jettyHome;
return this;
}
/**
* <p>Sets the path for the Jetty Base directory.</p>
* <p>If the path is relative, it will be resolved against the Jetty Home directory.</p>
*
* @param jettyBase Path to the local Jetty Base directory
* @return the {@link Builder}
*/
public Builder jettyBase(Path jettyBase)
{
config.jettyBase = jettyBase;
return this;
}
/**
* @param mavenLocalRepository Path to the local maven repository
* @return the {@link Builder}
*/
public Builder mavenLocalRepository(String mavenLocalRepository)
{
config.mavenLocalRepository = mavenLocalRepository;
return this;
}
/**
* If needed to resolve the Jetty distribution from another Maven remote repositories
*
* @param id the id
* @param url the Maven remote repository url
* @return the {@link Builder}
*/
public Builder addRemoteRepository(String id, String url)
{
config.mavenRemoteRepositories.put(id, url);
return this;
}
/**
* @return an empty instance of {@link Builder}
*/
public static Builder newInstance()
{
return new Builder();
}
/**
* @return a new configured instance of {@link DistributionTester}
*/
public DistributionTester build() throws Exception
{
DistributionTester tester = new DistributionTester(config);
tester.init();
return tester;
}
}
}

View File

@ -0,0 +1,47 @@
//
// ========================================================================
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.tests.distribution;
import java.util.function.Supplier;
import org.eclipse.jetty.client.HttpClient;
import org.junit.jupiter.api.AfterEach;
public class AbstractDistributionTest
{
protected HttpClient client;
protected void startHttpClient() throws Exception
{
startHttpClient(HttpClient::new);
}
protected void startHttpClient(Supplier<HttpClient> supplier) throws Exception
{
client = supplier.get();
client.start();
}
@AfterEach
public void dispose() throws Exception
{
if (client != null)
client.stop();
}
}

View File

@ -0,0 +1,207 @@
//
// ========================================================================
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.tests.distribution;
import java.io.File;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http2.client.HTTP2Client;
import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnJre;
import org.junit.jupiter.api.condition.JRE;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class DistributionTests extends AbstractDistributionTest
{
@Test
public void testStartStop() throws Exception
{
String jettyVersion = System.getProperty("jettyVersion");
DistributionTester distribution = DistributionTester.Builder.newInstance()
.jettyVersion(jettyVersion)
.mavenLocalRepository(System.getProperty("mavenRepoPath"))
.build();
try (DistributionTester.Run run1 = distribution.start("--add-to-start=http"))
{
assertTrue(run1.awaitFor(5, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
int port = distribution.freePort();
try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS));
startHttpClient();
ContentResponse response = client.GET("http://localhost:" + port);
assertEquals(HttpStatus.NOT_FOUND_404, response.getStatus());
run2.stop();
assertTrue(run2.awaitFor(5, TimeUnit.SECONDS));
}
}
}
@Test
public void testSimpleWebAppWithJSP() throws Exception
{
String jettyVersion = System.getProperty("jettyVersion");
DistributionTester distribution = DistributionTester.Builder.newInstance()
.jettyVersion(jettyVersion)
.mavenLocalRepository(System.getProperty("mavenRepoPath"))
.build();
String[] args1 = {
"--create-startd",
"--approve-all-licenses",
"--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,servlet,servlets"
};
try (DistributionTester.Run run1 = distribution.start(args1))
{
assertTrue(run1.awaitFor(5, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + jettyVersion);
distribution.installWarFile(war, "test");
int port = distribution.freePort();
try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS));
startHttpClient();
ContentResponse response = client.GET("http://localhost:" + port + "/test/index.jsp");
assertEquals(HttpStatus.OK_200, response.getStatus());
assertThat(response.getContentAsString(), containsString("Hello"));
assertThat(response.getContentAsString(), not(containsString("<%")));
}
}
}
@Test
@DisabledOnJre(JRE.JAVA_8)
public void testSimpleWebAppWithJSPOnModulePath() throws Exception
{
String jettyVersion = System.getProperty("jettyVersion");
DistributionTester distribution = DistributionTester.Builder.newInstance()
.jettyVersion(jettyVersion)
.mavenLocalRepository(System.getProperty("mavenRepoPath"))
.build();
String[] args1 = {
"--create-startd",
"--approve-all-licenses",
"--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,servlet,servlets"
};
try (DistributionTester.Run run1 = distribution.start(args1))
{
assertTrue(run1.awaitFor(5, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + jettyVersion);
distribution.installWarFile(war, "test");
int port = distribution.freePort();
String[] args2 = {
"--jpms",
"jetty.http.port=" + port
};
try (DistributionTester.Run run2 = distribution.start(args2))
{
assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS));
startHttpClient();
ContentResponse response = client.GET("http://localhost:" + port + "/test/index.jsp");
assertEquals(HttpStatus.OK_200, response.getStatus());
assertThat(response.getContentAsString(), containsString("Hello"));
assertThat(response.getContentAsString(), not(containsString("<%")));
}
}
}
@Test
@DisabledOnJre(JRE.JAVA_8)
public void testSimpleWebAppWithJSPOverH2C() throws Exception
{
String jettyVersion = System.getProperty("jettyVersion");
DistributionTester distribution = DistributionTester.Builder.newInstance()
.jettyVersion(jettyVersion)
.mavenLocalRepository(System.getProperty("mavenRepoPath"))
.build();
String[] args1 = {
"--create-startd",
"--add-to-start=http2c,jsp,deploy"
};
try (DistributionTester.Run run1 = distribution.start(args1))
{
assertTrue(run1.awaitFor(5, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + jettyVersion);
distribution.installWarFile(war, "test");
int port = distribution.freePort();
try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS));
HTTP2Client h2Client = new HTTP2Client();
startHttpClient(() -> new HttpClient(new HttpClientTransportOverHTTP2(h2Client), null));
ContentResponse response = client.GET("http://localhost:" + port + "/test/index.jsp");
assertEquals(HttpStatus.OK_200, response.getStatus());
assertThat(response.getContentAsString(), containsString("Hello"));
assertThat(response.getContentAsString(), not(containsString("<%")));
}
}
}
@Test
public void testDemoBase() throws Exception
{
String jettyVersion = System.getProperty("jettyVersion");
DistributionTester distribution = DistributionTester.Builder.newInstance()
.jettyVersion(jettyVersion)
.jettyBase(Paths.get("demo-base"))
.mavenLocalRepository(System.getProperty("mavenRepoPath"))
.build();
int port = distribution.freePort();
try (DistributionTester.Run run1 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run1.awaitConsoleLogsFor("Started @", 20, TimeUnit.SECONDS));
startHttpClient();
ContentResponse response = client.GET("http://localhost:" + port + "/test/jsp/dump.jsp");
assertEquals(HttpStatus.OK_200, response.getStatus());
assertThat(response.getContentAsString(), containsString("PathInfo"));
assertThat(response.getContentAsString(), not(containsString("<%")));
}
}
}

View File

@ -0,0 +1,2 @@
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
#org.eclipse.jetty.LEVEL=DEBUG

View File

@ -56,6 +56,7 @@ import org.eclipse.jetty.toolchain.test.JAR;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.toolchain.test.PathAssert;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
import org.junit.jupiter.api.Assertions;
/**
@ -315,19 +316,15 @@ public class JettyDistro
// The actual jetty-distribution-${version} directory is under this directory.
// Lets find it.
File subdirs[] = distroUnpackDir.listFiles(new FileFilter()
{
@Override
public boolean accept(File path)
File subdirs[] = distroUnpackDir.listFiles( path ->
{
if (!path.isDirectory())
{
return false;
}
return path.getName().startsWith(artifactName + "-");
}
});
);
if (subdirs.length == 0)
{
@ -550,7 +547,7 @@ public class JettyDistro
if (cmdLine == null || !cmdLine.contains("XmlConfiguration"))
{
fail("Unable to get Jetty command line");
Assertions.fail( "Unable to get Jetty command line");
}
// Need to breakdown commandline into parts, as spaces in command line will cause failures.
@ -595,7 +592,7 @@ public class JettyDistro
catch (InterruptedException e)
{
pid.destroy();
fail("Unable to get required information within time limit");
Assertions.fail( "Unable to get required information within time limit");
}
}
@ -804,7 +801,7 @@ public class JettyDistro
}
}
fail("Unable to find java bin");
Assertions.fail( "Unable to find java bin");
return "java";
}

View File

@ -49,7 +49,7 @@ import org.junit.jupiter.api.Disabled;
public class TestableJettyServer
{
private List<URL> _xmlConfigurations;
private final Map<String,String> _properties = new HashMap<String, String>();
private final Map<String,String> _properties = new HashMap<>();
private Server _server;
private int _serverPort;
private String _scheme = HttpScheme.HTTP.asString();
@ -60,7 +60,7 @@ public class TestableJettyServer
public TestableJettyServer() throws IOException
{
_xmlConfigurations = new ArrayList<URL>();
_xmlConfigurations = new ArrayList<>();
Properties properties = new Properties();
/* Establish Popular Directories */

View File

@ -39,5 +39,6 @@
<module>test-jaas-webapp</module>
<module>test-jndi-webapp</module>
<module>test-http2-webapp</module>
<module>test-simple-webapp</module>
</modules>
</project>
</project>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-webapps-parent</artifactId>
<version>10.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>test-simple-webapp</artifactId>
<packaging>war</packaging>
<name>Test :: Jetty Test Simple Webapp</name>
</project>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
metadata-complete="false"
version="3.1">
<display-name>Very Simple Web Application</display-name>
</web-app>

View File

@ -0,0 +1,5 @@
<html>
<body>
<h2>Hello World!</h2>
</body>
</html>