Merge branch 'jetty-9.4.x' of github.com:eclipse/jetty.project into jetty-9.4.x

This commit is contained in:
Joakim Erdfelt 2018-05-21 16:34:06 -05:00
commit 04c1447f88
184 changed files with 5212 additions and 2723 deletions

4
Jenkinsfile vendored
View File

@ -46,7 +46,7 @@ def getFullBuild(jdk, os) {
publisherStrategy: 'EXPLICIT',
globalMavenSettingsConfig: settingsName,
mavenLocalRepo: localRepo) {
sh "mvn -V -B clean install -DskipTests -T6"
sh "mvn -V -B clean install -DskipTests -T6 -e"
}
}
@ -68,7 +68,7 @@ def getFullBuild(jdk, os) {
publisherStrategy: 'EXPLICIT',
globalMavenSettingsConfig: settingsName,
mavenLocalRepo: localRepo) {
sh "mvn -V -B javadoc:javadoc -T6"
sh "mvn -V -B javadoc:javadoc -T6 -e"
}
}
}

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[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
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.9.v20160720|lib/alpn/alpn-boot-8.1.9.v20160720.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.9.v20160720.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[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
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.9.v20160720|lib/alpn/alpn-boot-8.1.9.v20160720.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.9.v20160720.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[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
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.9.v20160720|lib/alpn/alpn-boot-8.1.9.v20160720.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.9.v20160720.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.10.v20161026/alpn-boot-8.1.10.v20161026.jar|lib/alpn/alpn-boot-8.1.10.v20161026.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.10.v20161026|lib/alpn/alpn-boot-8.1.10.v20161026.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.10.v20161026.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.12.v20180117/alpn-boot-8.1.12.v20180117.jar|lib/alpn/alpn-boot-8.1.12.v20180117.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.12.v20180117|lib/alpn/alpn-boot-8.1.12.v20180117.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.12.v20180117.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.12.v20180117/alpn-boot-8.1.12.v20180117.jar|lib/alpn/alpn-boot-8.1.12.v20180117.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.12.v20180117|lib/alpn/alpn-boot-8.1.12.v20180117.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.12.v20180117.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.12.v20180117/alpn-boot-8.1.12.v20180117.jar|lib/alpn/alpn-boot-8.1.12.v20180117.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.12.v20180117|lib/alpn/alpn-boot-8.1.12.v20180117.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.12.v20180117.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.12.v20180117/alpn-boot-8.1.12.v20180117.jar|lib/alpn/alpn-boot-8.1.12.v20180117.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.12.v20180117|lib/alpn/alpn-boot-8.1.12.v20180117.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.12.v20180117.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.3.v20150130/alpn-boot-8.1.3.v20150130.jar|lib/alpn/alpn-boot-8.1.3.v20150130.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.3.v20150130|lib/alpn/alpn-boot-8.1.3.v20150130.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.3.v20150130.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.3.v20150130/alpn-boot-8.1.3.v20150130.jar|lib/alpn/alpn-boot-8.1.3.v20150130.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.3.v20150130|lib/alpn/alpn-boot-8.1.3.v20150130.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.3.v20150130.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.4.v20150727/alpn-boot-8.1.4.v20150727.jar|lib/alpn/alpn-boot-8.1.4.v20150727.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.4.v20150727|lib/alpn/alpn-boot-8.1.4.v20150727.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.4.v20150727.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.5.v20150921/alpn-boot-8.1.5.v20150921.jar|lib/alpn/alpn-boot-8.1.5.v20150921.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.5.v20150921|lib/alpn/alpn-boot-8.1.5.v20150921.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.5.v20150921.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.6.v20151105/alpn-boot-8.1.6.v20151105.jar|lib/alpn/alpn-boot-8.1.6.v20151105.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.6.v20151105|lib/alpn/alpn-boot-8.1.6.v20151105.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.6.v20151105.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.6.v20151105/alpn-boot-8.1.6.v20151105.jar|lib/alpn/alpn-boot-8.1.6.v20151105.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.6.v20151105|lib/alpn/alpn-boot-8.1.6.v20151105.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.6.v20151105.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.7.v20160121|lib/alpn/alpn-boot-8.1.7.v20160121.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.7.v20160121.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.7.v20160121|lib/alpn/alpn-boot-8.1.7.v20160121.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.7.v20160121.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.7.v20160121|lib/alpn/alpn-boot-8.1.7.v20160121.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.7.v20160121.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.7.v20160121|lib/alpn/alpn-boot-8.1.7.v20160121.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.7.v20160121.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.7.v20160121|lib/alpn/alpn-boot-8.1.7.v20160121.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.7.v20160121.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.7.v20160121|lib/alpn/alpn-boot-8.1.7.v20160121.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.7.v20160121.jar

View File

@ -1,7 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.8.v20160420/alpn-boot-8.1.8.v20160420.jar|lib/alpn/alpn-boot-8.1.8.v20160420.jar
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.8.v20160420|lib/alpn/alpn-boot-8.1.8.v20160420.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.8.v20160420.jar

View File

@ -14,7 +14,7 @@ specific version of Java.
# Java versions.
#
# All versions of the alpn-boot jar can be found at
# http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/
# https://repo1.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/
[depend]
alpn-impl/alpn-${java.version}

View File

@ -54,8 +54,7 @@ public class ContinueProtocolHandler implements ProtocolHandler
{
boolean is100 = response.getStatus() == HttpStatus.CONTINUE_100;
boolean expect100 = request.getHeaders().contains(HttpHeader.EXPECT, HttpHeaderValue.CONTINUE.asString());
HttpConversation conversation = ((HttpRequest)request).getConversation();
boolean handled100 = conversation.getAttribute(ATTRIBUTE) != null;
boolean handled100 = request.getAttributes().containsKey(ATTRIBUTE);
return (is100 || expect100) && !handled100;
}
@ -81,34 +80,28 @@ public class ContinueProtocolHandler implements ProtocolHandler
Request request = response.getRequest();
HttpConversation conversation = ((HttpRequest)request).getConversation();
// Mark the 100 Continue response as handled
conversation.setAttribute(ATTRIBUTE, Boolean.TRUE);
request.attribute(ATTRIBUTE, Boolean.TRUE);
// Reset the conversation listeners, since we are going to receive another response code
conversation.updateResponseListeners(null);
HttpExchange exchange = conversation.getExchanges().peekLast();
assert exchange.getResponse() == response;
switch (response.getStatus())
if (response.getStatus() == HttpStatus.CONTINUE_100)
{
case 100:
{
// All good, continue
exchange.resetResponse();
exchange.proceed(null);
onContinue(request);
break;
}
default:
{
// Server either does not support 100 Continue,
// or it does and wants to refuse the request content,
// or we got some other HTTP status code like a redirect.
List<Response.ResponseListener> listeners = exchange.getResponseListeners();
HttpContentResponse contentResponse = new HttpContentResponse(response, getContent(), getMediaType(), getEncoding());
notifier.forwardSuccess(listeners, contentResponse);
exchange.proceed(new HttpRequestException("Expectation failed", request));
break;
}
// All good, continue.
exchange.resetResponse();
exchange.proceed(null);
onContinue(request);
}
else
{
// Server either does not support 100 Continue,
// or it does and wants to refuse the request content,
// or we got some other HTTP status code like a redirect.
List<Response.ResponseListener> listeners = exchange.getResponseListeners();
HttpContentResponse contentResponse = new HttpContentResponse(response, getContent(), getMediaType(), getEncoding());
notifier.forwardSuccess(listeners, contentResponse);
exchange.proceed(new HttpRequestException("Expectation failed", request));
}
}

View File

@ -28,6 +28,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.api.Result;
@ -72,6 +73,7 @@ public abstract class HttpReceiver
private final AtomicReference<ResponseState> responseState = new AtomicReference<>(ResponseState.IDLE);
private final HttpChannel channel;
private List<Response.AsyncContentListener> contentListeners;
private ContentDecoder decoder;
private Throwable failure;
@ -262,7 +264,12 @@ public abstract class HttpReceiver
if (LOG.isDebugEnabled())
LOG.debug("Response headers {}{}{}", response, System.lineSeparator(), response.getHeaders().toString().trim());
ResponseNotifier notifier = getHttpDestination().getResponseNotifier();
notifier.notifyHeaders(exchange.getConversation().getResponseListeners(), response);
List<Response.ResponseListener> responseListeners = exchange.getConversation().getResponseListeners();
notifier.notifyHeaders(responseListeners, response);
contentListeners = responseListeners.stream()
.filter(Response.AsyncContentListener.class::isInstance)
.map(Response.AsyncContentListener.class::cast)
.collect(Collectors.toList());
Enumeration<String> contentEncodings = response.getHeaders().getValues(HttpHeader.CONTENT_ENCODING.asString(), ",");
if (contentEncodings != null)
@ -297,7 +304,7 @@ public abstract class HttpReceiver
* @param callback the callback
* @return whether the processing should continue
*/
protected boolean responseContent(HttpExchange exchange, ByteBuffer buffer, final Callback callback)
protected boolean responseContent(HttpExchange exchange, ByteBuffer buffer, Callback callback)
{
out: while (true)
{
@ -324,12 +331,11 @@ public abstract class HttpReceiver
LOG.debug("Response content {}{}{}", response, System.lineSeparator(), BufferUtil.toDetailString(buffer));
ResponseNotifier notifier = getHttpDestination().getResponseNotifier();
List<Response.ResponseListener> listeners = exchange.getConversation().getResponseListeners();
ContentDecoder decoder = this.decoder;
if (decoder == null)
{
notifier.notifyContent(listeners, response, buffer, callback);
notifier.notifyContent(response, buffer, callback, contentListeners);
}
else
{
@ -354,8 +360,8 @@ public abstract class HttpReceiver
{
int size = decodeds.size();
CountingCallback counter = new CountingCallback(callback, size);
for (int i = 0; i < size; ++i)
notifier.notifyContent(listeners, response, decodeds.get(i), counter);
for (ByteBuffer decoded : decodeds)
notifier.notifyContent(response, decoded, counter, contentListeners);
}
}
catch (Throwable x)
@ -476,6 +482,7 @@ public abstract class HttpReceiver
*/
protected void reset()
{
contentListeners = null;
destroyDecoder(decoder);
decoder = null;
}

View File

@ -21,6 +21,7 @@ package org.eclipse.jetty.client;
import java.nio.ByteBuffer;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
@ -28,7 +29,9 @@ import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.api.Result;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.CountingCallback;
import org.eclipse.jetty.util.IteratingNestedCallback;
import org.eclipse.jetty.util.Retainable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@ -110,11 +113,31 @@ public class ResponseNotifier
public void notifyContent(List<Response.ResponseListener> listeners, Response response, ByteBuffer buffer, Callback callback)
{
// Here we use an IteratingNestedCallback not to avoid the stack overflow, but to
// invoke the listeners one after the other. When all of them have invoked the
// callback they got passed, the callback passed to this method is finally invoked.
ContentCallback contentCallback = new ContentCallback(listeners, response, buffer, callback);
contentCallback.iterate();
List<Response.AsyncContentListener> contentListeners = listeners.stream()
.filter(Response.AsyncContentListener.class::isInstance)
.map(Response.AsyncContentListener.class::cast)
.collect(Collectors.toList());
notifyContent(response, buffer, callback, contentListeners);
}
public void notifyContent(Response response, ByteBuffer buffer, Callback callback, List<Response.AsyncContentListener> contentListeners)
{
if (contentListeners.isEmpty())
{
callback.succeeded();
}
else
{
CountingCallback counter = new CountingCallback(callback, contentListeners.size());
Retainable retainable = callback instanceof Retainable ? (Retainable)callback : null;
for (Response.AsyncContentListener listener : contentListeners)
{
ByteBuffer slice = buffer.slice();
if (retainable != null)
retainable.retain();
listener.onContent(response, slice, counter);
}
}
}
private void notifyContent(Response.AsyncContentListener listener, Response response, ByteBuffer buffer, Callback callback)

View File

@ -102,8 +102,8 @@ public class HttpChannelOverHTTP extends HttpChannel
if ((response.getVersion() == HttpVersion.HTTP_1_1) &&
(response.getStatus() == HttpStatus.SWITCHING_PROTOCOLS_101))
{
String connection = response.getHeaders().get(HttpHeader.CONNECTION);
if ((connection == null) || !connection.toLowerCase(Locale.US).contains("upgrade"))
String next_connection = response.getHeaders().get(HttpHeader.CONNECTION);
if ((next_connection == null) || !next_connection.toLowerCase(Locale.US).contains("upgrade"))
{
return new Result(result,new HttpResponseException("101 Switching Protocols without Connection: Upgrade not supported",response));
}

View File

@ -44,11 +44,13 @@ import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.util.IO;
import org.junit.After;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
@Ignore
public class ConnectionPoolTest
{
private Server server;

View File

@ -479,39 +479,41 @@ public class HttpClientTLSTest
latch.countDown();
});
Socket socket = server.accept();
SSLSocket sslSocket = (SSLSocket)serverTLSFactory.getSslContext().getSocketFactory().createSocket(socket, null, socket.getPort(), true);
sslSocket.setUseClientMode(false);
BufferedReader reader = new BufferedReader(new InputStreamReader(sslSocket.getInputStream(), StandardCharsets.UTF_8));
while (true)
try (Socket socket = server.accept())
{
String line = reader.readLine();
if (line == null || line.isEmpty())
break;
SSLSocket sslSocket = (SSLSocket)serverTLSFactory.getSslContext().getSocketFactory().createSocket(socket, null, socket.getPort(), true);
sslSocket.setUseClientMode(false);
BufferedReader reader = new BufferedReader(new InputStreamReader(sslSocket.getInputStream(), StandardCharsets.UTF_8));
while (true)
{
String line = reader.readLine();
if (line == null || line.isEmpty())
break;
}
// If the response is Content-Length delimited, allowing the
// missing TLS Close Message is fine because the application
// will see a EOFException anyway.
// If the response is connection delimited, allowing the
// missing TLS Close Message is bad because the application
// will see a successful response with truncated content.
// Verify that by not allowing the missing
// TLS Close Message we get a response failure.
byte[] half = new byte[8];
String response = "HTTP/1.1 200 OK\r\n" +
// "Content-Length: " + (half.length * 2) + "\r\n" +
"Connection: close\r\n" +
"\r\n";
OutputStream output = sslSocket.getOutputStream();
output.write(response.getBytes(StandardCharsets.UTF_8));
output.write(half);
output.flush();
// Simulate a truncation attack by raw closing
// the socket in the try-with-resources block end.
}
// If the response is Content-Length delimited, allowing the
// missing TLS Close Message is fine because the application
// will see a EOFException anyway.
// If the response is connection delimited, allowing the
// missing TLS Close Message is bad because the application
// will see a successful response with truncated content.
// Verify that by not allowing the missing
// TLS Close Message we get a response failure.
byte[] half = new byte[8];
String response = "HTTP/1.1 200 OK\r\n" +
// "Content-Length: " + (half.length * 2) + "\r\n" +
"Connection: close\r\n" +
"\r\n";
OutputStream output = sslSocket.getOutputStream();
output.write(response.getBytes(StandardCharsets.UTF_8));
output.write(half);
output.flush();
// Simulate a truncation attack by raw closing.
socket.close();
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
}
}

View File

@ -98,63 +98,66 @@ public class ServerConnectionCloseTest
private void testServerSendsConnectionClose(boolean shutdownOutput, boolean chunked, String content) throws Exception
{
ServerSocket server = new ServerSocket(0);
int port = server.getLocalPort();
startClient();
Request request = client.newRequest("localhost", port).path("/ctx/path");
FutureResponseListener listener = new FutureResponseListener(request);
request.send(listener);
Socket socket = server.accept();
InputStream input = socket.getInputStream();
consumeRequest(input);
OutputStream output = socket.getOutputStream();
String serverResponse = "" +
"HTTP/1.1 200 OK\r\n" +
"Connection: close\r\n";
if (chunked)
try (ServerSocket server = new ServerSocket(0))
{
serverResponse += "" +
"Transfer-Encoding: chunked\r\n" +
"\r\n";
int port = server.getLocalPort();
startClient();
Request request = client.newRequest("localhost", port).path("/ctx/path");
FutureResponseListener listener = new FutureResponseListener(request);
request.send(listener);
try (Socket socket = server.accept())
{
InputStream input = socket.getInputStream();
consumeRequest(input);
OutputStream output = socket.getOutputStream();
String serverResponse = "" +
"HTTP/1.1 200 OK\r\n" +
"Connection: close\r\n";
if (chunked)
{
serverResponse += "" +
"Transfer-Encoding: chunked\r\n" +
"\r\n";
for (int i = 0; i < 2; ++i)
{
serverResponse +=
Integer.toHexString(content.length()) + "\r\n" +
content + "\r\n";
content + "\r\n";
}
serverResponse += "" +
"0\r\n" +
"\r\n";
serverResponse += "" +
"0\r\n" +
"\r\n";
}
else
{
serverResponse += "Content-Length: " + content.length() + "\r\n";
serverResponse += "\r\n";
serverResponse += content;
}
output.write(serverResponse.getBytes("UTF-8"));
output.flush();
if (shutdownOutput)
socket.shutdownOutput();
ContentResponse response = listener.get(5, TimeUnit.SECONDS);
Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
// Give some time to process the connection.
Thread.sleep(1000);
// Connection should have been removed from pool.
HttpDestinationOverHTTP destination = (HttpDestinationOverHTTP)client.getDestination("http", "localhost", port);
DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool();
Assert.assertEquals(0, connectionPool.getConnectionCount());
Assert.assertEquals(0, connectionPool.getIdleConnectionCount());
Assert.assertEquals(0, connectionPool.getActiveConnectionCount());
}
}
else
{
serverResponse += "Content-Length: " + content.length() + "\r\n";
serverResponse += "\r\n";
serverResponse += content;
}
output.write(serverResponse.getBytes("UTF-8"));
output.flush();
if (shutdownOutput)
socket.shutdownOutput();
ContentResponse response = listener.get(5, TimeUnit.SECONDS);
Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
// Give some time to process the connection.
Thread.sleep(1000);
// Connection should have been removed from pool.
HttpDestinationOverHTTP destination = (HttpDestinationOverHTTP)client.getDestination("http", "localhost", port);
DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool();
Assert.assertEquals(0, connectionPool.getConnectionCount());
Assert.assertEquals(0, connectionPool.getIdleConnectionCount());
Assert.assertEquals(0, connectionPool.getActiveConnectionCount());
}
private boolean consumeRequest(InputStream input) throws IOException

View File

@ -79,41 +79,40 @@ public class Socks4ProxyTest
latch.countDown();
});
SocketChannel channel = server.accept();
try (SocketChannel channel = server.accept())
{
int socks4MessageLength = 9;
ByteBuffer buffer = ByteBuffer.allocate(socks4MessageLength);
int read = channel.read(buffer);
Assert.assertEquals(socks4MessageLength, read);
Assert.assertEquals(4, buffer.get(0) & 0xFF);
Assert.assertEquals(1, buffer.get(1) & 0xFF);
Assert.assertEquals(serverPort, buffer.getShort(2) & 0xFFFF);
Assert.assertEquals(ip1, buffer.get(4) & 0xFF);
Assert.assertEquals(ip2, buffer.get(5) & 0xFF);
Assert.assertEquals(ip3, buffer.get(6) & 0xFF);
Assert.assertEquals(ip4, buffer.get(7) & 0xFF);
Assert.assertEquals(0, buffer.get(8) & 0xFF);
int socks4MessageLength = 9;
ByteBuffer buffer = ByteBuffer.allocate(socks4MessageLength);
int read = channel.read(buffer);
Assert.assertEquals(socks4MessageLength, read);
Assert.assertEquals(4, buffer.get(0) & 0xFF);
Assert.assertEquals(1, buffer.get(1) & 0xFF);
Assert.assertEquals(serverPort, buffer.getShort(2) & 0xFFFF);
Assert.assertEquals(ip1, buffer.get(4) & 0xFF);
Assert.assertEquals(ip2, buffer.get(5) & 0xFF);
Assert.assertEquals(ip3, buffer.get(6) & 0xFF);
Assert.assertEquals(ip4, buffer.get(7) & 0xFF);
Assert.assertEquals(0, buffer.get(8) & 0xFF);
// Socks4 response.
channel.write(ByteBuffer.wrap(new byte[]{0, 0x5A, 0, 0, 0, 0, 0, 0}));
// Socks4 response.
channel.write(ByteBuffer.wrap(new byte[]{0, 0x5A, 0, 0, 0, 0, 0, 0}));
buffer = ByteBuffer.allocate(method.length() + 1 + path.length());
read = channel.read(buffer);
Assert.assertEquals(buffer.capacity(), read);
buffer.flip();
Assert.assertEquals(method + " " + path, StandardCharsets.UTF_8.decode(buffer).toString());
buffer = ByteBuffer.allocate(method.length() + 1 + path.length());
read = channel.read(buffer);
Assert.assertEquals(buffer.capacity(), read);
buffer.flip();
Assert.assertEquals(method + " " + path, StandardCharsets.UTF_8.decode(buffer).toString());
// Response
String response = "" +
"HTTP/1.1 200 OK\r\n" +
"Content-Length: 0\r\n" +
"Connection: close\r\n" +
"\r\n";
channel.write(ByteBuffer.wrap(response.getBytes("UTF-8")));
// Response
String response = "" +
"HTTP/1.1 200 OK\r\n" +
"Content-Length: 0\r\n" +
"Connection: close\r\n" +
"\r\n";
channel.write(ByteBuffer.wrap(response.getBytes("UTF-8")));
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
channel.close();
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
}
}
@Test
@ -139,39 +138,38 @@ public class Socks4ProxyTest
result.getFailure().printStackTrace();
});
SocketChannel channel = server.accept();
try (SocketChannel channel = server.accept())
{
int socks4MessageLength = 9;
ByteBuffer buffer = ByteBuffer.allocate(socks4MessageLength);
int read = channel.read(buffer);
Assert.assertEquals(socks4MessageLength, read);
int socks4MessageLength = 9;
ByteBuffer buffer = ByteBuffer.allocate(socks4MessageLength);
int read = channel.read(buffer);
Assert.assertEquals(socks4MessageLength, read);
// Socks4 response, with split bytes.
byte[] chunk1 = new byte[]{0, 0x5A, 0};
byte[] chunk2 = new byte[]{0, 0, 0, 0, 0};
channel.write(ByteBuffer.wrap(chunk1));
// Socks4 response, with split bytes.
byte[] chunk1 = new byte[]{0, 0x5A, 0};
byte[] chunk2 = new byte[]{0, 0, 0, 0, 0};
channel.write(ByteBuffer.wrap(chunk1));
// Wait before sending the second chunk.
Thread.sleep(1000);
// Wait before sending the second chunk.
Thread.sleep(1000);
channel.write(ByteBuffer.wrap(chunk2));
channel.write(ByteBuffer.wrap(chunk2));
buffer = ByteBuffer.allocate(method.length());
read = channel.read(buffer);
Assert.assertEquals(buffer.capacity(), read);
buffer.flip();
Assert.assertEquals(method, StandardCharsets.UTF_8.decode(buffer).toString());
buffer = ByteBuffer.allocate(method.length());
read = channel.read(buffer);
Assert.assertEquals(buffer.capacity(), read);
buffer.flip();
Assert.assertEquals(method, StandardCharsets.UTF_8.decode(buffer).toString());
// Response
String response = "" +
"HTTP/1.1 200 OK\r\n" +
"Content-Length: 0\r\n" +
"Connection: close\r\n" +
"\r\n";
channel.write(ByteBuffer.wrap(response.getBytes("UTF-8")));
// Response
String response = "" +
"HTTP/1.1 200 OK\r\n" +
"Content-Length: 0\r\n" +
"Connection: close\r\n" +
"\r\n";
channel.write(ByteBuffer.wrap(response.getBytes("UTF-8")));
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
channel.close();
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
}
}
}

