Merge branch 'jetty-9.4.x'

This commit is contained in:
Jesse McConnell 2017-01-27 17:16:24 -06:00
commit 9574ec2fa1
9 changed files with 134 additions and 28 deletions

View File

@ -430,18 +430,6 @@
<artifactId>jetty-deploy</artifactId> <artifactId>jetty-deploy</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>test-jetty-webapp</artifactId>
<type>war</type>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>test-proxy-webapp</artifactId>
<type>war</type>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jmx</artifactId> <artifactId>jetty-jmx</artifactId>

View File

@ -31,6 +31,20 @@
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Require-Capability>osgi.serviceloader; filter:="(osgi.serviceloader=org.eclipse.jetty.http.HttpFieldPreEncoder)";resolution:=optional;cardinality:=multiple, osgi.extender; filter:="(osgi.extender=osgi.serviceloader.processor)", osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)"</Require-Capability>
<!--
<Require-Capability>osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)"</Require-Capability>
-->
<Provide-Capability>osgi.serviceloader; osgi.serviceloader=org.eclipse.jetty.http.HttpFieldPreEncoder</Provide-Capability>
</instructions>
</configuration>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId> <artifactId>maven-jar-plugin</artifactId>
@ -50,6 +64,7 @@
<onlyAnalyze>org.eclipse.jetty.http.*</onlyAnalyze> <onlyAnalyze>org.eclipse.jetty.http.*</onlyAnalyze>
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
</project> </project>

View File

@ -614,7 +614,7 @@ public class HttpGenerator
HttpField transfer_encoding=null; HttpField transfer_encoding=null;
boolean http11 = info.getHttpVersion() == HttpVersion.HTTP_1_1; boolean http11 = info.getHttpVersion() == HttpVersion.HTTP_1_1;
boolean close = false; boolean close = false;
boolean chunked = false; boolean chunked_hint = false;
boolean content_type = false; boolean content_type = false;
long content_length = info.getContentLength(); long content_length = info.getContentLength();
boolean content_length_field = false; boolean content_length_field = false;
@ -661,7 +661,7 @@ public class HttpGenerator
// Don't add yet, treat this only as a hint that there is content // Don't add yet, treat this only as a hint that there is content
// with a preference to chunk if we can // with a preference to chunk if we can
transfer_encoding = field; transfer_encoding = field;
chunked = field.contains(HttpHeaderValue.CHUNKED.asString()); chunked_hint = field.contains(HttpHeaderValue.CHUNKED.asString());
} }
break; break;
} }
@ -704,7 +704,7 @@ public class HttpGenerator
// settings from http://tools.ietf.org/html/rfc7230#section-3.3.3 // settings from http://tools.ietf.org/html/rfc7230#section-3.3.3
boolean assumed_content_request = request!=null && Boolean.TRUE.equals(__assumedContentMethods.get(request.getMethod())); boolean assumed_content_request = request!=null && Boolean.TRUE.equals(__assumedContentMethods.get(request.getMethod()));
boolean assumed_content = assumed_content_request || content_type || chunked; boolean assumed_content = assumed_content_request || content_type || chunked_hint;
boolean nocontent_request = request!=null && content_length<=0 && !assumed_content; boolean nocontent_request = request!=null && content_length<=0 && !assumed_content;
// If the message is known not to have content // If the message is known not to have content
@ -728,12 +728,11 @@ public class HttpGenerator
} }
} }
// Else if we are HTTP/1.1 and the content length is unknown and we are either persistent // Else if we are HTTP/1.1 and the content length is unknown and we are either persistent
// or it is a request with content (which cannot EOF) // or it is a request with content (which cannot EOF) or the app has requested chunking
else if (http11 && content_length<0 && (_persistent || assumed_content_request)) else if (http11 && content_length<0 && (_persistent || assumed_content_request || chunked_hint))
{ {
// we use chunking // we use chunking
_endOfContent = EndOfContent.CHUNKED_CONTENT; _endOfContent = EndOfContent.CHUNKED_CONTENT;
chunked = true;
// try to use user supplied encoding as it may have other values. // try to use user supplied encoding as it may have other values.
if (transfer_encoding == null) if (transfer_encoding == null)
@ -743,6 +742,11 @@ public class HttpGenerator
putTo(transfer_encoding,header); putTo(transfer_encoding,header);
transfer_encoding = null; transfer_encoding = null;
} }
else if (!chunked_hint)
{
putTo(new HttpField(HttpHeader.TRANSFER_ENCODING,transfer_encoding.getValue()+",chunked"),header);
transfer_encoding = null;
}
else else
throw new BadMessageException(INTERNAL_SERVER_ERROR_500,"Bad Transfer-Encoding"); throw new BadMessageException(INTERNAL_SERVER_ERROR_500,"Bad Transfer-Encoding");
} }
@ -776,8 +780,20 @@ public class HttpGenerator
LOG.debug(_endOfContent.toString()); LOG.debug(_endOfContent.toString());
// Add transfer encoding if it is not chunking // Add transfer encoding if it is not chunking
if (transfer_encoding!=null && !chunked) if (transfer_encoding!=null)
putTo(transfer_encoding,header); {
if (chunked_hint)
{
String v = transfer_encoding.getValue();
int c = v.lastIndexOf(',');
if (c>0 && v.lastIndexOf(HttpHeaderValue.CHUNKED.toString(),c)>c)
putTo(new HttpField(HttpHeader.TRANSFER_ENCODING,v.substring(0,c).trim()),header);
}
else
{
putTo(transfer_encoding,header);
}
}
// Send server? // Send server?
int status=response!=null?response.getStatus():-1; int status=response!=null?response.getStatus():-1;

