337 lines
14 KiB
Java
337 lines
14 KiB
Java
|
package io.grpc.okhttp;
|
||
|
|
||
|
import com.google.common.base.Preconditions;
|
||
|
import com.google.common.io.BaseEncoding;
|
||
|
import io.grpc.Attributes;
|
||
|
import io.grpc.CallOptions;
|
||
|
import io.grpc.Metadata;
|
||
|
import io.grpc.MethodDescriptor;
|
||
|
import io.grpc.Status;
|
||
|
import io.grpc.internal.AbstractClientStream;
|
||
|
import io.grpc.internal.ClientStreamListener;
|
||
|
import io.grpc.internal.Http2ClientStreamTransportState;
|
||
|
import io.grpc.internal.StatsTraceContext;
|
||
|
import io.grpc.internal.TransportTracer;
|
||
|
import io.grpc.internal.WritableBuffer;
|
||
|
import io.grpc.okhttp.internal.framed.ErrorCode;
|
||
|
import io.grpc.okhttp.internal.framed.Header;
|
||
|
import java.util.List;
|
||
|
import o.C13115fRJ;
|
||
|
import o.C15111ghZ;
|
||
|
import o.fRN;
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* loaded from: classes6.dex */
|
||
|
public class OkHttpClientStream extends AbstractClientStream {
|
||
|
public static final int ABSENT_ID = -1;
|
||
|
private static final C15111ghZ EMPTY_BUFFER = new C15111ghZ();
|
||
|
private final Attributes attributes;
|
||
|
private String authority;
|
||
|
private volatile int id;
|
||
|
private final MethodDescriptor<?, ?> method;
|
||
|
private Object outboundFlowState;
|
||
|
private final Sink sink;
|
||
|
private final TransportState state;
|
||
|
private final StatsTraceContext statsTraceCtx;
|
||
|
private boolean useGet;
|
||
|
private final String userAgent;
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
public OkHttpClientStream(MethodDescriptor<?, ?> methodDescriptor, Metadata metadata, ExceptionHandlingFrameWriter exceptionHandlingFrameWriter, OkHttpClientTransport okHttpClientTransport, OutboundFlowController outboundFlowController, Object obj, int i, int i2, String str, String str2, StatsTraceContext statsTraceContext, TransportTracer transportTracer, CallOptions callOptions, boolean z) {
|
||
|
super(new OkHttpWritableBufferAllocator(), statsTraceContext, transportTracer, metadata, callOptions, z && methodDescriptor.isSafe());
|
||
|
this.id = -1;
|
||
|
this.sink = new Sink(this);
|
||
|
this.useGet = false;
|
||
|
this.statsTraceCtx = (StatsTraceContext) Preconditions.checkNotNull(statsTraceContext, "statsTraceCtx");
|
||
|
this.method = methodDescriptor;
|
||
|
this.authority = str;
|
||
|
this.userAgent = str2;
|
||
|
this.attributes = okHttpClientTransport.getAttributes();
|
||
|
this.state = new TransportState(this, i, statsTraceContext, obj, exceptionHandlingFrameWriter, outboundFlowController, okHttpClientTransport, i2, methodDescriptor.getFullMethodName());
|
||
|
}
|
||
|
|
||
|
public MethodDescriptor.MethodType getType() {
|
||
|
return this.method.getType();
|
||
|
}
|
||
|
|
||
|
@Override // io.grpc.internal.ClientStream
|
||
|
public void setAuthority(String str) {
|
||
|
this.authority = (String) Preconditions.checkNotNull(str, "authority");
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* loaded from: classes6.dex */
|
||
|
public class Sink implements AbstractClientStream.Sink {
|
||
|
final OkHttpClientStream this$0;
|
||
|
|
||
|
Sink(OkHttpClientStream okHttpClientStream) {
|
||
|
this.this$0 = okHttpClientStream;
|
||
|
}
|
||
|
|
||
|
@Override // io.grpc.internal.AbstractClientStream.Sink
|
||
|
public void writeHeaders(Metadata metadata, byte[] bArr) {
|
||
|
C13115fRJ.f();
|
||
|
StringBuilder sb = new StringBuilder("/");
|
||
|
sb.append(this.this$0.method.getFullMethodName());
|
||
|
String obj = sb.toString();
|
||
|
if (bArr != null) {
|
||
|
this.this$0.useGet = true;
|
||
|
StringBuilder sb2 = new StringBuilder();
|
||
|
sb2.append(obj);
|
||
|
sb2.append("?");
|
||
|
sb2.append(BaseEncoding.base64().encode(bArr));
|
||
|
obj = sb2.toString();
|
||
|
}
|
||
|
try {
|
||
|
synchronized (this.this$0.state.lock) {
|
||
|
this.this$0.state.streamReady(metadata, obj);
|
||
|
}
|
||
|
} finally {
|
||
|
C13115fRJ.j();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override // io.grpc.internal.AbstractClientStream.Sink
|
||
|
public void writeFrame(WritableBuffer writableBuffer, boolean z, boolean z2, int i) {
|
||
|
C15111ghZ buffer;
|
||
|
C13115fRJ.f();
|
||
|
if (writableBuffer != null) {
|
||
|
buffer = ((OkHttpWritableBuffer) writableBuffer).buffer();
|
||
|
int i2 = (int) buffer.c;
|
||
|
if (i2 > 0) {
|
||
|
this.this$0.onSendingBytes(i2);
|
||
|
}
|
||
|
} else {
|
||
|
buffer = OkHttpClientStream.EMPTY_BUFFER;
|
||
|
}
|
||
|
try {
|
||
|
synchronized (this.this$0.state.lock) {
|
||
|
this.this$0.state.sendBuffer(buffer, z, z2);
|
||
|
this.this$0.getTransportTracer().reportMessageSent(i);
|
||
|
}
|
||
|
} finally {
|
||
|
C13115fRJ.j();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override // io.grpc.internal.AbstractClientStream.Sink
|
||
|
public void cancel(Status status) {
|
||
|
C13115fRJ.f();
|
||
|
try {
|
||
|
synchronized (this.this$0.state.lock) {
|
||
|
this.this$0.state.cancel(status, true, null);
|
||
|
}
|
||
|
} finally {
|
||
|
C13115fRJ.j();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* loaded from: classes6.dex */
|
||
|
public class TransportState extends Http2ClientStreamTransportState {
|
||
|
private boolean canStart;
|
||
|
private boolean cancelSent;
|
||
|
private boolean flushPendingData;
|
||
|
private final ExceptionHandlingFrameWriter frameWriter;
|
||
|
private final int initialWindowSize;
|
||
|
private final Object lock;
|
||
|
private final OutboundFlowController outboundFlow;
|
||
|
private C15111ghZ pendingData;
|
||
|
private boolean pendingDataHasEndOfStream;
|
||
|
private int processedWindow;
|
||
|
private List<Header> requestHeaders;
|
||
|
private final fRN tag;
|
||
|
final OkHttpClientStream this$0;
|
||
|
private final OkHttpClientTransport transport;
|
||
|
private int window;
|
||
|
|
||
|
/* JADX WARN: 'super' call moved to the top of the method (can break code semantics) */
|
||
|
public TransportState(OkHttpClientStream okHttpClientStream, int i, StatsTraceContext statsTraceContext, Object obj, ExceptionHandlingFrameWriter exceptionHandlingFrameWriter, OutboundFlowController outboundFlowController, OkHttpClientTransport okHttpClientTransport, int i2, String str) {
|
||
|
super(i, statsTraceContext, okHttpClientStream.getTransportTracer());
|
||
|
this.this$0 = okHttpClientStream;
|
||
|
this.pendingData = new C15111ghZ();
|
||
|
this.pendingDataHasEndOfStream = false;
|
||
|
this.flushPendingData = false;
|
||
|
this.cancelSent = false;
|
||
|
this.canStart = true;
|
||
|
this.lock = Preconditions.checkNotNull(obj, "lock");
|
||
|
this.frameWriter = exceptionHandlingFrameWriter;
|
||
|
this.outboundFlow = outboundFlowController;
|
||
|
this.transport = okHttpClientTransport;
|
||
|
this.window = i2;
|
||
|
this.processedWindow = i2;
|
||
|
this.initialWindowSize = i2;
|
||
|
this.tag = C13115fRJ.d();
|
||
|
}
|
||
|
|
||
|
public void start(int i) {
|
||
|
Preconditions.checkState(this.this$0.id == -1, "the stream has been started with id %s", i);
|
||
|
this.this$0.id = i;
|
||
|
this.this$0.state.onStreamAllocated();
|
||
|
if (this.canStart) {
|
||
|
this.frameWriter.synStream(this.this$0.useGet, false, this.this$0.id, 0, this.requestHeaders);
|
||
|
this.this$0.statsTraceCtx.clientOutboundHeaders();
|
||
|
this.requestHeaders = null;
|
||
|
if (this.pendingData.c > 0) {
|
||
|
this.outboundFlow.data(this.pendingDataHasEndOfStream, this.this$0.id, this.pendingData, this.flushPendingData);
|
||
|
}
|
||
|
this.canStart = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override // io.grpc.internal.AbstractStream.TransportState
|
||
|
public void onStreamAllocated() {
|
||
|
super.onStreamAllocated();
|
||
|
getTransportTracer().reportLocalStreamStarted();
|
||
|
}
|
||
|
|
||
|
@Override // io.grpc.internal.Http2ClientStreamTransportState
|
||
|
public void http2ProcessingFailed(Status status, boolean z, Metadata metadata) {
|
||
|
cancel(status, z, metadata);
|
||
|
}
|
||
|
|
||
|
@Override // io.grpc.internal.MessageDeframer.Listener
|
||
|
public void deframeFailed(Throwable th) {
|
||
|
http2ProcessingFailed(Status.fromThrowable(th), true, new Metadata());
|
||
|
}
|
||
|
|
||
|
@Override // io.grpc.internal.MessageDeframer.Listener
|
||
|
public void bytesRead(int i) {
|
||
|
int i2 = this.processedWindow - i;
|
||
|
this.processedWindow = i2;
|
||
|
float f = i2;
|
||
|
int i3 = this.initialWindowSize;
|
||
|
if (f <= i3 * 0.5f) {
|
||
|
int i4 = i3 - i2;
|
||
|
this.window += i4;
|
||
|
this.processedWindow = i2 + i4;
|
||
|
this.frameWriter.windowUpdate(this.this$0.id(), i4);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override // io.grpc.internal.Http2ClientStreamTransportState, io.grpc.internal.AbstractClientStream.TransportState, io.grpc.internal.MessageDeframer.Listener
|
||
|
public void deframerClosed(boolean z) {
|
||
|
onEndOfStream();
|
||
|
super.deframerClosed(z);
|
||
|
}
|
||
|
|
||
|
@Override // io.grpc.internal.ApplicationThreadDeframerListener.TransportExecutor
|
||
|
public void runOnTransportThread(Runnable runnable) {
|
||
|
synchronized (this.lock) {
|
||
|
runnable.run();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void transportHeadersReceived(List<Header> list, boolean z) {
|
||
|
if (z) {
|
||
|
transportTrailersReceived(Utils.convertTrailers(list));
|
||
|
} else {
|
||
|
transportHeadersReceived(Utils.convertHeaders(list));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void onEndOfStream() {
|
||
|
if (!isOutboundClosed()) {
|
||
|
this.transport.finishStream(this.this$0.id(), null, ClientStreamListener.RpcProgress.PROCESSED, false, ErrorCode.CANCEL, null);
|
||
|
} else {
|
||
|
this.transport.finishStream(this.this$0.id(), null, ClientStreamListener.RpcProgress.PROCESSED, false, null, null);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: private */
|
||
|
public void cancel(Status status, boolean z, Metadata metadata) {
|
||
|
if (this.cancelSent) {
|
||
|
return;
|
||
|
}
|
||
|
this.cancelSent = true;
|
||
|
if (this.canStart) {
|
||
|
this.transport.removePendingStream(this.this$0);
|
||
|
this.requestHeaders = null;
|
||
|
C15111ghZ c15111ghZ = this.pendingData;
|
||
|
c15111ghZ.j(c15111ghZ.c);
|
||
|
this.canStart = false;
|
||
|
if (metadata == null) {
|
||
|
metadata = new Metadata();
|
||
|
}
|
||
|
transportReportStatus(status, true, metadata);
|
||
|
return;
|
||
|
}
|
||
|
this.transport.finishStream(this.this$0.id(), status, ClientStreamListener.RpcProgress.PROCESSED, z, ErrorCode.CANCEL, metadata);
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: private */
|
||
|
public void streamReady(Metadata metadata, String str) {
|
||
|
this.requestHeaders = Headers.createRequestHeaders(metadata, str, this.this$0.authority, this.this$0.userAgent, this.this$0.useGet, this.transport.isUsingPlaintext());
|
||
|
this.transport.streamReadyToStart(this.this$0);
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: private */
|
||
|
public void sendBuffer(C15111ghZ c15111ghZ, boolean z, boolean z2) {
|
||
|
if (this.cancelSent) {
|
||
|
return;
|
||
|
}
|
||
|
if (this.canStart) {
|
||
|
this.pendingData.write(c15111ghZ, (int) c15111ghZ.c);
|
||
|
this.pendingDataHasEndOfStream |= z;
|
||
|
this.flushPendingData |= z2;
|
||
|
} else {
|
||
|
Preconditions.checkState(this.this$0.id() != -1, "streamId should be set");
|
||
|
this.outboundFlow.data(z, this.this$0.id(), c15111ghZ, z2);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void transportDataReceived(C15111ghZ c15111ghZ, boolean z) {
|
||
|
int i = this.window - ((int) c15111ghZ.c);
|
||
|
this.window = i;
|
||
|
if (i < 0) {
|
||
|
this.frameWriter.rstStream(this.this$0.id(), ErrorCode.FLOW_CONTROL_ERROR);
|
||
|
this.transport.finishStream(this.this$0.id(), Status.INTERNAL.withDescription("Received data size exceeded our receiving window size"), ClientStreamListener.RpcProgress.PROCESSED, false, null, null);
|
||
|
} else {
|
||
|
super.transportDataReceived(new OkHttpReadableBuffer(c15111ghZ), z);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
public fRN tag() {
|
||
|
return this.tag;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
public boolean useGet() {
|
||
|
return this.useGet;
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: protected */
|
||
|
@Override // io.grpc.internal.AbstractClientStream, io.grpc.internal.AbstractStream
|
||
|
public TransportState transportState() {
|
||
|
return this.state;
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
public void setOutboundFlowState(Object obj) {
|
||
|
this.outboundFlowState = obj;
|
||
|
}
|
||
|
|
||
|
public int id() {
|
||
|
return this.id;
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
public Object getOutboundFlowState() {
|
||
|
return this.outboundFlowState;
|
||
|
}
|
||
|
|
||
|
@Override // io.grpc.internal.ClientStream
|
||
|
public Attributes getAttributes() {
|
||
|
return this.attributes;
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: protected */
|
||
|
@Override // io.grpc.internal.AbstractClientStream
|
||
|
public Sink abstractClientStreamSink() {
|
||
|
return this.sink;
|
||
|
}
|
||
|
}
|