View File

@ -104,87 +104,91 @@ public class TLSServerConnectionCloseTest
private void testServerSendsConnectionClose(boolean chunked, String content) throws Exception
{
ServerSocket server = new ServerSocket(0);
int port = server.getLocalPort();
startClient();
Request request = client.newRequest("localhost", port).scheme("https").path("/ctx/path");
FutureResponseListener listener = new FutureResponseListener(request);
request.send(listener);
Socket socket = server.accept();
SSLContext sslContext = client.getSslContextFactory().getSslContext();
SSLSocket sslSocket = (SSLSocket)sslContext.getSocketFactory().createSocket(socket, "localhost", port, false);
sslSocket.setUseClientMode(false);
sslSocket.startHandshake();
InputStream input = sslSocket.getInputStream();
consumeRequest(input);
OutputStream output = sslSocket.getOutputStream();
String serverResponse = "" +
"HTTP/1.1 200 OK\r\n" +
"Connection: close\r\n";
if (chunked)
try (ServerSocket server = new ServerSocket(0))
{
serverResponse += "" +
"Transfer-Encoding: chunked\r\n" +
"\r\n";
int port = server.getLocalPort();
startClient();
Request request = client.newRequest("localhost", port).scheme("https").path("/ctx/path");
FutureResponseListener listener = new FutureResponseListener(request);
request.send(listener);
try (Socket socket = server.accept())
{
SSLContext sslContext = client.getSslContextFactory().getSslContext();
SSLSocket sslSocket = (SSLSocket)sslContext.getSocketFactory().createSocket(socket, "localhost", port, false);
sslSocket.setUseClientMode(false);
sslSocket.startHandshake();
InputStream input = sslSocket.getInputStream();
consumeRequest(input);
OutputStream output = sslSocket.getOutputStream();
String serverResponse = "" +
"HTTP/1.1 200 OK\r\n" +
"Connection: close\r\n";
if (chunked)
{
serverResponse += "" +
"Transfer-Encoding: chunked\r\n" +
"\r\n";
for (int i = 0; i < 2; ++i)
{
serverResponse +=
Integer.toHexString(content.length()) + "\r\n" +
content + "\r\n";
content + "\r\n";
}
serverResponse += "" +
"0\r\n" +
"\r\n";
}
else
{
serverResponse += "Content-Length: " + content.length() + "\r\n";
serverResponse += "\r\n";
serverResponse += content;
}
serverResponse += "" +
"0\r\n" +
"\r\n";
}
else
{
serverResponse += "Content-Length: " + content.length() + "\r\n";
serverResponse += "\r\n";
serverResponse += content;
}
output.write(serverResponse.getBytes("UTF-8"));
output.flush();
output.write(serverResponse.getBytes("UTF-8"));
output.flush();
switch (closeMode)
{
case NONE:
{
break;
}
case CLOSE:
{
sslSocket.close();
break;
}
case ABRUPT:
{
socket.shutdownOutput();
break;
}
default:
{
throw new IllegalStateException();
switch (closeMode)
{
case NONE:
{
break;
}
case CLOSE:
{
sslSocket.close();
break;
}
case ABRUPT:
{
socket.shutdownOutput();
break;
}
default:
{
throw new IllegalStateException();
}
}
ContentResponse response = listener.get(5, TimeUnit.SECONDS);
Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
// Give some time to process the connection.
Thread.sleep(1000);
// Connection should have been removed from pool.
HttpDestinationOverHTTP destination = (HttpDestinationOverHTTP)client.getDestination("http", "localhost", port);
DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool();
Assert.assertEquals(0, connectionPool.getConnectionCount());
Assert.assertEquals(0, connectionPool.getIdleConnectionCount());
Assert.assertEquals(0, connectionPool.getActiveConnectionCount());
}
}
ContentResponse response = listener.get(5, TimeUnit.SECONDS);
Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
// Give some time to process the connection.
Thread.sleep(1000);
// Connection should have been removed from pool.
HttpDestinationOverHTTP destination = (HttpDestinationOverHTTP)client.getDestination("http", "localhost", port);
DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool();
Assert.assertEquals(0, connectionPool.getConnectionCount());
Assert.assertEquals(0, connectionPool.getIdleConnectionCount());
Assert.assertEquals(0, connectionPool.getActiveConnectionCount());
}
private boolean consumeRequest(InputStream input) throws IOException

View File

@ -101,72 +101,72 @@ public class SslBytesClientTest extends SslBytesTest
Assert.assertTrue(proxy.awaitClient(5, TimeUnit.SECONDS));
final SSLSocket server = (SSLSocket)acceptor.accept();
server.setUseClientMode(false);
Future<Object> handshake = threadPool.submit(() ->
try (SSLSocket server = (SSLSocket)acceptor.accept())
{
server.startHandshake();
return null;
});
server.setUseClientMode(false);
// Client Hello
TLSRecord record = proxy.readFromClient();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToServer(record);
Future<Object> handshake = threadPool.submit(() ->
{
server.startHandshake();
return null;
});
// Server Hello + Certificate + Server Done
record = proxy.readFromServer();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToClient(record);
// Client Hello
TLSRecord record = proxy.readFromClient();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToServer(record);
// Client Key Exchange
record = proxy.readFromClient();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToServer(record);
// Server Hello + Certificate + Server Done
record = proxy.readFromServer();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToClient(record);
// Change Cipher Spec
record = proxy.readFromClient();
Assert.assertEquals(TLSRecord.Type.CHANGE_CIPHER_SPEC, record.getType());
proxy.flushToServer(record);
// Client Key Exchange
record = proxy.readFromClient();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToServer(record);
// Client Done
record = proxy.readFromClient();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToServer(record);
// Change Cipher Spec
record = proxy.readFromClient();
Assert.assertEquals(TLSRecord.Type.CHANGE_CIPHER_SPEC, record.getType());
proxy.flushToServer(record);
// Change Cipher Spec
record = proxy.readFromServer();
Assert.assertEquals(TLSRecord.Type.CHANGE_CIPHER_SPEC, record.getType());
proxy.flushToClient(record);
// Client Done
record = proxy.readFromClient();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToServer(record);
// Server Done
record = proxy.readFromServer();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToClient(record);
// Change Cipher Spec
record = proxy.readFromServer();
Assert.assertEquals(TLSRecord.Type.CHANGE_CIPHER_SPEC, record.getType());
proxy.flushToClient(record);
Assert.assertNull(handshake.get(5, TimeUnit.SECONDS));
// Server Done
record = proxy.readFromServer();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToClient(record);
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
// Read request
BufferedReader reader = new BufferedReader(new InputStreamReader(server.getInputStream(), StandardCharsets.UTF_8));
String line = reader.readLine();
Assert.assertTrue(line.startsWith("GET"));
while (line.length() > 0)
line = reader.readLine();
Assert.assertNull(handshake.get(5, TimeUnit.SECONDS));
// Write response
OutputStream output = server.getOutputStream();
output.write(("HTTP/1.1 200 OK\r\n" +
"Content-Length: 0\r\n" +
"\r\n").getBytes(StandardCharsets.UTF_8));
output.flush();
Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS));
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
// Read request
BufferedReader reader = new BufferedReader(new InputStreamReader(server.getInputStream(), StandardCharsets.UTF_8));
String line = reader.readLine();
Assert.assertTrue(line.startsWith("GET"));
while (line.length() > 0)
line = reader.readLine();
ContentResponse response = listener.get(5, TimeUnit.SECONDS);
Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
// Write response
OutputStream output = server.getOutputStream();
output.write(("HTTP/1.1 200 OK\r\n" +
"Content-Length: 0\r\n" +
"\r\n").getBytes(StandardCharsets.UTF_8));
output.flush();
Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS));
server.close();
ContentResponse response = listener.get(5, TimeUnit.SECONDS);
Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
}
}
@Test
@ -178,109 +178,109 @@ public class SslBytesClientTest extends SslBytesTest
Assert.assertTrue(proxy.awaitClient(5, TimeUnit.SECONDS));
final SSLSocket server = (SSLSocket)acceptor.accept();
server.setUseClientMode(false);
Future<Object> handshake = threadPool.submit(() ->
try (SSLSocket server = (SSLSocket)acceptor.accept())
{
server.startHandshake();
return null;
});
server.setUseClientMode(false);
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
Assert.assertNull(handshake.get(5, TimeUnit.SECONDS));
Future<Object> handshake = threadPool.submit(() ->
{
server.startHandshake();
return null;
});
// Read request
InputStream serverInput = server.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(serverInput, StandardCharsets.UTF_8));
String line = reader.readLine();
Assert.assertTrue(line.startsWith("GET"));
while (line.length() > 0)
line = reader.readLine();
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
Assert.assertNull(handshake.get(5, TimeUnit.SECONDS));
OutputStream serverOutput = server.getOutputStream();
byte[] data1 = new byte[1024];
Arrays.fill(data1, (byte)'X');
String content1 = new String(data1, StandardCharsets.UTF_8);
byte[] data2 = new byte[1024];
Arrays.fill(data2, (byte)'Y');
final String content2 = new String(data2, StandardCharsets.UTF_8);
// Write first part of the response
serverOutput.write(("HTTP/1.1 200 OK\r\n" +
"Content-Type: text/plain\r\n" +
"Content-Length: " + (content1.length() + content2.length()) + "\r\n" +
"\r\n" +
content1).getBytes(StandardCharsets.UTF_8));
serverOutput.flush();
Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS));
// Read request
InputStream serverInput = server.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(serverInput, StandardCharsets.UTF_8));
String line = reader.readLine();
Assert.assertTrue(line.startsWith("GET"));
while (line.length() > 0)
line = reader.readLine();
// Renegotiate
Future<Object> renegotiation = threadPool.submit(() ->
{
server.startHandshake();
return null;
});
OutputStream serverOutput = server.getOutputStream();
byte[] data1 = new byte[1024];
Arrays.fill(data1, (byte)'X');
String content1 = new String(data1, StandardCharsets.UTF_8);
byte[] data2 = new byte[1024];
Arrays.fill(data2, (byte)'Y');
final String content2 = new String(data2, StandardCharsets.UTF_8);
// Write first part of the response
serverOutput.write(("HTTP/1.1 200 OK\r\n" +
"Content-Type: text/plain\r\n" +
"Content-Length: " + (content1.length() + content2.length()) + "\r\n" +
"\r\n" +
content1).getBytes(StandardCharsets.UTF_8));
serverOutput.flush();
Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS));
// Renegotiation Handshake
TLSRecord record = proxy.readFromServer();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToClient(record);
// Renegotiate
Future<Object> renegotiation = threadPool.submit(() ->
{
server.startHandshake();
return null;
});
// Renegotiation Handshake
record = proxy.readFromClient();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToServer(record);
// Renegotiation Handshake
TLSRecord record = proxy.readFromServer();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToClient(record);
// Trigger a read to have the server write the final renegotiation steps
server.setSoTimeout(100);
try
{
serverInput.read();
Assert.fail();
// Renegotiation Handshake
record = proxy.readFromClient();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToServer(record);
// Trigger a read to have the server write the final renegotiation steps
server.setSoTimeout(100);
try
{
serverInput.read();
Assert.fail();
}
catch (SocketTimeoutException x)
{
// Expected
}
// Renegotiation Handshake
record = proxy.readFromServer();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToClient(record);
// Renegotiation Change Cipher
record = proxy.readFromServer();
Assert.assertEquals(TLSRecord.Type.CHANGE_CIPHER_SPEC, record.getType());
proxy.flushToClient(record);
// Renegotiation Handshake
record = proxy.readFromServer();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToClient(record);
// Renegotiation Change Cipher
record = proxy.readFromClient();
Assert.assertEquals(TLSRecord.Type.CHANGE_CIPHER_SPEC, record.getType());
proxy.flushToServer(record);
// Renegotiation Handshake
record = proxy.readFromClient();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToServer(record);
Assert.assertNull(renegotiation.get(5, TimeUnit.SECONDS));
// Complete the response
automaticProxyFlow = proxy.startAutomaticFlow();
serverOutput.write(data2);
serverOutput.flush();
Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS));
ContentResponse response = listener.get(5, TimeUnit.SECONDS);
Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
Assert.assertEquals(data1.length + data2.length, response.getContent().length);
}
catch (SocketTimeoutException x)
{
// Expected
}
// Renegotiation Handshake
record = proxy.readFromServer();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToClient(record);
// Renegotiation Change Cipher
record = proxy.readFromServer();
Assert.assertEquals(TLSRecord.Type.CHANGE_CIPHER_SPEC, record.getType());
proxy.flushToClient(record);
// Renegotiation Handshake
record = proxy.readFromServer();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToClient(record);
// Renegotiation Change Cipher
record = proxy.readFromClient();
Assert.assertEquals(TLSRecord.Type.CHANGE_CIPHER_SPEC, record.getType());
proxy.flushToServer(record);
// Renegotiation Handshake
record = proxy.readFromClient();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToServer(record);
Assert.assertNull(renegotiation.get(5, TimeUnit.SECONDS));
// Complete the response
automaticProxyFlow = proxy.startAutomaticFlow();
serverOutput.write(data2);
serverOutput.flush();
Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS));
ContentResponse response = listener.get(5, TimeUnit.SECONDS);
Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
Assert.assertEquals(data1.length + data2.length, response.getContent().length);
server.close();
}
@Test
@ -294,60 +294,60 @@ public class SslBytesClientTest extends SslBytesTest
Assert.assertTrue(proxy.awaitClient(5, TimeUnit.SECONDS));
final SSLSocket server = (SSLSocket)acceptor.accept();
server.setUseClientMode(false);
Future<Object> handshake = threadPool.submit(() ->
try (SSLSocket server = (SSLSocket)acceptor.accept())
{
server.startHandshake();
return null;
});
server.setUseClientMode(false);
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
Assert.assertNull(handshake.get(5, TimeUnit.SECONDS));
Future<Object> handshake = threadPool.submit(() ->
{
server.startHandshake();
return null;
});
// Read request
InputStream serverInput = server.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(serverInput, StandardCharsets.UTF_8));
String line = reader.readLine();
Assert.assertTrue(line.startsWith("GET"));
while (line.length() > 0)
line = reader.readLine();
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
Assert.assertNull(handshake.get(5, TimeUnit.SECONDS));
OutputStream serverOutput = server.getOutputStream();
byte[] data1 = new byte[1024];
Arrays.fill(data1, (byte)'X');
String content1 = new String(data1, StandardCharsets.UTF_8);
byte[] data2 = new byte[1024];
Arrays.fill(data2, (byte)'Y');
final String content2 = new String(data2, StandardCharsets.UTF_8);
// Write first part of the response
serverOutput.write(("HTTP/1.1 200 OK\r\n" +
"Content-Type: text/plain\r\n" +
"Content-Length: " + (content1.length() + content2.length()) + "\r\n" +
"\r\n" +
content1).getBytes(StandardCharsets.UTF_8));
serverOutput.flush();
Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS));
// Read request
InputStream serverInput = server.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(serverInput, StandardCharsets.UTF_8));
String line = reader.readLine();
Assert.assertTrue(line.startsWith("GET"));
while (line.length() > 0)
line = reader.readLine();
// Renegotiate
threadPool.submit(() ->
{
server.startHandshake();
return null;
});
OutputStream serverOutput = server.getOutputStream();
byte[] data1 = new byte[1024];
Arrays.fill(data1, (byte)'X');
String content1 = new String(data1, StandardCharsets.UTF_8);
byte[] data2 = new byte[1024];
Arrays.fill(data2, (byte)'Y');
final String content2 = new String(data2, StandardCharsets.UTF_8);
// Write first part of the response
serverOutput.write(("HTTP/1.1 200 OK\r\n" +
"Content-Type: text/plain\r\n" +
"Content-Length: " + (content1.length() + content2.length()) + "\r\n" +
"\r\n" +
content1).getBytes(StandardCharsets.UTF_8));
serverOutput.flush();
Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS));
// Renegotiation Handshake
TLSRecord record = proxy.readFromServer();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToClient(record);
// Renegotiate
threadPool.submit(() ->
{
server.startHandshake();
return null;
});
// Client sends close alert.
record = proxy.readFromClient();
Assert.assertEquals(TLSRecord.Type.ALERT, record.getType());
record = proxy.readFromClient();
Assert.assertNull(record);
// Renegotiation Handshake
TLSRecord record = proxy.readFromServer();
Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToClient(record);
server.close();
// Client sends close alert.
record = proxy.readFromClient();
Assert.assertEquals(TLSRecord.Type.ALERT, record.getType());
record = proxy.readFromClient();
Assert.assertNull(record);
}
}
}

View File

@ -63,7 +63,7 @@
<JXURL>http://download.eclipse.org/jetty/stable-9/xref</JXURL>
<SRCDIR>${basedir}/..</SRCDIR>
<GITBROWSEURL>https://github.com/eclipse/jetty.project/tree/jetty-9.4.x</GITBROWSEURL>
<MVNCENTRAL>http://central.maven.org/maven2</MVNCENTRAL>
<MVNCENTRAL>https://repo1.maven.org/maven2</MVNCENTRAL>
<VERSION>${project.version}</VERSION>
</attributes>
</configuration>

View File

@ -113,7 +113,7 @@ When using JDK 9 or later and Jetty embedded, the ALPN service implementation is
To use ALPN in an OSGi environment, in addition to what described above, 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.
You can download the https://repo1.maven.org/maven2/org/eclipse/jetty/osgi/jetty-osgi-alpn/[jetty-osgi-alpn jar] from Maven Central.
____
[NOTE]

View File

@ -22,7 +22,7 @@
==== Setting up the Classpath
You will need to place the following Jetty jar files onto the classpath of your application.
You can obtain them from the https://www.eclipse.org/jetty/download.html[Jetty distribution], or the http://central.maven.org/maven2/org/eclipse/jetty/jetty-annotations[Maven repository]:
You can obtain them from the https://www.eclipse.org/jetty/download.html[Jetty distribution], or the https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-annotations[Maven repository]:
....
jetty-plus.jar

View File

@ -44,7 +44,7 @@ This is extremely useful in CometD web applications where it is now possible to
You will need to put the `jetty-servlets.jar` file onto your classpath.
If you are creating a webapp, ensure that this jar is included in your webapp's `WEB-INF/lib`.
Or, if you are running Jetty embedded you will need to ensure that `jetty-servlets.jar` is on the execution classpath.
You can download the `jetty-servlets.jar` from the Maven Central Repository at http://central.maven.org/maven2/org/eclipse/jetty/jetty-servlets/.
You can download the `jetty-servlets.jar` from the Maven Central Repository at https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-servlets/.
It is also available as part of the Jetty distribution in the `$JETTY_HOME/lib` directory.
[[cross-origin-config]]

View File

@ -126,7 +126,7 @@ All configuration options for BoneCP are described here: http://jolbox.com/bonec
[[c3p0-datasource]]
===== c3p0
Connection pooling, available at http://central.maven.org/maven2/c3p0/c3p0/0.9.1.2/c3p0-0.9.1.2.jar[c3p0 Jar].
Connection pooling, available at https://repo1.maven.org/maven2/c3p0/c3p0/0.9.1.2/c3p0-0.9.1.2.jar[c3p0 Jar].
[source, xml, subs="{sub-order}"]
----
@ -147,7 +147,7 @@ Connection pooling, available at http://central.maven.org/maven2/c3p0/c3p0/0.9.1
[[dbcp-datasource]]
===== DBCP
Connection pooling, available at http://central.maven.org/maven2/commons-dbcp/commons-dbcp/1.2/commons-dbcp-1.2.jar[dbcp Jar].
Connection pooling, available at https://repo1.maven.org/maven2/commons-dbcp/commons-dbcp/1.2/commons-dbcp-1.2.jar[dbcp Jar].
[source, xml, subs="{sub-order}"]
----

View File

@ -118,7 +118,7 @@ Proceed (y/N)? y
INFO : slf4j-api transitively enabled
INFO : logging-slf4j initialized in ${jetty.base}/start.d/logging-slf4j.ini
MKDIR : ${jetty.base}/lib/slf4j
DOWNLD: http://central.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-api-1.7.21.jar
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-api-1.7.21.jar
INFO : Base directory was modified
ERROR : Module logging-slf4j requires a module providing slf4j-impl from one of [slf4j-simple-impl, slf4j-logback, slf4j-jul, slf4j-log4j2, slf4j-log4j]
@ -137,7 +137,7 @@ To enable the simple SLF4J implementation, we will also need to activate the `sl
[my-base]$ java -jar ../start.jar --add-to-start=slf4j-simple-impl
INFO : slf4j-simple-impl initialized in ${jetty.base}/start.d/slf4j-simple-impl.ini
INFO : resources transitively enabled
DOWNLD: http://central.maven.org/maven2/org/slf4j/slf4j-simple/1.7.21/slf4j-simple-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-simple-1.7.21.jar
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/slf4j-simple/1.7.21/slf4j-simple-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-simple-1.7.21.jar
MKDIR : ${jetty.base}/resources
COPY : ${jetty.home}/modules/slf4j-simple-impl/resources/simplelogger.properties to ${jetty.base}/resources/simplelogger.properties
INFO : Base directory was modified
@ -207,12 +207,12 @@ INFO : resources transitively enabled
INFO : slf4j-log4j transitively enabled
INFO : logging-log4j initialized in ${jetty.base}/start.d/logging-log4j.ini
MKDIR : ${jetty.base}/lib/slf4j
DOWNLD: http://central.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-api-1.7.21.jar
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-api-1.7.21.jar
MKDIR : ${jetty.base}/lib/log4j
COPY : /Users/admin/.m2/repository/log4j/log4j/1.2.17/log4j-1.2.17.jar to ${jetty.base}/lib/log4j/log4j-1.2.17.jar
MKDIR : ${jetty.base}/resources
COPY : ${jetty.home}/modules/log4j-impl/resources/log4j.xml to ${jetty.base}/resources/log4j.xml
DOWNLD: http://central.maven.org/maven2/org/slf4j/slf4j-log4j12/1.7.21/slf4j-log4j12-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-log4j12-1.7.21.jar
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/slf4j-log4j12/1.7.21/slf4j-log4j12-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-log4j12-1.7.21.jar
INFO : Base directory was modified
[my-base]$ tree
@ -277,12 +277,12 @@ INFO : resources transitively enabled
INFO : slf4j-log4j2 transitively enabled
INFO : log4j2-impl transitively enabled
MKDIR : ${jetty.base}/lib/slf4j
DOWNLD: http://central.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-api-1.7.21.jar
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-api-1.7.21.jar
MKDIR : ${jetty.base}/lib/log4j2
DOWNLD: http://central.maven.org/maven2/org/apache/logging/log4j/log4j-api/2.6.1/log4j-api-2.6.1.jar to ${jetty.base}/lib/log4j2/log4j-api-2.6.1.jar
DOWNLD: https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-api/2.6.1/log4j-api-2.6.1.jar to ${jetty.base}/lib/log4j2/log4j-api-2.6.1.jar
MKDIR : ${jetty.base}/resources
DOWNLD: http://central.maven.org/maven2/org/apache/logging/log4j/log4j-slf4j-impl/2.6.1/log4j-slf4j-impl-2.6.1.jar to ${jetty.base}/lib/log4j2/log4j-slf4j-impl-2.6.1.jar
DOWNLD: http://central.maven.org/maven2/org/apache/logging/log4j/log4j-core/2.6.1/log4j-core-2.6.1.jar to ${jetty.base}/lib/log4j2/log4j-core-2.6.1.jar
DOWNLD: https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-slf4j-impl/2.6.1/log4j-slf4j-impl-2.6.1.jar to ${jetty.base}/lib/log4j2/log4j-slf4j-impl-2.6.1.jar
DOWNLD: https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-core/2.6.1/log4j-core-2.6.1.jar to ${jetty.base}/lib/log4j2/log4j-core-2.6.1.jar
COPY : ${jetty.home}/modules/log4j2-impl/resources/log4j2.xml to ${jetty.base}/resources/log4j2.xml
INFO : Base directory was modified
@ -362,12 +362,12 @@ INFO : slf4j-logback transitively enabled
INFO : logging-logback initialized in ${jetty.base}/start.d/logging-logback.ini
INFO : resources transitively enabled
MKDIR : ${jetty.base}/lib/slf4j
DOWNLD: http://central.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-api-1.7.21.jar
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-api-1.7.21.jar
MKDIR : ${jetty.base}/lib/logback
DOWNLD: http://central.maven.org/maven2/ch/qos/logback/logback-core/1.1.7/logback-core-1.1.7.jar to ${jetty.base}/lib/logback/logback-core-1.1.7.jar
DOWNLD: https://repo1.maven.org/maven2/ch/qos/logback/logback-core/1.1.7/logback-core-1.1.7.jar to ${jetty.base}/lib/logback/logback-core-1.1.7.jar
MKDIR : ${jetty.base}/resources
COPY : ${jetty.home}/modules/logback-impl/resources/logback.xml to ${jetty.base}/resources/logback.xml
DOWNLD: http://central.maven.org/maven2/ch/qos/logback/logback-classic/1.1.7/logback-classic-1.1.7.jar to ${jetty.base}/lib/logback/logback-classic-1.1.7.jar
DOWNLD: https://repo1.maven.org/maven2/ch/qos/logback/logback-classic/1.1.7/logback-classic-1.1.7.jar to ${jetty.base}/lib/logback/logback-classic-1.1.7.jar
INFO : Base directory was modified
[my-base]$ tree
@ -434,8 +434,8 @@ INFO : resources transitively enabled
MKDIR : ${jetty.base}/etc
COPY : ${jetty.home}/modules/jul-impl/etc/java-util-logging.properties to ${jetty.base}/etc/java-util-logging.properties
MKDIR : ${jetty.base}/lib/slf4j
DOWNLD: http://central.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-api-1.7.21.jar
DOWNLD: http://central.maven.org/maven2/org/slf4j/slf4j-jdk14/1.7.21/slf4j-jdk14-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-jdk14-1.7.21.jar
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-api-1.7.21.jar
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/slf4j-jdk14/1.7.21/slf4j-jdk14-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-jdk14-1.7.21.jar
INFO : Base directory was modified
[my-base]$ tree

View File

@ -37,9 +37,9 @@ A convenient replacement `logging` module has been created to bootstrap your `${
[mybase]$ java -jar /opt/jetty-dist/start.jar --add-to-start=logging
INFO: logging initialised in ${jetty.base}/start.ini (appended)
MKDIR: ${jetty.base}/logs
DOWNLOAD: http://central.maven.org/maven2/org/slf4j/slf4j-api/1.6.6/slf4j-api-1.6.6.jar to lib/logging/slf4j-api-1.6.6.jar
DOWNLOAD: http://central.maven.org/maven2/org/slf4j/slf4j-log4j12/1.6.6/slf4j-log4j12-1.6.6.jar to lib/logging/slf4j-log4j12-1.6.6.jar
DOWNLOAD: http://central.maven.org/maven2/log4j/log4j/1.2.17/log4j-1.2.17.jar to lib/logging/log4j-1.2.17.jar
DOWNLOAD: https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.6.6/slf4j-api-1.6.6.jar to lib/logging/slf4j-api-1.6.6.jar
DOWNLOAD: https://repo1.maven.org/maven2/org/slf4j/slf4j-log4j12/1.6.6/slf4j-log4j12-1.6.6.jar to lib/logging/slf4j-log4j12-1.6.6.jar
DOWNLOAD: https://repo1.maven.org/maven2/log4j/log4j/1.2.17/log4j-1.2.17.jar to lib/logging/log4j-1.2.17.jar
DOWNLOAD: https://raw.githubusercontent.com/jetty-project/logging-modules/master/log4j-1.2/log4j.properties to resources/log4j.properties
DOWNLOAD: https://raw.githubusercontent.com/jetty-project/logging-modules/master/log4j-1.2/jetty-logging.properties to resources/jetty-logging.properties
INFO: resources initialised transitively

View File

@ -39,8 +39,8 @@ A convenient replacement `logging` module has been created to bootstrap your `${
[mybase]$ java -jar /opt/jetty-dist/start.jar --add-to-start=logging
INFO: logging initialised in ${jetty.base}/start.ini (appended)
MKDIR: ${jetty.base}/logs
DOWNLOAD: http://central.maven.org/maven2/org/slf4j/slf4j-jdk14/1.6.6/slf4j-jdk14-1.6.6.jar to lib/logging/slf4j-jdk14-1.6.6.jar
DOWNLOAD: http://central.maven.org/maven2/org/slf4j/slf4j-api/1.6.6/slf4j-api-1.6.6.jar to lib/logging/slf4j-api-1.6.6.jar
DOWNLOAD: https://repo1.maven.org/maven2/org/slf4j/slf4j-jdk14/1.6.6/slf4j-jdk14-1.6.6.jar to lib/logging/slf4j-jdk14-1.6.6.jar
DOWNLOAD: https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.6.6/slf4j-api-1.6.6.jar to lib/logging/slf4j-api-1.6.6.jar
DOWNLOAD: https://raw.githubusercontent.com/jetty-project/logging-modules/master/java.util.logging-slf4j/jetty-logging.xml to etc/jetty-logging.xml
DOWNLOAD: https://raw.githubusercontent.com/jetty-project/logging-modules/master/java.util.logging-slf4j/logging.properties to resources/logging.properties
DOWNLOAD: https://raw.githubusercontent.com/jetty-project/logging-modules/master/java.util.logging-slf4j/jetty-logging.properties to resources/jetty-logging.properties

View File

@ -56,19 +56,19 @@ A convenient replacement `logging` module has been created to bootstrap your `${
[mybase]$ java -jar /opt/jetty-dist/start.jar --add-to-start=logging,webapp-logging
INFO: logging initialised in ${jetty.base}/start.ini (appended)
MKDIR: ${jetty.base}/logs
DOWNLOAD: http://central.maven.org/maven2/org/slf4j/slf4j-api/1.6.6/slf4j-api-1.6.6.jar to lib/logging/slf4j-api-1.6.6.jar
DOWNLOAD: http://central.maven.org/maven2/org/slf4j/log4j-over-slf4j/1.6.6/log4j-over-slf4j-1.6.6.jar to lib/logging/log4j-over-slf4j-1.6.6.jar
DOWNLOAD: http://central.maven.org/maven2/org/slf4j/jul-to-slf4j/1.6.6/jul-to-slf4j-1.6.6.jar to lib/logging/jul-to-slf4j-1.6.6.jar
DOWNLOAD: http://central.maven.org/maven2/org/slf4j/jcl-over-slf4j/1.6.6/jcl-over-slf4j-1.6.6.jar to lib/logging/jcl-over-slf4j-1.6.6.jar
DOWNLOAD: http://central.maven.org/maven2/ch/qos/logback/logback-core/1.0.7/logback-core-1.0.7.jar to lib/logging/logback-core-1.0.7.jar
DOWNLOAD: http://central.maven.org/maven2/ch/qos/logback/logback-classic/1.0.7/logback-classic-1.0.7.jar to lib/logging/logback-classic-1.0.7.jar
DOWNLOAD: https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.6.6/slf4j-api-1.6.6.jar to lib/logging/slf4j-api-1.6.6.jar
DOWNLOAD: https://repo1.maven.org/maven2/org/slf4j/log4j-over-slf4j/1.6.6/log4j-over-slf4j-1.6.6.jar to lib/logging/log4j-over-slf4j-1.6.6.jar
DOWNLOAD: https://repo1.maven.org/maven2/org/slf4j/jul-to-slf4j/1.6.6/jul-to-slf4j-1.6.6.jar to lib/logging/jul-to-slf4j-1.6.6.jar
DOWNLOAD: https://repo1.maven.org/maven2/org/slf4j/jcl-over-slf4j/1.6.6/jcl-over-slf4j-1.6.6.jar to lib/logging/jcl-over-slf4j-1.6.6.jar
DOWNLOAD: https://repo1.maven.org/maven2/ch/qos/logback/logback-core/1.0.7/logback-core-1.0.7.jar to lib/logging/logback-core-1.0.7.jar
DOWNLOAD: https://repo1.maven.org/maven2/ch/qos/logback/logback-classic/1.0.7/logback-classic-1.0.7.jar to lib/logging/logback-classic-1.0.7.jar
DOWNLOAD: https://raw.githubusercontent.com/jetty-project/logging-modules/master/capture-all/logback.xml to resources/logback.xml
DOWNLOAD: https://raw.githubusercontent.com/jetty-project/logging-modules/master/capture-all/jetty-logging.properties to resources/jetty-logging.properties
DOWNLOAD: https://raw.githubusercontent.com/jetty-project/logging-modules/master/capture-all/jetty-logging.xml to etc/jetty-logging.xml
INFO: resources initialised transitively
INFO: resources enabled in ${jetty.base}/start.ini
INFO: webapp-logging initialised in ${jetty.base}/start.ini (appended)
DOWNLOAD: http://central.maven.org/maven2/org/eclipse/jetty/jetty-webapp-logging/9.0.0/jetty-webapp-logging-9.0.0.jar to lib/webapp-logging/jetty-webapp-logging-9.0.0.jar
DOWNLOAD: https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-webapp-logging/9.0.0/jetty-webapp-logging-9.0.0.jar to lib/webapp-logging/jetty-webapp-logging-9.0.0.jar
DOWNLOAD: https://raw.githubusercontent.com/jetty-project/jetty-webapp-logging/master/src/main/config/etc/jetty-webapp-logging.xml to etc/jetty-webapp-logging.xml
DOWNLOAD: https://raw.githubusercontent.com/jetty-project/jetty-webapp-logging/master/src/main/config/etc/jetty-mdc-handler.xml to etc/jetty-mdc-handler.xml
INFO: deploy initialised transitively

View File

@ -37,9 +37,9 @@ A convenient replacement `logging` module has been created to bootstrap the `${j
[mybase]$ java -jar /opt/jetty-dist/start.jar --add-to-start=logging
INFO: logging initialised in ${jetty.base}/start.ini (appended)
MKDIR: ${jetty.base}/logs
DOWNLOAD: http://central.maven.org/maven2/org/slf4j/slf4j-api/1.6.6/slf4j-api-1.6.6.jar to lib/logging/slf4j-api-1.6.6.jar
DOWNLOAD: http://central.maven.org/maven2/ch/qos/logback/logback-core/1.0.7/logback-core-1.0.7.jar to lib/logging/logback-core-1.0.7.jar
DOWNLOAD: http://central.maven.org/maven2/ch/qos/logback/logback-classic/1.0.7/logback-classic-1.0.7.jar to lib/logging/logback-classic-1.0.7.jar
DOWNLOAD: https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.6.6/slf4j-api-1.6.6.jar to lib/logging/slf4j-api-1.6.6.jar
DOWNLOAD: https://repo1.maven.org/maven2/ch/qos/logback/logback-core/1.0.7/logback-core-1.0.7.jar to lib/logging/logback-core-1.0.7.jar
DOWNLOAD: https://repo1.maven.org/maven2/ch/qos/logback/logback-classic/1.0.7/logback-classic-1.0.7.jar to lib/logging/logback-classic-1.0.7.jar
DOWNLOAD: https://raw.githubusercontent.com/jetty-project/logging-modules/master/logback/logback.xml to resources/logback.xml
DOWNLOAD: https://raw.githubusercontent.com/jetty-project/logging-modules/master/logback/jetty-logging.properties to resources/jetty-logging.properties

View File

@ -102,12 +102,12 @@ A convenient replacement `logging` module has been created to bootstrap the `${j
[mybase]$ java -jar /opt/jetty-dist/start.jar --add-to-start=logging
INFO: logging initialised in ${jetty.base}/start.ini (appended)
MKDIR: ${jetty.base}/logs
DOWNLOAD: http://central.maven.org/maven2/org/slf4j/slf4j-api/1.6.6/slf4j-api-1.6.6.jar to lib/logging/slf4j-api-1.6.6.jar
DOWNLOAD: http://central.maven.org/maven2/org/slf4j/log4j-over-slf4j/1.6.6/log4j-over-slf4j-1.6.6.jar to lib/logging/log4j-over-slf4j-1.6.6.jar
DOWNLOAD: http://central.maven.org/maven2/org/slf4j/jul-to-slf4j/1.6.6/jul-to-slf4j-1.6.6.jar to lib/logging/jul-to-slf4j-1.6.6.jar
DOWNLOAD: http://central.maven.org/maven2/org/slf4j/jcl-over-slf4j/1.6.6/jcl-over-slf4j-1.6.6.jar to lib/logging/jcl-over-slf4j-1.6.6.jar
DOWNLOAD: http://central.maven.org/maven2/ch/qos/logback/logback-core/1.0.7/logback-core-1.0.7.jar to lib/logging/logback-core-1.0.7.jar
DOWNLOAD: http://central.maven.org/maven2/ch/qos/logback/logback-classic/1.0.7/logback-classic-1.0.7.jar to lib/logging/logback-classic-1.0.7.jar
DOWNLOAD: https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.6.6/slf4j-api-1.6.6.jar to lib/logging/slf4j-api-1.6.6.jar
DOWNLOAD: https://repo1.maven.org/maven2/org/slf4j/log4j-over-slf4j/1.6.6/log4j-over-slf4j-1.6.6.jar to lib/logging/log4j-over-slf4j-1.6.6.jar
DOWNLOAD: https://repo1.maven.org/maven2/org/slf4j/jul-to-slf4j/1.6.6/jul-to-slf4j-1.6.6.jar to lib/logging/jul-to-slf4j-1.6.6.jar
DOWNLOAD: https://repo1.maven.org/maven2/org/slf4j/jcl-over-slf4j/1.6.6/jcl-over-slf4j-1.6.6.jar to lib/logging/jcl-over-slf4j-1.6.6.jar
DOWNLOAD: https://repo1.maven.org/maven2/ch/qos/logback/logback-core/1.0.7/logback-core-1.0.7.jar to lib/logging/logback-core-1.0.7.jar
DOWNLOAD: https://repo1.maven.org/maven2/ch/qos/logback/logback-classic/1.0.7/logback-classic-1.0.7.jar to lib/logging/logback-classic-1.0.7.jar
DOWNLOAD: https://raw.githubusercontent.com/jetty-project/logging-modules/master/capture-all/logback.xml to resources/logback.xml
DOWNLOAD: https://raw.githubusercontent.com/jetty-project/logging-modules/master/capture-all/jetty-logging.properties to resources/jetty-logging.properties
DOWNLOAD: https://raw.githubusercontent.com/jetty-project/logging-modules/master/capture-all/jetty-logging.xml to etc/jetty-logging.xml

View File

@ -27,7 +27,7 @@ Of course, if your webapp is not as straightforward, the `jetty-runner` has comm
You will need the `jetty-runner` jar:
1. Download the `jetty-runner` jar available at http://central.maven.org/maven2/org/eclipse/jetty/jetty-runner/[Maven Central].
1. Download the `jetty-runner` jar available at https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-runner/[Maven Central].
==== Deploying a Simple Context

View File

@ -123,23 +123,23 @@ INFO : jndi transitively enabled
MKDIR : ${jetty.base}/etc
COPY : ${jetty.home}/modules/jul-impl/etc/java-util-logging.properties to ${jetty.base}/etc/java-util-logging.properties
MKDIR : ${jetty.base}/lib/slf4j
DOWNLD: http://central.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-api-1.7.21.jar
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-api-1.7.21.jar
MKDIR : ${jetty.base}/lib/gcloud
COPY : /Users/admin/.m2/repository/aopalliance/aopalliance/1.0/aopalliance-1.0.jar to ${jetty.base}/lib/gcloud/aopalliance-1.0.jar
COPY : /Users/admin/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.1.3/jackson-core-2.1.3.jar to ${jetty.base}/lib/gcloud/jackson-core-2.1.3.jar
COPY : /Users/admin/.m2/repository/com/google/api-client/google-api-client-appengine/1.21.0/google-api-client-appengine-1.21.0.jar to ${jetty.base}/lib/gcloud/google-api-client-appengine-1.21.0.jar
COPY : /Users/admin/.m2/repository/com/google/api-client/google-api-client/1.20.0/google-api-client-1.20.0.jar to ${jetty.base}/lib/gcloud/google-api-client-1.20.0.jar
COPY : /Users/admin/.m2/repository/com/google/api-client/google-api-client-servlet/1.21.0/google-api-client-servlet-1.21.0.jar to ${jetty.base}/lib/gcloud/google-api-client-servlet-1.21.0.jar
DOWNLD: http://central.maven.org/maven2/com/google/api/gax/0.0.21/gax-0.0.21.jar to ${jetty.base}/lib/gcloud/gax-0.0.21.jar
DOWNLD: https://repo1.maven.org/maven2/com/google/api/gax/0.0.21/gax-0.0.21.jar to ${jetty.base}/lib/gcloud/gax-0.0.21.jar
COPY : /Users/admin/.m2/repository/com/google/api/grpc/grpc-google-common-protos/0.1.0/grpc-google-common-protos-0.1.0.jar to ${jetty.base}/lib/gcloud/grpc-google-common-protos-0.1.0.jar
COPY : /Users/admin/.m2/repository/com/google/api/grpc/grpc-google-iam-v1/0.1.0/grpc-google-iam-v1-0.1.0.jar to ${jetty.base}/lib/gcloud/grpc-google-iam-v1-0.1.0.jar
COPY : /Users/admin/.m2/repository/com/google/auth/google-auth-library-credentials/0.3.1/google-auth-library-credentials-0.3.1.jar to ${jetty.base}/lib/gcloud/google-auth-library-credentials-0.3.1.jar
COPY : /Users/admin/.m2/repository/com/google/auth/google-auth-library-oauth2-http/0.3.1/google-auth-library-oauth2-http-0.3.1.jar to ${jetty.base}/lib/gcloud/google-auth-library-oauth2-http-0.3.1.jar
DOWNLD: http://central.maven.org/maven2/com/google/auto/value/auto-value/1.2/auto-value-1.2.jar to ${jetty.base}/lib/gcloud/auto-value-1.2.jar
DOWNLD: http://central.maven.org/maven2/com/google/cloud/datastore/datastore-v1-proto-client/1.3.0/datastore-v1-proto-client-1.3.0.jar to ${jetty.base}/lib/gcloud/datastore-v1-proto-client-1.3.0.jar
DOWNLD: http://central.maven.org/maven2/com/google/cloud/datastore/datastore-v1-protos/1.3.0/datastore-v1-protos-1.3.0.jar to ${jetty.base}/lib/gcloud/datastore-v1-protos-1.3.0.jar
DOWNLD: http://central.maven.org/maven2/com/google/cloud/google-cloud-core/0.5.1/google-cloud-core-0.5.1.jar to ${jetty.base}/lib/gcloud/google-cloud-core-0.5.0.jar
DOWNLD: http://central.maven.org/maven2/com/google/cloud/google-cloud-datastore/0.5.1/google-cloud-datastore-0.5.1.jar to ${jetty.base}/lib/gcloud/google-cloud-datastore-0.5.1.jar
DOWNLD: https://repo1.maven.org/maven2/com/google/auto/value/auto-value/1.2/auto-value-1.2.jar to ${jetty.base}/lib/gcloud/auto-value-1.2.jar
DOWNLD: https://repo1.maven.org/maven2/com/google/cloud/datastore/datastore-v1-proto-client/1.3.0/datastore-v1-proto-client-1.3.0.jar to ${jetty.base}/lib/gcloud/datastore-v1-proto-client-1.3.0.jar
DOWNLD: https://repo1.maven.org/maven2/com/google/cloud/datastore/datastore-v1-protos/1.3.0/datastore-v1-protos-1.3.0.jar to ${jetty.base}/lib/gcloud/datastore-v1-protos-1.3.0.jar
DOWNLD: https://repo1.maven.org/maven2/com/google/cloud/google-cloud-core/0.5.1/google-cloud-core-0.5.1.jar to ${jetty.base}/lib/gcloud/google-cloud-core-0.5.0.jar
DOWNLD: https://repo1.maven.org/maven2/com/google/cloud/google-cloud-datastore/0.5.1/google-cloud-datastore-0.5.1.jar to ${jetty.base}/lib/gcloud/google-cloud-datastore-0.5.1.jar
COPY : /Users/admin/.m2/repository/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.jar to ${jetty.base}/lib/gcloud/jsr305-1.3.9.jar
COPY : /Users/admin/.m2/repository/com/google/code/gson/gson/2.3/gson-2.3.jar to ${jetty.base}/lib/gcloud/gson-2.3.jar
COPY : /Users/admin/.m2/repository/com/google/guava/guava/19.0/guava-19.0.jar to ${jetty.base}/lib/gcloud/guava-19.0.jar
@ -168,7 +168,7 @@ COPY : /Users/admin/.m2/repository/org/apache/httpcomponents/httpclient/4.0.1/h
COPY : /Users/admin/.m2/repository/org/apache/httpcomponents/httpcore/4.0.1/httpcore-4.0.1.jar to ${jetty.base}/lib/gcloud/httpcore-4.0.1.jar
COPY : /Users/admin/.m2/repository/org/codehaus/jackson/jackson-core-asl/1.9.11/jackson-core-asl-1.9.11.jar to ${jetty.base}/lib/gcloud/jackson-core-asl-1.9.11.jar
COPY : /Users/admin/.m2/repository/org/json/json/20151123/json-20151123.jar to ${jetty.base}/lib/gcloud/json-20151123.jar
DOWNLD: http://central.maven.org/maven2/org/slf4j/jcl-over-slf4j/1.7.21/jcl-over-slf4j-1.7.21.jar to ${jetty.base}/lib/slf4j/jcl-over-slf4j-1.7.21.jar
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/jcl-over-slf4j/1.7.21/jcl-over-slf4j-1.7.21.jar to ${jetty.base}/lib/slf4j/jcl-over-slf4j-1.7.21.jar
COPY : ${jetty.home}/modules/gcloud/index.yaml to ${jetty.base}/etc/index.yaml
INFO : Base directory was modified
ERROR : Module jcl-slf4j requires a module providing slf4j-impl from one of [slf4j-simple-impl, slf4j-logback, slf4j-jul, slf4j-log4j2, slf4j-log4j]
@ -196,7 +196,7 @@ In this example, we will enable the `slf4j-simple-impl` module to provide a SLF4
$ java -jar ../start.jar --add-to-start=slf4j-simple-impl
INFO : slf4j-simple-impl initialized in ${jetty.base}/start.d/slf4j-simple-impl.ini
INFO : resources transitively enabled
DOWNLD: http://central.maven.org/maven2/org/slf4j/slf4j-simple/1.7.21/slf4j-simple-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-simple-1.7.21.jar
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/slf4j-simple/1.7.21/slf4j-simple-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-simple-1.7.21.jar
MKDIR : ${jetty.base}/resources
COPY : ${jetty.home}/modules/slf4j-simple-impl/resources/simplelogger.properties to ${jetty.base}/resources/simplelogger.properties
INFO : Base directory was modified

View File

@ -48,7 +48,7 @@ INFO : server transitively enabled, ini template available with --add-
INFO : sessions transitively enabled, ini template available with --add-to-start=sessions
INFO : session-store-hazelcast-remote initialized in ${jetty.base}/start.d/session-store-hazelcast-remote.ini
MKDIR : /Users/admin/mvn-repo/com/hazelcast/hazelcast/3.8.2
DOWNLD: http://central.maven.org/maven2/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to /Users/admin/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar
DOWNLD: https://repo1.maven.org/maven2/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to /Users/admin/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar
MKDIR : ${jetty.base}/lib/hazelcast
COPY : /Users/admin/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to ${jetty.base}/lib/hazelcast/hazelcast-3.8.2.jar
COPY : /Users/admin/mvn-repo/com/hazelcast/hazelcast-client/3.8.2/hazelcast-client-3.8.2.jar to ${jetty.base}/lib/hazelcast/hazelcast-client-3.8.2.jar
@ -136,7 +136,7 @@ INFO : server transitively enabled, ini template available with --add-
INFO : sessions transitively enabled, ini template available with --add-to-start=sessions
INFO : session-store-hazelcast-embedded initialized in ${jetty.base}/start.d/session-store-hazelcast-embedded.ini
MKDIR : /Users/admin/mvn-repo/com/hazelcast/hazelcast/3.8.2
DOWNLD: http://central.maven.org/maven2/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to /Users/admin/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar
DOWNLD: https://repo1.maven.org/maven2/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to /Users/admin/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar
MKDIR : ${jetty.base}/lib/hazelcast
COPY : /Users/admin/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to ${jetty.base}/lib/hazelcast/hazelcast-3.8.2.jar
COPY : /Users/admin/mvn-repo/com/hazelcast/hazelcast-client/3.8.2/hazelcast-client-3.8.2.jar to ${jetty.base}/lib/hazelcast/hazelcast-client-3.8.2.jar

View File

@ -52,7 +52,7 @@ INFO : server transitively enabled, ini template available with --add-
INFO : sessions transitively enabled, ini template available with --add-to-start=sessions
INFO : session-store-infinispan-remote initialized in ${jetty.base}/start.d/session-store-infinispan-remote.ini
MKDIR : ${jetty.base}/lib/infinispan
DOWNLD: http://central.maven.org/maven2/org/infinispan/infinispan-remote/7.1.1.Final/infinispan-remote-7.1.1.Final.jar to ${jetty.base}/lib/infinispan/infinispan-remote-7.1.1.Final.jar
DOWNLD: https://repo1.maven.org/maven2/org/infinispan/infinispan-remote/7.1.1.Final/infinispan-remote-7.1.1.Final.jar to ${jetty.base}/lib/infinispan/infinispan-remote-7.1.1.Final.jar
MKDIR : ${jetty.base}/resources
COPY : ${jetty.home}/modules/session-store-infinispan-remote/resources/hotrod-client.properties to ${jetty.base}/resources/hotrod-client.properties
INFO : Base directory was modified
@ -137,7 +137,7 @@ Proceed (y/N)? y
INFO : server initialised (transitively) in ${jetty.base}/start.d/server.ini
INFO : sessions initialised (transitively) in ${jetty.base}/start.d/sessions.ini
INFO : session-store-infinispan-embedded initialised in ${jetty.base}/start.d/session-store-infinispan-embedded.ini
DOWNLOAD: http://central.maven.org/maven2/org/infinispan/infinispan-embedded/7.1.1.Final/infinispan-embedded-7.1.1.Final.jar to ${jetty.base}/lib/infinispan/infinispan-embedded-7.1.1.Final.jar
DOWNLOAD: https://repo1.maven.org/maven2/org/infinispan/infinispan-embedded/7.1.1.Final/infinispan-embedded-7.1.1.Final.jar to ${jetty.base}/lib/infinispan/infinispan-embedded-7.1.1.Final.jar
INFO : Base directory was modified
----

View File

@ -48,7 +48,7 @@ INFO : sessions transitively enabled, ini template available with --add-
INFO : session-store-mongo initialized in ${jetty.base}/start.d/session-store-mongo.ini
INFO : sessions/mongo/address dynamic dependency of session-store-mongo
MKDIR : ${jetty.base}/lib/nosql
DOWNLD: http://central.maven.org/maven2/org/mongodb/mongo-java-driver/2.13.2/mongo-java-driver-2.13.2.jar to ${jetty.base}/lib/nosql/mongo-java-driver-2.13.2.jar
DOWNLD: https://repo1.maven.org/maven2/org/mongodb/mongo-java-driver/2.13.2/mongo-java-driver-2.13.2.jar to ${jetty.base}/lib/nosql/mongo-java-driver-2.13.2.jar
INFO : Base directory was modified
----

View File

@ -207,7 +207,7 @@ MKDIR : ${jetty.base}/lib/alpn
MKDIR : ${jetty.base}/etc
COPY : ${jetty.home}/modules/ssl/keystore to ${jetty.base}/etc/keystore
MKDIR : ${jetty.base}/webapps
DOWNLD: http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.8.v20160420/alpn-boot-8.1.8.v20160420.jar to ${jetty.base}/lib/alpn/alpn-boot-8.1.8.v20160420.jar
DOWNLD: https://repo1.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.8.v20160420/alpn-boot-8.1.8.v20160420.jar to ${jetty.base}/lib/alpn/alpn-boot-8.1.8.v20160420.jar
COPY : ${jetty.home}/modules/acme/acme.xml to ${jetty.base}/etc/acme.xml
INFO : Base directory was modified
----

View File

@ -261,4 +261,4 @@ You might need to escape the slash "\|" to use this on some environments.
maven.repo.uri=[url]::
The url to use to download Maven dependencies.
Default is http://central.maven.org/maven2/.
Default is https://repo1.maven.org/maven2/.

View File

@ -83,7 +83,7 @@ INFO : server transitively enabled, ini template available with --add-
INFO : conscrypt initialized in ${jetty.base}/start.d/conscrypt.ini
INFO : ssl initialized in ${jetty.base}/start.d/ssl.ini
MKDIR : ${jetty.base}/lib/conscrypt
DOWNLD: http://central.maven.org/maven2/org/conscrypt/conscrypt-openjdk-uber/1.0.0.RC11/conscrypt-openjdk-uber-1.0.0.RC11.jar to ${jetty.base}/lib/conscrypt/conscrypt-uber-1.0.0.RC11.jar
DOWNLD: https://repo1.maven.org/maven2/org/conscrypt/conscrypt-openjdk-uber/1.0.0.RC11/conscrypt-openjdk-uber-1.0.0.RC11.jar to ${jetty.base}/lib/conscrypt/conscrypt-uber-1.0.0.RC11.jar
MKDIR : ${jetty.base}/etc
COPY : ${jetty.home}/modules/conscrypt/conscrypt.xml to ${jetty.base}/etc/conscrypt.xml
COPY : ${jetty.home}/modules/ssl/keystore to ${jetty.base}/etc/keystore

View File

@ -38,7 +38,7 @@ Its purpose is to provide almost the same functionality as the Jetty plugin for
To set up your project for Ant to run Jetty, you need a Jetty distribution and the jetty-ant Jar:
1. https://www.eclipse.org/jetty/download.html[Download] a Jetty distribution and unpack it in the local filesystem.
2. http://central.maven.org/maven2/org/eclipse/jetty/jetty-ant/[Get] the jetty-ant Jar.
2. https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-ant/[Get] the jetty-ant Jar.
3. Make a directory in your project called `jetty-lib/`.
4. Copy all of the Jars in your Jetty distribution's `lib` directory, and all its subdirectories, into your new `jetty-lib` dir.
When copying the Jars, _don't_ preserve the Jetty distribution's lib dir hierarchy all the jars should be directly inside your ` jetty-lib` dir.

View File

@ -26,7 +26,7 @@ This section provides a tutorial that shows how you can quickly develop embedded
Jetty is decomposed into many jars and dependencies to achieve a minimal footprint by selecting the minimal set of jars.
Typically it is best to use something like link:#jetty-maven-helloworld[Maven] to manage jars, however this tutorial uses an aggregate Jar that contains all of the required Jetty classes in one Jar.
You can manually download the aggregate link:http://central.maven.org/maven2/org/eclipse/jetty/aggregate/jetty-all/{VERSION}/jetty-all-{VERSION}-uber.jar[`jetty-all.jar`] using `curl` or a browser.
You can manually download the aggregate link:https://repo1.maven.org/maven2/org/eclipse/jetty/aggregate/jetty-all/{VERSION}/jetty-all-{VERSION}-uber.jar[`jetty-all.jar`] using `curl` or a browser.
____
[NOTE]
@ -46,7 +46,7 @@ Use curl as follows:
....
> mkdir Demo
> cd Demo
> curl -o jetty-all-uber.jar http://central.maven.org/maven2/org/eclipse/jetty/aggregate/jetty-all/{VERSION}/jetty-all-{VERSION}-uber.jar
> curl -o jetty-all-uber.jar https://repo1.maven.org/maven2/org/eclipse/jetty/aggregate/jetty-all/{VERSION}/jetty-all-{VERSION}-uber.jar
....
[[writing-helloworld-example]]

View File

@ -56,9 +56,9 @@ You *must also install the Apache Aries SPI Fly bundles* as many parts of Jetty
|=======================================================================
|Jar |Bundle Symbolic Name |Location
|org.apache.aries.spifly:org.apache.aries.spifly.dynamic.bundle-1.0.1.jar |org.apache.aries.spifly.dynamic.bundle
|http://central.maven.org/maven2/org/apache/aries/spifly/org.apache.aries.spifly.dynamic.bundle/[Maven central]
|https://repo1.maven.org/maven2/org/apache/aries/spifly/org.apache.aries.spifly.dynamic.bundle/[Maven central]
|org.apache.aries:org.apache.aries.util-1.0.1.jar |org.apache.aries.util
|http://central.maven.org/maven2/org/apache/aries/org.apache.aries.util/[Maven
|https://repo1.maven.org/maven2/org/apache/aries/org.apache.aries.util/[Maven
central]
|=======================================================================
@ -74,7 +74,7 @@ If your OSGi container does not automatically make these available, you will nee
===== The jetty-osgi-boot jar
Now that you have the basic set of Jetty jars installed, you can install the http://central.maven.org/maven2/org/eclipse/jetty/osgi/jetty-osgi-boot/[jetty-osgi-boot.jar] bundle, downloadable from the maven central repo http://central.maven.org/maven2/org/eclipse/jetty/osgi/jetty-osgi-boot/[here.]
Now that you have the basic set of Jetty jars installed, you can install the https://repo1.maven.org/maven2/org/eclipse/jetty/osgi/jetty-osgi-boot/[jetty-osgi-boot.jar] bundle, downloadable from the maven central repo https://repo1.maven.org/maven2/org/eclipse/jetty/osgi/jetty-osgi-boot/[here.]
This bundle will instantiate and make available the Jetty OSGi container when it is started.
If this bundle is not auto-started upon installation into your OSGi container, you should start it manually using a command appropriate for your container.
@ -663,7 +663,7 @@ The Jetty OSGi container failed to deploy a `WebAppContext` or `ContextHandler`
===== Setup
In order to use JSPs with your webapps and bundles you will need to install the JSP and JSTL jars and their dependencies into your OSGi container.
Some you will find in the Jetty distribution, whereas others you will need to download from http://central.maven.org/maven2/org/eclipse/jetty/orbit/[Maven central].
Some you will find in the Jetty distribution, whereas others you will need to download from https://repo1.maven.org/maven2/org/eclipse/jetty/orbit/[Maven central].
Here is the list of recommended jars (NOTE the version numbers may change in future):
[[osgi-jsp]]
@ -688,7 +688,7 @@ Here is the list of recommended jars (NOTE the version numbers may change in fut
|org.eclipse.jetty.osgi:jetty-osgi-boot-jsp
|org.eclipse.jetty.osgi.boot.jsp
|http://central.maven.org/maven2/org/eclipse/jetty/osgi/jetty-osgi-boot-jsp[Maven central]
|https://repo1.maven.org/maven2/org/eclipse/jetty/osgi/jetty-osgi-boot-jsp[Maven central]
|=======================================================================
____
@ -738,8 +738,8 @@ Orbit]
===== The jetty-osgi-boot-jsp jar
To be able to use JSPs you will need to also install the http://central.maven.org/maven2/org/eclipse/jetty/osgi/jetty-osgi-boot-jsp/[jetty-osgi-boot-jsp.jar] into your OSGi container.
This jar can be obtained from maven central http://central.maven.org/maven2/org/eclipse/jetty/osgi/jetty-osgi-boot-jsp/[here].
To be able to use JSPs you will need to also install the https://repo1.maven.org/maven2/org/eclipse/jetty/osgi/jetty-osgi-boot-jsp/[jetty-osgi-boot-jsp.jar] into your OSGi container.
This jar can be obtained from maven central https://repo1.maven.org/maven2/org/eclipse/jetty/osgi/jetty-osgi-boot-jsp/[here].
This bundle acts as a fragment extension to the jetty-osgi-boot.jar and adds in support for using JSP.
@ -836,16 +836,16 @@ In order to use them with Jetty in OSGi, you will need to deploy some extra jars
|Jar |Bundle Symbolic Name |Location
|The link:#spifly[spifly jars] | |
|org.ow2.asm:asm-5.0.1.jar |org.objectweb.asm
|http://central.maven.org/maven2/org/ow2/asm/asm[Maven central]
|https://repo1.maven.org/maven2/org/ow2/asm/asm[Maven central]
|org.ow2.asm:asm-commons-5.0.1.jar |org.objectweb.asm.commons
|http://central.maven.org/maven2/org/ow2/asm/asm-commons[Maven central]
|https://repo1.maven.org/maven2/org/ow2/asm/asm-commons[Maven central]
|org.ow2.asm:asm-tree-5.0.1.jar |org.objectweb.asm.tree
|http://central.maven.org/maven2/org/ow2/asm/asm-tree[Maven central]
|https://repo1.maven.org/maven2/org/ow2/asm/asm-tree[Maven central]
|javax.annotation:javax.annotation-api-1.2.jar |javax.annotation-api
|http://central.maven.org/maven2/javax/annotation/javax.annotation-api/[Maven
|https://repo1.maven.org/maven2/javax/annotation/javax.annotation-api/[Maven
central]
|jta api version 1.1.1 (eg
@ -1161,6 +1161,6 @@ In addition, as the feature group includes websocket, you will need to download
|=======================================================================
|Jar |Bundle Symbolic Name |Location
|javax.websocket-api |javax.websocket-api
|http://central.maven.org/maven2/javax/websocket/websocket-api[Maven
|https://repo1.maven.org/maven2/javax/websocket/websocket-api[Maven
central]
|=======================================================================

View File

@ -113,7 +113,7 @@ Default value: the `org.apache.jasper.JspC` instance being configured.
+
The JspC class actually performs the pre-compilation.
All setters on the JspC class are available.
You can download the javadoc http://central.maven.org/maven2/org/glassfish/web/javax.servlet.jsp/2.3.2/javax.servlet.jsp-2.3.2-javadoc.jar[here].
You can download the javadoc https://repo1.maven.org/maven2/org/glassfish/web/javax.servlet.jsp/2.3.2/javax.servlet.jsp-2.3.2-javadoc.jar[here].
Taking all the default settings, here's how to configure the war plugin to use the generated `web.xml` that includes all of the jsp servlet declarations:

View File

@ -115,7 +115,7 @@ Use an editor to create the file `pom.xml` in the `JettyMavenHelloWorld` directo
<properties>
<!-- Adapt this to a version found on
http://central.maven.org/maven2/org/eclipse/jetty/jetty-maven-plugin/
https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-maven-plugin/
-->
<jettyVersion>9.3.9.v20160517</jettyVersion>
</properties>

View File

@ -145,7 +145,7 @@ INFO : http2 initialized in ${jetty.base}/start.d/http2.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}/lib/alpn
DOWNLD: http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.8.v20160420/alpn-boot-8.1.8.v20160420.jar to ${jetty.base}/lib/alpn/alpn-boot-8.1.8.v20160420.jar
DOWNLD: https://repo1.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.8.v20160420/alpn-boot-8.1.8.v20160420.jar to ${jetty.base}/lib/alpn/alpn-boot-8.1.8.v20160420.jar
MKDIR : ${jetty.base}/etc
COPY : ${jetty.home}/modules/ssl/keystore to ${jetty.base}/etc/keystore
INFO : Base directory was modified

