Merge branch 'jetty-9.4.x'

This commit is contained in:
Joakim Erdfelt 2016-07-08 08:40:28 -07:00
commit 2cfc5b1665
26 changed files with 427 additions and 156 deletions

View File

@ -55,20 +55,22 @@ public class SplitFileServer
// our jetty maven testing utilities to get the proper resource // our jetty maven testing utilities to get the proper resource
// directory, you needn't use these, you simply need to supply the paths // directory, you needn't use these, you simply need to supply the paths
// you are looking to serve content from. // you are looking to serve content from.
ResourceHandler rh0 = new ResourceHandler();
ContextHandler context0 = new ContextHandler(); ContextHandler context0 = new ContextHandler();
context0.setContextPath("/"); context0.setContextPath("/");
ResourceHandler rh0 = new ResourceHandler();
File dir0 = MavenTestingUtils.getTestResourceDir("dir0"); File dir0 = MavenTestingUtils.getTestResourceDir("dir0");
rh0.setBaseResource(Resource.newResource(dir0)); context0.setBaseResource(Resource.newResource(dir0));
context0.setHandler(rh0); context0.setHandler(rh0);
// Rinse and repeat the previous item, only specifying a different // Rinse and repeat the previous item, only specifying a different
// resource base. // resource base.
ResourceHandler rh1 = new ResourceHandler();
ContextHandler context1 = new ContextHandler(); ContextHandler context1 = new ContextHandler();
context1.setContextPath("/"); context1.setContextPath("/");
ResourceHandler rh1 = new ResourceHandler();
File dir1 = MavenTestingUtils.getTestResourceDir("dir1"); File dir1 = MavenTestingUtils.getTestResourceDir("dir1");
rh1.setBaseResource(Resource.newResource(dir1)); context1.setBaseResource(Resource.newResource(dir1));
context1.setHandler(rh1); context1.setHandler(rh1);
// Create a ContextHandlerCollection and set the context handlers to it. // Create a ContextHandlerCollection and set the context handlers to it.

View File

@ -32,7 +32,7 @@ This handler will serve static content and handle If-Modified-Since headers and
____ ____
[IMPORTANT] [IMPORTANT]
There is no caching done with this handler so if you are looking for a more featureful way of serving static content look to the xred:default-servlet[]. There is no caching done with this handler, so if you are looking for a more fully featured way of serving static content look to the xref:default-servlet[].
____ ____
____ ____
@ -43,7 +43,7 @@ ____
==== Improving the Look and Feel ==== Improving the Look and Feel
The resource handler has a default stylesheet which you can change by calling `setStyleSheet(String location)` with the location of a file on the system that it can locate through the resource loading system. The resource handler has a default stylesheet which you can change by calling `setStyleSheet(String location)` with the location of a file on the system that it can locate through the resource loading system.
The default css is called jetty-dir.css and is located in the jetty-util package, pulled as a classpath resource from the jetty-util jar when requested through the ResourceHandler. The default css is called `jetty-dir.css` and is located in the `jetty-util` package, pulled as a classpath resource from the `jetty-util` jar when requested through the `ResourceHandler`.
==== Embedded Example ==== Embedded Example

View File

@ -13,6 +13,7 @@
// //
// You may elect to redistribute this code under either of these licenses. // You may elect to redistribute this code under either of these licenses.
// ======================================================================== // ========================================================================
[[jetty-admin-guide]]
= Jetty Administration Guide = Jetty Administration Guide

View File

