package okhttp3.internal.http2; import java.io.EOFException; import java.io.IOException; import java.io.InterruptedIOException; import java.net.SocketTimeoutException; import java.util.ArrayList; import java.util.List; import okio.AsyncTimeout; import okio.Buffer; import okio.BufferedSource; import okio.Sink; import okio.Source; import okio.Timeout; /* loaded from: classes2.dex */ public final class Http2Stream { static final /* synthetic */ boolean $assertionsDisabled = false; long bytesLeftInWriteWindow; final Http2Connection connection; private boolean hasResponseHeaders; final int id; private final List
requestHeaders; private List
responseHeaders; final FramingSink sink; private final FramingSource source; long unacknowledgedBytesRead = 0; final StreamTimeout readTimeout = new StreamTimeout(); final StreamTimeout writeTimeout = new StreamTimeout(); ErrorCode errorCode = null; final class FramingSink implements Sink { static final /* synthetic */ boolean $assertionsDisabled = false; private static final long EMIT_BUFFER_SIZE = 16384; boolean closed; boolean finished; private final Buffer sendBuffer = new Buffer(); FramingSink() { } private void emitFrame(boolean z) throws IOException { long min; synchronized (Http2Stream.this) { Http2Stream.this.writeTimeout.enter(); while (Http2Stream.this.bytesLeftInWriteWindow <= 0 && !this.finished && !this.closed && Http2Stream.this.errorCode == null) { try { Http2Stream.this.waitForIo(); } finally { } } Http2Stream.this.writeTimeout.exitAndThrowIfTimedOut(); Http2Stream.this.checkOutNotClosed(); min = Math.min(Http2Stream.this.bytesLeftInWriteWindow, this.sendBuffer.size()); Http2Stream.this.bytesLeftInWriteWindow -= min; } Http2Stream.this.writeTimeout.enter(); try { Http2Stream.this.connection.writeData(Http2Stream.this.id, z && min == this.sendBuffer.size(), this.sendBuffer, min); } finally { } } @Override // okio.Sink, java.io.Closeable, java.lang.AutoCloseable public void close() throws IOException { synchronized (Http2Stream.this) { if (this.closed) { return; } if (!Http2Stream.this.sink.finished) { if (this.sendBuffer.size() > 0) { while (this.sendBuffer.size() > 0) { emitFrame(true); } } else { Http2Stream http2Stream = Http2Stream.this; http2Stream.connection.writeData(http2Stream.id, true, null, 0L); } } synchronized (Http2Stream.this) { this.closed = true; } Http2Stream.this.connection.flush(); Http2Stream.this.cancelStreamIfNecessary(); } } @Override // okio.Sink, java.io.Flushable public void flush() throws IOException { synchronized (Http2Stream.this) { Http2Stream.this.checkOutNotClosed(); } while (this.sendBuffer.size() > 0) { emitFrame(false); Http2Stream.this.connection.flush(); } } @Override // okio.Sink public Timeout timeout() { return Http2Stream.this.writeTimeout; } @Override // okio.Sink public void write(Buffer buffer, long j) throws IOException { this.sendBuffer.write(buffer, j); while (this.sendBuffer.size() >= 16384) { emitFrame(false); } } } private final class FramingSource implements Source { static final /* synthetic */ boolean $assertionsDisabled = false; boolean closed; boolean finished; private final long maxByteCount; private final Buffer receiveBuffer = new Buffer(); private final Buffer readBuffer = new Buffer(); FramingSource(long j) { this.maxByteCount = j; } private void updateConnectionFlowControl(long j) { Http2Stream.this.connection.updateConnectionFlowControl(j); } private void waitUntilReadable() throws IOException { Http2Stream.this.readTimeout.enter(); while (this.readBuffer.size() == 0 && !this.finished && !this.closed && Http2Stream.this.errorCode == null) { try { Http2Stream.this.waitForIo(); } finally { Http2Stream.this.readTimeout.exitAndThrowIfTimedOut(); } } } @Override // okio.Source, java.io.Closeable, java.lang.AutoCloseable public void close() throws IOException { long size; synchronized (Http2Stream.this) { this.closed = true; size = this.readBuffer.size(); this.readBuffer.clear(); Http2Stream.this.notifyAll(); } if (size > 0) { updateConnectionFlowControl(size); } Http2Stream.this.cancelStreamIfNecessary(); } @Override // okio.Source public long read(Buffer buffer, long j) throws IOException { ErrorCode errorCode; long j2; if (j < 0) { throw new IllegalArgumentException("byteCount < 0: " + j); } synchronized (Http2Stream.this) { waitUntilReadable(); if (this.closed) { throw new IOException("stream closed"); } errorCode = Http2Stream.this.errorCode; if (this.readBuffer.size() > 0) { j2 = this.readBuffer.read(buffer, Math.min(j, this.readBuffer.size())); Http2Stream.this.unacknowledgedBytesRead += j2; } else { j2 = -1; } if (errorCode == null && Http2Stream.this.unacknowledgedBytesRead >= Http2Stream.this.connection.okHttpSettings.getInitialWindowSize() / 2) { Http2Stream.this.connection.writeWindowUpdateLater(Http2Stream.this.id, Http2Stream.this.unacknowledgedBytesRead); Http2Stream.this.unacknowledgedBytesRead = 0L; } } if (j2 != -1) { updateConnectionFlowControl(j2); return j2; } if (errorCode == null) { return -1L; } throw new StreamResetException(errorCode); } void receive(BufferedSource bufferedSource, long j) throws IOException { boolean z; boolean z2; boolean z3; while (j > 0) { synchronized (Http2Stream.this) { z = this.finished; z2 = true; z3 = this.readBuffer.size() + j > this.maxByteCount; } if (z3) { bufferedSource.skip(j); Http2Stream.this.closeLater(ErrorCode.FLOW_CONTROL_ERROR); return; } if (z) { bufferedSource.skip(j); return; } long read = bufferedSource.read(this.receiveBuffer, j); if (read == -1) { throw new EOFException(); } j -= read; synchronized (Http2Stream.this) { if (this.readBuffer.size() != 0) { z2 = false; } this.readBuffer.writeAll(this.receiveBuffer); if (z2) { Http2Stream.this.notifyAll(); } } } } @Override // okio.Source public Timeout timeout() { return Http2Stream.this.readTimeout; } } class StreamTimeout extends AsyncTimeout { StreamTimeout() { } public void exitAndThrowIfTimedOut() throws IOException { if (exit()) { throw newTimeoutException(null); } } @Override // okio.AsyncTimeout protected IOException newTimeoutException(IOException iOException) { SocketTimeoutException socketTimeoutException = new SocketTimeoutException("timeout"); if (iOException != null) { socketTimeoutException.initCause(iOException); } return socketTimeoutException; } @Override // okio.AsyncTimeout protected void timedOut() { Http2Stream.this.closeLater(ErrorCode.CANCEL); } } Http2Stream(int i, Http2Connection http2Connection, boolean z, boolean z2, List
list) { if (http2Connection == null) { throw new NullPointerException("connection == null"); } if (list == null) { throw new NullPointerException("requestHeaders == null"); } this.id = i; this.connection = http2Connection; this.bytesLeftInWriteWindow = http2Connection.peerSettings.getInitialWindowSize(); this.source = new FramingSource(http2Connection.okHttpSettings.getInitialWindowSize()); this.sink = new FramingSink(); this.source.finished = z2; this.sink.finished = z; this.requestHeaders = list; } private boolean closeInternal(ErrorCode errorCode) { synchronized (this) { if (this.errorCode != null) { return false; } if (this.source.finished && this.sink.finished) { return false; } this.errorCode = errorCode; notifyAll(); this.connection.removeStream(this.id); return true; } } void addBytesToWriteWindow(long j) { this.bytesLeftInWriteWindow += j; if (j > 0) { notifyAll(); } } void cancelStreamIfNecessary() throws IOException { boolean z; boolean isOpen; synchronized (this) { z = !this.source.finished && this.source.closed && (this.sink.finished || this.sink.closed); isOpen = isOpen(); } if (z) { close(ErrorCode.CANCEL); } else { if (isOpen) { return; } this.connection.removeStream(this.id); } } void checkOutNotClosed() throws IOException { FramingSink framingSink = this.sink; if (framingSink.closed) { throw new IOException("stream closed"); } if (framingSink.finished) { throw new IOException("stream finished"); } ErrorCode errorCode = this.errorCode; if (errorCode != null) { throw new StreamResetException(errorCode); } } public void close(ErrorCode errorCode) throws IOException { if (closeInternal(errorCode)) { this.connection.writeSynReset(this.id, errorCode); } } public void closeLater(ErrorCode errorCode) { if (closeInternal(errorCode)) { this.connection.writeSynResetLater(this.id, errorCode); } } public Http2Connection getConnection() { return this.connection; } public synchronized ErrorCode getErrorCode() { return this.errorCode; } public int getId() { return this.id; } public List
getRequestHeaders() { return this.requestHeaders; } public Sink getSink() { synchronized (this) { if (!this.hasResponseHeaders && !isLocallyInitiated()) { throw new IllegalStateException("reply before requesting the sink"); } } return this.sink; } public Source getSource() { return this.source; } public boolean isLocallyInitiated() { return this.connection.client == ((this.id & 1) == 1); } public synchronized boolean isOpen() { if (this.errorCode != null) { return false; } if ((this.source.finished || this.source.closed) && (this.sink.finished || this.sink.closed)) { if (this.hasResponseHeaders) { return false; } } return true; } public Timeout readTimeout() { return this.readTimeout; } void receiveData(BufferedSource bufferedSource, int i) throws IOException { this.source.receive(bufferedSource, i); } void receiveFin() { boolean isOpen; synchronized (this) { this.source.finished = true; isOpen = isOpen(); notifyAll(); } if (isOpen) { return; } this.connection.removeStream(this.id); } void receiveHeaders(List
list) { boolean z; synchronized (this) { z = true; this.hasResponseHeaders = true; if (this.responseHeaders == null) { this.responseHeaders = list; z = isOpen(); notifyAll(); } else { ArrayList arrayList = new ArrayList(); arrayList.addAll(this.responseHeaders); arrayList.add(null); arrayList.addAll(list); this.responseHeaders = arrayList; } } if (z) { return; } this.connection.removeStream(this.id); } synchronized void receiveRstStream(ErrorCode errorCode) { if (this.errorCode == null) { this.errorCode = errorCode; notifyAll(); } } public void sendResponseHeaders(List
list, boolean z) throws IOException { boolean z2; boolean z3; if (list == null) { throw new NullPointerException("responseHeaders == null"); } synchronized (this) { this.hasResponseHeaders = true; if (z) { z2 = false; z3 = false; } else { this.sink.finished = true; z2 = true; z3 = true; } } if (!z2) { synchronized (this.connection) { z2 = this.connection.bytesLeftInWriteWindow == 0; } } this.connection.writeSynReply(this.id, z3, list); if (z2) { this.connection.flush(); } } public synchronized List
takeResponseHeaders() throws IOException { List
list; if (!isLocallyInitiated()) { throw new IllegalStateException("servers cannot read response headers"); } this.readTimeout.enter(); while (this.responseHeaders == null && this.errorCode == null) { try { waitForIo(); } catch (Throwable th) { this.readTimeout.exitAndThrowIfTimedOut(); throw th; } } this.readTimeout.exitAndThrowIfTimedOut(); list = this.responseHeaders; if (list == null) { throw new StreamResetException(this.errorCode); } this.responseHeaders = null; return list; } void waitForIo() throws InterruptedIOException { try { wait(); } catch (InterruptedException unused) { Thread.currentThread().interrupt(); throw new InterruptedIOException(); } } public Timeout writeTimeout() { return this.writeTimeout; } }