Merged branch 'jetty-9.4.x' into 'master'.
This commit is contained in:
commit
f068780749
22
README.TXT
22
README.TXT
|
@ -1,22 +0,0 @@
|
|||
This is a source checkout of the Eclipse Jetty webserver.
|
||||
|
||||
To build, use:
|
||||
|
||||
mvn clean install
|
||||
|
||||
The jetty distribution will be built in
|
||||
|
||||
jetty-distribution/target/distribution
|
||||
|
||||
The first build may take a long time as Maven downloads all the
|
||||
dependencies.
|
||||
|
||||
The tests do a lot of stress testing, and on some machines it is
|
||||
necessary to set the file descriptor limit to greater than 2048
|
||||
for the tests to all pass successfully.
|
||||
|
||||
Bypass tests by building with -Dmaven.test.skip=true but note
|
||||
that this will not produce some test jars that are leveraged
|
||||
in other places in the build.
|
||||
|
||||
See also README.md
|
17
README.md
17
README.md
|
@ -33,7 +33,22 @@ Documentation
|
|||
Project documentation is located on our Eclipse website.
|
||||
|
||||
- [http://www.eclipse.org/jetty/documentation](http://www.eclipse.org/jetty/documentation)
|
||||
- README.TXT
|
||||
|
||||
Building
|
||||
========
|
||||
|
||||
To build, use:
|
||||
```shell
|
||||
mvn clean install
|
||||
```
|
||||
|
||||
The jetty distribution will be built in `jetty-distribution/target/distribution`
|
||||
|
||||
The first build may take a long time as Maven downloads all the dependencies.
|
||||
|
||||
The tests do a lot of stress testing, and on some machines it is necessary to set the file descriptor limit to greater than 2048 for the tests to all pass successfully.
|
||||
|
||||
Bypass tests by building with `mvn -Dmaven.test.skip=true install` but note that this will not produce some test jars that are leveraged in other places in the build.
|
||||
|
||||
Professional Services
|
||||
---------------------
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
[name]
|
||||
alpn-boot
|
||||
|
||||
[files]
|
||||
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.9.v20160720/alpn-boot-8.1.9.v20160720.jar|lib/alpn/alpn-boot-8.1.9.v20160720.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.9.v20160720.jar
|
|
@ -0,0 +1,8 @@
|
|||
[name]
|
||||
alpn-boot
|
||||
|
||||
[files]
|
||||
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.9.v20160720/alpn-boot-8.1.9.v20160720.jar|lib/alpn/alpn-boot-8.1.9.v20160720.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.9.v20160720.jar
|
|
@ -26,15 +26,15 @@ For those browsers that support HTTP/2, they all now support the ALPN negotiatio
|
|||
|
||||
Starting with Jetty 9.3.0, only ALPN is supported by Jetty.
|
||||
|
||||
The Jetty project provides an implementation of the TLS extension for ALPN for OpenJDK 7 and OpenJDK 8.
|
||||
The Jetty project provides an implementation of the TLS extension for ALPN for OpenJDK 7 and OpenJDK 8.
|
||||
ALPN allows the application layer to negotiate which protocol to use over the secure connection.
|
||||
|
||||
Any protocol can be negotiated by ALPN within a TLS connection.
|
||||
The protocols that are most commonly negotiated are HTTP/2 (for browsers that support it) and, historically, SPDY.
|
||||
The ALPN implementation is therefore not HTTP/2 or SPDY specific in any way.
|
||||
Any protocol can be negotiated by ALPN within a TLS connection.
|
||||
The protocols that are most commonly negotiated are HTTP/2 (for browsers that support it) and, historically, SPDY.
|
||||
The ALPN implementation is therefore not HTTP/2 or SPDY specific in any way.
|
||||
Jetty's ALPN implementation, although hosted under the umbrella of the Jetty project, is independent of Jetty (the Servlet Container); you can use the ALPN implementation in any other Java network server.
|
||||
|
||||
The Jetty distribution will automatically enable ALPN when it is needed to by a HTTP/2 connector, so for the most part ALPN is transparent to the average deployer.
|
||||
The Jetty distribution will automatically enable ALPN when it is needed to by a HTTP/2 connector, so for the most part ALPN is transparent to the average deployer.
|
||||
This section provides the detail required for unusual deployments or developing to the ALPN API.
|
||||
|
||||
[[alpn-starting]]
|
||||
|
@ -54,7 +54,7 @@ Be certain link:#alpn-versions[to get the ALPN Boot Jar version which matches th
|
|||
[[alpn-osgi]]
|
||||
===== Starting in OSGi
|
||||
|
||||
To use ALPN in an OSGi environment, in addition to putting the ALPN jar on the boot classpath for the container, you will also need to deploy the jetty-osgi-alpn jar.
|
||||
To use ALPN in an OSGi environment, in addition to putting the ALPN jar on the boot classpath for the container, you will also need to deploy the jetty-osgi-alpn jar.
|
||||
This jar contains a Fragment-Host directive that ensures the ALPN classes will be available from the system bundle.
|
||||
|
||||
You can download the http://central.maven.org/maven2/org/eclipse/jetty/osgi/jetty-osgi-alpn/[jetty-osgi-alpn jar] from Maven Central.
|
||||
|
@ -62,14 +62,14 @@ You can download the http://central.maven.org/maven2/org/eclipse/jetty/osgi/jett
|
|||
[[alpn-understanding]]
|
||||
==== Understanding the ALPN API
|
||||
|
||||
Applications need to interact with ALPN TLS extension protocol negotiations.
|
||||
Applications need to interact with ALPN TLS extension protocol negotiations.
|
||||
For example, server applications need to know whether the client supports ALPN, and client applications needs to know whether the server supports ALPN.
|
||||
|
||||
To implement this interaction, Jetty's ALPN implementation provides an API to applications, hosted at Maven coordinates
|
||||
`org.eclipse.jetty.alpn:alpn-api`.
|
||||
`org.eclipse.jetty.alpn:alpn-api`.
|
||||
You need to declare this dependency as provided, because the `alpn-boot` Jar already includes it (see the previous section), and it is therefore available from the boot classpath.
|
||||
|
||||
The API consists of a single class, `org.eclipse.jetty.alpn.ALPN`, and applications need to register instances of `SSLSocket` or `SSLEngine` with a `ClientProvider` or `ServerProvider` (depending on whether the application is a client application or server application).
|
||||
The API consists of a single class, `org.eclipse.jetty.alpn.ALPN`, and applications need to register instances of `SSLSocket` or `SSLEngine` with a `ClientProvider` or `ServerProvider` (depending on whether the application is a client application or server application).
|
||||
Refer to `ALPN` Javadocs and to the examples below for further details about client and server provider methods.
|
||||
|
||||
[[alpn-client-example]]
|
||||
|
@ -156,7 +156,7 @@ Failing to do so will cause a memory leak.
|
|||
[[alpn-tests]]
|
||||
==== Unit Tests
|
||||
|
||||
You can write and run unit tests that use the ALPN implementation.
|
||||
You can write and run unit tests that use the ALPN implementation.
|
||||
The solution that we use with Maven is to specify an additional command line argument to the Surefire plugin:
|
||||
|
||||
[source, xml, subs="{sub-order}"]
|
||||
|
@ -202,7 +202,7 @@ Since the ALPN class is in the boot classpath, we chose not to use logging libra
|
|||
[[alpn-license-details]]
|
||||
==== License Details
|
||||
|
||||
The ALPN implementation relies on modification of a few OpenJDK classes and on a few new classes that need to live in the `sun.security.ssl` package.
|
||||
The ALPN implementation relies on modification of a few OpenJDK classes and on a few new classes that need to live in the `sun.security.ssl` package.
|
||||
These classes are released under the same GPLv2+exception license of OpenJDK.
|
||||
|
||||
The ALPN class and its nested classes are released under same license as the classes of the Jetty project.
|
||||
|
@ -248,6 +248,8 @@ The ALPN implementation, relying on modifications of OpenJDK classes, updates ev
|
|||
|1.8.0u77 |8.1.7.v20160121
|
||||
|1.8.0u91 |8.1.7.v20160121
|
||||
|1.8.0u92 |8.1.8.v20160420
|
||||
|1.8.0u101 |8.1.9.v20160720
|
||||
|1.8.0u102 |8.1.9.v20160720
|
||||
|=============================
|
||||
|
||||
[[alpn-build]]
|
||||
|
@ -263,7 +265,7 @@ $ hg clone http://hg.openjdk.java.net/jdk7u/jdk7u jdk7u # OpenJDK 7
|
|||
$ hg clone http://hg.openjdk.java.net/jdk8u/jdk8u jdk8u # OpenJDK 8
|
||||
$ cd !$
|
||||
$ ./get_source.sh
|
||||
|
||||
|
||||
....
|
||||
|
||||
To update the source to a specific tag, use the following command:
|
||||
|
@ -271,7 +273,7 @@ To update the source to a specific tag, use the following command:
|
|||
[source, screen, subs="{sub-order}"]
|
||||
....
|
||||
$ ./make/scripts/hgforest.sh update <tag-name>
|
||||
|
||||
|
||||
....
|
||||
|
||||
The list of OpenJDK tags can be obtained from these pages:
|
||||
|
|
|
@ -907,7 +907,7 @@ public class HttpParser
|
|||
|
||||
case HOST:
|
||||
_host=true;
|
||||
if (!(_field instanceof HostPortHttpField))
|
||||
if (!(_field instanceof HostPortHttpField) && _valueString!=null && !_valueString.isEmpty())
|
||||
{
|
||||
_field=new HostPortHttpField(_header,legacyString(_headerString,_header.asString()),_valueString);
|
||||
add_to_connection_trie=_connectionFields!=null;
|
||||
|
|
|
@ -18,21 +18,24 @@
|
|||
|
||||
package org.eclipse.jetty.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jetty.util.ArrayTrie;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Loader;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.Trie;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
@ -200,16 +203,36 @@ public class MimeTypes
|
|||
|
||||
try
|
||||
{
|
||||
ResourceBundle mime = ResourceBundle.getBundle("org/eclipse/jetty/http/mime");
|
||||
Enumeration<String> i = mime.getKeys();
|
||||
while(i.hasMoreElements())
|
||||
String resourceName = "org/eclipse/jetty/http/mime.properties";
|
||||
URL mimeTypesUrl = Loader.getResource(resourceName);
|
||||
if (mimeTypesUrl == null)
|
||||
{
|
||||
String ext = i.nextElement();
|
||||
String m = mime.getString(ext);
|
||||
__dftMimeMap.put(StringUtil.asciiToLowerCase(ext),normalizeMimeType(m));
|
||||
LOG.warn("Missing mime-type resource: {}", resourceName);
|
||||
}
|
||||
else
|
||||
{
|
||||
try (InputStream in = mimeTypesUrl.openStream();
|
||||
InputStreamReader reader = new InputStreamReader(in, StandardCharsets.UTF_8))
|
||||
{
|
||||
Properties mime = new Properties();
|
||||
mime.load(reader);
|
||||
mime.stringPropertyNames().stream()
|
||||
.filter(x->x!=null)
|
||||
.forEach(x->
|
||||
__dftMimeMap.put(StringUtil.asciiToLowerCase(x), normalizeMimeType(mime.getProperty(x))));
|
||||
|
||||
if (__dftMimeMap.size()<mime.size())
|
||||
{
|
||||
LOG.warn("Encountered duplicate or null mime-type extension in resource: {}", mimeTypesUrl);
|
||||
}
|
||||
}
|
||||
if (__dftMimeMap.size()==0)
|
||||
{
|
||||
LOG.warn("Empty mime types declaration at {}", mimeTypesUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(MissingResourceException e)
|
||||
catch(IOException e)
|
||||
{
|
||||
LOG.warn(e.toString());
|
||||
LOG.debug(e);
|
||||
|
@ -217,15 +240,37 @@ public class MimeTypes
|
|||
|
||||
try
|
||||
{
|
||||
ResourceBundle encoding = ResourceBundle.getBundle("org/eclipse/jetty/http/encoding");
|
||||
Enumeration<String> i = encoding.getKeys();
|
||||
while(i.hasMoreElements())
|
||||
String resourceName = "org/eclipse/jetty/http/encoding.properties";
|
||||
URL mimeTypesUrl = Loader.getResource(resourceName);
|
||||
if (mimeTypesUrl == null)
|
||||
{
|
||||
String type = i.nextElement();
|
||||
__encodings.put(type,encoding.getString(type));
|
||||
LOG.warn("Missing mime-type resource: {}", resourceName);
|
||||
}
|
||||
else
|
||||
{
|
||||
try (InputStream in = mimeTypesUrl.openStream();
|
||||
InputStreamReader reader = new InputStreamReader(in, StandardCharsets.UTF_8))
|
||||
{
|
||||
Properties encoding = new Properties();
|
||||
encoding.load(reader);
|
||||
|
||||
encoding.stringPropertyNames().stream()
|
||||
.filter(t->t!=null)
|
||||
.forEach(t->__encodings.put(t, encoding.getProperty(t)));
|
||||
|
||||
if (__encodings.size()<encoding.size())
|
||||
{
|
||||
LOG.warn("Encountered null or duplicate encoding type in resource: {}", mimeTypesUrl);
|
||||
}
|
||||
}
|
||||
|
||||
if (__encodings.size()==0)
|
||||
{
|
||||
LOG.warn("Empty mime types declaration at {}", mimeTypesUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(MissingResourceException e)
|
||||
catch(IOException e)
|
||||
{
|
||||
LOG.warn(e.toString());
|
||||
LOG.debug(e);
|
||||
|
|
|
@ -1707,6 +1707,21 @@ public class HttpParserTest
|
|||
Assert.assertEquals(8888, _port);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyHostPort() throws Exception
|
||||
{
|
||||
ByteBuffer buffer = BufferUtil.toBuffer(
|
||||
"GET / HTTP/1.1\r\n"
|
||||
+ "Host:\r\n"
|
||||
+ "Connection: close\r\n"
|
||||
+ "\r\n");
|
||||
|
||||
HttpParser.RequestHandler handler = new Handler();
|
||||
HttpParser parser = new HttpParser(handler);
|
||||
parser.parseNext(buffer);
|
||||
Assert.assertEquals(null, _host);
|
||||
Assert.assertEquals(null, _bad);
|
||||
}
|
||||
@Test
|
||||
public void testCachedField() throws Exception
|
||||
{
|
||||
|
|
|
@ -1330,12 +1330,14 @@ public class Request implements HttpServletRequest
|
|||
HttpField host = metadata==null?null:metadata.getFields().getField(HttpHeader.HOST);
|
||||
if (host!=null)
|
||||
{
|
||||
// TODO is this needed now?
|
||||
HostPortHttpField authority = (host instanceof HostPortHttpField)
|
||||
?((HostPortHttpField)host)
|
||||
:new HostPortHttpField(host.getValue());
|
||||
metadata.getURI().setAuthority(authority.getHost(),authority.getPort());
|
||||
return authority.getHost();
|
||||
if (!(host instanceof HostPortHttpField) && host.getValue()!=null && !host.getValue().isEmpty())
|
||||
host=new HostPortHttpField(host.getValue());
|
||||
if (host instanceof HostPortHttpField)
|
||||
{
|
||||
HostPortHttpField authority = (HostPortHttpField)host;
|
||||
metadata.getURI().setAuthority(authority.getHost(),authority.getPort());
|
||||
return authority.getHost();
|
||||
}
|
||||
}
|
||||
|
||||
// Return host from connection
|
||||
|
|
|
@ -396,6 +396,27 @@ public class HttpConnectionTest
|
|||
checkContains(response,0,"HTTP/1.1 400");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoHost() throws Exception
|
||||
{
|
||||
String response;
|
||||
|
||||
response=connector.getResponse("GET / HTTP/1.1\r\n"+
|
||||
"\r\n");
|
||||
checkContains(response,0,"HTTP/1.1 400");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyHost() throws Exception
|
||||
{
|
||||
String response;
|
||||
|
||||
response=connector.getResponse("GET / HTTP/1.1\r\n"+
|
||||
"Host:\r\n"+
|
||||
"\r\n");
|
||||
checkContains(response,0,"HTTP/1.1 200");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBadURIencoding() throws Exception
|
||||
{
|
||||
|
|
|
@ -591,7 +591,7 @@ public class PartialRFC2616Test
|
|||
|
||||
offset=0;
|
||||
response=connector.getResponse("GET /R1 HTTP/1.1\n"+"Host:\n"+"Connection: close\n"+"\n");
|
||||
offset=checkContains(response,offset,"HTTP/1.1 400","400")+1;
|
||||
offset=checkContains(response,offset,"HTTP/1.1 200","200")+1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -966,7 +966,7 @@ public class StartArgs
|
|||
licenseCheckRequired = true;
|
||||
return;
|
||||
}
|
||||
if (arg.startsWith("--add=") || arg.startsWith("--add-to-start="))
|
||||
if (arg.startsWith("--add-to-start="))
|
||||
{
|
||||
startModules.addAll(Props.getValues(arg));
|
||||
run = false;
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
[name]
|
||||
alpn-boot
|
||||
|
||||
[files]
|
||||
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.9.v20160720/alpn-boot-8.1.9.v20160720.jar|lib/alpn/alpn-boot-8.1.9.v20160720.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.9.v20160720.jar
|
|
@ -0,0 +1,8 @@
|
|||
[name]
|
||||
alpn-boot
|
||||
|
||||
[files]
|
||||
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.9.v20160720/alpn-boot-8.1.9.v20160720.jar|lib/alpn/alpn-boot-8.1.9.v20160720.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.9.v20160720.jar
|
26
pom.xml
26
pom.xml
|
@ -17,7 +17,7 @@
|
|||
<build-support-version>1.4</build-support-version>
|
||||
<slf4j-version>1.6.6</slf4j-version>
|
||||
<jetty-test-policy-version>1.2</jetty-test-policy-version>
|
||||
<alpn.api.version>1.1.2.v20150522</alpn.api.version>
|
||||
<alpn.api.version>1.1.3.v20160715</alpn.api.version>
|
||||
<jsp.version>8.0.33</jsp.version>
|
||||
<!-- default values are unsupported, but required to be defined for reactor sanity reasons -->
|
||||
<alpn.version>undefined</alpn.version>
|
||||
|
@ -1370,6 +1370,30 @@
|
|||
<alpn.version>8.1.8.v20160420</alpn.version>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>8u101</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>java.version</name>
|
||||
<value>1.8.0_101</value>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<alpn.version>8.1.9.v20160720</alpn.version>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>8u102</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>java.version</name>
|
||||
<value>1.8.0_102</value>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<alpn.version>8.1.9.v20160720</alpn.version>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<issueManagement>
|
||||
|
|
|
@ -1459,7 +1459,7 @@ public abstract class RFC2616BaseTest
|
|||
req4.append("\n");
|
||||
|
||||
HttpTester.Response response = http.request(req4);
|
||||
assertEquals("14.23 HTTP/1.1 - Empty Host", HttpStatus.BAD_REQUEST_400, response.getStatus());
|
||||
assertEquals("14.23 HTTP/1.1 - Empty Host", HttpStatus.OK_200, response.getStatus());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue