854 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			854 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
package okhttp3.internal.http2;
 | 
						|
 | 
						|
import java.io.Closeable;
 | 
						|
import java.io.IOException;
 | 
						|
import java.io.InterruptedIOException;
 | 
						|
import java.net.InetSocketAddress;
 | 
						|
import java.net.Socket;
 | 
						|
import java.util.LinkedHashMap;
 | 
						|
import java.util.LinkedHashSet;
 | 
						|
import java.util.List;
 | 
						|
import java.util.Map;
 | 
						|
import java.util.Set;
 | 
						|
import java.util.concurrent.ExecutorService;
 | 
						|
import java.util.concurrent.LinkedBlockingQueue;
 | 
						|
import java.util.concurrent.RejectedExecutionException;
 | 
						|
import java.util.concurrent.ScheduledExecutorService;
 | 
						|
import java.util.concurrent.ScheduledThreadPoolExecutor;
 | 
						|
import java.util.concurrent.SynchronousQueue;
 | 
						|
import java.util.concurrent.ThreadPoolExecutor;
 | 
						|
import java.util.concurrent.TimeUnit;
 | 
						|
import okhttp3.Protocol;
 | 
						|
import okhttp3.internal.NamedRunnable;
 | 
						|
import okhttp3.internal.Util;
 | 
						|
import okhttp3.internal.http2.Http2Reader;
 | 
						|
import okhttp3.internal.platform.Platform;
 | 
						|
import okio.Buffer;
 | 
						|
import okio.BufferedSink;
 | 
						|
import okio.BufferedSource;
 | 
						|
import okio.ByteString;
 | 
						|
import okio.Okio;
 | 
						|
 | 
						|
/* loaded from: classes2.dex */
 | 
						|
