Upstream version 5.34.92.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 back a SYN_REPLY.
2063 TEST_P(SpdyNetworkTransactionTest, PostWithEarlySynReply) {
2064   static const char upload[] = { "hello!" };
2065   ScopedVector<UploadElementReader> element_readers;
2066   element_readers.push_back(
2067       new UploadBytesElementReader(upload, sizeof(upload)));
2068   UploadDataStream stream(element_readers.Pass(), 0);
2069
2070   // Setup the request
2071   HttpRequestInfo request;
2072   request.method = "POST";
2073   request.url = GURL(kRequestUrl);
2074   request.upload_data_stream = &stream;
2075
2076   scoped_ptr<SpdyFrame> stream_reply(
2077       spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
2078   MockRead reads[] = {
2079     CreateMockRead(*stream_reply, 1),
2080     MockRead(ASYNC, 0, 4)  // EOF
2081   };
2082
2083   scoped_ptr<SpdyFrame> req(
2084       spdy_util_.ConstructSpdyPost(
2085           kRequestUrl, 1, kUploadDataSize, LOWEST, NULL, 0));
2086   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2087   scoped_ptr<SpdyFrame> rst(
2088       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
2089   MockWrite writes[] = {
2090     CreateMockWrite(*req, 0),
2091     CreateMockWrite(*body, 2),
2092     CreateMockWrite(*rst, 3)
2093   };
2094
2095   DeterministicSocketData data(reads, arraysize(reads),
2096                                writes, arraysize(writes));
2097   NormalSpdyTransactionHelper helper(CreatePostRequest(), DEFAULT_PRIORITY,
2098                                      BoundNetLog(), GetParam(), NULL);
2099   helper.SetDeterministic();
2100   helper.RunPreTestSetup();
2101   helper.AddDeterministicData(&data);
2102   HttpNetworkTransaction* trans = helper.trans();
2103
2104   TestCompletionCallback callback;
2105   int rv = trans->Start(
2106       &CreatePostRequest(), callback.callback(), BoundNetLog());
2107   EXPECT_EQ(ERR_IO_PENDING, rv);
2108
2109   data.RunFor(4);
2110   rv = callback.WaitForResult();
2111   EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv);
2112   data.RunFor(1);
2113 }
2114
2115 // The client upon cancellation tries to send a RST_STREAM frame. The mock
2116 // socket causes the TCP write to return zero. This test checks that the client
2117 // tries to queue up the RST_STREAM frame again.
2118 TEST_P(SpdyNetworkTransactionTest, SocketWriteReturnsZero) {
2119   scoped_ptr<SpdyFrame> req(
2120       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2121   scoped_ptr<SpdyFrame> rst(
2122       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
2123   MockWrite writes[] = {
2124     CreateMockWrite(*req.get(), 0, SYNCHRONOUS),
2125     MockWrite(SYNCHRONOUS, 0, 0, 2),
2126     CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
2127   };
2128
2129   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2130   MockRead reads[] = {
2131     CreateMockRead(*resp.get(), 1, ASYNC),
2132     MockRead(ASYNC, 0, 0, 4)  // EOF
2133   };
2134
2135   DeterministicSocketData data(reads, arraysize(reads),
2136                                writes, arraysize(writes));
2137   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2138                                      BoundNetLog(), GetParam(), NULL);
2139   helper.SetDeterministic();
2140   helper.RunPreTestSetup();
2141   helper.AddDeterministicData(&data);
2142   HttpNetworkTransaction* trans = helper.trans();
2143
2144   TestCompletionCallback callback;
2145   int rv = trans->Start(
2146       &CreateGetRequest(), callback.callback(), BoundNetLog());
2147   EXPECT_EQ(ERR_IO_PENDING, rv);
2148
2149   data.SetStop(2);
2150   data.Run();
2151   helper.ResetTrans();
2152   data.SetStop(20);
2153   data.Run();
2154
2155   helper.VerifyDataConsumed();
2156 }
2157
2158 // Test that the transaction doesn't crash when we don't have a reply.
2159 TEST_P(SpdyNetworkTransactionTest, ResponseWithoutSynReply) {
2160   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2161   MockRead reads[] = {
2162     CreateMockRead(*body),
2163     MockRead(ASYNC, 0, 0)  // EOF
2164   };
2165
2166   DelayedSocketData data(1, reads, arraysize(reads), NULL, 0);
2167   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2168                                      BoundNetLog(), GetParam(), NULL);
2169   helper.RunToCompletion(&data);
2170   TransactionHelperResult out = helper.output();
2171   EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
2172 }
2173
2174 // Test that the transaction doesn't crash when we get two replies on the same
2175 // stream ID. See http://crbug.com/45639.
2176 TEST_P(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) {
2177   scoped_ptr<SpdyFrame> req(
2178       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2179   scoped_ptr<SpdyFrame> rst(
2180       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
2181   MockWrite writes[] = {
2182     CreateMockWrite(*req),
2183     CreateMockWrite(*rst),
2184   };
2185
2186   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2187   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2188   MockRead reads[] = {
2189     CreateMockRead(*resp),
2190     CreateMockRead(*resp),
2191     CreateMockRead(*body),
2192     MockRead(ASYNC, 0, 0)  // EOF
2193   };
2194
2195   DelayedSocketData data(1, reads, arraysize(reads),
2196                          writes, arraysize(writes));
2197
2198   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2199                                      BoundNetLog(), GetParam(), NULL);
2200   helper.RunPreTestSetup();
2201   helper.AddData(&data);
2202
2203   HttpNetworkTransaction* trans = helper.trans();
2204
2205   TestCompletionCallback callback;
2206   int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
2207   EXPECT_EQ(ERR_IO_PENDING, rv);
2208   rv = callback.WaitForResult();
2209   EXPECT_EQ(OK, rv);
2210
2211   const HttpResponseInfo* response = trans->GetResponseInfo();
2212   ASSERT_TRUE(response != NULL);
2213   EXPECT_TRUE(response->headers.get() != NULL);
2214   EXPECT_TRUE(response->was_fetched_via_spdy);
2215   std::string response_data;
2216   rv = ReadTransaction(trans, &response_data);
2217   EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv);
2218
2219   helper.VerifyDataConsumed();
2220 }
2221
2222 TEST_P(SpdyNetworkTransactionTest, ResetReplyWithTransferEncoding) {
2223   // Construct the request.
2224   scoped_ptr<SpdyFrame> req(
2225       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2226   scoped_ptr<SpdyFrame> rst(
2227       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
2228   MockWrite writes[] = {
2229     CreateMockWrite(*req),
2230     CreateMockWrite(*rst),
2231   };
2232
2233   const char* const headers[] = {
2234     "transfer-encoding", "chunked"
2235   };
2236   scoped_ptr<SpdyFrame> resp(
2237       spdy_util_.ConstructSpdyGetSynReply(headers, 1, 1));
2238   scoped_ptr<SpdyFrame> body(
2239       spdy_util_.ConstructSpdyBodyFrame(1, true));
2240   MockRead reads[] = {
2241     CreateMockRead(*resp),
2242     CreateMockRead(*body),
2243     MockRead(ASYNC, 0, 0)  // EOF
2244   };
2245
2246   DelayedSocketData data(1, reads, arraysize(reads),
2247                          writes, arraysize(writes));
2248   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2249                                      BoundNetLog(), GetParam(), NULL);
2250   helper.RunToCompletion(&data);
2251   TransactionHelperResult out = helper.output();
2252   EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
2253
2254   helper.session()->spdy_session_pool()->CloseAllSessions();
2255   helper.VerifyDataConsumed();
2256 }
2257
2258 TEST_P(SpdyNetworkTransactionTest, ResetPushWithTransferEncoding) {
2259   // Construct the request.
2260   scoped_ptr<SpdyFrame> req(
2261       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2262   scoped_ptr<SpdyFrame> rst(
2263       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR));
2264   MockWrite writes[] = {
2265     CreateMockWrite(*req),
2266     CreateMockWrite(*rst),
2267   };
2268
2269   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2270   const char* const headers[] = {
2271     "transfer-encoding", "chunked"
2272   };
2273   scoped_ptr<SpdyFrame> push(
2274       spdy_util_.ConstructSpdyPush(headers, arraysize(headers) / 2,
2275                                    2, 1, "http://www.google.com/1"));
2276   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2277   MockRead reads[] = {
2278     CreateMockRead(*resp),
2279     CreateMockRead(*push),
2280     CreateMockRead(*body),
2281     MockRead(ASYNC, 0, 0)  // EOF
2282   };
2283
2284   DelayedSocketData data(1, reads, arraysize(reads),
2285                          writes, arraysize(writes));
2286   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2287                                      BoundNetLog(), GetParam(), NULL);
2288   helper.RunToCompletion(&data);
2289   TransactionHelperResult out = helper.output();
2290   EXPECT_EQ(OK, out.rv);
2291   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
2292   EXPECT_EQ("hello!", out.response_data);
2293
2294   helper.session()->spdy_session_pool()->CloseAllSessions();
2295   helper.VerifyDataConsumed();
2296 }
2297
2298 TEST_P(SpdyNetworkTransactionTest, CancelledTransaction) {
2299   // Construct the request.
2300   scoped_ptr<SpdyFrame> req(
2301       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2302   MockWrite writes[] = {
2303     CreateMockWrite(*req),
2304   };
2305
2306   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2307   MockRead reads[] = {
2308     CreateMockRead(*resp),
2309     // This following read isn't used by the test, except during the
2310     // RunUntilIdle() call at the end since the SpdySession survives the
2311     // HttpNetworkTransaction and still tries to continue Read()'ing.  Any
2312     // MockRead will do here.
2313     MockRead(ASYNC, 0, 0)  // EOF
2314   };
2315
2316   StaticSocketDataProvider data(reads, arraysize(reads),
2317                                 writes, arraysize(writes));
2318
2319   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2320                                      BoundNetLog(), GetParam(), NULL);
2321   helper.RunPreTestSetup();
2322   helper.AddData(&data);
2323   HttpNetworkTransaction* trans = helper.trans();
2324
2325   TestCompletionCallback callback;
2326   int rv = trans->Start(
2327       &CreateGetRequest(), callback.callback(), BoundNetLog());
2328   EXPECT_EQ(ERR_IO_PENDING, rv);
2329   helper.ResetTrans();  // Cancel the transaction.
2330
2331   // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
2332   // MockClientSocketFactory) are still alive.
2333   base::RunLoop().RunUntilIdle();
2334   helper.VerifyDataNotConsumed();
2335 }
2336
2337 // Verify that the client sends a Rst Frame upon cancelling the stream.
2338 TEST_P(SpdyNetworkTransactionTest, CancelledTransactionSendRst) {
2339   scoped_ptr<SpdyFrame> req(
2340       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2341   scoped_ptr<SpdyFrame> rst(
2342       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
2343   MockWrite writes[] = {
2344     CreateMockWrite(*req, 0, SYNCHRONOUS),
2345     CreateMockWrite(*rst, 2, SYNCHRONOUS),
2346   };
2347
2348   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2349   MockRead reads[] = {
2350     CreateMockRead(*resp, 1, ASYNC),
2351     MockRead(ASYNC, 0, 0, 3)  // EOF
2352   };
2353
2354   DeterministicSocketData data(reads, arraysize(reads),
2355                                writes, arraysize(writes));
2356
2357   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2358                                      BoundNetLog(),
2359                                      GetParam(), NULL);
2360   helper.SetDeterministic();
2361   helper.RunPreTestSetup();
2362   helper.AddDeterministicData(&data);
2363   HttpNetworkTransaction* trans = helper.trans();
2364
2365   TestCompletionCallback callback;
2366
2367   int rv = trans->Start(
2368       &CreateGetRequest(), callback.callback(), BoundNetLog());
2369   EXPECT_EQ(ERR_IO_PENDING, rv);
2370
2371   data.SetStop(2);
2372   data.Run();
2373   helper.ResetTrans();
2374   data.SetStop(20);
2375   data.Run();
2376
2377   helper.VerifyDataConsumed();
2378 }
2379
2380 // Verify that the client can correctly deal with the user callback attempting
2381 // to start another transaction on a session that is closing down. See
2382 // http://crbug.com/47455
2383 TEST_P(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) {
2384   scoped_ptr<SpdyFrame> req(
2385       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2386   MockWrite writes[] = { CreateMockWrite(*req) };
2387   MockWrite writes2[] = { CreateMockWrite(*req) };
2388
2389   // The indicated length of this frame is longer than its actual length. When
2390   // the session receives an empty frame after this one, it shuts down the
2391   // session, and calls the read callback with the incomplete data.
2392   const uint8 kGetBodyFrame2[] = {
2393     0x00, 0x00, 0x00, 0x01,
2394     0x01, 0x00, 0x00, 0x07,
2395     'h', 'e', 'l', 'l', 'o', '!',
2396   };
2397
2398   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2399   MockRead reads[] = {
2400     CreateMockRead(*resp, 2),
2401     MockRead(ASYNC, ERR_IO_PENDING, 3),  // Force a pause
2402     MockRead(ASYNC, reinterpret_cast<const char*>(kGetBodyFrame2),
2403              arraysize(kGetBodyFrame2), 4),
2404     MockRead(ASYNC, ERR_IO_PENDING, 5),  // Force a pause
2405     MockRead(ASYNC, 0, 0, 6),  // EOF
2406   };
2407   MockRead reads2[] = {
2408     CreateMockRead(*resp, 2),
2409     MockRead(ASYNC, 0, 0, 3),  // EOF
2410   };
2411
2412   OrderedSocketData data(reads, arraysize(reads),
2413                          writes, arraysize(writes));
2414   DelayedSocketData data2(1, reads2, arraysize(reads2),
2415                           writes2, arraysize(writes2));
2416
2417   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2418                                      BoundNetLog(), GetParam(), NULL);
2419   helper.RunPreTestSetup();
2420   helper.AddData(&data);
2421   helper.AddData(&data2);
2422   HttpNetworkTransaction* trans = helper.trans();
2423
2424   // Start the transaction with basic parameters.
2425   TestCompletionCallback callback;
2426   int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
2427   EXPECT_EQ(ERR_IO_PENDING, rv);
2428   rv = callback.WaitForResult();
2429
2430   const int kSize = 3000;
2431   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
2432   rv = trans->Read(
2433       buf.get(),
2434       kSize,
2435       base::Bind(&SpdyNetworkTransactionTest::StartTransactionCallback,
2436                  helper.session()));
2437   // This forces an err_IO_pending, which sets the callback.
2438   data.CompleteRead();
2439   // This finishes the read.
2440   data.CompleteRead();
2441   helper.VerifyDataConsumed();
2442 }
2443
2444 // Verify that the client can correctly deal with the user callback deleting the
2445 // transaction. Failures will usually be valgrind errors. See
2446 // http://crbug.com/46925
2447 TEST_P(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) {
2448   scoped_ptr<SpdyFrame> req(
2449       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2450   MockWrite writes[] = { CreateMockWrite(*req) };
2451
2452   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2453   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2454   MockRead reads[] = {
2455     CreateMockRead(*resp.get(), 2),
2456     MockRead(ASYNC, ERR_IO_PENDING, 3),  // Force a pause
2457     CreateMockRead(*body.get(), 4),
2458     MockRead(ASYNC, 0, 0, 5),  // EOF
2459   };
2460
2461   OrderedSocketData data(reads, arraysize(reads),
2462                          writes, arraysize(writes));
2463
2464   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2465                                      BoundNetLog(), GetParam(), NULL);
2466   helper.RunPreTestSetup();
2467   helper.AddData(&data);
2468   HttpNetworkTransaction* trans = helper.trans();
2469
2470   // Start the transaction with basic parameters.
2471   TestCompletionCallback callback;
2472   int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
2473   EXPECT_EQ(ERR_IO_PENDING, rv);
2474   rv = callback.WaitForResult();
2475
2476   // Setup a user callback which will delete the session, and clear out the
2477   // memory holding the stream object. Note that the callback deletes trans.
2478   const int kSize = 3000;
2479   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
2480   rv = trans->Read(
2481       buf.get(),
2482       kSize,
2483       base::Bind(&SpdyNetworkTransactionTest::DeleteSessionCallback,
2484                  base::Unretained(&helper)));
2485   ASSERT_EQ(ERR_IO_PENDING, rv);
2486   data.CompleteRead();
2487
2488   // Finish running rest of tasks.
2489   base::RunLoop().RunUntilIdle();
2490   helper.VerifyDataConsumed();
2491 }
2492
2493 // Send a spdy request to www.google.com that gets redirected to www.foo.com.
2494 TEST_P(SpdyNetworkTransactionTest, RedirectGetRequest) {
2495   const SpdyHeaderInfo kSynStartHeader = spdy_util_.MakeSpdyHeader(SYN_STREAM);
2496   scoped_ptr<SpdyHeaderBlock> headers(
2497       spdy_util_.ConstructGetHeaderBlock("http://www.google.com/"));
2498   (*headers)["user-agent"] = "";
2499   (*headers)["accept-encoding"] = "gzip,deflate";
2500   scoped_ptr<SpdyHeaderBlock> headers2(
2501       spdy_util_.ConstructGetHeaderBlock("http://www.foo.com/index.php"));
2502   (*headers2)["user-agent"] = "";
2503   (*headers2)["accept-encoding"] = "gzip,deflate";
2504
2505   // Setup writes/reads to www.google.com
2506   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyFrame(
2507       kSynStartHeader, headers.Pass()));
2508   scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyFrame(
2509       kSynStartHeader, headers2.Pass()));
2510   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReplyRedirect(1));
2511   MockWrite writes[] = {
2512     CreateMockWrite(*req, 1),
2513   };
2514   MockRead reads[] = {
2515     CreateMockRead(*resp, 2),
2516     MockRead(ASYNC, 0, 0, 3)  // EOF
2517   };
2518
2519   // Setup writes/reads to www.foo.com
2520   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2521   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
2522   MockWrite writes2[] = {
2523     CreateMockWrite(*req2, 1),
2524   };
2525   MockRead reads2[] = {
2526     CreateMockRead(*resp2, 2),
2527     CreateMockRead(*body2, 3),
2528     MockRead(ASYNC, 0, 0, 4)  // EOF
2529   };
2530   OrderedSocketData data(reads, arraysize(reads),
2531                          writes, arraysize(writes));
2532   OrderedSocketData data2(reads2, arraysize(reads2),
2533                           writes2, arraysize(writes2));
2534
2535   // TODO(erikchen): Make test support SPDYSSL, SPDYNPN
2536   HttpStreamFactory::set_force_spdy_over_ssl(false);
2537   HttpStreamFactory::set_force_spdy_always(true);
2538   TestDelegate d;
2539   {
2540     SpdyURLRequestContext spdy_url_request_context(GetParam().protocol);
2541     net::URLRequest r(GURL("http://www.google.com/"),
2542                       DEFAULT_PRIORITY,
2543                       &d,
2544                       &spdy_url_request_context);
2545     spdy_url_request_context.socket_factory().
2546         AddSocketDataProvider(&data);
2547     spdy_url_request_context.socket_factory().
2548         AddSocketDataProvider(&data2);
2549
2550     d.set_quit_on_redirect(true);
2551     r.Start();
2552     base::RunLoop().Run();
2553
2554     EXPECT_EQ(1, d.received_redirect_count());
2555
2556     r.FollowDeferredRedirect();
2557     base::RunLoop().Run();
2558     EXPECT_EQ(1, d.response_started_count());
2559     EXPECT_FALSE(d.received_data_before_response());
2560     EXPECT_EQ(net::URLRequestStatus::SUCCESS, r.status().status());
2561     std::string contents("hello!");
2562     EXPECT_EQ(contents, d.data_received());
2563   }
2564   EXPECT_TRUE(data.at_read_eof());
2565   EXPECT_TRUE(data.at_write_eof());
2566   EXPECT_TRUE(data2.at_read_eof());
2567   EXPECT_TRUE(data2.at_write_eof());
2568 }
2569
2570 // Send a spdy request to www.google.com. Get a pushed stream that redirects to
2571 // www.foo.com.
2572 TEST_P(SpdyNetworkTransactionTest, RedirectServerPush) {
2573   const SpdyHeaderInfo kSynStartHeader = spdy_util_.MakeSpdyHeader(SYN_STREAM);
2574
2575   scoped_ptr<SpdyHeaderBlock> headers(
2576       spdy_util_.ConstructGetHeaderBlock("http://www.google.com/"));
2577   (*headers)["user-agent"] = "";
2578   (*headers)["accept-encoding"] = "gzip,deflate";
2579
2580   // Setup writes/reads to www.google.com
2581   scoped_ptr<SpdyFrame> req(
2582       spdy_util_.ConstructSpdyFrame(kSynStartHeader, headers.Pass()));
2583   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2584   scoped_ptr<SpdyFrame> rep(
2585       spdy_util_.ConstructSpdyPush(NULL,
2586                         0,
2587                         2,
2588                         1,
2589                         "http://www.google.com/foo.dat",
2590                         "301 Moved Permanently",
2591                         "http://www.foo.com/index.php"));
2592   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2593   scoped_ptr<SpdyFrame> rst(
2594       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_CANCEL));
2595   MockWrite writes[] = {
2596     CreateMockWrite(*req, 1),
2597     CreateMockWrite(*rst, 6),
2598   };
2599   MockRead reads[] = {
2600     CreateMockRead(*resp, 2),
2601     CreateMockRead(*rep, 3),
2602     CreateMockRead(*body, 4),
2603     MockRead(ASYNC, ERR_IO_PENDING, 5),  // Force a pause
2604     MockRead(ASYNC, 0, 0, 7)  // EOF
2605   };
2606
2607   // Setup writes/reads to www.foo.com
2608   scoped_ptr<SpdyHeaderBlock> headers2(
2609       spdy_util_.ConstructGetHeaderBlock("http://www.foo.com/index.php"));
2610   (*headers2)["user-agent"] = "";
2611   (*headers2)["accept-encoding"] = "gzip,deflate";
2612   scoped_ptr<SpdyFrame> req2(
2613       spdy_util_.ConstructSpdyFrame(kSynStartHeader, headers2.Pass()));
2614   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2615   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
2616   MockWrite writes2[] = {
2617     CreateMockWrite(*req2, 1),
2618   };
2619   MockRead reads2[] = {
2620     CreateMockRead(*resp2, 2),
2621     CreateMockRead(*body2, 3),
2622     MockRead(ASYNC, 0, 0, 5)  // EOF
2623   };
2624   OrderedSocketData data(reads, arraysize(reads),
2625                          writes, arraysize(writes));
2626   OrderedSocketData data2(reads2, arraysize(reads2),
2627                           writes2, arraysize(writes2));
2628
2629   // TODO(erikchen): Make test support SPDYSSL, SPDYNPN
2630   HttpStreamFactory::set_force_spdy_over_ssl(false);
2631   HttpStreamFactory::set_force_spdy_always(true);
2632   TestDelegate d;
2633   TestDelegate d2;
2634   SpdyURLRequestContext spdy_url_request_context(GetParam().protocol);
2635   {
2636     net::URLRequest r(GURL("http://www.google.com/"),
2637                       DEFAULT_PRIORITY,
2638                       &d,
2639                       &spdy_url_request_context);
2640     spdy_url_request_context.socket_factory().
2641         AddSocketDataProvider(&data);
2642
2643     r.Start();
2644     base::RunLoop().Run();
2645
2646     EXPECT_EQ(0, d.received_redirect_count());
2647     std::string contents("hello!");
2648     EXPECT_EQ(contents, d.data_received());
2649
2650     net::URLRequest r2(GURL("http://www.google.com/foo.dat"),
2651                        DEFAULT_PRIORITY,
2652                        &d2,
2653                        &spdy_url_request_context);
2654     spdy_url_request_context.socket_factory().
2655         AddSocketDataProvider(&data2);
2656
2657     d2.set_quit_on_redirect(true);
2658     r2.Start();
2659     base::RunLoop().Run();
2660     EXPECT_EQ(1, d2.received_redirect_count());
2661
2662     r2.FollowDeferredRedirect();
2663     base::RunLoop().Run();
2664     EXPECT_EQ(1, d2.response_started_count());
2665     EXPECT_FALSE(d2.received_data_before_response());
2666     EXPECT_EQ(net::URLRequestStatus::SUCCESS, r2.status().status());
2667     std::string contents2("hello!");
2668     EXPECT_EQ(contents2, d2.data_received());
2669   }
2670   data.CompleteRead();
2671   data2.CompleteRead();
2672   EXPECT_TRUE(data.at_read_eof());
2673   EXPECT_TRUE(data.at_write_eof());
2674   EXPECT_TRUE(data2.at_read_eof());
2675   EXPECT_TRUE(data2.at_write_eof());
2676 }
2677
2678 TEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame) {
2679   scoped_ptr<SpdyFrame> stream1_syn(
2680       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2681   scoped_ptr<SpdyFrame> stream1_body(
2682       spdy_util_.ConstructSpdyBodyFrame(1, true));
2683   MockWrite writes[] = {
2684     CreateMockWrite(*stream1_syn, 1),
2685   };
2686
2687   scoped_ptr<SpdyFrame>
2688       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2689   scoped_ptr<SpdyFrame>
2690       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
2691                                     0,
2692                                     2,
2693                                     1,
2694                                     "http://www.google.com/foo.dat"));
2695   const char kPushedData[] = "pushed";
2696   scoped_ptr<SpdyFrame> stream2_body(
2697       spdy_util_.ConstructSpdyBodyFrame(
2698           2, kPushedData, strlen(kPushedData), true));
2699   MockRead reads[] = {
2700     CreateMockRead(*stream1_reply, 2),
2701     CreateMockRead(*stream2_syn, 3),
2702     CreateMockRead(*stream1_body, 4, SYNCHRONOUS),
2703     CreateMockRead(*stream2_body, 5),
2704     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
2705   };
2706
2707   HttpResponseInfo response;
2708   HttpResponseInfo response2;
2709   std::string expected_push_result("pushed");
2710   OrderedSocketData data(reads, arraysize(reads),
2711                          writes, arraysize(writes));
2712   RunServerPushTest(&data,
2713                     &response,
2714                     &response2,
2715                     expected_push_result);
2716
2717   // Verify the SYN_REPLY.
2718   EXPECT_TRUE(response.headers.get() != NULL);
2719   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
2720
2721   // Verify the pushed stream.
2722   EXPECT_TRUE(response2.headers.get() != NULL);
2723   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
2724 }
2725
2726 TEST_P(SpdyNetworkTransactionTest, ServerPushBeforeSynReply) {
2727   scoped_ptr<SpdyFrame> stream1_syn(
2728       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2729   scoped_ptr<SpdyFrame> stream1_body(
2730       spdy_util_.ConstructSpdyBodyFrame(1, true));
2731   MockWrite writes[] = {
2732     CreateMockWrite(*stream1_syn, 1),
2733   };
2734
2735   scoped_ptr<SpdyFrame>
2736       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2737   scoped_ptr<SpdyFrame>
2738       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
2739                                     0,
2740                                     2,
2741                                     1,
2742                                     "http://www.google.com/foo.dat"));
2743   const char kPushedData[] = "pushed";
2744   scoped_ptr<SpdyFrame> stream2_body(
2745       spdy_util_.ConstructSpdyBodyFrame(
2746           2, kPushedData, strlen(kPushedData), true));
2747   MockRead reads[] = {
2748     CreateMockRead(*stream2_syn, 2),
2749     CreateMockRead(*stream1_reply, 3),
2750     CreateMockRead(*stream1_body, 4, SYNCHRONOUS),
2751     CreateMockRead(*stream2_body, 5),
2752     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
2753   };
2754
2755   HttpResponseInfo response;
2756   HttpResponseInfo response2;
2757   std::string expected_push_result("pushed");
2758   OrderedSocketData data(reads, arraysize(reads),
2759                          writes, arraysize(writes));
2760   RunServerPushTest(&data,
2761                     &response,
2762                     &response2,
2763                     expected_push_result);
2764
2765   // Verify the SYN_REPLY.
2766   EXPECT_TRUE(response.headers.get() != NULL);
2767   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
2768
2769   // Verify the pushed stream.
2770   EXPECT_TRUE(response2.headers.get() != NULL);
2771   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
2772 }
2773
2774 TEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame2) {
2775   scoped_ptr<SpdyFrame> stream1_syn(
2776       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2777   MockWrite writes[] = { CreateMockWrite(*stream1_syn, 1), };
2778
2779   scoped_ptr<SpdyFrame>
2780       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2781   scoped_ptr<SpdyFrame>
2782       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
2783                                     0,
2784                                     2,
2785                                     1,
2786                                     "http://www.google.com/foo.dat"));
2787   const char kPushedData[] = "pushed";
2788   scoped_ptr<SpdyFrame> stream2_body(
2789       spdy_util_.ConstructSpdyBodyFrame(
2790           2, kPushedData, strlen(kPushedData), true));
2791   scoped_ptr<SpdyFrame>
2792       stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2793   MockRead reads[] = {
2794     CreateMockRead(*stream1_reply, 2),
2795     CreateMockRead(*stream2_syn, 3),
2796     CreateMockRead(*stream2_body, 4),
2797     CreateMockRead(*stream1_body, 5, SYNCHRONOUS),
2798     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
2799   };
2800
2801   HttpResponseInfo response;
2802   HttpResponseInfo response2;
2803   std::string expected_push_result("pushed");
2804   OrderedSocketData data(reads, arraysize(reads),
2805                          writes, arraysize(writes));
2806   RunServerPushTest(&data,
2807                     &response,
2808                     &response2,
2809                     expected_push_result);
2810
2811   // Verify the SYN_REPLY.
2812   EXPECT_TRUE(response.headers.get() != NULL);
2813   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
2814
2815   // Verify the pushed stream.
2816   EXPECT_TRUE(response2.headers.get() != NULL);
2817   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
2818 }
2819
2820 TEST_P(SpdyNetworkTransactionTest, ServerPushServerAborted) {
2821   scoped_ptr<SpdyFrame> stream1_syn(
2822       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2823   scoped_ptr<SpdyFrame> stream1_body(
2824       spdy_util_.ConstructSpdyBodyFrame(1, true));
2825   MockWrite writes[] = {
2826     CreateMockWrite(*stream1_syn, 1),
2827   };
2828
2829   scoped_ptr<SpdyFrame>
2830       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2831   scoped_ptr<SpdyFrame>
2832       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
2833                                     0,
2834                                     2,
2835                                     1,
2836                                     "http://www.google.com/foo.dat"));
2837   scoped_ptr<SpdyFrame> stream2_rst(
2838       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR));
2839   MockRead reads[] = {
2840     CreateMockRead(*stream1_reply, 2),
2841     CreateMockRead(*stream2_syn, 3),
2842     CreateMockRead(*stream2_rst, 4),
2843     CreateMockRead(*stream1_body, 5, SYNCHRONOUS),
2844     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
2845   };
2846
2847   OrderedSocketData data(reads, arraysize(reads),
2848                          writes, arraysize(writes));
2849   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2850                                      BoundNetLog(), GetParam(), NULL);
2851
2852   helper.RunPreTestSetup();
2853   helper.AddData(&data);
2854
2855   HttpNetworkTransaction* trans = helper.trans();
2856
2857   // Start the transaction with basic parameters.
2858   TestCompletionCallback callback;
2859   int rv = trans->Start(
2860       &CreateGetRequest(), callback.callback(), BoundNetLog());
2861   EXPECT_EQ(ERR_IO_PENDING, rv);
2862   rv = callback.WaitForResult();
2863   EXPECT_EQ(OK, rv);
2864
2865   // Verify that we consumed all test data.
2866   EXPECT_TRUE(data.at_read_eof()) << "Read count: "
2867                                    << data.read_count()
2868                                    << " Read index: "
2869                                    << data.read_index();
2870   EXPECT_TRUE(data.at_write_eof()) << "Write count: "
2871                                     << data.write_count()
2872                                     << " Write index: "
2873                                     << data.write_index();
2874
2875   // Verify the SYN_REPLY.
2876   HttpResponseInfo response = *trans->GetResponseInfo();
2877   EXPECT_TRUE(response.headers.get() != NULL);
2878   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
2879 }
2880
2881 // Verify that we don't leak streams and that we properly send a reset
2882 // if the server pushes the same stream twice.
2883 TEST_P(SpdyNetworkTransactionTest, ServerPushDuplicate) {
2884   scoped_ptr<SpdyFrame> stream1_syn(
2885       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2886   scoped_ptr<SpdyFrame> stream1_body(
2887       spdy_util_.ConstructSpdyBodyFrame(1, true));
2888   scoped_ptr<SpdyFrame> stream3_rst(
2889       spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_PROTOCOL_ERROR));
2890   MockWrite writes[] = {
2891     CreateMockWrite(*stream1_syn, 1),
2892     CreateMockWrite(*stream3_rst, 5),
2893   };
2894
2895   scoped_ptr<SpdyFrame>
2896       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2897   scoped_ptr<SpdyFrame>
2898       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
2899                                     0,
2900                                     2,
2901                                     1,
2902                                     "http://www.google.com/foo.dat"));
2903   const char kPushedData[] = "pushed";
2904   scoped_ptr<SpdyFrame> stream2_body(
2905       spdy_util_.ConstructSpdyBodyFrame(
2906           2, kPushedData, strlen(kPushedData), true));
2907   scoped_ptr<SpdyFrame>
2908       stream3_syn(spdy_util_.ConstructSpdyPush(NULL,
2909                                     0,
2910                                     4,
2911                                     1,
2912                                     "http://www.google.com/foo.dat"));
2913   MockRead reads[] = {
2914     CreateMockRead(*stream1_reply, 2),
2915     CreateMockRead(*stream2_syn, 3),
2916     CreateMockRead(*stream3_syn, 4),
2917     CreateMockRead(*stream1_body, 6, SYNCHRONOUS),
2918     CreateMockRead(*stream2_body, 7),
2919     MockRead(ASYNC, ERR_IO_PENDING, 8),  // Force a pause
2920   };
2921
2922   HttpResponseInfo response;
2923   HttpResponseInfo response2;
2924   std::string expected_push_result("pushed");
2925   OrderedSocketData data(reads, arraysize(reads),
2926                          writes, arraysize(writes));
2927   RunServerPushTest(&data,
2928                     &response,
2929                     &response2,
2930                     expected_push_result);
2931
2932   // Verify the SYN_REPLY.
2933   EXPECT_TRUE(response.headers.get() != NULL);
2934   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
2935
2936   // Verify the pushed stream.
2937   EXPECT_TRUE(response2.headers.get() != NULL);
2938   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
2939 }
2940
2941 TEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrame) {
2942   scoped_ptr<SpdyFrame> stream1_syn(
2943       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2944   scoped_ptr<SpdyFrame> stream1_body(
2945       spdy_util_.ConstructSpdyBodyFrame(1, true));
2946   MockWrite writes[] = {
2947     CreateMockWrite(*stream1_syn, 1),
2948   };
2949
2950   scoped_ptr<SpdyFrame>
2951       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2952   scoped_ptr<SpdyFrame>
2953       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
2954                                     0,
2955                                     2,
2956                                     1,
2957                                     "http://www.google.com/foo.dat"));
2958   static const char kPushedData[] = "pushed my darling hello my baby";
2959   scoped_ptr<SpdyFrame> stream2_body_base(
2960       spdy_util_.ConstructSpdyBodyFrame(
2961           2, kPushedData, strlen(kPushedData), true));
2962   const size_t kChunkSize = strlen(kPushedData) / 4;
2963   scoped_ptr<SpdyFrame> stream2_body1(
2964       new SpdyFrame(stream2_body_base->data(), kChunkSize, false));
2965   scoped_ptr<SpdyFrame> stream2_body2(
2966       new SpdyFrame(stream2_body_base->data() + kChunkSize, kChunkSize, false));
2967   scoped_ptr<SpdyFrame> stream2_body3(
2968       new SpdyFrame(stream2_body_base->data() + 2 * kChunkSize,
2969                     kChunkSize, false));
2970   scoped_ptr<SpdyFrame> stream2_body4(
2971       new SpdyFrame(stream2_body_base->data() + 3 * kChunkSize,
2972                     stream2_body_base->size() - 3 * kChunkSize, false));
2973   MockRead reads[] = {
2974     CreateMockRead(*stream1_reply, 2),
2975     CreateMockRead(*stream2_syn, 3),
2976     CreateMockRead(*stream2_body1, 4),
2977     CreateMockRead(*stream2_body2, 5),
2978     CreateMockRead(*stream2_body3, 6),
2979     CreateMockRead(*stream2_body4, 7),
2980     CreateMockRead(*stream1_body, 8, SYNCHRONOUS),
2981     MockRead(ASYNC, ERR_IO_PENDING, 9),  // Force a pause
2982   };
2983
2984   HttpResponseInfo response;
2985   HttpResponseInfo response2;
2986   std::string expected_push_result("pushed my darling hello my baby");
2987   OrderedSocketData data(reads, arraysize(reads),
2988                          writes, arraysize(writes));
2989   RunServerPushTest(&data, &response, &response2, kPushedData);
2990
2991   // Verify the SYN_REPLY.
2992   EXPECT_TRUE(response.headers.get() != NULL);
2993   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
2994
2995   // Verify the pushed stream.
2996   EXPECT_TRUE(response2.headers.get() != NULL);
2997   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
2998 }
2999
3000 TEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrameInterrupted) {
3001   scoped_ptr<SpdyFrame> stream1_syn(
3002       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3003   scoped_ptr<SpdyFrame> stream1_body(
3004       spdy_util_.ConstructSpdyBodyFrame(1, true));
3005   MockWrite writes[] = {
3006     CreateMockWrite(*stream1_syn, 1),
3007   };
3008
3009   scoped_ptr<SpdyFrame>
3010       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3011   scoped_ptr<SpdyFrame>
3012       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
3013                                     0,
3014                                     2,
3015                                     1,
3016                                     "http://www.google.com/foo.dat"));
3017   static const char kPushedData[] = "pushed my darling hello my baby";
3018   scoped_ptr<SpdyFrame> stream2_body_base(
3019       spdy_util_.ConstructSpdyBodyFrame(
3020           2, kPushedData, strlen(kPushedData), true));
3021   const size_t kChunkSize = strlen(kPushedData) / 4;
3022   scoped_ptr<SpdyFrame> stream2_body1(
3023       new SpdyFrame(stream2_body_base->data(), kChunkSize, false));
3024   scoped_ptr<SpdyFrame> stream2_body2(
3025       new SpdyFrame(stream2_body_base->data() + kChunkSize, kChunkSize, false));
3026   scoped_ptr<SpdyFrame> stream2_body3(
3027       new SpdyFrame(stream2_body_base->data() + 2 * kChunkSize,
3028                     kChunkSize, false));
3029   scoped_ptr<SpdyFrame> stream2_body4(
3030       new SpdyFrame(stream2_body_base->data() + 3 * kChunkSize,
3031                     stream2_body_base->size() - 3 * kChunkSize, false));
3032   MockRead reads[] = {
3033     CreateMockRead(*stream1_reply, 2),
3034     CreateMockRead(*stream2_syn, 3),
3035     CreateMockRead(*stream2_body1, 4),
3036     CreateMockRead(*stream2_body2, 5),
3037     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
3038     CreateMockRead(*stream2_body3, 7),
3039     CreateMockRead(*stream2_body4, 8),
3040     CreateMockRead(*stream1_body.get(), 9, SYNCHRONOUS),
3041     MockRead(ASYNC, ERR_IO_PENDING, 10)  // Force a pause.
3042   };
3043
3044   HttpResponseInfo response;
3045   HttpResponseInfo response2;
3046   OrderedSocketData data(reads, arraysize(reads),
3047                          writes, arraysize(writes));
3048   RunServerPushTest(&data, &response, &response2, kPushedData);
3049
3050   // Verify the SYN_REPLY.
3051   EXPECT_TRUE(response.headers.get() != NULL);
3052   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
3053
3054   // Verify the pushed stream.
3055   EXPECT_TRUE(response2.headers.get() != NULL);
3056   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
3057 }
3058
3059 TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID0) {
3060   if (spdy_util_.spdy_version() == SPDY4) {
3061     // TODO(jgraettinger): We don't support associated stream
3062     // checks in SPDY4 yet.
3063     return;
3064   }
3065   scoped_ptr<SpdyFrame> stream1_syn(
3066       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3067   scoped_ptr<SpdyFrame> stream1_body(
3068       spdy_util_.ConstructSpdyBodyFrame(1, true));
3069   scoped_ptr<SpdyFrame> stream2_rst(
3070       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
3071   MockWrite writes[] = {
3072     CreateMockWrite(*stream1_syn, 1),
3073     CreateMockWrite(*stream2_rst, 4),
3074   };
3075
3076   scoped_ptr<SpdyFrame>
3077       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3078   scoped_ptr<SpdyFrame>
3079       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
3080                                     0,
3081                                     2,
3082                                     0,
3083                                     "http://www.google.com/foo.dat"));
3084   MockRead reads[] = {
3085     CreateMockRead(*stream1_reply, 2),
3086     CreateMockRead(*stream2_syn, 3),
3087     CreateMockRead(*stream1_body, 4),
3088     MockRead(ASYNC, ERR_IO_PENDING, 5)  // Force a pause
3089   };
3090
3091   OrderedSocketData data(reads, arraysize(reads),
3092                          writes, arraysize(writes));
3093   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3094                                      BoundNetLog(), GetParam(), NULL);
3095
3096   helper.RunPreTestSetup();
3097   helper.AddData(&data);
3098
3099   HttpNetworkTransaction* trans = helper.trans();
3100
3101   // Start the transaction with basic parameters.
3102   TestCompletionCallback callback;
3103   int rv = trans->Start(
3104       &CreateGetRequest(), callback.callback(), BoundNetLog());
3105   EXPECT_EQ(ERR_IO_PENDING, rv);
3106   rv = callback.WaitForResult();
3107   EXPECT_EQ(OK, rv);
3108
3109   // Verify that we consumed all test data.
3110   EXPECT_TRUE(data.at_read_eof()) << "Read count: "
3111                                    << data.read_count()
3112                                    << " Read index: "
3113                                    << data.read_index();
3114   EXPECT_TRUE(data.at_write_eof()) << "Write count: "
3115                                     << data.write_count()
3116                                     << " Write index: "
3117                                     << data.write_index();
3118
3119   // Verify the SYN_REPLY.
3120   HttpResponseInfo response = *trans->GetResponseInfo();
3121   EXPECT_TRUE(response.headers.get() != NULL);
3122   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
3123 }
3124
3125 TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID9) {
3126   if (spdy_util_.spdy_version() == SPDY4) {
3127     // TODO(jgraettinger): We don't support associated stream
3128     // checks in SPDY4 yet.
3129     return;
3130   }
3131   scoped_ptr<SpdyFrame> stream1_syn(
3132       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3133   scoped_ptr<SpdyFrame> stream1_body(
3134       spdy_util_.ConstructSpdyBodyFrame(1, true));
3135   scoped_ptr<SpdyFrame> stream2_rst(
3136       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_INVALID_STREAM));
3137   MockWrite writes[] = {
3138     CreateMockWrite(*stream1_syn, 1),
3139     CreateMockWrite(*stream2_rst, 4),
3140   };
3141
3142   scoped_ptr<SpdyFrame>
3143       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3144   scoped_ptr<SpdyFrame>
3145       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
3146                                     0,
3147                                     2,
3148                                     9,
3149                                     "http://www.google.com/foo.dat"));
3150   MockRead reads[] = {
3151     CreateMockRead(*stream1_reply, 2),
3152     CreateMockRead(*stream2_syn, 3),
3153     CreateMockRead(*stream1_body, 4),
3154     MockRead(ASYNC, ERR_IO_PENDING, 5),  // Force a pause
3155   };
3156
3157   OrderedSocketData data(reads, arraysize(reads),
3158                          writes, arraysize(writes));
3159   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3160                                      BoundNetLog(), GetParam(), NULL);
3161
3162   helper.RunPreTestSetup();
3163   helper.AddData(&data);
3164
3165   HttpNetworkTransaction* trans = helper.trans();
3166
3167   // Start the transaction with basic parameters.
3168   TestCompletionCallback callback;
3169   int rv = trans->Start(
3170       &CreateGetRequest(), callback.callback(), BoundNetLog());
3171   EXPECT_EQ(ERR_IO_PENDING, rv);
3172   rv = callback.WaitForResult();
3173   EXPECT_EQ(OK, rv);
3174
3175   // Verify that we consumed all test data.
3176   EXPECT_TRUE(data.at_read_eof()) << "Read count: "
3177                                    << data.read_count()
3178                                    << " Read index: "
3179                                    << data.read_index();
3180   EXPECT_TRUE(data.at_write_eof()) << "Write count: "
3181                                     << data.write_count()
3182                                     << " Write index: "
3183                                     << data.write_index();
3184
3185   // Verify the SYN_REPLY.
3186   HttpResponseInfo response = *trans->GetResponseInfo();
3187   EXPECT_TRUE(response.headers.get() != NULL);
3188   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
3189 }
3190
3191 TEST_P(SpdyNetworkTransactionTest, ServerPushNoURL) {
3192   scoped_ptr<SpdyFrame> stream1_syn(
3193       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3194   scoped_ptr<SpdyFrame> stream1_body(
3195       spdy_util_.ConstructSpdyBodyFrame(1, true));
3196   scoped_ptr<SpdyFrame> stream2_rst(
3197       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR));
3198   MockWrite writes[] = {
3199     CreateMockWrite(*stream1_syn, 1),
3200     CreateMockWrite(*stream2_rst, 4),
3201   };
3202
3203   scoped_ptr<SpdyFrame>
3204       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3205   scoped_ptr<SpdyHeaderBlock> incomplete_headers(new SpdyHeaderBlock());
3206   (*incomplete_headers)["hello"] = "bye";
3207   (*incomplete_headers)[spdy_util_.GetStatusKey()] = "200 OK";
3208   (*incomplete_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
3209   scoped_ptr<SpdyFrame> stream2_syn(
3210       spdy_util_.ConstructSpdyControlFrame(incomplete_headers.Pass(),
3211                                            false,
3212                                            2,  // Stream ID
3213                                            LOWEST,
3214                                            SYN_STREAM,
3215                                            CONTROL_FLAG_NONE,
3216                                            // Associated stream ID
3217                                            1));
3218   MockRead reads[] = {
3219     CreateMockRead(*stream1_reply, 2),
3220     CreateMockRead(*stream2_syn, 3),
3221     CreateMockRead(*stream1_body, 4),
3222     MockRead(ASYNC, ERR_IO_PENDING, 5)  // Force a pause
3223   };
3224
3225   OrderedSocketData data(reads, arraysize(reads),
3226                          writes, arraysize(writes));
3227   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3228                                      BoundNetLog(), GetParam(), NULL);
3229
3230   helper.RunPreTestSetup();
3231   helper.AddData(&data);
3232
3233   HttpNetworkTransaction* trans = helper.trans();
3234
3235   // Start the transaction with basic parameters.
3236   TestCompletionCallback callback;
3237   int rv = trans->Start(
3238       &CreateGetRequest(), callback.callback(), BoundNetLog());
3239   EXPECT_EQ(ERR_IO_PENDING, rv);
3240   rv = callback.WaitForResult();
3241   EXPECT_EQ(OK, rv);
3242   // Verify that we consumed all test data.
3243   EXPECT_TRUE(data.at_read_eof()) << "Read count: "
3244                                    << data.read_count()
3245                                    << " Read index: "
3246                                    << data.read_index();
3247   EXPECT_TRUE(data.at_write_eof()) << "Write count: "
3248                                     << data.write_count()
3249                                     << " Write index: "
3250                                     << data.write_index();
3251
3252   // Verify the SYN_REPLY.
3253   HttpResponseInfo response = *trans->GetResponseInfo();
3254   EXPECT_TRUE(response.headers.get() != NULL);
3255   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
3256 }
3257
3258 // Verify that various SynReply headers parse correctly through the
3259 // HTTP layer.
3260 TEST_P(SpdyNetworkTransactionTest, SynReplyHeaders) {
3261   struct SynReplyHeadersTests {
3262     int num_headers;
3263     const char* extra_headers[5];
3264     SpdyHeaderBlock expected_headers;
3265   } test_cases[] = {
3266     // This uses a multi-valued cookie header.
3267     { 2,
3268       { "cookie", "val1",
3269         "cookie", "val2",  // will get appended separated by NULL
3270         NULL
3271       },
3272     },
3273     // This is the minimalist set of headers.
3274     { 0,
3275       { NULL },
3276     },
3277     // Headers with a comma separated list.
3278     { 1,
3279       { "cookie", "val1,val2",
3280         NULL
3281       },
3282     }
3283   };
3284
3285   test_cases[0].expected_headers["cookie"] = "val1";
3286   test_cases[0].expected_headers["cookie"] += '\0';
3287   test_cases[0].expected_headers["cookie"] += "val2";
3288   test_cases[0].expected_headers["hello"] = "bye";
3289   test_cases[0].expected_headers["status"] = "200";
3290   test_cases[0].expected_headers["version"] = "HTTP/1.1";
3291
3292   test_cases[1].expected_headers["hello"] = "bye";
3293   test_cases[1].expected_headers["status"] = "200";
3294   test_cases[1].expected_headers["version"] = "HTTP/1.1";
3295
3296   test_cases[2].expected_headers["cookie"] = "val1,val2";
3297   test_cases[2].expected_headers["hello"] = "bye";
3298   test_cases[2].expected_headers["status"] = "200";
3299   test_cases[2].expected_headers["version"] = "HTTP/1.1";
3300
3301   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
3302     scoped_ptr<SpdyFrame> req(
3303         spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3304     MockWrite writes[] = { CreateMockWrite(*req) };
3305
3306     scoped_ptr<SpdyFrame> resp(
3307         spdy_util_.ConstructSpdyGetSynReply(test_cases[i].extra_headers,
3308                                  test_cases[i].num_headers,
3309                                  1));
3310     scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3311     MockRead reads[] = {
3312       CreateMockRead(*resp),
3313       CreateMockRead(*body),
3314       MockRead(ASYNC, 0, 0)  // EOF
3315     };
3316
3317     DelayedSocketData data(1, reads, arraysize(reads),
3318                            writes, arraysize(writes));
3319     NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3320                                        BoundNetLog(), GetParam(), NULL);
3321     helper.RunToCompletion(&data);
3322     TransactionHelperResult out = helper.output();
3323
3324     EXPECT_EQ(OK, out.rv);
3325     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
3326     EXPECT_EQ("hello!", out.response_data);
3327
3328     scoped_refptr<HttpResponseHeaders> headers = out.response_info.headers;
3329     EXPECT_TRUE(headers.get() != NULL);
3330     void* iter = NULL;
3331     std::string name, value;
3332     SpdyHeaderBlock header_block;
3333     while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
3334       if (header_block[name].empty()) {
3335         header_block[name] = value;
3336       } else {
3337         header_block[name] += '\0';
3338         header_block[name] += value;
3339       }
3340     }
3341     EXPECT_EQ(test_cases[i].expected_headers, header_block);
3342   }
3343 }
3344
3345 // Verify that various SynReply headers parse vary fields correctly
3346 // through the HTTP layer, and the response matches the request.
3347 TEST_P(SpdyNetworkTransactionTest, SynReplyHeadersVary) {
3348   static const SpdyHeaderInfo syn_reply_info = {
3349     SYN_REPLY,                              // Syn Reply
3350     1,                                      // Stream ID
3351     0,                                      // Associated Stream ID
3352     ConvertRequestPriorityToSpdyPriority(
3353         LOWEST, spdy_util_.spdy_version()),
3354     kSpdyCredentialSlotUnused,
3355     CONTROL_FLAG_NONE,                      // Control Flags
3356     false,                                  // Compressed
3357     RST_STREAM_INVALID,                     // Status
3358     NULL,                                   // Data
3359     0,                                      // Data Length
3360     DATA_FLAG_NONE                          // Data Flags
3361   };
3362   // Modify the following data to change/add test cases:
3363   struct SynReplyTests {
3364     const SpdyHeaderInfo* syn_reply;
3365     bool vary_matches;
3366     int num_headers[2];
3367     const char* extra_headers[2][16];
3368   } test_cases[] = {
3369     // Test the case of a multi-valued cookie.  When the value is delimited
3370     // with NUL characters, it needs to be unfolded into multiple headers.
3371     {
3372       &syn_reply_info,
3373       true,
3374       { 1, 4 },
3375       { { "cookie",   "val1,val2",
3376           NULL
3377         },
3378         { "vary",     "cookie",
3379           spdy_util_.GetStatusKey(), "200",
3380           spdy_util_.GetPathKey(),      "/index.php",
3381           spdy_util_.GetVersionKey(), "HTTP/1.1",
3382           NULL
3383         }
3384       }
3385     }, {    // Multiple vary fields.
3386       &syn_reply_info,
3387       true,
3388       { 2, 5 },
3389       { { "friend",   "barney",
3390           "enemy",    "snaggletooth",
3391           NULL
3392         },
3393         { "vary",     "friend",
3394           "vary",     "enemy",
3395           spdy_util_.GetStatusKey(), "200",
3396           spdy_util_.GetPathKey(),      "/index.php",
3397           spdy_util_.GetVersionKey(), "HTTP/1.1",
3398           NULL
3399         }
3400       }
3401     }, {    // Test a '*' vary field.
3402       &syn_reply_info,
3403       false,
3404       { 1, 4 },
3405       { { "cookie",   "val1,val2",
3406           NULL
3407         },
3408         { "vary",     "*",
3409           spdy_util_.GetStatusKey(), "200",
3410           spdy_util_.GetPathKey(),      "/index.php",
3411           spdy_util_.GetVersionKey(), "HTTP/1.1",
3412           NULL
3413         }
3414       }
3415     }, {    // Multiple comma-separated vary fields.
3416       &syn_reply_info,
3417       true,
3418       { 2, 4 },
3419       { { "friend",   "barney",
3420           "enemy",    "snaggletooth",
3421           NULL
3422         },
3423         { "vary",     "friend,enemy",
3424           spdy_util_.GetStatusKey(), "200",
3425           spdy_util_.GetPathKey(),      "/index.php",
3426           spdy_util_.GetVersionKey(), "HTTP/1.1",
3427           NULL
3428         }
3429       }
3430     }
3431   };
3432
3433   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
3434     // Construct the request.
3435     scoped_ptr<SpdyFrame> frame_req(
3436         spdy_util_.ConstructSpdyGet(test_cases[i].extra_headers[0],
3437                                     test_cases[i].num_headers[0],
3438                                     false, 1, LOWEST, true));
3439
3440     MockWrite writes[] = {
3441       CreateMockWrite(*frame_req),
3442     };
3443
3444     // Construct the reply.
3445     scoped_ptr<SpdyFrame> frame_reply(
3446       spdy_util_.ConstructSpdyFrame(*test_cases[i].syn_reply,
3447                                     test_cases[i].extra_headers[1],
3448                                     test_cases[i].num_headers[1],
3449                                     NULL,
3450                                     0));
3451
3452     scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3453     MockRead reads[] = {
3454       CreateMockRead(*frame_reply),
3455       CreateMockRead(*body),
3456       MockRead(ASYNC, 0, 0)  // EOF
3457     };
3458
3459     // Attach the headers to the request.
3460     int header_count = test_cases[i].num_headers[0];
3461
3462     HttpRequestInfo request = CreateGetRequest();
3463     for (int ct = 0; ct < header_count; ct++) {
3464       const char* header_key = test_cases[i].extra_headers[0][ct * 2];
3465       const char* header_value = test_cases[i].extra_headers[0][ct * 2 + 1];
3466       request.extra_headers.SetHeader(header_key, header_value);
3467     }
3468
3469     DelayedSocketData data(1, reads, arraysize(reads),
3470                            writes, arraysize(writes));
3471     NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
3472                                        BoundNetLog(), GetParam(), NULL);
3473     helper.RunToCompletion(&data);
3474     TransactionHelperResult out = helper.output();
3475
3476     EXPECT_EQ(OK, out.rv) << i;
3477     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line) << i;
3478     EXPECT_EQ("hello!", out.response_data) << i;
3479
3480     // Test the response information.
3481     EXPECT_TRUE(out.response_info.response_time >
3482                 out.response_info.request_time) << i;
3483     base::TimeDelta test_delay = out.response_info.response_time -
3484                                  out.response_info.request_time;
3485     base::TimeDelta min_expected_delay;
3486     min_expected_delay.FromMilliseconds(10);
3487     EXPECT_GT(test_delay.InMillisecondsF(),
3488               min_expected_delay.InMillisecondsF()) << i;
3489     EXPECT_EQ(out.response_info.vary_data.is_valid(),
3490               test_cases[i].vary_matches) << i;
3491
3492     // Check the headers.
3493     scoped_refptr<HttpResponseHeaders> headers = out.response_info.headers;
3494     ASSERT_TRUE(headers.get() != NULL) << i;
3495     void* iter = NULL;
3496     std::string name, value, lines;
3497     while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
3498       lines.append(name);
3499       lines.append(": ");
3500       lines.append(value);
3501       lines.append("\n");
3502     }
3503
3504     // Construct the expected header reply string.
3505     SpdyHeaderBlock reply_headers;
3506     AppendToHeaderBlock(test_cases[i].extra_headers[1],
3507                         test_cases[i].num_headers[1],
3508                         &reply_headers);
3509     std::string expected_reply =
3510         spdy_util_.ConstructSpdyReplyString(reply_headers);
3511     EXPECT_EQ(expected_reply, lines) << i;
3512   }
3513 }
3514
3515 // Verify that we don't crash on invalid SynReply responses.
3516 TEST_P(SpdyNetworkTransactionTest, InvalidSynReply) {
3517   const SpdyHeaderInfo kSynStartHeader = {
3518     SYN_REPLY,              // Kind = SynReply
3519     1,                      // Stream ID
3520     0,                      // Associated stream ID
3521     ConvertRequestPriorityToSpdyPriority(
3522         LOWEST, spdy_util_.spdy_version()),
3523     kSpdyCredentialSlotUnused,
3524     CONTROL_FLAG_NONE,      // Control Flags
3525     false,                  // Compressed
3526     RST_STREAM_INVALID,     // Status
3527     NULL,                   // Data
3528     0,                      // Length
3529     DATA_FLAG_NONE          // Data Flags
3530   };
3531
3532   struct InvalidSynReplyTests {
3533     int num_headers;
3534     const char* headers[10];
3535   } test_cases[] = {
3536     // SYN_REPLY missing status header
3537     { 4,
3538       { "cookie", "val1",
3539         "cookie", "val2",
3540         spdy_util_.GetPathKey(), "/index.php",
3541         spdy_util_.GetVersionKey(), "HTTP/1.1",
3542         NULL
3543       },
3544     },
3545     // SYN_REPLY missing version header
3546     { 2,
3547       { "status", "200",
3548         spdy_util_.GetPathKey(), "/index.php",
3549         NULL
3550       },
3551     },
3552     // SYN_REPLY with no headers
3553     { 0, { NULL }, },
3554   };
3555
3556   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
3557     scoped_ptr<SpdyFrame> req(
3558         spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3559     scoped_ptr<SpdyFrame> rst(
3560       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
3561     MockWrite writes[] = {
3562       CreateMockWrite(*req),
3563       CreateMockWrite(*rst),
3564     };
3565
3566     scoped_ptr<SpdyFrame> resp(
3567        spdy_util_.ConstructSpdyFrame(kSynStartHeader,
3568                                      NULL, 0,
3569                                      test_cases[i].headers,
3570                                      test_cases[i].num_headers));
3571     scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3572     MockRead reads[] = {
3573       CreateMockRead(*resp),
3574       MockRead(ASYNC, 0, 0)  // EOF
3575     };
3576
3577     DelayedSocketData data(1, reads, arraysize(reads),
3578                            writes, arraysize(writes));
3579     NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3580                                        BoundNetLog(), GetParam(), NULL);
3581     helper.RunToCompletion(&data);
3582     TransactionHelperResult out = helper.output();
3583     EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
3584   }
3585 }
3586
3587 // Verify that we don't crash on some corrupt frames.
3588 TEST_P(SpdyNetworkTransactionTest, CorruptFrameSessionError) {
3589   // This is the length field that's too short.
3590   scoped_ptr<SpdyFrame> syn_reply_wrong_length(
3591       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3592   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
3593   size_t right_size =
3594       (spdy_util_.spdy_version() < SPDY4) ?
3595       syn_reply_wrong_length->size() - framer.GetControlFrameHeaderSize() :
3596       syn_reply_wrong_length->size();
3597   size_t wrong_size = right_size - 4;
3598   test::SetFrameLength(syn_reply_wrong_length.get(),
3599                        wrong_size,
3600                        spdy_util_.spdy_version());
3601
3602   struct SynReplyTests {
3603     const SpdyFrame* syn_reply;
3604   } test_cases[] = {
3605     { syn_reply_wrong_length.get(), },
3606   };
3607
3608   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
3609     scoped_ptr<SpdyFrame> req(
3610         spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3611     scoped_ptr<SpdyFrame> rst(
3612         spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
3613     MockWrite writes[] = {
3614       CreateMockWrite(*req),
3615       CreateMockWrite(*rst),
3616     };
3617
3618     scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3619     MockRead reads[] = {
3620       MockRead(ASYNC, test_cases[i].syn_reply->data(), wrong_size),
3621       CreateMockRead(*body),
3622       MockRead(ASYNC, 0, 0)  // EOF
3623     };
3624
3625     DelayedSocketData data(1, reads, arraysize(reads),
3626                            writes, arraysize(writes));
3627     NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3628                                        BoundNetLog(), GetParam(), NULL);
3629     helper.RunToCompletion(&data);
3630     TransactionHelperResult out = helper.output();
3631     EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
3632   }
3633 }
3634
3635 // Test that we shutdown correctly on write errors.
3636 TEST_P(SpdyNetworkTransactionTest, WriteError) {
3637   scoped_ptr<SpdyFrame> req(
3638       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3639   MockWrite writes[] = {
3640     // We'll write 10 bytes successfully
3641     MockWrite(ASYNC, req->data(), 10, 0),
3642     // Followed by ERROR!
3643     MockWrite(ASYNC, ERR_FAILED, 1),
3644   };
3645
3646   MockRead reads[] = {
3647     MockRead(ASYNC, 0, 2)  // EOF
3648   };
3649
3650   DeterministicSocketData data(reads, arraysize(reads),
3651                                writes, arraysize(writes));
3652
3653   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3654                                      BoundNetLog(), GetParam(), NULL);
3655   helper.SetDeterministic();
3656   helper.RunPreTestSetup();
3657   helper.AddDeterministicData(&data);
3658   EXPECT_TRUE(helper.StartDefaultTest());
3659   data.RunFor(2);
3660   helper.FinishDefaultTest();
3661   EXPECT_TRUE(data.at_write_eof());
3662   EXPECT_TRUE(!data.at_read_eof());
3663   TransactionHelperResult out = helper.output();
3664   EXPECT_EQ(ERR_FAILED, out.rv);
3665 }
3666
3667 // Test that partial writes work.
3668 TEST_P(SpdyNetworkTransactionTest, PartialWrite) {
3669   // Chop the SYN_STREAM frame into 5 chunks.
3670   scoped_ptr<SpdyFrame> req(
3671       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3672   const int kChunks = 5;
3673   scoped_ptr<MockWrite[]> writes(ChopWriteFrame(*req.get(), kChunks));
3674
3675   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3676   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3677   MockRead reads[] = {
3678     CreateMockRead(*resp),
3679     CreateMockRead(*body),
3680     MockRead(ASYNC, 0, 0)  // EOF
3681   };
3682
3683   DelayedSocketData data(kChunks, reads, arraysize(reads),
3684                          writes.get(), kChunks);
3685   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3686                                      BoundNetLog(), GetParam(), NULL);
3687   helper.RunToCompletion(&data);
3688   TransactionHelperResult out = helper.output();
3689   EXPECT_EQ(OK, out.rv);
3690   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
3691   EXPECT_EQ("hello!", out.response_data);
3692 }
3693
3694 // In this test, we enable compression, but get a uncompressed SynReply from
3695 // the server.  Verify that teardown is all clean.
3696 TEST_P(SpdyNetworkTransactionTest, DecompressFailureOnSynReply) {
3697   scoped_ptr<SpdyFrame> compressed(
3698       spdy_util_.ConstructSpdyGet(NULL, 0, true, 1, LOWEST, true));
3699   scoped_ptr<SpdyFrame> rst(
3700       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
3701   MockWrite writes[] = {
3702     CreateMockWrite(*compressed),
3703   };
3704
3705   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3706   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3707   MockRead reads[] = {
3708     CreateMockRead(*resp),
3709   };
3710
3711   DelayedSocketData data(1, reads, arraysize(reads),
3712                          writes, arraysize(writes));
3713   SpdySessionDependencies* session_deps =
3714       CreateSpdySessionDependencies(GetParam());
3715   session_deps->enable_compression = true;
3716   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3717                                      BoundNetLog(), GetParam(), session_deps);
3718   helper.RunToCompletion(&data);
3719   TransactionHelperResult out = helper.output();
3720   EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
3721   data.Reset();
3722 }
3723
3724 // Test that the NetLog contains good data for a simple GET request.
3725 TEST_P(SpdyNetworkTransactionTest, NetLog) {
3726   static const char* const kExtraHeaders[] = {
3727     "user-agent",   "Chrome",
3728   };
3729   scoped_ptr<SpdyFrame> req(
3730       spdy_util_.ConstructSpdyGet(kExtraHeaders, 1, false, 1, LOWEST, true));
3731   MockWrite writes[] = { CreateMockWrite(*req) };
3732
3733   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3734   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3735   MockRead reads[] = {
3736     CreateMockRead(*resp),
3737     CreateMockRead(*body),
3738     MockRead(ASYNC, 0, 0)  // EOF
3739   };
3740
3741   CapturingBoundNetLog log;
3742
3743   DelayedSocketData data(1, reads, arraysize(reads),
3744                          writes, arraysize(writes));
3745   NormalSpdyTransactionHelper helper(CreateGetRequestWithUserAgent(),
3746                                      DEFAULT_PRIORITY,
3747                                      log.bound(), GetParam(), NULL);
3748   helper.RunToCompletion(&data);
3749   TransactionHelperResult out = helper.output();
3750   EXPECT_EQ(OK, out.rv);
3751   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
3752   EXPECT_EQ("hello!", out.response_data);
3753
3754   // Check that the NetLog was filled reasonably.
3755   // This test is intentionally non-specific about the exact ordering of the
3756   // log; instead we just check to make sure that certain events exist, and that
3757   // they are in the right order.
3758   net::CapturingNetLog::CapturedEntryList entries;
3759   log.GetEntries(&entries);
3760
3761   EXPECT_LT(0u, entries.size());
3762   int pos = 0;
3763   pos = net::ExpectLogContainsSomewhere(entries, 0,
3764       net::NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST,
3765       net::NetLog::PHASE_BEGIN);
3766   pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
3767       net::NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST,
3768       net::NetLog::PHASE_END);
3769   pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
3770       net::NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS,
3771       net::NetLog::PHASE_BEGIN);
3772   pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
3773       net::NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS,
3774       net::NetLog::PHASE_END);
3775   pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
3776       net::NetLog::TYPE_HTTP_TRANSACTION_READ_BODY,
3777       net::NetLog::PHASE_BEGIN);
3778   pos = net::ExpectLogContainsSomewhere(entries, pos + 1,
3779       net::NetLog::TYPE_HTTP_TRANSACTION_READ_BODY,
3780       net::NetLog::PHASE_END);
3781
3782   // Check that we logged all the headers correctly
3783   pos = net::ExpectLogContainsSomewhere(
3784       entries, 0,
3785       net::NetLog::TYPE_SPDY_SESSION_SYN_STREAM,
3786       net::NetLog::PHASE_NONE);
3787
3788   base::ListValue* header_list;
3789   ASSERT_TRUE(entries[pos].params.get());
3790   ASSERT_TRUE(entries[pos].params->GetList("headers", &header_list));
3791
3792   std::vector<std::string> expected;
3793   expected.push_back(std::string(spdy_util_.GetHostKey()) + ": www.google.com");
3794   expected.push_back(std::string(spdy_util_.GetPathKey()) + ": /");
3795   expected.push_back(std::string(spdy_util_.GetSchemeKey()) + ": http");
3796   expected.push_back(std::string(spdy_util_.GetVersionKey()) + ": HTTP/1.1");
3797   expected.push_back(std::string(spdy_util_.GetMethodKey()) + ": GET");
3798   expected.push_back("user-agent: Chrome");
3799   EXPECT_EQ(expected.size(), header_list->GetSize());
3800   for (std::vector<std::string>::const_iterator it = expected.begin();
3801        it != expected.end();
3802        ++it) {
3803     base::StringValue header(*it);
3804     EXPECT_NE(header_list->end(), header_list->Find(header)) <<
3805         "Header not found: " << *it;
3806   }
3807 }
3808
3809 // Since we buffer the IO from the stream to the renderer, this test verifies
3810 // that when we read out the maximum amount of data (e.g. we received 50 bytes
3811 // on the network, but issued a Read for only 5 of those bytes) that the data
3812 // flow still works correctly.
3813 TEST_P(SpdyNetworkTransactionTest, BufferFull) {
3814   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
3815
3816   scoped_ptr<SpdyFrame> req(
3817       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3818   MockWrite writes[] = { CreateMockWrite(*req) };
3819
3820   // 2 data frames in a single read.
3821   scoped_ptr<SpdyFrame> data_frame_1(
3822       framer.CreateDataFrame(1, "goodby", 6, DATA_FLAG_NONE));
3823   scoped_ptr<SpdyFrame> data_frame_2(
3824       framer.CreateDataFrame(1, "e worl", 6, DATA_FLAG_NONE));
3825   const SpdyFrame* data_frames[2] = {
3826     data_frame_1.get(),
3827     data_frame_2.get(),
3828   };
3829   char combined_data_frames[100];
3830   int combined_data_frames_len =
3831       CombineFrames(data_frames, arraysize(data_frames),
3832                     combined_data_frames, arraysize(combined_data_frames));
3833   scoped_ptr<SpdyFrame> last_frame(
3834       framer.CreateDataFrame(1, "d", 1, DATA_FLAG_FIN));
3835
3836   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3837   MockRead reads[] = {
3838     CreateMockRead(*resp),
3839     MockRead(ASYNC, ERR_IO_PENDING),  // Force a pause
3840     MockRead(ASYNC, combined_data_frames, combined_data_frames_len),
3841     MockRead(ASYNC, ERR_IO_PENDING),  // Force a pause
3842     CreateMockRead(*last_frame),
3843     MockRead(ASYNC, 0, 0)  // EOF
3844   };
3845
3846   DelayedSocketData data(1, reads, arraysize(reads),
3847                          writes, arraysize(writes));
3848
3849   TestCompletionCallback callback;
3850
3851   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3852                                      BoundNetLog(), GetParam(), NULL);
3853   helper.RunPreTestSetup();
3854   helper.AddData(&data);
3855   HttpNetworkTransaction* trans = helper.trans();
3856   int rv = trans->Start(
3857       &CreateGetRequest(), callback.callback(), BoundNetLog());
3858   EXPECT_EQ(ERR_IO_PENDING, rv);
3859
3860   TransactionHelperResult out = helper.output();
3861   out.rv = callback.WaitForResult();
3862   EXPECT_EQ(out.rv, OK);
3863
3864   const HttpResponseInfo* response = trans->GetResponseInfo();
3865   EXPECT_TRUE(response->headers.get() != NULL);
3866   EXPECT_TRUE(response->was_fetched_via_spdy);
3867   out.status_line = response->headers->GetStatusLine();
3868   out.response_info = *response;  // Make a copy so we can verify.
3869
3870   // Read Data
3871   TestCompletionCallback read_callback;
3872
3873   std::string content;
3874   do {
3875     // Read small chunks at a time.
3876     const int kSmallReadSize = 3;
3877     scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize));
3878     rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback());
3879     if (rv == net::ERR_IO_PENDING) {
3880       data.CompleteRead();
3881       rv = read_callback.WaitForResult();
3882     }
3883     if (rv > 0) {
3884       content.append(buf->data(), rv);
3885     } else if (rv < 0) {
3886       NOTREACHED();
3887     }
3888   } while (rv > 0);
3889
3890   out.response_data.swap(content);
3891
3892   // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
3893   // MockClientSocketFactory) are still alive.
3894   base::RunLoop().RunUntilIdle();
3895
3896   // Verify that we consumed all test data.
3897   helper.VerifyDataConsumed();
3898
3899   EXPECT_EQ(OK, out.rv);
3900   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
3901   EXPECT_EQ("goodbye world", out.response_data);
3902 }
3903
3904 // Verify that basic buffering works; when multiple data frames arrive
3905 // at the same time, ensure that we don't notify a read completion for
3906 // each data frame individually.
3907 TEST_P(SpdyNetworkTransactionTest, Buffering) {
3908   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
3909
3910   scoped_ptr<SpdyFrame> req(
3911       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3912   MockWrite writes[] = { CreateMockWrite(*req) };
3913
3914   // 4 data frames in a single read.
3915   scoped_ptr<SpdyFrame> data_frame(
3916       framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
3917   scoped_ptr<SpdyFrame> data_frame_fin(
3918       framer.CreateDataFrame(1, "message", 7, DATA_FLAG_FIN));
3919   const SpdyFrame* data_frames[4] = {
3920     data_frame.get(),
3921     data_frame.get(),
3922     data_frame.get(),
3923     data_frame_fin.get()
3924   };
3925   char combined_data_frames[100];
3926   int combined_data_frames_len =
3927       CombineFrames(data_frames, arraysize(data_frames),
3928                     combined_data_frames, arraysize(combined_data_frames));
3929
3930   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3931   MockRead reads[] = {
3932     CreateMockRead(*resp),
3933     MockRead(ASYNC, ERR_IO_PENDING),  // Force a pause
3934     MockRead(ASYNC, combined_data_frames, combined_data_frames_len),
3935     MockRead(ASYNC, 0, 0)  // EOF
3936   };
3937
3938   DelayedSocketData data(1, reads, arraysize(reads),
3939                          writes, arraysize(writes));
3940
3941   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3942                                      BoundNetLog(), GetParam(), NULL);
3943   helper.RunPreTestSetup();
3944   helper.AddData(&data);
3945   HttpNetworkTransaction* trans = helper.trans();
3946
3947   TestCompletionCallback callback;
3948   int rv = trans->Start(
3949       &CreateGetRequest(), callback.callback(), BoundNetLog());
3950   EXPECT_EQ(ERR_IO_PENDING, rv);
3951
3952   TransactionHelperResult out = helper.output();
3953   out.rv = callback.WaitForResult();
3954   EXPECT_EQ(out.rv, OK);
3955
3956   const HttpResponseInfo* response = trans->GetResponseInfo();
3957   EXPECT_TRUE(response->headers.get() != NULL);
3958   EXPECT_TRUE(response->was_fetched_via_spdy);
3959   out.status_line = response->headers->GetStatusLine();
3960   out.response_info = *response;  // Make a copy so we can verify.
3961
3962   // Read Data
3963   TestCompletionCallback read_callback;
3964
3965   std::string content;
3966   int reads_completed = 0;
3967   do {
3968     // Read small chunks at a time.
3969     const int kSmallReadSize = 14;
3970     scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize));
3971     rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback());
3972     if (rv == net::ERR_IO_PENDING) {
3973       data.CompleteRead();
3974       rv = read_callback.WaitForResult();
3975     }
3976     if (rv > 0) {
3977       EXPECT_EQ(kSmallReadSize, rv);
3978       content.append(buf->data(), rv);
3979     } else if (rv < 0) {
3980       FAIL() << "Unexpected read error: " << rv;
3981     }
3982     reads_completed++;
3983   } while (rv > 0);
3984
3985   EXPECT_EQ(3, reads_completed);  // Reads are: 14 bytes, 14 bytes, 0 bytes.
3986
3987   out.response_data.swap(content);
3988
3989   // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
3990   // MockClientSocketFactory) are still alive.
3991   base::RunLoop().RunUntilIdle();
3992
3993   // Verify that we consumed all test data.
3994   helper.VerifyDataConsumed();
3995
3996   EXPECT_EQ(OK, out.rv);
3997   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
3998   EXPECT_EQ("messagemessagemessagemessage", out.response_data);
3999 }
4000
4001 // Verify the case where we buffer data but read it after it has been buffered.
4002 TEST_P(SpdyNetworkTransactionTest, BufferedAll) {
4003   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
4004
4005   scoped_ptr<SpdyFrame> req(
4006       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4007   MockWrite writes[] = { CreateMockWrite(*req) };
4008
4009   // 5 data frames in a single read.
4010   scoped_ptr<SpdyFrame> syn_reply(
4011       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4012   // turn off FIN bit
4013   test::SetFrameFlags(
4014       syn_reply.get(), CONTROL_FLAG_NONE, spdy_util_.spdy_version());
4015   scoped_ptr<SpdyFrame> data_frame(
4016       framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
4017   scoped_ptr<SpdyFrame> data_frame_fin(
4018       framer.CreateDataFrame(1, "message", 7, DATA_FLAG_FIN));
4019   const SpdyFrame* frames[5] = {
4020     syn_reply.get(),
4021     data_frame.get(),
4022     data_frame.get(),
4023     data_frame.get(),
4024     data_frame_fin.get()
4025   };
4026   char combined_frames[200];
4027   int combined_frames_len =
4028       CombineFrames(frames, arraysize(frames),
4029                     combined_frames, arraysize(combined_frames));
4030
4031   MockRead reads[] = {
4032     MockRead(ASYNC, combined_frames, combined_frames_len),
4033     MockRead(ASYNC, 0, 0)  // EOF
4034   };
4035
4036   DelayedSocketData data(1, reads, arraysize(reads),
4037                          writes, arraysize(writes));
4038
4039   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4040                                      BoundNetLog(), GetParam(), NULL);
4041   helper.RunPreTestSetup();
4042   helper.AddData(&data);
4043   HttpNetworkTransaction* trans = helper.trans();
4044
4045   TestCompletionCallback callback;
4046   int rv = trans->Start(
4047       &CreateGetRequest(), callback.callback(), BoundNetLog());
4048   EXPECT_EQ(ERR_IO_PENDING, rv);
4049
4050   TransactionHelperResult out = helper.output();
4051   out.rv = callback.WaitForResult();
4052   EXPECT_EQ(out.rv, OK);
4053
4054   const HttpResponseInfo* response = trans->GetResponseInfo();
4055   EXPECT_TRUE(response->headers.get() != NULL);
4056   EXPECT_TRUE(response->was_fetched_via_spdy);
4057   out.status_line = response->headers->GetStatusLine();
4058   out.response_info = *response;  // Make a copy so we can verify.
4059
4060   // Read Data
4061   TestCompletionCallback read_callback;
4062
4063   std::string content;
4064   int reads_completed = 0;
4065   do {
4066     // Read small chunks at a time.
4067     const int kSmallReadSize = 14;
4068     scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize));
4069     rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback());
4070     if (rv > 0) {
4071       EXPECT_EQ(kSmallReadSize, rv);
4072       content.append(buf->data(), rv);
4073     } else if (rv < 0) {
4074       FAIL() << "Unexpected read error: " << rv;
4075     }
4076     reads_completed++;
4077   } while (rv > 0);
4078
4079   EXPECT_EQ(3, reads_completed);
4080
4081   out.response_data.swap(content);
4082
4083   // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
4084   // MockClientSocketFactory) are still alive.
4085   base::RunLoop().RunUntilIdle();
4086
4087   // Verify that we consumed all test data.
4088   helper.VerifyDataConsumed();
4089
4090   EXPECT_EQ(OK, out.rv);
4091   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
4092   EXPECT_EQ("messagemessagemessagemessage", out.response_data);
4093 }
4094
4095 // Verify the case where we buffer data and close the connection.
4096 TEST_P(SpdyNetworkTransactionTest, BufferedClosed) {
4097   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
4098
4099   scoped_ptr<SpdyFrame> req(
4100       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4101   MockWrite writes[] = { CreateMockWrite(*req) };
4102
4103   // All data frames in a single read.
4104   // NOTE: We don't FIN the stream.
4105   scoped_ptr<SpdyFrame> data_frame(
4106       framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
4107   const SpdyFrame* data_frames[4] = {
4108     data_frame.get(),
4109     data_frame.get(),
4110     data_frame.get(),
4111     data_frame.get()
4112   };
4113   char combined_data_frames[100];
4114   int combined_data_frames_len =
4115       CombineFrames(data_frames, arraysize(data_frames),
4116                     combined_data_frames, arraysize(combined_data_frames));
4117   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4118   MockRead reads[] = {
4119     CreateMockRead(*resp),
4120     MockRead(ASYNC, ERR_IO_PENDING),  // Force a wait
4121     MockRead(ASYNC, combined_data_frames, combined_data_frames_len),
4122     MockRead(ASYNC, 0, 0)  // EOF
4123   };
4124
4125   DelayedSocketData data(1, reads, arraysize(reads),
4126                          writes, arraysize(writes));
4127
4128   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4129                                      BoundNetLog(), GetParam(), NULL);
4130   helper.RunPreTestSetup();
4131   helper.AddData(&data);
4132   HttpNetworkTransaction* trans = helper.trans();
4133
4134   TestCompletionCallback callback;
4135
4136   int rv = trans->Start(
4137       &CreateGetRequest(), callback.callback(), BoundNetLog());
4138   EXPECT_EQ(ERR_IO_PENDING, rv);
4139
4140   TransactionHelperResult out = helper.output();
4141   out.rv = callback.WaitForResult();
4142   EXPECT_EQ(out.rv, OK);
4143
4144   const HttpResponseInfo* response = trans->GetResponseInfo();
4145   EXPECT_TRUE(response->headers.get() != NULL);
4146   EXPECT_TRUE(response->was_fetched_via_spdy);
4147   out.status_line = response->headers->GetStatusLine();
4148   out.response_info = *response;  // Make a copy so we can verify.
4149
4150   // Read Data
4151   TestCompletionCallback read_callback;
4152
4153   std::string content;
4154   int reads_completed = 0;
4155   do {
4156     // Read small chunks at a time.
4157     const int kSmallReadSize = 14;
4158     scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSmallReadSize));
4159     rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback());
4160     if (rv == net::ERR_IO_PENDING) {
4161       data.CompleteRead();
4162       rv = read_callback.WaitForResult();
4163     }
4164     if (rv > 0) {
4165       content.append(buf->data(), rv);
4166     } else if (rv < 0) {
4167       // This test intentionally closes the connection, and will get an error.
4168       EXPECT_EQ(ERR_CONNECTION_CLOSED, rv);
4169       break;
4170     }
4171     reads_completed++;
4172   } while (rv > 0);
4173
4174   EXPECT_EQ(0, reads_completed);
4175
4176   out.response_data.swap(content);
4177
4178   // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
4179   // MockClientSocketFactory) are still alive.
4180   base::RunLoop().RunUntilIdle();
4181
4182   // Verify that we consumed all test data.
4183   helper.VerifyDataConsumed();
4184 }
4185
4186 // Verify the case where we buffer data and cancel the transaction.
4187 TEST_P(SpdyNetworkTransactionTest, BufferedCancelled) {
4188   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
4189
4190   scoped_ptr<SpdyFrame> req(
4191       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4192   MockWrite writes[] = { CreateMockWrite(*req) };
4193
4194   // NOTE: We don't FIN the stream.
4195   scoped_ptr<SpdyFrame> data_frame(
4196       framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
4197
4198   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4199   MockRead reads[] = {
4200     CreateMockRead(*resp),
4201     MockRead(ASYNC, ERR_IO_PENDING),  // Force a wait
4202     CreateMockRead(*data_frame),
4203     MockRead(ASYNC, 0, 0)  // EOF
4204   };
4205
4206   DelayedSocketData data(1, reads, arraysize(reads),
4207                          writes, arraysize(writes));
4208
4209   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4210                                      BoundNetLog(), GetParam(), NULL);
4211   helper.RunPreTestSetup();
4212   helper.AddData(&data);
4213   HttpNetworkTransaction* trans = helper.trans();
4214   TestCompletionCallback callback;
4215
4216   int rv = trans->Start(
4217       &CreateGetRequest(), callback.callback(), BoundNetLog());
4218   EXPECT_EQ(ERR_IO_PENDING, rv);
4219
4220   TransactionHelperResult out = helper.output();
4221   out.rv = callback.WaitForResult();
4222   EXPECT_EQ(out.rv, OK);
4223
4224   const HttpResponseInfo* response = trans->GetResponseInfo();
4225   EXPECT_TRUE(response->headers.get() != NULL);
4226   EXPECT_TRUE(response->was_fetched_via_spdy);
4227   out.status_line = response->headers->GetStatusLine();
4228   out.response_info = *response;  // Make a copy so we can verify.
4229
4230   // Read Data
4231   TestCompletionCallback read_callback;
4232
4233   do {
4234     const int kReadSize = 256;
4235     scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kReadSize));
4236     rv = trans->Read(buf.get(), kReadSize, read_callback.callback());
4237     if (rv == net::ERR_IO_PENDING) {
4238       // Complete the read now, which causes buffering to start.
4239       data.CompleteRead();
4240       // Destroy the transaction, causing the stream to get cancelled
4241       // and orphaning the buffered IO task.
4242       helper.ResetTrans();
4243       break;
4244     }
4245     // We shouldn't get here in this test.
4246     FAIL() << "Unexpected read: " << rv;
4247   } while (rv > 0);
4248
4249   // Flush the MessageLoop; this will cause the buffered IO task
4250   // to run for the final time.
4251   base::RunLoop().RunUntilIdle();
4252
4253   // Verify that we consumed all test data.
4254   helper.VerifyDataConsumed();
4255 }
4256
4257 // Test that if the server requests persistence of settings, that we save
4258 // the settings in the HttpServerProperties.
4259 TEST_P(SpdyNetworkTransactionTest, SettingsSaved) {
4260   static const SpdyHeaderInfo kSynReplyInfo = {
4261     SYN_REPLY,                              // Syn Reply
4262     1,                                      // Stream ID
4263     0,                                      // Associated Stream ID
4264     ConvertRequestPriorityToSpdyPriority(
4265         LOWEST, spdy_util_.spdy_version()),
4266     kSpdyCredentialSlotUnused,
4267     CONTROL_FLAG_NONE,                      // Control Flags
4268     false,                                  // Compressed
4269     RST_STREAM_INVALID,                     // Status
4270     NULL,                                   // Data
4271     0,                                      // Data Length
4272     DATA_FLAG_NONE                          // Data Flags
4273   };
4274
4275   BoundNetLog net_log;
4276   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4277                                      net_log, GetParam(), NULL);
4278   helper.RunPreTestSetup();
4279
4280   // Verify that no settings exist initially.
4281   HostPortPair host_port_pair("www.google.com", helper.port());
4282   SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
4283   EXPECT_TRUE(spdy_session_pool->http_server_properties()->GetSpdySettings(
4284       host_port_pair).empty());
4285
4286   // Construct the request.
4287   scoped_ptr<SpdyFrame> req(
4288       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4289   MockWrite writes[] = { CreateMockWrite(*req) };
4290
4291   // Construct the reply.
4292   scoped_ptr<SpdyHeaderBlock> reply_headers(new SpdyHeaderBlock());
4293   (*reply_headers)[spdy_util_.GetStatusKey()] = "200";
4294   (*reply_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
4295   scoped_ptr<SpdyFrame> reply(
4296     spdy_util_.ConstructSpdyFrame(kSynReplyInfo, reply_headers.Pass()));
4297
4298   const SpdySettingsIds kSampleId1 = SETTINGS_UPLOAD_BANDWIDTH;
4299   unsigned int kSampleValue1 = 0x0a0a0a0a;
4300   const SpdySettingsIds kSampleId2 = SETTINGS_DOWNLOAD_BANDWIDTH;
4301   unsigned int kSampleValue2 = 0x0b0b0b0b;
4302   const SpdySettingsIds kSampleId3 = SETTINGS_ROUND_TRIP_TIME;
4303   unsigned int kSampleValue3 = 0x0c0c0c0c;
4304   scoped_ptr<SpdyFrame> settings_frame;
4305   {
4306     // Construct the SETTINGS frame.
4307     SettingsMap settings;
4308     // First add a persisted setting.
4309     settings[kSampleId1] =
4310         SettingsFlagsAndValue(SETTINGS_FLAG_PLEASE_PERSIST, kSampleValue1);
4311     // Next add a non-persisted setting.
4312     settings[kSampleId2] =
4313         SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kSampleValue2);
4314     // Next add another persisted setting.
4315     settings[kSampleId3] =
4316         SettingsFlagsAndValue(SETTINGS_FLAG_PLEASE_PERSIST, kSampleValue3);
4317     settings_frame.reset(spdy_util_.ConstructSpdySettings(settings));
4318   }
4319
4320   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
4321   MockRead reads[] = {
4322     CreateMockRead(*reply),
4323     CreateMockRead(*body),
4324     CreateMockRead(*settings_frame),
4325     MockRead(ASYNC, 0, 0)  // EOF
4326   };
4327
4328   DelayedSocketData data(1, reads, arraysize(reads),
4329                          writes, arraysize(writes));
4330   helper.AddData(&data);
4331   helper.RunDefaultTest();
4332   helper.VerifyDataConsumed();
4333   TransactionHelperResult out = helper.output();
4334   EXPECT_EQ(OK, out.rv);
4335   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
4336   EXPECT_EQ("hello!", out.response_data);
4337
4338   {
4339     // Verify we had two persisted settings.
4340     const SettingsMap& settings_map =
4341         spdy_session_pool->http_server_properties()->GetSpdySettings(
4342             host_port_pair);
4343     ASSERT_EQ(2u, settings_map.size());
4344
4345     // Verify the first persisted setting.
4346     SettingsMap::const_iterator it1 = settings_map.find(kSampleId1);
4347     EXPECT_TRUE(it1 != settings_map.end());
4348     SettingsFlagsAndValue flags_and_value1 = it1->second;
4349     EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value1.first);
4350     EXPECT_EQ(kSampleValue1, flags_and_value1.second);
4351
4352     // Verify the second persisted setting.
4353     SettingsMap::const_iterator it3 = settings_map.find(kSampleId3);
4354     EXPECT_TRUE(it3 != settings_map.end());
4355     SettingsFlagsAndValue flags_and_value3 = it3->second;
4356     EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value3.first);
4357     EXPECT_EQ(kSampleValue3, flags_and_value3.second);
4358   }
4359 }
4360
4361 // Test that when there are settings saved that they are sent back to the
4362 // server upon session establishment.
4363 TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) {
4364   static const SpdyHeaderInfo kSynReplyInfo = {
4365     SYN_REPLY,                              // Syn Reply
4366     1,                                      // Stream ID
4367     0,                                      // Associated Stream ID
4368     ConvertRequestPriorityToSpdyPriority(
4369         LOWEST, spdy_util_.spdy_version()),
4370     kSpdyCredentialSlotUnused,
4371     CONTROL_FLAG_NONE,                      // Control Flags
4372     false,                                  // Compressed
4373     RST_STREAM_INVALID,                     // Status
4374     NULL,                                   // Data
4375     0,                                      // Data Length
4376     DATA_FLAG_NONE                          // Data Flags
4377   };
4378
4379   BoundNetLog net_log;
4380   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4381                                      net_log, GetParam(), NULL);
4382   helper.RunPreTestSetup();
4383
4384   SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
4385
4386   SpdySessionPoolPeer pool_peer(spdy_session_pool);
4387   pool_peer.SetEnableSendingInitialData(true);
4388
4389   // Verify that no settings exist initially.
4390   HostPortPair host_port_pair("www.google.com", helper.port());
4391   EXPECT_TRUE(spdy_session_pool->http_server_properties()->GetSpdySettings(
4392       host_port_pair).empty());
4393
4394   const SpdySettingsIds kSampleId1 = SETTINGS_UPLOAD_BANDWIDTH;
4395   unsigned int kSampleValue1 = 0x0a0a0a0a;
4396   const SpdySettingsIds kSampleId2 = SETTINGS_ROUND_TRIP_TIME;
4397   unsigned int kSampleValue2 = 0x0c0c0c0c;
4398
4399   // First add a persisted setting.
4400   spdy_session_pool->http_server_properties()->SetSpdySetting(
4401       host_port_pair,
4402       kSampleId1,
4403       SETTINGS_FLAG_PLEASE_PERSIST,
4404       kSampleValue1);
4405
4406   // Next add another persisted setting.
4407   spdy_session_pool->http_server_properties()->SetSpdySetting(
4408       host_port_pair,
4409       kSampleId2,
4410       SETTINGS_FLAG_PLEASE_PERSIST,
4411       kSampleValue2);
4412
4413   EXPECT_EQ(2u, spdy_session_pool->http_server_properties()->GetSpdySettings(
4414       host_port_pair).size());
4415
4416   // Construct the initial SETTINGS frame.
4417   SettingsMap initial_settings;
4418   initial_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
4419       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams);
4420   scoped_ptr<SpdyFrame> initial_settings_frame(
4421       spdy_util_.ConstructSpdySettings(initial_settings));
4422
4423   // Construct the initial window update.
4424   scoped_ptr<SpdyFrame> initial_window_update(
4425       spdy_util_.ConstructSpdyWindowUpdate(
4426           kSessionFlowControlStreamId,
4427           kDefaultInitialRecvWindowSize - kSpdySessionInitialWindowSize));
4428
4429   // Construct the persisted SETTINGS frame.
4430   const SettingsMap& settings =
4431       spdy_session_pool->http_server_properties()->GetSpdySettings(
4432           host_port_pair);
4433   scoped_ptr<SpdyFrame> settings_frame(
4434       spdy_util_.ConstructSpdySettings(settings));
4435
4436   // Construct the request.
4437   scoped_ptr<SpdyFrame> req(
4438       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4439
4440   std::vector<MockWrite> writes;
4441   if (GetParam().protocol == kProtoHTTP2Draft04) {
4442     writes.push_back(
4443         MockWrite(ASYNC,
4444                   kHttp2ConnectionHeaderPrefix,
4445                   kHttp2ConnectionHeaderPrefixSize));
4446   }
4447   writes.push_back(CreateMockWrite(*initial_settings_frame));
4448   if (GetParam().protocol >= kProtoSPDY31) {
4449     writes.push_back(CreateMockWrite(*initial_window_update));
4450   };
4451   writes.push_back(CreateMockWrite(*settings_frame));
4452   writes.push_back(CreateMockWrite(*req));
4453
4454   // Construct the reply.
4455   scoped_ptr<SpdyHeaderBlock> reply_headers(new SpdyHeaderBlock());
4456   (*reply_headers)[spdy_util_.GetStatusKey()] = "200";
4457   (*reply_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
4458   scoped_ptr<SpdyFrame> reply(
4459     spdy_util_.ConstructSpdyFrame(kSynReplyInfo, reply_headers.Pass()));
4460
4461   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
4462   MockRead reads[] = {
4463     CreateMockRead(*reply),
4464     CreateMockRead(*body),
4465     MockRead(ASYNC, 0, 0)  // EOF
4466   };
4467
4468   DelayedSocketData data(2, reads, arraysize(reads),
4469                          vector_as_array(&writes), writes.size());
4470   helper.AddData(&data);
4471   helper.RunDefaultTest();
4472   helper.VerifyDataConsumed();
4473   TransactionHelperResult out = helper.output();
4474   EXPECT_EQ(OK, out.rv);
4475   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
4476   EXPECT_EQ("hello!", out.response_data);
4477
4478   {
4479     // Verify we had two persisted settings.
4480     const SettingsMap& settings_map =
4481         spdy_session_pool->http_server_properties()->GetSpdySettings(
4482             host_port_pair);
4483     ASSERT_EQ(2u, settings_map.size());
4484
4485     // Verify the first persisted setting.
4486     SettingsMap::const_iterator it1 = settings_map.find(kSampleId1);
4487     EXPECT_TRUE(it1 != settings_map.end());
4488     SettingsFlagsAndValue flags_and_value1 = it1->second;
4489     EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value1.first);
4490     EXPECT_EQ(kSampleValue1, flags_and_value1.second);
4491
4492     // Verify the second persisted setting.
4493     SettingsMap::const_iterator it2 = settings_map.find(kSampleId2);
4494     EXPECT_TRUE(it2 != settings_map.end());
4495     SettingsFlagsAndValue flags_and_value2 = it2->second;
4496     EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value2.first);
4497     EXPECT_EQ(kSampleValue2, flags_and_value2.second);
4498   }
4499 }
4500
4501 TEST_P(SpdyNetworkTransactionTest, GoAwayWithActiveStream) {
4502   scoped_ptr<SpdyFrame> req(
4503       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4504   MockWrite writes[] = { CreateMockWrite(*req) };
4505
4506   scoped_ptr<SpdyFrame> go_away(spdy_util_.ConstructSpdyGoAway());
4507   MockRead reads[] = {
4508     CreateMockRead(*go_away),
4509   };
4510
4511   DelayedSocketData data(1, reads, arraysize(reads),
4512                          writes, arraysize(writes));
4513   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4514                                      BoundNetLog(), GetParam(), NULL);
4515   helper.AddData(&data);
4516   helper.RunToCompletion(&data);
4517   TransactionHelperResult out = helper.output();
4518   EXPECT_EQ(ERR_ABORTED, out.rv);
4519 }
4520
4521 TEST_P(SpdyNetworkTransactionTest, CloseWithActiveStream) {
4522   scoped_ptr<SpdyFrame> req(
4523       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4524   MockWrite writes[] = { CreateMockWrite(*req) };
4525
4526   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4527   MockRead reads[] = {
4528     CreateMockRead(*resp),
4529     MockRead(SYNCHRONOUS, 0, 0)  // EOF
4530   };
4531
4532   DelayedSocketData data(1, reads, arraysize(reads),
4533                          writes, arraysize(writes));
4534   BoundNetLog log;
4535   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4536                                      log, GetParam(), NULL);
4537   helper.RunPreTestSetup();
4538   helper.AddData(&data);
4539   HttpNetworkTransaction* trans = helper.trans();
4540
4541   TestCompletionCallback callback;
4542   TransactionHelperResult out;
4543   out.rv = trans->Start(&CreateGetRequest(), callback.callback(), log);
4544
4545   EXPECT_EQ(out.rv, ERR_IO_PENDING);
4546   out.rv = callback.WaitForResult();
4547   EXPECT_EQ(out.rv, OK);
4548
4549   const HttpResponseInfo* response = trans->GetResponseInfo();
4550   EXPECT_TRUE(response->headers.get() != NULL);
4551   EXPECT_TRUE(response->was_fetched_via_spdy);
4552   out.rv = ReadTransaction(trans, &out.response_data);
4553   EXPECT_EQ(ERR_CONNECTION_CLOSED, out.rv);
4554
4555   // Verify that we consumed all test data.
4556   helper.VerifyDataConsumed();
4557 }
4558
4559 // Test to make sure we can correctly connect through a proxy.
4560 TEST_P(SpdyNetworkTransactionTest, ProxyConnect) {
4561   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4562                                      BoundNetLog(), GetParam(), NULL);
4563   helper.session_deps().reset(CreateSpdySessionDependencies(
4564       GetParam(),
4565       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")));
4566   helper.SetSession(make_scoped_refptr(
4567       SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get())));
4568   helper.RunPreTestSetup();
4569   HttpNetworkTransaction* trans = helper.trans();
4570
4571   const char kConnect443[] = {"CONNECT www.google.com:443 HTTP/1.1\r\n"
4572                            "Host: www.google.com\r\n"
4573                            "Proxy-Connection: keep-alive\r\n\r\n"};
4574   const char kConnect80[] = {"CONNECT www.google.com:80 HTTP/1.1\r\n"
4575                            "Host: www.google.com\r\n"
4576                            "Proxy-Connection: keep-alive\r\n\r\n"};
4577   const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"};
4578   scoped_ptr<SpdyFrame> req(
4579       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4580   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4581   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
4582
4583   MockWrite writes_SPDYNPN[] = {
4584     MockWrite(SYNCHRONOUS, kConnect443, arraysize(kConnect443) - 1, 0),
4585     CreateMockWrite(*req, 2),
4586   };
4587   MockRead reads_SPDYNPN[] = {
4588     MockRead(SYNCHRONOUS, kHTTP200, arraysize(kHTTP200) - 1, 1),
4589     CreateMockRead(*resp, 3),
4590     CreateMockRead(*body.get(), 4),
4591     MockRead(ASYNC, 0, 0, 5),
4592   };
4593
4594   MockWrite writes_SPDYSSL[] = {
4595     MockWrite(SYNCHRONOUS, kConnect80, arraysize(kConnect80) - 1, 0),
4596     CreateMockWrite(*req, 2),
4597   };
4598   MockRead reads_SPDYSSL[] = {
4599     MockRead(SYNCHRONOUS, kHTTP200, arraysize(kHTTP200) - 1, 1),
4600     CreateMockRead(*resp, 3),
4601     CreateMockRead(*body.get(), 4),
4602     MockRead(ASYNC, 0, 0, 5),
4603   };
4604
4605   MockWrite writes_SPDYNOSSL[] = {
4606     CreateMockWrite(*req, 0),
4607   };
4608
4609   MockRead reads_SPDYNOSSL[] = {
4610     CreateMockRead(*resp, 1),
4611     CreateMockRead(*body.get(), 2),
4612     MockRead(ASYNC, 0, 0, 3),
4613   };
4614
4615   scoped_ptr<OrderedSocketData> data;
4616   switch(GetParam().ssl_type) {
4617     case SPDYNOSSL:
4618       data.reset(new OrderedSocketData(reads_SPDYNOSSL,
4619                                        arraysize(reads_SPDYNOSSL),
4620                                        writes_SPDYNOSSL,
4621                                        arraysize(writes_SPDYNOSSL)));
4622       break;
4623     case SPDYSSL:
4624       data.reset(new OrderedSocketData(reads_SPDYSSL,
4625                                        arraysize(reads_SPDYSSL),
4626                                        writes_SPDYSSL,
4627                                        arraysize(writes_SPDYSSL)));
4628       break;
4629     case SPDYNPN:
4630       data.reset(new OrderedSocketData(reads_SPDYNPN,
4631                                        arraysize(reads_SPDYNPN),
4632                                        writes_SPDYNPN,
4633                                        arraysize(writes_SPDYNPN)));
4634       break;
4635     default:
4636       NOTREACHED();
4637   }
4638
4639   helper.AddData(data.get());
4640   TestCompletionCallback callback;
4641
4642   int rv = trans->Start(
4643       &CreateGetRequest(), callback.callback(), BoundNetLog());
4644   EXPECT_EQ(ERR_IO_PENDING, rv);
4645
4646   rv = callback.WaitForResult();
4647   EXPECT_EQ(0, rv);
4648
4649   // Verify the SYN_REPLY.
4650   HttpResponseInfo response = *trans->GetResponseInfo();
4651   EXPECT_TRUE(response.headers.get() != NULL);
4652   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
4653
4654   std::string response_data;
4655   ASSERT_EQ(OK, ReadTransaction(trans, &response_data));
4656   EXPECT_EQ("hello!", response_data);
4657   helper.VerifyDataConsumed();
4658 }
4659
4660 // Test to make sure we can correctly connect through a proxy to www.google.com,
4661 // if there already exists a direct spdy connection to www.google.com. See
4662 // http://crbug.com/49874
4663 TEST_P(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) {
4664   // When setting up the first transaction, we store the SpdySessionPool so that
4665   // we can use the same pool in the second transaction.
4666   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4667                                      BoundNetLog(), GetParam(), NULL);
4668
4669   // Use a proxy service which returns a proxy fallback list from DIRECT to
4670   // myproxy:70. For this test there will be no fallback, so it is equivalent
4671   // to simply DIRECT. The reason for appending the second proxy is to verify
4672   // that the session pool key used does is just "DIRECT".
4673   helper.session_deps().reset(CreateSpdySessionDependencies(
4674       GetParam(),
4675       ProxyService::CreateFixedFromPacResult("DIRECT; PROXY myproxy:70")));
4676   helper.SetSession(make_scoped_refptr(
4677       SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get())));
4678
4679   SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
4680   helper.RunPreTestSetup();
4681
4682   // Construct and send a simple GET request.
4683   scoped_ptr<SpdyFrame> req(
4684       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4685   MockWrite writes[] = {
4686     CreateMockWrite(*req, 1),
4687   };
4688
4689   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4690   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
4691   MockRead reads[] = {
4692     CreateMockRead(*resp, 2),
4693     CreateMockRead(*body, 3),
4694     MockRead(ASYNC, ERR_IO_PENDING, 4),  // Force a pause
4695     MockRead(ASYNC, 0, 5)  // EOF
4696   };
4697   OrderedSocketData data(reads, arraysize(reads),
4698                          writes, arraysize(writes));
4699   helper.AddData(&data);
4700   HttpNetworkTransaction* trans = helper.trans();
4701
4702   TestCompletionCallback callback;
4703   TransactionHelperResult out;
4704   out.rv = trans->Start(
4705       &CreateGetRequest(), callback.callback(), BoundNetLog());
4706
4707   EXPECT_EQ(out.rv, ERR_IO_PENDING);
4708   out.rv = callback.WaitForResult();
4709   EXPECT_EQ(out.rv, OK);
4710
4711   const HttpResponseInfo* response = trans->GetResponseInfo();
4712   EXPECT_TRUE(response->headers.get() != NULL);
4713   EXPECT_TRUE(response->was_fetched_via_spdy);
4714   out.rv = ReadTransaction(trans, &out.response_data);
4715   EXPECT_EQ(OK, out.rv);
4716   out.status_line = response->headers->GetStatusLine();
4717   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
4718   EXPECT_EQ("hello!", out.response_data);
4719
4720   // Check that the SpdySession is still in the SpdySessionPool.
4721   HostPortPair host_port_pair("www.google.com", helper.port());
4722   SpdySessionKey session_pool_key_direct(
4723       host_port_pair, ProxyServer::Direct(), kPrivacyModeDisabled);
4724   EXPECT_TRUE(HasSpdySession(spdy_session_pool, session_pool_key_direct));
4725   SpdySessionKey session_pool_key_proxy(
4726       host_port_pair,
4727       ProxyServer::FromURI("www.foo.com", ProxyServer::SCHEME_HTTP),
4728       kPrivacyModeDisabled);
4729   EXPECT_FALSE(HasSpdySession(spdy_session_pool, session_pool_key_proxy));
4730
4731   // Set up data for the proxy connection.
4732   const char kConnect443[] = {"CONNECT www.google.com:443 HTTP/1.1\r\n"
4733                            "Host: www.google.com\r\n"
4734                            "Proxy-Connection: keep-alive\r\n\r\n"};
4735   const char kConnect80[] = {"CONNECT www.google.com:80 HTTP/1.1\r\n"
4736                            "Host: www.google.com\r\n"
4737                            "Proxy-Connection: keep-alive\r\n\r\n"};
4738   const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"};
4739   scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyGet(
4740       "http://www.google.com/foo.dat", false, 1, LOWEST));
4741   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4742   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
4743
4744   MockWrite writes_SPDYNPN[] = {
4745     MockWrite(SYNCHRONOUS, kConnect443, arraysize(kConnect443) - 1, 0),
4746     CreateMockWrite(*req2, 2),
4747   };
4748   MockRead reads_SPDYNPN[] = {
4749     MockRead(SYNCHRONOUS, kHTTP200, arraysize(kHTTP200) - 1, 1),
4750     CreateMockRead(*resp2, 3),
4751     CreateMockRead(*body2, 4),
4752     MockRead(ASYNC, 0, 5)  // EOF
4753   };
4754
4755   MockWrite writes_SPDYNOSSL[] = {
4756     CreateMockWrite(*req2, 0),
4757   };
4758   MockRead reads_SPDYNOSSL[] = {
4759     CreateMockRead(*resp2, 1),
4760     CreateMockRead(*body2, 2),
4761     MockRead(ASYNC, 0, 3)  // EOF
4762   };
4763
4764   MockWrite writes_SPDYSSL[] = {
4765     MockWrite(SYNCHRONOUS, kConnect80, arraysize(kConnect80) - 1, 0),
4766     CreateMockWrite(*req2, 2),
4767   };
4768   MockRead reads_SPDYSSL[] = {
4769     MockRead(SYNCHRONOUS, kHTTP200, arraysize(kHTTP200) - 1, 1),
4770     CreateMockRead(*resp2, 3),
4771     CreateMockRead(*body2, 4),
4772     MockRead(ASYNC, 0, 0, 5),
4773   };
4774
4775   scoped_ptr<OrderedSocketData> data_proxy;
4776   switch(GetParam().ssl_type) {
4777     case SPDYNPN:
4778       data_proxy.reset(new OrderedSocketData(reads_SPDYNPN,
4779                                              arraysize(reads_SPDYNPN),
4780                                              writes_SPDYNPN,
4781                                              arraysize(writes_SPDYNPN)));
4782       break;
4783     case SPDYNOSSL:
4784       data_proxy.reset(new OrderedSocketData(reads_SPDYNOSSL,
4785                                              arraysize(reads_SPDYNOSSL),
4786                                              writes_SPDYNOSSL,
4787                                              arraysize(writes_SPDYNOSSL)));
4788       break;
4789     case SPDYSSL:
4790       data_proxy.reset(new OrderedSocketData(reads_SPDYSSL,
4791                                              arraysize(reads_SPDYSSL),
4792                                              writes_SPDYSSL,
4793                                              arraysize(writes_SPDYSSL)));
4794       break;
4795     default:
4796       NOTREACHED();
4797   }
4798
4799   // Create another request to www.google.com, but this time through a proxy.
4800   HttpRequestInfo request_proxy;
4801   request_proxy.method = "GET";
4802   request_proxy.url = GURL("http://www.google.com/foo.dat");
4803   request_proxy.load_flags = 0;
4804   scoped_ptr<SpdySessionDependencies> ssd_proxy(
4805       CreateSpdySessionDependencies(GetParam()));
4806   // Ensure that this transaction uses the same SpdySessionPool.
4807   scoped_refptr<HttpNetworkSession> session_proxy(
4808       SpdySessionDependencies::SpdyCreateSession(ssd_proxy.get()));
4809   NormalSpdyTransactionHelper helper_proxy(request_proxy, DEFAULT_PRIORITY,
4810                                            BoundNetLog(), GetParam(), NULL);
4811   HttpNetworkSessionPeer session_peer(session_proxy);
4812   scoped_ptr<net::ProxyService> proxy_service(
4813           ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
4814   session_peer.SetProxyService(proxy_service.get());
4815   helper_proxy.session_deps().swap(ssd_proxy);
4816   helper_proxy.SetSession(session_proxy);
4817   helper_proxy.RunPreTestSetup();
4818   helper_proxy.AddData(data_proxy.get());
4819
4820   HttpNetworkTransaction* trans_proxy = helper_proxy.trans();
4821   TestCompletionCallback callback_proxy;
4822   int rv = trans_proxy->Start(
4823       &request_proxy, callback_proxy.callback(), BoundNetLog());
4824   EXPECT_EQ(ERR_IO_PENDING, rv);
4825   rv = callback_proxy.WaitForResult();
4826   EXPECT_EQ(0, rv);
4827
4828   HttpResponseInfo response_proxy = *trans_proxy->GetResponseInfo();
4829   EXPECT_TRUE(response_proxy.headers.get() != NULL);
4830   EXPECT_EQ("HTTP/1.1 200 OK", response_proxy.headers->GetStatusLine());
4831
4832   std::string response_data;
4833   ASSERT_EQ(OK, ReadTransaction(trans_proxy, &response_data));
4834   EXPECT_EQ("hello!", response_data);
4835
4836   data.CompleteRead();
4837   helper_proxy.VerifyDataConsumed();
4838 }
4839
4840 // When we get a TCP-level RST, we need to retry a HttpNetworkTransaction
4841 // on a new connection, if the connection was previously known to be good.
4842 // This can happen when a server reboots without saying goodbye, or when
4843 // we're behind a NAT that masked the RST.
4844 TEST_P(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) {
4845   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4846   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
4847   MockRead reads[] = {
4848     CreateMockRead(*resp),
4849     CreateMockRead(*body),
4850     MockRead(ASYNC, ERR_IO_PENDING),
4851     MockRead(ASYNC, ERR_CONNECTION_RESET),
4852   };
4853
4854   MockRead reads2[] = {
4855     CreateMockRead(*resp),
4856     CreateMockRead(*body),
4857     MockRead(ASYNC, 0, 0)  // EOF
4858   };
4859
4860   // This test has a couple of variants.
4861   enum {
4862     // Induce the RST while waiting for our transaction to send.
4863     VARIANT_RST_DURING_SEND_COMPLETION,
4864     // Induce the RST while waiting for our transaction to read.
4865     // In this case, the send completed - everything copied into the SNDBUF.
4866     VARIANT_RST_DURING_READ_COMPLETION
4867   };
4868
4869   for (int variant = VARIANT_RST_DURING_SEND_COMPLETION;
4870        variant <= VARIANT_RST_DURING_READ_COMPLETION;
4871        ++variant) {
4872     DelayedSocketData data1(1, reads, arraysize(reads), NULL, 0);
4873
4874     DelayedSocketData data2(1, reads2, arraysize(reads2), NULL, 0);
4875
4876     NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4877                                        BoundNetLog(), GetParam(), NULL);
4878     helper.AddData(&data1);
4879     helper.AddData(&data2);
4880     helper.RunPreTestSetup();
4881
4882     for (int i = 0; i < 2; ++i) {
4883       scoped_ptr<HttpNetworkTransaction> trans(
4884           new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
4885
4886       TestCompletionCallback callback;
4887       int rv = trans->Start(
4888           &helper.request(), callback.callback(), BoundNetLog());
4889       EXPECT_EQ(ERR_IO_PENDING, rv);
4890       // On the second transaction, we trigger the RST.
4891       if (i == 1) {
4892         if (variant == VARIANT_RST_DURING_READ_COMPLETION) {
4893           // Writes to the socket complete asynchronously on SPDY by running
4894           // through the message loop.  Complete the write here.
4895           base::RunLoop().RunUntilIdle();
4896         }
4897
4898         // Now schedule the ERR_CONNECTION_RESET.
4899         EXPECT_EQ(3u, data1.read_index());
4900         data1.CompleteRead();
4901         EXPECT_EQ(4u, data1.read_index());
4902       }
4903       rv = callback.WaitForResult();
4904       EXPECT_EQ(OK, rv);
4905
4906       const HttpResponseInfo* response = trans->GetResponseInfo();
4907       ASSERT_TRUE(response != NULL);
4908       EXPECT_TRUE(response->headers.get() != NULL);
4909       EXPECT_TRUE(response->was_fetched_via_spdy);
4910       std::string response_data;
4911       rv = ReadTransaction(trans.get(), &response_data);
4912       EXPECT_EQ(OK, rv);
4913       EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4914       EXPECT_EQ("hello!", response_data);
4915     }
4916
4917     helper.VerifyDataConsumed();
4918   }
4919 }
4920
4921 // Test that turning SPDY on and off works properly.
4922 TEST_P(SpdyNetworkTransactionTest, SpdyOnOffToggle) {
4923   net::HttpStreamFactory::set_spdy_enabled(true);
4924   scoped_ptr<SpdyFrame> req(
4925       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4926   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
4927
4928   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4929   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
4930   MockRead spdy_reads[] = {
4931     CreateMockRead(*resp),
4932     CreateMockRead(*body),
4933     MockRead(ASYNC, 0, 0)  // EOF
4934   };
4935
4936   DelayedSocketData data(1, spdy_reads, arraysize(spdy_reads),
4937                          spdy_writes, arraysize(spdy_writes));
4938   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4939                                      BoundNetLog(), GetParam(), NULL);
4940   helper.RunToCompletion(&data);
4941   TransactionHelperResult out = helper.output();
4942   EXPECT_EQ(OK, out.rv);
4943   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
4944   EXPECT_EQ("hello!", out.response_data);
4945
4946   net::HttpStreamFactory::set_spdy_enabled(false);
4947   MockRead http_reads[] = {
4948     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
4949     MockRead("hello from http"),
4950     MockRead(SYNCHRONOUS, OK),
4951   };
4952   DelayedSocketData data2(1, http_reads, arraysize(http_reads), NULL, 0);
4953   NormalSpdyTransactionHelper helper2(CreateGetRequest(), DEFAULT_PRIORITY,
4954                                      BoundNetLog(), GetParam(), NULL);
4955   helper2.SetSpdyDisabled();
4956   helper2.RunToCompletion(&data2);
4957   TransactionHelperResult out2 = helper2.output();
4958   EXPECT_EQ(OK, out2.rv);
4959   EXPECT_EQ("HTTP/1.1 200 OK", out2.status_line);
4960   EXPECT_EQ("hello from http", out2.response_data);
4961
4962   net::HttpStreamFactory::set_spdy_enabled(true);
4963 }
4964
4965 // Tests that Basic authentication works over SPDY
4966 TEST_P(SpdyNetworkTransactionTest, SpdyBasicAuth) {
4967   net::HttpStreamFactory::set_spdy_enabled(true);
4968
4969   // The first request will be a bare GET, the second request will be a
4970   // GET with an Authorization header.
4971   scoped_ptr<SpdyFrame> req_get(
4972       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4973   const char* const kExtraAuthorizationHeaders[] = {
4974     "authorization", "Basic Zm9vOmJhcg=="
4975   };
4976   scoped_ptr<SpdyFrame> req_get_authorization(
4977       spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
4978                                   arraysize(kExtraAuthorizationHeaders) / 2,
4979                                   false, 3, LOWEST, true));
4980   MockWrite spdy_writes[] = {
4981     CreateMockWrite(*req_get, 1),
4982     CreateMockWrite(*req_get_authorization, 4),
4983   };
4984
4985   // The first response is a 401 authentication challenge, and the second
4986   // response will be a 200 response since the second request includes a valid
4987   // Authorization header.
4988   const char* const kExtraAuthenticationHeaders[] = {
4989     "www-authenticate",
4990     "Basic realm=\"MyRealm\""
4991   };
4992   scoped_ptr<SpdyFrame> resp_authentication(
4993       spdy_util_.ConstructSpdySynReplyError(
4994           "401 Authentication Required",
4995           kExtraAuthenticationHeaders,
4996           arraysize(kExtraAuthenticationHeaders) / 2,
4997           1));
4998   scoped_ptr<SpdyFrame> body_authentication(
4999       spdy_util_.ConstructSpdyBodyFrame(1, true));
5000   scoped_ptr<SpdyFrame> resp_data(
5001       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
5002   scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
5003   MockRead spdy_reads[] = {
5004     CreateMockRead(*resp_authentication, 2),
5005     CreateMockRead(*body_authentication, 3),
5006     CreateMockRead(*resp_data, 5),
5007     CreateMockRead(*body_data, 6),
5008     MockRead(ASYNC, 0, 7),
5009   };
5010
5011   OrderedSocketData data(spdy_reads, arraysize(spdy_reads),
5012                          spdy_writes, arraysize(spdy_writes));
5013   HttpRequestInfo request(CreateGetRequest());
5014   BoundNetLog net_log;
5015   NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
5016                                      net_log, GetParam(), NULL);
5017
5018   helper.RunPreTestSetup();
5019   helper.AddData(&data);
5020   HttpNetworkTransaction* trans = helper.trans();
5021   TestCompletionCallback callback;
5022   const int rv_start = trans->Start(&request, callback.callback(), net_log);
5023   EXPECT_EQ(ERR_IO_PENDING, rv_start);
5024   const int rv_start_complete = callback.WaitForResult();
5025   EXPECT_EQ(OK, rv_start_complete);
5026
5027   // Make sure the response has an auth challenge.
5028   const HttpResponseInfo* const response_start = trans->GetResponseInfo();
5029   ASSERT_TRUE(response_start != NULL);
5030   ASSERT_TRUE(response_start->headers.get() != NULL);
5031   EXPECT_EQ(401, response_start->headers->response_code());
5032   EXPECT_TRUE(response_start->was_fetched_via_spdy);
5033   AuthChallengeInfo* auth_challenge = response_start->auth_challenge.get();
5034   ASSERT_TRUE(auth_challenge != NULL);
5035   EXPECT_FALSE(auth_challenge->is_proxy);
5036   EXPECT_EQ("basic", auth_challenge->scheme);
5037   EXPECT_EQ("MyRealm", auth_challenge->realm);
5038
5039   // Restart with a username/password.
5040   AuthCredentials credentials(base::ASCIIToUTF16("foo"),
5041                               base::ASCIIToUTF16("bar"));
5042   TestCompletionCallback callback_restart;
5043   const int rv_restart = trans->RestartWithAuth(
5044       credentials, callback_restart.callback());
5045   EXPECT_EQ(ERR_IO_PENDING, rv_restart);
5046   const int rv_restart_complete = callback_restart.WaitForResult();
5047   EXPECT_EQ(OK, rv_restart_complete);
5048   // TODO(cbentzel): This is actually the same response object as before, but
5049   // data has changed.
5050   const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
5051   ASSERT_TRUE(response_restart != NULL);
5052   ASSERT_TRUE(response_restart->headers.get() != NULL);
5053   EXPECT_EQ(200, response_restart->headers->response_code());
5054   EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
5055 }
5056
5057 TEST_P(SpdyNetworkTransactionTest, ServerPushWithHeaders) {
5058   scoped_ptr<SpdyFrame> stream1_syn(
5059       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5060   scoped_ptr<SpdyFrame> stream1_body(
5061       spdy_util_.ConstructSpdyBodyFrame(1, true));
5062   MockWrite writes[] = {
5063     CreateMockWrite(*stream1_syn, 1),
5064   };
5065
5066   scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
5067   spdy_util_.AddUrlToHeaderBlock(
5068       "http://www.google.com/foo.dat", initial_headers.get());
5069   scoped_ptr<SpdyFrame> stream2_syn(
5070       spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(),
5071                                            false,
5072                                            2,
5073                                            LOWEST,
5074                                            SYN_STREAM,
5075                                            CONTROL_FLAG_NONE,
5076                                            1));
5077
5078   scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
5079   (*late_headers)["hello"] = "bye";
5080   (*late_headers)[spdy_util_.GetStatusKey()] = "200";
5081   (*late_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
5082   scoped_ptr<SpdyFrame> stream2_headers(
5083       spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
5084                                            false,
5085                                            2,
5086                                            LOWEST,
5087                                            HEADERS,
5088                                            CONTROL_FLAG_NONE,
5089                                            0));
5090
5091   scoped_ptr<SpdyFrame>
5092       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5093   const char kPushedData[] = "pushed";
5094   scoped_ptr<SpdyFrame> stream2_body(
5095       spdy_util_.ConstructSpdyBodyFrame(
5096           2, kPushedData, strlen(kPushedData), true));
5097   MockRead reads[] = {
5098     CreateMockRead(*stream1_reply, 2),
5099     CreateMockRead(*stream2_syn, 3),
5100     CreateMockRead(*stream2_headers, 4),
5101     CreateMockRead(*stream1_body, 5, SYNCHRONOUS),
5102     CreateMockRead(*stream2_body, 5),
5103     MockRead(ASYNC, ERR_IO_PENDING, 7),  // Force a pause
5104   };
5105
5106   HttpResponseInfo response;
5107   HttpResponseInfo response2;
5108   std::string expected_push_result("pushed");
5109   OrderedSocketData data(reads, arraysize(reads),
5110                          writes, arraysize(writes));
5111   RunServerPushTest(&data,
5112                     &response,
5113                     &response2,
5114                     expected_push_result);
5115
5116   // Verify the SYN_REPLY.
5117   EXPECT_TRUE(response.headers.get() != NULL);
5118   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
5119
5120   // Verify the pushed stream.
5121   EXPECT_TRUE(response2.headers.get() != NULL);
5122   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
5123 }
5124
5125 TEST_P(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) {
5126   // We push a stream and attempt to claim it before the headers come down.
5127   scoped_ptr<SpdyFrame> stream1_syn(
5128       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5129   scoped_ptr<SpdyFrame> stream1_body(
5130       spdy_util_.ConstructSpdyBodyFrame(1, true));
5131   MockWrite writes[] = {
5132     CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS),
5133   };
5134
5135   scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
5136   spdy_util_.AddUrlToHeaderBlock(
5137       "http://www.google.com/foo.dat", initial_headers.get());
5138   scoped_ptr<SpdyFrame> stream2_syn(
5139       spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(),
5140                                            false,
5141                                            2,
5142                                            LOWEST,
5143                                            SYN_STREAM,
5144                                            CONTROL_FLAG_NONE,
5145                                            1));
5146
5147   scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
5148   (*late_headers)["hello"] = "bye";
5149   (*late_headers)[spdy_util_.GetStatusKey()] = "200";
5150   (*late_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
5151   scoped_ptr<SpdyFrame> stream2_headers(
5152       spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
5153                                            false,
5154                                            2,
5155                                            LOWEST,
5156                                            HEADERS,
5157                                            CONTROL_FLAG_NONE,
5158                                            0));
5159
5160   scoped_ptr<SpdyFrame>
5161       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5162   const char kPushedData[] = "pushed";
5163   scoped_ptr<SpdyFrame> stream2_body(
5164       spdy_util_.ConstructSpdyBodyFrame(
5165           2, kPushedData, strlen(kPushedData), true));
5166   MockRead reads[] = {
5167     CreateMockRead(*stream1_reply, 1),
5168     CreateMockRead(*stream2_syn, 2),
5169     CreateMockRead(*stream1_body, 3),
5170     CreateMockRead(*stream2_headers, 4),
5171     CreateMockRead(*stream2_body, 5),
5172     MockRead(ASYNC, 0, 6),  // EOF
5173   };
5174
5175   HttpResponseInfo response;
5176   HttpResponseInfo response2;
5177   std::string expected_push_result("pushed");
5178   DeterministicSocketData data(reads, arraysize(reads),
5179                                writes, arraysize(writes));
5180
5181   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5182                                      BoundNetLog(), GetParam(), NULL);
5183   helper.SetDeterministic();
5184   helper.AddDeterministicData(&data);
5185   helper.RunPreTestSetup();
5186
5187   HttpNetworkTransaction* trans = helper.trans();
5188
5189   // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
5190   // and the body of the primary stream, but before we've received the HEADERS
5191   // for the pushed stream.
5192   data.SetStop(3);
5193
5194   // Start the transaction.
5195   TestCompletionCallback callback;
5196   int rv = trans->Start(
5197       &CreateGetRequest(), callback.callback(), BoundNetLog());
5198   EXPECT_EQ(ERR_IO_PENDING, rv);
5199   data.Run();
5200   rv = callback.WaitForResult();
5201   EXPECT_EQ(0, rv);
5202
5203   // Request the pushed path.  At this point, we've received the push, but the
5204   // headers are not yet complete.
5205   scoped_ptr<HttpNetworkTransaction> trans2(
5206       new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
5207   rv = trans2->Start(
5208       &CreateGetPushRequest(), callback.callback(), BoundNetLog());
5209   EXPECT_EQ(ERR_IO_PENDING, rv);
5210   data.RunFor(3);
5211   base::RunLoop().RunUntilIdle();
5212
5213   // Read the server push body.
5214   std::string result2;
5215   ReadResult(trans2.get(), &data, &result2);
5216   // Read the response body.
5217   std::string result;
5218   ReadResult(trans, &data, &result);
5219
5220   // Verify that the received push data is same as the expected push data.
5221   EXPECT_EQ(result2.compare(expected_push_result), 0)
5222       << "Received data: "
5223       << result2
5224       << "||||| Expected data: "
5225       << expected_push_result;
5226
5227   // Verify the SYN_REPLY.
5228   // Copy the response info, because trans goes away.
5229   response = *trans->GetResponseInfo();
5230   response2 = *trans2->GetResponseInfo();
5231
5232   VerifyStreamsClosed(helper);
5233
5234   // Verify the SYN_REPLY.
5235   EXPECT_TRUE(response.headers.get() != NULL);
5236   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
5237
5238   // Verify the pushed stream.
5239   EXPECT_TRUE(response2.headers.get() != NULL);
5240   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
5241
5242   // Read the final EOF (which will close the session)
5243   data.RunFor(1);
5244
5245   // Verify that we consumed all test data.
5246   EXPECT_TRUE(data.at_read_eof());
5247   EXPECT_TRUE(data.at_write_eof());
5248 }
5249
5250 TEST_P(SpdyNetworkTransactionTest, ServerPushWithTwoHeaderFrames) {
5251   // We push a stream and attempt to claim it before the headers come down.
5252   scoped_ptr<SpdyFrame> stream1_syn(
5253       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5254   scoped_ptr<SpdyFrame> stream1_body(
5255       spdy_util_.ConstructSpdyBodyFrame(1, true));
5256   MockWrite writes[] = {
5257     CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS),
5258   };
5259
5260   scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
5261   spdy_util_.AddUrlToHeaderBlock(
5262       "http://www.google.com/foo.dat", initial_headers.get());
5263   scoped_ptr<SpdyFrame> stream2_syn(
5264       spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(),
5265                                            false,
5266                                            2,
5267                                            LOWEST,
5268                                            SYN_STREAM,
5269                                            CONTROL_FLAG_NONE,
5270                                            1));
5271
5272   scoped_ptr<SpdyHeaderBlock> middle_headers(new SpdyHeaderBlock());
5273   (*middle_headers)["hello"] = "bye";
5274   scoped_ptr<SpdyFrame> stream2_headers1(
5275       spdy_util_.ConstructSpdyControlFrame(middle_headers.Pass(),
5276                                            false,
5277                                            2,
5278                                            LOWEST,
5279                                            HEADERS,
5280                                            CONTROL_FLAG_NONE,
5281                                            0));
5282
5283   scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
5284   (*late_headers)[spdy_util_.GetStatusKey()] = "200";
5285   (*late_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
5286   scoped_ptr<SpdyFrame> stream2_headers2(
5287       spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
5288                                            false,
5289                                            2,
5290                                            LOWEST,
5291                                            HEADERS,
5292                                            CONTROL_FLAG_NONE,
5293                                            0));
5294
5295   scoped_ptr<SpdyFrame>
5296       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5297   const char kPushedData[] = "pushed";
5298   scoped_ptr<SpdyFrame> stream2_body(
5299       spdy_util_.ConstructSpdyBodyFrame(
5300           2, kPushedData, strlen(kPushedData), true));
5301   MockRead reads[] = {
5302     CreateMockRead(*stream1_reply, 1),
5303     CreateMockRead(*stream2_syn, 2),
5304     CreateMockRead(*stream1_body, 3),
5305     CreateMockRead(*stream2_headers1, 4),
5306     CreateMockRead(*stream2_headers2, 5),
5307     CreateMockRead(*stream2_body, 6),
5308     MockRead(ASYNC, 0, 7),  // EOF
5309   };
5310
5311   HttpResponseInfo response;
5312   HttpResponseInfo response2;
5313   std::string expected_push_result("pushed");
5314   DeterministicSocketData data(reads, arraysize(reads),
5315                                writes, arraysize(writes));
5316
5317   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5318                                      BoundNetLog(), GetParam(), NULL);
5319   helper.SetDeterministic();
5320   helper.AddDeterministicData(&data);
5321   helper.RunPreTestSetup();
5322
5323   HttpNetworkTransaction* trans = helper.trans();
5324
5325   // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
5326   // the first HEADERS frame, and the body of the primary stream, but before
5327   // we've received the final HEADERS for the pushed stream.
5328   data.SetStop(4);
5329
5330   // Start the transaction.
5331   TestCompletionCallback callback;
5332   int rv = trans->Start(
5333       &CreateGetRequest(), callback.callback(), BoundNetLog());
5334   EXPECT_EQ(ERR_IO_PENDING, rv);
5335   data.Run();
5336   rv = callback.WaitForResult();
5337   EXPECT_EQ(0, rv);
5338
5339   // Request the pushed path.  At this point, we've received the push, but the
5340   // headers are not yet complete.
5341   scoped_ptr<HttpNetworkTransaction> trans2(
5342       new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
5343   rv = trans2->Start(
5344       &CreateGetPushRequest(), callback.callback(), BoundNetLog());
5345   EXPECT_EQ(ERR_IO_PENDING, rv);
5346   data.RunFor(3);
5347   base::RunLoop().RunUntilIdle();
5348
5349   // Read the server push body.
5350   std::string result2;
5351   ReadResult(trans2.get(), &data, &result2);
5352   // Read the response body.
5353   std::string result;
5354   ReadResult(trans, &data, &result);
5355
5356   // Verify that the received push data is same as the expected push data.
5357   EXPECT_EQ(expected_push_result, result2);
5358
5359   // Verify the SYN_REPLY.
5360   // Copy the response info, because trans goes away.
5361   response = *trans->GetResponseInfo();
5362   response2 = *trans2->GetResponseInfo();
5363
5364   VerifyStreamsClosed(helper);
5365
5366   // Verify the SYN_REPLY.
5367   EXPECT_TRUE(response.headers.get() != NULL);
5368   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
5369
5370   // Verify the pushed stream.
5371   EXPECT_TRUE(response2.headers.get() != NULL);
5372   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
5373
5374   // Verify we got all the headers
5375   if (spdy_util_.spdy_version() < SPDY3) {
5376     EXPECT_TRUE(response2.headers->HasHeaderValue(
5377         "url",
5378         "http://www.google.com/foo.dat"));
5379   } else {
5380     EXPECT_TRUE(response2.headers->HasHeaderValue(
5381         "scheme", "http"));
5382     EXPECT_TRUE(response2.headers->HasHeaderValue(
5383         "host", "www.google.com"));
5384     EXPECT_TRUE(response2.headers->HasHeaderValue(
5385         "path", "/foo.dat"));
5386   }
5387   EXPECT_TRUE(response2.headers->HasHeaderValue("hello", "bye"));
5388   EXPECT_TRUE(response2.headers->HasHeaderValue("status", "200"));
5389   EXPECT_TRUE(response2.headers->HasHeaderValue("version", "HTTP/1.1"));
5390
5391   // Read the final EOF (which will close the session)
5392   data.RunFor(1);
5393
5394   // Verify that we consumed all test data.
5395   EXPECT_TRUE(data.at_read_eof());
5396   EXPECT_TRUE(data.at_write_eof());
5397 }
5398
5399 TEST_P(SpdyNetworkTransactionTest, ServerPushWithNoStatusHeaderFrames) {
5400   // We push a stream and attempt to claim it before the headers come down.
5401   scoped_ptr<SpdyFrame> stream1_syn(
5402       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5403   scoped_ptr<SpdyFrame> stream1_body(
5404       spdy_util_.ConstructSpdyBodyFrame(1, true));
5405   MockWrite writes[] = {
5406     CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS),
5407   };
5408
5409   scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
5410   spdy_util_.AddUrlToHeaderBlock(
5411       "http://www.google.com/foo.dat", initial_headers.get());
5412   scoped_ptr<SpdyFrame> stream2_syn(
5413       spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(),
5414                                            false,
5415                                            2,
5416                                            LOWEST,
5417                                            SYN_STREAM,
5418                                            CONTROL_FLAG_NONE,
5419                                            1));
5420
5421   scoped_ptr<SpdyHeaderBlock> middle_headers(new SpdyHeaderBlock());
5422   (*middle_headers)["hello"] = "bye";
5423   scoped_ptr<SpdyFrame> stream2_headers1(
5424       spdy_util_.ConstructSpdyControlFrame(middle_headers.Pass(),
5425                                            false,
5426                                            2,
5427                                            LOWEST,
5428                                            HEADERS,
5429                                            CONTROL_FLAG_NONE,
5430                                            0));
5431
5432   scoped_ptr<SpdyFrame>
5433       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5434   const char kPushedData[] = "pushed";
5435   scoped_ptr<SpdyFrame> stream2_body(
5436       spdy_util_.ConstructSpdyBodyFrame(
5437           2, kPushedData, strlen(kPushedData), true));
5438   MockRead reads[] = {
5439     CreateMockRead(*stream1_reply, 1),
5440     CreateMockRead(*stream2_syn, 2),
5441     CreateMockRead(*stream1_body, 3),
5442     CreateMockRead(*stream2_headers1, 4),
5443     CreateMockRead(*stream2_body, 5),
5444     MockRead(ASYNC, 0, 6),  // EOF
5445   };
5446
5447   DeterministicSocketData data(reads, arraysize(reads),
5448                                writes, arraysize(writes));
5449
5450   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5451                                      BoundNetLog(), GetParam(), NULL);
5452   helper.SetDeterministic();
5453   helper.AddDeterministicData(&data);
5454   helper.RunPreTestSetup();
5455
5456   HttpNetworkTransaction* trans = helper.trans();
5457
5458   // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
5459   // the first HEADERS frame, and the body of the primary stream, but before
5460   // we've received the final HEADERS for the pushed stream.
5461   data.SetStop(4);
5462
5463   // Start the transaction.
5464   TestCompletionCallback callback;
5465   int rv = trans->Start(
5466       &CreateGetRequest(), callback.callback(), BoundNetLog());
5467   EXPECT_EQ(ERR_IO_PENDING, rv);
5468   data.Run();
5469   rv = callback.WaitForResult();
5470   EXPECT_EQ(0, rv);
5471
5472   // Request the pushed path.  At this point, we've received the push, but the
5473   // headers are not yet complete.
5474   scoped_ptr<HttpNetworkTransaction> trans2(
5475       new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
5476   rv = trans2->Start(
5477       &CreateGetPushRequest(), callback.callback(), BoundNetLog());
5478   EXPECT_EQ(ERR_IO_PENDING, rv);
5479   data.RunFor(2);
5480   base::RunLoop().RunUntilIdle();
5481
5482   // Read the server push body.
5483   std::string result2;
5484   ReadResult(trans2.get(), &data, &result2);
5485   // Read the response body.
5486   std::string result;
5487   ReadResult(trans, &data, &result);
5488   EXPECT_EQ("hello!", result);
5489
5490   // Verify that we haven't received any push data.
5491   EXPECT_EQ("", result2);
5492
5493   // Verify the SYN_REPLY.
5494   // Copy the response info, because trans goes away.
5495   HttpResponseInfo response = *trans->GetResponseInfo();
5496   ASSERT_TRUE(trans2->GetResponseInfo() == NULL);
5497
5498   VerifyStreamsClosed(helper);
5499
5500   // Verify the SYN_REPLY.
5501   EXPECT_TRUE(response.headers.get() != NULL);
5502   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
5503
5504   // Read the final EOF (which will close the session).
5505   data.RunFor(1);
5506
5507   // Verify that we consumed all test data.
5508   EXPECT_TRUE(data.at_read_eof());
5509   EXPECT_TRUE(data.at_write_eof());
5510 }
5511
5512 TEST_P(SpdyNetworkTransactionTest, SynReplyWithHeaders) {
5513   scoped_ptr<SpdyFrame> req(
5514       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5515   scoped_ptr<SpdyFrame> rst(
5516       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
5517   MockWrite writes[] = {
5518     CreateMockWrite(*req),
5519     CreateMockWrite(*rst),
5520  };
5521
5522   scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
5523   (*initial_headers)[spdy_util_.GetStatusKey()] = "200 OK";
5524   (*initial_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
5525   scoped_ptr<SpdyFrame> stream1_reply(
5526       spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(),
5527                                            false,
5528                                            1,
5529                                            LOWEST,
5530                                            SYN_REPLY,
5531                                            CONTROL_FLAG_NONE,
5532                                            0));
5533
5534   scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
5535   (*late_headers)["hello"] = "bye";
5536   scoped_ptr<SpdyFrame> stream1_headers(
5537       spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
5538                                            false,
5539                                            1,
5540                                            LOWEST,
5541                                            HEADERS,
5542                                            CONTROL_FLAG_NONE,
5543                                            0));
5544   scoped_ptr<SpdyFrame> stream1_body(
5545       spdy_util_.ConstructSpdyBodyFrame(1, true));
5546   MockRead reads[] = {
5547     CreateMockRead(*stream1_reply),
5548     CreateMockRead(*stream1_headers),
5549     CreateMockRead(*stream1_body),
5550     MockRead(ASYNC, 0, 0)  // EOF
5551   };
5552
5553   DelayedSocketData data(1, reads, arraysize(reads),
5554                          writes, arraysize(writes));
5555   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5556                                      BoundNetLog(), GetParam(), NULL);
5557   helper.RunToCompletion(&data);
5558   TransactionHelperResult out = helper.output();
5559   EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
5560 }
5561
5562 TEST_P(SpdyNetworkTransactionTest, SynReplyWithLateHeaders) {
5563   scoped_ptr<SpdyFrame> req(
5564       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5565   scoped_ptr<SpdyFrame> rst(
5566       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
5567   MockWrite writes[] = {
5568     CreateMockWrite(*req),
5569     CreateMockWrite(*rst),
5570   };
5571
5572   scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
5573   (*initial_headers)[spdy_util_.GetStatusKey()] = "200 OK";
5574   (*initial_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
5575   scoped_ptr<SpdyFrame> stream1_reply(
5576       spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(),
5577                                            false,
5578                                            1,
5579                                            LOWEST,
5580                                            SYN_REPLY,
5581                                            CONTROL_FLAG_NONE,
5582                                            0));
5583
5584   scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
5585   (*late_headers)["hello"] = "bye";
5586   scoped_ptr<SpdyFrame> stream1_headers(
5587       spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
5588                                            false,
5589                                            1,
5590                                            LOWEST,
5591                                            HEADERS,
5592                                            CONTROL_FLAG_NONE,
5593                                            0));
5594   scoped_ptr<SpdyFrame> stream1_body(
5595       spdy_util_.ConstructSpdyBodyFrame(1, false));
5596   scoped_ptr<SpdyFrame> stream1_body2(
5597       spdy_util_.ConstructSpdyBodyFrame(1, true));
5598   MockRead reads[] = {
5599     CreateMockRead(*stream1_reply),
5600     CreateMockRead(*stream1_body),
5601     CreateMockRead(*stream1_headers),
5602     CreateMockRead(*stream1_body2),
5603     MockRead(ASYNC, 0, 0)  // EOF
5604   };
5605
5606   DelayedSocketData data(1, reads, arraysize(reads),
5607                          writes, arraysize(writes));
5608   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5609                                      BoundNetLog(), GetParam(), NULL);
5610   helper.RunToCompletion(&data);
5611   TransactionHelperResult out = helper.output();
5612   EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
5613 }
5614
5615 TEST_P(SpdyNetworkTransactionTest, ServerPushCrossOriginCorrectness) {
5616   if (spdy_util_.spdy_version() == SPDY4) {
5617     // TODO(jgraettinger): We don't support associated stream
5618     // checks in SPDY4 yet.
5619     return;
5620   }
5621   // In this test we want to verify that we can't accidentally push content
5622   // which can't be pushed by this content server.
5623   // This test assumes that:
5624   //   - if we're requesting http://www.foo.com/barbaz
5625   //   - the browser has made a connection to "www.foo.com".
5626
5627   // A list of the URL to fetch, followed by the URL being pushed.
5628   static const char* const kTestCases[] = {
5629     "http://www.google.com/foo.html",
5630     "http://www.google.com:81/foo.js",     // Bad port
5631
5632     "http://www.google.com/foo.html",
5633     "https://www.google.com/foo.js",       // Bad protocol
5634
5635     "http://www.google.com/foo.html",
5636     "ftp://www.google.com/foo.js",         // Invalid Protocol
5637
5638     "http://www.google.com/foo.html",
5639     "http://blat.www.google.com/foo.js",   // Cross subdomain
5640
5641     "http://www.google.com/foo.html",
5642     "http://www.foo.com/foo.js",           // Cross domain
5643   };
5644
5645   for (size_t index = 0; index < arraysize(kTestCases); index += 2) {
5646     const char* url_to_fetch = kTestCases[index];
5647     const char* url_to_push = kTestCases[index + 1];
5648
5649     scoped_ptr<SpdyFrame> stream1_syn(
5650         spdy_util_.ConstructSpdyGet(url_to_fetch, false, 1, LOWEST));
5651     scoped_ptr<SpdyFrame> stream1_body(
5652         spdy_util_.ConstructSpdyBodyFrame(1, true));
5653     scoped_ptr<SpdyFrame> push_rst(
5654         spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
5655     MockWrite writes[] = {
5656       CreateMockWrite(*stream1_syn, 1),
5657       CreateMockWrite(*push_rst, 4),
5658     };
5659
5660     scoped_ptr<SpdyFrame>
5661         stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5662     scoped_ptr<SpdyFrame>
5663         stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
5664                                                  0,
5665                                                  2,
5666                                                  1,
5667                                                  url_to_push));
5668     const char kPushedData[] = "pushed";
5669     scoped_ptr<SpdyFrame> stream2_body(
5670         spdy_util_.ConstructSpdyBodyFrame(
5671             2, kPushedData, strlen(kPushedData), true));
5672     scoped_ptr<SpdyFrame> rst(
5673         spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_CANCEL));
5674
5675     MockRead reads[] = {
5676       CreateMockRead(*stream1_reply, 2),
5677       CreateMockRead(*stream2_syn, 3),
5678       CreateMockRead(*stream1_body, 5, SYNCHRONOUS),
5679       CreateMockRead(*stream2_body, 6),
5680       MockRead(ASYNC, ERR_IO_PENDING, 7),  // Force a pause
5681     };
5682
5683     HttpResponseInfo response;
5684     OrderedSocketData data(reads, arraysize(reads),
5685                            writes, arraysize(writes));
5686
5687     HttpRequestInfo request;
5688     request.method = "GET";
5689     request.url = GURL(url_to_fetch);
5690     request.load_flags = 0;
5691
5692     // Enable cross-origin push. Since we are not using a proxy, this should
5693     // not actually enable cross-origin SPDY push.
5694     scoped_ptr<SpdySessionDependencies> session_deps(
5695         CreateSpdySessionDependencies(GetParam()));
5696     session_deps->trusted_spdy_proxy = "123.45.67.89:8080";
5697     NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
5698                                        BoundNetLog(), GetParam(),
5699                                        session_deps.release());
5700     helper.RunPreTestSetup();
5701     helper.AddData(&data);
5702
5703     HttpNetworkTransaction* trans = helper.trans();
5704
5705     // Start the transaction with basic parameters.
5706     TestCompletionCallback callback;
5707
5708     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
5709     EXPECT_EQ(ERR_IO_PENDING, rv);
5710     rv = callback.WaitForResult();
5711
5712     // Read the response body.
5713     std::string result;
5714     ReadResult(trans, &data, &result);
5715
5716     // Verify that we consumed all test data.
5717     EXPECT_TRUE(data.at_read_eof());
5718     EXPECT_TRUE(data.at_write_eof());
5719
5720     // Verify the SYN_REPLY.
5721     // Copy the response info, because trans goes away.
5722     response = *trans->GetResponseInfo();
5723
5724     VerifyStreamsClosed(helper);
5725
5726     // Verify the SYN_REPLY.
5727     EXPECT_TRUE(response.headers.get() != NULL);
5728     EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
5729   }
5730 }
5731
5732 TEST_P(SpdyNetworkTransactionTest, RetryAfterRefused) {
5733   // Construct the request.
5734   scoped_ptr<SpdyFrame> req(
5735       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5736   scoped_ptr<SpdyFrame> req2(
5737       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
5738   MockWrite writes[] = {
5739     CreateMockWrite(*req, 1),
5740     CreateMockWrite(*req2, 3),
5741   };
5742
5743   scoped_ptr<SpdyFrame> refused(
5744       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_REFUSED_STREAM));
5745   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
5746   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(3, true));
5747   MockRead reads[] = {
5748     CreateMockRead(*refused, 2),
5749     CreateMockRead(*resp, 4),
5750     CreateMockRead(*body, 5),
5751     MockRead(ASYNC, 0, 6)  // EOF
5752   };
5753
5754   OrderedSocketData data(reads, arraysize(reads),
5755                          writes, arraysize(writes));
5756   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5757                                      BoundNetLog(), GetParam(), NULL);
5758
5759   helper.RunPreTestSetup();
5760   helper.AddData(&data);
5761
5762   HttpNetworkTransaction* trans = helper.trans();
5763
5764   // Start the transaction with basic parameters.
5765   TestCompletionCallback callback;
5766   int rv = trans->Start(
5767       &CreateGetRequest(), callback.callback(), BoundNetLog());
5768   EXPECT_EQ(ERR_IO_PENDING, rv);
5769   rv = callback.WaitForResult();
5770   EXPECT_EQ(OK, rv);
5771
5772   // Verify that we consumed all test data.
5773   EXPECT_TRUE(data.at_read_eof()) << "Read count: "
5774                                    << data.read_count()
5775                                    << " Read index: "
5776                                    << data.read_index();
5777   EXPECT_TRUE(data.at_write_eof()) << "Write count: "
5778                                     << data.write_count()
5779                                     << " Write index: "
5780                                     << data.write_index();
5781
5782   // Verify the SYN_REPLY.
5783   HttpResponseInfo response = *trans->GetResponseInfo();
5784   EXPECT_TRUE(response.headers.get() != NULL);
5785   EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
5786 }
5787
5788 TEST_P(SpdyNetworkTransactionTest, OutOfOrderSynStream) {
5789   // This first request will start to establish the SpdySession.
5790   // Then we will start the second (MEDIUM priority) and then third
5791   // (HIGHEST priority) request in such a way that the third will actually
5792   // start before the second, causing the second to be numbered differently
5793   // than the order they were created.
5794   scoped_ptr<SpdyFrame> req1(
5795       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5796   scoped_ptr<SpdyFrame> req2(
5797       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, HIGHEST, true));
5798   scoped_ptr<SpdyFrame> req3(
5799       spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, MEDIUM, true));
5800   MockWrite writes[] = {
5801     CreateMockWrite(*req1, 0),
5802     CreateMockWrite(*req2, 3),
5803     CreateMockWrite(*req3, 4),
5804   };
5805
5806   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5807   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
5808   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
5809   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
5810   scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
5811   scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, true));
5812   MockRead reads[] = {
5813     CreateMockRead(*resp1, 1),
5814     CreateMockRead(*body1, 2),
5815     CreateMockRead(*resp2, 5),
5816     CreateMockRead(*body2, 6),
5817     CreateMockRead(*resp3, 7),
5818     CreateMockRead(*body3, 8),
5819     MockRead(ASYNC, 0, 9)  // EOF
5820   };
5821
5822   DeterministicSocketData data(reads, arraysize(reads),
5823                                writes, arraysize(writes));
5824   NormalSpdyTransactionHelper helper(CreateGetRequest(), LOWEST,
5825                                      BoundNetLog(), GetParam(), NULL);
5826   helper.SetDeterministic();
5827   helper.RunPreTestSetup();
5828   helper.AddDeterministicData(&data);
5829
5830   // Start the first transaction to set up the SpdySession
5831   HttpNetworkTransaction* trans = helper.trans();
5832   TestCompletionCallback callback;
5833   HttpRequestInfo info1 = CreateGetRequest();
5834   int rv = trans->Start(&info1, callback.callback(), BoundNetLog());
5835   EXPECT_EQ(ERR_IO_PENDING, rv);
5836
5837   // Run the message loop, but do not allow the write to complete.
5838   // This leaves the SpdySession with a write pending, which prevents
5839   // SpdySession from attempting subsequent writes until this write completes.
5840   base::RunLoop().RunUntilIdle();
5841
5842   // Now, start both new transactions
5843   HttpRequestInfo info2 = CreateGetRequest();
5844   TestCompletionCallback callback2;
5845   scoped_ptr<HttpNetworkTransaction> trans2(
5846       new HttpNetworkTransaction(MEDIUM, helper.session().get()));
5847   rv = trans2->Start(&info2, callback2.callback(), BoundNetLog());
5848   EXPECT_EQ(ERR_IO_PENDING, rv);
5849   base::RunLoop().RunUntilIdle();
5850
5851   HttpRequestInfo info3 = CreateGetRequest();
5852   TestCompletionCallback callback3;
5853   scoped_ptr<HttpNetworkTransaction> trans3(
5854       new HttpNetworkTransaction(HIGHEST, helper.session().get()));
5855   rv = trans3->Start(&info3, callback3.callback(), BoundNetLog());
5856   EXPECT_EQ(ERR_IO_PENDING, rv);
5857   base::RunLoop().RunUntilIdle();
5858
5859   // We now have two SYN_STREAM frames queued up which will be
5860   // dequeued only once the first write completes, which we
5861   // now allow to happen.
5862   data.RunFor(2);
5863   EXPECT_EQ(OK, callback.WaitForResult());
5864
5865   // And now we can allow everything else to run to completion.
5866   data.SetStop(10);
5867   data.Run();
5868   EXPECT_EQ(OK, callback2.WaitForResult());
5869   EXPECT_EQ(OK, callback3.WaitForResult());
5870
5871   helper.VerifyDataConsumed();
5872 }
5873
5874 // The tests below are only for SPDY/3 and above.
5875
5876 // Test that sent data frames and received WINDOW_UPDATE frames change
5877 // the send_window_size_ correctly.
5878
5879 // WINDOW_UPDATE is different than most other frames in that it can arrive
5880 // while the client is still sending the request body.  In order to enforce
5881 // this scenario, we feed a couple of dummy frames and give a delay of 0 to
5882 // socket data provider, so that initial read that is done as soon as the
5883 // stream is created, succeeds and schedules another read.  This way reads
5884 // and writes are interleaved; after doing a full frame write, SpdyStream
5885 // will break out of DoLoop and will read and process a WINDOW_UPDATE.
5886 // Once our WINDOW_UPDATE is read, we cannot send SYN_REPLY right away
5887 // since request has not been completely written, therefore we feed
5888 // enough number of WINDOW_UPDATEs to finish the first read and cause a
5889 // write, leading to a complete write of request body; after that we send
5890 // a reply with a body, to cause a graceful shutdown.
5891
5892 // TODO(agayev): develop a socket data provider where both, reads and
5893 // writes are ordered so that writing tests like these are easy and rewrite
5894 // all these tests using it.  Right now we are working around the
5895 // limitations as described above and it's not deterministic, tests may
5896 // fail under specific circumstances.
5897 TEST_P(SpdyNetworkTransactionTest, WindowUpdateReceived) {
5898   if (GetParam().protocol < kProtoSPDY3)
5899     return;
5900
5901   static int kFrameCount = 2;
5902   scoped_ptr<std::string> content(
5903       new std::string(kMaxSpdyFrameChunkSize, 'a'));
5904   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
5905       kRequestUrl, 1, kMaxSpdyFrameChunkSize * kFrameCount, LOWEST, NULL, 0));
5906   scoped_ptr<SpdyFrame> body(
5907       spdy_util_.ConstructSpdyBodyFrame(
5908           1, content->c_str(), content->size(), false));
5909   scoped_ptr<SpdyFrame> body_end(
5910       spdy_util_.ConstructSpdyBodyFrame(
5911           1, content->c_str(), content->size(), true));
5912
5913   MockWrite writes[] = {
5914     CreateMockWrite(*req, 0),
5915     CreateMockWrite(*body, 1),
5916     CreateMockWrite(*body_end, 2),
5917   };
5918
5919   static const int32 kDeltaWindowSize = 0xff;
5920   static const int kDeltaCount = 4;
5921   scoped_ptr<SpdyFrame> window_update(
5922       spdy_util_.ConstructSpdyWindowUpdate(1, kDeltaWindowSize));
5923   scoped_ptr<SpdyFrame> window_update_dummy(
5924       spdy_util_.ConstructSpdyWindowUpdate(2, kDeltaWindowSize));
5925   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
5926   MockRead reads[] = {
5927     CreateMockRead(*window_update_dummy, 3),
5928     CreateMockRead(*window_update_dummy, 4),
5929     CreateMockRead(*window_update_dummy, 5),
5930     CreateMockRead(*window_update, 6),     // Four updates, therefore window
5931     CreateMockRead(*window_update, 7),     // size should increase by
5932     CreateMockRead(*window_update, 8),     // kDeltaWindowSize * 4
5933     CreateMockRead(*window_update, 9),
5934     CreateMockRead(*resp, 10),
5935     CreateMockRead(*body_end, 11),
5936     MockRead(ASYNC, 0, 0, 12)  // EOF
5937   };
5938
5939   DeterministicSocketData data(reads, arraysize(reads),
5940                                writes, arraysize(writes));
5941
5942   ScopedVector<UploadElementReader> element_readers;
5943   for (int i = 0; i < kFrameCount; ++i) {
5944     element_readers.push_back(
5945         new UploadBytesElementReader(content->c_str(), content->size()));
5946   }
5947   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
5948
5949   // Setup the request
5950   HttpRequestInfo request;
5951   request.method = "POST";
5952   request.url = GURL(kDefaultURL);
5953   request.upload_data_stream = &upload_data_stream;
5954
5955   NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
5956                                      BoundNetLog(), GetParam(), NULL);
5957   helper.SetDeterministic();
5958   helper.AddDeterministicData(&data);
5959   helper.RunPreTestSetup();
5960
5961   HttpNetworkTransaction* trans = helper.trans();
5962
5963   TestCompletionCallback callback;
5964   int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
5965
5966   EXPECT_EQ(ERR_IO_PENDING, rv);
5967
5968   data.RunFor(11);
5969
5970   SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
5971   ASSERT_TRUE(stream != NULL);
5972   ASSERT_TRUE(stream->stream() != NULL);
5973   EXPECT_EQ(static_cast<int>(kSpdyStreamInitialWindowSize) +
5974             kDeltaWindowSize * kDeltaCount -
5975             kMaxSpdyFrameChunkSize * kFrameCount,
5976             stream->stream()->send_window_size());
5977
5978   data.RunFor(1);
5979
5980   rv = callback.WaitForResult();
5981   EXPECT_EQ(OK, rv);
5982
5983   helper.VerifyDataConsumed();
5984 }
5985
5986 // Test that received data frames and sent WINDOW_UPDATE frames change
5987 // the recv_window_size_ correctly.
5988 TEST_P(SpdyNetworkTransactionTest, WindowUpdateSent) {
5989   if (GetParam().protocol < kProtoSPDY3)
5990     return;
5991
5992   // Set the data in the body frame large enough to trigger sending a
5993   // WINDOW_UPDATE by the stream.
5994   const std::string body_data(kSpdyStreamInitialWindowSize / 2 + 1, 'x');
5995
5996   scoped_ptr<SpdyFrame> req(
5997       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5998   scoped_ptr<SpdyFrame> session_window_update(
5999       spdy_util_.ConstructSpdyWindowUpdate(0, body_data.size()));
6000   scoped_ptr<SpdyFrame> window_update(
6001       spdy_util_.ConstructSpdyWindowUpdate(1, body_data.size()));
6002
6003   std::vector<MockWrite> writes;
6004   writes.push_back(CreateMockWrite(*req));
6005   if (GetParam().protocol >= kProtoSPDY31)
6006     writes.push_back(CreateMockWrite(*session_window_update));
6007   writes.push_back(CreateMockWrite(*window_update));
6008
6009   scoped_ptr<SpdyFrame> resp(
6010       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
6011   scoped_ptr<SpdyFrame> body_no_fin(
6012       spdy_util_.ConstructSpdyBodyFrame(
6013           1, body_data.data(), body_data.size(), false));
6014   scoped_ptr<SpdyFrame> body_fin(
6015       spdy_util_.ConstructSpdyBodyFrame(1, NULL, 0, true));
6016   MockRead reads[] = {
6017     CreateMockRead(*resp),
6018     CreateMockRead(*body_no_fin),
6019     MockRead(ASYNC, ERR_IO_PENDING, 0),  // Force a pause
6020     CreateMockRead(*body_fin),
6021     MockRead(ASYNC, ERR_IO_PENDING, 0),  // Force a pause
6022     MockRead(ASYNC, 0, 0)  // EOF
6023   };
6024
6025   DelayedSocketData data(1, reads, arraysize(reads),
6026                          vector_as_array(&writes), writes.size());
6027
6028   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
6029                                      BoundNetLog(), GetParam(), NULL);
6030   helper.AddData(&data);
6031   helper.RunPreTestSetup();
6032   HttpNetworkTransaction* trans = helper.trans();
6033
6034   TestCompletionCallback callback;
6035   int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
6036
6037   EXPECT_EQ(ERR_IO_PENDING, rv);
6038   rv = callback.WaitForResult();
6039   EXPECT_EQ(OK, rv);
6040
6041   SpdyHttpStream* stream =
6042       static_cast<SpdyHttpStream*>(trans->stream_.get());
6043   ASSERT_TRUE(stream != NULL);
6044   ASSERT_TRUE(stream->stream() != NULL);
6045
6046   EXPECT_EQ(
6047       static_cast<int>(kSpdyStreamInitialWindowSize - body_data.size()),
6048       stream->stream()->recv_window_size());
6049
6050   const HttpResponseInfo* response = trans->GetResponseInfo();
6051   ASSERT_TRUE(response != NULL);
6052   ASSERT_TRUE(response->headers.get() != NULL);
6053   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6054   EXPECT_TRUE(response->was_fetched_via_spdy);
6055
6056   // Issue a read which will cause a WINDOW_UPDATE to be sent and window
6057   // size increased to default.
6058   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(body_data.size()));
6059   rv = trans->Read(buf.get(), body_data.size(), CompletionCallback());
6060   EXPECT_EQ(static_cast<int>(body_data.size()), rv);
6061   std::string content(buf->data(), buf->data() + body_data.size());
6062   EXPECT_EQ(body_data, content);
6063
6064   // Schedule the reading of empty data frame with FIN
6065   data.CompleteRead();
6066
6067   // Force write of WINDOW_UPDATE which was scheduled during the above
6068   // read.
6069   base::RunLoop().RunUntilIdle();
6070
6071   // Read EOF.
6072   data.CompleteRead();
6073
6074   helper.VerifyDataConsumed();
6075 }
6076
6077 // Test that WINDOW_UPDATE frame causing overflow is handled correctly.
6078 TEST_P(SpdyNetworkTransactionTest, WindowUpdateOverflow) {
6079   if (GetParam().protocol < kProtoSPDY3)
6080     return;
6081
6082   // Number of full frames we hope to write (but will not, used to
6083   // set content-length header correctly)
6084   static int kFrameCount = 3;
6085
6086   scoped_ptr<std::string> content(
6087       new std::string(kMaxSpdyFrameChunkSize, 'a'));
6088   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
6089       kRequestUrl, 1, kMaxSpdyFrameChunkSize * kFrameCount, LOWEST, NULL, 0));
6090   scoped_ptr<SpdyFrame> body(
6091       spdy_util_.ConstructSpdyBodyFrame(
6092           1, content->c_str(), content->size(), false));
6093   scoped_ptr<SpdyFrame> rst(
6094       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_FLOW_CONTROL_ERROR));
6095
6096   // We're not going to write a data frame with FIN, we'll receive a bad
6097   // WINDOW_UPDATE while sending a request and will send a RST_STREAM frame.
6098   MockWrite writes[] = {
6099     CreateMockWrite(*req, 0),
6100     CreateMockWrite(*body, 2),
6101     CreateMockWrite(*rst, 3),
6102   };
6103
6104   static const int32 kDeltaWindowSize = 0x7fffffff;  // cause an overflow
6105   scoped_ptr<SpdyFrame> window_update(
6106       spdy_util_.ConstructSpdyWindowUpdate(1, kDeltaWindowSize));
6107   MockRead reads[] = {
6108     CreateMockRead(*window_update, 1),
6109     MockRead(ASYNC, 0, 4)  // EOF
6110   };
6111
6112   DeterministicSocketData data(reads, arraysize(reads),
6113                                writes, arraysize(writes));
6114
6115   ScopedVector<UploadElementReader> element_readers;
6116   for (int i = 0; i < kFrameCount; ++i) {
6117     element_readers.push_back(
6118         new UploadBytesElementReader(content->c_str(), content->size()));
6119   }
6120   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
6121
6122   // Setup the request
6123   HttpRequestInfo request;
6124   request.method = "POST";
6125   request.url = GURL("http://www.google.com/");
6126   request.upload_data_stream = &upload_data_stream;
6127
6128   NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
6129                                      BoundNetLog(), GetParam(), NULL);
6130   helper.SetDeterministic();
6131   helper.RunPreTestSetup();
6132   helper.AddDeterministicData(&data);
6133   HttpNetworkTransaction* trans = helper.trans();
6134
6135   TestCompletionCallback callback;
6136   int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
6137   ASSERT_EQ(ERR_IO_PENDING, rv);
6138
6139   data.RunFor(5);
6140   ASSERT_TRUE(callback.have_result());
6141   EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, callback.WaitForResult());
6142   helper.VerifyDataConsumed();
6143 }
6144
6145 // Test that after hitting a send window size of 0, the write process
6146 // stalls and upon receiving WINDOW_UPDATE frame write resumes.
6147
6148 // This test constructs a POST request followed by enough data frames
6149 // containing 'a' that would make the window size 0, followed by another
6150 // data frame containing default content (which is "hello!") and this frame
6151 // also contains a FIN flag.  DelayedSocketData is used to enforce all
6152 // writes go through before a read could happen.  However, the last frame
6153 // ("hello!")  is not supposed to go through since by the time its turn
6154 // arrives, window size is 0.  At this point MessageLoop::Run() called via
6155 // callback would block.  Therefore we call MessageLoop::RunUntilIdle()
6156 // which returns after performing all possible writes.  We use DCHECKS to
6157 // ensure that last data frame is still there and stream has stalled.
6158 // After that, next read is artifically enforced, which causes a
6159 // WINDOW_UPDATE to be read and I/O process resumes.
6160 TEST_P(SpdyNetworkTransactionTest, FlowControlStallResume) {
6161   if (GetParam().protocol < kProtoSPDY3)
6162     return;
6163
6164   // Number of frames we need to send to zero out the window size: data
6165   // frames plus SYN_STREAM plus the last data frame; also we need another
6166   // data frame that we will send once the WINDOW_UPDATE is received,
6167   // therefore +3.
6168   size_t num_writes = kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3;
6169
6170   // Calculate last frame's size; 0 size data frame is legal.
6171   size_t last_frame_size =
6172       kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize;
6173
6174   // Construct content for a data frame of maximum size.
6175   std::string content(kMaxSpdyFrameChunkSize, 'a');
6176
6177   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
6178       kRequestUrl, 1, kSpdyStreamInitialWindowSize + kUploadDataSize,
6179       LOWEST, NULL, 0));
6180
6181   // Full frames.
6182   scoped_ptr<SpdyFrame> body1(
6183       spdy_util_.ConstructSpdyBodyFrame(
6184           1, content.c_str(), content.size(), false));
6185
6186   // Last frame to zero out the window size.
6187   scoped_ptr<SpdyFrame> body2(
6188       spdy_util_.ConstructSpdyBodyFrame(
6189           1, content.c_str(), last_frame_size, false));
6190
6191   // Data frame to be sent once WINDOW_UPDATE frame is received.
6192   scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(1, true));
6193
6194   // Fill in mock writes.
6195   scoped_ptr<MockWrite[]> writes(new MockWrite[num_writes]);
6196   size_t i = 0;
6197   writes[i] = CreateMockWrite(*req);
6198   for (i = 1; i < num_writes - 2; i++)
6199     writes[i] = CreateMockWrite(*body1);
6200   writes[i++] = CreateMockWrite(*body2);
6201   writes[i] = CreateMockWrite(*body3);
6202
6203   // Construct read frame, give enough space to upload the rest of the
6204   // data.
6205   scoped_ptr<SpdyFrame> session_window_update(
6206       spdy_util_.ConstructSpdyWindowUpdate(0, kUploadDataSize));
6207   scoped_ptr<SpdyFrame> window_update(
6208       spdy_util_.ConstructSpdyWindowUpdate(1, kUploadDataSize));
6209   scoped_ptr<SpdyFrame> reply(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
6210   MockRead reads[] = {
6211     CreateMockRead(*session_window_update),
6212     CreateMockRead(*session_window_update),
6213     CreateMockRead(*window_update),
6214     CreateMockRead(*window_update),
6215     CreateMockRead(*reply),
6216     CreateMockRead(*body2),
6217     CreateMockRead(*body3),
6218     MockRead(ASYNC, 0, 0)  // EOF
6219   };
6220
6221   // Skip the session window updates unless we're using SPDY/3.1 and
6222   // above.
6223   size_t read_offset = (GetParam().protocol >= kProtoSPDY31) ? 0 : 2;
6224   size_t num_reads = arraysize(reads) - read_offset;
6225
6226   // Force all writes to happen before any read, last write will not
6227   // actually queue a frame, due to window size being 0.
6228   DelayedSocketData data(num_writes, reads + read_offset, num_reads,
6229                          writes.get(), num_writes);
6230
6231   ScopedVector<UploadElementReader> element_readers;
6232   std::string upload_data_string(kSpdyStreamInitialWindowSize, 'a');
6233   upload_data_string.append(kUploadData, kUploadDataSize);
6234   element_readers.push_back(new UploadBytesElementReader(
6235       upload_data_string.c_str(), upload_data_string.size()));
6236   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
6237
6238   HttpRequestInfo request;
6239   request.method = "POST";
6240   request.url = GURL("http://www.google.com/");
6241   request.upload_data_stream = &upload_data_stream;
6242   NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
6243                                      BoundNetLog(), GetParam(), NULL);
6244   helper.AddData(&data);
6245   helper.RunPreTestSetup();
6246
6247   HttpNetworkTransaction* trans = helper.trans();
6248
6249   TestCompletionCallback callback;
6250   int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
6251   EXPECT_EQ(ERR_IO_PENDING, rv);
6252
6253   base::RunLoop().RunUntilIdle();  // Write as much as we can.
6254
6255   SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
6256   ASSERT_TRUE(stream != NULL);
6257   ASSERT_TRUE(stream->stream() != NULL);
6258   EXPECT_EQ(0, stream->stream()->send_window_size());
6259   // All the body data should have been read.
6260   // TODO(satorux): This is because of the weirdness in reading the request
6261   // body in OnSendBodyComplete(). See crbug.com/113107.
6262   EXPECT_TRUE(upload_data_stream.IsEOF());
6263   // But the body is not yet fully sent (kUploadData is not yet sent)
6264   // since we're send-stalled.
6265   EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
6266
6267   data.ForceNextRead();   // Read in WINDOW_UPDATE frame.
6268   rv = callback.WaitForResult();
6269   helper.VerifyDataConsumed();
6270 }
6271
6272 // Test we correctly handle the case where the SETTINGS frame results in
6273 // unstalling the send window.
6274 TEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) {
6275   if (GetParam().protocol < kProtoSPDY3)
6276     return;
6277
6278   // Number of frames we need to send to zero out the window size: data
6279   // frames plus SYN_STREAM plus the last data frame; also we need another
6280   // data frame that we will send once the SETTING is received, therefore +3.
6281   size_t num_writes = kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3;
6282
6283   // Calculate last frame's size; 0 size data frame is legal.
6284   size_t last_frame_size =
6285       kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize;
6286
6287   // Construct content for a data frame of maximum size.
6288   std::string content(kMaxSpdyFrameChunkSize, 'a');
6289
6290   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
6291       kRequestUrl, 1, kSpdyStreamInitialWindowSize + kUploadDataSize,
6292       LOWEST, NULL, 0));
6293
6294   // Full frames.
6295   scoped_ptr<SpdyFrame> body1(
6296       spdy_util_.ConstructSpdyBodyFrame(
6297           1, content.c_str(), content.size(), false));
6298
6299   // Last frame to zero out the window size.
6300   scoped_ptr<SpdyFrame> body2(
6301       spdy_util_.ConstructSpdyBodyFrame(
6302           1, content.c_str(), last_frame_size, false));
6303
6304   // Data frame to be sent once SETTINGS frame is received.
6305   scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(1, true));
6306
6307   // Fill in mock reads/writes.
6308   std::vector<MockRead> reads;
6309   std::vector<MockWrite> writes;
6310   size_t i = 0;
6311   writes.push_back(CreateMockWrite(*req, i++));
6312   while (i < num_writes - 2)
6313     writes.push_back(CreateMockWrite(*body1, i++));
6314   writes.push_back(CreateMockWrite(*body2, i++));
6315
6316   // Construct read frame for SETTINGS that gives enough space to upload the
6317   // rest of the data.
6318   SettingsMap settings;
6319   settings[SETTINGS_INITIAL_WINDOW_SIZE] =
6320       SettingsFlagsAndValue(
6321           SETTINGS_FLAG_NONE, kSpdyStreamInitialWindowSize * 2);
6322   scoped_ptr<SpdyFrame> settings_frame_large(
6323       spdy_util_.ConstructSpdySettings(settings));
6324
6325   reads.push_back(CreateMockRead(*settings_frame_large, i++));
6326
6327   scoped_ptr<SpdyFrame> session_window_update(
6328       spdy_util_.ConstructSpdyWindowUpdate(0, kUploadDataSize));
6329   if (GetParam().protocol >= kProtoSPDY31)
6330     reads.push_back(CreateMockRead(*session_window_update, i++));
6331
6332   writes.push_back(CreateMockWrite(*body3, i++));
6333
6334   scoped_ptr<SpdyFrame> reply(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
6335   reads.push_back(CreateMockRead(*reply, i++));
6336   reads.push_back(CreateMockRead(*body2, i++));
6337   reads.push_back(CreateMockRead(*body3, i++));
6338   reads.push_back(MockRead(ASYNC, 0, i++));  // EOF
6339
6340   // Force all writes to happen before any read, last write will not
6341   // actually queue a frame, due to window size being 0.
6342   DeterministicSocketData data(vector_as_array(&reads), reads.size(),
6343                                vector_as_array(&writes), writes.size());
6344
6345   ScopedVector<UploadElementReader> element_readers;
6346   std::string upload_data_string(kSpdyStreamInitialWindowSize, 'a');
6347   upload_data_string.append(kUploadData, kUploadDataSize);
6348   element_readers.push_back(new UploadBytesElementReader(
6349       upload_data_string.c_str(), upload_data_string.size()));
6350   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
6351
6352   HttpRequestInfo request;
6353   request.method = "POST";
6354   request.url = GURL("http://www.google.com/");
6355   request.upload_data_stream = &upload_data_stream;
6356   NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
6357                                      BoundNetLog(), GetParam(), NULL);
6358   helper.SetDeterministic();
6359   helper.RunPreTestSetup();
6360   helper.AddDeterministicData(&data);
6361
6362   HttpNetworkTransaction* trans = helper.trans();
6363
6364   TestCompletionCallback callback;
6365   int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
6366   EXPECT_EQ(ERR_IO_PENDING, rv);
6367
6368   data.RunFor(num_writes - 1);   // Write as much as we can.
6369
6370   SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
6371   ASSERT_TRUE(stream != NULL);
6372   ASSERT_TRUE(stream->stream() != NULL);
6373   EXPECT_EQ(0, stream->stream()->send_window_size());
6374
6375   // All the body data should have been read.
6376   // TODO(satorux): This is because of the weirdness in reading the request
6377   // body in OnSendBodyComplete(). See crbug.com/113107.
6378   EXPECT_TRUE(upload_data_stream.IsEOF());
6379   // But the body is not yet fully sent (kUploadData is not yet sent)
6380   // since we're send-stalled.
6381   EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
6382
6383   data.RunFor(6);   // Read in SETTINGS frame to unstall.
6384   rv = callback.WaitForResult();
6385   helper.VerifyDataConsumed();
6386   // If stream is NULL, that means it was unstalled and closed.
6387   EXPECT_TRUE(stream->stream() == NULL);
6388 }
6389
6390 // Test we correctly handle the case where the SETTINGS frame results in a
6391 // negative send window size.
6392 TEST_P(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) {
6393   if (GetParam().protocol < kProtoSPDY3)
6394     return;
6395
6396   // Number of frames we need to send to zero out the window size: data
6397   // frames plus SYN_STREAM plus the last data frame; also we need another
6398   // data frame that we will send once the SETTING is received, therefore +3.
6399   size_t num_writes = kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3;
6400
6401   // Calculate last frame's size; 0 size data frame is legal.
6402   size_t last_frame_size =
6403       kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize;
6404
6405   // Construct content for a data frame of maximum size.
6406   std::string content(kMaxSpdyFrameChunkSize, 'a');
6407
6408   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
6409       kRequestUrl, 1, kSpdyStreamInitialWindowSize + kUploadDataSize,
6410       LOWEST, NULL, 0));
6411
6412   // Full frames.
6413   scoped_ptr<SpdyFrame> body1(
6414       spdy_util_.ConstructSpdyBodyFrame(
6415           1, content.c_str(), content.size(), false));
6416
6417   // Last frame to zero out the window size.
6418   scoped_ptr<SpdyFrame> body2(
6419       spdy_util_.ConstructSpdyBodyFrame(
6420           1, content.c_str(), last_frame_size, false));
6421
6422   // Data frame to be sent once SETTINGS frame is received.
6423   scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(1, true));
6424
6425   // Fill in mock reads/writes.
6426   std::vector<MockRead> reads;
6427   std::vector<MockWrite> writes;
6428   size_t i = 0;
6429   writes.push_back(CreateMockWrite(*req, i++));
6430   while (i < num_writes - 2)
6431     writes.push_back(CreateMockWrite(*body1, i++));
6432   writes.push_back(CreateMockWrite(*body2, i++));
6433
6434   // Construct read frame for SETTINGS that makes the send_window_size
6435   // negative.
6436   SettingsMap new_settings;
6437   new_settings[SETTINGS_INITIAL_WINDOW_SIZE] =
6438       SettingsFlagsAndValue(
6439           SETTINGS_FLAG_NONE, kSpdyStreamInitialWindowSize / 2);
6440   scoped_ptr<SpdyFrame> settings_frame_small(
6441       spdy_util_.ConstructSpdySettings(new_settings));
6442   // Construct read frames for WINDOW_UPDATE that makes the send_window_size
6443   // positive.
6444   scoped_ptr<SpdyFrame> session_window_update_init_size(
6445       spdy_util_.ConstructSpdyWindowUpdate(0, kSpdyStreamInitialWindowSize));
6446   scoped_ptr<SpdyFrame> window_update_init_size(
6447       spdy_util_.ConstructSpdyWindowUpdate(1, kSpdyStreamInitialWindowSize));
6448
6449   reads.push_back(CreateMockRead(*settings_frame_small, i++));
6450
6451   if (GetParam().protocol >= kProtoSPDY3)
6452     reads.push_back(CreateMockRead(*session_window_update_init_size, i++));
6453
6454   reads.push_back(CreateMockRead(*window_update_init_size, i++));
6455
6456   writes.push_back(CreateMockWrite(*body3, i++));
6457
6458   scoped_ptr<SpdyFrame> reply(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
6459   reads.push_back(CreateMockRead(*reply, i++));
6460   reads.push_back(CreateMockRead(*body2, i++));
6461   reads.push_back(CreateMockRead(*body3, i++));
6462   reads.push_back(MockRead(ASYNC, 0, i++));  // EOF
6463
6464   // Force all writes to happen before any read, last write will not
6465   // actually queue a frame, due to window size being 0.
6466   DeterministicSocketData data(vector_as_array(&reads), reads.size(),
6467                                vector_as_array(&writes), writes.size());
6468
6469   ScopedVector<UploadElementReader> element_readers;
6470   std::string upload_data_string(kSpdyStreamInitialWindowSize, 'a');
6471   upload_data_string.append(kUploadData, kUploadDataSize);
6472   element_readers.push_back(new UploadBytesElementReader(
6473       upload_data_string.c_str(), upload_data_string.size()));
6474   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
6475
6476   HttpRequestInfo request;
6477   request.method = "POST";
6478   request.url = GURL("http://www.google.com/");
6479   request.upload_data_stream = &upload_data_stream;
6480   NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
6481                                      BoundNetLog(), GetParam(), NULL);
6482   helper.SetDeterministic();
6483   helper.RunPreTestSetup();
6484   helper.AddDeterministicData(&data);
6485
6486   HttpNetworkTransaction* trans = helper.trans();
6487
6488   TestCompletionCallback callback;
6489   int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
6490   EXPECT_EQ(ERR_IO_PENDING, rv);
6491
6492   data.RunFor(num_writes - 1);   // Write as much as we can.
6493
6494   SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
6495   ASSERT_TRUE(stream != NULL);
6496   ASSERT_TRUE(stream->stream() != NULL);
6497   EXPECT_EQ(0, stream->stream()->send_window_size());
6498
6499   // All the body data should have been read.
6500   // TODO(satorux): This is because of the weirdness in reading the request
6501   // body in OnSendBodyComplete(). See crbug.com/113107.
6502   EXPECT_TRUE(upload_data_stream.IsEOF());
6503   // But the body is not yet fully sent (kUploadData is not yet sent)
6504   // since we're send-stalled.
6505   EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
6506
6507   // Read in WINDOW_UPDATE or SETTINGS frame.
6508   data.RunFor((GetParam().protocol >= kProtoSPDY31) ? 8 : 7);
6509   rv = callback.WaitForResult();
6510   helper.VerifyDataConsumed();
6511 }
6512
6513 }  // namespace net