@ -23,9 +23,9 @@ If the content to be served to the aliases names is link:#different-virtual-hos
Virtual hosts are set on a link:{JDURL}/org/eclipse/jetty/server/handler/ContextHandler.html[context] by calling the link:{JDURL}/org/eclipse/jetty/server/handler/ContextHandler.html#setVirtualHosts-java.lang.String:A-[`setVirtualHosts`] or link:{JDURL}/org/eclipse/jetty/server/handler/ContextHandler.html#addVirtualHosts-java.lang.String:A-[`addVirtualHost`] method which can be done in several ways: Virtual hosts are set on a link:{JDURL}/org/eclipse/jetty/server/handler/ContextHandler.html[context] by calling the link:{JDURL}/org/eclipse/jetty/server/handler/ContextHandler.html#setVirtualHosts-java.lang.String:A-[`setVirtualHosts`] or link:{JDURL}/org/eclipse/jetty/server/handler/ContextHandler.html#addVirtualHosts-java.lang.String:A-[`addVirtualHost`] method which can be done in several ways:
* Using a link:#deployable-descriptor-file[context XML] file in the webapps directory (see the example in link:{SRCDIR}/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/webapps/test.xml[test.xml] in the Jetty distribution). * Using a link:#deployable-descriptor-file[context XML] file in the webapps directory (see the example in link:{SRCDIR}/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/webapps/test.xml[test.xml] in the Jetty distribution).
* Using a `WEB-INF/jetty-web.xml` file (deprecated).
* Creating a link:#deployment-architecture[custom deployer] with a binding to configure virtual hosts for all contexts found in the same `webapps` directory. * Creating a link:#deployment-architecture[custom deployer] with a binding to configure virtual hosts for all contexts found in the same `webapps` directory.
* Calling the link:{JDURL}/org/eclipse/jetty/server/handler/ContextHandler.html#setVirtualHosts-java.lang.String:A-[API] directly on an link:#advanced-embedding[embedded] usage. * Calling the link:{JDURL}/org/eclipse/jetty/server/handler/ContextHandler.html#setVirtualHosts-java.lang.String:A-[API] directly on an link:#advanced-embedding[embedded] usage.
* Using a `WEB-INF/jetty-web.xml` file (now deprecated).
[[configuring-a-virtual-host]] [[configuring-a-virtual-host]]
==== Virtual Host Names ==== Virtual Host Names
@ -48,7 +48,7 @@ www.√integral.com::
==== Example Virtual Host Configuration ==== Example Virtual Host Configuration
Virtual hosts can be used with any context that is a subclass of link:{JDURL}/org/eclipse/jetty/server/handler/ContextHandler.html[ContextHandler]. Virtual hosts can be used with any context that is a subclass of link:{JDURL}/org/eclipse/jetty/server/handler/ContextHandler.html[ContextHandler].
Lets look at an example where we configure a web application -represented by the link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html[WebAppContext] class - with virtual hosts. Lets look at an example where we configure a web application - represented by the link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html[WebAppContext] class - with virtual hosts.
You supply a list of IP addresses and names at which the web application is reachable, such as the following: You supply a list of IP addresses and names at which the web application is reachable, such as the following:
* `333.444.555.666` * `333.444.555.666`
@ -96,7 +96,7 @@ For example, suppose your imaginary machine has these DNS names:
Suppose also you have 2 webapps, one called `blah.war` that you would like served from the `*.blah.*` names, and one called `other.war` that you want served only from the `*.other.*` names. Suppose also you have 2 webapps, one called `blah.war` that you would like served from the `*.blah.*` names, and one called `other.war` that you want served only from the `*.other.*` names.
Using the method of preparing link:#deployable-descriptor-files[contextXML] files, one for each webapp yields the following: Using the method of preparing link:#deployable-descriptor-file[contextXML] files, one for each webapp yields the following:
For `blah` webapp: For `blah` webapp:

View File

