| Index: net/quic/reliable_quic_stream_test.cc
|
| diff --git a/net/quic/reliable_quic_stream_test.cc b/net/quic/reliable_quic_stream_test.cc
|
| index dc5c160ee9f8d606a4e7a0add2bfa6a4880b50ed..c73c5b11b03486b62e858a916e979e29f0122d7a 100644
|
| --- a/net/quic/reliable_quic_stream_test.cc
|
| +++ b/net/quic/reliable_quic_stream_test.cc
|
| @@ -44,6 +44,7 @@ class TestStream : public ReliableQuicStream {
|
| }
|
|
|
| virtual uint32 ProcessData(const char* data, uint32 data_len) OVERRIDE {
|
| + EXPECT_NE(0u, data_len);
|
| DVLOG(1) << "ProcessData data_len: " << data_len;
|
| data_ += string(data, data_len);
|
| return should_process_data_ ? data_len : 0;
|
| @@ -66,6 +67,30 @@ class ReliableQuicStreamTest : public ::testing::TestWithParam<bool> {
|
| headers_[":host"] = "www.google.com";
|
| headers_[":path"] = "/index.hml";
|
| headers_[":scheme"] = "https";
|
| + headers_["cookie"] =
|
| + "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; "
|
| + "__utmc=160408618; "
|
| + "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX"
|
| + "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX"
|
| + "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT"
|
| + "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0"
|
| + "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh"
|
| + "1zFMi5vzcns38-8_Sns; "
|
| + "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-"
|
| + "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339"
|
| + "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c"
|
| + "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%"
|
| + "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4"
|
| + "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1"
|
| + "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP"
|
| + "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6"
|
| + "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b"
|
| + "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6"
|
| + "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG"
|
| + "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk"
|
| + "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
|
| + "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
|
| + "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
|
| }
|
|
|
| void Initialize(bool stream_should_process_data) {
|
| @@ -263,6 +288,21 @@ TEST_F(ReliableQuicStreamTest, ProcessHeadersAndBodyFragments) {
|
| ASSERT_EQ(SpdyUtils::SerializeUncompressedHeaders(headers_) + body,
|
| stream_->data()) << "fragment_size: " << fragment_size;
|
| }
|
| +
|
| + for (size_t split_point = 1; split_point < data.size() - 1; ++split_point) {
|
| + Initialize(kShouldProcessData);
|
| +
|
| + StringPiece fragment1(data.data(), split_point);
|
| + QuicStreamFrame frame1(kStreamId, false, 0, fragment1);
|
| + stream_->OnStreamFrame(frame1);
|
| +
|
| + StringPiece fragment2(data.data() + split_point, data.size() - split_point);
|
| + QuicStreamFrame frame2(kStreamId, false, split_point, fragment2);
|
| + stream_->OnStreamFrame(frame2);
|
| +
|
| + ASSERT_EQ(SpdyUtils::SerializeUncompressedHeaders(headers_) + body,
|
| + stream_->data()) << "split_point: " << split_point;
|
| + }
|
| }
|
|
|
| TEST_F(ReliableQuicStreamTest, ProcessHeadersAndBodyReadv) {
|
| @@ -279,7 +319,7 @@ TEST_F(ReliableQuicStreamTest, ProcessHeadersAndBodyReadv) {
|
| stream_->OnStreamFrame(frame);
|
| EXPECT_EQ(uncompressed_headers, stream_->data());
|
|
|
| - char buffer[1024];
|
| + char buffer[2048];
|
| ASSERT_LT(data.length(), arraysize(buffer));
|
| struct iovec vec;
|
| vec.iov_base = buffer;
|
| @@ -348,6 +388,43 @@ TEST_F(ReliableQuicStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) {
|
| }
|
| }
|
|
|
| +TEST_F(ReliableQuicStreamTest, ProcessCorruptHeadersEarly) {
|
| + Initialize(kShouldProcessData);
|
| +
|
| + string compressed_headers1 = compressor_->CompressHeaders(headers_);
|
| + QuicStreamFrame frame1(stream_->id(), false, 0, compressed_headers1);
|
| + string decompressed_headers1 =
|
| + SpdyUtils::SerializeUncompressedHeaders(headers_);
|
| +
|
| + headers_["content-type"] = "text/plain";
|
| + string compressed_headers2 = compressor_->CompressHeaders(headers_);
|
| + compressed_headers2[4] ^= 0xA1; // Corrupt the comressed data.
|
| + QuicStreamFrame frame2(stream2_->id(), false, 0, compressed_headers2);
|
| + string decompressed_headers2 =
|
| + SpdyUtils::SerializeUncompressedHeaders(headers_);
|
| +
|
| + // Deliver frame2 to stream2 out of order. The decompressor is not
|
| + // available yet, so no data will be processed. The compressed data
|
| + // will be buffered until OnDecompressorAvailable() is called
|
| + // to process it.
|
| + stream2_->OnStreamFrame(frame2);
|
| + EXPECT_EQ("", stream2_->data());
|
| +
|
| + // Now deliver frame1 to stream1. The decompressor is available so
|
| + // the data will be processed, and the decompressor will become
|
| + // available for stream2.
|
| + stream_->OnStreamFrame(frame1);
|
| + EXPECT_EQ(decompressed_headers1, stream_->data());
|
| +
|
| + // Verify that the decompressor is available, and inform stream2
|
| + // that it can now decompress the buffered compressed data. Since
|
| + // the compressed data is corrupt, the stream will shutdown the session.
|
| + EXPECT_EQ(2u, session_->decompressor()->current_header_id());
|
| + EXPECT_CALL(*connection_, SendConnectionClose(QUIC_DECOMPRESSION_FAILURE));
|
| + stream2_->OnDecompressorAvailable();
|
| + EXPECT_EQ("", stream2_->data());
|
| +}
|
| +
|
| TEST_F(ReliableQuicStreamTest, ProcessHeadersEarly) {
|
| Initialize(kShouldProcessData);
|
|
|
| @@ -362,12 +439,21 @@ TEST_F(ReliableQuicStreamTest, ProcessHeadersEarly) {
|
| string decompressed_headers2 =
|
| SpdyUtils::SerializeUncompressedHeaders(headers_);
|
|
|
| + // Deliver frame2 to stream2 out of order. The decompressor is not
|
| + // available yet, so no data will be processed. The compressed data
|
| + // will be buffered until OnDecompressorAvailable() is called
|
| + // to process it.
|
| stream2_->OnStreamFrame(frame2);
|
| - EXPECT_EQ("", stream_->data());
|
| + EXPECT_EQ("", stream2_->data());
|
|
|
| + // Now deliver frame1 to stream1. The decompressor is available so
|
| + // the data will be processed, and the decompressor will become
|
| + // available for stream2.
|
| stream_->OnStreamFrame(frame1);
|
| EXPECT_EQ(decompressed_headers1, stream_->data());
|
|
|
| + // Verify that the decompressor is available, and inform stream2
|
| + // that it can now decompress the buffered compressed data.
|
| EXPECT_EQ(2u, session_->decompressor()->current_header_id());
|
| stream2_->OnDecompressorAvailable();
|
| EXPECT_EQ(decompressed_headers2, stream2_->data());
|
|
|