Fixes #4764 - HTTP2 Jetty Server does not send back content-length.

Updates after review.
Now the Content-Length header is generated by HpackEncoder based on
MetaData.contentLength, so that the MetaData.HttpFields are not modified.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
Simone Bordet 2020-04-14 11:44:58 +02:00
parent dc89f7f264
commit 2e85b3e169
3 changed files with 30 additions and 5 deletions

View File

@ -119,6 +119,11 @@ public class MetaData implements Iterable<HttpField>
return _contentLength;
}
public void setContentLength(long contentLength)
{
_contentLength = contentLength;
}
/**
* @return an iterator over the HTTP fields
* @see #getFields()

View File

@ -217,7 +217,8 @@ public class HpackEncoder
// Remove fields as specified in RFC 7540, 8.1.2.2.
if (fields != null)
{
// For example: Connection: Close, TE, Upgrade, Custom.
// Remove the headers specified in the Connection header,
// for example: Connection: Close, TE, Upgrade, Custom.
Set<String> hopHeaders = null;
for (String value : fields.getCSV(HttpHeader.CONNECTION, false))
{
@ -225,6 +226,8 @@ public class HpackEncoder
hopHeaders = new HashSet<>();
hopHeaders.add(StringUtil.asciiToLowerCase(value));
}
boolean contentLengthEncoded = false;
for (HttpField field : fields)
{
HttpHeader header = field.getHeader();
@ -239,8 +242,17 @@ public class HpackEncoder
String name = field.getLowerCaseName();
if (hopHeaders != null && hopHeaders.contains(name))
continue;
if (header == HttpHeader.CONTENT_LENGTH)
contentLengthEncoded = true;
encode(buffer, field);
}
if (!contentLengthEncoded)
{
long contentLength = metadata.getContentLength();
if (contentLength >= 0)
encode(buffer, new HttpField(HttpHeader.CONTENT_LENGTH, String.valueOf(contentLength)));
}
}
// Check size

View File

@ -22,8 +22,8 @@ import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
import org.eclipse.jetty.http.BadMessageException;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
@ -113,9 +113,17 @@ public class HttpTransportOverHTTP2 implements HttpTransport
{
if (lastContent)
{
HttpFields responseHeaders = info.getFields();
if (!responseHeaders.contains(HttpHeader.CONTENT_LENGTH))
responseHeaders.put(HttpHeader.CONTENT_LENGTH, String.valueOf(BufferUtil.length(content)));
long realContentLength = BufferUtil.length(content);
long contentLength = info.getContentLength();
if (contentLength < 0)
{
info.setContentLength(realContentLength);
}
else if (contentLength != realContentLength)
{
callback.failed(new BadMessageException(HttpStatus.INTERNAL_SERVER_ERROR_500, String.format("Incorrect Content-Length %d!=%d", contentLength, realContentLength)));
return;
}
}
if (hasContent)