786 lines
31 KiB
Java
786 lines
31 KiB
Java
package io.grpc.okhttp.internal.framed;
|
|
|
|
import com.airbnb.deeplinkdispatch.base.MatchIndex;
|
|
import com.google.common.primitives.UnsignedBytes;
|
|
import io.grpc.okhttp.internal.Protocol;
|
|
import io.grpc.okhttp.internal.framed.FrameReader;
|
|
import io.grpc.okhttp.internal.framed.Hpack;
|
|
import java.io.IOException;
|
|
import java.util.List;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
import o.C14957gcv;
|
|
import o.C15111ghZ;
|
|
import o.C15139giB;
|
|
import o.C15155gij;
|
|
import o.InterfaceC15148gic;
|
|
import o.InterfaceC15149gid;
|
|
import o.gdP;
|
|
import o.giD;
|
|
|
|
/* loaded from: classes6.dex */
|
|
public final class Http2 implements Variant {
|
|
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;
|
|
private static final Logger logger = Logger.getLogger(FrameLogger.class.getName());
|
|
private static final C15155gij CONNECTION_PREFACE = C15155gij.a("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n");
|
|
|
|
@Override // io.grpc.okhttp.internal.framed.Variant
|
|
public final Protocol getProtocol() {
|
|
return Protocol.HTTP_2;
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.framed.Variant
|
|
public final FrameReader newReader(InterfaceC15149gid interfaceC15149gid, boolean z) {
|
|
return new Reader(interfaceC15149gid, 4096, z);
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.framed.Variant
|
|
public final FrameWriter newWriter(InterfaceC15148gic interfaceC15148gic, boolean z) {
|
|
return new Writer(interfaceC15148gic, z);
|
|
}
|
|
|
|
/* loaded from: classes6.dex */
|
|
static final class Reader implements FrameReader {
|
|
private final boolean client;
|
|
private final ContinuationSource continuation;
|
|
final Hpack.Reader hpackReader;
|
|
private final InterfaceC15149gid source;
|
|
|
|
Reader(InterfaceC15149gid interfaceC15149gid, int i, boolean z) {
|
|
this.source = interfaceC15149gid;
|
|
this.client = z;
|
|
ContinuationSource continuationSource = new ContinuationSource(interfaceC15149gid);
|
|
this.continuation = continuationSource;
|
|
this.hpackReader = new Hpack.Reader(i, continuationSource);
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.framed.FrameReader
|
|
public final void readConnectionPreface() throws IOException {
|
|
if (this.client) {
|
|
return;
|
|
}
|
|
C15155gij c = this.source.c(Http2.CONNECTION_PREFACE.a());
|
|
if (Http2.logger.isLoggable(Level.FINE)) {
|
|
Http2.logger.fine(String.format("<< CONNECTION %s", c.c()));
|
|
}
|
|
if (Http2.CONNECTION_PREFACE.equals(c)) {
|
|
return;
|
|
}
|
|
String str = c.d;
|
|
if (str == null) {
|
|
byte[] b = c.b();
|
|
C14957gcv.e(b, "");
|
|
String str2 = new String(b, gdP.a);
|
|
c.d = str2;
|
|
str = str2;
|
|
}
|
|
throw Http2.ioException("Expected a connection header but was %s", str);
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.framed.FrameReader
|
|
public final boolean nextFrame(FrameReader.Handler handler) throws IOException {
|
|
try {
|
|
this.source.g(9L);
|
|
int readMedium = Http2.readMedium(this.source);
|
|
if (readMedium < 0 || readMedium > 16384) {
|
|
throw Http2.ioException("FRAME_SIZE_ERROR: %s", Integer.valueOf(readMedium));
|
|
}
|
|
byte f = this.source.f();
|
|
byte f2 = this.source.f();
|
|
int n = this.source.n() & Integer.MAX_VALUE;
|
|
if (Http2.logger.isLoggable(Level.FINE)) {
|
|
Http2.logger.fine(FrameLogger.formatHeader(true, n, readMedium, f, f2));
|
|
}
|
|
switch (f) {
|
|
case 0:
|
|
readData(handler, readMedium, f2, n);
|
|
return true;
|
|
case 1:
|
|
readHeaders(handler, readMedium, f2, n);
|
|
return true;
|
|
case 2:
|
|
readPriority(handler, readMedium, f2, n);
|
|
return true;
|
|
case 3:
|
|
readRstStream(handler, readMedium, f2, n);
|
|
return true;
|
|
case 4:
|
|
readSettings(handler, readMedium, f2, n);
|
|
return true;
|
|
case 5:
|
|
readPushPromise(handler, readMedium, f2, n);
|
|
return true;
|
|
case 6:
|
|
readPing(handler, readMedium, f2, n);
|
|
return true;
|
|
case 7:
|
|
readGoAway(handler, readMedium, f2, n);
|
|
return true;
|
|
case 8:
|
|
readWindowUpdate(handler, readMedium, f2, n);
|
|
return true;
|
|
default:
|
|
this.source.j(readMedium);
|
|
return true;
|
|
}
|
|
} catch (IOException unused) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private void readHeaders(FrameReader.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 f = (b & 8) != 0 ? (short) (this.source.f() & UnsignedBytes.MAX_VALUE) : (short) 0;
|
|
if ((b & 32) != 0) {
|
|
readPriority(handler, i2);
|
|
i -= 5;
|
|
}
|
|
handler.headers(false, z, i2, -1, readHeaderBlock(Http2.lengthWithoutPadding(i, b, f), f, b, i2), HeadersMode.HTTP_20_HEADERS);
|
|
}
|
|
|
|
private List<Header> readHeaderBlock(int i, short s, byte b, int i2) throws IOException {
|
|
ContinuationSource continuationSource = this.continuation;
|
|
continuationSource.left = i;
|
|
continuationSource.length = i;
|
|
this.continuation.padding = s;
|
|
this.continuation.flags = b;
|
|
this.continuation.streamId = i2;
|
|
this.hpackReader.readHeaders();
|
|
return this.hpackReader.getAndResetHeaderList();
|
|
}
|
|
|
|
private void readData(FrameReader.Handler handler, int i, byte b, int i2) throws IOException {
|
|
boolean z = (b & 1) != 0;
|
|
if ((b & 32) != 0) {
|
|
throw Http2.ioException("PROTOCOL_ERROR: FLAG_COMPRESSED without SETTINGS_COMPRESS_DATA", new Object[0]);
|
|
}
|
|
short f = (b & 8) != 0 ? (short) (this.source.f() & UnsignedBytes.MAX_VALUE) : (short) 0;
|
|
handler.data(z, i2, this.source, Http2.lengthWithoutPadding(i, b, f));
|
|
this.source.j(f);
|
|
}
|
|
|
|
private void readPriority(FrameReader.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 readPriority(FrameReader.Handler handler, int i) throws IOException {
|
|
int n = this.source.n();
|
|
handler.priority(i, n & Integer.MAX_VALUE, (this.source.f() & UnsignedBytes.MAX_VALUE) + 1, (Integer.MIN_VALUE & n) != 0);
|
|
}
|
|
|
|
private void readRstStream(FrameReader.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 n = this.source.n();
|
|
ErrorCode fromHttp2 = ErrorCode.fromHttp2(n);
|
|
if (fromHttp2 == null) {
|
|
throw Http2.ioException("TYPE_RST_STREAM unexpected error code: %d", Integer.valueOf(n));
|
|
}
|
|
handler.rstStream(i2, fromHttp2);
|
|
}
|
|
|
|
/* JADX WARN: Can't fix incorrect switch cases order, some code will duplicate */
|
|
/* JADX WARN: Failed to find 'out' block for switch in B:16:0x002e. Please report as an issue. */
|
|
private void readSettings(FrameReader.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) {
|
|
short s = this.source.s();
|
|
int n = this.source.n();
|
|
switch (s) {
|
|
case 1:
|
|
case 6:
|
|
settings.set(s, 0, n);
|
|
case 2:
|
|
if (n != 0 && n != 1) {
|
|
throw Http2.ioException("PROTOCOL_ERROR SETTINGS_ENABLE_PUSH != 0 or 1", new Object[0]);
|
|
}
|
|
settings.set(s, 0, n);
|
|
case 3:
|
|
s = 4;
|
|
settings.set(s, 0, n);
|
|
case 4:
|
|
if (n < 0) {
|
|
throw Http2.ioException("PROTOCOL_ERROR SETTINGS_INITIAL_WINDOW_SIZE > 2^31 - 1", new Object[0]);
|
|
}
|
|
s = 7;
|
|
settings.set(s, 0, n);
|
|
case 5:
|
|
if (n < 16384 || n > 16777215) {
|
|
throw Http2.ioException("PROTOCOL_ERROR SETTINGS_MAX_FRAME_SIZE: %s", Integer.valueOf(n));
|
|
}
|
|
settings.set(s, 0, n);
|
|
break;
|
|
default:
|
|
}
|
|
}
|
|
handler.settings(false, settings);
|
|
if (settings.getHeaderTableSize() >= 0) {
|
|
this.hpackReader.headerTableSizeSetting(settings.getHeaderTableSize());
|
|
}
|
|
}
|
|
|
|
private void readPushPromise(FrameReader.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 f = (b & 8) != 0 ? (short) (this.source.f() & UnsignedBytes.MAX_VALUE) : (short) 0;
|
|
handler.pushPromise(i2, Integer.MAX_VALUE & this.source.n(), readHeaderBlock(Http2.lengthWithoutPadding(i - 4, b, f), f, b, i2));
|
|
}
|
|
|
|
private void readPing(FrameReader.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.n(), this.source.n());
|
|
}
|
|
|
|
private void readGoAway(FrameReader.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 n = this.source.n();
|
|
int n2 = this.source.n();
|
|
int i3 = i - 8;
|
|
ErrorCode fromHttp2 = ErrorCode.fromHttp2(n2);
|
|
if (fromHttp2 == null) {
|
|
throw Http2.ioException("TYPE_GOAWAY unexpected error code: %d", Integer.valueOf(n2));
|
|
}
|
|
C15155gij c15155gij = C15155gij.e;
|
|
if (i3 > 0) {
|
|
c15155gij = this.source.c(i3);
|
|
}
|
|
handler.goAway(n, fromHttp2, c15155gij);
|
|
}
|
|
|
|
private void readWindowUpdate(FrameReader.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 n = this.source.n() & 2147483647L;
|
|
if (n == 0) {
|
|
throw Http2.ioException("windowSizeIncrement was 0", new Object[0]);
|
|
}
|
|
handler.windowUpdate(i2, n);
|
|
}
|
|
|
|
@Override // java.io.Closeable, java.lang.AutoCloseable
|
|
public final void close() throws IOException {
|
|
this.source.close();
|
|
}
|
|
}
|
|
|
|
/* loaded from: classes6.dex */
|
|
static final class Writer implements FrameWriter {
|
|
private final boolean client;
|
|
private boolean closed;
|
|
private final C15111ghZ hpackBuffer;
|
|
private final Hpack.Writer hpackWriter;
|
|
private int maxFrameSize;
|
|
private final InterfaceC15148gic sink;
|
|
|
|
Writer(InterfaceC15148gic interfaceC15148gic, boolean z) {
|
|
this.sink = interfaceC15148gic;
|
|
this.client = z;
|
|
C15111ghZ c15111ghZ = new C15111ghZ();
|
|
this.hpackBuffer = c15111ghZ;
|
|
this.hpackWriter = new Hpack.Writer(c15111ghZ);
|
|
this.maxFrameSize = 16384;
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.framed.FrameWriter
|
|
public final void flush() throws IOException {
|
|
synchronized (this) {
|
|
if (this.closed) {
|
|
throw new IOException("closed");
|
|
}
|
|
this.sink.flush();
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.framed.FrameWriter
|
|
public final void ackSettings(Settings settings) throws IOException {
|
|
synchronized (this) {
|
|
if (this.closed) {
|
|
throw new IOException("closed");
|
|
}
|
|
this.maxFrameSize = settings.getMaxFrameSize(this.maxFrameSize);
|
|
frameHeader(0, 0, (byte) 4, (byte) 1);
|
|
this.sink.flush();
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.framed.FrameWriter
|
|
public final void connectionPreface() throws IOException {
|
|
synchronized (this) {
|
|
if (this.closed) {
|
|
throw new IOException("closed");
|
|
}
|
|
if (this.client) {
|
|
if (Http2.logger.isLoggable(Level.FINE)) {
|
|
Http2.logger.fine(String.format(">> CONNECTION %s", Http2.CONNECTION_PREFACE.c()));
|
|
}
|
|
this.sink.a(Http2.CONNECTION_PREFACE.j());
|
|
this.sink.flush();
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.framed.FrameWriter
|
|
public final void synStream(boolean z, boolean z2, int i, int i2, List<Header> list) throws IOException {
|
|
synchronized (this) {
|
|
if (z2) {
|
|
throw new UnsupportedOperationException();
|
|
}
|
|
if (this.closed) {
|
|
throw new IOException("closed");
|
|
}
|
|
headers(z, i, list);
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.framed.FrameWriter
|
|
public final void synReply(boolean z, int i, List<Header> list) throws IOException {
|
|
synchronized (this) {
|
|
if (this.closed) {
|
|
throw new IOException("closed");
|
|
}
|
|
headers(z, i, list);
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.framed.FrameWriter
|
|
public final void headers(int i, List<Header> list) throws IOException {
|
|
synchronized (this) {
|
|
if (this.closed) {
|
|
throw new IOException("closed");
|
|
}
|
|
headers(false, i, list);
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.framed.FrameWriter
|
|
public final void pushPromise(int i, int i2, List<Header> list) throws IOException {
|
|
synchronized (this) {
|
|
if (this.closed) {
|
|
throw new IOException("closed");
|
|
}
|
|
this.hpackWriter.writeHeaders(list);
|
|
long j = this.hpackBuffer.c;
|
|
int min = (int) Math.min(this.maxFrameSize - 4, j);
|
|
long j2 = min;
|
|
frameHeader(i, min + 4, (byte) 5, j == j2 ? (byte) 4 : (byte) 0);
|
|
this.sink.j(i2 & Integer.MAX_VALUE);
|
|
this.sink.write(this.hpackBuffer, j2);
|
|
if (j > j2) {
|
|
writeContinuationFrames(i, j - j2);
|
|
}
|
|
}
|
|
}
|
|
|
|
final void headers(boolean z, int i, List<Header> list) throws IOException {
|
|
if (this.closed) {
|
|
throw new IOException("closed");
|
|
}
|
|
this.hpackWriter.writeHeaders(list);
|
|
long j = this.hpackBuffer.c;
|
|
int min = (int) Math.min(this.maxFrameSize, j);
|
|
long j2 = min;
|
|
byte b = j == j2 ? (byte) 4 : (byte) 0;
|
|
if (z) {
|
|
b = (byte) (b | 1);
|
|
}
|
|
frameHeader(i, min, (byte) 1, b);
|
|
this.sink.write(this.hpackBuffer, j2);
|
|
if (j > j2) {
|
|
writeContinuationFrames(i, j - j2);
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.framed.FrameWriter
|
|
public final void rstStream(int i, ErrorCode errorCode) throws IOException {
|
|
synchronized (this) {
|
|
if (this.closed) {
|
|
throw new IOException("closed");
|
|
}
|
|
if (errorCode.httpCode == -1) {
|
|
throw new IllegalArgumentException();
|
|
}
|
|
frameHeader(i, 4, (byte) 3, (byte) 0);
|
|
this.sink.j(errorCode.httpCode);
|
|
this.sink.flush();
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.framed.FrameWriter
|
|
public final void data(boolean z, int i, C15111ghZ c15111ghZ, int i2) throws IOException {
|
|
synchronized (this) {
|
|
if (this.closed) {
|
|
throw new IOException("closed");
|
|
}
|
|
dataFrame(i, z ? (byte) 1 : (byte) 0, c15111ghZ, i2);
|
|
}
|
|
}
|
|
|
|
final void dataFrame(int i, byte b, C15111ghZ c15111ghZ, int i2) throws IOException {
|
|
frameHeader(i, i2, (byte) 0, b);
|
|
if (i2 > 0) {
|
|
this.sink.write(c15111ghZ, i2);
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.framed.FrameWriter
|
|
public final void settings(Settings settings) throws IOException {
|
|
synchronized (this) {
|
|
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.g(i == 4 ? 3 : i == 7 ? 4 : i);
|
|
this.sink.j(settings.get(i));
|
|
}
|
|
i++;
|
|
}
|
|
this.sink.flush();
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.framed.FrameWriter
|
|
public final void ping(boolean z, int i, int i2) throws IOException {
|
|
synchronized (this) {
|
|
if (this.closed) {
|
|
throw new IOException("closed");
|
|
}
|
|
frameHeader(0, 8, (byte) 6, z ? (byte) 1 : (byte) 0);
|
|
this.sink.j(i);
|
|
this.sink.j(i2);
|
|
this.sink.flush();
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.framed.FrameWriter
|
|
public final void goAway(int i, ErrorCode errorCode, byte[] bArr) throws IOException {
|
|
synchronized (this) {
|
|
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.j(i);
|
|
this.sink.j(errorCode.httpCode);
|
|
if (bArr.length > 0) {
|
|
this.sink.a(bArr);
|
|
}
|
|
this.sink.flush();
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.framed.FrameWriter
|
|
public final void windowUpdate(int i, long j) throws IOException {
|
|
synchronized (this) {
|
|
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.j((int) j);
|
|
this.sink.flush();
|
|
}
|
|
}
|
|
|
|
@Override // java.io.Closeable, java.lang.AutoCloseable
|
|
public final void close() throws IOException {
|
|
synchronized (this) {
|
|
this.closed = true;
|
|
this.sink.close();
|
|
}
|
|
}
|
|
|
|
final void frameHeader(int i, int i2, byte b, byte b2) throws IOException {
|
|
if (Http2.logger.isLoggable(Level.FINE)) {
|
|
Http2.logger.fine(FrameLogger.formatHeader(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) {
|
|
Http2.writeMedium(this.sink, i2);
|
|
this.sink.b(b & UnsignedBytes.MAX_VALUE);
|
|
this.sink.b(b2 & UnsignedBytes.MAX_VALUE);
|
|
this.sink.j(i & Integer.MAX_VALUE);
|
|
return;
|
|
}
|
|
throw Http2.illegalArgument("reserved bit set: %s", Integer.valueOf(i));
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.framed.FrameWriter
|
|
public final int maxDataLength() {
|
|
return this.maxFrameSize;
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public static IllegalArgumentException illegalArgument(String str, Object... objArr) {
|
|
throw new IllegalArgumentException(String.format(str, objArr));
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public static IOException ioException(String str, Object... objArr) throws IOException {
|
|
throw new IOException(String.format(str, objArr));
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes6.dex */
|
|
public static final class ContinuationSource implements giD {
|
|
byte flags;
|
|
int left;
|
|
int length;
|
|
short padding;
|
|
private final InterfaceC15149gid source;
|
|
int streamId;
|
|
|
|
@Override // o.giD, java.io.Closeable, java.lang.AutoCloseable
|
|
public final void close() throws IOException {
|
|
}
|
|
|
|
public ContinuationSource(InterfaceC15149gid interfaceC15149gid) {
|
|
this.source = interfaceC15149gid;
|
|
}
|
|
|
|
@Override // o.giD
|
|
public final long read(C15111ghZ c15111ghZ, long j) throws IOException {
|
|
while (true) {
|
|
int i = this.left;
|
|
if (i == 0) {
|
|
this.source.j(this.padding);
|
|
this.padding = (short) 0;
|
|
if ((this.flags & 4) != 0) {
|
|
return -1L;
|
|
}
|
|
readContinuationHeader();
|
|
} else {
|
|
long read = this.source.read(c15111ghZ, Math.min(j, i));
|
|
if (read == -1) {
|
|
return -1L;
|
|
}
|
|
this.left -= (int) read;
|
|
return read;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override // o.giD
|
|
public final C15139giB timeout() {
|
|
return this.source.timeout();
|
|
}
|
|
|
|
private void readContinuationHeader() throws IOException {
|
|
int i = this.streamId;
|
|
int readMedium = Http2.readMedium(this.source);
|
|
this.left = readMedium;
|
|
this.length = readMedium;
|
|
byte f = this.source.f();
|
|
this.flags = this.source.f();
|
|
if (Http2.logger.isLoggable(Level.FINE)) {
|
|
Http2.logger.fine(FrameLogger.formatHeader(true, this.streamId, this.length, f, this.flags));
|
|
}
|
|
int n = this.source.n() & Integer.MAX_VALUE;
|
|
this.streamId = n;
|
|
if (f != 9) {
|
|
throw Http2.ioException("%s != TYPE_CONTINUATION", Byte.valueOf(f));
|
|
}
|
|
if (n != i) {
|
|
throw Http2.ioException("TYPE_CONTINUATION streamId changed", new Object[0]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public static int lengthWithoutPadding(int i, byte b, short s) throws IOException {
|
|
if ((b & 8) != 0) {
|
|
i--;
|
|
}
|
|
if (s <= i) {
|
|
return (short) (i - s);
|
|
}
|
|
throw ioException("PROTOCOL_ERROR padding %s > remaining length %s", Short.valueOf(s), Integer.valueOf(i));
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes6.dex */
|
|
public static final class FrameLogger {
|
|
private static final String[] TYPES = {"DATA", "HEADERS", "PRIORITY", "RST_STREAM", "SETTINGS", "PUSH_PROMISE", "PING", "GOAWAY", "WINDOW_UPDATE", "CONTINUATION"};
|
|
private static final String[] FLAGS = new String[64];
|
|
private static final String[] BINARY = new String[256];
|
|
|
|
FrameLogger() {
|
|
}
|
|
|
|
static String formatHeader(boolean z, int i, int i2, byte b, byte b2) {
|
|
String[] strArr = TYPES;
|
|
String format = b < strArr.length ? strArr[b] : String.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 String.format("%s 0x%08x %5d %-13s %s", objArr);
|
|
}
|
|
|
|
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];
|
|
if (b != 5 || (b2 & 4) == 0) {
|
|
return (b != 0 || (b2 & 32) == 0) ? str : str.replace("PRIORITY", "COMPRESSED");
|
|
}
|
|
return str.replace("HEADERS", "PUSH_PROMISE");
|
|
}
|
|
}
|
|
return BINARY[b2];
|
|
}
|
|
|
|
static {
|
|
int i = 0;
|
|
int i2 = 0;
|
|
while (true) {
|
|
String[] strArr = BINARY;
|
|
if (i2 >= strArr.length) {
|
|
break;
|
|
}
|
|
strArr[i2] = String.format("%8s", Integer.toBinaryString(i2)).replace(' ', '0');
|
|
i2++;
|
|
}
|
|
String[] strArr2 = FLAGS;
|
|
strArr2[0] = "";
|
|
strArr2[1] = "END_STREAM";
|
|
int[] iArr = {1};
|
|
strArr2[8] = "PADDED";
|
|
int i3 = iArr[0];
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.append(strArr2[i3]);
|
|
sb.append("|PADDED");
|
|
strArr2[i3 | 8] = sb.toString();
|
|
strArr2[4] = "END_HEADERS";
|
|
strArr2[32] = "PRIORITY";
|
|
strArr2[36] = "END_HEADERS|PRIORITY";
|
|
int[] iArr2 = {4, 32, 36};
|
|
for (int i4 = 0; i4 < 3; i4++) {
|
|
int i5 = iArr2[i4];
|
|
int i6 = iArr[0];
|
|
String[] strArr3 = FLAGS;
|
|
int i7 = i6 | i5;
|
|
StringBuilder sb2 = new StringBuilder();
|
|
sb2.append(strArr3[i6]);
|
|
sb2.append(MatchIndex.ALLOWED_VALUES_SEPARATOR);
|
|
sb2.append(strArr3[i5]);
|
|
strArr3[i7] = sb2.toString();
|
|
StringBuilder sb3 = new StringBuilder();
|
|
sb3.append(strArr3[i6]);
|
|
sb3.append(MatchIndex.ALLOWED_VALUES_SEPARATOR);
|
|
sb3.append(strArr3[i5]);
|
|
sb3.append("|PADDED");
|
|
strArr3[i7 | 8] = sb3.toString();
|
|
}
|
|
while (true) {
|
|
String[] strArr4 = FLAGS;
|
|
if (i >= strArr4.length) {
|
|
return;
|
|
}
|
|
if (strArr4[i] == null) {
|
|
strArr4[i] = BINARY[i];
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public static int readMedium(InterfaceC15149gid interfaceC15149gid) throws IOException {
|
|
return (interfaceC15149gid.f() & UnsignedBytes.MAX_VALUE) | ((interfaceC15149gid.f() & UnsignedBytes.MAX_VALUE) << 16) | ((interfaceC15149gid.f() & UnsignedBytes.MAX_VALUE) << 8);
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public static void writeMedium(InterfaceC15148gic interfaceC15148gic, int i) throws IOException {
|
|
interfaceC15148gic.b((i >>> 16) & 255);
|
|
interfaceC15148gic.b((i >>> 8) & 255);
|
|
interfaceC15148gic.b(i & 255);
|
|
}
|
|
}
|