Allow non-standard HTTP/2 settings
Motivation: The Http2Settings class currently disallows setting non-standard settings, which violates the spec. Modifications: Updated Http2Settings to permit arbitrary settings. Also adjusting the default initial capacity to allow setting all of the standard settings without reallocation. Result: Fixes #3560
This commit is contained in:
parent
cdd2e1c8c1
commit
96cd447ce9
@ -69,6 +69,7 @@ public final class Http2CodecUtil {
|
||||
public static final int SETTINGS_INITIAL_WINDOW_SIZE = 4;
|
||||
public static final int SETTINGS_MAX_FRAME_SIZE = 5;
|
||||
public static final int SETTINGS_MAX_HEADER_LIST_SIZE = 6;
|
||||
public static final int NUM_STANDARD_SETTINGS = 6;
|
||||
|
||||
public static final int MAX_HEADER_TABLE_SIZE = Integer.MAX_VALUE; // Size limited by HPACK library
|
||||
public static final long MAX_CONCURRENT_STREAMS = MAX_UNSIGNED_INT;
|
||||
|
@ -23,6 +23,7 @@ import static io.netty.handler.codec.http2.Http2CodecUtil.MIN_HEADER_TABLE_SIZE;
|
||||
import static io.netty.handler.codec.http2.Http2CodecUtil.MIN_CONCURRENT_STREAMS;
|
||||
import static io.netty.handler.codec.http2.Http2CodecUtil.MIN_INITIAL_WINDOW_SIZE;
|
||||
import static io.netty.handler.codec.http2.Http2CodecUtil.MIN_HEADER_LIST_SIZE;
|
||||
import static io.netty.handler.codec.http2.Http2CodecUtil.NUM_STANDARD_SETTINGS;
|
||||
import static io.netty.handler.codec.http2.Http2CodecUtil.SETTINGS_ENABLE_PUSH;
|
||||
import static io.netty.handler.codec.http2.Http2CodecUtil.SETTINGS_HEADER_TABLE_SIZE;
|
||||
import static io.netty.handler.codec.http2.Http2CodecUtil.SETTINGS_INITIAL_WINDOW_SIZE;
|
||||
@ -39,9 +40,14 @@ import io.netty.util.collection.IntObjectHashMap;
|
||||
* methods for standard settings.
|
||||
*/
|
||||
public final class Http2Settings extends IntObjectHashMap<Long> {
|
||||
/**
|
||||
* Default capacity based on the number of standard settings from the HTTP/2 spec, adjusted so that adding all of
|
||||
* the standard settings will not cause the map capacity to change.
|
||||
*/
|
||||
private static final int DEFAULT_CAPACITY = (int) (NUM_STANDARD_SETTINGS / DEFAULT_LOAD_FACTOR) + 1;
|
||||
|
||||
public Http2Settings() {
|
||||
this(6 /* number of standard settings */);
|
||||
this(DEFAULT_CAPACITY);
|
||||
}
|
||||
|
||||
public Http2Settings(int initialCapacity, float loadFactor) {
|
||||
@ -53,9 +59,10 @@ public final class Http2Settings extends IntObjectHashMap<Long> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the superclass method to perform verification of standard HTTP/2 settings.
|
||||
* Adds the given setting key/value pair. For standard settings defined by the HTTP/2 spec, performs
|
||||
* validation on the values.
|
||||
*
|
||||
* @throws IllegalArgumentException if verification of the setting fails.
|
||||
* @throws IllegalArgumentException if verification for a standard HTTP/2 setting fails.
|
||||
*/
|
||||
@Override
|
||||
public Long put(int key, Long value) {
|
||||
@ -176,7 +183,12 @@ public final class Http2Settings extends IntObjectHashMap<Long> {
|
||||
return this;
|
||||
}
|
||||
|
||||
Integer getIntValue(int key) {
|
||||
/**
|
||||
* A helper method that returns {@link Long#intValue()} on the return of {@link #get(int)}, if present. Note that
|
||||
* if the range of the value exceeds {@link Integer#MAX_VALUE}, the {@link #get(int)} method should
|
||||
* be used instead to avoid truncation of the value.
|
||||
*/
|
||||
public Integer getIntValue(int key) {
|
||||
Long value = get(key);
|
||||
if (value == null) {
|
||||
return null;
|
||||
@ -220,7 +232,8 @@ public final class Http2Settings extends IntObjectHashMap<Long> {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("key");
|
||||
// Non-standard HTTP/2 setting - don't do validation.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,4 +61,10 @@ public class Http2SettingsTest {
|
||||
assertEquals(MAX_FRAME_SIZE_UPPER_BOUND, (int) settings.maxFrameSize());
|
||||
assertEquals(4L, (long) settings.maxHeaderListSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonStandardSettingsShouldBeSet() {
|
||||
settings.put(0, 123L);
|
||||
assertEquals(123L, (long) settings.get(0));
|
||||
}
|
||||
}
|
||||
|
@ -33,10 +33,10 @@ import java.util.NoSuchElementException;
|
||||
public class IntObjectHashMap<V> implements IntObjectMap<V>, Iterable<IntObjectMap.Entry<V>> {
|
||||
|
||||
/** Default initial capacity. Used if not specified in the constructor */
|
||||
private static final int DEFAULT_CAPACITY = 11;
|
||||
public static final int DEFAULT_CAPACITY = 11;
|
||||
|
||||
/** Default load factor. Used if not specified in the constructor */
|
||||
private static final float DEFAULT_LOAD_FACTOR = 0.5f;
|
||||
public static final float DEFAULT_LOAD_FACTOR = 0.5f;
|
||||
|
||||
/**
|
||||
* Placeholder for null values, so we can use the actual null to mean available.
|
||||
|
Loading…
Reference in New Issue
Block a user