jimu-decompiled/sources/okhttp3/internal/ws/WebSocketReader.java
2025-05-13 19:24:51 +02:00

200 lines
7.3 KiB
Java

package okhttp3.internal.ws;
import com.ubtrobot.jimu.robotapi.PeripheralType;
import java.io.IOException;
import java.net.ProtocolException;
import java.util.concurrent.TimeUnit;
import okio.Buffer;
import okio.BufferedSource;
import okio.ByteString;
/* loaded from: classes2.dex */
final class WebSocketReader {
boolean closed;
final FrameCallback frameCallback;
long frameLength;
final boolean isClient;
boolean isControlFrame;
boolean isFinalFrame;
private final Buffer.UnsafeCursor maskCursor;
private final byte[] maskKey;
int opcode;
final BufferedSource source;
private final Buffer controlFrameBuffer = new Buffer();
private final Buffer messageFrameBuffer = new Buffer();
public interface FrameCallback {
void onReadClose(int i, String str);
void onReadMessage(String str) throws IOException;
void onReadMessage(ByteString byteString) throws IOException;
void onReadPing(ByteString byteString);
void onReadPong(ByteString byteString);
}
WebSocketReader(boolean z, BufferedSource bufferedSource, FrameCallback frameCallback) {
if (bufferedSource == null) {
throw new NullPointerException("source == null");
}
if (frameCallback == null) {
throw new NullPointerException("frameCallback == null");
}
this.isClient = z;
this.source = bufferedSource;
this.frameCallback = frameCallback;
this.maskKey = z ? null : new byte[4];
this.maskCursor = z ? null : new Buffer.UnsafeCursor();
}
private void readControlFrame() throws IOException {
String str;
long j = this.frameLength;
if (j > 0) {
this.source.readFully(this.controlFrameBuffer, j);
if (!this.isClient) {
this.controlFrameBuffer.readAndWriteUnsafe(this.maskCursor);
this.maskCursor.seek(0L);
WebSocketProtocol.toggleMask(this.maskCursor, this.maskKey);
this.maskCursor.close();
}
}
switch (this.opcode) {
case 8:
short s = 1005;
long size = this.controlFrameBuffer.size();
if (size == 1) {
throw new ProtocolException("Malformed close payload length of 1.");
}
if (size != 0) {
s = this.controlFrameBuffer.readShort();
str = this.controlFrameBuffer.readUtf8();
String closeCodeExceptionMessage = WebSocketProtocol.closeCodeExceptionMessage(s);
if (closeCodeExceptionMessage != null) {
throw new ProtocolException(closeCodeExceptionMessage);
}
} else {
str = "";
}
this.frameCallback.onReadClose(s, str);
this.closed = true;
return;
case 9:
this.frameCallback.onReadPing(this.controlFrameBuffer.readByteString());
return;
case 10:
this.frameCallback.onReadPong(this.controlFrameBuffer.readByteString());
return;
default:
throw new ProtocolException("Unknown control opcode: " + Integer.toHexString(this.opcode));
}
}
/* JADX WARN: Finally extract failed */
private void readHeader() throws IOException {
if (this.closed) {
throw new IOException("closed");
}
long timeoutNanos = this.source.timeout().timeoutNanos();
this.source.timeout().clearTimeout();
try {
int readByte = this.source.readByte() & 255;
this.source.timeout().timeout(timeoutNanos, TimeUnit.NANOSECONDS);
this.opcode = readByte & 15;
this.isFinalFrame = (readByte & PeripheralType.SERVO) != 0;
this.isControlFrame = (readByte & 8) != 0;
if (this.isControlFrame && !this.isFinalFrame) {
throw new ProtocolException("Control frames must be final.");
}
boolean z = (readByte & 64) != 0;
boolean z2 = (readByte & 32) != 0;
boolean z3 = (readByte & 16) != 0;
if (z || z2 || z3) {
throw new ProtocolException("Reserved flags are unsupported.");
}
boolean z4 = ((this.source.readByte() & 255) & PeripheralType.SERVO) != 0;
boolean z5 = this.isClient;
if (z4 == z5) {
throw new ProtocolException(z5 ? "Server-sent frames must not be masked." : "Client-sent frames must be masked.");
}
this.frameLength = r0 & 127;
long j = this.frameLength;
if (j == 126) {
this.frameLength = this.source.readShort() & 65535;
} else if (j == 127) {
this.frameLength = this.source.readLong();
if (this.frameLength < 0) {
throw new ProtocolException("Frame length 0x" + Long.toHexString(this.frameLength) + " > 0x7FFFFFFFFFFFFFFF");
}
}
if (this.isControlFrame && this.frameLength > 125) {
throw new ProtocolException("Control frame must be less than 125B.");
}
if (z4) {
this.source.readFully(this.maskKey);
}
} catch (Throwable th) {
this.source.timeout().timeout(timeoutNanos, TimeUnit.NANOSECONDS);
throw th;
}
}
private void readMessage() throws IOException {
while (!this.closed) {
long j = this.frameLength;
if (j > 0) {
this.source.readFully(this.messageFrameBuffer, j);
if (!this.isClient) {
this.messageFrameBuffer.readAndWriteUnsafe(this.maskCursor);
this.maskCursor.seek(this.messageFrameBuffer.size() - this.frameLength);
WebSocketProtocol.toggleMask(this.maskCursor, this.maskKey);
this.maskCursor.close();
}
}
if (this.isFinalFrame) {
return;
}
readUntilNonControlFrame();
if (this.opcode != 0) {
throw new ProtocolException("Expected continuation opcode. Got: " + Integer.toHexString(this.opcode));
}
}
throw new IOException("closed");
}
private void readMessageFrame() throws IOException {
int i = this.opcode;
if (i != 1 && i != 2) {
throw new ProtocolException("Unknown opcode: " + Integer.toHexString(i));
}
readMessage();
if (i == 1) {
this.frameCallback.onReadMessage(this.messageFrameBuffer.readUtf8());
} else {
this.frameCallback.onReadMessage(this.messageFrameBuffer.readByteString());
}
}
private void readUntilNonControlFrame() throws IOException {
while (!this.closed) {
readHeader();
if (!this.isControlFrame) {
return;
} else {
readControlFrame();
}
}
}
void processNextFrame() throws IOException {
readHeader();
if (this.isControlFrame) {
readControlFrame();
} else {
readMessageFrame();
}
}
}