okhttp3.internal.http2.Settings Maven / Gradle / Ivy
/*
* Copyright (C) 2012 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okhttp3.internal.http2;
import java.util.Arrays;
/**
* Settings describe characteristics of the sending peer, which are used by the receiving peer.
* Settings are {@link Http2Connection connection} scoped.
*/
public final class Settings {
/**
* From the HTTP/2 specs, the default initial window size for all streams is 64 KiB. (Chrome 25
* uses 10 MiB).
*/
static final int DEFAULT_INITIAL_WINDOW_SIZE = 65535;
/** HTTP/2: Size in bytes of the table used to decode the sender's header blocks. */
static final int HEADER_TABLE_SIZE = 1;
/** HTTP/2: The peer must not send a PUSH_PROMISE frame when this is 0. */
static final int ENABLE_PUSH = 2;
/** Sender's maximum number of concurrent streams. */
static final int MAX_CONCURRENT_STREAMS = 4;
/** HTTP/2: Size in bytes of the largest frame payload the sender will accept. */
static final int MAX_FRAME_SIZE = 5;
/** HTTP/2: Advisory only. Size in bytes of the largest header list the sender will accept. */
static final int MAX_HEADER_LIST_SIZE = 6;
/** Window size in bytes. */
static final int INITIAL_WINDOW_SIZE = 7;
/** Total number of settings. */
static final int COUNT = 10;
/** Bitfield of which flags that values. */
private int set;
/** Flag values. */
private final int[] values = new int[COUNT];
void clear() {
set = 0;
Arrays.fill(values, 0);
}
Settings set(int id, int value) {
if (id < 0 || id >= values.length) {
return this; // Discard unknown settings.
}
int bit = 1 << id;
set |= bit;
values[id] = value;
return this;
}
/** Returns true if a value has been assigned for the setting {@code id}. */
boolean isSet(int id) {
int bit = 1 << id;
return (set & bit) != 0;
}
/** Returns the value for the setting {@code id}, or 0 if unset. */
int get(int id) {
return values[id];
}
/** Returns the number of settings that have values assigned. */
int size() {
return Integer.bitCount(set);
}
/** Returns -1 if unset. */
int getHeaderTableSize() {
int bit = 1 << HEADER_TABLE_SIZE;
return (bit & set) != 0 ? values[HEADER_TABLE_SIZE] : -1;
}
// TODO: honor this setting.
boolean getEnablePush(boolean defaultValue) {
int bit = 1 << ENABLE_PUSH;
return ((bit & set) != 0 ? values[ENABLE_PUSH] : defaultValue ? 1 : 0) == 1;
}
int getMaxConcurrentStreams(int defaultValue) {
int bit = 1 << MAX_CONCURRENT_STREAMS;
return (bit & set) != 0 ? values[MAX_CONCURRENT_STREAMS] : defaultValue;
}
int getMaxFrameSize(int defaultValue) {
int bit = 1 << MAX_FRAME_SIZE;
return (bit & set) != 0 ? values[MAX_FRAME_SIZE] : defaultValue;
}
int getMaxHeaderListSize(int defaultValue) {
int bit = 1 << MAX_HEADER_LIST_SIZE;
return (bit & set) != 0 ? values[MAX_HEADER_LIST_SIZE] : defaultValue;
}
int getInitialWindowSize() {
int bit = 1 << INITIAL_WINDOW_SIZE;
return (bit & set) != 0 ? values[INITIAL_WINDOW_SIZE] : DEFAULT_INITIAL_WINDOW_SIZE;
}
/**
* Writes {@code other} into this. If any setting is populated by this and {@code other}, the
* value and flags from {@code other} will be kept.
*/
void merge(Settings other) {
for (int i = 0; i < COUNT; i++) {
if (!other.isSet(i)) continue;
set(i, other.get(i));
}
}
}