1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_http_stream.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_session.h"
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_test_util.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace net {
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdyHttpStreamTest : public testing::Test {
133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public:
143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  OrderedSocketData* data() { return data_; }
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  SpdyHttpStreamTest() {}
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void EnableCompression(bool enabled) {
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    spdy::SpdyFramer::set_enable_compression_default(enabled);
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void TearDown() {
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->RunAllPending();
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int InitSession(MockRead* reads, size_t reads_count,
263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                  MockWrite* writes, size_t writes_count,
273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                  HostPortPair& host_port_pair) {
283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    data_ = new OrderedSocketData(reads, reads_count, writes, writes_count);
303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    session_deps_.socket_factory->AddSocketDataProvider(data_.get());
313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
32dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    session_ = http_session_->spdy_session_pool()->Get(pair, BoundNetLog());
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    transport_params_ = new TransportSocketParams(host_port_pair,
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                      MEDIUM, GURL(), false, false);
353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    TestCompletionCallback callback;
363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(ERR_IO_PENDING,
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              connection->Init(host_port_pair.ToString(),
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                transport_params_,
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                MEDIUM,
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                &callback,
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                http_session_->transport_socket_pool(),
433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                BoundNetLog()));
443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(OK, callback.WaitForResult());
453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return session_->InitializeWithSocket(connection.release(), false, OK);
463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  SpdySessionDependencies session_deps_;
483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_refptr<OrderedSocketData> data_;
493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_refptr<HttpNetworkSession> http_session_;
503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_refptr<SpdySession> session_;
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<TransportSocketParams> transport_params_;
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(SpdyHttpStreamTest, SendRequest) {
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EnableCompression(false);
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SpdySession::SetSSLMode(false);
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockWrite writes[] = {
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CreateMockWrite(*req.get(), 1),
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockRead reads[] = {
643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    CreateMockRead(*resp, 2),
653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    MockRead(false, 0, 3)  // EOF
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HostPortPair host_port_pair("www.google.com", 80);
693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(OK, InitSession(reads, arraysize(reads), writes, arraysize(writes),
713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      host_port_pair));
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HttpRequestInfo request;
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  request.method = "GET";
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  request.url = GURL("http://www.google.com/");
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestCompletionCallback callback;
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HttpResponseInfo response;
78513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  HttpRequestHeaders headers;
793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  BoundNetLog net_log;
803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<SpdyHttpStream> http_stream(
813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      new SpdyHttpStream(session_.get(), true));
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      OK,
843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      http_stream->InitializeStream(&request, net_log, NULL));
853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ERR_IO_PENDING,
87513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch            http_stream->SendRequest(headers, NULL, &response, &callback));
883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(pair));
893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // This triggers the MockWrite and read 2
913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  callback.WaitForResult();
923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // This triggers read 3. The empty read causes the session to shut down.
943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  data()->CompleteRead();
953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Because we abandoned the stream, we don't expect to find a session in the
973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // pool anymore.
98dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(pair));
99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(data()->at_read_eof());
100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(data()->at_write_eof());
101dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
102dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
103dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_F(SpdyHttpStreamTest, SendChunkedPost) {
104dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EnableCompression(false);
105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  SpdySession::SetSSLMode(false);
106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  UploadDataStream::set_merge_chunks(false);
107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_ptr<spdy::SpdyFrame> req(ConstructChunkedSpdyPost(NULL, 0));
109dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_ptr<spdy::SpdyFrame> chunk1(ConstructSpdyBodyFrame(1, false));
110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_ptr<spdy::SpdyFrame> chunk2(ConstructSpdyBodyFrame(1, true));
111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  MockWrite writes[] = {
112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    CreateMockWrite(*req.get(), 1),
113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    CreateMockWrite(*chunk1, 2),  // POST upload frames
114dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    CreateMockWrite(*chunk2, 3),
115dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  };
116dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
117dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  MockRead reads[] = {
118dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    CreateMockRead(*resp, 4),
119dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    CreateMockRead(*chunk1, 5),
120dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    CreateMockRead(*chunk2, 5),
121dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    MockRead(false, 0, 6)  // EOF
122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  };
123dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
124dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  HostPortPair host_port_pair("www.google.com", 80);
125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
126dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(OK, InitSession(reads, arraysize(reads), writes, arraysize(writes),
127dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                            host_port_pair));
128dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  HttpRequestInfo request;
130dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  request.method = "POST";
131dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  request.url = GURL("http://www.google.com/");
132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  request.upload_data = new UploadData();
133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  request.upload_data->set_is_chunked(true);
134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  request.upload_data->AppendChunk(kUploadData, kUploadDataSize, false);
135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  request.upload_data->AppendChunk(kUploadData, kUploadDataSize, true);
136dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  TestCompletionCallback callback;
137dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  HttpResponseInfo response;
138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  HttpRequestHeaders headers;
139dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  BoundNetLog net_log;
140dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  SpdyHttpStream http_stream(session_.get(), true);
141dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(
142dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      OK,
143dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      http_stream.InitializeStream(&request, net_log, NULL));
144dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
145dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  UploadDataStream* upload_stream =
146dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      UploadDataStream::Create(request.upload_data, NULL);
147dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(ERR_IO_PENDING, http_stream.SendRequest(
148dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      headers, upload_stream, &response, &callback));
149dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(pair));
150dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
151dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // This triggers the MockWrite and read 2
152dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  callback.WaitForResult();
153dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // This triggers read 3. The empty read causes the session to shut down.
155dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  data()->CompleteRead();
156dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  MessageLoop::current()->RunAllPending();
157dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
158dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Because we abandoned the stream, we don't expect to find a session in the
159dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // pool anymore.
160dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(pair));
1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(data()->at_read_eof());
1623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(data()->at_write_eof());
1633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
1643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test case for bug: http://code.google.com/p/chromium/issues/detail?id=50058
1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(SpdyHttpStreamTest, SpdyURLTest) {
1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EnableCompression(false);
1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  SpdySession::SetSSLMode(false);
1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const char * const full_url = "http://www.google.com/foo?query=what#anchor";
1713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const char * const base_url = "http://www.google.com/foo?query=what";
1723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(base_url, false, 1, LOWEST));
1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MockWrite writes[] = {
1743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    CreateMockWrite(*req.get(), 1),
1753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  };
1763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
1773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MockRead reads[] = {
1783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    CreateMockRead(*resp, 2),
1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    MockRead(false, 0, 3)  // EOF
1803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  };
1813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HostPortPair host_port_pair("www.google.com", 80);
1833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(OK, InitSession(reads, arraysize(reads), writes, arraysize(writes),
1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      host_port_pair));
1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HttpRequestInfo request;
1883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  request.method = "GET";
1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  request.url = GURL(full_url);
1903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback;
1913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HttpResponseInfo response;
192513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  HttpRequestHeaders headers;
1933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  BoundNetLog net_log;
1943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<SpdyHttpStream> http_stream(new SpdyHttpStream(session_, true));
1953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(
1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      OK,
1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      http_stream->InitializeStream(&request, net_log, NULL));
1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING,
200513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch            http_stream->SendRequest(headers, NULL, &response, &callback));
2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  spdy::SpdyHeaderBlock* spdy_header =
2033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    http_stream->stream()->spdy_headers().get();
2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(spdy_header != NULL);
2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (spdy_header->find("url") != spdy_header->end())
2063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ("/foo?query=what", spdy_header->find("url")->second);
2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  else
2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FAIL() << "No url is set in spdy_header!";
2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // This triggers the MockWrite and read 2
2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  callback.WaitForResult();
2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // This triggers read 3. The empty read causes the session to shut down.
2143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  data()->CompleteRead();
2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Because we abandoned the stream, we don't expect to find a session in the
2173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // pool anymore.
218dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(pair));
2193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(data()->at_read_eof());
2203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(data()->at_write_eof());
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(willchan): Write a longer test for SpdyStream that exercises all
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// methods.
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace net
227