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
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
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
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); } }