jimu-decompiled/sources/okhttp3/internal/http2/Http2Codec.java
2025-05-13 19:24:51 +02:00

191 lines
8.0 KiB
Java

package okhttp3.internal.http2;
import java.io.IOException;
import java.net.ProtocolException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.internal.Internal;
import okhttp3.internal.Util;
import okhttp3.internal.connection.StreamAllocation;
import okhttp3.internal.http.HttpCodec;
import okhttp3.internal.http.HttpHeaders;
import okhttp3.internal.http.RealResponseBody;
import okhttp3.internal.http.RequestLine;
import okhttp3.internal.http.StatusLine;
import okio.Buffer;
import okio.ByteString;
import okio.ForwardingSource;
import okio.Okio;
import okio.Sink;
import okio.Source;
/* loaded from: classes2.dex */
public final class Http2Codec implements HttpCodec {
private final Interceptor.Chain chain;
private final Http2Connection connection;
private final Protocol protocol;
private Http2Stream stream;
final StreamAllocation streamAllocation;
private static final ByteString CONNECTION = ByteString.encodeUtf8("connection");
private static final ByteString HOST = ByteString.encodeUtf8("host");
private static final ByteString KEEP_ALIVE = ByteString.encodeUtf8("keep-alive");
private static final ByteString PROXY_CONNECTION = ByteString.encodeUtf8("proxy-connection");
private static final ByteString TRANSFER_ENCODING = ByteString.encodeUtf8("transfer-encoding");
private static final ByteString TE = ByteString.encodeUtf8("te");
private static final ByteString ENCODING = ByteString.encodeUtf8("encoding");
private static final ByteString UPGRADE = ByteString.encodeUtf8("upgrade");
private static final List<ByteString> HTTP_2_SKIPPED_REQUEST_HEADERS = Util.immutableList(CONNECTION, HOST, KEEP_ALIVE, PROXY_CONNECTION, TE, TRANSFER_ENCODING, ENCODING, UPGRADE, Header.TARGET_METHOD, Header.TARGET_PATH, Header.TARGET_SCHEME, Header.TARGET_AUTHORITY);
private static final List<ByteString> HTTP_2_SKIPPED_RESPONSE_HEADERS = Util.immutableList(CONNECTION, HOST, KEEP_ALIVE, PROXY_CONNECTION, TE, TRANSFER_ENCODING, ENCODING, UPGRADE);
class StreamFinishingSource extends ForwardingSource {
long bytesRead;
boolean completed;
StreamFinishingSource(Source source) {
super(source);
this.completed = false;
this.bytesRead = 0L;
}
private void endOfInput(IOException iOException) {
if (this.completed) {
return;
}
this.completed = true;
Http2Codec http2Codec = Http2Codec.this;
http2Codec.streamAllocation.streamFinished(false, http2Codec, this.bytesRead, iOException);
}
@Override // okio.ForwardingSource, okio.Source, java.io.Closeable, java.lang.AutoCloseable
public void close() throws IOException {
super.close();
endOfInput(null);
}
@Override // okio.ForwardingSource, okio.Source
public long read(Buffer buffer, long j) throws IOException {
try {
long read = delegate().read(buffer, j);
if (read > 0) {
this.bytesRead += read;
}
return read;
} catch (IOException e) {
endOfInput(e);
throw e;
}
}
}
public Http2Codec(OkHttpClient okHttpClient, Interceptor.Chain chain, StreamAllocation streamAllocation, Http2Connection http2Connection) {
this.chain = chain;
this.streamAllocation = streamAllocation;
this.connection = http2Connection;
this.protocol = okHttpClient.protocols().contains(Protocol.H2_PRIOR_KNOWLEDGE) ? Protocol.H2_PRIOR_KNOWLEDGE : Protocol.HTTP_2;
}
public static List<Header> http2HeadersList(Request request) {
Headers headers = request.headers();
ArrayList arrayList = new ArrayList(headers.size() + 4);
arrayList.add(new Header(Header.TARGET_METHOD, request.method()));
arrayList.add(new Header(Header.TARGET_PATH, RequestLine.requestPath(request.url())));
String header = request.header("Host");
if (header != null) {
arrayList.add(new Header(Header.TARGET_AUTHORITY, header));
}
arrayList.add(new Header(Header.TARGET_SCHEME, request.url().scheme()));
int size = headers.size();
for (int i = 0; i < size; i++) {
ByteString encodeUtf8 = ByteString.encodeUtf8(headers.name(i).toLowerCase(Locale.US));
if (!HTTP_2_SKIPPED_REQUEST_HEADERS.contains(encodeUtf8)) {
arrayList.add(new Header(encodeUtf8, headers.value(i)));
}
}
return arrayList;
}
public static Response.Builder readHttp2HeadersList(List<Header> list, Protocol protocol) throws IOException {
Headers.Builder builder = new Headers.Builder();
int size = list.size();
Headers.Builder builder2 = builder;
StatusLine statusLine = null;
for (int i = 0; i < size; i++) {
Header header = list.get(i);
if (header != null) {
ByteString byteString = header.name;
String utf8 = header.value.utf8();
if (byteString.equals(Header.RESPONSE_STATUS)) {
statusLine = StatusLine.parse("HTTP/1.1 " + utf8);
} else if (!HTTP_2_SKIPPED_RESPONSE_HEADERS.contains(byteString)) {
Internal.instance.addLenient(builder2, byteString.utf8(), utf8);
}
} else if (statusLine != null && statusLine.code == 100) {
builder2 = new Headers.Builder();
statusLine = null;
}
}
if (statusLine != null) {
return new Response.Builder().protocol(protocol).code(statusLine.code).message(statusLine.message).headers(builder2.build());
}
throw new ProtocolException("Expected ':status' header not present");
}
@Override // okhttp3.internal.http.HttpCodec
public void cancel() {
Http2Stream http2Stream = this.stream;
if (http2Stream != null) {
http2Stream.closeLater(ErrorCode.CANCEL);
}
}
@Override // okhttp3.internal.http.HttpCodec
public Sink createRequestBody(Request request, long j) {
return this.stream.getSink();
}
@Override // okhttp3.internal.http.HttpCodec
public void finishRequest() throws IOException {
this.stream.getSink().close();
}
@Override // okhttp3.internal.http.HttpCodec
public void flushRequest() throws IOException {
this.connection.flush();
}
@Override // okhttp3.internal.http.HttpCodec
public ResponseBody openResponseBody(Response response) throws IOException {
StreamAllocation streamAllocation = this.streamAllocation;
streamAllocation.eventListener.responseBodyStart(streamAllocation.call);
return new RealResponseBody(response.header("Content-Type"), HttpHeaders.contentLength(response), Okio.buffer(new StreamFinishingSource(this.stream.getSource())));
}
@Override // okhttp3.internal.http.HttpCodec
public Response.Builder readResponseHeaders(boolean z) throws IOException {
Response.Builder readHttp2HeadersList = readHttp2HeadersList(this.stream.takeResponseHeaders(), this.protocol);
if (z && Internal.instance.code(readHttp2HeadersList) == 100) {
return null;
}
return readHttp2HeadersList;
}
@Override // okhttp3.internal.http.HttpCodec
public void writeRequestHeaders(Request request) throws IOException {
if (this.stream != null) {
return;
}
this.stream = this.connection.newStream(http2HeadersList(request), request.body() != null);
this.stream.readTimeout().timeout(this.chain.readTimeoutMillis(), TimeUnit.MILLISECONDS);
this.stream.writeTimeout().timeout(this.chain.writeTimeoutMillis(), TimeUnit.MILLISECONDS);
}
}