public final class Http2Connection implements Closeable {
 | 
						|
    static final /* synthetic */ boolean $assertionsDisabled = false;
 | 
						|
    static final int OKHTTP_CLIENT_WINDOW_SIZE = 16777216;
 | 
						|
    private static final ExecutorService listenerExecutor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue(), Util.threadFactory("OkHttp Http2Connection", true));
 | 
						|
    private boolean awaitingPong;
 | 
						|
    long bytesLeftInWriteWindow;
 | 
						|
    final boolean client;
 | 
						|
    final String hostname;
 | 
						|
    int lastGoodStreamId;
 | 
						|
    final Listener listener;
 | 
						|
    int nextStreamId;
 | 
						|
    private final ExecutorService pushExecutor;
 | 
						|
    final PushObserver pushObserver;
 | 
						|
    final ReaderRunnable readerRunnable;
 | 
						|
    boolean shutdown;
 | 
						|
    final Socket socket;
 | 
						|
    final Http2Writer writer;
 | 
						|
    private final ScheduledExecutorService writerExecutor;
 | 
						|
    final Map<Integer, Http2Stream> streams = new LinkedHashMap();
 | 
						|
    long unacknowledgedBytesRead = 0;
 | 
						|
    Settings okHttpSettings = new Settings();
 | 
						|
    final Settings peerSettings = new Settings();
 | 
						|
    boolean receivedInitialPeerSettings = false;
 | 
						|
    final Set<Integer> currentPushRequests = new LinkedHashSet();
 | 
						|
 | 
						|
    public static abstract class Listener {
 | 
						|
        public static final Listener REFUSE_INCOMING_STREAMS = new Listener() { // from class: okhttp3.internal.http2.Http2Connection.Listener.1
 | 
						|
            @Override // okhttp3.internal.http2.Http2Connection.Listener
 | 
						|
            public void onStream(Http2Stream http2Stream) throws IOException {
 | 
						|
                http2Stream.close(ErrorCode.REFUSED_STREAM);
 | 
						|
            }
 | 
						|
        };
 | 
						|
 | 
						|
        public void onSettings(Http2Connection http2Connection) {
 | 
						|
        }
 | 
						|
 | 
						|
        public abstract void onStream(Http2Stream http2Stream) throws IOException;
 | 
						|
    }
 | 
						|
 | 
						|
    final class PingRunnable extends NamedRunnable {
 | 
						|
        final int payload1;
 | 
						|
        final int payload2;
 | 
						|
        final boolean reply;
 | 
						|
 | 
						|
        PingRunnable(boolean z, int i, int i2) {
 | 
						|
            super("OkHttp %s ping %08x%08x", Http2Connection.this.hostname, Integer.valueOf(i), Integer.valueOf(i2));
 | 
						|
            this.reply = z;
 | 
						|
            this.payload1 = i;
 | 
						|
            this.payload2 = i2;
 | 
						|
        }
 | 
						|
 | 
						|
        @Override // okhttp3.internal.NamedRunnable
 | 
						|
        public void execute() {
 | 
						|
            Http2Connection.this.writePing(this.reply, this.payload1, this.payload2);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    class ReaderRunnable extends NamedRunnable implements Http2Reader.Handler {
 | 
						|
        final Http2Reader reader;
 | 
						|
 | 
						|
        ReaderRunnable(Http2Reader http2Reader) {
 | 
						|
            super("OkHttp %s", Http2Connection.this.hostname);
 | 
						|
            this.reader = http2Reader;
 | 
						|
        }
 | 
						|
 | 
						|
        private void applyAndAckSettings(final Settings settings) {
 | 
						|
            try {
 | 
						|
                Http2Connection.this.writerExecutor.execute(new NamedRunnable("OkHttp %s ACK Settings", new Object[]{Http2Connection.this.hostname}) { // from class: okhttp3.internal.http2.Http2Connection.ReaderRunnable.3
 | 
						|
                    @Override // okhttp3.internal.NamedRunnable
 | 
						|
                    public void execute() {
 | 
						|
                        try {
 | 
						|
                            Http2Connection.this.writer.applyAndAckSettings(settings);
 | 
						|
                        } catch (IOException unused) {
 | 
						|
                            Http2Connection.this.failConnection();
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                });
 | 
						|
            } catch (RejectedExecutionException unused) {
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        @Override // okhttp3.internal.http2.Http2Reader.Handler
 | 
						|
        public void ackSettings() {
 | 
						|
        }
 | 
						|
 | 
						|
        @Override // okhttp3.internal.http2.Http2Reader.Handler
 | 
						|
        public void alternateService(int i, String str, ByteString byteString, String str2, int i2, long j) {
 | 
						|
        }
 | 
						|
 | 
						|
        @Override // okhttp3.internal.http2.Http2Reader.Handler
 | 
						|
        public void data(boolean z, int i, BufferedSource bufferedSource, int i2) throws IOException {
 | 
						|
            if (Http2Connection.this.pushedStream(i)) {
 | 
						|
                Http2Connection.this.pushDataLater(i, bufferedSource, i2, z);
 | 
						|
                return;
 | 
						|
            }
 | 
						|
            Http2Stream stream = Http2Connection.this.getStream(i);
 | 
						|
            if (stream == null) {
 | 
						|
                Http2Connection.this.writeSynResetLater(i, ErrorCode.PROTOCOL_ERROR);
 | 
						|
                long j = i2;
 | 
						|
                Http2Connection.this.updateConnectionFlowControl(j);
 | 
						|
                bufferedSource.skip(j);
 | 
						|
                return;
 | 
						|
            }
 | 
						|
            stream.receiveData(bufferedSource, i2);
 | 
						|
            if (z) {
 | 
						|
                stream.receiveFin();
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        @Override // okhttp3.internal.NamedRunnable
 | 
						|
        protected void execute() {
 | 
						|
            ErrorCode errorCode;
 | 
						|
            Http2Connection http2Connection;
 | 
						|
            ErrorCode errorCode2 = ErrorCode.INTERNAL_ERROR;
 | 
						|
            try {
 | 
						|
                try {
 | 
						|
                    try {
 | 
						|
                        this.reader.readConnectionPreface(this);
 | 
						|
                        while (this.reader.nextFrame(false, this)) {
 | 
						|
                        }
 | 
						|
                        errorCode = ErrorCode.NO_ERROR;
 | 
						|
                    } catch (IOException unused) {
 | 
						|
                    } catch (Throwable th) {
 | 
						|
                        th = th;
 | 
						|
                        errorCode = errorCode2;
 | 
						|
                        try {
 | 
						|
                            Http2Connection.this.close(errorCode, errorCode2);
 | 
						|
                        } catch (IOException unused2) {
 | 
						|
                        }
 | 
						|
                        Util.closeQuietly(this.reader);
 | 
						|
                        throw th;
 | 
						|
                    }
 | 
						|
                    try {
 | 
						|
                        errorCode2 = ErrorCode.CANCEL;
 | 
						|
                        http2Connection = Http2Connection.this;
 | 
						|
                    } catch (IOException unused3) {
 | 
						|
                        errorCode = ErrorCode.PROTOCOL_ERROR;
 | 
						|
                        errorCode2 = ErrorCode.PROTOCOL_ERROR;
 | 
						|
                        http2Connection = Http2Connection.this;
 | 
						|
                        http2Connection.close(errorCode, errorCode2);
 | 
						|
                        Util.closeQuietly(this.reader);
 | 
						|
                    }
 | 
						|
                    http2Connection.close(errorCode, errorCode2);
 | 
						|
                } catch (IOException unused4) {
 | 
						|
                }
 | 
						|
                Util.closeQuietly(this.reader);
 | 
						|
            } catch (Throwable th2) {
 | 
						|
                th = th2;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        @Override // okhttp3.internal.http2.Http2Reader.Handler
 | 
						|
        public void goAway(int i, ErrorCode errorCode, ByteString byteString) {
 | 
						|
            Http2Stream[] http2StreamArr;
 | 
						|
            byteString.size();
 | 
						|
            synchronized (Http2Connection.this) {
 | 
						|
                http2StreamArr = (Http2Stream[]) Http2Connection.this.streams.values().toArray(new Http2Stream[Http2Connection.this.streams.size()]);
 | 
						|
                Http2Connection.this.shutdown = true;
 | 
						|
            }
 | 
						|
            for (Http2Stream http2Stream : http2StreamArr) {
 | 
						|
                if (http2Stream.getId() > i && http2Stream.isLocallyInitiated()) {
 | 
						|
                    http2Stream.receiveRstStream(ErrorCode.REFUSED_STREAM);
 | 
						|
                    Http2Connection.this.removeStream(http2Stream.getId());
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        @Override // okhttp3.internal.http2.Http2Reader.Handler
 | 
						|
        public void headers(boolean z, int i, int i2, List<Header> list) {
 | 
						|
            if (Http2Connection.this.pushedStream(i)) {
 | 
						|
                Http2Connection.this.pushHeadersLater(i, list, z);
 | 
						|
                return;
 | 
						|
            }
 | 
						|
            synchronized (Http2Connection.this) {
 | 
						|
                Http2Stream stream = Http2Connection.this.getStream(i);
 | 
						|
                if (stream != null) {
 | 
						|
                    stream.receiveHeaders(list);
 | 
						|
                    if (z) {
 | 
						|
                        stream.receiveFin();
 | 
						|
                        return;
 | 
						|
                    }
 | 
						|
                    return;
 | 
						|
                }
 | 
						|
                if (Http2Connection.this.shutdown) {
 | 
						|
                    return;
 | 
						|
                }
 | 
						|
                if (i <= Http2Connection.this.lastGoodStreamId) {
 | 
						|
                    return;
 | 
						|
                }
 | 
						|
                if (i % 2 == Http2Connection.this.nextStreamId % 2) {
 | 
						|
                    return;
 | 
						|
                }
 | 
						|
                final Http2Stream http2Stream = new Http2Stream(i, Http2Connection.this, false, z, list);
 | 
						|
                Http2Connection.this.lastGoodStreamId = i;
 | 
						|
                Http2Connection.this.streams.put(Integer.valueOf(i), http2Stream);
 | 
						|
                Http2Connection.listenerExecutor.execute(new NamedRunnable("OkHttp %s stream %d", new Object[]{Http2Connection.this.hostname, Integer.valueOf(i)}) { // from class: okhttp3.internal.http2.Http2Connection.ReaderRunnable.1
 | 
						|
                    @Override // okhttp3.internal.NamedRunnable
 | 
						|
                    public void execute() {
 | 
						|
                        try {
 | 
						|
                            Http2Connection.this.listener.onStream(http2Stream);
 | 
						|
                        } catch (IOException e) {
 | 
						|
                            Platform.get().log(4, "Http2Connection.Listener failure for " + Http2Connection.this.hostname, e);
 | 
						|
                            try {
 | 
						|
                                http2Stream.close(ErrorCode.PROTOCOL_ERROR);
 | 
						|
                            } catch (IOException unused) {
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                });
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        @Override // okhttp3.internal.http2.Http2Reader.Handler
 | 
						|
        public void ping(boolean z, int i, int i2) {
 | 
						|
            if (!z) {
 | 
						|
                try {
 | 
						|
                    Http2Connection.this.writerExecutor.execute(Http2Connection.this.new PingRunnable(true, i, i2));
 | 
						|
                } catch (RejectedExecutionException unused) {
 | 
						|
                }
 | 
						|
            } else {
 | 
						|
                synchronized (Http2Connection.this) {
 | 
						|
                    Http2Connection.this.awaitingPong = false;
 | 
						|
                    Http2Connection.this.notifyAll();
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        @Override // okhttp3.internal.http2.Http2Reader.Handler
 | 
						|
        public void priority(int i, int i2, int i3, boolean z) {
 | 
						|
        }
 | 
						|
 | 
						|
        @Override // okhttp3.internal.http2.Http2Reader.Handler
 | 
						|
        public void pushPromise(int i, int i2, List<Header> list) {
 | 
						|
            Http2Connection.this.pushRequestLater(i2, list);
 | 
						|
        }
 | 
						|
 | 
						|
        @Override // okhttp3.internal.http2.Http2Reader.Handler
 | 
						|
        public void rstStream(int i, ErrorCode errorCode) {
 | 
						|
            if (Http2Connection.this.pushedStream(i)) {
 | 
						|
                Http2Connection.this.pushResetLater(i, errorCode);
 | 
						|
                return;
 | 
						|
            }
 | 
						|
            Http2Stream removeStream = Http2Connection.this.removeStream(i);
 | 
						|
            if (removeStream != null) {
 | 
						|
                removeStream.receiveRstStream(errorCode);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        @Override // okhttp3.internal.http2.Http2Reader.Handler
 | 
						|
        public void settings(boolean z, Settings settings) {
 | 
						|
            Http2Stream[] http2StreamArr;
 | 
						|
            long j;
 | 
						|
            int i;
 | 
						|
            synchronized (Http2Connection.this) {
 | 
						|
                int initialWindowSize = Http2Connection.this.peerSettings.getInitialWindowSize();
 | 
						|
                if (z) {
 | 
						|
                    Http2Connection.this.peerSettings.clear();
 | 
						|
                }
 | 
						|
                Http2Connection.this.peerSettings.merge(settings);
 | 
						|
                applyAndAckSettings(settings);
 | 
						|
                int initialWindowSize2 = Http2Connection.this.peerSettings.getInitialWindowSize();
 | 
						|
                http2StreamArr = null;
 | 
						|
                if (initialWindowSize2 == -1 || initialWindowSize2 == initialWindowSize) {
 | 
						|
                    j = 0;
 | 
						|
                } else {
 | 
						|
                    j = initialWindowSize2 - initialWindowSize;
 | 
						|
                    if (!Http2Connection.this.receivedInitialPeerSettings) {
 | 
						|
                        Http2Connection.this.receivedInitialPeerSettings = true;
 | 
						|
                    }
 | 
						|
                    if (!Http2Connection.this.streams.isEmpty()) {
 | 
						|
                        http2StreamArr = (Http2Stream[]) Http2Connection.this.streams.values().toArray(new Http2Stream[Http2Connection.this.streams.size()]);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                Http2Connection.listenerExecutor.execute(new NamedRunnable("OkHttp %s settings", Http2Connection.this.hostname) { // from class: okhttp3.internal.http2.Http2Connection.ReaderRunnable.2
 | 
						|
                    @Override // okhttp3.internal.NamedRunnable
 | 
						|
                    public void execute() {
 | 
						|
                        Http2Connection http2Connection = Http2Connection.this;
 | 
						|
                        http2Connection.listener.onSettings(http2Connection);
 | 
						|
                    }
 | 
						|
                });
 | 
						|
            }
 | 
						|
            if (http2StreamArr == null || j == 0) {
 | 
						|
                return;
 | 
						|
            }
 | 
						|
            for (Http2Stream http2Stream : http2StreamArr) {
 | 
						|
                synchronized (http2Stream) {
 | 
						|
                    http2Stream.addBytesToWriteWindow(j);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        @Override // okhttp3.internal.http2.Http2Reader.Handler
 | 
						|
        public void windowUpdate(int i, long j) {
 | 
						|
            if (i == 0) {
 | 
						|
                synchronized (Http2Connection.this) {
 | 
						|
                    Http2Connection.this.bytesLeftInWriteWindow += j;
 | 
						|
                    Http2Connection.this.notifyAll();
 | 
						|
                }
 | 
						|
                return;
 | 
						|
            }
 | 
						|
            Http2Stream stream = Http2Connection.this.getStream(i);
 | 
						|
            if (stream != null) {
 | 
						|
                synchronized (stream) {
 | 
						|
                    stream.addBytesToWriteWindow(j);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    Http2Connection(Builder builder) {
 | 
						|
        this.pushObserver = builder.pushObserver;
 | 
						|
        boolean z = builder.client;
 | 
						|
        this.client = z;
 | 
						|
        this.listener = builder.listener;
 | 
						|
        this.nextStreamId = z ? 1 : 2;
 | 
						|
        if (builder.client) {
 | 
						|
            this.nextStreamId += 2;
 | 
						|
        }
 | 
						|
        if (builder.client) {
 | 
						|
            this.okHttpSettings.set(7, OKHTTP_CLIENT_WINDOW_SIZE);
 | 
						|
        }
 | 
						|
        this.hostname = builder.hostname;
 | 
						|
        this.writerExecutor = new ScheduledThreadPoolExecutor(1, Util.threadFactory(Util.format("OkHttp %s Writer", this.hostname), false));
 | 
						|
        if (builder.pingIntervalMillis != 0) {
 | 
						|
            ScheduledExecutorService scheduledExecutorService = this.writerExecutor;
 | 
						|
            PingRunnable pingRunnable = new PingRunnable(false, 0, 0);
 | 
						|
            int i = builder.pingIntervalMillis;
 | 
						|
            scheduledExecutorService.scheduleAtFixedRate(pingRunnable, i, i, TimeUnit.MILLISECONDS);
 | 
						|
        }
 | 
						|
        this.pushExecutor = new ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue(), Util.threadFactory(Util.format("OkHttp %s Push Observer", this.hostname), true));
 | 
						|
        this.peerSettings.set(7, 65535);
 | 
						|
        this.peerSettings.set(5, 16384);
 | 
						|
        this.bytesLeftInWriteWindow = this.peerSettings.getInitialWindowSize();
 | 
						|
        this.socket = builder.socket;
 | 
						|
        this.writer = new Http2Writer(builder.sink, this.client);
 | 
						|
        this.readerRunnable = new ReaderRunnable(new Http2Reader(builder.source, this.client));
 | 
						|
    }
 | 
						|
 | 
						|
    /* JADX INFO: Access modifiers changed from: private */
 | 
						|
    public void failConnection() {
 | 
						|
        try {
 | 
						|
            close(ErrorCode.PROTOCOL_ERROR, ErrorCode.PROTOCOL_ERROR);
 | 
						|
        } catch (IOException unused) {
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    private synchronized void pushExecutorExecute(NamedRunnable namedRunnable) {
 | 
						|
        if (!isShutdown()) {
 | 
						|
            this.pushExecutor.execute(namedRunnable);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    synchronized void awaitPong() throws InterruptedException {
 | 
						|
        while (this.awaitingPong) {
 | 
						|
            wait();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    @Override // java.io.Closeable, java.lang.AutoCloseable
 | 
						|
    public void close() throws IOException {
 | 
						|
        close(ErrorCode.NO_ERROR, ErrorCode.CANCEL);
 | 
						|
    }
 | 
						|
 | 
						|
    public void flush() throws IOException {
 | 
						|
        this.writer.flush();
 | 
						|
    }
 | 
						|
 | 
						|
    public Protocol getProtocol() {
 | 
						|
        return Protocol.HTTP_2;
 | 
						|
    }
 | 
						|
 | 
						|
    synchronized Http2Stream getStream(int i) {
 | 
						|
        return this.streams.get(Integer.valueOf(i));
 | 
						|
    }
 | 
						|
 | 
						|
    public synchronized boolean isShutdown() {
 | 
						|
        return this.shutdown;
 | 
						|
    }
 | 
						|
 | 
						|
    public synchronized int maxConcurrentStreams() {
 | 
						|
        return this.peerSettings.getMaxConcurrentStreams(Integer.MAX_VALUE);
 | 
						|
    }
 | 
						|
 | 
						|
    public Http2Stream newStream(List<Header> list, boolean z) throws IOException {
 | 
						|
        return newStream(0, list, z);
 | 
						|
    }
 | 
						|
 | 
						|
    public synchronized int openStreamCount() {
 | 
						|
        return this.streams.size();
 | 
						|
    }
 | 
						|
 | 
						|
    void pushDataLater(final int i, BufferedSource bufferedSource, final int i2, final boolean z) throws IOException {
 | 
						|
        final Buffer buffer = new Buffer();
 | 
						|
        long j = i2;
 | 
						|
        bufferedSource.require(j);
 | 
						|
        bufferedSource.read(buffer, j);
 | 
						|
        if (buffer.size() == j) {
 | 
						|
            pushExecutorExecute(new NamedRunnable("OkHttp %s Push Data[%s]", new Object[]{this.hostname, Integer.valueOf(i)}) { // from class: okhttp3.internal.http2.Http2Connection.5
 | 
						|
                @Override // okhttp3.internal.NamedRunnable
 | 
						|
                public void execute() {
 | 
						|
                    try {
 | 
						|
                        boolean onData = Http2Connection.this.pushObserver.onData(i, buffer, i2, z);
 | 
						|
                        if (onData) {
 | 
						|
                            Http2Connection.this.writer.rstStream(i, ErrorCode.CANCEL);
 | 
						|
                        }
 | 
						|
                        if (onData || z) {
 | 
						|
                            synchronized (Http2Connection.this) {
 | 
						|
                                Http2Connection.this.currentPushRequests.remove(Integer.valueOf(i));
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    } catch (IOException unused) {
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            });
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        throw new IOException(buffer.size() + " != " + i2);
 | 
						|
    }
 | 
						|
 | 
						|
    void pushHeadersLater(final int i, final List<Header> list, final boolean z) {
 | 
						|
        try {
 | 
						|
            pushExecutorExecute(new NamedRunnable("OkHttp %s Push Headers[%s]", new Object[]{this.hostname, Integer.valueOf(i)}) { // from class: okhttp3.internal.http2.Http2Connection.4
 | 
						|
                @Override // okhttp3.internal.NamedRunnable
 | 
						|
                public void execute() {
 | 
						|
                    boolean onHeaders = Http2Connection.this.pushObserver.onHeaders(i, list, z);
 | 
						|
                    if (onHeaders) {
 | 
						|
                        try {
 | 
						|
                            Http2Connection.this.writer.rstStream(i, ErrorCode.CANCEL);
 | 
						|
                        } catch (IOException unused) {
 | 
						|
                            return;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                    if (onHeaders || z) {
 | 
						|
                        synchronized (Http2Connection.this) {
 | 
						|
                            Http2Connection.this.currentPushRequests.remove(Integer.valueOf(i));
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            });
 | 
						|
        } catch (RejectedExecutionException unused) {
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    void pushRequestLater(final int i, final List<Header> list) {
 | 
						|
        synchronized (this) {
 | 
						|
            if (this.currentPushRequests.contains(Integer.valueOf(i))) {
 | 
						|
                writeSynResetLater(i, ErrorCode.PROTOCOL_ERROR);
 | 
						|
                return;
 | 
						|
            }
 | 
						|
            this.currentPushRequests.add(Integer.valueOf(i));
 | 
						|
            try {
 | 
						|
                pushExecutorExecute(new NamedRunnable("OkHttp %s Push Request[%s]", new Object[]{this.hostname, Integer.valueOf(i)}) { // from class: okhttp3.internal.http2.Http2Connection.3
 | 
						|
                    @Override // okhttp3.internal.NamedRunnable
 | 
						|
                    public void execute() {
 | 
						|
                        if (Http2Connection.this.pushObserver.onRequest(i, list)) {
 | 
						|
                            try {
 | 
						|
                                Http2Connection.this.writer.rstStream(i, ErrorCode.CANCEL);
 | 
						|
                                synchronized (Http2Connection.this) {
 | 
						|
                                    Http2Connection.this.currentPushRequests.remove(Integer.valueOf(i));
 | 
						|
                                }
 | 
						|
                            } catch (IOException unused) {
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                });
 | 
						|
            } catch (RejectedExecutionException unused) {
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    void pushResetLater(final int i, final ErrorCode errorCode) {
 | 
						|
        pushExecutorExecute(new NamedRunnable("OkHttp %s Push Reset[%s]", new Object[]{this.hostname, Integer.valueOf(i)}) { // from class: okhttp3.internal.http2.Http2Connection.6
 | 
						|
            @Override // okhttp3.internal.NamedRunnable
 | 
						|
            public void execute() {
 | 
						|
                Http2Connection.this.pushObserver.onReset(i, errorCode);
 | 
						|
                synchronized (Http2Connection.this) {
 | 
						|
                    Http2Connection.this.currentPushRequests.remove(Integer.valueOf(i));
 | 
						|
                }
 | 
						|
            }
 | 
						|
        });
 | 
						|
    }
 | 
						|
 | 
						|
    public Http2Stream pushStream(int i, List<Header> list, boolean z) throws IOException {
 | 
						|
        if (this.client) {
 | 
						|
            throw new IllegalStateException("Client cannot push requests.");
 | 
						|
        }
 | 
						|
        return newStream(i, list, z);
 | 
						|
    }
 | 
						|
 | 
						|
    boolean pushedStream(int i) {
 | 
						|
        return i != 0 && (i & 1) == 0;
 | 
						|
    }
 | 
						|
 | 
						|
    synchronized Http2Stream removeStream(int i) {
 | 
						|
        Http2Stream remove;
 | 
						|
        remove = this.streams.remove(Integer.valueOf(i));
 | 
						|
        notifyAll();
 | 
						|
        return remove;
 | 
						|
    }
 | 
						|
 | 
						|
    public void setSettings(Settings settings) throws IOException {
 | 
						|
        synchronized (this.writer) {
 | 
						|
            synchronized (this) {
 | 
						|
                if (this.shutdown) {
 | 
						|
                    throw new ConnectionShutdownException();
 | 
						|
                }
 | 
						|
                this.okHttpSettings.merge(settings);
 | 
						|
            }
 | 
						|
            this.writer.settings(settings);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public void shutdown(ErrorCode errorCode) throws IOException {
 | 
						|
        synchronized (this.writer) {
 | 
						|
            synchronized (this) {
 | 
						|
                if (this.shutdown) {
 | 
						|
                    return;
 | 
						|
                }
 | 
						|
                this.shutdown = true;
 | 
						|
                this.writer.goAway(this.lastGoodStreamId, errorCode, Util.EMPTY_BYTE_ARRAY);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public void start() throws IOException {
 | 
						|
        start(true);
 | 
						|
    }
 | 
						|
 | 
						|
    synchronized void updateConnectionFlowControl(long j) {
 | 
						|
        this.unacknowledgedBytesRead += j;
 | 
						|
        if (this.unacknowledgedBytesRead >= this.okHttpSettings.getInitialWindowSize() / 2) {
 | 
						|
            writeWindowUpdateLater(0, this.unacknowledgedBytesRead);
 | 
						|
            this.unacknowledgedBytesRead = 0L;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public void writeData(int i, boolean z, Buffer buffer, long j) throws IOException {
 | 
						|
        int min;
 | 
						|
        long j2;
 | 
						|
        if (j == 0) {
 | 
						|
            this.writer.data(z, i, buffer, 0);
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        while (j > 0) {
 | 
						|
            synchronized (this) {
 | 
						|
                while (this.bytesLeftInWriteWindow <= 0) {
 | 
						|
                    try {
 | 
						|
                        if (!this.streams.containsKey(Integer.valueOf(i))) {
 | 
						|
                            throw new IOException("stream closed");
 | 
						|
                        }
 | 
						|
                        wait();
 | 
						|
                    } catch (InterruptedException unused) {
 | 
						|
                        Thread.currentThread().interrupt();
 | 
						|
                        throw new InterruptedIOException();
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                min = Math.min((int) Math.min(j, this.bytesLeftInWriteWindow), this.writer.maxDataLength());
 | 
						|
                j2 = min;
 | 
						|
                this.bytesLeftInWriteWindow -= j2;
 | 
						|
            }
 | 
						|
            j -= j2;
 | 
						|
            this.writer.data(z && j == 0, i, buffer, min);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    void writePing(boolean z, int i, int i2) {
 | 
						|
        boolean z2;
 | 
						|
        if (!z) {
 | 
						|
            synchronized (this) {
 | 
						|
                z2 = this.awaitingPong;
 | 
						|
                this.awaitingPong = true;
 | 
						|
            }
 | 
						|
            if (z2) {
 | 
						|
                failConnection();
 | 
						|
                return;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        try {
 | 
						|
            this.writer.ping(z, i, i2);
 | 
						|
        } catch (IOException unused) {
 | 
						|
            failConnection();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    void writePingAndAwaitPong() throws InterruptedException {
 | 
						|
        writePing(false, 1330343787, -257978967);
 | 
						|
        awaitPong();
 | 
						|
    }
 | 
						|
 | 
						|
    void writeSynReply(int i, boolean z, List<Header> list) throws IOException {
 | 
						|
        this.writer.synReply(z, i, list);
 | 
						|
    }
 | 
						|
 | 
						|
    void writeSynReset(int i, ErrorCode errorCode) throws IOException {
 | 
						|
        this.writer.rstStream(i, errorCode);
 | 
						|
    }
 | 
						|
 | 
						|
    void writeSynResetLater(final int i, final ErrorCode errorCode) {
 | 
						|
        try {
 | 
						|
            this.writerExecutor.execute(new NamedRunnable("OkHttp %s stream %d", new Object[]{this.hostname, Integer.valueOf(i)}) { // from class: okhttp3.internal.http2.Http2Connection.1
 | 
						|
                @Override // okhttp3.internal.NamedRunnable
 | 
						|
                public void execute() {
 | 
						|
                    try {
 | 
						|
                        Http2Connection.this.writeSynReset(i, errorCode);
 | 
						|
                    } catch (IOException unused) {
 | 
						|
                        Http2Connection.this.failConnection();
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            });
 | 
						|
        } catch (RejectedExecutionException unused) {
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    void writeWindowUpdateLater(final int i, final long j) {
 | 
						|
        try {
 | 
						|
            this.writerExecutor.execute(new NamedRunnable("OkHttp Window Update %s stream %d", new Object[]{this.hostname, Integer.valueOf(i)}) { // from class: okhttp3.internal.http2.Http2Connection.2
 | 
						|
                @Override // okhttp3.internal.NamedRunnable
 | 
						|
                public void execute() {
 | 
						|
                    try {
 | 
						|
                        Http2Connection.this.writer.windowUpdate(i, j);
 | 
						|
                    } catch (IOException unused) {
 | 
						|
                        Http2Connection.this.failConnection();
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            });
 | 
						|
        } catch (RejectedExecutionException unused) {
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /* JADX WARN: Removed duplicated region for block: B:21:0x0043 A[Catch: all -> 0x0075, TryCatch #0 {, blocks: (B:6:0x0007, B:8:0x000e, B:9:0x0013, B:11:0x0017, B:13:0x002b, B:15:0x0033, B:19:0x003d, B:21:0x0043, B:22:0x004c, B:36:0x006f, B:37:0x0074), top: B:5:0x0007, outer: #1 }] */
 | 
						|
    /*
 | 
						|
        Code decompiled incorrectly, please refer to instructions dump.
 | 
						|
        To view partially-correct code enable 'Show inconsistent code' option in preferences
 | 
						|
    */
 | 
						|
    private okhttp3.internal.http2.Http2Stream newStream(int r11, java.util.List<okhttp3.internal.http2.Header> r12, boolean r13) throws java.io.IOException {
 | 
						|
        /*
 | 
						|
            r10 = this;
 | 
						|
            r6 = r13 ^ 1
 | 
						|
            r4 = 0
 | 
						|
            okhttp3.internal.http2.Http2Writer r7 = r10.writer
 | 
						|
            monitor-enter(r7)
 | 
						|
            monitor-enter(r10)     // Catch: java.lang.Throwable -> L78
 | 
						|
            int r0 = r10.nextStreamId     // Catch: java.lang.Throwable -> L75
 | 
						|
            r1 = 1073741823(0x3fffffff, float:1.9999999)
 | 
						|
            if (r0 <= r1) goto L13
 | 
						|
            okhttp3.internal.http2.ErrorCode r0 = okhttp3.internal.http2.ErrorCode.REFUSED_STREAM     // Catch: java.lang.Throwable -> L75
 | 
						|
            r10.shutdown(r0)     // Catch: java.lang.Throwable -> L75
 | 
						|
        L13:
 | 
						|
            boolean r0 = r10.shutdown     // Catch: java.lang.Throwable -> L75
 | 
						|
            if (r0 != 0) goto L6f
 | 
						|
            int r8 = r10.nextStreamId     // Catch: java.lang.Throwable -> L75
 | 
						|
            int r0 = r10.nextStreamId     // Catch: java.lang.Throwable -> L75
 | 
						|
            int r0 = r0 + 2
 | 
						|
            r10.nextStreamId = r0     // Catch: java.lang.Throwable -> L75
 | 
						|
            okhttp3.internal.http2.Http2Stream r9 = new okhttp3.internal.http2.Http2Stream     // Catch: java.lang.Throwable -> L75
 | 
						|
            r0 = r9
 | 
						|
            r1 = r8
 | 
						|
            r2 = r10
 | 
						|
            r3 = r6
 | 
						|
            r5 = r12
 | 
						|
            r0.<init>(r1, r2, r3, r4, r5)     // Catch: java.lang.Throwable -> L75
 | 
						|
            if (r13 == 0) goto L3c
 | 
						|
            long r0 = r10.bytesLeftInWriteWindow     // Catch: java.lang.Throwable -> L75
 | 
						|
            r2 = 0
 | 
						|
            int r13 = (r0 > r2 ? 1 : (r0 == r2 ? 0 : -1))
 | 
						|
            if (r13 == 0) goto L3c
 | 
						|
            long r0 = r9.bytesLeftInWriteWindow     // Catch: java.lang.Throwable -> L75
 | 
						|
            int r13 = (r0 > r2 ? 1 : (r0 == r2 ? 0 : -1))
 | 
						|
            if (r13 != 0) goto L3a
 | 
						|
            goto L3c
 | 
						|
        L3a:
 | 
						|
            r13 = 0
 | 
						|
            goto L3d
 | 
						|
        L3c:
 | 
						|
            r13 = 1
 | 
						|
        L3d:
 | 
						|
            boolean r0 = r9.isOpen()     // Catch: java.lang.Throwable -> L75
 | 
						|
            if (r0 == 0) goto L4c
 | 
						|
            java.util.Map<java.lang.Integer, okhttp3.internal.http2.Http2Stream> r0 = r10.streams     // Catch: java.lang.Throwable -> L75
 | 
						|
            java.lang.Integer r1 = java.lang.Integer.valueOf(r8)     // Catch: java.lang.Throwable -> L75
 | 
						|
            r0.put(r1, r9)     // Catch: java.lang.Throwable -> L75
 | 
						|
        L4c:
 | 
						|
            monitor-exit(r10)     // Catch: java.lang.Throwable -> L75
 | 
						|
            if (r11 != 0) goto L55
 | 
						|
            okhttp3.internal.http2.Http2Writer r0 = r10.writer     // Catch: java.lang.Throwable -> L78
 | 
						|
            r0.synStream(r6, r8, r11, r12)     // Catch: java.lang.Throwable -> L78
 | 
						|
            goto L5e
 | 
						|
        L55:
 | 
						|
            boolean r0 = r10.client     // Catch: java.lang.Throwable -> L78
 | 
						|
            if (r0 != 0) goto L67
 | 
						|
            okhttp3.internal.http2.Http2Writer r0 = r10.writer     // Catch: java.lang.Throwable -> L78
 | 
						|
            r0.pushPromise(r11, r8, r12)     // Catch: java.lang.Throwable -> L78
 | 
						|
        L5e:
 | 
						|
            monitor-exit(r7)     // Catch: java.lang.Throwable -> L78
 | 
						|
            if (r13 == 0) goto L66
 | 
						|
            okhttp3.internal.http2.Http2Writer r11 = r10.writer
 | 
						|
            r11.flush()
 | 
						|
        L66:
 | 
						|
            return r9
 | 
						|
        L67:
 | 
						|
            java.lang.IllegalArgumentException r11 = new java.lang.IllegalArgumentException     // Catch: java.lang.Throwable -> L78
 | 
						|
            java.lang.String r12 = "client streams shouldn't have associated stream IDs"
 | 
						|
            r11.<init>(r12)     // Catch: java.lang.Throwable -> L78
 | 
						|
            throw r11     // Catch: java.lang.Throwable -> L78
 | 
						|
        L6f:
 | 
						|
            okhttp3.internal.http2.ConnectionShutdownException r11 = new okhttp3.internal.http2.ConnectionShutdownException     // Catch: java.lang.Throwable -> L75
 | 
						|
            r11.<init>()     // Catch: java.lang.Throwable -> L75
 | 
						|
            throw r11     // Catch: java.lang.Throwable -> L75
 | 
						|
        L75:
 | 
						|
            r11 = move-exception
 | 
						|
            monitor-exit(r10)     // Catch: java.lang.Throwable -> L75
 | 
						|
            throw r11     // Catch: java.lang.Throwable -> L78
 | 
						|
        L78:
 | 
						|
            r11 = move-exception
 | 
						|
            monitor-exit(r7)     // Catch: java.lang.Throwable -> L78
 | 
						|
            throw r11
 | 
						|
        */
 | 
						|
        throw new UnsupportedOperationException("Method not decompiled: okhttp3.internal.http2.Http2Connection.newStream(int, java.util.List, boolean):okhttp3.internal.http2.Http2Stream");
 | 
						|
    }
 | 
						|
 | 
						|
    void close(ErrorCode errorCode, ErrorCode errorCode2) throws IOException {
 | 
						|
        Http2Stream[] http2StreamArr = null;
 | 
						|
        try {
 | 
						|
            shutdown(errorCode);
 | 
						|
            e = null;
 | 
						|
        } catch (IOException e) {
 | 
						|
            e = e;
 | 
						|
        }
 | 
						|
        synchronized (this) {
 | 
						|
            if (!this.streams.isEmpty()) {
 | 
						|
                http2StreamArr = (Http2Stream[]) this.streams.values().toArray(new Http2Stream[this.streams.size()]);
 | 
						|
                this.streams.clear();
 | 
						|
            }
 | 
						|
        }
 | 
						|
        if (http2StreamArr != null) {
 | 
						|
            for (Http2Stream http2Stream : http2StreamArr) {
 | 
						|
                try {
 | 
						|
                    http2Stream.close(errorCode2);
 | 
						|
                } catch (IOException e2) {
 | 
						|
                    if (e != null) {
 | 
						|
                        e = e2;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        try {
 | 
						|
            this.writer.close();
 | 
						|
        } catch (IOException e3) {
 | 
						|
            if (e == null) {
 | 
						|
                e = e3;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        try {
 | 
						|
            this.socket.close();
 | 
						|
        } catch (IOException e4) {
 | 
						|
            e = e4;
 | 
						|
        }
 | 
						|
        this.writerExecutor.shutdown();
 | 
						|
        this.pushExecutor.shutdown();
 | 
						|
        if (e != null) {
 | 
						|
            throw e;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    void start(boolean z) throws IOException {
 | 
						|
        if (z) {
 | 
						|
            this.writer.connectionPreface();
 | 
						|
            this.writer.settings(this.okHttpSettings);
 | 
						|
            if (this.okHttpSettings.getInitialWindowSize() != 65535) {
 | 
						|
                this.writer.windowUpdate(0, r6 - 65535);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        new Thread(this.readerRunnable).start();
 | 
						|
    }
 | 
						|
 | 
						|
    public static class Builder {
 | 
						|
        boolean client;
 | 
						|
        String hostname;
 | 
						|
        int pingIntervalMillis;
 | 
						|
        BufferedSink sink;
 | 
						|
        Socket socket;
 | 
						|
        BufferedSource source;
 | 
						|
        Listener listener = Listener.REFUSE_INCOMING_STREAMS;
 | 
						|
        PushObserver pushObserver = PushObserver.CANCEL;
 | 
						|
 | 
						|
        public Builder(boolean z) {
 | 
						|
            this.client = z;
 | 
						|
        }
 | 
						|
 | 
						|
        public Http2Connection build() {
 | 
						|
            return new Http2Connection(this);
 | 
						|
        }
 | 
						|
 | 
						|
        public Builder listener(Listener listener) {
 | 
						|
            this.listener = listener;
 | 
						|
            return this;
 | 
						|
        }
 | 
						|
 | 
						|
        public Builder pingIntervalMillis(int i) {
 | 
						|
            this.pingIntervalMillis = i;
 | 
						|
            return this;
 | 
						|
        }
 | 
						|
 | 
						|
        public Builder pushObserver(PushObserver pushObserver) {
 | 
						|
            this.pushObserver = pushObserver;
 | 
						|
            return this;
 | 
						|
        }
 | 
						|
 | 
						|
        public Builder socket(Socket socket) throws IOException {
 | 
						|
            return socket(socket, ((InetSocketAddress) socket.getRemoteSocketAddress()).getHostName(), Okio.buffer(Okio.source(socket)), Okio.buffer(Okio.sink(socket)));
 | 
						|
        }
 | 
						|
 | 
						|
        public Builder socket(Socket socket, String str, BufferedSource bufferedSource, BufferedSink bufferedSink) {
 | 
						|
            this.socket = socket;
 | 
						|
            this.hostname = str;
 | 
						|
            this.source = bufferedSource;
 | 
						|
            this.sink = bufferedSink;
 | 
						|
            return this;
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |