Initial commit
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
package okhttp3.internal.http2;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
public final class ConnectionShutdownException extends IOException {
|
||||
}
|
31
sources/okhttp3/internal/http2/ErrorCode.java
Normal file
31
sources/okhttp3/internal/http2/ErrorCode.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package okhttp3.internal.http2;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
public enum ErrorCode {
|
||||
NO_ERROR(0),
|
||||
PROTOCOL_ERROR(1),
|
||||
INTERNAL_ERROR(2),
|
||||
FLOW_CONTROL_ERROR(3),
|
||||
REFUSED_STREAM(7),
|
||||
CANCEL(8),
|
||||
COMPRESSION_ERROR(9),
|
||||
CONNECT_ERROR(10),
|
||||
ENHANCE_YOUR_CALM(11),
|
||||
INADEQUATE_SECURITY(12),
|
||||
HTTP_1_1_REQUIRED(13);
|
||||
|
||||
public final int httpCode;
|
||||
|
||||
ErrorCode(int i) {
|
||||
this.httpCode = i;
|
||||
}
|
||||
|
||||
public static ErrorCode fromHttp2(int i) {
|
||||
for (ErrorCode errorCode : values()) {
|
||||
if (errorCode.httpCode == i) {
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
47
sources/okhttp3/internal/http2/Header.java
Normal file
47
sources/okhttp3/internal/http2/Header.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package okhttp3.internal.http2;
|
||||
|
||||
import okhttp3.internal.Util;
|
||||
import okio.ByteString;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
public final class Header {
|
||||
final int hpackSize;
|
||||
public final ByteString name;
|
||||
public final ByteString value;
|
||||
public static final ByteString PSEUDO_PREFIX = ByteString.encodeUtf8(":");
|
||||
public static final ByteString RESPONSE_STATUS = ByteString.encodeUtf8(":status");
|
||||
public static final ByteString TARGET_METHOD = ByteString.encodeUtf8(":method");
|
||||
public static final ByteString TARGET_PATH = ByteString.encodeUtf8(":path");
|
||||
public static final ByteString TARGET_SCHEME = ByteString.encodeUtf8(":scheme");
|
||||
public static final ByteString TARGET_AUTHORITY = ByteString.encodeUtf8(":authority");
|
||||
|
||||
public Header(String str, String str2) {
|
||||
this(ByteString.encodeUtf8(str), ByteString.encodeUtf8(str2));
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof Header)) {
|
||||
return false;
|
||||
}
|
||||
Header header = (Header) obj;
|
||||
return this.name.equals(header.name) && this.value.equals(header.value);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return ((527 + this.name.hashCode()) * 31) + this.value.hashCode();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return Util.format("%s: %s", this.name.utf8(), this.value.utf8());
|
||||
}
|
||||
|
||||
public Header(ByteString byteString, String str) {
|
||||
this(byteString, ByteString.encodeUtf8(str));
|
||||
}
|
||||
|
||||
public Header(ByteString byteString, ByteString byteString2) {
|
||||
this.name = byteString;
|
||||
this.value = byteString2;
|
||||
this.hpackSize = byteString.size() + 32 + byteString2.size();
|
||||
}
|
||||
}
|
487
sources/okhttp3/internal/http2/Hpack.java
Normal file
487
sources/okhttp3/internal/http2/Hpack.java
Normal file
@@ -0,0 +1,487 @@
|
||||
package okhttp3.internal.http2;
|
||||
|
||||
import com.liulishuo.filedownloader.model.FileDownloadModel;
|
||||
import com.ubt.jimu.base.entities.Constant;
|
||||
import com.ubt.jimu.base.http.ApiConstants;
|
||||
import com.ubt.jimu.unity.bluetooth.MyUnityListener;
|
||||
import com.ubtrobot.jimu.robotapi.PeripheralType;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import okhttp3.internal.Util;
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSource;
|
||||
import okio.ByteString;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
final class Hpack {
|
||||
private static final int PREFIX_4_BITS = 15;
|
||||
private static final int PREFIX_5_BITS = 31;
|
||||
private static final int PREFIX_6_BITS = 63;
|
||||
private static final int PREFIX_7_BITS = 127;
|
||||
static final Header[] STATIC_HEADER_TABLE = {new Header(Header.TARGET_AUTHORITY, ""), new Header(Header.TARGET_METHOD, "GET"), new Header(Header.TARGET_METHOD, "POST"), new Header(Header.TARGET_PATH, "/"), new Header(Header.TARGET_PATH, "/index.html"), new Header(Header.TARGET_SCHEME, "http"), new Header(Header.TARGET_SCHEME, "https"), new Header(Header.RESPONSE_STATUS, "200"), new Header(Header.RESPONSE_STATUS, "204"), new Header(Header.RESPONSE_STATUS, "206"), new Header(Header.RESPONSE_STATUS, "304"), new Header(Header.RESPONSE_STATUS, "400"), new Header(Header.RESPONSE_STATUS, "404"), new Header(Header.RESPONSE_STATUS, "500"), new Header("accept-charset", ""), new Header("accept-encoding", "gzip, deflate"), new Header("accept-language", ""), new Header("accept-ranges", ""), new Header("accept", ""), new Header("access-control-allow-origin", ""), new Header("age", ""), new Header("allow", ""), new Header(ApiConstants.AUTHORIZATION, ""), new Header("cache-control", ""), new Header("content-disposition", ""), new Header("content-encoding", ""), new Header("content-language", ""), new Header("content-length", ""), new Header("content-location", ""), new Header("content-range", ""), new Header("content-type", ""), new Header("cookie", ""), new Header("date", ""), new Header(FileDownloadModel.ETAG, ""), new Header("expect", ""), new Header("expires", ""), new Header(MyUnityListener.CALLER, ""), new Header("host", ""), new Header("if-match", ""), new Header("if-modified-since", ""), new Header("if-none-match", ""), new Header("if-range", ""), new Header("if-unmodified-since", ""), new Header("last-modified", ""), new Header(Constant.Community.SOURCE_LINK_TYPE, ""), new Header("location", ""), new Header("max-forwards", ""), new Header("proxy-authenticate", ""), new Header("proxy-authorization", ""), new Header("range", ""), new Header("referer", ""), new Header("refresh", ""), new Header("retry-after", ""), new Header("server", ""), new Header("set-cookie", ""), new Header("strict-transport-security", ""), new Header("transfer-encoding", ""), new Header("user-agent", ""), new Header("vary", ""), new Header("via", ""), new Header("www-authenticate", "")};
|
||||
static final Map<ByteString, Integer> NAME_TO_FIRST_INDEX = nameToFirstIndex();
|
||||
|
||||
static final class Reader {
|
||||
Header[] dynamicTable;
|
||||
int dynamicTableByteCount;
|
||||
int headerCount;
|
||||
private final List<Header> headerList;
|
||||
private final int headerTableSizeSetting;
|
||||
private int maxDynamicTableByteCount;
|
||||
int nextHeaderIndex;
|
||||
private final BufferedSource source;
|
||||
|
||||
Reader(int i, Source source) {
|
||||
this(i, i, source);
|
||||
}
|
||||
|
||||
private void adjustDynamicTableByteCount() {
|
||||
int i = this.maxDynamicTableByteCount;
|
||||
int i2 = this.dynamicTableByteCount;
|
||||
if (i < i2) {
|
||||
if (i == 0) {
|
||||
clearDynamicTable();
|
||||
} else {
|
||||
evictToRecoverBytes(i2 - i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void clearDynamicTable() {
|
||||
Arrays.fill(this.dynamicTable, (Object) null);
|
||||
this.nextHeaderIndex = this.dynamicTable.length - 1;
|
||||
this.headerCount = 0;
|
||||
this.dynamicTableByteCount = 0;
|
||||
}
|
||||
|
||||
private int dynamicTableIndex(int i) {
|
||||
return this.nextHeaderIndex + 1 + i;
|
||||
}
|
||||
|
||||
private int evictToRecoverBytes(int i) {
|
||||
int i2 = 0;
|
||||
if (i > 0) {
|
||||
int length = this.dynamicTable.length;
|
||||
while (true) {
|
||||
length--;
|
||||
if (length < this.nextHeaderIndex || i <= 0) {
|
||||
break;
|
||||
}
|
||||
Header[] headerArr = this.dynamicTable;
|
||||
i -= headerArr[length].hpackSize;
|
||||
this.dynamicTableByteCount -= headerArr[length].hpackSize;
|
||||
this.headerCount--;
|
||||
i2++;
|
||||
}
|
||||
Header[] headerArr2 = this.dynamicTable;
|
||||
int i3 = this.nextHeaderIndex;
|
||||
System.arraycopy(headerArr2, i3 + 1, headerArr2, i3 + 1 + i2, this.headerCount);
|
||||
this.nextHeaderIndex += i2;
|
||||
}
|
||||
return i2;
|
||||
}
|
||||
|
||||
private ByteString getName(int i) throws IOException {
|
||||
if (isStaticHeader(i)) {
|
||||
return Hpack.STATIC_HEADER_TABLE[i].name;
|
||||
}
|
||||
int dynamicTableIndex = dynamicTableIndex(i - Hpack.STATIC_HEADER_TABLE.length);
|
||||
if (dynamicTableIndex >= 0) {
|
||||
Header[] headerArr = this.dynamicTable;
|
||||
if (dynamicTableIndex < headerArr.length) {
|
||||
return headerArr[dynamicTableIndex].name;
|
||||
}
|
||||
}
|
||||
throw new IOException("Header index too large " + (i + 1));
|
||||
}
|
||||
|
||||
private void insertIntoDynamicTable(int i, Header header) {
|
||||
this.headerList.add(header);
|
||||
int i2 = header.hpackSize;
|
||||
if (i != -1) {
|
||||
i2 -= this.dynamicTable[dynamicTableIndex(i)].hpackSize;
|
||||
}
|
||||
int i3 = this.maxDynamicTableByteCount;
|
||||
if (i2 > i3) {
|
||||
clearDynamicTable();
|
||||
return;
|
||||
}
|
||||
int evictToRecoverBytes = evictToRecoverBytes((this.dynamicTableByteCount + i2) - i3);
|
||||
if (i == -1) {
|
||||
int i4 = this.headerCount + 1;
|
||||
Header[] headerArr = this.dynamicTable;
|
||||
if (i4 > headerArr.length) {
|
||||
Header[] headerArr2 = new Header[headerArr.length * 2];
|
||||
System.arraycopy(headerArr, 0, headerArr2, headerArr.length, headerArr.length);
|
||||
this.nextHeaderIndex = this.dynamicTable.length - 1;
|
||||
this.dynamicTable = headerArr2;
|
||||
}
|
||||
int i5 = this.nextHeaderIndex;
|
||||
this.nextHeaderIndex = i5 - 1;
|
||||
this.dynamicTable[i5] = header;
|
||||
this.headerCount++;
|
||||
} else {
|
||||
this.dynamicTable[i + dynamicTableIndex(i) + evictToRecoverBytes] = header;
|
||||
}
|
||||
this.dynamicTableByteCount += i2;
|
||||
}
|
||||
|
||||
private boolean isStaticHeader(int i) {
|
||||
return i >= 0 && i <= Hpack.STATIC_HEADER_TABLE.length - 1;
|
||||
}
|
||||
|
||||
private int readByte() throws IOException {
|
||||
return this.source.readByte() & 255;
|
||||
}
|
||||
|
||||
private void readIndexedHeader(int i) throws IOException {
|
||||
if (isStaticHeader(i)) {
|
||||
this.headerList.add(Hpack.STATIC_HEADER_TABLE[i]);
|
||||
return;
|
||||
}
|
||||
int dynamicTableIndex = dynamicTableIndex(i - Hpack.STATIC_HEADER_TABLE.length);
|
||||
if (dynamicTableIndex >= 0) {
|
||||
Header[] headerArr = this.dynamicTable;
|
||||
if (dynamicTableIndex < headerArr.length) {
|
||||
this.headerList.add(headerArr[dynamicTableIndex]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new IOException("Header index too large " + (i + 1));
|
||||
}
|
||||
|
||||
private void readLiteralHeaderWithIncrementalIndexingIndexedName(int i) throws IOException {
|
||||
insertIntoDynamicTable(-1, new Header(getName(i), readByteString()));
|
||||
}
|
||||
|
||||
private void readLiteralHeaderWithIncrementalIndexingNewName() throws IOException {
|
||||
insertIntoDynamicTable(-1, new Header(Hpack.checkLowercase(readByteString()), readByteString()));
|
||||
}
|
||||
|
||||
private void readLiteralHeaderWithoutIndexingIndexedName(int i) throws IOException {
|
||||
this.headerList.add(new Header(getName(i), readByteString()));
|
||||
}
|
||||
|
||||
private void readLiteralHeaderWithoutIndexingNewName() throws IOException {
|
||||
this.headerList.add(new Header(Hpack.checkLowercase(readByteString()), readByteString()));
|
||||
}
|
||||
|
||||
public List<Header> getAndResetHeaderList() {
|
||||
ArrayList arrayList = new ArrayList(this.headerList);
|
||||
this.headerList.clear();
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
int maxDynamicTableByteCount() {
|
||||
return this.maxDynamicTableByteCount;
|
||||
}
|
||||
|
||||
ByteString readByteString() throws IOException {
|
||||
int readByte = readByte();
|
||||
boolean z = (readByte & PeripheralType.SERVO) == 128;
|
||||
int readInt = readInt(readByte, Hpack.PREFIX_7_BITS);
|
||||
return z ? ByteString.of(Huffman.get().decode(this.source.readByteArray(readInt))) : this.source.readByteString(readInt);
|
||||
}
|
||||
|
||||
void readHeaders() throws IOException {
|
||||
while (!this.source.exhausted()) {
|
||||
int readByte = this.source.readByte() & 255;
|
||||
if (readByte == 128) {
|
||||
throw new IOException("index == 0");
|
||||
}
|
||||
if ((readByte & PeripheralType.SERVO) == 128) {
|
||||
readIndexedHeader(readInt(readByte, Hpack.PREFIX_7_BITS) - 1);
|
||||
} else if (readByte == 64) {
|
||||
readLiteralHeaderWithIncrementalIndexingNewName();
|
||||
} else if ((readByte & 64) == 64) {
|
||||
readLiteralHeaderWithIncrementalIndexingIndexedName(readInt(readByte, 63) - 1);
|
||||
} else if ((readByte & 32) == 32) {
|
||||
this.maxDynamicTableByteCount = readInt(readByte, 31);
|
||||
int i = this.maxDynamicTableByteCount;
|
||||
if (i < 0 || i > this.headerTableSizeSetting) {
|
||||
throw new IOException("Invalid dynamic table size update " + this.maxDynamicTableByteCount);
|
||||
}
|
||||
adjustDynamicTableByteCount();
|
||||
} else if (readByte == 16 || readByte == 0) {
|
||||
readLiteralHeaderWithoutIndexingNewName();
|
||||
} else {
|
||||
readLiteralHeaderWithoutIndexingIndexedName(readInt(readByte, 15) - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int readInt(int i, int i2) throws IOException {
|
||||
int i3 = i & i2;
|
||||
if (i3 < i2) {
|
||||
return i3;
|
||||
}
|
||||
int i4 = 0;
|
||||
while (true) {
|
||||
int readByte = readByte();
|
||||
if ((readByte & PeripheralType.SERVO) == 0) {
|
||||
return i2 + (readByte << i4);
|
||||
}
|
||||
i2 += (readByte & Hpack.PREFIX_7_BITS) << i4;
|
||||
i4 += 7;
|
||||
}
|
||||
}
|
||||
|
||||
Reader(int i, int i2, Source source) {
|
||||
this.headerList = new ArrayList();
|
||||
this.dynamicTable = new Header[8];
|
||||
this.nextHeaderIndex = this.dynamicTable.length - 1;
|
||||
this.headerCount = 0;
|
||||
this.dynamicTableByteCount = 0;
|
||||
this.headerTableSizeSetting = i;
|
||||
this.maxDynamicTableByteCount = i2;
|
||||
this.source = Okio.buffer(source);
|
||||
}
|
||||
}
|
||||
|
||||
static final class Writer {
|
||||
private static final int SETTINGS_HEADER_TABLE_SIZE = 4096;
|
||||
private static final int SETTINGS_HEADER_TABLE_SIZE_LIMIT = 16384;
|
||||
Header[] dynamicTable;
|
||||
int dynamicTableByteCount;
|
||||
private boolean emitDynamicTableSizeUpdate;
|
||||
int headerCount;
|
||||
int headerTableSizeSetting;
|
||||
int maxDynamicTableByteCount;
|
||||
int nextHeaderIndex;
|
||||
private final Buffer out;
|
||||
private int smallestHeaderTableSizeSetting;
|
||||
private final boolean useCompression;
|
||||
|
||||
Writer(Buffer buffer) {
|
||||
this(4096, true, buffer);
|
||||
}
|
||||
|
||||
private void adjustDynamicTableByteCount() {
|
||||
int i = this.maxDynamicTableByteCount;
|
||||
int i2 = this.dynamicTableByteCount;
|
||||
if (i < i2) {
|
||||
if (i == 0) {
|
||||
clearDynamicTable();
|
||||
} else {
|
||||
evictToRecoverBytes(i2 - i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void clearDynamicTable() {
|
||||
Arrays.fill(this.dynamicTable, (Object) null);
|
||||
this.nextHeaderIndex = this.dynamicTable.length - 1;
|
||||
this.headerCount = 0;
|
||||
this.dynamicTableByteCount = 0;
|
||||
}
|
||||
|
||||
private int evictToRecoverBytes(int i) {
|
||||
int i2 = 0;
|
||||
if (i > 0) {
|
||||
int length = this.dynamicTable.length;
|
||||
while (true) {
|
||||
length--;
|
||||
if (length < this.nextHeaderIndex || i <= 0) {
|
||||
break;
|
||||
}
|
||||
Header[] headerArr = this.dynamicTable;
|
||||
i -= headerArr[length].hpackSize;
|
||||
this.dynamicTableByteCount -= headerArr[length].hpackSize;
|
||||
this.headerCount--;
|
||||
i2++;
|
||||
}
|
||||
Header[] headerArr2 = this.dynamicTable;
|
||||
int i3 = this.nextHeaderIndex;
|
||||
System.arraycopy(headerArr2, i3 + 1, headerArr2, i3 + 1 + i2, this.headerCount);
|
||||
Header[] headerArr3 = this.dynamicTable;
|
||||
int i4 = this.nextHeaderIndex;
|
||||
Arrays.fill(headerArr3, i4 + 1, i4 + 1 + i2, (Object) null);
|
||||
this.nextHeaderIndex += i2;
|
||||
}
|
||||
return i2;
|
||||
}
|
||||
|
||||
private void insertIntoDynamicTable(Header header) {
|
||||
int i = header.hpackSize;
|
||||
int i2 = this.maxDynamicTableByteCount;
|
||||
if (i > i2) {
|
||||
clearDynamicTable();
|
||||
return;
|
||||
}
|
||||
evictToRecoverBytes((this.dynamicTableByteCount + i) - i2);
|
||||
int i3 = this.headerCount + 1;
|
||||
Header[] headerArr = this.dynamicTable;
|
||||
if (i3 > headerArr.length) {
|
||||
Header[] headerArr2 = new Header[headerArr.length * 2];
|
||||
System.arraycopy(headerArr, 0, headerArr2, headerArr.length, headerArr.length);
|
||||
this.nextHeaderIndex = this.dynamicTable.length - 1;
|
||||
this.dynamicTable = headerArr2;
|
||||
}
|
||||
int i4 = this.nextHeaderIndex;
|
||||
this.nextHeaderIndex = i4 - 1;
|
||||
this.dynamicTable[i4] = header;
|
||||
this.headerCount++;
|
||||
this.dynamicTableByteCount += i;
|
||||
}
|
||||
|
||||
void setHeaderTableSizeSetting(int i) {
|
||||
this.headerTableSizeSetting = i;
|
||||
int min = Math.min(i, SETTINGS_HEADER_TABLE_SIZE_LIMIT);
|
||||
int i2 = this.maxDynamicTableByteCount;
|
||||
if (i2 == min) {
|
||||
return;
|
||||
}
|
||||
if (min < i2) {
|
||||
this.smallestHeaderTableSizeSetting = Math.min(this.smallestHeaderTableSizeSetting, min);
|
||||
}
|
||||
this.emitDynamicTableSizeUpdate = true;
|
||||
this.maxDynamicTableByteCount = min;
|
||||
adjustDynamicTableByteCount();
|
||||
}
|
||||
|
||||
void writeByteString(ByteString byteString) throws IOException {
|
||||
if (!this.useCompression || Huffman.get().encodedLength(byteString) >= byteString.size()) {
|
||||
writeInt(byteString.size(), Hpack.PREFIX_7_BITS, 0);
|
||||
this.out.write(byteString);
|
||||
return;
|
||||
}
|
||||
Buffer buffer = new Buffer();
|
||||
Huffman.get().encode(byteString, buffer);
|
||||
ByteString readByteString = buffer.readByteString();
|
||||
writeInt(readByteString.size(), Hpack.PREFIX_7_BITS, PeripheralType.SERVO);
|
||||
this.out.write(readByteString);
|
||||
}
|
||||
|
||||
void writeHeaders(List<Header> list) throws IOException {
|
||||
int i;
|
||||
int i2;
|
||||
if (this.emitDynamicTableSizeUpdate) {
|
||||
int i3 = this.smallestHeaderTableSizeSetting;
|
||||
if (i3 < this.maxDynamicTableByteCount) {
|
||||
writeInt(i3, 31, 32);
|
||||
}
|
||||
this.emitDynamicTableSizeUpdate = false;
|
||||
this.smallestHeaderTableSizeSetting = Integer.MAX_VALUE;
|
||||
writeInt(this.maxDynamicTableByteCount, 31, 32);
|
||||
}
|
||||
int size = list.size();
|
||||
for (int i4 = 0; i4 < size; i4++) {
|
||||
Header header = list.get(i4);
|
||||
ByteString asciiLowercase = header.name.toAsciiLowercase();
|
||||
ByteString byteString = header.value;
|
||||
Integer num = Hpack.NAME_TO_FIRST_INDEX.get(asciiLowercase);
|
||||
if (num != null) {
|
||||
i = num.intValue() + 1;
|
||||
if (i > 1 && i < 8) {
|
||||
if (Util.equal(Hpack.STATIC_HEADER_TABLE[i - 1].value, byteString)) {
|
||||
i2 = i;
|
||||
} else if (Util.equal(Hpack.STATIC_HEADER_TABLE[i].value, byteString)) {
|
||||
i2 = i;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
i2 = i;
|
||||
i = -1;
|
||||
} else {
|
||||
i = -1;
|
||||
i2 = -1;
|
||||
}
|
||||
if (i == -1) {
|
||||
int i5 = this.nextHeaderIndex + 1;
|
||||
int length = this.dynamicTable.length;
|
||||
while (true) {
|
||||
if (i5 >= length) {
|
||||
break;
|
||||
}
|
||||
if (Util.equal(this.dynamicTable[i5].name, asciiLowercase)) {
|
||||
if (Util.equal(this.dynamicTable[i5].value, byteString)) {
|
||||
i = Hpack.STATIC_HEADER_TABLE.length + (i5 - this.nextHeaderIndex);
|
||||
break;
|
||||
} else if (i2 == -1) {
|
||||
i2 = (i5 - this.nextHeaderIndex) + Hpack.STATIC_HEADER_TABLE.length;
|
||||
}
|
||||
}
|
||||
i5++;
|
||||
}
|
||||
}
|
||||
if (i != -1) {
|
||||
writeInt(i, Hpack.PREFIX_7_BITS, PeripheralType.SERVO);
|
||||
} else if (i2 == -1) {
|
||||
this.out.writeByte(64);
|
||||
writeByteString(asciiLowercase);
|
||||
writeByteString(byteString);
|
||||
insertIntoDynamicTable(header);
|
||||
} else if (!asciiLowercase.startsWith(Header.PSEUDO_PREFIX) || Header.TARGET_AUTHORITY.equals(asciiLowercase)) {
|
||||
writeInt(i2, 63, 64);
|
||||
writeByteString(byteString);
|
||||
insertIntoDynamicTable(header);
|
||||
} else {
|
||||
writeInt(i2, 15, 0);
|
||||
writeByteString(byteString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void writeInt(int i, int i2, int i3) {
|
||||
if (i < i2) {
|
||||
this.out.writeByte(i | i3);
|
||||
return;
|
||||
}
|
||||
this.out.writeByte(i3 | i2);
|
||||
int i4 = i - i2;
|
||||
while (i4 >= 128) {
|
||||
this.out.writeByte(128 | (i4 & Hpack.PREFIX_7_BITS));
|
||||
i4 >>>= 7;
|
||||
}
|
||||
this.out.writeByte(i4);
|
||||
}
|
||||
|
||||
Writer(int i, boolean z, Buffer buffer) {
|
||||
this.smallestHeaderTableSizeSetting = Integer.MAX_VALUE;
|
||||
this.dynamicTable = new Header[8];
|
||||
this.nextHeaderIndex = this.dynamicTable.length - 1;
|
||||
this.headerCount = 0;
|
||||
this.dynamicTableByteCount = 0;
|
||||
this.headerTableSizeSetting = i;
|
||||
this.maxDynamicTableByteCount = i;
|
||||
this.useCompression = z;
|
||||
this.out = buffer;
|
||||
}
|
||||
}
|
||||
|
||||
private Hpack() {
|
||||
}
|
||||
|
||||
static ByteString checkLowercase(ByteString byteString) throws IOException {
|
||||
int size = byteString.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
byte b = byteString.getByte(i);
|
||||
if (b >= 65 && b <= 90) {
|
||||
throw new IOException("PROTOCOL_ERROR response malformed: mixed case name: " + byteString.utf8());
|
||||
}
|
||||
}
|
||||
return byteString;
|
||||
}
|
||||
|
||||
private static Map<ByteString, Integer> nameToFirstIndex() {
|
||||
LinkedHashMap linkedHashMap = new LinkedHashMap(STATIC_HEADER_TABLE.length);
|
||||
int i = 0;
|
||||
while (true) {
|
||||
Header[] headerArr = STATIC_HEADER_TABLE;
|
||||
if (i >= headerArr.length) {
|
||||
return Collections.unmodifiableMap(linkedHashMap);
|
||||
}
|
||||
if (!linkedHashMap.containsKey(headerArr[i].name)) {
|
||||
linkedHashMap.put(STATIC_HEADER_TABLE[i].name, Integer.valueOf(i));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
116
sources/okhttp3/internal/http2/Http2.java
Normal file
116
sources/okhttp3/internal/http2/Http2.java
Normal file
@@ -0,0 +1,116 @@
|
||||
package okhttp3.internal.http2;
|
||||
|
||||
import com.ijm.dataencryption.de.DataDecryptTool;
|
||||
import java.io.IOException;
|
||||
import okhttp3.internal.Util;
|
||||
import okio.ByteString;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
public final class Http2 {
|
||||
static final byte FLAG_ACK = 1;
|
||||
static final byte FLAG_COMPRESSED = 32;
|
||||
static final byte FLAG_END_HEADERS = 4;
|
||||
static final byte FLAG_END_PUSH_PROMISE = 4;
|
||||
static final byte FLAG_END_STREAM = 1;
|
||||
static final byte FLAG_NONE = 0;
|
||||
static final byte FLAG_PADDED = 8;
|
||||
static final byte FLAG_PRIORITY = 32;
|
||||
static final int INITIAL_MAX_FRAME_SIZE = 16384;
|
||||
static final byte TYPE_CONTINUATION = 9;
|
||||
static final byte TYPE_DATA = 0;
|
||||
static final byte TYPE_GOAWAY = 7;
|
||||
static final byte TYPE_HEADERS = 1;
|
||||
static final byte TYPE_PING = 6;
|
||||
static final byte TYPE_PRIORITY = 2;
|
||||
static final byte TYPE_PUSH_PROMISE = 5;
|
||||
static final byte TYPE_RST_STREAM = 3;
|
||||
static final byte TYPE_SETTINGS = 4;
|
||||
static final byte TYPE_WINDOW_UPDATE = 8;
|
||||
static final ByteString CONNECTION_PREFACE = ByteString.encodeUtf8("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n");
|
||||
private static final String[] FRAME_NAMES = {"DATA", "HEADERS", "PRIORITY", "RST_STREAM", "SETTINGS", "PUSH_PROMISE", "PING", "GOAWAY", "WINDOW_UPDATE", "CONTINUATION"};
|
||||
static final String[] FLAGS = new String[64];
|
||||
static final String[] BINARY = new String[DataDecryptTool.DECRYPT_ALL_FILE];
|
||||
|
||||
static {
|
||||
int i = 0;
|
||||
int i2 = 0;
|
||||
while (true) {
|
||||
String[] strArr = BINARY;
|
||||
if (i2 >= strArr.length) {
|
||||
break;
|
||||
}
|
||||
strArr[i2] = Util.format("%8s", Integer.toBinaryString(i2)).replace(' ', '0');
|
||||
i2++;
|
||||
}
|
||||
String[] strArr2 = FLAGS;
|
||||
strArr2[0] = "";
|
||||
strArr2[1] = "END_STREAM";
|
||||
int[] iArr = {1};
|
||||
strArr2[8] = "PADDED";
|
||||
for (int i3 : iArr) {
|
||||
FLAGS[i3 | 8] = FLAGS[i3] + "|PADDED";
|
||||
}
|
||||
String[] strArr3 = FLAGS;
|
||||
strArr3[4] = "END_HEADERS";
|
||||
strArr3[32] = "PRIORITY";
|
||||
strArr3[36] = "END_HEADERS|PRIORITY";
|
||||
for (int i4 : new int[]{4, 32, 36}) {
|
||||
for (int i5 : iArr) {
|
||||
int i6 = i5 | i4;
|
||||
FLAGS[i6] = FLAGS[i5] + '|' + FLAGS[i4];
|
||||
FLAGS[i6 | 8] = FLAGS[i5] + '|' + FLAGS[i4] + "|PADDED";
|
||||
}
|
||||
}
|
||||
while (true) {
|
||||
String[] strArr4 = FLAGS;
|
||||
if (i >= strArr4.length) {
|
||||
return;
|
||||
}
|
||||
if (strArr4[i] == null) {
|
||||
strArr4[i] = BINARY[i];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private Http2() {
|
||||
}
|
||||
|
||||
static String formatFlags(byte b, byte b2) {
|
||||
if (b2 == 0) {
|
||||
return "";
|
||||
}
|
||||
if (b != 2 && b != 3) {
|
||||
if (b == 4 || b == 6) {
|
||||
return b2 == 1 ? "ACK" : BINARY[b2];
|
||||
}
|
||||
if (b != 7 && b != 8) {
|
||||
String[] strArr = FLAGS;
|
||||
String str = b2 < strArr.length ? strArr[b2] : BINARY[b2];
|
||||
return (b != 5 || (b2 & 4) == 0) ? (b != 0 || (b2 & 32) == 0) ? str : str.replace("PRIORITY", "COMPRESSED") : str.replace("HEADERS", "PUSH_PROMISE");
|
||||
}
|
||||
}
|
||||
return BINARY[b2];
|
||||
}
|
||||
|
||||
static String frameLog(boolean z, int i, int i2, byte b, byte b2) {
|
||||
String[] strArr = FRAME_NAMES;
|
||||
String format = b < strArr.length ? strArr[b] : Util.format("0x%02x", Byte.valueOf(b));
|
||||
String formatFlags = formatFlags(b, b2);
|
||||
Object[] objArr = new Object[5];
|
||||
objArr[0] = z ? "<<" : ">>";
|
||||
objArr[1] = Integer.valueOf(i);
|
||||
objArr[2] = Integer.valueOf(i2);
|
||||
objArr[3] = format;
|
||||
objArr[4] = formatFlags;
|
||||
return Util.format("%s 0x%08x %5d %-13s %s", objArr);
|
||||
}
|
||||
|
||||
static IllegalArgumentException illegalArgument(String str, Object... objArr) {
|
||||
throw new IllegalArgumentException(Util.format(str, objArr));
|
||||
}
|
||||
|
||||
static IOException ioException(String str, Object... objArr) throws IOException {
|
||||
throw new IOException(Util.format(str, objArr));
|
||||
}
|
||||
}
|
190
sources/okhttp3/internal/http2/Http2Codec.java
Normal file
190
sources/okhttp3/internal/http2/Http2Codec.java
Normal file
@@ -0,0 +1,190 @@
|
||||
package okhttp3.internal.http2;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ProtocolException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import okhttp3.Headers;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Protocol;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.ResponseBody;
|
||||
import okhttp3.internal.Internal;
|
||||
import okhttp3.internal.Util;
|
||||
import okhttp3.internal.connection.StreamAllocation;
|
||||
import okhttp3.internal.http.HttpCodec;
|
||||
import okhttp3.internal.http.HttpHeaders;
|
||||
import okhttp3.internal.http.RealResponseBody;
|
||||
import okhttp3.internal.http.RequestLine;
|
||||
import okhttp3.internal.http.StatusLine;
|
||||
import okio.Buffer;
|
||||
import okio.ByteString;
|
||||
import okio.ForwardingSource;
|
||||
import okio.Okio;
|
||||
import okio.Sink;
|
||||
import okio.Source;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
public final class Http2Codec implements HttpCodec {
|
||||
private final Interceptor.Chain chain;
|
||||
private final Http2Connection connection;
|
||||
private final Protocol protocol;
|
||||
private Http2Stream stream;
|
||||
final StreamAllocation streamAllocation;
|
||||
private static final ByteString CONNECTION = ByteString.encodeUtf8("connection");
|
||||
private static final ByteString HOST = ByteString.encodeUtf8("host");
|
||||
private static final ByteString KEEP_ALIVE = ByteString.encodeUtf8("keep-alive");
|
||||
private static final ByteString PROXY_CONNECTION = ByteString.encodeUtf8("proxy-connection");
|
||||
private static final ByteString TRANSFER_ENCODING = ByteString.encodeUtf8("transfer-encoding");
|
||||
private static final ByteString TE = ByteString.encodeUtf8("te");
|
||||
private static final ByteString ENCODING = ByteString.encodeUtf8("encoding");
|
||||
private static final ByteString UPGRADE = ByteString.encodeUtf8("upgrade");
|
||||
private static final List<ByteString> HTTP_2_SKIPPED_REQUEST_HEADERS = Util.immutableList(CONNECTION, HOST, KEEP_ALIVE, PROXY_CONNECTION, TE, TRANSFER_ENCODING, ENCODING, UPGRADE, Header.TARGET_METHOD, Header.TARGET_PATH, Header.TARGET_SCHEME, Header.TARGET_AUTHORITY);
|
||||
private static final List<ByteString> HTTP_2_SKIPPED_RESPONSE_HEADERS = Util.immutableList(CONNECTION, HOST, KEEP_ALIVE, PROXY_CONNECTION, TE, TRANSFER_ENCODING, ENCODING, UPGRADE);
|
||||
|
||||
class StreamFinishingSource extends ForwardingSource {
|
||||
long bytesRead;
|
||||
boolean completed;
|
||||
|
||||
StreamFinishingSource(Source source) {
|
||||
super(source);
|
||||
this.completed = false;
|
||||
this.bytesRead = 0L;
|
||||
}
|
||||
|
||||
private void endOfInput(IOException iOException) {
|
||||
if (this.completed) {
|
||||
return;
|
||||
}
|
||||
this.completed = true;
|
||||
Http2Codec http2Codec = Http2Codec.this;
|
||||
http2Codec.streamAllocation.streamFinished(false, http2Codec, this.bytesRead, iOException);
|
||||
}
|
||||
|
||||
@Override // okio.ForwardingSource, okio.Source, java.io.Closeable, java.lang.AutoCloseable
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
endOfInput(null);
|
||||
}
|
||||
|
||||
@Override // okio.ForwardingSource, okio.Source
|
||||
public long read(Buffer buffer, long j) throws IOException {
|
||||
try {
|
||||
long read = delegate().read(buffer, j);
|
||||
if (read > 0) {
|
||||
this.bytesRead += read;
|
||||
}
|
||||
return read;
|
||||
} catch (IOException e) {
|
||||
endOfInput(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Http2Codec(OkHttpClient okHttpClient, Interceptor.Chain chain, StreamAllocation streamAllocation, Http2Connection http2Connection) {
|
||||
this.chain = chain;
|
||||
this.streamAllocation = streamAllocation;
|
||||
this.connection = http2Connection;
|
||||
this.protocol = okHttpClient.protocols().contains(Protocol.H2_PRIOR_KNOWLEDGE) ? Protocol.H2_PRIOR_KNOWLEDGE : Protocol.HTTP_2;
|
||||
}
|
||||
|
||||
public static List<Header> http2HeadersList(Request request) {
|
||||
Headers headers = request.headers();
|
||||
ArrayList arrayList = new ArrayList(headers.size() + 4);
|
||||
arrayList.add(new Header(Header.TARGET_METHOD, request.method()));
|
||||
arrayList.add(new Header(Header.TARGET_PATH, RequestLine.requestPath(request.url())));
|
||||
String header = request.header("Host");
|
||||
if (header != null) {
|
||||
arrayList.add(new Header(Header.TARGET_AUTHORITY, header));
|
||||
}
|
||||
arrayList.add(new Header(Header.TARGET_SCHEME, request.url().scheme()));
|
||||
int size = headers.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
ByteString encodeUtf8 = ByteString.encodeUtf8(headers.name(i).toLowerCase(Locale.US));
|
||||
if (!HTTP_2_SKIPPED_REQUEST_HEADERS.contains(encodeUtf8)) {
|
||||
arrayList.add(new Header(encodeUtf8, headers.value(i)));
|
||||
}
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
public static Response.Builder readHttp2HeadersList(List<Header> list, Protocol protocol) throws IOException {
|
||||
Headers.Builder builder = new Headers.Builder();
|
||||
int size = list.size();
|
||||
Headers.Builder builder2 = builder;
|
||||
StatusLine statusLine = null;
|
||||
for (int i = 0; i < size; i++) {
|
||||
Header header = list.get(i);
|
||||
if (header != null) {
|
||||
ByteString byteString = header.name;
|
||||
String utf8 = header.value.utf8();
|
||||
if (byteString.equals(Header.RESPONSE_STATUS)) {
|
||||
statusLine = StatusLine.parse("HTTP/1.1 " + utf8);
|
||||
} else if (!HTTP_2_SKIPPED_RESPONSE_HEADERS.contains(byteString)) {
|
||||
Internal.instance.addLenient(builder2, byteString.utf8(), utf8);
|
||||
}
|
||||
} else if (statusLine != null && statusLine.code == 100) {
|
||||
builder2 = new Headers.Builder();
|
||||
statusLine = null;
|
||||
}
|
||||
}
|
||||
if (statusLine != null) {
|
||||
return new Response.Builder().protocol(protocol).code(statusLine.code).message(statusLine.message).headers(builder2.build());
|
||||
}
|
||||
throw new ProtocolException("Expected ':status' header not present");
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http.HttpCodec
|
||||
public void cancel() {
|
||||
Http2Stream http2Stream = this.stream;
|
||||
if (http2Stream != null) {
|
||||
http2Stream.closeLater(ErrorCode.CANCEL);
|
||||
}
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http.HttpCodec
|
||||
public Sink createRequestBody(Request request, long j) {
|
||||
return this.stream.getSink();
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http.HttpCodec
|
||||
public void finishRequest() throws IOException {
|
||||
this.stream.getSink().close();
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http.HttpCodec
|
||||
public void flushRequest() throws IOException {
|
||||
this.connection.flush();
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http.HttpCodec
|
||||
public ResponseBody openResponseBody(Response response) throws IOException {
|
||||
StreamAllocation streamAllocation = this.streamAllocation;
|
||||
streamAllocation.eventListener.responseBodyStart(streamAllocation.call);
|
||||
return new RealResponseBody(response.header("Content-Type"), HttpHeaders.contentLength(response), Okio.buffer(new StreamFinishingSource(this.stream.getSource())));
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http.HttpCodec
|
||||
public Response.Builder readResponseHeaders(boolean z) throws IOException {
|
||||
Response.Builder readHttp2HeadersList = readHttp2HeadersList(this.stream.takeResponseHeaders(), this.protocol);
|
||||
if (z && Internal.instance.code(readHttp2HeadersList) == 100) {
|
||||
return null;
|
||||
}
|
||||
return readHttp2HeadersList;
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http.HttpCodec
|
||||
public void writeRequestHeaders(Request request) throws IOException {
|
||||
if (this.stream != null) {
|
||||
return;
|
||||
}
|
||||
this.stream = this.connection.newStream(http2HeadersList(request), request.body() != null);
|
||||
this.stream.readTimeout().timeout(this.chain.readTimeoutMillis(), TimeUnit.MILLISECONDS);
|
||||
this.stream.writeTimeout().timeout(this.chain.writeTimeoutMillis(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
853
sources/okhttp3/internal/http2/Http2Connection.java
Normal file
853
sources/okhttp3/internal/http2/Http2Connection.java
Normal file
@@ -0,0 +1,853 @@
|
||||
package okhttp3.internal.http2;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import okhttp3.Protocol;
|
||||
import okhttp3.internal.NamedRunnable;
|
||||
import okhttp3.internal.Util;
|
||||
import okhttp3.internal.http2.Http2Reader;
|
||||
import okhttp3.internal.platform.Platform;
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSink;
|
||||
import okio.BufferedSource;
|
||||
import okio.ByteString;
|
||||
import okio.Okio;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
public final class Http2Connection implements Closeable {
|
||||
static final /* synthetic */ boolean $assertionsDisabled = false;
|
||||
static final int OKHTTP_CLIENT_WINDOW_SIZE = 16777216;
|
||||
private static final ExecutorService listenerExecutor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue(), Util.threadFactory("OkHttp Http2Connection", true));
|
||||
private boolean awaitingPong;
|
||||
long bytesLeftInWriteWindow;
|
||||
final boolean client;
|
||||
final String hostname;
|
||||
int lastGoodStreamId;
|
||||
final Listener listener;
|
||||
int nextStreamId;
|
||||
private final ExecutorService pushExecutor;
|
||||
final PushObserver pushObserver;
|
||||
final ReaderRunnable readerRunnable;
|
||||
boolean shutdown;
|
||||
final Socket socket;
|
||||
final Http2Writer writer;
|
||||
private final ScheduledExecutorService writerExecutor;
|
||||
final Map<Integer, Http2Stream> streams = new LinkedHashMap();
|
||||
long unacknowledgedBytesRead = 0;
|
||||
Settings okHttpSettings = new Settings();
|
||||
final Settings peerSettings = new Settings();
|
||||
boolean receivedInitialPeerSettings = false;
|
||||
final Set<Integer> currentPushRequests = new LinkedHashSet();
|
||||
|
||||
public static abstract class Listener {
|
||||
public static final Listener REFUSE_INCOMING_STREAMS = new Listener() { // from class: okhttp3.internal.http2.Http2Connection.Listener.1
|
||||
@Override // okhttp3.internal.http2.Http2Connection.Listener
|
||||
public void onStream(Http2Stream http2Stream) throws IOException {
|
||||
http2Stream.close(ErrorCode.REFUSED_STREAM);
|
||||
}
|
||||
};
|
||||
|
||||
public void onSettings(Http2Connection http2Connection) {
|
||||
}
|
||||
|
||||
public abstract void onStream(Http2Stream http2Stream) throws IOException;
|
||||
}
|
||||
|
||||
final class PingRunnable extends NamedRunnable {
|
||||
final int payload1;
|
||||
final int payload2;
|
||||
final boolean reply;
|
||||
|
||||
PingRunnable(boolean z, int i, int i2) {
|
||||
super("OkHttp %s ping %08x%08x", Http2Connection.this.hostname, Integer.valueOf(i), Integer.valueOf(i2));
|
||||
this.reply = z;
|
||||
this.payload1 = i;
|
||||
this.payload2 = i2;
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.NamedRunnable
|
||||
public void execute() {
|
||||
Http2Connection.this.writePing(this.reply, this.payload1, this.payload2);
|
||||
}
|
||||
}
|
||||
|
||||
class ReaderRunnable extends NamedRunnable implements Http2Reader.Handler {
|
||||
final Http2Reader reader;
|
||||
|
||||
ReaderRunnable(Http2Reader http2Reader) {
|
||||
super("OkHttp %s", Http2Connection.this.hostname);
|
||||
this.reader = http2Reader;
|
||||
}
|
||||
|
||||
private void applyAndAckSettings(final Settings settings) {
|
||||
try {
|
||||
Http2Connection.this.writerExecutor.execute(new NamedRunnable("OkHttp %s ACK Settings", new Object[]{Http2Connection.this.hostname}) { // from class: okhttp3.internal.http2.Http2Connection.ReaderRunnable.3
|
||||
@Override // okhttp3.internal.NamedRunnable
|
||||
public void execute() {
|
||||
try {
|
||||
Http2Connection.this.writer.applyAndAckSettings(settings);
|
||||
} catch (IOException unused) {
|
||||
Http2Connection.this.failConnection();
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (RejectedExecutionException unused) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http2.Http2Reader.Handler
|
||||
public void ackSettings() {
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http2.Http2Reader.Handler
|
||||
public void alternateService(int i, String str, ByteString byteString, String str2, int i2, long j) {
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http2.Http2Reader.Handler
|
||||
public void data(boolean z, int i, BufferedSource bufferedSource, int i2) throws IOException {
|
||||
if (Http2Connection.this.pushedStream(i)) {
|
||||
Http2Connection.this.pushDataLater(i, bufferedSource, i2, z);
|
||||
return;
|
||||
}
|
||||
Http2Stream stream = Http2Connection.this.getStream(i);
|
||||
if (stream == null) {
|
||||
Http2Connection.this.writeSynResetLater(i, ErrorCode.PROTOCOL_ERROR);
|
||||
long j = i2;
|
||||
Http2Connection.this.updateConnectionFlowControl(j);
|
||||
bufferedSource.skip(j);
|
||||
return;
|
||||
}
|
||||
stream.receiveData(bufferedSource, i2);
|
||||
if (z) {
|
||||
stream.receiveFin();
|
||||
}
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.NamedRunnable
|
||||
protected void execute() {
|
||||
ErrorCode errorCode;
|
||||
Http2Connection http2Connection;
|
||||
ErrorCode errorCode2 = ErrorCode.INTERNAL_ERROR;
|
||||
try {
|
||||
try {
|
||||
try {
|
||||
this.reader.readConnectionPreface(this);
|
||||
while (this.reader.nextFrame(false, this)) {
|
||||
}
|
||||
errorCode = ErrorCode.NO_ERROR;
|
||||
} catch (IOException unused) {
|
||||
} catch (Throwable th) {
|
||||
th = th;
|
||||
errorCode = errorCode2;
|
||||
try {
|
||||
Http2Connection.this.close(errorCode, errorCode2);
|
||||
} catch (IOException unused2) {
|
||||
}
|
||||
Util.closeQuietly(this.reader);
|
||||
throw th;
|
||||
}
|
||||
try {
|
||||
errorCode2 = ErrorCode.CANCEL;
|
||||
http2Connection = Http2Connection.this;
|
||||
} catch (IOException unused3) {
|
||||
errorCode = ErrorCode.PROTOCOL_ERROR;
|
||||
errorCode2 = ErrorCode.PROTOCOL_ERROR;
|
||||
http2Connection = Http2Connection.this;
|
||||
http2Connection.close(errorCode, errorCode2);
|
||||
Util.closeQuietly(this.reader);
|
||||
}
|
||||
http2Connection.close(errorCode, errorCode2);
|
||||
} catch (IOException unused4) {
|
||||
}
|
||||
Util.closeQuietly(this.reader);
|
||||
} catch (Throwable th2) {
|
||||
th = th2;
|
||||
}
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http2.Http2Reader.Handler
|
||||
public void goAway(int i, ErrorCode errorCode, ByteString byteString) {
|
||||
Http2Stream[] http2StreamArr;
|
||||
byteString.size();
|
||||
synchronized (Http2Connection.this) {
|
||||
http2StreamArr = (Http2Stream[]) Http2Connection.this.streams.values().toArray(new Http2Stream[Http2Connection.this.streams.size()]);
|
||||
Http2Connection.this.shutdown = true;
|
||||
}
|
||||
for (Http2Stream http2Stream : http2StreamArr) {
|
||||
if (http2Stream.getId() > i && http2Stream.isLocallyInitiated()) {
|
||||
http2Stream.receiveRstStream(ErrorCode.REFUSED_STREAM);
|
||||
Http2Connection.this.removeStream(http2Stream.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http2.Http2Reader.Handler
|
||||
public void headers(boolean z, int i, int i2, List<Header> list) {
|
||||
if (Http2Connection.this.pushedStream(i)) {
|
||||
Http2Connection.this.pushHeadersLater(i, list, z);
|
||||
return;
|
||||
}
|
||||
synchronized (Http2Connection.this) {
|
||||
Http2Stream stream = Http2Connection.this.getStream(i);
|
||||
if (stream != null) {
|
||||
stream.receiveHeaders(list);
|
||||
if (z) {
|
||||
stream.receiveFin();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (Http2Connection.this.shutdown) {
|
||||
return;
|
||||
}
|
||||
if (i <= Http2Connection.this.lastGoodStreamId) {
|
||||
return;
|
||||
}
|
||||
if (i % 2 == Http2Connection.this.nextStreamId % 2) {
|
||||
return;
|
||||
}
|
||||
final Http2Stream http2Stream = new Http2Stream(i, Http2Connection.this, false, z, list);
|
||||
Http2Connection.this.lastGoodStreamId = i;
|
||||
Http2Connection.this.streams.put(Integer.valueOf(i), http2Stream);
|
||||
Http2Connection.listenerExecutor.execute(new NamedRunnable("OkHttp %s stream %d", new Object[]{Http2Connection.this.hostname, Integer.valueOf(i)}) { // from class: okhttp3.internal.http2.Http2Connection.ReaderRunnable.1
|
||||
@Override // okhttp3.internal.NamedRunnable
|
||||
public void execute() {
|
||||
try {
|
||||
Http2Connection.this.listener.onStream(http2Stream);
|
||||
} catch (IOException e) {
|
||||
Platform.get().log(4, "Http2Connection.Listener failure for " + Http2Connection.this.hostname, e);
|
||||
try {
|
||||
http2Stream.close(ErrorCode.PROTOCOL_ERROR);
|
||||
} catch (IOException unused) {
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http2.Http2Reader.Handler
|
||||
public void ping(boolean z, int i, int i2) {
|
||||
if (!z) {
|
||||
try {
|
||||
Http2Connection.this.writerExecutor.execute(Http2Connection.this.new PingRunnable(true, i, i2));
|
||||
} catch (RejectedExecutionException unused) {
|
||||
}
|
||||
} else {
|
||||
synchronized (Http2Connection.this) {
|
||||
Http2Connection.this.awaitingPong = false;
|
||||
Http2Connection.this.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http2.Http2Reader.Handler
|
||||
public void priority(int i, int i2, int i3, boolean z) {
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http2.Http2Reader.Handler
|
||||
public void pushPromise(int i, int i2, List<Header> list) {
|
||||
Http2Connection.this.pushRequestLater(i2, list);
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http2.Http2Reader.Handler
|
||||
public void rstStream(int i, ErrorCode errorCode) {
|
||||
if (Http2Connection.this.pushedStream(i)) {
|
||||
Http2Connection.this.pushResetLater(i, errorCode);
|
||||
return;
|
||||
}
|
||||
Http2Stream removeStream = Http2Connection.this.removeStream(i);
|
||||
if (removeStream != null) {
|
||||
removeStream.receiveRstStream(errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http2.Http2Reader.Handler
|
||||
public void settings(boolean z, Settings settings) {
|
||||
Http2Stream[] http2StreamArr;
|
||||
long j;
|
||||
int i;
|
||||
synchronized (Http2Connection.this) {
|
||||
int initialWindowSize = Http2Connection.this.peerSettings.getInitialWindowSize();
|
||||
if (z) {
|
||||
Http2Connection.this.peerSettings.clear();
|
||||
}
|
||||
Http2Connection.this.peerSettings.merge(settings);
|
||||
applyAndAckSettings(settings);
|
||||
int initialWindowSize2 = Http2Connection.this.peerSettings.getInitialWindowSize();
|
||||
http2StreamArr = null;
|
||||
if (initialWindowSize2 == -1 || initialWindowSize2 == initialWindowSize) {
|
||||
j = 0;
|
||||
} else {
|
||||
j = initialWindowSize2 - initialWindowSize;
|
||||
if (!Http2Connection.this.receivedInitialPeerSettings) {
|
||||
Http2Connection.this.receivedInitialPeerSettings = true;
|
||||
}
|
||||
if (!Http2Connection.this.streams.isEmpty()) {
|
||||
http2StreamArr = (Http2Stream[]) Http2Connection.this.streams.values().toArray(new Http2Stream[Http2Connection.this.streams.size()]);
|
||||
}
|
||||
}
|
||||
Http2Connection.listenerExecutor.execute(new NamedRunnable("OkHttp %s settings", Http2Connection.this.hostname) { // from class: okhttp3.internal.http2.Http2Connection.ReaderRunnable.2
|
||||
@Override // okhttp3.internal.NamedRunnable
|
||||
public void execute() {
|
||||
Http2Connection http2Connection = Http2Connection.this;
|
||||
http2Connection.listener.onSettings(http2Connection);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (http2StreamArr == null || j == 0) {
|
||||
return;
|
||||
}
|
||||
for (Http2Stream http2Stream : http2StreamArr) {
|
||||
synchronized (http2Stream) {
|
||||
http2Stream.addBytesToWriteWindow(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http2.Http2Reader.Handler
|
||||
public void windowUpdate(int i, long j) {
|
||||
if (i == 0) {
|
||||
synchronized (Http2Connection.this) {
|
||||
Http2Connection.this.bytesLeftInWriteWindow += j;
|
||||
Http2Connection.this.notifyAll();
|
||||
}
|
||||
return;
|
||||
}
|
||||
Http2Stream stream = Http2Connection.this.getStream(i);
|
||||
if (stream != null) {
|
||||
synchronized (stream) {
|
||||
stream.addBytesToWriteWindow(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Http2Connection(Builder builder) {
|
||||
this.pushObserver = builder.pushObserver;
|
||||
boolean z = builder.client;
|
||||
this.client = z;
|
||||
this.listener = builder.listener;
|
||||
this.nextStreamId = z ? 1 : 2;
|
||||
if (builder.client) {
|
||||
this.nextStreamId += 2;
|
||||
}
|
||||
if (builder.client) {
|
||||
this.okHttpSettings.set(7, OKHTTP_CLIENT_WINDOW_SIZE);
|
||||
}
|
||||
this.hostname = builder.hostname;
|
||||
this.writerExecutor = new ScheduledThreadPoolExecutor(1, Util.threadFactory(Util.format("OkHttp %s Writer", this.hostname), false));
|
||||
if (builder.pingIntervalMillis != 0) {
|
||||
ScheduledExecutorService scheduledExecutorService = this.writerExecutor;
|
||||
PingRunnable pingRunnable = new PingRunnable(false, 0, 0);
|
||||
int i = builder.pingIntervalMillis;
|
||||
scheduledExecutorService.scheduleAtFixedRate(pingRunnable, i, i, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
this.pushExecutor = new ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue(), Util.threadFactory(Util.format("OkHttp %s Push Observer", this.hostname), true));
|
||||
this.peerSettings.set(7, 65535);
|
||||
this.peerSettings.set(5, 16384);
|
||||
this.bytesLeftInWriteWindow = this.peerSettings.getInitialWindowSize();
|
||||
this.socket = builder.socket;
|
||||
this.writer = new Http2Writer(builder.sink, this.client);
|
||||
this.readerRunnable = new ReaderRunnable(new Http2Reader(builder.source, this.client));
|
||||
}
|
||||
|
||||
/* JADX INFO: Access modifiers changed from: private */
|
||||
public void failConnection() {
|
||||
try {
|
||||
close(ErrorCode.PROTOCOL_ERROR, ErrorCode.PROTOCOL_ERROR);
|
||||
} catch (IOException unused) {
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void pushExecutorExecute(NamedRunnable namedRunnable) {
|
||||
if (!isShutdown()) {
|
||||
this.pushExecutor.execute(namedRunnable);
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void awaitPong() throws InterruptedException {
|
||||
while (this.awaitingPong) {
|
||||
wait();
|
||||
}
|
||||
}
|
||||
|
||||
@Override // java.io.Closeable, java.lang.AutoCloseable
|
||||
public void close() throws IOException {
|
||||
close(ErrorCode.NO_ERROR, ErrorCode.CANCEL);
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
this.writer.flush();
|
||||
}
|
||||
|
||||
public Protocol getProtocol() {
|
||||
return Protocol.HTTP_2;
|
||||
}
|
||||
|
||||
synchronized Http2Stream getStream(int i) {
|
||||
return this.streams.get(Integer.valueOf(i));
|
||||
}
|
||||
|
||||
public synchronized boolean isShutdown() {
|
||||
return this.shutdown;
|
||||
}
|
||||
|
||||
public synchronized int maxConcurrentStreams() {
|
||||
return this.peerSettings.getMaxConcurrentStreams(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public Http2Stream newStream(List<Header> list, boolean z) throws IOException {
|
||||
return newStream(0, list, z);
|
||||
}
|
||||
|
||||
public synchronized int openStreamCount() {
|
||||
return this.streams.size();
|
||||
}
|
||||
|
||||
void pushDataLater(final int i, BufferedSource bufferedSource, final int i2, final boolean z) throws IOException {
|
||||
final Buffer buffer = new Buffer();
|
||||
long j = i2;
|
||||
bufferedSource.require(j);
|
||||
bufferedSource.read(buffer, j);
|
||||
if (buffer.size() == j) {
|
||||
pushExecutorExecute(new NamedRunnable("OkHttp %s Push Data[%s]", new Object[]{this.hostname, Integer.valueOf(i)}) { // from class: okhttp3.internal.http2.Http2Connection.5
|
||||
@Override // okhttp3.internal.NamedRunnable
|
||||
public void execute() {
|
||||
try {
|
||||
boolean onData = Http2Connection.this.pushObserver.onData(i, buffer, i2, z);
|
||||
if (onData) {
|
||||
Http2Connection.this.writer.rstStream(i, ErrorCode.CANCEL);
|
||||
}
|
||||
if (onData || z) {
|
||||
synchronized (Http2Connection.this) {
|
||||
Http2Connection.this.currentPushRequests.remove(Integer.valueOf(i));
|
||||
}
|
||||
}
|
||||
} catch (IOException unused) {
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
throw new IOException(buffer.size() + " != " + i2);
|
||||
}
|
||||
|
||||
void pushHeadersLater(final int i, final List<Header> list, final boolean z) {
|
||||
try {
|
||||
pushExecutorExecute(new NamedRunnable("OkHttp %s Push Headers[%s]", new Object[]{this.hostname, Integer.valueOf(i)}) { // from class: okhttp3.internal.http2.Http2Connection.4
|
||||
@Override // okhttp3.internal.NamedRunnable
|
||||
public void execute() {
|
||||
boolean onHeaders = Http2Connection.this.pushObserver.onHeaders(i, list, z);
|
||||
if (onHeaders) {
|
||||
try {
|
||||
Http2Connection.this.writer.rstStream(i, ErrorCode.CANCEL);
|
||||
} catch (IOException unused) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (onHeaders || z) {
|
||||
synchronized (Http2Connection.this) {
|
||||
Http2Connection.this.currentPushRequests.remove(Integer.valueOf(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (RejectedExecutionException unused) {
|
||||
}
|
||||
}
|
||||
|
||||
void pushRequestLater(final int i, final List<Header> list) {
|
||||
synchronized (this) {
|
||||
if (this.currentPushRequests.contains(Integer.valueOf(i))) {
|
||||
writeSynResetLater(i, ErrorCode.PROTOCOL_ERROR);
|
||||
return;
|
||||
}
|
||||
this.currentPushRequests.add(Integer.valueOf(i));
|
||||
try {
|
||||
pushExecutorExecute(new NamedRunnable("OkHttp %s Push Request[%s]", new Object[]{this.hostname, Integer.valueOf(i)}) { // from class: okhttp3.internal.http2.Http2Connection.3
|
||||
@Override // okhttp3.internal.NamedRunnable
|
||||
public void execute() {
|
||||
if (Http2Connection.this.pushObserver.onRequest(i, list)) {
|
||||
try {
|
||||
Http2Connection.this.writer.rstStream(i, ErrorCode.CANCEL);
|
||||
synchronized (Http2Connection.this) {
|
||||
Http2Connection.this.currentPushRequests.remove(Integer.valueOf(i));
|
||||
}
|
||||
} catch (IOException unused) {
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (RejectedExecutionException unused) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pushResetLater(final int i, final ErrorCode errorCode) {
|
||||
pushExecutorExecute(new NamedRunnable("OkHttp %s Push Reset[%s]", new Object[]{this.hostname, Integer.valueOf(i)}) { // from class: okhttp3.internal.http2.Http2Connection.6
|
||||
@Override // okhttp3.internal.NamedRunnable
|
||||
public void execute() {
|
||||
Http2Connection.this.pushObserver.onReset(i, errorCode);
|
||||
synchronized (Http2Connection.this) {
|
||||
Http2Connection.this.currentPushRequests.remove(Integer.valueOf(i));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Http2Stream pushStream(int i, List<Header> list, boolean z) throws IOException {
|
||||
if (this.client) {
|
||||
throw new IllegalStateException("Client cannot push requests.");
|
||||
}
|
||||
return newStream(i, list, z);
|
||||
}
|
||||
|
||||
boolean pushedStream(int i) {
|
||||
return i != 0 && (i & 1) == 0;
|
||||
}
|
||||
|
||||
synchronized Http2Stream removeStream(int i) {
|
||||
Http2Stream remove;
|
||||
remove = this.streams.remove(Integer.valueOf(i));
|
||||
notifyAll();
|
||||
return remove;
|
||||
}
|
||||
|
||||
public void setSettings(Settings settings) throws IOException {
|
||||
synchronized (this.writer) {
|
||||
synchronized (this) {
|
||||
if (this.shutdown) {
|
||||
throw new ConnectionShutdownException();
|
||||
}
|
||||
this.okHttpSettings.merge(settings);
|
||||
}
|
||||
this.writer.settings(settings);
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown(ErrorCode errorCode) throws IOException {
|
||||
synchronized (this.writer) {
|
||||
synchronized (this) {
|
||||
if (this.shutdown) {
|
||||
return;
|
||||
}
|
||||
this.shutdown = true;
|
||||
this.writer.goAway(this.lastGoodStreamId, errorCode, Util.EMPTY_BYTE_ARRAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void start() throws IOException {
|
||||
start(true);
|
||||
}
|
||||
|
||||
synchronized void updateConnectionFlowControl(long j) {
|
||||
this.unacknowledgedBytesRead += j;
|
||||
if (this.unacknowledgedBytesRead >= this.okHttpSettings.getInitialWindowSize() / 2) {
|
||||
writeWindowUpdateLater(0, this.unacknowledgedBytesRead);
|
||||
this.unacknowledgedBytesRead = 0L;
|
||||
}
|
||||
}
|
||||
|
||||
public void writeData(int i, boolean z, Buffer buffer, long j) throws IOException {
|
||||
int min;
|
||||
long j2;
|
||||
if (j == 0) {
|
||||
this.writer.data(z, i, buffer, 0);
|
||||
return;
|
||||
}
|
||||
while (j > 0) {
|
||||
synchronized (this) {
|
||||
while (this.bytesLeftInWriteWindow <= 0) {
|
||||
try {
|
||||
if (!this.streams.containsKey(Integer.valueOf(i))) {
|
||||
throw new IOException("stream closed");
|
||||
}
|
||||
wait();
|
||||
} catch (InterruptedException unused) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new InterruptedIOException();
|
||||
}
|
||||
}
|
||||
min = Math.min((int) Math.min(j, this.bytesLeftInWriteWindow), this.writer.maxDataLength());
|
||||
j2 = min;
|
||||
this.bytesLeftInWriteWindow -= j2;
|
||||
}
|
||||
j -= j2;
|
||||
this.writer.data(z && j == 0, i, buffer, min);
|
||||
}
|
||||
}
|
||||
|
||||
void writePing(boolean z, int i, int i2) {
|
||||
boolean z2;
|
||||
if (!z) {
|
||||
synchronized (this) {
|
||||
z2 = this.awaitingPong;
|
||||
this.awaitingPong = true;
|
||||
}
|
||||
if (z2) {
|
||||
failConnection();
|
||||
return;
|
||||
}
|
||||
}
|
||||
try {
|
||||
this.writer.ping(z, i, i2);
|
||||
} catch (IOException unused) {
|
||||
failConnection();
|
||||
}
|
||||
}
|
||||
|
||||
void writePingAndAwaitPong() throws InterruptedException {
|
||||
writePing(false, 1330343787, -257978967);
|
||||
awaitPong();
|
||||
}
|
||||
|
||||
void writeSynReply(int i, boolean z, List<Header> list) throws IOException {
|
||||
this.writer.synReply(z, i, list);
|
||||
}
|
||||
|
||||
void writeSynReset(int i, ErrorCode errorCode) throws IOException {
|
||||
this.writer.rstStream(i, errorCode);
|
||||
}
|
||||
|
||||
void writeSynResetLater(final int i, final ErrorCode errorCode) {
|
||||
try {
|
||||
this.writerExecutor.execute(new NamedRunnable("OkHttp %s stream %d", new Object[]{this.hostname, Integer.valueOf(i)}) { // from class: okhttp3.internal.http2.Http2Connection.1
|
||||
@Override // okhttp3.internal.NamedRunnable
|
||||
public void execute() {
|
||||
try {
|
||||
Http2Connection.this.writeSynReset(i, errorCode);
|
||||
} catch (IOException unused) {
|
||||
Http2Connection.this.failConnection();
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (RejectedExecutionException unused) {
|
||||
}
|
||||
}
|
||||
|
||||
void writeWindowUpdateLater(final int i, final long j) {
|
||||
try {
|
||||
this.writerExecutor.execute(new NamedRunnable("OkHttp Window Update %s stream %d", new Object[]{this.hostname, Integer.valueOf(i)}) { // from class: okhttp3.internal.http2.Http2Connection.2
|
||||
@Override // okhttp3.internal.NamedRunnable
|
||||
public void execute() {
|
||||
try {
|
||||
Http2Connection.this.writer.windowUpdate(i, j);
|
||||
} catch (IOException unused) {
|
||||
Http2Connection.this.failConnection();
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (RejectedExecutionException unused) {
|
||||
}
|
||||
}
|
||||
|
||||
/* JADX WARN: Removed duplicated region for block: B:21:0x0043 A[Catch: all -> 0x0075, TryCatch #0 {, blocks: (B:6:0x0007, B:8:0x000e, B:9:0x0013, B:11:0x0017, B:13:0x002b, B:15:0x0033, B:19:0x003d, B:21:0x0043, B:22:0x004c, B:36:0x006f, B:37:0x0074), top: B:5:0x0007, outer: #1 }] */
|
||||
/*
|
||||
Code decompiled incorrectly, please refer to instructions dump.
|
||||
To view partially-correct code enable 'Show inconsistent code' option in preferences
|
||||
*/
|
||||
private okhttp3.internal.http2.Http2Stream newStream(int r11, java.util.List<okhttp3.internal.http2.Header> r12, boolean r13) throws java.io.IOException {
|
||||
/*
|
||||
r10 = this;
|
||||
r6 = r13 ^ 1
|
||||
r4 = 0
|
||||
okhttp3.internal.http2.Http2Writer r7 = r10.writer
|
||||
monitor-enter(r7)
|
||||
monitor-enter(r10) // Catch: java.lang.Throwable -> L78
|
||||
int r0 = r10.nextStreamId // Catch: java.lang.Throwable -> L75
|
||||
r1 = 1073741823(0x3fffffff, float:1.9999999)
|
||||
if (r0 <= r1) goto L13
|
||||
okhttp3.internal.http2.ErrorCode r0 = okhttp3.internal.http2.ErrorCode.REFUSED_STREAM // Catch: java.lang.Throwable -> L75
|
||||
r10.shutdown(r0) // Catch: java.lang.Throwable -> L75
|
||||
L13:
|
||||
boolean r0 = r10.shutdown // Catch: java.lang.Throwable -> L75
|
||||
if (r0 != 0) goto L6f
|
||||
int r8 = r10.nextStreamId // Catch: java.lang.Throwable -> L75
|
||||
int r0 = r10.nextStreamId // Catch: java.lang.Throwable -> L75
|
||||
int r0 = r0 + 2
|
||||
r10.nextStreamId = r0 // Catch: java.lang.Throwable -> L75
|
||||
okhttp3.internal.http2.Http2Stream r9 = new okhttp3.internal.http2.Http2Stream // Catch: java.lang.Throwable -> L75
|
||||
r0 = r9
|
||||
r1 = r8
|
||||
r2 = r10
|
||||
r3 = r6
|
||||
r5 = r12
|
||||
r0.<init>(r1, r2, r3, r4, r5) // Catch: java.lang.Throwable -> L75
|
||||
if (r13 == 0) goto L3c
|
||||
long r0 = r10.bytesLeftInWriteWindow // Catch: java.lang.Throwable -> L75
|
||||
r2 = 0
|
||||
int r13 = (r0 > r2 ? 1 : (r0 == r2 ? 0 : -1))
|
||||
if (r13 == 0) goto L3c
|
||||
long r0 = r9.bytesLeftInWriteWindow // Catch: java.lang.Throwable -> L75
|
||||
int r13 = (r0 > r2 ? 1 : (r0 == r2 ? 0 : -1))
|
||||
if (r13 != 0) goto L3a
|
||||
goto L3c
|
||||
L3a:
|
||||
r13 = 0
|
||||
goto L3d
|
||||
L3c:
|
||||
r13 = 1
|
||||
L3d:
|
||||
boolean r0 = r9.isOpen() // Catch: java.lang.Throwable -> L75
|
||||
if (r0 == 0) goto L4c
|
||||
java.util.Map<java.lang.Integer, okhttp3.internal.http2.Http2Stream> r0 = r10.streams // Catch: java.lang.Throwable -> L75
|
||||
java.lang.Integer r1 = java.lang.Integer.valueOf(r8) // Catch: java.lang.Throwable -> L75
|
||||
r0.put(r1, r9) // Catch: java.lang.Throwable -> L75
|
||||
L4c:
|
||||
monitor-exit(r10) // Catch: java.lang.Throwable -> L75
|
||||
if (r11 != 0) goto L55
|
||||
okhttp3.internal.http2.Http2Writer r0 = r10.writer // Catch: java.lang.Throwable -> L78
|
||||
r0.synStream(r6, r8, r11, r12) // Catch: java.lang.Throwable -> L78
|
||||
goto L5e
|
||||
L55:
|
||||
boolean r0 = r10.client // Catch: java.lang.Throwable -> L78
|
||||
if (r0 != 0) goto L67
|
||||
okhttp3.internal.http2.Http2Writer r0 = r10.writer // Catch: java.lang.Throwable -> L78
|
||||
r0.pushPromise(r11, r8, r12) // Catch: java.lang.Throwable -> L78
|
||||
L5e:
|
||||
monitor-exit(r7) // Catch: java.lang.Throwable -> L78
|
||||
if (r13 == 0) goto L66
|
||||
okhttp3.internal.http2.Http2Writer r11 = r10.writer
|
||||
r11.flush()
|
||||
L66:
|
||||
return r9
|
||||
L67:
|
||||
java.lang.IllegalArgumentException r11 = new java.lang.IllegalArgumentException // Catch: java.lang.Throwable -> L78
|
||||
java.lang.String r12 = "client streams shouldn't have associated stream IDs"
|
||||
r11.<init>(r12) // Catch: java.lang.Throwable -> L78
|
||||
throw r11 // Catch: java.lang.Throwable -> L78
|
||||
L6f:
|
||||
okhttp3.internal.http2.ConnectionShutdownException r11 = new okhttp3.internal.http2.ConnectionShutdownException // Catch: java.lang.Throwable -> L75
|
||||
r11.<init>() // Catch: java.lang.Throwable -> L75
|
||||
throw r11 // Catch: java.lang.Throwable -> L75
|
||||
L75:
|
||||
r11 = move-exception
|
||||
monitor-exit(r10) // Catch: java.lang.Throwable -> L75
|
||||
throw r11 // Catch: java.lang.Throwable -> L78
|
||||
L78:
|
||||
r11 = move-exception
|
||||
monitor-exit(r7) // Catch: java.lang.Throwable -> L78
|
||||
throw r11
|
||||
*/
|
||||
throw new UnsupportedOperationException("Method not decompiled: okhttp3.internal.http2.Http2Connection.newStream(int, java.util.List, boolean):okhttp3.internal.http2.Http2Stream");
|
||||
}
|
||||
|
||||
void close(ErrorCode errorCode, ErrorCode errorCode2) throws IOException {
|
||||
Http2Stream[] http2StreamArr = null;
|
||||
try {
|
||||
shutdown(errorCode);
|
||||
e = null;
|
||||
} catch (IOException e) {
|
||||
e = e;
|
||||
}
|
||||
synchronized (this) {
|
||||
if (!this.streams.isEmpty()) {
|
||||
http2StreamArr = (Http2Stream[]) this.streams.values().toArray(new Http2Stream[this.streams.size()]);
|
||||
this.streams.clear();
|
||||
}
|
||||
}
|
||||
if (http2StreamArr != null) {
|
||||
for (Http2Stream http2Stream : http2StreamArr) {
|
||||
try {
|
||||
http2Stream.close(errorCode2);
|
||||
} catch (IOException e2) {
|
||||
if (e != null) {
|
||||
e = e2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
this.writer.close();
|
||||
} catch (IOException e3) {
|
||||
if (e == null) {
|
||||
e = e3;
|
||||
}
|
||||
}
|
||||
try {
|
||||
this.socket.close();
|
||||
} catch (IOException e4) {
|
||||
e = e4;
|
||||
}
|
||||
this.writerExecutor.shutdown();
|
||||
this.pushExecutor.shutdown();
|
||||
if (e != null) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
void start(boolean z) throws IOException {
|
||||
if (z) {
|
||||
this.writer.connectionPreface();
|
||||
this.writer.settings(this.okHttpSettings);
|
||||
if (this.okHttpSettings.getInitialWindowSize() != 65535) {
|
||||
this.writer.windowUpdate(0, r6 - 65535);
|
||||
}
|
||||
}
|
||||
new Thread(this.readerRunnable).start();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
boolean client;
|
||||
String hostname;
|
||||
int pingIntervalMillis;
|
||||
BufferedSink sink;
|
||||
Socket socket;
|
||||
BufferedSource source;
|
||||
Listener listener = Listener.REFUSE_INCOMING_STREAMS;
|
||||
PushObserver pushObserver = PushObserver.CANCEL;
|
||||
|
||||
public Builder(boolean z) {
|
||||
this.client = z;
|
||||
}
|
||||
|
||||
public Http2Connection build() {
|
||||
return new Http2Connection(this);
|
||||
}
|
||||
|
||||
public Builder listener(Listener listener) {
|
||||
this.listener = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder pingIntervalMillis(int i) {
|
||||
this.pingIntervalMillis = i;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder pushObserver(PushObserver pushObserver) {
|
||||
this.pushObserver = pushObserver;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder socket(Socket socket) throws IOException {
|
||||
return socket(socket, ((InetSocketAddress) socket.getRemoteSocketAddress()).getHostName(), Okio.buffer(Okio.source(socket)), Okio.buffer(Okio.sink(socket)));
|
||||
}
|
||||
|
||||
public Builder socket(Socket socket, String str, BufferedSource bufferedSource, BufferedSink bufferedSink) {
|
||||
this.socket = socket;
|
||||
this.hostname = str;
|
||||
this.source = bufferedSource;
|
||||
this.sink = bufferedSink;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
367
sources/okhttp3/internal/http2/Http2Reader.java
Normal file
367
sources/okhttp3/internal/http2/Http2Reader.java
Normal file
@@ -0,0 +1,367 @@
|
||||
package okhttp3.internal.http2;
|
||||
|
||||
import com.ubt.jimu.base.util.FileUtil;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import okhttp3.internal.Util;
|
||||
import okhttp3.internal.http2.Hpack;
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSource;
|
||||
import okio.ByteString;
|
||||
import okio.Source;
|
||||
import okio.Timeout;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
final class Http2Reader implements Closeable {
|
||||
static final Logger logger = Logger.getLogger(Http2.class.getName());
|
||||
private final boolean client;
|
||||
private final ContinuationSource continuation;
|
||||
final Hpack.Reader hpackReader;
|
||||
private final BufferedSource source;
|
||||
|
||||
static final class ContinuationSource implements Source {
|
||||
byte flags;
|
||||
int left;
|
||||
int length;
|
||||
short padding;
|
||||
private final BufferedSource source;
|
||||
int streamId;
|
||||
|
||||
ContinuationSource(BufferedSource bufferedSource) {
|
||||
this.source = bufferedSource;
|
||||
}
|
||||
|
||||
private void readContinuationHeader() throws IOException {
|
||||
int i = this.streamId;
|
||||
int readMedium = Http2Reader.readMedium(this.source);
|
||||
this.left = readMedium;
|
||||
this.length = readMedium;
|
||||
byte readByte = (byte) (this.source.readByte() & 255);
|
||||
this.flags = (byte) (this.source.readByte() & 255);
|
||||
if (Http2Reader.logger.isLoggable(Level.FINE)) {
|
||||
Http2Reader.logger.fine(Http2.frameLog(true, this.streamId, this.length, readByte, this.flags));
|
||||
}
|
||||
this.streamId = this.source.readInt() & Integer.MAX_VALUE;
|
||||
if (readByte != 9) {
|
||||
throw Http2.ioException("%s != TYPE_CONTINUATION", Byte.valueOf(readByte));
|
||||
}
|
||||
if (this.streamId != i) {
|
||||
throw Http2.ioException("TYPE_CONTINUATION streamId changed", new Object[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override // okio.Source, java.io.Closeable, java.lang.AutoCloseable
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
@Override // okio.Source
|
||||
public long read(Buffer buffer, long j) throws IOException {
|
||||
while (true) {
|
||||
int i = this.left;
|
||||
if (i != 0) {
|
||||
long read = this.source.read(buffer, Math.min(j, i));
|
||||
if (read == -1) {
|
||||
return -1L;
|
||||
}
|
||||
this.left = (int) (this.left - read);
|
||||
return read;
|
||||
}
|
||||
this.source.skip(this.padding);
|
||||
this.padding = (short) 0;
|
||||
if ((this.flags & 4) != 0) {
|
||||
return -1L;
|
||||
}
|
||||
readContinuationHeader();
|
||||
}
|
||||
}
|
||||
|
||||
@Override // okio.Source
|
||||
public Timeout timeout() {
|
||||
return this.source.timeout();
|
||||
}
|
||||
}
|
||||
|
||||
interface Handler {
|
||||
void ackSettings();
|
||||
|
||||
void alternateService(int i, String str, ByteString byteString, String str2, int i2, long j);
|
||||
|
||||
void data(boolean z, int i, BufferedSource bufferedSource, int i2) throws IOException;
|
||||
|
||||
void goAway(int i, ErrorCode errorCode, ByteString byteString);
|
||||
|
||||
void headers(boolean z, int i, int i2, List<Header> list);
|
||||
|
||||
void ping(boolean z, int i, int i2);
|
||||
|
||||
void priority(int i, int i2, int i3, boolean z);
|
||||
|
||||
void pushPromise(int i, int i2, List<Header> list) throws IOException;
|
||||
|
||||
void rstStream(int i, ErrorCode errorCode);
|
||||
|
||||
void settings(boolean z, Settings settings);
|
||||
|
||||
void windowUpdate(int i, long j);
|
||||
}
|
||||
|
||||
Http2Reader(BufferedSource bufferedSource, boolean z) {
|
||||
this.source = bufferedSource;
|
||||
this.client = z;
|
||||
this.continuation = new ContinuationSource(this.source);
|
||||
this.hpackReader = new Hpack.Reader(FileUtil.ZIP_BUFFER_SIZE, this.continuation);
|
||||
}
|
||||
|
||||
static int lengthWithoutPadding(int i, byte b, short s) throws IOException {
|
||||
if ((b & 8) != 0) {
|
||||
i--;
|
||||
}
|
||||
if (s <= i) {
|
||||
return (short) (i - s);
|
||||
}
|
||||
throw Http2.ioException("PROTOCOL_ERROR padding %s > remaining length %s", Short.valueOf(s), Integer.valueOf(i));
|
||||
}
|
||||
|
||||
private void readData(Handler handler, int i, byte b, int i2) throws IOException {
|
||||
if (i2 == 0) {
|
||||
throw Http2.ioException("PROTOCOL_ERROR: TYPE_DATA streamId == 0", new Object[0]);
|
||||
}
|
||||
boolean z = (b & 1) != 0;
|
||||
if ((b & 32) != 0) {
|
||||
throw Http2.ioException("PROTOCOL_ERROR: FLAG_COMPRESSED without SETTINGS_COMPRESS_DATA", new Object[0]);
|
||||
}
|
||||
short readByte = (b & 8) != 0 ? (short) (this.source.readByte() & 255) : (short) 0;
|
||||
handler.data(z, i2, this.source, lengthWithoutPadding(i, b, readByte));
|
||||
this.source.skip(readByte);
|
||||
}
|
||||
|
||||
private void readGoAway(Handler handler, int i, byte b, int i2) throws IOException {
|
||||
if (i < 8) {
|
||||
throw Http2.ioException("TYPE_GOAWAY length < 8: %s", Integer.valueOf(i));
|
||||
}
|
||||
if (i2 != 0) {
|
||||
throw Http2.ioException("TYPE_GOAWAY streamId != 0", new Object[0]);
|
||||
}
|
||||
int readInt = this.source.readInt();
|
||||
int readInt2 = this.source.readInt();
|
||||
int i3 = i - 8;
|
||||
ErrorCode fromHttp2 = ErrorCode.fromHttp2(readInt2);
|
||||
if (fromHttp2 == null) {
|
||||
throw Http2.ioException("TYPE_GOAWAY unexpected error code: %d", Integer.valueOf(readInt2));
|
||||
}
|
||||
ByteString byteString = ByteString.EMPTY;
|
||||
if (i3 > 0) {
|
||||
byteString = this.source.readByteString(i3);
|
||||
}
|
||||
handler.goAway(readInt, fromHttp2, byteString);
|
||||
}
|
||||
|
||||
private List<Header> readHeaderBlock(int i, short s, byte b, int i2) throws IOException {
|
||||
ContinuationSource continuationSource = this.continuation;
|
||||
continuationSource.left = i;
|
||||
continuationSource.length = i;
|
||||
continuationSource.padding = s;
|
||||
continuationSource.flags = b;
|
||||
continuationSource.streamId = i2;
|
||||
this.hpackReader.readHeaders();
|
||||
return this.hpackReader.getAndResetHeaderList();
|
||||
}
|
||||
|
||||
private void readHeaders(Handler handler, int i, byte b, int i2) throws IOException {
|
||||
if (i2 == 0) {
|
||||
throw Http2.ioException("PROTOCOL_ERROR: TYPE_HEADERS streamId == 0", new Object[0]);
|
||||
}
|
||||
boolean z = (b & 1) != 0;
|
||||
short readByte = (b & 8) != 0 ? (short) (this.source.readByte() & 255) : (short) 0;
|
||||
if ((b & 32) != 0) {
|
||||
readPriority(handler, i2);
|
||||
i -= 5;
|
||||
}
|
||||
handler.headers(z, i2, -1, readHeaderBlock(lengthWithoutPadding(i, b, readByte), readByte, b, i2));
|
||||
}
|
||||
|
||||
static int readMedium(BufferedSource bufferedSource) throws IOException {
|
||||
return (bufferedSource.readByte() & 255) | ((bufferedSource.readByte() & 255) << 16) | ((bufferedSource.readByte() & 255) << 8);
|
||||
}
|
||||
|
||||
private void readPing(Handler handler, int i, byte b, int i2) throws IOException {
|
||||
if (i != 8) {
|
||||
throw Http2.ioException("TYPE_PING length != 8: %s", Integer.valueOf(i));
|
||||
}
|
||||
if (i2 != 0) {
|
||||
throw Http2.ioException("TYPE_PING streamId != 0", new Object[0]);
|
||||
}
|
||||
handler.ping((b & 1) != 0, this.source.readInt(), this.source.readInt());
|
||||
}
|
||||
|
||||
private void readPriority(Handler handler, int i, byte b, int i2) throws IOException {
|
||||
if (i != 5) {
|
||||
throw Http2.ioException("TYPE_PRIORITY length: %d != 5", Integer.valueOf(i));
|
||||
}
|
||||
if (i2 == 0) {
|
||||
throw Http2.ioException("TYPE_PRIORITY streamId == 0", new Object[0]);
|
||||
}
|
||||
readPriority(handler, i2);
|
||||
}
|
||||
|
||||
private void readPushPromise(Handler handler, int i, byte b, int i2) throws IOException {
|
||||
if (i2 == 0) {
|
||||
throw Http2.ioException("PROTOCOL_ERROR: TYPE_PUSH_PROMISE streamId == 0", new Object[0]);
|
||||
}
|
||||
short readByte = (b & 8) != 0 ? (short) (this.source.readByte() & 255) : (short) 0;
|
||||
handler.pushPromise(i2, this.source.readInt() & Integer.MAX_VALUE, readHeaderBlock(lengthWithoutPadding(i - 4, b, readByte), readByte, b, i2));
|
||||
}
|
||||
|
||||
private void readRstStream(Handler handler, int i, byte b, int i2) throws IOException {
|
||||
if (i != 4) {
|
||||
throw Http2.ioException("TYPE_RST_STREAM length: %d != 4", Integer.valueOf(i));
|
||||
}
|
||||
if (i2 == 0) {
|
||||
throw Http2.ioException("TYPE_RST_STREAM streamId == 0", new Object[0]);
|
||||
}
|
||||
int readInt = this.source.readInt();
|
||||
ErrorCode fromHttp2 = ErrorCode.fromHttp2(readInt);
|
||||
if (fromHttp2 == null) {
|
||||
throw Http2.ioException("TYPE_RST_STREAM unexpected error code: %d", Integer.valueOf(readInt));
|
||||
}
|
||||
handler.rstStream(i2, fromHttp2);
|
||||
}
|
||||
|
||||
private void readSettings(Handler handler, int i, byte b, int i2) throws IOException {
|
||||
if (i2 != 0) {
|
||||
throw Http2.ioException("TYPE_SETTINGS streamId != 0", new Object[0]);
|
||||
}
|
||||
if ((b & 1) != 0) {
|
||||
if (i != 0) {
|
||||
throw Http2.ioException("FRAME_SIZE_ERROR ack frame should be empty!", new Object[0]);
|
||||
}
|
||||
handler.ackSettings();
|
||||
return;
|
||||
}
|
||||
if (i % 6 != 0) {
|
||||
throw Http2.ioException("TYPE_SETTINGS length %% 6 != 0: %s", Integer.valueOf(i));
|
||||
}
|
||||
Settings settings = new Settings();
|
||||
for (int i3 = 0; i3 < i; i3 += 6) {
|
||||
int readShort = this.source.readShort() & 65535;
|
||||
int readInt = this.source.readInt();
|
||||
switch (readShort) {
|
||||
case 2:
|
||||
if (readInt != 0 && readInt != 1) {
|
||||
throw Http2.ioException("PROTOCOL_ERROR SETTINGS_ENABLE_PUSH != 0 or 1", new Object[0]);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
readShort = 4;
|
||||
break;
|
||||
case 4:
|
||||
readShort = 7;
|
||||
if (readInt < 0) {
|
||||
throw Http2.ioException("PROTOCOL_ERROR SETTINGS_INITIAL_WINDOW_SIZE > 2^31 - 1", new Object[0]);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (readInt < 16384 || readInt > 16777215) {
|
||||
throw Http2.ioException("PROTOCOL_ERROR SETTINGS_MAX_FRAME_SIZE: %s", Integer.valueOf(readInt));
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
settings.set(readShort, readInt);
|
||||
}
|
||||
handler.settings(false, settings);
|
||||
}
|
||||
|
||||
private void readWindowUpdate(Handler handler, int i, byte b, int i2) throws IOException {
|
||||
if (i != 4) {
|
||||
throw Http2.ioException("TYPE_WINDOW_UPDATE length !=4: %s", Integer.valueOf(i));
|
||||
}
|
||||
long readInt = this.source.readInt() & 2147483647L;
|
||||
if (readInt == 0) {
|
||||
throw Http2.ioException("windowSizeIncrement was 0", Long.valueOf(readInt));
|
||||
}
|
||||
handler.windowUpdate(i2, readInt);
|
||||
}
|
||||
|
||||
@Override // java.io.Closeable, java.lang.AutoCloseable
|
||||
public void close() throws IOException {
|
||||
this.source.close();
|
||||
}
|
||||
|
||||
public boolean nextFrame(boolean z, Handler handler) throws IOException {
|
||||
try {
|
||||
this.source.require(9L);
|
||||
int readMedium = readMedium(this.source);
|
||||
if (readMedium < 0 || readMedium > 16384) {
|
||||
throw Http2.ioException("FRAME_SIZE_ERROR: %s", Integer.valueOf(readMedium));
|
||||
}
|
||||
byte readByte = (byte) (this.source.readByte() & 255);
|
||||
if (z && readByte != 4) {
|
||||
throw Http2.ioException("Expected a SETTINGS frame but was %s", Byte.valueOf(readByte));
|
||||
}
|
||||
byte readByte2 = (byte) (this.source.readByte() & 255);
|
||||
int readInt = this.source.readInt() & Integer.MAX_VALUE;
|
||||
if (logger.isLoggable(Level.FINE)) {
|
||||
logger.fine(Http2.frameLog(true, readInt, readMedium, readByte, readByte2));
|
||||
}
|
||||
switch (readByte) {
|
||||
case 0:
|
||||
readData(handler, readMedium, readByte2, readInt);
|
||||
return true;
|
||||
case 1:
|
||||
readHeaders(handler, readMedium, readByte2, readInt);
|
||||
return true;
|
||||
case 2:
|
||||
readPriority(handler, readMedium, readByte2, readInt);
|
||||
return true;
|
||||
case 3:
|
||||
readRstStream(handler, readMedium, readByte2, readInt);
|
||||
return true;
|
||||
case 4:
|
||||
readSettings(handler, readMedium, readByte2, readInt);
|
||||
return true;
|
||||
case 5:
|
||||
readPushPromise(handler, readMedium, readByte2, readInt);
|
||||
return true;
|
||||
case 6:
|
||||
readPing(handler, readMedium, readByte2, readInt);
|
||||
return true;
|
||||
case 7:
|
||||
readGoAway(handler, readMedium, readByte2, readInt);
|
||||
return true;
|
||||
case 8:
|
||||
readWindowUpdate(handler, readMedium, readByte2, readInt);
|
||||
return true;
|
||||
default:
|
||||
this.source.skip(readMedium);
|
||||
return true;
|
||||
}
|
||||
} catch (IOException unused) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void readConnectionPreface(Handler handler) throws IOException {
|
||||
if (this.client) {
|
||||
if (!nextFrame(true, handler)) {
|
||||
throw Http2.ioException("Required SETTINGS preface not received", new Object[0]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
ByteString readByteString = this.source.readByteString(Http2.CONNECTION_PREFACE.size());
|
||||
if (logger.isLoggable(Level.FINE)) {
|
||||
logger.fine(Util.format("<< CONNECTION %s", readByteString.hex()));
|
||||
}
|
||||
if (!Http2.CONNECTION_PREFACE.equals(readByteString)) {
|
||||
throw Http2.ioException("Expected a connection header but was %s", readByteString.utf8());
|
||||
}
|
||||
}
|
||||
|
||||
private void readPriority(Handler handler, int i) throws IOException {
|
||||
int readInt = this.source.readInt();
|
||||
handler.priority(i, readInt & Integer.MAX_VALUE, (this.source.readByte() & 255) + 1, (Integer.MIN_VALUE & readInt) != 0);
|
||||
}
|
||||
}
|
497
sources/okhttp3/internal/http2/Http2Stream.java
Normal file
497
sources/okhttp3/internal/http2/Http2Stream.java
Normal file
@@ -0,0 +1,497 @@
|
||||
package okhttp3.internal.http2;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import okio.AsyncTimeout;
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSource;
|
||||
import okio.Sink;
|
||||
import okio.Source;
|
||||
import okio.Timeout;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
public final class Http2Stream {
|
||||
static final /* synthetic */ boolean $assertionsDisabled = false;
|
||||
long bytesLeftInWriteWindow;
|
||||
final Http2Connection connection;
|
||||
private boolean hasResponseHeaders;
|
||||
final int id;
|
||||
private final List<Header> requestHeaders;
|
||||
private List<Header> responseHeaders;
|
||||
final FramingSink sink;
|
||||
private final FramingSource source;
|
||||
long unacknowledgedBytesRead = 0;
|
||||
final StreamTimeout readTimeout = new StreamTimeout();
|
||||
final StreamTimeout writeTimeout = new StreamTimeout();
|
||||
ErrorCode errorCode = null;
|
||||
|
||||
final class FramingSink implements Sink {
|
||||
static final /* synthetic */ boolean $assertionsDisabled = false;
|
||||
private static final long EMIT_BUFFER_SIZE = 16384;
|
||||
boolean closed;
|
||||
boolean finished;
|
||||
private final Buffer sendBuffer = new Buffer();
|
||||
|
||||
FramingSink() {
|
||||
}
|
||||
|
||||
private void emitFrame(boolean z) throws IOException {
|
||||
long min;
|
||||
synchronized (Http2Stream.this) {
|
||||
Http2Stream.this.writeTimeout.enter();
|
||||
while (Http2Stream.this.bytesLeftInWriteWindow <= 0 && !this.finished && !this.closed && Http2Stream.this.errorCode == null) {
|
||||
try {
|
||||
Http2Stream.this.waitForIo();
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
Http2Stream.this.writeTimeout.exitAndThrowIfTimedOut();
|
||||
Http2Stream.this.checkOutNotClosed();
|
||||
min = Math.min(Http2Stream.this.bytesLeftInWriteWindow, this.sendBuffer.size());
|
||||
Http2Stream.this.bytesLeftInWriteWindow -= min;
|
||||
}
|
||||
Http2Stream.this.writeTimeout.enter();
|
||||
try {
|
||||
Http2Stream.this.connection.writeData(Http2Stream.this.id, z && min == this.sendBuffer.size(), this.sendBuffer, min);
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
@Override // okio.Sink, java.io.Closeable, java.lang.AutoCloseable
|
||||
public void close() throws IOException {
|
||||
synchronized (Http2Stream.this) {
|
||||
if (this.closed) {
|
||||
return;
|
||||
}
|
||||
if (!Http2Stream.this.sink.finished) {
|
||||
if (this.sendBuffer.size() > 0) {
|
||||
while (this.sendBuffer.size() > 0) {
|
||||
emitFrame(true);
|
||||
}
|
||||
} else {
|
||||
Http2Stream http2Stream = Http2Stream.this;
|
||||
http2Stream.connection.writeData(http2Stream.id, true, null, 0L);
|
||||
}
|
||||
}
|
||||
synchronized (Http2Stream.this) {
|
||||
this.closed = true;
|
||||
}
|
||||
Http2Stream.this.connection.flush();
|
||||
Http2Stream.this.cancelStreamIfNecessary();
|
||||
}
|
||||
}
|
||||
|
||||
@Override // okio.Sink, java.io.Flushable
|
||||
public void flush() throws IOException {
|
||||
synchronized (Http2Stream.this) {
|
||||
Http2Stream.this.checkOutNotClosed();
|
||||
}
|
||||
while (this.sendBuffer.size() > 0) {
|
||||
emitFrame(false);
|
||||
Http2Stream.this.connection.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@Override // okio.Sink
|
||||
public Timeout timeout() {
|
||||
return Http2Stream.this.writeTimeout;
|
||||
}
|
||||
|
||||
@Override // okio.Sink
|
||||
public void write(Buffer buffer, long j) throws IOException {
|
||||
this.sendBuffer.write(buffer, j);
|
||||
while (this.sendBuffer.size() >= 16384) {
|
||||
emitFrame(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class FramingSource implements Source {
|
||||
static final /* synthetic */ boolean $assertionsDisabled = false;
|
||||
boolean closed;
|
||||
boolean finished;
|
||||
private final long maxByteCount;
|
||||
private final Buffer receiveBuffer = new Buffer();
|
||||
private final Buffer readBuffer = new Buffer();
|
||||
|
||||
FramingSource(long j) {
|
||||
this.maxByteCount = j;
|
||||
}
|
||||
|
||||
private void updateConnectionFlowControl(long j) {
|
||||
Http2Stream.this.connection.updateConnectionFlowControl(j);
|
||||
}
|
||||
|
||||
private void waitUntilReadable() throws IOException {
|
||||
Http2Stream.this.readTimeout.enter();
|
||||
while (this.readBuffer.size() == 0 && !this.finished && !this.closed && Http2Stream.this.errorCode == null) {
|
||||
try {
|
||||
Http2Stream.this.waitForIo();
|
||||
} finally {
|
||||
Http2Stream.this.readTimeout.exitAndThrowIfTimedOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override // okio.Source, java.io.Closeable, java.lang.AutoCloseable
|
||||
public void close() throws IOException {
|
||||
long size;
|
||||
synchronized (Http2Stream.this) {
|
||||
this.closed = true;
|
||||
size = this.readBuffer.size();
|
||||
this.readBuffer.clear();
|
||||
Http2Stream.this.notifyAll();
|
||||
}
|
||||
if (size > 0) {
|
||||
updateConnectionFlowControl(size);
|
||||
}
|
||||
Http2Stream.this.cancelStreamIfNecessary();
|
||||
}
|
||||
|
||||
@Override // okio.Source
|
||||
public long read(Buffer buffer, long j) throws IOException {
|
||||
ErrorCode errorCode;
|
||||
long j2;
|
||||
if (j < 0) {
|
||||
throw new IllegalArgumentException("byteCount < 0: " + j);
|
||||
}
|
||||
synchronized (Http2Stream.this) {
|
||||
waitUntilReadable();
|
||||
if (this.closed) {
|
||||
throw new IOException("stream closed");
|
||||
}
|
||||
errorCode = Http2Stream.this.errorCode;
|
||||
if (this.readBuffer.size() > 0) {
|
||||
j2 = this.readBuffer.read(buffer, Math.min(j, this.readBuffer.size()));
|
||||
Http2Stream.this.unacknowledgedBytesRead += j2;
|
||||
} else {
|
||||
j2 = -1;
|
||||
}
|
||||
if (errorCode == null && Http2Stream.this.unacknowledgedBytesRead >= Http2Stream.this.connection.okHttpSettings.getInitialWindowSize() / 2) {
|
||||
Http2Stream.this.connection.writeWindowUpdateLater(Http2Stream.this.id, Http2Stream.this.unacknowledgedBytesRead);
|
||||
Http2Stream.this.unacknowledgedBytesRead = 0L;
|
||||
}
|
||||
}
|
||||
if (j2 != -1) {
|
||||
updateConnectionFlowControl(j2);
|
||||
return j2;
|
||||
}
|
||||
if (errorCode == null) {
|
||||
return -1L;
|
||||
}
|
||||
throw new StreamResetException(errorCode);
|
||||
}
|
||||
|
||||
void receive(BufferedSource bufferedSource, long j) throws IOException {
|
||||
boolean z;
|
||||
boolean z2;
|
||||
boolean z3;
|
||||
while (j > 0) {
|
||||
synchronized (Http2Stream.this) {
|
||||
z = this.finished;
|
||||
z2 = true;
|
||||
z3 = this.readBuffer.size() + j > this.maxByteCount;
|
||||
}
|
||||
if (z3) {
|
||||
bufferedSource.skip(j);
|
||||
Http2Stream.this.closeLater(ErrorCode.FLOW_CONTROL_ERROR);
|
||||
return;
|
||||
}
|
||||
if (z) {
|
||||
bufferedSource.skip(j);
|
||||
return;
|
||||
}
|
||||
long read = bufferedSource.read(this.receiveBuffer, j);
|
||||
if (read == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
j -= read;
|
||||
synchronized (Http2Stream.this) {
|
||||
if (this.readBuffer.size() != 0) {
|
||||
z2 = false;
|
||||
}
|
||||
this.readBuffer.writeAll(this.receiveBuffer);
|
||||
if (z2) {
|
||||
Http2Stream.this.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override // okio.Source
|
||||
public Timeout timeout() {
|
||||
return Http2Stream.this.readTimeout;
|
||||
}
|
||||
}
|
||||
|
||||
class StreamTimeout extends AsyncTimeout {
|
||||
StreamTimeout() {
|
||||
}
|
||||
|
||||
public void exitAndThrowIfTimedOut() throws IOException {
|
||||
if (exit()) {
|
||||
throw newTimeoutException(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override // okio.AsyncTimeout
|
||||
protected IOException newTimeoutException(IOException iOException) {
|
||||
SocketTimeoutException socketTimeoutException = new SocketTimeoutException("timeout");
|
||||
if (iOException != null) {
|
||||
socketTimeoutException.initCause(iOException);
|
||||
}
|
||||
return socketTimeoutException;
|
||||
}
|
||||
|
||||
@Override // okio.AsyncTimeout
|
||||
protected void timedOut() {
|
||||
Http2Stream.this.closeLater(ErrorCode.CANCEL);
|
||||
}
|
||||
}
|
||||
|
||||
Http2Stream(int i, Http2Connection http2Connection, boolean z, boolean z2, List<Header> list) {
|
||||
if (http2Connection == null) {
|
||||
throw new NullPointerException("connection == null");
|
||||
}
|
||||
if (list == null) {
|
||||
throw new NullPointerException("requestHeaders == null");
|
||||
}
|
||||
this.id = i;
|
||||
this.connection = http2Connection;
|
||||
this.bytesLeftInWriteWindow = http2Connection.peerSettings.getInitialWindowSize();
|
||||
this.source = new FramingSource(http2Connection.okHttpSettings.getInitialWindowSize());
|
||||
this.sink = new FramingSink();
|
||||
this.source.finished = z2;
|
||||
this.sink.finished = z;
|
||||
this.requestHeaders = list;
|
||||
}
|
||||
|
||||
private boolean closeInternal(ErrorCode errorCode) {
|
||||
synchronized (this) {
|
||||
if (this.errorCode != null) {
|
||||
return false;
|
||||
}
|
||||
if (this.source.finished && this.sink.finished) {
|
||||
return false;
|
||||
}
|
||||
this.errorCode = errorCode;
|
||||
notifyAll();
|
||||
this.connection.removeStream(this.id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void addBytesToWriteWindow(long j) {
|
||||
this.bytesLeftInWriteWindow += j;
|
||||
if (j > 0) {
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
void cancelStreamIfNecessary() throws IOException {
|
||||
boolean z;
|
||||
boolean isOpen;
|
||||
synchronized (this) {
|
||||
z = !this.source.finished && this.source.closed && (this.sink.finished || this.sink.closed);
|
||||
isOpen = isOpen();
|
||||
}
|
||||
if (z) {
|
||||
close(ErrorCode.CANCEL);
|
||||
} else {
|
||||
if (isOpen) {
|
||||
return;
|
||||
}
|
||||
this.connection.removeStream(this.id);
|
||||
}
|
||||
}
|
||||
|
||||
void checkOutNotClosed() throws IOException {
|
||||
FramingSink framingSink = this.sink;
|
||||
if (framingSink.closed) {
|
||||
throw new IOException("stream closed");
|
||||
}
|
||||
if (framingSink.finished) {
|
||||
throw new IOException("stream finished");
|
||||
}
|
||||
ErrorCode errorCode = this.errorCode;
|
||||
if (errorCode != null) {
|
||||
throw new StreamResetException(errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
public void close(ErrorCode errorCode) throws IOException {
|
||||
if (closeInternal(errorCode)) {
|
||||
this.connection.writeSynReset(this.id, errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
public void closeLater(ErrorCode errorCode) {
|
||||
if (closeInternal(errorCode)) {
|
||||
this.connection.writeSynResetLater(this.id, errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
public Http2Connection getConnection() {
|
||||
return this.connection;
|
||||
}
|
||||
|
||||
public synchronized ErrorCode getErrorCode() {
|
||||
return this.errorCode;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public List<Header> getRequestHeaders() {
|
||||
return this.requestHeaders;
|
||||
}
|
||||
|
||||
public Sink getSink() {
|
||||
synchronized (this) {
|
||||
if (!this.hasResponseHeaders && !isLocallyInitiated()) {
|
||||
throw new IllegalStateException("reply before requesting the sink");
|
||||
}
|
||||
}
|
||||
return this.sink;
|
||||
}
|
||||
|
||||
public Source getSource() {
|
||||
return this.source;
|
||||
}
|
||||
|
||||
public boolean isLocallyInitiated() {
|
||||
return this.connection.client == ((this.id & 1) == 1);
|
||||
}
|
||||
|
||||
public synchronized boolean isOpen() {
|
||||
if (this.errorCode != null) {
|
||||
return false;
|
||||
}
|
||||
if ((this.source.finished || this.source.closed) && (this.sink.finished || this.sink.closed)) {
|
||||
if (this.hasResponseHeaders) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public Timeout readTimeout() {
|
||||
return this.readTimeout;
|
||||
}
|
||||
|
||||
void receiveData(BufferedSource bufferedSource, int i) throws IOException {
|
||||
this.source.receive(bufferedSource, i);
|
||||
}
|
||||
|
||||
void receiveFin() {
|
||||
boolean isOpen;
|
||||
synchronized (this) {
|
||||
this.source.finished = true;
|
||||
isOpen = isOpen();
|
||||
notifyAll();
|
||||
}
|
||||
if (isOpen) {
|
||||
return;
|
||||
}
|
||||
this.connection.removeStream(this.id);
|
||||
}
|
||||
|
||||
void receiveHeaders(List<Header> list) {
|
||||
boolean z;
|
||||
synchronized (this) {
|
||||
z = true;
|
||||
this.hasResponseHeaders = true;
|
||||
if (this.responseHeaders == null) {
|
||||
this.responseHeaders = list;
|
||||
z = isOpen();
|
||||
notifyAll();
|
||||
} else {
|
||||
ArrayList arrayList = new ArrayList();
|
||||
arrayList.addAll(this.responseHeaders);
|
||||
arrayList.add(null);
|
||||
arrayList.addAll(list);
|
||||
this.responseHeaders = arrayList;
|
||||
}
|
||||
}
|
||||
if (z) {
|
||||
return;
|
||||
}
|
||||
this.connection.removeStream(this.id);
|
||||
}
|
||||
|
||||
synchronized void receiveRstStream(ErrorCode errorCode) {
|
||||
if (this.errorCode == null) {
|
||||
this.errorCode = errorCode;
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
public void sendResponseHeaders(List<Header> list, boolean z) throws IOException {
|
||||
boolean z2;
|
||||
boolean z3;
|
||||
if (list == null) {
|
||||
throw new NullPointerException("responseHeaders == null");
|
||||
}
|
||||
synchronized (this) {
|
||||
this.hasResponseHeaders = true;
|
||||
if (z) {
|
||||
z2 = false;
|
||||
z3 = false;
|
||||
} else {
|
||||
this.sink.finished = true;
|
||||
z2 = true;
|
||||
z3 = true;
|
||||
}
|
||||
}
|
||||
if (!z2) {
|
||||
synchronized (this.connection) {
|
||||
z2 = this.connection.bytesLeftInWriteWindow == 0;
|
||||
}
|
||||
}
|
||||
this.connection.writeSynReply(this.id, z3, list);
|
||||
if (z2) {
|
||||
this.connection.flush();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized List<Header> takeResponseHeaders() throws IOException {
|
||||
List<Header> list;
|
||||
if (!isLocallyInitiated()) {
|
||||
throw new IllegalStateException("servers cannot read response headers");
|
||||
}
|
||||
this.readTimeout.enter();
|
||||
while (this.responseHeaders == null && this.errorCode == null) {
|
||||
try {
|
||||
waitForIo();
|
||||
} catch (Throwable th) {
|
||||
this.readTimeout.exitAndThrowIfTimedOut();
|
||||
throw th;
|
||||
}
|
||||
}
|
||||
this.readTimeout.exitAndThrowIfTimedOut();
|
||||
list = this.responseHeaders;
|
||||
if (list == null) {
|
||||
throw new StreamResetException(this.errorCode);
|
||||
}
|
||||
this.responseHeaders = null;
|
||||
return list;
|
||||
}
|
||||
|
||||
void waitForIo() throws InterruptedIOException {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException unused) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new InterruptedIOException();
|
||||
}
|
||||
}
|
||||
|
||||
public Timeout writeTimeout() {
|
||||
return this.writeTimeout;
|
||||
}
|
||||
}
|
240
sources/okhttp3/internal/http2/Http2Writer.java
Normal file
240
sources/okhttp3/internal/http2/Http2Writer.java
Normal file
@@ -0,0 +1,240 @@
|
||||
package okhttp3.internal.http2;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import okhttp3.internal.Util;
|
||||
import okhttp3.internal.http2.Hpack;
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSink;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
final class Http2Writer implements Closeable {
|
||||
private static final Logger logger = Logger.getLogger(Http2.class.getName());
|
||||
private final boolean client;
|
||||
private boolean closed;
|
||||
private final Buffer hpackBuffer = new Buffer();
|
||||
final Hpack.Writer hpackWriter = new Hpack.Writer(this.hpackBuffer);
|
||||
private int maxFrameSize = 16384;
|
||||
private final BufferedSink sink;
|
||||
|
||||
Http2Writer(BufferedSink bufferedSink, boolean z) {
|
||||
this.sink = bufferedSink;
|
||||
this.client = z;
|
||||
}
|
||||
|
||||
private void writeContinuationFrames(int i, long j) throws IOException {
|
||||
while (j > 0) {
|
||||
int min = (int) Math.min(this.maxFrameSize, j);
|
||||
long j2 = min;
|
||||
j -= j2;
|
||||
frameHeader(i, min, (byte) 9, j == 0 ? (byte) 4 : (byte) 0);
|
||||
this.sink.write(this.hpackBuffer, j2);
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeMedium(BufferedSink bufferedSink, int i) throws IOException {
|
||||
bufferedSink.writeByte((i >>> 16) & 255);
|
||||
bufferedSink.writeByte((i >>> 8) & 255);
|
||||
bufferedSink.writeByte(i & 255);
|
||||
}
|
||||
|
||||
public synchronized void applyAndAckSettings(Settings settings) throws IOException {
|
||||
if (this.closed) {
|
||||
throw new IOException("closed");
|
||||
}
|
||||
this.maxFrameSize = settings.getMaxFrameSize(this.maxFrameSize);
|
||||
if (settings.getHeaderTableSize() != -1) {
|
||||
this.hpackWriter.setHeaderTableSizeSetting(settings.getHeaderTableSize());
|
||||
}
|
||||
frameHeader(0, 0, (byte) 4, (byte) 1);
|
||||
this.sink.flush();
|
||||
}
|
||||
|
||||
@Override // java.io.Closeable, java.lang.AutoCloseable
|
||||
public synchronized void close() throws IOException {
|
||||
this.closed = true;
|
||||
this.sink.close();
|
||||
}
|
||||
|
||||
public synchronized void connectionPreface() throws IOException {
|
||||
if (this.closed) {
|
||||
throw new IOException("closed");
|
||||
}
|
||||
if (this.client) {
|
||||
if (logger.isLoggable(Level.FINE)) {
|
||||
logger.fine(Util.format(">> CONNECTION %s", Http2.CONNECTION_PREFACE.hex()));
|
||||
}
|
||||
this.sink.write(Http2.CONNECTION_PREFACE.toByteArray());
|
||||
this.sink.flush();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void data(boolean z, int i, Buffer buffer, int i2) throws IOException {
|
||||
if (this.closed) {
|
||||
throw new IOException("closed");
|
||||
}
|
||||
dataFrame(i, z ? (byte) 1 : (byte) 0, buffer, i2);
|
||||
}
|
||||
|
||||
void dataFrame(int i, byte b, Buffer buffer, int i2) throws IOException {
|
||||
frameHeader(i, i2, (byte) 0, b);
|
||||
if (i2 > 0) {
|
||||
this.sink.write(buffer, i2);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void flush() throws IOException {
|
||||
if (this.closed) {
|
||||
throw new IOException("closed");
|
||||
}
|
||||
this.sink.flush();
|
||||
}
|
||||
|
||||
public void frameHeader(int i, int i2, byte b, byte b2) throws IOException {
|
||||
if (logger.isLoggable(Level.FINE)) {
|
||||
logger.fine(Http2.frameLog(false, i, i2, b, b2));
|
||||
}
|
||||
int i3 = this.maxFrameSize;
|
||||
if (i2 > i3) {
|
||||
throw Http2.illegalArgument("FRAME_SIZE_ERROR length > %d: %d", Integer.valueOf(i3), Integer.valueOf(i2));
|
||||
}
|
||||
if ((Integer.MIN_VALUE & i) != 0) {
|
||||
throw Http2.illegalArgument("reserved bit set: %s", Integer.valueOf(i));
|
||||
}
|
||||
writeMedium(this.sink, i2);
|
||||
this.sink.writeByte(b & 255);
|
||||
this.sink.writeByte(b2 & 255);
|
||||
this.sink.writeInt(i & Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public synchronized void goAway(int i, ErrorCode errorCode, byte[] bArr) throws IOException {
|
||||
if (this.closed) {
|
||||
throw new IOException("closed");
|
||||
}
|
||||
if (errorCode.httpCode == -1) {
|
||||
throw Http2.illegalArgument("errorCode.httpCode == -1", new Object[0]);
|
||||
}
|
||||
frameHeader(0, bArr.length + 8, (byte) 7, (byte) 0);
|
||||
this.sink.writeInt(i);
|
||||
this.sink.writeInt(errorCode.httpCode);
|
||||
if (bArr.length > 0) {
|
||||
this.sink.write(bArr);
|
||||
}
|
||||
this.sink.flush();
|
||||
}
|
||||
|
||||
public synchronized void headers(int i, List<Header> list) throws IOException {
|
||||
if (this.closed) {
|
||||
throw new IOException("closed");
|
||||
}
|
||||
headers(false, i, list);
|
||||
}
|
||||
|
||||
public int maxDataLength() {
|
||||
return this.maxFrameSize;
|
||||
}
|
||||
|
||||
public synchronized void ping(boolean z, int i, int i2) throws IOException {
|
||||
if (this.closed) {
|
||||
throw new IOException("closed");
|
||||
}
|
||||
frameHeader(0, 8, (byte) 6, z ? (byte) 1 : (byte) 0);
|
||||
this.sink.writeInt(i);
|
||||
this.sink.writeInt(i2);
|
||||
this.sink.flush();
|
||||
}
|
||||
|
||||
public synchronized void pushPromise(int i, int i2, List<Header> list) throws IOException {
|
||||
if (this.closed) {
|
||||
throw new IOException("closed");
|
||||
}
|
||||
this.hpackWriter.writeHeaders(list);
|
||||
long size = this.hpackBuffer.size();
|
||||
int min = (int) Math.min(this.maxFrameSize - 4, size);
|
||||
long j = min;
|
||||
frameHeader(i, min + 4, (byte) 5, size == j ? (byte) 4 : (byte) 0);
|
||||
this.sink.writeInt(i2 & Integer.MAX_VALUE);
|
||||
this.sink.write(this.hpackBuffer, j);
|
||||
if (size > j) {
|
||||
writeContinuationFrames(i, size - j);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void rstStream(int i, ErrorCode errorCode) throws IOException {
|
||||
if (this.closed) {
|
||||
throw new IOException("closed");
|
||||
}
|
||||
if (errorCode.httpCode == -1) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
frameHeader(i, 4, (byte) 3, (byte) 0);
|
||||
this.sink.writeInt(errorCode.httpCode);
|
||||
this.sink.flush();
|
||||
}
|
||||
|
||||
public synchronized void settings(Settings settings) throws IOException {
|
||||
if (this.closed) {
|
||||
throw new IOException("closed");
|
||||
}
|
||||
int i = 0;
|
||||
frameHeader(0, settings.size() * 6, (byte) 4, (byte) 0);
|
||||
while (i < 10) {
|
||||
if (settings.isSet(i)) {
|
||||
this.sink.writeShort(i == 4 ? 3 : i == 7 ? 4 : i);
|
||||
this.sink.writeInt(settings.get(i));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
this.sink.flush();
|
||||
}
|
||||
|
||||
public synchronized void synReply(boolean z, int i, List<Header> list) throws IOException {
|
||||
if (this.closed) {
|
||||
throw new IOException("closed");
|
||||
}
|
||||
headers(z, i, list);
|
||||
}
|
||||
|
||||
public synchronized void synStream(boolean z, int i, int i2, List<Header> list) throws IOException {
|
||||
if (this.closed) {
|
||||
throw new IOException("closed");
|
||||
}
|
||||
headers(z, i, list);
|
||||
}
|
||||
|
||||
public synchronized void windowUpdate(int i, long j) throws IOException {
|
||||
if (this.closed) {
|
||||
throw new IOException("closed");
|
||||
}
|
||||
if (j == 0 || j > 2147483647L) {
|
||||
throw Http2.illegalArgument("windowSizeIncrement == 0 || windowSizeIncrement > 0x7fffffffL: %s", Long.valueOf(j));
|
||||
}
|
||||
frameHeader(i, 4, (byte) 8, (byte) 0);
|
||||
this.sink.writeInt((int) j);
|
||||
this.sink.flush();
|
||||
}
|
||||
|
||||
void headers(boolean z, int i, List<Header> list) throws IOException {
|
||||
if (!this.closed) {
|
||||
this.hpackWriter.writeHeaders(list);
|
||||
long size = this.hpackBuffer.size();
|
||||
int min = (int) Math.min(this.maxFrameSize, size);
|
||||
long j = min;
|
||||
byte b = size == j ? (byte) 4 : (byte) 0;
|
||||
if (z) {
|
||||
b = (byte) (b | 1);
|
||||
}
|
||||
frameHeader(i, min, (byte) 1, b);
|
||||
this.sink.write(this.hpackBuffer, j);
|
||||
if (size > j) {
|
||||
writeContinuationFrames(i, size - j);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
throw new IOException("closed");
|
||||
}
|
||||
}
|
137
sources/okhttp3/internal/http2/Huffman.java
Normal file
137
sources/okhttp3/internal/http2/Huffman.java
Normal file
@@ -0,0 +1,137 @@
|
||||
package okhttp3.internal.http2;
|
||||
|
||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||
import com.ijm.dataencryption.de.DataDecryptTool;
|
||||
import com.ubt.jimu.unity.bluetooth.UnityActivity;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import okio.BufferedSink;
|
||||
import okio.ByteString;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
class Huffman {
|
||||
private static final int[] CODES = {8184, 8388568, 268435426, 268435427, 268435428, 268435429, 268435430, 268435431, 268435432, 16777194, 1073741820, 268435433, 268435434, 1073741821, 268435435, 268435436, 268435437, 268435438, 268435439, 268435440, 268435441, 268435442, 1073741822, 268435443, 268435444, 268435445, 268435446, 268435447, 268435448, 268435449, 268435450, 268435451, 20, UnityActivity.CODE_AR_GAME, 1017, 4090, 8185, 21, 248, 2042, 1018, 1019, 249, 2043, ItemTouchHelper.Callback.DEFAULT_SWIPE_ANIMATION_DURATION, 22, 23, 24, 0, 1, 2, 25, 26, 27, 28, 29, 30, 31, 92, 251, 32764, 32, 4091, 1020, 8186, 33, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 252, 115, 253, 8187, 524272, 8188, 16380, 34, 32765, 3, 35, 4, 36, 5, 37, 38, 39, 6, 116, 117, 40, 41, 42, 7, 43, 118, 44, 8, 9, 45, 119, 120, 121, 122, 123, 32766, 2044, 16381, 8189, 268435452, 1048550, 4194258, 1048551, 1048552, 4194259, 4194260, 4194261, 8388569, 4194262, 8388570, 8388571, 8388572, 8388573, 8388574, 16777195, 8388575, 16777196, 16777197, 4194263, 8388576, 16777198, 8388577, 8388578, 8388579, 8388580, 2097116, 4194264, 8388581, 4194265, 8388582, 8388583, 16777199, 4194266, 2097117, 1048553, 4194267, 4194268, 8388584, 8388585, 2097118, 8388586, 4194269, 4194270, 16777200, 2097119, 4194271, 8388587, 8388588, 2097120, 2097121, 4194272, 2097122, 8388589, 4194273, 8388590, 8388591, 1048554, 4194274, 4194275, 4194276, 8388592, 4194277, 4194278, 8388593, 67108832, 67108833, 1048555, 524273, 4194279, 8388594, 4194280, 33554412, 67108834, 67108835, 67108836, 134217694, 134217695, 67108837, 16777201, 33554413, 524274, 2097123, 67108838, 134217696, 134217697, 67108839, 134217698, 16777202, 2097124, 2097125, 67108840, 67108841, 268435453, 134217699, 134217700, 134217701, 1048556, 16777203, 1048557, 2097126, 4194281, 2097127, 2097128, 8388595, 4194282, 4194283, 33554414, 33554415, 16777204, 16777205, 67108842, 8388596, 67108843, 134217702, 67108844, 67108845, 134217703, 134217704, 134217705, 134217706, 134217707, 268435454, 134217708, 134217709, 134217710, 134217711, 134217712, 67108846};
|
||||
private static final byte[] CODE_LENGTHS = {13, 23, 28, 28, 28, 28, 28, 28, 28, 24, 30, 28, 28, 30, 28, 28, 28, 28, 28, 28, 28, 28, 30, 28, 28, 28, 28, 28, 28, 28, 28, 28, 6, 10, 10, 12, 13, 6, 8, 11, 10, 10, 8, 11, 8, 6, 6, 6, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 8, 15, 6, 12, 10, 13, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 13, 19, 13, 14, 6, 15, 5, 6, 5, 6, 5, 6, 6, 6, 5, 7, 7, 6, 6, 6, 5, 6, 7, 6, 5, 5, 6, 7, 7, 7, 7, 7, 15, 11, 14, 13, 28, 20, 22, 20, 20, 22, 22, 22, 23, 22, 23, 23, 23, 23, 23, 24, 23, 24, 24, 22, 23, 24, 23, 23, 23, 23, 21, 22, 23, 22, 23, 23, 24, 22, 21, 20, 22, 22, 23, 23, 21, 23, 22, 22, 24, 21, 22, 23, 23, 21, 21, 22, 21, 23, 22, 23, 23, 20, 22, 22, 22, 23, 22, 22, 23, 26, 26, 20, 19, 22, 23, 22, 25, 26, 26, 26, 27, 27, 26, 24, 25, 19, 21, 26, 27, 27, 26, 27, 24, 21, 21, 26, 26, 28, 27, 27, 27, 20, 24, 20, 21, 22, 21, 21, 23, 22, 22, 25, 25, 24, 24, 26, 23, 26, 27, 26, 26, 27, 27, 27, 27, 27, 28, 27, 27, 27, 27, 27, 26};
|
||||
private static final Huffman INSTANCE = new Huffman();
|
||||
private final Node root = new Node();
|
||||
|
||||
private Huffman() {
|
||||
buildTree();
|
||||
}
|
||||
|
||||
private void addCode(int i, int i2, byte b) {
|
||||
Node node = new Node(i, b);
|
||||
Node node2 = this.root;
|
||||
while (b > 8) {
|
||||
b = (byte) (b - 8);
|
||||
int i3 = (i2 >>> b) & 255;
|
||||
Node[] nodeArr = node2.children;
|
||||
if (nodeArr == null) {
|
||||
throw new IllegalStateException("invalid dictionary: prefix not unique");
|
||||
}
|
||||
if (nodeArr[i3] == null) {
|
||||
nodeArr[i3] = new Node();
|
||||
}
|
||||
node2 = node2.children[i3];
|
||||
}
|
||||
int i4 = 8 - b;
|
||||
int i5 = (i2 << i4) & 255;
|
||||
int i6 = 1 << i4;
|
||||
for (int i7 = i5; i7 < i5 + i6; i7++) {
|
||||
node2.children[i7] = node;
|
||||
}
|
||||
}
|
||||
|
||||
private void buildTree() {
|
||||
int i = 0;
|
||||
while (true) {
|
||||
byte[] bArr = CODE_LENGTHS;
|
||||
if (i >= bArr.length) {
|
||||
return;
|
||||
}
|
||||
addCode(i, CODES[i], bArr[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
public static Huffman get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
byte[] decode(byte[] bArr) {
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
Node node = this.root;
|
||||
int i = 0;
|
||||
int i2 = 0;
|
||||
for (byte b : bArr) {
|
||||
i = (i << 8) | (b & 255);
|
||||
i2 += 8;
|
||||
while (i2 >= 8) {
|
||||
node = node.children[(i >>> (i2 - 8)) & 255];
|
||||
if (node.children == null) {
|
||||
byteArrayOutputStream.write(node.symbol);
|
||||
i2 -= node.terminalBits;
|
||||
node = this.root;
|
||||
} else {
|
||||
i2 -= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (i2 > 0) {
|
||||
Node node2 = node.children[(i << (8 - i2)) & 255];
|
||||
if (node2.children != null || node2.terminalBits > i2) {
|
||||
break;
|
||||
}
|
||||
byteArrayOutputStream.write(node2.symbol);
|
||||
i2 -= node2.terminalBits;
|
||||
node = this.root;
|
||||
}
|
||||
return byteArrayOutputStream.toByteArray();
|
||||
}
|
||||
|
||||
void encode(ByteString byteString, BufferedSink bufferedSink) throws IOException {
|
||||
long j = 0;
|
||||
int i = 0;
|
||||
for (int i2 = 0; i2 < byteString.size(); i2++) {
|
||||
int i3 = byteString.getByte(i2) & 255;
|
||||
int i4 = CODES[i3];
|
||||
byte b = CODE_LENGTHS[i3];
|
||||
j = (j << b) | i4;
|
||||
i += b;
|
||||
while (i >= 8) {
|
||||
i -= 8;
|
||||
bufferedSink.writeByte((int) (j >> i));
|
||||
}
|
||||
}
|
||||
if (i > 0) {
|
||||
bufferedSink.writeByte((int) ((255 >>> i) | (j << (8 - i))));
|
||||
}
|
||||
}
|
||||
|
||||
int encodedLength(ByteString byteString) {
|
||||
long j = 0;
|
||||
for (int i = 0; i < byteString.size(); i++) {
|
||||
j += CODE_LENGTHS[byteString.getByte(i) & 255];
|
||||
}
|
||||
return (int) ((j + 7) >> 3);
|
||||
}
|
||||
|
||||
private static final class Node {
|
||||
final Node[] children;
|
||||
final int symbol;
|
||||
final int terminalBits;
|
||||
|
||||
Node() {
|
||||
this.children = new Node[DataDecryptTool.DECRYPT_ALL_FILE];
|
||||
this.symbol = 0;
|
||||
this.terminalBits = 0;
|
||||
}
|
||||
|
||||
Node(int i, int i2) {
|
||||
this.children = null;
|
||||
this.symbol = i;
|
||||
int i3 = i2 & 7;
|
||||
this.terminalBits = i3 == 0 ? 8 : i3;
|
||||
}
|
||||
}
|
||||
}
|
38
sources/okhttp3/internal/http2/PushObserver.java
Normal file
38
sources/okhttp3/internal/http2/PushObserver.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package okhttp3.internal.http2;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import okio.BufferedSource;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
public interface PushObserver {
|
||||
public static final PushObserver CANCEL = new PushObserver() { // from class: okhttp3.internal.http2.PushObserver.1
|
||||
@Override // okhttp3.internal.http2.PushObserver
|
||||
public boolean onData(int i, BufferedSource bufferedSource, int i2, boolean z) throws IOException {
|
||||
bufferedSource.skip(i2);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http2.PushObserver
|
||||
public boolean onHeaders(int i, List<Header> list, boolean z) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http2.PushObserver
|
||||
public boolean onRequest(int i, List<Header> list) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http2.PushObserver
|
||||
public void onReset(int i, ErrorCode errorCode) {
|
||||
}
|
||||
};
|
||||
|
||||
boolean onData(int i, BufferedSource bufferedSource, int i2, boolean z) throws IOException;
|
||||
|
||||
boolean onHeaders(int i, List<Header> list, boolean z);
|
||||
|
||||
boolean onRequest(int i, List<Header> list);
|
||||
|
||||
void onReset(int i, ErrorCode errorCode);
|
||||
}
|
81
sources/okhttp3/internal/http2/Settings.java
Normal file
81
sources/okhttp3/internal/http2/Settings.java
Normal file
@@ -0,0 +1,81 @@
|
||||
package okhttp3.internal.http2;
|
||||
|
||||
import com.ubtrobot.jimu.robotapi.PeripheralType;
|
||||
import java.util.Arrays;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
public final class Settings {
|
||||
static final int COUNT = 10;
|
||||
static final int DEFAULT_INITIAL_WINDOW_SIZE = 65535;
|
||||
static final int ENABLE_PUSH = 2;
|
||||
static final int HEADER_TABLE_SIZE = 1;
|
||||
static final int INITIAL_WINDOW_SIZE = 7;
|
||||
static final int MAX_CONCURRENT_STREAMS = 4;
|
||||
static final int MAX_FRAME_SIZE = 5;
|
||||
static final int MAX_HEADER_LIST_SIZE = 6;
|
||||
private int set;
|
||||
private final int[] values = new int[10];
|
||||
|
||||
void clear() {
|
||||
this.set = 0;
|
||||
Arrays.fill(this.values, 0);
|
||||
}
|
||||
|
||||
int get(int i) {
|
||||
return this.values[i];
|
||||
}
|
||||
|
||||
boolean getEnablePush(boolean z) {
|
||||
return ((this.set & 4) != 0 ? this.values[2] : z ? 1 : 0) == 1;
|
||||
}
|
||||
|
||||
int getHeaderTableSize() {
|
||||
if ((this.set & 2) != 0) {
|
||||
return this.values[1];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getInitialWindowSize() {
|
||||
return (this.set & PeripheralType.SERVO) != 0 ? this.values[7] : DEFAULT_INITIAL_WINDOW_SIZE;
|
||||
}
|
||||
|
||||
int getMaxConcurrentStreams(int i) {
|
||||
return (this.set & 16) != 0 ? this.values[4] : i;
|
||||
}
|
||||
|
||||
int getMaxFrameSize(int i) {
|
||||
return (this.set & 32) != 0 ? this.values[5] : i;
|
||||
}
|
||||
|
||||
int getMaxHeaderListSize(int i) {
|
||||
return (this.set & 64) != 0 ? this.values[6] : i;
|
||||
}
|
||||
|
||||
boolean isSet(int i) {
|
||||
return ((1 << i) & this.set) != 0;
|
||||
}
|
||||
|
||||
void merge(Settings settings) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (settings.isSet(i)) {
|
||||
set(i, settings.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Settings set(int i, int i2) {
|
||||
if (i >= 0) {
|
||||
int[] iArr = this.values;
|
||||
if (i < iArr.length) {
|
||||
this.set = (1 << i) | this.set;
|
||||
iArr[i] = i2;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
int size() {
|
||||
return Integer.bitCount(this.set);
|
||||
}
|
||||
}
|
13
sources/okhttp3/internal/http2/StreamResetException.java
Normal file
13
sources/okhttp3/internal/http2/StreamResetException.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package okhttp3.internal.http2;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
public final class StreamResetException extends IOException {
|
||||
public final ErrorCode errorCode;
|
||||
|
||||
public StreamResetException(ErrorCode errorCode) {
|
||||
super("stream was reset: " + errorCode);
|
||||
this.errorCode = errorCode;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user