- add sources.
[platform/framework/web/crosswalk.git] / src / net / spdy / spdy_network_transaction_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <string>
6 #include <vector>
7
8 #include "base/bind.h"
9 #include "base/bind_helpers.h"
10 #include "base/file_util.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/memory/scoped_vector.h"
13 #include "base/run_loop.h"
14 #include "base/stl_util.h"
15 #include "net/base/auth.h"
16 #include "net/base/net_log_unittest.h"
17 #include "net/base/request_priority.h"
18 #include "net/base/upload_bytes_element_reader.h"
19 #include "net/base/upload_data_stream.h"
20 #include "net/base/upload_file_element_reader.h"
21 #include "net/http/http_network_session_peer.h"
22 #include "net/http/http_network_transaction.h"
23 #include "net/http/http_server_properties.h"
24 #include "net/http/http_transaction_unittest.h"
25 #include "net/socket/client_socket_pool_base.h"
26 #include "net/socket/next_proto.h"
27 #include "net/spdy/buffered_spdy_framer.h"
28 #include "net/spdy/spdy_http_stream.h"
29 #include "net/spdy/spdy_http_utils.h"
30 #include "net/spdy/spdy_session.h"
31 #include "net/spdy/spdy_session_pool.h"
32 #include "net/spdy/spdy_test_util_common.h"
33 #include "net/spdy/spdy_test_utils.h"
34 #include "net/url_request/url_request_test_util.h"
35 #include "testing/platform_test.h"
36
37 //-----------------------------------------------------------------------------
38
39 namespace net {
40
41 namespace {
42 const char kRequestUrl[] = "http://www.google.com/";
43
44 enum SpdyNetworkTransactionTestSSLType {
45   SPDYNPN,
46   SPDYNOSSL,
47   SPDYSSL,
48 };
49
50 struct SpdyNetworkTransactionTestParams {
51   SpdyNetworkTransactionTestParams()
52       : protocol(kProtoSPDY3),
53         ssl_type(SPDYNPN) {}
54
55   SpdyNetworkTransactionTestParams(
56       NextProto protocol,
57       SpdyNetworkTransactionTestSSLType ssl_type)
58       : protocol(protocol),
59         ssl_type(ssl_type) {}
60
61   NextProto protocol;
62   SpdyNetworkTransactionTestSSLType ssl_type;
63 };
64
65 SpdySessionDependencies* CreateSpdySessionDependencies(
66     SpdyNetworkTransactionTestParams test_params) {
67   return new SpdySessionDependencies(test_params.protocol);
68 }
69
70 SpdySessionDependencies* CreateSpdySessionDependencies(
71     SpdyNetworkTransactionTestParams test_params,
72     ProxyService* proxy_service) {
73   return new SpdySessionDependencies(test_params.protocol, proxy_service);
74 }
75
76 }  // namespace
77
78 class SpdyNetworkTransactionTest
79     : public ::testing::TestWithParam<SpdyNetworkTransactionTestParams> {
80  protected:
81   SpdyNetworkTransactionTest() : spdy_util_(GetParam().protocol) {
82   }
83
84   virtual ~SpdyNetworkTransactionTest() {
85     // UploadDataStream posts deletion tasks back to the message loop on
86     // destruction.
87     upload_data_stream_.reset();
88     base::RunLoop().RunUntilIdle();
89   }
90
91   virtual void SetUp() {
92     google_get_request_initialized_ = false;
93     google_post_request_initialized_ = false;
94     google_chunked_post_request_initialized_ = false;
95     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
96   }
97
98   struct TransactionHelperResult {
99     int rv;
100     std::string status_line;
101     std::string response_data;
102     HttpResponseInfo response_info;
103   };
104
105   // A helper class that handles all the initial npn/ssl setup.
106   class NormalSpdyTransactionHelper {
107    public:
108     NormalSpdyTransactionHelper(const HttpRequestInfo& request,
109                                 RequestPriority priority,
110                                 const BoundNetLog& log,
111                                 SpdyNetworkTransactionTestParams test_params,
112                                 SpdySessionDependencies* session_deps)
113         : request_(request),
114           priority_(priority),
115           session_deps_(session_deps == NULL ?
116                         CreateSpdySessionDependencies(test_params) :
117                         session_deps),
118           session_(SpdySessionDependencies::SpdyCreateSession(
119                        session_deps_.get())),
120           log_(log),
121           test_params_(test_params),
122           deterministic_(false),
123           spdy_enabled_(true) {
124       switch (test_params_.ssl_type) {
125         case SPDYNOSSL:
126         case SPDYSSL:
127           port_ = 80;
128           break;
129         case SPDYNPN:
130           port_ = 443;
131           break;
132         default:
133           NOTREACHED();
134       }
135     }
136
137     ~NormalSpdyTransactionHelper() {
138       // Any test which doesn't close the socket by sending it an EOF will
139       // have a valid session left open, which leaks the entire session pool.
140       // This is just fine - in fact, some of our tests intentionally do this
141       // so that we can check consistency of the SpdySessionPool as the test
142       // finishes.  If we had put an EOF on the socket, the SpdySession would
143       // have closed and we wouldn't be able to check the consistency.
144
145       // Forcefully close existing sessions here.
146       session()->spdy_session_pool()->CloseAllSessions();
147     }
148
149     void SetDeterministic() {
150       session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
151           session_deps_.get());
152       deterministic_ = true;
153     }
154
155     void SetSpdyDisabled() {
156       spdy_enabled_ = false;
157       port_ = 80;
158     }
159
160     void RunPreTestSetup() {
161       if (!session_deps_.get())
162         session_deps_.reset(CreateSpdySessionDependencies(test_params_));
163       if (!session_.get())
164         session_ = SpdySessionDependencies::SpdyCreateSession(
165             session_deps_.get());
166       HttpStreamFactory::set_use_alternate_protocols(false);
167       HttpStreamFactory::set_force_spdy_over_ssl(false);
168       HttpStreamFactory::set_force_spdy_always(false);
169
170       std::vector<NextProto> next_protos = SpdyNextProtos();
171
172       switch (test_params_.ssl_type) {
173         case SPDYNPN:
174           session_->http_server_properties()->SetAlternateProtocol(
175               HostPortPair("www.google.com", 80), 443,
176               AlternateProtocolFromNextProto(test_params_.protocol));
177           HttpStreamFactory::set_use_alternate_protocols(true);
178           HttpStreamFactory::SetNextProtos(next_protos);
179           break;
180         case SPDYNOSSL:
181           HttpStreamFactory::set_force_spdy_over_ssl(false);
182           HttpStreamFactory::set_force_spdy_always(true);
183           break;
184         case SPDYSSL:
185           HttpStreamFactory::set_force_spdy_over_ssl(true);
186           HttpStreamFactory::set_force_spdy_always(true);
187           break;
188         default:
189           NOTREACHED();
190       }
191
192       // We're now ready to use SSL-npn SPDY.
193       trans_.reset(new HttpNetworkTransaction(priority_, session_.get()));
194     }
195
196     // Start the transaction, read some data, finish.
197     void RunDefaultTest() {
198       if (!StartDefaultTest())
199         return;
200       FinishDefaultTest();
201     }
202
203     bool StartDefaultTest() {
204       output_.rv = trans_->Start(&request_, callback.callback(), log_);
205
206       // We expect an IO Pending or some sort of error.
207       EXPECT_LT(output_.rv, 0);
208       return output_.rv == ERR_IO_PENDING;
209     }
210
211     void FinishDefaultTest() {
212       output_.rv = callback.WaitForResult();
213       if (output_.rv != OK) {
214         session_->spdy_session_pool()->CloseCurrentSessions(net::ERR_ABORTED);
215         return;
216       }
217
218       // Verify responses.
219       const HttpResponseInfo* response = trans_->GetResponseInfo();
220       ASSERT_TRUE(response != NULL);
221       ASSERT_TRUE(response->headers.get() != NULL);
222       EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
223       EXPECT_EQ(spdy_enabled_, response->was_fetched_via_spdy);
224       if (HttpStreamFactory::spdy_enabled()) {
225         EXPECT_EQ(
226             HttpResponseInfo::ConnectionInfoFromNextProto(
227                 test_params_.protocol),
228             response->connection_info);
229       } else {
230         EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1,
231                   response->connection_info);
232       }
233       if (test_params_.ssl_type == SPDYNPN && spdy_enabled_) {
234         EXPECT_TRUE(response->was_npn_negotiated);
235       } else {
236         EXPECT_TRUE(!response->was_npn_negotiated);
237       }
238       // If SPDY is not enabled, a HTTP request should not be diverted
239       // over a SSL session.
240       if (!spdy_enabled_) {
241         EXPECT_EQ(request_.url.SchemeIs("https"),
242                   response->was_npn_negotiated);
243       }
244       EXPECT_EQ("127.0.0.1", response->socket_address.host());
245       EXPECT_EQ(port_, response->socket_address.port());
246       output_.status_line = response->headers->GetStatusLine();
247       output_.response_info = *response;  // Make a copy so we can verify.
248       output_.rv = ReadTransaction(trans_.get(), &output_.response_data);
249     }
250
251     // Most tests will want to call this function. In particular, the MockReads
252     // should end with an empty read, and that read needs to be processed to
253     // ensure proper deletion of the spdy_session_pool.
254     void VerifyDataConsumed() {
255       for (DataVector::iterator it = data_vector_.begin();
256           it != data_vector_.end(); ++it) {
257         EXPECT_TRUE((*it)->at_read_eof()) << "Read count: "
258                                           << (*it)->read_count()
259                                           << " Read index: "
260                                           << (*it)->read_index();
261         EXPECT_TRUE((*it)->at_write_eof()) << "Write count: "
262                                            << (*it)->write_count()
263                                            << " Write index: "
264                                            << (*it)->write_index();
265       }
266     }
267
268     // Occasionally a test will expect to error out before certain reads are
269     // processed. In that case we want to explicitly ensure that the reads were
270     // not processed.
271     void VerifyDataNotConsumed() {
272       for (DataVector::iterator it = data_vector_.begin();
273           it != data_vector_.end(); ++it) {
274         EXPECT_TRUE(!(*it)->at_read_eof()) << "Read count: "
275                                            << (*it)->read_count()
276                                            << " Read index: "
277                                            << (*it)->read_index();
278         EXPECT_TRUE(!(*it)->at_write_eof()) << "Write count: "
279                                             << (*it)->write_count()
280                                             << " Write index: "
281                                             << (*it)->write_index();
282       }
283     }
284
285     void RunToCompletion(StaticSocketDataProvider* data) {
286       RunPreTestSetup();
287       AddData(data);
288       RunDefaultTest();
289       VerifyDataConsumed();
290     }
291
292     void AddData(StaticSocketDataProvider* data) {
293       DCHECK(!deterministic_);
294       data_vector_.push_back(data);
295       SSLSocketDataProvider* ssl_provider =
296           new SSLSocketDataProvider(ASYNC, OK);
297       if (test_params_.ssl_type == SPDYNPN)
298         ssl_provider->SetNextProto(test_params_.protocol);
299
300       ssl_vector_.push_back(ssl_provider);
301       if (test_params_.ssl_type == SPDYNPN || test_params_.ssl_type == SPDYSSL)
302         session_deps_->socket_factory->AddSSLSocketDataProvider(ssl_provider);
303
304       session_deps_->socket_factory->AddSocketDataProvider(data);
305       if (test_params_.ssl_type == SPDYNPN) {
306         MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
307         StaticSocketDataProvider* hanging_non_alternate_protocol_socket =
308             new StaticSocketDataProvider(NULL, 0, NULL, 0);
309         hanging_non_alternate_protocol_socket->set_connect_data(
310             never_finishing_connect);
311         session_deps_->socket_factory->AddSocketDataProvider(
312             hanging_non_alternate_protocol_socket);
313         alternate_vector_.push_back(hanging_non_alternate_protocol_socket);
314       }
315     }
316
317     void AddDeterministicData(DeterministicSocketData* data) {
318       DCHECK(deterministic_);
319       data_vector_.push_back(data);
320       SSLSocketDataProvider* ssl_provider =
321           new SSLSocketDataProvider(ASYNC, OK);
322       if (test_params_.ssl_type == SPDYNPN)
323         ssl_provider->SetNextProto(test_params_.protocol);
324
325       ssl_vector_.push_back(ssl_provider);
326       if (test_params_.ssl_type == SPDYNPN ||
327           test_params_.ssl_type == SPDYSSL) {
328         session_deps_->deterministic_socket_factory->
329             AddSSLSocketDataProvider(ssl_provider);
330       }
331       session_deps_->deterministic_socket_factory->AddSocketDataProvider(data);
332       if (test_params_.ssl_type == SPDYNPN) {
333         MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
334         DeterministicSocketData* hanging_non_alternate_protocol_socket =
335             new DeterministicSocketData(NULL, 0, NULL, 0);
336         hanging_non_alternate_protocol_socket->set_connect_data(
337             never_finishing_connect);
338         session_deps_->deterministic_socket_factory->AddSocketDataProvider(
339             hanging_non_alternate_protocol_socket);
340         alternate_deterministic_vector_.push_back(
341             hanging_non_alternate_protocol_socket);
342       }
343     }
344
345     void SetSession(const scoped_refptr<HttpNetworkSession>& session) {
346       session_ = session;
347     }
348     HttpNetworkTransaction* trans() { return trans_.get(); }
349     void ResetTrans() { trans_.reset(); }
350     TransactionHelperResult& output() { return output_; }
351     const HttpRequestInfo& request() const { return request_; }
352     const scoped_refptr<HttpNetworkSession>& session() const {
353       return session_;
354     }
355     scoped_ptr<SpdySessionDependencies>& session_deps() {
356       return session_deps_;
357     }
358     int port() const { return port_; }
359     SpdyNetworkTransactionTestParams test_params() const {
360       return test_params_;
361     }
362
363    private:
364     typedef std::vector<StaticSocketDataProvider*> DataVector;
365     typedef ScopedVector<SSLSocketDataProvider> SSLVector;
366     typedef ScopedVector<StaticSocketDataProvider> AlternateVector;
367     typedef ScopedVector<DeterministicSocketData> AlternateDeterministicVector;
368     HttpRequestInfo request_;
369     RequestPriority priority_;
370     scoped_ptr<SpdySessionDependencies> session_deps_;
371     scoped_refptr<HttpNetworkSession> session_;
372     TransactionHelperResult output_;
373     scoped_ptr<StaticSocketDataProvider> first_transaction_;
374     SSLVector ssl_vector_;
375     TestCompletionCallback callback;
376     scoped_ptr<HttpNetworkTransaction> trans_;
377     scoped_ptr<HttpNetworkTransaction> trans_http_;
378     DataVector data_vector_;
379     AlternateVector alternate_vector_;
380     AlternateDeterministicVector alternate_deterministic_vector_;
381     const BoundNetLog& log_;
382     SpdyNetworkTransactionTestParams test_params_;
383     int port_;
384     bool deterministic_;
385     bool spdy_enabled_;
386   };
387
388   void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
389                                              int expected_status);
390
391   void ConnectStatusHelper(const MockRead& status);
392
393   const HttpRequestInfo& CreateGetPushRequest() {
394     google_get_push_request_.method = "GET";
395     google_get_push_request_.url = GURL("http://www.google.com/foo.dat");
396     google_get_push_request_.load_flags = 0;
397     return google_get_push_request_;
398   }
399
400   const HttpRequestInfo& CreateGetRequest() {
401     if (!google_get_request_initialized_) {
402       google_get_request_.method = "GET";
403       google_get_request_.url = GURL(kDefaultURL);
404       google_get_request_.load_flags = 0;
405       google_get_request_initialized_ = true;
406     }
407     return google_get_request_;
408   }
409
410   const HttpRequestInfo& CreateGetRequestWithUserAgent() {
411     if (!google_get_request_initialized_) {
412       google_get_request_.method = "GET";
413       google_get_request_.url = GURL(kDefaultURL);
414       google_get_request_.load_flags = 0;
415       google_get_request_.extra_headers.SetHeader("User-Agent", "Chrome");
416       google_get_request_initialized_ = true;
417     }
418     return google_get_request_;
419   }
420
421   const HttpRequestInfo& CreatePostRequest() {
422     if (!google_post_request_initialized_) {
423       ScopedVector<UploadElementReader> element_readers;
424       element_readers.push_back(
425           new UploadBytesElementReader(kUploadData, kUploadDataSize));
426       upload_data_stream_.reset(
427           new UploadDataStream(element_readers.Pass(), 0));
428
429       google_post_request_.method = "POST";
430       google_post_request_.url = GURL(kDefaultURL);
431       google_post_request_.upload_data_stream = upload_data_stream_.get();
432       google_post_request_initialized_ = true;
433     }
434     return google_post_request_;
435   }
436
437   const HttpRequestInfo& CreateFilePostRequest() {
438     if (!google_post_request_initialized_) {
439       base::FilePath file_path;
440       CHECK(file_util::CreateTemporaryFileInDir(temp_dir_.path(), &file_path));
441       CHECK_EQ(static_cast<int>(kUploadDataSize),
442                file_util::WriteFile(file_path, kUploadData, kUploadDataSize));
443
444       ScopedVector<UploadElementReader> element_readers;
445       element_readers.push_back(
446           new UploadFileElementReader(base::MessageLoopProxy::current().get(),
447                                       file_path,
448                                       0,
449                                       kUploadDataSize,
450                                       base::Time()));
451       upload_data_stream_.reset(
452           new UploadDataStream(element_readers.Pass(), 0));
453
454       google_post_request_.method = "POST";
455       google_post_request_.url = GURL(kDefaultURL);
456       google_post_request_.upload_data_stream = upload_data_stream_.get();
457       google_post_request_initialized_ = true;
458     }
459     return google_post_request_;
460   }
461
462   const HttpRequestInfo& CreateComplexPostRequest() {
463     if (!google_post_request_initialized_) {
464       const int kFileRangeOffset = 1;
465       const int kFileRangeLength = 3;
466       CHECK_LT(kFileRangeOffset + kFileRangeLength, kUploadDataSize);
467
468       base::FilePath file_path;
469       CHECK(file_util::CreateTemporaryFileInDir(temp_dir_.path(), &file_path));
470       CHECK_EQ(static_cast<int>(kUploadDataSize),
471                file_util::WriteFile(file_path, kUploadData, kUploadDataSize));
472
473       ScopedVector<UploadElementReader> element_readers;
474       element_readers.push_back(
475           new UploadBytesElementReader(kUploadData, kFileRangeOffset));
476       element_readers.push_back(
477           new UploadFileElementReader(base::MessageLoopProxy::current().get(),
478                                       file_path,
479                                       kFileRangeOffset,
480                                       kFileRangeLength,
481                                       base::Time()));
482       element_readers.push_back(new UploadBytesElementReader(
483           kUploadData + kFileRangeOffset + kFileRangeLength,
484           kUploadDataSize - (kFileRangeOffset + kFileRangeLength)));
485       upload_data_stream_.reset(
486           new UploadDataStream(element_readers.Pass(), 0));
487
488       google_post_request_.method = "POST";
489       google_post_request_.url = GURL(kDefaultURL);
490       google_post_request_.upload_data_stream = upload_data_stream_.get();
491       google_post_request_initialized_ = true;
492     }
493     return google_post_request_;
494   }
495
496   const HttpRequestInfo& CreateChunkedPostRequest() {
497     if (!google_chunked_post_request_initialized_) {
498       upload_data_stream_.reset(
499           new UploadDataStream(UploadDataStream::CHUNKED, 0));
500       google_chunked_post_request_.method = "POST";
501       google_chunked_post_request_.url = GURL(kDefaultURL);
502       google_chunked_post_request_.upload_data_stream =
503           upload_data_stream_.get();
504       google_chunked_post_request_initialized_ = true;
505     }
506     return google_chunked_post_request_;
507   }
508
509   // Read the result of a particular transaction, knowing that we've got
510   // multiple transactions in the read pipeline; so as we read, we may have
511   // to skip over data destined for other transactions while we consume
512   // the data for |trans|.
513   int ReadResult(HttpNetworkTransaction* trans,
514                  StaticSocketDataProvider* data,
515                  std::string* result) {
516     const int kSize = 3000;
517
518     int bytes_read = 0;
519     scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(kSize));
520     TestCompletionCallback callback;
521     while (true) {
522       int rv = trans->Read(buf.get(), kSize, callback.callback());
523       if (rv == ERR_IO_PENDING) {
524         // Multiple transactions may be in the data set.  Keep pulling off
525         // reads until we complete our callback.
526         while (!callback.have_result()) {
527           data->CompleteRead();
528           base::RunLoop().RunUntilIdle();
529         }
530         rv = callback.WaitForResult();
531       } else if (rv <= 0) {
532         break;
533       }
534       result->append(buf->data(), rv);
535       bytes_read += rv;
536     }
537     return bytes_read;
538   }
539
540   void VerifyStreamsClosed(const NormalSpdyTransactionHelper& helper) {
541     // This lengthy block is reaching into the pool to dig out the active
542     // session.  Once we have the session, we verify that the streams are
543     // all closed and not leaked at this point.
544     const GURL& url = helper.request().url;
545     int port = helper.test_params().ssl_type == SPDYNPN ? 443 : 80;
546     HostPortPair host_port_pair(url.host(), port);
547     SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
548                        kPrivacyModeDisabled);
549     BoundNetLog log;
550     const scoped_refptr<HttpNetworkSession>& session = helper.session();
551     base::WeakPtr<SpdySession> spdy_session =
552         session->spdy_session_pool()->FindAvailableSession(key, log);
553     ASSERT_TRUE(spdy_session != NULL);
554     EXPECT_EQ(0u, spdy_session->num_active_streams());
555     EXPECT_EQ(0u, spdy_session->num_unclaimed_pushed_streams());
556   }
557
558   void RunServerPushTest(OrderedSocketData* data,
559                          HttpResponseInfo* response,
560                          HttpResponseInfo* push_response,
561                          const std::string& expected) {
562     NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
563                                        BoundNetLog(), GetParam(), NULL);
564     helper.RunPreTestSetup();
565     helper.AddData(data);
566
567     HttpNetworkTransaction* trans = helper.trans();
568
569     // Start the transaction with basic parameters.
570     TestCompletionCallback callback;
571     int rv = trans->Start(
572         &CreateGetRequest(), callback.callback(), BoundNetLog());
573     EXPECT_EQ(ERR_IO_PENDING, rv);
574     rv = callback.WaitForResult();
575
576     // Request the pushed path.
577     scoped_ptr<HttpNetworkTransaction> trans2(
578         new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
579     rv = trans2->Start(
580         &CreateGetPushRequest(), callback.callback(), BoundNetLog());
581     EXPECT_EQ(ERR_IO_PENDING, rv);
582     base::RunLoop().RunUntilIdle();
583
584     // The data for the pushed path may be coming in more than 1 frame. Compile
585     // the results into a single string.
586
587     // Read the server push body.
588     std::string result2;
589     ReadResult(trans2.get(), data, &result2);
590     // Read the response body.
591     std::string result;
592     ReadResult(trans, data, &result);
593
594     // Verify that we consumed all test data.
595     EXPECT_TRUE(data->at_read_eof());
596     EXPECT_TRUE(data->at_write_eof());
597
598     // Verify that the received push data is same as the expected push data.
599     EXPECT_EQ(result2.compare(expected), 0) << "Received data: "
600                                             << result2
601                                             << "||||| Expected data: "
602                                             << expected;
603
604     // Verify the SYN_REPLY.
605     // Copy the response info, because trans goes away.
606     *response = *trans->GetResponseInfo();
607     *push_response = *trans2->GetResponseInfo();
608
609     VerifyStreamsClosed(helper);
610   }
611
612   static void DeleteSessionCallback(NormalSpdyTransactionHelper* helper,
613                                     int result) {
614     helper->ResetTrans();
615   }
616
617   static void StartTransactionCallback(
618       const scoped_refptr<HttpNetworkSession>& session,
619       int result) {
620     scoped_ptr<HttpNetworkTransaction> trans(
621         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
622     TestCompletionCallback callback;
623     HttpRequestInfo request;
624     request.method = "GET";
625     request.url = GURL("http://www.google.com/");
626     request.load_flags = 0;
627     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
628     EXPECT_EQ(ERR_IO_PENDING, rv);
629     callback.WaitForResult();
630   }
631
632   SpdyTestUtil spdy_util_;
633
634  private:
635   scoped_ptr<UploadDataStream> upload_data_stream_;
636   bool google_get_request_initialized_;
637   bool google_post_request_initialized_;
638   bool google_chunked_post_request_initialized_;
639   HttpRequestInfo google_get_request_;
640   HttpRequestInfo google_post_request_;
641   HttpRequestInfo google_chunked_post_request_;
642   HttpRequestInfo google_get_push_request_;
643   base::ScopedTempDir temp_dir_;
644 };
645
646 //-----------------------------------------------------------------------------
647 // All tests are run with three different connection types: SPDY after NPN
648 // negotiation, SPDY without SSL, and SPDY with SSL.
649 //
650 // TODO(akalin): Use ::testing::Combine() when we are able to use
651 // <tr1/tuple>.
652 INSTANTIATE_TEST_CASE_P(
653     Spdy,
654     SpdyNetworkTransactionTest,
655     ::testing::Values(
656         SpdyNetworkTransactionTestParams(kProtoDeprecatedSPDY2, SPDYNOSSL),
657         SpdyNetworkTransactionTestParams(kProtoDeprecatedSPDY2, SPDYSSL),
658         SpdyNetworkTransactionTestParams(kProtoDeprecatedSPDY2, SPDYNPN),
659         SpdyNetworkTransactionTestParams(kProtoSPDY3, SPDYNOSSL),
660         SpdyNetworkTransactionTestParams(kProtoSPDY3, SPDYSSL),
661         SpdyNetworkTransactionTestParams(kProtoSPDY3, SPDYNPN),
662         SpdyNetworkTransactionTestParams(kProtoSPDY31, SPDYNOSSL),
663         SpdyNetworkTransactionTestParams(kProtoSPDY31, SPDYSSL),
664         SpdyNetworkTransactionTestParams(kProtoSPDY31, SPDYNPN),
665         SpdyNetworkTransactionTestParams(kProtoSPDY4a2, SPDYNOSSL),
666         SpdyNetworkTransactionTestParams(kProtoSPDY4a2, SPDYSSL),
667         SpdyNetworkTransactionTestParams(kProtoSPDY4a2, SPDYNPN),
668         SpdyNetworkTransactionTestParams(kProtoHTTP2Draft04, SPDYNOSSL),
669         SpdyNetworkTransactionTestParams(kProtoHTTP2Draft04, SPDYSSL),
670         SpdyNetworkTransactionTestParams(kProtoHTTP2Draft04, SPDYNPN)));
671
672 // Verify HttpNetworkTransaction constructor.
673 TEST_P(SpdyNetworkTransactionTest, Constructor) {
674   scoped_ptr<SpdySessionDependencies> session_deps(
675       CreateSpdySessionDependencies(GetParam()));
676   scoped_refptr<HttpNetworkSession> session(
677       SpdySessionDependencies::SpdyCreateSession(session_deps.get()));
678   scoped_ptr<HttpTransaction> trans(
679       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
680 }
681
682 TEST_P(SpdyNetworkTransactionTest, Get) {
683   // Construct the request.
684   scoped_ptr<SpdyFrame> req(
685       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
686   MockWrite writes[] = { CreateMockWrite(*req) };
687
688   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
689   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
690   MockRead reads[] = {
691     CreateMockRead(*resp),
692     CreateMockRead(*body),
693     MockRead(ASYNC, 0, 0)  // EOF
694   };
695
696   DelayedSocketData data(1, reads, arraysize(reads),
697                          writes, arraysize(writes));
698   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
699                                      BoundNetLog(), GetParam(), NULL);
700   helper.RunToCompletion(&data);
701   TransactionHelperResult out = helper.output();
702   EXPECT_EQ(OK, out.rv);
703   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
704   EXPECT_EQ("hello!", out.response_data);
705 }
706
707 TEST_P(SpdyNetworkTransactionTest, GetAtEachPriority) {
708   for (RequestPriority p = MINIMUM_PRIORITY; p <= MAXIMUM_PRIORITY;
709        p = RequestPriority(p + 1)) {
710     // Construct the request.
711     scoped_ptr<SpdyFrame> req(
712         spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, p, true));
713     MockWrite writes[] = { CreateMockWrite(*req) };
714
715     SpdyPriority spdy_prio = 0;
716     EXPECT_TRUE(GetSpdyPriority(spdy_util_.spdy_version(), *req, &spdy_prio));
717     // this repeats the RequestPriority-->SpdyPriority mapping from
718     // SpdyFramer::ConvertRequestPriorityToSpdyPriority to make
719     // sure it's being done right.
720     if (spdy_util_.spdy_version() < SPDY3) {
721       switch(p) {
722         case HIGHEST:
723           EXPECT_EQ(0, spdy_prio);
724           break;
725         case MEDIUM:
726           EXPECT_EQ(1, spdy_prio);
727           break;
728         case LOW:
729         case LOWEST:
730           EXPECT_EQ(2, spdy_prio);
731           break;
732         case IDLE:
733           EXPECT_EQ(3, spdy_prio);
734           break;
735         default:
736           FAIL();
737       }
738     } else {
739       switch(p) {
740         case HIGHEST:
741           EXPECT_EQ(0, spdy_prio);
742           break;
743         case MEDIUM:
744           EXPECT_EQ(1, spdy_prio);
745           break;
746         case LOW:
747           EXPECT_EQ(2, spdy_prio);
748           break;
749         case LOWEST:
750           EXPECT_EQ(3, spdy_prio);
751           break;
752         case IDLE:
753           EXPECT_EQ(4, spdy_prio);
754           break;
755         default:
756           FAIL();
757       }
758     }
759
760     scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
761     scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
762     MockRead reads[] = {
763       CreateMockRead(*resp),
764       CreateMockRead(*body),
765       MockRead(ASYNC, 0, 0)  // EOF
766     };
767
768     DelayedSocketData data(1, reads, arraysize(reads),
769                               writes, arraysize(writes));
770     HttpRequestInfo http_req = CreateGetRequest();
771
772     NormalSpdyTransactionHelper helper(http_req, p, BoundNetLog(),
773                                        GetParam(), NULL);
774     helper.RunToCompletion(&data);
775     TransactionHelperResult out = helper.output();
776     EXPECT_EQ(OK, out.rv);
777     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
778     EXPECT_EQ("hello!", out.response_data);
779   }
780 }
781
782 // Start three gets simultaniously; making sure that multiplexed
783 // streams work properly.
784
785 // This can't use the TransactionHelper method, since it only
786 // handles a single transaction, and finishes them as soon
787 // as it launches them.
788
789 // TODO(gavinp): create a working generalized TransactionHelper that
790 // can allow multiple streams in flight.
791
792 TEST_P(SpdyNetworkTransactionTest, ThreeGets) {
793   scoped_ptr<SpdyFrame> req(
794       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
795   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
796   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
797   scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
798
799   scoped_ptr<SpdyFrame> req2(
800       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
801   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
802   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
803   scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
804
805   scoped_ptr<SpdyFrame> req3(
806       spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, LOWEST, true));
807   scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
808   scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, false));
809   scoped_ptr<SpdyFrame> fbody3(spdy_util_.ConstructSpdyBodyFrame(5, true));
810
811   MockWrite writes[] = {
812     CreateMockWrite(*req),
813     CreateMockWrite(*req2),
814     CreateMockWrite(*req3),
815   };
816   MockRead reads[] = {
817     CreateMockRead(*resp, 1),
818     CreateMockRead(*body),
819     CreateMockRead(*resp2, 4),
820     CreateMockRead(*body2),
821     CreateMockRead(*resp3, 7),
822     CreateMockRead(*body3),
823
824     CreateMockRead(*fbody),
825     CreateMockRead(*fbody2),
826     CreateMockRead(*fbody3),
827
828     MockRead(ASYNC, 0, 0),  // EOF
829   };
830   OrderedSocketData data(reads, arraysize(reads),
831                          writes, arraysize(writes));
832   OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
833
834   BoundNetLog log;
835   TransactionHelperResult out;
836   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
837                                      BoundNetLog(), GetParam(), NULL);
838   helper.RunPreTestSetup();
839   helper.AddData(&data);
840   // We require placeholder data because three get requests are sent out, so
841   // there needs to be three sets of SSL connection data.
842   helper.AddData(&data_placeholder);
843   helper.AddData(&data_placeholder);
844   scoped_ptr<HttpNetworkTransaction> trans1(
845       new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
846   scoped_ptr<HttpNetworkTransaction> trans2(
847       new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
848   scoped_ptr<HttpNetworkTransaction> trans3(
849       new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
850
851   TestCompletionCallback callback1;
852   TestCompletionCallback callback2;
853   TestCompletionCallback callback3;
854
855   HttpRequestInfo httpreq1 = CreateGetRequest();
856   HttpRequestInfo httpreq2 = CreateGetRequest();
857   HttpRequestInfo httpreq3 = CreateGetRequest();
858
859   out.rv = trans1->Start(&httpreq1, callback1.callback(), log);
860   ASSERT_EQ(ERR_IO_PENDING, out.rv);
861   out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
862   ASSERT_EQ(ERR_IO_PENDING, out.rv);
863   out.rv = trans3->Start(&httpreq3, callback3.callback(), log);
864   ASSERT_EQ(ERR_IO_PENDING, out.rv);
865
866   out.rv = callback1.WaitForResult();
867   ASSERT_EQ(OK, out.rv);
868   out.rv = callback3.WaitForResult();
869   ASSERT_EQ(OK, out.rv);
870
871   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
872   EXPECT_TRUE(response1->headers.get() != NULL);
873   EXPECT_TRUE(response1->was_fetched_via_spdy);
874   out.status_line = response1->headers->GetStatusLine();
875   out.response_info = *response1;
876
877   trans2->GetResponseInfo();
878
879   out.rv = ReadTransaction(trans1.get(), &out.response_data);
880   helper.VerifyDataConsumed();
881   EXPECT_EQ(OK, out.rv);
882
883   EXPECT_EQ(OK, out.rv);
884   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
885   EXPECT_EQ("hello!hello!", out.response_data);
886 }
887
888 TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBinding) {
889   scoped_ptr<SpdyFrame> req(
890       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
891   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
892   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
893   scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
894
895   scoped_ptr<SpdyFrame> req2(
896       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
897   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
898   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
899   scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
900
901   MockWrite writes[] = {
902     CreateMockWrite(*req),
903     CreateMockWrite(*req2),
904   };
905   MockRead reads[] = {
906     CreateMockRead(*resp, 1),
907     CreateMockRead(*body),
908     CreateMockRead(*resp2, 4),
909     CreateMockRead(*body2),
910     CreateMockRead(*fbody),
911     CreateMockRead(*fbody2),
912     MockRead(ASYNC, 0, 0),  // EOF
913   };
914   OrderedSocketData data(reads, arraysize(reads),
915                          writes, arraysize(writes));
916
917   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
918
919   OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
920   data_placeholder.set_connect_data(never_finishing_connect);
921
922   BoundNetLog log;
923   TransactionHelperResult out;
924   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
925                                      BoundNetLog(), GetParam(), NULL);
926   helper.RunPreTestSetup();
927   helper.AddData(&data);
928   // We require placeholder data because two get requests are sent out, so
929   // there needs to be two sets of SSL connection data.
930   helper.AddData(&data_placeholder);
931   scoped_ptr<HttpNetworkTransaction> trans1(
932       new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
933   scoped_ptr<HttpNetworkTransaction> trans2(
934       new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
935
936   TestCompletionCallback callback1;
937   TestCompletionCallback callback2;
938
939   HttpRequestInfo httpreq1 = CreateGetRequest();
940   HttpRequestInfo httpreq2 = CreateGetRequest();
941
942   out.rv = trans1->Start(&httpreq1, callback1.callback(), log);
943   ASSERT_EQ(ERR_IO_PENDING, out.rv);
944   out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
945   ASSERT_EQ(ERR_IO_PENDING, out.rv);
946
947   out.rv = callback1.WaitForResult();
948   ASSERT_EQ(OK, out.rv);
949   out.rv = callback2.WaitForResult();
950   ASSERT_EQ(OK, out.rv);
951
952   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
953   EXPECT_TRUE(response1->headers.get() != NULL);
954   EXPECT_TRUE(response1->was_fetched_via_spdy);
955   out.status_line = response1->headers->GetStatusLine();
956   out.response_info = *response1;
957   out.rv = ReadTransaction(trans1.get(), &out.response_data);
958   EXPECT_EQ(OK, out.rv);
959   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
960   EXPECT_EQ("hello!hello!", out.response_data);
961
962   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
963   EXPECT_TRUE(response2->headers.get() != NULL);
964   EXPECT_TRUE(response2->was_fetched_via_spdy);
965   out.status_line = response2->headers->GetStatusLine();
966   out.response_info = *response2;
967   out.rv = ReadTransaction(trans2.get(), &out.response_data);
968   EXPECT_EQ(OK, out.rv);
969   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
970   EXPECT_EQ("hello!hello!", out.response_data);
971
972   helper.VerifyDataConsumed();
973 }
974
975 TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) {
976   scoped_ptr<SpdyFrame> req(
977       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
978   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
979   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
980   scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
981
982   scoped_ptr<SpdyFrame> req2(
983       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
984   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
985   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
986   scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
987
988   MockWrite writes[] = {
989     CreateMockWrite(*req),
990     CreateMockWrite(*req2),
991   };
992   MockRead reads[] = {
993     CreateMockRead(*resp, 1),
994     CreateMockRead(*body),
995     CreateMockRead(*resp2, 4),
996     CreateMockRead(*body2),
997     CreateMockRead(*fbody),
998     CreateMockRead(*fbody2),
999     MockRead(ASYNC, 0, 0),  // EOF
1000   };
1001   OrderedSocketData preconnect_data(reads, arraysize(reads),
1002                                     writes, arraysize(writes));
1003
1004   MockConnect never_finishing_connect(ASYNC, ERR_IO_PENDING);
1005
1006   OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
1007   data_placeholder.set_connect_data(never_finishing_connect);
1008
1009   BoundNetLog log;
1010   TransactionHelperResult out;
1011   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
1012                                      BoundNetLog(), GetParam(), NULL);
1013   helper.RunPreTestSetup();
1014   helper.AddData(&preconnect_data);
1015   // We require placeholder data because 3 connections are attempted (first is
1016   // the preconnect, 2nd and 3rd are the never finished connections.
1017   helper.AddData(&data_placeholder);
1018   helper.AddData(&data_placeholder);
1019
1020   scoped_ptr<HttpNetworkTransaction> trans1(
1021       new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
1022   scoped_ptr<HttpNetworkTransaction> trans2(
1023       new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
1024
1025   TestCompletionCallback callback1;
1026   TestCompletionCallback callback2;
1027
1028   HttpRequestInfo httpreq = CreateGetRequest();
1029
1030   // Preconnect the first.
1031   SSLConfig preconnect_ssl_config;
1032   helper.session()->ssl_config_service()->GetSSLConfig(&preconnect_ssl_config);
1033   HttpStreamFactory* http_stream_factory =
1034       helper.session()->http_stream_factory();
1035   if (http_stream_factory->has_next_protos()) {
1036     preconnect_ssl_config.next_protos = http_stream_factory->next_protos();
1037   }
1038
1039   http_stream_factory->PreconnectStreams(
1040       1, httpreq, DEFAULT_PRIORITY,
1041       preconnect_ssl_config, preconnect_ssl_config);
1042
1043   out.rv = trans1->Start(&httpreq, callback1.callback(), log);
1044   ASSERT_EQ(ERR_IO_PENDING, out.rv);
1045   out.rv = trans2->Start(&httpreq, callback2.callback(), log);
1046   ASSERT_EQ(ERR_IO_PENDING, out.rv);
1047
1048   out.rv = callback1.WaitForResult();
1049   ASSERT_EQ(OK, out.rv);
1050   out.rv = callback2.WaitForResult();
1051   ASSERT_EQ(OK, out.rv);
1052
1053   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
1054   EXPECT_TRUE(response1->headers.get() != NULL);
1055   EXPECT_TRUE(response1->was_fetched_via_spdy);
1056   out.status_line = response1->headers->GetStatusLine();
1057   out.response_info = *response1;
1058   out.rv = ReadTransaction(trans1.get(), &out.response_data);
1059   EXPECT_EQ(OK, out.rv);
1060   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1061   EXPECT_EQ("hello!hello!", out.response_data);
1062
1063   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
1064   EXPECT_TRUE(response2->headers.get() != NULL);
1065   EXPECT_TRUE(response2->was_fetched_via_spdy);
1066   out.status_line = response2->headers->GetStatusLine();
1067   out.response_info = *response2;
1068   out.rv = ReadTransaction(trans2.get(), &out.response_data);
1069   EXPECT_EQ(OK, out.rv);
1070   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1071   EXPECT_EQ("hello!hello!", out.response_data);
1072
1073   helper.VerifyDataConsumed();
1074 }
1075
1076 // Similar to ThreeGets above, however this test adds a SETTINGS
1077 // frame.  The SETTINGS frame is read during the IO loop waiting on
1078 // the first transaction completion, and sets a maximum concurrent
1079 // stream limit of 1.  This means that our IO loop exists after the
1080 // second transaction completes, so we can assert on read_index().
1081 TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) {
1082   // Construct the request.
1083   scoped_ptr<SpdyFrame> req(
1084       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
1085   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1086   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
1087   scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
1088
1089   scoped_ptr<SpdyFrame> req2(
1090       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
1091   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
1092   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
1093   scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
1094
1095   scoped_ptr<SpdyFrame> req3(
1096       spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, LOWEST, true));
1097   scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
1098   scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, false));
1099   scoped_ptr<SpdyFrame> fbody3(spdy_util_.ConstructSpdyBodyFrame(5, true));
1100
1101   SettingsMap settings;
1102   const uint32 max_concurrent_streams = 1;
1103   settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
1104       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
1105   scoped_ptr<SpdyFrame> settings_frame(
1106       spdy_util_.ConstructSpdySettings(settings));
1107
1108   MockWrite writes[] = {
1109     CreateMockWrite(*req),
1110     CreateMockWrite(*req2),
1111     CreateMockWrite(*req3),
1112   };
1113
1114   MockRead reads[] = {
1115     CreateMockRead(*settings_frame, 1),
1116     CreateMockRead(*resp),
1117     CreateMockRead(*body),
1118     CreateMockRead(*fbody),
1119     CreateMockRead(*resp2, 7),
1120     CreateMockRead(*body2),
1121     CreateMockRead(*fbody2),
1122     CreateMockRead(*resp3, 12),
1123     CreateMockRead(*body3),
1124     CreateMockRead(*fbody3),
1125
1126     MockRead(ASYNC, 0, 0),  // EOF
1127   };
1128
1129   OrderedSocketData data(reads, arraysize(reads),
1130                          writes, arraysize(writes));
1131   OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
1132
1133   BoundNetLog log;
1134   TransactionHelperResult out;
1135   {
1136     NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
1137                                        BoundNetLog(), GetParam(), NULL);
1138     helper.RunPreTestSetup();
1139     helper.AddData(&data);
1140     // We require placeholder data because three get requests are sent out, so
1141     // there needs to be three sets of SSL connection data.
1142     helper.AddData(&data_placeholder);
1143     helper.AddData(&data_placeholder);
1144     scoped_ptr<HttpNetworkTransaction> trans1(
1145         new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
1146     scoped_ptr<HttpNetworkTransaction> trans2(
1147         new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
1148     scoped_ptr<HttpNetworkTransaction> trans3(
1149         new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
1150
1151     TestCompletionCallback callback1;
1152     TestCompletionCallback callback2;
1153     TestCompletionCallback callback3;
1154
1155     HttpRequestInfo httpreq1 = CreateGetRequest();
1156     HttpRequestInfo httpreq2 = CreateGetRequest();
1157     HttpRequestInfo httpreq3 = CreateGetRequest();
1158
1159     out.rv = trans1->Start(&httpreq1, callback1.callback(), log);
1160     ASSERT_EQ(out.rv, ERR_IO_PENDING);
1161     // Run transaction 1 through quickly to force a read of our SETTINGS
1162     // frame.
1163     out.rv = callback1.WaitForResult();
1164     ASSERT_EQ(OK, out.rv);
1165
1166     out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
1167     ASSERT_EQ(out.rv, ERR_IO_PENDING);
1168     out.rv = trans3->Start(&httpreq3, callback3.callback(), log);
1169     ASSERT_EQ(out.rv, ERR_IO_PENDING);
1170     out.rv = callback2.WaitForResult();
1171     ASSERT_EQ(OK, out.rv);
1172     EXPECT_EQ(7U, data.read_index());  // i.e. the third trans was queued
1173
1174     out.rv = callback3.WaitForResult();
1175     ASSERT_EQ(OK, out.rv);
1176
1177     const HttpResponseInfo* response1 = trans1->GetResponseInfo();
1178     ASSERT_TRUE(response1 != NULL);
1179     EXPECT_TRUE(response1->headers.get() != NULL);
1180     EXPECT_TRUE(response1->was_fetched_via_spdy);
1181     out.status_line = response1->headers->GetStatusLine();
1182     out.response_info = *response1;
1183     out.rv = ReadTransaction(trans1.get(), &out.response_data);
1184     EXPECT_EQ(OK, out.rv);
1185     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1186     EXPECT_EQ("hello!hello!", out.response_data);
1187
1188     const HttpResponseInfo* response2 = trans2->GetResponseInfo();
1189     out.status_line = response2->headers->GetStatusLine();
1190     out.response_info = *response2;
1191     out.rv = ReadTransaction(trans2.get(), &out.response_data);
1192     EXPECT_EQ(OK, out.rv);
1193     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1194     EXPECT_EQ("hello!hello!", out.response_data);
1195
1196     const HttpResponseInfo* response3 = trans3->GetResponseInfo();
1197     out.status_line = response3->headers->GetStatusLine();
1198     out.response_info = *response3;
1199     out.rv = ReadTransaction(trans3.get(), &out.response_data);
1200     EXPECT_EQ(OK, out.rv);
1201     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1202     EXPECT_EQ("hello!hello!", out.response_data);
1203
1204     helper.VerifyDataConsumed();
1205   }
1206   EXPECT_EQ(OK, out.rv);
1207 }
1208
1209 // Similar to ThreeGetsWithMaxConcurrent above, however this test adds
1210 // a fourth transaction.  The third and fourth transactions have
1211 // different data ("hello!" vs "hello!hello!") and because of the
1212 // user specified priority, we expect to see them inverted in
1213 // the response from the server.
1214 TEST_P(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) {
1215   // Construct the request.
1216   scoped_ptr<SpdyFrame> req(
1217       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
1218   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1219   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
1220   scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
1221
1222   scoped_ptr<SpdyFrame> req2(
1223       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
1224   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
1225   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
1226   scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
1227
1228   scoped_ptr<SpdyFrame> req4(
1229       spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, HIGHEST, true));
1230   scoped_ptr<SpdyFrame> resp4(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
1231   scoped_ptr<SpdyFrame> fbody4(spdy_util_.ConstructSpdyBodyFrame(5, true));
1232
1233   scoped_ptr<SpdyFrame> req3(
1234       spdy_util_.ConstructSpdyGet(NULL, 0, false, 7, LOWEST, true));
1235   scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 7));
1236   scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(7, false));
1237   scoped_ptr<SpdyFrame> fbody3(spdy_util_.ConstructSpdyBodyFrame(7, true));
1238
1239   SettingsMap settings;
1240   const uint32 max_concurrent_streams = 1;
1241   settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
1242       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
1243   scoped_ptr<SpdyFrame> settings_frame(
1244       spdy_util_.ConstructSpdySettings(settings));
1245
1246   MockWrite writes[] = { CreateMockWrite(*req),
1247     CreateMockWrite(*req2),
1248     CreateMockWrite(*req4),
1249     CreateMockWrite(*req3),
1250   };
1251   MockRead reads[] = {
1252     CreateMockRead(*settings_frame, 1),
1253     CreateMockRead(*resp),
1254     CreateMockRead(*body),
1255     CreateMockRead(*fbody),
1256     CreateMockRead(*resp2, 7),
1257     CreateMockRead(*body2),
1258     CreateMockRead(*fbody2),
1259     CreateMockRead(*resp4, 13),
1260     CreateMockRead(*fbody4),
1261     CreateMockRead(*resp3, 16),
1262     CreateMockRead(*body3),
1263     CreateMockRead(*fbody3),
1264
1265     MockRead(ASYNC, 0, 0),  // EOF
1266   };
1267
1268   OrderedSocketData data(reads, arraysize(reads),
1269                          writes, arraysize(writes));
1270   OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
1271
1272   BoundNetLog log;
1273   TransactionHelperResult out;
1274   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
1275                                      BoundNetLog(), GetParam(), NULL);
1276   helper.RunPreTestSetup();
1277   helper.AddData(&data);
1278   // We require placeholder data because four get requests are sent out, so
1279   // there needs to be four sets of SSL connection data.
1280   helper.AddData(&data_placeholder);
1281   helper.AddData(&data_placeholder);
1282   helper.AddData(&data_placeholder);
1283   scoped_ptr<HttpNetworkTransaction> trans1(
1284       new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
1285   scoped_ptr<HttpNetworkTransaction> trans2(
1286       new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
1287   scoped_ptr<HttpNetworkTransaction> trans3(
1288       new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
1289   scoped_ptr<HttpNetworkTransaction> trans4(
1290       new HttpNetworkTransaction(HIGHEST, helper.session().get()));
1291
1292   TestCompletionCallback callback1;
1293   TestCompletionCallback callback2;
1294   TestCompletionCallback callback3;
1295   TestCompletionCallback callback4;
1296
1297   HttpRequestInfo httpreq1 = CreateGetRequest();
1298   HttpRequestInfo httpreq2 = CreateGetRequest();
1299   HttpRequestInfo httpreq3 = CreateGetRequest();
1300   HttpRequestInfo httpreq4 = CreateGetRequest();
1301
1302   out.rv = trans1->Start(&httpreq1, callback1.callback(), log);
1303   ASSERT_EQ(ERR_IO_PENDING, out.rv);
1304   // Run transaction 1 through quickly to force a read of our SETTINGS frame.
1305   out.rv = callback1.WaitForResult();
1306   ASSERT_EQ(OK, out.rv);
1307
1308   out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
1309   ASSERT_EQ(ERR_IO_PENDING, out.rv);
1310   out.rv = trans3->Start(&httpreq3, callback3.callback(), log);
1311   ASSERT_EQ(ERR_IO_PENDING, out.rv);
1312   out.rv = trans4->Start(&httpreq4, callback4.callback(), log);
1313   ASSERT_EQ(ERR_IO_PENDING, out.rv);
1314
1315   out.rv = callback2.WaitForResult();
1316   ASSERT_EQ(OK, out.rv);
1317   EXPECT_EQ(data.read_index(), 7U);  // i.e. the third & fourth trans queued
1318
1319   out.rv = callback3.WaitForResult();
1320   ASSERT_EQ(OK, out.rv);
1321
1322   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
1323   EXPECT_TRUE(response1->headers.get() != NULL);
1324   EXPECT_TRUE(response1->was_fetched_via_spdy);
1325   out.status_line = response1->headers->GetStatusLine();
1326   out.response_info = *response1;
1327   out.rv = ReadTransaction(trans1.get(), &out.response_data);
1328   EXPECT_EQ(OK, out.rv);
1329   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1330   EXPECT_EQ("hello!hello!", out.response_data);
1331
1332   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
1333   out.status_line = response2->headers->GetStatusLine();
1334   out.response_info = *response2;
1335   out.rv = ReadTransaction(trans2.get(), &out.response_data);
1336   EXPECT_EQ(OK, out.rv);
1337   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1338   EXPECT_EQ("hello!hello!", out.response_data);
1339
1340   // notice: response3 gets two hellos, response4 gets one
1341   // hello, so we know dequeuing priority was respected.
1342   const HttpResponseInfo* response3 = trans3->GetResponseInfo();
1343   out.status_line = response3->headers->GetStatusLine();
1344   out.response_info = *response3;
1345   out.rv = ReadTransaction(trans3.get(), &out.response_data);
1346   EXPECT_EQ(OK, out.rv);
1347   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1348   EXPECT_EQ("hello!hello!", out.response_data);
1349
1350   out.rv = callback4.WaitForResult();
1351   EXPECT_EQ(OK, out.rv);
1352   const HttpResponseInfo* response4 = trans4->GetResponseInfo();
1353   out.status_line = response4->headers->GetStatusLine();
1354   out.response_info = *response4;
1355   out.rv = ReadTransaction(trans4.get(), &out.response_data);
1356   EXPECT_EQ(OK, out.rv);
1357   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1358   EXPECT_EQ("hello!", out.response_data);
1359   helper.VerifyDataConsumed();
1360   EXPECT_EQ(OK, out.rv);
1361 }
1362
1363 // Similar to ThreeGetsMaxConcurrrent above, however, this test
1364 // deletes a session in the middle of the transaction to insure
1365 // that we properly remove pendingcreatestream objects from
1366 // the spdy_session
1367 TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) {
1368   // Construct the request.
1369   scoped_ptr<SpdyFrame> req(
1370       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
1371   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1372   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
1373   scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
1374
1375   scoped_ptr<SpdyFrame> req2(
1376       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
1377   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
1378   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
1379   scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
1380
1381   SettingsMap settings;
1382   const uint32 max_concurrent_streams = 1;
1383   settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
1384       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
1385   scoped_ptr<SpdyFrame> settings_frame(
1386       spdy_util_.ConstructSpdySettings(settings));
1387
1388   MockWrite writes[] = { CreateMockWrite(*req),
1389     CreateMockWrite(*req2),
1390   };
1391   MockRead reads[] = {
1392     CreateMockRead(*settings_frame, 1),
1393     CreateMockRead(*resp),
1394     CreateMockRead(*body),
1395     CreateMockRead(*fbody),
1396     CreateMockRead(*resp2, 7),
1397     CreateMockRead(*body2),
1398     CreateMockRead(*fbody2),
1399     MockRead(ASYNC, 0, 0),  // EOF
1400   };
1401
1402   OrderedSocketData data(reads, arraysize(reads),
1403                          writes, arraysize(writes));
1404   OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
1405
1406   BoundNetLog log;
1407   TransactionHelperResult out;
1408   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
1409                                      BoundNetLog(), GetParam(), NULL);
1410   helper.RunPreTestSetup();
1411   helper.AddData(&data);
1412   // We require placeholder data because three get requests are sent out, so
1413   // there needs to be three sets of SSL connection data.
1414   helper.AddData(&data_placeholder);
1415   helper.AddData(&data_placeholder);
1416   scoped_ptr<HttpNetworkTransaction> trans1(
1417       new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
1418   scoped_ptr<HttpNetworkTransaction> trans2(
1419       new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
1420   scoped_ptr<HttpNetworkTransaction> trans3(
1421       new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
1422
1423   TestCompletionCallback callback1;
1424   TestCompletionCallback callback2;
1425   TestCompletionCallback callback3;
1426
1427   HttpRequestInfo httpreq1 = CreateGetRequest();
1428   HttpRequestInfo httpreq2 = CreateGetRequest();
1429   HttpRequestInfo httpreq3 = CreateGetRequest();
1430
1431   out.rv = trans1->Start(&httpreq1, callback1.callback(), log);
1432   ASSERT_EQ(out.rv, ERR_IO_PENDING);
1433   // Run transaction 1 through quickly to force a read of our SETTINGS frame.
1434   out.rv = callback1.WaitForResult();
1435   ASSERT_EQ(OK, out.rv);
1436
1437   out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
1438   ASSERT_EQ(out.rv, ERR_IO_PENDING);
1439   out.rv = trans3->Start(&httpreq3, callback3.callback(), log);
1440   delete trans3.release();
1441   ASSERT_EQ(out.rv, ERR_IO_PENDING);
1442   out.rv = callback2.WaitForResult();
1443   ASSERT_EQ(OK, out.rv);
1444
1445   EXPECT_EQ(8U, data.read_index());
1446
1447   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
1448   ASSERT_TRUE(response1 != NULL);
1449   EXPECT_TRUE(response1->headers.get() != NULL);
1450   EXPECT_TRUE(response1->was_fetched_via_spdy);
1451   out.status_line = response1->headers->GetStatusLine();
1452   out.response_info = *response1;
1453   out.rv = ReadTransaction(trans1.get(), &out.response_data);
1454   EXPECT_EQ(OK, out.rv);
1455   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1456   EXPECT_EQ("hello!hello!", out.response_data);
1457
1458   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
1459   ASSERT_TRUE(response2 != NULL);
1460   out.status_line = response2->headers->GetStatusLine();
1461   out.response_info = *response2;
1462   out.rv = ReadTransaction(trans2.get(), &out.response_data);
1463   EXPECT_EQ(OK, out.rv);
1464   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1465   EXPECT_EQ("hello!hello!", out.response_data);
1466   helper.VerifyDataConsumed();
1467   EXPECT_EQ(OK, out.rv);
1468 }
1469
1470 namespace {
1471
1472 // The KillerCallback will delete the transaction on error as part of the
1473 // callback.
1474 class KillerCallback : public TestCompletionCallbackBase {
1475  public:
1476   explicit KillerCallback(HttpNetworkTransaction* transaction)
1477       : transaction_(transaction),
1478         callback_(base::Bind(&KillerCallback::OnComplete,
1479                              base::Unretained(this))) {
1480   }
1481
1482   virtual ~KillerCallback() {}
1483
1484   const CompletionCallback& callback() const { return callback_; }
1485
1486  private:
1487   void OnComplete(int result) {
1488     if (result < 0)
1489       delete transaction_;
1490
1491     SetResult(result);
1492   }
1493
1494   HttpNetworkTransaction* transaction_;
1495   CompletionCallback callback_;
1496 };
1497
1498 }  // namespace
1499
1500 // Similar to ThreeGetsMaxConcurrrentDelete above, however, this test
1501 // closes the socket while we have a pending transaction waiting for
1502 // a pending stream creation.  http://crbug.com/52901
1503 TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentSocketClose) {
1504   // Construct the request.
1505   scoped_ptr<SpdyFrame> req(
1506       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
1507   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1508   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
1509   scoped_ptr<SpdyFrame> fin_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
1510
1511   scoped_ptr<SpdyFrame> req2(
1512       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
1513   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
1514
1515   SettingsMap settings;
1516   const uint32 max_concurrent_streams = 1;
1517   settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
1518       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
1519   scoped_ptr<SpdyFrame> settings_frame(
1520       spdy_util_.ConstructSpdySettings(settings));
1521
1522   MockWrite writes[] = { CreateMockWrite(*req),
1523     CreateMockWrite(*req2),
1524   };
1525   MockRead reads[] = {
1526     CreateMockRead(*settings_frame, 1),
1527     CreateMockRead(*resp),
1528     CreateMockRead(*body),
1529     CreateMockRead(*fin_body),
1530     CreateMockRead(*resp2, 7),
1531     MockRead(ASYNC, ERR_CONNECTION_RESET, 0),  // Abort!
1532   };
1533
1534   OrderedSocketData data(reads, arraysize(reads),
1535                          writes, arraysize(writes));
1536   OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
1537
1538   BoundNetLog log;
1539   TransactionHelperResult out;
1540   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
1541                                      BoundNetLog(), GetParam(), NULL);
1542   helper.RunPreTestSetup();
1543   helper.AddData(&data);
1544   // We require placeholder data because three get requests are sent out, so
1545   // there needs to be three sets of SSL connection data.
1546   helper.AddData(&data_placeholder);
1547   helper.AddData(&data_placeholder);
1548   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session().get());
1549   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session().get());
1550   HttpNetworkTransaction* trans3(
1551       new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
1552
1553   TestCompletionCallback callback1;
1554   TestCompletionCallback callback2;
1555   KillerCallback callback3(trans3);
1556
1557   HttpRequestInfo httpreq1 = CreateGetRequest();
1558   HttpRequestInfo httpreq2 = CreateGetRequest();
1559   HttpRequestInfo httpreq3 = CreateGetRequest();
1560
1561   out.rv = trans1.Start(&httpreq1, callback1.callback(), log);
1562   ASSERT_EQ(out.rv, ERR_IO_PENDING);
1563   // Run transaction 1 through quickly to force a read of our SETTINGS frame.
1564   out.rv = callback1.WaitForResult();
1565   ASSERT_EQ(OK, out.rv);
1566
1567   out.rv = trans2.Start(&httpreq2, callback2.callback(), log);
1568   ASSERT_EQ(out.rv, ERR_IO_PENDING);
1569   out.rv = trans3->Start(&httpreq3, callback3.callback(), log);
1570   ASSERT_EQ(out.rv, ERR_IO_PENDING);
1571   out.rv = callback3.WaitForResult();
1572   ASSERT_EQ(ERR_ABORTED, out.rv);
1573
1574   EXPECT_EQ(6U, data.read_index());
1575
1576   const HttpResponseInfo* response1 = trans1.GetResponseInfo();
1577   ASSERT_TRUE(response1 != NULL);
1578   EXPECT_TRUE(response1->headers.get() != NULL);
1579   EXPECT_TRUE(response1->was_fetched_via_spdy);
1580   out.status_line = response1->headers->GetStatusLine();
1581   out.response_info = *response1;
1582   out.rv = ReadTransaction(&trans1, &out.response_data);
1583   EXPECT_EQ(OK, out.rv);
1584
1585   const HttpResponseInfo* response2 = trans2.GetResponseInfo();
1586   ASSERT_TRUE(response2 != NULL);
1587   out.status_line = response2->headers->GetStatusLine();
1588   out.response_info = *response2;
1589   out.rv = ReadTransaction(&trans2, &out.response_data);
1590   EXPECT_EQ(ERR_CONNECTION_RESET, out.rv);
1591
1592   helper.VerifyDataConsumed();
1593 }
1594
1595 // Test that a simple PUT request works.
1596 TEST_P(SpdyNetworkTransactionTest, Put) {
1597   // Setup the request
1598   HttpRequestInfo request;
1599   request.method = "PUT";
1600   request.url = GURL("http://www.google.com/");
1601
1602   const SpdyHeaderInfo kSynStartHeader = {
1603     SYN_STREAM,             // Kind = Syn
1604     1,                      // Stream ID
1605     0,                      // Associated stream ID
1606     ConvertRequestPriorityToSpdyPriority(
1607         LOWEST, spdy_util_.spdy_version()),
1608     kSpdyCredentialSlotUnused,
1609     CONTROL_FLAG_FIN,       // Control Flags
1610     false,                  // Compressed
1611     RST_STREAM_INVALID,     // Status
1612     NULL,                   // Data
1613     0,                      // Length
1614     DATA_FLAG_NONE          // Data Flags
1615   };
1616   scoped_ptr<SpdyHeaderBlock> put_headers(
1617       spdy_util_.ConstructPutHeaderBlock("http://www.google.com", 0));
1618   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyFrame(
1619       kSynStartHeader, put_headers.Pass()));
1620   MockWrite writes[] = {
1621     CreateMockWrite(*req),
1622   };
1623
1624   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
1625   const SpdyHeaderInfo kSynReplyHeader = {
1626     SYN_REPLY,              // Kind = SynReply
1627     1,                      // Stream ID
1628     0,                      // Associated stream ID
1629     ConvertRequestPriorityToSpdyPriority(
1630         LOWEST, spdy_util_.spdy_version()),
1631     kSpdyCredentialSlotUnused,
1632     CONTROL_FLAG_NONE,      // Control Flags
1633     false,                  // Compressed
1634     RST_STREAM_INVALID,     // Status
1635     NULL,                   // Data
1636     0,                      // Length
1637     DATA_FLAG_NONE          // Data Flags
1638   };
1639   scoped_ptr<SpdyHeaderBlock> reply_headers(new SpdyHeaderBlock());
1640   (*reply_headers)[spdy_util_.GetStatusKey()] = "200";
1641   (*reply_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
1642   (*reply_headers)["content-length"] = "1234";
1643   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyFrame(
1644       kSynReplyHeader, reply_headers.Pass()));
1645   MockRead reads[] = {
1646     CreateMockRead(*resp),
1647     CreateMockRead(*body),
1648     MockRead(ASYNC, 0, 0)  // EOF
1649   };
1650
1651   DelayedSocketData data(1, reads, arraysize(reads),
1652                          writes, arraysize(writes));
1653   NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
1654                                      BoundNetLog(), GetParam(), NULL);
1655   helper.RunToCompletion(&data);
1656   TransactionHelperResult out = helper.output();
1657
1658   EXPECT_EQ(OK, out.rv);
1659   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1660 }
1661
1662 // Test that a simple HEAD request works.
1663 TEST_P(SpdyNetworkTransactionTest, Head) {
1664   // Setup the request
1665   HttpRequestInfo request;
1666   request.method = "HEAD";
1667   request.url = GURL("http://www.google.com/");
1668
1669   const SpdyHeaderInfo kSynStartHeader = {
1670     SYN_STREAM,             // Kind = Syn
1671     1,                      // Stream ID
1672     0,                      // Associated stream ID
1673     ConvertRequestPriorityToSpdyPriority(
1674         LOWEST, spdy_util_.spdy_version()),
1675     kSpdyCredentialSlotUnused,
1676     CONTROL_FLAG_FIN,       // Control Flags
1677     false,                  // Compressed
1678     RST_STREAM_INVALID,     // Status
1679     NULL,                   // Data
1680     0,                      // Length
1681     DATA_FLAG_NONE          // Data Flags
1682   };
1683   scoped_ptr<SpdyHeaderBlock> head_headers(
1684       spdy_util_.ConstructHeadHeaderBlock("http://www.google.com", 0));
1685   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyFrame(
1686       kSynStartHeader, head_headers.Pass()));
1687   MockWrite writes[] = {
1688     CreateMockWrite(*req),
1689   };
1690
1691   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
1692   const SpdyHeaderInfo kSynReplyHeader = {
1693     SYN_REPLY,              // Kind = SynReply
1694     1,                      // Stream ID
1695     0,                      // Associated stream ID
1696     ConvertRequestPriorityToSpdyPriority(
1697         LOWEST, spdy_util_.spdy_version()),
1698     kSpdyCredentialSlotUnused,
1699     CONTROL_FLAG_NONE,      // Control Flags
1700     false,                  // Compressed
1701     RST_STREAM_INVALID,     // Status
1702     NULL,                   // Data
1703     0,                      // Length
1704     DATA_FLAG_NONE          // Data Flags
1705   };
1706   scoped_ptr<SpdyHeaderBlock> reply_headers(new SpdyHeaderBlock());
1707   (*reply_headers)[spdy_util_.GetStatusKey()] = "200";
1708   (*reply_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
1709   (*reply_headers)["content-length"] = "1234";
1710   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyFrame(
1711       kSynReplyHeader,
1712       reply_headers.Pass()));
1713   MockRead reads[] = {
1714     CreateMockRead(*resp),
1715     CreateMockRead(*body),
1716     MockRead(ASYNC, 0, 0)  // EOF
1717   };
1718
1719   DelayedSocketData data(1, reads, arraysize(reads),
1720                          writes, arraysize(writes));
1721   NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
1722                                      BoundNetLog(), GetParam(), NULL);
1723   helper.RunToCompletion(&data);
1724   TransactionHelperResult out = helper.output();
1725
1726   EXPECT_EQ(OK, out.rv);
1727   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1728 }
1729
1730 // Test that a simple POST works.
1731 TEST_P(SpdyNetworkTransactionTest, Post) {
1732   scoped_ptr<SpdyFrame> req(
1733       spdy_util_.ConstructSpdyPost(
1734           kRequestUrl, 1, kUploadDataSize, LOWEST, NULL, 0));
1735   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
1736   MockWrite writes[] = {
1737     CreateMockWrite(*req),
1738     CreateMockWrite(*body),  // POST upload frame
1739   };
1740
1741   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
1742   MockRead reads[] = {
1743     CreateMockRead(*resp),
1744     CreateMockRead(*body),
1745     MockRead(ASYNC, 0, 0)  // EOF
1746   };
1747
1748   DelayedSocketData data(2, reads, arraysize(reads),
1749                          writes, arraysize(writes));
1750   NormalSpdyTransactionHelper helper(CreatePostRequest(), DEFAULT_PRIORITY,
1751                                      BoundNetLog(), GetParam(), NULL);
1752   helper.RunToCompletion(&data);
1753   TransactionHelperResult out = helper.output();
1754   EXPECT_EQ(OK, out.rv);
1755   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1756   EXPECT_EQ("hello!", out.response_data);
1757 }
1758
1759 // Test that a POST with a file works.
1760 TEST_P(SpdyNetworkTransactionTest, FilePost) {
1761   scoped_ptr<SpdyFrame> req(
1762       spdy_util_.ConstructSpdyPost(
1763           kRequestUrl, 1, kUploadDataSize, LOWEST, NULL, 0));
1764   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
1765   MockWrite writes[] = {
1766     CreateMockWrite(*req),
1767     CreateMockWrite(*body),  // POST upload frame
1768   };
1769
1770   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
1771   MockRead reads[] = {
1772     CreateMockRead(*resp),
1773     CreateMockRead(*body),
1774     MockRead(ASYNC, 0, 0)  // EOF
1775   };
1776
1777   DelayedSocketData data(2, reads, arraysize(reads),
1778                          writes, arraysize(writes));
1779   NormalSpdyTransactionHelper helper(CreateFilePostRequest(), DEFAULT_PRIORITY,
1780                                      BoundNetLog(), GetParam(), NULL);
1781   helper.RunToCompletion(&data);
1782   TransactionHelperResult out = helper.output();
1783   EXPECT_EQ(OK, out.rv);
1784   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1785   EXPECT_EQ("hello!", out.response_data);
1786 }
1787
1788 // Test that a complex POST works.
1789 TEST_P(SpdyNetworkTransactionTest, ComplexPost) {
1790   scoped_ptr<SpdyFrame> req(
1791       spdy_util_.ConstructSpdyPost(
1792           kRequestUrl, 1, kUploadDataSize, LOWEST, NULL, 0));
1793   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
1794   MockWrite writes[] = {
1795     CreateMockWrite(*req),
1796     CreateMockWrite(*body),  // POST upload frame
1797   };
1798
1799   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
1800   MockRead reads[] = {
1801     CreateMockRead(*resp),
1802     CreateMockRead(*body),
1803     MockRead(ASYNC, 0, 0)  // EOF
1804   };
1805
1806   DelayedSocketData data(2, reads, arraysize(reads),
1807                          writes, arraysize(writes));
1808   NormalSpdyTransactionHelper helper(CreateComplexPostRequest(),
1809                                      DEFAULT_PRIORITY,
1810                                      BoundNetLog(), GetParam(), NULL);
1811   helper.RunToCompletion(&data);
1812   TransactionHelperResult out = helper.output();
1813   EXPECT_EQ(OK, out.rv);
1814   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1815   EXPECT_EQ("hello!", out.response_data);
1816 }
1817
1818 // Test that a chunked POST works.
1819 TEST_P(SpdyNetworkTransactionTest, ChunkedPost) {
1820   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
1821   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
1822   MockWrite writes[] = {
1823     CreateMockWrite(*req),
1824     CreateMockWrite(*body),
1825   };
1826
1827   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
1828   MockRead reads[] = {
1829     CreateMockRead(*resp),
1830     CreateMockRead(*body),
1831     MockRead(ASYNC, 0, 0)  // EOF
1832   };
1833
1834   DelayedSocketData data(2, reads, arraysize(reads),
1835                          writes, arraysize(writes));
1836   NormalSpdyTransactionHelper helper(CreateChunkedPostRequest(),
1837                                      DEFAULT_PRIORITY,
1838                                      BoundNetLog(), GetParam(), NULL);
1839
1840   // These chunks get merged into a single frame when being sent.
1841   const int kFirstChunkSize = kUploadDataSize/2;
1842   helper.request().upload_data_stream->AppendChunk(
1843       kUploadData, kFirstChunkSize, false);
1844   helper.request().upload_data_stream->AppendChunk(
1845       kUploadData + kFirstChunkSize, kUploadDataSize - kFirstChunkSize, true);
1846
1847   helper.RunToCompletion(&data);
1848   TransactionHelperResult out = helper.output();
1849   EXPECT_EQ(OK, out.rv);
1850   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1851   EXPECT_EQ(kUploadData, out.response_data);
1852 }
1853
1854 // Test that a chunked POST works with chunks appended after transaction starts.
1855 TEST_P(SpdyNetworkTransactionTest, DelayedChunkedPost) {
1856   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
1857   scoped_ptr<SpdyFrame> chunk1(spdy_util_.ConstructSpdyBodyFrame(1, false));
1858   scoped_ptr<SpdyFrame> chunk2(spdy_util_.ConstructSpdyBodyFrame(1, false));
1859   scoped_ptr<SpdyFrame> chunk3(spdy_util_.ConstructSpdyBodyFrame(1, true));
1860   MockWrite writes[] = {
1861     CreateMockWrite(*req),
1862     CreateMockWrite(*chunk1),
1863     CreateMockWrite(*chunk2),
1864     CreateMockWrite(*chunk3),
1865   };
1866
1867   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
1868   MockRead reads[] = {
1869     CreateMockRead(*resp),
1870     CreateMockRead(*chunk1),
1871     CreateMockRead(*chunk2),
1872     CreateMockRead(*chunk3),
1873     MockRead(ASYNC, 0, 0)  // EOF
1874   };
1875
1876   DelayedSocketData data(4, reads, arraysize(reads),
1877                          writes, arraysize(writes));
1878   NormalSpdyTransactionHelper helper(CreateChunkedPostRequest(),
1879                                      DEFAULT_PRIORITY,
1880                                      BoundNetLog(), GetParam(), NULL);
1881
1882   helper.request().upload_data_stream->AppendChunk(
1883       kUploadData, kUploadDataSize, false);
1884
1885   helper.RunPreTestSetup();
1886   helper.AddData(&data);
1887   ASSERT_TRUE(helper.StartDefaultTest());
1888
1889   base::RunLoop().RunUntilIdle();
1890   helper.request().upload_data_stream->AppendChunk(
1891       kUploadData, kUploadDataSize, false);
1892   base::RunLoop().RunUntilIdle();
1893   helper.request().upload_data_stream->AppendChunk(
1894       kUploadData, kUploadDataSize, true);
1895
1896   helper.FinishDefaultTest();
1897   helper.VerifyDataConsumed();
1898
1899   std::string expected_response;
1900   expected_response += kUploadData;
1901   expected_response += kUploadData;
1902   expected_response += kUploadData;
1903
1904   TransactionHelperResult out = helper.output();
1905   EXPECT_EQ(OK, out.rv);
1906   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1907   EXPECT_EQ(expected_response, out.response_data);
1908 }
1909
1910 // Test that a POST without any post data works.
1911 TEST_P(SpdyNetworkTransactionTest, NullPost) {
1912   // Setup the request
1913   HttpRequestInfo request;
1914   request.method = "POST";
1915   request.url = GURL(kRequestUrl);
1916   // Create an empty UploadData.
1917   request.upload_data_stream = NULL;
1918
1919   // When request.upload_data_stream is NULL for post, content-length is
1920   // expected to be 0.
1921   scoped_ptr<SpdyFrame> req(
1922       spdy_util_.ConstructSpdyPost(kRequestUrl, 1, 0, LOWEST, NULL, 0));
1923   // Set the FIN bit since there will be no body.
1924   test::SetFrameFlags(req.get(), CONTROL_FLAG_FIN, spdy_util_.spdy_version());
1925   MockWrite writes[] = {
1926     CreateMockWrite(*req),
1927   };
1928
1929   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
1930   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
1931   MockRead reads[] = {
1932     CreateMockRead(*resp),
1933     CreateMockRead(*body),
1934     MockRead(ASYNC, 0, 0)  // EOF
1935   };
1936
1937   DelayedSocketData data(1, reads, arraysize(reads),
1938                          writes, arraysize(writes));
1939
1940   NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
1941                                      BoundNetLog(), GetParam(), NULL);
1942   helper.RunToCompletion(&data);
1943   TransactionHelperResult out = helper.output();
1944   EXPECT_EQ(OK, out.rv);
1945   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1946   EXPECT_EQ("hello!", out.response_data);
1947 }
1948
1949 // Test that a simple POST works.
1950 TEST_P(SpdyNetworkTransactionTest, EmptyPost) {
1951   // Create an empty UploadDataStream.
1952   ScopedVector<UploadElementReader> element_readers;
1953   UploadDataStream stream(element_readers.Pass(), 0);
1954
1955   // Setup the request
1956   HttpRequestInfo request;
1957   request.method = "POST";
1958   request.url = GURL(kRequestUrl);
1959   request.upload_data_stream = &stream;
1960
1961   const uint64 kContentLength = 0;
1962   scoped_ptr<SpdyFrame> req(
1963       spdy_util_.ConstructSpdyPost(
1964           kRequestUrl, 1, kContentLength, LOWEST, NULL, 0));
1965   // Set the FIN bit since there will be no body.
1966   test::SetFrameFlags(req.get(), CONTROL_FLAG_FIN, spdy_util_.spdy_version());
1967   MockWrite writes[] = {
1968     CreateMockWrite(*req),
1969   };
1970
1971   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
1972   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
1973   MockRead reads[] = {
1974     CreateMockRead(*resp),
1975     CreateMockRead(*body),
1976     MockRead(ASYNC, 0, 0)  // EOF
1977   };
1978
1979   DelayedSocketData data(1, reads, arraysize(reads), writes, arraysize(writes));
1980
1981   NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
1982                                      BoundNetLog(), GetParam(), NULL);
1983   helper.RunToCompletion(&data);
1984   TransactionHelperResult out = helper.output();
1985   EXPECT_EQ(OK, out.rv);
1986   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1987   EXPECT_EQ("hello!", out.response_data);
1988 }
1989
1990 // While we're doing a post, the server sends back a SYN_REPLY.
1991 TEST_P(SpdyNetworkTransactionTest, PostWithEarlySynReply) {
1992   static const char upload[] = { "hello!" };
1993   ScopedVector<UploadElementReader> element_readers;
1994   element_readers.push_back(
1995       new UploadBytesElementReader(upload, sizeof(upload)));
1996   UploadDataStream stream(element_readers.Pass(), 0);
1997
1998   // Setup the request
1999   HttpRequestInfo request;
2000   request.method = "POST";
2001   request.url = GURL(kRequestUrl);
2002   request.upload_data_stream = &stream;
2003
2004   scoped_ptr<SpdyFrame> stream_reply(
2005       spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
2006   MockRead reads[] = {
2007     CreateMockRead(*stream_reply, 1),
2008     MockRead(ASYNC, 0, 4)  // EOF
2009   };
2010
2011   scoped_ptr<SpdyFrame> req(
2012       spdy_util_.ConstructSpdyPost(
2013           kRequestUrl, 1, kUploadDataSize, LOWEST, NULL, 0));
2014   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2015   scoped_ptr<SpdyFrame> rst(
2016       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
2017   MockWrite writes[] = {
2018     CreateMockWrite(*req, 0),
2019     CreateMockWrite(*body, 2),
2020     CreateMockWrite(*rst, 3)
2021   };
2022
2023   DeterministicSocketData data(reads, arraysize(reads),
2024                                writes, arraysize(writes));
2025   NormalSpdyTransactionHelper helper(CreatePostRequest(), DEFAULT_PRIORITY,
2026                                      BoundNetLog(), GetParam(), NULL);
2027   helper.SetDeterministic();
2028   helper.RunPreTestSetup();
2029   helper.AddDeterministicData(&data);
2030   HttpNetworkTransaction* trans = helper.trans();
2031
2032   TestCompletionCallback callback;
2033   int rv = trans->Start(
2034       &CreatePostRequest(), callback.callback(), BoundNetLog());
2035   EXPECT_EQ(ERR_IO_PENDING, rv);
2036
2037   data.RunFor(4);
2038   rv = callback.WaitForResult();
2039   EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv);
2040   data.RunFor(1);
2041 }
2042
2043 // The client upon cancellation tries to send a RST_STREAM frame. The mock
2044 // socket causes the TCP write to return zero. This test checks that the client
2045 // tries to queue up the RST_STREAM frame again.
2046 TEST_P(SpdyNetworkTransactionTest, SocketWriteReturnsZero) {
2047   scoped_ptr<SpdyFrame> req(
2048       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2049   scoped_ptr<SpdyFrame> rst(
2050       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
2051   MockWrite writes[] = {
2052     CreateMockWrite(*req.get(), 0, SYNCHRONOUS),
2053     MockWrite(SYNCHRONOUS, 0, 0, 2),
2054     CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
2055   };
2056
2057   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2058   MockRead reads[] = {
2059     CreateMockRead(*resp.get(), 1, ASYNC),
2060     MockRead(ASYNC, 0, 0, 4)  // EOF
2061   };
2062
2063   DeterministicSocketData data(reads, arraysize(reads),
2064                                writes, arraysize(writes));
2065   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2066                                      BoundNetLog(), GetParam(), NULL);
2067   helper.SetDeterministic();
2068   helper.RunPreTestSetup();
2069   helper.AddDeterministicData(&data);
2070   HttpNetworkTransaction* trans = helper.trans();
2071
2072   TestCompletionCallback callback;
2073   int rv = trans->Start(
2074       &CreateGetRequest(), callback.callback(), BoundNetLog());
2075   EXPECT_EQ(ERR_IO_PENDING, rv);
2076
2077   data.SetStop(2);
2078   data.Run();
2079   helper.ResetTrans();
2080   data.SetStop(20);
2081   data.Run();
2082
2083   helper.VerifyDataConsumed();
2084 }
2085
2086 // Test that the transaction doesn't crash when we don't have a reply.
2087 TEST_P(SpdyNetworkTransactionTest, ResponseWithoutSynReply) {
2088   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2089   MockRead reads[] = {
2090     CreateMockRead(*body),
2091     MockRead(ASYNC, 0, 0)  // EOF
2092   };
2093
2094   DelayedSocketData data(1, reads, arraysize(reads), NULL, 0);
2095   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2096                                      BoundNetLog(), GetParam(), NULL);
2097   helper.RunToCompletion(&data);
2098   TransactionHelperResult out = helper.output();
2099   EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
2100 }
2101
2102 // Test that the transaction doesn't crash when we get two replies on the same
2103 // stream ID. See http://crbug.com/45639.
2104 TEST_P(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) {
2105   scoped_ptr<SpdyFrame> req(
2106       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2107   scoped_ptr<SpdyFrame> rst(
2108       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_STREAM_IN_USE));
2109   MockWrite writes[] = {
2110     CreateMockWrite(*req),
2111     CreateMockWrite(*rst),
2112   };
2113
2114   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2115   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2116   MockRead reads[] = {
2117     CreateMockRead(*resp),
2118     CreateMockRead(*resp),
2119     CreateMockRead(*body),
2120     MockRead(ASYNC, 0, 0)  // EOF
2121   };
2122
2123   DelayedSocketData data(1, reads, arraysize(reads),
2124                          writes, arraysize(writes));
2125
2126   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2127                                      BoundNetLog(), GetParam(), NULL);
2128   helper.RunPreTestSetup();
2129   helper.AddData(&data);
2130
2131   HttpNetworkTransaction* trans = helper.trans();
2132
2133   TestCompletionCallback callback;
2134   int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
2135   EXPECT_EQ(ERR_IO_PENDING, rv);
2136   rv = callback.WaitForResult();
2137   EXPECT_EQ(OK, rv);
2138
2139   const HttpResponseInfo* response = trans->GetResponseInfo();
2140   ASSERT_TRUE(response != NULL);
2141   EXPECT_TRUE(response->headers.get() != NULL);
2142   EXPECT_TRUE(response->was_fetched_via_spdy);
2143   std::string response_data;
2144   rv = ReadTransaction(trans, &response_data);
2145   EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv);
2146
2147   helper.VerifyDataConsumed();
2148 }
2149
2150 TEST_P(SpdyNetworkTransactionTest, ResetReplyWithTransferEncoding) {
2151   // Construct the request.
2152   scoped_ptr<SpdyFrame> req(
2153       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2154   scoped_ptr<SpdyFrame> rst(
2155       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
2156   MockWrite writes[] = {
2157     CreateMockWrite(*req),
2158     CreateMockWrite(*rst),
2159   };
2160
2161   const char* const headers[] = {
2162     "transfer-encoding", "chunked"
2163   };
2164   scoped_ptr<SpdyFrame> resp(
2165       spdy_util_.ConstructSpdyGetSynReply(headers, 1, 1));
2166   scoped_ptr<SpdyFrame> body(
2167       spdy_util_.ConstructSpdyBodyFrame(1, true));
2168   MockRead reads[] = {
2169     CreateMockRead(*resp),
2170     CreateMockRead(*body),
2171     MockRead(ASYNC, 0, 0)  // EOF
2172   };
2173
2174   DelayedSocketData data(1, reads, arraysize(reads),
2175                          writes, arraysize(writes));
2176   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2177                                      BoundNetLog(), GetParam(), NULL);
2178   helper.RunToCompletion(&data);
2179   TransactionHelperResult out = helper.output();
2180   EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
2181
2182   helper.session()->spdy_session_pool()->CloseAllSessions();
2183   helper.VerifyDataConsumed();
2184 }
2185
2186 TEST_P(SpdyNetworkTransactionTest, ResetPushWithTransferEncoding) {
2187   // Construct the request.
2188   scoped_ptr<SpdyFrame> req(
2189       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2190   scoped_ptr<SpdyFrame> rst(
2191       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR));
2192   MockWrite writes[] = {
2193     CreateMockWrite(*req),
2194     CreateMockWrite(*rst),
2195   };
2196
2197   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2198   const char* const headers[] = {
2199     "transfer-encoding", "chunked"
2200   };
2201   scoped_ptr<SpdyFrame> push(
2202       spdy_util_.ConstructSpdyPush(headers, arraysize(headers) / 2,
2203                                    2, 1, "http://www.google.com/1"));
2204   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2205   MockRead reads[] = {
2206     CreateMockRead(*resp),
2207     CreateMockRead(*push),
2208     CreateMockRead(*body),
2209     MockRead(ASYNC, 0, 0)  // EOF
2210   };
2211
2212   DelayedSocketData data(1, reads, arraysize(reads),
2213                          writes, arraysize(writes));
2214   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2215                                      BoundNetLog(), GetParam(), NULL);
2216   helper.RunToCompletion(&data);
2217   TransactionHelperResult out = helper.output();
2218   EXPECT_EQ(OK, out.rv);
2219   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
2220   EXPECT_EQ("hello!", out.response_data);
2221
2222   helper.session()->spdy_session_pool()->CloseAllSessions();
2223   helper.VerifyDataConsumed();
2224 }
2225
2226 TEST_P(SpdyNetworkTransactionTest, CancelledTransaction) {
2227   // Construct the request.
2228   scoped_ptr<SpdyFrame> req(
2229       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2230   MockWrite writes[] = {
2231     CreateMockWrite(*req),
2232   };
2233
2234   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2235   MockRead reads[] = {
2236     CreateMockRead(*resp),
2237     // This following read isn't used by the test, except during the
2238     // RunUntilIdle() call at the end since the SpdySession survives the
2239     // HttpNetworkTransaction and still tries to continue Read()'ing.  Any
2240     // MockRead will do here.
2241     MockRead(ASYNC, 0, 0)  // EOF
2242   };
2243
2244   StaticSocketDataProvider data(reads, arraysize(reads),
2245                                 writes, arraysize(writes));
2246
2247   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2248                                      BoundNetLog(), GetParam(), NULL);
2249   helper.RunPreTestSetup();
2250   helper.AddData(&data);
2251   HttpNetworkTransaction* trans = helper.trans();
2252
2253   TestCompletionCallback callback;
2254   int rv = trans->Start(
2255       &CreateGetRequest(), callback.callback(), BoundNetLog());
2256   EXPECT_EQ(ERR_IO_PENDING, rv);
2257   helper.ResetTrans();  // Cancel the transaction.
2258
2259   // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
2260   // MockClientSocketFactory) are still alive.
2261   base::RunLoop().RunUntilIdle();
2262   helper.VerifyDataNotConsumed();
2263 }
2264
2265 // Verify that the client sends a Rst Frame upon cancelling the stream.
2266 TEST_P(SpdyNetworkTransactionTest, CancelledTransactionSendRst) {
2267   scoped_ptr<SpdyFrame> req(
2268       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2269   scoped_ptr<SpdyFrame> rst(
2270       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
2271   MockWrite writes[] = {
2272     CreateMockWrite(*req, 0, SYNCHRONOUS),
2273     CreateMockWrite(*rst, 2, SYNCHRONOUS),
2274   };
2275
2276   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2277   MockRead reads[] = {
2278     CreateMockRead(*resp, 1, ASYNC),
2279     MockRead(ASYNC, 0, 0, 3)  // EOF
2280   };
2281
2282   DeterministicSocketData data(reads, arraysize(reads),
2283                                writes, arraysize(writes));
2284
2285   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2286                                      BoundNetLog(),
2287                                      GetParam(), NULL);
2288   helper.SetDeterministic();
2289   helper.RunPreTestSetup();
2290   helper.AddDeterministicData(&data);
2291   HttpNetworkTransaction* trans = helper.trans();
2292
2293   TestCompletionCallback callback;
2294
2295   int rv = trans->Start(
2296       &CreateGetRequest(), callback.callback(), BoundNetLog());
2297   EXPECT_EQ(ERR_IO_PENDING, rv);
2298
2299   data.SetStop(2);
2300   data.Run();
2301   helper.ResetTrans();
2302   data.SetStop(20);
2303   data.Run();
2304
2305   helper.VerifyDataConsumed();
2306 }
2307
2308 // Verify that the client can correctly deal with the user callback attempting
2309 // to start another transaction on a session that is closing down. See
2310 // http://crbug.com/47455
2311 TEST_P(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) {
2312   scoped_ptr<SpdyFrame> req(
2313       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2314   MockWrite writes[] = { CreateMockWrite(*req) };
2315   MockWrite writes2[] = { CreateMockWrite(*req) };
2316
2317   // The indicated length of this frame is longer than its actual length. When
2318   // the session receives an empty frame after this one, it shuts down the
2319   // session, and calls the read callback with the incomplete data.
2320   const uint8 kGetBodyFrame2[] = {
2321     0x00, 0x00, 0x00, 0x01,
2322     0x01, 0x00, 0x00, 0x07,
2323     'h', 'e', 'l', 'l', 'o', '!',
2324   };
2325
2326   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2327   MockRead reads[] = {
2328     CreateMockRead(*resp, 2),
2329     MockRead(ASYNC, ERR_IO_PENDING, 3),  // Force a pause
2330     MockRead(ASYNC, reinterpret_cast<const char*>(kGetBodyFrame2),
2331              arraysize(kGetBodyFrame2), 4),
2332     MockRead(ASYNC, ERR_IO_PENDING, 5),  // Force a pause
2333     MockRead(ASYNC, 0, 0, 6),  // EOF
2334   };
2335   MockRead reads2[] = {
2336     CreateMockRead(*resp, 2),
2337     MockRead(ASYNC, 0, 0, 3),  // EOF
2338   };
2339
2340   OrderedSocketData data(reads, arraysize(reads),
2341                          writes, arraysize(writes));
2342   DelayedSocketData data2(1, reads2, arraysize(reads2),
2343                           writes2, arraysize(writes2));
2344
2345   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2346                                      BoundNetLog(), GetParam(), NULL);
2347   helper.RunPreTestSetup();
2348   helper.AddData(&data);
2349   helper.AddData(&data2);
2350   HttpNetworkTransaction* trans = helper.trans();
2351
2352   // Start the transaction with basic parameters.
2353   TestCompletionCallback callback;
2354   int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
2355   EXPECT_EQ(ERR_IO_PENDING, rv);
2356   rv = callback.WaitForResult();
2357
2358   const int kSize = 3000;
2359   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
2360   rv = trans->Read(
2361       buf.get(),
2362       kSize,
2363       base::Bind(&SpdyNetworkTransactionTest::StartTransactionCallback,
2364                  helper.session()));
2365   // This forces an err_IO_pending, which sets the callback.
2366   data.CompleteRead();
2367   // This finishes the read.
2368   data.CompleteRead();
2369   helper.VerifyDataConsumed();
2370 }
2371
2372 // Verify that the client can correctly deal with the user callback deleting the
2373 // transaction. Failures will usually be valgrind errors. See
2374 // http://crbug.com/46925
2375 TEST_P(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) {
2376   scoped_ptr<SpdyFrame> req(
2377       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2378   MockWrite writes[] = { CreateMockWrite(*req) };
2379
2380   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2381   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2382   MockRead reads[] = {
2383     CreateMockRead(*resp.get(), 2),
2384     MockRead(ASYNC, ERR_IO_PENDING, 3),  // Force a pause
2385     CreateMockRead(*body.get(), 4),
2386     MockRead(ASYNC, 0, 0, 5),  // EOF
2387   };
2388
2389   OrderedSocketData data(reads, arraysize(reads),
2390                          writes, arraysize(writes));
2391
2392   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2393                                      BoundNetLog(), GetParam(), NULL);
2394   helper.RunPreTestSetup();
2395   helper.AddData(&data);
2396   HttpNetworkTransaction* trans = helper.trans();
2397
2398   // Start the transaction with basic parameters.
2399   TestCompletionCallback callback;
2400   int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
2401   EXPECT_EQ(ERR_IO_PENDING, rv);
2402   rv = callback.WaitForResult();
2403
2404   // Setup a user callback which will delete the session, and clear out the
2405   // memory holding the stream object. Note that the callback deletes trans.
2406   const int kSize = 3000;
2407   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
2408   rv = trans->Read(
2409       buf.get(),
2410       kSize,
2411       base::Bind(&SpdyNetworkTransactionTest::DeleteSessionCallback,
2412                  base::Unretained(&helper)));
2413   ASSERT_EQ(ERR_IO_PENDING, rv);
2414   data.CompleteRead();
2415
2416   // Finish running rest of tasks.
2417   base::RunLoop().RunUntilIdle();
2418   helper.VerifyDataConsumed();
2419 }
2420
2421 // Send a spdy request to www.google.com that gets redirected to www.foo.com.
2422 TEST_P(SpdyNetworkTransactionTest, RedirectGetRequest) {
2423   const SpdyHeaderInfo kSynStartHeader = spdy_util_.MakeSpdyHeader(SYN_STREAM);
2424   scoped_ptr<SpdyHeaderBlock> headers(
2425       spdy_util_.ConstructGetHeaderBlock("http://www.google.com/"));
2426   (*headers)["user-agent"] = "";
2427   (*headers)["accept-encoding"] = "gzip,deflate";
2428   scoped_ptr<SpdyHeaderBlock> headers2(
2429       spdy_util_.ConstructGetHeaderBlock("http://www.foo.com/index.php"));
2430   (*headers2)["user-agent"] = "";
2431   (*headers2)["accept-encoding"] = "gzip,deflate";
2432
2433   // Setup writes/reads to www.google.com
2434   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyFrame(
2435       kSynStartHeader, headers.Pass()));
2436   scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyFrame(
2437       kSynStartHeader, headers2.Pass()));
2438   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReplyRedirect(1));
2439   MockWrite writes[] = {
2440     CreateMockWrite(*req, 1),
2441   };
2442   MockRead reads[] = {
2443     CreateMockRead(*resp, 2),
2444     MockRead(ASYNC, 0, 0, 3)  // EOF
2445   };
2446
2447   // Setup writes/reads to www.foo.com
2448   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2449   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
2450   MockWrite writes2[] = {
2451     CreateMockWrite(*req2, 1),
2452   };
2453   MockRead reads2[] = {
2454     CreateMockRead(*resp2, 2),
2455     CreateMockRead(*body2, 3),
2456     MockRead(ASYNC, 0, 0, 4)  // EOF
2457   };
2458   OrderedSocketData data(reads, arraysize(reads),
2459                          writes, arraysize(writes));
2460   OrderedSocketData data2(reads2, arraysize(reads2),
2461                           writes2, arraysize(writes2));
2462
2463   // TODO(erikchen): Make test support SPDYSSL, SPDYNPN
2464   HttpStreamFactory::set_force_spdy_over_ssl(false);
2465   HttpStreamFactory::set_force_spdy_always(true);
2466   TestDelegate d;
2467   {
2468     SpdyURLRequestContext spdy_url_request_context(GetParam().protocol);
2469     net::URLRequest r(GURL("http://www.google.com/"),
2470                       DEFAULT_PRIORITY,
2471                       &d,
2472                       &spdy_url_request_context);
2473     spdy_url_request_context.socket_factory().
2474         AddSocketDataProvider(&data);
2475     spdy_url_request_context.socket_factory().
2476         AddSocketDataProvider(&data2);
2477
2478     d.set_quit_on_redirect(true);
2479     r.Start();
2480     base::RunLoop().Run();
2481
2482     EXPECT_EQ(1, d.received_redirect_count());
2483
2484     r.FollowDeferredRedirect();
2485     base::RunLoop().Run();
2486     EXPECT_EQ(1, d.response_started_count());
2487     EXPECT_FALSE(d.received_data_before_response());
2488     EXPECT_EQ(net::URLRequestStatus::SUCCESS, r.status().status());
2489     std::string contents("hello!");
2490     EXPECT_EQ(contents, d.data_received());
2491   }
2492   EXPECT_TRUE(data.at_read_eof());
2493   EXPECT_TRUE(data.at_write_eof());
2494   EXPECT_TRUE(data2.at_read_eof());
2495   EXPECT_TRUE(data2.at_write_eof());
2496 }
2497
2498 // Send a spdy request to www.google.com. Get a pushed stream that redirects to
2499 // www.foo.com.
2500 TEST_P(SpdyNetworkTransactionTest, RedirectServerPush) {
2501   const SpdyHeaderInfo kSynStartHeader = spdy_util_.MakeSpdyHeader(SYN_STREAM);
2502
2503   scoped_ptr<SpdyHeaderBlock> headers(
2504       spdy_util_.ConstructGetHeaderBlock("http://www.google.com/"));
2505   (*headers)["user-agent"] = "";
2506   (*headers)["accept-encoding"] = "gzip,deflate";
2507
2508   // Setup writes/reads to www.google.com
2509   scoped_ptr<SpdyFrame> req(
2510       spdy_util_.ConstructSpdyFrame(kSynStartHeader, headers.Pass()));
2511   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2512   scoped_ptr<SpdyFrame> rep(
2513       spdy_util_.ConstructSpdyPush(NULL,
2514                         0,
2515                         2,
2516                         1,
2517                         "http://www.google.com/foo.dat",
2518                         "301 Moved Permanently",
2519                         "http://www.foo.com/index.php"));
2520   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2521   scoped_ptr<SpdyFrame> rst(
2522       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_CANCEL));
2523   MockWrite writes[] = {
2524     CreateMockWrite(*req, 1),
2525     CreateMockWrite(*rst, 6),
2526   };
2527   MockRead reads[] = {
2528     CreateMockRead(*resp, 2),
2529     CreateMockRead(*rep, 3),
2530     CreateMockRead(*body, 4),
2531     MockRead(ASYNC, ERR_IO_PENDING, 5),  // Force a pause
2532     MockRead(ASYNC, 0, 0, 7)  // EOF
2533   };
2534
2535   // Setup writes/reads to www.foo.com
2536   scoped_ptr<SpdyHeaderBlock> headers2(
2537       spdy_util_.ConstructGetHeaderBlock("http://www.foo.com/index.php"));
2538   (*headers2)["user-agent"] = "";
2539   (*headers2)["accept-encoding"] = "gzip,deflate";
2540   scoped_ptr<SpdyFrame> req2(
2541       spdy_util_.ConstructSpdyFrame(kSynStartHeader, headers2.Pass()));
2542   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2543   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
2544   MockWrite writes2[] = {
2545     CreateMockWrite(*req2, 1),
2546   };
2547   MockRead reads2[] = {
2548     CreateMockRead(*resp2, 2),
2549     CreateMockRead(*body2, 3),
2550     MockRead(ASYNC, 0, 0, 5)  // EOF
2551   };
2552   OrderedSocketData data(reads, arraysize(reads),
2553                          writes, arraysize(writes));
2554   OrderedSocketData data2(reads2, arraysize(reads2),
2555                           writes2, arraysize(writes2));
2556
2557   // TODO(erikchen): Make test support SPDYSSL, SPDYNPN
2558   HttpStreamFactory::set_force_spdy_over_ssl(false);
2559   HttpStreamFactory::set_force_spdy_always(true);
2560   TestDelegate d;
2561   TestDelegate d2;
2562   SpdyURLRequestContext spdy_url_request_context(GetParam().protocol);
2563   {
2564     net::URLRequest r(GURL("http://www.google.com/"),
2565                       DEFAULT_PRIORITY,
2566                       &d,
2567                       &spdy_url_request_context);
2568     spdy_url_request_context.socket_factory().
2569         AddSocketDataProvider(&data);
2570
2571     r.Start();
2572     base::RunLoop().Run();
2573
2574     EXPECT_EQ(0, d.received_redirect_count());
2575     std::string contents("hello!");
2576     EXPECT_EQ(contents, d.data_received());
2577
2578     net::URLRequest r2(GURL("http://www.google.com/foo.dat"),
2579                        DEFAULT_PRIORITY,
2580                        &d2,
2581                        &spdy_url_request_context);
2582     spdy_url_request_context.socket_factory().
2583         AddSocketDataProvider(&data2);
2584
2585     d2.set_quit_on_redirect(true);
2586     r2.Start();
2587     base::RunLoop().Run();
2588     EXPECT_EQ(1, d2.received_redirect_count());
2589
2590     r2.FollowDeferredRedirect();
2591     base::RunLoop().Run();
2592     EXPECT_EQ(1, d2.response_started_count());
2593     EXPECT_FALSE(d2.received_data_before_response());
2594     EXPECT_EQ(net::URLRequestStatus::SUCCESS, r2.status().status());
2595     std::string contents2("hello!");
2596     EXPECT_EQ(contents2, d2.data_received());
2597   }
2598   data.CompleteRead();
2599   data2.CompleteRead();
2600   EXPECT_TRUE(data.at_read_eof());
2601   EXPECT_TRUE(data.at_write_eof());
2602   EXPECT_TRUE(data2.at_read_eof());
2603   EXPECT_TRUE(data2.at_write_eof());
2604 }
2605
2606 TEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame) {
2607   scoped_ptr<SpdyFrame> stream1_syn(
2608       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2609   scoped_ptr<SpdyFrame> stream1_body(
2610       spdy_util_.ConstructSpdyBodyFrame(1, true));
2611   MockWrite writes[] = {
2612     CreateMockWrite(*stream1_syn, 1),
2613   };
2614
2615   scoped_ptr<SpdyFrame>
2616       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2617   scoped_ptr<SpdyFrame>
2618       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
2619                                     0,
2620                                     2,
2621                                     1,
2622                                     "http://www.google.com/foo.dat"));
2623   const char kPushedData[] = "pushed";
2624   scoped_ptr<SpdyFrame> stream2_body(
2625       spdy_util_.ConstructSpdyBodyFrame(
2626           2, kPushedData, strlen(kPushedData), true));
2627   MockRead reads[] = {
2628     CreateMockRead(*stream1_reply, 2),
2629     CreateMockRead(*stream2_syn, 3),
2630     CreateMockRead(*stream1_body, 4, SYNCHRONOUS),
2631     CreateMockRead(*stream2_body, 5),
2632     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
2633   };
2634
2635   HttpResponseInfo response;
2636   HttpResponseInfo response2;
2637   std::string expected_push_result("pushed");
2638   OrderedSocketData data(reads, arraysize(reads),
2639                          writes, arraysize(writes));
2640   RunServerPushTest(&data,
2641                     &response,
2642                     &response2,
2643                     expected_push_result);
2644
2645   // Verify the SYN_REPLY.
2646   EXPECT_TRUE(response.headers.get() != NULL);
2647   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
2648
2649   // Verify the pushed stream.
2650   EXPECT_TRUE(response2.headers.get() != NULL);
2651   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
2652 }
2653
2654 TEST_P(SpdyNetworkTransactionTest, ServerPushBeforeSynReply) {
2655   scoped_ptr<SpdyFrame> stream1_syn(
2656       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2657   scoped_ptr<SpdyFrame> stream1_body(
2658       spdy_util_.ConstructSpdyBodyFrame(1, true));
2659   MockWrite writes[] = {
2660     CreateMockWrite(*stream1_syn, 1),
2661   };
2662
2663   scoped_ptr<SpdyFrame>
2664       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2665   scoped_ptr<SpdyFrame>
2666       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
2667                                     0,
2668                                     2,
2669                                     1,
2670                                     "http://www.google.com/foo.dat"));
2671   const char kPushedData[] = "pushed";
2672   scoped_ptr<SpdyFrame> stream2_body(
2673       spdy_util_.ConstructSpdyBodyFrame(
2674           2, kPushedData, strlen(kPushedData), true));
2675   MockRead reads[] = {
2676     CreateMockRead(*stream2_syn, 2),
2677     CreateMockRead(*stream1_reply, 3),
2678     CreateMockRead(*stream1_body, 4, SYNCHRONOUS),
2679     CreateMockRead(*stream2_body, 5),
2680     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
2681   };
2682
2683   HttpResponseInfo response;
2684   HttpResponseInfo response2;
2685   std::string expected_push_result("pushed");
2686   OrderedSocketData data(reads, arraysize(reads),
2687                          writes, arraysize(writes));
2688   RunServerPushTest(&data,
2689                     &response,
2690                     &response2,
2691                     expected_push_result);
2692
2693   // Verify the SYN_REPLY.
2694   EXPECT_TRUE(response.headers.get() != NULL);
2695   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
2696
2697   // Verify the pushed stream.
2698   EXPECT_TRUE(response2.headers.get() != NULL);
2699   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
2700 }
2701
2702 TEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame2) {
2703   scoped_ptr<SpdyFrame> stream1_syn(
2704       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2705   MockWrite writes[] = { CreateMockWrite(*stream1_syn, 1), };
2706
2707   scoped_ptr<SpdyFrame>
2708       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2709   scoped_ptr<SpdyFrame>
2710       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
2711                                     0,
2712                                     2,
2713                                     1,
2714                                     "http://www.google.com/foo.dat"));
2715   const char kPushedData[] = "pushed";
2716   scoped_ptr<SpdyFrame> stream2_body(
2717       spdy_util_.ConstructSpdyBodyFrame(
2718           2, kPushedData, strlen(kPushedData), true));
2719   scoped_ptr<SpdyFrame>
2720       stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2721   MockRead reads[] = {
2722     CreateMockRead(*stream1_reply, 2),
2723     CreateMockRead(*stream2_syn, 3),
2724     CreateMockRead(*stream2_body, 4),
2725     CreateMockRead(*stream1_body, 5, SYNCHRONOUS),
2726     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
2727   };
2728
2729   HttpResponseInfo response;
2730   HttpResponseInfo response2;
2731   std::string expected_push_result("pushed");
2732   OrderedSocketData data(reads, arraysize(reads),
2733                          writes, arraysize(writes));
2734   RunServerPushTest(&data,
2735                     &response,
2736                     &response2,
2737                     expected_push_result);
2738
2739   // Verify the SYN_REPLY.
2740   EXPECT_TRUE(response.headers.get() != NULL);
2741   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
2742
2743   // Verify the pushed stream.
2744   EXPECT_TRUE(response2.headers.get() != NULL);
2745   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
2746 }
2747
2748 TEST_P(SpdyNetworkTransactionTest, ServerPushServerAborted) {
2749   scoped_ptr<SpdyFrame> stream1_syn(
2750       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2751   scoped_ptr<SpdyFrame> stream1_body(
2752       spdy_util_.ConstructSpdyBodyFrame(1, true));
2753   MockWrite writes[] = {
2754     CreateMockWrite(*stream1_syn, 1),
2755   };
2756
2757   scoped_ptr<SpdyFrame>
2758       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2759   scoped_ptr<SpdyFrame>
2760       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
2761                                     0,
2762                                     2,
2763                                     1,
2764                                     "http://www.google.com/foo.dat"));
2765   scoped_ptr<SpdyFrame> stream2_rst(
2766       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR));
2767   MockRead reads[] = {
2768     CreateMockRead(*stream1_reply, 2),
2769     CreateMockRead(*stream2_syn, 3),
2770     CreateMockRead(*stream2_rst, 4),
2771     CreateMockRead(*stream1_body, 5, SYNCHRONOUS),
2772     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
2773   };
2774
2775   OrderedSocketData data(reads, arraysize(reads),
2776                          writes, arraysize(writes));
2777   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2778                                      BoundNetLog(), GetParam(), NULL);
2779
2780   helper.RunPreTestSetup();
2781   helper.AddData(&data);
2782
2783   HttpNetworkTransaction* trans = helper.trans();
2784
2785   // Start the transaction with basic parameters.
2786   TestCompletionCallback callback;
2787   int rv = trans->Start(
2788       &CreateGetRequest(), callback.callback(), BoundNetLog());
2789   EXPECT_EQ(ERR_IO_PENDING, rv);
2790   rv = callback.WaitForResult();
2791   EXPECT_EQ(OK, rv);
2792
2793   // Verify that we consumed all test data.
2794   EXPECT_TRUE(data.at_read_eof()) << "Read count: "
2795                                    << data.read_count()
2796                                    << " Read index: "
2797                                    << data.read_index();
2798   EXPECT_TRUE(data.at_write_eof()) << "Write count: "
2799                                     << data.write_count()
2800                                     << " Write index: "
2801                                     << data.write_index();
2802
2803   // Verify the SYN_REPLY.
2804   HttpResponseInfo response = *trans->GetResponseInfo();
2805   EXPECT_TRUE(response.headers.get() != NULL);
2806   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
2807 }
2808
2809 // Verify that we don't leak streams and that we properly send a reset
2810 // if the server pushes the same stream twice.
2811 TEST_P(SpdyNetworkTransactionTest, ServerPushDuplicate) {
2812   scoped_ptr<SpdyFrame> stream1_syn(
2813       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2814   scoped_ptr<SpdyFrame> stream1_body(
2815       spdy_util_.ConstructSpdyBodyFrame(1, true));
2816   scoped_ptr<SpdyFrame> stream3_rst(
2817       spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_PROTOCOL_ERROR));
2818   MockWrite writes[] = {
2819     CreateMockWrite(*stream1_syn, 1),
2820     CreateMockWrite(*stream3_rst, 5),
2821   };
2822
2823   scoped_ptr<SpdyFrame>
2824       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2825   scoped_ptr<SpdyFrame>
2826       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
2827                                     0,
2828                                     2,
2829                                     1,
2830                                     "http://www.google.com/foo.dat"));
2831   const char kPushedData[] = "pushed";
2832   scoped_ptr<SpdyFrame> stream2_body(
2833       spdy_util_.ConstructSpdyBodyFrame(
2834           2, kPushedData, strlen(kPushedData), true));
2835   scoped_ptr<SpdyFrame>
2836       stream3_syn(spdy_util_.ConstructSpdyPush(NULL,
2837                                     0,
2838                                     4,
2839                                     1,
2840                                     "http://www.google.com/foo.dat"));
2841   MockRead reads[] = {
2842     CreateMockRead(*stream1_reply, 2),
2843     CreateMockRead(*stream2_syn, 3),
2844     CreateMockRead(*stream3_syn, 4),
2845     CreateMockRead(*stream1_body, 6, SYNCHRONOUS),
2846     CreateMockRead(*stream2_body, 7),
2847     MockRead(ASYNC, ERR_IO_PENDING, 8),  // Force a pause
2848   };
2849
2850   HttpResponseInfo response;
2851   HttpResponseInfo response2;
2852   std::string expected_push_result("pushed");
2853   OrderedSocketData data(reads, arraysize(reads),
2854                          writes, arraysize(writes));
2855   RunServerPushTest(&data,
2856                     &response,
2857                     &response2,
2858                     expected_push_result);
2859
2860   // Verify the SYN_REPLY.
2861   EXPECT_TRUE(response.headers.get() != NULL);
2862   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
2863
2864   // Verify the pushed stream.
2865   EXPECT_TRUE(response2.headers.get() != NULL);
2866   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
2867 }
2868
2869 TEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrame) {
2870   scoped_ptr<SpdyFrame> stream1_syn(
2871       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2872   scoped_ptr<SpdyFrame> stream1_body(
2873       spdy_util_.ConstructSpdyBodyFrame(1, true));
2874   MockWrite writes[] = {
2875     CreateMockWrite(*stream1_syn, 1),
2876   };
2877
2878   scoped_ptr<SpdyFrame>
2879       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2880   scoped_ptr<SpdyFrame>
2881       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
2882                                     0,
2883                                     2,
2884                                     1,
2885                                     "http://www.google.com/foo.dat"));
2886   static const char kPushedData[] = "pushed my darling hello my baby";
2887   scoped_ptr<SpdyFrame> stream2_body_base(
2888       spdy_util_.ConstructSpdyBodyFrame(
2889           2, kPushedData, strlen(kPushedData), true));
2890   const size_t kChunkSize = strlen(kPushedData) / 4;
2891   scoped_ptr<SpdyFrame> stream2_body1(
2892       new SpdyFrame(stream2_body_base->data(), kChunkSize, false));
2893   scoped_ptr<SpdyFrame> stream2_body2(
2894       new SpdyFrame(stream2_body_base->data() + kChunkSize, kChunkSize, false));
2895   scoped_ptr<SpdyFrame> stream2_body3(
2896       new SpdyFrame(stream2_body_base->data() + 2 * kChunkSize,
2897                     kChunkSize, false));
2898   scoped_ptr<SpdyFrame> stream2_body4(
2899       new SpdyFrame(stream2_body_base->data() + 3 * kChunkSize,
2900                     stream2_body_base->size() - 3 * kChunkSize, false));
2901   MockRead reads[] = {
2902     CreateMockRead(*stream1_reply, 2),
2903     CreateMockRead(*stream2_syn, 3),
2904     CreateMockRead(*stream2_body1, 4),
2905     CreateMockRead(*stream2_body2, 5),
2906     CreateMockRead(*stream2_body3, 6),
2907     CreateMockRead(*stream2_body4, 7),
2908     CreateMockRead(*stream1_body, 8, SYNCHRONOUS),
2909     MockRead(ASYNC, ERR_IO_PENDING, 9),  // Force a pause
2910   };
2911
2912   HttpResponseInfo response;
2913   HttpResponseInfo response2;
2914   std::string expected_push_result("pushed my darling hello my baby");
2915   OrderedSocketData data(reads, arraysize(reads),
2916                          writes, arraysize(writes));
2917   RunServerPushTest(&data, &response, &response2, kPushedData);
2918
2919   // Verify the SYN_REPLY.
2920   EXPECT_TRUE(response.headers.get() != NULL);
2921   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
2922
2923   // Verify the pushed stream.
2924   EXPECT_TRUE(response2.headers.get() != NULL);
2925   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
2926 }
2927
2928 TEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrameInterrupted) {
2929   scoped_ptr<SpdyFrame> stream1_syn(
2930       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2931   scoped_ptr<SpdyFrame> stream1_body(
2932       spdy_util_.ConstructSpdyBodyFrame(1, true));
2933   MockWrite writes[] = {
2934     CreateMockWrite(*stream1_syn, 1),
2935   };
2936
2937   scoped_ptr<SpdyFrame>
2938       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2939   scoped_ptr<SpdyFrame>
2940       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
2941                                     0,
2942                                     2,
2943                                     1,
2944                                     "http://www.google.com/foo.dat"));
2945   static const char kPushedData[] = "pushed my darling hello my baby";
2946   scoped_ptr<SpdyFrame> stream2_body_base(
2947       spdy_util_.ConstructSpdyBodyFrame(
2948           2, kPushedData, strlen(kPushedData), true));
2949   const size_t kChunkSize = strlen(kPushedData) / 4;
2950   scoped_ptr<SpdyFrame> stream2_body1(
2951       new SpdyFrame(stream2_body_base->data(), kChunkSize, false));
2952   scoped_ptr<SpdyFrame> stream2_body2(
2953       new SpdyFrame(stream2_body_base->data() + kChunkSize, kChunkSize, false));
2954   scoped_ptr<SpdyFrame> stream2_body3(
2955       new SpdyFrame(stream2_body_base->data() + 2 * kChunkSize,
2956                     kChunkSize, false));
2957   scoped_ptr<SpdyFrame> stream2_body4(
2958       new SpdyFrame(stream2_body_base->data() + 3 * kChunkSize,
2959                     stream2_body_base->size() - 3 * kChunkSize, false));
2960   MockRead reads[] = {
2961     CreateMockRead(*stream1_reply, 2),
2962     CreateMockRead(*stream2_syn, 3),
2963     CreateMockRead(*stream2_body1, 4),
2964     CreateMockRead(*stream2_body2, 5),
2965     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
2966     CreateMockRead(*stream2_body3, 7),
2967     CreateMockRead(*stream2_body4, 8),
2968     CreateMockRead(*stream1_body.get(), 9, SYNCHRONOUS),
2969     MockRead(ASYNC, ERR_IO_PENDING, 10)  // Force a pause.
2970   };
2971
2972   HttpResponseInfo response;
2973   HttpResponseInfo response2;
2974   OrderedSocketData data(reads, arraysize(reads),
2975                          writes, arraysize(writes));
2976   RunServerPushTest(&data, &response, &response2, kPushedData);
2977
2978   // Verify the SYN_REPLY.
2979   EXPECT_TRUE(response.headers.get() != NULL);
2980   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
2981
2982   // Verify the pushed stream.
2983   EXPECT_TRUE(response2.headers.get() != NULL);
2984   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
2985 }
2986
2987 TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID0) {
2988   scoped_ptr<SpdyFrame> stream1_syn(
2989       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2990   scoped_ptr<SpdyFrame> stream1_body(
2991       spdy_util_.ConstructSpdyBodyFrame(1, true));
2992   scoped_ptr<SpdyFrame> stream2_rst(
2993       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
2994   MockWrite writes[] = {
2995     CreateMockWrite(*stream1_syn, 1),
2996     CreateMockWrite(*stream2_rst, 4),
2997   };
2998
2999   scoped_ptr<SpdyFrame>
3000       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3001   scoped_ptr<SpdyFrame>
3002       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
3003                                     0,
3004                                     2,
3005                                     0,
3006                                     "http://www.google.com/foo.dat"));
3007   MockRead reads[] = {
3008     CreateMockRead(*stream1_reply, 2),
3009     CreateMockRead(*stream2_syn, 3),
3010     CreateMockRead(*stream1_body, 4),
3011     MockRead(ASYNC, ERR_IO_PENDING, 5)  // Force a pause
3012   };
3013
3014   OrderedSocketData data(reads, arraysize(reads),
3015                          writes, arraysize(writes));
3016   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3017                                      BoundNetLog(), GetParam(), NULL);
3018
3019   helper.RunPreTestSetup();
3020   helper.AddData(&data);
3021
3022   HttpNetworkTransaction* trans = helper.trans();
3023
3024   // Start the transaction with basic parameters.
3025   TestCompletionCallback callback;
3026   int rv = trans->Start(
3027       &CreateGetRequest(), callback.callback(), BoundNetLog());
3028   EXPECT_EQ(ERR_IO_PENDING, rv);
3029   rv = callback.WaitForResult();
3030   EXPECT_EQ(OK, rv);
3031
3032   // Verify that we consumed all test data.
3033   EXPECT_TRUE(data.at_read_eof()) << "Read count: "
3034                                    << data.read_count()
3035                                    << " Read index: "
3036                                    << data.read_index();
3037   EXPECT_TRUE(data.at_write_eof()) << "Write count: "
3038                                     << data.write_count()
3039                                     << " Write index: "
3040                                     << data.write_index();
3041
3042   // Verify the SYN_REPLY.
3043   HttpResponseInfo response = *trans->GetResponseInfo();
3044   EXPECT_TRUE(response.headers.get() != NULL);
3045   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
3046 }
3047
3048 TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID9) {
3049   scoped_ptr<SpdyFrame> stream1_syn(
3050       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3051   scoped_ptr<SpdyFrame> stream1_body(
3052       spdy_util_.ConstructSpdyBodyFrame(1, true));
3053   scoped_ptr<SpdyFrame> stream2_rst(
3054       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_INVALID_STREAM));
3055   MockWrite writes[] = {
3056     CreateMockWrite(*stream1_syn, 1),
3057     CreateMockWrite(*stream2_rst, 4),
3058   };
3059
3060   scoped_ptr<SpdyFrame>
3061       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3062   scoped_ptr<SpdyFrame>
3063       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
3064                                     0,
3065                                     2,
3066                                     9,
3067                                     "http://www.google.com/foo.dat"));
3068   MockRead reads[] = {
3069     CreateMockRead(*stream1_reply, 2),
3070     CreateMockRead(*stream2_syn, 3),
3071     CreateMockRead(*stream1_body, 4),
3072     MockRead(ASYNC, ERR_IO_PENDING, 5),  // Force a pause
3073   };
3074
3075   OrderedSocketData data(reads, arraysize(reads),
3076                          writes, arraysize(writes));
3077   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3078                                      BoundNetLog(), GetParam(), NULL);
3079
3080   helper.RunPreTestSetup();
3081   helper.AddData(&data);
3082
3083   HttpNetworkTransaction* trans = helper.trans();
3084
3085   // Start the transaction with basic parameters.
3086   TestCompletionCallback callback;
3087   int rv = trans->Start(
3088       &CreateGetRequest(), callback.callback(), BoundNetLog());
3089   EXPECT_EQ(ERR_IO_PENDING, rv);
3090   rv = callback.WaitForResult();
3091   EXPECT_EQ(OK, rv);
3092
3093   // Verify that we consumed all test data.
3094   EXPECT_TRUE(data.at_read_eof()) << "Read count: "
3095                                    << data.read_count()
3096                                    << " Read index: "
3097                                    << data.read_index();
3098   EXPECT_TRUE(data.at_write_eof()) << "Write count: "
3099                                     << data.write_count()
3100                                     << " Write index: "
3101                                     << data.write_index();
3102
3103   // Verify the SYN_REPLY.
3104   HttpResponseInfo response = *trans->GetResponseInfo();
3105   EXPECT_TRUE(response.headers.get() != NULL);
3106   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
3107 }
3108
3109 TEST_P(SpdyNetworkTransactionTest, ServerPushNoURL) {
3110   scoped_ptr<SpdyFrame> stream1_syn(
3111       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3112   scoped_ptr<SpdyFrame> stream1_body(
3113       spdy_util_.ConstructSpdyBodyFrame(1, true));
3114   scoped_ptr<SpdyFrame> stream2_rst(
3115       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR));
3116   MockWrite writes[] = {
3117     CreateMockWrite(*stream1_syn, 1),
3118     CreateMockWrite(*stream2_rst, 4),
3119   };
3120
3121   scoped_ptr<SpdyFrame>
3122       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3123   scoped_ptr<SpdyHeaderBlock> incomplete_headers(new SpdyHeaderBlock());
3124   (*incomplete_headers)["hello"] = "bye";
3125   (*incomplete_headers)[spdy_util_.GetStatusKey()] = "200 OK";
3126   (*incomplete_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
3127   scoped_ptr<SpdyFrame> stream2_syn(
3128       spdy_util_.ConstructSpdyControlFrame(incomplete_headers.Pass(),
3129                                            false,
3130                                            2,  // Stream ID
3131                                            LOWEST,
3132                                            SYN_STREAM,
3133                                            CONTROL_FLAG_NONE,
3134                                            // Associated stream ID
3135                                            1));
3136   MockRead reads[] = {
3137     CreateMockRead(*stream1_reply, 2),
3138     CreateMockRead(*stream2_syn, 3),
3139     CreateMockRead(*stream1_body, 4),
3140     MockRead(ASYNC, ERR_IO_PENDING, 5)  // Force a pause
3141   };
3142
3143   OrderedSocketData data(reads, arraysize(reads),
3144                          writes, arraysize(writes));
3145   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3146                                      BoundNetLog(), GetParam(), NULL);
3147
3148   helper.RunPreTestSetup();
3149   helper.AddData(&data);
3150
3151   HttpNetworkTransaction* trans = helper.trans();
3152
3153   // Start the transaction with basic parameters.
3154   TestCompletionCallback callback;
3155   int rv = trans->Start(
3156       &CreateGetRequest(), callback.callback(), BoundNetLog());
3157   EXPECT_EQ(ERR_IO_PENDING, rv);
3158   rv = callback.WaitForResult();
3159   EXPECT_EQ(OK, rv);
3160   // Verify that we consumed all test data.
3161   EXPECT_TRUE(data.at_read_eof()) << "Read count: "
3162                                    << data.read_count()
3163                                    << " Read index: "
3164                                    << data.read_index();
3165   EXPECT_TRUE(data.at_write_eof()) << "Write count: "
3166                                     << data.write_count()
3167                                     << " Write index: "
3168                                     << data.write_index();
3169
3170   // Verify the SYN_REPLY.
3171   HttpResponseInfo response = *trans->GetResponseInfo();
3172   EXPECT_TRUE(response.headers.get() != NULL);
3173   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
3174 }
3175
3176 // Verify that various SynReply headers parse correctly through the
3177 // HTTP layer.
3178 TEST_P(SpdyNetworkTransactionTest, SynReplyHeaders) {
3179   struct SynReplyHeadersTests {
3180     int num_headers;
3181     const char* extra_headers[5];
3182     SpdyHeaderBlock expected_headers;
3183   } test_cases[] = {
3184     // This uses a multi-valued cookie header.
3185     { 2,
3186       { "cookie", "val1",
3187         "cookie", "val2",  // will get appended separated by NULL
3188         NULL
3189       },
3190     },
3191     // This is the minimalist set of headers.
3192     { 0,
3193       { NULL },
3194     },
3195     // Headers with a comma separated list.
3196     { 1,
3197       { "cookie", "val1,val2",
3198         NULL
3199       },
3200     }
3201   };
3202
3203   test_cases[0].expected_headers["cookie"] = "val1";
3204   test_cases[0].expected_headers["cookie"] += '\0';
3205   test_cases[0].expected_headers["cookie"] += "val2";
3206   test_cases[0].expected_headers["hello"] = "bye";
3207   test_cases[0].expected_headers["status"] = "200";
3208   test_cases[0].expected_headers["version"] = "HTTP/1.1";
3209
3210   test_cases[1].expected_headers["hello"] = "bye";
3211   test_cases[1].expected_headers["status"] = "200";
3212   test_cases[1].expected_headers["version"] = "HTTP/1.1";
3213
3214   test_cases[2].expected_headers["cookie"] = "val1,val2";
3215   test_cases[2].expected_headers["hello"] = "bye";
3216   test_cases[2].expected_headers["status"] = "200";
3217   test_cases[2].expected_headers["version"] = "HTTP/1.1";
3218
3219   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
3220     scoped_ptr<SpdyFrame> req(
3221         spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3222     MockWrite writes[] = { CreateMockWrite(*req) };
3223
3224     scoped_ptr<SpdyFrame> resp(
3225         spdy_util_.ConstructSpdyGetSynReply(test_cases[i].extra_headers,
3226                                  test_cases[i].num_headers,
3227                                  1));
3228     scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3229     MockRead reads[] = {
3230       CreateMockRead(*resp),
3231       CreateMockRead(*body),
3232       MockRead(ASYNC, 0, 0)  // EOF
3233     };
3234
3235     DelayedSocketData data(1, reads, arraysize(reads),
3236                            writes, arraysize(writes));
3237     NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3238                                        BoundNetLog(), GetParam(), NULL);
3239     helper.RunToCompletion(&data);
3240     TransactionHelperResult out = helper.output();
3241
3242     EXPECT_EQ(OK, out.rv);
3243     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
3244     EXPECT_EQ("hello!", out.response_data);
3245
3246     scoped_refptr<HttpResponseHeaders> headers = out.response_info.headers;
3247     EXPECT_TRUE(headers.get() != NULL);
3248     void* iter = NULL;
3249     std::string name, value;
3250     SpdyHeaderBlock header_block;
3251     while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
3252       if (header_block[name].empty()) {
3253         header_block[name] = value;
3254       } else {
3255         header_block[name] += '\0';
3256         header_block[name] += value;
3257       }
3258     }
3259     EXPECT_EQ(test_cases[i].expected_headers, header_block);
3260   }
3261 }
3262
3263 // Verify that various SynReply headers parse vary fields correctly
3264 // through the HTTP layer, and the response matches the request.
3265 TEST_P(SpdyNetworkTransactionTest, SynReplyHeadersVary) {
3266   static const SpdyHeaderInfo syn_reply_info = {
3267     SYN_REPLY,                              // Syn Reply
3268     1,                                      // Stream ID
3269     0,                                      // Associated Stream ID
3270     ConvertRequestPriorityToSpdyPriority(
3271         LOWEST, spdy_util_.spdy_version()),
3272     kSpdyCredentialSlotUnused,
3273     CONTROL_FLAG_NONE,                      // Control Flags
3274     false,                                  // Compressed
3275     RST_STREAM_INVALID,                     // Status
3276     NULL,                                   // Data
3277     0,                                      // Data Length
3278     DATA_FLAG_NONE                          // Data Flags
3279   };
3280   // Modify the following data to change/add test cases:
3281   struct SynReplyTests {
3282     const SpdyHeaderInfo* syn_reply;
3283     bool vary_matches;
3284     int num_headers[2];
3285     const char* extra_headers[2][16];
3286   } test_cases[] = {
3287     // Test the case of a multi-valued cookie.  When the value is delimited
3288     // with NUL characters, it needs to be unfolded into multiple headers.
3289     {
3290       &syn_reply_info,
3291       true,
3292       { 1, 4 },
3293       { { "cookie",   "val1,val2",
3294           NULL
3295         },
3296         { "vary",     "cookie",
3297           spdy_util_.GetStatusKey(), "200",
3298           spdy_util_.GetPathKey(),      "/index.php",
3299           spdy_util_.GetVersionKey(), "HTTP/1.1",
3300           NULL
3301         }
3302       }
3303     }, {    // Multiple vary fields.
3304       &syn_reply_info,
3305       true,
3306       { 2, 5 },
3307       { { "friend",   "barney",
3308           "enemy",    "snaggletooth",
3309           NULL
3310         },
3311         { "vary",     "friend",
3312           "vary",     "enemy",
3313           spdy_util_.GetStatusKey(), "200",
3314           spdy_util_.GetPathKey(),      "/index.php",
3315           spdy_util_.GetVersionKey(), "HTTP/1.1",
3316           NULL
3317         }
3318       }
3319     }, {    // Test a '*' vary field.
3320       &syn_reply_info,
3321       false,
3322       { 1, 4 },
3323       { { "cookie",   "val1,val2",
3324           NULL
3325         },
3326         { "vary",     "*",
3327           spdy_util_.GetStatusKey(), "200",
3328           spdy_util_.GetPathKey(),      "/index.php",
3329           spdy_util_.GetVersionKey(), "HTTP/1.1",
3330           NULL
3331         }
3332       }
3333     }, {    // Multiple comma-separated vary fields.
3334       &syn_reply_info,
3335       true,
3336       { 2, 4 },
3337       { { "friend",   "barney",
3338           "enemy",    "snaggletooth",
3339           NULL
3340         },
3341         { "vary",     "friend,enemy",
3342           spdy_util_.GetStatusKey(), "200",
3343           spdy_util_.GetPathKey(),      "/index.php",
3344           spdy_util_.GetVersionKey(), "HTTP/1.1",
3345           NULL
3346         }
3347       }
3348     }
3349   };
3350
3351   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
3352     // Construct the request.
3353     scoped_ptr<SpdyFrame> frame_req(
3354         spdy_util_.ConstructSpdyGet(test_cases[i].extra_headers[0],
3355                                     test_cases[i].num_headers[0],
3356                                     false, 1, LOWEST, true));
3357
3358     MockWrite writes[] = {
3359       CreateMockWrite(*frame_req),
3360     };
3361
3362     // Construct the reply.
3363     scoped_ptr<SpdyFrame> frame_reply(
3364       spdy_util_.ConstructSpdyFrame(*test_cases[i].syn_reply,
3365                                     test_cases[i].extra_headers[1],
3366                                     test_cases[i].num_headers[1],
3367                                     NULL,
3368                                     0));
3369
3370     scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3371     MockRead reads[] = {
3372       CreateMockRead(*frame_reply),
3373       CreateMockRead(*body),
3374       MockRead(ASYNC, 0, 0)  // EOF
3375     };
3376
3377     // Attach the headers to the request.
3378     int header_count = test_cases[i].num_headers[0];
3379
3380     HttpRequestInfo request = CreateGetRequest();
3381     for (int ct = 0; ct < header_count; ct++) {
3382       const char* header_key = test_cases[i].extra_headers[0][ct * 2];
3383       const char* header_value = test_cases[i].extra_headers[0][ct * 2 + 1];
3384       request.extra_headers.SetHeader(header_key, header_value);
3385     }
3386
3387     DelayedSocketData data(1, reads, arraysize(reads),
3388                            writes, arraysize(writes));
3389     NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
3390                                        BoundNetLog(), GetParam(), NULL);
3391     helper.RunToCompletion(&data);
3392     TransactionHelperResult out = helper.output();
3393
3394     EXPECT_EQ(OK, out.rv) << i;
3395     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line) << i;
3396     EXPECT_EQ("hello!", out.response_data) << i;
3397
3398     // Test the response information.
3399     EXPECT_TRUE(out.response_info.response_time >
3400                 out.response_info.request_time) << i;
3401     base::TimeDelta test_delay = out.response_info.response_time -
3402                                  out.response_info.request_time;
3403     base::TimeDelta min_expected_delay;
3404     min_expected_delay.FromMilliseconds(10);
3405     EXPECT_GT(test_delay.InMillisecondsF(),
3406               min_expected_delay.InMillisecondsF()) << i;
3407     EXPECT_EQ(out.response_info.vary_data.is_valid(),
3408               test_cases[i].vary_matches) << i;
3409
3410     // Check the headers.
3411     scoped_refptr<HttpResponseHeaders> headers = out.response_info.headers;
3412     ASSERT_TRUE(headers.get() != NULL) << i;
3413     void* iter = NULL;
3414     std::string name, value, lines;
3415     while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
3416       lines.append(name);
3417       lines.append(": ");
3418       lines.append(value);
3419       lines.append("\n");
3420     }
3421
3422     // Construct the expected header reply string.
3423     SpdyHeaderBlock reply_headers;
3424     AppendToHeaderBlock(test_cases[i].extra_headers[1],
3425                         test_cases[i].num_headers[1],
3426                         &reply_headers);
3427     std::string expected_reply =
3428         spdy_util_.ConstructSpdyReplyString(reply_headers);
3429     EXPECT_EQ(expected_reply, lines) << i;
3430   }
3431 }
3432
3433 // Verify that we don't crash on invalid SynReply responses.
3434 TEST_P(SpdyNetworkTransactionTest, InvalidSynReply) {
3435   const SpdyHeaderInfo kSynStartHeader = {
3436     SYN_REPLY,              // Kind = SynReply
3437     1,                      // Stream ID
3438     0,                      // Associated stream ID
3439     ConvertRequestPriorityToSpdyPriority(
3440         LOWEST, spdy_util_.spdy_version()),
3441     kSpdyCredentialSlotUnused,
3442     CONTROL_FLAG_NONE,      // Control Flags
3443     false,                  // Compressed
3444     RST_STREAM_INVALID,     // Status
3445     NULL,                   // Data
3446     0,                      // Length
3447     DATA_FLAG_NONE          // Data Flags
3448   };
3449
3450   struct InvalidSynReplyTests {
3451     int num_headers;
3452     const char* headers[10];
3453   } test_cases[] = {
3454     // SYN_REPLY missing status header
3455     { 4,
3456       { "cookie", "val1",
3457         "cookie", "val2",
3458         spdy_util_.GetPathKey(), "/index.php",
3459         spdy_util_.GetVersionKey(), "HTTP/1.1",
3460         NULL
3461       },
3462     },
3463     // SYN_REPLY missing version header
3464     { 2,
3465       { "status", "200",
3466         spdy_util_.GetPathKey(), "/index.php",
3467         NULL
3468       },
3469     },
3470     // SYN_REPLY with no headers
3471     { 0, { NULL }, },
3472   };
3473
3474   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
3475     scoped_ptr<SpdyFrame> req(
3476         spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3477     scoped_ptr<SpdyFrame> rst(
3478       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
3479     MockWrite writes[] = {
3480       CreateMockWrite(*req),
3481       CreateMockWrite(*rst),
3482     };
3483
3484     scoped_ptr<SpdyFrame> resp(
3485        spdy_util_.ConstructSpdyFrame(kSynStartHeader,
3486                                      NULL, 0,
3487                                      test_cases[i].headers,
3488                                      test_cases[i].num_headers));
3489     scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3490     MockRead reads[] = {
3491       CreateMockRead(*resp),
3492       MockRead(ASYNC, 0, 0)  // EOF
3493     };
3494
3495     DelayedSocketData data(1, reads, arraysize(reads),
3496                            writes, arraysize(writes));
3497     NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3498                                        BoundNetLog(), GetParam(), NULL);
3499     helper.RunToCompletion(&data);
3500     TransactionHelperResult out = helper.output();
3501     EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
3502   }
3503 }
3504
3505 // Verify that we don't crash on some corrupt frames.
3506 TEST_P(SpdyNetworkTransactionTest, CorruptFrameSessionError) {
3507   // This is the length field that's too short.
3508   scoped_ptr<SpdyFrame> syn_reply_wrong_length(
3509       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3510   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
3511   size_t right_size =
3512       (spdy_util_.spdy_version() < SPDY4) ?
3513       syn_reply_wrong_length->size() - framer.GetControlFrameHeaderSize() :
3514       syn_reply_wrong_length->size();
3515   size_t wrong_size = right_size - 4;
3516   test::SetFrameLength(syn_reply_wrong_length.get(),
3517                        wrong_size,
3518                        spdy_util_.spdy_version());
3519
3520   struct SynReplyTests {
3521     const SpdyFrame* syn_reply;
3522   } test_cases[] = {
3523     { syn_reply_wrong_length.get(), },
3524   };
3525
3526   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
3527     scoped_ptr<SpdyFrame> req(
3528         spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3529     scoped_ptr<SpdyFrame> rst(
3530         spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
3531     MockWrite writes[] = {
3532       CreateMockWrite(*req),
3533       CreateMockWrite(*rst),
3534     };
3535
3536     scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3537     MockRead reads[] = {
3538       MockRead(ASYNC, test_cases[i].syn_reply->data(), wrong_size),
3539       CreateMockRead(*body),
3540       MockRead(ASYNC, 0, 0)  // EOF
3541     };
3542
3543     DelayedSocketData data(1, reads, arraysize(reads),
3544                            writes, arraysize(writes));
3545     NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3546                                        BoundNetLog(), GetParam(), NULL);
3547     helper.RunToCompletion(&data);
3548     TransactionHelperResult out = helper.output();
3549     EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
3550   }
3551 }
3552
3553 // Test that we shutdown correctly on write errors.
3554 TEST_P(SpdyNetworkTransactionTest, WriteError) {
3555   scoped_ptr<SpdyFrame> req(
3556       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3557   MockWrite writes[] = {
3558     // We'll write 10 bytes successfully
3559     MockWrite(ASYNC, req->data(), 10, 0),
3560     // Followed by ERROR!
3561     MockWrite(ASYNC, ERR_FAILED, 1),
3562   };
3563
3564   MockRead reads[] = {
3565     MockRead(ASYNC, 0, 2)  // EOF
3566   };
3567
3568   DeterministicSocketData data(reads, arraysize(reads),
3569                                writes, arraysize(writes));
3570
3571   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3572                                      BoundNetLog(), GetParam(), NULL);
3573   helper.SetDeterministic();
3574   helper.RunPreTestSetup();
3575   helper.AddDeterministicData(&data);
3576   EXPECT_TRUE(helper.StartDefaultTest());
3577   data.RunFor(2);
3578   helper.FinishDefaultTest();
3579   EXPECT_TRUE(data.at_write_eof());
3580   EXPECT_TRUE(!data.at_read_eof());
3581   TransactionHelperResult out = helper.output();
3582   EXPECT_EQ(ERR_FAILED, out.rv);
3583 }
3584
3585 // Test that partial writes work.
3586 TEST_P(SpdyNetworkTransactionTest, PartialWrite) {
3587   // Chop the SYN_STREAM frame into 5 chunks.
3588   scoped_ptr<SpdyFrame> req(
3589       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3590   const int kChunks = 5;
3591   scoped_ptr<MockWrite[]> writes(ChopWriteFrame(*req.get(), kChunks));
3592
3593   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3594   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3595   MockRead reads[] = {
3596     CreateMockRead(*resp),
3597     CreateMockRead(*body),
3598     MockRead(ASYNC, 0, 0)  // EOF
3599   };
3600
3601   DelayedSocketData data(kChunks, reads, arraysize(reads),
3602                          writes.get(), kChunks);
3603   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3604                                      BoundNetLog(), GetParam(), NULL);
3605   helper.RunToCompletion(&data);
3606   TransactionHelperResult out = helper.output();
3607   EXPECT_EQ(OK, out.rv);
3608   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
3609   EXPECT_EQ("hello!", out.response_data);
3610 }
3611
3612 // In this test, we enable compression, but get a uncompressed SynReply from
3613 // the server.  Verify that teardown is all clean.
3614 TEST_P(SpdyNetworkTransactionTest, DecompressFailureOnSynReply) {
3615   scoped_ptr<SpdyFrame> compressed(
3616       spdy_util_.ConstructSpdyGet(NULL, 0, true, 1, LOWEST, true));
3617   scoped_ptr<SpdyFrame> rst(
3618       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
3619   MockWrite writes[] = {
3620     CreateMockWrite(*compressed),
3621   };
3622
3623   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3624   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3625   MockRead reads[] = {
3626     CreateMockRead(*resp),
3627   };
3628
3629   DelayedSocketData data(1, reads, arraysize(reads),
3630                          writes, arraysize(writes));
3631   SpdySessionDependencies* session_deps =
3632       CreateSpdySessionDependencies(GetParam());
3633   session_deps->enable_compression = true;
3634   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3635                                      BoundNetLog(), GetParam(), session_deps);
3636   helper.RunToCompletion(&data);
3637   TransactionHelperResult out = helper.output();
3638   EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
3639   data.Reset();
3640 }
3641
3642 // Test that the NetLog contains good data for a simple GET request.
3643 TEST_P(SpdyNetworkTransactionTest, NetLog) {
3644   static const char* const kExtraHeaders[] = {
3645     "user-agent",   "Chrome",
3646   };
3647   scoped_ptr<SpdyFrame> req(
3648       spdy_util_.ConstructSpdyGet(kExtraHeaders, 1, false, 1, LOWEST, true));
3649   MockWrite writes[] = { CreateMockWrite(*req) };
3650
3651   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3652   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3653   MockRead reads[] = {
3654     CreateMockRead(*resp),
3655     CreateMockRead(*body),
3656     MockRead(ASYNC, 0, 0)  // EOF
3657   };
3658
3659   CapturingBoundNetLog log;
3660
3661   DelayedSocketData data(1, reads, arraysize(reads),
3662                          writes, arraysize(writes));
3663   NormalSpdyTransactionHelper helper(CreateGetRequestWithUserAgent(),
3664                                      DEFAULT_PRIORITY,
3665                                      log.bound(), GetParam(), NULL);
3666   helper.RunToCompletion(&data);
3667   TransactionHelperResult out = helper.output();
3668   EXPECT_EQ(OK, out.rv);
3669   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
3670   EXPECT_EQ("hello!", out.response_data);
3671
3672   // Check that the NetLog was filled reasonably.
3673   // This test is intentionally non-specific about the exact ordering of the
3674   // log; instead we just check to make sure that certain events exist, and that
3675   // they are in the right order.
3676   net::CapturingNetLog::CapturedEntryList entries;
3677   log.GetEntries(&entries);
3678
3679   EXPECT_LT(0u, entries.size());
3680   int pos = 0;
3681   pos = net::ExpectLogContainsSomewhere(entries, 0,
3682       net::NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST,
3683       net::NetLog::PHASE_BEGIN);
3684   pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
3685       net::NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST,
3686       net::NetLog::PHASE_END);
3687   pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
3688       net::NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS,
3689       net::NetLog::PHASE_BEGIN);
3690   pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
3691       net::NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS,
3692       net::NetLog::PHASE_END);
3693   pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
3694       net::NetLog::TYPE_HTTP_TRANSACTION_READ_BODY,
3695       net::NetLog::PHASE_BEGIN);
3696   pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
3697       net::NetLog::TYPE_HTTP_TRANSACTION_READ_BODY,
3698       net::NetLog::PHASE_END);
3699
3700   // Check that we logged all the headers correctly
3701   pos = net::ExpectLogContainsSomewhere(
3702       entries, 0,
3703       net::NetLog::TYPE_SPDY_SESSION_SYN_STREAM,
3704       net::NetLog::PHASE_NONE);
3705
3706   base::ListValue* header_list;
3707   ASSERT_TRUE(entries[pos].params.get());
3708   ASSERT_TRUE(entries[pos].params->GetList("headers", &header_list));
3709
3710   std::vector<std::string> expected;
3711   expected.push_back(std::string(spdy_util_.GetHostKey()) + ": www.google.com");
3712   expected.push_back(std::string(spdy_util_.GetPathKey()) + ": /");
3713   expected.push_back(std::string(spdy_util_.GetSchemeKey()) + ": http");
3714   expected.push_back(std::string(spdy_util_.GetVersionKey()) + ": HTTP/1.1");
3715   expected.push_back(std::string(spdy_util_.GetMethodKey()) + ": GET");
3716   expected.push_back("user-agent: Chrome");
3717   EXPECT_EQ(expected.size(), header_list->GetSize());
3718   for (std::vector<std::string>::const_iterator it = expected.begin();
3719        it != expected.end();
3720        ++it) {
3721     base::StringValue header(*it);
3722     EXPECT_NE(header_list->end(), header_list->Find(header)) <<
3723         "Header not found: " << *it;
3724   }
3725 }
3726
3727 // Since we buffer the IO from the stream to the renderer, this test verifies
3728 // that when we read out the maximum amount of data (e.g. we received 50 bytes
3729 // on the network, but issued a Read for only 5 of those bytes) that the data
3730 // flow still works correctly.
3731 TEST_P(SpdyNetworkTransactionTest, BufferFull) {
3732   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
3733
3734   scoped_ptr<SpdyFrame> req(
3735       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3736   MockWrite writes[] = { CreateMockWrite(*req) };
3737
3738   // 2 data frames in a single read.
3739   scoped_ptr<SpdyFrame> data_frame_1(
3740       framer.CreateDataFrame(1, "goodby", 6, DATA_FLAG_NONE));
3741   scoped_ptr<SpdyFrame> data_frame_2(
3742       framer.CreateDataFrame(1, "e worl", 6, DATA_FLAG_NONE));
3743   const SpdyFrame* data_frames[2] = {
3744     data_frame_1.get(),
3745     data_frame_2.get(),
3746   };
3747   char combined_data_frames[100];
3748   int combined_data_frames_len =
3749       CombineFrames(data_frames, arraysize(data_frames),
3750                     combined_data_frames, arraysize(combined_data_frames));
3751   scoped_ptr<SpdyFrame> last_frame(
3752       framer.CreateDataFrame(1, "d", 1, DATA_FLAG_FIN));
3753
3754   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3755   MockRead reads[] = {
3756     CreateMockRead(*resp),
3757     MockRead(ASYNC, ERR_IO_PENDING),  // Force a pause
3758     MockRead(ASYNC, combined_data_frames, combined_data_frames_len),
3759     MockRead(ASYNC, ERR_IO_PENDING),  // Force a pause
3760     CreateMockRead(*last_frame),
3761     MockRead(ASYNC, 0, 0)  // EOF
3762   };
3763
3764   DelayedSocketData data(1, reads, arraysize(reads),
3765                          writes, arraysize(writes));
3766
3767   TestCompletionCallback callback;
3768
3769   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3770                                      BoundNetLog(), GetParam(), NULL);
3771   helper.RunPreTestSetup();
3772   helper.AddData(&data);
3773   HttpNetworkTransaction* trans = helper.trans();
3774   int rv = trans->Start(
3775       &CreateGetRequest(), callback.callback(), BoundNetLog());
3776   EXPECT_EQ(ERR_IO_PENDING, rv);
3777
3778   TransactionHelperResult out = helper.output();
3779   out.rv = callback.WaitForResult();
3780   EXPECT_EQ(out.rv, OK);
3781
3782   const HttpResponseInfo* response = trans->GetResponseInfo();
3783   EXPECT_TRUE(response->headers.get() != NULL);
3784   EXPECT_TRUE(response->was_fetched_via_spdy);
3785   out.status_line = response->headers->GetStatusLine();
3786   out.response_info = *response;  // Make a copy so we can verify.
3787
3788   // Read Data
3789   TestCompletionCallback read_callback;
3790
3791   std::string content;
3792   do {
3793     // Read small chunks at a time.
3794     const int kSmallReadSize = 3;
3795     scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize));
3796     rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback());
3797     if (rv == net::ERR_IO_PENDING) {
3798       data.CompleteRead();
3799       rv = read_callback.WaitForResult();
3800     }
3801     if (rv > 0) {
3802       content.append(buf->data(), rv);
3803     } else if (rv < 0) {
3804       NOTREACHED();
3805     }
3806   } while (rv > 0);
3807
3808   out.response_data.swap(content);
3809
3810   // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
3811   // MockClientSocketFactory) are still alive.
3812   base::RunLoop().RunUntilIdle();
3813
3814   // Verify that we consumed all test data.
3815   helper.VerifyDataConsumed();
3816
3817   EXPECT_EQ(OK, out.rv);
3818   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
3819   EXPECT_EQ("goodbye world", out.response_data);
3820 }
3821
3822 // Verify that basic buffering works; when multiple data frames arrive
3823 // at the same time, ensure that we don't notify a read completion for
3824 // each data frame individually.
3825 TEST_P(SpdyNetworkTransactionTest, Buffering) {
3826   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
3827
3828   scoped_ptr<SpdyFrame> req(
3829       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3830   MockWrite writes[] = { CreateMockWrite(*req) };
3831
3832   // 4 data frames in a single read.
3833   scoped_ptr<SpdyFrame> data_frame(
3834       framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
3835   scoped_ptr<SpdyFrame> data_frame_fin(
3836       framer.CreateDataFrame(1, "message", 7, DATA_FLAG_FIN));
3837   const SpdyFrame* data_frames[4] = {
3838     data_frame.get(),
3839     data_frame.get(),
3840     data_frame.get(),
3841     data_frame_fin.get()
3842   };
3843   char combined_data_frames[100];
3844   int combined_data_frames_len =
3845       CombineFrames(data_frames, arraysize(data_frames),
3846                     combined_data_frames, arraysize(combined_data_frames));
3847
3848   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3849   MockRead reads[] = {
3850     CreateMockRead(*resp),
3851     MockRead(ASYNC, ERR_IO_PENDING),  // Force a pause
3852     MockRead(ASYNC, combined_data_frames, combined_data_frames_len),
3853     MockRead(ASYNC, 0, 0)  // EOF
3854   };
3855
3856   DelayedSocketData data(1, reads, arraysize(reads),
3857                          writes, arraysize(writes));
3858
3859   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3860                                      BoundNetLog(), GetParam(), NULL);
3861   helper.RunPreTestSetup();
3862   helper.AddData(&data);
3863   HttpNetworkTransaction* trans = helper.trans();
3864
3865   TestCompletionCallback callback;
3866   int rv = trans->Start(
3867       &CreateGetRequest(), callback.callback(), BoundNetLog());
3868   EXPECT_EQ(ERR_IO_PENDING, rv);
3869
3870   TransactionHelperResult out = helper.output();
3871   out.rv = callback.WaitForResult();
3872   EXPECT_EQ(out.rv, OK);
3873
3874   const HttpResponseInfo* response = trans->GetResponseInfo();
3875   EXPECT_TRUE(response->headers.get() != NULL);
3876   EXPECT_TRUE(response->was_fetched_via_spdy);
3877   out.status_line = response->headers->GetStatusLine();
3878   out.response_info = *response;  // Make a copy so we can verify.
3879
3880   // Read Data
3881   TestCompletionCallback read_callback;
3882
3883   std::string content;
3884   int reads_completed = 0;
3885   do {
3886     // Read small chunks at a time.
3887     const int kSmallReadSize = 14;
3888     scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize));
3889     rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback());
3890     if (rv == net::ERR_IO_PENDING) {
3891       data.CompleteRead();
3892       rv = read_callback.WaitForResult();
3893     }
3894     if (rv > 0) {
3895       EXPECT_EQ(kSmallReadSize, rv);
3896       content.append(buf->data(), rv);
3897     } else if (rv < 0) {
3898       FAIL() << "Unexpected read error: " << rv;
3899     }
3900     reads_completed++;
3901   } while (rv > 0);
3902
3903   EXPECT_EQ(3, reads_completed);  // Reads are: 14 bytes, 14 bytes, 0 bytes.
3904
3905   out.response_data.swap(content);
3906
3907   // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
3908   // MockClientSocketFactory) are still alive.
3909   base::RunLoop().RunUntilIdle();
3910
3911   // Verify that we consumed all test data.
3912   helper.VerifyDataConsumed();
3913
3914   EXPECT_EQ(OK, out.rv);
3915   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
3916   EXPECT_EQ("messagemessagemessagemessage", out.response_data);
3917 }
3918
3919 // Verify the case where we buffer data but read it after it has been buffered.
3920 TEST_P(SpdyNetworkTransactionTest, BufferedAll) {
3921   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
3922
3923   scoped_ptr<SpdyFrame> req(
3924       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3925   MockWrite writes[] = { CreateMockWrite(*req) };
3926
3927   // 5 data frames in a single read.
3928   scoped_ptr<SpdyFrame> syn_reply(
3929       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3930   // turn off FIN bit
3931   test::SetFrameFlags(
3932       syn_reply.get(), CONTROL_FLAG_NONE, spdy_util_.spdy_version());
3933   scoped_ptr<SpdyFrame> data_frame(
3934       framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
3935   scoped_ptr<SpdyFrame> data_frame_fin(
3936       framer.CreateDataFrame(1, "message", 7, DATA_FLAG_FIN));
3937   const SpdyFrame* frames[5] = {
3938     syn_reply.get(),
3939     data_frame.get(),
3940     data_frame.get(),
3941     data_frame.get(),
3942     data_frame_fin.get()
3943   };
3944   char combined_frames[200];
3945   int combined_frames_len =
3946       CombineFrames(frames, arraysize(frames),
3947                     combined_frames, arraysize(combined_frames));
3948
3949   MockRead reads[] = {
3950     MockRead(ASYNC, combined_frames, combined_frames_len),
3951     MockRead(ASYNC, 0, 0)  // EOF
3952   };
3953
3954   DelayedSocketData data(1, reads, arraysize(reads),
3955                          writes, arraysize(writes));
3956
3957   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3958                                      BoundNetLog(), GetParam(), NULL);
3959   helper.RunPreTestSetup();
3960   helper.AddData(&data);
3961   HttpNetworkTransaction* trans = helper.trans();
3962
3963   TestCompletionCallback callback;
3964   int rv = trans->Start(
3965       &CreateGetRequest(), callback.callback(), BoundNetLog());
3966   EXPECT_EQ(ERR_IO_PENDING, rv);
3967
3968   TransactionHelperResult out = helper.output();
3969   out.rv = callback.WaitForResult();
3970   EXPECT_EQ(out.rv, OK);
3971
3972   const HttpResponseInfo* response = trans->GetResponseInfo();
3973   EXPECT_TRUE(response->headers.get() != NULL);
3974   EXPECT_TRUE(response->was_fetched_via_spdy);
3975   out.status_line = response->headers->GetStatusLine();
3976   out.response_info = *response;  // Make a copy so we can verify.
3977
3978   // Read Data
3979   TestCompletionCallback read_callback;
3980
3981   std::string content;
3982   int reads_completed = 0;
3983   do {
3984     // Read small chunks at a time.
3985     const int kSmallReadSize = 14;
3986     scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize));
3987     rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback());
3988     if (rv > 0) {
3989       EXPECT_EQ(kSmallReadSize, rv);
3990       content.append(buf->data(), rv);
3991     } else if (rv < 0) {
3992       FAIL() << "Unexpected read error: " << rv;
3993     }
3994     reads_completed++;
3995   } while (rv > 0);
3996
3997   EXPECT_EQ(3, reads_completed);
3998
3999   out.response_data.swap(content);
4000
4001   // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
4002   // MockClientSocketFactory) are still alive.
4003   base::RunLoop().RunUntilIdle();
4004
4005   // Verify that we consumed all test data.
4006   helper.VerifyDataConsumed();
4007
4008   EXPECT_EQ(OK, out.rv);
4009   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
4010   EXPECT_EQ("messagemessagemessagemessage", out.response_data);
4011 }
4012
4013 // Verify the case where we buffer data and close the connection.
4014 TEST_P(SpdyNetworkTransactionTest, BufferedClosed) {
4015   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
4016
4017   scoped_ptr<SpdyFrame> req(
4018       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4019   MockWrite writes[] = { CreateMockWrite(*req) };
4020
4021   // All data frames in a single read.
4022   // NOTE: We don't FIN the stream.
4023   scoped_ptr<SpdyFrame> data_frame(
4024       framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
4025   const SpdyFrame* data_frames[4] = {
4026     data_frame.get(),
4027     data_frame.get(),
4028     data_frame.get(),
4029     data_frame.get()
4030   };
4031   char combined_data_frames[100];
4032   int combined_data_frames_len =
4033       CombineFrames(data_frames, arraysize(data_frames),
4034                     combined_data_frames, arraysize(combined_data_frames));
4035   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4036   MockRead reads[] = {
4037     CreateMockRead(*resp),
4038     MockRead(ASYNC, ERR_IO_PENDING),  // Force a wait
4039     MockRead(ASYNC, combined_data_frames, combined_data_frames_len),
4040     MockRead(ASYNC, 0, 0)  // EOF
4041   };
4042
4043   DelayedSocketData data(1, reads, arraysize(reads),
4044                          writes, arraysize(writes));
4045
4046   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4047                                      BoundNetLog(), GetParam(), NULL);
4048   helper.RunPreTestSetup();
4049   helper.AddData(&data);
4050   HttpNetworkTransaction* trans = helper.trans();
4051
4052   TestCompletionCallback callback;
4053
4054   int rv = trans->Start(
4055       &CreateGetRequest(), callback.callback(), BoundNetLog());
4056   EXPECT_EQ(ERR_IO_PENDING, rv);
4057
4058   TransactionHelperResult out = helper.output();
4059   out.rv = callback.WaitForResult();
4060   EXPECT_EQ(out.rv, OK);
4061
4062   const HttpResponseInfo* response = trans->GetResponseInfo();
4063   EXPECT_TRUE(response->headers.get() != NULL);
4064   EXPECT_TRUE(response->was_fetched_via_spdy);
4065   out.status_line = response->headers->GetStatusLine();
4066   out.response_info = *response;  // Make a copy so we can verify.
4067
4068   // Read Data
4069   TestCompletionCallback read_callback;
4070
4071   std::string content;
4072   int reads_completed = 0;
4073   do {
4074     // Read small chunks at a time.
4075     const int kSmallReadSize = 14;
4076     scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize));
4077     rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback());
4078     if (rv == net::ERR_IO_PENDING) {
4079       data.CompleteRead();
4080       rv = read_callback.WaitForResult();
4081     }
4082     if (rv > 0) {
4083       content.append(buf->data(), rv);
4084     } else if (rv < 0) {
4085       // This test intentionally closes the connection, and will get an error.
4086       EXPECT_EQ(ERR_CONNECTION_CLOSED, rv);
4087       break;
4088     }
4089     reads_completed++;
4090   } while (rv > 0);
4091
4092   EXPECT_EQ(0, reads_completed);
4093
4094   out.response_data.swap(content);
4095
4096   // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
4097   // MockClientSocketFactory) are still alive.
4098   base::RunLoop().RunUntilIdle();
4099
4100   // Verify that we consumed all test data.
4101   helper.VerifyDataConsumed();
4102 }
4103
4104 // Verify the case where we buffer data and cancel the transaction.
4105 TEST_P(SpdyNetworkTransactionTest, BufferedCancelled) {
4106   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
4107
4108   scoped_ptr<SpdyFrame> req(
4109       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4110   MockWrite writes[] = { CreateMockWrite(*req) };
4111
4112   // NOTE: We don't FIN the stream.
4113   scoped_ptr<SpdyFrame> data_frame(
4114       framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
4115
4116   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4117   MockRead reads[] = {
4118     CreateMockRead(*resp),
4119     MockRead(ASYNC, ERR_IO_PENDING),  // Force a wait
4120     CreateMockRead(*data_frame),
4121     MockRead(ASYNC, 0, 0)  // EOF
4122   };
4123
4124   DelayedSocketData data(1, reads, arraysize(reads),
4125                          writes, arraysize(writes));
4126
4127   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4128                                      BoundNetLog(), GetParam(), NULL);
4129   helper.RunPreTestSetup();
4130   helper.AddData(&data);
4131   HttpNetworkTransaction* trans = helper.trans();
4132   TestCompletionCallback callback;
4133
4134   int rv = trans->Start(
4135       &CreateGetRequest(), callback.callback(), BoundNetLog());
4136   EXPECT_EQ(ERR_IO_PENDING, rv);
4137
4138   TransactionHelperResult out = helper.output();
4139   out.rv = callback.WaitForResult();
4140   EXPECT_EQ(out.rv, OK);
4141
4142   const HttpResponseInfo* response = trans->GetResponseInfo();
4143   EXPECT_TRUE(response->headers.get() != NULL);
4144   EXPECT_TRUE(response->was_fetched_via_spdy);
4145   out.status_line = response->headers->GetStatusLine();
4146   out.response_info = *response;  // Make a copy so we can verify.
4147
4148   // Read Data
4149   TestCompletionCallback read_callback;
4150
4151   do {
4152     const int kReadSize = 256;
4153     scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kReadSize));
4154     rv = trans->Read(buf.get(), kReadSize, read_callback.callback());
4155     if (rv == net::ERR_IO_PENDING) {
4156       // Complete the read now, which causes buffering to start.
4157       data.CompleteRead();
4158       // Destroy the transaction, causing the stream to get cancelled
4159       // and orphaning the buffered IO task.
4160       helper.ResetTrans();
4161       break;
4162     }
4163     // We shouldn't get here in this test.
4164     FAIL() << "Unexpected read: " << rv;
4165   } while (rv > 0);
4166
4167   // Flush the MessageLoop; this will cause the buffered IO task
4168   // to run for the final time.
4169   base::RunLoop().RunUntilIdle();
4170
4171   // Verify that we consumed all test data.
4172   helper.VerifyDataConsumed();
4173 }
4174
4175 // Test that if the server requests persistence of settings, that we save
4176 // the settings in the HttpServerProperties.
4177 TEST_P(SpdyNetworkTransactionTest, SettingsSaved) {
4178   static const SpdyHeaderInfo kSynReplyInfo = {
4179     SYN_REPLY,                              // Syn Reply
4180     1,                                      // Stream ID
4181     0,                                      // Associated Stream ID
4182     ConvertRequestPriorityToSpdyPriority(
4183         LOWEST, spdy_util_.spdy_version()),
4184     kSpdyCredentialSlotUnused,
4185     CONTROL_FLAG_NONE,                      // Control Flags
4186     false,                                  // Compressed
4187     RST_STREAM_INVALID,                     // Status
4188     NULL,                                   // Data
4189     0,                                      // Data Length
4190     DATA_FLAG_NONE                          // Data Flags
4191   };
4192
4193   BoundNetLog net_log;
4194   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4195                                      net_log, GetParam(), NULL);
4196   helper.RunPreTestSetup();
4197
4198   // Verify that no settings exist initially.
4199   HostPortPair host_port_pair("www.google.com", helper.port());
4200   SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
4201   EXPECT_TRUE(spdy_session_pool->http_server_properties()->GetSpdySettings(
4202       host_port_pair).empty());
4203
4204   // Construct the request.
4205   scoped_ptr<SpdyFrame> req(
4206       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4207   MockWrite writes[] = { CreateMockWrite(*req) };
4208
4209   // Construct the reply.
4210   scoped_ptr<SpdyHeaderBlock> reply_headers(new SpdyHeaderBlock());
4211   (*reply_headers)[spdy_util_.GetStatusKey()] = "200";
4212   (*reply_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
4213   scoped_ptr<SpdyFrame> reply(
4214     spdy_util_.ConstructSpdyFrame(kSynReplyInfo, reply_headers.Pass()));
4215
4216   const SpdySettingsIds kSampleId1 = SETTINGS_UPLOAD_BANDWIDTH;
4217   unsigned int kSampleValue1 = 0x0a0a0a0a;
4218   const SpdySettingsIds kSampleId2 = SETTINGS_DOWNLOAD_BANDWIDTH;
4219   unsigned int kSampleValue2 = 0x0b0b0b0b;
4220   const SpdySettingsIds kSampleId3 = SETTINGS_ROUND_TRIP_TIME;
4221   unsigned int kSampleValue3 = 0x0c0c0c0c;
4222   scoped_ptr<SpdyFrame> settings_frame;
4223   {
4224     // Construct the SETTINGS frame.
4225     SettingsMap settings;
4226     // First add a persisted setting.
4227     settings[kSampleId1] =
4228         SettingsFlagsAndValue(SETTINGS_FLAG_PLEASE_PERSIST, kSampleValue1);
4229     // Next add a non-persisted setting.
4230     settings[kSampleId2] =
4231         SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kSampleValue2);
4232     // Next add another persisted setting.
4233     settings[kSampleId3] =
4234         SettingsFlagsAndValue(SETTINGS_FLAG_PLEASE_PERSIST, kSampleValue3);
4235     settings_frame.reset(spdy_util_.ConstructSpdySettings(settings));
4236   }
4237
4238   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
4239   MockRead reads[] = {
4240     CreateMockRead(*reply),
4241     CreateMockRead(*body),
4242     CreateMockRead(*settings_frame),
4243     MockRead(ASYNC, 0, 0)  // EOF
4244   };
4245
4246   DelayedSocketData data(1, reads, arraysize(reads),
4247                          writes, arraysize(writes));
4248   helper.AddData(&data);
4249   helper.RunDefaultTest();
4250   helper.VerifyDataConsumed();
4251   TransactionHelperResult out = helper.output();
4252   EXPECT_EQ(OK, out.rv);
4253   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
4254   EXPECT_EQ("hello!", out.response_data);
4255
4256   {
4257     // Verify we had two persisted settings.
4258     const SettingsMap& settings_map =
4259         spdy_session_pool->http_server_properties()->GetSpdySettings(
4260             host_port_pair);
4261     ASSERT_EQ(2u, settings_map.size());
4262
4263     // Verify the first persisted setting.
4264     SettingsMap::const_iterator it1 = settings_map.find(kSampleId1);
4265     EXPECT_TRUE(it1 != settings_map.end());
4266     SettingsFlagsAndValue flags_and_value1 = it1->second;
4267     EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value1.first);
4268     EXPECT_EQ(kSampleValue1, flags_and_value1.second);
4269
4270     // Verify the second persisted setting.
4271     SettingsMap::const_iterator it3 = settings_map.find(kSampleId3);
4272     EXPECT_TRUE(it3 != settings_map.end());
4273     SettingsFlagsAndValue flags_and_value3 = it3->second;
4274     EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value3.first);
4275     EXPECT_EQ(kSampleValue3, flags_and_value3.second);
4276   }
4277 }
4278
4279 // Test that when there are settings saved that they are sent back to the
4280 // server upon session establishment.
4281 TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) {
4282   static const SpdyHeaderInfo kSynReplyInfo = {
4283     SYN_REPLY,                              // Syn Reply
4284     1,                                      // Stream ID
4285     0,                                      // Associated Stream ID
4286     ConvertRequestPriorityToSpdyPriority(
4287         LOWEST, spdy_util_.spdy_version()),
4288     kSpdyCredentialSlotUnused,
4289     CONTROL_FLAG_NONE,                      // Control Flags
4290     false,                                  // Compressed
4291     RST_STREAM_INVALID,                     // Status
4292     NULL,                                   // Data
4293     0,                                      // Data Length
4294     DATA_FLAG_NONE                          // Data Flags
4295   };
4296
4297   BoundNetLog net_log;
4298   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4299                                      net_log, GetParam(), NULL);
4300   helper.RunPreTestSetup();
4301
4302   SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
4303
4304   SpdySessionPoolPeer pool_peer(spdy_session_pool);
4305   pool_peer.SetEnableSendingInitialData(true);
4306
4307   // Verify that no settings exist initially.
4308   HostPortPair host_port_pair("www.google.com", helper.port());
4309   EXPECT_TRUE(spdy_session_pool->http_server_properties()->GetSpdySettings(
4310       host_port_pair).empty());
4311
4312   const SpdySettingsIds kSampleId1 = SETTINGS_UPLOAD_BANDWIDTH;
4313   unsigned int kSampleValue1 = 0x0a0a0a0a;
4314   const SpdySettingsIds kSampleId2 = SETTINGS_ROUND_TRIP_TIME;
4315   unsigned int kSampleValue2 = 0x0c0c0c0c;
4316
4317   // First add a persisted setting.
4318   spdy_session_pool->http_server_properties()->SetSpdySetting(
4319       host_port_pair,
4320       kSampleId1,
4321       SETTINGS_FLAG_PLEASE_PERSIST,
4322       kSampleValue1);
4323
4324   // Next add another persisted setting.
4325   spdy_session_pool->http_server_properties()->SetSpdySetting(
4326       host_port_pair,
4327       kSampleId2,
4328       SETTINGS_FLAG_PLEASE_PERSIST,
4329       kSampleValue2);
4330
4331   EXPECT_EQ(2u, spdy_session_pool->http_server_properties()->GetSpdySettings(
4332       host_port_pair).size());
4333
4334   // Construct the initial SETTINGS frame.
4335   SettingsMap initial_settings;
4336   initial_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
4337       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams);
4338   scoped_ptr<SpdyFrame> initial_settings_frame(
4339       spdy_util_.ConstructSpdySettings(initial_settings));
4340
4341   // Construct the initial window update.
4342   scoped_ptr<SpdyFrame> initial_window_update(
4343       spdy_util_.ConstructSpdyWindowUpdate(
4344           kSessionFlowControlStreamId,
4345           kDefaultInitialRecvWindowSize - kSpdySessionInitialWindowSize));
4346
4347   // Construct the persisted SETTINGS frame.
4348   const SettingsMap& settings =
4349       spdy_session_pool->http_server_properties()->GetSpdySettings(
4350           host_port_pair);
4351   scoped_ptr<SpdyFrame> settings_frame(
4352       spdy_util_.ConstructSpdySettings(settings));
4353
4354   // Construct the request.
4355   scoped_ptr<SpdyFrame> req(
4356       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4357
4358   std::vector<MockWrite> writes;
4359   if (GetParam().protocol == kProtoHTTP2Draft04) {
4360     writes.push_back(
4361         MockWrite(ASYNC,
4362                   kHttp2ConnectionHeaderPrefix,
4363                   kHttp2ConnectionHeaderPrefixSize));
4364   }
4365   writes.push_back(CreateMockWrite(*initial_settings_frame));
4366   if (GetParam().protocol >= kProtoSPDY31) {
4367     writes.push_back(CreateMockWrite(*initial_window_update));
4368   };
4369   writes.push_back(CreateMockWrite(*settings_frame));
4370   writes.push_back(CreateMockWrite(*req));
4371
4372   // Construct the reply.
4373   scoped_ptr<SpdyHeaderBlock> reply_headers(new SpdyHeaderBlock());
4374   (*reply_headers)[spdy_util_.GetStatusKey()] = "200";
4375   (*reply_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
4376   scoped_ptr<SpdyFrame> reply(
4377     spdy_util_.ConstructSpdyFrame(kSynReplyInfo, reply_headers.Pass()));
4378
4379   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
4380   MockRead reads[] = {
4381     CreateMockRead(*reply),
4382     CreateMockRead(*body),
4383     MockRead(ASYNC, 0, 0)  // EOF
4384   };
4385
4386   DelayedSocketData data(2, reads, arraysize(reads),
4387                          vector_as_array(&writes), writes.size());
4388   helper.AddData(&data);
4389   helper.RunDefaultTest();
4390   helper.VerifyDataConsumed();
4391   TransactionHelperResult out = helper.output();
4392   EXPECT_EQ(OK, out.rv);
4393   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
4394   EXPECT_EQ("hello!", out.response_data);
4395
4396   {
4397     // Verify we had two persisted settings.
4398     const SettingsMap& settings_map =
4399         spdy_session_pool->http_server_properties()->GetSpdySettings(
4400             host_port_pair);
4401     ASSERT_EQ(2u, settings_map.size());
4402
4403     // Verify the first persisted setting.
4404     SettingsMap::const_iterator it1 = settings_map.find(kSampleId1);
4405     EXPECT_TRUE(it1 != settings_map.end());
4406     SettingsFlagsAndValue flags_and_value1 = it1->second;
4407     EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value1.first);
4408     EXPECT_EQ(kSampleValue1, flags_and_value1.second);
4409
4410     // Verify the second persisted setting.
4411     SettingsMap::const_iterator it2 = settings_map.find(kSampleId2);
4412     EXPECT_TRUE(it2 != settings_map.end());
4413     SettingsFlagsAndValue flags_and_value2 = it2->second;
4414     EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value2.first);
4415     EXPECT_EQ(kSampleValue2, flags_and_value2.second);
4416   }
4417 }
4418
4419 TEST_P(SpdyNetworkTransactionTest, GoAwayWithActiveStream) {
4420   scoped_ptr<SpdyFrame> req(
4421       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4422   MockWrite writes[] = { CreateMockWrite(*req) };
4423
4424   scoped_ptr<SpdyFrame> go_away(spdy_util_.ConstructSpdyGoAway());
4425   MockRead reads[] = {
4426     CreateMockRead(*go_away),
4427   };
4428
4429   DelayedSocketData data(1, reads, arraysize(reads),
4430                          writes, arraysize(writes));
4431   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4432                                      BoundNetLog(), GetParam(), NULL);
4433   helper.AddData(&data);
4434   helper.RunToCompletion(&data);
4435   TransactionHelperResult out = helper.output();
4436   EXPECT_EQ(ERR_ABORTED, out.rv);
4437 }
4438
4439 TEST_P(SpdyNetworkTransactionTest, CloseWithActiveStream) {
4440   scoped_ptr<SpdyFrame> req(
4441       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4442   MockWrite writes[] = { CreateMockWrite(*req) };
4443
4444   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4445   MockRead reads[] = {
4446     CreateMockRead(*resp),
4447     MockRead(SYNCHRONOUS, 0, 0)  // EOF
4448   };
4449
4450   DelayedSocketData data(1, reads, arraysize(reads),
4451                          writes, arraysize(writes));
4452   BoundNetLog log;
4453   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4454                                      log, GetParam(), NULL);
4455   helper.RunPreTestSetup();
4456   helper.AddData(&data);
4457   HttpNetworkTransaction* trans = helper.trans();
4458
4459   TestCompletionCallback callback;
4460   TransactionHelperResult out;
4461   out.rv = trans->Start(&CreateGetRequest(), callback.callback(), log);
4462
4463   EXPECT_EQ(out.rv, ERR_IO_PENDING);
4464   out.rv = callback.WaitForResult();
4465   EXPECT_EQ(out.rv, OK);
4466
4467   const HttpResponseInfo* response = trans->GetResponseInfo();
4468   EXPECT_TRUE(response->headers.get() != NULL);
4469   EXPECT_TRUE(response->was_fetched_via_spdy);
4470   out.rv = ReadTransaction(trans, &out.response_data);
4471   EXPECT_EQ(ERR_CONNECTION_CLOSED, out.rv);
4472
4473   // Verify that we consumed all test data.
4474   helper.VerifyDataConsumed();
4475 }
4476
4477 // Test to make sure we can correctly connect through a proxy.
4478 TEST_P(SpdyNetworkTransactionTest, ProxyConnect) {
4479   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4480                                      BoundNetLog(), GetParam(), NULL);
4481   helper.session_deps().reset(CreateSpdySessionDependencies(
4482       GetParam(),
4483       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")));
4484   helper.SetSession(make_scoped_refptr(
4485       SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get())));
4486   helper.RunPreTestSetup();
4487   HttpNetworkTransaction* trans = helper.trans();
4488
4489   const char kConnect443[] = {"CONNECT www.google.com:443 HTTP/1.1\r\n"
4490                            "Host: www.google.com\r\n"
4491                            "Proxy-Connection: keep-alive\r\n\r\n"};
4492   const char kConnect80[] = {"CONNECT www.google.com:80 HTTP/1.1\r\n"
4493                            "Host: www.google.com\r\n"
4494                            "Proxy-Connection: keep-alive\r\n\r\n"};
4495   const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"};
4496   scoped_ptr<SpdyFrame> req(
4497       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4498   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4499   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
4500
4501   MockWrite writes_SPDYNPN[] = {
4502     MockWrite(SYNCHRONOUS, kConnect443, arraysize(kConnect443) - 1, 0),
4503     CreateMockWrite(*req, 2),
4504   };
4505   MockRead reads_SPDYNPN[] = {
4506     MockRead(SYNCHRONOUS, kHTTP200, arraysize(kHTTP200) - 1, 1),
4507     CreateMockRead(*resp, 3),
4508     CreateMockRead(*body.get(), 4),
4509     MockRead(ASYNC, 0, 0, 5),
4510   };
4511
4512   MockWrite writes_SPDYSSL[] = {
4513     MockWrite(SYNCHRONOUS, kConnect80, arraysize(kConnect80) - 1, 0),
4514     CreateMockWrite(*req, 2),
4515   };
4516   MockRead reads_SPDYSSL[] = {
4517     MockRead(SYNCHRONOUS, kHTTP200, arraysize(kHTTP200) - 1, 1),
4518     CreateMockRead(*resp, 3),
4519     CreateMockRead(*body.get(), 4),
4520     MockRead(ASYNC, 0, 0, 5),
4521   };
4522
4523   MockWrite writes_SPDYNOSSL[] = {
4524     CreateMockWrite(*req, 0),
4525   };
4526
4527   MockRead reads_SPDYNOSSL[] = {
4528     CreateMockRead(*resp, 1),
4529     CreateMockRead(*body.get(), 2),
4530     MockRead(ASYNC, 0, 0, 3),
4531   };
4532
4533   scoped_ptr<OrderedSocketData> data;
4534   switch(GetParam().ssl_type) {
4535     case SPDYNOSSL:
4536       data.reset(new OrderedSocketData(reads_SPDYNOSSL,
4537                                        arraysize(reads_SPDYNOSSL),
4538                                        writes_SPDYNOSSL,
4539                                        arraysize(writes_SPDYNOSSL)));
4540       break;
4541     case SPDYSSL:
4542       data.reset(new OrderedSocketData(reads_SPDYSSL,
4543                                        arraysize(reads_SPDYSSL),
4544                                        writes_SPDYSSL,
4545                                        arraysize(writes_SPDYSSL)));
4546       break;
4547     case SPDYNPN:
4548       data.reset(new OrderedSocketData(reads_SPDYNPN,
4549                                        arraysize(reads_SPDYNPN),
4550                                        writes_SPDYNPN,
4551                                        arraysize(writes_SPDYNPN)));
4552       break;
4553     default:
4554       NOTREACHED();
4555   }
4556
4557   helper.AddData(data.get());
4558   TestCompletionCallback callback;
4559
4560   int rv = trans->Start(
4561       &CreateGetRequest(), callback.callback(), BoundNetLog());
4562   EXPECT_EQ(ERR_IO_PENDING, rv);
4563
4564   rv = callback.WaitForResult();
4565   EXPECT_EQ(0, rv);
4566
4567   // Verify the SYN_REPLY.
4568   HttpResponseInfo response = *trans->GetResponseInfo();
4569   EXPECT_TRUE(response.headers.get() != NULL);
4570   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
4571
4572   std::string response_data;
4573   ASSERT_EQ(OK, ReadTransaction(trans, &response_data));
4574   EXPECT_EQ("hello!", response_data);
4575   helper.VerifyDataConsumed();
4576 }
4577
4578 // Test to make sure we can correctly connect through a proxy to www.google.com,
4579 // if there already exists a direct spdy connection to www.google.com. See
4580 // http://crbug.com/49874
4581 TEST_P(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) {
4582   // When setting up the first transaction, we store the SpdySessionPool so that
4583   // we can use the same pool in the second transaction.
4584   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4585                                      BoundNetLog(), GetParam(), NULL);
4586
4587   // Use a proxy service which returns a proxy fallback list from DIRECT to
4588   // myproxy:70. For this test there will be no fallback, so it is equivalent
4589   // to simply DIRECT. The reason for appending the second proxy is to verify
4590   // that the session pool key used does is just "DIRECT".
4591   helper.session_deps().reset(CreateSpdySessionDependencies(
4592       GetParam(),
4593       ProxyService::CreateFixedFromPacResult("DIRECT; PROXY myproxy:70")));
4594   helper.SetSession(make_scoped_refptr(
4595       SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get())));
4596
4597   SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
4598   helper.RunPreTestSetup();
4599
4600   // Construct and send a simple GET request.
4601   scoped_ptr<SpdyFrame> req(
4602       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4603   MockWrite writes[] = {
4604     CreateMockWrite(*req, 1),
4605   };
4606
4607   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4608   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
4609   MockRead reads[] = {
4610     CreateMockRead(*resp, 2),
4611     CreateMockRead(*body, 3),
4612     MockRead(ASYNC, ERR_IO_PENDING, 4),  // Force a pause
4613     MockRead(ASYNC, 0, 5)  // EOF
4614   };
4615   OrderedSocketData data(reads, arraysize(reads),
4616                          writes, arraysize(writes));
4617   helper.AddData(&data);
4618   HttpNetworkTransaction* trans = helper.trans();
4619
4620   TestCompletionCallback callback;
4621   TransactionHelperResult out;
4622   out.rv = trans->Start(
4623       &CreateGetRequest(), callback.callback(), BoundNetLog());
4624
4625   EXPECT_EQ(out.rv, ERR_IO_PENDING);
4626   out.rv = callback.WaitForResult();
4627   EXPECT_EQ(out.rv, OK);
4628
4629   const HttpResponseInfo* response = trans->GetResponseInfo();
4630   EXPECT_TRUE(response->headers.get() != NULL);
4631   EXPECT_TRUE(response->was_fetched_via_spdy);
4632   out.rv = ReadTransaction(trans, &out.response_data);
4633   EXPECT_EQ(OK, out.rv);
4634   out.status_line = response->headers->GetStatusLine();
4635   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
4636   EXPECT_EQ("hello!", out.response_data);
4637
4638   // Check that the SpdySession is still in the SpdySessionPool.
4639   HostPortPair host_port_pair("www.google.com", helper.port());
4640   SpdySessionKey session_pool_key_direct(
4641       host_port_pair, ProxyServer::Direct(), kPrivacyModeDisabled);
4642   EXPECT_TRUE(HasSpdySession(spdy_session_pool, session_pool_key_direct));
4643   SpdySessionKey session_pool_key_proxy(
4644       host_port_pair,
4645       ProxyServer::FromURI("www.foo.com", ProxyServer::SCHEME_HTTP),
4646       kPrivacyModeDisabled);
4647   EXPECT_FALSE(HasSpdySession(spdy_session_pool, session_pool_key_proxy));
4648
4649   // Set up data for the proxy connection.
4650   const char kConnect443[] = {"CONNECT www.google.com:443 HTTP/1.1\r\n"
4651                            "Host: www.google.com\r\n"
4652                            "Proxy-Connection: keep-alive\r\n\r\n"};
4653   const char kConnect80[] = {"CONNECT www.google.com:80 HTTP/1.1\r\n"
4654                            "Host: www.google.com\r\n"
4655                            "Proxy-Connection: keep-alive\r\n\r\n"};
4656   const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"};
4657   scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyGet(
4658       "http://www.google.com/foo.dat", false, 1, LOWEST));
4659   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4660   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
4661
4662   MockWrite writes_SPDYNPN[] = {
4663     MockWrite(SYNCHRONOUS, kConnect443, arraysize(kConnect443) - 1, 0),
4664     CreateMockWrite(*req2, 2),
4665   };
4666   MockRead reads_SPDYNPN[] = {
4667     MockRead(SYNCHRONOUS, kHTTP200, arraysize(kHTTP200) - 1, 1),
4668     CreateMockRead(*resp2, 3),
4669     CreateMockRead(*body2, 4),
4670     MockRead(ASYNC, 0, 5)  // EOF
4671   };
4672
4673   MockWrite writes_SPDYNOSSL[] = {
4674     CreateMockWrite(*req2, 0),
4675   };
4676   MockRead reads_SPDYNOSSL[] = {
4677     CreateMockRead(*resp2, 1),
4678     CreateMockRead(*body2, 2),
4679     MockRead(ASYNC, 0, 3)  // EOF
4680   };
4681
4682   MockWrite writes_SPDYSSL[] = {
4683     MockWrite(SYNCHRONOUS, kConnect80, arraysize(kConnect80) - 1, 0),
4684     CreateMockWrite(*req2, 2),
4685   };
4686   MockRead reads_SPDYSSL[] = {
4687     MockRead(SYNCHRONOUS, kHTTP200, arraysize(kHTTP200) - 1, 1),
4688     CreateMockRead(*resp2, 3),
4689     CreateMockRead(*body2, 4),
4690     MockRead(ASYNC, 0, 0, 5),
4691   };
4692
4693   scoped_ptr<OrderedSocketData> data_proxy;
4694   switch(GetParam().ssl_type) {
4695     case SPDYNPN:
4696       data_proxy.reset(new OrderedSocketData(reads_SPDYNPN,
4697                                              arraysize(reads_SPDYNPN),
4698                                              writes_SPDYNPN,
4699                                              arraysize(writes_SPDYNPN)));
4700       break;
4701     case SPDYNOSSL:
4702       data_proxy.reset(new OrderedSocketData(reads_SPDYNOSSL,
4703                                              arraysize(reads_SPDYNOSSL),
4704                                              writes_SPDYNOSSL,
4705                                              arraysize(writes_SPDYNOSSL)));
4706       break;
4707     case SPDYSSL:
4708       data_proxy.reset(new OrderedSocketData(reads_SPDYSSL,
4709                                              arraysize(reads_SPDYSSL),
4710                                              writes_SPDYSSL,
4711                                              arraysize(writes_SPDYSSL)));
4712       break;
4713     default:
4714       NOTREACHED();
4715   }
4716
4717   // Create another request to www.google.com, but this time through a proxy.
4718   HttpRequestInfo request_proxy;
4719   request_proxy.method = "GET";
4720   request_proxy.url = GURL("http://www.google.com/foo.dat");
4721   request_proxy.load_flags = 0;
4722   scoped_ptr<SpdySessionDependencies> ssd_proxy(
4723       CreateSpdySessionDependencies(GetParam()));
4724   // Ensure that this transaction uses the same SpdySessionPool.
4725   scoped_refptr<HttpNetworkSession> session_proxy(
4726       SpdySessionDependencies::SpdyCreateSession(ssd_proxy.get()));
4727   NormalSpdyTransactionHelper helper_proxy(request_proxy, DEFAULT_PRIORITY,
4728                                            BoundNetLog(), GetParam(), NULL);
4729   HttpNetworkSessionPeer session_peer(session_proxy);
4730   scoped_ptr<net::ProxyService> proxy_service(
4731           ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
4732   session_peer.SetProxyService(proxy_service.get());
4733   helper_proxy.session_deps().swap(ssd_proxy);
4734   helper_proxy.SetSession(session_proxy);
4735   helper_proxy.RunPreTestSetup();
4736   helper_proxy.AddData(data_proxy.get());
4737
4738   HttpNetworkTransaction* trans_proxy = helper_proxy.trans();
4739   TestCompletionCallback callback_proxy;
4740   int rv = trans_proxy->Start(
4741       &request_proxy, callback_proxy.callback(), BoundNetLog());
4742   EXPECT_EQ(ERR_IO_PENDING, rv);
4743   rv = callback_proxy.WaitForResult();
4744   EXPECT_EQ(0, rv);
4745
4746   HttpResponseInfo response_proxy = *trans_proxy->GetResponseInfo();
4747   EXPECT_TRUE(response_proxy.headers.get() != NULL);
4748   EXPECT_EQ("HTTP/1.1 200 OK", response_proxy.headers->GetStatusLine());
4749
4750   std::string response_data;
4751   ASSERT_EQ(OK, ReadTransaction(trans_proxy, &response_data));
4752   EXPECT_EQ("hello!", response_data);
4753
4754   data.CompleteRead();
4755   helper_proxy.VerifyDataConsumed();
4756 }
4757
4758 // When we get a TCP-level RST, we need to retry a HttpNetworkTransaction
4759 // on a new connection, if the connection was previously known to be good.
4760 // This can happen when a server reboots without saying goodbye, or when
4761 // we're behind a NAT that masked the RST.
4762 TEST_P(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) {
4763   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4764   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
4765   MockRead reads[] = {
4766     CreateMockRead(*resp),
4767     CreateMockRead(*body),
4768     MockRead(ASYNC, ERR_IO_PENDING),
4769     MockRead(ASYNC, ERR_CONNECTION_RESET),
4770   };
4771
4772   MockRead reads2[] = {
4773     CreateMockRead(*resp),
4774     CreateMockRead(*body),
4775     MockRead(ASYNC, 0, 0)  // EOF
4776   };
4777
4778   // This test has a couple of variants.
4779   enum {
4780     // Induce the RST while waiting for our transaction to send.
4781     VARIANT_RST_DURING_SEND_COMPLETION,
4782     // Induce the RST while waiting for our transaction to read.
4783     // In this case, the send completed - everything copied into the SNDBUF.
4784     VARIANT_RST_DURING_READ_COMPLETION
4785   };
4786
4787   for (int variant = VARIANT_RST_DURING_SEND_COMPLETION;
4788        variant <= VARIANT_RST_DURING_READ_COMPLETION;
4789        ++variant) {
4790     DelayedSocketData data1(1, reads, arraysize(reads), NULL, 0);
4791
4792     DelayedSocketData data2(1, reads2, arraysize(reads2), NULL, 0);
4793
4794     NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4795                                        BoundNetLog(), GetParam(), NULL);
4796     helper.AddData(&data1);
4797     helper.AddData(&data2);
4798     helper.RunPreTestSetup();
4799
4800     for (int i = 0; i < 2; ++i) {
4801       scoped_ptr<HttpNetworkTransaction> trans(
4802           new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
4803
4804       TestCompletionCallback callback;
4805       int rv = trans->Start(
4806           &helper.request(), callback.callback(), BoundNetLog());
4807       EXPECT_EQ(ERR_IO_PENDING, rv);
4808       // On the second transaction, we trigger the RST.
4809       if (i == 1) {
4810         if (variant == VARIANT_RST_DURING_READ_COMPLETION) {
4811           // Writes to the socket complete asynchronously on SPDY by running
4812           // through the message loop.  Complete the write here.
4813           base::RunLoop().RunUntilIdle();
4814         }
4815
4816         // Now schedule the ERR_CONNECTION_RESET.
4817         EXPECT_EQ(3u, data1.read_index());
4818         data1.CompleteRead();
4819         EXPECT_EQ(4u, data1.read_index());
4820       }
4821       rv = callback.WaitForResult();
4822       EXPECT_EQ(OK, rv);
4823
4824       const HttpResponseInfo* response = trans->GetResponseInfo();
4825       ASSERT_TRUE(response != NULL);
4826       EXPECT_TRUE(response->headers.get() != NULL);
4827       EXPECT_TRUE(response->was_fetched_via_spdy);
4828       std::string response_data;
4829       rv = ReadTransaction(trans.get(), &response_data);
4830       EXPECT_EQ(OK, rv);
4831       EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4832       EXPECT_EQ("hello!", response_data);
4833     }
4834
4835     helper.VerifyDataConsumed();
4836   }
4837 }
4838
4839 // Test that turning SPDY on and off works properly.
4840 TEST_P(SpdyNetworkTransactionTest, SpdyOnOffToggle) {
4841   net::HttpStreamFactory::set_spdy_enabled(true);
4842   scoped_ptr<SpdyFrame> req(
4843       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4844   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
4845
4846   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4847   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
4848   MockRead spdy_reads[] = {
4849     CreateMockRead(*resp),
4850     CreateMockRead(*body),
4851     MockRead(ASYNC, 0, 0)  // EOF
4852   };
4853
4854   DelayedSocketData data(1, spdy_reads, arraysize(spdy_reads),
4855                          spdy_writes, arraysize(spdy_writes));
4856   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4857                                      BoundNetLog(), GetParam(), NULL);
4858   helper.RunToCompletion(&data);
4859   TransactionHelperResult out = helper.output();
4860   EXPECT_EQ(OK, out.rv);
4861   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
4862   EXPECT_EQ("hello!", out.response_data);
4863
4864   net::HttpStreamFactory::set_spdy_enabled(false);
4865   MockRead http_reads[] = {
4866     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
4867     MockRead("hello from http"),
4868     MockRead(SYNCHRONOUS, OK),
4869   };
4870   DelayedSocketData data2(1, http_reads, arraysize(http_reads), NULL, 0);
4871   NormalSpdyTransactionHelper helper2(CreateGetRequest(), DEFAULT_PRIORITY,
4872                                      BoundNetLog(), GetParam(), NULL);
4873   helper2.SetSpdyDisabled();
4874   helper2.RunToCompletion(&data2);
4875   TransactionHelperResult out2 = helper2.output();
4876   EXPECT_EQ(OK, out2.rv);
4877   EXPECT_EQ("HTTP/1.1 200 OK", out2.status_line);
4878   EXPECT_EQ("hello from http", out2.response_data);
4879
4880   net::HttpStreamFactory::set_spdy_enabled(true);
4881 }
4882
4883 // Tests that Basic authentication works over SPDY
4884 TEST_P(SpdyNetworkTransactionTest, SpdyBasicAuth) {
4885   net::HttpStreamFactory::set_spdy_enabled(true);
4886
4887   // The first request will be a bare GET, the second request will be a
4888   // GET with an Authorization header.
4889   scoped_ptr<SpdyFrame> req_get(
4890       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4891   const char* const kExtraAuthorizationHeaders[] = {
4892     "authorization", "Basic Zm9vOmJhcg=="
4893   };
4894   scoped_ptr<SpdyFrame> req_get_authorization(
4895       spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
4896                                   arraysize(kExtraAuthorizationHeaders) / 2,
4897                                   false, 3, LOWEST, true));
4898   MockWrite spdy_writes[] = {
4899     CreateMockWrite(*req_get, 1),
4900     CreateMockWrite(*req_get_authorization, 4),
4901   };
4902
4903   // The first response is a 401 authentication challenge, and the second
4904   // response will be a 200 response since the second request includes a valid
4905   // Authorization header.
4906   const char* const kExtraAuthenticationHeaders[] = {
4907     "www-authenticate",
4908     "Basic realm=\"MyRealm\""
4909   };
4910   scoped_ptr<SpdyFrame> resp_authentication(
4911       spdy_util_.ConstructSpdySynReplyError(
4912           "401 Authentication Required",
4913           kExtraAuthenticationHeaders,
4914           arraysize(kExtraAuthenticationHeaders) / 2,
4915           1));
4916   scoped_ptr<SpdyFrame> body_authentication(
4917       spdy_util_.ConstructSpdyBodyFrame(1, true));
4918   scoped_ptr<SpdyFrame> resp_data(
4919       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
4920   scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
4921   MockRead spdy_reads[] = {
4922     CreateMockRead(*resp_authentication, 2),
4923     CreateMockRead(*body_authentication, 3),
4924     CreateMockRead(*resp_data, 5),
4925     CreateMockRead(*body_data, 6),
4926     MockRead(ASYNC, 0, 7),
4927   };
4928
4929   OrderedSocketData data(spdy_reads, arraysize(spdy_reads),
4930                          spdy_writes, arraysize(spdy_writes));
4931   HttpRequestInfo request(CreateGetRequest());
4932   BoundNetLog net_log;
4933   NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
4934                                      net_log, GetParam(), NULL);
4935
4936   helper.RunPreTestSetup();
4937   helper.AddData(&data);
4938   HttpNetworkTransaction* trans = helper.trans();
4939   TestCompletionCallback callback;
4940   const int rv_start = trans->Start(&request, callback.callback(), net_log);
4941   EXPECT_EQ(ERR_IO_PENDING, rv_start);
4942   const int rv_start_complete = callback.WaitForResult();
4943   EXPECT_EQ(OK, rv_start_complete);
4944
4945   // Make sure the response has an auth challenge.
4946   const HttpResponseInfo* const response_start = trans->GetResponseInfo();
4947   ASSERT_TRUE(response_start != NULL);
4948   ASSERT_TRUE(response_start->headers.get() != NULL);
4949   EXPECT_EQ(401, response_start->headers->response_code());
4950   EXPECT_TRUE(response_start->was_fetched_via_spdy);
4951   AuthChallengeInfo* auth_challenge = response_start->auth_challenge.get();
4952   ASSERT_TRUE(auth_challenge != NULL);
4953   EXPECT_FALSE(auth_challenge->is_proxy);
4954   EXPECT_EQ("basic", auth_challenge->scheme);
4955   EXPECT_EQ("MyRealm", auth_challenge->realm);
4956
4957   // Restart with a username/password.
4958   AuthCredentials credentials(ASCIIToUTF16("foo"), ASCIIToUTF16("bar"));
4959   TestCompletionCallback callback_restart;
4960   const int rv_restart = trans->RestartWithAuth(
4961       credentials, callback_restart.callback());
4962   EXPECT_EQ(ERR_IO_PENDING, rv_restart);
4963   const int rv_restart_complete = callback_restart.WaitForResult();
4964   EXPECT_EQ(OK, rv_restart_complete);
4965   // TODO(cbentzel): This is actually the same response object as before, but
4966   // data has changed.
4967   const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
4968   ASSERT_TRUE(response_restart != NULL);
4969   ASSERT_TRUE(response_restart->headers.get() != NULL);
4970   EXPECT_EQ(200, response_restart->headers->response_code());
4971   EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
4972 }
4973
4974 TEST_P(SpdyNetworkTransactionTest, ServerPushWithHeaders) {
4975   scoped_ptr<SpdyFrame> stream1_syn(
4976       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4977   scoped_ptr<SpdyFrame> stream1_body(
4978       spdy_util_.ConstructSpdyBodyFrame(1, true));
4979   MockWrite writes[] = {
4980     CreateMockWrite(*stream1_syn, 1),
4981   };
4982
4983   scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
4984   spdy_util_.AddUrlToHeaderBlock(
4985       "http://www.google.com/foo.dat", initial_headers.get());
4986   scoped_ptr<SpdyFrame> stream2_syn(
4987       spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(),
4988                                            false,
4989                                            2,
4990                                            LOWEST,
4991                                            SYN_STREAM,
4992                                            CONTROL_FLAG_NONE,
4993                                            1));
4994
4995   scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
4996   (*late_headers)["hello"] = "bye";
4997   (*late_headers)[spdy_util_.GetStatusKey()] = "200";
4998   (*late_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
4999   scoped_ptr<SpdyFrame> stream2_headers(
5000       spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
5001                                            false,
5002                                            2,
5003                                            LOWEST,
5004                                            HEADERS,
5005                                            CONTROL_FLAG_NONE,
5006                                            0));
5007
5008   scoped_ptr<SpdyFrame>
5009       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5010   const char kPushedData[] = "pushed";
5011   scoped_ptr<SpdyFrame> stream2_body(
5012       spdy_util_.ConstructSpdyBodyFrame(
5013           2, kPushedData, strlen(kPushedData), true));
5014   MockRead reads[] = {
5015     CreateMockRead(*stream1_reply, 2),
5016     CreateMockRead(*stream2_syn, 3),
5017     CreateMockRead(*stream2_headers, 4),
5018     CreateMockRead(*stream1_body, 5, SYNCHRONOUS),
5019     CreateMockRead(*stream2_body, 5),
5020     MockRead(ASYNC, ERR_IO_PENDING, 7),  // Force a pause
5021   };
5022
5023   HttpResponseInfo response;
5024   HttpResponseInfo response2;
5025   std::string expected_push_result("pushed");
5026   OrderedSocketData data(reads, arraysize(reads),
5027                          writes, arraysize(writes));
5028   RunServerPushTest(&data,
5029                     &response,
5030                     &response2,
5031                     expected_push_result);
5032
5033   // Verify the SYN_REPLY.
5034   EXPECT_TRUE(response.headers.get() != NULL);
5035   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
5036
5037   // Verify the pushed stream.
5038   EXPECT_TRUE(response2.headers.get() != NULL);
5039   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
5040 }
5041
5042 TEST_P(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) {
5043   // We push a stream and attempt to claim it before the headers come down.
5044   scoped_ptr<SpdyFrame> stream1_syn(
5045       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5046   scoped_ptr<SpdyFrame> stream1_body(
5047       spdy_util_.ConstructSpdyBodyFrame(1, true));
5048   MockWrite writes[] = {
5049     CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS),
5050   };
5051
5052   scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
5053   spdy_util_.AddUrlToHeaderBlock(
5054       "http://www.google.com/foo.dat", initial_headers.get());
5055   scoped_ptr<SpdyFrame> stream2_syn(
5056       spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(),
5057                                            false,
5058                                            2,
5059                                            LOWEST,
5060                                            SYN_STREAM,
5061                                            CONTROL_FLAG_NONE,
5062                                            1));
5063
5064   scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
5065   (*late_headers)["hello"] = "bye";
5066   (*late_headers)[spdy_util_.GetStatusKey()] = "200";
5067   (*late_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
5068   scoped_ptr<SpdyFrame> stream2_headers(
5069       spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
5070                                            false,
5071                                            2,
5072                                            LOWEST,
5073                                            HEADERS,
5074                                            CONTROL_FLAG_NONE,
5075                                            0));
5076
5077   scoped_ptr<SpdyFrame>
5078       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5079   const char kPushedData[] = "pushed";
5080   scoped_ptr<SpdyFrame> stream2_body(
5081       spdy_util_.ConstructSpdyBodyFrame(
5082           2, kPushedData, strlen(kPushedData), true));
5083   MockRead reads[] = {
5084     CreateMockRead(*stream1_reply, 1),
5085     CreateMockRead(*stream2_syn, 2),
5086     CreateMockRead(*stream1_body, 3),
5087     CreateMockRead(*stream2_headers, 4),
5088     CreateMockRead(*stream2_body, 5),
5089     MockRead(ASYNC, 0, 6),  // EOF
5090   };
5091
5092   HttpResponseInfo response;
5093   HttpResponseInfo response2;
5094   std::string expected_push_result("pushed");
5095   DeterministicSocketData data(reads, arraysize(reads),
5096                                writes, arraysize(writes));
5097
5098   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5099                                      BoundNetLog(), GetParam(), NULL);
5100   helper.SetDeterministic();
5101   helper.AddDeterministicData(&data);
5102   helper.RunPreTestSetup();
5103
5104   HttpNetworkTransaction* trans = helper.trans();
5105
5106   // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
5107   // and the body of the primary stream, but before we've received the HEADERS
5108   // for the pushed stream.
5109   data.SetStop(3);
5110
5111   // Start the transaction.
5112   TestCompletionCallback callback;
5113   int rv = trans->Start(
5114       &CreateGetRequest(), callback.callback(), BoundNetLog());
5115   EXPECT_EQ(ERR_IO_PENDING, rv);
5116   data.Run();
5117   rv = callback.WaitForResult();
5118   EXPECT_EQ(0, rv);
5119
5120   // Request the pushed path.  At this point, we've received the push, but the
5121   // headers are not yet complete.
5122   scoped_ptr<HttpNetworkTransaction> trans2(
5123       new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
5124   rv = trans2->Start(
5125       &CreateGetPushRequest(), callback.callback(), BoundNetLog());
5126   EXPECT_EQ(ERR_IO_PENDING, rv);
5127   data.RunFor(3);
5128   base::RunLoop().RunUntilIdle();
5129
5130   // Read the server push body.
5131   std::string result2;
5132   ReadResult(trans2.get(), &data, &result2);
5133   // Read the response body.
5134   std::string result;
5135   ReadResult(trans, &data, &result);
5136
5137   // Verify that the received push data is same as the expected push data.
5138   EXPECT_EQ(result2.compare(expected_push_result), 0)
5139       << "Received data: "
5140       << result2
5141       << "||||| Expected data: "
5142       << expected_push_result;
5143
5144   // Verify the SYN_REPLY.
5145   // Copy the response info, because trans goes away.
5146   response = *trans->GetResponseInfo();
5147   response2 = *trans2->GetResponseInfo();
5148
5149   VerifyStreamsClosed(helper);
5150
5151   // Verify the SYN_REPLY.
5152   EXPECT_TRUE(response.headers.get() != NULL);
5153   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
5154
5155   // Verify the pushed stream.
5156   EXPECT_TRUE(response2.headers.get() != NULL);
5157   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
5158
5159   // Read the final EOF (which will close the session)
5160   data.RunFor(1);
5161
5162   // Verify that we consumed all test data.
5163   EXPECT_TRUE(data.at_read_eof());
5164   EXPECT_TRUE(data.at_write_eof());
5165 }
5166
5167 TEST_P(SpdyNetworkTransactionTest, ServerPushWithTwoHeaderFrames) {
5168   // We push a stream and attempt to claim it before the headers come down.
5169   scoped_ptr<SpdyFrame> stream1_syn(
5170       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5171   scoped_ptr<SpdyFrame> stream1_body(
5172       spdy_util_.ConstructSpdyBodyFrame(1, true));
5173   MockWrite writes[] = {
5174     CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS),
5175   };
5176
5177   scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
5178   spdy_util_.AddUrlToHeaderBlock(
5179       "http://www.google.com/foo.dat", initial_headers.get());
5180   scoped_ptr<SpdyFrame> stream2_syn(
5181       spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(),
5182                                            false,
5183                                            2,
5184                                            LOWEST,
5185                                            SYN_STREAM,
5186                                            CONTROL_FLAG_NONE,
5187                                            1));
5188
5189   scoped_ptr<SpdyHeaderBlock> middle_headers(new SpdyHeaderBlock());
5190   (*middle_headers)["hello"] = "bye";
5191   scoped_ptr<SpdyFrame> stream2_headers1(
5192       spdy_util_.ConstructSpdyControlFrame(middle_headers.Pass(),
5193                                            false,
5194                                            2,
5195                                            LOWEST,
5196                                            HEADERS,
5197                                            CONTROL_FLAG_NONE,
5198                                            0));
5199
5200   scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
5201   (*late_headers)[spdy_util_.GetStatusKey()] = "200";
5202   (*late_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
5203   scoped_ptr<SpdyFrame> stream2_headers2(
5204       spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
5205                                            false,
5206                                            2,
5207                                            LOWEST,
5208                                            HEADERS,
5209                                            CONTROL_FLAG_NONE,
5210                                            0));
5211
5212   scoped_ptr<SpdyFrame>
5213       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5214   const char kPushedData[] = "pushed";
5215   scoped_ptr<SpdyFrame> stream2_body(
5216       spdy_util_.ConstructSpdyBodyFrame(
5217           2, kPushedData, strlen(kPushedData), true));
5218   MockRead reads[] = {
5219     CreateMockRead(*stream1_reply, 1),
5220     CreateMockRead(*stream2_syn, 2),
5221     CreateMockRead(*stream1_body, 3),
5222     CreateMockRead(*stream2_headers1, 4),
5223     CreateMockRead(*stream2_headers2, 5),
5224     CreateMockRead(*stream2_body, 6),
5225     MockRead(ASYNC, 0, 7),  // EOF
5226   };
5227
5228   HttpResponseInfo response;
5229   HttpResponseInfo response2;
5230   std::string expected_push_result("pushed");
5231   DeterministicSocketData data(reads, arraysize(reads),
5232                                writes, arraysize(writes));
5233
5234   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5235                                      BoundNetLog(), GetParam(), NULL);
5236   helper.SetDeterministic();
5237   helper.AddDeterministicData(&data);
5238   helper.RunPreTestSetup();
5239
5240   HttpNetworkTransaction* trans = helper.trans();
5241
5242   // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
5243   // the first HEADERS frame, and the body of the primary stream, but before
5244   // we've received the final HEADERS for the pushed stream.
5245   data.SetStop(4);
5246
5247   // Start the transaction.
5248   TestCompletionCallback callback;
5249   int rv = trans->Start(
5250       &CreateGetRequest(), callback.callback(), BoundNetLog());
5251   EXPECT_EQ(ERR_IO_PENDING, rv);
5252   data.Run();
5253   rv = callback.WaitForResult();
5254   EXPECT_EQ(0, rv);
5255
5256   // Request the pushed path.  At this point, we've received the push, but the
5257   // headers are not yet complete.
5258   scoped_ptr<HttpNetworkTransaction> trans2(
5259       new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
5260   rv = trans2->Start(
5261       &CreateGetPushRequest(), callback.callback(), BoundNetLog());
5262   EXPECT_EQ(ERR_IO_PENDING, rv);
5263   data.RunFor(3);
5264   base::RunLoop().RunUntilIdle();
5265
5266   // Read the server push body.
5267   std::string result2;
5268   ReadResult(trans2.get(), &data, &result2);
5269   // Read the response body.
5270   std::string result;
5271   ReadResult(trans, &data, &result);
5272
5273   // Verify that the received push data is same as the expected push data.
5274   EXPECT_EQ(expected_push_result, result2);
5275
5276   // Verify the SYN_REPLY.
5277   // Copy the response info, because trans goes away.
5278   response = *trans->GetResponseInfo();
5279   response2 = *trans2->GetResponseInfo();
5280
5281   VerifyStreamsClosed(helper);
5282
5283   // Verify the SYN_REPLY.
5284   EXPECT_TRUE(response.headers.get() != NULL);
5285   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
5286
5287   // Verify the pushed stream.
5288   EXPECT_TRUE(response2.headers.get() != NULL);
5289   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
5290
5291   // Verify we got all the headers
5292   if (spdy_util_.spdy_version() < SPDY3) {
5293     EXPECT_TRUE(response2.headers->HasHeaderValue(
5294         "url",
5295         "http://www.google.com/foo.dat"));
5296   } else {
5297     EXPECT_TRUE(response2.headers->HasHeaderValue(
5298         "scheme", "http"));
5299     EXPECT_TRUE(response2.headers->HasHeaderValue(
5300         "host", "www.google.com"));
5301     EXPECT_TRUE(response2.headers->HasHeaderValue(
5302         "path", "/foo.dat"));
5303   }
5304   EXPECT_TRUE(response2.headers->HasHeaderValue("hello", "bye"));
5305   EXPECT_TRUE(response2.headers->HasHeaderValue("status", "200"));
5306   EXPECT_TRUE(response2.headers->HasHeaderValue("version", "HTTP/1.1"));
5307
5308   // Read the final EOF (which will close the session)
5309   data.RunFor(1);
5310
5311   // Verify that we consumed all test data.
5312   EXPECT_TRUE(data.at_read_eof());
5313   EXPECT_TRUE(data.at_write_eof());
5314 }
5315
5316 TEST_P(SpdyNetworkTransactionTest, ServerPushWithNoStatusHeaderFrames) {
5317   // We push a stream and attempt to claim it before the headers come down.
5318   scoped_ptr<SpdyFrame> stream1_syn(
5319       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5320   scoped_ptr<SpdyFrame> stream1_body(
5321       spdy_util_.ConstructSpdyBodyFrame(1, true));
5322   MockWrite writes[] = {
5323     CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS),
5324   };
5325
5326   scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
5327   spdy_util_.AddUrlToHeaderBlock(
5328       "http://www.google.com/foo.dat", initial_headers.get());
5329   scoped_ptr<SpdyFrame> stream2_syn(
5330       spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(),
5331                                            false,
5332                                            2,
5333                                            LOWEST,
5334                                            SYN_STREAM,
5335                                            CONTROL_FLAG_NONE,
5336                                            1));
5337
5338   scoped_ptr<SpdyHeaderBlock> middle_headers(new SpdyHeaderBlock());
5339   (*middle_headers)["hello"] = "bye";
5340   scoped_ptr<SpdyFrame> stream2_headers1(
5341       spdy_util_.ConstructSpdyControlFrame(middle_headers.Pass(),
5342                                            false,
5343                                            2,
5344                                            LOWEST,
5345                                            HEADERS,
5346                                            CONTROL_FLAG_NONE,
5347                                            0));
5348
5349   scoped_ptr<SpdyFrame>
5350       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5351   const char kPushedData[] = "pushed";
5352   scoped_ptr<SpdyFrame> stream2_body(
5353       spdy_util_.ConstructSpdyBodyFrame(
5354           2, kPushedData, strlen(kPushedData), true));
5355   MockRead reads[] = {
5356     CreateMockRead(*stream1_reply, 1),
5357     CreateMockRead(*stream2_syn, 2),
5358     CreateMockRead(*stream1_body, 3),
5359     CreateMockRead(*stream2_headers1, 4),
5360     CreateMockRead(*stream2_body, 5),
5361     MockRead(ASYNC, 0, 6),  // EOF
5362   };
5363
5364   DeterministicSocketData data(reads, arraysize(reads),
5365                                writes, arraysize(writes));
5366
5367   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5368                                      BoundNetLog(), GetParam(), NULL);
5369   helper.SetDeterministic();
5370   helper.AddDeterministicData(&data);
5371   helper.RunPreTestSetup();
5372
5373   HttpNetworkTransaction* trans = helper.trans();
5374
5375   // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
5376   // the first HEADERS frame, and the body of the primary stream, but before
5377   // we've received the final HEADERS for the pushed stream.
5378   data.SetStop(4);
5379
5380   // Start the transaction.
5381   TestCompletionCallback callback;
5382   int rv = trans->Start(
5383       &CreateGetRequest(), callback.callback(), BoundNetLog());
5384   EXPECT_EQ(ERR_IO_PENDING, rv);
5385   data.Run();
5386   rv = callback.WaitForResult();
5387   EXPECT_EQ(0, rv);
5388
5389   // Request the pushed path.  At this point, we've received the push, but the
5390   // headers are not yet complete.
5391   scoped_ptr<HttpNetworkTransaction> trans2(
5392       new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
5393   rv = trans2->Start(
5394       &CreateGetPushRequest(), callback.callback(), BoundNetLog());
5395   EXPECT_EQ(ERR_IO_PENDING, rv);
5396   data.RunFor(2);
5397   base::RunLoop().RunUntilIdle();
5398
5399   // Read the server push body.
5400   std::string result2;
5401   ReadResult(trans2.get(), &data, &result2);
5402   // Read the response body.
5403   std::string result;
5404   ReadResult(trans, &data, &result);
5405   EXPECT_EQ("hello!", result);
5406
5407   // Verify that we haven't received any push data.
5408   EXPECT_EQ("", result2);
5409
5410   // Verify the SYN_REPLY.
5411   // Copy the response info, because trans goes away.
5412   HttpResponseInfo response = *trans->GetResponseInfo();
5413   ASSERT_TRUE(trans2->GetResponseInfo() == NULL);
5414
5415   VerifyStreamsClosed(helper);
5416
5417   // Verify the SYN_REPLY.
5418   EXPECT_TRUE(response.headers.get() != NULL);
5419   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
5420
5421   // Read the final EOF (which will close the session).
5422   data.RunFor(1);
5423
5424   // Verify that we consumed all test data.
5425   EXPECT_TRUE(data.at_read_eof());
5426   EXPECT_TRUE(data.at_write_eof());
5427 }
5428
5429 TEST_P(SpdyNetworkTransactionTest, SynReplyWithHeaders) {
5430   scoped_ptr<SpdyFrame> req(
5431       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5432   scoped_ptr<SpdyFrame> rst(
5433       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
5434   MockWrite writes[] = {
5435     CreateMockWrite(*req),
5436     CreateMockWrite(*rst),
5437  };
5438
5439   scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
5440   (*initial_headers)[spdy_util_.GetStatusKey()] = "200 OK";
5441   (*initial_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
5442   scoped_ptr<SpdyFrame> stream1_reply(
5443       spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(),
5444                                            false,
5445                                            1,
5446                                            LOWEST,
5447                                            SYN_REPLY,
5448                                            CONTROL_FLAG_NONE,
5449                                            0));
5450
5451   scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
5452   (*late_headers)["hello"] = "bye";
5453   scoped_ptr<SpdyFrame> stream1_headers(
5454       spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
5455                                            false,
5456                                            1,
5457                                            LOWEST,
5458                                            HEADERS,
5459                                            CONTROL_FLAG_NONE,
5460                                            0));
5461   scoped_ptr<SpdyFrame> stream1_body(
5462       spdy_util_.ConstructSpdyBodyFrame(1, true));
5463   MockRead reads[] = {
5464     CreateMockRead(*stream1_reply),
5465     CreateMockRead(*stream1_headers),
5466     CreateMockRead(*stream1_body),
5467     MockRead(ASYNC, 0, 0)  // EOF
5468   };
5469
5470   DelayedSocketData data(1, reads, arraysize(reads),
5471                          writes, arraysize(writes));
5472   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5473                                      BoundNetLog(), GetParam(), NULL);
5474   helper.RunToCompletion(&data);
5475   TransactionHelperResult out = helper.output();
5476   EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
5477 }
5478
5479 TEST_P(SpdyNetworkTransactionTest, SynReplyWithLateHeaders) {
5480   scoped_ptr<SpdyFrame> req(
5481       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5482   scoped_ptr<SpdyFrame> rst(
5483       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
5484   MockWrite writes[] = {
5485     CreateMockWrite(*req),
5486     CreateMockWrite(*rst),
5487   };
5488
5489   scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
5490   (*initial_headers)[spdy_util_.GetStatusKey()] = "200 OK";
5491   (*initial_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
5492   scoped_ptr<SpdyFrame> stream1_reply(
5493       spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(),
5494                                            false,
5495                                            1,
5496                                            LOWEST,
5497                                            SYN_REPLY,
5498                                            CONTROL_FLAG_NONE,
5499                                            0));
5500
5501   scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
5502   (*late_headers)["hello"] = "bye";
5503   scoped_ptr<SpdyFrame> stream1_headers(
5504       spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
5505                                            false,
5506                                            1,
5507                                            LOWEST,
5508                                            HEADERS,
5509                                            CONTROL_FLAG_NONE,
5510                                            0));
5511   scoped_ptr<SpdyFrame> stream1_body(
5512       spdy_util_.ConstructSpdyBodyFrame(1, false));
5513   scoped_ptr<SpdyFrame> stream1_body2(
5514       spdy_util_.ConstructSpdyBodyFrame(1, true));
5515   MockRead reads[] = {
5516     CreateMockRead(*stream1_reply),
5517     CreateMockRead(*stream1_body),
5518     CreateMockRead(*stream1_headers),
5519     CreateMockRead(*stream1_body2),
5520     MockRead(ASYNC, 0, 0)  // EOF
5521   };
5522
5523   DelayedSocketData data(1, reads, arraysize(reads),
5524                          writes, arraysize(writes));
5525   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5526                                      BoundNetLog(), GetParam(), NULL);
5527   helper.RunToCompletion(&data);
5528   TransactionHelperResult out = helper.output();
5529   EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
5530 }
5531
5532 TEST_P(SpdyNetworkTransactionTest, ServerPushCrossOriginCorrectness) {
5533   // In this test we want to verify that we can't accidentally push content
5534   // which can't be pushed by this content server.
5535   // This test assumes that:
5536   //   - if we're requesting http://www.foo.com/barbaz
5537   //   - the browser has made a connection to "www.foo.com".
5538
5539   // A list of the URL to fetch, followed by the URL being pushed.
5540   static const char* const kTestCases[] = {
5541     "http://www.google.com/foo.html",
5542     "http://www.google.com:81/foo.js",     // Bad port
5543
5544     "http://www.google.com/foo.html",
5545     "https://www.google.com/foo.js",       // Bad protocol
5546
5547     "http://www.google.com/foo.html",
5548     "ftp://www.google.com/foo.js",         // Invalid Protocol
5549
5550     "http://www.google.com/foo.html",
5551     "http://blat.www.google.com/foo.js",   // Cross subdomain
5552
5553     "http://www.google.com/foo.html",
5554     "http://www.foo.com/foo.js",           // Cross domain
5555   };
5556
5557   for (size_t index = 0; index < arraysize(kTestCases); index += 2) {
5558     const char* url_to_fetch = kTestCases[index];
5559     const char* url_to_push = kTestCases[index + 1];
5560
5561     scoped_ptr<SpdyFrame> stream1_syn(
5562         spdy_util_.ConstructSpdyGet(url_to_fetch, false, 1, LOWEST));
5563     scoped_ptr<SpdyFrame> stream1_body(
5564         spdy_util_.ConstructSpdyBodyFrame(1, true));
5565     scoped_ptr<SpdyFrame> push_rst(
5566         spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
5567     MockWrite writes[] = {
5568       CreateMockWrite(*stream1_syn, 1),
5569       CreateMockWrite(*push_rst, 4),
5570     };
5571
5572     scoped_ptr<SpdyFrame>
5573         stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5574     scoped_ptr<SpdyFrame>
5575         stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
5576                                                  0,
5577                                                  2,
5578                                                  1,
5579                                                  url_to_push));
5580     const char kPushedData[] = "pushed";
5581     scoped_ptr<SpdyFrame> stream2_body(
5582         spdy_util_.ConstructSpdyBodyFrame(
5583             2, kPushedData, strlen(kPushedData), true));
5584     scoped_ptr<SpdyFrame> rst(
5585         spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_CANCEL));
5586
5587     MockRead reads[] = {
5588       CreateMockRead(*stream1_reply, 2),
5589       CreateMockRead(*stream2_syn, 3),
5590       CreateMockRead(*stream1_body, 5, SYNCHRONOUS),
5591       CreateMockRead(*stream2_body, 6),
5592       MockRead(ASYNC, ERR_IO_PENDING, 7),  // Force a pause
5593     };
5594
5595     HttpResponseInfo response;
5596     OrderedSocketData data(reads, arraysize(reads),
5597                            writes, arraysize(writes));
5598
5599     HttpRequestInfo request;
5600     request.method = "GET";
5601     request.url = GURL(url_to_fetch);
5602     request.load_flags = 0;
5603
5604     // Enable cross-origin push. Since we are not using a proxy, this should
5605     // not actually enable cross-origin SPDY push.
5606     scoped_ptr<SpdySessionDependencies> session_deps(
5607         CreateSpdySessionDependencies(GetParam()));
5608     session_deps->trusted_spdy_proxy = "123.45.67.89:8080";
5609     NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
5610                                        BoundNetLog(), GetParam(),
5611                                        session_deps.release());
5612     helper.RunPreTestSetup();
5613     helper.AddData(&data);
5614
5615     HttpNetworkTransaction* trans = helper.trans();
5616
5617     // Start the transaction with basic parameters.
5618     TestCompletionCallback callback;
5619
5620     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
5621     EXPECT_EQ(ERR_IO_PENDING, rv);
5622     rv = callback.WaitForResult();
5623
5624     // Read the response body.
5625     std::string result;
5626     ReadResult(trans, &data, &result);
5627
5628     // Verify that we consumed all test data.
5629     EXPECT_TRUE(data.at_read_eof());
5630     EXPECT_TRUE(data.at_write_eof());
5631
5632     // Verify the SYN_REPLY.
5633     // Copy the response info, because trans goes away.
5634     response = *trans->GetResponseInfo();
5635
5636     VerifyStreamsClosed(helper);
5637
5638     // Verify the SYN_REPLY.
5639     EXPECT_TRUE(response.headers.get() != NULL);
5640     EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
5641   }
5642 }
5643
5644 TEST_P(SpdyNetworkTransactionTest, RetryAfterRefused) {
5645   // Construct the request.
5646   scoped_ptr<SpdyFrame> req(
5647       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5648   scoped_ptr<SpdyFrame> req2(
5649       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
5650   MockWrite writes[] = {
5651     CreateMockWrite(*req, 1),
5652     CreateMockWrite(*req2, 3),
5653   };
5654
5655   scoped_ptr<SpdyFrame> refused(
5656       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_REFUSED_STREAM));
5657   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
5658   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(3, true));
5659   MockRead reads[] = {
5660     CreateMockRead(*refused, 2),
5661     CreateMockRead(*resp, 4),
5662     CreateMockRead(*body, 5),
5663     MockRead(ASYNC, 0, 6)  // EOF
5664   };
5665
5666   OrderedSocketData data(reads, arraysize(reads),
5667                          writes, arraysize(writes));
5668   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5669                                      BoundNetLog(), GetParam(), NULL);
5670
5671   helper.RunPreTestSetup();
5672   helper.AddData(&data);
5673
5674   HttpNetworkTransaction* trans = helper.trans();
5675
5676   // Start the transaction with basic parameters.
5677   TestCompletionCallback callback;
5678   int rv = trans->Start(
5679       &CreateGetRequest(), callback.callback(), BoundNetLog());
5680   EXPECT_EQ(ERR_IO_PENDING, rv);
5681   rv = callback.WaitForResult();
5682   EXPECT_EQ(OK, rv);
5683
5684   // Verify that we consumed all test data.
5685   EXPECT_TRUE(data.at_read_eof()) << "Read count: "
5686                                    << data.read_count()
5687                                    << " Read index: "
5688                                    << data.read_index();
5689   EXPECT_TRUE(data.at_write_eof()) << "Write count: "
5690                                     << data.write_count()
5691                                     << " Write index: "
5692                                     << data.write_index();
5693
5694   // Verify the SYN_REPLY.
5695   HttpResponseInfo response = *trans->GetResponseInfo();
5696   EXPECT_TRUE(response.headers.get() != NULL);
5697   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
5698 }
5699
5700 TEST_P(SpdyNetworkTransactionTest, OutOfOrderSynStream) {
5701   // This first request will start to establish the SpdySession.
5702   // Then we will start the second (MEDIUM priority) and then third
5703   // (HIGHEST priority) request in such a way that the third will actually
5704   // start before the second, causing the second to be numbered differently
5705   // than the order they were created.
5706   scoped_ptr<SpdyFrame> req1(
5707       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5708   scoped_ptr<SpdyFrame> req2(
5709       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, HIGHEST, true));
5710   scoped_ptr<SpdyFrame> req3(
5711       spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, MEDIUM, true));
5712   MockWrite writes[] = {
5713     CreateMockWrite(*req1, 0),
5714     CreateMockWrite(*req2, 3),
5715     CreateMockWrite(*req3, 4),
5716   };
5717
5718   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5719   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
5720   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
5721   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
5722   scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
5723   scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, true));
5724   MockRead reads[] = {
5725     CreateMockRead(*resp1, 1),
5726     CreateMockRead(*body1, 2),
5727     CreateMockRead(*resp2, 5),
5728     CreateMockRead(*body2, 6),
5729     CreateMockRead(*resp3, 7),
5730     CreateMockRead(*body3, 8),
5731     MockRead(ASYNC, 0, 9)  // EOF
5732   };
5733
5734   DeterministicSocketData data(reads, arraysize(reads),
5735                                writes, arraysize(writes));
5736   NormalSpdyTransactionHelper helper(CreateGetRequest(), LOWEST,
5737                                      BoundNetLog(), GetParam(), NULL);
5738   helper.SetDeterministic();
5739   helper.RunPreTestSetup();
5740   helper.AddDeterministicData(&data);
5741
5742   // Start the first transaction to set up the SpdySession
5743   HttpNetworkTransaction* trans = helper.trans();
5744   TestCompletionCallback callback;
5745   HttpRequestInfo info1 = CreateGetRequest();
5746   int rv = trans->Start(&info1, callback.callback(), BoundNetLog());
5747   EXPECT_EQ(ERR_IO_PENDING, rv);
5748
5749   // Run the message loop, but do not allow the write to complete.
5750   // This leaves the SpdySession with a write pending, which prevents
5751   // SpdySession from attempting subsequent writes until this write completes.
5752   base::RunLoop().RunUntilIdle();
5753
5754   // Now, start both new transactions
5755   HttpRequestInfo info2 = CreateGetRequest();
5756   TestCompletionCallback callback2;
5757   scoped_ptr<HttpNetworkTransaction> trans2(
5758       new HttpNetworkTransaction(MEDIUM, helper.session().get()));
5759   rv = trans2->Start(&info2, callback2.callback(), BoundNetLog());
5760   EXPECT_EQ(ERR_IO_PENDING, rv);
5761   base::RunLoop().RunUntilIdle();
5762
5763   HttpRequestInfo info3 = CreateGetRequest();
5764   TestCompletionCallback callback3;
5765   scoped_ptr<HttpNetworkTransaction> trans3(
5766       new HttpNetworkTransaction(HIGHEST, helper.session().get()));
5767   rv = trans3->Start(&info3, callback3.callback(), BoundNetLog());
5768   EXPECT_EQ(ERR_IO_PENDING, rv);
5769   base::RunLoop().RunUntilIdle();
5770
5771   // We now have two SYN_STREAM frames queued up which will be
5772   // dequeued only once the first write completes, which we
5773   // now allow to happen.
5774   data.RunFor(2);
5775   EXPECT_EQ(OK, callback.WaitForResult());
5776
5777   // And now we can allow everything else to run to completion.
5778   data.SetStop(10);
5779   data.Run();
5780   EXPECT_EQ(OK, callback2.WaitForResult());
5781   EXPECT_EQ(OK, callback3.WaitForResult());
5782
5783   helper.VerifyDataConsumed();
5784 }
5785
5786 // The tests below are only for SPDY/3 and above.
5787
5788 // Test that sent data frames and received WINDOW_UPDATE frames change
5789 // the send_window_size_ correctly.
5790
5791 // WINDOW_UPDATE is different than most other frames in that it can arrive
5792 // while the client is still sending the request body.  In order to enforce
5793 // this scenario, we feed a couple of dummy frames and give a delay of 0 to
5794 // socket data provider, so that initial read that is done as soon as the
5795 // stream is created, succeeds and schedules another read.  This way reads
5796 // and writes are interleaved; after doing a full frame write, SpdyStream
5797 // will break out of DoLoop and will read and process a WINDOW_UPDATE.
5798 // Once our WINDOW_UPDATE is read, we cannot send SYN_REPLY right away
5799 // since request has not been completely written, therefore we feed
5800 // enough number of WINDOW_UPDATEs to finish the first read and cause a
5801 // write, leading to a complete write of request body; after that we send
5802 // a reply with a body, to cause a graceful shutdown.
5803
5804 // TODO(agayev): develop a socket data provider where both, reads and
5805 // writes are ordered so that writing tests like these are easy and rewrite
5806 // all these tests using it.  Right now we are working around the
5807 // limitations as described above and it's not deterministic, tests may
5808 // fail under specific circumstances.
5809 TEST_P(SpdyNetworkTransactionTest, WindowUpdateReceived) {
5810   if (GetParam().protocol < kProtoSPDY3)
5811     return;
5812
5813   static int kFrameCount = 2;
5814   scoped_ptr<std::string> content(
5815       new std::string(kMaxSpdyFrameChunkSize, 'a'));
5816   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
5817       kRequestUrl, 1, kMaxSpdyFrameChunkSize * kFrameCount, LOWEST, NULL, 0));
5818   scoped_ptr<SpdyFrame> body(
5819       spdy_util_.ConstructSpdyBodyFrame(
5820           1, content->c_str(), content->size(), false));
5821   scoped_ptr<SpdyFrame> body_end(
5822       spdy_util_.ConstructSpdyBodyFrame(
5823           1, content->c_str(), content->size(), true));
5824
5825   MockWrite writes[] = {
5826     CreateMockWrite(*req, 0),
5827     CreateMockWrite(*body, 1),
5828     CreateMockWrite(*body_end, 2),
5829   };
5830
5831   static const int32 kDeltaWindowSize = 0xff;
5832   static const int kDeltaCount = 4;
5833   scoped_ptr<SpdyFrame> window_update(
5834       spdy_util_.ConstructSpdyWindowUpdate(1, kDeltaWindowSize));
5835   scoped_ptr<SpdyFrame> window_update_dummy(
5836       spdy_util_.ConstructSpdyWindowUpdate(2, kDeltaWindowSize));
5837   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
5838   MockRead reads[] = {
5839     CreateMockRead(*window_update_dummy, 3),
5840     CreateMockRead(*window_update_dummy, 4),
5841     CreateMockRead(*window_update_dummy, 5),
5842     CreateMockRead(*window_update, 6),     // Four updates, therefore window
5843     CreateMockRead(*window_update, 7),     // size should increase by
5844     CreateMockRead(*window_update, 8),     // kDeltaWindowSize * 4
5845     CreateMockRead(*window_update, 9),
5846     CreateMockRead(*resp, 10),
5847     CreateMockRead(*body_end, 11),
5848     MockRead(ASYNC, 0, 0, 12)  // EOF
5849   };
5850
5851   DeterministicSocketData data(reads, arraysize(reads),
5852                                writes, arraysize(writes));
5853
5854   ScopedVector<UploadElementReader> element_readers;
5855   for (int i = 0; i < kFrameCount; ++i) {
5856     element_readers.push_back(
5857         new UploadBytesElementReader(content->c_str(), content->size()));
5858   }
5859   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
5860
5861   // Setup the request
5862   HttpRequestInfo request;
5863   request.method = "POST";
5864   request.url = GURL(kDefaultURL);
5865   request.upload_data_stream = &upload_data_stream;
5866
5867   NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
5868                                      BoundNetLog(), GetParam(), NULL);
5869   helper.SetDeterministic();
5870   helper.AddDeterministicData(&data);
5871   helper.RunPreTestSetup();
5872
5873   HttpNetworkTransaction* trans = helper.trans();
5874
5875   TestCompletionCallback callback;
5876   int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
5877
5878   EXPECT_EQ(ERR_IO_PENDING, rv);
5879
5880   data.RunFor(11);
5881
5882   SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
5883   ASSERT_TRUE(stream != NULL);
5884   ASSERT_TRUE(stream->stream() != NULL);
5885   EXPECT_EQ(static_cast<int>(kSpdyStreamInitialWindowSize) +
5886             kDeltaWindowSize * kDeltaCount -
5887             kMaxSpdyFrameChunkSize * kFrameCount,
5888             stream->stream()->send_window_size());
5889
5890   data.RunFor(1);
5891
5892   rv = callback.WaitForResult();
5893   EXPECT_EQ(OK, rv);
5894
5895   helper.VerifyDataConsumed();
5896 }
5897
5898 // Test that received data frames and sent WINDOW_UPDATE frames change
5899 // the recv_window_size_ correctly.
5900 TEST_P(SpdyNetworkTransactionTest, WindowUpdateSent) {
5901   if (GetParam().protocol < kProtoSPDY3)
5902     return;
5903
5904   // Set the data in the body frame large enough to trigger sending a
5905   // WINDOW_UPDATE by the stream.
5906   const std::string body_data(kSpdyStreamInitialWindowSize / 2 + 1, 'x');
5907
5908   scoped_ptr<SpdyFrame> req(
5909       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5910   scoped_ptr<SpdyFrame> session_window_update(
5911       spdy_util_.ConstructSpdyWindowUpdate(0, body_data.size()));
5912   scoped_ptr<SpdyFrame> window_update(
5913       spdy_util_.ConstructSpdyWindowUpdate(1, body_data.size()));
5914
5915   std::vector<MockWrite> writes;
5916   writes.push_back(CreateMockWrite(*req));
5917   if (GetParam().protocol >= kProtoSPDY31)
5918     writes.push_back(CreateMockWrite(*session_window_update));
5919   writes.push_back(CreateMockWrite(*window_update));
5920
5921   scoped_ptr<SpdyFrame> resp(
5922       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5923   scoped_ptr<SpdyFrame> body_no_fin(
5924       spdy_util_.ConstructSpdyBodyFrame(
5925           1, body_data.data(), body_data.size(), false));
5926   scoped_ptr<SpdyFrame> body_fin(
5927       spdy_util_.ConstructSpdyBodyFrame(1, NULL, 0, true));
5928   MockRead reads[] = {
5929     CreateMockRead(*resp),
5930     CreateMockRead(*body_no_fin),
5931     MockRead(ASYNC, ERR_IO_PENDING, 0),  // Force a pause
5932     CreateMockRead(*body_fin),
5933     MockRead(ASYNC, ERR_IO_PENDING, 0),  // Force a pause
5934     MockRead(ASYNC, 0, 0)  // EOF
5935   };
5936
5937   DelayedSocketData data(1, reads, arraysize(reads),
5938                          vector_as_array(&writes), writes.size());
5939
5940   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5941                                      BoundNetLog(), GetParam(), NULL);
5942   helper.AddData(&data);
5943   helper.RunPreTestSetup();
5944   HttpNetworkTransaction* trans = helper.trans();
5945
5946   TestCompletionCallback callback;
5947   int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
5948
5949   EXPECT_EQ(ERR_IO_PENDING, rv);
5950   rv = callback.WaitForResult();
5951   EXPECT_EQ(OK, rv);
5952
5953   SpdyHttpStream* stream =
5954       static_cast<SpdyHttpStream*>(trans->stream_.get());
5955   ASSERT_TRUE(stream != NULL);
5956   ASSERT_TRUE(stream->stream() != NULL);
5957
5958   EXPECT_EQ(
5959       static_cast<int>(kSpdyStreamInitialWindowSize - body_data.size()),
5960       stream->stream()->recv_window_size());
5961
5962   const HttpResponseInfo* response = trans->GetResponseInfo();
5963   ASSERT_TRUE(response != NULL);
5964   ASSERT_TRUE(response->headers.get() != NULL);
5965   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5966   EXPECT_TRUE(response->was_fetched_via_spdy);
5967
5968   // Issue a read which will cause a WINDOW_UPDATE to be sent and window
5969   // size increased to default.
5970   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(body_data.size()));
5971   rv = trans->Read(buf.get(), body_data.size(), CompletionCallback());
5972   EXPECT_EQ(static_cast<int>(body_data.size()), rv);
5973   std::string content(buf->data(), buf->data() + body_data.size());
5974   EXPECT_EQ(body_data, content);
5975
5976   // Schedule the reading of empty data frame with FIN
5977   data.CompleteRead();
5978
5979   // Force write of WINDOW_UPDATE which was scheduled during the above
5980   // read.
5981   base::RunLoop().RunUntilIdle();
5982
5983   // Read EOF.
5984   data.CompleteRead();
5985
5986   helper.VerifyDataConsumed();
5987 }
5988
5989 // Test that WINDOW_UPDATE frame causing overflow is handled correctly.
5990 TEST_P(SpdyNetworkTransactionTest, WindowUpdateOverflow) {
5991   if (GetParam().protocol < kProtoSPDY3)
5992     return;
5993
5994   // Number of full frames we hope to write (but will not, used to
5995   // set content-length header correctly)
5996   static int kFrameCount = 3;
5997
5998   scoped_ptr<std::string> content(
5999       new std::string(kMaxSpdyFrameChunkSize, 'a'));
6000   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
6001       kRequestUrl, 1, kMaxSpdyFrameChunkSize * kFrameCount, LOWEST, NULL, 0));
6002   scoped_ptr<SpdyFrame> body(
6003       spdy_util_.ConstructSpdyBodyFrame(
6004           1, content->c_str(), content->size(), false));
6005   scoped_ptr<SpdyFrame> rst(
6006       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_FLOW_CONTROL_ERROR));
6007
6008   // We're not going to write a data frame with FIN, we'll receive a bad
6009   // WINDOW_UPDATE while sending a request and will send a RST_STREAM frame.
6010   MockWrite writes[] = {
6011     CreateMockWrite(*req, 0),
6012     CreateMockWrite(*body, 2),
6013     CreateMockWrite(*rst, 3),
6014   };
6015
6016   static const int32 kDeltaWindowSize = 0x7fffffff;  // cause an overflow
6017   scoped_ptr<SpdyFrame> window_update(
6018       spdy_util_.ConstructSpdyWindowUpdate(1, kDeltaWindowSize));
6019   MockRead reads[] = {
6020     CreateMockRead(*window_update, 1),
6021     MockRead(ASYNC, 0, 4)  // EOF
6022   };
6023
6024   DeterministicSocketData data(reads, arraysize(reads),
6025                                writes, arraysize(writes));
6026
6027   ScopedVector<UploadElementReader> element_readers;
6028   for (int i = 0; i < kFrameCount; ++i) {
6029     element_readers.push_back(
6030         new UploadBytesElementReader(content->c_str(), content->size()));
6031   }
6032   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
6033
6034   // Setup the request
6035   HttpRequestInfo request;
6036   request.method = "POST";
6037   request.url = GURL("http://www.google.com/");
6038   request.upload_data_stream = &upload_data_stream;
6039
6040   NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
6041                                      BoundNetLog(), GetParam(), NULL);
6042   helper.SetDeterministic();
6043   helper.RunPreTestSetup();
6044   helper.AddDeterministicData(&data);
6045   HttpNetworkTransaction* trans = helper.trans();
6046
6047   TestCompletionCallback callback;
6048   int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
6049   ASSERT_EQ(ERR_IO_PENDING, rv);
6050
6051   data.RunFor(5);
6052   ASSERT_TRUE(callback.have_result());
6053   EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, callback.WaitForResult());
6054   helper.VerifyDataConsumed();
6055 }
6056
6057 // Test that after hitting a send window size of 0, the write process
6058 // stalls and upon receiving WINDOW_UPDATE frame write resumes.
6059
6060 // This test constructs a POST request followed by enough data frames
6061 // containing 'a' that would make the window size 0, followed by another
6062 // data frame containing default content (which is "hello!") and this frame
6063 // also contains a FIN flag.  DelayedSocketData is used to enforce all
6064 // writes go through before a read could happen.  However, the last frame
6065 // ("hello!")  is not supposed to go through since by the time its turn
6066 // arrives, window size is 0.  At this point MessageLoop::Run() called via
6067 // callback would block.  Therefore we call MessageLoop::RunUntilIdle()
6068 // which returns after performing all possible writes.  We use DCHECKS to
6069 // ensure that last data frame is still there and stream has stalled.
6070 // After that, next read is artifically enforced, which causes a
6071 // WINDOW_UPDATE to be read and I/O process resumes.
6072 TEST_P(SpdyNetworkTransactionTest, FlowControlStallResume) {
6073   if (GetParam().protocol < kProtoSPDY3)
6074     return;
6075
6076   // Number of frames we need to send to zero out the window size: data
6077   // frames plus SYN_STREAM plus the last data frame; also we need another
6078   // data frame that we will send once the WINDOW_UPDATE is received,
6079   // therefore +3.
6080   size_t num_writes = kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3;
6081
6082   // Calculate last frame's size; 0 size data frame is legal.
6083   size_t last_frame_size =
6084       kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize;
6085
6086   // Construct content for a data frame of maximum size.
6087   std::string content(kMaxSpdyFrameChunkSize, 'a');
6088
6089   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
6090       kRequestUrl, 1, kSpdyStreamInitialWindowSize + kUploadDataSize,
6091       LOWEST, NULL, 0));
6092
6093   // Full frames.
6094   scoped_ptr<SpdyFrame> body1(
6095       spdy_util_.ConstructSpdyBodyFrame(
6096           1, content.c_str(), content.size(), false));
6097
6098   // Last frame to zero out the window size.
6099   scoped_ptr<SpdyFrame> body2(
6100       spdy_util_.ConstructSpdyBodyFrame(
6101           1, content.c_str(), last_frame_size, false));
6102
6103   // Data frame to be sent once WINDOW_UPDATE frame is received.
6104   scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(1, true));
6105
6106   // Fill in mock writes.
6107   scoped_ptr<MockWrite[]> writes(new MockWrite[num_writes]);
6108   size_t i = 0;
6109   writes[i] = CreateMockWrite(*req);
6110   for (i = 1; i < num_writes - 2; i++)
6111     writes[i] = CreateMockWrite(*body1);
6112   writes[i++] = CreateMockWrite(*body2);
6113   writes[i] = CreateMockWrite(*body3);
6114
6115   // Construct read frame, give enough space to upload the rest of the
6116   // data.
6117   scoped_ptr<SpdyFrame> session_window_update(
6118       spdy_util_.ConstructSpdyWindowUpdate(0, kUploadDataSize));
6119   scoped_ptr<SpdyFrame> window_update(
6120       spdy_util_.ConstructSpdyWindowUpdate(1, kUploadDataSize));
6121   scoped_ptr<SpdyFrame> reply(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
6122   MockRead reads[] = {
6123     CreateMockRead(*session_window_update),
6124     CreateMockRead(*session_window_update),
6125     CreateMockRead(*window_update),
6126     CreateMockRead(*window_update),
6127     CreateMockRead(*reply),
6128     CreateMockRead(*body2),
6129     CreateMockRead(*body3),
6130     MockRead(ASYNC, 0, 0)  // EOF
6131   };
6132
6133   // Skip the session window updates unless we're using SPDY/3.1 and
6134   // above.
6135   size_t read_offset = (GetParam().protocol >= kProtoSPDY31) ? 0 : 2;
6136   size_t num_reads = arraysize(reads) - read_offset;
6137
6138   // Force all writes to happen before any read, last write will not
6139   // actually queue a frame, due to window size being 0.
6140   DelayedSocketData data(num_writes, reads + read_offset, num_reads,
6141                          writes.get(), num_writes);
6142
6143   ScopedVector<UploadElementReader> element_readers;
6144   std::string upload_data_string(kSpdyStreamInitialWindowSize, 'a');
6145   upload_data_string.append(kUploadData, kUploadDataSize);
6146   element_readers.push_back(new UploadBytesElementReader(
6147       upload_data_string.c_str(), upload_data_string.size()));
6148   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
6149
6150   HttpRequestInfo request;
6151   request.method = "POST";
6152   request.url = GURL("http://www.google.com/");
6153   request.upload_data_stream = &upload_data_stream;
6154   NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
6155                                      BoundNetLog(), GetParam(), NULL);
6156   helper.AddData(&data);
6157   helper.RunPreTestSetup();
6158
6159   HttpNetworkTransaction* trans = helper.trans();
6160
6161   TestCompletionCallback callback;
6162   int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
6163   EXPECT_EQ(ERR_IO_PENDING, rv);
6164
6165   base::RunLoop().RunUntilIdle();  // Write as much as we can.
6166
6167   SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
6168   ASSERT_TRUE(stream != NULL);
6169   ASSERT_TRUE(stream->stream() != NULL);
6170   EXPECT_EQ(0, stream->stream()->send_window_size());
6171   // All the body data should have been read.
6172   // TODO(satorux): This is because of the weirdness in reading the request
6173   // body in OnSendBodyComplete(). See crbug.com/113107.
6174   EXPECT_TRUE(upload_data_stream.IsEOF());
6175   // But the body is not yet fully sent (kUploadData is not yet sent)
6176   // since we're send-stalled.
6177   EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
6178
6179   data.ForceNextRead();   // Read in WINDOW_UPDATE frame.
6180   rv = callback.WaitForResult();
6181   helper.VerifyDataConsumed();
6182 }
6183
6184 // Test we correctly handle the case where the SETTINGS frame results in
6185 // unstalling the send window.
6186 TEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) {
6187   if (GetParam().protocol < kProtoSPDY3)
6188     return;
6189
6190   // Number of frames we need to send to zero out the window size: data
6191   // frames plus SYN_STREAM plus the last data frame; also we need another
6192   // data frame that we will send once the SETTING is received, therefore +3.
6193   size_t num_writes = kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3;
6194
6195   // Calculate last frame's size; 0 size data frame is legal.
6196   size_t last_frame_size =
6197       kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize;
6198
6199   // Construct content for a data frame of maximum size.
6200   std::string content(kMaxSpdyFrameChunkSize, 'a');
6201
6202   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
6203       kRequestUrl, 1, kSpdyStreamInitialWindowSize + kUploadDataSize,
6204       LOWEST, NULL, 0));
6205
6206   // Full frames.
6207   scoped_ptr<SpdyFrame> body1(
6208       spdy_util_.ConstructSpdyBodyFrame(
6209           1, content.c_str(), content.size(), false));
6210
6211   // Last frame to zero out the window size.
6212   scoped_ptr<SpdyFrame> body2(
6213       spdy_util_.ConstructSpdyBodyFrame(
6214           1, content.c_str(), last_frame_size, false));
6215
6216   // Data frame to be sent once SETTINGS frame is received.
6217   scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(1, true));
6218
6219   // Fill in mock reads/writes.
6220   std::vector<MockRead> reads;
6221   std::vector<MockWrite> writes;
6222   size_t i = 0;
6223   writes.push_back(CreateMockWrite(*req, i++));
6224   while (i < num_writes - 2)
6225     writes.push_back(CreateMockWrite(*body1, i++));
6226   writes.push_back(CreateMockWrite(*body2, i++));
6227
6228   // Construct read frame for SETTINGS that gives enough space to upload the
6229   // rest of the data.
6230   SettingsMap settings;
6231   settings[SETTINGS_INITIAL_WINDOW_SIZE] =
6232       SettingsFlagsAndValue(
6233           SETTINGS_FLAG_NONE, kSpdyStreamInitialWindowSize * 2);
6234   scoped_ptr<SpdyFrame> settings_frame_large(
6235       spdy_util_.ConstructSpdySettings(settings));
6236
6237   reads.push_back(CreateMockRead(*settings_frame_large, i++));
6238
6239   scoped_ptr<SpdyFrame> session_window_update(
6240       spdy_util_.ConstructSpdyWindowUpdate(0, kUploadDataSize));
6241   if (GetParam().protocol >= kProtoSPDY31)
6242     reads.push_back(CreateMockRead(*session_window_update, i++));
6243
6244   writes.push_back(CreateMockWrite(*body3, i++));
6245
6246   scoped_ptr<SpdyFrame> reply(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
6247   reads.push_back(CreateMockRead(*reply, i++));
6248   reads.push_back(CreateMockRead(*body2, i++));
6249   reads.push_back(CreateMockRead(*body3, i++));
6250   reads.push_back(MockRead(ASYNC, 0, i++));  // EOF
6251
6252   // Force all writes to happen before any read, last write will not
6253   // actually queue a frame, due to window size being 0.
6254   DeterministicSocketData data(vector_as_array(&reads), reads.size(),
6255                                vector_as_array(&writes), writes.size());
6256
6257   ScopedVector<UploadElementReader> element_readers;
6258   std::string upload_data_string(kSpdyStreamInitialWindowSize, 'a');
6259   upload_data_string.append(kUploadData, kUploadDataSize);
6260   element_readers.push_back(new UploadBytesElementReader(
6261       upload_data_string.c_str(), upload_data_string.size()));
6262   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
6263
6264   HttpRequestInfo request;
6265   request.method = "POST";
6266   request.url = GURL("http://www.google.com/");
6267   request.upload_data_stream = &upload_data_stream;
6268   NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
6269                                      BoundNetLog(), GetParam(), NULL);
6270   helper.SetDeterministic();
6271   helper.RunPreTestSetup();
6272   helper.AddDeterministicData(&data);
6273
6274   HttpNetworkTransaction* trans = helper.trans();
6275
6276   TestCompletionCallback callback;
6277   int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
6278   EXPECT_EQ(ERR_IO_PENDING, rv);
6279
6280   data.RunFor(num_writes - 1);   // Write as much as we can.
6281
6282   SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
6283   ASSERT_TRUE(stream != NULL);
6284   ASSERT_TRUE(stream->stream() != NULL);
6285   EXPECT_EQ(0, stream->stream()->send_window_size());
6286
6287   // All the body data should have been read.
6288   // TODO(satorux): This is because of the weirdness in reading the request
6289   // body in OnSendBodyComplete(). See crbug.com/113107.
6290   EXPECT_TRUE(upload_data_stream.IsEOF());
6291   // But the body is not yet fully sent (kUploadData is not yet sent)
6292   // since we're send-stalled.
6293   EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
6294
6295   data.RunFor(6);   // Read in SETTINGS frame to unstall.
6296   rv = callback.WaitForResult();
6297   helper.VerifyDataConsumed();
6298   // If stream is NULL, that means it was unstalled and closed.
6299   EXPECT_TRUE(stream->stream() == NULL);
6300 }
6301
6302 // Test we correctly handle the case where the SETTINGS frame results in a
6303 // negative send window size.
6304 TEST_P(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) {
6305   if (GetParam().protocol < kProtoSPDY3)
6306     return;
6307
6308   // Number of frames we need to send to zero out the window size: data
6309   // frames plus SYN_STREAM plus the last data frame; also we need another
6310   // data frame that we will send once the SETTING is received, therefore +3.
6311   size_t num_writes = kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3;
6312
6313   // Calculate last frame's size; 0 size data frame is legal.
6314   size_t last_frame_size =
6315       kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize;
6316
6317   // Construct content for a data frame of maximum size.
6318   std::string content(kMaxSpdyFrameChunkSize, 'a');
6319
6320   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
6321       kRequestUrl, 1, kSpdyStreamInitialWindowSize + kUploadDataSize,
6322       LOWEST, NULL, 0));
6323
6324   // Full frames.
6325   scoped_ptr<SpdyFrame> body1(
6326       spdy_util_.ConstructSpdyBodyFrame(
6327           1, content.c_str(), content.size(), false));
6328
6329   // Last frame to zero out the window size.
6330   scoped_ptr<SpdyFrame> body2(
6331       spdy_util_.ConstructSpdyBodyFrame(
6332           1, content.c_str(), last_frame_size, false));
6333
6334   // Data frame to be sent once SETTINGS frame is received.
6335   scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(1, true));
6336
6337   // Fill in mock reads/writes.
6338   std::vector<MockRead> reads;
6339   std::vector<MockWrite> writes;
6340   size_t i = 0;
6341   writes.push_back(CreateMockWrite(*req, i++));
6342   while (i < num_writes - 2)
6343     writes.push_back(CreateMockWrite(*body1, i++));
6344   writes.push_back(CreateMockWrite(*body2, i++));
6345
6346   // Construct read frame for SETTINGS that makes the send_window_size
6347   // negative.
6348   SettingsMap new_settings;
6349   new_settings[SETTINGS_INITIAL_WINDOW_SIZE] =
6350       SettingsFlagsAndValue(
6351           SETTINGS_FLAG_NONE, kSpdyStreamInitialWindowSize / 2);
6352   scoped_ptr<SpdyFrame> settings_frame_small(
6353       spdy_util_.ConstructSpdySettings(new_settings));
6354   // Construct read frames for WINDOW_UPDATE that makes the send_window_size
6355   // positive.
6356   scoped_ptr<SpdyFrame> session_window_update_init_size(
6357       spdy_util_.ConstructSpdyWindowUpdate(0, kSpdyStreamInitialWindowSize));
6358   scoped_ptr<SpdyFrame> window_update_init_size(
6359       spdy_util_.ConstructSpdyWindowUpdate(1, kSpdyStreamInitialWindowSize));
6360
6361   reads.push_back(CreateMockRead(*settings_frame_small, i++));
6362
6363   if (GetParam().protocol >= kProtoSPDY3)
6364     reads.push_back(CreateMockRead(*session_window_update_init_size, i++));
6365
6366   reads.push_back(CreateMockRead(*window_update_init_size, i++));
6367
6368   writes.push_back(CreateMockWrite(*body3, i++));
6369
6370   scoped_ptr<SpdyFrame> reply(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
6371   reads.push_back(CreateMockRead(*reply, i++));
6372   reads.push_back(CreateMockRead(*body2, i++));
6373   reads.push_back(CreateMockRead(*body3, i++));
6374   reads.push_back(MockRead(ASYNC, 0, i++));  // EOF
6375
6376   // Force all writes to happen before any read, last write will not
6377   // actually queue a frame, due to window size being 0.
6378   DeterministicSocketData data(vector_as_array(&reads), reads.size(),
6379                                vector_as_array(&writes), writes.size());
6380
6381   ScopedVector<UploadElementReader> element_readers;
6382   std::string upload_data_string(kSpdyStreamInitialWindowSize, 'a');
6383   upload_data_string.append(kUploadData, kUploadDataSize);
6384   element_readers.push_back(new UploadBytesElementReader(
6385       upload_data_string.c_str(), upload_data_string.size()));
6386   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
6387
6388   HttpRequestInfo request;
6389   request.method = "POST";
6390   request.url = GURL("http://www.google.com/");
6391   request.upload_data_stream = &upload_data_stream;
6392   NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
6393                                      BoundNetLog(), GetParam(), NULL);
6394   helper.SetDeterministic();
6395   helper.RunPreTestSetup();
6396   helper.AddDeterministicData(&data);
6397
6398   HttpNetworkTransaction* trans = helper.trans();
6399
6400   TestCompletionCallback callback;
6401   int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
6402   EXPECT_EQ(ERR_IO_PENDING, rv);
6403
6404   data.RunFor(num_writes - 1);   // Write as much as we can.
6405
6406   SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
6407   ASSERT_TRUE(stream != NULL);
6408   ASSERT_TRUE(stream->stream() != NULL);
6409   EXPECT_EQ(0, stream->stream()->send_window_size());
6410
6411   // All the body data should have been read.
6412   // TODO(satorux): This is because of the weirdness in reading the request
6413   // body in OnSendBodyComplete(). See crbug.com/113107.
6414   EXPECT_TRUE(upload_data_stream.IsEOF());
6415   // But the body is not yet fully sent (kUploadData is not yet sent)
6416   // since we're send-stalled.
6417   EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
6418
6419   // Read in WINDOW_UPDATE or SETTINGS frame.
6420   data.RunFor((GetParam().protocol >= kProtoSPDY31) ? 8 : 7);
6421   rv = callback.WaitForResult();
6422   helper.VerifyDataConsumed();
6423 }
6424
6425 }  // namespace net