View File

@ -72,7 +72,7 @@ Jetty-Home can be downloaded from the Maven Central repository:
____
*Jetty-Home*
http://central.maven.org/maven2/org/eclipse/jetty/jetty-home/
https://repo1.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.

View File

@ -47,7 +47,7 @@ The top level Project Object Model (POM) for the Jetty project is located under
The changes between versions of Jetty are tracked in a file called VERSIONS.txt, which is under source control and is generated on release.
Those generated files are also uploaded into Maven Central during the release of the top level POM. You can find them as a classifier marked artifact.
http://central.maven.org/maven2/org/eclipse/jetty/jetty-project/
https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-project/
[source, xml, subs="{sub-order}"]
----

View File

@ -50,15 +50,17 @@ import org.eclipse.jetty.util.log.Logger;
*/
public enum HttpCompliance // TODO in Jetty-10 convert this enum to a class so that extra custom modes can be defined dynamically
{
/** A Legacy compliance mode to match jetty's behavior prior to RFC2616 and RFC7230. It only
* contains {@link HttpComplianceSection#METHOD_CASE_SENSITIVE}
/** A Legacy compliance mode to match jetty's behavior prior to RFC2616 and RFC7230.
*/
LEGACY(sectionsBySpec("0,METHOD_CASE_SENSITIVE")),
/** The legacy RFC2616 support, which incorrectly excludes
* {@link HttpComplianceSection#METHOD_CASE_SENSITIVE}, {@link HttpComplianceSection#FIELD_COLON}
* {@link HttpComplianceSection#METHOD_CASE_SENSITIVE},
* {@link HttpComplianceSection#FIELD_COLON},
* {@link HttpComplianceSection#TRANSFER_ENCODING_WITH_CONTENT_LENGTH},
* {@link HttpComplianceSection#MULTIPLE_CONTENT_LENGTHS},
*/
RFC2616_LEGACY(sectionsBySpec("RFC2616,-FIELD_COLON,-METHOD_CASE_SENSITIVE")),
RFC2616_LEGACY(sectionsBySpec("RFC2616,-FIELD_COLON,-METHOD_CASE_SENSITIVE,-TRANSFER_ENCODING_WITH_CONTENT_LENGTH,-MULTIPLE_CONTENT_LENGTHS")),
/** The strict RFC2616 support mode */
RFC2616(sectionsBySpec("RFC2616")),

View File

@ -28,7 +28,9 @@ public enum HttpComplianceSection
FIELD_NAME_CASE_INSENSITIVE("https://tools.ietf.org/html/rfc7230#section-3.2","Field name is case-insensitive"),
NO_WS_AFTER_FIELD_NAME("https://tools.ietf.org/html/rfc7230#section-3.2.4","Whitespace not allowed after field name"),
NO_FIELD_FOLDING("https://tools.ietf.org/html/rfc7230#section-3.2.4","No line Folding"),
NO_HTTP_0_9("https://tools.ietf.org/html/rfc7230#appendix-A.2","No HTTP/0.9");
NO_HTTP_0_9("https://tools.ietf.org/html/rfc7230#appendix-A.2","No HTTP/0.9"),
TRANSFER_ENCODING_WITH_CONTENT_LENGTH("https://tools.ietf.org/html/rfc7230#section-3.3.1","Transfer-Encoding and Content-Length"),
MULTIPLE_CONTENT_LENGTHS("https://tools.ietf.org/html/rfc7230#section-3.3.1","Multiple Content-Lengths");
final String url;
final String description;

View File

@ -18,21 +18,174 @@
package org.eclipse.jetty.http;
import org.eclipse.jetty.util.TypeUtil;
/**
* HTTP constants
*/
public interface HttpTokens
public class HttpTokens
{
// Terminal symbols.
static final byte COLON= (byte)':';
static final byte TAB= 0x09;
static final byte LINE_FEED= 0x0A;
static final byte CARRIAGE_RETURN= 0x0D;
static final byte SPACE= 0x20;
static final byte[] CRLF = {CARRIAGE_RETURN,LINE_FEED};
static final byte SEMI_COLON= (byte)';';
public enum EndOfContent { UNKNOWN_CONTENT,NO_CONTENT,EOF_CONTENT,CONTENT_LENGTH,CHUNKED_CONTENT }
public enum Type
{
CNTL, // Control characters excluding LF, CR
HTAB, // Horizontal tab
LF, // Line feed
CR, // Carriage return
SPACE, // Space
COLON, // Colon character
DIGIT, // Digit
ALPHA, // Alpha
TCHAR, // token characters excluding COLON,DIGIT,ALPHA, which is equivalent to VCHAR excluding delimiters
VCHAR, // Visible characters excluding COLON,DIGIT,ALPHA
OTEXT // Obsolete text
}
public static class Token
{
private final Type _type;
private final byte _b;
private final char _c;
private final int _x;
private Token(byte b, Type type)
{
_type = type;
_b = b;
_c = (char)(0xff&b);
char lc = (_c>='A' & _c<='Z')?((char)(_c-'A'+'a')):_c;
_x = (_type==Type.DIGIT || _type==Type.ALPHA && lc>='a' && lc<='f')?TypeUtil.convertHexDigit(b):-1;
}
public Type getType()
{
return _type;
}
public byte getByte()
{
return _b;
}
public char getChar()
{
return _c;
}
public boolean isHexDigit()
{
return _x>=0;
}
public int getHexDigit()
{
return _x;
}
@Override
public String toString()
{
switch(_type)
{
case SPACE:
case COLON:
case ALPHA:
case DIGIT:
case TCHAR:
case VCHAR:
return _type+"='"+_c+"'";
case CR:
return "CR=\\r";
case LF:
return "LF=\\n";
default:
return String.format("%s=0x%x",_type,_b);
}
}
}
public final static Token[] TOKENS = new Token[256];
static
{
for (int b=0; b<256; b++)
{
// token = 1*tchar
// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
// / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
// / DIGIT / ALPHA
// ; any VCHAR, except delimiters
// quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE
// qdtext = HTAB / SP /%x21 / %x23-5B / %x5D-7E / obs-text
// obs-text = %x80-FF
// comment = "(" *( ctext / quoted-pair / comment ) ")"
// ctext = HTAB / SP / %x21-27 / %x2A-5B / %x5D-7E / obs-text
// quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
switch (b)
{
case LINE_FEED:
TOKENS[b] = new Token((byte)b,Type.LF);
break;
case CARRIAGE_RETURN:
TOKENS[b] = new Token((byte)b,Type.CR);
break;
case SPACE:
TOKENS[b] = new Token((byte)b,Type.SPACE);
break;
case TAB:
TOKENS[b] = new Token((byte)b,Type.HTAB);
break;
case COLON:
TOKENS[b] = new Token((byte)b,Type.COLON);
break;
case '!':
case '#':
case '$':
case '%':
case '&':
case '\'':
case '*':
case '+':
case '-':
case '.':
case '^':
case '_':
case '`':
case '|':
case '~':
TOKENS[b] = new Token((byte)b,Type.TCHAR);
break;
default:
if (b>=0x30 &&b<=0x39) // DIGIT
TOKENS[b] = new Token((byte)b,Type.DIGIT);
else if (b>=0x41 &&b<=0x5A) // ALPHA (uppercase)
TOKENS[b] = new Token((byte)b,Type.ALPHA);
else if (b>=0x61 &&b<=0x7A) // ALPHA (lowercase)
TOKENS[b] = new Token((byte)b,Type.ALPHA);
else if (b>=0x21 &&b<=0x7E) // Visible
TOKENS[b] = new Token((byte)b,Type.VCHAR);
else if (b>=0x80) // OBS
TOKENS[b] = new Token((byte)b,Type.OTEXT);
else
TOKENS[b] = new Token((byte)b,Type.CNTL);
}
}
}
}

View File

@ -40,13 +40,7 @@ import org.eclipse.jetty.util.log.Logger;
public class MultiPartParser
{
public static final Logger LOG = Log.getLogger(MultiPartParser.class);
private static final byte COLON = (byte)':';
private static final byte TAB = 0x09;
private static final byte LINE_FEED = 0x0A;
private static final byte CARRIAGE_RETURN = 0x0D;
private static final byte SPACE = 0x20;
// States
public enum FieldState
{
@ -134,41 +128,49 @@ public class MultiPartParser
}
/* ------------------------------------------------------------------------------- */
private byte getNextByte(ByteBuffer buffer)
private HttpTokens.Token next(ByteBuffer buffer)
{
byte ch = buffer.get();
HttpTokens.Token t = HttpTokens.TOKENS[0xff & ch];
HttpParser.CharState s = HttpParser.TOKEN_CHAR[0xff & ch];
switch (s)
if (DEBUG)
LOG.debug("token={}",t);
switch(t.getType())
{
case CNTL:
throw new IllegalCharacterException(_state,t,buffer);
case LF:
_cr = false;
return ch;
_cr=false;
break;
case CR:
if (_cr)
throw new BadMessageException("Bad EOL");
_cr = true;
if (buffer.hasRemaining())
return getNextByte(buffer);
// Can return 0 here to indicate the need for more characters,
// because a real 0 in the buffer would cause a BadMessage below
return 0;
case LEGAL:
_cr=true;
return null;
case ALPHA:
case DIGIT:
case TCHAR:
case VCHAR:
case HTAB:
case SPACE:
case OTEXT:
case COLON:
if (_cr)
throw new BadMessageException("Bad EOL");
break;
return ch;
case ILLEGAL:
default:
throw new IllegalCharacterException(_state, ch, buffer);
break;
}
}
return t;
}
/* ------------------------------------------------------------------------------- */
private void setString(String s)
@ -307,11 +309,11 @@ public class MultiPartParser
{
while (__delimiterStates.contains(_state) && hasNextByte(buffer))
{
byte b = getNextByte(buffer);
if (b == 0)
HttpTokens.Token t = next(buffer);
if (t == null)
return;
if (b == '\n')
if (t.getType()==HttpTokens.Type.LF)
{
setState(State.BODY_PART);
@ -325,14 +327,14 @@ public class MultiPartParser
switch (_state)
{
case DELIMITER:
if (b == '-')
if (t.getChar() == '-')
setState(State.DELIMITER_CLOSE);
else
setState(State.DELIMITER_PADDING);
continue;
case DELIMITER_CLOSE:
if (b == '-')
if (t.getChar() == '-')
{
setState(State.EPILOGUE);
return;
@ -356,11 +358,11 @@ public class MultiPartParser
while (_state == State.BODY_PART && hasNextByte(buffer))
{
// process each character
byte b = getNextByte(buffer);
if (b == 0)
HttpTokens.Token t = next(buffer);
if (t == null)
break;
if (b != LINE_FEED)
if (t.getType() != HttpTokens.Type.LF)
_totalHeaderLineLength++;
if (_totalHeaderLineLength > MAX_HEADER_LINE_LENGTH)
@ -369,10 +371,10 @@ public class MultiPartParser
switch (_fieldState)
{
case FIELD:
switch (b)
switch (t.getType())
{
case SPACE:
case TAB:
case HTAB:
{
// Folded field value!
@ -395,8 +397,7 @@ public class MultiPartParser
break;
}
case LINE_FEED:
{
case LF:
handleField();
setState(State.FIRST_OCTETS);
_partialBoundary = 2; // CRLF is option for empty parts
@ -407,24 +408,28 @@ public class MultiPartParser
if (_handler.headerComplete())
return true;
break;
}
default:
{
case ALPHA:
case DIGIT:
case TCHAR:
// process previous header
handleField();
// New header
setState(FieldState.IN_NAME);
_string.reset();
_string.append(b);
_string.append(t.getChar());
_length = 1;
}
break;
default:
throw new IllegalCharacterException(_state,t,buffer);
}
break;
case IN_NAME:
switch (b)
switch(t.getType())
{
case COLON:
_fieldName = takeString();
@ -437,7 +442,7 @@ public class MultiPartParser
setState(FieldState.AFTER_NAME);
break;
case LINE_FEED:
case LF:
{
if (LOG.isDebugEnabled())
LOG.debug("Line Feed in Name {}", this);
@ -446,16 +451,21 @@ public class MultiPartParser
setState(FieldState.FIELD);
break;
}
default:
_string.append(b);
case ALPHA:
case DIGIT:
case TCHAR:
_string.append(t.getChar());
_length = _string.length();
break;
default:
throw new IllegalCharacterException(_state,t,buffer);
}
break;
case AFTER_NAME:
switch (b)
switch(t.getType())
{
case COLON:
_fieldName = takeString();
@ -463,7 +473,7 @@ public class MultiPartParser
setState(FieldState.VALUE);
break;
case LINE_FEED:
case LF:
_fieldName = takeString();
_string.reset();
_fieldValue = "";
@ -474,14 +484,14 @@ public class MultiPartParser
break;
default:
throw new IllegalCharacterException(_state, b, buffer);
throw new IllegalCharacterException(_state, t, buffer);
}
break;
case VALUE:
switch (b)
switch(t.getType())
{
case LINE_FEED:
case LF:
_string.reset();
_fieldValue = "";
_length = -1;
@ -490,25 +500,34 @@ public class MultiPartParser
break;
case SPACE:
case TAB:
case HTAB:
break;
default:
_string.append(b);
case ALPHA:
case DIGIT:
case TCHAR:
case VCHAR:
case COLON:
case OTEXT:
_string.append(t.getByte());
_length = _string.length();
setState(FieldState.IN_VALUE);
break;
default:
throw new IllegalCharacterException(_state,t,buffer);
}
break;
case IN_VALUE:
switch (b)
switch(t.getType())
{
case SPACE:
_string.append(b);
case HTAB:
_string.append(' ');
break;
case LINE_FEED:
case LF:
if (_length > 0)
{
_fieldValue = takeString();
@ -517,12 +536,19 @@ public class MultiPartParser
}
setState(FieldState.FIELD);
break;
default:
_string.append(b);
if (b > SPACE || b < 0)
_length = _string.length();
case ALPHA:
case DIGIT:
case TCHAR:
case VCHAR:
case COLON:
case OTEXT:
_string.append(t.getByte());
_length=_string.length();
break;
default:
throw new IllegalCharacterException(_state,t,buffer);
}
break;
@ -694,16 +720,16 @@ public class MultiPartParser
{
}
}
/* ------------------------------------------------------------------------------- */
@SuppressWarnings("serial")
private static class IllegalCharacterException extends IllegalArgumentException
private static class IllegalCharacterException extends BadMessageException
{
private IllegalCharacterException(State state, byte ch, ByteBuffer buffer)
private IllegalCharacterException(State state,HttpTokens.Token token,ByteBuffer buffer)
{
super(String.format("Illegal character 0x%X", ch));
// Bug #460642 - don't reveal buffers to end user
LOG.warn(String.format("Illegal character 0x%X in state=%s for buffer %s", ch, state, BufferUtil.toDetailString(buffer)));
super(400,String.format("Illegal character %s",token));
if (LOG.isDebugEnabled())
LOG.debug(String.format("Illegal character %s in state=%s for buffer %s",token,state,BufferUtil.toDetailString(buffer)));
}
}
}

View File

@ -216,6 +216,31 @@ public class HttpParserTest
Assert.assertEquals(-1, _headers);
}
@Test
public void testAllowedLinePreamble() throws Exception
{
ByteBuffer buffer= BufferUtil.toBuffer("\r\n\r\nGET / HTTP/1.0\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
Assert.assertEquals("GET", _methodOrVersion);
Assert.assertEquals("/", _uriOrStatus);
Assert.assertEquals("HTTP/1.0", _versionOrReason);
Assert.assertEquals(-1, _headers);
}
@Test
public void testDisallowedLinePreamble() throws Exception
{
ByteBuffer buffer= BufferUtil.toBuffer("\r\n \r\nGET / HTTP/1.0\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
Assert.assertEquals("Illegal character SPACE=' '", _bad);
}
@Test
public void testConnect() throws Exception
{
@ -446,7 +471,7 @@ public class HttpParserTest
Assert.assertEquals("HTTP/1.1", _methodOrVersion);
Assert.assertEquals("204", _uriOrStatus);
Assert.assertEquals("No Content", _versionOrReason);
Assert.assertThat(_bad, Matchers.containsString("Illegal character 0x20"));
Assert.assertThat(_bad, Matchers.containsString("Illegal character "));
}
@Test
@ -723,6 +748,40 @@ public class HttpParserTest
parseAll(parser, buffer);
Assert.assertThat(_bad, Matchers.notNullValue());
}
@Test
public void testBadHeaderNames() throws Exception
{
String[] bad = new String[]
{
"Foo\\Bar: value\r\n",
"Foo@Bar: value\r\n",
"Foo,Bar: value\r\n",
"Foo}Bar: value\r\n",
"Foo{Bar: value\r\n",
"Foo=Bar: value\r\n",
"Foo>Bar: value\r\n",
"Foo<Bar: value\r\n",
"Foo)Bar: value\r\n",
"Foo(Bar: value\r\n",
"Foo?Bar: value\r\n",
"Foo\"Bar: value\r\n",
"Foo/Bar: value\r\n",
"Foo]Bar: value\r\n",
"Foo[Bar: value\r\n",
};
for (int i=0; i<bad.length; i++)
{
ByteBuffer buffer= BufferUtil.toBuffer(
"GET / HTTP/1.0\r\n" + bad[i]+ "\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
Assert.assertThat(bad[i],_bad,Matchers.notNullValue());
}
}
@Test
public void testHeaderTab() throws Exception
@ -1741,7 +1800,7 @@ public class HttpParserTest
}
@Test
public void testDuplicateContentLengthWithLargerThenCorrectValue()
public void testMultipleContentLengthWithLargerThenCorrectValue()
{
ByteBuffer buffer = BufferUtil.toBuffer(
"POST / HTTP/1.1\r\n"
@ -1756,7 +1815,7 @@ public class HttpParserTest
parser.parseNext(buffer);
Assert.assertEquals("POST", _methodOrVersion);
Assert.assertEquals("Duplicate Content-Length", _bad);
Assert.assertEquals("Multiple Content-Lengths", _bad);
Assert.assertFalse(buffer.hasRemaining());
Assert.assertEquals(HttpParser.State.CLOSE, parser.getState());
parser.atEOF();
@ -1765,7 +1824,7 @@ public class HttpParserTest
}
@Test
public void testDuplicateContentLengthWithCorrectThenLargerValue()
public void testMultipleContentLengthWithCorrectThenLargerValue()
{
ByteBuffer buffer = BufferUtil.toBuffer(
"POST / HTTP/1.1\r\n"
@ -1780,7 +1839,7 @@ public class HttpParserTest
parser.parseNext(buffer);
Assert.assertEquals("POST", _methodOrVersion);
Assert.assertEquals("Duplicate Content-Length", _bad);
Assert.assertEquals("Multiple Content-Lengths", _bad);
Assert.assertFalse(buffer.hasRemaining());
Assert.assertEquals(HttpParser.State.CLOSE, parser.getState());
parser.atEOF();
@ -1803,7 +1862,7 @@ public class HttpParserTest
+ "\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
HttpParser parser = new HttpParser(handler, HttpCompliance.RFC2616_LEGACY);
parseAll(parser, buffer);
Assert.assertEquals("POST", _methodOrVersion);
@ -1813,6 +1872,8 @@ public class HttpParserTest
Assert.assertTrue(_headerCompleted);
Assert.assertTrue(_messageCompleted);
Assert.assertThat(_complianceViolation, contains(HttpComplianceSection.TRANSFER_ENCODING_WITH_CONTENT_LENGTH));
}
@Test
@ -1830,7 +1891,7 @@ public class HttpParserTest
+ "\r\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);
HttpParser parser = new HttpParser(handler, HttpCompliance.RFC2616_LEGACY);
parseAll(parser, buffer);
Assert.assertEquals("POST", _methodOrVersion);
@ -1840,6 +1901,8 @@ public class HttpParserTest
Assert.assertTrue(_headerCompleted);
Assert.assertTrue(_messageCompleted);
Assert.assertThat(_complianceViolation, contains(HttpComplianceSection.TRANSFER_ENCODING_WITH_CONTENT_LENGTH));
}
@Test

View File

@ -482,6 +482,49 @@ public class MultiPartParserTest
}
@Test
public void testBadHeaderNames() throws Exception
{
String[] bad = new String[]
{
"Foo\\Bar: value\r\n",
"Foo@Bar: value\r\n",
"Foo,Bar: value\r\n",
"Foo}Bar: value\r\n",
"Foo{Bar: value\r\n",
"Foo=Bar: value\r\n",
"Foo>Bar: value\r\n",
"Foo<Bar: value\r\n",
"Foo)Bar: value\r\n",
"Foo(Bar: value\r\n",
"Foo?Bar: value\r\n",
"Foo\"Bar: value\r\n",
"Foo/Bar: value\r\n",
"Foo]Bar: value\r\n",
"Foo[Bar: value\r\n",
"\u0192\u00f8\u00f8\u00df\u00e5\u00ae: value\r\n"
};
for (int i=0; i<bad.length; i++)
{
ByteBuffer buffer= BufferUtil.toBuffer(
"--AaB03x\r\n" + bad[i] + "\r\n--AaB03x--\r\n");
MultiPartParser.Handler handler = new TestHandler();
MultiPartParser parser= new MultiPartParser(handler, "AaB03x");
try
{
parser.parse(buffer, true);
}
catch(BadMessageException e)
{
assertTrue(e.getMessage().contains("Illegal character"));
}
}
}
@Test
public void splitTest()
{

View File

@ -1,3 +1,4 @@
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
#org.eclipse.jetty.LEVEL=DEBUG
#org.eclipse.jetty.server.LEVEL=DEBUG
#org.eclipse.jetty.http.LEVEL=DEBUG

View File

@ -17,8 +17,7 @@ Content-Transfer-Encoding: 8bit
Value 3
--z5xWs05oeiE0TAdFlrrlAX5RSgHrHzVcgskrru
Content-Disposition: form-data; name="other\";
what=\"Something\""
Content-Disposition: form-data; name="other\"; what=\"Something\""
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

View File

@ -19,7 +19,7 @@
package org.eclipse.jetty.http2.client;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executor;
@ -107,7 +107,8 @@ public class HTTP2ClientConnectionFactory implements ClientConnectionFactory
{
Map<Integer, Integer> settings = listener.onPreface(getSession());
if (settings == null)
settings = Collections.emptyMap();
settings = new HashMap<>();
settings.computeIfAbsent(SettingsFrame.INITIAL_WINDOW_SIZE, k -> client.getInitialStreamRecvWindow());
PrefaceFrame prefaceFrame = new PrefaceFrame();
SettingsFrame settingsFrame = new SettingsFrame(settings, false);

View File

@ -103,7 +103,7 @@ public class AsyncServletTest extends AbstractTest
{
try
{
buffer.write(BufferUtil.toArray(frame.getData()));
BufferUtil.writeTo(frame.getData(), buffer);
callback.succeeded();
if (frame.isEndStream())
latch.countDown();

View File

@ -679,13 +679,7 @@ public abstract class FlowControlStrategyTest
@Override
public void onData(Stream stream, DataFrame frame, Callback callback)
{
// Since we echo back the data
// asynchronously we must copy it.
ByteBuffer data = frame.getData();
ByteBuffer copy = ByteBuffer.allocateDirect(data.remaining());
copy.put(data).flip();
completable.thenRun(() ->
stream.data(new DataFrame(stream.getId(), copy, frame.isEndStream()), callback));
completable.thenRun(() -> stream.data(frame, callback));
}
};
}

View File

@ -0,0 +1,176 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http2.client;
import java.net.InetSocketAddress;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.ISession;
import org.eclipse.jetty.http2.IStream;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.server.RawHTTP2ServerConnectionFactory;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.util.FuturePromise;
import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
public class FlowControlWindowsTest
{
private Server server;
private ServerConnector connector;
private HTTP2Client client;
private int serverSessionRecvWindow = 3 * 1024 * 1024;
private int serverStreamRecvWindow = 2 * 1024 * 1024;
private int clientSessionRecvWindow = 5 * 1024 * 1024;
private int clientStreamRecvWindow = 4 * 1024 * 1024;
private void start(ServerSessionListener listener) throws Exception
{
RawHTTP2ServerConnectionFactory connectionFactory = new RawHTTP2ServerConnectionFactory(new HttpConfiguration(), listener);
connectionFactory.setInitialSessionRecvWindow(serverSessionRecvWindow);
connectionFactory.setInitialStreamRecvWindow(serverStreamRecvWindow);
QueuedThreadPool serverExecutor = new QueuedThreadPool();
serverExecutor.setName("server");
server = new Server(serverExecutor);
connector = new ServerConnector(server, 1, 1, connectionFactory);
server.addConnector(connector);
server.start();
client = new HTTP2Client();
QueuedThreadPool clientExecutor = new QueuedThreadPool();
clientExecutor.setName("client");
client.setExecutor(clientExecutor);
client.setInitialSessionRecvWindow(clientSessionRecvWindow);
client.setInitialStreamRecvWindow(clientStreamRecvWindow);
client.start();
}
@After
public void dispose() throws Exception
{
if (client != null)
client.stop();
if (server != null)
server.stop();
}
protected ISession newClient(Session.Listener listener) throws Exception
{
String host = "localhost";
int port = connector.getLocalPort();
InetSocketAddress address = new InetSocketAddress(host, port);
FuturePromise<Session> promise = new FuturePromise<>();
client.connect(address, listener, promise);
return (ISession)promise.get(5, TimeUnit.SECONDS);
}
@Test
public void testClientFlowControlWindows() throws Exception
{
start(new ServerSessionListener.Adapter());
ISession clientSession = newClient(new Session.Listener.Adapter());
// Wait while client and server exchange SETTINGS and WINDOW_UPDATE frames.
Thread.sleep(1000);
int sessionSendWindow = clientSession.updateSendWindow(0);
Assert.assertEquals(serverSessionRecvWindow, sessionSendWindow);
int sessionRecvWindow = clientSession.updateRecvWindow(0);
Assert.assertEquals(clientSessionRecvWindow, sessionRecvWindow);
HostPortHttpField hostPort = new HostPortHttpField("localhost:" + connector.getLocalPort());
MetaData.Request request = new MetaData.Request(HttpMethod.GET.asString(), HttpScheme.HTTP, hostPort, "/", HttpVersion.HTTP_2, new HttpFields());
HeadersFrame frame = new HeadersFrame(request, null, true);
FuturePromise<Stream> promise = new FuturePromise<>();
clientSession.newStream(frame, promise, new Stream.Listener.Adapter());
IStream clientStream = (IStream)promise.get(5, TimeUnit.SECONDS);
int streamSendWindow = clientStream.updateSendWindow(0);
Assert.assertEquals(serverStreamRecvWindow, streamSendWindow);
int streamRecvWindow = clientStream.updateRecvWindow(0);
Assert.assertEquals(clientStreamRecvWindow, streamRecvWindow);
}
@Test
public void testServerFlowControlWindows() throws Exception
{
AtomicReference<ISession> sessionRef = new AtomicReference<>();
CountDownLatch sessionLatch = new CountDownLatch(1);
AtomicReference<IStream> streamRef = new AtomicReference<>();
CountDownLatch streamLatch = new CountDownLatch(1);
start(new ServerSessionListener.Adapter()
{
@Override
public void onAccept(Session session)
{
sessionRef.set((ISession)session);
sessionLatch.countDown();
}
@Override
public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
{
streamRef.set((IStream)stream);
streamLatch.countDown();
return null;
}
});
ISession clientSession = newClient(new Session.Listener.Adapter());
Assert.assertTrue(sessionLatch.await(5, TimeUnit.SECONDS));
ISession serverSession = sessionRef.get();
// Wait while client and server exchange SETTINGS and WINDOW_UPDATE frames.
Thread.sleep(1000);
int sessionSendWindow = serverSession.updateSendWindow(0);
Assert.assertEquals(clientSessionRecvWindow, sessionSendWindow);
int sessionRecvWindow = serverSession.updateRecvWindow(0);
Assert.assertEquals(serverSessionRecvWindow, sessionRecvWindow);
HostPortHttpField hostPort = new HostPortHttpField("localhost:" + connector.getLocalPort());
MetaData.Request request = new MetaData.Request(HttpMethod.GET.asString(), HttpScheme.HTTP, hostPort, "/", HttpVersion.HTTP_2, new HttpFields());
HeadersFrame frame = new HeadersFrame(request, null, true);
clientSession.newStream(frame, new Promise.Adapter<>(), new Stream.Listener.Adapter());
Assert.assertTrue(streamLatch.await(5, TimeUnit.SECONDS));
IStream serverStream = streamRef.get();
int streamSendWindow = serverStream.updateSendWindow(0);
Assert.assertEquals(clientStreamRecvWindow, streamSendWindow);
int streamRecvWindow = serverStream.updateRecvWindow(0);
Assert.assertEquals(serverStreamRecvWindow, streamRecvWindow);
}
}

View File

@ -59,6 +59,7 @@ import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FuturePromise;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.Jetty;
import org.eclipse.jetty.util.Promise;
import org.junit.Assert;
@ -196,6 +197,49 @@ public class HTTP2Test extends AbstractTest
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
}
@Test
public void testRequestContentResponseContent() throws Exception
{
start(new EmptyHttpServlet()
{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
IO.copy(request.getInputStream(), response.getOutputStream());
}
});
Session session = newClient(new Session.Listener.Adapter());
CountDownLatch latch = new CountDownLatch(1);
MetaData.Request metaData = newRequest("POST", new HttpFields());
HeadersFrame frame = new HeadersFrame(metaData, null, false);
Promise.Completable<Stream> streamCompletable = new Promise.Completable<>();
session.newStream(frame, streamCompletable, new Stream.Listener.Adapter()
{
@Override
public void onData(Stream stream, DataFrame frame, Callback callback)
{
callback.succeeded();
if (frame.isEndStream())
latch.countDown();
}
});
streamCompletable.thenCompose(stream ->
{
DataFrame dataFrame = new DataFrame(stream.getId(), ByteBuffer.allocate(1024), false);
Callback.Completable dataCompletable = new Callback.Completable();
stream.data(dataFrame, dataCompletable);
return dataCompletable.thenApply(y -> stream);
}).thenAccept(stream ->
{
DataFrame dataFrame = new DataFrame(stream.getId(), ByteBuffer.allocate(1024), true);
stream.data(dataFrame, Callback.NOOP);
});
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
}
@Test
public void testMultipleRequests() throws Exception
{

View File

@ -42,6 +42,7 @@ import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.Frame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.SettingsFrame;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FuturePromise;
import org.eclipse.jetty.util.log.Log;
@ -80,16 +81,13 @@ public class InterleavingTest extends AbstractTest
}
});
BlockingQueue<FrameBytesCallback> dataFrames = new LinkedBlockingDeque<>();
BlockingQueue<DataFrameCallback> dataFrames = new LinkedBlockingDeque<>();
Stream.Listener streamListener = new Stream.Listener.Adapter()
{
@Override
public void onData(Stream stream, DataFrame frame, Callback callback)
{
ByteBuffer data = frame.getData();
byte[] bytes = new byte[data.remaining()];
data.get(bytes);
dataFrames.offer(new FrameBytesCallback(frame, bytes, callback));
dataFrames.offer(new DataFrameCallback(frame, callback));
}
};
@ -146,20 +144,20 @@ public class InterleavingTest extends AbstractTest
int finished = 0;
while (finished < 2)
{
FrameBytesCallback frameBytesCallback = dataFrames.poll(5, TimeUnit.SECONDS);
if (frameBytesCallback == null)
DataFrameCallback dataFrameCallback = dataFrames.poll(5, TimeUnit.SECONDS);
if (dataFrameCallback == null)
Assert.fail();
DataFrame dataFrame = frameBytesCallback.frame;
DataFrame dataFrame = dataFrameCallback.frame;
int streamId = dataFrame.getStreamId();
int length = dataFrame.remaining();
streamLengths.add(new StreamLength(streamId, length));
if (dataFrame.isEndStream())
++finished;
contents.get(streamId).write(frameBytesCallback.bytes);
BufferUtil.writeTo(dataFrame.getData(), contents.get(streamId));
frameBytesCallback.callback.succeeded();
dataFrameCallback.callback.succeeded();
}
// Verify that the content has been sent properly.
@ -197,16 +195,14 @@ public class InterleavingTest extends AbstractTest
});
}
private static class FrameBytesCallback
private static class DataFrameCallback
{
private final DataFrame frame;
private final byte[] bytes;
private final Callback callback;
private FrameBytesCallback(DataFrame frame, byte[] bytes, Callback callback)
private DataFrameCallback(DataFrame frame, Callback callback)
{
this.frame = frame;
this.bytes = bytes;
this.callback = callback;
}
}

View File

@ -54,22 +54,24 @@ public class InvalidServerTest extends AbstractTest
}
}, promise);
Socket socket = server.accept();
OutputStream output = socket.getOutputStream();
output.write("enough_junk_bytes".getBytes(StandardCharsets.UTF_8));
Session session = promise.get(5, TimeUnit.SECONDS);
Assert.assertNotNull(session);
Assert.assertTrue(failureLatch.await(5, TimeUnit.SECONDS));
// Verify that the client closed the socket.
InputStream input = socket.getInputStream();
while (true)
try (Socket socket = server.accept())
{
int read = input.read();
if (read < 0)
break;
OutputStream output = socket.getOutputStream();
output.write("enough_junk_bytes".getBytes(StandardCharsets.UTF_8));
Session session = promise.get(5, TimeUnit.SECONDS);
Assert.assertNotNull(session);
Assert.assertTrue(failureLatch.await(5, TimeUnit.SECONDS));
// Verify that the client closed the socket.
InputStream input = socket.getInputStream();
while (true)
{
int read = input.read();
if (read < 0)
break;
}
}
}
}

