summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-08 14:47:15 +0000
committerrch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-08 14:47:15 +0000
commit4fee9672b34ce093651ee0d291b296dcd6a10e5c (patch)
treeb94564e22b192539f877f59a2666c86dc6691251
parentf773eb59fa48d6917845fd1300d598f71ff719c8 (diff)
downloadchromium_src-4fee9672b34ce093651ee0d291b296dcd6a10e5c.zip
chromium_src-4fee9672b34ce093651ee0d291b296dcd6a10e5c.tar.gz
chromium_src-4fee9672b34ce093651ee0d291b296dcd6a10e5c.tar.bz2
Do not delete a QuicSession in StartReading.
BUG=332237 Review URL: https://codereview.chromium.org/127113003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@243559 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--net/quic/quic_client_session.cc2
-rw-r--r--net/quic/quic_network_transaction_unittest.cc51
-rw-r--r--net/quic/quic_stream_factory.cc3
3 files changed, 55 insertions, 1 deletions
diff --git a/net/quic/quic_client_session.cc b/net/quic/quic_client_session.cc
index 8fbe5f1..3a71b0f 100644
--- a/net/quic/quic_client_session.cc
+++ b/net/quic/quic_client_session.cc
@@ -537,7 +537,7 @@ void QuicClientSession::OnReadComplete(int result) {
// use a weak pointer to be safe.
connection()->ProcessUdpPacket(local_address, peer_address, packet);
if (!connection()->connected()) {
- stream_factory_->OnSessionClosed(this);
+ NotifyFactoryOfSessionClosedLater();
return;
}
StartReading();
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc
index 5830e56..dd0bdb7 100644
--- a/net/quic/quic_network_transaction_unittest.cc
+++ b/net/quic/quic_network_transaction_unittest.cc
@@ -838,5 +838,56 @@ TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
EXPECT_TRUE(quic_data.at_write_eof());
}
+TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
+ HttpStreamFactory::EnableNpnSpdy3(); // Enables QUIC too.
+
+ QuicStreamId stream_id = GetParam() > QUIC_VERSION_12 ? 5 : 3;
+ MockQuicData mock_quic_data;
+ mock_quic_data.AddRead(ConstructConnectionClosePacket(1));
+ if (GetParam() > QUIC_VERSION_12) {
+ mock_quic_data.AddWrite(
+ ConstructRequestHeadersPacket(1, stream_id, true, true,
+ GetRequestHeaders("GET", "http", "/")));
+ mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
+ } else {
+ mock_quic_data.AddWrite(
+ ConstructDataPacket(1, stream_id, true, true, 0,
+ GetRequestString("GET", "http", "/")));
+ mock_quic_data.AddWrite(ConstructAckPacket(1, 0));
+ }
+ mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 0);
+
+ // When the QUIC connection fails, we will try the request again over HTTP.
+ MockRead http_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead(kQuicAlternateProtocolHttpHeader),
+ MockRead("hello world"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)
+ };
+
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
+ NULL, 0);
+ socket_factory_.AddSocketDataProvider(&http_data);
+
+ // In order for a new QUIC session to be established via alternate-protocol
+ // without racing an HTTP connection, we need the host resolution to happen
+ // synchronously.
+ host_resolver_.set_synchronous_mode(true);
+ host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
+ HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
+ AddressList address;
+ host_resolver_.Resolve(info,
+ DEFAULT_PRIORITY,
+ &address,
+ CompletionCallback(),
+ NULL,
+ net_log_.bound());
+
+ CreateSession();
+ AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
+ SendRequestAndExpectHttpResponse("hello world");
+}
+
} // namespace test
} // namespace net
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc
index efa9fca..a31b5cb 100644
--- a/net/quic/quic_stream_factory.cc
+++ b/net/quic/quic_stream_factory.cc
@@ -240,6 +240,9 @@ int QuicStreamFactory::Job::DoConnect() {
}
session_->StartReading();
+ if (!session_->connection()->connected()) {
+ return ERR_QUIC_PROTOCOL_ERROR;
+ }
rv = session_->CryptoConnect(
factory_->require_confirmation() || is_https_,
base::Bind(&QuicStreamFactory::Job::OnIOComplete,