1919import static io .grpc .okhttp .OkHttpServerBuilder .MAX_CONNECTION_AGE_NANOS_DISABLED ;
2020import static io .grpc .okhttp .OkHttpServerBuilder .MAX_CONNECTION_IDLE_NANOS_DISABLED ;
2121
22+ import com .google .common .annotations .VisibleForTesting ;
2223import com .google .common .base .Preconditions ;
2324import com .google .common .util .concurrent .Futures ;
2425import com .google .common .util .concurrent .ListenableFuture ;
@@ -139,6 +140,8 @@ final class OkHttpServerTransport implements ServerTransport,
139140 @ GuardedBy ("lock" )
140141 private Long gracefulShutdownPeriod = null ;
141142
143+ private FrameHandler handler ;
144+
142145 public OkHttpServerTransport (Config config , Socket bareSocket ) {
143146 this .config = Preconditions .checkNotNull (config , "config" );
144147 this .socket = Preconditions .checkNotNull (bareSocket , "bareSocket" );
@@ -248,8 +251,8 @@ public void data(boolean outFinished, int streamId, Buffer source, int byteCount
248251 TimeUnit .NANOSECONDS );
249252 }
250253
251- transportExecutor . execute (
252- new FrameHandler ( variant . newReader ( Okio . buffer ( Okio . source ( socket )), false )) );
254+ handler = new FrameHandler ( variant . newReader ( Okio . buffer ( Okio . source ( socket )), false ));
255+ transportExecutor . execute ( handler );
253256 } catch (Error | IOException | RuntimeException ex ) {
254257 synchronized (lock ) {
255258 if (!handshakeShutdown ) {
@@ -261,6 +264,11 @@ public void data(boolean outFinished, int streamId, Buffer source, int byteCount
261264 }
262265 }
263266
267+ @ VisibleForTesting
268+ FrameHandler getHandler () {
269+ return handler ;
270+ }
271+
264272 @ Override
265273 public void shutdown () {
266274 shutdown (null );
@@ -708,7 +716,7 @@ public void headers(boolean outFinished,
708716 return ;
709717 }
710718 // Ignore the trailers, but still half-close the stream
711- stream .inboundDataReceived (new Buffer (), 0 , true );
719+ stream .inboundDataReceived (new Buffer (), 0 , 0 , true );
712720 return ;
713721 }
714722 } else {
@@ -799,7 +807,7 @@ public void headers(boolean outFinished,
799807 listener .streamCreated (streamForApp , method , metadata );
800808 stream .onStreamAllocated ();
801809 if (inFinished ) {
802- stream .inboundDataReceived (new Buffer (), 0 , inFinished );
810+ stream .inboundDataReceived (new Buffer (), 0 , 0 , inFinished );
803811 }
804812 }
805813 }
@@ -854,15 +862,15 @@ public void data(boolean inFinished, int streamId, BufferedSource in, int length
854862 "Received DATA for half-closed (remote) stream. RFC7540 section 5.1" );
855863 return ;
856864 }
857- if (stream .inboundWindowAvailable () < length ) {
865+ if (stream .inboundWindowAvailable () < paddedLength ) {
858866 in .skip (length );
859867 streamError (streamId , ErrorCode .FLOW_CONTROL_ERROR ,
860868 "Received DATA size exceeded window size. RFC7540 section 6.9" );
861869 return ;
862870 }
863871 Buffer buf = new Buffer ();
864872 buf .write (in .getBuffer (), length );
865- stream .inboundDataReceived (buf , length , inFinished );
873+ stream .inboundDataReceived (buf , length , paddedLength - length , inFinished );
866874 }
867875
868876 // connection window update
@@ -1065,7 +1073,7 @@ private void respondWithHttpError(
10651073 }
10661074 streams .put (streamId , stream );
10671075 if (inFinished ) {
1068- stream .inboundDataReceived (new Buffer (), 0 , true );
1076+ stream .inboundDataReceived (new Buffer (), 0 , 0 , true );
10691077 }
10701078 frameWriter .headers (streamId , headers );
10711079 outboundFlow .data (
@@ -1123,7 +1131,7 @@ public void onPingTimeout() {
11231131
11241132 interface StreamState {
11251133 /** Must be holding 'lock' when calling. */
1126- void inboundDataReceived (Buffer frame , int windowConsumed , boolean endOfStream );
1134+ void inboundDataReceived (Buffer frame , int dataLength , int paddingLength , boolean endOfStream );
11271135
11281136 /** Must be holding 'lock' when calling. */
11291137 boolean hasReceivedEndOfStream ();
@@ -1160,12 +1168,12 @@ static class Http2ErrorStreamState implements StreamState, OutboundFlowControlle
11601168 @ Override public void onSentBytes (int frameBytes ) {}
11611169
11621170 @ Override public void inboundDataReceived (
1163- Buffer frame , int windowConsumed , boolean endOfStream ) {
1171+ Buffer frame , int dataLength , int paddingLength , boolean endOfStream ) {
11641172 synchronized (lock ) {
11651173 if (endOfStream ) {
11661174 receivedEndOfStream = true ;
11671175 }
1168- window -= windowConsumed ;
1176+ window -= dataLength + paddingLength ;
11691177 try {
11701178 frame .skip (frame .size ()); // Recycle segments
11711179 } catch (IOException ex ) {
0 commit comments