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

This commit is contained in:
Simone Bordet 2017-09-04 15:57:01 +02:00
commit bce20d1b2e
14 changed files with 505 additions and 65 deletions

View File

@ -20,6 +20,12 @@ package org.eclipse.jetty.embedded;
import java.io.File;
import java.io.FileNotFoundException;
import java.lang.reflect.Method;
import java.security.Provider;
import java.security.Security;
import java.util.function.BiFunction;
import javax.net.ssl.SSLEngine;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.server.Connector;
@ -84,10 +90,14 @@ public class ManyConnectors
// to know about. Much more configuration is available the ssl context,
// including things like choosing the particular certificate out of a
// keystore to be used.
Security.addProvider((Provider)ClassLoader.getSystemClassLoader().loadClass("org.conscrypt.OpenSSLProvider").newInstance());
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath(keystoreFile.getAbsolutePath());
sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
sslContextFactory.setProvider("Conscrypt");
// HTTPS Configuration
// A new HttpConfiguration object is needed for the next connector and
@ -126,6 +136,19 @@ public class ManyConnectors
// Start the server
server.start();
SSLEngine engine = sslContextFactory.newSSLEngine();
System.err.println(engine);
System.err.println(engine.getClass());
for (Method m : engine.getClass().getMethods())
{
System.err.println(m);
}
server.join();
}
}

View File

@ -16,7 +16,7 @@
[source, screen, subs="{sub-order}"]
....
[mybase]$ java -jar /opt/jetty-distribution/start.jar --list-config
[mybase]$ java -jar $JETTY_HOME/start.jar --list-config
Java Environment:
-----------------
@ -28,7 +28,7 @@ Java Environment:
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 = /Users/staff/installs/repository/jetty-distribution-9.4.0/mybase
user.dir = /Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase
user.language = en
user.country = US
@ -36,14 +36,14 @@ Jetty Environment:
-----------------
jetty.version = {VERSION}
jetty.tag.version = master
jetty.home = /Users/staff/installs/repository/jetty-distribution-9.4.0
jetty.base = /Users/staff/installs/repository/jetty-distribution-9.4.0/mybase
jetty.home = /Users/staff/installs/repository/jetty-distribution-{VERSION}
jetty.base = /Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase
Config Search Order:
--------------------
<command-line>
${jetty.base} -> /Users/staff/installs/repository/jetty-distribution-9.4.0/mybase
${jetty.home} -> /Users/staff/installs/repository/jetty-distribution-9.4.0
${jetty.base} -> /Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase
${jetty.home} -> /Users/staff/installs/repository/jetty-distribution-{VERSION}
JVM Arguments:

View File

@ -16,7 +16,7 @@
[source, screen, subs="{sub-order}"]
....
[mybase]$ java -jar ../start.jar --list-config
[mybase]$ java -jar $JETTY_HOME/start.jar --list-config
Java Environment:
-----------------
@ -28,7 +28,7 @@ Java Environment:
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 = /Users/staff/installs/repository/jetty-distribution-9.4.0/mybase
user.dir = /Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase
user.language = en
user.country = US
@ -36,14 +36,14 @@ Jetty Environment:
-----------------
jetty.version = {VERSION}
jetty.tag.version = master
jetty.home = /Users/staff/installs/repository/jetty-distribution-9.4.0
jetty.base = /Users/staff/installs/repository/jetty-distribution-9.4.0/mybase
jetty.home = /Users/staff/installs/repository/jetty-distribution-{VERSION}
jetty.base = /Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase
Config Search Order:
--------------------
<command-line>
${jetty.base} -> /Users/staff/installs/repository/jetty-distribution-9.4.0/mybase
${jetty.home} -> /Users/staff/installs/repository/jetty-distribution-9.4.0
${jetty.base} -> /Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase
${jetty.home} -> /Users/staff/installs/repository/jetty-distribution-{VERSION}
JVM Arguments:
@ -81,7 +81,8 @@ Note: order presented here is how they would appear on the classpath.
Jetty Active XMLs:
------------------
${jetty.home}/etc/jetty.xml
${jetty.home}/etc/jetty-deploy.xml
${jetty.home}/etc/jetty-http.xml
${jetty.home}/etc/jetty.xml
${jetty.home}/etc/jetty-webapp.xml
${jetty.home}/etc/jetty-deploy.xml
${jetty.home}/etc/jetty-http.xml
....

