Merge branch 'jetty-9.4.x'

This commit is contained in:
Joakim Erdfelt 2016-12-16 08:38:16 -07:00
commit 1c16964118
13 changed files with 397 additions and 267 deletions

View File

@ -69,6 +69,8 @@ When executed `start.jar` performs the following actions:
==== start.jar Command Line Options
===== Command Line Options
--help::
Obtains the current list of command line options and some basic usage help.
--version::
@ -77,8 +79,6 @@ Shows the list of server classpath entries, and prints version information found
Similar to --version, shows the server classpath.
--list-config::
Lists the resolved configuration that will start Jetty.
+
* Java environment
* Jetty environment
* JVM arguments
@ -89,6 +89,15 @@ Lists the resolved configuration that will start Jetty.
Prints the resolved command line that `start.jar` should use to start a forked instance of Jetty.
--exec::
Starts a forked instance of Jetty.
--exec-properties=<filename>::
Assign a fixed name to the file used to transfer properties to the sub process.
This allows the generated properties file to be saved and reused.
Without this option, a temporary file is used.
--commands=<filename>::
Instructs `start.jar` to use each line of the specified file as arguments on the command line.
===== Debugg and Start Logging
--debug::
Enables debugging output of the startup procedure.
+
@ -98,22 +107,55 @@ For information on logging, please see the section on <<configuring-jetty-loggin
Sends all startup output to the filename specified.
Filename is relative to `${jetty.base}`.
This is useful for capturing startup issues where the Jetty-specific logger has not yet kicked in due to a possible startup configuration error.
===== Module Management
--list-modules::
Lists all the modules defined by the system.
Looks for module files using the link:#startup-base-and-home[normal `${jetty.base}` and `${jetty.home}` resolution logic].
Also lists enabled state based on information present on the command line, and all active startup INI files.
--list-modules=<tag>(,<tag>)*::
List modules by link:#startup-modules[tag.]
Use '*' for all tags.
Prefix a tag with '-' to exclude the tag.
The special tag "internal" is always excluded unless it is explicitly included.
--list-all-modules::
List all modules.
--module=<name>,(<name>)*::
Enables one or more modules by name (use `--list-modules` to see the list of available modules).
This enables all transitive (dependent) modules from the module system as well.
If you use this from the shell command line, it is considered a temporary effect, useful for testing out a scenario.
If you want this module to always be enabled, add this command to your `${jetty.base}/start.ini.`
--create-startd::
Creates a `${jetty.base}/start.d/` directory.
If a `${jetty.base}/start.ini` file already exists, it is copied to the `${jetty.base}/start.d` directory.
--add-to-start=<name>,(<name>)*::
Enables a module by appending lines to the `${jetty.base}/start.ini` file.
The lines that are added are provided by the module-defined INI templates.
Note: Transitive modules are also appended.
If a module contains an .ini template with properties, you can also edit these properties when activating the module.
To do this, simply list the property and its value after the `-add-to-start` command, such as in the following example:
+
[source, screen, subs="{sub-order}"]
....
$ java -jar start.jar --add-to-start=http jetty.http.port=8379 jetty.http.host=1.2.3.4
....
+
Doing this will uncomment the property in the associated .ini file and set it to the value specified.
--update-ini::
Used to update a specified property or properties that exist in an existing .ini file.
Jetty scans the command line, `${jetty.base}` and `${jetty.home}` for .ini files that have the specified property and update it accordingly.
+
[source, screen, subs="{sub-order}"]
....
$ java -jar ../start.jar --update-ini jetty.http.port=8417
ConfigSource <command-line>
ConfigSource ${jetty.base}
INFO : http property updated jetty.http.port=8417
INFO : http updated ${jetty.base}/start.d/http.ini
ConfigSource ${jetty.home}
....
+
--create-startd::
Creates a `${jetty.base}/start.d/` directory.
If a `${jetty.base}/start.ini` file already exists, it is copied to the `${jetty.base}/start.d` directory.
[NOTE]
--
@ -136,6 +178,25 @@ $ dot -Tpng -o modules.png modules.dot
+
See http://graphviz.org/[graphviz.org] for details on http://graphviz.org/content/command-line-invocation[how to post-process this dotty file] into the output best suited for your needs.
--create-files::
Create any missing files that are required by initialized modules.
This may download a file from the network if the module provides a URL.
--skip-file-validation=<modulename>(,<modulename)*::
Disable the [files] section validation of content in the `${jetty.base}` directory for a specific module.
Useful for modules that have downloadable content that is being overridden with alternatives in the `${jetty.base}`` directory.
____
[CAUTION]
This advanced option is for administrators that fully understand the configuration of their `${jetty.base}` and are willing to forego some of the safety checks built into the jetty-start mechanism.
____
--approve-all-licenses::
Approve all license questions.
Useful for enabling modules from a script that does not require user interaction.
===== Startup / Shutdown Command Line
--stop::
Sends a stop signal to the running Jetty instance.
+

View File

@ -253,7 +253,7 @@ If there are multiple entries in the `[tags]` section, it sorts by the first tag
____
[NOTE]
By default, the `--list-modules` command line argument shows all modules that do not include `internal` in the `[tags]` section of the associated `.mod` file.
If you would like to see *all* modules, use `--list-modules=*`
If you would like to see *all* modules, use `--list-all-modules`
____
Here's an example of the `--list-modules` command:

View File

@ -255,187 +255,11 @@ First notice the separation of `${jetty.base}` and `${jetty.home}`.
Notice that you have `--module=<name>` here and there; you have wrapped up the goal of a module (libs, configuration XMLs, and properties) into a single unit, with dependencies on other modules.
You can see the list of modules:
You can see the list of modules by appending `--list-modules` to the command line.
[source, screen, subs="{sub-order}"]
....
[my-base]$ java -jar /home/user/jetty-distribution-{VERSION}/start.jar --list-modules
Jetty All Available Modules:
----------------------------
Module: annotations
LIB: lib/jetty-annotations-${jetty.version}.jar
LIB: lib/annotations/*.jar
XML: etc/jetty-annotations.xml
depends: [plus]
Module: client
LIB: lib/jetty-client-${jetty.version}.jar
depends: []
Module: debug
XML: etc/jetty-debug.xml
depends: [server]
Module: deploy
LIB: lib/jetty-deploy-${jetty.version}.jar
XML: etc/jetty-deploy.xml
depends: [webapp]
enabled: ${jetty.base}/start.ini
Module: ext
LIB: lib/ext/*.jar
depends: []
Module: http
XML: etc/jetty-http.xml
depends: [server]
enabled: ${jetty.base}/start.ini
Module: http2
LIB: lib/http2/*.jar
XML: etc/jetty-http2.xml
depends: [ssl, alpn]
Module: http2c
LIB: lib/http2/*.jar
XML: etc/jetty-http2c.xml
depends: [http]
Module: https
XML: etc/jetty-https.xml
depends: [ssl]
Module: ipaccess
XML: etc/jetty-ipaccess.xml
depends: [server]
Module: jaas
LIB: lib/jetty-jaas-${jetty.version}.jar
XML: etc/jetty-jaas.xml
depends: [server]
Module: jaspi
LIB: lib/jetty-jaspi-${jetty.version}.jar
LIB: lib/jaspi/*.jar
depends: [security]
Module: jmx
LIB: lib/jetty-jmx-${jetty.version}.jar
XML: etc/jetty-jmx.xml
depends: []
Module: jndi
LIB: lib/jetty-jndi-${jetty.version}.jar
LIB: lib/jndi/*.jar
depends: [server]
Module: jsp
LIB: lib/jsp/*.jar
depends: [servlet]
Module: jvm
depends: []
Module: logging
XML: etc/jetty-logging.xml
depends: []
Module: lowresources
XML: etc/jetty-lowresources.xml
depends: [server]
Module: monitor
LIB: lib/jetty-monitor-${jetty.version}.jar
XML: etc/jetty-monitor.xml
depends: [client, server]
Module: npn
depends: []
Module: plus
LIB: lib/jetty-plus-${jetty.version}.jar
XML: etc/jetty-plus.xml
depends: [server, security, jndi]
Module: proxy
LIB: lib/jetty-proxy-${jetty.version}.jar
XML: etc/jetty-proxy.xml
depends: [client, server]
Module: requestlog
XML: etc/jetty-requestlog.xml
depends: [server]
Module: resources
LIB: resources
depends: []
Module: rewrite
LIB: lib/jetty-rewrite-${jetty.version}.jar
XML: etc/jetty-rewrite.xml
depends: [server]
Module: security
LIB: lib/jetty-security-${jetty.version}.jar
depends: [server]
Module: server
LIB: lib/servlet-api-3.1.jar
LIB: lib/jetty-schemas-3.1.jar
LIB: lib/jetty-http-${jetty.version}.jar
LIB: lib/jetty-continuation-${jetty.version}.jar
LIB: lib/jetty-server-${jetty.version}.jar
LIB: lib/jetty-xml-${jetty.version}.jar
LIB: lib/jetty-util-${jetty.version}.jar
LIB: lib/jetty-io-${jetty.version}.jar
XML: etc/jetty.xml
depends: []
enabled: ${jetty.base}/start.ini
Module: servlet
LIB: lib/jetty-servlet-${jetty.version}.jar
depends: [server]
Module: servlets
LIB: lib/jetty-servlets-${jetty.version}.jar
depends: [servlet]
Module: setuid
LIB: lib/setuid/jetty-setuid-java-1.0.1.jar
XML: etc/jetty-setuid.xml
depends: [server]
Module: ssl
XML: etc/jetty-ssl.xml
depends: [server]
enabled: ${jetty.base}/start.ini
Module: stats
XML: etc/jetty-stats.xml
depends: [server]
Module: webapp
LIB: lib/jetty-webapp-${jetty.version}.jar
depends: [servlet]
Module: websocket
LIB: lib/websocket/*.jar
depends: [annotations]
Module: xinetd
XML: etc/jetty-xinetd.xml
depends: [server]
Jetty Active Module Tree:
-------------------------
+ Module: server [enabled]
+ Module: http [enabled]
+ Module: servlet [transitive]
+ Module: ssl [enabled]
+ Module: webapp [transitive]
+ Module: deploy [enabled]
[my-base] $ java -jar ../jetty-distribution-{VERSION}/start.jar --list-modules
....
These are the modules by name, the libraries they bring in, the XML configurations they use, the other modules they depend on (even optional ones), and if the module is in use, where it was enabled.
@ -458,6 +282,7 @@ ____
Notice that your `${jetty.base}/start.ini` has no references to the XML files.
That's because the module system and its graph of dependencies now dictate all of the XML files, and their load order.
Much more information on modules can be found in the section on link:#startup-modules[Managing Startup Modules.]
[[parameterizing]]
===== Parameters

View File

@ -17,19 +17,19 @@
[[quickstart-config-how]]
=== How to Configure Jetty
To understand Jetty configuration, you need to understand the "How" and the "What".
This section covers how to configure Jetty in terms of what mechanisms exist to perform configuration.
To understand Jetty configuration, you need to understand the "How" and the "What".
This section covers how to configure Jetty in terms of what mechanisms exist to perform configuration.
The link:#quickstart-config-what[next section] gives an overview of the action components and fields that you can configure with these mechanisms.
==== Jetty POJO Configuration
The core components of Jetty are Plain Old Java Objects (http://en.wikipedia.org/wiki/Plain_Old_Java_Object[POJOs])
The process of configuring Jetty is mostly the process of instantiating, assembling and setting fields on the Jetty POJOs.
The process of configuring Jetty is mostly the process of instantiating, assembling and setting fields on the Jetty POJOs.
This can be achieved by:
* Writing Java code to directly instantiate and assemble Jetty objects.
* Writing Java code to directly instantiate and assemble Jetty objects.
This is referred to as xref:embedding-jetty[].
* Using Jetty XML configuration, which is an http://en.wikipedia.org/wiki/Inversion_of_Control[Inversion of Control (IoC)] framework, to instantiate and assemble Jetty objects as XML objects.
* Using Jetty XML configuration, which is an http://en.wikipedia.org/wiki/Inversion_of_Control[Inversion of Control (IoC)] framework, to instantiate and assemble Jetty objects as XML objects.
The `etc/jetty.xml` file is the main Jetty XML configuration file, but there are many other `etc/jetty-__feature__.xml` files included in the Jetty distribution.
* Using a third party http://en.wikipedia.org/wiki/Inversion_of_Control[IoC] framework like http://en.wikipedia.org/wiki/Spring_Framework[Spring], to instantiate and assemble Jetty objects as Spring beans.
@ -40,9 +40,9 @@ Because the main Jetty configuration is done by IoC, the link:{JDURL}/[Jetty API
The Jetty distribution uses the following configuration files to instantiate, inject and start server via the `start.jar` mechanism.
`ini` files::
The Jetty Start mechanism uses the command line, the `$JETTY_BASE/start.ini` and/or `$JETTY_BASE/start.d/*.ini` files to create an effective command line of arguments.
The Jetty Start mechanism uses the command line, the `$JETTY_BASE/start.ini` and/or `$JETTY_BASE/start.d/*.ini` files to create an effective command line of arguments.
Arguments may be:
* Module activations in the form `--module=name`
* Properties in the form of `name=value`, used to parameterize Jetty IoC XML
* XML files in Jetty IoC (or Spring) XML format
@ -53,31 +53,31 @@ The Jetty distribution uses the following configuration files to instantiate, in
____
[NOTE]
--
As of Jetty 9 it is the `ini` files located in the Jetty base directory (if different from Jetty home) that are typically edited to change the configuration (e.g. change ports).
It is the `ini` files located in the Jetty base directory (if different from Jetty home) that are typically edited to change the configuration (e.g. change ports).
--
____
`mod` files::
The `$JETTY_HOME/modules/*.mod` files contain the definition of modules that can be activated by `--module=name`.
The `$JETTY_HOME/modules/*.mod` files contain the definition of modules that can be activated by `--module=name`.
Each `mod` file defines:
* Module dependencies for ordering and activation
* The libraries needed by the module to be added to the classpath
* The XML files needed by the module to be added to the effective command line
* Files needed by the activated module
* A template `ini` file to be used when activating the `--add-to-start=name` option
+
Typically module files are rarely edited and only then for significant structural changes.
The `*.mod` files are normally located in `$JETTY_HOME/modules/`, but extra or edited modules may be added to `$JETTY_BASE/module`.
+
Typically module files are rarely edited and only then for significant structural changes.
The `*.mod` files are normally located in `$JETTY_HOME/modules/`, but extra or edited modules may be added to `$JETTY_BASE/module`.
If module changes are required, it is best practice to copy the particular `*.mod` file from `$JETTY_HOME/modules/` to `$JETTY_BASE/modules/` before being modified.
XML files::
XML files in link:#jetty-xml-syntax[Jetty IoC XML format] or Spring IoC format are listed either on the command line, in `ini` files, or are added to the effective command line by a module definition.
The XML files instantiate and inject the actual Java objects that comprise the server, connectors and contexts.
XML files in link:#jetty-xml-syntax[Jetty IoC XML format] or Spring IoC format are listed either on the command line, in `ini` files, or are added to the effective command line by a module definition.
The XML files instantiate and inject the actual Java objects that comprise the server, connectors and contexts.
Because Jetty IoC XML files use properties, most common configuration tasks can be accomplished without editing these XML files and can instead be achieved by editing the property in the corresponding `ini` files.
XML files are normally located in `$JETTY_HOME/etc/`, but extra or edited XML files may be added to `$JETTY_BASE/etc/`.
XML files are normally located in `$JETTY_HOME/etc/`, but extra or edited XML files may be added to `$JETTY_BASE/etc/`.
*Note* If XML configuration changes are required, it is best practice to copy the XML file from `$JETTY_HOME/etc/` to `$JETTY_BASE/etc/` before being modified.
Below is an illustration of how the various Jetty configuration files (`ini`, `mod` and XML) are related:
image:images/Jetty_Configuration_File_Relationships.png[image,width=693]
@ -87,23 +87,23 @@ image:images/Jetty_Configuration_File_Relationships.png[image,width=693]
In addition to the configuration files described above, the configuration of the server can use the following file types:
Context XML files::
Any XML files in link:#jetty-xml-syntax[Jetty IoC XML format] or Spring IoC format that is discovered in the `/webapps` directory are used by the deploy module to instantiate and inject `HttpContext` instances to create a specific context.
Any XML files in link:#jetty-xml-syntax[Jetty IoC XML format] or Spring IoC format that is discovered in the `/webapps` directory are used by the deploy module to instantiate and inject `HttpContext` instances to create a specific context.
These may be standard web applications or bespoke contexts created from special purpose handlers.
web.xml::
The http://en.wikipedia.org/wiki/Servlet[Servlet] Specification defines the http://en.wikipedia.org/wiki/Web.xml[`web.xml`] deployment descriptor that defines and configures the filters, servlets and resources a http://en.wikipedia.org/wiki/Web_application[web application] uses.
The http://en.wikipedia.org/wiki/Servlet[Servlet] Specification defines the http://en.wikipedia.org/wiki/Web.xml[`web.xml`] deployment descriptor that defines and configures the filters, servlets and resources a http://en.wikipedia.org/wiki/Web_application[web application] uses.
The Jetty `WebAppContext` component uses this XML format to:
* Set up the default configuration of a web application context.
* Interpret the application-specific configuration supplied with a web application in the `WEB-INF/web.xml` file.
* Interpret descriptor fragments included in the `META-INF` directory of Jar files within `WEB-INF/lib.`
+
Normally the `web.xml` file for a web application is found in the `WEB-INF/web.xml` location within the war file/directory or as `web.xml` fragments with `.jar` files found in `WEB-INF/lib`.
Normally the `web.xml` file for a web application is found in the `WEB-INF/web.xml` location within the war file/directory or as `web.xml` fragments with `.jar` files found in `WEB-INF/lib`.
Jetty also supports multiple `web.xml` files so that a default descriptor may be applied before `WEB-INF/web.xml` (typically set to `etc/webdefault.xml` by the deploy module) and an override descriptor may be applied after `WEB-INF/web.xml` (typically set by a context XML file see `test.xml`)
Property Files::
Standard http://en.wikipedia.org/wiki/Java_properties[Java property files] are also used for Jetty configuration in several ways:
+
+
* To parameterize Jetty IoC XML via the use of the `Property` element.
* To configure the default logging mechanism (`StdErrLog`). Other logging frameworks can be utilized and also use property files (for example, `log4j`).
* As a simple database for login usernames and credentials.
@ -124,5 +124,5 @@ link:#jetty-xml-syntax[Jetty IoC XML format] allows you to instantiate and confi
include::{SRCDIR}/examples/embedded/src/main/resources/exampleserver.xml[]
----
//In practice, most commonly used Jetty features have XML files that are included in the standard distribution in the `/etc` directory.
//In practice, most commonly used Jetty features have XML files that are included in the standard distribution in the `/etc` directory.
//Thus configuring Jetty is often a matter of just editing existing XML files and altering the property values injected into them.

View File

@ -25,16 +25,16 @@ ____
http://download.eclipse.org/jetty
____
It is available in both zip and gzip formats; download the one most appropriate for your system.
Notice that there are a number of other files with extensions of .sha or .md5 which are checksum files.
When you download and unpack the binary, it is extracted into a directory called `jetty-distribution-VERSION.`
Put this directory in a convenient location.
It is available in both zip and gzip formats; download the one most appropriate for your system.
When you download and unpack the binary, it is extracted into a directory called `jetty-distribution-VERSION.`
Put this directory in a convenient location.
The rest of the instructions in this documentation refer to this location as either `JETTY_HOME` or as `$(jetty.home).`
[[distribution-content]]
==== Distribution Content
A quick rundown of the distribution's contents follows. The top-level directory contains:
A summary of the distribution's contents follows.
The top-level directory contains:
.Contents
[width="80%",cols="40%,60%",options="header"]
@ -50,8 +50,42 @@ A quick rundown of the distribution's contents follows. The top-level directory
|modules/ |Directory of module definitions
|notice.html |License information and exceptions
|resources/ |Directory containing additional resources for classpath, activated via configuration
|start.d/ |Directory of *.ini files containing arguments that are added to the effective command line (see start.ini)
|start.ini |File containing the arguments that are added to the effective command line (modules, properties and XML configuration files)
|start.jar |Jar that invokes Jetty (see also xref:quickstart-running-jetty[])
|webapps/ |Directory containing webapps that run under the default configuration of Jetty
|=======================================================================
[[jetty-home-downloading]]
==== Downloading the Jetty-Home Distribution
Jetty-Home is an alternate version of the distribution that contains only the necessary items to host a Jetty distribution.
It is intended for advanced users who are already familiar with Jetty and want to download a smaller distribution package.
Jetty-Home can be downloaded from the Maven Central repository:
____
*Jetty-Home*
http://central.maven.org/maven2/org/eclipse/jetty/jetty-home/
____
Like the main Jetty distribution, Jetty-Home is available in both zip and gzip formats; download the one most appropriate for your system.
Notice that there are a number of other files with extensions of .sha or .md5 which are checksum files.
When you download and unpack the binary, it is extracted into a directory called `jetty-home-VERSION.`
Put this directory in a convenient location.
[[jetty-home-distribution-content]]
==== Distribution Content
A summary of the Jetty-Home's distribution contents follows.
The top-level directory contains:
.Contents
[width="80%",cols="40%,60%",options="header"]
|=======================================================================
|Location |Description |license-eplv10-aslv20.html |License file for Jetty
|VERSION.txt |Release information
|etc/ |Directory for Jetty XML configuration files
|lib/ |All the JAR files necessary to run Jetty
|modules/ |Directory of module definitions
|notice.html |License information and exceptions
|start.jar |Jar that invokes Jetty (see also xref:quickstart-running-jetty[])
|=======================================================================

View File

@ -24,6 +24,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.function.Predicate;
import org.eclipse.jetty.util.ArrayTernaryTrie;
import org.eclipse.jetty.util.Trie;
@ -81,6 +82,11 @@ public class PathMappings<E> implements Iterable<MappedResource<E>>, Dumpable
_suffixMap.clear();
}
public void removeIf(Predicate<MappedResource<E>> predicate)
{
_mappings.removeIf(predicate);
}
/**
* Return a list of MappedResource matches for the specified path.
*
@ -172,7 +178,7 @@ public class PathMappings<E> implements Iterable<MappedResource<E>>, Dumpable
}
default:
}
}
}
if (mr.getPathSpec().matches(path))

View File

@ -80,8 +80,6 @@ import org.eclipse.jetty.util.thread.Invocable;
public class SslConnection extends AbstractConnection
{
private static final Logger LOG = Log.getLogger(SslConnection.class);
private static final ByteBuffer __FILL_CALLED_FLUSH= BufferUtil.allocate(0);
private static final ByteBuffer __FLUSH_CALLED_FILL= BufferUtil.allocate(0);
private final List<SslHandshakeListener> handshakeListeners = new ArrayList<>();
private final ByteBufferPool _bufferPool;
@ -634,9 +632,10 @@ public class SslConnection extends AbstractConnection
HandshakeStatus unwrapHandshakeStatus = unwrapResult.getHandshakeStatus();
Status unwrapResultStatus = unwrapResult.getStatus();
// Extra check on unwrapResultStatus == OK with zero length buffer is due
// to SSL client on android (see bug #454773)
_underFlown = unwrapResultStatus == Status.BUFFER_UNDERFLOW || unwrapResultStatus == Status.OK && unwrapResult.bytesConsumed()==0 && unwrapResult.bytesProduced()==0;
// Extra check on unwrapResultStatus == OK with zero bytes consumed
// or produced is due to an SSL client on Android (see bug #454773).
_underFlown = unwrapResultStatus == Status.BUFFER_UNDERFLOW ||
unwrapResultStatus == Status.OK && unwrapResult.bytesConsumed() == 0 && unwrapResult.bytesProduced() == 0;
if (_underFlown)
{
@ -730,15 +729,17 @@ public class SslConnection extends AbstractConnection
{
// If we are called from flush()
// return to let it do the wrapping.
if (buffer == __FLUSH_CALLED_FILL)
if (_flushRequiresFillToProgress)
return 0;
_fillRequiresFlushToProgress = true;
flush(__FILL_CALLED_FLUSH);
flush(BufferUtil.EMPTY_BUFFER);
if (BufferUtil.isEmpty(_encryptedOutput))
{
// The flush wrote all the encrypted bytes so continue to fill
// The flush wrote all the encrypted bytes so continue to fill.
_fillRequiresFlushToProgress = false;
if (_underFlown)
break decryption;
continue;
}
else
@ -961,11 +962,11 @@ public class SslConnection extends AbstractConnection
case NEED_UNWRAP:
// Ah we need to fill some data so we can write.
// So if we were not called from fill and the app is not reading anyway
if (appOuts[0]!=__FILL_CALLED_FLUSH && !getFillInterest().isInterested())
if (!_fillRequiresFlushToProgress && !getFillInterest().isInterested())
{
// Tell the onFillable method that there might be a write to complete
_flushRequiresFillToProgress = true;
fill(__FLUSH_CALLED_FILL);
fill(BufferUtil.EMPTY_BUFFER);
// Check if after the fill() we need to wrap again
if (_sslEngine.getHandshakeStatus() == HandshakeStatus.NEED_WRAP)
continue;

View File

@ -31,6 +31,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
@ -46,6 +47,7 @@ import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.DispatcherType;
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
@ -55,10 +57,13 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.server.LocalConnector.LocalEndPoint;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.toolchain.test.FS;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.MultiPartInputStreamParser;
import org.eclipse.jetty.util.Utf8Appendable;
@ -831,8 +836,79 @@ public class RequestTest
String response = _connector.getResponse(request);
assertThat(response,Matchers.containsString(" 200 OK"));
}
@Test
@Ignore("See issue #1175")
public void testMultiPartFormDataReadInputThenParams() throws Exception
{
final File tmpdir = MavenTestingUtils.getTargetTestingDir("multipart");
FS.ensureEmpty(tmpdir);
Handler handler = new AbstractHandler()
{
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException,
ServletException
{
if (baseRequest.getDispatcherType() != DispatcherType.REQUEST)
return;
// Fake a @MultiPartConfig'd servlet endpoint
MultipartConfigElement multipartConfig = new MultipartConfigElement(tmpdir.getAbsolutePath());
request.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, multipartConfig);
// Normal processing
baseRequest.setHandled(true);
// Fake the commons-fileupload behavior
int length = request.getContentLength();
InputStream in = request.getInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream();
IO.copy(in, out, length); // KEY STEP (Don't Change!) commons-fileupload does not read to EOF
// Record what happened as servlet response headers
response.setIntHeader("x-request-content-length", request.getContentLength());
response.setIntHeader("x-request-content-read", out.size());
String foo = request.getParameter("foo"); // uri query parameter
String bar = request.getParameter("bar"); // form-data content parameter
response.setHeader("x-foo", foo == null ? "null" : foo);
response.setHeader("x-bar", bar == null ? "null" : bar);
}
};
_server.stop();
_server.setHandler(handler);
_server.start();
String multipart = "--AaBbCc\r\n"+
"content-disposition: form-data; name=\"bar\"\r\n"+
"\r\n"+
"BarContent\r\n"+
"--AaBbCc\r\n"+
"content-disposition: form-data; name=\"stuff\"\r\n"+
"Content-Type: text/plain;charset=ISO-8859-1\r\n"+
"\r\n"+
"000000000000000000000000000000000000000000000000000\r\n"+
"--AaBbCc--\r\n";
String request="POST /?foo=FooUri HTTP/1.1\r\n"+
"Host: whatever\r\n"+
"Content-Type: multipart/form-data; boundary=\"AaBbCc\"\r\n"+
"Content-Length: "+multipart.getBytes().length+"\r\n"+
"Connection: close\r\n"+
"\r\n"+
multipart;
HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
// It should always be possible to read query string
assertThat("response.x-foo", response.get("x-foo"), is("FooUri"));
// Not possible to read request content parameters?
assertThat("response.x-bar", response.get("x-bar"), is("null")); // TODO: should this work?
}
@Test
public void testPartialRead() throws Exception
{
@ -849,36 +925,35 @@ public class RequestTest
response.getOutputStream().write(b);
response.flushBuffer();
}
};
_server.stop();
_server.setHandler(handler);
_server.start();
String requests="GET / HTTP/1.1\r\n"+
"Host: whatever\r\n"+
"Content-Type: text/plane\r\n"+
"Content-Length: "+10+"\r\n"+
"\r\n"+
"0123456789\r\n"+
"GET / HTTP/1.1\r\n"+
"Host: whatever\r\n"+
"Content-Type: text/plane\r\n"+
"Content-Length: "+10+"\r\n"+
"Connection: close\r\n"+
"\r\n"+
"ABCDEFGHIJ\r\n";
LocalEndPoint endp = _connector.executeRequest(requests);
String response = endp.getResponse()+endp.getResponse();
int index=response.indexOf("read="+(int)'0');
String request="GET / HTTP/1.1\r\n"+
"Host: whatever\r\n"+
"Content-Type: text/plane\r\n"+
"Content-Length: "+10+"\r\n"+
"\r\n"+
"0123456789\r\n"+
"GET / HTTP/1.1\r\n"+
"Host: whatever\r\n"+
"Content-Type: text/plane\r\n"+
"Content-Length: "+10+"\r\n"+
"Connection: close\r\n"+
"\r\n"+
"ABCDEFGHIJ\r\n";
String responses = _connector.getResponses(request);
int index=responses.indexOf("read="+(int)'0');
assertTrue(index>0);
index=response.indexOf("read="+(int)'A',index+7);
index=responses.indexOf("read="+(int)'A',index+7);
assertTrue(index>0);
}
@Test
public void testQueryAfterRead()
throws Exception

View File

@ -99,18 +99,7 @@ Module Management:
If the ini template contains properties, these may be
amended in the generated file by specifying those
properties on the command line.
FS.ensureDirectoryExists(startDir);
FS.ensureDirectoryExists(startDir);
modules that the specified module depends on are also
.
If the directory ${jetty.base}/start.d
exists then <modulename>.ini files are created within
that directory, otherwise then enabling configuration
is appended to the ${jetty.base}/start.ini file.
Lines that are added come from the ini template that
the module itself maintains.
Note: not all modules have ini templates and thus may
be transitively enabled and not explicitly enabled in
a ini file.

View File

@ -32,7 +32,7 @@
<dependency>
<groupId>com.github.jnr</groupId>
<artifactId>jnr-unixsocket</artifactId>
<version>0.8</version>
<version>0.15</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>

View File

@ -60,7 +60,7 @@ public class NativeWebSocketConfiguration extends ContainerLifeCycle implements
@Override
public void doStop() throws Exception
{
mappings.reset();
mappings.removeIf((mapped) -> !(mapped.getResource() instanceof PersistedWebSocketCreator));
super.doStop();
}
@ -111,13 +111,23 @@ public class NativeWebSocketConfiguration extends ContainerLifeCycle implements
/**
* Manually add a WebSocket mapping.
* <p>
* If mapping is added before this configuration is started, then it is persisted through
* stop/start of this configuration's lifecycle. Otherwise it will be removed when
* this configuration is stopped.
* </p>
*
* @param pathSpec the pathspec to respond on
* @param creator the websocket creator to activate on the provided mapping.
*/
public void addMapping(PathSpec pathSpec, WebSocketCreator creator)
{
mappings.put(pathSpec, creator);
WebSocketCreator wsCreator = creator;
if (!isRunning())
{
wsCreator = new PersistedWebSocketCreator(creator);
}
mappings.put(pathSpec, wsCreator);
}
/**
@ -170,4 +180,26 @@ public class NativeWebSocketConfiguration extends ContainerLifeCycle implements
}
});
}
private class PersistedWebSocketCreator implements WebSocketCreator
{
private final WebSocketCreator delegate;
public PersistedWebSocketCreator(WebSocketCreator delegate)
{
this.delegate = delegate;
}
@Override
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
{
return delegate.createWebSocket(req, resp);
}
@Override
public String toString()
{
return "Persisted[" + super.toString() + "]";
}
}
}

View File

@ -34,6 +34,7 @@ import javax.servlet.DispatcherType;
import org.eclipse.jetty.http.pathmap.ServletPathSpec;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.toolchain.test.EventQueue;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
@ -127,13 +128,43 @@ public class WebSocketUpgradeFilterTest
NativeWebSocketConfiguration configuration = new NativeWebSocketConfiguration(context.getServletContext());
configuration.getFactory().getPolicy().setMaxTextMessageSize(10 * 1024 * 1024);
configuration.addMapping(new ServletPathSpec("/info/*"), infoCreator);
context.getServletContext().setAttribute(NativeWebSocketConfiguration.class.getName(), configuration);
context.setAttribute(NativeWebSocketConfiguration.class.getName(), configuration);
server13.start();
return server13;
}});
// Embedded WSUF, added as filter, apply app-ws configuration via wsuf constructor
cases.add(new Object[]{"wsuf/addFilter/WSUF Constructor configure", new ServerProvider()
{
@Override
public Server newServer() throws Exception
{
Server server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setPort(0);
server.addConnector(connector);
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
server.setHandler(context);
NativeWebSocketConfiguration configuration = new NativeWebSocketConfiguration(context.getServletContext());
configuration.getFactory().getPolicy().setMaxTextMessageSize(10 * 1024 * 1024);
configuration.addMapping(new ServletPathSpec("/info/*"), infoCreator);
context.addBean(configuration, true);
FilterHolder wsufHolder = new FilterHolder(new WebSocketUpgradeFilter(configuration));
context.addFilter(wsufHolder, "/*", EnumSet.of(DispatcherType.REQUEST));
server.start();
return server;
}
}});
// Embedded WSUF, added as filter, apply app-ws configuration via ServletContextListener
cases.add(new Object[]{"wsuf.configureContext/ServletContextListener configure", (ServerProvider) () ->
@ -235,7 +266,7 @@ public class WebSocketUpgradeFilterTest
}
@Test
public void testConfiguration() throws Exception
public void testNormalConfiguration() throws Exception
{
URI destUri = serverUri.resolve("/info/");
@ -255,4 +286,45 @@ public class WebSocketUpgradeFilterTest
assertThat("payload", payload, containsString("session.maxTextMessageSize=" + (10 * 1024 * 1024)));
}
}
@Test
public void testStopStartOfHandler() throws Exception
{
URI destUri = serverUri.resolve("/info/");
try (BlockheadClient client = new BlockheadClient(destUri))
{
client.connect();
client.sendStandardRequest();
client.expectUpgradeResponse();
client.write(new TextFrame().setPayload("hello 1"));
EventQueue<WebSocketFrame> frames = client.readFrames(1, 1000, TimeUnit.MILLISECONDS);
String payload = frames.poll().getPayloadAsUTF8();
// If we can connect and send a text message, we know that the endpoint was
// added properly, and the response will help us verify the policy configuration too
assertThat("payload", payload, containsString("session.maxTextMessageSize=" + (10 * 1024 * 1024)));
}
server.getHandler().stop();
server.getHandler().start();
try (BlockheadClient client = new BlockheadClient(destUri))
{
client.connect();
client.sendStandardRequest();
client.expectUpgradeResponse();
client.write(new TextFrame().setPayload("hello 2"));
EventQueue<WebSocketFrame> frames = client.readFrames(1, 1000, TimeUnit.MILLISECONDS);
String payload = frames.poll().getPayloadAsUTF8();
// If we can connect and send a text message, we know that the endpoint was
// added properly, and the response will help us verify the policy configuration too
assertThat("payload", payload, containsString("session.maxTextMessageSize=" + (10 * 1024 * 1024)));
}
}
}

View File

@ -33,6 +33,7 @@ import java.util.stream.IntStream;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -510,6 +511,40 @@ public class HttpClientTest extends AbstractTest
Assert.assertEquals(1, completes.get());
}
@Test
public void testHEADResponds200() throws Exception
{
testHEAD(servletPath, HttpStatus.OK_200);
}
@Test
public void testHEADResponds404() throws Exception
{
testHEAD("/notMapped", HttpStatus.NOT_FOUND_404);
}
private void testHEAD(String path, int status) throws Exception
{
byte[] data = new byte[1024];
new Random().nextBytes(data);
start(new HttpServlet()
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
response.getOutputStream().write(data);
}
});
ContentResponse response = client.newRequest(newURI())
.method(HttpMethod.HEAD)
.path(path)
.send();
Assert.assertEquals(status, response.getStatus());
Assert.assertEquals(0, response.getContent().length);
}
private void sleep(long time) throws IOException
{
try