View File

@ -31,6 +31,7 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.UnaryOperator;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpStatus;
@ -165,6 +166,7 @@ public class PrefaceTest extends AbstractTest
settings.offer(frame);
}
}, 4096, 8192);
parser.init(UnaryOperator.identity());
ByteBuffer buffer = byteBufferPool.acquire(1024, true);
while (true)
@ -307,6 +309,7 @@ public class PrefaceTest extends AbstractTest
responded.set(true);
}
}, 4096, 8192);
parser.init(UnaryOperator.identity());
// HTTP/2 parsing.
while (true)

View File

@ -39,6 +39,7 @@ import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.ProxyConnectionFactory;
@ -49,6 +50,7 @@ import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.FuturePromise;
import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.TypeUtil;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
@ -144,8 +146,12 @@ public class ProxyProtocolTest
{
Assert.assertEquals("10.0.0.4",request.getRemoteAddr());
Assert.assertEquals(33824,request.getRemotePort());
Assert.assertEquals("10.0.0.4",request.getLocalAddr());
Assert.assertEquals("10.0.0.5",request.getLocalAddr());
Assert.assertEquals(8888,request.getLocalPort());
EndPoint endPoint = baseRequest.getHttpChannel().getEndPoint();
Assert.assertThat(endPoint, Matchers.instanceOf(ProxyConnectionFactory.ProxyEndPoint.class));
ProxyConnectionFactory.ProxyEndPoint proxyEndPoint = (ProxyConnectionFactory.ProxyEndPoint)endPoint;
Assert.assertNotNull(proxyEndPoint.getAttribute(ProxyConnectionFactory.TLS_VERSION));
}
catch(Throwable th)
{
@ -156,7 +162,9 @@ public class ProxyProtocolTest
}
});
String request1 = "0D0A0D0A000D0A515549540A211100140A0000040A000004842022B82000050000000000";
// String is: "MAGIC VER|CMD FAM|PROT LEN SRC_ADDR DST_ADDR SRC_PORT DST_PORT PP2_TYPE_SSL LEN CLIENT VERIFY PP2_SUBTYPE_SSL_VERSION LEN 1.2"
String request1 = "0D0A0D0A000D0A515549540A 21 11 001A 0A000004 0A000005 8420 22B8 20 000B 01 00000000 21 0003 312E32";
request1 = request1.replace(" ", "");
SocketChannel channel = SocketChannel.open();
channel.connect(new InetSocketAddress("localhost", connector.getLocalPort()));
channel.write(ByteBuffer.wrap(TypeUtil.fromHexString(request1)));

