1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <cstddef> 6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <string> 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <vector> 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/stl_util.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log_unittest.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/request_priority.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/socket/next_proto.h" 177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/socket/socket_test_util.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/buffered_spdy_framer.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_http_utils.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_protocol.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_session.h" 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/spdy/spdy_stream.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_stream_test_util.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_test_util_common.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(ukai): factor out common part with spdy_http_stream_unittest.cc 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace test { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kStreamUrl[] = "http://www.google.com/"; 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kPostBody[] = "\0hello!\xff"; 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const size_t kPostBodyLength = arraysize(kPostBody); 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::StringPiece kPostBodyStringPiece(kPostBody, kPostBodyLength); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class SpdyStreamTest : public ::testing::Test, 41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public ::testing::WithParamInterface<NextProto> { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // A function that takes a SpdyStream and the number of bytes which 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // will unstall the next frame completely. 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) typedef base::Callback<void(const base::WeakPtr<SpdyStream>&, int32)> 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UnstallFunction; 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SpdyStreamTest() 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : spdy_util_(GetParam()), 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) session_deps_(GetParam()), 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) offset_(0) {} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 53ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> CreateDefaultSpdySession() { 547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SpdySessionKey key(HostPortPair("www.google.com", 80), 557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ProxyServer::Direct(), 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) kPrivacyModeDisabled); 577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return CreateInsecureSpdySession(session_, key, BoundNetLog()); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() { 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void RunResumeAfterUnstallRequestResponseTest( 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const UnstallFunction& unstall_function); 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void RunResumeAfterUnstallBidirectionalTest( 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const UnstallFunction& unstall_function); 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Add{Read,Write}() populates lists that are eventually passed to a 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // SocketData class. |frame| must live for the whole test. 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void AddRead(const SpdyFrame& frame) { 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) reads_.push_back(CreateMockRead(frame, offset_++)); 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void AddWrite(const SpdyFrame& frame) { 78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) writes_.push_back(CreateMockWrite(frame, offset_++)); 79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void AddReadEOF() { 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) reads_.push_back(MockRead(ASYNC, 0, offset_++)); 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) MockRead* GetReads() { 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return vector_as_array(&reads_); 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) size_t GetNumReads() const { 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return reads_.size(); 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) MockWrite* GetWrites() { 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return vector_as_array(&writes_); 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int GetNumWrites() const { 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return writes_.size(); 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 101b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) SpdyTestUtil spdy_util_; 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdySessionDependencies session_deps_; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<HttpNetworkSession> session_; 104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Used by Add{Read,Write}() above. 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<MockWrite> writes_; 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<MockRead> reads_; 109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int offset_; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)INSTANTIATE_TEST_CASE_P( 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NextProto, 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SpdyStreamTest, 115558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2, 116558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch kProtoHTTP2Draft04)); 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_P(SpdyStreamTest, SendDataAfterOpen) { 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url(kStreamUrl); 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> req( 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0)); 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddWrite(*req); 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<SpdyFrame> resp( 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddRead(*resp); 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> msg( 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false)); 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddWrite(*msg); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> echo( 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false)); 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddRead(*echo); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddReadEOF(); 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) OrderedSocketData data(GetReads(), GetNumReads(), 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GetWrites(), GetNumWrites()); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 149ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session(CreateDefaultSpdySession()); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 151a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream = 15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously( 15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SPDY_BIDIRECTIONAL_STREAM, session, url, LOWEST, BoundNetLog()); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(stream.get() != NULL); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream->SetDelegate(&delegate); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 159ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream->HasUrlFromHeaders()); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 162b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength)); 16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); 165ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream->HasUrlFromHeaders()); 166ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec()); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose()); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(delegate.send_headers_completed()); 171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy_util_.GetStatusKey())); 172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ("HTTP/1.1", 173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) delegate.GetResponseHeaderValue(spdy_util_.GetVersionKey())); 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(std::string(kPostBody, kPostBodyLength), 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delegate.TakeReceivedData()); 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_P(SpdyStreamTest, PushedStream) { 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddReadEOF(); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OrderedSocketData data(GetReads(), GetNumReads(), 185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GetWrites(), GetNumWrites()); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 191ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> spdy_session(CreateDefaultSpdySession()); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Conjure up a stream. 19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SpdyStream stream(SPDY_PUSH_STREAM, 195ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch spdy_session, 196ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch GURL(), 197a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DEFAULT_PRIORITY, 198a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) kSpdyStreamInitialWindowSize, 199a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) kSpdyStreamInitialWindowSize, 2007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch BoundNetLog()); 201a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) stream.set_stream_id(2); 202ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream.HasUrlFromHeaders()); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set a couple of headers. 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdyHeaderBlock response; 206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.AddUrlToHeaderBlock(kStreamUrl, &response); 207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream.OnInitialResponseHeadersReceived( 208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch response, base::Time::Now(), base::TimeTicks::Now()); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send some basic headers. 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdyHeaderBlock headers; 212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch headers[spdy_util_.GetStatusKey()] = "200"; 213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch headers[spdy_util_.GetVersionKey()] = "OK"; 214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream.OnAdditionalResponseHeadersReceived(headers); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 216ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream.HasUrlFromHeaders()); 217ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream.GetUrlFromHeaders().spec()); 218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StreamDelegateDoNothing delegate(stream.GetWeakPtr()); 220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream.SetDelegate(&delegate); 221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::MessageLoop::current()->RunUntilIdle(); 223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy_util_.GetStatusKey())); 225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 226ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(spdy_session == NULL); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_P(SpdyStreamTest, StreamError) { 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url(kStreamUrl); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> req( 235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0)); 237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddWrite(*req); 238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<SpdyFrame> resp( 240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddRead(*resp); 242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> msg( 244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false)); 245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddWrite(*msg); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpdyFrame> echo( 248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false)); 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddRead(*echo); 250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddReadEOF(); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CapturingBoundNetLog log; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) OrderedSocketData data(GetReads(), GetNumReads(), 256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GetWrites(), GetNumWrites()); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.set_connect_data(connect_data); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 262ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session(CreateDefaultSpdySession()); 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 264a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream = 26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously( 26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SPDY_BIDIRECTIONAL_STREAM, session, url, LOWEST, log.bound()); 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(stream.get() != NULL); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece); 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream->SetDelegate(&delegate); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 272ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream->HasUrlFromHeaders()); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 275b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength)); 27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); 278ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream->HasUrlFromHeaders()); 279ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec()); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose()); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 283a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const SpdyStreamId stream_id = delegate.stream_id(); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(delegate.send_headers_completed()); 286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy_util_.GetStatusKey())); 287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ("HTTP/1.1", 288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) delegate.GetResponseHeaderValue(spdy_util_.GetVersionKey())); 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(std::string(kPostBody, kPostBodyLength), 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delegate.TakeReceivedData()); 29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that the NetLog was filled reasonably. 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CapturingNetLog::CapturedEntryList entries; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log.GetEntries(&entries); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LT(0u, entries.size()); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that we logged SPDY_STREAM_ERROR correctly. 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pos = net::ExpectLogContainsSomewhere( 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries, 0, 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_SPDY_STREAM_ERROR, 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::PHASE_NONE); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int stream_id2; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &stream_id2)); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(static_cast<int>(stream_id), stream_id2); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Make sure that large blocks of data are properly split up into 31090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// frame-sized chunks for a request/response (i.e., an HTTP-like) 31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// stream. 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_P(SpdyStreamTest, SendLargeDataAfterOpenRequestResponse) { 31390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GURL url(kStreamUrl); 31490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 31590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); 31690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 31790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0)); 320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddWrite(*req); 321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string chunk_data(kMaxSpdyFrameChunkSize, 'x'); 32390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> chunk( 324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame( 32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1, chunk_data.data(), chunk_data.length(), false)); 326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddWrite(*chunk); 327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddWrite(*chunk); 328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 32990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> last_chunk( 330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame( 33190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1, chunk_data.data(), chunk_data.length(), true)); 332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddWrite(*last_chunk); 33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddRead(*resp); 336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddReadEOF(); 33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) OrderedSocketData data(GetReads(), GetNumReads(), 340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GetWrites(), GetNumWrites()); 34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data.set_connect_data(connect_data); 34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 34590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 346ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session(CreateDefaultSpdySession()); 34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::WeakPtr<SpdyStream> stream = 34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously( 35090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SPDY_REQUEST_RESPONSE_STREAM, session, url, LOWEST, BoundNetLog()); 35190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(stream.get() != NULL); 35290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 35390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string body_data(3 * kMaxSpdyFrameChunkSize, 'x'); 35490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StreamDelegateWithBody delegate(stream, body_data); 35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->SetDelegate(&delegate); 35690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 357ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream->HasUrlFromHeaders()); 35890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 35990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 36090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength)); 36190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 36290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); 363ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream->HasUrlFromHeaders()); 364ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec()); 36590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 36690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose()); 36790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 36890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(delegate.send_headers_completed()); 369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy_util_.GetStatusKey())); 370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ("HTTP/1.1", 371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) delegate.GetResponseHeaderValue(spdy_util_.GetVersionKey())); 37290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(std::string(), delegate.TakeReceivedData()); 37390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 37490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 37590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 37690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Make sure that large blocks of data are properly split up into 37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// frame-sized chunks for a bidirectional (i.e., non-HTTP-like) 37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// stream. 379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_P(SpdyStreamTest, SendLargeDataAfterOpenBidirectional) { 38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GURL url(kStreamUrl); 38190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); 38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 38490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0)); 387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddWrite(*req); 388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddRead(*resp); 391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 39290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string chunk_data(kMaxSpdyFrameChunkSize, 'x'); 39390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> chunk( 394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame( 39590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1, chunk_data.data(), chunk_data.length(), false)); 396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddWrite(*chunk); 397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddWrite(*chunk); 398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddWrite(*chunk); 39990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddReadEOF(); 40190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 402868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) OrderedSocketData data(GetReads(), GetNumReads(), 403868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GetWrites(), GetNumWrites()); 40490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 40590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data.set_connect_data(connect_data); 40690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 40790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session_deps_.socket_factory->AddSocketDataProvider(&data); 40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 409ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session(CreateDefaultSpdySession()); 41090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::WeakPtr<SpdyStream> stream = 41290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously( 41390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SPDY_BIDIRECTIONAL_STREAM, session, url, LOWEST, BoundNetLog()); 41490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(stream.get() != NULL); 41590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 41690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string body_data(3 * kMaxSpdyFrameChunkSize, 'x'); 41790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StreamDelegateSendImmediate delegate(stream, body_data); 41890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->SetDelegate(&delegate); 41990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 420ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream->HasUrlFromHeaders()); 42190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 42290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 42390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength)); 42490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 42590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); 426ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream->HasUrlFromHeaders()); 427ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec()); 42890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 42990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose()); 43090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 43190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(delegate.send_headers_completed()); 432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy_util_.GetStatusKey())); 433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ("HTTP/1.1", 434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) delegate.GetResponseHeaderValue(spdy_util_.GetVersionKey())); 43590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(std::string(), delegate.TakeReceivedData()); 43690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 43790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 43890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 439eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Receiving a header with uppercase ASCII should result in a protocol 440eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// error. 441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyStreamTest, UpperCaseHeaders) { 442eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url(kStreamUrl); 443eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 444eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_ = 445eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_); 446eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 447eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> syn( 448eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 449eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddWrite(*syn); 450eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 451eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char* const kExtraHeaders[] = {"X-UpperCase", "yes"}; 452eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 453eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reply(spdy_util_.ConstructSpdyGetSynReply(kExtraHeaders, 1, 1)); 454eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddRead(*reply); 455eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 456eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> rst( 457eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR)); 458eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddWrite(*rst); 459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 460eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddReadEOF(); 461eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 462eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(GetReads(), GetNumReads(), 463eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GetWrites(), GetNumWrites()); 464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 465eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.set_connect_data(connect_data); 466eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 467eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 468eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 469ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session(CreateDefaultSpdySession()); 470eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 471eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> stream = 472eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously( 473eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SPDY_REQUEST_RESPONSE_STREAM, session, url, LOWEST, BoundNetLog()); 474eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(stream.get() != NULL); 475eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 476eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StreamDelegateDoNothing delegate(stream); 477eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream->SetDelegate(&delegate); 478eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 479ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream->HasUrlFromHeaders()); 480eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 481eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers( 482eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock(kStreamUrl)); 483eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, 484eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND)); 485ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream->HasUrlFromHeaders()); 486ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec()); 487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(4); 489eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, delegate.WaitForClose()); 491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Receiving a header with uppercase ASCII should result in a protocol 494eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// error even for a push stream. 495eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyStreamTest, UpperCaseHeadersOnPush) { 496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url(kStreamUrl); 497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_ = 499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_); 500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> syn( 502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddWrite(*syn); 504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 506eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 507eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddRead(*reply); 508eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 509eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char* const extra_headers[] = {"X-UpperCase", "yes"}; 510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch push(spdy_util_.ConstructSpdyPush(extra_headers, 1, 2, 1, kStreamUrl)); 512eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddRead(*push); 513eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 514eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> rst( 515eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR)); 516eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddWrite(*rst); 517eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 518eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddReadEOF(); 519eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 520eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(GetReads(), GetNumReads(), 521eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GetWrites(), GetNumWrites()); 522eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 523eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.set_connect_data(connect_data); 524eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 525eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 526eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 527ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session(CreateDefaultSpdySession()); 528eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 529eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> stream = 530eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously( 531eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SPDY_REQUEST_RESPONSE_STREAM, session, url, LOWEST, BoundNetLog()); 532eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(stream.get() != NULL); 533eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 534eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StreamDelegateDoNothing delegate(stream); 535eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream->SetDelegate(&delegate); 536eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 537ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream->HasUrlFromHeaders()); 538eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 539eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers( 540eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock(kStreamUrl)); 541eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, 542eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND)); 543ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream->HasUrlFromHeaders()); 544ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec()); 545eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 546eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(4); 547eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 548eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> push_stream; 549eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, session->GetPushStream(url, &push_stream, BoundNetLog())); 550eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(push_stream); 551eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 552eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 553eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 554eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose()); 555eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 556eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 557eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Receiving a header with uppercase ASCII in a HEADERS frame should 558eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// result in a protocol error. 559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyStreamTest, UpperCaseHeadersInHeadersFrame) { 560eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url(kStreamUrl); 561eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 562eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_ = 563eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_); 564eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 565eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> syn( 566eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 567eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddWrite(*syn); 568eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 569eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 570eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 571eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddRead(*reply); 572eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 573eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 574eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch push(spdy_util_.ConstructSpdyPush(NULL, 0, 2, 1, kStreamUrl)); 575eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddRead(*push); 576eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 577eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock()); 578eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*late_headers)["X-UpperCase"] = "yes"; 579eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> headers_frame( 580eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(), 581eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch false, 582eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 583eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOWEST, 584eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HEADERS, 585eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CONTROL_FLAG_NONE, 586eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0)); 587eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddRead(*headers_frame); 588eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 589eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> rst( 590eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR)); 591eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddWrite(*rst); 592eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 593eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddReadEOF(); 594eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 595eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(GetReads(), GetNumReads(), 596eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GetWrites(), GetNumWrites()); 597eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 598eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.set_connect_data(connect_data); 599eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 600eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 601eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 602ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session(CreateDefaultSpdySession()); 603eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 604eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> stream = 605eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously( 606eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SPDY_REQUEST_RESPONSE_STREAM, session, url, LOWEST, BoundNetLog()); 607eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(stream.get() != NULL); 608eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StreamDelegateDoNothing delegate(stream); 610eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream->SetDelegate(&delegate); 611eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 612ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream->HasUrlFromHeaders()); 613eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 614eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers( 615eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock(kStreamUrl)); 616eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, 617eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND)); 618ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream->HasUrlFromHeaders()); 619ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec()); 620eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 621eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(3); 622eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 623eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> push_stream; 624eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, session->GetPushStream(url, &push_stream, BoundNetLog())); 625eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(push_stream); 626eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 627eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 628eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 629eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, session->GetPushStream(url, &push_stream, BoundNetLog())); 630eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(push_stream); 631eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 632eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(2); 633eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 634eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose()); 635eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 636eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 637eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Receiving a duplicate header in a HEADERS frame should result in a 638eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// protocol error. 639eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(SpdyStreamTest, DuplicateHeaders) { 640eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url(kStreamUrl); 641eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 642eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_ = 643eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_); 644eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> syn( 646eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddWrite(*syn); 648eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 649eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 650eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 651eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddRead(*reply); 652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 653eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> 654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch push(spdy_util_.ConstructSpdyPush(NULL, 0, 2, 1, kStreamUrl)); 655eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddRead(*push); 656eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 657eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock()); 658eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*late_headers)[spdy_util_.GetStatusKey()] = "500 Server Error"; 659eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> headers_frame( 660eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(), 661eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch false, 662eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2, 663eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOWEST, 664eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HEADERS, 665eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CONTROL_FLAG_NONE, 666eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0)); 667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddRead(*headers_frame); 668eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 669eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyFrame> rst( 670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR)); 671eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddWrite(*rst); 672eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 673eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddReadEOF(); 674eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 675eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeterministicSocketData data(GetReads(), GetNumReads(), 676eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GetWrites(), GetNumWrites()); 677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MockConnect connect_data(SYNCHRONOUS, OK); 678eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.set_connect_data(connect_data); 679eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 680eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 681eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 682ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session(CreateDefaultSpdySession()); 683eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 684eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> stream = 685eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateStreamSynchronously( 686eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SPDY_REQUEST_RESPONSE_STREAM, session, url, LOWEST, BoundNetLog()); 687eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(stream.get() != NULL); 688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StreamDelegateDoNothing delegate(stream); 690eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream->SetDelegate(&delegate); 691eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 692ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream->HasUrlFromHeaders()); 693eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 694eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> headers( 695eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_util_.ConstructGetHeaderBlock(kStreamUrl)); 696eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_IO_PENDING, 697eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND)); 698ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream->HasUrlFromHeaders()); 699ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec()); 700eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 701eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(3); 702eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 703eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> push_stream; 704eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, session->GetPushStream(url, &push_stream, BoundNetLog())); 705eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(push_stream); 706eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 707eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(1); 708eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 709eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(OK, session->GetPushStream(url, &push_stream, BoundNetLog())); 710eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(push_stream); 711eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 712eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch data.RunFor(2); 713eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 714eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose()); 715eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 716eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 717868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// The tests below are only for SPDY/3 and above. 718868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Call IncreaseSendWindowSize on a stream with a large enough delta 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// to overflow an int32. The SpdyStream should handle that case 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// gracefully. 722868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_P(SpdyStreamTest, IncreaseSendWindowSizeOverflow) { 723868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (spdy_util_.protocol() < kProtoSPDY3) 724868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 725868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 726a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) session_ = 727a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_); 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 729a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 730868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 731868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0)); 732868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddWrite(*req); 733868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Triggered by the overflowing call to IncreaseSendWindowSize 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // below. 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> rst( 73790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_FLOW_CONTROL_ERROR)); 738868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddWrite(*rst); 739868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 740868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddReadEOF(); 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CapturingBoundNetLog log; 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 744868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DeterministicSocketData data(GetReads(), GetNumReads(), 745868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GetWrites(), GetNumWrites()); 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 749a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 751ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session(CreateDefaultSpdySession()); 7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url(kStreamUrl); 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 754a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream = 75590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously( 75690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SPDY_BIDIRECTIONAL_STREAM, session, url, LOWEST, log.bound()); 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(stream.get() != NULL); 75890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece); 7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream->SetDelegate(&delegate); 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 76190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 762a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength)); 76390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 76490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); 765ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream->HasUrlFromHeaders()); 766ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec()); 767a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 768a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) data.RunFor(1); 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32 old_send_window_size = stream->send_window_size(); 7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_GT(old_send_window_size, 0); 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32 delta_window_size = kint32max - old_send_window_size + 1; 7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream->IncreaseSendWindowSize(delta_window_size); 774a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(NULL, stream.get()); 7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 776a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) data.RunFor(2); 777a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 778a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, delegate.WaitForClose()); 7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 78190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Functions used with 78290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// RunResumeAfterUnstall{RequestResponse,Bidirectional}Test(). 78390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 78490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void StallStream(const base::WeakPtr<SpdyStream>& stream) { 78590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Reduce the send window size to 0 to stall. 78690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) while (stream->send_window_size() > 0) { 78790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->DecreaseSendWindowSize( 78890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::min(kMaxSpdyFrameChunkSize, stream->send_window_size())); 78990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 79090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 79190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 79290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void IncreaseStreamSendWindowSize(const base::WeakPtr<SpdyStream>& stream, 79390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int32 delta_window_size) { 79490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(stream->send_stalled_by_flow_control()); 79590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->IncreaseSendWindowSize(delta_window_size); 79690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_FALSE(stream->send_stalled_by_flow_control()); 79790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 79890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 79990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AdjustStreamSendWindowSize(const base::WeakPtr<SpdyStream>& stream, 80090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int32 delta_window_size) { 80190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Make sure that negative adjustments are handled properly. 80290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(stream->send_stalled_by_flow_control()); 80390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->AdjustSendWindowSize(-delta_window_size); 80490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(stream->send_stalled_by_flow_control()); 80590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->AdjustSendWindowSize(+delta_window_size); 80690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(stream->send_stalled_by_flow_control()); 80790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->AdjustSendWindowSize(+delta_window_size); 80890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_FALSE(stream->send_stalled_by_flow_control()); 80990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 81090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 81190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Given an unstall function, runs a test to make sure that a 81290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// request/response (i.e., an HTTP-like) stream resumes after a stall 81390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// and unstall. 814868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void SpdyStreamTest::RunResumeAfterUnstallRequestResponseTest( 81590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const UnstallFunction& unstall_function) { 8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url(kStreamUrl); 8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_ = 8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_); 8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 822868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 823868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0)); 824868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddWrite(*req); 825868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 82690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyFrame> body( 827868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, true)); 828868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddWrite(*body); 8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 830868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 831868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddRead(*resp); 832868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 833868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddReadEOF(); 8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 835868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DeterministicSocketData data(GetReads(), GetNumReads(), 836868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GetWrites(), GetNumWrites()); 8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 842ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session(CreateDefaultSpdySession()); 8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 844a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream = 84590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously( 84690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SPDY_REQUEST_RESPONSE_STREAM, session, url, LOWEST, BoundNetLog()); 8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(stream.get() != NULL); 8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 849a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) StreamDelegateWithBody delegate(stream, kPostBodyStringPiece); 8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream->SetDelegate(&delegate); 8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 852ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream->HasUrlFromHeaders()); 85390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_FALSE(stream->send_stalled_by_flow_control()); 8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 85590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 856b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength)); 85790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 85890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); 859ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream->HasUrlFromHeaders()); 860ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec()); 8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 86290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StallStream(stream); 8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 86490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data.RunFor(1); 8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(stream->send_stalled_by_flow_control()); 8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 86890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) unstall_function.Run(stream, kPostBodyLength); 8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(stream->send_stalled_by_flow_control()); 8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(3); 8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose()); 8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(delegate.send_headers_completed()); 8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status")); 8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ("HTTP/1.1", delegate.GetResponseHeaderValue(":version")); 87990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(std::string(), delegate.TakeReceivedData()); 88090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 883868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_P(SpdyStreamTest, ResumeAfterSendWindowSizeIncreaseRequestResponse) { 884eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (spdy_util_.protocol() < kProtoSPDY3) 885eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 886eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 88790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RunResumeAfterUnstallRequestResponseTest( 88890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&IncreaseStreamSendWindowSize)); 88990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 89090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 891868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_P(SpdyStreamTest, ResumeAfterSendWindowSizeAdjustRequestResponse) { 892eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (spdy_util_.protocol() < kProtoSPDY3) 893eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 894eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 89590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RunResumeAfterUnstallRequestResponseTest( 89690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&AdjustStreamSendWindowSize)); 89790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 89890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 89990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Given an unstall function, runs a test to make sure that a 90090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// bidirectional (i.e., non-HTTP-like) stream resumes after a stall 90190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// and unstall. 902868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void SpdyStreamTest::RunResumeAfterUnstallBidirectionalTest( 90390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const UnstallFunction& unstall_function) { 9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url(kStreamUrl); 9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_ = 9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_); 9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> req( 910868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.ConstructSpdyPost( 911868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0)); 912868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddWrite(*req); 913868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 914868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 915868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddRead(*resp); 916868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> msg( 918868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false)); 919868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddWrite(*msg); 9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SpdyFrame> echo( 922868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false)); 923868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddRead(*echo); 9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 925868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddReadEOF(); 926868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 927868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DeterministicSocketData data(GetReads(), GetNumReads(), 928868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GetWrites(), GetNumWrites()); 9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnect connect_data(SYNCHRONOUS, OK); 9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.set_connect_data(connect_data); 9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 934ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> session(CreateDefaultSpdySession()); 9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 936a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream = 93790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateStreamSynchronously( 93890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SPDY_BIDIRECTIONAL_STREAM, session, url, LOWEST, BoundNetLog()); 9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(stream.get() != NULL); 9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 94190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece); 9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream->SetDelegate(&delegate); 9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 944ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_FALSE(stream->HasUrlFromHeaders()); 9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 94690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> headers( 947b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength)); 94890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 94990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); 950ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(stream->HasUrlFromHeaders()); 951ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec()); 9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 95390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data.RunFor(1); 9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(stream->send_stalled_by_flow_control()); 9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 95790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StallStream(stream); 9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 95990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data.RunFor(1); 9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(stream->send_stalled_by_flow_control()); 9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 96390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) unstall_function.Run(stream, kPostBodyLength); 9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(stream->send_stalled_by_flow_control()); 9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.RunFor(3); 9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose()); 9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(delegate.send_headers_completed()); 9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status")); 9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ("HTTP/1.1", delegate.GetResponseHeaderValue(":version")); 974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(std::string(kPostBody, kPostBodyLength), 975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delegate.TakeReceivedData()); 97690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(data.at_write_eof()); 97790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 97890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 979868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_P(SpdyStreamTest, ResumeAfterSendWindowSizeIncreaseBidirectional) { 980eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (spdy_util_.protocol() < kProtoSPDY3) 981eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 982eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 98390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RunResumeAfterUnstallBidirectionalTest( 98490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&IncreaseStreamSendWindowSize)); 98590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 98690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 987868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_P(SpdyStreamTest, ResumeAfterSendWindowSizeAdjustBidirectional) { 988eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (spdy_util_.protocol() < kProtoSPDY3) 989eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 990eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 99190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RunResumeAfterUnstallBidirectionalTest( 99290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&AdjustStreamSendWindowSize)); 9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace test 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 1000