diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3858e9bd5cb..90a9c7039dc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -52,3 +52,13 @@ Create a new bug Be sure to search for existing bugs before you create another one. Remember that contributions are always welcome! - [https://github.com/eclipse/jetty.project/issues](https://github.com/eclipse/jetty.project/issues) + +Reporting Security Issues +----------------- +There are a number of avenues for reporting security issues to the Jetty project available. +If the issue is directly related to Jetty itself then reporting to the Jetty developers is encouraged. +The most direct method is to mail [security@webtide.com](mailto:security@webtide.com). +Webtide is comprised of the active committers of the Jetty project is our preferred reporting method. +We are flexible in how we work with reporters of security issues but we reserve the right to act in the interests of the Jetty project in all circumstances. + +If the issue is related to Eclipse or its Jetty integration then we encourage you to reach out to [security@eclipse.org](mailto:security@eclipse.org). diff --git a/apache-jstl/src/test/java/org/eclipse/jetty/jstl/JstlTest.java b/apache-jstl/src/test/java/org/eclipse/jetty/jstl/JstlTest.java index a30e51881ee..43cfd15e04a 100644 --- a/apache-jstl/src/test/java/org/eclipse/jetty/jstl/JstlTest.java +++ b/apache-jstl/src/test/java/org/eclipse/jetty/jstl/JstlTest.java @@ -19,12 +19,16 @@ package org.eclipse.jetty.jstl; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertThat; import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; import java.net.URI; +import java.nio.charset.StandardCharsets; import javax.servlet.jsp.JspException; @@ -33,7 +37,7 @@ import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.toolchain.test.FS; import org.eclipse.jetty.toolchain.test.JAR; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.toolchain.test.SimpleRequest; +import org.eclipse.jetty.util.IO; import org.eclipse.jetty.webapp.Configuration; import org.eclipse.jetty.webapp.WebAppContext; import org.junit.AfterClass; @@ -104,32 +108,43 @@ public class JstlTest @Test public void testUrlsBasic() throws IOException { - SimpleRequest req = new SimpleRequest(baseUri); - String resp = req.getString("/urls.jsp"); - assertThat("Response should be JSP processed", resp, not(containsString(""))); - assertThat("Response should be JSP processed", resp, not(containsString(""))); - assertThat("Response", resp, not(containsString("[jtest:errorhandler] exception is null"))); + HttpURLConnection http = (HttpURLConnection) baseUri.resolve("/catch-taglib.jsp").toURL().openConnection(); + assertThat("http response", http.getResponseCode(), is(200)); + try(InputStream input = http.getInputStream()) + { + String resp = IO.toString(input, StandardCharsets.UTF_8); + assertThat("Response should be JSP processed", resp, not(containsString(""))); + assertThat("Response should be JSP processed", resp, not(containsString(""))); + assertThat("Response", resp, not(containsString("[jtest:errorhandler] exception is null"))); + } } } diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java index f8da64bdf20..8ab3cfe5f9a 100644 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java @@ -171,7 +171,7 @@ public class TestAnnotationParser // Intentionally using a base director name that starts with a "." // This mimics what you see in jenkins, hudson, hadoop, solr, camel, and selenium for their // installed and/or managed webapps - File basedir = testdir.getFile(".base/workspace/classes"); + File basedir = testdir.getPathFile(".base/workspace/classes").toFile(); FS.ensureEmpty(basedir); // Copy in class that is known to have annotations. diff --git a/jetty-ant/src/test/java/org/eclipse/jetty/ant/AntBuild.java b/jetty-ant/src/test/java/org/eclipse/jetty/ant/AntBuild.java index 48a6edbfccb..c16b4592d5a 100644 --- a/jetty-ant/src/test/java/org/eclipse/jetty/ant/AntBuild.java +++ b/jetty-ant/src/test/java/org/eclipse/jetty/ant/AntBuild.java @@ -64,7 +64,7 @@ public class AntBuild Project antProject = new Project(); try { - antProject.setBaseDir(MavenTestingUtils.getBasedir()); + antProject.setBaseDir(MavenTestingUtils.getBaseDir()); antProject.setUserProperty("ant.file",buildFile.getAbsolutePath()); DefaultLogger logger = new DefaultLogger(); diff --git a/jetty-cdi/cdi-servlet/src/test/java/org/eclipse/jetty/cdi/servlet/WeldInitializationTest.java b/jetty-cdi/cdi-servlet/src/test/java/org/eclipse/jetty/cdi/servlet/WeldInitializationTest.java index e9c490de333..1eff479d8ca 100644 --- a/jetty-cdi/cdi-servlet/src/test/java/org/eclipse/jetty/cdi/servlet/WeldInitializationTest.java +++ b/jetty-cdi/cdi-servlet/src/test/java/org/eclipse/jetty/cdi/servlet/WeldInitializationTest.java @@ -19,15 +19,18 @@ package org.eclipse.jetty.cdi.servlet; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import java.io.File; +import java.io.InputStream; +import java.net.HttpURLConnection; import java.net.URI; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.toolchain.test.SimpleRequest; +import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.log.JettyLogHandler; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -91,25 +94,27 @@ public class WeldInitializationTest @Test public void testRequestParamServletDefault() throws Exception { - SimpleRequest req = new SimpleRequest(serverHttpURI); - String resp = req.getString("req-info"); - - System.out.println(resp); - - assertThat("Response",resp,containsString("request is PRESENT")); - assertThat("Response",resp,containsString("parameters.size = [0]")); + HttpURLConnection http = (HttpURLConnection) serverHttpURI.resolve("req-info").toURL().openConnection(); + assertThat("response code", http.getResponseCode(), is(200)); + try(InputStream inputStream = http.getInputStream()) + { + String resp = IO.toString(inputStream); + assertThat("Response", resp, containsString("request is PRESENT")); + assertThat("Response", resp, containsString("parameters.size = [0]")); + } } @Test public void testRequestParamServletAbc() throws Exception { - SimpleRequest req = new SimpleRequest(serverHttpURI); - String resp = req.getString("req-info?abc=123"); - - System.out.println(resp); - - assertThat("Response",resp,containsString("request is PRESENT")); - assertThat("Response",resp,containsString("parameters.size = [1]")); - assertThat("Response",resp,containsString(" param[abc] = [123]")); + HttpURLConnection http = (HttpURLConnection) serverHttpURI.resolve("req-info?abc=123").toURL().openConnection(); + assertThat("response code", http.getResponseCode(), is(200)); + try(InputStream inputStream = http.getInputStream()) + { + String resp = IO.toString(inputStream); + assertThat("Response", resp, containsString("request is PRESENT")); + assertThat("Response", resp, containsString("parameters.size = [1]")); + assertThat("Response", resp, containsString(" param[abc] = [123]")); + } } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/GZIPContentDecoder.java b/jetty-client/src/main/java/org/eclipse/jetty/client/GZIPContentDecoder.java index 3ccfde883e1..a3d033a7dfd 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/GZIPContentDecoder.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/GZIPContentDecoder.java @@ -18,6 +18,7 @@ package org.eclipse.jetty.client; +import org.eclipse.jetty.io.ByteBufferPool; /** * {@link ContentDecoder} for the "gzip" encoding. @@ -26,14 +27,21 @@ package org.eclipse.jetty.client; public class GZIPContentDecoder extends org.eclipse.jetty.http.GZIPContentDecoder implements ContentDecoder { + private static final int DEFAULT_BUFFER_SIZE = 2048; + public GZIPContentDecoder() { - this(2048); + this(DEFAULT_BUFFER_SIZE); } public GZIPContentDecoder(int bufferSize) { - super(null,bufferSize); + this(null,bufferSize); + } + + public GZIPContentDecoder(ByteBufferPool byteBufferPool, int bufferSize) + { + super(byteBufferPool, bufferSize); } /** @@ -42,22 +50,34 @@ public class GZIPContentDecoder extends org.eclipse.jetty.http.GZIPContentDecode public static class Factory extends ContentDecoder.Factory { private final int bufferSize; + private final ByteBufferPool byteBufferPool; public Factory() { - this(2048); + this(DEFAULT_BUFFER_SIZE); } public Factory(int bufferSize) + { + this(null, bufferSize); + } + + public Factory(ByteBufferPool byteBufferPool) + { + this(byteBufferPool, DEFAULT_BUFFER_SIZE); + } + + public Factory(ByteBufferPool byteBufferPool, int bufferSize) { super("gzip"); + this.byteBufferPool = byteBufferPool; this.bufferSize = bufferSize; } @Override public ContentDecoder newContentDecoder() { - return new GZIPContentDecoder(bufferSize); + return new GZIPContentDecoder(byteBufferPool, bufferSize); } } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java index 4dd571cf871..554b467d720 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java @@ -224,7 +224,7 @@ public class HttpClient extends ContainerLifeCycle handlers.put(new WWWAuthenticationProtocolHandler(this)); handlers.put(new ProxyAuthenticationProtocolHandler(this)); - decoderFactories.add(new GZIPContentDecoder.Factory()); + decoderFactories.add(new GZIPContentDecoder.Factory(byteBufferPool)); cookieManager = newCookieManager(); cookieStore = cookieManager.getCookieStore(); diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java index 77e21f10051..3239f703b89 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java @@ -271,6 +271,12 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res return !proceed || async; } + @Override + public boolean contentComplete() + { + return false; + } + @Override public boolean messageComplete() { diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/AppLifeCycleTest.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/AppLifeCycleTest.java index 9c9f70976e5..a39ab36c7bf 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/AppLifeCycleTest.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/AppLifeCycleTest.java @@ -176,7 +176,7 @@ public class AppLifeCycleTest AppLifeCycle lifecycle = new AppLifeCycle(); List expected = new ArrayList(); - File outputDir = testdir.getEmptyDir(); + File outputDir = testdir.getEmptyPathDir().toFile(); // Modify graph to add new 'staging' -> 'staged' between 'deployed' and 'started' GraphOutputDot.write(lifecycle,new File(outputDir,"multiple-1.dot")); // before change diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java index 95b4beffdbd..6f9b7ce9df6 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java @@ -70,7 +70,7 @@ public class XmlConfiguredJetty _xmlConfigurations = new ArrayList<>(); Properties properties = new Properties(); - String jettyHomeBase = testdir.getDir().getAbsolutePath(); + String jettyHomeBase = testdir.getPath().toString(); // Ensure we have a new (pristene) directory to work with. int idx = 0; _jettyHome = new File(jettyHomeBase + "#" + idx); @@ -116,7 +116,7 @@ public class XmlConfiguredJetty System.setProperty("java.io.tmpdir",tmpDir.getAbsolutePath()); properties.setProperty("jetty.home",_jettyHome.getAbsolutePath()); System.setProperty("jetty.home",_jettyHome.getAbsolutePath()); - properties.setProperty("test.basedir",MavenTestingUtils.getBasedir().getAbsolutePath()); + properties.setProperty("test.basedir",MavenTestingUtils.getBaseDir().getAbsolutePath()); properties.setProperty("test.resourcesdir",MavenTestingUtils.getTestResourcesDir().getAbsolutePath()); properties.setProperty("test.webapps",webappsDir.getAbsolutePath()); properties.setProperty("test.targetdir",MavenTestingUtils.getTargetDir().getAbsolutePath()); diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/start-jar.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/start-jar.adoc index 1634c26eda6..4a205a3f685 100644 --- a/jetty-documentation/src/main/asciidoc/administration/startup/start-jar.adoc +++ b/jetty-documentation/src/main/asciidoc/administration/startup/start-jar.adoc @@ -55,6 +55,7 @@ When executed `start.jar` performs the following actions: * Loads and parses all INIs found in `${jetty.base}/start.d/*.ini` as command line arguments. * Loads and parses `${jetty.base}/start.ini` as command line arguments. +** Please see link:#start-vs-startd[Start.ini vs. Start.d] for more information on the difference between these. * Parses actual command line arguments used to execute `start.jar` itself. * Resolves any XML configuration files, modules, and libraries using base vs. home resolution steps: 1. Checks whether file exists as relative reference to `${jetty.base}.` @@ -217,3 +218,18 @@ The time (in seconds) to wait for confirmation that the running Jetty server has If not specified, the stopper waits indefinitely for the server to stop. + If the time specified elapses, without a confirmation of server stop, then the `--stop` command exits with a non-zero return code. + +===== Advanced Commands + +--lib=:: +Add arbitrary classpath entries to the the server classpath. + +--include-jetty-dir=:: +Include an extra Jetty directory to use as a source for configuration details. +This directory behaves similarly to `${jetty.base}` but sits at a layer between `${jetty.base}` and `${jetty.home}`. +This allows for some complex hierarchies of configuration details. + +--download=|:: +If the file does not exist at the given location, download it from the given http URI. +Note: location is always relative to `${jetty.base}`. +You might need to escape the slash "\|" to use this on some environments. diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/startup-base-vs-home.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/startup-base-vs-home.adoc index 5dd8ef12e5e..496c50c99c7 100644 --- a/jetty-documentation/src/main/asciidoc/administration/startup/startup-base-vs-home.adoc +++ b/jetty-documentation/src/main/asciidoc/administration/startup/startup-base-vs-home.adoc @@ -18,7 +18,7 @@ === Managing Jetty Base and Jetty Home Instead of managing multiple Jetty implementations out of several different distribution locations, it is possible to maintain a separation between the binary installation of the standalone Jetty (known as `${jetty.home}`), and the customizations for your specific environment(s) (known as `${jetty.base}`). -There should always only be one Jetty Home, but there can be multiple Jetty Base directories that references. +There should always only be *one* Jetty Home (per version of Jetty), but there can be multiple Jetty Base directories that reference it. Jetty Base:: * Also known as the `${jetty.base}` property. @@ -36,26 +36,22 @@ ____ [[base-vs-home-resolution]] Potential configuration is resolved from these 2 directory locations. +When Jetty starts up in processes configuration from them as follows: -Check Jetty Base:: - If the referenced configuration exists, relative to the defined Jetty base, use it. -Check Jetty Home:: - If the referenced configuration exists, relative to the defined Jetty home, use it. +Check Jetty Base First:: + If the referenced configuration exists, relative to the defined Jetty base, it is used. +Check Jetty Home Second:: + If the referenced configuration exists, relative to the defined Jetty home, it is used. Use java.io.File(String pathname) Logic:: - Lastly, use the reference as a `java.io.File(String pathname)` reference, following the default resolution rules outlined by that constructor. + Lastly, use the reference as a `java.io.File(String pathname)` reference, following the default resolution rules outlined by that constructor. In brief, the reference will be used as-is, be it relative (to current working directory, aka $\{user.dir}) or absolute path, or even network reference (such as on Windows and use of UNC paths). -+ -In brief, the reference will be used as-is, be it relative (to current working directory, aka $\{user.dir}) or absolute path, or even network reference (such as on Windows and use of UNC paths). - -For more details on how startup with start.jar works, see link:#execute-start-jar[Using start.jar: Executing] +For more details on how startup with start.jar works, see link:#executing-startjar[Using start.jar: Executing] [[demo-base]] ==== Demo-Base in the Jetty Distribution The Jetty Distribution comes with an example `${jetty.base}` which enables the various demonstration webapps and server configurations. -How to use the demo-base directory as a Jetty Base directory. - [source, screen, subs="{sub-order}"] .... [jetty-distribution-{VERSION}]$ ls -la @@ -89,31 +85,39 @@ drwxrwxr-x 2 user group 4096 Oct 8 06:54 webapps/ ... .... -As you can see above, you are executing the demo-base configuration using the Jetty base concepts. - -If you want to see what the Jetty base looks like without executing Jetty, you can simply list the configuration +If you want to see what the Jetty base looks like without executing Jetty, you can simply list the configuration by using the `--list-config` command. [source, screen, subs="{sub-order}"] .... -[my-base]$ java -jar $JETTY_HOME/start.jar --list-config +[demo-base]$ java -jar $JETTY_HOME/start.jar --list-config Java Environment: ----------------- java.home=/usr/lib/jvm/jdk-7u21-x64/jre - java.vm.vendor=Oracle Corporation - java.vm.version=23.21-b01 - java.vm.name=Java HotSpot(TM) 64-Bit Server VM - java.vm.info=mixed mode - java.runtime.name=Java(TM) SE Runtime Environment - java.runtime.version=1.7.0_21-b11 - java.io.tmpdir=/tmp + java.vm.vendor = Oracle Corporation + java.vm.version = 25.92-b14 + java.vm.name = Java HotSpot(TM) 64-Bit Server VM + java.vm.info = mixed mode + java.runtime.name = Java(TM) SE Runtime Environment + java.runtime.version = 1.8.0_92-b14 + java.io.tmpdir = /var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/ + user.dir = /home/user/jetty-distribution-{VERSION} + user.language = en + user.country = US Jetty Environment: ----------------- jetty.home=/home/user/jetty-distribution-{VERSION} + jetty.tag.version = master jetty.base=/home/user/jetty-distribution-{VERSION}/demo-base jetty.version={VERSION} + Config Search Order: + -------------------- + + ${jetty.base} -> /home/user/jetty-distribution-9.4.1.v20170120/demo-base + ${jetty.home} -> /home/user/Desktop/jetty-distribution-9.4.1.v20170120 + JVM Arguments: -------------- (no jvm args specified) @@ -194,20 +198,22 @@ Note: order presented here is how they would appear on the classpath. Jetty Active XMLs: ------------------ ${jetty.home}/etc/jetty.xml - ${jetty.home}/etc/jetty-http.xml - ${jetty.home}/etc/jetty-jaas.xml - ${jetty.home}/etc/jetty-rewrite.xml - ${jetty.home}/etc/jetty-ssl.xml - ${jetty.home}/etc/jetty-https.xml + ${jetty.home}/etc/jetty-webapp.xml ${jetty.home}/etc/jetty-plus.xml ${jetty.home}/etc/jetty-annotations.xml ${jetty.home}/etc/jetty-deploy.xml + ${jetty.home}/etc/jetty-http.xml + ${jetty.home}/etc/jetty-ssl.xml + ${jetty.home}/etc/jetty-ssl-context.xml + ${jetty.home}/etc/jetty-https.xml + ${jetty.home}/etc/jetty-jaas.xml + ${jetty.home}/etc/jetty-rewrite.xml ${jetty.base}/etc/demo-rewrite-rules.xml ${jetty.base}/etc/test-realm.xml .... -This demonstrates the powerful `--list-config` command line option and how you can use it to see what the configuration will look like when starting Jetty. -From the Java environment, to the system properties, to the classpath, and finally the Active Jetty IoC XML used to build up the Jetty server configuration. +The `--list-config` command line option displays what the configuration will look like when starting Jetty. +This includes information on the Java environment to the system properties, the classpath and the Active Jetty IoC XML used to build up the Jetty server configuration. Of note, is that the output will make it known where the configuration elements came from, be it in either in `${jetty.home}` or `${jetty.base}`. diff --git a/jetty-documentation/src/main/asciidoc/development/embedding/jetty-helloworld.adoc b/jetty-documentation/src/main/asciidoc/development/embedding/jetty-helloworld.adoc index 89699ef8b84..491872bd241 100644 --- a/jetty-documentation/src/main/asciidoc/development/embedding/jetty-helloworld.adoc +++ b/jetty-documentation/src/main/asciidoc/development/embedding/jetty-helloworld.adoc @@ -23,8 +23,8 @@ This section provides a tutorial that shows how you can quickly develop embedded ==== Downloading the Jars Jetty is decomposed into many jars and dependencies to achieve a minimal footprint by selecting the minimal set of jars. -Typically it is best to use something like Maven to manage jars, however this tutorial uses an aggregate Jar that contains all of the Jetty classes in one Jar. -You can manually download the aggregate link:http://central.maven.org/maven2/org/eclipse/jetty/aggregate/jetty-all/{VERSION}/jetty-all-{VERSION}-uber.jar[`jetty-all.jar`] using `curl`) or a browser. +Typically it is best to use something like link:#jetty-maven-helloworld[Maven] to manage jars, however this tutorial uses an aggregate Jar that contains all of the required Jetty classes in one Jar. +You can manually download the aggregate link:http://central.maven.org/maven2/org/eclipse/jetty/aggregate/jetty-all/{VERSION}/jetty-all-{VERSION}-uber.jar[`jetty-all.jar`] using `curl` or a browser. ____ [NOTE] @@ -32,6 +32,12 @@ The central Maven repository has started to aggressively reject/deny access to t The administrators of the central maven repository have stated that the recommended command line download tool is now curl. ____ +____ +[IMPORTANT] +The `jetty-all` jar referenced in this section is for example purposes only and should not be used outside of this context. +Please consider using link:#jetty-maven-helloworld[Maven] to manage your project dependencies. +____ + Use curl as follows: [source, screen, subs="{sub-order}"] diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ResponseContentParser.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ResponseContentParser.java index f28155382bd..8a186b792fe 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ResponseContentParser.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ResponseContentParser.java @@ -284,6 +284,12 @@ public class ResponseContentParser extends StreamContentParser } } + @Override + public boolean contentComplete() + { + return false; + } + @Override public boolean messageComplete() { diff --git a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnection.java b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnection.java index 9f5c44ab2ef..19e570118fc 100644 --- a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnection.java +++ b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnection.java @@ -175,6 +175,7 @@ public class ServerFCGIConnection extends AbstractConnection LOG.debug("Request {} end on {}", request, channel); if (channel != null) { + channel.onContentComplete(); channel.onRequestComplete(); } } diff --git a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml index 913ef9af731..0ddf377e667 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml +++ b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml @@ -20,6 +20,17 @@ com.google.cloud google-cloud-datastore ${gcloud.version} + + + javax.servlet + servlet-api + + + javax.servlet + javax.servlet-api + + + org.eclipse.jetty @@ -69,6 +80,86 @@ + + org.apache.maven.plugins + maven-dependency-plugin + 3.0.0 + + + build-deps-file + generate-resources + + list + + + false + ${project.build.directory}/deps.txt + true + true + runtime + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + process-deps + process-resources + + run + + + + + + + + + + process-mod + process-resources + + run + + + + + + + + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + package + + single + + + + src/main/assembly/config.xml + + + + + diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/assembly/config.xml b/jetty-gcloud/jetty-gcloud-session-manager/src/main/assembly/config.xml new file mode 100644 index 00000000000..29e5be1228a --- /dev/null +++ b/jetty-gcloud/jetty-gcloud-session-manager/src/main/assembly/config.xml @@ -0,0 +1,27 @@ + + + config + false + + jar + + + + src/main/config-template + + + ** + + + **/gcloud-datastore.mod + + + + target + modules + + gcloud-datastore.mod + + + + diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config/etc/sessions/gcloud/session-store.xml b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/etc/sessions/gcloud/session-store.xml similarity index 100% rename from jetty-gcloud/jetty-gcloud-session-manager/src/main/config/etc/sessions/gcloud/session-store.xml rename to jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/etc/sessions/gcloud/session-store.xml diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud-datastore.mod b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud-datastore.mod new file mode 100644 index 00000000000..c65ccd33704 --- /dev/null +++ b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud-datastore.mod @@ -0,0 +1,12 @@ +[description] +Enables GCloud Datastore API and implementation + +[tags] +3rdparty +gcloud + +[depends] +gcloud +jcl-slf4j +jul-impl + diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config/modules/gcloud.mod b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud.mod similarity index 100% rename from jetty-gcloud/jetty-gcloud-session-manager/src/main/config/modules/gcloud.mod rename to jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud.mod diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config/modules/gcloud/index.yaml b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud/index.yaml similarity index 100% rename from jetty-gcloud/jetty-gcloud-session-manager/src/main/config/modules/gcloud/index.yaml rename to jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud/index.yaml diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config/modules/session-store-gcloud.mod b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/session-store-gcloud.mod similarity index 100% rename from jetty-gcloud/jetty-gcloud-session-manager/src/main/config/modules/session-store-gcloud.mod rename to jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/session-store-gcloud.mod diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config/modules/gcloud-datastore.mod b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config/modules/gcloud-datastore.mod deleted file mode 100644 index 6547bc2e532..00000000000 --- a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config/modules/gcloud-datastore.mod +++ /dev/null @@ -1,58 +0,0 @@ -[description] -Enables GCloud Datastore API and implementation - -[tags] -3rdparty -gcloud - -[depends] -gcloud -jcl-slf4j -jul-impl - -[files] -maven://aopalliance/aopalliance/1.0|lib/gcloud/aopalliance-1.0.jar -maven://com.fasterxml.jackson.core/jackson-core/2.1.3|lib/gcloud/jackson-core-2.1.3.jar -maven://com.google.api/api-common/0.0.2|lib/gcloud/api-common-0.0.2.jar -maven://com.google.api-client/google-api-client/1.20.0|lib/gcloud/google-api-client-1.20.0.jar -maven://com.google.api-client/google-api-client-appengine/1.21.0|lib/gcloud/google-api-client-appengine-1.21.0.jar -maven://com.google.api-client/google-api-client-servlet/1.21.0|lib/gcloud/google-api-client-servlet-1.21.0.jar -maven://com.google.api/gax/0.0.25|lib/gcloud/gax-0.0.25.jar -maven://com.google.api.grpc/grpc-google-common-protos/0.1.3|lib/gcloud/grpc-google-common-protos-0.1.3.jar -maven://com.google.api.grpc/grpc-google-iam-v1/0.1.3|lib/gcloud/grpc-google-iam-v1-0.1.3.jar -maven://com.google.auth/google-auth-library-credentials/0.6.0|lib/gcloud/google-auth-library-credentials-0.6.0.jar -maven://com.google.auth/google-auth-library-oauth2-http/0.6.0|lib/gcloud/google-auth-library-oauth2-http-0.6.0.jar -maven://com.google.auto.value/auto-value/1.2|lib/gcloud/auto-value-1.2.jar -maven://com.google.cloud.datastore/datastore-v1-proto-client/1.3.0|lib/gcloud/datastore-v1-proto-client-1.3.0.jar -maven://com.google.cloud.datastore/datastore-v1-protos/1.3.0|lib/gcloud/datastore-v1-protos-1.3.0.jar -maven://com.google.cloud/google-cloud-core/0.7.0|lib/gcloud/google-cloud-core-0.7.0.jar -maven://com.google.cloud/google-cloud-datastore/0.7.0|lib/gcloud/google-cloud-datastore-0.7.0.jar -maven://com.google.code.findbugs/jsr305/1.3.9|lib/gcloud/jsr305-1.3.9.jar -maven://com.google.code.gson/gson/2.3|lib/gcloud/gson-2.3.jar -maven://com.google.guava/guava/19.0|lib/gcloud/guava-19.0.jar -maven://com.google.http-client/google-http-client/1.21.0|lib/gcloud/google-http-client-1.21.0.jar -maven://com.google.http-client/google-http-client-appengine/1.21.0|lib/gcloud/google-http-client-appengine-1.21.0.jar -maven://com.google.http-client/google-http-client-jackson/1.21.0|lib/gcloud/google-http-client-jackson-1.21.0.jar -maven://com.google.http-client/google-http-client-jackson2/1.19.0|lib/gcloud/google-http-client-jackson2-1.19.0.jar -maven://com.google.http-client/google-http-client-jdo/1.21.0|lib/gcloud/google-http-client-jdo-1.21.0.jar -maven://com.google.http-client/google-http-client-protobuf/1.20.0|lib/gcloud/google-http-client-protobuf-1.20.0.jar -maven://com.google.inject/guice/4.0|lib/gcloud/guice-4.0.jar -maven://com.google.oauth-client/google-oauth-client/1.21.0|lib/gcloud/google-oauth-client-1.21.0.jar -maven://com.google.oauth-client/google-oauth-client-appengine/1.21.0|lib/gcloud/google-oauth-client-appengine-1.21.0.jar -maven://com.google.oauth-client/google-oauth-client-servlet/1.21.0|lib/gcloud/google-oauth-client-servlet-1.21.0.jar -maven://com.google.protobuf/protobuf-java/3.0.0|lib/gcloud/protobuf-java-3.0.0.jar -maven://com.google.protobuf/protobuf-java-util/3.0.0|lib/gcloud/protobuf-java-util-3.0.0.jar -maven://commons-codec/commons-codec/1.3|lib/gcloud/commons-codec-1.3.jar -maven://commons-logging/commons-logging/1.1.1|lib/gcloud/commons-logging-1.1.1.jar -maven://io.grpc/grpc-context/1.0.1|lib/gcloud/grpc-context-1.0.1.jar -maven://io.grpc/grpc-core/1.0.1|lib/gcloud/grpc-core-1.0.1.jar -maven://io.grpc/grpc-protobuf/1.0.1|lib/gcloud/grpc-protobuf-1.0.1.jar -maven://io.grpc/grpc-protobuf-lite/1.0.1|lib/gcloud/grpc-protobuf-lite-1.0.1.jar -maven://javax.inject/javax.inject/1|lib/gcloud/javax.inject-1.jar -maven://javax.jdo/jdo2-api/2.3-eb|lib/gcloud/jdo2-api-2.3-eb.jar -maven://javax.transaction/transaction-api/1.1|lib/gcloud/transaction-api-1.1.jar -maven://joda-time/joda-time/2.9.2|lib/gcloud/joda-time-2.9.2.jar -maven://org.apache.httpcomponents/httpclient/4.0.1|lib/gcloud/httpclient-4.0.1.jar -maven://org.apache.httpcomponents/httpcore/4.0.1|lib/gcloud/httpcore-4.0.1.jar -maven://org.codehaus.jackson/jackson-core-asl/1.9.11|lib/gcloud/jackson-core-asl-1.9.11.jar -maven://org.json/json/20151123|lib/gcloud/json-20151123.jar diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java b/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java index c7e5d039959..7e6179b52ea 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java +++ b/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java @@ -422,9 +422,9 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore if (!_dsProvided) { if (!StringUtil.isBlank(getNamespace())) - _datastore = DatastoreOptions.builder().namespace(getNamespace()).build().service(); + _datastore = DatastoreOptions.newBuilder().setNamespace(getNamespace()).build().getService(); else - _datastore = DatastoreOptions.defaultInstance().service(); + _datastore = DatastoreOptions.getDefaultInstance().getService(); } if (_model == null) @@ -433,7 +433,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore addBean(_model,true); } - _keyFactory = _datastore.newKeyFactory().kind(_model.getKind()); + _keyFactory = _datastore.newKeyFactory().setKind(_model.getKind()); _indexesPresent = checkIndexes(); if (!_indexesPresent) @@ -566,9 +566,9 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore { try { - Query q = Query.keyQueryBuilder() - .kind(_model.getKind()) - .filter(PropertyFilter.eq(_model.getId(), s)) + Query q = Query.newKeyQueryBuilder() + .setKind(_model.getKind()) + .setFilter(PropertyFilter.eq(_model.getId(), s)) .build(); QueryResults res = _datastore.run(q); if (!res.hasNext()) @@ -604,10 +604,10 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore Set info = new HashSet<>(); //get up to maxResult number of sessions that have expired - Query query = Query.entityQueryBuilder() - .kind(_model.getKind()) - .filter(CompositeFilter.and(PropertyFilter.gt(_model.getExpiry(), 0), PropertyFilter.le(_model.getExpiry(), System.currentTimeMillis()))) - .limit(_maxResults) + Query query = Query.newEntityQueryBuilder() + .setKind(_model.getKind()) + .setFilter(CompositeFilter.and(PropertyFilter.gt(_model.getExpiry(), 0), PropertyFilter.le(_model.getExpiry(), System.currentTimeMillis()))) + .setLimit(_maxResults) .build(); QueryResults results; @@ -637,11 +637,11 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore protected Set queryExpiryByIndex () throws Exception { Set info = new HashSet<>(); - Query query = Query.projectionEntityQueryBuilder() - .kind(_model.getKind()) - .projection(_model.getId(), _model.getLastNode(), _model.getExpiry()) - .filter(CompositeFilter.and(PropertyFilter.gt(_model.getExpiry(), 0), PropertyFilter.le(_model.getExpiry(), System.currentTimeMillis()))) - .limit(_maxResults) + Query query = Query.newProjectionEntityQueryBuilder() + .setKind(_model.getKind()) + .setProjection(_model.getId(), _model.getLastNode(), _model.getExpiry()) + .setFilter(CompositeFilter.and(PropertyFilter.gt(_model.getExpiry(), 0), PropertyFilter.le(_model.getExpiry(), System.currentTimeMillis()))) + .setLimit(_maxResults) .build(); QueryResults presults; @@ -674,10 +674,10 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore { if (_indexesPresent) { - Query query = Query.projectionEntityQueryBuilder() - .kind(_model.getKind()) - .projection(_model.getExpiry()) - .filter(PropertyFilter.eq(_model.getId(), id)) + Query query = Query.newProjectionEntityQueryBuilder() + .setKind(_model.getKind()) + .setProjection(_model.getExpiry()) + .setFilter(PropertyFilter.eq(_model.getId(), id)) .build(); QueryResults presults; @@ -700,9 +700,9 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore } else { - Query query = Query.entityQueryBuilder() - .kind(_model.getKind()) - .filter(PropertyFilter.eq(_model.getId(), id)) + Query query = Query.newEntityQueryBuilder() + .setKind(_model.getKind()) + .setFilter(PropertyFilter.eq(_model.getId(), id)) .build(); QueryResults results; @@ -761,7 +761,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore } catch (DatastoreException e) { - if (e.retryable()) + if (e.isRetryable()) { if (LOG.isDebugEnabled()) LOG.debug("Datastore put retry {} waiting {}ms", attempts, backoff); @@ -814,12 +814,14 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore */ protected boolean checkIndexes () { + long start =0; + try { - Query query = Query.projectionEntityQueryBuilder() - .kind(_model.getKind()) - .projection(_model.getExpiry()) - .filter(PropertyFilter.eq(_model.getId(), "-")) + Query query = Query.newProjectionEntityQueryBuilder() + .setKind(_model.getKind()) + .setProjection(_model.getExpiry()) + .setFilter(PropertyFilter.eq(_model.getId(), "-")) .build(); _datastore.run(query); return true; @@ -855,7 +857,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore oos.flush(); //turn a session into an entity - entity = Entity.builder(key) + entity = Entity.newBuilder(key) .set(_model.getId(), session.getId()) .set(_model.getContextPath(), session.getContextPath()) .set(_model.getVhost(), session.getVhost()) @@ -866,7 +868,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore .set(_model.getLastNode(),session.getLastNode()) .set(_model.getExpiry(), session.getExpiry()) .set(_model.getMaxInactive(), session.getMaxInactiveMs()) - .set(_model.getAttributes(), BlobValue.builder(Blob.copyFrom(baos.toByteArray())).excludeFromIndexes(true).build()).build(); + .set(_model.getAttributes(), BlobValue.newBuilder(Blob.copyFrom(baos.toByteArray())).setExcludeFromIndexes(true).build()).build(); return entity; diff --git a/jetty-gcloud/pom.xml b/jetty-gcloud/pom.xml index cb220caa7e6..403684e66df 100644 --- a/jetty-gcloud/pom.xml +++ b/jetty-gcloud/pom.xml @@ -13,7 +13,7 @@ Jetty :: GCloud - 0.7.0 + 0.8.2-beta diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java index 12c63dd85c3..d6ca0436c9e 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java @@ -24,6 +24,7 @@ import java.io.IOException; import java.nio.BufferOverflowException; import java.nio.ByteBuffer; import java.util.Arrays; +import java.util.function.Supplier; import org.eclipse.jetty.http.HttpTokens.EndOfContent; import org.eclipse.jetty.util.ArrayTrie; @@ -55,7 +56,7 @@ public class HttpGenerator // states public enum State { START, COMMITTED, COMPLETING, COMPLETING_1XX, END } - public enum Result { NEED_CHUNK,NEED_INFO,NEED_HEADER,FLUSH,CONTINUE,SHUTDOWN_OUT,DONE} + public enum Result { NEED_CHUNK,NEED_INFO,NEED_HEADER,NEED_CHUNK_TRAILER, FLUSH,CONTINUE,SHUTDOWN_OUT,DONE} // other statics public static final int CHUNK_SIZE = 12; @@ -66,6 +67,7 @@ public class HttpGenerator private long _contentPrepared = 0; private boolean _noContentResponse = false; private Boolean _persistent = null; + private Supplier _trailers = null; private final int _send; private final static int SEND_SERVER = 0x01; @@ -111,6 +113,7 @@ public class HttpGenerator _persistent = null; _contentPrepared = 0; _needCRLF = false; + _trailers = null; } /* ------------------------------------------------------------ */ @@ -278,52 +281,12 @@ public class HttpGenerator case COMMITTED: { - int len = BufferUtil.length(content); - - if (len>0) - { - // Do we need a chunk buffer? - if (isChunking()) - { - // Do we need a chunk buffer? - if (chunk==null) - return Result.NEED_CHUNK; - BufferUtil.clearToFill(chunk); - prepareChunk(chunk,len); - BufferUtil.flipToFlush(chunk,0); - } - _contentPrepared+=len; - } - - if (last) - _state=State.COMPLETING; - - return len>0?Result.FLUSH:Result.CONTINUE; + return committed(chunk,content,last); } case COMPLETING: { - if (BufferUtil.hasContent(content)) - { - if (LOG.isDebugEnabled()) - LOG.debug("discarding content in COMPLETING"); - BufferUtil.clear(content); - } - - if (isChunking()) - { - // Do we need a chunk buffer? - if (chunk==null) - return Result.NEED_CHUNK; - BufferUtil.clearToFill(chunk); - prepareChunk(chunk,0); - BufferUtil.flipToFlush(chunk,0); - _endOfContent=EndOfContent.UNKNOWN_CONTENT; - return Result.FLUSH; - } - - _state=State.END; - return Boolean.TRUE.equals(_persistent)?Result.DONE:Result.SHUTDOWN_OUT; + return completing(chunk,content); } case END: @@ -340,7 +303,82 @@ public class HttpGenerator } } + private Result committed( ByteBuffer chunk, ByteBuffer content, boolean last) + { + int len = BufferUtil.length(content); + + // handle the content. + if (len>0) + { + if (isChunking()) + { + if (chunk==null) + return Result.NEED_CHUNK; + BufferUtil.clearToFill(chunk); + prepareChunk(chunk,len); + BufferUtil.flipToFlush(chunk,0); + } + _contentPrepared+=len; + } + + if (last) + { + _state=State.COMPLETING; + return len>0?Result.FLUSH:Result.CONTINUE; + } + return len>0?Result.FLUSH:Result.DONE; + } + + private Result completing( ByteBuffer chunk, ByteBuffer content) + { + if (BufferUtil.hasContent(content)) + { + if (LOG.isDebugEnabled()) + LOG.debug("discarding content in COMPLETING"); + BufferUtil.clear(content); + } + + if (isChunking()) + { + if (_trailers!=null) + { + // Do we need a chunk buffer? + if (chunk==null || chunk.capacity()<=CHUNK_SIZE) + return Result.NEED_CHUNK_TRAILER; + + HttpFields trailers = _trailers.get(); + + if (trailers!=null) + { + // Write the last chunk + BufferUtil.clearToFill(chunk); + generateTrailers(chunk,trailers); + BufferUtil.flipToFlush(chunk,0); + _endOfContent=EndOfContent.UNKNOWN_CONTENT; + return Result.FLUSH; + } + } + + // Do we need a chunk buffer? + if (chunk==null) + return Result.NEED_CHUNK; + + // Write the last chunk + BufferUtil.clearToFill(chunk); + prepareChunk(chunk,0); + BufferUtil.flipToFlush(chunk,0); + _endOfContent=EndOfContent.UNKNOWN_CONTENT; + return Result.FLUSH; + } + + _state=State.END; + return Boolean.TRUE.equals(_persistent)?Result.DONE:Result.SHUTDOWN_OUT; + + } + + /* ------------------------------------------------------------ */ + @Deprecated public Result generateResponse(MetaData.Response info, ByteBuffer header, ByteBuffer chunk, ByteBuffer content, boolean last) throws IOException { return generateResponse(info,false,header,chunk,content,last); @@ -386,7 +424,7 @@ public class HttpGenerator // prepare the header int pos=BufferUtil.flipToFill(header); try - { + { // generate ResponseLine generateResponseLine(info,header); @@ -442,29 +480,7 @@ public class HttpGenerator case COMMITTED: { - int len = BufferUtil.length(content); - - // handle the content. - if (len>0) - { - if (isChunking()) - { - if (chunk==null) - return Result.NEED_CHUNK; - BufferUtil.clearToFill(chunk); - prepareChunk(chunk,len); - BufferUtil.flipToFlush(chunk,0); - } - _contentPrepared+=len; - } - - if (last) - { - _state=State.COMPLETING; - return len>0?Result.FLUSH:Result.CONTINUE; - } - return len>0?Result.FLUSH:Result.DONE; - + return committed(chunk,content,last); } case COMPLETING_1XX: @@ -475,30 +491,7 @@ public class HttpGenerator case COMPLETING: { - if (BufferUtil.hasContent(content)) - { - if (LOG.isDebugEnabled()) - LOG.debug("discarding content in COMPLETING"); - BufferUtil.clear(content); - } - - if (isChunking()) - { - // Do we need a chunk buffer? - if (chunk==null) - return Result.NEED_CHUNK; - - // Write the last chunk - BufferUtil.clearToFill(chunk); - prepareChunk(chunk,0); - BufferUtil.flipToFlush(chunk,0); - _endOfContent=EndOfContent.UNKNOWN_CONTENT; - return Result.FLUSH; - } - - _state=State.END; - - return Boolean.TRUE.equals(_persistent)?Result.DONE:Result.SHUTDOWN_OUT; + return completing(chunk,content); } case END: @@ -535,6 +528,30 @@ public class HttpGenerator _needCRLF=false; } } + + /* ------------------------------------------------------------ */ + private void generateTrailers(ByteBuffer buffer, HttpFields trailer) + { + // if we need CRLF add this to header + if (_needCRLF) + BufferUtil.putCRLF(buffer); + + // Add the chunk size to the header + buffer.put(ZERO_CHUNK); + + int n=trailer.size(); + for (int f=0;f0 && _headResponse) { setState(State.END); - return _handler.messageComplete(); + return handleContentMessage(); } else { @@ -1420,7 +1429,7 @@ public class HttpParser { // Be forgiving of missing last CRLF setState(State.CLOSED); - return _handler.messageComplete(); + return handleContentMessage(); } setState(State.CLOSED); _handler.earlyEOF(); @@ -1477,7 +1486,7 @@ public class HttpParser if (content == 0) { setState(State.END); - return _handler.messageComplete(); + return handleContentMessage(); } } @@ -1501,7 +1510,7 @@ public class HttpParser if (content == 0) { setState(State.END); - return _handler.messageComplete(); + return handleContentMessage(); } else { @@ -1524,7 +1533,7 @@ public class HttpParser if(_contentPosition == _contentLength) { setState(State.END); - return _handler.messageComplete(); + return handleContentMessage(); } } break; @@ -1551,7 +1560,11 @@ public class HttpParser if (ch == HttpTokens.LINE_FEED) { if (_chunkLength == 0) + { setState(State.TRAILER); + if (_handler.contentComplete()) + return true; + } else setState(State.CHUNK); } @@ -1568,7 +1581,11 @@ public class HttpParser if (ch == HttpTokens.LINE_FEED) { if (_chunkLength == 0) + { setState(State.TRAILER); + if (_handler.contentComplete()) + return true; + } else setState(State.CHUNK); } @@ -1729,6 +1746,8 @@ public class HttpParser public boolean headerComplete(); + public boolean contentComplete(); + public boolean messageComplete(); /** diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/MetaData.java b/jetty-http/src/main/java/org/eclipse/jetty/http/MetaData.java index 1853b9820cd..7fb2d4dde96 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/MetaData.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/MetaData.java @@ -20,12 +20,14 @@ package org.eclipse.jetty.http; import java.util.Collections; import java.util.Iterator; +import java.util.function.Supplier; public class MetaData implements Iterable { private HttpVersion _httpVersion; - private HttpFields _fields; + private final HttpFields _fields; private long _contentLength; + private Supplier _trailers; public MetaData(HttpVersion version, HttpFields fields) { @@ -90,6 +92,16 @@ public class MetaData implements Iterable return _fields; } + public Supplier getTrailerSupplier() + { + return _trailers; + } + + public void setTrailerSupplier(Supplier trailers) + { + _trailers = trailers; + } + /** * @return the content length if available, otherwise {@link Long#MIN_VALUE} */ diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java index 7dd1886da6d..11e93f6f9a5 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java @@ -69,7 +69,7 @@ public class HttpGeneratorClientTest String out = BufferUtil.toString(header); BufferUtil.clear(header); - result=gen.generateResponse(null,null,null,null, false); + result=gen.generateResponse(null,false,null,null, null, false); Assert.assertEquals(HttpGenerator.Result.DONE, result); Assert.assertEquals(HttpGenerator.State.END, gen.getState()); Assert.assertTrue(!gen.isChunking()); @@ -106,7 +106,7 @@ public class HttpGeneratorClientTest String out = BufferUtil.toString(header); BufferUtil.clear(header); - result=gen.generateResponse(null,null,null,null, false); + result=gen.generateResponse(null,false,null,null, null, false); Assert.assertEquals(HttpGenerator.Result.DONE, result); Assert.assertEquals(HttpGenerator.State.END, gen.getState()); Assert.assertTrue(!gen.isChunking()); @@ -146,7 +146,7 @@ public class HttpGeneratorClientTest out+=BufferUtil.toString(content0); BufferUtil.clear(content0); - result=gen.generateResponse(null,null,null,null, false); + result=gen.generateResponse(null,false,null,null, null, false); Assert.assertEquals(HttpGenerator.Result.DONE, result); Assert.assertEquals(HttpGenerator.State.END, gen.getState()); Assert.assertTrue(!gen.isChunking()); @@ -205,19 +205,19 @@ public class HttpGeneratorClientTest out+=BufferUtil.toString(content1); BufferUtil.clear(content1); - result=gen.generateResponse(null,null,chunk,null, true); + result=gen.generateResponse(null,false,null,chunk, null, true); Assert.assertEquals(HttpGenerator.Result.CONTINUE, result); Assert.assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); Assert.assertTrue(gen.isChunking()); - result=gen.generateResponse(null,null,chunk,null, true); + result=gen.generateResponse(null,false,null,chunk, null, true); Assert.assertEquals(HttpGenerator.Result.FLUSH, result); Assert.assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); out+=BufferUtil.toString(chunk); BufferUtil.clear(chunk); Assert.assertTrue(!gen.isChunking()); - result=gen.generateResponse(null,null,chunk,null, true); + result=gen.generateResponse(null,false,null,chunk, null, true); Assert.assertEquals(HttpGenerator.Result.DONE, result); Assert.assertEquals(HttpGenerator.State.END, gen.getState()); @@ -271,12 +271,12 @@ public class HttpGeneratorClientTest out+=BufferUtil.toString(content1); BufferUtil.clear(content1); - result=gen.generateResponse(null,null,null,null, true); + result=gen.generateResponse(null,false,null,null, null, true); Assert.assertEquals(HttpGenerator.Result.CONTINUE, result); Assert.assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); Assert.assertTrue(!gen.isChunking()); - result=gen.generateResponse(null,null,null,null, true); + result=gen.generateResponse(null,false,null,null, null, true); Assert.assertEquals(HttpGenerator.Result.DONE, result); Assert.assertEquals(HttpGenerator.State.END, gen.getState()); out+=BufferUtil.toString(chunk); diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerHTTPTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerHTTPTest.java index 5f8313e9c9e..a85239cea56 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerHTTPTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerHTTPTest.java @@ -164,6 +164,11 @@ public class HttpGeneratorServerHTTPTest chunk = BufferUtil.allocate(HttpGenerator.CHUNK_SIZE); continue; + case NEED_CHUNK_TRAILER: + chunk = BufferUtil.allocate(2048); + continue; + + case FLUSH: if (BufferUtil.hasContent(header)) { @@ -231,6 +236,12 @@ public class HttpGeneratorServerHTTPTest return false; } + @Override + public boolean contentComplete() + { + return false; + } + @Override public boolean messageComplete() { diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerTest.java index 937539c6632..b363c29c579 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerTest.java @@ -26,6 +26,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import java.nio.ByteBuffer; +import java.util.function.Supplier; import org.eclipse.jetty.util.BufferUtil; import org.hamcrest.Matchers; @@ -42,7 +43,7 @@ public class HttpGeneratorServerTest HttpGenerator gen = new HttpGenerator(); - HttpGenerator.Result result = gen.generateResponse(null, null, null, content, true); + HttpGenerator.Result result = gen.generateResponse(null, false, null, null, content, true); assertEquals(HttpGenerator.Result.NEED_INFO, result); assertEquals(HttpGenerator.State.START, gen.getState()); @@ -50,7 +51,7 @@ public class HttpGeneratorServerTest info.getFields().add("Content-Type", "test/data"); info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); - result = gen.generateResponse(info, null, null, content, true); + result = gen.generateResponse(info, false, null, null, content, true); assertEquals(HttpGenerator.Result.FLUSH, result); assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); String response = BufferUtil.toString(header); @@ -58,7 +59,7 @@ public class HttpGeneratorServerTest response += BufferUtil.toString(content); BufferUtil.clear(content); - result = gen.generateResponse(null, null, null, content, false); + result = gen.generateResponse(null, false, null, null, content, false); assertEquals(HttpGenerator.Result.SHUTDOWN_OUT, result); assertEquals(HttpGenerator.State.END, gen.getState()); @@ -78,7 +79,7 @@ public class HttpGeneratorServerTest HttpGenerator gen = new HttpGenerator(); - HttpGenerator.Result result = gen.generateResponse(null, null, null, content, true); + HttpGenerator.Result result = gen.generateResponse(null, false, null, null, content, true); assertEquals(HttpGenerator.Result.NEED_INFO, result); assertEquals(HttpGenerator.State.START, gen.getState()); @@ -86,10 +87,10 @@ public class HttpGeneratorServerTest info.getFields().add("Content-Type", "test/data"); info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); - result = gen.generateResponse(info, null, null, content, true); + result = gen.generateResponse(info, false, null, null, content, true); assertEquals(HttpGenerator.Result.NEED_HEADER, result); - result = gen.generateResponse(info, header, null, content, true); + result = gen.generateResponse(info, false, header, null, content, true); assertEquals(HttpGenerator.Result.FLUSH, result); assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); String response = BufferUtil.toString(header); @@ -97,7 +98,7 @@ public class HttpGeneratorServerTest response += BufferUtil.toString(content); BufferUtil.clear(content); - result = gen.generateResponse(null, null, null, content, false); + result = gen.generateResponse(null, false, null, null, content, false); assertEquals(HttpGenerator.Result.DONE, result); assertEquals(HttpGenerator.State.END, gen.getState()); @@ -121,7 +122,7 @@ public class HttpGeneratorServerTest info.getFields().add("Content-Type", "test/data"); info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); - HttpGenerator.Result result = gen.generateResponse(info, header, null, content, true); + HttpGenerator.Result result = gen.generateResponse(info, false, header, null, content, true); assertEquals(gen.isNoContent(), true); assertEquals(HttpGenerator.Result.FLUSH, result); @@ -129,7 +130,7 @@ public class HttpGeneratorServerTest String responseheaders = BufferUtil.toString(header); BufferUtil.clear(header); - result = gen.generateResponse(null, null, null, content, false); + result = gen.generateResponse(null, false, null, null, content, false); assertEquals(HttpGenerator.Result.DONE, result); assertEquals(HttpGenerator.State.END, gen.getState()); @@ -150,7 +151,7 @@ public class HttpGeneratorServerTest HttpGenerator gen = new HttpGenerator(); - HttpGenerator.Result result = gen.generateResponse(null, null, null, content, true); + HttpGenerator.Result result = gen.generateResponse(null, false, null, null, content, true); assertEquals(HttpGenerator.Result.NEED_INFO, result); assertEquals(HttpGenerator.State.START, gen.getState()); @@ -158,10 +159,10 @@ public class HttpGeneratorServerTest info.getFields().add("Content-Type", "test/data;\r\nextra=value"); info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); - result = gen.generateResponse(info, null, null, content, true); + result = gen.generateResponse(info, false, null, null, content, true); assertEquals(HttpGenerator.Result.NEED_HEADER, result); - result = gen.generateResponse(info, header, null, content, true); + result = gen.generateResponse(info, false, header, null, content, true); assertEquals(HttpGenerator.Result.FLUSH, result); assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); String response = BufferUtil.toString(header); @@ -169,7 +170,7 @@ public class HttpGeneratorServerTest response += BufferUtil.toString(content); BufferUtil.clear(content); - result = gen.generateResponse(null, null, null, content, false); + result = gen.generateResponse(null, false, null, null, content, false); assertEquals(HttpGenerator.Result.DONE, result); assertEquals(HttpGenerator.State.END, gen.getState()); @@ -194,14 +195,14 @@ public class HttpGeneratorServerTest String head; HttpGenerator gen = new HttpGenerator(true, true); - gen.generateResponse(info, header, null, null, true); + gen.generateResponse(info, false, header, null, null, true); head = BufferUtil.toString(header); BufferUtil.clear(header); assertThat(head, containsString("HTTP/1.1 200 OK")); assertThat(head, containsString("Server: Jetty(9.x.x)")); assertThat(head, containsString("X-Powered-By: Jetty(9.x.x)")); gen.reset(); - gen.generateResponse(infoF, header, null, null, true); + gen.generateResponse(infoF, false, header, null, null, true); head = BufferUtil.toString(header); BufferUtil.clear(header); assertThat(head, containsString("HTTP/1.1 200 OK")); @@ -212,14 +213,14 @@ public class HttpGeneratorServerTest gen.reset(); gen = new HttpGenerator(false, false); - gen.generateResponse(info, header, null, null, true); + gen.generateResponse(info, false, header, null, null, true); head = BufferUtil.toString(header); BufferUtil.clear(header); assertThat(head, containsString("HTTP/1.1 200 OK")); assertThat(head, not(containsString("Server: Jetty(9.x.x)"))); assertThat(head, not(containsString("X-Powered-By: Jetty(9.x.x)"))); gen.reset(); - gen.generateResponse(infoF, header, null, null, true); + gen.generateResponse(infoF, false, header, null, null, true); head = BufferUtil.toString(header); BufferUtil.clear(header); assertThat(head, containsString("HTTP/1.1 200 OK")); @@ -237,7 +238,7 @@ public class HttpGeneratorServerTest HttpGenerator gen = new HttpGenerator(); - HttpGenerator.Result result = gen.generateResponse(null, null, null, null, true); + HttpGenerator.Result result = gen.generateResponse(null, false, null, null, null, true); assertEquals(HttpGenerator.Result.NEED_INFO, result); assertEquals(HttpGenerator.State.START, gen.getState()); @@ -245,12 +246,12 @@ public class HttpGeneratorServerTest info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); info.getFields().add("Content-Length", "11"); - result = gen.generateResponse(info, null, null, null, true); + result = gen.generateResponse(info, false, null, null, null, true); assertEquals(HttpGenerator.Result.NEED_HEADER, result); try { - gen.generateResponse(info, header, null, null, true); + gen.generateResponse(info, false, header, null, null, true); Assert.fail(); } catch(BadMessageException e) @@ -266,23 +267,23 @@ public class HttpGeneratorServerTest HttpGenerator gen = new HttpGenerator(); - HttpGenerator.Result result = gen.generateResponse(null, null, null, null, true); + HttpGenerator.Result result = gen.generateResponse(null, false, null, null, null, true); assertEquals(HttpGenerator.Result.NEED_INFO, result); assertEquals(HttpGenerator.State.START, gen.getState()); MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 200, null, new HttpFields(), 0); info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); - result = gen.generateResponse(info, null, null, null, true); + result = gen.generateResponse(info, false, null, null, null, true); assertEquals(HttpGenerator.Result.NEED_HEADER, result); - result = gen.generateResponse(info, header, null, null, true); + result = gen.generateResponse(info, false, header, null, null, true); assertEquals(HttpGenerator.Result.FLUSH, result); assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); String head = BufferUtil.toString(header); BufferUtil.clear(header); - result = gen.generateResponse(null, null, null, null, false); + result = gen.generateResponse(null, false, null, null, null, false); assertEquals(HttpGenerator.Result.DONE, result); assertEquals(HttpGenerator.State.END, gen.getState()); @@ -299,7 +300,7 @@ public class HttpGeneratorServerTest HttpGenerator gen = new HttpGenerator(); - HttpGenerator.Result result = gen.generateResponse(null, null, null, null, true); + HttpGenerator.Result result = gen.generateResponse(null, false, null, null, null, true); assertEquals(HttpGenerator.Result.NEED_INFO, result); assertEquals(HttpGenerator.State.START, gen.getState()); @@ -307,16 +308,16 @@ public class HttpGeneratorServerTest info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); info.getFields().add("Connection", "close"); - result = gen.generateResponse(info, null, null, null, true); + result = gen.generateResponse(info, false, null, null, null, true); assertEquals(HttpGenerator.Result.NEED_HEADER, result); - result = gen.generateResponse(info, header, null, null, true); + result = gen.generateResponse(info, false, header, null, null, true); assertEquals(HttpGenerator.Result.FLUSH, result); assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); String head = BufferUtil.toString(header); BufferUtil.clear(header); - result = gen.generateResponse(null, null, null, null, false); + result = gen.generateResponse(null, false, null, null, null, false); assertEquals(HttpGenerator.Result.SHUTDOWN_OUT, result); assertEquals(HttpGenerator.State.END, gen.getState()); @@ -333,7 +334,7 @@ public class HttpGeneratorServerTest HttpGenerator gen = new HttpGenerator(); - HttpGenerator.Result result = gen.generateResponse(null, null, null, null, true); + HttpGenerator.Result result = gen.generateResponse(null, false, null, null, null, true); assertEquals(HttpGenerator.Result.NEED_INFO, result); assertEquals(HttpGenerator.State.START, gen.getState()); @@ -342,13 +343,13 @@ public class HttpGeneratorServerTest info.getFields().add("Connection", "Upgrade"); info.getFields().add("Sec-WebSocket-Accept", "123456789=="); - result = gen.generateResponse(info, header, null, null, true); + result = gen.generateResponse(info, false, header, null, null, true); assertEquals(HttpGenerator.Result.FLUSH, result); assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); String head = BufferUtil.toString(header); BufferUtil.clear(header); - result = gen.generateResponse(info, null, null, null, false); + result = gen.generateResponse(info, false, null, null, null, false); assertEquals(HttpGenerator.Result.DONE, result); assertEquals(HttpGenerator.State.END, gen.getState()); @@ -368,17 +369,17 @@ public class HttpGeneratorServerTest ByteBuffer content1 = BufferUtil.toBuffer("The quick brown fox jumped over the lazy dog. "); HttpGenerator gen = new HttpGenerator(); - HttpGenerator.Result result = gen.generateResponse(null, null, null, content0, false); + HttpGenerator.Result result = gen.generateResponse(null, false, null, null, content0, false); assertEquals(HttpGenerator.Result.NEED_INFO, result); assertEquals(HttpGenerator.State.START, gen.getState()); MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 200, null, new HttpFields(), -1); info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); - result = gen.generateResponse(info, null, null, content0, false); + result = gen.generateResponse(info, false, null, null, content0, false); assertEquals(HttpGenerator.Result.NEED_HEADER, result); assertEquals(HttpGenerator.State.START, gen.getState()); - result = gen.generateResponse(info, header, null, content0, false); + result = gen.generateResponse(info, false, header, null, content0, false); assertEquals(HttpGenerator.Result.FLUSH, result); assertEquals(HttpGenerator.State.COMMITTED, gen.getState()); @@ -387,7 +388,7 @@ public class HttpGeneratorServerTest out += BufferUtil.toString(content0); BufferUtil.clear(content0); - result = gen.generateResponse(null, null, chunk, content1, false); + result = gen.generateResponse(null, false, null, chunk, content1, false); assertEquals(HttpGenerator.Result.FLUSH, result); assertEquals(HttpGenerator.State.COMMITTED, gen.getState()); out += BufferUtil.toString(chunk); @@ -395,17 +396,17 @@ public class HttpGeneratorServerTest out += BufferUtil.toString(content1); BufferUtil.clear(content1); - result = gen.generateResponse(null, null, chunk, null, true); + result = gen.generateResponse(null, false, null, chunk, null, true); assertEquals(HttpGenerator.Result.CONTINUE, result); assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); - result = gen.generateResponse(null, null, chunk, null, true); + result = gen.generateResponse(null, false, null, chunk, null, true); assertEquals(HttpGenerator.Result.FLUSH, result); assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); out += BufferUtil.toString(chunk); BufferUtil.clear(chunk); - result = gen.generateResponse(null, null, chunk, null, true); + result = gen.generateResponse(null, false, null, chunk, null, true); assertEquals(HttpGenerator.Result.DONE, result); assertEquals(HttpGenerator.State.END, gen.getState()); @@ -433,18 +434,18 @@ public class HttpGeneratorServerTest HttpGenerator gen = new HttpGenerator(); gen.setPersistent(false); - HttpGenerator.Result result = gen.generateResponse(null, null, null, content0, false); + HttpGenerator.Result result = gen.generateResponse(null, false, null, null, content0, false); assertEquals(HttpGenerator.Result.NEED_INFO, result); assertEquals(HttpGenerator.State.START, gen.getState()); MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 200, null, new HttpFields(), -1); info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); info.getFields().add(HttpHeader.TRANSFER_ENCODING, HttpHeaderValue.CHUNKED); - result = gen.generateResponse(info, null, null, content0, false); + result = gen.generateResponse(info, false, null, null, content0, false); assertEquals(HttpGenerator.Result.NEED_HEADER, result); assertEquals(HttpGenerator.State.START, gen.getState()); - result = gen.generateResponse(info, header, null, content0, false); + result = gen.generateResponse(info, false, header, null, content0, false); assertEquals(HttpGenerator.Result.FLUSH, result); assertEquals(HttpGenerator.State.COMMITTED, gen.getState()); @@ -453,7 +454,10 @@ public class HttpGeneratorServerTest out += BufferUtil.toString(content0); BufferUtil.clear(content0); - result = gen.generateResponse(null, null, chunk, content1, false); + result = gen.generateResponse(null, false, null, null, content1, false); + assertEquals(HttpGenerator.Result.NEED_CHUNK, result); + + result = gen.generateResponse(null, false, null, chunk, content1, false); assertEquals(HttpGenerator.Result.FLUSH, result); assertEquals(HttpGenerator.State.COMMITTED, gen.getState()); out += BufferUtil.toString(chunk); @@ -461,17 +465,17 @@ public class HttpGeneratorServerTest out += BufferUtil.toString(content1); BufferUtil.clear(content1); - result = gen.generateResponse(null, null, chunk, null, true); + result = gen.generateResponse(null, false, null, chunk, null, true); assertEquals(HttpGenerator.Result.CONTINUE, result); assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); - result = gen.generateResponse(null, null, chunk, null, true); + result = gen.generateResponse(null, false, null, chunk, null, true); assertEquals(HttpGenerator.Result.FLUSH, result); assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); out += BufferUtil.toString(chunk); BufferUtil.clear(chunk); - result = gen.generateResponse(null, null, chunk, null, true); + result = gen.generateResponse(null, false, null, chunk, null, true); assertEquals(HttpGenerator.Result.SHUTDOWN_OUT, result); assertEquals(HttpGenerator.State.END, gen.getState()); @@ -489,6 +493,170 @@ public class HttpGeneratorServerTest "\r\n")); } + @Test + public void testResponseWithContentAndTrailer() throws Exception + { + ByteBuffer header = BufferUtil.allocate(4096); + ByteBuffer chunk = BufferUtil.allocate(HttpGenerator.CHUNK_SIZE); + ByteBuffer trailer = BufferUtil.allocate(4096); + ByteBuffer content0 = BufferUtil.toBuffer("Hello World! "); + ByteBuffer content1 = BufferUtil.toBuffer("The quick brown fox jumped over the lazy dog. "); + HttpGenerator gen = new HttpGenerator(); + gen.setPersistent(false); + + HttpGenerator.Result result = gen.generateResponse(null, false, null, null, content0, false); + assertEquals(HttpGenerator.Result.NEED_INFO, result); + assertEquals(HttpGenerator.State.START, gen.getState()); + + MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 200, null, new HttpFields(), -1); + info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); + info.getFields().add(HttpHeader.TRANSFER_ENCODING, HttpHeaderValue.CHUNKED); + info.setTrailerSupplier(new Supplier() + { + @Override + public HttpFields get() + { + HttpFields trailer = new HttpFields(); + trailer.add("T-Name0","T-ValueA"); + trailer.add("T-Name0","T-ValueB"); + trailer.add("T-Name1","T-ValueC"); + return trailer; + } + }); + + result = gen.generateResponse(info, false, null, null, content0, false); + assertEquals(HttpGenerator.Result.NEED_HEADER, result); + assertEquals(HttpGenerator.State.START, gen.getState()); + + result = gen.generateResponse(info, false, header, null, content0, false); + assertEquals(HttpGenerator.Result.FLUSH, result); + assertEquals(HttpGenerator.State.COMMITTED, gen.getState()); + + String out = BufferUtil.toString(header); + BufferUtil.clear(header); + out += BufferUtil.toString(content0); + BufferUtil.clear(content0); + + result = gen.generateResponse(null, false, null, null, content1, false); + assertEquals(HttpGenerator.Result.NEED_CHUNK, result); + + result = gen.generateResponse(null, false, null, chunk, content1, false); + assertEquals(HttpGenerator.Result.FLUSH, result); + assertEquals(HttpGenerator.State.COMMITTED, gen.getState()); + out += BufferUtil.toString(chunk); + BufferUtil.clear(chunk); + out += BufferUtil.toString(content1); + BufferUtil.clear(content1); + + result = gen.generateResponse(null, false, null, chunk, null, true); + assertEquals(HttpGenerator.Result.CONTINUE, result); + assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); + + result = gen.generateResponse(null, false, null, chunk, null, true); + + assertEquals(HttpGenerator.Result.NEED_CHUNK_TRAILER, result); + assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); + + result = gen.generateResponse(null, false, null, trailer, null, true); + + assertEquals(HttpGenerator.Result.FLUSH, result); + assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); + out += BufferUtil.toString(trailer); + BufferUtil.clear(trailer); + + result = gen.generateResponse(null, false, null, trailer, null, true); + assertEquals(HttpGenerator.Result.SHUTDOWN_OUT, result); + assertEquals(HttpGenerator.State.END, gen.getState()); + + assertThat(out, containsString("HTTP/1.1 200 OK")); + assertThat(out, containsString("Last-Modified: Thu, 01 Jan 1970 00:00:00 GMT")); + assertThat(out, not(containsString("Content-Length"))); + assertThat(out, containsString("Transfer-Encoding: chunked")); + + assertThat(out, endsWith( + "\r\n\r\nD\r\n"+ + "Hello World! \r\n"+ + "2E\r\n"+ + "The quick brown fox jumped over the lazy dog. \r\n"+ + "0\r\n"+ + "T-Name0: T-ValueA\r\n"+ + "T-Name0: T-ValueB\r\n"+ + "T-Name1: T-ValueC\r\n"+ + "\r\n")); + } + + @Test + public void testResponseWithTrailer() throws Exception + { + ByteBuffer header = BufferUtil.allocate(4096); + ByteBuffer chunk = BufferUtil.allocate(HttpGenerator.CHUNK_SIZE); + ByteBuffer trailer = BufferUtil.allocate(4096); + HttpGenerator gen = new HttpGenerator(); + gen.setPersistent(false); + + HttpGenerator.Result result = gen.generateResponse(null, false, null, null, null, true); + assertEquals(HttpGenerator.Result.NEED_INFO, result); + assertEquals(HttpGenerator.State.START, gen.getState()); + + MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 200, null, new HttpFields(), -1); + info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); + info.getFields().add(HttpHeader.TRANSFER_ENCODING, HttpHeaderValue.CHUNKED); + info.setTrailerSupplier(new Supplier() + { + @Override + public HttpFields get() + { + HttpFields trailer = new HttpFields(); + trailer.add("T-Name0","T-ValueA"); + trailer.add("T-Name0","T-ValueB"); + trailer.add("T-Name1","T-ValueC"); + return trailer; + } + }); + + result = gen.generateResponse(info, false, null, null, null, true); + assertEquals(HttpGenerator.Result.NEED_HEADER, result); + assertEquals(HttpGenerator.State.START, gen.getState()); + + result = gen.generateResponse(info, false, header, null, null, true); + assertEquals(HttpGenerator.Result.FLUSH, result); + assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); + + String out = BufferUtil.toString(header); + BufferUtil.clear(header); + + result = gen.generateResponse(null, false, null, null, null, true); + assertEquals(HttpGenerator.Result.NEED_CHUNK_TRAILER, result); + assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); + + result = gen.generateResponse(null, false, null, chunk, null, true); + assertEquals(HttpGenerator.Result.NEED_CHUNK_TRAILER, result); + assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); + + result = gen.generateResponse(null, false, null, trailer, null, true); + + assertEquals(HttpGenerator.Result.FLUSH, result); + assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); + out += BufferUtil.toString(trailer); + BufferUtil.clear(trailer); + + result = gen.generateResponse(null, false, null, trailer, null, true); + assertEquals(HttpGenerator.Result.SHUTDOWN_OUT, result); + assertEquals(HttpGenerator.State.END, gen.getState()); + + assertThat(out, containsString("HTTP/1.1 200 OK")); + assertThat(out, containsString("Last-Modified: Thu, 01 Jan 1970 00:00:00 GMT")); + assertThat(out, not(containsString("Content-Length"))); + assertThat(out, containsString("Transfer-Encoding: chunked")); + + assertThat(out, endsWith( + "\r\n\r\n"+ + "0\r\n"+ + "T-Name0: T-ValueA\r\n"+ + "T-Name0: T-ValueB\r\n"+ + "T-Name1: T-ValueC\r\n"+ + "\r\n")); + } @Test public void testResponseWithKnownContentLengthFromMetaData() throws Exception @@ -498,17 +666,17 @@ public class HttpGeneratorServerTest ByteBuffer content1 = BufferUtil.toBuffer("The quick brown fox jumped over the lazy dog. "); HttpGenerator gen = new HttpGenerator(); - HttpGenerator.Result result = gen.generateResponse(null, null, null, content0, false); + HttpGenerator.Result result = gen.generateResponse(null, false, null, null, content0, false); assertEquals(HttpGenerator.Result.NEED_INFO, result); assertEquals(HttpGenerator.State.START, gen.getState()); MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 200, null, new HttpFields(), 59); info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); - result = gen.generateResponse(info, null, null, content0, false); + result = gen.generateResponse(info, false, null, null, content0, false); assertEquals(HttpGenerator.Result.NEED_HEADER, result); assertEquals(HttpGenerator.State.START, gen.getState()); - result = gen.generateResponse(info, header, null, content0, false); + result = gen.generateResponse(info, false, header, null, content0, false); assertEquals(HttpGenerator.Result.FLUSH, result); assertEquals(HttpGenerator.State.COMMITTED, gen.getState()); @@ -517,17 +685,17 @@ public class HttpGeneratorServerTest out += BufferUtil.toString(content0); BufferUtil.clear(content0); - result = gen.generateResponse(null, null, null, content1, false); + result = gen.generateResponse(null, false, null, null, content1, false); assertEquals(HttpGenerator.Result.FLUSH, result); assertEquals(HttpGenerator.State.COMMITTED, gen.getState()); out += BufferUtil.toString(content1); BufferUtil.clear(content1); - result = gen.generateResponse(null, null, null, null, true); + result = gen.generateResponse(null, false, null, null, null, true); assertEquals(HttpGenerator.Result.CONTINUE, result); assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); - result = gen.generateResponse(null, null, null, null, true); + result = gen.generateResponse(null, false, null, null, null, true); assertEquals(HttpGenerator.Result.DONE, result); assertEquals(HttpGenerator.State.END, gen.getState()); @@ -546,18 +714,18 @@ public class HttpGeneratorServerTest ByteBuffer content1 = BufferUtil.toBuffer("The quick brown fox jumped over the lazy dog. "); HttpGenerator gen = new HttpGenerator(); - HttpGenerator.Result result = gen.generateResponse(null, null, null, content0, false); + HttpGenerator.Result result = gen.generateResponse(null, false, null, null, content0, false); assertEquals(HttpGenerator.Result.NEED_INFO, result); assertEquals(HttpGenerator.State.START, gen.getState()); MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 200, null, new HttpFields(), -1); info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); info.getFields().add("Content-Length",""+(content0.remaining()+content1.remaining())); - result = gen.generateResponse(info, null, null, content0, false); + result = gen.generateResponse(info, false, null, null, content0, false); assertEquals(HttpGenerator.Result.NEED_HEADER, result); assertEquals(HttpGenerator.State.START, gen.getState()); - result = gen.generateResponse(info, header, null, content0, false); + result = gen.generateResponse(info, false, header, null, content0, false); assertEquals(HttpGenerator.Result.FLUSH, result); assertEquals(HttpGenerator.State.COMMITTED, gen.getState()); @@ -566,17 +734,17 @@ public class HttpGeneratorServerTest out += BufferUtil.toString(content0); BufferUtil.clear(content0); - result = gen.generateResponse(null, null, null, content1, false); + result = gen.generateResponse(null, false, null, null, content1, false); assertEquals(HttpGenerator.Result.FLUSH, result); assertEquals(HttpGenerator.State.COMMITTED, gen.getState()); out += BufferUtil.toString(content1); BufferUtil.clear(content1); - result = gen.generateResponse(null, null, null, null, true); + result = gen.generateResponse(null, false, null, null, null, true); assertEquals(HttpGenerator.Result.CONTINUE, result); assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); - result = gen.generateResponse(null, null, null, null, true); + result = gen.generateResponse(null, false, null, null, null, true); assertEquals(HttpGenerator.Result.DONE, result); assertEquals(HttpGenerator.State.END, gen.getState()); @@ -598,32 +766,32 @@ public class HttpGeneratorServerTest ByteBuffer content1 = BufferUtil.toBuffer("The quick brown fox jumped over the lazy dog. "); HttpGenerator gen = new HttpGenerator(); - HttpGenerator.Result result = gen.generateResponse(HttpGenerator.CONTINUE_100_INFO, null, null, null, false); + HttpGenerator.Result result = gen.generateResponse(HttpGenerator.CONTINUE_100_INFO, false, null, null, null, false); assertEquals(HttpGenerator.Result.NEED_HEADER, result); assertEquals(HttpGenerator.State.START, gen.getState()); - result = gen.generateResponse(HttpGenerator.CONTINUE_100_INFO, header, null, null, false); + result = gen.generateResponse(HttpGenerator.CONTINUE_100_INFO, false, header, null, null, false); assertEquals(HttpGenerator.Result.FLUSH, result); assertEquals(HttpGenerator.State.COMPLETING_1XX, gen.getState()); String out = BufferUtil.toString(header); - result = gen.generateResponse(null, null, null, null, false); + result = gen.generateResponse(null, false, null, null, null, false); assertEquals(HttpGenerator.Result.DONE, result); assertEquals(HttpGenerator.State.START, gen.getState()); assertThat(out, containsString("HTTP/1.1 100 Continue")); - result = gen.generateResponse(null, null, null, content0, false); + result = gen.generateResponse(null, false, null, null, content0, false); assertEquals(HttpGenerator.Result.NEED_INFO, result); assertEquals(HttpGenerator.State.START, gen.getState()); MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 200, null, new HttpFields(), BufferUtil.length(content0)+BufferUtil.length(content1)); info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); - result = gen.generateResponse(info, null, null, content0, false); + result = gen.generateResponse(info, false, null, null, content0, false); assertEquals(HttpGenerator.Result.NEED_HEADER, result); assertEquals(HttpGenerator.State.START, gen.getState()); - result = gen.generateResponse(info, header, null, content0, false); + result = gen.generateResponse(info, false, header, null, content0, false); assertEquals(HttpGenerator.Result.FLUSH, result); assertEquals(HttpGenerator.State.COMMITTED, gen.getState()); @@ -632,17 +800,17 @@ public class HttpGeneratorServerTest out += BufferUtil.toString(content0); BufferUtil.clear(content0); - result = gen.generateResponse(null, null, null, content1, false); + result = gen.generateResponse(null, false, null, null, content1, false); assertEquals(HttpGenerator.Result.FLUSH, result); assertEquals(HttpGenerator.State.COMMITTED, gen.getState()); out += BufferUtil.toString(content1); BufferUtil.clear(content1); - result = gen.generateResponse(null, null, null, null, true); + result = gen.generateResponse(null, false, null, null, null, true); assertEquals(HttpGenerator.Result.CONTINUE, result); assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); - result = gen.generateResponse(null, null, null, null, true); + result = gen.generateResponse(null, false, null, null, null, true); assertEquals(HttpGenerator.Result.DONE, result); assertEquals(HttpGenerator.State.END, gen.getState()); @@ -664,7 +832,7 @@ public class HttpGeneratorServerTest fields.add(HttpHeader.CONNECTION, customValue); MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_0, 200, "OK", fields, -1); ByteBuffer header = BufferUtil.allocate(4096); - HttpGenerator.Result result = generator.generateResponse(info, header, null, null, true); + HttpGenerator.Result result = generator.generateResponse(info, false, header, null, null, true); Assert.assertSame(HttpGenerator.Result.FLUSH, result); String headers = BufferUtil.toString(header); Assert.assertTrue(headers.contains(HttpHeaderValue.KEEP_ALIVE.asString())); diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java index eb394ab8646..65633ecf3a1 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java @@ -2044,6 +2044,12 @@ public class HttpParserTest _trailers.add(field); } + @Override + public boolean contentComplete() + { + return false; + } + @Override public boolean messageComplete() { diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpTester.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpTester.java index 2ef6e34c457..0ade4d7777a 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpTester.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpTester.java @@ -21,15 +21,16 @@ package org.eclipse.jetty.http; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.net.Socket; import java.nio.ByteBuffer; -import java.nio.channels.ByteChannel; import java.nio.channels.ReadableByteChannel; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; /** @@ -60,6 +61,8 @@ import org.eclipse.jetty.util.StringUtil; */ public class HttpTester { + private final static Logger LOG = Log.getLogger(HttpTester.class); + private HttpTester() { } @@ -88,7 +91,7 @@ public class HttpTester parser.parseNext(request); return r; } - + public static Response parseResponse(String response) { Response r=new Response(); @@ -104,7 +107,18 @@ public class HttpTester parser.parseNext(response); return r; } - + + public static Response parseResponse(InputStream responseStream) throws IOException + { + ByteArrayOutputStream contentStream = new ByteArrayOutputStream(); + IO.copy(responseStream, contentStream); + + Response r=new Response(); + HttpParser parser =new HttpParser(r); + parser.parseNext(ByteBuffer.wrap(contentStream.toByteArray())); + return r; + } + public abstract static class Input { final ByteBuffer _buffer; @@ -202,17 +216,41 @@ public class HttpTester } public static Response parseResponse(Input in) throws IOException - { + { Response r; HttpParser parser=in.takeHttpParser(); if (parser==null) { r=new Response(); - parser =new HttpParser(r); + parser = new HttpParser(r); } else r=(Response)parser.getHandler(); + parseResponse(in, parser, r); + + if(r.isComplete()) + return r; + + in.setHttpParser(parser); + return null; + } + + public static void parseResponse(Input in, Response response) throws IOException + { + HttpParser parser = in.takeHttpParser(); + if (parser == null) + { + parser = new HttpParser(response); + } + parseResponse(in, parser, response); + + if (!response.isComplete()) + in.setHttpParser(parser); + } + + private static void parseResponse(Input in, HttpParser parser, Response r) throws IOException + { ByteBuffer buffer = in.getBuffer(); while(true) @@ -230,16 +268,11 @@ public class HttpTester break; } } - - if (r.isComplete()) - return r; - in.setHttpParser(parser); - return null; } - public abstract static class Message extends HttpFields implements HttpParser.HttpHandler { + boolean _earlyEOF; boolean _complete=false; ByteArrayOutputStream _content; HttpVersion _version=HttpVersion.HTTP_1_0; @@ -329,6 +362,12 @@ public class HttpTester add(field.getName(),field.getValue()); } + @Override + public boolean contentComplete() + { + return false; + } + @Override public boolean messageComplete() { @@ -346,8 +385,14 @@ public class HttpTester @Override public void earlyEOF() { + _earlyEOF = true; } - + + public boolean isEarlyEOF() + { + return _earlyEOF; + } + @Override public boolean content(ByteBuffer ref) { @@ -398,6 +443,10 @@ public class HttpTester chunk=BufferUtil.allocate(HttpGenerator.CHUNK_SIZE); continue; + case NEED_CHUNK_TRAILER: + chunk=BufferUtil.allocate(8192); + continue; + case NEED_INFO: throw new IllegalStateException(); diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpTesterTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpTesterTest.java index c0e642ae887..4ecfaf277ba 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpTesterTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpTesterTest.java @@ -20,7 +20,7 @@ package org.eclipse.jetty.http; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.*; +import static org.junit.Assert.assertThat; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -30,14 +30,11 @@ import java.net.Socket; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -import org.junit.Ignore; import org.junit.Test; public class HttpTesterTest { - @Test - @Ignore public void testExampleUsage() throws Exception { try(Socket socket = new Socket("www.google.com",80)) @@ -59,10 +56,8 @@ public class HttpTesterTest System.err.printf("%s: %s%n",field.getName(),field.getValue()); System.err.printf("%n%s%n",response.getContent()); } - } - @Test public void testGetRequestBuffer10() { diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java index 9e383ceacf7..21f463100e1 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java @@ -114,7 +114,10 @@ public class HttpChannelOverHTTP2 extends HttpChannel boolean endStream = frame.isEndStream(); if (endStream) + { + onContentComplete(); onRequestComplete(); + } _delayedUntilContent = getHttpConfiguration().isDelayDispatchUntilContent() && !endStream && !_expect100Continue; @@ -150,6 +153,7 @@ public class HttpChannelOverHTTP2 extends HttpChannel { onRequest(request); getRequest().setAttribute("org.eclipse.jetty.pushed", Boolean.TRUE); + onContentComplete(); onRequestComplete(); if (LOG.isDebugEnabled()) @@ -255,7 +259,11 @@ public class HttpChannelOverHTTP2 extends HttpChannel boolean endStream = frame.isEndStream(); if (endStream) - handle |= onRequestComplete(); + { + boolean handle_content = onContentComplete(); + boolean handle_request = onRequestComplete(); + handle |= handle_content | handle_request; + } if (LOG.isDebugEnabled()) { diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/FillInterest.java b/jetty-io/src/main/java/org/eclipse/jetty/io/FillInterest.java index 62594560ce2..ea90b4a8246 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/FillInterest.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/FillInterest.java @@ -88,8 +88,6 @@ public abstract class FillInterest try { - if (LOG.isDebugEnabled()) - LOG.debug("{} register {}",this,callback); needsFillInterest(); } catch (Throwable e) diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletFailureTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletFailureTest.java index 9337d751167..becb361c61e 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletFailureTest.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletFailureTest.java @@ -18,10 +18,8 @@ package org.eclipse.jetty.proxy; -import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; import java.nio.ByteBuffer; @@ -45,14 +43,13 @@ import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.client.util.BytesContentProvider; import org.eclipse.jetty.client.util.DeferredContentProvider; import org.eclipse.jetty.server.HttpChannel; +import org.eclipse.jetty.http.HttpTester; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.toolchain.test.TestTracker; -import org.eclipse.jetty.toolchain.test.http.SimpleHttpParser; -import org.eclipse.jetty.toolchain.test.http.SimpleHttpResponse; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.util.thread.QueuedThreadPool; @@ -68,7 +65,7 @@ public class ProxyServletFailureTest { private static final String PROXIED_HEADER = "X-Proxied"; - @Parameterized.Parameters + @Parameterized.Parameters(name = "{0}") public static Iterable data() { return Arrays.asList(new Object[][]{ @@ -206,14 +203,13 @@ public class ProxyServletFailureTest // Do not send the promised content, wait to idle timeout. socket.setSoTimeout(2 * idleTimeout); - SimpleHttpParser parser = new SimpleHttpParser(); - BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8")); - SimpleHttpResponse response = parser.readResponse(reader); - Assert.assertTrue(Integer.parseInt(response.getCode()) >= 500); - String connectionHeader = response.getHeaders().get("connection"); + + HttpTester.Response response = HttpTester.parseResponse(socket.getInputStream()); + Assert.assertTrue(response.getStatus() >= 500); + String connectionHeader = response.get("connection"); Assert.assertNotNull(connectionHeader); Assert.assertTrue(connectionHeader.contains("close")); - Assert.assertEquals(-1, reader.read()); + Assert.assertEquals(-1, socket.getInputStream().read()); } } @@ -242,14 +238,13 @@ public class ProxyServletFailureTest // Do not send all the promised content, wait to idle timeout. socket.setSoTimeout(2 * idleTimeout); - SimpleHttpParser parser = new SimpleHttpParser(); - BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8")); - SimpleHttpResponse response = parser.readResponse(reader); - Assert.assertTrue(Integer.parseInt(response.getCode()) >= 500); - String connectionHeader = response.getHeaders().get("connection"); + + HttpTester.Response response = HttpTester.parseResponse(socket.getInputStream()); + Assert.assertTrue(response.getStatus() >= 500); + String connectionHeader = response.get("connection"); Assert.assertNotNull(connectionHeader); Assert.assertTrue(connectionHeader.contains("close")); - Assert.assertEquals(-1, reader.read()); + Assert.assertEquals(-1, socket.getInputStream().read()); } } diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java index a30f0019895..935df6f3e81 100644 --- a/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java +++ b/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java @@ -94,7 +94,7 @@ public class PropertyUserStoreTest private File initUsersText() throws Exception { - Path dir = testdir.getDir().toPath().toRealPath(); + Path dir = testdir.getPath().toRealPath(); FS.ensureDirExists(dir.toFile()); File users = dir.resolve("users.txt").toFile(); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java index 00e5da3b80f..223cd3c9c53 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java @@ -581,13 +581,22 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor public boolean onContent(HttpInput.Content content) { if (LOG.isDebugEnabled()) - LOG.debug("{} content {}", this, content); + LOG.debug("{} onContent {}", this, content); return _request.getHttpInput().addContent(content); } + public boolean onContentComplete() + { + if (LOG.isDebugEnabled()) + LOG.debug("{} onContentComplete", this); + return false; + } + public void onTrailers(HttpFields trailers) { + if (LOG.isDebugEnabled()) + LOG.debug("{} onTrailers {}", this, trailers); _request.setTrailers(trailers); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java index b26c20a700e..66b96a8c67b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java @@ -467,14 +467,20 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque _httpConnection.getGenerator().setPersistent(false); } + @Override + public boolean contentComplete() + { + boolean handle = onContentComplete() || _delayedForContent; + _delayedForContent = false; + return handle; + } + @Override public boolean messageComplete() { if (_trailers != null) onTrailers(_trailers); - boolean handle = onRequestComplete() || _delayedForContent; - _delayedForContent = false; - return handle; + return onRequestComplete(); } @Override diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java index fbc79579c79..59422a7652e 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java @@ -284,7 +284,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http { int filled = fillRequestBuffer(); handled = parseRequestBuffer(); - if (handled || filled<=0 || _channel.getRequest().getHttpInput().hasContent()) + if (handled || filled<=0 || _input.hasContent()) break; } return handled; @@ -398,7 +398,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http else if (_parser.inContentState() && _generator.isPersistent()) { // If we are async, then we have problems to complete neatly - if (_channel.getRequest().getHttpInput().isAsync()) + if (_input.isAsync()) { if (LOG.isDebugEnabled()) LOG.debug("unconsumed async input {}", this); @@ -409,7 +409,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http if (LOG.isDebugEnabled()) LOG.debug("unconsumed input {}", this); // Complete reading the request - if (!_channel.getRequest().getHttpInput().consumeAll()) + if (!_input.consumeAll()) _channel.abort(new IOException("unconsumed input")); } } @@ -551,7 +551,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http public void asyncReadFillInterested() { - getEndPoint().fillInterested(_asyncReadCallback); + getEndPoint().tryFillInterested(_asyncReadCallback); } public void blockingReadFillInterested() @@ -627,7 +627,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http { if (fillAndParseForContent()) _channel.handle(); - else if (!_input.isFinished()) + else if (!_input.isFinished() && !_input.hasContent()) asyncReadFillInterested(); } @@ -716,6 +716,13 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http chunk = _chunk = _bufferPool.acquire(HttpGenerator.CHUNK_SIZE, CHUNK_BUFFER_DIRECT); continue; } + case NEED_CHUNK_TRAILER: + { + if (_chunk!=null) + _bufferPool.release(_chunk); + chunk = _chunk = _bufferPool.acquire(_config.getResponseHeaderSize(), CHUNK_BUFFER_DIRECT); + continue; + } case FLUSH: { // Don't write the chunk or the content if this is a HEAD response, or any other type of response that should have no content diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java index 4e65b59df83..f5524572669 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java @@ -421,6 +421,12 @@ public class LocalConnector extends AbstractConnector public void parsedHeader(HttpField field) { } + + @Override + public boolean contentComplete() + { + return false; + } @Override public boolean messageComplete() diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/Session.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/Session.java index 5bbb9f1c3f3..29a3548b6bc 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/Session.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/Session.java @@ -844,36 +844,14 @@ public class Session implements SessionHandler.SessionIf if (_handler == null) throw new IllegalStateException ("No session manager for session "+ _sessionData.getId()); - boolean result = false; - - try (Lock lock = _lock.lockIfNotHeld()) - { - switch (_state) - { - case INVALID: - { - throw new IllegalStateException(); //spec does not allow invalidate of already invalid session - } - case VALID: - { - //only first change from valid to invalidating should be actionable - result = true; - _state = State.INVALIDATING; - break; - } - default: - { - LOG.info("Session {} already being invalidated", _sessionData.getId()); - } - } - } + boolean result = beginInvalidate(); try { //if the session was not already invalid, or in process of being invalidated, do invalidate if (result) { - //tell id mgr to remove session from all other contexts + //tell id mgr to remove session from all contexts _handler.getSessionIdManager().invalidateAll(_sessionData.getId()); } } @@ -901,6 +879,39 @@ public class Session implements SessionHandler.SessionIf { return _lock.lockIfNotHeld(); } + + /* ------------------------------------------------------------- */ + /** + * @return true if the session is not already invalid or being invalidated. + */ + protected boolean beginInvalidate() + { + boolean result = false; + + try (Lock lock = _lock.lockIfNotHeld()) + { + switch (_state) + { + case INVALID: + { + throw new IllegalStateException(); //spec does not allow invalidate of already invalid session + } + case VALID: + { + //only first change from valid to invalidating should be actionable + result = true; + _state = State.INVALIDATING; + break; + } + default: + { + LOG.info("Session {} already being invalidated", _sessionData.getId()); + } + } + } + + return result; + } /* ------------------------------------------------------------- */ /** Call HttpSessionAttributeListeners as part of invalidating @@ -908,7 +919,20 @@ public class Session implements SessionHandler.SessionIf * * @throws IllegalStateException */ + @Deprecated protected void doInvalidate() throws IllegalStateException + { + finishInvalidate(); + } + + + /* ------------------------------------------------------------- */ + /** Call HttpSessionAttributeListeners as part of invalidating + * a Session. + * + * @throws IllegalStateException + */ + protected void finishInvalidate() throws IllegalStateException { try (Lock lock = _lock.lockIfNotHeld()) { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java index ddaf1f47ed7..e8984592fac 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java @@ -1048,6 +1048,8 @@ public class SessionHandler extends ScopedHandler { if (invalidate) { + session.beginInvalidate(); + if (_sessionListeners!=null) { HttpSessionEvent event=new HttpSessionEvent(session); @@ -1214,8 +1216,7 @@ public class SessionHandler extends ScopedHandler /* ------------------------------------------------------------ */ /** - * Called either when a session has expired, or the app has - * invalidated it. + * Called when a session has expired. * * @param id the id to invalidate */ @@ -1232,7 +1233,7 @@ public class SessionHandler extends ScopedHandler if (session != null) { _sessionTimeStats.set(round((System.currentTimeMillis() - session.getSessionData().getCreated())/1000.0)); - session.doInvalidate(); + session.finishInvalidate(); } } catch (Exception e) @@ -1242,7 +1243,11 @@ public class SessionHandler extends ScopedHandler } - + /* ------------------------------------------------------------ */ + /** + * Called periodically by the HouseKeeper to handle the list of + * sessions that have expired since the last call to scavenge. + */ public void scavenge () { //don't attempt to scavenge if we are shutting down @@ -1279,7 +1284,7 @@ public class SessionHandler extends ScopedHandler } } - + /* ------------------------------------------------------------ */ /** * Each session has a timer that is configured to go off * when either the session has not been accessed for a diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractHttpTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractHttpTest.java index bb5e0b4b2af..7db394abf7a 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractHttpTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractHttpTest.java @@ -21,14 +21,11 @@ package org.eclipse.jetty.server; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import java.net.URISyntaxException; -import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.HashSet; import java.util.Set; @@ -37,11 +34,10 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpTester; import org.eclipse.jetty.io.ArrayByteBufferPool; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.toolchain.test.TestTracker; -import org.eclipse.jetty.toolchain.test.http.SimpleHttpParser; -import org.eclipse.jetty.toolchain.test.http.SimpleHttpResponse; import org.eclipse.jetty.util.log.StacklessLogging; import org.junit.After; import org.junit.Before; @@ -57,8 +53,7 @@ public abstract class AbstractHttpTest protected static Server server; protected static ServerConnector connector; protected String httpVersion; - protected SimpleHttpParser httpParser; - StacklessLogging stackless; + private StacklessLogging stacklessChannelLogging; public AbstractHttpTest(String httpVersion) @@ -71,53 +66,56 @@ public abstract class AbstractHttpTest { server = new Server(); connector = new ServerConnector(server,null,null,new ArrayByteBufferPool(64,2048,64*1024),1,1,new HttpConnectionFactory()); - connector.setIdleTimeout(10000); + connector.setIdleTimeout(100000); server.addConnector(connector); - httpParser = new SimpleHttpParser(); - stackless=new StacklessLogging(HttpChannel.class); + stacklessChannelLogging =new StacklessLogging(HttpChannel.class); } @After public void tearDown() throws Exception { server.stop(); - stackless.close(); + stacklessChannelLogging.close(); } - protected SimpleHttpResponse executeRequest() throws URISyntaxException, IOException + protected HttpTester.Response executeRequest() throws URISyntaxException, IOException { try(Socket socket = new Socket("localhost", connector.getLocalPort())) { socket.setSoTimeout((int)connector.getIdleTimeout()); - BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8)); - PrintWriter writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream())); - - writer.write("GET / " + httpVersion + "\r\n"); - writer.write("Host: localhost\r\n"); - writer.write("\r\n"); - writer.flush(); - - // TODO replace the SimpleHttp stuff - SimpleHttpResponse response = httpParser.readResponse(reader); - if ("HTTP/1.1".equals(httpVersion) - && response.getHeaders().get("content-length") == null - && response.getHeaders().get("transfer-encoding") == null - && !__noBodyCodes.contains(response.getCode())) - assertThat("If HTTP/1.1 response doesn't contain transfer-encoding or content-length headers, " + - "it should contain connection:close", response.getHeaders().get("connection"), is("close")); - return response; + + try(PrintWriter writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()))) + { + writer.write("GET / " + httpVersion + "\r\n"); + writer.write("Host: localhost\r\n"); + writer.write("\r\n"); + writer.flush(); + + HttpTester.Response response = new HttpTester.Response(); + HttpTester.Input input = HttpTester.from(socket.getInputStream()); + HttpTester.parseResponse(input, response); + + if ("HTTP/1.1".equals(httpVersion) + && response.isComplete() + && response.get("content-length") == null + && response.get("transfer-encoding") == null + && !__noBodyCodes.contains(response.getStatus())) + assertThat("If HTTP/1.1 response doesn't contain transfer-encoding or content-length headers, " + + "it should contain connection:close", response.get("connection"), is("close")); + return response; + } } } - protected void assertResponseBody(SimpleHttpResponse response, String expectedResponseBody) + protected void assertResponseBody(HttpTester.Response response, String expectedResponseBody) { - assertThat("response body is" + expectedResponseBody, response.getBody(), is(expectedResponseBody)); + assertThat("response body is" + expectedResponseBody, response.getContent(), is(expectedResponseBody)); } - protected void assertHeader(SimpleHttpResponse response, String headerName, String expectedValue) + protected void assertHeader(HttpTester.Response response, String headerName, String expectedValue) { - assertThat(headerName + "=" + expectedValue, response.getHeaders().get(headerName), is(expectedValue)); + assertThat(headerName + "=" + expectedValue, response.get(headerName), is(expectedValue)); } protected static class TestCommitException extends IllegalStateException diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectionOpenCloseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectionOpenCloseTest.java index e5f2c63fb17..a1e5a86eb74 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectionOpenCloseTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectionOpenCloseTest.java @@ -18,10 +18,12 @@ package org.eclipse.jetty.server; -import java.io.BufferedReader; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + import java.io.File; import java.io.IOException; -import java.io.InputStreamReader; +import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.nio.charset.StandardCharsets; @@ -33,12 +35,12 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpTester; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.annotation.Slow; -import org.eclipse.jetty.toolchain.test.http.SimpleHttpResponse; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.ssl.SslContextFactory; @@ -136,30 +138,32 @@ public class ConnectionOpenCloseTest extends AbstractHttpTest } }); - Socket socket = new Socket("localhost", connector.getLocalPort()); - socket.setSoTimeout((int)connector.getIdleTimeout()); - OutputStream output = socket.getOutputStream(); - output.write(( - "GET / HTTP/1.1\r\n" + - "Host: localhost:" + connector.getLocalPort() + "\r\n" + - "Connection: close\r\n" + - "\r\n").getBytes(StandardCharsets.UTF_8)); - output.flush(); - - BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); - SimpleHttpResponse response = httpParser.readResponse(reader); - Assert.assertEquals("200", response.getCode()); - - Assert.assertEquals(-1, reader.read()); - socket.close(); - - Assert.assertTrue(openLatch.await(5, TimeUnit.SECONDS)); - Assert.assertTrue(closeLatch.await(5, TimeUnit.SECONDS)); - - // Wait some time to see if the callbacks are called too many times - TimeUnit.SECONDS.sleep(1); - - Assert.assertEquals(2, callbacks.get()); + try( Socket socket = new Socket("localhost", connector.getLocalPort()) ) + { + socket.setSoTimeout((int) connector.getIdleTimeout()); + OutputStream output = socket.getOutputStream(); + output.write(( + "GET / HTTP/1.1\r\n" + + "Host: localhost:" + connector.getLocalPort() + "\r\n" + + "Connection: close\r\n" + + "\r\n").getBytes(StandardCharsets.UTF_8)); + output.flush(); + + InputStream inputStream = socket.getInputStream(); + HttpTester.Response response = HttpTester.parseResponse(inputStream); + assertThat("Status Code", response.getStatus(), is(200)); + + Assert.assertEquals(-1, inputStream.read()); + socket.close(); + + Assert.assertTrue(openLatch.await(5, TimeUnit.SECONDS)); + Assert.assertTrue(closeLatch.await(5, TimeUnit.SECONDS)); + + // Wait some time to see if the callbacks are called too many times + TimeUnit.SECONDS.sleep(1); + + Assert.assertEquals(2, callbacks.get()); + } } @Slow @@ -217,11 +221,11 @@ public class ConnectionOpenCloseTest extends AbstractHttpTest "\r\n").getBytes(StandardCharsets.UTF_8)); output.flush(); - BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); - SimpleHttpResponse response = httpParser.readResponse(reader); - Assert.assertEquals("200", response.getCode()); + InputStream inputStream = socket.getInputStream(); + HttpTester.Response response = HttpTester.parseResponse(inputStream); + Assert.assertEquals(200, response.getStatus()); - Assert.assertEquals(-1, reader.read()); + Assert.assertEquals(-1, inputStream.read()); socket.close(); Assert.assertTrue(openLatch.await(5, TimeUnit.SECONDS)); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HostHeaderCustomizerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HostHeaderCustomizerTest.java index b50382d7a88..2f95f49008b 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/HostHeaderCustomizerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HostHeaderCustomizerTest.java @@ -18,9 +18,7 @@ package org.eclipse.jetty.server; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; import java.nio.charset.StandardCharsets; @@ -29,10 +27,9 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpTester; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.toolchain.test.TestTracker; -import org.eclipse.jetty.toolchain.test.http.SimpleHttpParser; -import org.eclipse.jetty.toolchain.test.http.SimpleHttpResponse; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; @@ -69,24 +66,25 @@ public class HostHeaderCustomizerTest { try (Socket socket = new Socket("localhost", connector.getLocalPort())) { - OutputStream output = socket.getOutputStream(); - String request = "" + - "GET / HTTP/1.0\r\n" + - "\r\n"; - output.write(request.getBytes(StandardCharsets.UTF_8)); - output.flush(); - - BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8)); - SimpleHttpParser parser = new SimpleHttpParser(); - SimpleHttpResponse response = parser.readResponse(input); - - String location = response.getHeaders().get("location"); - Assert.assertNotNull(location); - String schemePrefix = "http://"; - Assert.assertTrue(location.startsWith(schemePrefix)); - Assert.assertTrue(location.endsWith(redirectPath)); - String hostPort = location.substring(schemePrefix.length(), location.length() - redirectPath.length()); - Assert.assertEquals(serverName + ":" + serverPort, hostPort); + try(OutputStream output = socket.getOutputStream()) + { + String request = "" + + "GET / HTTP/1.0\r\n" + + "\r\n"; + output.write(request.getBytes(StandardCharsets.UTF_8)); + output.flush(); + + HttpTester.Input input = HttpTester.from(socket.getInputStream()); + HttpTester.Response response = HttpTester.parseResponse(input); + + String location = response.get("location"); + Assert.assertNotNull(location); + String schemePrefix = "http://"; + Assert.assertTrue(location.startsWith(schemePrefix)); + Assert.assertTrue(location.endsWith(redirectPath)); + String hostPort = location.substring(schemePrefix.length(), location.length() - redirectPath.length()); + Assert.assertEquals(serverName + ":" + serverPort, hostPort); + } } } finally diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpConnectionTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpConnectionTest.java index cc533e59397..ef6772626d9 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpConnectionTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpConnectionTest.java @@ -328,6 +328,66 @@ public class HttpConnectionTest checkContains(response,offset,"/R1"); } + @Test + public void testChunk() throws Exception + { + String response=connector.getResponse("GET /R1 HTTP/1.1\r\n"+ + "Host: localhost\r\n"+ + "Transfer-Encoding: chunked\r\n"+ + "Content-Type: text/plain\r\n"+ + "Connection: close\r\n"+ + "\r\n"+ + "A\r\n" + + "0123456789\r\n"+ + "0\r\n" + + "\r\n"); + + int offset=0; + offset = checkContains(response,offset,"HTTP/1.1 200"); + offset = checkContains(response,offset,"/R1"); + checkContains(response,offset,"0123456789"); + } + + @Test + public void testChunkTrailer() throws Exception + { + String response=connector.getResponse("GET /R1 HTTP/1.1\r\n"+ + "Host: localhost\r\n"+ + "Transfer-Encoding: chunked\r\n"+ + "Content-Type: text/plain\r\n"+ + "Connection: close\r\n"+ + "\r\n"+ + "A\r\n" + + "0123456789\r\n"+ + "0\r\n" + + "Trailer: ignored\r\n" + + "\r\n"); + + int offset=0; + offset = checkContains(response,offset,"HTTP/1.1 200"); + offset = checkContains(response,offset,"/R1"); + checkContains(response,offset,"0123456789"); + } + + @Test + public void testChunkNoTrailer() throws Exception + { + String response=connector.getResponse("GET /R1 HTTP/1.1\r\n"+ + "Host: localhost\r\n"+ + "Transfer-Encoding: chunked\r\n"+ + "Content-Type: text/plain\r\n"+ + "Connection: close\r\n"+ + "\r\n"+ + "A\r\n" + + "0123456789\r\n"+ + "0\r\n"); + + int offset=0; + offset = checkContains(response,offset,"HTTP/1.1 200"); + offset = checkContains(response,offset,"/R1"); + checkContains(response,offset,"0123456789"); + } + @Test public void testHead() throws Exception { diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpManyWaysToAsyncCommitBadBehaviourTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpManyWaysToAsyncCommitBadBehaviourTest.java index 56257ea99f3..cc3e0142cb4 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpManyWaysToAsyncCommitBadBehaviourTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpManyWaysToAsyncCommitBadBehaviourTest.java @@ -35,8 +35,8 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpTester; import org.eclipse.jetty.http.HttpVersion; -import org.eclipse.jetty.toolchain.test.http.SimpleHttpResponse; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -71,9 +71,9 @@ public class HttpManyWaysToAsyncCommitBadBehaviourTest extends AbstractHttpTest server.setHandler(new SetHandledWriteSomeDataHandler(false)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 500", response.getCode(), is("500")); + assertThat("response code is 500", response.getStatus(), is(500)); } private class SetHandledWriteSomeDataHandler extends ThrowExceptionOnDemandHandler diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpManyWaysToAsyncCommitTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpManyWaysToAsyncCommitTest.java index e5c3c02598c..e99a24d52fd 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpManyWaysToAsyncCommitTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpManyWaysToAsyncCommitTest.java @@ -32,8 +32,8 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpTester; import org.eclipse.jetty.http.HttpVersion; -import org.eclipse.jetty.toolchain.test.http.SimpleHttpResponse; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -46,7 +46,7 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest private final String CONTEXT_ATTRIBUTE = getClass().getName() + ".asyncContext"; private boolean dispatch; // if true we dispatch, otherwise we complete - @Parameterized.Parameters + @Parameterized.Parameters(name = "{0} dispatch={1}") public static Collection data() { Object[][] data = new Object[][] @@ -73,9 +73,9 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 404", response.getCode(), is("404")); + assertThat("response code", response.getStatus(), is(404)); assertThat("no exceptions", handler.failure(), is(nullValue())); } @@ -86,9 +86,9 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 500", response.getCode(), is("500")); + assertThat("response code", response.getStatus(), is(500)); assertThat("no exceptions", handler.failure(), is(nullValue())); } @@ -129,9 +129,9 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); - - assertThat("response code is 200", response.getCode(), is("200")); + HttpTester.Response response = executeRequest(); + + assertThat("response code", response.getStatus(), is(200)); if (HttpVersion.HTTP_1_1.asString().equals(httpVersion)) assertHeader(response, "content-length", "0"); assertThat("no exceptions", handler.failure(), is(nullValue())); @@ -144,9 +144,9 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 500", response.getCode(), is("500")); + assertThat("response code", response.getStatus(), is(500)); assertThat("no exceptions", handler.failure(), is(nullValue())); } @@ -188,9 +188,9 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); assertHeader(response, "content-length", "6"); assertThat("no exceptions", handler.failure(), is(nullValue())); } @@ -202,9 +202,9 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 500", response.getCode(), is("500")); + assertThat("response code", response.getStatus(), is(500)); assertThat("no exceptions", handler.failure(), is(nullValue())); } @@ -254,10 +254,10 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); assertThat("no exceptions", handler.failure(), is(nullValue())); if (!"HTTP/1.0".equals(httpVersion)) assertHeader(response, "transfer-encoding", "chunked"); @@ -270,9 +270,9 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); assertThat("no exceptions", handler.failure(), is(nullValue())); if (!"HTTP/1.0".equals(httpVersion)) assertHeader(response, "transfer-encoding", "chunked"); @@ -326,9 +326,9 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); assertThat("no exceptions", handler.failure(), is(nullValue())); if (!"HTTP/1.0".equals(httpVersion)) assertHeader(response, "transfer-encoding", "chunked"); @@ -341,9 +341,9 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); assertThat("no exceptions", handler.failure(), is(nullValue())); if (!"HTTP/1.0".equals(httpVersion)) assertHeader(response, "transfer-encoding", "chunked"); @@ -395,9 +395,9 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); assertThat("no exceptions", handler.failure(), is(nullValue())); if (!"HTTP/1.0".equals(httpVersion)) assertHeader(response, "transfer-encoding", "chunked"); // HTTP/1.0 does not do chunked. it will just send content and close @@ -410,9 +410,9 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); assertThat("no exceptions", handler.failure(), is(nullValue())); if (!"HTTP/1.0".equals(httpVersion)) assertHeader(response, "transfer-encoding", "chunked"); @@ -467,9 +467,9 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); assertResponseBody(response, "foobar"); if (!"HTTP/1.0".equals(httpVersion)) assertHeader(response, "transfer-encoding", "chunked"); @@ -483,10 +483,10 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); // Buffer size is too small, so the content is written directly producing a 200 response - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); assertResponseBody(response, "foobar"); if (!"HTTP/1.0".equals(httpVersion)) assertHeader(response, "transfer-encoding", "chunked"); @@ -541,10 +541,10 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); - assertThat("response body is foo", response.getBody(), is("foo")); + assertThat("response code", response.getStatus(), is(200)); + assertThat("response body", response.getContent(), is("foo")); assertHeader(response, "content-length", "3"); assertThat("no exceptions", handler.failure(), is(nullValue())); } @@ -556,11 +556,11 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); //TODO: should we expect 500 here? - assertThat("response code is 200", response.getCode(), is("200")); - assertThat("response body is foo", response.getBody(), is("foo")); + assertThat("response code", response.getStatus(), is(200)); + assertThat("response body", response.getContent(), is("foo")); assertHeader(response, "content-length", "3"); assertThat("no exceptions", handler.failure(), is(nullValue())); } @@ -613,11 +613,11 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); // jetty truncates the body when content-length is reached.! This is correct and desired behaviour? - assertThat("response body is foo", response.getBody(), is("foo")); + assertThat("response body", response.getContent(), is("foo")); assertHeader(response, "content-length", "3"); assertThat("no exceptions", handler.failure(), is(nullValue())); } @@ -629,11 +629,11 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); // TODO: we throw before response is committed. should we expect 500? - assertThat("response code is 200", response.getCode(), is("200")); - assertThat("response body is foo", response.getBody(), is("foo")); + assertThat("response code", response.getStatus(), is(200)); + assertThat("response body", response.getContent(), is("foo")); assertHeader(response, "content-length", "3"); assertThat("no exceptions", handler.failure(), is(nullValue())); } @@ -686,9 +686,9 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); assertThat("no exceptions", handler.failure(), is(nullValue())); //TODO: jetty ignores setContentLength and sends transfer-encoding header. Correct? } @@ -700,9 +700,9 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); assertThat("no exceptions", handler.failure(), is(nullValue())); } @@ -754,10 +754,10 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); // Setting a content-length too small throws an IllegalStateException - assertThat("response code is 500", response.getCode(), is("500")); + assertThat("response code", response.getStatus(), is(500)); assertThat("no exceptions", handler.failure(), is(nullValue())); } @@ -768,10 +768,10 @@ public class HttpManyWaysToAsyncCommitTest extends AbstractHttpTest server.setHandler(handler); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); // Setting a content-length too small throws an IllegalStateException - assertThat(response.getCode(), is("500")); + assertThat("response code", response.getStatus(), is(500)); assertThat("no exceptions", handler.failure(), is(nullValue())); } diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpManyWaysToCommitTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpManyWaysToCommitTest.java index 7a49d917708..9cb27c4d48e 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpManyWaysToCommitTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpManyWaysToCommitTest.java @@ -21,8 +21,8 @@ package org.eclipse.jetty.server; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; -import java.io.EOFException; import java.io.IOException; import java.util.Arrays; import java.util.Collection; @@ -31,20 +31,19 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpTester; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.server.handler.AbstractHandler; -import org.eclipse.jetty.toolchain.test.http.SimpleHttpResponse; -import org.hamcrest.Matchers; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; //TODO: reset buffer tests //TODO: add protocol specific tests for connection: close and/or chunking -@RunWith(value = Parameterized.class) +@RunWith(Parameterized.class) public class HttpManyWaysToCommitTest extends AbstractHttpTest { - @Parameterized.Parameters + @Parameterized.Parameters(name = "{0}") public static Collection data() { Object[][] data = new Object[][]{{HttpVersion.HTTP_1_0.asString()}, {HttpVersion.HTTP_1_1.asString()}}; @@ -61,10 +60,10 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest { server.setHandler(new DoesNotSetHandledHandler(false)); server.start(); + + HttpTester.Response response = executeRequest(); - SimpleHttpResponse response = executeRequest(); - - assertThat("response code is 404", response.getCode(), is("404")); + assertThat("response code", response.getStatus(), is(404)); } @Test @@ -72,10 +71,10 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest { server.setHandler(new DoesNotSetHandledHandler(true)); server.start(); + + HttpTester.Response response = executeRequest(); - SimpleHttpResponse response = executeRequest(); - - assertThat("response code is 500", response.getCode(), is("500")); + assertThat("response code", response.getStatus(), is(500)); } private class DoesNotSetHandledHandler extends ThrowExceptionOnDemandHandler @@ -99,10 +98,9 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new OnlySetHandledHandler(false)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); - + assertThat("response code", response.getStatus(), is(200)); if (HttpVersion.HTTP_1_1.asString().equals(httpVersion)) assertHeader(response, "content-length", "0"); } @@ -113,9 +111,9 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new OnlySetHandledHandler(true)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 500", response.getCode(), is("500")); + assertThat("response code", response.getStatus(), is(500)); } private class OnlySetHandledHandler extends ThrowExceptionOnDemandHandler @@ -139,9 +137,9 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new SetHandledWriteSomeDataHandler(false)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); assertResponseBody(response, "foobar"); assertHeader(response, "content-length", "6"); } @@ -152,10 +150,10 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new SetHandledWriteSomeDataHandler(true)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 500", response.getCode(), is("500")); - assertThat("response body is not foobar", response.getBody(), not(is("foobar"))); + assertThat("response code", response.getStatus(), is(500)); + assertThat("response body", response.getContent(), not(is("foobar"))); } private class SetHandledWriteSomeDataHandler extends ThrowExceptionOnDemandHandler @@ -180,9 +178,9 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new ExplicitFlushHandler(false)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); assertResponseBody(response, "foobar"); if (!"HTTP/1.0".equals(httpVersion)) assertHeader(response, "transfer-encoding", "chunked"); @@ -194,11 +192,11 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new ExplicitFlushHandler(true)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); // Since the 200 was committed, the 500 did not get the chance to be written - assertThat("response code is 200", response.getCode(), is("200")); - assertThat("response body is foobar", response.getBody(), is("foobar")); + assertThat("response code", response.getStatus(), is(200)); + assertThat("response body", response.getContent(), is("foobar")); if (!"HTTP/1.0".equals(httpVersion)) assertHeader(response, "transfer-encoding", "chunked"); } @@ -226,9 +224,9 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new SetHandledAndFlushWithoutContentHandler(false)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); if (!"HTTP/1.0".equals(httpVersion)) assertHeader(response, "transfer-encoding", "chunked"); } @@ -239,9 +237,9 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new SetHandledAndFlushWithoutContentHandler(true)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); if (!"HTTP/1.0".equals(httpVersion)) assertHeader(response, "transfer-encoding", "chunked"); } @@ -268,9 +266,9 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new WriteFlushWriteMoreHandler(false)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); assertResponseBody(response, "foobar"); if (!"HTTP/1.0".equals(httpVersion)) assertHeader(response, "transfer-encoding", "chunked"); @@ -282,11 +280,10 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new WriteFlushWriteMoreHandler(true)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); // Since the 200 was committed, the 500 did not get the chance to be written - assertThat("response code is 200", response.getCode(), is("200")); - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); if (!"HTTP/1.0".equals(httpVersion)) assertHeader(response, "transfer-encoding", "chunked"); } @@ -315,9 +312,9 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new OverflowHandler(false)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); assertResponseBody(response, "foobar"); if (!"HTTP/1.0".equals(httpVersion)) assertHeader(response, "transfer-encoding", "chunked"); @@ -329,9 +326,9 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new Overflow2Handler(false)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); assertResponseBody(response, "foobarfoobar"); if (!"HTTP/1.0".equals(httpVersion)) assertHeader(response, "transfer-encoding", "chunked"); @@ -343,9 +340,9 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new Overflow3Handler(false)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); assertResponseBody(response, "foobarfoobar"); if (!"HTTP/1.0".equals(httpVersion)) assertHeader(response, "transfer-encoding", "chunked"); @@ -357,10 +354,10 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new OverflowHandler(true)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); // Response was committed when we throw, so 200 expected - assertThat("response code is 200", response.getCode(), is("200")); + assertThat("response code", response.getStatus(), is(200)); assertResponseBody(response, "foobar"); if (!"HTTP/1.0".equals(httpVersion)) assertHeader(response, "transfer-encoding", "chunked"); @@ -428,21 +425,14 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest { server.setHandler(new SetContentLengthAndWriteInsufficientBytesHandler(true)); server.start(); - try - { - // TODO This test is compromised by the SimpleHttpResponse mechanism. - // Replace with a better client - - SimpleHttpResponse response = executeRequest(); - String failed_body = ""+(char)-1+(char)-1+(char)-1; - assertThat("response code is 200", response.getCode(), is("200")); - assertThat(response.getBody(), Matchers.endsWith(failed_body)); - assertHeader(response, "content-length", "6"); - } - catch(EOFException e) - { - // possible good response - } + + HttpTester.Response response = executeRequest(); + System.out.println(response.toString()); + assertThat("response code", response.getStatus(), is(200)); + assertHeader(response, "content-length", "6"); + byte content[] = response.getContentBytes(); + assertThat("content bytes", content.length, is(0)); + assertTrue("response eof", response.isEarlyEOF()); } @Test @@ -451,20 +441,9 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new SetContentLengthAndWriteInsufficientBytesHandler(false)); server.start(); - try - { - // TODO This test is compromised by the SimpleHttpResponse mechanism. - // Replace with a better client - SimpleHttpResponse response = executeRequest(); - String failed_body = ""+(char)-1+(char)-1+(char)-1; - assertThat("response code is 200", response.getCode(), is("200")); - assertThat(response.getBody(), Matchers.endsWith(failed_body)); - assertHeader(response, "content-length", "6"); - } - catch(EOFException e) - { - // expected - } + HttpTester.Response response = executeRequest(); + assertThat("response has no status", response.getStatus(), is(0)); + assertTrue("response eof", response.isEarlyEOF()); } @Test @@ -473,10 +452,10 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new SetContentLengthAndWriteThatAmountOfBytesHandler(false)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); - assertThat("response body is foo", response.getBody(), is("foo")); + assertThat("response code", response.getStatus(), is(200)); + assertThat("response body", response.getContent(), is("foo")); assertHeader(response, "content-length", "3"); } @@ -486,11 +465,11 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new SetContentLengthAndWriteThatAmountOfBytesHandler(true)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); // Setting the content-length and then writing the bytes commits the response - assertThat("response code is 200", response.getCode(), is("200")); - assertThat("response body is foo", response.getBody(), is("foo")); + assertThat("response code", response.getStatus(), is(200)); + assertThat("response body", response.getContent(), is("foo")); } private class SetContentLengthAndWriteInsufficientBytesHandler extends AbstractHandler @@ -535,10 +514,10 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new SetContentLengthAndWriteMoreBytesHandler(false)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); - assertThat("response body is foo", response.getBody(), is("foo")); + assertThat("response code", response.getStatus(), is(200)); + assertThat("response body", response.getContent(), is("foo")); assertHeader(response, "content-length", "3"); } @@ -548,11 +527,11 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new SetContentLengthAndWriteMoreBytesHandler(true)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); // Setting the content-length and then writing the bytes commits the response - assertThat("response code is 200", response.getCode(), is("200")); - assertThat("response body is foo", response.getBody(), is("foo")); + assertThat("response code", response.getStatus(), is(200)); + assertThat("response body", response.getContent(), is("foo")); } private class SetContentLengthAndWriteMoreBytesHandler extends ThrowExceptionOnDemandHandler @@ -579,10 +558,10 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new WriteAndSetContentLengthHandler(false)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); - assertThat("response code is 200", response.getCode(), is("200")); - assertThat("response body is foo", response.getBody(), is("foo")); + assertThat("response code", response.getStatus(), is(200)); + assertThat("response body", response.getContent(), is("foo")); assertHeader(response, "content-length", "3"); } @@ -592,11 +571,11 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new WriteAndSetContentLengthHandler(true)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); // Writing the bytes and then setting the content-length commits the response - assertThat("response code is 200", response.getCode(), is("200")); - assertThat("response body is foo", response.getBody(), is("foo")); + assertThat("response code", response.getStatus(), is(200)); + assertThat("response body", response.getContent(), is("foo")); } private class WriteAndSetContentLengthHandler extends ThrowExceptionOnDemandHandler @@ -622,11 +601,11 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new WriteAndSetContentLengthTooSmallHandler(false)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); // Setting a content-length too small throws an IllegalStateException - assertThat("response code is 500", response.getCode(), is("500")); - assertThat("response body is not foo", response.getBody(), not(is("foo"))); + assertThat("response code", response.getStatus(), is(500)); + assertThat("response body", response.getContent(), not(is("foo"))); } @Test @@ -635,11 +614,11 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest server.setHandler(new WriteAndSetContentLengthTooSmallHandler(true)); server.start(); - SimpleHttpResponse response = executeRequest(); + HttpTester.Response response = executeRequest(); // Setting a content-length too small throws an IllegalStateException - assertThat("response code is 500", response.getCode(), is("500")); - assertThat("response body is not foo", response.getBody(), not(is("foo"))); + assertThat("response code", response.getStatus(), is(500)); + assertThat("response body", response.getContent(), not(is("foo"))); } private class WriteAndSetContentLengthTooSmallHandler extends ThrowExceptionOnDemandHandler diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/DebugHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/DebugHandlerTest.java index f691ea00871..020b2831f9e 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/DebugHandlerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/DebugHandlerTest.java @@ -18,14 +18,14 @@ package org.eclipse.jetty.server.handler; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.not; -import static org.junit.Assert.assertThat; +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.net.HttpURLConnection; import java.net.URI; import java.nio.charset.StandardCharsets; import java.security.KeyStore; @@ -50,7 +50,6 @@ import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.toolchain.test.SimpleRequest; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.Scheduler; import org.junit.After; @@ -155,8 +154,8 @@ public class DebugHandlerTest @Test public void testThreadName() throws IOException { - SimpleRequest req = new SimpleRequest(serverURI); - req.getString("/foo/bar?a=b"); + HttpURLConnection http = (HttpURLConnection) serverURI.resolve("/foo/bar?a=b").toURL().openConnection(); + assertThat("Response Code", http.getResponseCode(), is(200)); String log = capturedLog.toString(StandardCharsets.UTF_8.name()); String expectedThreadName = String.format("//%s:%s/foo/bar?a=b",serverURI.getHost(),serverURI.getPort()); @@ -169,8 +168,8 @@ public class DebugHandlerTest @Test public void testSecureThreadName() throws IOException { - SimpleRequest req = new SimpleRequest(secureServerURI); - req.getString("/foo/bar?a=b"); + HttpURLConnection http = (HttpURLConnection) secureServerURI.resolve("/foo/bar?a=b").toURL().openConnection(); + assertThat("Response Code", http.getResponseCode(), is(200)); String log = capturedLog.toString(StandardCharsets.UTF_8.name()); String expectedThreadName = String.format("https://%s:%s/foo/bar?a=b",secureServerURI.getHost(),secureServerURI.getPort()); diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncContextListenersTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncContextListenersTest.java index cca7a6a97d2..a5407488c82 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncContextListenersTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncContextListenersTest.java @@ -18,15 +18,12 @@ package org.eclipse.jetty.servlet; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import javax.servlet.AsyncContext; @@ -37,10 +34,9 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpTester; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.toolchain.test.http.SimpleHttpParser; -import org.eclipse.jetty.toolchain.test.http.SimpleHttpResponse; import org.junit.After; import org.junit.Assert; import org.junit.Test; @@ -67,7 +63,8 @@ public class AsyncContextListenersTest { _server.stop(); } - + + @SuppressWarnings("Duplicates") @Test public void testListenerClearedOnSecondRequest() throws Exception { @@ -105,7 +102,7 @@ public class AsyncContextListenersTest asyncContext.complete(); } }); - + try (Socket socket = new Socket("localhost", _connector.getLocalPort())) { OutputStream output = socket.getOutputStream(); @@ -116,11 +113,10 @@ public class AsyncContextListenersTest "\r\n"; output.write(request.getBytes(StandardCharsets.UTF_8)); output.flush(); - - BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8)); - SimpleHttpParser parser = new SimpleHttpParser(); - SimpleHttpResponse response = parser.readResponse(reader); - Assert.assertEquals("200", response.getCode()); + + HttpTester.Input input = HttpTester.from(socket.getInputStream()); + HttpTester.Response response = HttpTester.parseResponse(input); + Assert.assertEquals(200, response.getStatus()); completes.get().await(10,TimeUnit.SECONDS); // Send a second request @@ -128,12 +124,13 @@ public class AsyncContextListenersTest output.write(request.getBytes(StandardCharsets.UTF_8)); output.flush(); - response = parser.readResponse(reader); - Assert.assertEquals("200", response.getCode()); + response = HttpTester.parseResponse(input); + Assert.assertEquals(200, response.getStatus()); completes.get().await(10,TimeUnit.SECONDS); } } + @SuppressWarnings("Duplicates") @Test public void testListenerAddedFromListener() throws Exception { @@ -188,19 +185,18 @@ public class AsyncContextListenersTest output.write(request.getBytes(StandardCharsets.UTF_8)); output.flush(); - BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8)); - SimpleHttpParser parser = new SimpleHttpParser(); - SimpleHttpResponse response = parser.readResponse(reader); - Assert.assertEquals("200", response.getCode()); + HttpTester.Input input = HttpTester.from(socket.getInputStream()); + HttpTester.Response response = HttpTester.parseResponse(input); + Assert.assertEquals(200, response.getStatus()); completes.get().await(10,TimeUnit.SECONDS); // Send a second request completes.set(new CountDownLatch(1)); output.write(request.getBytes(StandardCharsets.UTF_8)); output.flush(); - - response = parser.readResponse(reader); - Assert.assertEquals("200", response.getCode()); + + response = HttpTester.parseResponse(input); + Assert.assertEquals(200, response.getStatus()); completes.get().await(10,TimeUnit.SECONDS); } } @@ -265,11 +261,10 @@ public class AsyncContextListenersTest "\r\n"; output.write(request.getBytes(StandardCharsets.UTF_8)); output.flush(); - - BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8)); - SimpleHttpParser parser = new SimpleHttpParser(); - SimpleHttpResponse response = parser.readResponse(reader); - Assert.assertEquals("200", response.getCode()); + + HttpTester.Input input = HttpTester.from(socket.getInputStream()); + HttpTester.Response response = HttpTester.parseResponse(input); + Assert.assertEquals(200, response.getStatus()); completes.get().await(10,TimeUnit.SECONDS); // Send a second request @@ -277,8 +272,8 @@ public class AsyncContextListenersTest output.write(request.getBytes(StandardCharsets.UTF_8)); output.flush(); - response = parser.readResponse(reader); - Assert.assertEquals("200", response.getCode()); + response = HttpTester.parseResponse(input); + Assert.assertEquals(200, response.getStatus()); completes.get().await(10,TimeUnit.SECONDS); } } diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncServletLongPollTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncServletLongPollTest.java index 2ff3f4b5144..9275557dd4e 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncServletLongPollTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncServletLongPollTest.java @@ -18,9 +18,7 @@ package org.eclipse.jetty.servlet; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; import java.nio.charset.StandardCharsets; @@ -33,11 +31,10 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpTester; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.toolchain.test.TestTracker; -import org.eclipse.jetty.toolchain.test.http.SimpleHttpParser; -import org.eclipse.jetty.toolchain.test.http.SimpleHttpResponse; import org.junit.After; import org.junit.Assert; import org.junit.Rule; @@ -129,7 +126,7 @@ public class AsyncServletLongPollTest Assert.assertTrue(asyncLatch.await(5, TimeUnit.SECONDS)); - String error = "408"; + int error = 408; try (Socket socket2 = new Socket("localhost", connector.getLocalPort())) { String request2 = "DELETE " + uri + "?error=" + error + " HTTP/1.1\r\n" + @@ -139,17 +136,16 @@ public class AsyncServletLongPollTest output2.write(request2.getBytes(StandardCharsets.UTF_8)); output2.flush(); - SimpleHttpParser parser2 = new SimpleHttpParser(); - BufferedReader input2 = new BufferedReader(new InputStreamReader(socket2.getInputStream(), StandardCharsets.UTF_8)); - SimpleHttpResponse response2 = parser2.readResponse(input2); - Assert.assertEquals("200", response2.getCode()); + HttpTester.Input input2 = HttpTester.from(socket2.getInputStream()); + HttpTester.Response response2 = HttpTester.parseResponse(input2); + Assert.assertEquals(200, response2.getStatus()); } socket1.setSoTimeout(2 * wait); - SimpleHttpParser parser1 = new SimpleHttpParser(); - BufferedReader input1 = new BufferedReader(new InputStreamReader(socket1.getInputStream(), StandardCharsets.UTF_8)); - SimpleHttpResponse response1 = parser1.readResponse(input1); - Assert.assertEquals(error, response1.getCode()); + + HttpTester.Input input1 = HttpTester.from(socket1.getInputStream()); + HttpTester.Response response1 = HttpTester.parseResponse(input1); + Assert.assertEquals(error, response1.getStatus()); // Now try to make another request on the first connection // to verify that we set correctly the read interest (#409842) @@ -159,8 +155,8 @@ public class AsyncServletLongPollTest output1.write(request3.getBytes(StandardCharsets.UTF_8)); output1.flush(); - SimpleHttpResponse response3 = parser1.readResponse(input1); - Assert.assertEquals("200", response3.getCode()); + HttpTester.Response response3 = HttpTester.parseResponse(input1); + Assert.assertEquals(200, response3.getStatus()); } } } diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletRangesTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletRangesTest.java index f208f4df3ff..7dc4c9af50f 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletRangesTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletRangesTest.java @@ -67,7 +67,7 @@ public class DefaultServletRangesTest testdir.ensureEmpty(); - File resBase = testdir.getFile("docroot"); + File resBase = testdir.getPathFile("docroot").toFile(); FS.ensureDirExists(resBase); File data = new File(resBase, "data.txt"); createFile(data, DATA); diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/SSLAsyncIOServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/SSLAsyncIOServletTest.java index d72f1969e30..fb210779c4f 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/SSLAsyncIOServletTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/SSLAsyncIOServletTest.java @@ -18,9 +18,8 @@ package org.eclipse.jetty.servlet; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStreamReader; +import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.util.Arrays; @@ -35,10 +34,9 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpTester; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.toolchain.test.http.SimpleHttpParser; -import org.eclipse.jetty.toolchain.test.http.SimpleHttpResponse; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.junit.After; import org.junit.Assert; @@ -49,7 +47,7 @@ import org.junit.runners.Parameterized; @RunWith(Parameterized.class) public class SSLAsyncIOServletTest { - @Parameterized.Parameters + @Parameterized.Parameters(name = "ssl={0}") public static Collection parameters() { return Arrays.asList(new SslContextFactory[]{null}, new SslContextFactory[]{new SslContextFactory()}); @@ -159,16 +157,16 @@ public class SSLAsyncIOServletTest String request = "" + "GET " + contextPath + servletPath + " HTTP/1.1\r\n" + "Host: localhost\r\n" + + "Connection: close\r\n" + "\r\n"; OutputStream output = client.getOutputStream(); output.write(request.getBytes("UTF-8")); output.flush(); - - BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream(), "UTF-8")); - SimpleHttpParser parser = new SimpleHttpParser(); - SimpleHttpResponse response = parser.readResponse(input); - Assert.assertEquals("200", response.getCode()); - Assert.assertArrayEquals(content, response.getBody().getBytes("UTF-8")); + + InputStream inputStream = client.getInputStream(); + HttpTester.Response response = HttpTester.parseResponse(inputStream); + Assert.assertEquals(200, response.getStatus()); + Assert.assertArrayEquals(content, response.getContent().getBytes("UTF-8")); } } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipDefaultNoRecompressTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipDefaultNoRecompressTest.java index b69af6b2100..bd3edffe860 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipDefaultNoRecompressTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipDefaultNoRecompressTest.java @@ -106,7 +106,7 @@ public class GzipDefaultNoRecompressTest private void copyTestFileToServer(String testFilename) throws IOException { File testFile = MavenTestingUtils.getTestResourceFile(testFilename); - File outFile = testingdir.getFile(testFilename); + File outFile = testingdir.getPathFile(testFilename).toFile(); IO.copy(testFile,outFile); } } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipDefaultTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipDefaultTest.java index 840a531a71c..cd1250faac8 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipDefaultTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipDefaultTest.java @@ -158,7 +158,7 @@ public class GzipDefaultTest String content = tester.readResponse(response); assertThat("Response content size",content.length(),is(filesize)); - String expectedContent = IO.readToString(testingdir.getFile("file.txt")); + String expectedContent = IO.readToString(testingdir.getPathFile("file.txt").toFile()); assertThat("Response content",content,is(expectedContent)); } finally @@ -216,7 +216,7 @@ public class GzipDefaultTest String content = tester.readResponse(response); assertThat("Response content size",content.length(),is(0)); - String expectedContent = IO.readToString(testingdir.getFile("empty.txt")); + String expectedContent = IO.readToString(testingdir.getPathFile("empty.txt").toFile()); assertThat("Response content",content,is(expectedContent)); } finally @@ -737,7 +737,7 @@ public class GzipDefaultTest assertThat("ETag",response.get("ETAG"),startsWith("W/")); } - File serverFile = testingdir.getFile(filename); + File serverFile = testingdir.getPathFile(filename).toFile(); String expectedResponse = IO.readToString(serverFile); String actual = tester.readResponse(response); diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipTester.java b/jetty-servlets/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipTester.java index 943b1b9429b..f7ec3f02293 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipTester.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipTester.java @@ -276,7 +276,7 @@ public class GzipTester Assert.assertThat(response.get("ETag"),Matchers.startsWith("W/")); // Assert that the decompressed contents are what we expect. - File serverFile = testdir.getFile(serverFilename); + File serverFile = testdir.getPathFile(serverFilename).toFile(); String expected = IO.readToString(serverFile); String actual = null; @@ -538,7 +538,7 @@ public class GzipTester */ public File prepareServerFile(String filename, int filesize) throws IOException { - File dir = testdir.getDir(); + File dir = testdir.getPath().toFile(); File testFile = new File(dir,filename); // Make sure we have a uniq filename (to work around windows File.delete bug) int i = 0; @@ -573,7 +573,7 @@ public class GzipTester public void copyTestServerFile(String filename) throws IOException { File srcFile = MavenTestingUtils.getTestResourceFile(filename); - File testFile = testdir.getFile(filename); + File testFile = testdir.getPathFile(filename).toFile(); IO.copy(srcFile,testFile); } @@ -587,10 +587,11 @@ public class GzipTester */ public void setContentServlet(Class servletClass) throws IOException { + String resourceBase = testdir.getPath().toString(); tester.setContextPath("/context"); - tester.setResourceBase(testdir.getDir().getCanonicalPath()); + tester.setResourceBase(resourceBase); ServletHolder servletHolder = tester.addServlet(servletClass,"/"); - servletHolder.setInitParameter("baseDir",testdir.getDir().getAbsolutePath()); + servletHolder.setInitParameter("baseDir",resourceBase); servletHolder.setInitParameter("etags","true"); } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/server/handler/gzip/IncludedGzipTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/server/handler/gzip/IncludedGzipTest.java index 80363ac3ba7..7be81ae6e0e 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/server/handler/gzip/IncludedGzipTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/server/handler/gzip/IncludedGzipTest.java @@ -77,7 +77,7 @@ public class IncludedGzipTest { testdir.ensureEmpty(); - File testFile = testdir.getFile("file.txt"); + File testFile = testdir.getPathFile("file.txt").toFile(); try (OutputStream testOut = new BufferedOutputStream(new FileOutputStream(testFile))) { ByteArrayInputStream testIn = new ByteArrayInputStream(__content.getBytes("ISO8859_1")); @@ -85,7 +85,7 @@ public class IncludedGzipTest } tester=new ServletTester("/context"); - tester.getContext().setResourceBase(testdir.getDir().getCanonicalPath()); + tester.getContext().setResourceBase(testdir.getPath().toString()); tester.getContext().addServlet(org.eclipse.jetty.servlet.DefaultServlet.class, "/"); GzipHandler gzipHandler = new GzipHandler(); @@ -97,7 +97,6 @@ public class IncludedGzipTest public void tearDown() throws Exception { tester.stop(); - IO.delete(testdir.getDir()); } @Test diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/IncludeJettyDirTest.java b/jetty-start/src/test/java/org/eclipse/jetty/start/IncludeJettyDirTest.java index 75d38487ece..d3c8c338480 100644 --- a/jetty-start/src/test/java/org/eclipse/jetty/start/IncludeJettyDirTest.java +++ b/jetty-start/src/test/java/org/eclipse/jetty/start/IncludeJettyDirTest.java @@ -23,6 +23,7 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import java.io.File; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; @@ -69,13 +70,13 @@ public class IncludeJettyDirTest @Rule public TestingDir testdir = new TestingDir(); - private MainResult runMain(File baseDir, File homeDir, String... cmdLineArgs) throws Exception + private MainResult runMain(Path baseDir, Path homeDir, String... cmdLineArgs) throws Exception { MainResult ret = new MainResult(); ret.main = new Main(); List cmdLine = new ArrayList<>(); - cmdLine.add("jetty.home=" + homeDir.getAbsolutePath()); - cmdLine.add("jetty.base=" + baseDir.getAbsolutePath()); + cmdLine.add("jetty.home=" + homeDir.toString()); + cmdLine.add("jetty.base=" + baseDir.toString()); // cmdLine.add("--debug"); for (String arg : cmdLineArgs) { @@ -89,13 +90,12 @@ public class IncludeJettyDirTest public void testNoExtras() throws Exception { // Create home - testdir.getPathFile("home").toFile(); - File home = testdir.getPathFile("home").toFile(); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create base - File base = testdir.getPathFile("base").toFile(); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1"); @@ -115,17 +115,17 @@ public class IncludeJettyDirTest public void testCommandLine_1Extra() throws Exception { // Create home - File home = testdir.getPathFile("home").toFile(); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create common - File common = testdir.getPathFile("common").toFile(); + Path common = testdir.getPathFile("common"); FS.ensureEmpty(common); TestEnv.makeFile(common,"start.ini","jetty.http.port=8080"); // Create base - File base = testdir.getPathFile("base").toFile(); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1"); @@ -133,11 +133,11 @@ public class IncludeJettyDirTest // Simple command line reference to include-jetty-dir MainResult result = runMain(base,home, // direct reference via path - "--include-jetty-dir=" + common.getAbsolutePath()); + "--include-jetty-dir=" + common.toString()); List expectedSearchOrder = new ArrayList<>(); expectedSearchOrder.add("${jetty.base}"); - expectedSearchOrder.add(common.getAbsolutePath()); + expectedSearchOrder.add(common.toString()); expectedSearchOrder.add("${jetty.home}"); result.assertSearchOrder(expectedSearchOrder); @@ -149,17 +149,17 @@ public class IncludeJettyDirTest public void testCommandLine_1Extra_FromSimpleProp() throws Exception { // Create home - File home = testdir.getPathFile("home").toFile(); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create common - File common = testdir.getPathFile("common").toFile(); + Path common = testdir.getPathFile("common"); FS.ensureEmpty(common); TestEnv.makeFile(common,"start.ini","jetty.http.port=8080"); // Create base - File base = testdir.getPathFile("base").toFile(); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1"); @@ -167,7 +167,7 @@ public class IncludeJettyDirTest // Simple command line reference to include-jetty-dir via property (also on command line) MainResult result = runMain(base,home, // property - "my.common=" + common.getAbsolutePath(), + "my.common=" + common.toString(), // reference via property "--include-jetty-dir=${my.common}"); @@ -185,21 +185,21 @@ public class IncludeJettyDirTest public void testCommandLine_1Extra_FromPropPrefix() throws Exception { // Create home - File home = testdir.getPathFile("home").toFile(); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create opt - File opt = testdir.getPathFile("opt").toFile(); + Path opt = testdir.getPathFile("opt"); FS.ensureEmpty(opt); // Create common - File common = new File(opt,"common"); + Path common = opt.resolve("common"); FS.ensureEmpty(common); TestEnv.makeFile(common,"start.ini","jetty.http.port=8080"); // Create base - File base = testdir.getPathFile("base").toFile(); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1"); @@ -209,7 +209,7 @@ public class IncludeJettyDirTest // Simple command line reference to include-jetty-dir via property (also on command line) MainResult result = runMain(base,home, // property to 'opt' dir - "my.opt=" + opt.getAbsolutePath(), + "my.opt=" + opt.toString(), // reference via property prefix "--include-jetty-dir=" + dirRef); @@ -227,21 +227,21 @@ public class IncludeJettyDirTest public void testCommandLine_1Extra_FromCompoundProp() throws Exception { // Create home - File home = testdir.getPathFile("home").toFile(); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create opt - File opt = testdir.getPathFile("opt").toFile(); + Path opt = testdir.getPathFile("opt"); FS.ensureEmpty(opt); // Create common - File common = new File(opt,"common"); + Path common = opt.resolve("common"); FS.ensureEmpty(common); TestEnv.makeFile(common,"start.ini","jetty.http.port=8080"); // Create base - File base = testdir.getPathFile("base").toFile(); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1"); @@ -251,7 +251,7 @@ public class IncludeJettyDirTest // Simple command line reference to include-jetty-dir via property (also on command line) MainResult result = runMain(base,home, // property to 'opt' dir - "my.opt=" + opt.getAbsolutePath(), + "my.opt=" + opt.toString(), // property to commmon dir name "my.dir=common", // reference via property prefix @@ -271,27 +271,27 @@ public class IncludeJettyDirTest public void testRefCommon() throws Exception { // Create home - File home = testdir.getPathFile("home").toFile(); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create common - File common = testdir.getPathFile("common").toFile(); + Path common = testdir.getPathFile("common"); FS.ensureEmpty(common); TestEnv.makeFile(common,"start.ini","jetty.http.port=8080"); // Create base - File base = testdir.getPathFile("base").toFile(); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1",// - "--include-jetty-dir=" + common.getAbsolutePath()); + "--include-jetty-dir=" + common.toString()); MainResult result = runMain(base,home); List expectedSearchOrder = new ArrayList<>(); expectedSearchOrder.add("${jetty.base}"); - expectedSearchOrder.add(common.getAbsolutePath()); + expectedSearchOrder.add(common.toString()); expectedSearchOrder.add("${jetty.home}"); result.assertSearchOrder(expectedSearchOrder); @@ -303,33 +303,33 @@ public class IncludeJettyDirTest public void testRefCommonAndCorp() throws Exception { // Create home - File home = testdir.getPathFile("home").toFile(); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create common - File common = testdir.getPathFile("common").toFile(); + Path common = testdir.getPathFile("common"); FS.ensureEmpty(common); TestEnv.makeFile(common,"start.ini","jetty.http.port=8080"); // Create corp - File corp = testdir.getPathFile("corp").toFile(); + Path corp = testdir.getPathFile("corp"); FS.ensureEmpty(corp); // Create base - File base = testdir.getPathFile("base").toFile(); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1",// - "--include-jetty-dir=" + common.getAbsolutePath(), // - "--include-jetty-dir=" + corp.getAbsolutePath()); + "--include-jetty-dir=" + common.toString(), // + "--include-jetty-dir=" + corp.toString()); MainResult result = runMain(base,home); List expectedSearchOrder = new ArrayList<>(); expectedSearchOrder.add("${jetty.base}"); - expectedSearchOrder.add(common.getAbsolutePath()); - expectedSearchOrder.add(corp.getAbsolutePath()); + expectedSearchOrder.add(common.toString()); + expectedSearchOrder.add(corp.toString()); expectedSearchOrder.add("${jetty.home}"); result.assertSearchOrder(expectedSearchOrder); @@ -341,35 +341,35 @@ public class IncludeJettyDirTest public void testRefCommonRefCorp() throws Exception { // Create home - File home = testdir.getPathFile("home").toFile(); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create corp - File corp = testdir.getPathFile("corp").toFile(); + Path corp = testdir.getPathFile("corp"); FS.ensureEmpty(corp); TestEnv.makeFile(corp,"start.ini","jetty.http.port=9090"); // Create common - File common = testdir.getPathFile("common").toFile(); + Path common = testdir.getPathFile("common"); FS.ensureEmpty(common); TestEnv.makeFile(common,"start.ini", // - "--include-jetty-dir=" + corp.getAbsolutePath(), // + "--include-jetty-dir=" + corp.toString(), // "jetty.http.port=8080"); // Create base - File base = testdir.getPathFile("base").toFile(); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1",// - "--include-jetty-dir=" + common.getAbsolutePath()); + "--include-jetty-dir=" + common.toString()); MainResult result = runMain(base,home); List expectedSearchOrder = new ArrayList<>(); expectedSearchOrder.add("${jetty.base}"); - expectedSearchOrder.add(common.getAbsolutePath()); - expectedSearchOrder.add(corp.getAbsolutePath()); + expectedSearchOrder.add(common.toString()); + expectedSearchOrder.add(corp.toString()); expectedSearchOrder.add("${jetty.home}"); result.assertSearchOrder(expectedSearchOrder); @@ -381,30 +381,30 @@ public class IncludeJettyDirTest public void testRefCommonRefCorp_FromSimpleProps() throws Exception { // Create home - File home = testdir.getPathFile("home").toFile(); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create corp - File corp = testdir.getPathFile("corp").toFile(); + Path corp = testdir.getPathFile("corp"); FS.ensureEmpty(corp); TestEnv.makeFile(corp,"start.ini", // "jetty.http.port=9090"); // Create common - File common = testdir.getPathFile("common").toFile(); + Path common = testdir.getPathFile("common"); FS.ensureEmpty(common); TestEnv.makeFile(common,"start.ini", // - "my.corp=" + corp.getAbsolutePath(), // + "my.corp=" + corp.toString(), // "--include-jetty-dir=${my.corp}", // "jetty.http.port=8080"); // Create base - File base = testdir.getPathFile("base").toFile(); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1",// - "my.common=" + common.getAbsolutePath(), // + "my.common=" + common.toString(), // "--include-jetty-dir=${my.common}"); MainResult result = runMain(base,home); @@ -424,46 +424,46 @@ public class IncludeJettyDirTest public void testRefCommonRefCorp_CmdLineRef() throws Exception { // Create home - File home = testdir.getPathFile("home").toFile(); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create devops - File devops = testdir.getPathFile("devops").toFile(); + Path devops = testdir.getPathFile("devops"); FS.ensureEmpty(devops); TestEnv.makeFile(devops,"start.ini", // "--module=optional", // "jetty.http.port=2222"); // Create corp - File corp = testdir.getPathFile("corp").toFile(); + Path corp = testdir.getPathFile("corp"); FS.ensureEmpty(corp); TestEnv.makeFile(corp,"start.ini", // "jetty.http.port=9090"); // Create common - File common = testdir.getPathFile("common").toFile(); + Path common = testdir.getPathFile("common"); FS.ensureEmpty(common); TestEnv.makeFile(common,"start.ini", // - "--include-jetty-dir=" + corp.getAbsolutePath(), // + "--include-jetty-dir=" + corp.toString(), // "jetty.http.port=8080"); // Create base - File base = testdir.getPathFile("base").toFile(); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1",// - "--include-jetty-dir=" + common.getAbsolutePath()); + "--include-jetty-dir=" + common.toString()); MainResult result = runMain(base,home, // command line provided include-jetty-dir ref - "--include-jetty-dir=" + devops.getAbsolutePath()); + "--include-jetty-dir=" + devops.toString()); List expectedSearchOrder = new ArrayList<>(); expectedSearchOrder.add("${jetty.base}"); - expectedSearchOrder.add(devops.getAbsolutePath()); - expectedSearchOrder.add(common.getAbsolutePath()); - expectedSearchOrder.add(corp.getAbsolutePath()); + expectedSearchOrder.add(devops.toString()); + expectedSearchOrder.add(common.toString()); + expectedSearchOrder.add(corp.toString()); expectedSearchOrder.add("${jetty.home}"); result.assertSearchOrder(expectedSearchOrder); @@ -475,29 +475,29 @@ public class IncludeJettyDirTest public void testRefCommonRefCorp_CmdLineProp() throws Exception { // Create home - File home = testdir.getPathFile("home").toFile(); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create corp - File corp = testdir.getPathFile("corp").toFile(); + Path corp = testdir.getPathFile("corp"); FS.ensureEmpty(corp); TestEnv.makeFile(corp,"start.ini", // "jetty.http.port=9090"); // Create common - File common = testdir.getPathFile("common").toFile(); + Path common = testdir.getPathFile("common"); FS.ensureEmpty(common); TestEnv.makeFile(common,"start.ini", // - "--include-jetty-dir=" + corp.getAbsolutePath(), // + "--include-jetty-dir=" + corp.toString(), // "jetty.http.port=8080"); // Create base - File base = testdir.getPathFile("base").toFile(); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1",// - "--include-jetty-dir=" + common.getAbsolutePath()); + "--include-jetty-dir=" + common.toString()); MainResult result = runMain(base,home, // command line property should override all others @@ -505,8 +505,8 @@ public class IncludeJettyDirTest List expectedSearchOrder = new ArrayList<>(); expectedSearchOrder.add("${jetty.base}"); - expectedSearchOrder.add(common.getAbsolutePath()); - expectedSearchOrder.add(corp.getAbsolutePath()); + expectedSearchOrder.add(common.toString()); + expectedSearchOrder.add(corp.toString()); expectedSearchOrder.add("${jetty.home}"); result.assertSearchOrder(expectedSearchOrder); @@ -518,36 +518,36 @@ public class IncludeJettyDirTest public void testBadDoubleRef() throws Exception { // Create home - File home = testdir.getPathFile("home").toFile(); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create common - File common = testdir.getPathFile("common").toFile(); + Path common = testdir.getPathFile("common"); FS.ensureEmpty(common); // Create corp - File corp = testdir.getPathFile("corp").toFile(); + Path corp = testdir.getPathFile("corp"); FS.ensureEmpty(corp); TestEnv.makeFile(corp,"start.ini", // standard property "jetty.http.port=9090", // INTENTIONAL BAD Reference (duplicate) - "--include-jetty-dir=" + common.getAbsolutePath()); + "--include-jetty-dir=" + common.toString()); // Populate common TestEnv.makeFile(common,"start.ini", // standard property "jetty.http.port=8080", // reference to corp - "--include-jetty-dir=" + corp.getAbsolutePath()); + "--include-jetty-dir=" + corp.toString()); // Create base - File base = testdir.getPathFile("base").toFile(); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1",// - "--include-jetty-dir=" + common.getAbsolutePath()); + "--include-jetty-dir=" + common.toString()); try { diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/ModuleGraphWriterTest.java b/jetty-start/src/test/java/org/eclipse/jetty/start/ModuleGraphWriterTest.java index 3969156fbce..84f5151ffad 100644 --- a/jetty-start/src/test/java/org/eclipse/jetty/start/ModuleGraphWriterTest.java +++ b/jetty-start/src/test/java/org/eclipse/jetty/start/ModuleGraphWriterTest.java @@ -20,7 +20,6 @@ package org.eclipse.jetty.start; import static org.hamcrest.Matchers.is; -import java.io.File; import java.io.IOException; import java.nio.file.Path; @@ -43,16 +42,16 @@ public class ModuleGraphWriterTest public void testGenerate_NothingEnabled() throws IOException { // Test Env - File homeDir = MavenTestingUtils.getTestResourceDir("dist-home"); - File baseDir = testdir.getEmptyDir(); + Path homeDir = MavenTestingUtils.getTestResourcePathDir("dist-home"); + Path baseDir = testdir.getEmptyPathDir(); String cmdLine[] = new String[] {"jetty.version=TEST"}; // Configuration CommandLineConfigSource cmdLineSource = new CommandLineConfigSource(cmdLine); ConfigSources config = new ConfigSources(); config.add(cmdLineSource); - config.add(new JettyHomeConfigSource(homeDir.toPath())); - config.add(new JettyBaseConfigSource(baseDir.toPath())); + config.add(new JettyHomeConfigSource(homeDir)); + config.add(new JettyBaseConfigSource(baseDir)); // Initialize BaseHome basehome = new BaseHome(config); diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/ModuleTest.java b/jetty-start/src/test/java/org/eclipse/jetty/start/ModuleTest.java index 89565658718..12854879f98 100644 --- a/jetty-start/src/test/java/org/eclipse/jetty/start/ModuleTest.java +++ b/jetty-start/src/test/java/org/eclipse/jetty/start/ModuleTest.java @@ -24,6 +24,7 @@ import static org.hamcrest.Matchers.is; import java.io.File; import java.io.IOException; +import java.nio.file.Path; import org.eclipse.jetty.start.config.CommandLineConfigSource; import org.eclipse.jetty.start.config.ConfigSources; @@ -44,16 +45,16 @@ public class ModuleTest public void testLoadMain() throws IOException { // Test Env - File homeDir = MavenTestingUtils.getTestResourceDir("dist-home"); - File baseDir = testdir.getEmptyPathDir().toFile(); + Path homeDir = MavenTestingUtils.getTestResourcePathDir("dist-home"); + Path baseDir = testdir.getEmptyPathDir(); String cmdLine[] = new String[] {"jetty.version=TEST"}; // Configuration CommandLineConfigSource cmdLineSource = new CommandLineConfigSource(cmdLine); ConfigSources config = new ConfigSources(); config.add(cmdLineSource); - config.add(new JettyHomeConfigSource(homeDir.toPath())); - config.add(new JettyBaseConfigSource(baseDir.toPath())); + config.add(new JettyHomeConfigSource(homeDir)); + config.add(new JettyBaseConfigSource(baseDir)); // Initialize BaseHome basehome = new BaseHome(config); diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/PathFinderTest.java b/jetty-start/src/test/java/org/eclipse/jetty/start/PathFinderTest.java index 9fb58b89aad..8ce0c55e838 100644 --- a/jetty-start/src/test/java/org/eclipse/jetty/start/PathFinderTest.java +++ b/jetty-start/src/test/java/org/eclipse/jetty/start/PathFinderTest.java @@ -42,8 +42,7 @@ public class PathFinderTest { File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); Path homePath = homeDir.toPath().toAbsolutePath(); - File baseDir = testdir.getEmptyDir(); - Path basePath = baseDir.toPath().toAbsolutePath(); + Path basePath = testdir.getEmptyPathDir(); PathFinder finder = new PathFinder(); finder.setFileMatcher("glob:**/*.ini"); @@ -69,8 +68,7 @@ public class PathFinderTest { File homeDir = MavenTestingUtils.getTestResourceDir("dist-home"); Path homePath = homeDir.toPath().toAbsolutePath(); - File baseDir = testdir.getEmptyDir(); - Path basePath = baseDir.toPath().toAbsolutePath(); + Path basePath = testdir.getEmptyPathDir(); List expected = new ArrayList<>(); File modulesDir = new File(homeDir,"modules"); diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/TestEnv.java b/jetty-start/src/test/java/org/eclipse/jetty/start/TestEnv.java index 72d50974f89..9a104d3e714 100644 --- a/jetty-start/src/test/java/org/eclipse/jetty/start/TestEnv.java +++ b/jetty-start/src/test/java/org/eclipse/jetty/start/TestEnv.java @@ -18,10 +18,12 @@ package org.eclipse.jetty.start; +import java.io.BufferedWriter; import java.io.File; -import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.Path; import org.eclipse.jetty.toolchain.test.FS; import org.eclipse.jetty.toolchain.test.IO; @@ -30,18 +32,19 @@ import org.eclipse.jetty.toolchain.test.OS; public class TestEnv { - public static void copyTestDir(String testResourceDir, File destDir) throws IOException + public static void copyTestDir(String testResourceDir, Path destDir) throws IOException { FS.ensureDirExists(destDir); File srcDir = MavenTestingUtils.getTestResourceDir(testResourceDir); - IO.copyDir(srcDir,destDir); + IO.copyDir(srcDir,destDir.toFile()); } - public static void makeFile(File dir, String relFilePath, String... contents) throws IOException + public static void makeFile(Path dir, String relFilePath, String... contents) throws IOException { - File outputFile = new File(dir,OS.separators(relFilePath)); - FS.ensureDirExists(outputFile.getParentFile()); - try (FileWriter writer = new FileWriter(outputFile); PrintWriter out = new PrintWriter(writer)) + Path outputFile = dir.resolve(OS.separators(relFilePath)); + FS.ensureDirExists(outputFile.getParent()); + try (BufferedWriter writer = Files.newBufferedWriter(outputFile); + PrintWriter out = new PrintWriter(writer)) { for (String content : contents) { diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/config/ConfigSourcesTest.java b/jetty-start/src/test/java/org/eclipse/jetty/start/config/ConfigSourcesTest.java index 6ed7245eec4..28772c83653 100644 --- a/jetty-start/src/test/java/org/eclipse/jetty/start/config/ConfigSourcesTest.java +++ b/jetty-start/src/test/java/org/eclipse/jetty/start/config/ConfigSourcesTest.java @@ -55,7 +55,7 @@ public class ConfigSourcesTest ConfigurationAssert.assertOrdered("ConfigSources.id order",expectedList,actualList); } - private void assertDirOrder(ConfigSources sources, File... expectedDirOrder) + private void assertDirOrder(ConfigSources sources, Path... expectedDirOrder) throws IOException { List actualList = new ArrayList<>(); for (ConfigSource source : sources) @@ -66,9 +66,9 @@ public class ConfigSourcesTest } } List expectedList = new ArrayList<>(); - for (File path : expectedDirOrder) + for (Path path : expectedDirOrder) { - expectedList.add(path.getAbsolutePath()); + expectedList.add(path.toRealPath().toString()); } ConfigurationAssert.assertOrdered("ConfigSources.dir order",expectedList,actualList); } @@ -84,12 +84,12 @@ public class ConfigSourcesTest public void testOrder_BasicConfig() throws IOException { // Create home - File home = testdir.getFile("home"); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create base - File base = testdir.getFile("base"); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1"); @@ -98,8 +98,8 @@ public class ConfigSourcesTest String[] cmdLine = new String[0]; sources.add(new CommandLineConfigSource(cmdLine)); - sources.add(new JettyBaseConfigSource(base.toPath())); - sources.add(new JettyHomeConfigSource(home.toPath())); + sources.add(new JettyBaseConfigSource(base)); + sources.add(new JettyHomeConfigSource(home)); assertIdOrder(sources,"","${jetty.base}","${jetty.home}"); } @@ -108,17 +108,17 @@ public class ConfigSourcesTest public void testOrder_With1ExtraConfig() throws IOException { // Create home - File home = testdir.getFile("home"); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create common - Path common = testdir.getFile("common").toPath(); + Path common = testdir.getPathFile("common"); FS.ensureEmpty(common.toFile()); common = common.toRealPath(); // Create base - File base = testdir.getFile("base"); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1",// @@ -128,8 +128,8 @@ public class ConfigSourcesTest String[] cmdLine = new String[0]; sources.add(new CommandLineConfigSource(cmdLine)); - sources.add(new JettyHomeConfigSource(home.toPath().toRealPath())); - sources.add(new JettyBaseConfigSource(base.toPath().toRealPath())); + sources.add(new JettyHomeConfigSource(home.toRealPath())); + sources.add(new JettyBaseConfigSource(base.toRealPath())); assertIdOrder(sources,"","${jetty.base}",common.toString(),"${jetty.home}"); } @@ -138,17 +138,17 @@ public class ConfigSourcesTest public void testCommandLine_1Extra_FromSimpleProp() throws Exception { // Create home - File home = testdir.getFile("home"); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create common - File common = testdir.getFile("common"); + Path common = testdir.getPathFile("common"); FS.ensureEmpty(common); TestEnv.makeFile(common,"start.ini","jetty.http.port=8080"); // Create base - File base = testdir.getFile("base"); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1"); @@ -159,13 +159,13 @@ public class ConfigSourcesTest String[] cmdLine = new String[] { // property - "my.common=" + common.getAbsolutePath(), + "my.common=" + common.toString(), // reference via property "--include-jetty-dir=${my.common}" }; sources.add(new CommandLineConfigSource(cmdLine)); - sources.add(new JettyHomeConfigSource(home.toPath())); - sources.add(new JettyBaseConfigSource(base.toPath())); + sources.add(new JettyHomeConfigSource(home)); + sources.add(new JettyBaseConfigSource(base)); assertIdOrder(sources,"","${jetty.base}","${my.common}","${jetty.home}"); @@ -179,21 +179,21 @@ public class ConfigSourcesTest public void testCommandLine_1Extra_FromPropPrefix() throws Exception { // Create home - File home = testdir.getFile("home"); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create opt - File opt = testdir.getFile("opt"); + Path opt = testdir.getPathFile("opt"); FS.ensureEmpty(opt); // Create common - File common = new File(opt,"common"); + Path common = opt.resolve("common"); FS.ensureEmpty(common); TestEnv.makeFile(common,"start.ini","jetty.http.port=8080"); // Create base - File base = testdir.getFile("base"); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1"); @@ -205,13 +205,13 @@ public class ConfigSourcesTest // Simple command line reference to include-jetty-dir via property (also on command line) String[] cmdLine = new String[] { // property to 'opt' dir - "my.opt=" + opt.getAbsolutePath(), + "my.opt=" + opt.toString(), // reference via property prefix "--include-jetty-dir=" + dirRef }; sources.add(new CommandLineConfigSource(cmdLine)); - sources.add(new JettyHomeConfigSource(home.toPath())); - sources.add(new JettyBaseConfigSource(base.toPath())); + sources.add(new JettyHomeConfigSource(home)); + sources.add(new JettyBaseConfigSource(base)); assertIdOrder(sources,"","${jetty.base}",dirRef,"${jetty.home}"); @@ -225,21 +225,21 @@ public class ConfigSourcesTest public void testCommandLine_1Extra_FromCompoundProp() throws Exception { // Create home - File home = testdir.getFile("home"); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create opt - File opt = testdir.getFile("opt"); + Path opt = testdir.getPathFile("opt"); FS.ensureEmpty(opt); // Create common - File common = new File(opt,"common"); + Path common = opt.resolve("common"); FS.ensureEmpty(common); TestEnv.makeFile(common,"start.ini","jetty.http.port=8080"); // Create base - File base = testdir.getFile("base"); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1"); @@ -252,15 +252,15 @@ public class ConfigSourcesTest String[] cmdLine = new String[] { // property to 'opt' dir - "my.opt=" + opt.getAbsolutePath(), + "my.opt=" + opt.toString(), // property to commmon dir name "my.dir=common", // reference via property prefix "--include-jetty-dir=" + dirRef }; sources.add(new CommandLineConfigSource(cmdLine)); - sources.add(new JettyHomeConfigSource(home.toPath())); - sources.add(new JettyBaseConfigSource(base.toPath())); + sources.add(new JettyHomeConfigSource(home)); + sources.add(new JettyBaseConfigSource(base)); assertIdOrder(sources,"","${jetty.base}",dirRef,"${jetty.home}"); @@ -274,30 +274,30 @@ public class ConfigSourcesTest public void testRefCommon() throws Exception { // Create home - File home = testdir.getFile("home"); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create common - File common = testdir.getFile("common"); + Path common = testdir.getPathFile("common"); FS.ensureEmpty(common); TestEnv.makeFile(common,"start.ini","jetty.http.port=8080"); // Create base - File base = testdir.getFile("base"); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1",// - "--include-jetty-dir=" + common.getAbsolutePath()); + "--include-jetty-dir=" + common.toString()); ConfigSources sources = new ConfigSources(); String cmdLine[] = new String[0]; sources.add(new CommandLineConfigSource(cmdLine)); - sources.add(new JettyHomeConfigSource(home.toPath())); - sources.add(new JettyBaseConfigSource(base.toPath())); + sources.add(new JettyHomeConfigSource(home)); + sources.add(new JettyBaseConfigSource(base)); - assertIdOrder(sources,"","${jetty.base}",common.getAbsolutePath(),"${jetty.home}"); + assertIdOrder(sources,"","${jetty.base}",common.toString(),"${jetty.home}"); assertDirOrder(sources,base,common,home); @@ -309,37 +309,37 @@ public class ConfigSourcesTest public void testRefCommonAndCorp() throws Exception { // Create home - File home = testdir.getFile("home"); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create common - File common = testdir.getFile("common"); + Path common = testdir.getPathFile("common"); FS.ensureEmpty(common); TestEnv.makeFile(common,"start.ini","jetty.http.port=8080"); // Create corp - File corp = testdir.getFile("corp"); + Path corp = testdir.getPathFile("corp"); FS.ensureEmpty(corp); // Create base - File base = testdir.getFile("base"); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1",// - "--include-jetty-dir=" + common.getAbsolutePath(), // - "--include-jetty-dir=" + corp.getAbsolutePath()); + "--include-jetty-dir=" + common.toString(), // + "--include-jetty-dir=" + corp.toString()); ConfigSources sources = new ConfigSources(); String cmdLine[] = new String[0]; sources.add(new CommandLineConfigSource(cmdLine)); - sources.add(new JettyHomeConfigSource(home.toPath())); - sources.add(new JettyBaseConfigSource(base.toPath())); + sources.add(new JettyHomeConfigSource(home)); + sources.add(new JettyBaseConfigSource(base)); assertIdOrder(sources,"","${jetty.base}", - common.getAbsolutePath(), - corp.getAbsolutePath(), + common.toString(), + corp.toString(), "${jetty.home}"); assertDirOrder(sources,base,common,corp,home); @@ -352,40 +352,40 @@ public class ConfigSourcesTest public void testRefCommonRefCorp() throws Exception { // Create home - File home = testdir.getFile("home"); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create corp - File corp = testdir.getFile("corp"); + Path corp = testdir.getPathFile("corp"); FS.ensureEmpty(corp); TestEnv.makeFile(corp,"start.ini", // "jetty.http.port=9090"); // Create common - File common = testdir.getFile("common"); + Path common = testdir.getPathFile("common"); FS.ensureEmpty(common); TestEnv.makeFile(common,"start.ini", // - "--include-jetty-dir=" + corp.getAbsolutePath(), // + "--include-jetty-dir=" + corp.toString(), // "jetty.http.port=8080"); // Create base - File base = testdir.getFile("base"); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1",// - "--include-jetty-dir=" + common.getAbsolutePath()); + "--include-jetty-dir=" + common.toString()); ConfigSources sources = new ConfigSources(); String cmdLine[] = new String[0]; sources.add(new CommandLineConfigSource(cmdLine)); - sources.add(new JettyHomeConfigSource(home.toPath())); - sources.add(new JettyBaseConfigSource(base.toPath())); + sources.add(new JettyHomeConfigSource(home)); + sources.add(new JettyBaseConfigSource(base)); assertIdOrder(sources,"","${jetty.base}", - common.getAbsolutePath(), - corp.getAbsolutePath(), + common.toString(), + corp.toString(), "${jetty.home}"); assertDirOrder(sources,base,common,corp,home); @@ -398,38 +398,38 @@ public class ConfigSourcesTest public void testRefCommonRefCorp_FromSimpleProps() throws Exception { // Create home - File home = testdir.getFile("home"); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create corp - File corp = testdir.getFile("corp"); + Path corp = testdir.getPathFile("corp"); FS.ensureEmpty(corp); TestEnv.makeFile(corp,"start.ini", // "jetty.http.port=9090"); // Create common - File common = testdir.getFile("common"); + Path common = testdir.getPathFile("common"); FS.ensureEmpty(common); TestEnv.makeFile(common,"start.ini", // - "my.corp=" + corp.getAbsolutePath(), // + "my.corp=" + corp.toString(), // "--include-jetty-dir=${my.corp}", // "jetty.http.port=8080"); // Create base - File base = testdir.getFile("base"); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1",// - "my.common="+common.getAbsolutePath(), // + "my.common="+common.toString(), // "--include-jetty-dir=${my.common}"); ConfigSources sources = new ConfigSources(); String cmdLine[] = new String[0]; sources.add(new CommandLineConfigSource(cmdLine)); - sources.add(new JettyHomeConfigSource(home.toPath())); - sources.add(new JettyBaseConfigSource(base.toPath())); + sources.add(new JettyHomeConfigSource(home)); + sources.add(new JettyBaseConfigSource(base)); assertIdOrder(sources,"", "${jetty.base}", @@ -447,51 +447,51 @@ public class ConfigSourcesTest public void testRefCommonRefCorp_CmdLineRef() throws Exception { // Create home - File home = testdir.getFile("home"); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create devops - File devops = testdir.getFile("devops"); + Path devops = testdir.getPathFile("devops"); FS.ensureEmpty(devops); TestEnv.makeFile(devops,"start.ini", // "--module=logging", // "jetty.http.port=2222"); // Create corp - File corp = testdir.getFile("corp"); + Path corp = testdir.getPathFile("corp"); FS.ensureEmpty(corp); TestEnv.makeFile(corp,"start.ini", // "jetty.http.port=9090"); // Create common - File common = testdir.getFile("common"); + Path common = testdir.getPathFile("common"); FS.ensureEmpty(common); TestEnv.makeFile(common,"start.ini", // - "--include-jetty-dir=" + corp.getAbsolutePath(), // + "--include-jetty-dir=" + corp.toString(), // "jetty.http.port=8080"); // Create base - File base = testdir.getFile("base"); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1",// - "--include-jetty-dir=" + common.getAbsolutePath()); + "--include-jetty-dir=" + common.toString()); ConfigSources sources = new ConfigSources(); String cmdLine[] = new String[]{ // command line provided include-jetty-dir ref - "--include-jetty-dir=" + devops.getAbsolutePath()}; + "--include-jetty-dir=" + devops.toString()}; sources.add(new CommandLineConfigSource(cmdLine)); - sources.add(new JettyHomeConfigSource(home.toPath())); - sources.add(new JettyBaseConfigSource(base.toPath())); + sources.add(new JettyHomeConfigSource(home)); + sources.add(new JettyBaseConfigSource(base)); assertIdOrder(sources,"", "${jetty.base}", - devops.getAbsolutePath(), - common.getAbsolutePath(), - corp.getAbsolutePath(), + devops.toString(), + common.toString(), + corp.toString(), "${jetty.home}"); assertDirOrder(sources,base,devops,common,corp,home); @@ -504,29 +504,29 @@ public class ConfigSourcesTest public void testRefCommonRefCorp_CmdLineProp() throws Exception { // Create home - File home = testdir.getFile("home"); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create corp - File corp = testdir.getFile("corp"); + Path corp = testdir.getPathFile("corp"); FS.ensureEmpty(corp); TestEnv.makeFile(corp,"start.ini", // "jetty.http.port=9090"); // Create common - File common = testdir.getFile("common"); + Path common = testdir.getPathFile("common"); FS.ensureEmpty(common); TestEnv.makeFile(common,"start.ini", // - "--include-jetty-dir=" + corp.getAbsolutePath(), // + "--include-jetty-dir=" + corp.toString(), // "jetty.http.port=8080"); // Create base - File base = testdir.getFile("base"); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1",// - "--include-jetty-dir=" + common.getAbsolutePath()); + "--include-jetty-dir=" + common.toString()); ConfigSources sources = new ConfigSources(); @@ -535,12 +535,12 @@ public class ConfigSourcesTest "jetty.http.port=7070" }; sources.add(new CommandLineConfigSource(cmdLine)); - sources.add(new JettyHomeConfigSource(home.toPath())); - sources.add(new JettyBaseConfigSource(base.toPath())); + sources.add(new JettyHomeConfigSource(home)); + sources.add(new JettyBaseConfigSource(base)); assertIdOrder(sources,"","${jetty.base}", - common.getAbsolutePath(), - corp.getAbsolutePath(), + common.toString(), + corp.toString(), "${jetty.home}"); assertDirOrder(sources,base,common,corp,home); @@ -553,36 +553,36 @@ public class ConfigSourcesTest public void testBadDoubleRef() throws Exception { // Create home - File home = testdir.getFile("home"); + Path home = testdir.getPathFile("home"); FS.ensureEmpty(home); TestEnv.copyTestDir("dist-home",home); // Create common - File common = testdir.getFile("common"); + Path common = testdir.getPathFile("common"); FS.ensureEmpty(common); // Create corp - File corp = testdir.getFile("corp"); + Path corp = testdir.getPathFile("corp"); FS.ensureEmpty(corp); TestEnv.makeFile(corp,"start.ini", // standard property "jetty.http.port=9090", // INTENTIONAL BAD Reference (duplicate) - "--include-jetty-dir=" + common.getAbsolutePath()); + "--include-jetty-dir=" + common.toString()); // Populate common TestEnv.makeFile(common,"start.ini", // standard property "jetty.http.port=8080", // reference to corp - "--include-jetty-dir=" + corp.getAbsolutePath()); + "--include-jetty-dir=" + corp.toString()); // Create base - File base = testdir.getFile("base"); + Path base = testdir.getPathFile("base"); FS.ensureEmpty(base); TestEnv.makeFile(base,"start.ini", // "jetty.http.host=127.0.0.1",// - "--include-jetty-dir=" + common.getAbsolutePath()); + "--include-jetty-dir=" + common.toString()); ConfigSources sources = new ConfigSources(); @@ -590,8 +590,8 @@ public class ConfigSourcesTest { String cmdLine[] = new String[0]; sources.add(new CommandLineConfigSource(cmdLine)); - sources.add(new JettyHomeConfigSource(home.toPath())); - sources.add(new JettyBaseConfigSource(base.toPath())); + sources.add(new JettyHomeConfigSource(home)); + sources.add(new JettyBaseConfigSource(base)); Assert.fail("Should have thrown a UsageException"); } diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/fileinits/MavenLocalRepoFileInitializerTest.java b/jetty-start/src/test/java/org/eclipse/jetty/start/fileinits/MavenLocalRepoFileInitializerTest.java index c70e0b357df..cac7d146a4a 100644 --- a/jetty-start/src/test/java/org/eclipse/jetty/start/fileinits/MavenLocalRepoFileInitializerTest.java +++ b/jetty-start/src/test/java/org/eclipse/jetty/start/fileinits/MavenLocalRepoFileInitializerTest.java @@ -24,9 +24,9 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertThat; -import java.io.File; import java.io.IOException; import java.net.URI; +import java.nio.file.Path; import org.eclipse.jetty.start.BaseHome; import org.eclipse.jetty.start.config.ConfigSources; @@ -52,11 +52,11 @@ public class MavenLocalRepoFileInitializerTest @Before public void setupBaseHome() throws IOException { - File homeDir = testdir.getEmptyDir(); + Path homeDir = testdir.getEmptyPathDir(); ConfigSources config = new ConfigSources(); - config.add(new JettyHomeConfigSource(homeDir.toPath())); - config.add(new JettyBaseConfigSource(homeDir.toPath())); + config.add(new JettyHomeConfigSource(homeDir)); + config.add(new JettyBaseConfigSource(homeDir)); this.baseHome = new BaseHome(config); } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/PathWatcherTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/PathWatcherTest.java index 49cb2374576..5e05758366c 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/PathWatcherTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/PathWatcherTest.java @@ -291,7 +291,7 @@ public class PathWatcherTest @Test public void testConfig_ShouldRecurse_0() throws IOException { - Path dir = testdir.getEmptyDir().toPath(); + Path dir = testdir.getEmptyPathDir(); // Create a few directories Files.createDirectories(dir.resolve("a/b/c/d")); @@ -307,7 +307,7 @@ public class PathWatcherTest @Test public void testConfig_ShouldRecurse_1() throws IOException { - Path dir = testdir.getEmptyDir().toPath(); + Path dir = testdir.getEmptyPathDir(); // Create a few directories Files.createDirectories(dir.resolve("a/b/c/d")); @@ -323,7 +323,7 @@ public class PathWatcherTest @Test public void testConfig_ShouldRecurse_2() throws IOException { - Path dir = testdir.getEmptyDir().toPath(); + Path dir = testdir.getEmptyPathDir(); // Create a few directories Files.createDirectories(dir.resolve("a/b/c/d")); @@ -341,7 +341,7 @@ public class PathWatcherTest @Test public void testConfig_ShouldRecurse_3() throws IOException { - Path dir = testdir.getEmptyDir().toPath(); + Path dir = testdir.getEmptyPathDir(); //Create some deep dirs Files.createDirectories(dir.resolve("a/b/c/d/e/f/g")); @@ -361,7 +361,7 @@ public class PathWatcherTest @Test public void testRestart() throws Exception { - Path dir = testdir.getEmptyDir().toPath(); + Path dir = testdir.getEmptyPathDir(); Files.createDirectories(dir.resolve("b/c")); Files.createFile(dir.resolve("a.txt")); Files.createFile(dir.resolve("b.txt")); @@ -427,7 +427,7 @@ public class PathWatcherTest @Test public void testStartupFindFiles() throws Exception { - Path dir = testdir.getEmptyDir().toPath(); + Path dir = testdir.getEmptyPathDir(); // Files we are interested in Files.createFile(dir.resolve("foo.war")); @@ -479,7 +479,7 @@ public class PathWatcherTest @Test public void testGlobPattern () throws Exception { - Path dir = testdir.getEmptyDir().toPath(); + Path dir = testdir.getEmptyPathDir(); // Files we are interested in Files.createFile(dir.resolve("a.txt")); @@ -531,7 +531,7 @@ public class PathWatcherTest @Test public void testDeployFiles_Update_Delete() throws Exception { - Path dir = testdir.getEmptyDir().toPath(); + Path dir = testdir.getEmptyPathDir(); // Files we are interested in Files.createFile(dir.resolve("foo.war")); @@ -592,7 +592,7 @@ public class PathWatcherTest @Test public void testDeployFiles_NewWar() throws Exception { - Path dir = testdir.getEmptyDir().toPath(); + Path dir = testdir.getEmptyPathDir(); // Files we are interested in Files.createFile(dir.resolve("foo.war")); @@ -656,7 +656,7 @@ public class PathWatcherTest @Test public void testDeployFiles_NewWar_LargeSlowCopy() throws Exception { - Path dir = testdir.getEmptyDir().toPath(); + Path dir = testdir.getEmptyPathDir(); // Files we are interested in Files.createFile(dir.resolve("foo.war")); diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java index aea47791faf..03e52c6b5f8 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java @@ -335,7 +335,7 @@ public class FileSystemResourceTest public void testLastModified() throws Exception { Path dir = testdir.getPath().normalize().toRealPath(); - File file = testdir.getFile("foo"); + File file = testdir.getPathFile("foo").toFile(); file.createNewFile(); long expected = file.lastModified(); @@ -1398,4 +1398,4 @@ public class FileSystemResourceTest } -} \ No newline at end of file +} diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/WSServer.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/WSServer.java index a5e7f2b11fc..2dcac785e1d 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/WSServer.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/WSServer.java @@ -67,7 +67,7 @@ public class WSServer public WSServer(TestingDir testdir, String contextName) { - this(testdir.getDir(),contextName); + this(testdir.getPath().toFile(),contextName); } public WSServer(File testdir, String contextName) diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WSServer.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WSServer.java index ee406260c42..02a7fe4c52b 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WSServer.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WSServer.java @@ -70,7 +70,7 @@ public class WSServer public WSServer(TestingDir testdir, String contextName) { - this(testdir.getDir(),contextName); + this(testdir.getPath().toFile(),contextName); } public WSServer(File testdir, String contextName) diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java index 078387df897..8b7c8e4ac04 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java @@ -124,7 +124,7 @@ public class WebSocketServletRFCTest client.write(bin); // write buf3 (fin=true) // Read frame echo'd back (hopefully a single binary frame) - EventQueue frames = client.readFrames(1,1000,TimeUnit.MILLISECONDS); + EventQueue frames = client.readFrames(1,30,TimeUnit.SECONDS); Frame binmsg = frames.poll(); int expectedSize = buf1.length + buf2.length + buf3.length; Assert.assertThat("BinaryFrame.payloadLength",binmsg.getPayloadLength(),is(expectedSize)); @@ -293,7 +293,7 @@ public class WebSocketServletRFCTest client.writeRaw(bbHeader); client.writeRaw(txt.getPayload()); - EventQueue frames = client.readFrames(1,1,TimeUnit.SECONDS); + EventQueue frames = client.readFrames(1,30,TimeUnit.SECONDS); WebSocketFrame frame = frames.poll(); Assert.assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); diff --git a/pom.xml b/pom.xml index 70fac0fff54..4c33b8d397d 100644 --- a/pom.xml +++ b/pom.xml @@ -940,7 +940,7 @@ org.eclipse.jetty.toolchain jetty-test-helper - 3.1 + 4.0 org.eclipse.jetty.toolchain diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/AsyncIOServletTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/AsyncIOServletTest.java index 49ef12422cf..9454ffd1e10 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/AsyncIOServletTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/AsyncIOServletTest.java @@ -18,15 +18,21 @@ package org.eclipse.jetty.http.client; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InterruptedIOException; import java.io.UncheckedIOException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; +import java.util.Deque; import java.util.Queue; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -49,6 +55,7 @@ import org.eclipse.jetty.client.api.Result; import org.eclipse.jetty.client.http.HttpConnectionOverHTTP; import org.eclipse.jetty.client.util.BufferingResponseListener; import org.eclipse.jetty.client.util.DeferredContentProvider; +import org.eclipse.jetty.client.util.InputStreamContentProvider; import org.eclipse.jetty.client.util.StringContentProvider; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; @@ -135,7 +142,7 @@ public class AsyncIOServletTest extends AbstractTest scope.set(null); } - private void sleep(long ms) throws IOException + private void sleep(long ms) { try { @@ -143,7 +150,7 @@ public class AsyncIOServletTest extends AbstractTest } catch (InterruptedException e) { - throw new InterruptedIOException(); + throw new UncheckedIOException(new InterruptedIOException()); } } @@ -1324,5 +1331,136 @@ public class AsyncIOServletTest extends AbstractTest } - + + @Test + public void testWriteListenerFromOtherThread() throws Exception + { + start(new HttpServlet() + { + @Override + protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + AsyncContext asyncContext = request.startAsync(); + asyncContext.setTimeout(0); + request.getInputStream().setReadListener(new Listener(asyncContext)); + } + }); + + int cores = 4; + int iterations = 10; + CountDownLatch latch = new CountDownLatch(cores * iterations); + Deque failures = new LinkedBlockingDeque<>(); + for (int i = 0; i < cores; ++i) + { + client.getExecutor().execute(() -> + { + for (int j = 0; j < iterations; ++j) + { + try + { + ContentResponse response = client.newRequest(newURI()) + .method(HttpMethod.POST) + .path(servletPath) + .content(new InputStreamContentProvider(new ByteArrayInputStream(new byte[16 * 1024]) + { + @Override + public int read(byte[] b, int off, int len) + { + sleep(5); + return super.read(b, off, Math.min(len, 4242)); + } + })) + .send(); + Assert.assertEquals(HttpStatus.OK_200, response.getStatus()); + latch.countDown(); + } + catch (Throwable x) + { + failures.offer(x); + } + } + }); + } + + Assert.assertTrue(latch.await(30, TimeUnit.SECONDS)); + Assert.assertTrue(failures.isEmpty()); + } + + private class Listener implements ReadListener, WriteListener + { + private final Executor executor = Executors.newFixedThreadPool(32); + private final CompletableFuture inputComplete = new CompletableFuture<>(); + private final CompletableFuture outputComplete = new CompletableFuture<>(); + private final AtomicBoolean responseWritten = new AtomicBoolean(); + private final AsyncContext asyncContext; + private final HttpServletResponse response; + private final ServletInputStream input; + private final ServletOutputStream output; + + public Listener(AsyncContext asyncContext) throws IOException + { + this.asyncContext = asyncContext; + this.response = (HttpServletResponse)asyncContext.getResponse(); + this.input = asyncContext.getRequest().getInputStream(); + this.output = response.getOutputStream(); + CompletableFuture.allOf(inputComplete, outputComplete) + .whenComplete((ignoredResult, ignoredThrowable) -> asyncContext.complete()); + // Dispatch setting the write listener to another thread. + executor.execute(() -> output.setWriteListener(this)); + } + + @Override + public void onDataAvailable() throws IOException + { + byte[] buffer = new byte[16 * 1024]; + while (input.isReady()) + { + if (input.read(buffer) < 0) + return; + } + } + + @Override + public void onAllDataRead() throws IOException + { + inputComplete.complete(null); + } + + @Override + public void onWritePossible() throws IOException + { + // Dispatch OWP to another thread. + executor.execute(() -> + { + while (output.isReady()) + { + if (responseWritten.compareAndSet(false, true)) + { + try + { + response.setStatus(HttpServletResponse.SC_OK); + response.setContentType("text/plain;charset=utf-8"); + output.write("Hello world".getBytes()); + } + catch (IOException x) + { + throw new UncheckedIOException(x); + } + } + else + { + outputComplete.complete(null); + return; + } + } + }); + } + + @Override + public void onError(Throwable t) + { + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + asyncContext.complete(); + } + } } diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/JettyDistro.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/JettyDistro.java index 98219508d69..5dfa546f700 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/JettyDistro.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/JettyDistro.java @@ -276,7 +276,7 @@ public class JettyDistro */ public JettyDistro(TestingDir testdir) throws IOException { - this.jettyHomeDir = testdir.getDir(); + this.jettyHomeDir = testdir.getPath().toFile(); copyBaseDistro(); } @@ -292,7 +292,7 @@ public class JettyDistro */ public JettyDistro(TestingDir testdir, String artifact) throws IOException { - this.jettyHomeDir = testdir.getDir(); + this.jettyHomeDir = testdir.getPath().toFile(); if (artifact != null) { this.artifactName = artifact; diff --git a/tests/test-jmx/jmx-webapp-it/src/test/java/org/eclipse/jetty/test/jmx/JmxIT.java b/tests/test-jmx/jmx-webapp-it/src/test/java/org/eclipse/jetty/test/jmx/JmxIT.java index 67308fcb9b1..22b36d6b176 100644 --- a/tests/test-jmx/jmx-webapp-it/src/test/java/org/eclipse/jetty/test/jmx/JmxIT.java +++ b/tests/test-jmx/jmx-webapp-it/src/test/java/org/eclipse/jetty/test/jmx/JmxIT.java @@ -25,7 +25,9 @@ import static org.hamcrest.Matchers.startsWith; import static org.junit.Assert.assertThat; import java.io.File; +import java.io.InputStream; import java.lang.management.ManagementFactory; +import java.net.HttpURLConnection; import java.net.URI; import javax.management.MBeanServerConnection; @@ -34,14 +36,14 @@ import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.toolchain.test.SimpleRequest; -import org.eclipse.jetty.webapp.Configuration; -import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.jmx.ConnectorServer; import org.eclipse.jetty.jmx.MBeanContainer; import org.eclipse.jetty.server.NetworkConnector; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.webapp.Configuration; +import org.eclipse.jetty.webapp.WebAppContext; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -140,8 +142,13 @@ public class JmxIT public void testBasic() throws Exception { URI serverURI = new URI("http://localhost:"+String.valueOf(__port)+"/jmx-webapp/"); - SimpleRequest req = new SimpleRequest(serverURI); - assertThat(req.getString("ping"),startsWith("Servlet Pong at ")); + HttpURLConnection http = (HttpURLConnection) serverURI.resolve("ping").toURL().openConnection(); + assertThat("http response", http.getResponseCode(), is(200)); + try(InputStream inputStream = http.getInputStream()) + { + String resp = IO.toString(inputStream); + assertThat(resp,startsWith("Servlet Pong at ")); + } } @Test diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTestSupport.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTestSupport.java index 71809a3f39e..ddab62c3712 100644 --- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTestSupport.java +++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTestSupport.java @@ -29,6 +29,7 @@ import java.util.Set; import org.eclipse.jetty.server.session.SessionDataStore; import org.eclipse.jetty.server.session.SessionHandler; +import org.joda.time.Duration; import com.google.cloud.datastore.Datastore; import com.google.cloud.datastore.DatastoreOptions; @@ -100,10 +101,15 @@ public class GCloudSessionTestSupport public void tearDown() throws Exception { - _helper.stop(); + _helper.stop(Duration.standardMinutes(1)); //wait up to 1min for shutdown } + public void reset() throws Exception + { + _helper.reset(); + } + public Set getSessionIds () throws Exception { diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/SessionExpiryTest.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/SessionExpiryTest.java index 6796caa75b9..cc57a0badde 100644 --- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/SessionExpiryTest.java +++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/SessionExpiryTest.java @@ -22,6 +22,7 @@ package org.eclipse.jetty.gcloud.session; import org.eclipse.jetty.server.session.AbstractSessionExpiryTest; import org.eclipse.jetty.server.session.SessionDataStoreFactory; import org.junit.AfterClass; +import org.junit.After; import org.junit.Assert; import org.junit.Test; @@ -34,8 +35,8 @@ import org.junit.Test; public class SessionExpiryTest extends AbstractSessionExpiryTest { - @AfterClass - public static void teardown () throws Exception + @After + public void teardown () throws Exception { GCloudTestSuite.__testSupport.deleteSessions(); } @@ -50,25 +51,7 @@ public class SessionExpiryTest extends AbstractSessionExpiryTest return GCloudSessionTestSupport.newSessionDataStoreFactory(GCloudTestSuite.__testSupport.getDatastore()); } - @Test - @Override - public void testSessionNotExpired() throws Exception - { - super.testSessionNotExpired(); - GCloudTestSuite.__testSupport.deleteSessions(); - } - /** - * @see org.eclipse.jetty.server.session.AbstractSessionExpiryTest#testSessionExpiry() - */ - @Test - @Override - public void testSessionExpiry() throws Exception - { - super.testSessionExpiry(); - - GCloudTestSuite.__testSupport.deleteSessions(); - } @Override public void verifySessionCreated(TestHttpSessionListener listener, String sessionId) @@ -77,6 +60,9 @@ public class SessionExpiryTest extends AbstractSessionExpiryTest try {GCloudTestSuite.__testSupport.assertSessions(1);}catch(Exception e){ Assert.fail(e.getMessage());} } + + + @Override public void verifySessionDestroyed(TestHttpSessionListener listener, String sessionId) { diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReloadedSessionMissingClassTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReloadedSessionMissingClassTest.java index 64ec239e00c..af2bedf084b 100644 --- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReloadedSessionMissingClassTest.java +++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReloadedSessionMissingClassTest.java @@ -57,8 +57,7 @@ public class ReloadedSessionMissingClassTest Resource.setDefaultUseCaches(false); String contextPath = "/foo"; - File unpackedWarDir = testdir.getDir(); - testdir.ensureEmpty(); + File unpackedWarDir = testdir.getEmptyPathDir().toFile(); File webInfDir = new File (unpackedWarDir, "WEB-INF"); webInfDir.mkdir(); diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SessionExpiryTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SessionExpiryTest.java index b0d07db74da..664d6f59bc7 100644 --- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SessionExpiryTest.java +++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SessionExpiryTest.java @@ -50,9 +50,16 @@ public class SessionExpiryTest extends AbstractSessionExpiryTest super.testSessionExpiry(); } } - - - + + /** + * @see org.eclipse.jetty.server.session.AbstractSessionExpiryTest#testSessionExpiresWithListener() + */ + @Test + public void testSessionExpiresWithListener() throws Exception + { + super.testSessionExpiresWithListener(); + } + @Test diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionExpiryTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionExpiryTest.java index 04f389c6b4f..2e34fe1a455 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionExpiryTest.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionExpiryTest.java @@ -68,18 +68,97 @@ public abstract class AbstractSessionExpiryTest extends AbstractTestBase { public List createdSessions = new ArrayList(); public List destroyedSessions = new ArrayList(); + public boolean accessAttribute = false; + public Exception ex = null; + + public TestHttpSessionListener(boolean access) + { + accessAttribute = access; + } + + public TestHttpSessionListener() + { + accessAttribute = false; + } public void sessionDestroyed(HttpSessionEvent se) { destroyedSessions.add(se.getSession().getId()); + if (accessAttribute) + { + try + { + + se.getSession().getAttribute("anything"); + } + catch (Exception e) + { + ex = e; + } + } } - + public void sessionCreated(HttpSessionEvent se) { createdSessions.add(se.getSession().getId()); } }; + @Test + public void testSessionExpiresWithListener() throws Exception + { + String contextPath = ""; + String servletMapping = "/server"; + int inactivePeriod = 3; + int scavengePeriod = 1; + + DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); + cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT); + SessionDataStoreFactory storeFactory = createSessionDataStoreFactory(); + ((AbstractSessionDataStoreFactory)storeFactory).setGracePeriodSec(scavengePeriod); + + TestServer server1 = new TestServer(0, inactivePeriod, scavengePeriod, + cacheFactory, storeFactory); + TestServlet servlet = new TestServlet(); + ServletHolder holder = new ServletHolder(servlet); + ServletContextHandler context = server1.addContext(contextPath); + context.addServlet(holder, servletMapping); + TestHttpSessionListener listener = new TestHttpSessionListener(true); + + context.getSessionHandler().addEventListener(listener); + + server1.start(); + int port1 = server1.getPort(); + + try + { + HttpClient client = new HttpClient(); + client.start(); + String url = "http://localhost:" + port1 + contextPath + servletMapping; + + //make a request to set up a session on the server + ContentResponse response1 = client.GET(url + "?action=init"); + assertEquals(HttpServletResponse.SC_OK,response1.getStatus()); + String sessionCookie = response1.getHeaders().get("Set-Cookie"); + assertTrue(sessionCookie != null); + // Mangle the cookie, replacing Path with $Path, etc. + sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path="); + + String sessionId = TestServer.extractSessionId(sessionCookie); + + verifySessionCreated(listener,sessionId); + + //and wait until the session should have expired + pause(inactivePeriod+(scavengePeriod*2)); + + verifySessionDestroyed (listener, sessionId); + assertNull(listener.ex); + } + finally + { + server1.stop(); + } + } /** * Check session is preserved over stop/start