View File

@ -47,7 +47,7 @@ public class PreEncodedHttpField extends HttpField
static static
{ {
List<HttpFieldPreEncoder> encoders = new ArrayList<>(); List<HttpFieldPreEncoder> encoders = new ArrayList<>();
Iterator<HttpFieldPreEncoder> iter = ServiceLoader.load(HttpFieldPreEncoder.class,PreEncodedHttpField.class.getClassLoader()).iterator(); Iterator<HttpFieldPreEncoder> iter = ServiceLoader.load(HttpFieldPreEncoder.class).iterator();
while (iter.hasNext()) while (iter.hasNext())
{ {
try try
@ -118,4 +118,4 @@ public class PreEncodedHttpField extends HttpField
{ {
bufferInFillMode.put(_encodedField[index(version)]); bufferInFillMode.put(_encodedField[index(version)]);
} }
} }

View File

@ -409,7 +409,6 @@ public class HttpGeneratorServerTest
assertEquals(HttpGenerator.Result.DONE, result); assertEquals(HttpGenerator.Result.DONE, result);
assertEquals(HttpGenerator.State.END, gen.getState()); assertEquals(HttpGenerator.State.END, gen.getState());
assertThat(out, containsString("HTTP/1.1 200 OK")); assertThat(out, containsString("HTTP/1.1 200 OK"));
assertThat(out, containsString("Last-Modified: Thu, 01 Jan 1970 00:00:00 GMT")); assertThat(out, containsString("Last-Modified: Thu, 01 Jan 1970 00:00:00 GMT"));
assertThat(out, not(containsString("Content-Length"))); assertThat(out, not(containsString("Content-Length")));
@ -423,6 +422,73 @@ public class HttpGeneratorServerTest
"0\r\n"+ "0\r\n"+
"\r\n")); "\r\n"));
} }
@Test
public void testResponseWithHintedChunkedContent() throws Exception
{
ByteBuffer header = BufferUtil.allocate(4096);
ByteBuffer chunk = BufferUtil.allocate(HttpGenerator.CHUNK_SIZE);
ByteBuffer content0 = BufferUtil.toBuffer("Hello World! ");
ByteBuffer content1 = BufferUtil.toBuffer("The quick brown fox jumped over the lazy dog. ");
HttpGenerator gen = new HttpGenerator();
gen.setPersistent(false);
HttpGenerator.Result result = gen.generateResponse(null, null, null, content0, false);
assertEquals(HttpGenerator.Result.NEED_INFO, result);
assertEquals(HttpGenerator.State.START, gen.getState());
MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 200, null, new HttpFields(), -1);
info.getFields().add("Last-Modified", DateGenerator.__01Jan1970);
info.getFields().add(HttpHeader.TRANSFER_ENCODING, HttpHeaderValue.CHUNKED);
result = gen.generateResponse(info, null, null, content0, false);
assertEquals(HttpGenerator.Result.NEED_HEADER, result);
assertEquals(HttpGenerator.State.START, gen.getState());
result = gen.generateResponse(info, header, null, content0, false);
assertEquals(HttpGenerator.Result.FLUSH, result);
assertEquals(HttpGenerator.State.COMMITTED, gen.getState());
String out = BufferUtil.toString(header);
BufferUtil.clear(header);
out += BufferUtil.toString(content0);
BufferUtil.clear(content0);
result = gen.generateResponse(null, null, chunk, content1, false);
assertEquals(HttpGenerator.Result.FLUSH, result);
assertEquals(HttpGenerator.State.COMMITTED, gen.getState());
out += BufferUtil.toString(chunk);
BufferUtil.clear(chunk);
out += BufferUtil.toString(content1);
BufferUtil.clear(content1);
result = gen.generateResponse(null, null, chunk, null, true);
assertEquals(HttpGenerator.Result.CONTINUE, result);
assertEquals(HttpGenerator.State.COMPLETING, gen.getState());
result = gen.generateResponse(null, null, chunk, null, true);
assertEquals(HttpGenerator.Result.FLUSH, result);
assertEquals(HttpGenerator.State.COMPLETING, gen.getState());
out += BufferUtil.toString(chunk);
BufferUtil.clear(chunk);
result = gen.generateResponse(null, null, chunk, null, true);
assertEquals(HttpGenerator.Result.SHUTDOWN_OUT, result);
assertEquals(HttpGenerator.State.END, gen.getState());
assertThat(out, containsString("HTTP/1.1 200 OK"));
assertThat(out, containsString("Last-Modified: Thu, 01 Jan 1970 00:00:00 GMT"));
assertThat(out, not(containsString("Content-Length")));
assertThat(out, containsString("Transfer-Encoding: chunked"));
assertThat(out, endsWith(
"\r\n\r\nD\r\n"+
"Hello World! \r\n"+
"2E\r\n"+
"The quick brown fox jumped over the lazy dog. \r\n"+
"0\r\n"+
"\r\n"));
}
@Test @Test
public void testResponseWithKnownContentLengthFromMetaData() throws Exception public void testResponseWithKnownContentLengthFromMetaData() throws Exception

