Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: net/tools/quic/quic_client_session_test.cc

Issue 2850523002: QUIC: correctly update local stream state on receipt of trailers after sending RST. Protected by FL… (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/quic/core/quic_spdy_session.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/tools/quic/quic_client_session.h" 5 #include "net/tools/quic/quic_client_session.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "net/quic/core/crypto/aes_128_gcm_12_encrypter.h" 9 #include "net/quic/core/crypto/aes_128_gcm_12_encrypter.h"
10 #include "net/quic/core/spdy_utils.h" 10 #include "net/quic/core/spdy_utils.h"
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 } 192 }
193 193
194 TEST_P(QuicClientSessionTest, MaxNumStreamsWithRst) { 194 TEST_P(QuicClientSessionTest, MaxNumStreamsWithRst) {
195 EXPECT_CALL(*connection_, SendRstStream(_, _, _)).Times(AnyNumber()); 195 EXPECT_CALL(*connection_, SendRstStream(_, _, _)).Times(AnyNumber());
196 196
197 const uint32_t kServerMaxIncomingStreams = 1; 197 const uint32_t kServerMaxIncomingStreams = 1;
198 CompleteCryptoHandshake(kServerMaxIncomingStreams); 198 CompleteCryptoHandshake(kServerMaxIncomingStreams);
199 199
200 QuicSpdyClientStream* stream = 200 QuicSpdyClientStream* stream =
201 session_->CreateOutgoingDynamicStream(kDefaultPriority); 201 session_->CreateOutgoingDynamicStream(kDefaultPriority);
202 ASSERT_TRUE(stream); 202 ASSERT_NE(nullptr, stream);
203 EXPECT_FALSE(session_->CreateOutgoingDynamicStream(kDefaultPriority)); 203 EXPECT_EQ(nullptr, session_->CreateOutgoingDynamicStream(kDefaultPriority));
204 204
205 // Close the stream and receive an RST frame to remove the unfinished stream 205 // Close the stream and receive an RST frame to remove the unfinished stream
206 session_->CloseStream(stream->id()); 206 session_->CloseStream(stream->id());
207 session_->OnRstStream( 207 session_->OnRstStream(
208 QuicRstStreamFrame(stream->id(), QUIC_RST_ACKNOWLEDGEMENT, 0)); 208 QuicRstStreamFrame(stream->id(), QUIC_RST_ACKNOWLEDGEMENT, 0));
209 // Check that a new one can be created. 209 // Check that a new one can be created.
210 EXPECT_EQ(0u, session_->GetNumOpenOutgoingStreams()); 210 EXPECT_EQ(0u, session_->GetNumOpenOutgoingStreams());
211 stream = session_->CreateOutgoingDynamicStream(kDefaultPriority); 211 stream = session_->CreateOutgoingDynamicStream(kDefaultPriority);
212 EXPECT_TRUE(stream); 212 EXPECT_NE(nullptr, stream);
213 }
214
215 TEST_P(QuicClientSessionTest, ResetAndTrailers) {
216 // Tests the situation in which the client sends a RST at the same time that
217 // the server sends trailing headers (trailers). Receipt of the trailers by
218 // the client should result in all outstanding stream state being tidied up
219 // (including flow control, and number of available outgoing streams).
220 const uint32_t kServerMaxIncomingStreams = 1;
221 CompleteCryptoHandshake(kServerMaxIncomingStreams);
222
223 QuicSpdyClientStream* stream =
224 session_->CreateOutgoingDynamicStream(kDefaultPriority);
225 ASSERT_NE(nullptr, stream);
226 EXPECT_FALSE(session_->CreateOutgoingDynamicStream(kDefaultPriority));
227
228 QuicStreamId stream_id = stream->id();
229 EXPECT_CALL(*connection_, SendRstStream(_, _, _)).Times(1);
230 session_->SendRstStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY, 0);
231
232 // A new stream cannot be created as the reset stream still counts as an open
233 // outgoing stream until closed by the server.
234 EXPECT_EQ(1u, session_->GetNumOpenOutgoingStreams());
235 stream = session_->CreateOutgoingDynamicStream(kDefaultPriority);
236 EXPECT_EQ(nullptr, stream);
237
238 // The stream receives trailers with final byte offset: this is one of three
239 // ways that a peer can signal the end of a stream (the others being RST,
240 // stream data + FIN).
241 QuicHeaderList trailers;
242 trailers.OnHeaderBlockStart();
243 trailers.OnHeader(kFinalOffsetHeaderKey, "0");
244 trailers.OnHeaderBlockEnd(0);
245 session_->OnStreamHeaderList(stream_id, /*fin=*/false, 0, trailers);
246
247 if (FLAGS_quic_reloadable_flag_quic_final_offset_from_trailers) {
248 // The stream is now complete from the client's perspective, and it should
249 // be able to create a new outgoing stream.
250 EXPECT_EQ(0u, session_->GetNumOpenOutgoingStreams());
251 stream = session_->CreateOutgoingDynamicStream(kDefaultPriority);
252 EXPECT_NE(nullptr, stream);
253 } else {
254 // The old behavior: receiving trailers with final offset does not trigger
255 // cleanup of local stream state. New streams cannot be created.
256 EXPECT_EQ(1u, session_->GetNumOpenOutgoingStreams());
257 stream = session_->CreateOutgoingDynamicStream(kDefaultPriority);
258 EXPECT_EQ(nullptr, stream);
259 }
260 }
261
262 TEST_P(QuicClientSessionTest, ReceivedMalformedTrailersAfterSendingRst) {
263 // Tests the situation where the client has sent a RST to the server, and has
264 // received trailing headers with a malformed final byte offset value.
265 FLAGS_quic_reloadable_flag_quic_final_offset_from_trailers = true;
266 CompleteCryptoHandshake();
267
268 QuicSpdyClientStream* stream =
269 session_->CreateOutgoingDynamicStream(kDefaultPriority);
270 ASSERT_NE(nullptr, stream);
271
272 // Send the RST, which results in the stream being closed locally (but some
273 // state remains while the client waits for a response from the server).
274 QuicStreamId stream_id = stream->id();
275 EXPECT_CALL(*connection_, SendRstStream(_, _, _)).Times(1);
276 session_->SendRstStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY, 0);
277
278 // The stream receives trailers with final byte offset, but the header value
279 // is non-numeric and should be treated as malformed.
280 QuicHeaderList trailers;
281 trailers.OnHeaderBlockStart();
282 trailers.OnHeader(kFinalOffsetHeaderKey, "invalid non-numeric value");
283 trailers.OnHeaderBlockEnd(0);
284
285 EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
286 session_->OnStreamHeaderList(stream_id, /*fin=*/false, 0, trailers);
213 } 287 }
214 288
215 TEST_P(QuicClientSessionTest, GoAwayReceived) { 289 TEST_P(QuicClientSessionTest, GoAwayReceived) {
216 CompleteCryptoHandshake(); 290 CompleteCryptoHandshake();
217 291
218 // After receiving a GoAway, I should no longer be able to create outgoing 292 // After receiving a GoAway, I should no longer be able to create outgoing
219 // streams. 293 // streams.
220 session_->connection()->OnGoAwayFrame( 294 session_->connection()->OnGoAwayFrame(
221 QuicGoAwayFrame(QUIC_PEER_GOING_AWAY, 1u, "Going away.")); 295 QuicGoAwayFrame(QUIC_PEER_GOING_AWAY, 1u, "Going away."));
222 EXPECT_EQ(nullptr, session_->CreateOutgoingDynamicStream(kDefaultPriority)); 296 EXPECT_EQ(nullptr, session_->CreateOutgoingDynamicStream(kDefaultPriority));
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 QuicClientPromisedInfo* promised = 558 QuicClientPromisedInfo* promised =
485 session_->GetPromisedById(promised_stream_id_); 559 session_->GetPromisedById(promised_stream_id_);
486 EXPECT_NE(promised, nullptr); 560 EXPECT_NE(promised, nullptr);
487 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr); 561 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
488 EXPECT_EQ(session_->GetPromisedStream(promised_stream_id_), nullptr); 562 EXPECT_EQ(session_->GetPromisedStream(promised_stream_id_), nullptr);
489 } 563 }
490 564
491 } // namespace 565 } // namespace
492 } // namespace test 566 } // namespace test
493 } // namespace net 567 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/core/quic_spdy_session.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698