View File

@ -16,11 +16,13 @@
[source, screen, subs="{sub-order}"]
....
[mybase]$ java -jar ../start.jar --add-to-start=http,webapp,deploy
INFO : webapp initialised in ${jetty.base}/start.d/webapp.ini
INFO : server initialised (transitively) in ${jetty.base}/start.d/server.ini
INFO : http initialised in ${jetty.base}/start.d/http.ini
INFO : deploy initialised in ${jetty.base}/start.d/deploy.ini
MKDIR: ${jetty.base}/webapps
INFO : Base directory was modified
[mybase]$ java -jar $JETTY_HOME/start.jar --add-to-start=http,webapp,deploy
INFO : webapp initialized in ${jetty.base}/start.ini
INFO : server transitively enabled, ini template available with --add-to-start=server
INFO : security transitively enabled
INFO : servlet transitively enabled
INFO : http initialized in ${jetty.base}/start.ini
INFO : deploy initialized in ${jetty.base}/start.ini
MKDIR : ${jetty.base}/webapps
INFO : Base directory was modified
....

View File

@ -16,7 +16,7 @@
[source, screen, subs="{sub-order}"]
....
[mybase]$ java -jar ../start.jar --list-modules=logging,-internal
[mybase]$ java -jar $JETTY_HOME/start.jar --list-modules=logging,-internal
Available Modules:
==================

View File

@ -18,7 +18,8 @@
=== Managing Startup Modules
The standard Jetty Distribution ships with several modules defined in `${jetty.home}/modules/`.
These modules allow flexibility for implementations and make configuration a much more plug-and-play set up.
Modules interact with Jetty XML files to configure options and parameters for the server and are the primary configuration method for Jetty distributions.
Modules allow flexibility for implementations and their plug-and-play nature makes adding or removing server functionality virtually painless.
[[enabling-modules]]
==== Enabling Modules
@ -28,27 +29,27 @@ The default distribution has a co-mingled `${jetty.home}` and `${jetty.base}` wh
It is highly encouraged that you learn about the differences in link:#startup-base-and-home[Jetty Base vs Jetty Home] and take full advantage of this setup.
____
Jetty ships with many modules defined in `${jetty.home}/modules`.
Enabling a module is a simple process: simply add the `--add-to-start` syntax on the command line.
Doing this will enable the module and any dependent modules.
An example of this, with a new, empty, base directory.
We can see from this output, that the directory is new.
An example of this with a new, empty, base directory:
If we try to start the Jetty server with no configuration or modules enabled, it will promptly exit:
include::screen-empty-base.adoc[]
Lets see what the configuration looks like so far:
By using the `--list-config` parameter to our startup command, we can see that there are no modules enabled and no Jetty XML files are active:
include::screen-empty-base-listconfig.adoc[]
Lets try adding some basic support for webapps, with automatic deploy (hot deploy), and a single basic HTTP/1.1 connector.
Let's try adding some basic support for webapps, with automatic deploy (hot deploy), and a single basic HTTP/1.1 connector.
include::screen-http-webapp-deploy.adoc[]
This created the webapps directory in our `mybase` directory and appended the `start.ini` file with the ini template arguments from the associated module files.
Additionally, where needed, Jetty enabled any module dependencies and added their module ini template properties.
This creates the webapps directory in our `mybase` directory and appended the `start.ini` file with the ini template arguments from the associated module files.
Additionally, where needed, Jetty enabled any module dependencies.
Lets see what it looks like configuration wise.
Now that we have added some modules to our server, let's run `--list-config` again to review our new configuration.
include::screen-http-webapp-deploy-listconfig.adoc[]

