io.vertx.core.http.Http2Settings Maven / Gradle / Ivy
/*
* Copyright (c) 2011-2019 Contributors to the Eclipse Foundation
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*/
package io.vertx.core.http;
import io.netty.handler.codec.http2.Http2CodecUtil;
import io.vertx.codegen.annotations.DataObject;
import io.vertx.codegen.annotations.GenIgnore;
import io.vertx.codegen.json.annotations.JsonGen;
import io.vertx.core.impl.Arguments;
import io.vertx.core.json.JsonObject;
import java.util.HashMap;
import java.util.Map;
/**
* HTTP2 settings, the settings is initialized with the default HTTP/2 values.
*
* The settings expose the parameters defined by the HTTP/2 specification, as well as extra settings for
* protocol extensions.
*
* @author Julien Viet
*/
@DataObject
@JsonGen(publicConverter = false)
public class Http2Settings {
/**
* Default HTTP/2 spec value for {@link #getHeaderTableSize} : {@code 4096}
*/
public static final long DEFAULT_HEADER_TABLE_SIZE = 4096;
/**
* Default HTTP/2 spec value for {@link #isPushEnabled} : {@code true}
*/
public static final boolean DEFAULT_ENABLE_PUSH = true;
/**
* Default HTTP/2 spec value for {@link #getMaxConcurrentStreams} : {@code 0xFFFFFFFFL}
*/
public static final long DEFAULT_MAX_CONCURRENT_STREAMS = 0xFFFFFFFFL;
/**
* Default HTTP/2 spec value for {@link #getInitialWindowSize} : {@code 65535}
*/
public static final int DEFAULT_INITIAL_WINDOW_SIZE = 65535;
/**
* Default HTTP/2 spec value for {@link #getMaxFrameSize} : {@code 16384}
*/
public static final int DEFAULT_MAX_FRAME_SIZE = 16384;
/**
* Default HTTP/2 spec value for {@link #getMaxHeaderListSize} : {@code 8192}
*/
public static final int DEFAULT_MAX_HEADER_LIST_SIZE = 8192;
/**
* Default HTTP/2 spec value for {@link #getExtraSettings} : {@code null}
*/
public static final Map DEFAULT_EXTRA_SETTINGS = null;
private long headerTableSize;
private boolean pushEnabled;
private long maxConcurrentStreams;
private int initialWindowSize;
private int maxFrameSize;
private long maxHeaderListSize;
private Map extraSettings;
/**
* Default constructor
*/
public Http2Settings() {
headerTableSize = DEFAULT_HEADER_TABLE_SIZE;
pushEnabled = DEFAULT_ENABLE_PUSH;
maxConcurrentStreams = DEFAULT_MAX_CONCURRENT_STREAMS;
initialWindowSize = DEFAULT_INITIAL_WINDOW_SIZE;
maxFrameSize = DEFAULT_MAX_FRAME_SIZE;
maxHeaderListSize = DEFAULT_MAX_HEADER_LIST_SIZE;
extraSettings = DEFAULT_EXTRA_SETTINGS;
}
/**
* Create an settings from JSON
*
* @param json the JSON
*/
public Http2Settings(JsonObject json) {
this();
Http2SettingsConverter.fromJson(json, this);
}
/**
* Copy constructor
*
* @param other the settings to copy
*/
public Http2Settings(Http2Settings other) {
headerTableSize = other.headerTableSize;
pushEnabled = other.pushEnabled;
maxConcurrentStreams = other.maxConcurrentStreams;
initialWindowSize = other.initialWindowSize;
maxFrameSize = other.maxFrameSize;
maxHeaderListSize = other.maxHeaderListSize;
extraSettings = other.extraSettings != null ? new HashMap<>(other.extraSettings) : null;
}
/**
* @return the {@literal SETTINGS_HEADER_TABLE_SIZE} HTTP/2 setting
*/
public long getHeaderTableSize() {
return headerTableSize;
}
/**
* Set {@literal SETTINGS_HEADER_TABLE_SIZE} HTTP/2 setting.
*
* @param headerTableSize the new value
* @return a reference to this, so the API can be used fluently
*/
public Http2Settings setHeaderTableSize(long headerTableSize) {
Arguments.require(headerTableSize >= Http2CodecUtil.MIN_HEADER_TABLE_SIZE,
"headerTableSize must be >= " + Http2CodecUtil.MIN_HEADER_TABLE_SIZE);
Arguments.require(headerTableSize <= Http2CodecUtil.MAX_HEADER_TABLE_SIZE,
"headerTableSize must be <= " + Http2CodecUtil.MAX_HEADER_TABLE_SIZE);
this.headerTableSize = headerTableSize;
return this;
}
/**
* @return the {@literal SETTINGS_ENABLE_PUSH} HTTP/2 setting
*/
public boolean isPushEnabled() {
return pushEnabled;
}
/**
* Set the {@literal SETTINGS_ENABLE_PUSH} HTTP/2 setting
*
* @param pushEnabled the new value
* @return a reference to this, so the API can be used fluently
*/
public Http2Settings setPushEnabled(boolean pushEnabled) {
this.pushEnabled = pushEnabled;
return this;
}
/**
* @return the {@literal SETTINGS_MAX_CONCURRENT_STREAMS} HTTP/2 setting
*/
public long getMaxConcurrentStreams() {
return maxConcurrentStreams;
}
/**
* Set the {@literal SETTINGS_MAX_CONCURRENT_STREAMS} HTTP/2 setting
*
* @param maxConcurrentStreams the new value
* @return a reference to this, so the API can be used fluently
*/
public Http2Settings setMaxConcurrentStreams(long maxConcurrentStreams) {
Arguments.require(maxConcurrentStreams >= Http2CodecUtil.MIN_CONCURRENT_STREAMS,
"maxConcurrentStreams must be >= " + Http2CodecUtil.MIN_CONCURRENT_STREAMS);
Arguments.require(maxConcurrentStreams <= Http2CodecUtil.MAX_CONCURRENT_STREAMS,
"maxConcurrentStreams must be < " + Http2CodecUtil.MAX_CONCURRENT_STREAMS);
this.maxConcurrentStreams = maxConcurrentStreams;
return this;
}
/**
* @return the {@literal SETTINGS_INITIAL_WINDOW_SIZE} HTTP/2 setting
*/
public int getInitialWindowSize() {
return initialWindowSize;
}
/**
* Set the {@literal SETTINGS_INITIAL_WINDOW_SIZE} HTTP/2 setting
*
* @param initialWindowSize the new value
* @return a reference to this, so the API can be used fluently
*/
public Http2Settings setInitialWindowSize(int initialWindowSize) {
Arguments.require(initialWindowSize >= Http2CodecUtil.MIN_INITIAL_WINDOW_SIZE,
"initialWindowSize must be >= " + Http2CodecUtil.MIN_INITIAL_WINDOW_SIZE);
this.initialWindowSize = initialWindowSize;
return this;
}
/**
* @return the {@literal SETTINGS_MAX_FRAME_SIZE} HTTP/2 setting
*/
public int getMaxFrameSize() {
return maxFrameSize;
}
/**
* Set the {@literal SETTINGS_MAX_FRAME_SIZE} HTTP/2 setting
*
* @param maxFrameSize the new value
* @return a reference to this, so the API can be used fluently
*/
public Http2Settings setMaxFrameSize(int maxFrameSize) {
Arguments.require(maxFrameSize >= Http2CodecUtil.MAX_FRAME_SIZE_LOWER_BOUND,
"maxFrameSize must be >= " + Http2CodecUtil.MAX_FRAME_SIZE_LOWER_BOUND);
Arguments.require(maxFrameSize <= Http2CodecUtil.MAX_FRAME_SIZE_UPPER_BOUND,
"maxFrameSize must be <= " + Http2CodecUtil.MAX_FRAME_SIZE_UPPER_BOUND);
this.maxFrameSize = maxFrameSize;
return this;
}
/**
* @return the {@literal SETTINGS_MAX_HEADER_LIST_SIZE} HTTP/2 setting
*/
public long getMaxHeaderListSize() {
return maxHeaderListSize;
}
/**
* Set the {@literal SETTINGS_MAX_HEADER_LIST_SIZE} HTTP/2 setting
*
* @param maxHeaderListSize the new value
* @return a reference to this, so the API can be used fluently
*/
public Http2Settings setMaxHeaderListSize(long maxHeaderListSize) {
Arguments.require(maxHeaderListSize >= 0, "maxHeaderListSize must be >= 0");
Arguments.require(maxHeaderListSize >= Http2CodecUtil.MIN_HEADER_LIST_SIZE,
"maxHeaderListSize must be >= " + Http2CodecUtil.MIN_HEADER_LIST_SIZE);
this.maxHeaderListSize = maxHeaderListSize;
return this;
}
/**
* @return the extra settings used for extending HTTP/2
*/
@GenIgnore
public Map getExtraSettings() {
return extraSettings;
}
/**
* Set the extra setting used for extending HTTP/2
*
* @param settings the new extra settings
* @return a reference to this, so the API can be used fluently
*/
@GenIgnore
public Http2Settings setExtraSettings(Map settings) {
extraSettings = settings;
return this;
}
/**
* Return a setting value according to its identifier.
*
* @param id the setting identifier
* @return the setting value
*/
public Long get(int id) {
switch (id) {
case 1:
return headerTableSize;
case 2:
return pushEnabled ? 1L : 0L;
case 3:
return maxConcurrentStreams;
case 4:
return (long)initialWindowSize;
case 5:
return (long)maxFrameSize;
case 6:
return (long)maxHeaderListSize;
default:
return extraSettings != null ? extraSettings.get(id) : null;
}
}
/**
* Set a setting {@code value} for a given setting {@code id}.
*
* @param id the setting id
* @param value the setting value
* @return a reference to this, so the API can be used fluently
*/
public Http2Settings set(int id, long value) {
Arguments.require(id >= 0 && id <= 0xFFFF, "Setting id must me an unsigned 16-bit value");
Arguments.require(value >= 0L && value <= 0xFFFFFFFFL, "Setting value must me an unsigned 32-bit value");
switch (id) {
case 1:
setHeaderTableSize(value);
break;
case 2:
Arguments.require(value == 0 || value == 1, "enablePush must be 0 or 1");
setPushEnabled(value == 1);
break;
case 3:
setMaxConcurrentStreams(value);
break;
case 4:
setInitialWindowSize((int) value);
break;
case 5:
setMaxFrameSize((int) value);
break;
case 6:
Arguments.require(value <= Integer.MAX_VALUE, "maxHeaderListSize must be <= " + Integer.MAX_VALUE);
setMaxHeaderListSize((int) value);
break;
default:
if (extraSettings == null) {
extraSettings = new HashMap<>();
}
extraSettings.put(id, value);
}
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Http2Settings that = (Http2Settings) o;
if (headerTableSize != that.headerTableSize) return false;
if (pushEnabled != that.pushEnabled) return false;
if (maxConcurrentStreams != that.maxConcurrentStreams) return false;
if (initialWindowSize != that.initialWindowSize) return false;
if (maxFrameSize != that.maxFrameSize) return false;
if (maxHeaderListSize != that.maxHeaderListSize) return false;
return true;
}
@Override
public int hashCode() {
int result = (int) (headerTableSize ^ (headerTableSize >>> 32));
result = 31 * result + (pushEnabled ? 1 : 0);
result = 31 * result + (int) (maxConcurrentStreams ^ (maxConcurrentStreams >>> 32));
result = 31 * result + initialWindowSize;
result = 31 * result + maxFrameSize;
result = 31 * result + (int) (maxHeaderListSize ^ (maxHeaderListSize >>> 32));
return result;
}
@Override
public String toString() {
return toJson().encode();
}
public JsonObject toJson() {
JsonObject json = new JsonObject();
Http2SettingsConverter.toJson(this, json);
return json;
}
}