Rabbit-R1/switch port/java/sources/okhttp3/internal/ws/WebSocketReader.java

270 lines
14 KiB
Java
Raw Normal View History

2024-05-21 16:08:36 -05:00
package okhttp3.internal.ws;
import io.sentry.clientreport.DiscardedEvent;
import io.sentry.protocol.TransactionInfo;
import java.io.Closeable;
import java.io.IOException;
import java.net.ProtocolException;
import java.util.concurrent.TimeUnit;
import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import okhttp3.internal.Util;
import okio.Buffer;
import okio.BufferedSource;
import okio.ByteString;
/* compiled from: WebSocketReader.kt */
@Metadata(bv = {1, 0, 3}, d1 = {"\u0000P\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0000\n\u0002\u0010\u000b\n\u0000\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0005\n\u0002\u0018\u0002\n\u0000\n\u0002\u0010\t\n\u0002\b\u0003\n\u0002\u0018\u0002\n\u0000\n\u0002\u0010\u0012\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0000\n\u0002\u0010\b\n\u0002\b\u0004\n\u0002\u0010\u0002\n\u0002\b\b\u0018\u00002\u00020\u0001:\u0001&B-\u0012\u0006\u0010\u0002\u001a\u00020\u0003\u0012\u0006\u0010\u0004\u001a\u00020\u0005\u0012\u0006\u0010\u0006\u001a\u00020\u0007\u0012\u0006\u0010\b\u001a\u00020\u0003\u0012\u0006\u0010\t\u001a\u00020\u0003¢\u0006\u0002\u0010\nJ\b\u0010\u001e\u001a\u00020\u001fH\u0016J\u0006\u0010 \u001a\u00020\u001fJ\b\u0010!\u001a\u00020\u001fH\u0002J\b\u0010\"\u001a\u00020\u001fH\u0002J\b\u0010#\u001a\u00020\u001fH\u0002J\b\u0010$\u001a\u00020\u001fH\u0002J\b\u0010%\u001a\u00020\u001fH\u0002R\u000e\u0010\u000b\u001a\u00020\u0003X\u0082\u000e¢\u0006\u0002\n\u0000R\u000e\u0010\f\u001a\u00020\rX\u0082\u0004¢\u0006\u0002\n\u0000R\u000e\u0010\u0006\u001a\u00020\u0007X\u0082\u0004¢\u0006\u0002\n\u0000R\u000e\u0010\u000e\u001a\u00020\u000fX\u0082\u000e¢\u0006\u0002\n\u0000R\u000e\u0010\u0002\u001a\u00020\u0003X\u0082\u0004¢\u0006\u0002\n\u0000R\u000e\u0010\u0010\u001a\u00020\u0003X\u0082\u000e¢\u0006\u0002\n\u0000R\u000e\u0010\u0011\u001a\u00020\u0003X\u0082\u000e¢\u0006\u0002\n\u0000R\u0010\u0010\u0012\u001a\u0004\u0018\u00010\u0013X\u0082\u0004¢\u0006\u0002\n\u0000R\u0010\u0010\u0014\u001a\u0004\u0018\u00010\u0015X\u0082\u0004¢\u0006\u0002\n\u0000R\u000e\u0010\u0016\u001a\u00020\rX\u0082\u0004¢\u0006\u0002\n\u0000R\u0010\u0010\u0017\u001a\u0004\u0018\u00010\u0018X\u0082\u000e¢\u0006\u0002\n\u0000R\u000e\u0010\t\u001a\u00020\u0003X\u0082\u0004¢\u0006\u0002\n\u0000R\u000e\u0010\u0019\u001a\u00020\u001aX\u0082\u000e¢\u0006\u0002\n\u0000R\u000e\u0010\b\u001a\u00020\u0003X\u0082\u0004¢\u0006\u0002\n\u0000R\u000e\u0010\u001b\u001a\u00020\u0003X\u0082\u000e¢\u0006\u0002\n\u0000R\u0011\u0010\u0004\u001a\u00020\u0005¢\u0006\b\n\u0000\u001a\u0004\b\u001c\u0010\u001d¨\u0006'"}, d2 = {"Lokhttp3/internal/ws/WebSocketReader;", "Ljava/io/Closeable;", "isClient", "", TransactionInfo.JsonKeys.SOURCE, "Lokio/BufferedSource;", "frameCallback", "Lokhttp3/internal/ws/WebSocketReader$FrameCallback;", "perMessageDeflate", "noContextTakeover", "(ZLokio/BufferedSource;Lokhttp3/internal/ws/WebSocketReader$FrameCallback;ZZ)V", "closed", "controlFrameBuffer", "Lokio/Buffer;", "frameLength", "", "isControlFrame", "isFinalFrame", "maskCursor", "Lokio/Buffer$UnsafeCursor;", "maskKey", "", "messageFrameBuffer", "messageInflater", "Lokhttp3/internal/ws/MessageInflater;", "opcode", "", "readingCompressedMessage", "getSource", "()Lokio/BufferedSource;", "close", "", "processNextFrame", "readControlFrame", "readHeader", "readMessage", "readMessageFrame", "readUntilNonControlFrame", "FrameCallback", "okhttp"}, k = 1, mv = {1, 4, 0})
/* loaded from: classes3.dex */
public final class WebSocketReader implements Closeable {
private boolean closed;
private final Buffer controlFrameBuffer;
private final FrameCallback frameCallback;
private long frameLength;
private final boolean isClient;
private boolean isControlFrame;
private boolean isFinalFrame;
private final Buffer.UnsafeCursor maskCursor;
private final byte[] maskKey;
private final Buffer messageFrameBuffer;
private MessageInflater messageInflater;
private final boolean noContextTakeover;
private int opcode;
private final boolean perMessageDeflate;
private boolean readingCompressedMessage;
private final BufferedSource source;
/* compiled from: WebSocketReader.kt */
@Metadata(bv = {1, 0, 3}, d1 = {"\u0000&\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0010\u0002\n\u0000\n\u0002\u0010\b\n\u0000\n\u0002\u0010\u000e\n\u0002\b\u0003\n\u0002\u0018\u0002\n\u0002\b\u0004\bf\u0018\u00002\u00020\u0001J\u0018\u0010\u0002\u001a\u00020\u00032\u0006\u0010\u0004\u001a\u00020\u00052\u0006\u0010\u0006\u001a\u00020\u0007H&J\u0010\u0010\b\u001a\u00020\u00032\u0006\u0010\t\u001a\u00020\u0007H&J\u0010\u0010\b\u001a\u00020\u00032\u0006\u0010\n\u001a\u00020\u000bH&J\u0010\u0010\f\u001a\u00020\u00032\u0006\u0010\r\u001a\u00020\u000bH&J\u0010\u0010\u000e\u001a\u00020\u00032\u0006\u0010\r\u001a\u00020\u000bH&¨\u0006\u000f"}, d2 = {"Lokhttp3/internal/ws/WebSocketReader$FrameCallback;", "", "onReadClose", "", "code", "", DiscardedEvent.JsonKeys.REASON, "", "onReadMessage", "text", "bytes", "Lokio/ByteString;", "onReadPing", "payload", "onReadPong", "okhttp"}, k = 1, mv = {1, 4, 0})
/* loaded from: classes3.dex */
public interface FrameCallback {
void onReadClose(int code, String reason);
void onReadMessage(String text) throws IOException;
void onReadMessage(ByteString bytes) throws IOException;
void onReadPing(ByteString payload);
void onReadPong(ByteString payload);
}
public final BufferedSource getSource() {
return this.source;
}
public WebSocketReader(boolean z, BufferedSource source, FrameCallback frameCallback, boolean z2, boolean z3) {
Intrinsics.checkNotNullParameter(source, "source");
Intrinsics.checkNotNullParameter(frameCallback, "frameCallback");
this.isClient = z;
this.source = source;
this.frameCallback = frameCallback;
this.perMessageDeflate = z2;
this.noContextTakeover = z3;
this.controlFrameBuffer = new Buffer();
this.messageFrameBuffer = new Buffer();
this.maskKey = z ? null : new byte[4];
this.maskCursor = z ? null : new Buffer.UnsafeCursor();
}
public final void processNextFrame() throws IOException {
readHeader();
if (this.isControlFrame) {
readControlFrame();
} else {
readMessageFrame();
}
}
private final void readHeader() throws IOException, ProtocolException {
boolean z;
if (this.closed) {
throw new IOException("closed");
}
long timeoutNanos = this.source.getTimeout().getTimeoutNanos();
this.source.getTimeout().clearTimeout();
try {
int and = Util.and(this.source.readByte(), 255);
this.source.getTimeout().timeout(timeoutNanos, TimeUnit.NANOSECONDS);
int i = and & 15;
this.opcode = i;
boolean z2 = (and & 128) != 0;
this.isFinalFrame = z2;
boolean z3 = (and & 8) != 0;
this.isControlFrame = z3;
if (z3 && !z2) {
throw new ProtocolException("Control frames must be final.");
}
boolean z4 = (and & 64) != 0;
if (i == 1 || i == 2) {
if (!z4) {
z = false;
} else {
if (!this.perMessageDeflate) {
throw new ProtocolException("Unexpected rsv1 flag");
}
z = true;
}
this.readingCompressedMessage = z;
} else if (z4) {
throw new ProtocolException("Unexpected rsv1 flag");
}
if ((and & 32) != 0) {
throw new ProtocolException("Unexpected rsv2 flag");
}
if ((and & 16) != 0) {
throw new ProtocolException("Unexpected rsv3 flag");
}
int and2 = Util.and(this.source.readByte(), 255);
boolean z5 = (and2 & 128) != 0;
if (z5 == this.isClient) {
throw new ProtocolException(this.isClient ? "Server-sent frames must not be masked." : "Client-sent frames must be masked.");
}
long j = and2 & 127;
this.frameLength = j;
if (j == WebSocketProtocol.PAYLOAD_SHORT) {
this.frameLength = Util.and(this.source.readShort(), 65535);
} else if (j == 127) {
long readLong = this.source.readLong();
this.frameLength = readLong;
if (readLong < 0) {
throw new ProtocolException("Frame length 0x" + Util.toHexString(this.frameLength) + " > 0x7FFFFFFFFFFFFFFF");
}
}
if (this.isControlFrame && this.frameLength > 125) {
throw new ProtocolException("Control frame must be less than 125B.");
}
if (z5) {
BufferedSource bufferedSource = this.source;
byte[] bArr = this.maskKey;
Intrinsics.checkNotNull(bArr);
bufferedSource.readFully(bArr);
}
} catch (Throwable th) {
this.source.getTimeout().timeout(timeoutNanos, TimeUnit.NANOSECONDS);
throw th;
}
}
private final void readControlFrame() throws IOException {
short s;
String str;
long j = this.frameLength;
if (j > 0) {
this.source.readFully(this.controlFrameBuffer, j);
if (!this.isClient) {
Buffer buffer = this.controlFrameBuffer;
Buffer.UnsafeCursor unsafeCursor = this.maskCursor;
Intrinsics.checkNotNull(unsafeCursor);
buffer.readAndWriteUnsafe(unsafeCursor);
this.maskCursor.seek(0L);
WebSocketProtocol webSocketProtocol = WebSocketProtocol.INSTANCE;
Buffer.UnsafeCursor unsafeCursor2 = this.maskCursor;
byte[] bArr = this.maskKey;
Intrinsics.checkNotNull(bArr);
webSocketProtocol.toggleMask(unsafeCursor2, bArr);
this.maskCursor.close();
}
}
switch (this.opcode) {
case 8:
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.INSTANCE.closeCodeExceptionMessage(s);
if (closeCodeExceptionMessage != null) {
throw new ProtocolException(closeCodeExceptionMessage);
}
} else {
s = 1005;
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: " + Util.toHexString(this.opcode));
}
}
private final void readMessageFrame() throws IOException {
int i = this.opcode;
if (i != 1 && i != 2) {
throw new ProtocolException("Unknown opcode: " + Util.toHexString(i));
}
readMessage();
if (this.readingCompressedMessage) {
MessageInflater messageInflater = this.messageInflater;
if (messageInflater == null) {
messageInflater = new MessageInflater(this.noContextTakeover);
this.messageInflater = messageInflater;
}
messageInflater.inflate(this.messageFrameBuffer);
}
if (i == 1) {
this.frameCallback.onReadMessage(this.messageFrameBuffer.readUtf8());
} else {
this.frameCallback.onReadMessage(this.messageFrameBuffer.readByteString());
}
}
private final void readUntilNonControlFrame() throws IOException {
while (!this.closed) {
readHeader();
if (!this.isControlFrame) {
return;
} else {
readControlFrame();
}
}
}
private final void readMessage() throws IOException {
while (!this.closed) {
long j = this.frameLength;
if (j > 0) {
this.source.readFully(this.messageFrameBuffer, j);
if (!this.isClient) {
Buffer buffer = this.messageFrameBuffer;
Buffer.UnsafeCursor unsafeCursor = this.maskCursor;
Intrinsics.checkNotNull(unsafeCursor);
buffer.readAndWriteUnsafe(unsafeCursor);
this.maskCursor.seek(this.messageFrameBuffer.size() - this.frameLength);
WebSocketProtocol webSocketProtocol = WebSocketProtocol.INSTANCE;
Buffer.UnsafeCursor unsafeCursor2 = this.maskCursor;
byte[] bArr = this.maskKey;
Intrinsics.checkNotNull(bArr);
webSocketProtocol.toggleMask(unsafeCursor2, bArr);
this.maskCursor.close();
}
}
if (this.isFinalFrame) {
return;
}
readUntilNonControlFrame();
if (this.opcode != 0) {
throw new ProtocolException("Expected continuation opcode. Got: " + Util.toHexString(this.opcode));
}
}
throw new IOException("closed");
}
@Override // java.io.Closeable, java.lang.AutoCloseable
public void close() throws IOException {
MessageInflater messageInflater = this.messageInflater;
if (messageInflater != null) {
messageInflater.close();
}
}
}