HTTP/2 Headers Code Using String instead of AsciiString
Motivation: The HTTP/2 headers code should be using binary string (currently AsciiString) objects instead of String objects. The DefaultHttp2HeadersEncoder was still using String for sensitiveHeaders. Modifications: - Remove the usage of String from DefaultHttp2HeadersEncoder. - Introduce an interface to determine if a header name/value is sensitive or not to 1. prevent necessarily creating/copying sets. 2. Allow the name/value to be considered when checking if sensitive. Result: No more String in DefaultHttp2HeadersEncoder and less required set creation/operations.
This commit is contained in:
parent
9517edd498
commit
609e065fcf
@ -16,10 +16,11 @@
|
|||||||
package io.netty.handler.codec.http2;
|
package io.netty.handler.codec.http2;
|
||||||
|
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_HEADER_TABLE_SIZE;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_HEADER_TABLE_SIZE;
|
||||||
import static io.netty.handler.codec.http2.Http2Error.INTERNAL_ERROR;
|
|
||||||
import static io.netty.handler.codec.http2.Http2Error.COMPRESSION_ERROR;
|
import static io.netty.handler.codec.http2.Http2Error.COMPRESSION_ERROR;
|
||||||
|
import static io.netty.handler.codec.http2.Http2Error.INTERNAL_ERROR;
|
||||||
import static io.netty.handler.codec.http2.Http2Error.PROTOCOL_ERROR;
|
import static io.netty.handler.codec.http2.Http2Error.PROTOCOL_ERROR;
|
||||||
import static io.netty.handler.codec.http2.Http2Exception.connectionError;
|
import static io.netty.handler.codec.http2.Http2Exception.connectionError;
|
||||||
|
import static io.netty.util.internal.ObjectUtil.checkNotNull;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufOutputStream;
|
import io.netty.buffer.ByteBufOutputStream;
|
||||||
import io.netty.handler.codec.AsciiString;
|
import io.netty.handler.codec.AsciiString;
|
||||||
@ -28,26 +29,23 @@ import io.netty.handler.codec.BinaryHeaders.EntryVisitor;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
|
|
||||||
import com.twitter.hpack.Encoder;
|
import com.twitter.hpack.Encoder;
|
||||||
|
|
||||||
public class DefaultHttp2HeadersEncoder implements Http2HeadersEncoder, Http2HeadersEncoder.Configuration {
|
public class DefaultHttp2HeadersEncoder implements Http2HeadersEncoder, Http2HeadersEncoder.Configuration {
|
||||||
private final Encoder encoder;
|
private final Encoder encoder;
|
||||||
private final ByteArrayOutputStream tableSizeChangeOutput = new ByteArrayOutputStream();
|
private final ByteArrayOutputStream tableSizeChangeOutput = new ByteArrayOutputStream();
|
||||||
private final Set<String> sensitiveHeaders = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
|
private final SensitivityDetector sensitivityDetector;
|
||||||
private final Http2HeaderTable headerTable;
|
private final Http2HeaderTable headerTable;
|
||||||
|
|
||||||
public DefaultHttp2HeadersEncoder() {
|
public DefaultHttp2HeadersEncoder() {
|
||||||
this(DEFAULT_HEADER_TABLE_SIZE, Collections.<String>emptySet());
|
this(DEFAULT_HEADER_TABLE_SIZE, NEVER_SENSITIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DefaultHttp2HeadersEncoder(int maxHeaderTableSize, Set<String> sensitiveHeaders) {
|
public DefaultHttp2HeadersEncoder(int maxHeaderTableSize, SensitivityDetector sensitivityDetector) {
|
||||||
|
this.sensitivityDetector = checkNotNull(sensitivityDetector, "sensitiveDetector");
|
||||||
encoder = new Encoder(maxHeaderTableSize);
|
encoder = new Encoder(maxHeaderTableSize);
|
||||||
this.sensitiveHeaders.addAll(sensitiveHeaders);
|
|
||||||
headerTable = new Http2HeaderTableEncoder();
|
headerTable = new Http2HeaderTableEncoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,8 +109,7 @@ public class DefaultHttp2HeadersEncoder implements Http2HeadersEncoder, Http2Hea
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void encodeHeader(AsciiString key, AsciiString value, OutputStream stream) throws IOException {
|
private void encodeHeader(AsciiString key, AsciiString value, OutputStream stream) throws IOException {
|
||||||
boolean sensitive = sensitiveHeaders.contains(key.toString());
|
encoder.encodeHeader(stream, key.array(), value.array(), sensitivityDetector.isSensitive(key, value));
|
||||||
encoder.encodeHeader(stream, key.array(), value.array(), sensitive);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
package io.netty.handler.codec.http2;
|
package io.netty.handler.codec.http2;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.handler.codec.AsciiString;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encodes {@link Http2Headers} into HPACK-encoded headers blocks.
|
* Encodes {@link Http2Headers} into HPACK-encoded headers blocks.
|
||||||
@ -31,6 +32,24 @@ public interface Http2HeadersEncoder {
|
|||||||
Http2HeaderTable headerTable();
|
Http2HeaderTable headerTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if a header name/value pair is treated as
|
||||||
|
* <a href="http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-12#section-7.1.3">sensitive</a>.
|
||||||
|
* If the object can be dynamically modified and shared across multiple connections it may need to be thread safe.
|
||||||
|
*/
|
||||||
|
interface SensitivityDetector {
|
||||||
|
/**
|
||||||
|
* Determine if a header {@code name}/{@code value} pair should be treated as
|
||||||
|
* <a href="http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-12#section-7.1.3">sensitive</a>.
|
||||||
|
* @param name The name for the header.
|
||||||
|
* @param value The value of the header.
|
||||||
|
* @return {@code true} if a header {@code name}/{@code value} pair should be treated as
|
||||||
|
* <a href="http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-12#section-7.1.3">sensitive</a>.
|
||||||
|
* {@code false} otherwise.
|
||||||
|
*/
|
||||||
|
boolean isSensitive(AsciiString name, AsciiString value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encodes the given headers and writes the output headers block to the given output buffer.
|
* Encodes the given headers and writes the output headers block to the given output buffer.
|
||||||
*
|
*
|
||||||
@ -43,4 +62,14 @@ public interface Http2HeadersEncoder {
|
|||||||
* Get the {@link Configuration} for this {@link Http2HeadersEncoder}
|
* Get the {@link Configuration} for this {@link Http2HeadersEncoder}
|
||||||
*/
|
*/
|
||||||
Configuration configuration();
|
Configuration configuration();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Always return {@code false} for {@link SensitivityDetector#isSensitive(AsciiString, AsciiString)}.
|
||||||
|
*/
|
||||||
|
SensitivityDetector NEVER_SENSITIVE = new SensitivityDetector() {
|
||||||
|
@Override
|
||||||
|
public boolean isSensitive(AsciiString name, AsciiString value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user