View File

@ -263,14 +263,6 @@ public class RawHTTP2ProxyTest
Assert.assertTrue(latch2.await(5, TimeUnit.SECONDS));
}
private static DataFrame copyDataFrame(DataFrame frame)
{
ByteBuffer data = frame.getData();
ByteBuffer dataCopy = ByteBuffer.allocate(data.remaining());
dataCopy.put(data).flip();
return new DataFrame(frame.getStreamId(), dataCopy, frame.isEndStream(), frame.padding());
}
private static class ClientToProxySessionListener extends ServerSessionListener.Adapter
{
private final Map<Integer, ClientToProxyToServer> forwarders = new ConcurrentHashMap<>();
@ -505,8 +497,7 @@ public class RawHTTP2ProxyTest
{
if (LOGGER.isDebugEnabled())
LOGGER.debug("CPS received {} on {}", frame, stream);
// Must copy the bytes because they are not consumed here.
offer(stream, copyDataFrame(frame), callback);
offer(stream, frame, callback);
}
@Override
@ -668,8 +659,7 @@ public class RawHTTP2ProxyTest
{
if (LOGGER.isDebugEnabled())
LOGGER.debug("SPC received {} on {}", frame, stream);
// Must copy the bytes because they are not consumed here.
offer(stream, copyDataFrame(frame), callback);
offer(stream, frame, callback);
}
@Override

View File

@ -132,23 +132,17 @@ public class StreamCloseTest extends AbstractTest
{
Assert.assertTrue(((HTTP2Stream)stream).isRemotelyClosed());
// We must copy the data that we send asynchronously.
ByteBuffer data = frame.getData();
ByteBuffer copy = ByteBuffer.allocate(data.remaining());
copy.put(data).flip();
completable.thenRun(() ->
stream.data(new DataFrame(stream.getId(), copy, frame.isEndStream()), new Callback()
{
@Override
public void succeeded()
{
Assert.assertTrue(stream.isClosed());
Assert.assertEquals(0, stream.getSession().getStreams().size());
callback.succeeded();
serverDataLatch.countDown();
}
}));
completable.thenRun(() -> stream.data(frame, new Callback()
{
@Override
public void succeeded()
{
Assert.assertTrue(stream.isClosed());
Assert.assertEquals(0, stream.getSession().getStreams().size());
callback.succeeded();
serverDataLatch.countDown();
}
}));
}
};
}

View File

@ -623,7 +623,7 @@ public class StreamResetTest extends AbstractTest
}
});
Deque<Object> dataQueue = new ArrayDeque<>();
Deque<Callback> dataQueue = new ArrayDeque<>();
AtomicLong received = new AtomicLong();
CountDownLatch latch = new CountDownLatch(1);
Session client = newClient(new Session.Listener.Adapter());
@ -635,7 +635,6 @@ public class StreamResetTest extends AbstractTest
@Override
public void onData(Stream stream, DataFrame frame, Callback callback)
{
dataQueue.offer(frame);
dataQueue.offer(callback);
// Do not consume the data yet.
if (received.addAndGet(frame.getData().remaining()) == windowSize)
@ -647,10 +646,7 @@ public class StreamResetTest extends AbstractTest
// Reset and consume.
stream.reset(new ResetFrame(stream.getId(), ErrorCode.CANCEL_STREAM_ERROR.code), Callback.NOOP);
dataQueue.stream()
.filter(item -> item instanceof Callback)
.map(item -> (Callback)item)
.forEach(Callback::succeeded);
dataQueue.forEach(Callback::succeeded);
Assert.assertTrue(writeLatch.await(5, TimeUnit.SECONDS));
}

View File

@ -92,6 +92,8 @@ public abstract class AbstractFlowControlStrategy implements FlowControlStrategy
this.initialStreamSendWindow = initialStreamWindow;
}
int delta = initialStreamWindow - previousInitialStreamWindow;
if (delta == 0)
return;
// SPEC: updates of the initial window size only affect stream windows, not session's.
for (Stream stream : session.getStreams())

View File

