279 lines
10 KiB
Java
279 lines
10 KiB
Java
package okhttp3.internal.ws;
|
|
|
|
import java.io.Closeable;
|
|
import java.io.IOException;
|
|
import java.net.ProtocolException;
|
|
import java.util.concurrent.TimeUnit;
|
|
import o.C14957gcv;
|
|
import o.C15111ghZ;
|
|
import o.C15155gij;
|
|
import o.InterfaceC15149gid;
|
|
import o.gdP;
|
|
import o.giJ;
|
|
import okhttp3.internal.Util;
|
|
|
|
/* loaded from: classes6.dex */
|
|
public final class WebSocketReader implements Closeable {
|
|
private boolean closed;
|
|
private final C15111ghZ controlFrameBuffer;
|
|
private final FrameCallback frameCallback;
|
|
private long frameLength;
|
|
private final boolean isClient;
|
|
private boolean isControlFrame;
|
|
private boolean isFinalFrame;
|
|
private final C15111ghZ.RVV maskCursor;
|
|
private final byte[] maskKey;
|
|
private final C15111ghZ messageFrameBuffer;
|
|
private MessageInflater messageInflater;
|
|
private final boolean noContextTakeover;
|
|
private int opcode;
|
|
private final boolean perMessageDeflate;
|
|
private boolean readingCompressedMessage;
|
|
private final InterfaceC15149gid source;
|
|
|
|
/* loaded from: classes6.dex */
|
|
public interface FrameCallback {
|
|
void onReadClose(int i, String str);
|
|
|
|
void onReadMessage(String str) throws IOException;
|
|
|
|
void onReadMessage(C15155gij c15155gij) throws IOException;
|
|
|
|
void onReadPing(C15155gij c15155gij);
|
|
|
|
void onReadPong(C15155gij c15155gij);
|
|
}
|
|
|
|
public WebSocketReader(boolean z, InterfaceC15149gid interfaceC15149gid, FrameCallback frameCallback, boolean z2, boolean z3) {
|
|
C14957gcv.e(interfaceC15149gid, "");
|
|
C14957gcv.e(frameCallback, "");
|
|
this.isClient = z;
|
|
this.source = interfaceC15149gid;
|
|
this.frameCallback = frameCallback;
|
|
this.perMessageDeflate = z2;
|
|
this.noContextTakeover = z3;
|
|
this.controlFrameBuffer = new C15111ghZ();
|
|
this.messageFrameBuffer = new C15111ghZ();
|
|
this.maskKey = z ? null : new byte[4];
|
|
this.maskCursor = z ? null : new C15111ghZ.RVV();
|
|
}
|
|
|
|
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.timeout().timeoutNanos();
|
|
this.source.timeout().clearTimeout();
|
|
try {
|
|
int and = Util.and(this.source.f(), 255);
|
|
this.source.timeout().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.f(), 255);
|
|
boolean z5 = (and2 & 128) != 0;
|
|
boolean z6 = this.isClient;
|
|
if (z5 == z6) {
|
|
throw new ProtocolException(z6 ? "Server-sent frames must not be masked." : "Client-sent frames must be masked.");
|
|
}
|
|
long j = and2 & 127;
|
|
this.frameLength = j;
|
|
if (j == 126) {
|
|
this.frameLength = Util.and(this.source.s(), 65535);
|
|
} else if (j == 127) {
|
|
long p = this.source.p();
|
|
this.frameLength = p;
|
|
if (p < 0) {
|
|
StringBuilder sb = new StringBuilder("Frame length 0x");
|
|
sb.append(Util.toHexString(this.frameLength));
|
|
sb.append(" > 0x7FFFFFFFFFFFFFFF");
|
|
throw new ProtocolException(sb.toString());
|
|
}
|
|
}
|
|
if (this.isControlFrame && this.frameLength > 125) {
|
|
throw new ProtocolException("Control frame must be less than 125B.");
|
|
}
|
|
if (z5) {
|
|
InterfaceC15149gid interfaceC15149gid = this.source;
|
|
byte[] bArr = this.maskKey;
|
|
C14957gcv.e(bArr);
|
|
interfaceC15149gid.d(bArr);
|
|
}
|
|
} catch (Throwable th) {
|
|
this.source.timeout().timeout(timeoutNanos, TimeUnit.NANOSECONDS);
|
|
throw th;
|
|
}
|
|
}
|
|
|
|
private final void readControlFrame() throws IOException {
|
|
short s;
|
|
long j = this.frameLength;
|
|
String str = "";
|
|
if (j > 0) {
|
|
this.source.e(this.controlFrameBuffer, j);
|
|
if (!this.isClient) {
|
|
C15111ghZ c15111ghZ = this.controlFrameBuffer;
|
|
C15111ghZ.RVV rvv = this.maskCursor;
|
|
C14957gcv.e(rvv);
|
|
C14957gcv.e(rvv, "");
|
|
giJ.d(c15111ghZ, rvv);
|
|
this.maskCursor.e(0L);
|
|
WebSocketProtocol webSocketProtocol = WebSocketProtocol.INSTANCE;
|
|
C15111ghZ.RVV rvv2 = this.maskCursor;
|
|
byte[] bArr = this.maskKey;
|
|
C14957gcv.e(bArr);
|
|
webSocketProtocol.toggleMask(rvv2, bArr);
|
|
this.maskCursor.close();
|
|
}
|
|
}
|
|
switch (this.opcode) {
|
|
case 8:
|
|
long j2 = this.controlFrameBuffer.c;
|
|
if (j2 == 1) {
|
|
throw new ProtocolException("Malformed close payload length of 1.");
|
|
}
|
|
if (j2 != 0) {
|
|
s = this.controlFrameBuffer.s();
|
|
C15111ghZ c15111ghZ2 = this.controlFrameBuffer;
|
|
str = c15111ghZ2.b(c15111ghZ2.c, gdP.a);
|
|
String closeCodeExceptionMessage = WebSocketProtocol.INSTANCE.closeCodeExceptionMessage(s);
|
|
if (closeCodeExceptionMessage != null) {
|
|
throw new ProtocolException(closeCodeExceptionMessage);
|
|
}
|
|
} else {
|
|
s = 1005;
|
|
}
|
|
this.frameCallback.onReadClose(s, str);
|
|
this.closed = true;
|
|
return;
|
|
case 9:
|
|
FrameCallback frameCallback = this.frameCallback;
|
|
C15111ghZ c15111ghZ3 = this.controlFrameBuffer;
|
|
frameCallback.onReadPing(c15111ghZ3.c(c15111ghZ3.c));
|
|
return;
|
|
case 10:
|
|
FrameCallback frameCallback2 = this.frameCallback;
|
|
C15111ghZ c15111ghZ4 = this.controlFrameBuffer;
|
|
frameCallback2.onReadPong(c15111ghZ4.c(c15111ghZ4.c));
|
|
return;
|
|
default:
|
|
throw new ProtocolException(C14957gcv.c("Unknown control opcode: ", (Object) Util.toHexString(this.opcode)));
|
|
}
|
|
}
|
|
|
|
private final void readMessageFrame() throws IOException {
|
|
int i = this.opcode;
|
|
if (i != 1 && i != 2) {
|
|
throw new ProtocolException(C14957gcv.c("Unknown opcode: ", (Object) 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) {
|
|
FrameCallback frameCallback = this.frameCallback;
|
|
C15111ghZ c15111ghZ = this.messageFrameBuffer;
|
|
frameCallback.onReadMessage(c15111ghZ.b(c15111ghZ.c, gdP.a));
|
|
} else {
|
|
FrameCallback frameCallback2 = this.frameCallback;
|
|
C15111ghZ c15111ghZ2 = this.messageFrameBuffer;
|
|
frameCallback2.onReadMessage(c15111ghZ2.c(c15111ghZ2.c));
|
|
}
|
|
}
|
|
|
|
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.e(this.messageFrameBuffer, j);
|
|
if (!this.isClient) {
|
|
C15111ghZ c15111ghZ = this.messageFrameBuffer;
|
|
C15111ghZ.RVV rvv = this.maskCursor;
|
|
C14957gcv.e(rvv);
|
|
C14957gcv.e(rvv, "");
|
|
giJ.d(c15111ghZ, rvv);
|
|
this.maskCursor.e(this.messageFrameBuffer.c - this.frameLength);
|
|
WebSocketProtocol webSocketProtocol = WebSocketProtocol.INSTANCE;
|
|
C15111ghZ.RVV rvv2 = this.maskCursor;
|
|
byte[] bArr = this.maskKey;
|
|
C14957gcv.e(bArr);
|
|
webSocketProtocol.toggleMask(rvv2, bArr);
|
|
this.maskCursor.close();
|
|
}
|
|
}
|
|
if (this.isFinalFrame) {
|
|
return;
|
|
}
|
|
readUntilNonControlFrame();
|
|
if (this.opcode != 0) {
|
|
throw new ProtocolException(C14957gcv.c("Expected continuation opcode. Got: ", (Object) Util.toHexString(this.opcode)));
|
|
}
|
|
}
|
|
throw new IOException("closed");
|
|
}
|
|
|
|
@Override // java.io.Closeable, java.lang.AutoCloseable
|
|
public final void close() throws IOException {
|
|
MessageInflater messageInflater = this.messageInflater;
|
|
if (messageInflater != null) {
|
|
messageInflater.close();
|
|
}
|
|
}
|
|
|
|
public final InterfaceC15149gid getSource() {
|
|
return this.source;
|
|
}
|
|
}
|