package okhttp3.internal.ws; import java.io.Closeable; import java.io.IOException; import java.net.ProtocolException; import java.net.SocketTimeoutException; import java.util.ArrayDeque; import java.util.Collections; import java.util.List; import java.util.Random; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import okhttp3.Call; import okhttp3.Callback; import okhttp3.EventListener; import okhttp3.OkHttpClient; import okhttp3.Protocol; import okhttp3.Request; import okhttp3.Response; import okhttp3.WebSocket; import okhttp3.WebSocketListener; import okhttp3.internal.Internal; import okhttp3.internal.Util; import okhttp3.internal.connection.StreamAllocation; import okhttp3.internal.ws.WebSocketReader; import okio.BufferedSink; import okio.BufferedSource; import okio.ByteString; /* loaded from: classes2.dex */ public final class RealWebSocket implements WebSocket, WebSocketReader.FrameCallback { static final /* synthetic */ boolean $assertionsDisabled = false; private static final long CANCEL_AFTER_CLOSE_MILLIS = 60000; private static final long MAX_QUEUE_SIZE = 16777216; private static final List ONLY_HTTP1 = Collections.singletonList(Protocol.HTTP_1_1); private boolean awaitingPong; private Call call; private ScheduledFuture cancelFuture; private boolean enqueuedClose; private ScheduledExecutorService executor; private boolean failed; private final String key; final WebSocketListener listener; private final Request originalRequest; private final long pingIntervalMillis; private long queueSize; private final Random random; private WebSocketReader reader; private String receivedCloseReason; private int receivedPingCount; private int receivedPongCount; private int sentPingCount; private Streams streams; private WebSocketWriter writer; private final Runnable writerRunnable; private final ArrayDeque pongQueue = new ArrayDeque<>(); private final ArrayDeque messageAndCloseQueue = new ArrayDeque<>(); private int receivedCloseCode = -1; final class CancelRunnable implements Runnable { CancelRunnable() { } @Override // java.lang.Runnable public void run() { RealWebSocket.this.cancel(); } } static final class Close { final long cancelAfterCloseMillis; final int code; final ByteString reason; Close(int i, ByteString byteString, long j) { this.code = i; this.reason = byteString; this.cancelAfterCloseMillis = j; } } static final class Message { final ByteString data; final int formatOpcode; Message(int i, ByteString byteString) { this.formatOpcode = i; this.data = byteString; } } private final class PingRunnable implements Runnable { PingRunnable() { } @Override // java.lang.Runnable public void run() { RealWebSocket.this.writePingFrame(); } } public static abstract class Streams implements Closeable { public final boolean client; public final BufferedSink sink; public final BufferedSource source; public Streams(boolean z, BufferedSource bufferedSource, BufferedSink bufferedSink) { this.client = z; this.source = bufferedSource; this.sink = bufferedSink; } } public RealWebSocket(Request request, WebSocketListener webSocketListener, Random random, long j) { if (!"GET".equals(request.method())) { throw new IllegalArgumentException("Request must be GET: " + request.method()); } this.originalRequest = request; this.listener = webSocketListener; this.random = random; this.pingIntervalMillis = j; byte[] bArr = new byte[16]; random.nextBytes(bArr); this.key = ByteString.of(bArr).base64(); this.writerRunnable = new Runnable() { // from class: okhttp3.internal.ws.RealWebSocket.1 @Override // java.lang.Runnable public void run() { do { try { } catch (IOException e) { RealWebSocket.this.failWebSocket(e, null); return; } } while (RealWebSocket.this.writeOneFrame()); } }; } private void runWriter() { ScheduledExecutorService scheduledExecutorService = this.executor; if (scheduledExecutorService != null) { scheduledExecutorService.execute(this.writerRunnable); } } void awaitTermination(int i, TimeUnit timeUnit) throws InterruptedException { this.executor.awaitTermination(i, timeUnit); } @Override // okhttp3.WebSocket public void cancel() { this.call.cancel(); } void checkResponse(Response response) throws ProtocolException { if (response.code() != 101) { throw new ProtocolException("Expected HTTP 101 response but was '" + response.code() + " " + response.message() + "'"); } String header = response.header("Connection"); if (!"Upgrade".equalsIgnoreCase(header)) { throw new ProtocolException("Expected 'Connection' header value 'Upgrade' but was '" + header + "'"); } String header2 = response.header("Upgrade"); if (!"websocket".equalsIgnoreCase(header2)) { throw new ProtocolException("Expected 'Upgrade' header value 'websocket' but was '" + header2 + "'"); } String header3 = response.header("Sec-WebSocket-Accept"); String base64 = ByteString.encodeUtf8(this.key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").sha1().base64(); if (base64.equals(header3)) { return; } throw new ProtocolException("Expected 'Sec-WebSocket-Accept' header value '" + base64 + "' but was '" + header3 + "'"); } @Override // okhttp3.WebSocket public boolean close(int i, String str) { return close(i, str, CANCEL_AFTER_CLOSE_MILLIS); } public void connect(OkHttpClient okHttpClient) { OkHttpClient build = okHttpClient.newBuilder().eventListener(EventListener.NONE).protocols(ONLY_HTTP1).build(); final Request build2 = this.originalRequest.newBuilder().header("Upgrade", "websocket").header("Connection", "Upgrade").header("Sec-WebSocket-Key", this.key).header("Sec-WebSocket-Version", "13").build(); this.call = Internal.instance.newWebSocketCall(build, build2); this.call.enqueue(new Callback() { // from class: okhttp3.internal.ws.RealWebSocket.2 @Override // okhttp3.Callback public void onFailure(Call call, IOException iOException) { RealWebSocket.this.failWebSocket(iOException, null); } @Override // okhttp3.Callback public void onResponse(Call call, Response response) { try { RealWebSocket.this.checkResponse(response); StreamAllocation streamAllocation = Internal.instance.streamAllocation(call); streamAllocation.noNewStreams(); Streams newWebSocketStreams = streamAllocation.connection().newWebSocketStreams(streamAllocation); try { RealWebSocket.this.listener.onOpen(RealWebSocket.this, response); RealWebSocket.this.initReaderAndWriter("OkHttp WebSocket " + build2.url().redact(), newWebSocketStreams); streamAllocation.connection().socket().setSoTimeout(0); RealWebSocket.this.loopReader(); } catch (Exception e) { RealWebSocket.this.failWebSocket(e, null); } } catch (ProtocolException e2) { RealWebSocket.this.failWebSocket(e2, response); Util.closeQuietly(response); } } }); } public void failWebSocket(Exception exc, Response response) { synchronized (this) { if (this.failed) { return; } this.failed = true; Streams streams = this.streams; this.streams = null; if (this.cancelFuture != null) { this.cancelFuture.cancel(false); } if (this.executor != null) { this.executor.shutdown(); } try { this.listener.onFailure(this, exc, response); } finally { Util.closeQuietly(streams); } } } public void initReaderAndWriter(String str, Streams streams) throws IOException { synchronized (this) { this.streams = streams; this.writer = new WebSocketWriter(streams.client, streams.sink, this.random); this.executor = new ScheduledThreadPoolExecutor(1, Util.threadFactory(str, false)); if (this.pingIntervalMillis != 0) { this.executor.scheduleAtFixedRate(new PingRunnable(), this.pingIntervalMillis, this.pingIntervalMillis, TimeUnit.MILLISECONDS); } if (!this.messageAndCloseQueue.isEmpty()) { runWriter(); } } this.reader = new WebSocketReader(streams.client, streams.source, this); } public void loopReader() throws IOException { while (this.receivedCloseCode == -1) { this.reader.processNextFrame(); } } @Override // okhttp3.internal.ws.WebSocketReader.FrameCallback public void onReadClose(int i, String str) { Streams streams; if (i == -1) { throw new IllegalArgumentException(); } synchronized (this) { if (this.receivedCloseCode != -1) { throw new IllegalStateException("already closed"); } this.receivedCloseCode = i; this.receivedCloseReason = str; if (this.enqueuedClose && this.messageAndCloseQueue.isEmpty()) { streams = this.streams; this.streams = null; if (this.cancelFuture != null) { this.cancelFuture.cancel(false); } this.executor.shutdown(); } else { streams = null; } } try { this.listener.onClosing(this, i, str); if (streams != null) { this.listener.onClosed(this, i, str); } } finally { Util.closeQuietly(streams); } } @Override // okhttp3.internal.ws.WebSocketReader.FrameCallback public void onReadMessage(String str) throws IOException { this.listener.onMessage(this, str); } @Override // okhttp3.internal.ws.WebSocketReader.FrameCallback public synchronized void onReadPing(ByteString byteString) { if (!this.failed && (!this.enqueuedClose || !this.messageAndCloseQueue.isEmpty())) { this.pongQueue.add(byteString); runWriter(); this.receivedPingCount++; } } @Override // okhttp3.internal.ws.WebSocketReader.FrameCallback public synchronized void onReadPong(ByteString byteString) { this.receivedPongCount++; this.awaitingPong = false; } synchronized boolean pong(ByteString byteString) { if (!this.failed && (!this.enqueuedClose || !this.messageAndCloseQueue.isEmpty())) { this.pongQueue.add(byteString); runWriter(); return true; } return false; } boolean processNextFrame() throws IOException { try { this.reader.processNextFrame(); return this.receivedCloseCode == -1; } catch (Exception e) { failWebSocket(e, null); return false; } } @Override // okhttp3.WebSocket public synchronized long queueSize() { return this.queueSize; } synchronized int receivedPingCount() { return this.receivedPingCount; } synchronized int receivedPongCount() { return this.receivedPongCount; } @Override // okhttp3.WebSocket public Request request() { return this.originalRequest; } @Override // okhttp3.WebSocket public boolean send(String str) { if (str != null) { return send(ByteString.encodeUtf8(str), 1); } throw new NullPointerException("text == null"); } synchronized int sentPingCount() { return this.sentPingCount; } void tearDown() throws InterruptedException { ScheduledFuture scheduledFuture = this.cancelFuture; if (scheduledFuture != null) { scheduledFuture.cancel(false); } this.executor.shutdown(); this.executor.awaitTermination(10L, TimeUnit.SECONDS); } /* JADX WARN: Removed duplicated region for block: B:18:0x0052 A[Catch: all -> 0x00a5, TRY_ENTER, TryCatch #1 {all -> 0x00a5, blocks: (B:18:0x0052, B:21:0x0056, B:23:0x005a, B:24:0x0076, B:32:0x0085, B:33:0x0086, B:35:0x008a, B:37:0x0095, B:38:0x009f, B:39:0x00a4, B:26:0x0077, B:27:0x0081), top: B:16:0x0050 }] */ /* JADX WARN: Removed duplicated region for block: B:21:0x0056 A[Catch: all -> 0x00a5, TryCatch #1 {all -> 0x00a5, blocks: (B:18:0x0052, B:21:0x0056, B:23:0x005a, B:24:0x0076, B:32:0x0085, B:33:0x0086, B:35:0x008a, B:37:0x0095, B:38:0x009f, B:39:0x00a4, B:26:0x0077, B:27:0x0081), top: B:16:0x0050 }] */ /* Code decompiled incorrectly, please refer to instructions dump. To view partially-correct code enable 'Show inconsistent code' option in preferences */ boolean writeOneFrame() throws java.io.IOException { /* r11 = this; monitor-enter(r11) boolean r0 = r11.failed // Catch: java.lang.Throwable -> Laa r1 = 0 if (r0 == 0) goto L8 monitor-exit(r11) // Catch: java.lang.Throwable -> Laa return r1 L8: okhttp3.internal.ws.WebSocketWriter r0 = r11.writer // Catch: java.lang.Throwable -> Laa java.util.ArrayDeque r2 = r11.pongQueue // Catch: java.lang.Throwable -> Laa java.lang.Object r2 = r2.poll() // Catch: java.lang.Throwable -> Laa okio.ByteString r2 = (okio.ByteString) r2 // Catch: java.lang.Throwable -> Laa r3 = -1 r4 = 0 if (r2 != 0) goto L4c java.util.ArrayDeque r5 = r11.messageAndCloseQueue // Catch: java.lang.Throwable -> Laa java.lang.Object r5 = r5.poll() // Catch: java.lang.Throwable -> Laa boolean r6 = r5 instanceof okhttp3.internal.ws.RealWebSocket.Close // Catch: java.lang.Throwable -> Laa if (r6 == 0) goto L46 int r1 = r11.receivedCloseCode // Catch: java.lang.Throwable -> Laa java.lang.String r6 = r11.receivedCloseReason // Catch: java.lang.Throwable -> Laa if (r1 == r3) goto L31 okhttp3.internal.ws.RealWebSocket$Streams r3 = r11.streams // Catch: java.lang.Throwable -> Laa r11.streams = r4 // Catch: java.lang.Throwable -> Laa java.util.concurrent.ScheduledExecutorService r4 = r11.executor // Catch: java.lang.Throwable -> Laa r4.shutdown() // Catch: java.lang.Throwable -> Laa r4 = r3 goto L4f L31: java.util.concurrent.ScheduledExecutorService r3 = r11.executor // Catch: java.lang.Throwable -> Laa okhttp3.internal.ws.RealWebSocket$CancelRunnable r7 = new okhttp3.internal.ws.RealWebSocket$CancelRunnable // Catch: java.lang.Throwable -> Laa r7.() // Catch: java.lang.Throwable -> Laa r8 = r5 okhttp3.internal.ws.RealWebSocket$Close r8 = (okhttp3.internal.ws.RealWebSocket.Close) r8 // Catch: java.lang.Throwable -> Laa long r8 = r8.cancelAfterCloseMillis // Catch: java.lang.Throwable -> Laa java.util.concurrent.TimeUnit r10 = java.util.concurrent.TimeUnit.MILLISECONDS // Catch: java.lang.Throwable -> Laa java.util.concurrent.ScheduledFuture r3 = r3.schedule(r7, r8, r10) // Catch: java.lang.Throwable -> Laa r11.cancelFuture = r3 // Catch: java.lang.Throwable -> Laa goto L4f L46: if (r5 != 0) goto L4a monitor-exit(r11) // Catch: java.lang.Throwable -> Laa return r1 L4a: r6 = r4 goto L4e L4c: r5 = r4 r6 = r5 L4e: r1 = -1 L4f: monitor-exit(r11) // Catch: java.lang.Throwable -> Laa if (r2 == 0) goto L56 r0.writePong(r2) // Catch: java.lang.Throwable -> La5 goto L9a L56: boolean r2 = r5 instanceof okhttp3.internal.ws.RealWebSocket.Message // Catch: java.lang.Throwable -> La5 if (r2 == 0) goto L86 r1 = r5 okhttp3.internal.ws.RealWebSocket$Message r1 = (okhttp3.internal.ws.RealWebSocket.Message) r1 // Catch: java.lang.Throwable -> La5 okio.ByteString r1 = r1.data // Catch: java.lang.Throwable -> La5 okhttp3.internal.ws.RealWebSocket$Message r5 = (okhttp3.internal.ws.RealWebSocket.Message) r5 // Catch: java.lang.Throwable -> La5 int r2 = r5.formatOpcode // Catch: java.lang.Throwable -> La5 int r3 = r1.size() // Catch: java.lang.Throwable -> La5 long r5 = (long) r3 // Catch: java.lang.Throwable -> La5 okio.Sink r0 = r0.newMessageSink(r2, r5) // Catch: java.lang.Throwable -> La5 okio.BufferedSink r0 = okio.Okio.buffer(r0) // Catch: java.lang.Throwable -> La5 r0.write(r1) // Catch: java.lang.Throwable -> La5 r0.close() // Catch: java.lang.Throwable -> La5 monitor-enter(r11) // Catch: java.lang.Throwable -> La5 long r2 = r11.queueSize // Catch: java.lang.Throwable -> L83 int r0 = r1.size() // Catch: java.lang.Throwable -> L83 long r0 = (long) r0 // Catch: java.lang.Throwable -> L83 long r2 = r2 - r0 r11.queueSize = r2 // Catch: java.lang.Throwable -> L83 monitor-exit(r11) // Catch: java.lang.Throwable -> L83 goto L9a L83: r0 = move-exception monitor-exit(r11) // Catch: java.lang.Throwable -> L83 throw r0 // Catch: java.lang.Throwable -> La5 L86: boolean r2 = r5 instanceof okhttp3.internal.ws.RealWebSocket.Close // Catch: java.lang.Throwable -> La5 if (r2 == 0) goto L9f okhttp3.internal.ws.RealWebSocket$Close r5 = (okhttp3.internal.ws.RealWebSocket.Close) r5 // Catch: java.lang.Throwable -> La5 int r2 = r5.code // Catch: java.lang.Throwable -> La5 okio.ByteString r3 = r5.reason // Catch: java.lang.Throwable -> La5 r0.writeClose(r2, r3) // Catch: java.lang.Throwable -> La5 if (r4 == 0) goto L9a okhttp3.WebSocketListener r0 = r11.listener // Catch: java.lang.Throwable -> La5 r0.onClosed(r11, r1, r6) // Catch: java.lang.Throwable -> La5 L9a: r0 = 1 okhttp3.internal.Util.closeQuietly(r4) return r0 L9f: java.lang.AssertionError r0 = new java.lang.AssertionError // Catch: java.lang.Throwable -> La5 r0.() // Catch: java.lang.Throwable -> La5 throw r0 // Catch: java.lang.Throwable -> La5 La5: r0 = move-exception okhttp3.internal.Util.closeQuietly(r4) throw r0 Laa: r0 = move-exception monitor-exit(r11) // Catch: java.lang.Throwable -> Laa throw r0 */ throw new UnsupportedOperationException("Method not decompiled: okhttp3.internal.ws.RealWebSocket.writeOneFrame():boolean"); } void writePingFrame() { synchronized (this) { if (this.failed) { return; } WebSocketWriter webSocketWriter = this.writer; int i = this.awaitingPong ? this.sentPingCount : -1; this.sentPingCount++; this.awaitingPong = true; if (i == -1) { try { webSocketWriter.writePing(ByteString.EMPTY); return; } catch (IOException e) { failWebSocket(e, null); return; } } failWebSocket(new SocketTimeoutException("sent ping but didn't receive pong within " + this.pingIntervalMillis + "ms (after " + (i - 1) + " successful ping/pongs)"), null); } } synchronized boolean close(int i, String str, long j) { WebSocketProtocol.validateCloseCode(i); ByteString byteString = null; if (str != null) { byteString = ByteString.encodeUtf8(str); if (byteString.size() > 123) { throw new IllegalArgumentException("reason.size() > 123: " + str); } } if (!this.failed && !this.enqueuedClose) { this.enqueuedClose = true; this.messageAndCloseQueue.add(new Close(i, byteString, j)); runWriter(); return true; } return false; } @Override // okhttp3.internal.ws.WebSocketReader.FrameCallback public void onReadMessage(ByteString byteString) throws IOException { this.listener.onMessage(this, byteString); } @Override // okhttp3.WebSocket public boolean send(ByteString byteString) { if (byteString != null) { return send(byteString, 2); } throw new NullPointerException("bytes == null"); } private synchronized boolean send(ByteString byteString, int i) { if (!this.failed && !this.enqueuedClose) { if (this.queueSize + byteString.size() > MAX_QUEUE_SIZE) { close(1001, null); return false; } this.queueSize += byteString.size(); this.messageAndCloseQueue.add(new Message(i, byteString)); runWriter(); return true; } return false; } }