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