@ -23,8 +23,18 @@ import java.nio.ByteBuffer;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.GoAwayFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.PingFrame;
import org.eclipse.jetty.http2.frames.PriorityFrame;
import org.eclipse.jetty.http2.frames.PushPromiseFrame;
import org.eclipse.jetty.http2.frames.ResetFrame;
import org.eclipse.jetty.http2.frames.SettingsFrame;
import org.eclipse.jetty.http2.frames.WindowUpdateFrame;
import org.eclipse.jetty.http2.parser.Parser;
import org.eclipse.jetty.io.AbstractConnection;
import org.eclipse.jetty.io.ByteBufferPool;
@ -32,6 +42,7 @@ import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.WriteFlusher;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Retainable;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@ -66,6 +77,7 @@ public class HTTP2Connection extends AbstractConnection implements WriteFlusher.
executor = new TryExecutor.NoTryExecutor(executor);
this.strategy = new EatWhatYouKill(producer, executor);
LifeCycle.start(strategy);
parser.init(ParserListener::new);
}
@Override
@ -92,7 +104,8 @@ public class HTTP2Connection extends AbstractConnection implements WriteFlusher.
protected void setInputBuffer(ByteBuffer buffer)
{
producer.buffer = buffer;
if (buffer != null)
producer.setInputBuffer(buffer);
}
@Override
@ -205,9 +218,16 @@ public class HTTP2Connection extends AbstractConnection implements WriteFlusher.
protected class HTTP2Producer implements ExecutionStrategy.Producer
{
private final Callback fillableCallback = new FillableCallback();
private ByteBuffer buffer;
private NetworkBuffer buffer;
private boolean shutdown;
private void setInputBuffer(ByteBuffer byteBuffer)
{
if (buffer == null)
buffer = acquireNetworkBuffer();
buffer.put(byteBuffer);
}
@Override
public Runnable produce()
{
@ -221,38 +241,50 @@ public class HTTP2Connection extends AbstractConnection implements WriteFlusher.
return null;
if (buffer == null)
buffer = byteBufferPool.acquire(bufferSize, false); // TODO: make directness customizable
boolean looping = BufferUtil.hasContent(buffer);
buffer = acquireNetworkBuffer();
boolean parse = buffer.hasRemaining();
while (true)
{
if (looping)
if (parse)
{
buffer.retain();
while (buffer.hasRemaining())
parser.parse(buffer);
parser.parse(buffer.buffer);
boolean released = buffer.tryRelease();
task = pollTask();
if (LOG.isDebugEnabled())
LOG.debug("Dequeued new task {}", task);
if (task != null)
{
release();
if (released)
releaseNetworkBuffer();
else
buffer = null;
return task;
}
else
{
if (!released)
buffer = acquireNetworkBuffer();
}
}
int filled = fill(getEndPoint(), buffer);
int filled = fill(getEndPoint(), buffer.buffer);
if (LOG.isDebugEnabled())
LOG.debug("Filled {} bytes", filled);
LOG.debug("Filled {} bytes in {}", filled, buffer);
if (filled == 0)
{
release();
releaseNetworkBuffer();
getEndPoint().fillInterested(fillableCallback);
return null;
}
else if (filled < 0)
{
release();
releaseNetworkBuffer();
shutdown = true;
session.onShutdown();
return null;
@ -260,17 +292,27 @@ public class HTTP2Connection extends AbstractConnection implements WriteFlusher.
else
{
bytesIn.addAndGet(filled);
parse = true;
}
looping = true;
}
}
private void release()
private NetworkBuffer acquireNetworkBuffer()
{
if (buffer != null && !buffer.hasRemaining())
NetworkBuffer networkBuffer = new NetworkBuffer();
if (LOG.isDebugEnabled())
LOG.debug("Acquired {}", networkBuffer);
return networkBuffer;
}
private void releaseNetworkBuffer()
{
if (!buffer.hasRemaining())
{
byteBufferPool.release(buffer);
if (LOG.isDebugEnabled())
LOG.debug("Released {}", buffer);
buffer.release();
byteBufferPool.release(buffer.buffer);
buffer = null;
}
}
@ -302,4 +344,143 @@ public class HTTP2Connection extends AbstractConnection implements WriteFlusher.
return InvocationType.EITHER;
}
}
private class ParserListener implements Parser.Listener
{
private final Parser.Listener listener;
private ParserListener(Parser.Listener listener)
{
this.listener = listener;
}
@Override
public void onData(DataFrame frame)
{
NetworkBuffer buffer = producer.buffer;
buffer.retain();
Callback callback = buffer;
session.onData(frame, callback);
}
@Override
public void onHeaders(HeadersFrame frame)
{
listener.onHeaders(frame);
}
@Override
public void onPriority(PriorityFrame frame)
{
listener.onPriority(frame);
}
@Override
public void onReset(ResetFrame frame)
{
listener.onReset(frame);
}
@Override
public void onSettings(SettingsFrame frame)
{
listener.onSettings(frame);
}
@Override
public void onPushPromise(PushPromiseFrame frame)
{
listener.onPushPromise(frame);
}
@Override
public void onPing(PingFrame frame)
{
listener.onPing(frame);
}
@Override
public void onGoAway(GoAwayFrame frame)
{
listener.onGoAway(frame);
}
@Override
public void onWindowUpdate(WindowUpdateFrame frame)
{
listener.onWindowUpdate(frame);
}
@Override
public void onConnectionFailure(int error, String reason)
{
listener.onConnectionFailure(error, reason);
}
}
private class NetworkBuffer implements Callback, Retainable
{
private final AtomicInteger refCount = new AtomicInteger();
private final ByteBuffer buffer;
private NetworkBuffer()
{
buffer = byteBufferPool.acquire(bufferSize, false); // TODO: make directness customizable
}
private void put(ByteBuffer source)
{
BufferUtil.append(buffer, source);
}
private boolean hasRemaining()
{
return buffer.hasRemaining();
}
@Override
public void retain()
{
refCount.incrementAndGet();
}
@Override
public void succeeded()
{
release();
}
@Override
public void failed(Throwable x)
{
release();
}
@Override
public InvocationType getInvocationType()
{
return InvocationType.NON_BLOCKING;
}
private void release()
{
if (tryRelease())
{
byteBufferPool.release(buffer);
if (LOG.isDebugEnabled())
LOG.debug("Released retained {}", this);
}
}
private boolean tryRelease()
{
return refCount.decrementAndGet() == 0;
}
@Override
public String toString()
{
return String.format("%s@%x[%s]", getClass().getSimpleName(), hashCode(), buffer);
}
}
}

View File

@ -57,6 +57,7 @@ import org.eclipse.jetty.util.Atomics;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.CountingCallback;
import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.Retainable;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
@ -216,7 +217,13 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
}
@Override
public void onData(final DataFrame frame)
public void onData(DataFrame frame)
{
onData(frame, Callback.NOOP);
}
@Override
public void onData(final DataFrame frame, Callback callback)
{
if (LOG.isDebugEnabled())
LOG.debug("Received {}", frame);
@ -233,39 +240,11 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
{
if (getRecvWindow() < 0)
{
close(ErrorCode.FLOW_CONTROL_ERROR.code, "session_window_exceeded", Callback.NOOP);
close(ErrorCode.FLOW_CONTROL_ERROR.code, "session_window_exceeded", callback);
}
else
{
stream.process(frame, new Callback()
{
@Override
public void succeeded()
{
complete();
}
@Override
public void failed(Throwable x)
{
// Consume also in case of failures, to free the
// session flow control window for other streams.
complete();
}
@Override
public InvocationType getInvocationType()
{
return InvocationType.NON_BLOCKING;
}
private void complete()
{
notIdle();
stream.notIdle();
flowControl.onDataConsumed(HTTP2Session.this, stream, flowControlLength);
}
});
stream.process(frame, new DataCallback(callback, stream, flowControlLength));
}
}
else
@ -275,6 +254,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
// We must enlarge the session flow control window,
// otherwise other requests will be stalled.
flowControl.onDataConsumed(this, null, flowControlLength);
callback.succeeded();
}
}
@ -492,31 +472,36 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
@Override
public void newStream(HeadersFrame frame, Promise<Stream> promise, Stream.Listener listener)
{
// Synchronization is necessary to atomically create
// the stream id and enqueue the frame to be sent.
boolean queued;
synchronized (this)
try
{
int streamId = frame.getStreamId();
if (streamId <= 0)
// Synchronization is necessary to atomically create
// the stream id and enqueue the frame to be sent.
boolean queued;
synchronized (this)
{
streamId = streamIds.getAndAdd(2);
PriorityFrame priority = frame.getPriority();
priority = priority == null ? null : new PriorityFrame(streamId, priority.getParentStreamId(),
priority.getWeight(), priority.isExclusive());
frame = new HeadersFrame(streamId, frame.getMetaData(), priority, frame.isEndStream());
}
final IStream stream = createLocalStream(streamId, promise);
if (stream == null)
return;
stream.setListener(listener);
int streamId = frame.getStreamId();
if (streamId <= 0)
{
streamId = streamIds.getAndAdd(2);
PriorityFrame priority = frame.getPriority();
priority = priority == null ? null : new PriorityFrame(streamId, priority.getParentStreamId(),
priority.getWeight(), priority.isExclusive());
frame = new HeadersFrame(streamId, frame.getMetaData(), priority, frame.isEndStream());
}
IStream stream = createLocalStream(streamId);
stream.setListener(listener);
ControlEntry entry = new ControlEntry(frame, stream, new PromiseCallback<>(promise, stream));
queued = flusher.append(entry);
ControlEntry entry = new ControlEntry(frame, stream, new PromiseCallback<>(promise, stream));
queued = flusher.append(entry);
}
// Iterate outside the synchronized block.
if (queued)
flusher.iterate();
}
catch (Throwable x)
{
promise.failed(x);
}
// Iterate outside the synchronized block.
if (queued)
flusher.iterate();
}
@Override
@ -537,25 +522,30 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
@Override
public void push(IStream stream, Promise<Stream> promise, PushPromiseFrame frame, Stream.Listener listener)
{
// Synchronization is necessary to atomically create
// the stream id and enqueue the frame to be sent.
boolean queued;
synchronized (this)
try
{
int streamId = streamIds.getAndAdd(2);
frame = new PushPromiseFrame(frame.getStreamId(), streamId, frame.getMetaData());
// Synchronization is necessary to atomically create
// the stream id and enqueue the frame to be sent.
boolean queued;
synchronized (this)
{
int streamId = streamIds.getAndAdd(2);
frame = new PushPromiseFrame(frame.getStreamId(), streamId, frame.getMetaData());
final IStream pushStream = createLocalStream(streamId, promise);
if (pushStream == null)
return;
pushStream.setListener(listener);
IStream pushStream = createLocalStream(streamId);
pushStream.setListener(listener);
ControlEntry entry = new ControlEntry(frame, pushStream, new PromiseCallback<>(promise, pushStream));
queued = flusher.append(entry);
ControlEntry entry = new ControlEntry(frame, pushStream, new PromiseCallback<>(promise, pushStream));
queued = flusher.append(entry);
}
// Iterate outside the synchronized block.
if (queued)
flusher.iterate();
}
catch (Throwable x)
{
promise.failed(x);
}
// Iterate outside the synchronized block.
if (queued)
flusher.iterate();
}
@Override
@ -696,17 +686,14 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
}
}
protected IStream createLocalStream(int streamId, Promise<Stream> promise)
protected IStream createLocalStream(int streamId)
{
while (true)
{
int localCount = localStreamCount.get();
int maxCount = getMaxLocalStreams();
if (maxCount >= 0 && localCount >= maxCount)
{
promise.failed(new IllegalStateException("Max local stream count " + maxCount + " exceeded"));
return null;
}
throw new IllegalStateException("Max local stream count " + maxCount + " exceeded");
if (localStreamCount.compareAndSet(localCount, localCount + 1))
break;
}
@ -722,8 +709,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
}
else
{
promise.failed(new IllegalStateException("Duplicate stream " + streamId));
return null;
throw new IllegalStateException("Duplicate stream " + streamId);
}
}
@ -1415,6 +1401,50 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
}
}
private class DataCallback extends Callback.Nested implements Retainable
{
private final IStream stream;
private final int flowControlLength;
public DataCallback(Callback callback, IStream stream, int flowControlLength)
{
super(callback);
this.stream = stream;
this.flowControlLength = flowControlLength;
}
@Override
public void retain()
{
Callback callback = getCallback();
if (callback instanceof Retainable)
((Retainable)callback).retain();
}
@Override
public void succeeded()
{
complete();
super.succeeded();
}
@Override
public void failed(Throwable x)
{
// Consume also in case of failures, to free the
// session flow control window for other streams.
complete();
super.failed(x);
}
private void complete()
{
notIdle();
stream.notIdle();
flowControl.onDataConsumed(HTTP2Session.this, stream, flowControlLength);
}
}
private class ResetCallback implements Callback
{
@Override

View File

@ -119,7 +119,7 @@ public interface ISession extends Session
*
* @see #onShutdown()
* @see #close(int, String, Callback)
* @return <code>true</code> if the session has expired
* @return {@code true} if the session has expired
*/
public boolean onIdleTimeout();
@ -143,4 +143,12 @@ public interface ISession extends Session
* @return the number of bytes written by this session
*/
public long getBytesWritten();
/**
* <p>Callback method invoked when a DATA frame is received.</p>
*
* @param frame the DATA frame received
* @param callback the callback to notify when the frame has been processed
*/
public void onData(DataFrame frame, Callback callback);
}

View File

@ -19,6 +19,7 @@
package org.eclipse.jetty.http2.parser;
import java.nio.ByteBuffer;
import java.util.function.UnaryOperator;
import org.eclipse.jetty.http2.ErrorCode;
import org.eclipse.jetty.http2.Flags;
@ -49,6 +50,7 @@ public class Parser
private final Listener listener;
private final HeaderParser headerParser;
private final HeaderBlockParser headerBlockParser;
private final BodyParser[] bodyParsers;
private boolean continuation;
private State state = State.HEADER;
@ -57,11 +59,14 @@ public class Parser
{
this.listener = listener;
this.headerParser = new HeaderParser();
this.headerBlockParser = new HeaderBlockParser(byteBufferPool, new HpackDecoder(maxDynamicTableSize, maxHeaderSize));
this.bodyParsers = new BodyParser[FrameType.values().length];
}
HeaderBlockParser headerBlockParser = new HeaderBlockParser(byteBufferPool, new HpackDecoder(maxDynamicTableSize, maxHeaderSize));
public void init(UnaryOperator<Listener> wrapper)
{
Listener listener = wrapper.apply(this.listener);
HeaderBlockFragments headerBlockFragments = new HeaderBlockFragments();
bodyParsers[FrameType.DATA.getType()] = new DataBodyParser(headerParser, listener);
bodyParsers[FrameType.HEADERS.getType()] = new HeadersBodyParser(headerParser, listener, headerBlockParser, headerBlockFragments);
bodyParsers[FrameType.PRIORITY.getType()] = new PriorityBodyParser(headerParser, listener);

View File

@ -21,6 +21,7 @@ package org.eclipse.jetty.http2.frames;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.function.UnaryOperator;
import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http.HttpField;
@ -61,6 +62,7 @@ public class ContinuationParseTest
frames.add(new HeadersFrame(null, null, false));
}
}, 4096, 8192);
parser.init(UnaryOperator.identity());
// Iterate a few times to be sure the parser is properly reset.
for (int i = 0; i < 2; ++i)

View File

@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.function.UnaryOperator;
import org.eclipse.jetty.http2.generator.DataGenerator;
import org.eclipse.jetty.http2.generator.HeaderGenerator;
@ -98,6 +99,7 @@ public class DataGenerateParseTest
frames.add(frame);
}
}, 4096, 8192);
parser.init(UnaryOperator.identity());
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
@ -137,6 +139,7 @@ public class DataGenerateParseTest
frames.add(frame);
}
}, 4096, 8192);
parser.init(UnaryOperator.identity());
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)

View File

@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.function.UnaryOperator;
import org.eclipse.jetty.http2.generator.GoAwayGenerator;
import org.eclipse.jetty.http2.generator.HeaderGenerator;
@ -49,6 +50,7 @@ public class GoAwayGenerateParseTest
frames.add(frame);
}
}, 4096, 8192);
parser.init(UnaryOperator.identity());
int lastStreamId = 13;
int error = 17;
@ -90,6 +92,7 @@ public class GoAwayGenerateParseTest
frames.add(frame);
}
}, 4096, 8192);
parser.init(UnaryOperator.identity());
int lastStreamId = 13;
int error = 17;

View File

@ -21,6 +21,7 @@ package org.eclipse.jetty.http2.frames;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.function.UnaryOperator;
import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http.HttpField;
@ -61,6 +62,7 @@ public class HeadersGenerateParseTest
frames.add(frame);
}
}, 4096, 8192);
parser.init(UnaryOperator.identity());
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
@ -113,6 +115,7 @@ public class HeadersGenerateParseTest
frames.add(frame);
}
}, 4096, 8192);
parser.init(UnaryOperator.identity());
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)

View File

@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.function.UnaryOperator;
import org.eclipse.jetty.http2.generator.HeaderGenerator;
import org.eclipse.jetty.http2.generator.PingGenerator;
@ -49,6 +50,7 @@ public class PingGenerateParseTest
frames.add(frame);
}
}, 4096, 8192);
parser.init(UnaryOperator.identity());
byte[] payload = new byte[8];
new Random().nextBytes(payload);
@ -89,6 +91,7 @@ public class PingGenerateParseTest
frames.add(frame);
}
}, 4096, 8192);
parser.init(UnaryOperator.identity());
byte[] payload = new byte[8];
new Random().nextBytes(payload);
@ -129,6 +132,7 @@ public class PingGenerateParseTest
frames.add(frame);
}
}, 4096, 8192);
parser.init(UnaryOperator.identity());
ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
PingFrame ping = new PingFrame(System.nanoTime(), true);

View File

@ -21,6 +21,7 @@ package org.eclipse.jetty.http2.frames;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.function.UnaryOperator;
import org.eclipse.jetty.http2.generator.HeaderGenerator;
import org.eclipse.jetty.http2.generator.PriorityGenerator;
@ -48,6 +49,7 @@ public class PriorityGenerateParseTest
frames.add(frame);
}
}, 4096, 8192);
parser.init(UnaryOperator.identity());
int streamId = 13;
int parentStreamId = 17;
@ -92,6 +94,7 @@ public class PriorityGenerateParseTest
frames.add(frame);
}
}, 4096, 8192);
parser.init(UnaryOperator.identity());
int streamId = 13;
int parentStreamId = 17;

View File

@ -21,6 +21,7 @@ package org.eclipse.jetty.http2.frames;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.function.UnaryOperator;
import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http.HttpField;
@ -55,6 +56,7 @@ public class PushPromiseGenerateParseTest
frames.add(frame);
}
}, 4096, 8192);
parser.init(UnaryOperator.identity());
int streamId = 13;
int promisedStreamId = 17;
@ -107,6 +109,7 @@ public class PushPromiseGenerateParseTest
frames.add(frame);
}
}, 4096, 8192);
parser.init(UnaryOperator.identity());
int streamId = 13;
int promisedStreamId = 17;

View File

@ -21,6 +21,7 @@ package org.eclipse.jetty.http2.frames;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.function.UnaryOperator;
import org.eclipse.jetty.http2.generator.HeaderGenerator;
import org.eclipse.jetty.http2.generator.ResetGenerator;
@ -48,6 +49,7 @@ public class ResetGenerateParseTest
frames.add(frame);
}
}, 4096, 8192);
parser.init(UnaryOperator.identity());
int streamId = 13;
int error = 17;
@ -88,6 +90,7 @@ public class ResetGenerateParseTest
frames.add(frame);
}
}, 4096, 8192);
parser.init(UnaryOperator.identity());
int streamId = 13;
int error = 17;

Some files were not shown because too many files have changed in this diff Show More