@@ -120,6 +120,76 @@ await ExpectAsync(Http2FrameType.HEADERS,
120
120
_mockTimeoutHandler . VerifyNoOtherCalls ( ) ;
121
121
}
122
122
123
+ [ Fact ]
124
+ public async Task PING_WithinKeepAliveTimeout_ResetKeepAliveTimeout ( )
125
+ {
126
+ var mockSystemClock = _serviceContext . MockSystemClock ;
127
+ var limits = _serviceContext . ServerOptions . Limits ;
128
+
129
+ _timeoutControl . Initialize ( mockSystemClock . UtcNow . Ticks ) ;
130
+
131
+ CreateConnection ( ) ;
132
+
133
+ await InitializeConnectionAsync ( _noopApplication ) ;
134
+
135
+ // Connection starts and sets keep alive timeout
136
+ _mockTimeoutControl . Verify ( c => c . SetTimeout ( It . IsAny < long > ( ) , TimeoutReason . KeepAlive ) , Times . Once ) ;
137
+ _mockTimeoutControl . Verify ( c => c . ResetTimeout ( It . IsAny < long > ( ) , TimeoutReason . KeepAlive ) , Times . Never ) ;
138
+
139
+ await SendPingAsync ( Http2PingFrameFlags . NONE ) ;
140
+ await ExpectAsync ( Http2FrameType . PING ,
141
+ withLength : 8 ,
142
+ withFlags : ( byte ) Http2PingFrameFlags . ACK ,
143
+ withStreamId : 0 ) ;
144
+
145
+ // Server resets keep alive timeout
146
+ _mockTimeoutControl . Verify ( c => c . ResetTimeout ( It . IsAny < long > ( ) , TimeoutReason . KeepAlive ) , Times . Once ) ;
147
+ }
148
+
149
+ [ Fact ]
150
+ public async Task PING_NoKeepAliveTimeout_DoesNotResetKeepAliveTimeout ( )
151
+ {
152
+ var mockSystemClock = _serviceContext . MockSystemClock ;
153
+ var limits = _serviceContext . ServerOptions . Limits ;
154
+
155
+ _timeoutControl . Initialize ( mockSystemClock . UtcNow . Ticks ) ;
156
+
157
+ CreateConnection ( ) ;
158
+
159
+ await InitializeConnectionAsync ( _echoApplication ) ;
160
+
161
+ // Connection starts and sets keep alive timeout
162
+ _mockTimeoutControl . Verify ( c => c . SetTimeout ( It . IsAny < long > ( ) , TimeoutReason . KeepAlive ) , Times . Once ) ;
163
+ _mockTimeoutControl . Verify ( c => c . ResetTimeout ( It . IsAny < long > ( ) , TimeoutReason . KeepAlive ) , Times . Never ) ;
164
+ _mockTimeoutControl . Verify ( c => c . CancelTimeout ( ) , Times . Never ) ;
165
+
166
+ // Stream will stay open because it is waiting for request body to end
167
+ await StartStreamAsync ( 1 , _browserRequestHeaders , endStream : false ) ;
168
+
169
+ // Starting a stream cancels the keep alive timeout
170
+ _mockTimeoutControl . Verify ( c => c . CancelTimeout ( ) , Times . Once ) ;
171
+
172
+ await SendPingAsync ( Http2PingFrameFlags . NONE ) ;
173
+ await ExpectAsync ( Http2FrameType . PING ,
174
+ withLength : 8 ,
175
+ withFlags : ( byte ) Http2PingFrameFlags . ACK ,
176
+ withStreamId : 0 ) ;
177
+
178
+ // Server doesn't reset keep alive timeout because it isn't running
179
+ _mockTimeoutControl . Verify ( c => c . ResetTimeout ( It . IsAny < long > ( ) , TimeoutReason . KeepAlive ) , Times . Never ) ;
180
+
181
+ // End stream
182
+ await SendDataAsync ( 1 , _helloWorldBytes , endStream : true ) ;
183
+ await ExpectAsync ( Http2FrameType . HEADERS ,
184
+ withLength : 37 ,
185
+ withFlags : ( byte ) Http2HeadersFrameFlags . END_HEADERS ,
186
+ withStreamId : 1 ) ;
187
+ await ExpectAsync ( Http2FrameType . DATA ,
188
+ withLength : _helloWorldBytes . Length ,
189
+ withFlags : ( byte ) Http2DataFrameFlags . NONE ,
190
+ withStreamId : 1 ) ;
191
+ }
192
+
123
193
[ Fact ]
124
194
public async Task HEADERS_ReceivedWithoutAllCONTINUATIONs_WithinRequestHeadersTimeout_AbortsConnection ( )
125
195
{
0 commit comments