View File

@ -24,13 +24,274 @@ Configuring a connector is a combination of configuring the following:
* Services the connector uses (for example: executors, schedulers).
* Connection factories that instantiate and configure the protocol for an accepted connection.
Jetty primarily uses a single connector type called link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[ServerConnector].
Typically connectors require very little configuration aside from setting the listening port, and enabling `X-Forwarded-For` customization when applicable.
Additional settings, including construction your own constructor Jetty XML files, are for expert configuration only.
==== Enabling Connectors
Out of the box, Jetty provides several link:#startup-modules[modules] for enabling different types of connectors, from HTTP to HTTPS, HTTP/2, and others.
If you startup Jetty with the `--list-modules=connector` command, you can see a list of all available connector modules:
[source, screen, subs="{sub-order}"]
....
[mybase]$ java -jar $JETTY_HOME/start.jar --list-modules=connector
Available Modules:
==================
tags: [connector]
Modules for tag 'connector':
----------------------------
Module: http
: Enables a HTTP connector on the server.
: By default HTTP/1 is support, but HTTP2C can
: be added to the connector with the http2c module.
Tags: connector, http
Depend: server
XML: etc/jetty-http.xml
Enabled: ${jetty.base}/start.ini
Module: http-forwarded
: Adds a forwarded request customizer to the HTTP Connector
: to process forwarded-for style headers from a proxy.
Tags: connector
Depend: http
XML: etc/jetty-http-forwarded.xml
Module: http2
: Enables HTTP2 protocol support on the TLS(SSL) Connector,
: using the ALPN extension to select which protocol to use.
Tags: connector, http2, http, ssl
Depend: ssl, alpn
LIB: lib/http2/*.jar
XML: etc/jetty-http2.xml
Module: http2c
: Enables the HTTP2C protocol on the HTTP Connector
: The connector will accept both HTTP/1 and HTTP/2 connections.
Tags: connector, http2, http
Depend: http
LIB: lib/http2/*.jar
XML: etc/jetty-http2c.xml
Module: https
: Adds HTTPS protocol support to the TLS(SSL) Connector
Tags: connector, https, http, ssl
Depend: ssl
Optional: http-forwarded, http2
XML: etc/jetty-https.xml
Module: proxy-protocol-ssl
: Enables the Proxy Protocol on the TLS(SSL) Connector.
: http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt
: This allows a Proxy operating in TCP mode to transport
: details of the proxied connection to the server.
: Both V1 and V2 versions of the protocol are supported.
Tags: connector, ssl
Depend: ssl
XML: etc/jetty-proxy-protocol-ssl.xml
Module: ssl
: Enables a TLS(SSL) Connector on the server.
: This may be used for HTTPS and/or HTTP2 by enabling
: the associated support modules.
Tags: connector, ssl
Depend: server
XML: etc/jetty-ssl.xml
XML: etc/jetty-ssl-context.xml
Module: unixsocket
: Enables a Unix Domain Socket Connector that can receive
: requests from a local proxy and/or SSL offloader (eg haproxy) in either
: HTTP or TCP mode. Unix Domain Sockets are more efficient than
: localhost TCP/IP connections as they reduce data copies, avoid
: needless fragmentation and have better dispatch behaviours.
: When enabled with corresponding support modules, the connector can
: accept HTTP, HTTPS or HTTP2C traffic.
Tags: connector
Depend: server
LIB: lib/jetty-unixsocket-${jetty.version}.jar
LIB: lib/jnr/*.jar
XML: etc/jetty-unixsocket.xml
Module: unixsocket-forwarded
: Adds a forwarded request customizer to the HTTP configuration used
: by the Unix Domain Socket connector, for use when behind a proxy operating
: in HTTP mode that adds forwarded-for style HTTP headers. Typically this
: is an alternate to the Proxy Protocol used mostly for TCP mode.
Tags: connector
Depend: unixsocket-http
XML: etc/jetty-unixsocket-forwarded.xml
Module: unixsocket-http
: Adds a HTTP protocol support to the Unix Domain Socket connector.
: It should be used when a proxy is forwarding either HTTP or decrypted
: HTTPS traffic to the connector and may be used with the
: unix-socket-http2c modules to upgrade to HTTP/2.
Tags: connector, http
Depend: unixsocket
XML: etc/jetty-unixsocket-http.xml
Module: unixsocket-http2c
: Adds a HTTP2C connetion factory to the Unix Domain Socket Connector
: It can be used when either the proxy forwards direct
: HTTP/2C (unecrypted) or decrypted HTTP/2 traffic.
Tags: connector, http2
Depend: unixsocket-http
LIB: lib/http2/*.jar
XML: etc/jetty-unixsocket-http2c.xml
Module: unixsocket-proxy-protocol
: Enables the proxy protocol on the Unix Domain Socket Connector
: http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt
: This allows information about the proxied connection to be
: efficiently forwarded as the connection is accepted.
: Both V1 and V2 versions of the protocol are supported and any
: SSL properties may be interpreted by the unixsocket-secure
: module to indicate secure HTTPS traffic. Typically this
: is an alternate to the forwarded module.
Tags: connector
Depend: unixsocket
XML: etc/jetty-unixsocket-proxy-protocol.xml
Module: unixsocket-secure
: Enable a secure request customizer on the HTTP Configuration
: used by the Unix Domain Socket Connector.
: This looks for a secure scheme transported either by the
: unixsocket-forwarded, unixsocket-proxy-protocol or in a
: HTTP2 request.
Tags: connector
Depend: unixsocket-http
XML: etc/jetty-unixsocket-secure.xml
...
....
To enable a connector, simply activate the associated module.
Below is an example of activating both the `http` and `https` modules in a fresh link:#startup-base-and-home[Jetty base] using the link:#start-vs-startd[start.d directory]:
[source, screen, subs="{sub-order}"]
....
[mybase] java -jar $JETTY_HOME/start.jar --create-startd
MKDIR : ${jetty.base}/start.d
INFO : Base directory was modified
[mybase] java -jar $JETTY_HOME/start.jar --add-to-start=http,https
INFO : server transitively enabled, ini template available with --add-to-start=server
INFO : http initialized in ${jetty.base}/start.d/http.ini
INFO : https initialized in ${jetty.base}/start.d/https.ini
INFO : ssl transitively enabled, ini template available with --add-to-start=ssl
MKDIR : ${jetty.base}/etc
COPY : ${jetty.home}/modules/ssl/keystore to ${jetty.base}/etc/keystore
INFO : Base directory was modified
[mybase] tree
.
├── etc
│   └── keystore
└── start.d
├── http.ini
└── https.ini
....
When the `http` and `https` modules were activated, so too were any modules they were dependent on, in this case `server` and `ssl`, as well as any dependencies for those modules, such as the `etc` and `ketystore` directories for `ssl`.
At this point the server has been configured with connectors for both HTTP and HTTPS and can be started:
[source, screen, subs="{sub-order}"]
....
[mybase] java -jar $JETTY_HOME/start.jar
2017-08-31 10:19:58.855:INFO::main: Logging initialized @372ms to org.eclipse.jetty.util.log.StdErrLog
2017-08-31 10:19:59.076:INFO:oejs.Server:main: jetty-9.4.6.v20170531
2017-08-31 10:19:59.125:INFO:oejs.AbstractConnector:main: Started ServerConnector@421e98e0{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2017-08-31 10:19:59.150:INFO:oejus.SslContextFactory:main: x509=X509@5315b42e(jetty,h=[jetty.eclipse.org],w=[]) for SslContextFactory@2ef9b8bc(file:///Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase/etc/keystore,file:///Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase/etc/keystore)
2017-08-31 10:19:59.151:INFO:oejus.SslContextFactory:main: x509=X509@5d624da6(mykey,h=[],w=[]) for SslContextFactory@2ef9b8bc(file:///Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase/etc/keystore,file:///Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase/etc/keystore)
2017-08-31 10:19:59.273:INFO:oejs.AbstractConnector:main: Started ServerConnector@2b98378d{SSL,[ssl, http/1.1]}{0.0.0.0:8443}
2017-08-31 10:19:59.274:INFO:oejs.Server:main: Started @791ms
....
When modules are enabled, they are loaded with several default options.
These can be changed by editing the associated module ini file in the `start.d` directory (or the associated lines in `server.ini` if your implementation does not use `start.d`).
For example, if we examine the `http.ini` file in our `start.d` directory created above, we will see the following settings:
[source, screen, subs="{sub-order}"]
....
# ---------------------------------------
# Module: http
# Enables a HTTP connector on the server.
# By default HTTP/1 is support, but HTTP2C can
# be added to the connector with the http2c module.
# ---------------------------------------
--module=http
### HTTP Connector Configuration
## Connector host/address to bind to
# jetty.http.host=0.0.0.0
## Connector port to listen on
# jetty.http.port=8080
## Connector idle timeout in milliseconds
# jetty.http.idleTimeout=30000
## Connector socket linger time in seconds (-1 to disable)
# jetty.http.soLingerTime=-1
## Number of acceptors (-1 picks default based on number of cores)
# jetty.http.acceptors=-1
## Number of selectors (-1 picks default based on number of cores)
# jetty.http.selectors=-1
## ServerSocketChannel backlog (0 picks platform default)
# jetty.http.acceptorQueueSize=0
## Thread priority delta to give to acceptor threads
# jetty.http.acceptorPriorityDelta=0
## HTTP Compliance: RFC7230, RFC2616, LEGACY
# jetty.http.compliance=RFC7230
....
To make a change to these settings, uncomment the line (by removing the #) and change the property to the desired value.
For example, if you wanted to change the HTTP port to 5231, you would edit the line as follows:
[source, screen, subs="{sub-order}"]
....
...
## Connector port to listen on
jetty.http.port=5231
...
....
Now when the server is started, HTTP connections will enter on port 5231:
[source, screen, subs="{sub-order}"]
....
[mybase] java -jar ../start.jar
2017-08-31 10:31:32.955:INFO::main: Logging initialized @366ms to org.eclipse.jetty.util.log.StdErrLog
2017-08-31 10:31:33.109:INFO:oejs.Server:main: jetty-9.4.6.v20170531
2017-08-31 10:31:33.146:INFO:oejs.AbstractConnector:main: Started ServerConnector@2ef9b8bc{HTTP/1.1,[http/1.1]}{0.0.0.0:5231}
...
2017-08-31 10:31:33.263:INFO:oejs.Server:main: Started @675ms
....
Every module has their own set of configuration options, and reviewing them all is recommended.
For additional information on the module system, please refer to our documentation on link:#startup-modules[Startup Modules].
____
[NOTE]
Editing these module files is the recommended way to edit the configuration of your server.
Making changes to the associated Jetty XML file for connectors is *not* recommended, and is for advanced users only.
If you do wish to edit Jetty XML, please see our section on managing link:#[Jetty Home and Jetty Base] to ensure your Jetty Home remains a standard of truth for your implementation.
____
==== Advanced Configuration
Jetty primarily uses a single connector type called link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[ServerConnector].
Prior to Jetty 9, the type of the connector specified both the protocol and the implementation used; for example, selector-based non blocking I/O vs blocking I/O, or SSL connector vs non-SSL connector.
Jetty 9 has a single selector-based non-blocking I/O connector, and a collection of link:{JDURL}/org/eclipse/jetty/server/ConnectionFactory.html[`ConnectionFactories`] now configure the protocol on the connector.
____
The standard Jetty distribution comes with the following Jetty XML files that create and configure connectors; you should examine them as you read this section:
@ -48,15 +309,6 @@ link:{GITBROWSEURL}/jetty-http2/http2-server/src/main/config/etc/jetty-http2.xml
link:{GITBROWSEURL}/jetty-alpn/jetty-alpn-server/src/main/config/etc/jetty-alpn.xml[`jetty-alpn.xml`]::
Adds an link:{JDURL}/org/eclipse/jetty/alpn/server/ALPNServerConnectionFactory.html[`ALPNServerConnectionFactory`] to the link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[`ServerConnector`] configured by `jetty-ssl.xml` which allows the one SSL connector to support multiple protocols with the ALPN extension used to select the protocol to be used for each connection.
Typically connectors require very little configuration aside from setting the listening port (see link:#jetty-connectors-network-settings[Network Settings]), and enabling `X-Forwarded-For` customization when applicable. (see link:#jetty-connectors-http-configuration[HTTP Configuration]).
Additional settings are for expert configuration only.
____
[NOTE]
All the connectors discussed in this chapter can be enabled in the Jetty Distribution by enabling them via the module system.
Please refer to our chapter on link:#startup-modules[Managing Startup Modules] for more information.
____
==== Constructing a ServerConnector
The services a link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[`ServerConnector`] instance uses are set by constructor injection and once instantiated cannot be changed.
@ -79,9 +331,9 @@ You can see the other arguments that can be passed when constructing a `ServerCo
Typically the defaults are sufficient for almost all deployments.
[[jetty-connectors-network-settings]]
==== Network Settings.
==== Network Settings
You configure connector network settings by calling setters on the connector before it is started.
You can configure connector network settings by calling setters on the connector before it is started.
For example, you can set the port with the Jetty XML:
[source, xml, subs="{sub-order}"]
@ -107,7 +359,7 @@ Thus typically the port is set within Jetty XML, but uses the `Property` element
</New>
----
The network settings that you can set on the link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[`ServerConnector`] include:
The network settings available for configuration on the link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[`ServerConnector`] include:
.Connector Configuration
[width="100%",cols="22%,78%",options="header",]
@ -238,13 +490,13 @@ These headers can be interpreted by an instance of link:{JDURL}/org/eclipse/jett
===== Proxy Protocol
The http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt[Proxy Protocol] is a de facto standard created by HAProxy and used by environments such as Amazon Elastic Cloud.
The http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt[Proxy Protocol] is the _de facto_ standard created by HAProxy and used by environments such as Amazon Elastic Cloud.
This mechanism is independent of any protocol, so it can be used for HTTP2, TLS etc.
The information about the client connection is sent as a small data frame on each newly established connection.
In Jetty, this protocol can be handled by the link:{JDURL}/org/eclipse/jetty/server/ProxyConnectionFactory.html[`ProxyConnectionFactory`] which parses the data frame and then instantiates the next `ConnectionFactory` on the connection with an end point that has been customized with the data obtained about the original client connection.
The connection factory can be added to any link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[`ServerConnector`] and should be the first link:{JDURL}/org/eclipse/jetty/server/ConnectionFactory.html[`ConnectionFactory`].
An example of adding the factory to a HTTP connector is:
An example of adding the factory to a HTTP connector is shown below:
[source, xml, subs="{sub-order}"]
----

View File

@ -129,13 +129,13 @@ xmlns:date="http://exslt.org/dates-and-times"
</td>
<td style="width: 50%">
<script type="text/javascript"> (function() {
var cx = '016459005284625897022:obd4lsai2ds';
<script>
(function() {
var cx = '005120552842603642412:peimxy9z8nu';
var gcse = document.createElement('script');
gcse.type = 'text/javascript';
gcse.async = true;
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
'//www.google.com/cse/cse.js?cx=' + cx;
gcse.src = 'https://cse.google.com/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(gcse, s);
})();

View File

@ -560,10 +560,6 @@ public class HttpGenerator
for (int f=0;f<n;f++)
{
HttpField field = trailer.getField(f);
String v = field.getValue();
if (v==null || v.length()==0)
continue; // rfc7230 does not allow no value
putTo(field,buffer);
}
@ -662,10 +658,6 @@ public class HttpGenerator
for (int f=0;f<n;f++)
{
HttpField field = fields.getField(f);
String v = field.getValue();
if (v==null || v.length()==0)
continue; // rfc7230 does not allow no value
HttpHeader h = field.getHeader();
if (h==null)
putTo(field,header);

View File

@ -79,6 +79,47 @@ public class HttpGeneratorClientTest
Assert.assertThat(out, Matchers.not(Matchers.containsString("Content-Length")));
}
@Test
public void testEmptyHeaders() throws Exception
{
ByteBuffer header=BufferUtil.allocate(2048);
HttpGenerator gen = new HttpGenerator();
HttpGenerator.Result
result=gen.generateRequest(null,null,null,null, true);
Assert.assertEquals(HttpGenerator.Result.NEED_INFO, result);
Assert.assertEquals(HttpGenerator.State.START, gen.getState());
Info info = new Info("GET","/index.html");
info.getFields().add("Host","something");
info.getFields().add("Null",null);
info.getFields().add("Empty","");
Assert.assertTrue(!gen.isChunking());
result=gen.generateRequest(info,null,null,null, true);
Assert.assertEquals(HttpGenerator.Result.NEED_HEADER, result);
Assert.assertEquals(HttpGenerator.State.START, gen.getState());
result=gen.generateRequest(info,header,null,null, true);
Assert.assertEquals(HttpGenerator.Result.FLUSH, result);
Assert.assertEquals(HttpGenerator.State.COMPLETING, gen.getState());
Assert.assertTrue(!gen.isChunking());
String out = BufferUtil.toString(header);
BufferUtil.clear(header);
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());
Assert.assertEquals(0, gen.getContentPrepared());
Assert.assertThat(out, Matchers.containsString("GET /index.html HTTP/1.1"));
Assert.assertThat(out, Matchers.not(Matchers.containsString("Content-Length")));
Assert.assertThat(out, Matchers.containsString("Empty:"));
Assert.assertThat(out, Matchers.not(Matchers.containsString("Null:")));
}
@Test
public void testPOSTRequestNoContent() throws Exception
{

View File

@ -1168,7 +1168,7 @@ public class SslConnection extends AbstractConnection
@Override
public boolean isInputShutdown()
{
return _sslEngine.isInboundDone();
return getEndPoint().isInputShutdown() || _sslEngine.isInboundDone();
}
private void notifyHandshakeSucceeded(SSLEngine sslEngine)

View File

@ -574,7 +574,7 @@ public class DoSFilter implements Filter
}
else
{
loadId = isRemotePort() ? (request.getRemoteAddr() + request.getRemotePort()) : request.getRemoteAddr();
loadId = isRemotePort() ? createRemotePortId(request) : request.getRemoteAddr();
type = USER_IP;
}
}
@ -607,6 +607,10 @@ public class DoSFilter implements Filter
return tracker;
}
public void addToRateTracker (RateTracker tracker)
{
_rateTrackers.put(tracker.getId(), tracker);
@ -1347,4 +1351,12 @@ public class DoSFilter implements Filter
super.onTimeout(event);
}
}
private String createRemotePortId(final ServletRequest request) {
final String addr = request.getRemoteAddr();
final int port = request.getRemotePort();
if (addr.contains(":")) return "[" + addr + "]:" + port;
return addr + ":" + port;
}
}

View File

@ -18,8 +18,20 @@
package org.eclipse.jetty.servlets;
import javax.servlet.ServletContext;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import java.net.InetSocketAddress;
import java.util.Collections;
import java.util.Enumeration;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.servlets.DoSFilter.RateTracker;
import org.hamcrest.Matchers;
@ -29,12 +41,88 @@ import org.junit.Test;
public class DoSFilterTest extends AbstractDoSFilterTest
{
private static class RemoteAddressRequest extends Request
{
public RemoteAddressRequest(String remoteHost, int remotePort)
{
super(null, null);
setRemoteAddr(new InetSocketAddress(remoteHost, remotePort));
}
}
private static class NoOpFilterConfig implements FilterConfig
{
@Override
public String getFilterName()
{
return "noop";
}
@Override
public ServletContext getServletContext()
{
return null;
}
@Override
public String getInitParameter(String name)
{
return null;
}
@Override
public Enumeration<String> getInitParameterNames()
{
return Collections.emptyEnumeration();
}
}
@Before
public void setUp() throws Exception
{
startServer(DoSFilter.class);
}
@Test
public void testRemotePortLoadIdCreation_ipv6() throws ServletException {
final ServletRequest request = new RemoteAddressRequest("::192.9.5.5", 12345);
DoSFilter doSFilter = new DoSFilter();
doSFilter.init(new NoOpFilterConfig());
doSFilter.setRemotePort(true);
try
{
RateTracker tracker = doSFilter.getRateTracker(request);
assertThat("tracker.id", tracker.getId(),
anyOf(
is("[::192.9.5.5]:12345"), // short form
is("[0:0:0:0:0:0:c009:505]:12345") // long form
));
}
finally
{
doSFilter.stopScheduler();
}
}
@Test
public void testRemotePortLoadIdCreation_ipv4() throws ServletException {
final ServletRequest request = new RemoteAddressRequest("127.0.0.1", 12345);
DoSFilter doSFilter = new DoSFilter();
doSFilter.init(new NoOpFilterConfig());
doSFilter.setRemotePort(true);
try
{
RateTracker tracker = doSFilter.getRateTracker(request);
assertThat("tracker.id", tracker.getId(), is("127.0.0.1:12345"));
}
finally
{
doSFilter.stopScheduler();
}
}
@Test
public void testRateIsRateExceeded() throws InterruptedException
{
@ -70,7 +158,7 @@ public class DoSFilterTest extends AbstractDoSFilterTest
{
String last="GET /ctx/timeout/?sleep="+2*_requestMaxTime+" HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
String responses = doRequests("",0,0,0,last);
Assert.assertThat(responses, Matchers.containsString(" 503 "));
assertThat(responses, Matchers.containsString(" 503 "));
}
private boolean hitRateTracker(DoSFilter doSFilter, int sleep) throws InterruptedException

View File

@ -78,6 +78,9 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
private final int id = ThreadLocalRandom.current().nextInt();
// defaults to true for backwards compatibility
private boolean stopAtShutdown = true;
/**
* Instantiate a WebSocketClient with defaults
*/
@ -552,7 +555,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
private synchronized void init() throws IOException
{
if (!ShutdownThread.isRegistered(this))
if (isStopAtShutdown() && !ShutdownThread.isRegistered(this))
{
ShutdownThread.register(this);
}
@ -722,6 +725,31 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
return this.httpClient;
}
/**
* Set JVM shutdown behavior.
* @param stop If true, this client instance will be explicitly stopped when the
* JVM is shutdown. Otherwise the application is responsible for maintaining the WebSocketClient lifecycle.
* @see Runtime#addShutdownHook(Thread)
* @see ShutdownThread
*/
public synchronized void setStopAtShutdown(boolean stop)
{
if (stop)
{
if (!stopAtShutdown && isStarted() && !ShutdownThread.isRegistered(this))
ShutdownThread.register(this);
}
else
ShutdownThread.deregister(this);
stopAtShutdown = stop;
}
public boolean isStopAtShutdown()
{
return stopAtShutdown;
}
@Override
public String toString()
{