Issue #4115 - Drop HTTP/2 pseudo headers.
Updates after review. Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
parent
609c144ae0
commit
6acc9f7be5
|
@ -69,6 +69,11 @@ public class HttpField
|
|||
return _name;
|
||||
}
|
||||
|
||||
public String getLowCaseName()
|
||||
{
|
||||
return _header != null ? _header.lowCaseName() : StringUtil.asciiToLowerCase(_name);
|
||||
}
|
||||
|
||||
public String getValue()
|
||||
{
|
||||
return _value;
|
||||
|
|
|
@ -149,6 +149,7 @@ public enum HttpHeader
|
|||
}
|
||||
|
||||
private final String _string;
|
||||
private final String _lowCase;
|
||||
private final byte[] _bytes;
|
||||
private final byte[] _bytesColonSpace;
|
||||
private final ByteBuffer _buffer;
|
||||
|
@ -156,11 +157,17 @@ public enum HttpHeader
|
|||
HttpHeader(String s)
|
||||
{
|
||||
_string = s;
|
||||
_lowCase = StringUtil.asciiToLowerCase(s);
|
||||
_bytes = StringUtil.getBytes(s);
|
||||
_bytesColonSpace = StringUtil.getBytes(s + ": ");
|
||||
_buffer = ByteBuffer.wrap(_bytes);
|
||||
}
|
||||
|
||||
public String lowCaseName()
|
||||
{
|
||||
return _lowCase;
|
||||
}
|
||||
|
||||
public ByteBuffer toBuffer()
|
||||
{
|
||||
return _buffer.asReadOnlyBuffer();
|
||||
|
|
|
@ -261,7 +261,7 @@ public class HpackContext
|
|||
_dynamicTableSizeInBytes += size;
|
||||
_dynamicTable.add(entry);
|
||||
_fieldMap.put(field, entry);
|
||||
_nameMap.put(StringUtil.asciiToLowerCase(field.getName()), entry);
|
||||
_nameMap.put(field.getLowCaseName(), entry);
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug(String.format("HdrTbl[%x] added %s", hashCode(), entry));
|
||||
|
@ -383,7 +383,7 @@ public class HpackContext
|
|||
_dynamicTableSizeInBytes -= entry.getSize();
|
||||
entry._slot = -1;
|
||||
_fieldMap.remove(entry.getHttpField());
|
||||
String lc = StringUtil.asciiToLowerCase(entry.getHttpField().getName());
|
||||
String lc = entry.getHttpField().getLowCaseName();
|
||||
if (entry == _nameMap.get(lc))
|
||||
_nameMap.remove(lc);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.eclipse.jetty.http2.hpack;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
@ -27,6 +28,7 @@ import java.util.Set;
|
|||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpScheme;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
|
@ -77,6 +79,9 @@ public class HpackEncoder
|
|||
private static final EnumSet<HttpHeader> IGNORED_HEADERS = EnumSet.of(HttpHeader.CONNECTION, HttpHeader.KEEP_ALIVE,
|
||||
HttpHeader.PROXY_CONNECTION, HttpHeader.TRANSFER_ENCODING, HttpHeader.UPGRADE);
|
||||
private static final PreEncodedHttpField TE_TRAILERS = new PreEncodedHttpField(HttpHeader.TE, "trailers");
|
||||
private static final PreEncodedHttpField C_SCHEME_HTTP = new PreEncodedHttpField(HttpHeader.C_SCHEME, "http");
|
||||
private static final PreEncodedHttpField C_SCHEME_HTTPS = new PreEncodedHttpField(HttpHeader.C_SCHEME, "https");
|
||||
private static final EnumMap<HttpMethod, PreEncodedHttpField> C_METHODS = new EnumMap<>(HttpMethod.class);
|
||||
|
||||
static
|
||||
{
|
||||
|
@ -84,6 +89,10 @@ public class HpackEncoder
|
|||
{
|
||||
STATUSES[code.getCode()] = new PreEncodedHttpField(HttpHeader.C_STATUS, Integer.toString(code.getCode()));
|
||||
}
|
||||
for (HttpMethod method : HttpMethod.values())
|
||||
{
|
||||
C_METHODS.put(method, new PreEncodedHttpField(HttpHeader.C_METHOD, method.asString()));
|
||||
}
|
||||
}
|
||||
|
||||
private final HpackContext _context;
|
||||
|
@ -161,21 +170,17 @@ public class HpackEncoder
|
|||
LOG.debug(String.format("CtxTbl[%x] encoding", _context.hashCode()));
|
||||
|
||||
HttpFields fields = metadata.getFields();
|
||||
if (isValidateEncoding())
|
||||
{
|
||||
// Verify that we can encode without errors.
|
||||
if (fields != null)
|
||||
if (isValidateEncoding() && fields != null)
|
||||
{
|
||||
for (HttpField field : fields)
|
||||
{
|
||||
String name = field.getName();
|
||||
String lowName = StringUtil.asciiToLowerCase(name);
|
||||
char firstChar = lowName.charAt(0);
|
||||
char firstChar = name.charAt(0);
|
||||
if (firstChar <= ' ' || firstChar == ':')
|
||||
throw new HpackException.StreamException("Invalid header name: '%s'", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_headerListSize = 0;
|
||||
int pos = buffer.position();
|
||||
|
@ -190,10 +195,12 @@ public class HpackEncoder
|
|||
{
|
||||
MetaData.Request request = (MetaData.Request)metadata;
|
||||
|
||||
// TODO optimise these to avoid HttpField creation
|
||||
String scheme = request.getURI().getScheme();
|
||||
encode(buffer, new HttpField(HttpHeader.C_SCHEME, scheme == null ? HttpScheme.HTTP.asString() : scheme));
|
||||
encode(buffer, new HttpField(HttpHeader.C_METHOD, request.getMethod()));
|
||||
encode(buffer, HttpScheme.HTTPS.is(scheme) ? C_SCHEME_HTTPS : C_SCHEME_HTTP);
|
||||
String method = request.getMethod();
|
||||
HttpMethod httpMethod = HttpMethod.fromString(method);
|
||||
HttpField methodField = C_METHODS.get(httpMethod);
|
||||
encode(buffer, methodField == null ? new HttpField(HttpHeader.C_METHOD, method) : methodField);
|
||||
encode(buffer, new HttpField(HttpHeader.C_AUTHORITY, request.getURI().getAuthority()));
|
||||
encode(buffer, new HttpField(HttpHeader.C_PATH, request.getURI().getPathQuery()));
|
||||
}
|
||||
|
@ -229,7 +236,7 @@ public class HpackEncoder
|
|||
encode(buffer, TE_TRAILERS);
|
||||
continue;
|
||||
}
|
||||
String name = StringUtil.asciiToLowerCase(field.getName());
|
||||
String name = field.getLowCaseName();
|
||||
if (hopHeaders != null && hopHeaders.contains(name))
|
||||
continue;
|
||||
encode(buffer, field);
|
||||
|
|
Loading…
Reference in New Issue