Skip to content

Commit

Permalink
Issue #8057 - Support Http Response 103 (Early Hints)
Browse files Browse the repository at this point in the history
Improved implementation on the client-side.
Introduced HttpStatus.isInterim() for 1XX codes that are not 101.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
  • Loading branch information
sbordet committed May 30, 2022
1 parent 01bf0f4 commit d0cfd7c
Show file tree
Hide file tree
Showing 10 changed files with 27 additions and 25 deletions.
Expand Up @@ -411,9 +411,8 @@ protected boolean responseSuccess(HttpExchange exchange)
ResponseNotifier notifier = getHttpDestination().getResponseNotifier();
notifier.notifySuccess(listeners, response);

// Special case for 100 Continue that cannot
// be handled by the ContinueProtocolHandler.
if (exchange.getResponse().getStatus() == HttpStatus.CONTINUE_100)
// Interim responses do not terminate the exchange.
if (HttpStatus.isInterim(exchange.getResponse().getStatus()))
return true;

// Mark atomically the response as terminated, with
Expand Down
Expand Up @@ -187,12 +187,10 @@ private void process()
}
else if (read == 0)
{
if (networkBuffer.isEmpty())
{
releaseNetworkBuffer();
fillInterested();
return;
}
assert networkBuffer.isEmpty();
releaseNetworkBuffer();
fillInterested();
return;
}
else
{
Expand Down Expand Up @@ -256,7 +254,6 @@ private boolean parse()
{
if (LOG.isDebugEnabled())
LOG.debug("Discarding unexpected content after response {}: {}", status, networkBuffer);
LOG.info("Discarding unexpected content after response {}: {}", status, networkBuffer);
networkBuffer.clear();
}
return false;
Expand Down Expand Up @@ -379,7 +376,7 @@ public boolean messageComplete()
}

int status = exchange.getResponse().getStatus();
if (status != HttpStatus.CONTINUE_100)
if (!HttpStatus.isInterim(status))
{
inMessages.increment();
complete = true;
Expand Down
Expand Up @@ -88,6 +88,7 @@ public enum HttpHeader
AGE("Age"),
ALT_SVC("Alt-Svc"),
ETAG("ETag"),
LINK("Link"),
LOCATION("Location"),
PROXY_AUTHENTICATE("Proxy-Authenticate"),
RETRY_AFTER("Retry-After"),
Expand Down
11 changes: 11 additions & 0 deletions jetty-http/src/main/java/org/eclipse/jetty/http/HttpStatus.java
Expand Up @@ -341,6 +341,17 @@ public static boolean isInformational(int code)
return ((100 <= code) && (code <= 199));
}

/**
* Tests whether the status code is informational but not {@code 101 Switching Protocols}.
*
* @param code the code to test
* @return whether the status code is informational but not {@code 101 Switching Protocols}
*/
public static boolean isInterim(int code)
{
return isInformational(code) && code != HttpStatus.SWITCHING_PROTOCOLS_101;
}

/**
* Simple test against an code to determine if it falls into the
* <code>Success</code> message category as defined in the <a
Expand Down
Expand Up @@ -120,8 +120,7 @@ void onHeaders(Stream stream, HeadersFrame frame)
if (responseHeaders(exchange))
{
int status = response.getStatus();
boolean informational = HttpStatus.isInformational(status) && status != HttpStatus.SWITCHING_PROTOCOLS_101;
if (frame.isEndStream() || informational)
if (frame.isEndStream() || HttpStatus.isInterim(status))
responseSuccess(exchange);
}
else
Expand Down
Expand Up @@ -98,8 +98,7 @@ public void sendHeaders(MetaData.Request request, MetaData.Response response, By
boolean isHeadRequest = HttpMethod.HEAD.is(request.getMethod());
boolean hasContent = BufferUtil.hasContent(content) && !isHeadRequest;
int status = response.getStatus();
boolean interimResponse = HttpStatus.isInformational(status) && status != HttpStatus.SWITCHING_PROTOCOLS_101;
if (interimResponse)
if (HttpStatus.isInterim(status))
{
// Must not commit interim responses.
if (hasContent)
Expand Down
Expand Up @@ -89,8 +89,7 @@ public void onResponse(Stream.Client stream, HeadersFrame frame)
if (responseHeaders(exchange))
{
int status = response.getStatus();
boolean informational = HttpStatus.isInformational(status) && status != HttpStatus.SWITCHING_PROTOCOLS_101;
if (frame.isLast() || informational)
if (frame.isLast() || HttpStatus.isInterim(status))
responseSuccess(exchange);
else
stream.demand();
Expand Down
Expand Up @@ -71,8 +71,7 @@ private void sendHeaders(MetaData.Request request, MetaData.Response response, B
boolean isHeadRequest = HttpMethod.HEAD.is(request.getMethod());
boolean hasContent = BufferUtil.hasContent(content) && !isHeadRequest;
int status = response.getStatus();
boolean interimResponse = HttpStatus.isInformational(status) && status != HttpStatus.SWITCHING_PROTOCOLS_101;
if (interimResponse)
if (HttpStatus.isInterim(status))
{
// Must not commit interim responses.
if (hasContent)
Expand Down
Expand Up @@ -1044,10 +1044,10 @@ protected boolean sendResponse(MetaData.Response response, ByteBuffer content, b
_combinedListener.onResponseBegin(_request);
_request.onResponseCommit();

// wrap callback to process 100 responses
// wrap callback to process informational responses
final int status = response.getStatus();
final Callback committed = HttpStatus.isInformational(status)
? new Send100Callback(callback)
? new Send1XXCallback(callback)
: new SendCallback(callback, content, true, complete);

// committing write
Expand Down Expand Up @@ -1477,9 +1477,9 @@ public void failed(Throwable th)
}
}

private class Send100Callback extends SendCallback
private class Send1XXCallback extends SendCallback
{
private Send100Callback(Callback callback)
private Send1XXCallback(Callback callback)
{
super(callback, null, false, false);
}
Expand Down
Expand Up @@ -107,7 +107,6 @@ public void onSuccess(Response response)
{
// All good, continue.
exchange.resetResponse();
exchange.proceed(null);
}
else
{
Expand Down Expand Up @@ -197,7 +196,6 @@ public void onSuccess(Response response)
// All good, continue.
hints.add(response.getHeaders().get("Hint"));
exchange.resetResponse();
exchange.proceed(null);
}
else
{
Expand Down

0 comments on commit d0cfd7c

Please sign in to comment.