@ -70,7 +70,7 @@ javax.servlet.error.status_code::
==== Configuring error pages context files ==== Configuring error pages context files
You can use context IoC XML files to configure the default error page mappings with more flexibility than is available with `web.xml`, specifically with the support of error code ranges. You can use context IoC XML files to configure the default error page mappings with more flexibility than is available with `web.xml`, specifically with the support of error code ranges.
Context files are normally located in `${jetty.home}/webapps/` (see `DeployerManager` for more details) and an example of more flexible error page mapping is below: Context files are normally located in `${jetty.base}/webapps/` (see `DeployerManager` for more details) and an example of more flexible error page mapping is below:
[source, xml, subs="{sub-order}"] [source, xml, subs="{sub-order}"]
---- ----
@ -80,7 +80,7 @@ Context files are normally located in `${jetty.home}/webapps/` (see `DeployerMan
<Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/test</Set> <Set name="contextPath">/test</Set>
<Set name="war"> <Set name="war">
<SystemProperty name="jetty.home" default="."/>/webapps/test <SystemProperty name="jetty.base" default="."/>/webapps/test
</Set> </Set>
<!-- by Code --> <!-- by Code -->
@ -146,7 +146,7 @@ For example:
---- ----
An `ErrorHandler` instance may be set on the entire server by setting it as a dependent bean on the Server instance. An `ErrorHandler` instance may be set on the entire server by setting it as a dependent bean on the Server instance.
This can be done by calling `Server.addBean(Object)` via embedded code or in `jetty.xml` IoC XML like: This can be done by calling `Server.addBean(Object)` via embedded code or in `jetty.xml` IoC XML:
[source, xml, subs="{sub-order}"] [source, xml, subs="{sub-order}"]
---- ----

View File

@ -25,15 +25,27 @@ However, if contexts need to share resources (eg data sources, authentication),
==== Creating Multiple Server Instances ==== Creating Multiple Server Instances
Creating multiple server instances is a straight forward process that includes embedding Jetty code by creating multiples instances of the Server class and configuring them as needed. Creating multiple server instances is a straight forward process that includes embedding Jetty code by creating multiples instances of the Server class and configuring them as needed.
This is also easy to achieve if you are configuring your servers in XML. This is also easy to achieve if you are configuring Jetty servers via XML.
The `id` field in the Configure element of `jetty.xml` files is used to identify the instance that the configuration applies to, so to run two instances of the Server, you can copy the `jetty.xml`, jetty-http.xml and other jetty configuration files used and change the "Server" id to a new name. The `id` field in the Configure element of `jetty.xml` files is used to identify the instance that the configuration applies to, so to run two instances of the Server, you can copy the `jetty.xml`, jetty-http.xml and other jetty configuration files used and change the "Server" id to a new name.
This can be done in the same style and layout as the existing `jetty.xml` files or the multiple XML files may be combined to a single file. This can be done in the same style and layout as the existing `jetty.xml` files or the multiple XML files may be combined to a single file.
When creating new configurations for alternative server: When creating new configurations for alternative server:
* Change all `id="Server"` to the new server name: `<Configure id="OtherServer" class="org.eclipse.jetty.server.Server">` * Change all `id="Server"` to the new server name:
* For all connectors for the new server change the `refid` in the server argument: `<Arg name="server"><Ref refid="OtherServer" /></Arg>`
* Make sure that any references to properties like `jetty.http.port` are either renamed or replaced with absolute values [source, xml, subs="{sub-order}"]
----
<Configure id="OtherServer" class="org.eclipse.jetty.server.Server">
----
* For all connectors for the new server change the `refid` in the server argument:
[source, xml, subs="{sub-order}"]
----
<Arg name="server"><Ref refid="OtherServer" /></Arg>
----
* Make sure that any references to properties like `jetty.http.port` are either renamed or replaced with absolute values.
* Make sure that any deployers `AppProviders` refer to a different "webapps" directory so that a different set of applications are deployed. * Make sure that any deployers `AppProviders` refer to a different "webapps" directory so that a different set of applications are deployed.
[[jetty-otherserver.xml]] [[jetty-otherserver.xml]]

View File

@ -57,4 +57,4 @@ Set an attribute on the Server instance for which you want to modify the maximum
==== For All Apps in the JVM ==== For All Apps in the JVM
Use the system property `org.eclipse.jetty.server.Request.maxFormContentSize`. Use the system property `org.eclipse.jetty.server.Request.maxFormContentSize`.
This can be set on the command line or in the `start.ini` file. This can be set on the command line or in the `start.ini` or `start.d\server.ini` file.

View File

@ -77,8 +77,8 @@ context.setAttribute("org.eclipse.jetty.webapp.basetempdir", "/tmp/foo");
There are several ways to use a particular directory as the temporary directory: There are several ways to use a particular directory as the temporary directory:
*Call WebAppContext.setTempDirectory(String dir)* ====== Call WebAppContext.setTempDirectory(String dir)
Like before this can be accomplished with an xml file or directly in code. Here's an example of setting the temp directory in xml: As before this can be accomplished with an xml file or directly in code. Here's an example of setting the temp directory in xml:
[source, xml, subs="{sub-order}"] [source, xml, subs="{sub-order}"]
---- ----
@ -101,7 +101,7 @@ context.setWar("foo.war");
context.setTempDirectory(new File("/some/dir/foo")); context.setTempDirectory(new File("/some/dir/foo"));
---- ----
*Set the `javax.servlet.context.tempdir` context attribute* ====== Set the javax.servlet.context.tempdir context attribute
You should set this context attribute with the name of directory you want to use as the temp directory. Again, you can do this in xml: You should set this context attribute with the name of directory you want to use as the temp directory. Again, you can do this in xml:
[source, xml, subs="{sub-order}"] [source, xml, subs="{sub-order}"]
@ -129,27 +129,27 @@ context.setWar("foo.war");
context.setAttribute("javax.servlet.context.tempdir", "/some/dir/foo"); context.setAttribute("javax.servlet.context.tempdir", "/some/dir/foo");
---- ----
Once a temporary directory has been created by either of these methods, a File instance for it is set as the value of the `javax.servlet.context.tempdir` attribute of the web application. Once a temporary directory has been created by either of these methods, a file instance for it is set as the value of the `javax.servlet.context.tempdir` attribute of the web application.
____ ____
[NOTE] [NOTE]
Be wary of setting an explicit temp directory if you are likely to change the jars in WEB-INF/lib between redeployments. Be wary of setting an explicit temp directory if you are likely to change the jars in WEB-INF/lib between redeployments.
There is a JVM bug concerning caching of jar contents: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4774421 There is a JVM bug concerning link:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4774421[caching of jar contents.]
____ ____
==== The "work" directory ==== The "work" directory
Mostly for backward compatibility, from jetty-9.1.1 onwards, it is be possible to create a directory named "work" in the `$\{jetty.base}` directory. Mostly for backward compatibility, from Jetty 9.1.1 onwards, it is possible to create a directory named "work" in the `$\{jetty.base}` directory.
If such a directory is found, it is assumed you want to use it as the parent directory for all of the temporary directories of the webapps in that `$\{jetty.base}`. If such a directory is found, it is assumed you want to use it as the parent directory for all of the temporary directories of the webapps in `$\{jetty.base}`.
Moreover, as has historically been the case, these temp directories inside the work directory are not cleaned up when jetty exists (or more correctly speaking, the `temp` directory corresponding to a context is not cleaned up when that context stops). Moreover, as has historically been the case, these temp directories inside the work directory are not cleaned up when Jetty exits (or more correctly speaking, the `temp` directory corresponding to a context is not cleaned up when that context stops).
When a work directory is used, the algorithm for generating the name of the context-specific temp directories omits the random digit string. When a work directory is used, the algorithm for generating the name of the context-specific temp directories omits the random digit string.
This ensures the name of the directory remains consistent across context restarts. This ensures the name of the directory remains consistent across context restarts.
==== Persisting the temp directory ==== Persisting the temp directory
Sometimes you may find it useful to keep the contents of the temporary directory between restarts of the web application. Sometimes it is useful to keep the contents of the temporary directory between restarts of the web application.
By default, Jetty will _not_ persist the temp directory. By default, Jetty will *not* persist the temp directory.
To configure Jetty to keep it, use link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html[WebAppContext.setPersistTempDirectory(true)]. To configure Jetty to keep it, use link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html[WebAppContext.setPersistTempDirectory(true)].
____ ____

View File

@ -17,7 +17,7 @@
[[automatic-webapp-deployment]] [[automatic-webapp-deployment]]
=== Automatic Web Application Deployment === Automatic Web Application Deployment
The most basic technique for deploying Web Applications is to put a WAR file or Exploded WAR directory into the `${jetty.home}/webapps/` directory and let Jetty's deployment scanner find it and deploy it under a Context path of the same name. The most basic technique for deploying Web Applications is to put a WAR file or Exploded WAR directory into the `${jetty.base}/webapps/` directory and let Jetty's deployment scanner find it and deploy it under a Context path of the same name.
Only Web Applications that follow the Web Application Layout will be detected by Jetty and deployed this way. Only Web Applications that follow the Web Application Layout will be detected by Jetty and deployed this way.
@ -34,7 +34,7 @@ The Context Path assigned to this automatic deployment is based the filename (or
|`/webapps/belaying-pins/WEB-INF/web.xml` |http://host/belaying-pins/ |`/webapps/belaying-pins/WEB-INF/web.xml` |http://host/belaying-pins/
|`/webapps/root.war` _(special name)_ |http://host/ |`/webapps/root.war` _(reserved name)_ |http://host/
|`/webapps/root/WEB-INF/web.xml` _(special name)_ |http://host/ |`/webapps/root/WEB-INF/web.xml` _(reserved name)_ |http://host/
|======================================================================= |=======================================================================

View File

@ -130,7 +130,7 @@ This feature is useful when adding parameters or additional Servlet mappings wit
</Configure> </Configure>
---- ----
The next example configures not only the web application context, but also a database connection pool (see xref:jndi-datasource-examples[] that the application can then use. The next example configures not only the web application context, but also a database connection pool (see xref:jndi-datasource-examples[]) that the application can then use.
If the `web.xml` does not include a reference to this data source, an override descriptor mechanism (as shown in the previous example) can be used to include it. If the `web.xml` does not include a reference to this data source, an override descriptor mechanism (as shown in the previous example) can be used to include it.
[source, xml, subs="{sub-order}"] [source, xml, subs="{sub-order}"]

View File

@ -20,8 +20,8 @@
Jetty is built around an extensible Deployment Manager architecture complete with formal LifeCycle for Web Applications going through it. Jetty is built around an extensible Deployment Manager architecture complete with formal LifeCycle for Web Applications going through it.
For Jetty to serve content (static or dynamic), a link:{JDURL}/org/eclipse/jetty/server/handler/ContextHandler.html[ContextHandler] needs to be configured and added to Jetty in the appropriate location. For Jetty to serve content (static or dynamic), a link:{JDURL}/org/eclipse/jetty/server/handler/ContextHandler.html[ContextHandler] needs to be configured and added to Jetty in the appropriate location.
A pluggable `DeploymentManager` exists in Jetty 7 and later to make this process easier. A pluggable `DeploymentManager` exists to make this process easier.
The Jetty distribution contains example `DeploymentManager` configurations to deploy WAR files found in a directory to Jetty, and to deploy Jetty `context.xml` files into Jetty as well. The Jetty distribution contains example `DeploymentManager` configurations to deploy WAR files found in a directory to Jetty, and to deploy Jetty context xml files into Jetty as well.
The `DeploymentManager` is the heart of the typical webapp deployment mechanism; it operates as a combination of an Application LifeCycle Graph, Application Providers that find and provide Applications into the Application LifeCycle Graph, and a set of bindings in the graph that control the deployment process. The `DeploymentManager` is the heart of the typical webapp deployment mechanism; it operates as a combination of an Application LifeCycle Graph, Application Providers that find and provide Applications into the Application LifeCycle Graph, and a set of bindings in the graph that control the deployment process.
@ -115,9 +115,9 @@ contexts::
monitoredDirName:: monitoredDirName::
The file path or URL to the directory to scan for web applications. The file path or URL to the directory to scan for web applications.
+
Scanning follows these rules: Scanning follows these rules:
+
1. A base directory must exist. 1. A base directory must exist.
2. Hidden Files (starting with `"."`) are ignored. 2. Hidden Files (starting with `"."`) are ignored.
3. Directories with names ending in `".d"` are ignored. 3. Directories with names ending in `".d"` are ignored.

View File

@ -137,7 +137,7 @@ Let's see an example of how we would add in the Configurations for both JNDI _an
<Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/my-cool-webapp</Set> <Set name="war"><SystemProperty name="jetty.base" default="."/>/webapps/my-cool-webapp</Set>
<Set name="configurationClasses"> <Set name="configurationClasses">
<Array type="java.lang.String"> <Array type="java.lang.String">
@ -178,7 +178,7 @@ They will then be applied to each `WebAppContext` deployed by the deployer:
<Call id="webappprovider" name="addAppProvider"> <Call id="webappprovider" name="addAppProvider">
<Arg> <Arg>
<New class="org.eclipse.jetty.deploy.providers.WebAppProvider"> <New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
<Set name="monitoredDirName"><Property name="jetty.home" default="." />/webapps</Set> <Set name="monitoredDirName"><Property name="jetty.base" default="." />/webapps</Set>
<Set name="configurationClasses"> <Set name="configurationClasses">
<Array type="java.lang.String"> <Array type="java.lang.String">
<Item>org.eclipse.jetty.webapp.WebInfConfiguration</Item> <Item>org.eclipse.jetty.webapp.WebInfConfiguration</Item>

View File

@ -35,7 +35,8 @@ The default location for this configuration is in the `${jetty.home}/etc/jetty-d
[source, xml, subs="{sub-order}"] [source, xml, subs="{sub-order}"]
---- ----
<?xml version="1.0"?> <?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd"> <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server"> <Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call name="addBean"> <Call name="addBean">
@ -46,16 +47,16 @@ The default location for this configuration is in the `${jetty.home}/etc/jetty-d
</Set> </Set>
<Call name="setContextAttribute"> <Call name="setContextAttribute">
<Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg> <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
<Arg>.*/servlet-api-[^/]*\.jar$</Arg> <Arg>.*/[^/]*servlet-api-[^/]*\.jar$|.*/javax.servlet.jsp.jstl-.*\.jar$|.*/org.apache.taglibs.taglibs-standard-impl-.*\.jar$</Arg>
</Call> </Call>
<Call id="webappprovider" name="addAppProvider"> <Call id="webappprovider" name="addAppProvider">
<Arg> <Arg>
<New class="org.eclipse.jetty.deploy.providers.WebAppProvider"> <New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
<Set name="monitoredDirName"><Property name="jetty.home" default="." />/webapps</Set> <Set name="monitoredDirName"><Property name="jetty.base" default="." />/<Property name="jetty.deploy.monitoredDir" deprecated="jetty.deploy.monitoredDirName" default="webapps"/></Set>
<Set name="defaultsDescriptor"><Property name="jetty.home" default="." />/etc/webdefault.xml</Set> <Set name="defaultsDescriptor"><Property name="jetty.home" default="." />/etc/webdefault.xml</Set>
<Set name="scanInterval">1</Set> <Set name="scanInterval"><Property name="jetty.deploy.scanInterval" default="1"/></Set>
<Set name="extractWars">true</Set> <Set name="extractWars"><Property name="jetty.deploy.extractWars" default="true"/></Set>
</New> </New>
</Arg> </Arg>
</Call> </Call>

View File

@ -19,7 +19,7 @@
____ ____
[NOTE] [NOTE]
This feature is reintroduced in Jetty 9.0.4 This feature was reintroduced in Jetty 9.0.4
____ ____
The Jetty Overlay Deployer allows multiple WAR files to be overlaid so that a web application can be customized, configured, and deployed without unpacking, modifying and repacking the WAR file. The Jetty Overlay Deployer allows multiple WAR files to be overlaid so that a web application can be customized, configured, and deployed without unpacking, modifying and repacking the WAR file.
@ -50,7 +50,7 @@ If either the container or the base WAR file is upgraded to a new version, it ca
[[overlay-overlays]] [[overlay-overlays]]
==== Overlays ==== Overlays
To solve the problems highlighted above, Jetty 7.4 introduces WAR overlays (a concept borrowed from the Maven WAR plugin). To solve the problems highlighted above, Jetty introduced WAR overlays (a concept borrowed from the Maven WAR plugin).
An overlay is basically just another WAR file, whose contents merge on top of the original WAR so that filed can be added or replaced. An overlay is basically just another WAR file, whose contents merge on top of the original WAR so that filed can be added or replaced.
Jetty overlays also allow fragments of `web.xml` to be mixed in, which means the configuration can be modified without replacing it. Jetty overlays also allow fragments of `web.xml` to be mixed in, which means the configuration can be modified without replacing it.
@ -59,12 +59,12 @@ Jetty overlays also allow fragments of `web.xml` to be mixed in, which means the
The JTrac issue tracking web application is a good example of a typical web application, as it uses the usual suspects of libs: spring, hibernate, dom4j, commons-*, wicket, etc. The JTrac issue tracking web application is a good example of a typical web application, as it uses the usual suspects of libs: spring, hibernate, dom4j, commons-*, wicket, etc.
The files for this demonstration are available in overlays-demo.tar.gz. The files for this demonstration are available in overlays-demo.tar.gz.
The demonstation can be expanded on top of the jetty distribution; this tutorial expands it to /tmp and installs the components step-by-step: The demonstration can be expanded on top of the Jetty distribution; this tutorial expands it to /tmp and installs the components step-by-step:
[source, screen, subs="{sub-order}"] [source, screen, subs="{sub-order}"]
---- ----
$ cd /tmp $ cd /tmp
$ wget http://webtide.intalio.com/wp-content/uploads/2011/05/overlays-demo.tar.gz $ wget http://webtide.com/wp-content/uploads/2011/05/overlays-demo.tar.gz
$ tar xfvz overlays-demo.tar.gz $ tar xfvz overlays-demo.tar.gz
$ export OVERLAYS=/tmp/overlays $ export OVERLAYS=/tmp/overlays
---- ----
@ -96,7 +96,7 @@ Jetty is now listening on port 8080, but with no webapp deployed.
____ ____
[IMPORTANT] [IMPORTANT]
You should conduct the rest of the tutorial in another window with the JETTY_HOME environment set to the jetty distribution directory. You should conduct the rest of the tutorial in another window with the JETTY_HOME environmental variable set to the Jetty distribution directory.
____ ____
[[overlay-install]] [[overlay-install]]

View File

@ -18,7 +18,7 @@
=== Configuring Static Content Deployment === Configuring Static Content Deployment
To serve purely static content, the Jetty Deployment Descriptor XML concepts and the internal `ResourceHandler` can be used. To serve purely static content, the Jetty Deployment Descriptor XML concepts and the internal `ResourceHandler` can be used.
Create a file called `scratch.xml` in the `${jetty.home}/webapps` directory and paste the following file contents in it. Create a file called `scratch.xml` in the `${jetty.base}/webapps` directory and paste the following file contents in it.
[source, xml, subs="{sub-order}"] [source, xml, subs="{sub-order}"]
---- ----

View File

@ -13,6 +13,7 @@
// //
// You may elect to redistribute this code under either of these licenses. // You may elect to redistribute this code under either of these licenses.
// ======================================================================== // ========================================================================
[[jetty-config-guide]]
= Jetty Configuration Guide = Jetty Configuration Guide

View File

@ -13,6 +13,7 @@
// //
// You may elect to redistribute this code under either of these licenses. // You may elect to redistribute this code under either of these licenses.
// ======================================================================== // ========================================================================
[[jetty-dev-guide]]
= Jetty Development Guide = Jetty Development Guide

View File

@ -19,10 +19,27 @@
Jetty is an open-source project providing an HTTP server, HTTP client, and javax.servlet container. Jetty is an open-source project providing an HTTP server, HTTP client, and javax.servlet container.
This guide is in two parts. This guide is broken up in to five parts:
* The first part emphasizes beginning to use Jetty. It provides information about downloading Jetty, changing things like the port Jetty runs on, adjusting logging levels, and configuring many of the most common servlet container features such as JNDI, JMX, and session management. * The link:#quick-start[first section] emphasizes beginning to use Jetty.
* The second part describes advanced uses of Jetty, providing in depth coverage of specific features like our highly scalable async client, proxy servlet configuration, the Jetty Maven plugin, and using Jetty as an embedded server. The advanced section includes tutorials, howtos, videos, and reference materials. It provides information about what Jetty is and where you can download it, and where to find Jetty in repositories like Central Maven.
It also provides a Quick Start guide on how to get Jetty up and running as well as an overview of how and what to configure in Jetty.
* The link:#jetty-config-guide[second section] of the guide deals with configuring Jetty at a more granular level.
It explains how to use Jetty to deploy web applications, configure contexts and connects, and how to implement SSL and other security measures.
* Administration of Jetty is the focus of the link:#jetty-admin-guide[third section] of the guide.
From server startup to session management, logging, HTTP/2 support and Jetty optimization, these chapters will help administrators get the most out of their Jetty server instances.
This section also covers configuring many of the most common servlet container features such as JNDI and JMX.
* Aimed at advanced users of Jetty, the link:#jetty-dev-guide[fourth section] of the guide focuses on Jetty development.
A large portion of this section is focused on using Jetty as an embedded server in existing applications.
It contains several examples and how-to guides for making the most out of the Jetty framework.
This section also includes a guide on using the Jetty Maven plugin as well as information on debugging Jetty.
* The link:#jetty-ref-guide[final section] of the guide is a reference section.
Included there are guides on Jetty architecture and Jetty XML syntax, alternate distributions of Jetty and even troubleshooting of common issues.
There is also a chapter on getting involved in the Jetty community including information on how to contribute code and how to find help.
Feedback is always welcome! Feedback is always welcome!
Additionally, if you are interested in how to contribute to the open source project there is a link:#community[section on that as well!] Additionally, if you are interested in how to contribute to the open source project there is a link:#community[section on that as well!]

View File

@ -13,6 +13,7 @@
// //
// You may elect to redistribute this code under either of these licenses. // You may elect to redistribute this code under either of these licenses.
// ======================================================================== // ========================================================================
[[quick-start]]
= Getting Started With Jetty = Getting Started With Jetty

View File

@ -13,6 +13,7 @@
// //
// You may elect to redistribute this code under either of these licenses. // You may elect to redistribute this code under either of these licenses.
// ======================================================================== // ========================================================================
[[jetty-ref-guide]]
= Jetty Reference Guide = Jetty Reference Guide

View File

@ -339,9 +339,10 @@ public class ByteArrayEndPoint extends AbstractEndPoint
try(Locker.Lock lock = _locker.lock()) try(Locker.Lock lock = _locker.lock())
{ {
if (BufferUtil.isEmpty(_out) && isOpen() && !isOutputShutdown()) while (BufferUtil.isEmpty(_out) && !isOutputShutdown())
{
_hasOutput.await(time,unit); _hasOutput.await(time,unit);
}
b=_out; b=_out;
_out=BufferUtil.allocate(b.capacity()); _out=BufferUtil.allocate(b.capacity());
} }
@ -531,5 +532,20 @@ public class ByteArrayEndPoint extends AbstractEndPoint
_growOutput=growOutput; _growOutput=growOutput;
} }
/* ------------------------------------------------------------ */
@Override
public String toString()
{
int q;
ByteBuffer b;
String o;
try(Locker.Lock lock = _locker.lock())
{
q=_inQ.size();
b=_inQ.peek();
o=BufferUtil.toDetailString(_out);
}
return String.format("%s[q=%d,q[0]=%s,o=%s]",super.toString(),q,b,o);
}
} }

View File

@ -668,11 +668,24 @@ public class HttpInput extends ServletInputStream implements Runnable
@Override @Override
public String toString() public String toString()
{ {
return String.format("%s@%x[c=%d,s=%s]", State state;
long consumed;
int q;
Content content;
synchronized (_inputQ)
{
state=_state;
consumed=_contentConsumed;
q=_inputQ.size();
content=_inputQ.peekFirst();
}
return String.format("%s@%x[c=%d,q=%d,[0]=%s,s=%s]",
getClass().getSimpleName(), getClass().getSimpleName(),
hashCode(), hashCode(),
_contentConsumed, consumed,
_state); q,
content,
state);
} }
public static class PoisonPillContent extends Content public static class PoisonPillContent extends Content

View File

@ -96,6 +96,7 @@ public class LocalConnector extends AbstractConnector
* @throws Exception if the requests fail * @throws Exception if the requests fail
* @deprecated Use {@link #getResponse(String)} * @deprecated Use {@link #getResponse(String)}
*/ */
@Deprecated
public String getResponses(String requests) throws Exception public String getResponses(String requests) throws Exception
{ {
return getResponses(requests, 5, TimeUnit.SECONDS); return getResponses(requests, 5, TimeUnit.SECONDS);
@ -115,6 +116,7 @@ public class LocalConnector extends AbstractConnector
* @throws Exception if the requests fail * @throws Exception if the requests fail
* @deprecated Use {@link #getResponse(String, boolean, long, TimeUnit)} * @deprecated Use {@link #getResponse(String, boolean, long, TimeUnit)}
*/ */
@Deprecated
public String getResponses(String requests,long idleFor,TimeUnit units) throws Exception public String getResponses(String requests,long idleFor,TimeUnit units) throws Exception
{ {
ByteBuffer result = getResponses(BufferUtil.toBuffer(requests,StandardCharsets.UTF_8),idleFor,units); ByteBuffer result = getResponses(BufferUtil.toBuffer(requests,StandardCharsets.UTF_8),idleFor,units);
@ -133,6 +135,7 @@ public class LocalConnector extends AbstractConnector
* @throws Exception if the requests fail * @throws Exception if the requests fail
* @deprecated Use {@link #getResponse(ByteBuffer)} * @deprecated Use {@link #getResponse(ByteBuffer)}
*/ */
@Deprecated
public ByteBuffer getResponses(ByteBuffer requestsBuffer) throws Exception public ByteBuffer getResponses(ByteBuffer requestsBuffer) throws Exception
{ {
return getResponses(requestsBuffer, 5, TimeUnit.SECONDS); return getResponses(requestsBuffer, 5, TimeUnit.SECONDS);
@ -151,6 +154,7 @@ public class LocalConnector extends AbstractConnector
* @throws Exception if the requests fail * @throws Exception if the requests fail
* @deprecated Use {@link #getResponse(ByteBuffer, boolean, long, TimeUnit)} * @deprecated Use {@link #getResponse(ByteBuffer, boolean, long, TimeUnit)}
*/ */
@Deprecated
public ByteBuffer getResponses(ByteBuffer requestsBuffer,long idleFor,TimeUnit units) throws Exception public ByteBuffer getResponses(ByteBuffer requestsBuffer,long idleFor,TimeUnit units) throws Exception
{ {
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
@ -186,6 +190,13 @@ public class LocalConnector extends AbstractConnector
return endp; return endp;
} }
public LocalEndPoint connect()
{
LocalEndPoint endp = new LocalEndPoint();
_connects.add(endp);
return endp;
}
@Override @Override
protected void accept(int acceptorID) throws IOException, InterruptedException protected void accept(int acceptorID) throws IOException, InterruptedException
{ {

View File

@ -71,6 +71,16 @@ public class DumpHandler extends AbstractHandler
if (!isStarted()) if (!isStarted())
return; return;
if (Boolean.valueOf(request.getParameter("flush")))
response.flushBuffer();
if (Boolean.valueOf(request.getParameter("empty")))
{
baseRequest.setHandled(true);
response.setStatus(200);
return;
}
StringBuilder read = null; StringBuilder read = null;
if (request.getParameter("read")!=null) if (request.getParameter("read")!=null)
{ {
@ -214,6 +224,7 @@ public class DumpHandler extends AbstractHandler
} }
catch(IOException e) catch(IOException e)
{ {
e.printStackTrace();
writer.write(e.toString()); writer.write(e.toString());
} }
} }

View File

@ -63,6 +63,11 @@ public class LocalAsyncContextTest
_server.setHandler(session); _server.setHandler(session);
_server.start(); _server.start();
reset();
}
public void reset()
{
_completed0.set(null); _completed0.set(null);
_completed1.set(null); _completed1.set(null);
} }
@ -183,7 +188,6 @@ public class LocalAsyncContextTest
check(response, "COMPLETED"); check(response, "COMPLETED");
_handler.setRead(6); _handler.setRead(6);
_handler.setResumeAfter(0); _handler.setResumeAfter(0);
_handler.setCompleteAfter(-1); _handler.setCompleteAfter(-1);
response = process("wibble"); response = process("wibble");
@ -192,6 +196,7 @@ public class LocalAsyncContextTest
_handler.setResumeAfter(100); _handler.setResumeAfter(100);
_handler.setCompleteAfter(-1); _handler.setCompleteAfter(-1);
response = process("wibble"); response = process("wibble");
check(response, "DISPATCHED"); check(response, "DISPATCHED");
_handler.setResumeAfter(-1); _handler.setResumeAfter(-1);
@ -203,6 +208,7 @@ public class LocalAsyncContextTest
_handler.setCompleteAfter(100); _handler.setCompleteAfter(100);
response = process("wibble"); response = process("wibble");
check(response, "COMPLETED"); check(response, "COMPLETED");
} }
@Test @Test
@ -238,6 +244,7 @@ public class LocalAsyncContextTest
private synchronized String process(String content) throws Exception private synchronized String process(String content) throws Exception
{ {
reset();
String request = "GET / HTTP/1.1\r\n" + String request = "GET / HTTP/1.1\r\n" +
"Host: localhost\r\n" + "Host: localhost\r\n" +
"Connection: close\r\n"; "Connection: close\r\n";

View File

@ -19,6 +19,8 @@
package org.eclipse.jetty.server; package org.eclipse.jetty.server;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
@ -27,6 +29,7 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.server.LocalConnector.LocalEndPoint;
import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.BufferUtil;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@ -105,23 +108,196 @@ public class LocalConnectorTest
@Test @Test
public void testOneResponse_10_keep_alive() throws Exception public void testOneResponse_10_keep_alive() throws Exception
{ {
String response=_connector.getResponse("GET /R1 HTTP/1.0\r\n" + String response=_connector.getResponse(
"GET /R1 HTTP/1.0\r\n" +
"Connection: keep-alive\r\n" + "Connection: keep-alive\r\n" +
"\r\n"); "\r\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R1")); assertThat(response,containsString("pathInfo=/R1"));
} }
@Test
public void testOneResponse_10_keep_alive_empty() throws Exception
{
String response=_connector.getResponse(
"GET /R1?empty=true HTTP/1.0\r\n" +
"Connection: keep-alive\r\n" +
"\r\n");
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,not(containsString("pathInfo=/R1")));
}
@Test @Test
public void testOneResponse_11() throws Exception public void testOneResponse_11() throws Exception
{ {
String response=_connector.getResponse("GET /R1 HTTP/1.1\r\n" + String response=_connector.getResponse(
"GET /R1 HTTP/1.1\r\n" +
"Host: localhost\r\n" + "Host: localhost\r\n" +
"\r\n"); "\r\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R1")); assertThat(response,containsString("pathInfo=/R1"));
} }
@Test
public void testOneResponse_11_close() throws Exception
{
String response=_connector.getResponse(
"GET /R1 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Connection: close\r\n" +
"\r\n");
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R1"));
}
@Test
public void testOneResponse_11_empty() throws Exception
{
String response=_connector.getResponse(
"GET /R1?empty=true HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Connection: close\r\n" +
"\r\n");
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,not(containsString("pathInfo=/R1")));
}
@Test
public void testOneResponse_11_chunked() throws Exception
{
String response=_connector.getResponse(
"GET /R1?flush=true HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n");
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R1"));
assertThat(response,containsString("\r\n0\r\n"));
}
@Test
public void testThreeResponsePipeline_11() throws Exception
{
LocalEndPoint endp = _connector.connect();
endp.addInput(
"GET /R1 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n"+
"GET /R2 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n"+
"GET /R3 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n"
);
String response=endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R1"));
response=endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R2"));
response=endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R3"));
}
@Test
public void testThreeResponse_11() throws Exception
{
LocalEndPoint endp = _connector.connect();
endp.addInput(
"GET /R1 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n");
String response=endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R1"));
endp.addInput(
"GET /R2 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n");
response=endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R2"));
endp.addInput(
"GET /R3 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n"
);
response=endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R3"));
}
@Test
public void testThreeResponseClosed_11() throws Exception
{
LocalEndPoint endp = _connector.connect();
endp.addInput(
"GET /R1 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n"+
"GET /R2 HTTP/1.1\r\n" +
"Connection: close\r\n" +
"Host: localhost\r\n" +
"\r\n"+
"GET /R3 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n"
);
String response=endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R1"));
response=endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R2"));
response=endp.getResponse();
assertThat(response,nullValue());
}
@Test
public void testExpectContinuesAvailable() throws Exception
{
LocalEndPoint endp = _connector.connect();
endp.addInput(
"GET /R1 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Content-Type: text/plain; charset=UTF-8\r\n" +
"Expect: 100-Continue\r\n" +
"Content-Length: 10\r\n" +
"\r\n"+
"01234567890\r\n");
String response = endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R1"));
assertThat(response,containsString("0123456789"));
}
@Test
public void testExpectContinues() throws Exception
{
LocalEndPoint endp = _connector.executeRequest(
"GET /R1 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Content-Type: text/plain; charset=UTF-8\r\n" +
"Expect: 100-Continue\r\n" +
"Content-Length: 10\r\n" +
"\r\n");
String response = endp.getResponse();
assertThat(response,containsString("HTTP/1.1 100 Continue"));
endp.addInput("01234567890\r\n");
response = endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R1"));
assertThat(response,containsString("0123456789"));
}
@Test @Test
public void testStopStart() throws Exception public void testStopStart() throws Exception
{ {
@ -213,11 +389,11 @@ public class LocalConnectorTest
@Test @Test
public void testGETandGET() throws Exception public void testGETandGET() throws Exception
{ {
String response=_connector.getResponses("GET /R1 HTTP/1.0\r\n\r\n"); String response=_connector.getResponse("GET /R1 HTTP/1.0\r\n\r\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R1")); assertThat(response,containsString("pathInfo=/R1"));
response=_connector.getResponses("GET /R2 HTTP/1.0\r\n\r\n"); response=_connector.getResponse("GET /R2 HTTP/1.0\r\n\r\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R2")); assertThat(response,containsString("pathInfo=/R2"));
} }