View File

@ -43,6 +43,21 @@
</dependencies> </dependencies>
<build> <build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-Description>Http2 Hpack</Bundle-Description>
<Require-Capability>osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)"</Require-Capability>
<Provide-Capability>osgi.serviceloader;osgi.serviceloader=org.eclipse.jetty.http.HttpFieldPreEncoder</Provide-Capability>
<_nouses>true</_nouses>
</instructions>
</configuration>
</plugin>
</plugins>
</build> </build>
</project> </project>

View File

@ -318,6 +318,11 @@
<artifactId>http2-server</artifactId> <artifactId>http2-server</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-hpack</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty.osgi</groupId> <groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-alpn</artifactId> <artifactId>jetty-osgi-alpn</artifactId>

View File

@ -107,7 +107,7 @@ public class TestJettyOSGiBootCore
res.add(mavenBundle().groupId( "org.eclipse.jetty" ).artifactId( "jetty-deploy" ).versionAsInProject().noStart()); res.add(mavenBundle().groupId( "org.eclipse.jetty" ).artifactId( "jetty-deploy" ).versionAsInProject().noStart());
res.add(mavenBundle().groupId( "org.eclipse.jetty" ).artifactId( "jetty-server" ).versionAsInProject().noStart()); res.add(mavenBundle().groupId( "org.eclipse.jetty" ).artifactId( "jetty-server" ).versionAsInProject().noStart());
res.add(mavenBundle().groupId( "org.eclipse.jetty" ).artifactId( "jetty-servlet" ).versionAsInProject().noStart()); res.add(mavenBundle().groupId( "org.eclipse.jetty" ).artifactId( "jetty-servlet" ).versionAsInProject().noStart());
res.add(mavenBundle().groupId( "org.eclipse.jetty" ).artifactId( "jetty-http" ).versionAsInProject().noStart()); res.add(mavenBundle().groupId( "org.eclipse.jetty" ).artifactId( "jetty-http" ).versionAsInProject());
res.add(mavenBundle().groupId( "org.eclipse.jetty" ).artifactId( "jetty-xml" ).versionAsInProject().noStart()); res.add(mavenBundle().groupId( "org.eclipse.jetty" ).artifactId( "jetty-xml" ).versionAsInProject().noStart());
res.add(mavenBundle().groupId( "org.eclipse.jetty" ).artifactId( "jetty-webapp" ).versionAsInProject().noStart()); res.add(mavenBundle().groupId( "org.eclipse.jetty" ).artifactId( "jetty-webapp" ).versionAsInProject().noStart());
res.add(mavenBundle().groupId( "org.eclipse.jetty" ).artifactId( "jetty-io" ).versionAsInProject().noStart()); res.add(mavenBundle().groupId( "org.eclipse.jetty" ).artifactId( "jetty-io" ).versionAsInProject().noStart());

View File

@ -81,9 +81,9 @@ public class TestJettyOSGiBootHTTP2
res.add(mavenBundle().groupId("org.eclipse.jetty.osgi").artifactId("jetty-osgi-alpn").versionAsInProject().noStart()); res.add(mavenBundle().groupId("org.eclipse.jetty.osgi").artifactId("jetty-osgi-alpn").versionAsInProject().noStart());
res.add(mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-alpn-server").versionAsInProject().start()); res.add(mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-alpn-server").versionAsInProject().start());
res.add(mavenBundle().groupId("org.eclipse.jetty.http2").artifactId("http2-common").versionAsInProject().noStart()); res.add(mavenBundle().groupId("org.eclipse.jetty.http2").artifactId("http2-common").versionAsInProject());
res.add(mavenBundle().groupId("org.eclipse.jetty.http2").artifactId("http2-hpack").versionAsInProject().noStart()); res.add(mavenBundle().groupId("org.eclipse.jetty.http2").artifactId("http2-hpack").versionAsInProject());
res.add(mavenBundle().groupId("org.eclipse.jetty.http2").artifactId("http2-server").versionAsInProject().noStart()); res.add(mavenBundle().groupId("org.eclipse.jetty.http2").artifactId("http2-server").versionAsInProject());
return res; return res;
} }
@ -99,7 +99,8 @@ public class TestJettyOSGiBootHTTP2
@Test @Test
public void assertAllBundlesActiveOrResolved() throws Exception public void assertAllBundlesActiveOrResolved() throws Exception
{ {
TestOSGiUtil.assertAllBundlesActiveOrResolved(bundleContext); //TestOSGiUtil.assertAllBundlesActiveOrResolved(bundleContext);
TestOSGiUtil.debugBundles(bundleContext);
} }