• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
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 <cmath>
6 #include <utility>
7 #include <vector>
8 
9 #include "base/files/file_util.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/functional/bind.h"
12 #include "base/functional/callback_helpers.h"
13 #include "base/memory/raw_ptr.h"
14 #include "base/run_loop.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_piece.h"
17 #include "base/task/single_thread_task_runner.h"
18 #include "base/test/metrics/histogram_tester.h"
19 #include "base/test/scoped_feature_list.h"
20 #include "base/test/test_file_util.h"
21 #include "build/build_config.h"
22 #include "net/base/auth.h"
23 #include "net/base/chunked_upload_data_stream.h"
24 #include "net/base/completion_once_callback.h"
25 #include "net/base/elements_upload_data_stream.h"
26 #include "net/base/features.h"
27 #include "net/base/ip_endpoint.h"
28 #include "net/base/network_anonymization_key.h"
29 #include "net/base/proxy_delegate.h"
30 #include "net/base/proxy_server.h"
31 #include "net/base/proxy_string_util.h"
32 #include "net/base/request_priority.h"
33 #include "net/base/schemeful_site.h"
34 #include "net/base/test_proxy_delegate.h"
35 #include "net/base/upload_bytes_element_reader.h"
36 #include "net/base/upload_file_element_reader.h"
37 #include "net/dns/mock_host_resolver.h"
38 #include "net/dns/public/secure_dns_policy.h"
39 #include "net/http/http_auth_scheme.h"
40 #include "net/http/http_network_session.h"
41 #include "net/http/http_network_session_peer.h"
42 #include "net/http/http_network_transaction.h"
43 #include "net/http/http_proxy_connect_job.h"
44 #include "net/http/http_response_info.h"
45 #include "net/http/http_server_properties.h"
46 #include "net/http/http_transaction_test_util.h"
47 #include "net/http/test_upload_data_stream_not_allow_http1.h"
48 #include "net/http/transport_security_state.h"
49 #include "net/log/net_log_event_type.h"
50 #include "net/log/net_log_with_source.h"
51 #include "net/log/test_net_log.h"
52 #include "net/log/test_net_log_util.h"
53 #include "net/proxy_resolution/configured_proxy_resolution_service.h"
54 #include "net/socket/next_proto.h"
55 #include "net/socket/socket_tag.h"
56 #include "net/spdy/alps_decoder.h"
57 #include "net/spdy/buffered_spdy_framer.h"
58 #include "net/spdy/spdy_http_stream.h"
59 #include "net/spdy/spdy_http_utils.h"
60 #include "net/spdy/spdy_session.h"
61 #include "net/spdy/spdy_session_pool.h"
62 #include "net/spdy/spdy_test_util_common.h"
63 #include "net/ssl/ssl_connection_status_flags.h"
64 #include "net/test/cert_test_util.h"
65 #include "net/test/gtest_util.h"
66 #include "net/test/test_data_directory.h"
67 #include "net/test/test_with_task_environment.h"
68 #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"
69 #include "net/third_party/quiche/src/quiche/spdy/test_tools/spdy_test_utils.h"
70 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
71 #include "net/url_request/url_request_context.h"
72 #include "net/url_request/url_request_context_builder.h"
73 #include "net/url_request/url_request_test_util.h"
74 #include "net/websockets/websocket_test_util.h"
75 #include "testing/gmock/include/gmock/gmock.h"
76 #include "testing/platform_test.h"
77 #include "url/gurl.h"
78 
79 using net::test::IsError;
80 using net::test::IsOk;
81 
82 //-----------------------------------------------------------------------------
83 
84 namespace net {
85 
86 namespace {
87 
88 using testing::Each;
89 using testing::Eq;
90 
91 const int32_t kBufferSize = SpdyHttpStream::kRequestBodyBufferSize;
92 
93 }  // namespace
94 
95 const char kPushedUrl[] = "https://www.example.org/foo.dat";
96 
97 class SpdyNetworkTransactionTest : public TestWithTaskEnvironment {
98  protected:
SpdyNetworkTransactionTest()99   SpdyNetworkTransactionTest()
100       : TestWithTaskEnvironment(
101             base::test::TaskEnvironment::TimeSource::MOCK_TIME),
102         default_url_(kDefaultUrl),
103         host_port_pair_(HostPortPair::FromURL(default_url_)) {}
104 
~SpdyNetworkTransactionTest()105   ~SpdyNetworkTransactionTest() override {
106     // UploadDataStream may post a deletion task back to the message loop on
107     // destruction.
108     upload_data_stream_.reset();
109     base::RunLoop().RunUntilIdle();
110   }
111 
SetUp()112   void SetUp() override {
113     request_.method = "GET";
114     request_.url = GURL(kDefaultUrl);
115     request_.traffic_annotation =
116         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
117     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
118   }
119 
120   struct TransactionHelperResult {
121     int rv;
122     std::string status_line;
123     std::string response_data;
124     HttpResponseInfo response_info;
125   };
126 
127   // A helper class that handles all the initial npn/ssl setup.
128   class NormalSpdyTransactionHelper {
129    public:
NormalSpdyTransactionHelper(const HttpRequestInfo & request,RequestPriority priority,const NetLogWithSource & log,std::unique_ptr<SpdySessionDependencies> session_deps)130     NormalSpdyTransactionHelper(
131         const HttpRequestInfo& request,
132         RequestPriority priority,
133         const NetLogWithSource& log,
134         std::unique_ptr<SpdySessionDependencies> session_deps)
135         : request_(request),
136           priority_(priority),
137           session_deps_(session_deps.get() == nullptr
138                             ? std::make_unique<SpdySessionDependencies>()
139                             : std::move(session_deps)),
140           log_(log) {
141       session_deps_->net_log = log.net_log();
142       session_ =
143           SpdySessionDependencies::SpdyCreateSession(session_deps_.get());
144     }
145 
~NormalSpdyTransactionHelper()146     ~NormalSpdyTransactionHelper() {
147       // Any test which doesn't close the socket by sending it an EOF will
148       // have a valid session left open, which leaks the entire session pool.
149       // This is just fine - in fact, some of our tests intentionally do this
150       // so that we can check consistency of the SpdySessionPool as the test
151       // finishes.  If we had put an EOF on the socket, the SpdySession would
152       // have closed and we wouldn't be able to check the consistency.
153 
154       // Forcefully close existing sessions here.
155       session()->spdy_session_pool()->CloseAllSessions();
156     }
157 
RunPreTestSetup()158     void RunPreTestSetup() {
159       // We're now ready to use SSL-npn SPDY.
160       trans_ =
161           std::make_unique<HttpNetworkTransaction>(priority_, session_.get());
162     }
163 
164     // Start the transaction, read some data, finish.
RunDefaultTest()165     void RunDefaultTest() {
166       if (!StartDefaultTest())
167         return;
168       FinishDefaultTest();
169     }
170 
StartDefaultTest()171     bool StartDefaultTest() {
172       output_.rv = trans_->Start(&request_, callback_.callback(), log_);
173 
174       // We expect an IO Pending or some sort of error.
175       EXPECT_LT(output_.rv, 0);
176       return output_.rv == ERR_IO_PENDING;
177     }
178 
FinishDefaultTest()179     void FinishDefaultTest() {
180       output_.rv = callback_.WaitForResult();
181       // Finish async network reads/writes.
182       base::RunLoop().RunUntilIdle();
183       if (output_.rv != OK) {
184         session_->spdy_session_pool()->CloseCurrentSessions(ERR_ABORTED);
185         return;
186       }
187 
188       // Verify responses.
189       const HttpResponseInfo* response = trans_->GetResponseInfo();
190       ASSERT_TRUE(response);
191       ASSERT_TRUE(response->headers);
192       EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
193                 response->connection_info);
194       EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
195       EXPECT_TRUE(response->was_fetched_via_spdy);
196       EXPECT_TRUE(response->was_alpn_negotiated);
197       EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
198       EXPECT_EQ(443, response->remote_endpoint.port());
199       output_.status_line = response->headers->GetStatusLine();
200       output_.response_info = *response;  // Make a copy so we can verify.
201       output_.rv = ReadTransaction(trans_.get(), &output_.response_data);
202     }
203 
FinishDefaultTestWithoutVerification()204     void FinishDefaultTestWithoutVerification() {
205       output_.rv = callback_.WaitForResult();
206       // Finish async network reads/writes.
207       base::RunLoop().RunUntilIdle();
208       if (output_.rv != OK)
209         session_->spdy_session_pool()->CloseCurrentSessions(ERR_ABORTED);
210     }
211 
WaitForCallbackToComplete()212     void WaitForCallbackToComplete() { output_.rv = callback_.WaitForResult(); }
213 
214     // Most tests will want to call this function. In particular, the MockReads
215     // should end with an empty read, and that read needs to be processed to
216     // ensure proper deletion of the spdy_session_pool.
VerifyDataConsumed()217     void VerifyDataConsumed() {
218       for (const SocketDataProvider* provider : data_vector_) {
219         EXPECT_TRUE(provider->AllReadDataConsumed());
220         EXPECT_TRUE(provider->AllWriteDataConsumed());
221       }
222     }
223 
224     // Occasionally a test will expect to error out before certain reads are
225     // processed. In that case we want to explicitly ensure that the reads were
226     // not processed.
VerifyDataNotConsumed()227     void VerifyDataNotConsumed() {
228       for (const SocketDataProvider* provider : data_vector_) {
229         EXPECT_FALSE(provider->AllReadDataConsumed());
230         EXPECT_FALSE(provider->AllWriteDataConsumed());
231       }
232     }
233 
RunToCompletion(SocketDataProvider * data)234     void RunToCompletion(SocketDataProvider* data) {
235       RunPreTestSetup();
236       AddData(data);
237       RunDefaultTest();
238       VerifyDataConsumed();
239     }
240 
RunToCompletionWithSSLData(SocketDataProvider * data,std::unique_ptr<SSLSocketDataProvider> ssl_provider)241     void RunToCompletionWithSSLData(
242         SocketDataProvider* data,
243         std::unique_ptr<SSLSocketDataProvider> ssl_provider) {
244       RunPreTestSetup();
245       AddDataWithSSLSocketDataProvider(data, std::move(ssl_provider));
246       RunDefaultTest();
247       VerifyDataConsumed();
248     }
249 
AddData(SocketDataProvider * data)250     void AddData(SocketDataProvider* data) {
251       auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
252       ssl_provider->ssl_info.cert =
253           ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
254       AddDataWithSSLSocketDataProvider(data, std::move(ssl_provider));
255     }
256 
AddDataWithSSLSocketDataProvider(SocketDataProvider * data,std::unique_ptr<SSLSocketDataProvider> ssl_provider)257     void AddDataWithSSLSocketDataProvider(
258         SocketDataProvider* data,
259         std::unique_ptr<SSLSocketDataProvider> ssl_provider) {
260       data_vector_.push_back(data);
261       if (ssl_provider->next_proto == kProtoUnknown)
262         ssl_provider->next_proto = kProtoHTTP2;
263 
264       session_deps_->socket_factory->AddSSLSocketDataProvider(
265           ssl_provider.get());
266       ssl_vector_.push_back(std::move(ssl_provider));
267 
268       session_deps_->socket_factory->AddSocketDataProvider(data);
269     }
270 
GetSpdySessionCount()271     size_t GetSpdySessionCount() {
272       std::unique_ptr<base::Value> value(
273           session_->spdy_session_pool()->SpdySessionPoolInfoToValue());
274       CHECK(value && value->is_list());
275       return value->GetList().size();
276     }
277 
trans()278     HttpNetworkTransaction* trans() { return trans_.get(); }
ResetTrans()279     void ResetTrans() { trans_.reset(); }
output()280     const TransactionHelperResult& output() { return output_; }
session() const281     HttpNetworkSession* session() const { return session_.get(); }
session_deps()282     SpdySessionDependencies* session_deps() { return session_deps_.get(); }
283 
284    private:
285     typedef std::vector<SocketDataProvider*> DataVector;
286     typedef std::vector<std::unique_ptr<SSLSocketDataProvider>> SSLVector;
287     typedef std::vector<std::unique_ptr<SocketDataProvider>> AlternateVector;
288     const HttpRequestInfo request_;
289     const RequestPriority priority_;
290     std::unique_ptr<SpdySessionDependencies> session_deps_;
291     std::unique_ptr<HttpNetworkSession> session_;
292     TransactionHelperResult output_;
293     SSLVector ssl_vector_;
294     TestCompletionCallback callback_;
295     std::unique_ptr<HttpNetworkTransaction> trans_;
296     DataVector data_vector_;
297     const NetLogWithSource log_;
298   };
299 
300   void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
301                                              int expected_status);
302 
303   void ConnectStatusHelper(const MockRead& status);
304 
CreateGetPushRequest() const305   [[nodiscard]] HttpRequestInfo CreateGetPushRequest() const {
306     HttpRequestInfo request;
307     request.method = "GET";
308     request.url = GURL(kPushedUrl);
309     request.traffic_annotation =
310         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
311     return request;
312   }
313 
UsePostRequest()314   void UsePostRequest() {
315     ASSERT_FALSE(upload_data_stream_);
316     std::vector<std::unique_ptr<UploadElementReader>> element_readers;
317     element_readers.push_back(std::make_unique<UploadBytesElementReader>(
318         kUploadData, kUploadDataSize));
319     upload_data_stream_ = std::make_unique<ElementsUploadDataStream>(
320         std::move(element_readers), 0);
321 
322     request_.method = "POST";
323     request_.upload_data_stream = upload_data_stream_.get();
324   }
325 
UseFilePostRequest()326   void UseFilePostRequest() {
327     ASSERT_FALSE(upload_data_stream_);
328     base::FilePath file_path;
329     CHECK(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &file_path));
330     CHECK(base::WriteFile(file_path, kUploadData));
331 
332     std::vector<std::unique_ptr<UploadElementReader>> element_readers;
333     element_readers.push_back(std::make_unique<UploadFileElementReader>(
334         base::SingleThreadTaskRunner::GetCurrentDefault().get(), file_path, 0,
335         kUploadDataSize, base::Time()));
336     upload_data_stream_ = std::make_unique<ElementsUploadDataStream>(
337         std::move(element_readers), 0);
338 
339     request_.method = "POST";
340     request_.upload_data_stream = upload_data_stream_.get();
341     request_.traffic_annotation =
342         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
343   }
344 
UseUnreadableFilePostRequest()345   void UseUnreadableFilePostRequest() {
346     ASSERT_FALSE(upload_data_stream_);
347     base::FilePath file_path;
348     CHECK(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &file_path));
349     CHECK(base::WriteFile(file_path, kUploadData));
350     CHECK(base::MakeFileUnreadable(file_path));
351 
352     std::vector<std::unique_ptr<UploadElementReader>> element_readers;
353     element_readers.push_back(std::make_unique<UploadFileElementReader>(
354         base::SingleThreadTaskRunner::GetCurrentDefault().get(), file_path, 0,
355         kUploadDataSize, base::Time()));
356     upload_data_stream_ = std::make_unique<ElementsUploadDataStream>(
357         std::move(element_readers), 0);
358 
359     request_.method = "POST";
360     request_.upload_data_stream = upload_data_stream_.get();
361   }
362 
UseComplexPostRequest()363   void UseComplexPostRequest() {
364     ASSERT_FALSE(upload_data_stream_);
365     const int kFileRangeOffset = 1;
366     const int kFileRangeLength = 3;
367     CHECK_LT(kFileRangeOffset + kFileRangeLength, kUploadDataSize);
368 
369     base::FilePath file_path;
370     CHECK(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &file_path));
371     CHECK(base::WriteFile(file_path, kUploadData));
372 
373     std::vector<std::unique_ptr<UploadElementReader>> element_readers;
374     element_readers.push_back(std::make_unique<UploadBytesElementReader>(
375         kUploadData, kFileRangeOffset));
376     element_readers.push_back(std::make_unique<UploadFileElementReader>(
377         base::SingleThreadTaskRunner::GetCurrentDefault().get(), file_path,
378         kFileRangeOffset, kFileRangeLength, base::Time()));
379     element_readers.push_back(std::make_unique<UploadBytesElementReader>(
380         kUploadData + kFileRangeOffset + kFileRangeLength,
381         kUploadDataSize - (kFileRangeOffset + kFileRangeLength)));
382     upload_data_stream_ = std::make_unique<ElementsUploadDataStream>(
383         std::move(element_readers), 0);
384 
385     request_.method = "POST";
386     request_.upload_data_stream = upload_data_stream_.get();
387   }
388 
UseChunkedPostRequest()389   void UseChunkedPostRequest() {
390     ASSERT_FALSE(upload_chunked_data_stream_);
391     upload_chunked_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
392     request_.method = "POST";
393     request_.upload_data_stream = upload_chunked_data_stream_.get();
394   }
395 
396   // Read the result of a particular transaction, knowing that we've got
397   // multiple transactions in the read pipeline; so as we read, we may have
398   // to skip over data destined for other transactions while we consume
399   // the data for |trans|.
ReadResult(HttpNetworkTransaction * trans,std::string * result)400   int ReadResult(HttpNetworkTransaction* trans, std::string* result) {
401     const int kSize = 3000;
402 
403     int bytes_read = 0;
404     scoped_refptr<IOBufferWithSize> buf =
405         base::MakeRefCounted<IOBufferWithSize>(kSize);
406     TestCompletionCallback callback;
407     while (true) {
408       int rv = trans->Read(buf.get(), kSize, callback.callback());
409       if (rv == ERR_IO_PENDING) {
410         rv = callback.WaitForResult();
411       } else if (rv <= 0) {
412         break;
413       }
414       result->append(buf->data(), rv);
415       bytes_read += rv;
416     }
417     return bytes_read;
418   }
419 
VerifyStreamsClosed(const NormalSpdyTransactionHelper & helper)420   void VerifyStreamsClosed(const NormalSpdyTransactionHelper& helper) {
421     // This lengthy block is reaching into the pool to dig out the active
422     // session.  Once we have the session, we verify that the streams are
423     // all closed and not leaked at this point.
424     SpdySessionKey key(HostPortPair::FromURL(request_.url),
425                        ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
426                        SpdySessionKey::IsProxySession::kFalse, SocketTag(),
427                        request_.network_anonymization_key,
428                        SecureDnsPolicy::kAllow);
429     HttpNetworkSession* session = helper.session();
430     base::WeakPtr<SpdySession> spdy_session =
431         session->spdy_session_pool()->FindAvailableSession(
432             key, /* enable_ip_based_pooling = */ true,
433             /* is_websocket = */ false, log_);
434     ASSERT_TRUE(spdy_session);
435     EXPECT_EQ(0u, num_active_streams(spdy_session));
436     EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session));
437   }
438 
DeleteSessionCallback(NormalSpdyTransactionHelper * helper,int result)439   static void DeleteSessionCallback(NormalSpdyTransactionHelper* helper,
440                                     int result) {
441     helper->ResetTrans();
442   }
443 
StartTransactionCallback(HttpNetworkSession * session,GURL url,NetLogWithSource log,int result)444   static void StartTransactionCallback(HttpNetworkSession* session,
445                                        GURL url,
446                                        NetLogWithSource log,
447                                        int result) {
448     HttpRequestInfo request;
449     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
450     TestCompletionCallback callback;
451     request.method = "GET";
452     request.url = url;
453     request.traffic_annotation =
454         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
455     int rv = trans.Start(&request, callback.callback(), log);
456     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
457     callback.WaitForResult();
458   }
459 
upload_chunked_data_stream()460   ChunkedUploadDataStream* upload_chunked_data_stream() {
461     return upload_chunked_data_stream_.get();
462   }
463 
num_active_streams(base::WeakPtr<SpdySession> session)464   size_t num_active_streams(base::WeakPtr<SpdySession> session) {
465     return session->active_streams_.size();
466   }
467 
num_unclaimed_pushed_streams(base::WeakPtr<SpdySession> session)468   static size_t num_unclaimed_pushed_streams(
469       base::WeakPtr<SpdySession> session) {
470     return session->pool_->push_promise_index()->CountStreamsForSession(
471         session.get());
472   }
473 
has_unclaimed_pushed_stream_for_url(base::WeakPtr<SpdySession> session,const GURL & url)474   static bool has_unclaimed_pushed_stream_for_url(
475       base::WeakPtr<SpdySession> session,
476       const GURL& url) {
477     return session->pool_->push_promise_index()->FindStream(
478                url, session.get()) != kNoPushedStreamFound;
479   }
480 
spdy_stream_hi_water_mark(base::WeakPtr<SpdySession> session)481   static spdy::SpdyStreamId spdy_stream_hi_water_mark(
482       base::WeakPtr<SpdySession> session) {
483     return session->stream_hi_water_mark_;
484   }
485 
FastForwardByCallback(base::TimeDelta delta)486   base::RepeatingClosure FastForwardByCallback(base::TimeDelta delta) {
487     return base::BindRepeating(&SpdyNetworkTransactionTest::FastForwardBy,
488                                base::Unretained(this), delta);
489   }
490 
491   const GURL default_url_;
492   const HostPortPair host_port_pair_;
493   HttpRequestInfo request_;
494   SpdyTestUtil spdy_util_;
495   const NetLogWithSource log_;
496 
497  private:
498   std::unique_ptr<ChunkedUploadDataStream> upload_chunked_data_stream_;
499   std::unique_ptr<UploadDataStream> upload_data_stream_;
500   base::ScopedTempDir temp_dir_;
501 };
502 
503 // Verify HttpNetworkTransaction constructor.
TEST_F(SpdyNetworkTransactionTest,Constructor)504 TEST_F(SpdyNetworkTransactionTest, Constructor) {
505   auto session_deps = std::make_unique<SpdySessionDependencies>();
506   std::unique_ptr<HttpNetworkSession> session(
507       SpdySessionDependencies::SpdyCreateSession(session_deps.get()));
508   auto trans =
509       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
510 }
511 
TEST_F(SpdyNetworkTransactionTest,Get)512 TEST_F(SpdyNetworkTransactionTest, Get) {
513   // Construct the request.
514   spdy::SpdySerializedFrame req(
515       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
516   MockWrite writes[] = {CreateMockWrite(req, 0)};
517 
518   spdy::SpdySerializedFrame resp(
519       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
520   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
521   MockRead reads[] = {
522       CreateMockRead(resp, 1), CreateMockRead(body, 2),
523       MockRead(ASYNC, 0, 3)  // EOF
524   };
525 
526   SequencedSocketData data(reads, writes);
527   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
528   helper.RunToCompletion(&data);
529   TransactionHelperResult out = helper.output();
530   EXPECT_THAT(out.rv, IsOk());
531   EXPECT_EQ("HTTP/1.1 200", out.status_line);
532   EXPECT_EQ("hello!", out.response_data);
533 }
534 
TEST_F(SpdyNetworkTransactionTest,SetPriority)535 TEST_F(SpdyNetworkTransactionTest, SetPriority) {
536   for (bool set_priority_before_starting_transaction : {true, false}) {
537     SpdyTestUtil spdy_test_util;
538     spdy::SpdySerializedFrame req(
539         spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
540     MockWrite writes[] = {CreateMockWrite(req, 0)};
541 
542     spdy::SpdySerializedFrame resp(
543         spdy_test_util.ConstructSpdyGetReply(nullptr, 0, 1));
544     spdy::SpdySerializedFrame body(
545         spdy_test_util.ConstructSpdyDataFrame(1, true));
546     MockRead reads[] = {CreateMockRead(resp, 1), CreateMockRead(body, 2),
547                         MockRead(ASYNC, 0, 3)};
548 
549     SequencedSocketData data(reads, writes);
550     NormalSpdyTransactionHelper helper(request_, HIGHEST, log_, nullptr);
551     helper.RunPreTestSetup();
552     helper.AddData(&data);
553 
554     if (set_priority_before_starting_transaction) {
555       helper.trans()->SetPriority(LOWEST);
556       EXPECT_TRUE(helper.StartDefaultTest());
557     } else {
558       EXPECT_TRUE(helper.StartDefaultTest());
559       helper.trans()->SetPriority(LOWEST);
560     }
561 
562     helper.FinishDefaultTest();
563     helper.VerifyDataConsumed();
564 
565     TransactionHelperResult out = helper.output();
566     EXPECT_THAT(out.rv, IsOk());
567     EXPECT_EQ("HTTP/1.1 200", out.status_line);
568     EXPECT_EQ("hello!", out.response_data);
569   }
570 }
571 
572 // Test that changing the request priority of an existing stream triggers
573 // sending PRIORITY frames in case there are multiple open streams and their
574 // relative priorities change.
TEST_F(SpdyNetworkTransactionTest,SetPriorityOnExistingStream)575 TEST_F(SpdyNetworkTransactionTest, SetPriorityOnExistingStream) {
576   const char* kUrl2 = "https://www.example.org/bar";
577 
578   spdy::SpdySerializedFrame req1(
579       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
580   spdy::SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(kUrl2, 3, MEDIUM));
581   spdy::SpdySerializedFrame priority1(
582       spdy_util_.ConstructSpdyPriority(3, 0, MEDIUM, true));
583   spdy::SpdySerializedFrame priority2(
584       spdy_util_.ConstructSpdyPriority(1, 3, LOWEST, true));
585   MockWrite writes[] = {CreateMockWrite(req1, 0), CreateMockWrite(req2, 2),
586                         CreateMockWrite(priority1, 4),
587                         CreateMockWrite(priority2, 5)};
588 
589   spdy::SpdySerializedFrame resp1(
590       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
591   spdy::SpdySerializedFrame resp2(
592       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
593   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
594   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
595   MockRead reads[] = {CreateMockRead(resp1, 1), CreateMockRead(resp2, 3),
596                       CreateMockRead(body1, 6), CreateMockRead(body2, 7),
597                       MockRead(ASYNC, 0, 8)};
598 
599   SequencedSocketData data(reads, writes);
600   NormalSpdyTransactionHelper helper(request_, HIGHEST, log_, nullptr);
601   helper.RunPreTestSetup();
602   helper.AddData(&data);
603   EXPECT_TRUE(helper.StartDefaultTest());
604 
605   // Open HTTP/2 connection and create first stream.
606   base::RunLoop().RunUntilIdle();
607 
608   HttpNetworkTransaction trans2(MEDIUM, helper.session());
609   HttpRequestInfo request2;
610   request2.url = GURL(kUrl2);
611   request2.method = "GET";
612   request2.traffic_annotation =
613       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
614   TestCompletionCallback callback2;
615   int rv = trans2.Start(&request2, callback2.callback(), log_);
616   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
617 
618   // Create second stream.
619   base::RunLoop().RunUntilIdle();
620 
621   // First request has HIGHEST priority, second request has MEDIUM priority.
622   // Changing the priority of the first request to LOWEST changes their order,
623   // and therefore triggers sending PRIORITY frames.
624   helper.trans()->SetPriority(LOWEST);
625 
626   helper.FinishDefaultTest();
627   helper.VerifyDataConsumed();
628 
629   TransactionHelperResult out = helper.output();
630   EXPECT_THAT(out.rv, IsOk());
631   EXPECT_EQ("HTTP/1.1 200", out.status_line);
632   EXPECT_EQ("hello!", out.response_data);
633 
634   rv = callback2.WaitForResult();
635   ASSERT_THAT(rv, IsOk());
636   const HttpResponseInfo* response2 = trans2.GetResponseInfo();
637   ASSERT_TRUE(response2);
638   ASSERT_TRUE(response2->headers);
639   EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
640             response2->connection_info);
641   EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
642 }
643 
644 // Create two requests: a lower priority one first, then a higher priority one.
645 // Test that the second request gets sent out first.
TEST_F(SpdyNetworkTransactionTest,RequestsOrderedByPriority)646 TEST_F(SpdyNetworkTransactionTest, RequestsOrderedByPriority) {
647   const char* kUrl2 = "https://www.example.org/foo";
648 
649   // First send second request on stream 1, then first request on stream 3.
650   spdy::SpdySerializedFrame req2(
651       spdy_util_.ConstructSpdyGet(kUrl2, 1, HIGHEST));
652   spdy::SpdySerializedFrame req1(
653       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOW));
654   MockWrite writes[] = {CreateMockWrite(req2, 0), CreateMockWrite(req1, 1)};
655 
656   spdy::SpdySerializedFrame resp2(
657       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
658   spdy::SpdySerializedFrame resp1(
659       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
660   spdy::SpdySerializedFrame body2(
661       spdy_util_.ConstructSpdyDataFrame(1, "stream 1", true));
662   spdy::SpdySerializedFrame body1(
663       spdy_util_.ConstructSpdyDataFrame(3, "stream 3", true));
664   MockRead reads[] = {CreateMockRead(resp2, 2), CreateMockRead(body2, 3),
665                       CreateMockRead(resp1, 4), CreateMockRead(body1, 5),
666                       MockRead(ASYNC, 0, 6)};
667 
668   SequencedSocketData data(reads, writes);
669   NormalSpdyTransactionHelper helper(request_, LOW, log_, nullptr);
670   helper.RunPreTestSetup();
671   helper.AddData(&data);
672 
673   // Create HTTP/2 connection.  This is necessary because starting the first
674   // transaction does not create the connection yet, so the second request
675   // could not use the same connection, whereas running the message loop after
676   // starting the first transaction would call Socket::Write() with the first
677   // HEADERS frame, so the second transaction could not get ahead of it.
678   SpdySessionKey key(HostPortPair("www.example.org", 443),
679                      ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
680                      SpdySessionKey::IsProxySession::kFalse, SocketTag(),
681                      NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
682   auto spdy_session = CreateSpdySession(helper.session(), key, log_);
683   EXPECT_TRUE(spdy_session);
684 
685   // Start first transaction.
686   EXPECT_TRUE(helper.StartDefaultTest());
687 
688   // Start second transaction.
689   HttpNetworkTransaction trans2(HIGHEST, helper.session());
690   HttpRequestInfo request2;
691   request2.url = GURL(kUrl2);
692   request2.method = "GET";
693   request2.traffic_annotation =
694       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
695   TestCompletionCallback callback2;
696   int rv = trans2.Start(&request2, callback2.callback(), log_);
697   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
698 
699   // Complete first transaction and verify results.
700   helper.FinishDefaultTest();
701   helper.VerifyDataConsumed();
702 
703   TransactionHelperResult out = helper.output();
704   EXPECT_THAT(out.rv, IsOk());
705   EXPECT_EQ("HTTP/1.1 200", out.status_line);
706   EXPECT_EQ("stream 3", out.response_data);
707 
708   // Complete second transaction and verify results.
709   rv = callback2.WaitForResult();
710   ASSERT_THAT(rv, IsOk());
711   const HttpResponseInfo* response2 = trans2.GetResponseInfo();
712   ASSERT_TRUE(response2);
713   ASSERT_TRUE(response2->headers);
714   EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
715             response2->connection_info);
716   EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
717   std::string response_data;
718   ReadTransaction(&trans2, &response_data);
719   EXPECT_EQ("stream 1", response_data);
720 }
721 
722 // Test that already enqueued HEADERS frames are reordered if their relative
723 // priority changes.
TEST_F(SpdyNetworkTransactionTest,QueuedFramesReorderedOnPriorityChange)724 TEST_F(SpdyNetworkTransactionTest, QueuedFramesReorderedOnPriorityChange) {
725   const char* kUrl2 = "https://www.example.org/foo";
726   const char* kUrl3 = "https://www.example.org/bar";
727 
728   spdy::SpdySerializedFrame req1(
729       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, DEFAULT_PRIORITY));
730   spdy::SpdySerializedFrame req3(spdy_util_.ConstructSpdyGet(kUrl3, 3, MEDIUM));
731   spdy::SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(kUrl2, 5, LOWEST));
732   MockWrite writes[] = {MockWrite(ASYNC, ERR_IO_PENDING, 0),
733                         CreateMockWrite(req1, 1), CreateMockWrite(req3, 2),
734                         CreateMockWrite(req2, 3)};
735 
736   spdy::SpdySerializedFrame resp1(
737       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
738   spdy::SpdySerializedFrame resp3(
739       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
740   spdy::SpdySerializedFrame resp2(
741       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 5));
742   spdy::SpdySerializedFrame body1(
743       spdy_util_.ConstructSpdyDataFrame(1, "stream 1", true));
744   spdy::SpdySerializedFrame body3(
745       spdy_util_.ConstructSpdyDataFrame(3, "stream 3", true));
746   spdy::SpdySerializedFrame body2(
747       spdy_util_.ConstructSpdyDataFrame(5, "stream 5", true));
748   MockRead reads[] = {CreateMockRead(resp1, 4), CreateMockRead(body1, 5),
749                       CreateMockRead(resp3, 6), CreateMockRead(body3, 7),
750                       CreateMockRead(resp2, 8), CreateMockRead(body2, 9),
751                       MockRead(ASYNC, 0, 10)};
752 
753   SequencedSocketData data(reads, writes);
754   // Priority of first request does not matter, because Socket::Write() will be
755   // called with its HEADERS frame before the other requests start.
756   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
757   helper.RunPreTestSetup();
758   helper.AddData(&data);
759   EXPECT_TRUE(helper.StartDefaultTest());
760 
761   // Open HTTP/2 connection, create HEADERS frame for first request, and call
762   // Socket::Write() with that frame.  After this, no other request can get
763   // ahead of the first one.
764   base::RunLoop().RunUntilIdle();
765 
766   HttpNetworkTransaction trans2(HIGHEST, helper.session());
767   HttpRequestInfo request2;
768   request2.url = GURL(kUrl2);
769   request2.method = "GET";
770   request2.traffic_annotation =
771       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
772   TestCompletionCallback callback2;
773   int rv = trans2.Start(&request2, callback2.callback(), log_);
774   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
775 
776   HttpNetworkTransaction trans3(MEDIUM, helper.session());
777   HttpRequestInfo request3;
778   request3.url = GURL(kUrl3);
779   request3.method = "GET";
780   request3.traffic_annotation =
781       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
782   TestCompletionCallback callback3;
783   rv = trans3.Start(&request3, callback3.callback(), log_);
784   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
785 
786   // Create HEADERS frames for second and third request and enqueue them in
787   // SpdyWriteQueue with their original priorities.  Writing of the first
788   // HEADERS frame to the socked still has not completed.
789   base::RunLoop().RunUntilIdle();
790 
791   // Second request is of HIGHEST, third of MEDIUM priority.  Changing second
792   // request to LOWEST changes their relative order.  This should result in
793   // already enqueued frames being reordered within SpdyWriteQueue.
794   trans2.SetPriority(LOWEST);
795 
796   // Complete async write of the first HEADERS frame.
797   data.Resume();
798 
799   helper.FinishDefaultTest();
800   TransactionHelperResult out = helper.output();
801   EXPECT_THAT(out.rv, IsOk());
802   EXPECT_EQ("HTTP/1.1 200", out.status_line);
803   EXPECT_EQ("stream 1", out.response_data);
804 
805   rv = callback2.WaitForResult();
806   ASSERT_THAT(rv, IsOk());
807   const HttpResponseInfo* response2 = trans2.GetResponseInfo();
808   ASSERT_TRUE(response2);
809   ASSERT_TRUE(response2->headers);
810   EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
811             response2->connection_info);
812   EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
813   std::string response_data;
814   ReadTransaction(&trans2, &response_data);
815   EXPECT_EQ("stream 5", response_data);
816 
817   rv = callback3.WaitForResult();
818   ASSERT_THAT(rv, IsOk());
819   const HttpResponseInfo* response3 = trans3.GetResponseInfo();
820   ASSERT_TRUE(response3);
821   ASSERT_TRUE(response3->headers);
822   EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
823             response3->connection_info);
824   EXPECT_EQ("HTTP/1.1 200", response3->headers->GetStatusLine());
825   ReadTransaction(&trans3, &response_data);
826   EXPECT_EQ("stream 3", response_data);
827 
828   helper.VerifyDataConsumed();
829 }
830 
TEST_F(SpdyNetworkTransactionTest,GetAtEachPriority)831 TEST_F(SpdyNetworkTransactionTest, GetAtEachPriority) {
832   for (RequestPriority p = MINIMUM_PRIORITY; p <= MAXIMUM_PRIORITY;
833        p = RequestPriority(p + 1)) {
834     SpdyTestUtil spdy_test_util;
835 
836     // Construct the request.
837     spdy::SpdySerializedFrame req(
838         spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, p));
839     MockWrite writes[] = {CreateMockWrite(req, 0)};
840 
841     spdy::SpdyPriority spdy_prio = 0;
842     EXPECT_TRUE(GetSpdyPriority(req, &spdy_prio));
843     // this repeats the RequestPriority-->spdy::SpdyPriority mapping from
844     // spdy::SpdyFramer::ConvertRequestPriorityToSpdyPriority to make
845     // sure it's being done right.
846     switch (p) {
847       case HIGHEST:
848         EXPECT_EQ(0, spdy_prio);
849         break;
850       case MEDIUM:
851         EXPECT_EQ(1, spdy_prio);
852         break;
853       case LOW:
854         EXPECT_EQ(2, spdy_prio);
855         break;
856       case LOWEST:
857         EXPECT_EQ(3, spdy_prio);
858         break;
859       case IDLE:
860         EXPECT_EQ(4, spdy_prio);
861         break;
862       case THROTTLED:
863         EXPECT_EQ(5, spdy_prio);
864         break;
865       default:
866         FAIL();
867     }
868 
869     spdy::SpdySerializedFrame resp(
870         spdy_test_util.ConstructSpdyGetReply(nullptr, 0, 1));
871     spdy::SpdySerializedFrame body(
872         spdy_test_util.ConstructSpdyDataFrame(1, true));
873     MockRead reads[] = {
874         CreateMockRead(resp, 1), CreateMockRead(body, 2),
875         MockRead(ASYNC, 0, 3)  // EOF
876     };
877 
878     SequencedSocketData data(reads, writes);
879 
880     NormalSpdyTransactionHelper helper(request_, p, log_, nullptr);
881     helper.RunToCompletion(&data);
882     TransactionHelperResult out = helper.output();
883     EXPECT_THAT(out.rv, IsOk());
884     EXPECT_EQ("HTTP/1.1 200", out.status_line);
885     EXPECT_EQ("hello!", out.response_data);
886   }
887 }
888 
889 // Start three gets simultaniously; making sure that multiplexed
890 // streams work properly.
891 
892 // This can't use the TransactionHelper method, since it only
893 // handles a single transaction, and finishes them as soon
894 // as it launches them.
895 
896 // TODO(gavinp): create a working generalized TransactionHelper that
897 // can allow multiple streams in flight.
898 
TEST_F(SpdyNetworkTransactionTest,ThreeGets)899 TEST_F(SpdyNetworkTransactionTest, ThreeGets) {
900   spdy::SpdySerializedFrame req(
901       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
902   spdy::SpdySerializedFrame resp(
903       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
904   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false));
905   spdy::SpdySerializedFrame fbody(spdy_util_.ConstructSpdyDataFrame(1, true));
906 
907   spdy::SpdySerializedFrame req2(
908       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
909   spdy::SpdySerializedFrame resp2(
910       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
911   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, false));
912   spdy::SpdySerializedFrame fbody2(spdy_util_.ConstructSpdyDataFrame(3, true));
913 
914   spdy::SpdySerializedFrame req3(
915       spdy_util_.ConstructSpdyGet(nullptr, 0, 5, LOWEST));
916   spdy::SpdySerializedFrame resp3(
917       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 5));
918   spdy::SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(5, false));
919   spdy::SpdySerializedFrame fbody3(spdy_util_.ConstructSpdyDataFrame(5, true));
920 
921   MockWrite writes[] = {
922       CreateMockWrite(req, 0), CreateMockWrite(req2, 3),
923       CreateMockWrite(req3, 6),
924   };
925   MockRead reads[] = {
926       CreateMockRead(resp, 1),    CreateMockRead(body, 2),
927       CreateMockRead(resp2, 4),   CreateMockRead(body2, 5),
928       CreateMockRead(resp3, 7),   CreateMockRead(body3, 8),
929 
930       CreateMockRead(fbody, 9),   CreateMockRead(fbody2, 10),
931       CreateMockRead(fbody3, 11),
932 
933       MockRead(ASYNC, 0, 12),  // EOF
934   };
935   SequencedSocketData data(reads, writes);
936   SequencedSocketData data_placeholder1;
937   SequencedSocketData data_placeholder2;
938 
939   TransactionHelperResult out;
940   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
941   helper.RunPreTestSetup();
942   helper.AddData(&data);
943   // We require placeholder data because three get requests are sent out at
944   // the same time which results in three sockets being connected. The first
945   // on will negotiate SPDY and will be used for all requests.
946   helper.AddData(&data_placeholder1);
947   helper.AddData(&data_placeholder2);
948   TestCompletionCallback callback1;
949   TestCompletionCallback callback2;
950   TestCompletionCallback callback3;
951 
952   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
953   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
954   HttpNetworkTransaction trans3(DEFAULT_PRIORITY, helper.session());
955 
956   out.rv = trans1.Start(&request_, callback1.callback(), log_);
957   ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
958   out.rv = trans2.Start(&request_, callback2.callback(), log_);
959   ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
960   out.rv = trans3.Start(&request_, callback3.callback(), log_);
961   ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
962 
963   out.rv = callback1.WaitForResult();
964   ASSERT_THAT(out.rv, IsOk());
965   out.rv = callback3.WaitForResult();
966   ASSERT_THAT(out.rv, IsOk());
967 
968   const HttpResponseInfo* response1 = trans1.GetResponseInfo();
969   EXPECT_TRUE(response1->headers);
970   EXPECT_TRUE(response1->was_fetched_via_spdy);
971   out.status_line = response1->headers->GetStatusLine();
972   out.response_info = *response1;
973 
974   trans2.GetResponseInfo();
975 
976   out.rv = ReadTransaction(&trans1, &out.response_data);
977   helper.VerifyDataConsumed();
978   EXPECT_THAT(out.rv, IsOk());
979 
980   EXPECT_THAT(out.rv, IsOk());
981   EXPECT_EQ("HTTP/1.1 200", out.status_line);
982   EXPECT_EQ("hello!hello!", out.response_data);
983 }
984 
TEST_F(SpdyNetworkTransactionTest,TwoGetsLateBinding)985 TEST_F(SpdyNetworkTransactionTest, TwoGetsLateBinding) {
986   spdy::SpdySerializedFrame req(
987       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
988   spdy::SpdySerializedFrame resp(
989       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
990   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false));
991   spdy::SpdySerializedFrame fbody(spdy_util_.ConstructSpdyDataFrame(1, true));
992 
993   spdy::SpdySerializedFrame req2(
994       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
995   spdy::SpdySerializedFrame resp2(
996       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
997   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, false));
998   spdy::SpdySerializedFrame fbody2(spdy_util_.ConstructSpdyDataFrame(3, true));
999 
1000   MockWrite writes[] = {
1001       CreateMockWrite(req, 0), CreateMockWrite(req2, 3),
1002   };
1003   MockRead reads[] = {
1004       CreateMockRead(resp, 1),  CreateMockRead(body, 2),
1005       CreateMockRead(resp2, 4), CreateMockRead(body2, 5),
1006       CreateMockRead(fbody, 6), CreateMockRead(fbody2, 7),
1007       MockRead(ASYNC, 0, 8),  // EOF
1008   };
1009   SequencedSocketData data(reads, writes);
1010 
1011   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
1012   SequencedSocketData data_placeholder;
1013   data_placeholder.set_connect_data(never_finishing_connect);
1014 
1015   TransactionHelperResult out;
1016   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
1017   helper.RunPreTestSetup();
1018   helper.AddData(&data);
1019   // We require placeholder data because two requests are sent out at
1020   // the same time which results in two sockets being connected. The first
1021   // on will negotiate SPDY and will be used for all requests.
1022   helper.AddData(&data_placeholder);
1023   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
1024   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
1025 
1026   TestCompletionCallback callback1;
1027   TestCompletionCallback callback2;
1028 
1029   out.rv = trans1.Start(&request_, callback1.callback(), log_);
1030   ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
1031   out.rv = trans2.Start(&request_, callback2.callback(), log_);
1032   ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
1033 
1034   out.rv = callback1.WaitForResult();
1035   ASSERT_THAT(out.rv, IsOk());
1036   out.rv = callback2.WaitForResult();
1037   ASSERT_THAT(out.rv, IsOk());
1038 
1039   const HttpResponseInfo* response1 = trans1.GetResponseInfo();
1040   EXPECT_TRUE(response1->headers);
1041   EXPECT_TRUE(response1->was_fetched_via_spdy);
1042   out.status_line = response1->headers->GetStatusLine();
1043   out.response_info = *response1;
1044   out.rv = ReadTransaction(&trans1, &out.response_data);
1045   EXPECT_THAT(out.rv, IsOk());
1046   EXPECT_EQ("HTTP/1.1 200", out.status_line);
1047   EXPECT_EQ("hello!hello!", out.response_data);
1048 
1049   const HttpResponseInfo* response2 = trans2.GetResponseInfo();
1050   EXPECT_TRUE(response2->headers);
1051   EXPECT_TRUE(response2->was_fetched_via_spdy);
1052   out.status_line = response2->headers->GetStatusLine();
1053   out.response_info = *response2;
1054   out.rv = ReadTransaction(&trans2, &out.response_data);
1055   EXPECT_THAT(out.rv, IsOk());
1056   EXPECT_EQ("HTTP/1.1 200", out.status_line);
1057   EXPECT_EQ("hello!hello!", out.response_data);
1058 
1059   helper.VerifyDataConsumed();
1060 }
1061 
TEST_F(SpdyNetworkTransactionTest,TwoGetsLateBindingFromPreconnect)1062 TEST_F(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) {
1063   spdy::SpdySerializedFrame req(
1064       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
1065   spdy::SpdySerializedFrame resp(
1066       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1067   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false));
1068   spdy::SpdySerializedFrame fbody(spdy_util_.ConstructSpdyDataFrame(1, true));
1069 
1070   spdy::SpdySerializedFrame req2(
1071       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
1072   spdy::SpdySerializedFrame resp2(
1073       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
1074   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, false));
1075   spdy::SpdySerializedFrame fbody2(spdy_util_.ConstructSpdyDataFrame(3, true));
1076 
1077   MockWrite writes[] = {
1078       CreateMockWrite(req, 0), CreateMockWrite(req2, 3),
1079   };
1080   MockRead reads[] = {
1081       CreateMockRead(resp, 1),  CreateMockRead(body, 2),
1082       CreateMockRead(resp2, 4), CreateMockRead(body2, 5),
1083       CreateMockRead(fbody, 6), CreateMockRead(fbody2, 7),
1084       MockRead(ASYNC, 0, 8),  // EOF
1085   };
1086   SequencedSocketData preconnect_data(reads, writes);
1087 
1088   MockConnect never_finishing_connect(ASYNC, ERR_IO_PENDING);
1089 
1090   SequencedSocketData data_placeholder;
1091   data_placeholder.set_connect_data(never_finishing_connect);
1092 
1093   TransactionHelperResult out;
1094   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
1095   helper.RunPreTestSetup();
1096   helper.AddData(&preconnect_data);
1097   // We require placeholder data because 3 connections are attempted (first is
1098   // the preconnect, 2nd and 3rd are the never finished connections.
1099   helper.AddData(&data_placeholder);
1100   helper.AddData(&data_placeholder);
1101 
1102   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
1103   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
1104 
1105   TestCompletionCallback callback1;
1106   TestCompletionCallback callback2;
1107 
1108   // Preconnect the first.
1109   HttpStreamFactory* http_stream_factory =
1110       helper.session()->http_stream_factory();
1111 
1112   http_stream_factory->PreconnectStreams(1, request_);
1113 
1114   out.rv = trans1.Start(&request_, callback1.callback(), log_);
1115   ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
1116   out.rv = trans2.Start(&request_, callback2.callback(), log_);
1117   ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
1118 
1119   out.rv = callback1.WaitForResult();
1120   ASSERT_THAT(out.rv, IsOk());
1121   out.rv = callback2.WaitForResult();
1122   ASSERT_THAT(out.rv, IsOk());
1123 
1124   const HttpResponseInfo* response1 = trans1.GetResponseInfo();
1125   EXPECT_TRUE(response1->headers);
1126   EXPECT_TRUE(response1->was_fetched_via_spdy);
1127   out.status_line = response1->headers->GetStatusLine();
1128   out.response_info = *response1;
1129   out.rv = ReadTransaction(&trans1, &out.response_data);
1130   EXPECT_THAT(out.rv, IsOk());
1131   EXPECT_EQ("HTTP/1.1 200", out.status_line);
1132   EXPECT_EQ("hello!hello!", out.response_data);
1133 
1134   const HttpResponseInfo* response2 = trans2.GetResponseInfo();
1135   EXPECT_TRUE(response2->headers);
1136   EXPECT_TRUE(response2->was_fetched_via_spdy);
1137   out.status_line = response2->headers->GetStatusLine();
1138   out.response_info = *response2;
1139   out.rv = ReadTransaction(&trans2, &out.response_data);
1140   EXPECT_THAT(out.rv, IsOk());
1141   EXPECT_EQ("HTTP/1.1 200", out.status_line);
1142   EXPECT_EQ("hello!hello!", out.response_data);
1143 
1144   helper.VerifyDataConsumed();
1145 }
1146 
1147 // Similar to ThreeGets above, however this test adds a SETTINGS
1148 // frame.  The SETTINGS frame is read during the IO loop waiting on
1149 // the first transaction completion, and sets a maximum concurrent
1150 // stream limit of 1.  This means that our IO loop exists after the
1151 // second transaction completes, so we can assert on read_index().
TEST_F(SpdyNetworkTransactionTest,ThreeGetsWithMaxConcurrent)1152 TEST_F(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) {
1153   // Construct the request.
1154   // Each request fully completes before the next starts.
1155   spdy::SpdySerializedFrame req(
1156       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
1157   spdy::SpdySerializedFrame resp(
1158       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1159   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false));
1160   spdy::SpdySerializedFrame fbody(spdy_util_.ConstructSpdyDataFrame(1, true));
1161   spdy_util_.UpdateWithStreamDestruction(1);
1162 
1163   spdy::SpdySerializedFrame req2(
1164       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
1165   spdy::SpdySerializedFrame resp2(
1166       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
1167   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, false));
1168   spdy::SpdySerializedFrame fbody2(spdy_util_.ConstructSpdyDataFrame(3, true));
1169   spdy_util_.UpdateWithStreamDestruction(3);
1170 
1171   spdy::SpdySerializedFrame req3(
1172       spdy_util_.ConstructSpdyGet(nullptr, 0, 5, LOWEST));
1173   spdy::SpdySerializedFrame resp3(
1174       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 5));
1175   spdy::SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(5, false));
1176   spdy::SpdySerializedFrame fbody3(spdy_util_.ConstructSpdyDataFrame(5, true));
1177 
1178   spdy::SettingsMap settings;
1179   const uint32_t max_concurrent_streams = 1;
1180   settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] = max_concurrent_streams;
1181   spdy::SpdySerializedFrame settings_frame(
1182       spdy_util_.ConstructSpdySettings(settings));
1183   spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
1184 
1185   MockWrite writes[] = {
1186       CreateMockWrite(req, 0), CreateMockWrite(settings_ack, 5),
1187       CreateMockWrite(req2, 6), CreateMockWrite(req3, 10),
1188   };
1189 
1190   MockRead reads[] = {
1191       CreateMockRead(settings_frame, 1),
1192       CreateMockRead(resp, 2),
1193       CreateMockRead(body, 3),
1194       CreateMockRead(fbody, 4),
1195       CreateMockRead(resp2, 7),
1196       CreateMockRead(body2, 8),
1197       CreateMockRead(fbody2, 9),
1198       CreateMockRead(resp3, 11),
1199       CreateMockRead(body3, 12),
1200       CreateMockRead(fbody3, 13),
1201 
1202       MockRead(ASYNC, 0, 14),  // EOF
1203   };
1204 
1205   SequencedSocketData data(reads, writes);
1206 
1207   TransactionHelperResult out;
1208   {
1209     NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
1210                                        nullptr);
1211     helper.RunPreTestSetup();
1212     helper.AddData(&data);
1213     HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
1214     HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
1215     HttpNetworkTransaction trans3(DEFAULT_PRIORITY, helper.session());
1216 
1217     TestCompletionCallback callback1;
1218     TestCompletionCallback callback2;
1219     TestCompletionCallback callback3;
1220 
1221     out.rv = trans1.Start(&request_, callback1.callback(), log_);
1222     ASSERT_EQ(out.rv, ERR_IO_PENDING);
1223     // Run transaction 1 through quickly to force a read of our SETTINGS
1224     // frame.
1225     out.rv = callback1.WaitForResult();
1226     ASSERT_THAT(out.rv, IsOk());
1227 
1228     out.rv = trans2.Start(&request_, callback2.callback(), log_);
1229     ASSERT_EQ(out.rv, ERR_IO_PENDING);
1230     out.rv = trans3.Start(&request_, callback3.callback(), log_);
1231     ASSERT_EQ(out.rv, ERR_IO_PENDING);
1232     out.rv = callback2.WaitForResult();
1233     ASSERT_THAT(out.rv, IsOk());
1234 
1235     out.rv = callback3.WaitForResult();
1236     ASSERT_THAT(out.rv, IsOk());
1237 
1238     const HttpResponseInfo* response1 = trans1.GetResponseInfo();
1239     ASSERT_TRUE(response1);
1240     EXPECT_TRUE(response1->headers);
1241     EXPECT_TRUE(response1->was_fetched_via_spdy);
1242     out.status_line = response1->headers->GetStatusLine();
1243     out.response_info = *response1;
1244     out.rv = ReadTransaction(&trans1, &out.response_data);
1245     EXPECT_THAT(out.rv, IsOk());
1246     EXPECT_EQ("HTTP/1.1 200", out.status_line);
1247     EXPECT_EQ("hello!hello!", out.response_data);
1248 
1249     const HttpResponseInfo* response2 = trans2.GetResponseInfo();
1250     out.status_line = response2->headers->GetStatusLine();
1251     out.response_info = *response2;
1252     out.rv = ReadTransaction(&trans2, &out.response_data);
1253     EXPECT_THAT(out.rv, IsOk());
1254     EXPECT_EQ("HTTP/1.1 200", out.status_line);
1255     EXPECT_EQ("hello!hello!", out.response_data);
1256 
1257     const HttpResponseInfo* response3 = trans3.GetResponseInfo();
1258     out.status_line = response3->headers->GetStatusLine();
1259     out.response_info = *response3;
1260     out.rv = ReadTransaction(&trans3, &out.response_data);
1261     EXPECT_THAT(out.rv, IsOk());
1262     EXPECT_EQ("HTTP/1.1 200", out.status_line);
1263     EXPECT_EQ("hello!hello!", out.response_data);
1264 
1265     helper.VerifyDataConsumed();
1266   }
1267   EXPECT_THAT(out.rv, IsOk());
1268 }
1269 
1270 // Similar to ThreeGetsWithMaxConcurrent above, however this test adds
1271 // a fourth transaction.  The third and fourth transactions have
1272 // different data ("hello!" vs "hello!hello!") and because of the
1273 // user specified priority, we expect to see them inverted in
1274 // the response from the server.
TEST_F(SpdyNetworkTransactionTest,FourGetsWithMaxConcurrentPriority)1275 TEST_F(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) {
1276   // Construct the request.
1277   spdy::SpdySerializedFrame req(
1278       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
1279   spdy::SpdySerializedFrame resp(
1280       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1281   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false));
1282   spdy::SpdySerializedFrame fbody(spdy_util_.ConstructSpdyDataFrame(1, true));
1283   spdy_util_.UpdateWithStreamDestruction(1);
1284 
1285   spdy::SpdySerializedFrame req2(
1286       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
1287   spdy::SpdySerializedFrame resp2(
1288       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
1289   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, false));
1290   spdy::SpdySerializedFrame fbody2(spdy_util_.ConstructSpdyDataFrame(3, true));
1291   spdy_util_.UpdateWithStreamDestruction(3);
1292 
1293   spdy::SpdySerializedFrame req4(
1294       spdy_util_.ConstructSpdyGet(nullptr, 0, 5, HIGHEST));
1295   spdy::SpdySerializedFrame resp4(
1296       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 5));
1297   spdy::SpdySerializedFrame fbody4(spdy_util_.ConstructSpdyDataFrame(5, true));
1298   spdy_util_.UpdateWithStreamDestruction(5);
1299 
1300   spdy::SpdySerializedFrame req3(
1301       spdy_util_.ConstructSpdyGet(nullptr, 0, 7, LOWEST));
1302   spdy::SpdySerializedFrame resp3(
1303       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 7));
1304   spdy::SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(7, false));
1305   spdy::SpdySerializedFrame fbody3(spdy_util_.ConstructSpdyDataFrame(7, true));
1306 
1307   spdy::SettingsMap settings;
1308   const uint32_t max_concurrent_streams = 1;
1309   settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] = max_concurrent_streams;
1310   spdy::SpdySerializedFrame settings_frame(
1311       spdy_util_.ConstructSpdySettings(settings));
1312   spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
1313   MockWrite writes[] = {
1314       CreateMockWrite(req, 0), CreateMockWrite(settings_ack, 5),
1315       // By making these synchronous, it guarantees that they are not *started*
1316       // before their sequence number, which in turn verifies that only a single
1317       // request is in-flight at a time.
1318       CreateMockWrite(req2, 6, SYNCHRONOUS),
1319       CreateMockWrite(req4, 10, SYNCHRONOUS),
1320       CreateMockWrite(req3, 13, SYNCHRONOUS),
1321   };
1322   MockRead reads[] = {
1323       CreateMockRead(settings_frame, 1),
1324       CreateMockRead(resp, 2),
1325       CreateMockRead(body, 3),
1326       CreateMockRead(fbody, 4),
1327       CreateMockRead(resp2, 7),
1328       CreateMockRead(body2, 8),
1329       CreateMockRead(fbody2, 9),
1330       CreateMockRead(resp4, 11),
1331       CreateMockRead(fbody4, 12),
1332       CreateMockRead(resp3, 14),
1333       CreateMockRead(body3, 15),
1334       CreateMockRead(fbody3, 16),
1335 
1336       MockRead(ASYNC, 0, 17),  // EOF
1337   };
1338   SequencedSocketData data(reads, writes);
1339   TransactionHelperResult out;
1340   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
1341   helper.RunPreTestSetup();
1342   helper.AddData(&data);
1343 
1344   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
1345   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
1346   HttpNetworkTransaction trans3(DEFAULT_PRIORITY, helper.session());
1347   HttpNetworkTransaction trans4(HIGHEST, helper.session());
1348 
1349   TestCompletionCallback callback1;
1350   TestCompletionCallback callback2;
1351   TestCompletionCallback callback3;
1352   TestCompletionCallback callback4;
1353 
1354   out.rv = trans1.Start(&request_, callback1.callback(), log_);
1355   ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
1356   // Run transaction 1 through quickly to force a read of our SETTINGS frame.
1357   out.rv = callback1.WaitForResult();
1358   ASSERT_THAT(out.rv, IsOk());
1359 
1360   // Finish async network reads and writes associated with |trans1|.
1361   base::RunLoop().RunUntilIdle();
1362 
1363   out.rv = trans2.Start(&request_, callback2.callback(), log_);
1364   ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
1365   out.rv = trans3.Start(&request_, callback3.callback(), log_);
1366   ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
1367   out.rv = trans4.Start(&request_, callback4.callback(), log_);
1368   ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
1369 
1370   out.rv = callback2.WaitForResult();
1371   ASSERT_THAT(out.rv, IsOk());
1372 
1373   out.rv = callback3.WaitForResult();
1374   ASSERT_THAT(out.rv, IsOk());
1375 
1376   const HttpResponseInfo* response1 = trans1.GetResponseInfo();
1377   EXPECT_TRUE(response1->headers);
1378   EXPECT_TRUE(response1->was_fetched_via_spdy);
1379   out.status_line = response1->headers->GetStatusLine();
1380   out.response_info = *response1;
1381   out.rv = ReadTransaction(&trans1, &out.response_data);
1382   EXPECT_THAT(out.rv, IsOk());
1383   EXPECT_EQ("HTTP/1.1 200", out.status_line);
1384   EXPECT_EQ("hello!hello!", out.response_data);
1385 
1386   const HttpResponseInfo* response2 = trans2.GetResponseInfo();
1387   out.status_line = response2->headers->GetStatusLine();
1388   out.response_info = *response2;
1389   out.rv = ReadTransaction(&trans2, &out.response_data);
1390   EXPECT_THAT(out.rv, IsOk());
1391   EXPECT_EQ("HTTP/1.1 200", out.status_line);
1392   EXPECT_EQ("hello!hello!", out.response_data);
1393 
1394   // notice: response3 gets two hellos, response4 gets one
1395   // hello, so we know dequeuing priority was respected.
1396   const HttpResponseInfo* response3 = trans3.GetResponseInfo();
1397   out.status_line = response3->headers->GetStatusLine();
1398   out.response_info = *response3;
1399   out.rv = ReadTransaction(&trans3, &out.response_data);
1400   EXPECT_THAT(out.rv, IsOk());
1401   EXPECT_EQ("HTTP/1.1 200", out.status_line);
1402   EXPECT_EQ("hello!hello!", out.response_data);
1403 
1404   out.rv = callback4.WaitForResult();
1405   EXPECT_THAT(out.rv, IsOk());
1406   const HttpResponseInfo* response4 = trans4.GetResponseInfo();
1407   out.status_line = response4->headers->GetStatusLine();
1408   out.response_info = *response4;
1409   out.rv = ReadTransaction(&trans4, &out.response_data);
1410   EXPECT_THAT(out.rv, IsOk());
1411   EXPECT_EQ("HTTP/1.1 200", out.status_line);
1412   EXPECT_EQ("hello!", out.response_data);
1413   helper.VerifyDataConsumed();
1414   EXPECT_THAT(out.rv, IsOk());
1415 }
1416 
1417 // Similar to ThreeGetsMaxConcurrrent above, however, this test
1418 // deletes a session in the middle of the transaction to ensure
1419 // that we properly remove pendingcreatestream objects from
1420 // the spdy_session
TEST_F(SpdyNetworkTransactionTest,ThreeGetsWithMaxConcurrentDelete)1421 TEST_F(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) {
1422   // Construct the request.
1423   spdy::SpdySerializedFrame req(
1424       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
1425   spdy::SpdySerializedFrame resp(
1426       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1427   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false));
1428   spdy::SpdySerializedFrame fbody(spdy_util_.ConstructSpdyDataFrame(1, true));
1429   spdy_util_.UpdateWithStreamDestruction(1);
1430 
1431   spdy::SpdySerializedFrame req2(
1432       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
1433   spdy::SpdySerializedFrame resp2(
1434       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
1435   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, false));
1436   spdy::SpdySerializedFrame fbody2(spdy_util_.ConstructSpdyDataFrame(3, true));
1437 
1438   spdy::SettingsMap settings;
1439   const uint32_t max_concurrent_streams = 1;
1440   settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] = max_concurrent_streams;
1441   spdy::SpdySerializedFrame settings_frame(
1442       spdy_util_.ConstructSpdySettings(settings));
1443   spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
1444 
1445   MockWrite writes[] = {
1446       CreateMockWrite(req, 0), CreateMockWrite(settings_ack, 5),
1447       CreateMockWrite(req2, 6),
1448   };
1449   MockRead reads[] = {
1450       CreateMockRead(settings_frame, 1), CreateMockRead(resp, 2),
1451       CreateMockRead(body, 3),           CreateMockRead(fbody, 4),
1452       CreateMockRead(resp2, 7),          CreateMockRead(body2, 8),
1453       CreateMockRead(fbody2, 9),         MockRead(ASYNC, 0, 10),  // EOF
1454   };
1455 
1456   SequencedSocketData data(reads, writes);
1457 
1458   TransactionHelperResult out;
1459   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
1460   helper.RunPreTestSetup();
1461   helper.AddData(&data);
1462   auto trans1 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
1463                                                          helper.session());
1464   auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
1465                                                          helper.session());
1466   auto trans3 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
1467                                                          helper.session());
1468 
1469   TestCompletionCallback callback1;
1470   TestCompletionCallback callback2;
1471   TestCompletionCallback callback3;
1472 
1473   out.rv = trans1->Start(&request_, 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_THAT(out.rv, IsOk());
1478 
1479   out.rv = trans2->Start(&request_, callback2.callback(), log_);
1480   ASSERT_EQ(out.rv, ERR_IO_PENDING);
1481   out.rv = trans3->Start(&request_, callback3.callback(), log_);
1482   trans3.reset();
1483   ASSERT_EQ(out.rv, ERR_IO_PENDING);
1484   out.rv = callback2.WaitForResult();
1485   ASSERT_THAT(out.rv, IsOk());
1486 
1487   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
1488   ASSERT_TRUE(response1);
1489   EXPECT_TRUE(response1->headers);
1490   EXPECT_TRUE(response1->was_fetched_via_spdy);
1491   out.status_line = response1->headers->GetStatusLine();
1492   out.response_info = *response1;
1493   out.rv = ReadTransaction(trans1.get(), &out.response_data);
1494   EXPECT_THAT(out.rv, IsOk());
1495   EXPECT_EQ("HTTP/1.1 200", out.status_line);
1496   EXPECT_EQ("hello!hello!", out.response_data);
1497 
1498   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
1499   ASSERT_TRUE(response2);
1500   out.status_line = response2->headers->GetStatusLine();
1501   out.response_info = *response2;
1502   out.rv = ReadTransaction(trans2.get(), &out.response_data);
1503   EXPECT_THAT(out.rv, IsOk());
1504   EXPECT_EQ("HTTP/1.1 200", out.status_line);
1505   EXPECT_EQ("hello!hello!", out.response_data);
1506   helper.VerifyDataConsumed();
1507   EXPECT_THAT(out.rv, IsOk());
1508 }
1509 
1510 namespace {
1511 
1512 // A helper class that will delete |transaction| on error when the callback is
1513 // invoked.
1514 class KillerCallback : public TestCompletionCallbackBase {
1515  public:
KillerCallback(std::unique_ptr<HttpNetworkTransaction> transaction)1516   explicit KillerCallback(std::unique_ptr<HttpNetworkTransaction> transaction)
1517       : transaction_(std::move(transaction)) {}
1518 
1519   ~KillerCallback() override = default;
1520 
callback()1521   CompletionOnceCallback callback() {
1522     return base::BindOnce(&KillerCallback::OnComplete, base::Unretained(this));
1523   }
1524 
1525  private:
OnComplete(int result)1526   void OnComplete(int result) {
1527     if (result < 0)
1528       transaction_.reset();
1529 
1530     SetResult(result);
1531   }
1532 
1533   std::unique_ptr<HttpNetworkTransaction> transaction_;
1534 };
1535 
1536 }  // namespace
1537 
1538 // Similar to ThreeGetsMaxConcurrrentDelete above, however, this test
1539 // closes the socket while we have a pending transaction waiting for
1540 // a pending stream creation.  http://crbug.com/52901
TEST_F(SpdyNetworkTransactionTest,ThreeGetsWithMaxConcurrentSocketClose)1541 TEST_F(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentSocketClose) {
1542   // Construct the request. Each stream uses a different priority to provide
1543   // more useful failure information if the requests are made in an unexpected
1544   // order.
1545   spdy::SpdySerializedFrame req(
1546       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
1547   spdy::SpdySerializedFrame resp(
1548       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1549   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false));
1550   spdy::SpdySerializedFrame fin_body(
1551       spdy_util_.ConstructSpdyDataFrame(1, true));
1552   spdy_util_.UpdateWithStreamDestruction(1);
1553 
1554   spdy::SpdySerializedFrame req2(
1555       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM));
1556   spdy::SpdySerializedFrame resp2(
1557       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
1558 
1559   spdy::SettingsMap settings;
1560   const uint32_t max_concurrent_streams = 1;
1561   settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] = max_concurrent_streams;
1562   spdy::SpdySerializedFrame settings_frame(
1563       spdy_util_.ConstructSpdySettings(settings));
1564   spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
1565 
1566   MockWrite writes[] = {CreateMockWrite(req, 0),
1567                         CreateMockWrite(settings_ack, 6),
1568                         CreateMockWrite(req2, 7)};
1569   MockRead reads[] = {
1570       CreateMockRead(settings_frame, 1), CreateMockRead(resp, 2),
1571       CreateMockRead(body, 3),
1572       // Delay the request here. For this test to pass, the three HTTP streams
1573       // have to be created in order, but SpdySession doesn't actually guarantee
1574       // that (See note in SpdySession::ProcessPendingStreamRequests). As a
1575       // workaround, delay finishing up the first stream until the second and
1576       // third streams are waiting in the SPDY stream request queue.
1577       MockRead(ASYNC, ERR_IO_PENDING, 4), CreateMockRead(fin_body, 5),
1578       CreateMockRead(resp2, 8),
1579       // The exact error does not matter, but some errors, such as
1580       // ERR_CONNECTION_RESET, may trigger a retry, which this test does not
1581       // account for.
1582       MockRead(ASYNC, ERR_SSL_BAD_RECORD_MAC_ALERT, 9),  // Abort!
1583   };
1584 
1585   SequencedSocketData data(reads, writes);
1586   SequencedSocketData data_placeholder;
1587 
1588   TransactionHelperResult out;
1589   NormalSpdyTransactionHelper helper(request_, HIGHEST, log_, nullptr);
1590   helper.RunPreTestSetup();
1591   helper.AddData(&data);
1592   // We require placeholder data because three get requests are sent out, so
1593   // there needs to be three sets of SSL connection data.
1594   helper.AddData(&data_placeholder);
1595   helper.AddData(&data_placeholder);
1596   HttpNetworkTransaction trans1(HIGHEST, helper.session());
1597   HttpNetworkTransaction trans2(MEDIUM, helper.session());
1598   auto trans3 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
1599                                                          helper.session());
1600   auto* trans3_ptr = trans3.get();
1601 
1602   TestCompletionCallback callback1;
1603   TestCompletionCallback callback2;
1604   KillerCallback callback3(std::move(trans3));
1605 
1606   out.rv = trans1.Start(&request_, callback1.callback(), log_);
1607   ASSERT_EQ(out.rv, ERR_IO_PENDING);
1608   // Run transaction 1 through quickly to force a read of our SETTINGS frame.
1609   out.rv = callback1.WaitForResult();
1610   ASSERT_THAT(out.rv, IsOk());
1611 
1612   out.rv = trans2.Start(&request_, callback2.callback(), log_);
1613   ASSERT_EQ(out.rv, ERR_IO_PENDING);
1614   out.rv = trans3_ptr->Start(&request_, callback3.callback(), log_);
1615   ASSERT_EQ(out.rv, ERR_IO_PENDING);
1616 
1617   // Run until both transactions are in the SpdySession's queue, waiting for the
1618   // final request to complete.
1619   base::RunLoop().RunUntilIdle();
1620   data.Resume();
1621 
1622   out.rv = callback3.WaitForResult();
1623   EXPECT_THAT(out.rv, IsError(ERR_SSL_BAD_RECORD_MAC_ALERT));
1624 
1625   const HttpResponseInfo* response1 = trans1.GetResponseInfo();
1626   ASSERT_TRUE(response1);
1627   EXPECT_TRUE(response1->headers);
1628   EXPECT_TRUE(response1->was_fetched_via_spdy);
1629   out.status_line = response1->headers->GetStatusLine();
1630   out.response_info = *response1;
1631   out.rv = ReadTransaction(&trans1, &out.response_data);
1632   EXPECT_THAT(out.rv, IsOk());
1633 
1634   const HttpResponseInfo* response2 = trans2.GetResponseInfo();
1635   ASSERT_TRUE(response2);
1636   out.status_line = response2->headers->GetStatusLine();
1637   out.response_info = *response2;
1638   out.rv = ReadTransaction(&trans2, &out.response_data);
1639   EXPECT_THAT(out.rv, IsError(ERR_SSL_BAD_RECORD_MAC_ALERT));
1640 
1641   helper.VerifyDataConsumed();
1642 }
1643 
1644 // Test that a simple PUT request works.
TEST_F(SpdyNetworkTransactionTest,Put)1645 TEST_F(SpdyNetworkTransactionTest, Put) {
1646   // Setup the request.
1647   request_.method = "PUT";
1648 
1649   spdy::Http2HeaderBlock put_headers(
1650       spdy_util_.ConstructPutHeaderBlock(kDefaultUrl, 0));
1651   spdy::SpdySerializedFrame req(
1652       spdy_util_.ConstructSpdyHeaders(1, std::move(put_headers), LOWEST, true));
1653   MockWrite writes[] = {
1654       CreateMockWrite(req, 0),
1655   };
1656 
1657   spdy::SpdySerializedFrame resp(
1658       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1659   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
1660   MockRead reads[] = {
1661       CreateMockRead(resp, 1), CreateMockRead(body, 2),
1662       MockRead(ASYNC, 0, 3)  // EOF
1663   };
1664 
1665   SequencedSocketData data(reads, writes);
1666   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
1667   helper.RunToCompletion(&data);
1668   TransactionHelperResult out = helper.output();
1669 
1670   EXPECT_THAT(out.rv, IsOk());
1671   EXPECT_EQ("HTTP/1.1 200", out.status_line);
1672 }
1673 
1674 // Test that a simple HEAD request works.
TEST_F(SpdyNetworkTransactionTest,Head)1675 TEST_F(SpdyNetworkTransactionTest, Head) {
1676   // Setup the request.
1677   request_.method = "HEAD";
1678 
1679   spdy::Http2HeaderBlock head_headers(
1680       spdy_util_.ConstructHeadHeaderBlock(kDefaultUrl, 0));
1681   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyHeaders(
1682       1, std::move(head_headers), LOWEST, true));
1683   MockWrite writes[] = {
1684       CreateMockWrite(req, 0),
1685   };
1686 
1687   spdy::SpdySerializedFrame resp(
1688       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1689   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
1690   MockRead reads[] = {
1691       CreateMockRead(resp, 1), CreateMockRead(body, 2),
1692       MockRead(ASYNC, 0, 3)  // EOF
1693   };
1694 
1695   SequencedSocketData data(reads, writes);
1696   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
1697   helper.RunToCompletion(&data);
1698   TransactionHelperResult out = helper.output();
1699 
1700   EXPECT_THAT(out.rv, IsOk());
1701   EXPECT_EQ("HTTP/1.1 200", out.status_line);
1702 }
1703 
1704 // Test that a simple POST works.
TEST_F(SpdyNetworkTransactionTest,Post)1705 TEST_F(SpdyNetworkTransactionTest, Post) {
1706   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
1707       kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
1708   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
1709   MockWrite writes[] = {
1710       CreateMockWrite(req, 0), CreateMockWrite(body, 1),  // POST upload frame
1711   };
1712 
1713   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
1714   MockRead reads[] = {
1715       CreateMockRead(resp, 2), CreateMockRead(body, 3),
1716       MockRead(ASYNC, 0, 4)  // EOF
1717   };
1718 
1719   SequencedSocketData data(reads, writes);
1720   UsePostRequest();
1721   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
1722   helper.RunToCompletion(&data);
1723   TransactionHelperResult out = helper.output();
1724   EXPECT_THAT(out.rv, IsOk());
1725   EXPECT_EQ("HTTP/1.1 200", out.status_line);
1726   EXPECT_EQ("hello!", out.response_data);
1727 }
1728 
1729 // Test that a POST with a file works.
TEST_F(SpdyNetworkTransactionTest,FilePost)1730 TEST_F(SpdyNetworkTransactionTest, FilePost) {
1731   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
1732       kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
1733   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
1734   MockWrite writes[] = {
1735       CreateMockWrite(req, 0), CreateMockWrite(body, 1),  // POST upload frame
1736   };
1737 
1738   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
1739   MockRead reads[] = {
1740       CreateMockRead(resp, 2), CreateMockRead(body, 3),
1741       MockRead(ASYNC, 0, 4)  // EOF
1742   };
1743 
1744   SequencedSocketData data(reads, writes);
1745   UseFilePostRequest();
1746   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
1747   helper.RunToCompletion(&data);
1748   TransactionHelperResult out = helper.output();
1749   EXPECT_THAT(out.rv, IsOk());
1750   EXPECT_EQ("HTTP/1.1 200", out.status_line);
1751   EXPECT_EQ("hello!", out.response_data);
1752 }
1753 
1754 // Test that a POST with a unreadable file fails.
TEST_F(SpdyNetworkTransactionTest,UnreadableFilePost)1755 TEST_F(SpdyNetworkTransactionTest, UnreadableFilePost) {
1756   MockWrite writes[] = {
1757       MockWrite(ASYNC, 0, 0)  // EOF
1758   };
1759   MockRead reads[] = {
1760       MockRead(ASYNC, 0, 1)  // EOF
1761   };
1762 
1763   SequencedSocketData data(reads, writes);
1764   UseUnreadableFilePostRequest();
1765   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
1766   helper.RunPreTestSetup();
1767   helper.AddData(&data);
1768   helper.RunDefaultTest();
1769 
1770   base::RunLoop().RunUntilIdle();
1771   helper.VerifyDataNotConsumed();
1772   EXPECT_THAT(helper.output().rv, IsError(ERR_ACCESS_DENIED));
1773 }
1774 
1775 // Test that a complex POST works.
TEST_F(SpdyNetworkTransactionTest,ComplexPost)1776 TEST_F(SpdyNetworkTransactionTest, ComplexPost) {
1777   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
1778       kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
1779   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
1780   MockWrite writes[] = {
1781       CreateMockWrite(req, 0), CreateMockWrite(body, 1),  // POST upload frame
1782   };
1783 
1784   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
1785   MockRead reads[] = {
1786       CreateMockRead(resp, 2), CreateMockRead(body, 3),
1787       MockRead(ASYNC, 0, 4)  // EOF
1788   };
1789 
1790   SequencedSocketData data(reads, writes);
1791   UseComplexPostRequest();
1792   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
1793   helper.RunToCompletion(&data);
1794   TransactionHelperResult out = helper.output();
1795   EXPECT_THAT(out.rv, IsOk());
1796   EXPECT_EQ("HTTP/1.1 200", out.status_line);
1797   EXPECT_EQ("hello!", out.response_data);
1798 }
1799 
1800 // Test that a chunked POST works.
TEST_F(SpdyNetworkTransactionTest,ChunkedPost)1801 TEST_F(SpdyNetworkTransactionTest, ChunkedPost) {
1802   spdy::SpdySerializedFrame req(
1803       spdy_util_.ConstructChunkedSpdyPost(nullptr, 0));
1804   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
1805   MockWrite writes[] = {
1806       CreateMockWrite(req, 0), CreateMockWrite(body, 1),
1807   };
1808 
1809   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
1810   MockRead reads[] = {
1811       CreateMockRead(resp, 2), CreateMockRead(body, 3),
1812       MockRead(ASYNC, 0, 4)  // EOF
1813   };
1814 
1815   SequencedSocketData data(reads, writes);
1816   UseChunkedPostRequest();
1817   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
1818 
1819   // These chunks get merged into a single frame when being sent.
1820   const int kFirstChunkSize = kUploadDataSize/2;
1821   upload_chunked_data_stream()->AppendData(kUploadData, kFirstChunkSize, false);
1822   upload_chunked_data_stream()->AppendData(
1823       kUploadData + kFirstChunkSize, kUploadDataSize - kFirstChunkSize, true);
1824 
1825   helper.RunToCompletion(&data);
1826   TransactionHelperResult out = helper.output();
1827   EXPECT_THAT(out.rv, IsOk());
1828   EXPECT_EQ("HTTP/1.1 200", out.status_line);
1829   EXPECT_EQ(kUploadData, out.response_data);
1830 }
1831 
1832 // Test that a chunked POST works with chunks appended after transaction starts.
TEST_F(SpdyNetworkTransactionTest,DelayedChunkedPost)1833 TEST_F(SpdyNetworkTransactionTest, DelayedChunkedPost) {
1834   spdy::SpdySerializedFrame req(
1835       spdy_util_.ConstructChunkedSpdyPost(nullptr, 0));
1836   spdy::SpdySerializedFrame chunk1(spdy_util_.ConstructSpdyDataFrame(1, false));
1837   spdy::SpdySerializedFrame chunk2(spdy_util_.ConstructSpdyDataFrame(1, false));
1838   spdy::SpdySerializedFrame chunk3(spdy_util_.ConstructSpdyDataFrame(1, true));
1839   MockWrite writes[] = {
1840       CreateMockWrite(req, 0), CreateMockWrite(chunk1, 1),
1841       CreateMockWrite(chunk2, 2), CreateMockWrite(chunk3, 3),
1842   };
1843 
1844   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
1845   MockRead reads[] = {
1846       CreateMockRead(resp, 4), CreateMockRead(chunk1, 5),
1847       CreateMockRead(chunk2, 6), CreateMockRead(chunk3, 7),
1848       MockRead(ASYNC, 0, 8)  // EOF
1849   };
1850 
1851   SequencedSocketData data(reads, writes);
1852   UseChunkedPostRequest();
1853   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
1854 
1855   upload_chunked_data_stream()->AppendData(kUploadData, kUploadDataSize, false);
1856 
1857   helper.RunPreTestSetup();
1858   helper.AddData(&data);
1859   ASSERT_TRUE(helper.StartDefaultTest());
1860 
1861   base::RunLoop().RunUntilIdle();
1862   upload_chunked_data_stream()->AppendData(kUploadData, kUploadDataSize, false);
1863   base::RunLoop().RunUntilIdle();
1864   upload_chunked_data_stream()->AppendData(kUploadData, kUploadDataSize, true);
1865 
1866   helper.FinishDefaultTest();
1867   helper.VerifyDataConsumed();
1868 
1869   std::string expected_response;
1870   expected_response += kUploadData;
1871   expected_response += kUploadData;
1872   expected_response += kUploadData;
1873 
1874   TransactionHelperResult out = helper.output();
1875   EXPECT_THAT(out.rv, IsOk());
1876   EXPECT_EQ("HTTP/1.1 200", out.status_line);
1877   EXPECT_EQ(expected_response, out.response_data);
1878 }
1879 
1880 // Test that a POST without any post data works.
TEST_F(SpdyNetworkTransactionTest,NullPost)1881 TEST_F(SpdyNetworkTransactionTest, NullPost) {
1882   // Setup the request.
1883   request_.method = "POST";
1884   // Create an empty UploadData.
1885   request_.upload_data_stream = nullptr;
1886 
1887   // When request.upload_data_stream is NULL for post, content-length is
1888   // expected to be 0.
1889   spdy::Http2HeaderBlock req_block(
1890       spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, 0));
1891   spdy::SpdySerializedFrame req(
1892       spdy_util_.ConstructSpdyHeaders(1, std::move(req_block), LOWEST, true));
1893 
1894   MockWrite writes[] = {
1895       CreateMockWrite(req, 0),
1896   };
1897 
1898   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
1899   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
1900   MockRead reads[] = {
1901       CreateMockRead(resp, 1), CreateMockRead(body, 2),
1902       MockRead(ASYNC, 0, 3)  // EOF
1903   };
1904 
1905   SequencedSocketData data(reads, writes);
1906 
1907   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
1908   helper.RunToCompletion(&data);
1909   TransactionHelperResult out = helper.output();
1910   EXPECT_THAT(out.rv, IsOk());
1911   EXPECT_EQ("HTTP/1.1 200", out.status_line);
1912   EXPECT_EQ("hello!", out.response_data);
1913 }
1914 
1915 // Test that a simple POST works.
TEST_F(SpdyNetworkTransactionTest,EmptyPost)1916 TEST_F(SpdyNetworkTransactionTest, EmptyPost) {
1917   // Create an empty UploadDataStream.
1918   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
1919   ElementsUploadDataStream stream(std::move(element_readers), 0);
1920 
1921   // Setup the request.
1922   request_.method = "POST";
1923   request_.upload_data_stream = &stream;
1924 
1925   const uint64_t kContentLength = 0;
1926 
1927   spdy::Http2HeaderBlock req_block(
1928       spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kContentLength));
1929   spdy::SpdySerializedFrame req(
1930       spdy_util_.ConstructSpdyHeaders(1, std::move(req_block), LOWEST, true));
1931 
1932   MockWrite writes[] = {
1933       CreateMockWrite(req, 0),
1934   };
1935 
1936   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
1937   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
1938   MockRead reads[] = {
1939       CreateMockRead(resp, 1), CreateMockRead(body, 2),
1940       MockRead(ASYNC, 0, 3)  // EOF
1941   };
1942 
1943   SequencedSocketData data(reads, writes);
1944 
1945   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
1946   helper.RunToCompletion(&data);
1947   TransactionHelperResult out = helper.output();
1948   EXPECT_THAT(out.rv, IsOk());
1949   EXPECT_EQ("HTTP/1.1 200", out.status_line);
1950   EXPECT_EQ("hello!", out.response_data);
1951 }
1952 
1953 // While we're doing a post, the server sends the reply before upload completes.
TEST_F(SpdyNetworkTransactionTest,ResponseBeforePostCompletes)1954 TEST_F(SpdyNetworkTransactionTest, ResponseBeforePostCompletes) {
1955   spdy::SpdySerializedFrame req(
1956       spdy_util_.ConstructChunkedSpdyPost(nullptr, 0));
1957   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
1958   MockWrite writes[] = {
1959       CreateMockWrite(req, 0), CreateMockWrite(body, 3),
1960   };
1961   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
1962   MockRead reads[] = {
1963       CreateMockRead(resp, 1), CreateMockRead(body, 2),
1964       MockRead(ASYNC, 0, 4)  // EOF
1965   };
1966 
1967   // Write the request headers, and read the complete response
1968   // while still waiting for chunked request data.
1969   SequencedSocketData data(reads, writes);
1970   UseChunkedPostRequest();
1971   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
1972   helper.RunPreTestSetup();
1973   helper.AddData(&data);
1974 
1975   ASSERT_TRUE(helper.StartDefaultTest());
1976 
1977   base::RunLoop().RunUntilIdle();
1978 
1979   // Process the request headers, response headers, and response body.
1980   // The request body is still in flight.
1981   const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
1982   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1983 
1984   // Finish sending the request body.
1985   upload_chunked_data_stream()->AppendData(kUploadData, kUploadDataSize, true);
1986   helper.WaitForCallbackToComplete();
1987   EXPECT_THAT(helper.output().rv, IsOk());
1988 
1989   std::string response_body;
1990   EXPECT_THAT(ReadTransaction(helper.trans(), &response_body), IsOk());
1991   EXPECT_EQ(kUploadData, response_body);
1992 
1993   // Finish async network reads/writes.
1994   base::RunLoop().RunUntilIdle();
1995   helper.VerifyDataConsumed();
1996 }
1997 
1998 // The client upon cancellation tries to send a RST_STREAM frame. The mock
1999 // socket causes the TCP write to return zero. This test checks that the client
2000 // tries to queue up the RST_STREAM frame again.
TEST_F(SpdyNetworkTransactionTest,SocketWriteReturnsZero)2001 TEST_F(SpdyNetworkTransactionTest, SocketWriteReturnsZero) {
2002   spdy::SpdySerializedFrame req(
2003       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
2004   spdy::SpdySerializedFrame rst(
2005       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
2006   MockWrite writes[] = {
2007       CreateMockWrite(req, 0, SYNCHRONOUS),
2008       MockWrite(SYNCHRONOUS, nullptr, 0, 2),
2009       CreateMockWrite(rst, 3, SYNCHRONOUS),
2010   };
2011 
2012   spdy::SpdySerializedFrame resp(
2013       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
2014   MockRead reads[] = {
2015       CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, nullptr, 0, 4)  // EOF
2016   };
2017 
2018   SequencedSocketData data(reads, writes);
2019   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
2020   helper.RunPreTestSetup();
2021   helper.AddData(&data);
2022   helper.StartDefaultTest();
2023   EXPECT_THAT(helper.output().rv, IsError(ERR_IO_PENDING));
2024 
2025   helper.WaitForCallbackToComplete();
2026   EXPECT_THAT(helper.output().rv, IsOk());
2027 
2028   helper.ResetTrans();
2029   base::RunLoop().RunUntilIdle();
2030 
2031   helper.VerifyDataConsumed();
2032 }
2033 
2034 // Test that the transaction doesn't crash when we don't have a reply.
TEST_F(SpdyNetworkTransactionTest,ResponseWithoutHeaders)2035 TEST_F(SpdyNetworkTransactionTest, ResponseWithoutHeaders) {
2036   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
2037   MockRead reads[] = {
2038       CreateMockRead(body, 1), MockRead(ASYNC, 0, 3)  // EOF
2039   };
2040 
2041   spdy::SpdySerializedFrame req(
2042       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
2043   spdy::SpdySerializedFrame rst(
2044       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
2045   MockWrite writes[] = {
2046       CreateMockWrite(req, 0), CreateMockWrite(rst, 2),
2047   };
2048   SequencedSocketData data(reads, writes);
2049   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
2050   helper.RunToCompletion(&data);
2051   TransactionHelperResult out = helper.output();
2052   EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
2053 }
2054 
2055 // Test that the transaction doesn't crash when we get two replies on the same
2056 // stream ID. See http://crbug.com/45639.
TEST_F(SpdyNetworkTransactionTest,ResponseWithTwoSynReplies)2057 TEST_F(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) {
2058   spdy::SpdySerializedFrame req(
2059       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
2060   spdy::SpdySerializedFrame rst(
2061       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
2062   MockWrite writes[] = {
2063       CreateMockWrite(req, 0), CreateMockWrite(rst, 4),
2064   };
2065 
2066   spdy::SpdySerializedFrame resp0(
2067       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
2068   spdy::SpdySerializedFrame resp1(
2069       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
2070   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
2071   MockRead reads[] = {
2072       CreateMockRead(resp0, 1), CreateMockRead(resp1, 2),
2073       CreateMockRead(body, 3), MockRead(ASYNC, 0, 5)  // EOF
2074   };
2075 
2076   SequencedSocketData data(reads, writes);
2077 
2078   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
2079   helper.RunPreTestSetup();
2080   helper.AddData(&data);
2081 
2082   HttpNetworkTransaction* trans = helper.trans();
2083 
2084   TestCompletionCallback callback;
2085   int rv = trans->Start(&request_, callback.callback(), log_);
2086   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2087   rv = callback.WaitForResult();
2088   EXPECT_THAT(rv, IsOk());
2089 
2090   const HttpResponseInfo* response = trans->GetResponseInfo();
2091   ASSERT_TRUE(response);
2092   EXPECT_TRUE(response->headers);
2093   EXPECT_TRUE(response->was_fetched_via_spdy);
2094   std::string response_data;
2095   rv = ReadTransaction(trans, &response_data);
2096   EXPECT_THAT(rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
2097 
2098   helper.VerifyDataConsumed();
2099 }
2100 
TEST_F(SpdyNetworkTransactionTest,ResetReplyWithTransferEncoding)2101 TEST_F(SpdyNetworkTransactionTest, ResetReplyWithTransferEncoding) {
2102   // Construct the request.
2103   spdy::SpdySerializedFrame req(
2104       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
2105   spdy::SpdySerializedFrame rst(
2106       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
2107   MockWrite writes[] = {
2108       CreateMockWrite(req, 0), CreateMockWrite(rst, 2),
2109   };
2110 
2111   const char* const headers[] = {
2112     "transfer-encoding", "chunked"
2113   };
2114   spdy::SpdySerializedFrame resp(
2115       spdy_util_.ConstructSpdyGetReply(headers, 1, 1));
2116   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
2117   MockRead reads[] = {
2118       CreateMockRead(resp, 1), CreateMockRead(body, 3),
2119       MockRead(ASYNC, 0, 4)  // EOF
2120   };
2121 
2122   SequencedSocketData data(reads, writes);
2123   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
2124   helper.RunToCompletion(&data);
2125   TransactionHelperResult out = helper.output();
2126   EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
2127 
2128   helper.session()->spdy_session_pool()->CloseAllSessions();
2129   helper.VerifyDataConsumed();
2130 }
2131 
TEST_F(SpdyNetworkTransactionTest,CancelledTransaction)2132 TEST_F(SpdyNetworkTransactionTest, CancelledTransaction) {
2133   // Construct the request.
2134   spdy::SpdySerializedFrame req(
2135       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
2136   MockWrite writes[] = {
2137       CreateMockWrite(req),
2138   };
2139 
2140   spdy::SpdySerializedFrame resp(
2141       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
2142   MockRead reads[] = {
2143       CreateMockRead(resp),
2144       // This following read isn't used by the test, except during the
2145       // RunUntilIdle() call at the end since the SpdySession survives the
2146       // HttpNetworkTransaction and still tries to continue Read()'ing.  Any
2147       // MockRead will do here.
2148       MockRead(ASYNC, 0, 0)  // EOF
2149   };
2150 
2151   StaticSocketDataProvider data(reads, writes);
2152 
2153   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
2154   helper.RunPreTestSetup();
2155   helper.AddData(&data);
2156   HttpNetworkTransaction* trans = helper.trans();
2157 
2158   TestCompletionCallback callback;
2159   int rv = trans->Start(&request_, callback.callback(), log_);
2160   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2161   helper.ResetTrans();  // Cancel the transaction.
2162 
2163   // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
2164   // MockClientSocketFactory) are still alive.
2165   base::RunLoop().RunUntilIdle();
2166   helper.VerifyDataNotConsumed();
2167 }
2168 
2169 // Verify that the client sends a Rst Frame upon cancelling the stream.
TEST_F(SpdyNetworkTransactionTest,CancelledTransactionSendRst)2170 TEST_F(SpdyNetworkTransactionTest, CancelledTransactionSendRst) {
2171   spdy::SpdySerializedFrame req(
2172       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
2173   spdy::SpdySerializedFrame rst(
2174       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
2175   MockWrite writes[] = {
2176       CreateMockWrite(req, 0, SYNCHRONOUS),
2177       CreateMockWrite(rst, 2, SYNCHRONOUS),
2178   };
2179 
2180   spdy::SpdySerializedFrame resp(
2181       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
2182   MockRead reads[] = {
2183       CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, nullptr, 0, 3)  // EOF
2184   };
2185 
2186   SequencedSocketData data(reads, writes);
2187 
2188   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
2189   helper.RunPreTestSetup();
2190   helper.AddData(&data);
2191   HttpNetworkTransaction* trans = helper.trans();
2192 
2193   TestCompletionCallback callback;
2194 
2195   int rv = trans->Start(&request_, callback.callback(), log_);
2196   EXPECT_THAT(callback.GetResult(rv), IsOk());
2197 
2198   helper.ResetTrans();
2199   base::RunLoop().RunUntilIdle();
2200 
2201   helper.VerifyDataConsumed();
2202 }
2203 
2204 // Verify that the client can correctly deal with the user callback attempting
2205 // to start another transaction on a session that is closing down. See
2206 // http://crbug.com/47455
TEST_F(SpdyNetworkTransactionTest,StartTransactionOnReadCallback)2207 TEST_F(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) {
2208   spdy::SpdySerializedFrame req(
2209       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
2210   MockWrite writes[] = {CreateMockWrite(req)};
2211   MockWrite writes2[] = {CreateMockWrite(req, 0),
2212                          MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 3)};
2213 
2214   // The indicated length of this frame is longer than its actual length. When
2215   // the session receives an empty frame after this one, it shuts down the
2216   // session, and calls the read callback with the incomplete data.
2217   const uint8_t kGetBodyFrame2[] = {
2218       0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
2219       0x07, 'h',  'e',  'l',  'l',  'o',  '!',
2220   };
2221 
2222   spdy::SpdySerializedFrame resp(
2223       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
2224   MockRead reads[] = {
2225       CreateMockRead(resp, 1),
2226       MockRead(ASYNC, ERR_IO_PENDING, 2),  // Force a pause
2227       MockRead(ASYNC, reinterpret_cast<const char*>(kGetBodyFrame2),
2228                std::size(kGetBodyFrame2), 3),
2229       MockRead(ASYNC, ERR_IO_PENDING, 4),  // Force a pause
2230       MockRead(ASYNC, nullptr, 0, 5),      // EOF
2231   };
2232   MockRead reads2[] = {
2233       CreateMockRead(resp, 1), MockRead(ASYNC, nullptr, 0, 2),  // EOF
2234   };
2235 
2236   SequencedSocketData data(reads, writes);
2237   SequencedSocketData data2(reads2, writes2);
2238 
2239   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
2240   helper.RunPreTestSetup();
2241   helper.AddData(&data);
2242   helper.AddData(&data2);
2243   HttpNetworkTransaction* trans = helper.trans();
2244 
2245   // Start the transaction with basic parameters.
2246   TestCompletionCallback callback;
2247   int rv = trans->Start(&request_, callback.callback(), log_);
2248   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2249   rv = callback.WaitForResult();
2250 
2251   const int kSize = 3000;
2252   scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(kSize);
2253   rv = trans->Read(
2254       buf.get(), kSize,
2255       base::BindOnce(&SpdyNetworkTransactionTest::StartTransactionCallback,
2256                      helper.session(), default_url_, log_));
2257   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2258   // This forces an err_IO_pending, which sets the callback.
2259   data.Resume();
2260   data.RunUntilPaused();
2261 
2262   // This finishes the read.
2263   data.Resume();
2264   base::RunLoop().RunUntilIdle();
2265   helper.VerifyDataConsumed();
2266 }
2267 
2268 // Verify that the client can correctly deal with the user callback deleting
2269 // the transaction. Failures will usually be flagged by thread and/or memory
2270 // checking tools. See http://crbug.com/46925
TEST_F(SpdyNetworkTransactionTest,DeleteSessionOnReadCallback)2271 TEST_F(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) {
2272   spdy::SpdySerializedFrame req(
2273       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
2274   MockWrite writes[] = {CreateMockWrite(req, 0)};
2275 
2276   spdy::SpdySerializedFrame resp(
2277       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
2278   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
2279   MockRead reads[] = {
2280       CreateMockRead(resp, 1),
2281       MockRead(ASYNC, ERR_IO_PENDING, 2),                       // Force a pause
2282       CreateMockRead(body, 3), MockRead(ASYNC, nullptr, 0, 4),  // EOF
2283   };
2284 
2285   SequencedSocketData data(reads, writes);
2286 
2287   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
2288   helper.RunPreTestSetup();
2289   helper.AddData(&data);
2290   HttpNetworkTransaction* trans = helper.trans();
2291 
2292   // Start the transaction with basic parameters.
2293   TestCompletionCallback callback;
2294   int rv = trans->Start(&request_, callback.callback(), log_);
2295   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2296   rv = callback.WaitForResult();
2297 
2298   // Setup a user callback which will delete the session, and clear out the
2299   // memory holding the stream object. Note that the callback deletes trans.
2300   const int kSize = 3000;
2301   scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(kSize);
2302   rv = trans->Read(
2303       buf.get(), kSize,
2304       base::BindOnce(&SpdyNetworkTransactionTest::DeleteSessionCallback,
2305                      base::Unretained(&helper)));
2306   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2307   data.Resume();
2308 
2309   // Finish running rest of tasks.
2310   base::RunLoop().RunUntilIdle();
2311   helper.VerifyDataConsumed();
2312 }
2313 
TEST_F(SpdyNetworkTransactionTest,RedirectGetRequest)2314 TEST_F(SpdyNetworkTransactionTest, RedirectGetRequest) {
2315   MockClientSocketFactory socket_factory;
2316   auto context_builder =
2317       CreateSpdyTestURLRequestContextBuilder(&socket_factory);
2318   auto spdy_url_request_context = context_builder->Build();
2319   SpdySessionPoolPeer pool_peer(
2320       spdy_url_request_context->http_transaction_factory()
2321           ->GetSession()
2322           ->spdy_session_pool());
2323   pool_peer.SetEnableSendingInitialData(false);
2324   // Use a different port to avoid trying to reuse the initial H2 session.
2325   const char kRedirectUrl[] = "https://www.foo.com:8080/index.php";
2326 
2327   SSLSocketDataProvider ssl_provider0(ASYNC, OK);
2328   ssl_provider0.next_proto = kProtoHTTP2;
2329   socket_factory.AddSSLSocketDataProvider(&ssl_provider0);
2330 
2331   spdy::Http2HeaderBlock headers0(
2332       spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
2333   headers0["user-agent"] = "";
2334   headers0["accept-encoding"] = "gzip, deflate";
2335 
2336   spdy::SpdySerializedFrame req0(
2337       spdy_util_.ConstructSpdyHeaders(1, std::move(headers0), LOWEST, true));
2338   spdy::SpdySerializedFrame rst(
2339       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
2340   MockWrite writes0[] = {CreateMockWrite(req0, 0), CreateMockWrite(rst, 2)};
2341 
2342   const char* const kExtraHeaders[] = {"location", kRedirectUrl};
2343   spdy::SpdySerializedFrame resp0(spdy_util_.ConstructSpdyReplyError(
2344       "301", kExtraHeaders, std::size(kExtraHeaders) / 2, 1));
2345   MockRead reads0[] = {CreateMockRead(resp0, 1), MockRead(ASYNC, 0, 3)};
2346 
2347   SequencedSocketData data0(reads0, writes0);
2348   socket_factory.AddSocketDataProvider(&data0);
2349 
2350   SSLSocketDataProvider ssl_provider1(ASYNC, OK);
2351   ssl_provider1.next_proto = kProtoHTTP2;
2352   socket_factory.AddSSLSocketDataProvider(&ssl_provider1);
2353 
2354   SpdyTestUtil spdy_util1;
2355   spdy::Http2HeaderBlock headers1(
2356       spdy_util1.ConstructGetHeaderBlock(kRedirectUrl));
2357   headers1["user-agent"] = "";
2358   headers1["accept-encoding"] = "gzip, deflate";
2359   spdy::SpdySerializedFrame req1(
2360       spdy_util1.ConstructSpdyHeaders(1, std::move(headers1), LOWEST, true));
2361   MockWrite writes1[] = {CreateMockWrite(req1, 0)};
2362 
2363   spdy::SpdySerializedFrame resp1(
2364       spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
2365   spdy::SpdySerializedFrame body1(spdy_util1.ConstructSpdyDataFrame(1, true));
2366   MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
2367                        MockRead(ASYNC, 0, 3)};
2368 
2369   SequencedSocketData data1(reads1, writes1);
2370   socket_factory.AddSocketDataProvider(&data1);
2371 
2372   TestDelegate delegate;
2373 
2374   std::unique_ptr<URLRequest> request = spdy_url_request_context->CreateRequest(
2375       default_url_, DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
2376   request->Start();
2377   delegate.RunUntilRedirect();
2378 
2379   EXPECT_EQ(1, delegate.received_redirect_count());
2380 
2381   request->FollowDeferredRedirect(absl::nullopt /* removed_headers */,
2382                                   absl::nullopt /* modified_headers */);
2383   delegate.RunUntilComplete();
2384 
2385   EXPECT_EQ(1, delegate.response_started_count());
2386   EXPECT_FALSE(delegate.received_data_before_response());
2387   EXPECT_THAT(delegate.request_status(), IsOk());
2388   EXPECT_EQ("hello!", delegate.data_received());
2389 
2390   // Pump the message loop to allow read data to be consumed.
2391   base::RunLoop().RunUntilIdle();
2392 
2393   EXPECT_TRUE(data0.AllReadDataConsumed());
2394   EXPECT_TRUE(data0.AllWriteDataConsumed());
2395   EXPECT_TRUE(data1.AllReadDataConsumed());
2396   EXPECT_TRUE(data1.AllWriteDataConsumed());
2397 }
2398 
TEST_F(SpdyNetworkTransactionTest,RedirectMultipleLocations)2399 TEST_F(SpdyNetworkTransactionTest, RedirectMultipleLocations) {
2400   const spdy::SpdyStreamId kStreamId = 1;
2401   // Construct the request and the RST frame.
2402   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(
2403       /*extra_headers=*/nullptr, /*extra_header_count=*/0, kStreamId, LOWEST));
2404   spdy::SpdySerializedFrame rst(spdy_util_.ConstructSpdyRstStream(
2405       kStreamId, spdy::ERROR_CODE_PROTOCOL_ERROR));
2406   MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(rst, 4)};
2407 
2408   // Construct the response.
2409   const char* const kExtraResponseHeaders[] = {
2410       "location",
2411       "https://example1.test",
2412       "location",
2413       "https://example2.test",
2414   };
2415   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
2416       "301", kExtraResponseHeaders, std::size(kExtraResponseHeaders) / 2,
2417       kStreamId));
2418   spdy::SpdySerializedFrame body(
2419       spdy_util_.ConstructSpdyDataFrame(kStreamId, /*fin=*/true));
2420   MockRead reads[] = {
2421       CreateMockRead(resp, 1), CreateMockRead(body, 2),
2422       MockRead(ASYNC, 0, 3)  // EOF
2423   };
2424 
2425   SequencedSocketData data(reads, writes);
2426   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
2427   helper.RunToCompletion(&data);
2428   TransactionHelperResult out = helper.output();
2429   EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
2430 }
2431 
2432 // Server push is not supported. Verify that SETTINGS_ENABLE_PUSH = 0 is sent in
2433 // the initial SETTINGS frame, and that an incoming pushed stream is reset.
TEST_F(SpdyNetworkTransactionTest,ServerPushReset)2434 TEST_F(SpdyNetworkTransactionTest, ServerPushReset) {
2435   base::HistogramTester histogram_tester;
2436 
2437   spdy::SpdySerializedFrame preface(
2438       const_cast<char*>(spdy::kHttp2ConnectionHeaderPrefix),
2439       spdy::kHttp2ConnectionHeaderPrefixSize,
2440       /* owns_buffer = */ false);
2441 
2442   spdy::SettingsMap initial_settings;
2443   initial_settings[spdy::SETTINGS_HEADER_TABLE_SIZE] = kSpdyMaxHeaderTableSize;
2444   initial_settings[spdy::SETTINGS_ENABLE_PUSH] = 0;
2445   initial_settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] =
2446       kSpdyMaxConcurrentPushedStreams;
2447   initial_settings[spdy::SETTINGS_MAX_HEADER_LIST_SIZE] =
2448       kSpdyMaxHeaderListSize;
2449   spdy::SpdySerializedFrame initial_settings_frame(
2450       spdy_util_.ConstructSpdySettings(initial_settings));
2451 
2452   spdy::SpdySerializedFrame req(
2453       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
2454   spdy::SpdySerializedFrame rst(
2455       spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
2456 
2457   MockWrite writes[] = {CreateMockWrite(preface, 0),
2458                         CreateMockWrite(initial_settings_frame, 1),
2459                         CreateMockWrite(req, 2), CreateMockWrite(rst, 5)};
2460 
2461   spdy::SpdySerializedFrame reply(
2462       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
2463   spdy::SpdySerializedFrame push(
2464       spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
2465   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
2466   MockRead reads[] = {CreateMockRead(reply, 3), CreateMockRead(push, 4),
2467                       CreateMockRead(body, 6), MockRead(ASYNC, OK, 7)};
2468 
2469   SequencedSocketData data(reads, writes);
2470 
2471   auto session_deps = std::make_unique<SpdySessionDependencies>();
2472   session_deps->http2_settings[spdy::SETTINGS_ENABLE_PUSH] = 0;
2473   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
2474                                      std::move(session_deps));
2475 
2476   SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
2477   SpdySessionPoolPeer pool_peer(spdy_session_pool);
2478   pool_peer.SetEnableSendingInitialData(true);
2479 
2480   helper.RunToCompletion(&data);
2481 
2482   histogram_tester.ExpectBucketCount(
2483       "Net.SpdyPushedStreamFate",
2484       static_cast<int>(SpdyPushedStreamFate::kPushDisabled), 1);
2485   histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
2486 }
2487 
2488 // PUSH_PROMISE on a closed client-initiated stream should trigger RST_STREAM.
TEST_F(SpdyNetworkTransactionTest,ServerPushOnClosedStream)2489 TEST_F(SpdyNetworkTransactionTest, ServerPushOnClosedStream) {
2490   base::HistogramTester histogram_tester;
2491 
2492   spdy::SpdySerializedFrame stream1_syn(
2493       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
2494   spdy::SpdySerializedFrame rst(
2495       spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
2496   MockWrite writes[] = {
2497       CreateMockWrite(stream1_syn, 0),
2498       CreateMockWrite(rst, 5),
2499   };
2500 
2501   spdy::SpdySerializedFrame stream1_reply(
2502       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
2503   spdy::SpdySerializedFrame stream1_body(
2504       spdy_util_.ConstructSpdyDataFrame(1, true));
2505   spdy::SpdySerializedFrame stream2_syn(
2506       spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
2507   MockRead reads[] = {
2508       CreateMockRead(stream1_reply, 1),
2509       CreateMockRead(stream1_body, 2),
2510       CreateMockRead(stream2_syn, 3),
2511       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 4),
2512   };
2513 
2514   SequencedSocketData data(reads, writes);
2515   auto session_deps = std::make_unique<SpdySessionDependencies>();
2516   session_deps->http2_settings[spdy::SETTINGS_ENABLE_PUSH] = 1;
2517   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
2518                                      std::move(session_deps));
2519   helper.RunPreTestSetup();
2520   helper.AddData(&data);
2521 
2522   HttpNetworkTransaction* trans = helper.trans();
2523 
2524   TestCompletionCallback callback;
2525   int rv = trans->Start(&request_, callback.callback(), log_);
2526   rv = callback.GetResult(rv);
2527   EXPECT_THAT(rv, IsOk());
2528 
2529   // Finish async network reads/writes.
2530   base::RunLoop().RunUntilIdle();
2531 
2532   HttpResponseInfo response = *trans->GetResponseInfo();
2533   EXPECT_TRUE(response.headers);
2534   EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
2535 
2536   EXPECT_TRUE(data.AllReadDataConsumed());
2537   EXPECT_TRUE(data.AllWriteDataConsumed());
2538   VerifyStreamsClosed(helper);
2539 
2540   histogram_tester.ExpectBucketCount(
2541       "Net.SpdyPushedStreamFate",
2542       static_cast<int>(SpdyPushedStreamFate::kPushDisabled), 1);
2543   histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
2544 }
2545 
TEST_F(SpdyNetworkTransactionTest,NoConnectionPoolingOverTunnel)2546 TEST_F(SpdyNetworkTransactionTest, NoConnectionPoolingOverTunnel) {
2547   // Use port 443 for two reasons:  This makes the endpoint is port 443 check in
2548   // NormalSpdyTransactionHelper pass, and this means that the tunnel uses the
2549   // same port as the servers, to further confuse things.
2550   const char kPacString[] = "PROXY myproxy:443";
2551 
2552   auto session_deps = std::make_unique<SpdySessionDependencies>(
2553       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
2554           kPacString, TRAFFIC_ANNOTATION_FOR_TESTS));
2555   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
2556                                      std::move(session_deps));
2557 
2558   // Only one request uses the first connection.
2559   spdy::SpdySerializedFrame req1(
2560       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
2561   MockWrite writes1[] = {
2562       MockWrite(ASYNC, 0,
2563                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2564                 "Host: www.example.org:443\r\n"
2565                 "Proxy-Connection: keep-alive\r\n\r\n"),
2566       CreateMockWrite(req1, 2),
2567   };
2568 
2569   spdy::SpdySerializedFrame resp1(
2570       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
2571   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
2572   MockRead reads1[] = {MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
2573                        CreateMockRead(resp1, 3), CreateMockRead(body1, 4),
2574                        MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5)};
2575 
2576   MockConnect connect1(ASYNC, OK);
2577   SequencedSocketData data1(connect1, reads1, writes1);
2578 
2579   // Run a transaction to completion to set up a SPDY session.
2580   helper.RunToCompletion(&data1);
2581   TransactionHelperResult out = helper.output();
2582   EXPECT_THAT(out.rv, IsOk());
2583   EXPECT_EQ("HTTP/1.1 200", out.status_line);
2584   EXPECT_EQ("hello!", out.response_data);
2585 
2586   // A new SPDY session should have been created.
2587   SpdySessionKey key1(HostPortPair("www.example.org", 443),
2588                       PacResultElementToProxyServer(kPacString),
2589                       PRIVACY_MODE_DISABLED,
2590                       SpdySessionKey::IsProxySession::kFalse, SocketTag(),
2591                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
2592   base::WeakPtr<SpdySession> session1 =
2593       helper.session()->spdy_session_pool()->FindAvailableSession(
2594           key1, true /* enable_ip_based_pooling */, false /* is_websocket */,
2595           NetLogWithSource());
2596   ASSERT_TRUE(session1);
2597 
2598   // The second request uses a second connection.
2599   SpdyTestUtil spdy_util2;
2600   spdy::SpdySerializedFrame req2(
2601       spdy_util2.ConstructSpdyGet("https://example.test", 1, LOWEST));
2602   MockWrite writes2[] = {
2603       MockWrite(ASYNC, 0,
2604                 "CONNECT example.test:443 HTTP/1.1\r\n"
2605                 "Host: example.test:443\r\n"
2606                 "Proxy-Connection: keep-alive\r\n\r\n"),
2607       CreateMockWrite(req2, 2),
2608   };
2609 
2610   spdy::SpdySerializedFrame resp2(
2611       spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
2612   spdy::SpdySerializedFrame body2(spdy_util2.ConstructSpdyDataFrame(1, true));
2613   MockRead reads2[] = {MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
2614                        CreateMockRead(resp2, 3), CreateMockRead(body2, 4),
2615                        MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5)};
2616 
2617   MockConnect connect2(ASYNC, OK);
2618   SequencedSocketData data2(connect2, reads2, writes2);
2619   helper.AddData(&data2);
2620 
2621   HttpRequestInfo request2;
2622   request2.method = "GET";
2623   request2.url = GURL("https://example.test/");
2624   request2.load_flags = 0;
2625   request2.traffic_annotation =
2626       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2627   auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
2628                                                          helper.session());
2629 
2630   TestCompletionCallback callback;
2631   EXPECT_THAT(trans2->Start(&request2, callback.callback(), NetLogWithSource()),
2632               IsError(ERR_IO_PENDING));
2633 
2634   // Wait for the second request to get headers.  It should create a new H2
2635   // session to do so.
2636   EXPECT_THAT(callback.WaitForResult(), IsOk());
2637 
2638   const HttpResponseInfo* response = trans2->GetResponseInfo();
2639   ASSERT_TRUE(response);
2640   ASSERT_TRUE(response->headers);
2641   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
2642   EXPECT_TRUE(response->was_fetched_via_spdy);
2643   EXPECT_TRUE(response->was_alpn_negotiated);
2644   std::string response_data;
2645   ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
2646   EXPECT_EQ("hello!", response_data);
2647 
2648   // Inspect the new session.
2649   SpdySessionKey key2(HostPortPair("example.test", 443),
2650                       PacResultElementToProxyServer(kPacString),
2651                       PRIVACY_MODE_DISABLED,
2652                       SpdySessionKey::IsProxySession::kFalse, SocketTag(),
2653                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
2654   base::WeakPtr<SpdySession> session2 =
2655       helper.session()->spdy_session_pool()->FindAvailableSession(
2656           key2, true /* enable_ip_based_pooling */, false /* is_websocket */,
2657           NetLogWithSource());
2658   ASSERT_TRUE(session2);
2659   ASSERT_TRUE(session1);
2660   EXPECT_NE(session1.get(), session2.get());
2661 }
2662 
2663 // Check that if a session is found after host resolution, but is closed before
2664 // the task to try to use it executes, the request will continue to create a new
2665 // socket and use it.
TEST_F(SpdyNetworkTransactionTest,ConnectionPoolingSessionClosedBeforeUse)2666 TEST_F(SpdyNetworkTransactionTest, ConnectionPoolingSessionClosedBeforeUse) {
2667   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
2668 
2669   // Only one request uses the first connection.
2670   spdy::SpdySerializedFrame req1(
2671       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
2672   MockWrite writes1[] = {
2673       CreateMockWrite(req1, 0),
2674   };
2675 
2676   spdy::SpdySerializedFrame resp1(
2677       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
2678   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
2679   MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
2680                        MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
2681 
2682   MockConnect connect1(ASYNC, OK);
2683   SequencedSocketData data1(connect1, reads1, writes1);
2684 
2685   // Run a transaction to completion to set up a SPDY session.
2686   helper.RunToCompletion(&data1);
2687   TransactionHelperResult out = helper.output();
2688   EXPECT_THAT(out.rv, IsOk());
2689   EXPECT_EQ("HTTP/1.1 200", out.status_line);
2690   EXPECT_EQ("hello!", out.response_data);
2691 
2692   // A new SPDY session should have been created.
2693   SpdySessionKey key1(HostPortPair("www.example.org", 443),
2694                       ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
2695                       SpdySessionKey::IsProxySession::kFalse, SocketTag(),
2696                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
2697   EXPECT_TRUE(helper.session()->spdy_session_pool()->FindAvailableSession(
2698       key1, true /* enable_ip_based_pooling */, false /* is_websocket */,
2699       NetLogWithSource()));
2700 
2701   // The second request uses a second connection.
2702   SpdyTestUtil spdy_util2;
2703   spdy::SpdySerializedFrame req2(
2704       spdy_util2.ConstructSpdyGet("https://example.test", 1, LOWEST));
2705   MockWrite writes2[] = {
2706       CreateMockWrite(req2, 0),
2707   };
2708 
2709   spdy::SpdySerializedFrame resp2(
2710       spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
2711   spdy::SpdySerializedFrame body2(spdy_util2.ConstructSpdyDataFrame(1, true));
2712   MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
2713                        MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
2714 
2715   MockConnect connect2(ASYNC, OK);
2716   SequencedSocketData data2(connect2, reads2, writes2);
2717   helper.AddData(&data2);
2718 
2719   HttpRequestInfo request2;
2720   request2.method = "GET";
2721   request2.url = GURL("https://example.test/");
2722   request2.load_flags = 0;
2723   request2.traffic_annotation =
2724       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2725   auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
2726                                                          helper.session());
2727 
2728   // Set on-demand mode and run the second request to the DNS lookup.
2729   helper.session_deps()->host_resolver->set_ondemand_mode(true);
2730   TestCompletionCallback callback;
2731   EXPECT_THAT(trans2->Start(&request2, callback.callback(), NetLogWithSource()),
2732               IsError(ERR_IO_PENDING));
2733   base::RunLoop().RunUntilIdle();
2734   ASSERT_TRUE(helper.session_deps()->host_resolver->has_pending_requests());
2735 
2736   // Resolve the request now, which should create an alias for the SpdySession
2737   // immediately, but the task to use the session for the second request should
2738   // run asynchronously, so it hasn't run yet.
2739   helper.session_deps()->host_resolver->ResolveOnlyRequestNow();
2740   SpdySessionKey key2(HostPortPair("example.test", 443), ProxyServer::Direct(),
2741                       PRIVACY_MODE_DISABLED,
2742                       SpdySessionKey::IsProxySession::kFalse, SocketTag(),
2743                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
2744   base::WeakPtr<SpdySession> session1 =
2745       helper.session()->spdy_session_pool()->FindAvailableSession(
2746           key2, true /* enable_ip_based_pooling */, false /* is_websocket */,
2747           NetLogWithSource());
2748   ASSERT_TRUE(session1);
2749   EXPECT_EQ(key1, session1->spdy_session_key());
2750   // Remove the session before the second request can try to use it.
2751   helper.session()->spdy_session_pool()->CloseAllSessions();
2752 
2753   // Wait for the second request to get headers.  It should create a new H2
2754   // session to do so.
2755   EXPECT_THAT(callback.WaitForResult(), IsOk());
2756 
2757   const HttpResponseInfo* response = trans2->GetResponseInfo();
2758   ASSERT_TRUE(response);
2759   ASSERT_TRUE(response->headers);
2760   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
2761   EXPECT_TRUE(response->was_fetched_via_spdy);
2762   EXPECT_TRUE(response->was_alpn_negotiated);
2763   std::string response_data;
2764   ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
2765   EXPECT_EQ("hello!", response_data);
2766 
2767   // Inspect the new session.
2768   base::WeakPtr<SpdySession> session2 =
2769       helper.session()->spdy_session_pool()->FindAvailableSession(
2770           key2, true /* enable_ip_based_pooling */, false /* is_websocket */,
2771           NetLogWithSource());
2772   ASSERT_TRUE(session2);
2773   EXPECT_EQ(key2, session2->spdy_session_key());
2774   helper.VerifyDataConsumed();
2775 }
2776 
2777 #if BUILDFLAG(IS_ANDROID)
2778 
2779 // Test this if two HttpNetworkTransactions try to repurpose the same
2780 // SpdySession with two different SocketTags, only one request gets the session,
2781 // while the other makes a new SPDY session.
TEST_F(SpdyNetworkTransactionTest,ConnectionPoolingMultipleSocketTags)2782 TEST_F(SpdyNetworkTransactionTest, ConnectionPoolingMultipleSocketTags) {
2783   const SocketTag kSocketTag1(SocketTag::UNSET_UID, 1);
2784   const SocketTag kSocketTag2(SocketTag::UNSET_UID, 2);
2785   const SocketTag kSocketTag3(SocketTag::UNSET_UID, 3);
2786 
2787   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
2788 
2789   // The first and third requests use the first connection.
2790   spdy::SpdySerializedFrame req1(
2791       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
2792   spdy_util_.UpdateWithStreamDestruction(1);
2793   spdy::SpdySerializedFrame req3(
2794       spdy_util_.ConstructSpdyGet("https://example.test/request3", 3, LOWEST));
2795   MockWrite writes1[] = {
2796       CreateMockWrite(req1, 0),
2797       CreateMockWrite(req3, 3),
2798   };
2799 
2800   spdy::SpdySerializedFrame resp1(
2801       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
2802   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
2803   spdy::SpdySerializedFrame resp3(
2804       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
2805   spdy::SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(3, true));
2806   MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
2807                        CreateMockRead(resp3, 4), CreateMockRead(body3, 5),
2808                        MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6)};
2809 
2810   SequencedSocketData data1(MockConnect(ASYNC, OK), reads1, writes1);
2811   helper.AddData(&data1);
2812 
2813   // Due to the vagaries of how the socket pools work, in this particular case,
2814   // the second ConnectJob will be cancelled, but only after it tries to start
2815   // connecting. This does not happen in the general case of a bunch of requests
2816   // using the same socket tag.
2817   SequencedSocketData data2(MockConnect(SYNCHRONOUS, ERR_IO_PENDING),
2818                             base::span<const MockRead>(),
2819                             base::span<const MockWrite>());
2820   helper.AddData(&data2);
2821 
2822   // The second request uses a second connection.
2823   SpdyTestUtil spdy_util2;
2824   spdy::SpdySerializedFrame req2(
2825       spdy_util2.ConstructSpdyGet("https://example.test/request2", 1, LOWEST));
2826   MockWrite writes2[] = {
2827       CreateMockWrite(req2, 0),
2828   };
2829 
2830   spdy::SpdySerializedFrame resp2(
2831       spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
2832   spdy::SpdySerializedFrame body2(spdy_util2.ConstructSpdyDataFrame(1, true));
2833   MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
2834                        MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
2835 
2836   SequencedSocketData data3(MockConnect(ASYNC, OK), reads2, writes2);
2837   helper.AddData(&data3);
2838 
2839   // Run a transaction to completion to set up a SPDY session. This can't use
2840   // RunToCompletion(), since it can't call VerifyDataConsumed() yet.
2841   helper.RunPreTestSetup();
2842   helper.RunDefaultTest();
2843   TransactionHelperResult out = helper.output();
2844   EXPECT_THAT(out.rv, IsOk());
2845   EXPECT_EQ("HTTP/1.1 200", out.status_line);
2846   EXPECT_EQ("hello!", out.response_data);
2847 
2848   // A new SPDY session should have been created.
2849   SpdySessionKey key1(HostPortPair("www.example.org", 443),
2850                       ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
2851                       SpdySessionKey::IsProxySession::kFalse, SocketTag(),
2852                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
2853   EXPECT_TRUE(helper.session()->spdy_session_pool()->FindAvailableSession(
2854       key1, true /* enable_ip_based_pooling */, false /* is_websocket */,
2855       NetLogWithSource()));
2856 
2857   // Set on-demand mode for the next two requests.
2858   helper.session_deps()->host_resolver->set_ondemand_mode(true);
2859 
2860   HttpRequestInfo request2;
2861   request2.socket_tag = kSocketTag2;
2862   request2.method = "GET";
2863   request2.url = GURL("https://example.test/request2");
2864   request2.load_flags = 0;
2865   request2.traffic_annotation =
2866       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2867   auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
2868                                                          helper.session());
2869   TestCompletionCallback callback2;
2870   EXPECT_THAT(
2871       trans2->Start(&request2, callback2.callback(), NetLogWithSource()),
2872       IsError(ERR_IO_PENDING));
2873 
2874   HttpRequestInfo request3;
2875   request3.socket_tag = kSocketTag3;
2876   request3.method = "GET";
2877   request3.url = GURL("https://example.test/request3");
2878   request3.load_flags = 0;
2879   request3.traffic_annotation =
2880       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2881   auto trans3 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
2882                                                          helper.session());
2883   TestCompletionCallback callback3;
2884   EXPECT_THAT(
2885       trans3->Start(&request3, callback3.callback(), NetLogWithSource()),
2886       IsError(ERR_IO_PENDING));
2887 
2888   // Run the message loop until both requests are waiting on the host resolver.
2889   base::RunLoop().RunUntilIdle();
2890   ASSERT_TRUE(helper.session_deps()->host_resolver->has_pending_requests());
2891 
2892   // Complete the second requests's DNS lookup now, which should create an alias
2893   // for the SpdySession immediately, but the task to use the session for the
2894   // second request should run asynchronously, so it hasn't run yet.
2895   helper.session_deps()->host_resolver->ResolveNow(2);
2896   SpdySessionKey key2(HostPortPair("example.test", 443), ProxyServer::Direct(),
2897                       PRIVACY_MODE_DISABLED,
2898                       SpdySessionKey::IsProxySession::kFalse, kSocketTag2,
2899                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
2900 
2901   // Complete the third requests's DNS lookup now, which should hijack the
2902   // SpdySession from the second request.
2903   helper.session_deps()->host_resolver->ResolveNow(3);
2904   SpdySessionKey key3(HostPortPair("example.test", 443), ProxyServer::Direct(),
2905                       PRIVACY_MODE_DISABLED,
2906                       SpdySessionKey::IsProxySession::kFalse, kSocketTag3,
2907                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
2908 
2909   // Wait for the second request to get headers.  It should create a new H2
2910   // session to do so.
2911   EXPECT_THAT(callback2.WaitForResult(), IsOk());
2912 
2913   const HttpResponseInfo* response = trans2->GetResponseInfo();
2914   ASSERT_TRUE(response);
2915   ASSERT_TRUE(response->headers);
2916   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
2917   EXPECT_TRUE(response->was_fetched_via_spdy);
2918   EXPECT_TRUE(response->was_alpn_negotiated);
2919   std::string response_data;
2920   ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
2921   EXPECT_EQ("hello!", response_data);
2922 
2923   // Wait for the third request to get headers.  It should have reused the first
2924   // session.
2925   EXPECT_THAT(callback3.WaitForResult(), IsOk());
2926 
2927   response = trans3->GetResponseInfo();
2928   ASSERT_TRUE(response);
2929   ASSERT_TRUE(response->headers);
2930   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
2931   EXPECT_TRUE(response->was_fetched_via_spdy);
2932   EXPECT_TRUE(response->was_alpn_negotiated);
2933   ASSERT_THAT(ReadTransaction(trans3.get(), &response_data), IsOk());
2934   EXPECT_EQ("hello!", response_data);
2935 
2936   helper.VerifyDataConsumed();
2937 }
2938 
TEST_F(SpdyNetworkTransactionTest,SocketTagChangeSessionTagWithDnsAliases)2939 TEST_F(SpdyNetworkTransactionTest, SocketTagChangeSessionTagWithDnsAliases) {
2940   SocketTag socket_tag_1(SocketTag::UNSET_UID, 1);
2941   SocketTag socket_tag_2(SocketTag::UNSET_UID, 2);
2942   request_.socket_tag = socket_tag_1;
2943 
2944   std::unique_ptr<SpdySessionDependencies> session_deps =
2945       std::make_unique<SpdySessionDependencies>();
2946   std::unique_ptr<MockCachingHostResolver> host_resolver =
2947       std::make_unique<MockCachingHostResolver>(2 /* cache_invalidation_num */);
2948   session_deps->host_resolver = std::move(host_resolver);
2949 
2950   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
2951                                      std::move(session_deps));
2952 
2953   GURL url = request_.url;
2954   std::set<std::string> dns_aliases({"alias1", "alias2", "alias3"});
2955   helper.session_deps()->host_resolver->rules()->AddIPLiteralRuleWithDnsAliases(
2956       url.host(), "127.0.0.1", dns_aliases);
2957 
2958   spdy::SpdySerializedFrame req1(
2959       spdy_util_.ConstructSpdyGet(url.spec().c_str(), 1, DEFAULT_PRIORITY));
2960   spdy_util_.UpdateWithStreamDestruction(1);
2961   spdy::SpdySerializedFrame req2(
2962       spdy_util_.ConstructSpdyGet(url.spec().c_str(), 3, DEFAULT_PRIORITY));
2963   MockWrite writes[] = {
2964       CreateMockWrite(req1, 0),
2965       CreateMockWrite(req2, 3),
2966   };
2967 
2968   spdy::SpdySerializedFrame resp1(
2969       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
2970   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
2971   spdy::SpdySerializedFrame resp2(
2972       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
2973   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
2974   MockRead reads[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
2975                       CreateMockRead(resp2, 4), CreateMockRead(body2, 5),
2976                       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6)};
2977 
2978   SequencedSocketData data(MockConnect(ASYNC, OK), reads, writes);
2979   helper.AddData(&data);
2980 
2981   // Run a transaction to completion to set up a SPDY session. This can't use
2982   // RunToCompletion(), since it can't call VerifyDataConsumed() yet because
2983   // there are still further requests expected.
2984   helper.RunPreTestSetup();
2985   helper.RunDefaultTest();
2986   TransactionHelperResult out = helper.output();
2987   EXPECT_THAT(out.rv, IsOk());
2988   EXPECT_EQ("HTTP/1.1 200", out.status_line);
2989   EXPECT_EQ("hello!", out.response_data);
2990 
2991   // A new SPDY session should have been created.
2992   EXPECT_EQ(1u, helper.GetSpdySessionCount());
2993   SpdySessionKey key1(HostPortPair(url.host(), 443), ProxyServer::Direct(),
2994                       PRIVACY_MODE_DISABLED,
2995                       SpdySessionKey::IsProxySession::kFalse, socket_tag_1,
2996                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
2997   EXPECT_TRUE(helper.session()->spdy_session_pool()->FindAvailableSession(
2998       key1, true /* enable_ip_based_pooling */, false /* is_websocket */,
2999       NetLogWithSource()));
3000   EXPECT_EQ(
3001       dns_aliases,
3002       helper.session()->spdy_session_pool()->GetDnsAliasesForSessionKey(key1));
3003 
3004   // Clear host resolver rules to ensure that cached values for DNS aliases
3005   // are used.
3006   helper.session_deps()->host_resolver->rules()->ClearRules();
3007 
3008   HttpRequestInfo request2;
3009   request2.socket_tag = socket_tag_2;
3010   request2.method = "GET";
3011   request2.url = url;
3012   request2.load_flags = 0;
3013   request2.traffic_annotation =
3014       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3015   SpdySessionKey key2(HostPortPair(url.host(), 443), ProxyServer::Direct(),
3016                       PRIVACY_MODE_DISABLED,
3017                       SpdySessionKey::IsProxySession::kFalse, socket_tag_2,
3018                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
3019   auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
3020                                                          helper.session());
3021   TestCompletionCallback callback2;
3022   EXPECT_THAT(
3023       trans2->Start(&request2, callback2.callback(), NetLogWithSource()),
3024       IsError(ERR_IO_PENDING));
3025 
3026   // Wait for the second request to get headers.  It should have reused the
3027   // first session but changed the tag.
3028   EXPECT_THAT(callback2.WaitForResult(), IsOk());
3029 
3030   EXPECT_EQ(1u, helper.GetSpdySessionCount());
3031   EXPECT_FALSE(helper.session()->spdy_session_pool()->FindAvailableSession(
3032       key1, true /* enable_ip_based_pooling */, false /* is_websocket */,
3033       NetLogWithSource()));
3034   EXPECT_TRUE(helper.session()
3035                   ->spdy_session_pool()
3036                   ->GetDnsAliasesForSessionKey(key1)
3037                   .empty());
3038   EXPECT_TRUE(helper.session()->spdy_session_pool()->FindAvailableSession(
3039       key2, true /* enable_ip_based_pooling */, false /* is_websocket */,
3040       NetLogWithSource()));
3041   EXPECT_EQ(
3042       dns_aliases,
3043       helper.session()->spdy_session_pool()->GetDnsAliasesForSessionKey(key2));
3044 
3045   const HttpResponseInfo* response = trans2->GetResponseInfo();
3046   ASSERT_TRUE(response);
3047   ASSERT_TRUE(response->headers);
3048   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
3049   EXPECT_TRUE(response->was_fetched_via_spdy);
3050   EXPECT_TRUE(response->was_alpn_negotiated);
3051   std::string response_data;
3052   ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
3053   EXPECT_EQ("hello!", response_data);
3054 
3055   helper.VerifyDataConsumed();
3056 }
3057 
TEST_F(SpdyNetworkTransactionTest,SocketTagChangeFromIPAliasedSessionWithDnsAliases)3058 TEST_F(SpdyNetworkTransactionTest,
3059        SocketTagChangeFromIPAliasedSessionWithDnsAliases) {
3060   SocketTag socket_tag_1(SocketTag::UNSET_UID, 1);
3061   SocketTag socket_tag_2(SocketTag::UNSET_UID, 2);
3062   request_.socket_tag = socket_tag_1;
3063 
3064   std::unique_ptr<SpdySessionDependencies> session_deps =
3065       std::make_unique<SpdySessionDependencies>();
3066   std::unique_ptr<MockCachingHostResolver> host_resolver =
3067       std::make_unique<MockCachingHostResolver>(2 /* cache_invalidation_num */);
3068   session_deps->host_resolver = std::move(host_resolver);
3069 
3070   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
3071                                      std::move(session_deps));
3072   GURL url1 = request_.url;
3073   std::set<std::string> dns_aliases1({"alias1", "alias2", "alias3"});
3074   GURL url2("https://example.test/");
3075   std::set<std::string> dns_aliases2({"example.net", "example.com"});
3076 
3077   helper.session_deps()->host_resolver->rules()->AddIPLiteralRuleWithDnsAliases(
3078       url1.host(), "127.0.0.1", dns_aliases1);
3079   helper.session_deps()->host_resolver->rules()->AddIPLiteralRuleWithDnsAliases(
3080       url2.host(), "127.0.0.1", dns_aliases2);
3081 
3082   spdy::SpdySerializedFrame req1(
3083       spdy_util_.ConstructSpdyGet(url1.spec().c_str(), 1, DEFAULT_PRIORITY));
3084   spdy_util_.UpdateWithStreamDestruction(1);
3085   spdy::SpdySerializedFrame req2(
3086       spdy_util_.ConstructSpdyGet(url2.spec().c_str(), 3, DEFAULT_PRIORITY));
3087   spdy_util_.UpdateWithStreamDestruction(3);
3088   spdy::SpdySerializedFrame req3(
3089       spdy_util_.ConstructSpdyGet(url2.spec().c_str(), 5, DEFAULT_PRIORITY));
3090   spdy_util_.UpdateWithStreamDestruction(5);
3091   spdy::SpdySerializedFrame req4(
3092       spdy_util_.ConstructSpdyGet(url1.spec().c_str(), 7, DEFAULT_PRIORITY));
3093   MockWrite writes[] = {
3094       CreateMockWrite(req1, 0),
3095       CreateMockWrite(req2, 3),
3096       CreateMockWrite(req3, 6),
3097       CreateMockWrite(req4, 9),
3098   };
3099 
3100   spdy::SpdySerializedFrame resp1(
3101       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
3102   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
3103   spdy::SpdySerializedFrame resp2(
3104       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
3105   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
3106   spdy::SpdySerializedFrame resp3(
3107       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 5));
3108   spdy::SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(5, true));
3109   spdy::SpdySerializedFrame resp4(
3110       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 7));
3111   spdy::SpdySerializedFrame body4(spdy_util_.ConstructSpdyDataFrame(7, true));
3112   MockRead reads[] = {CreateMockRead(resp1, 1),
3113                       CreateMockRead(body1, 2),
3114                       CreateMockRead(resp2, 4),
3115                       CreateMockRead(body2, 5),
3116                       CreateMockRead(resp3, 7),
3117                       CreateMockRead(body3, 8),
3118                       CreateMockRead(resp4, 10),
3119                       CreateMockRead(body4, 11),
3120                       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 12)};
3121 
3122   SequencedSocketData data(MockConnect(ASYNC, OK), reads, writes);
3123   helper.AddData(&data);
3124 
3125   // Run a transaction to completion to set up a SPDY session. This can't use
3126   // RunToCompletion(), since it can't call VerifyDataConsumed() yet.
3127   helper.RunPreTestSetup();
3128   helper.RunDefaultTest();
3129   TransactionHelperResult out = helper.output();
3130   EXPECT_THAT(out.rv, IsOk());
3131   EXPECT_EQ("HTTP/1.1 200", out.status_line);
3132   EXPECT_EQ("hello!", out.response_data);
3133 
3134   // A new SPDY session should have been created.
3135   EXPECT_EQ(1u, helper.GetSpdySessionCount());
3136   SpdySessionKey key1(HostPortPair(url1.host(), 443), ProxyServer::Direct(),
3137                       PRIVACY_MODE_DISABLED,
3138                       SpdySessionKey::IsProxySession::kFalse, socket_tag_1,
3139                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
3140   EXPECT_TRUE(helper.session()->spdy_session_pool()->FindAvailableSession(
3141       key1, true /* enable_ip_based_pooling */, false /* is_websocket */,
3142       NetLogWithSource()));
3143   EXPECT_EQ(
3144       dns_aliases1,
3145       helper.session()->spdy_session_pool()->GetDnsAliasesForSessionKey(key1));
3146 
3147   HttpRequestInfo request2;
3148   request2.socket_tag = socket_tag_1;
3149   request2.method = "GET";
3150   request2.url = url2;
3151   request2.load_flags = 0;
3152   request2.traffic_annotation =
3153       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3154   SpdySessionKey key2(HostPortPair(url2.host(), 443), ProxyServer::Direct(),
3155                       PRIVACY_MODE_DISABLED,
3156                       SpdySessionKey::IsProxySession::kFalse, socket_tag_1,
3157                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
3158   auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
3159                                                          helper.session());
3160   TestCompletionCallback callback2;
3161   EXPECT_THAT(
3162       trans2->Start(&request2, callback2.callback(), NetLogWithSource()),
3163       IsError(ERR_IO_PENDING));
3164 
3165   // Wait for the second request to get headers.  It should have reused the
3166   // first session.
3167   EXPECT_THAT(callback2.WaitForResult(), IsOk());
3168 
3169   EXPECT_EQ(1u, helper.GetSpdySessionCount());
3170   EXPECT_TRUE(helper.session()->spdy_session_pool()->FindAvailableSession(
3171       key2, true /* enable_ip_based_pooling */, false /* is_websocket */,
3172       NetLogWithSource()));
3173   EXPECT_EQ(
3174       dns_aliases2,
3175       helper.session()->spdy_session_pool()->GetDnsAliasesForSessionKey(key2));
3176 
3177   const HttpResponseInfo* response = trans2->GetResponseInfo();
3178   ASSERT_TRUE(response);
3179   ASSERT_TRUE(response->headers);
3180   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
3181   EXPECT_TRUE(response->was_fetched_via_spdy);
3182   EXPECT_TRUE(response->was_alpn_negotiated);
3183   std::string response_data;
3184   ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
3185   EXPECT_EQ("hello!", response_data);
3186 
3187   // Clear host resolver rules to ensure that cached values for DNS aliases
3188   // are used.
3189   helper.session_deps()->host_resolver->rules()->ClearRules();
3190   trans2.reset();
3191 
3192   HttpRequestInfo request3;
3193   request3.socket_tag = socket_tag_2;
3194   request3.method = "GET";
3195   request3.url = url2;
3196   request3.load_flags = 0;
3197   request3.traffic_annotation =
3198       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3199   SpdySessionKey key3(HostPortPair(url2.host(), 443), ProxyServer::Direct(),
3200                       PRIVACY_MODE_DISABLED,
3201                       SpdySessionKey::IsProxySession::kFalse, socket_tag_2,
3202                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
3203   auto trans3 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
3204                                                          helper.session());
3205   TestCompletionCallback callback3;
3206   EXPECT_THAT(
3207       trans3->Start(&request3, callback3.callback(), NetLogWithSource()),
3208       IsError(ERR_IO_PENDING));
3209 
3210   // Wait for the third request to get headers.  It should have reused the
3211   // first session but changed the socket tag.
3212   EXPECT_THAT(callback3.WaitForResult(), IsOk());
3213 
3214   EXPECT_EQ(1u, helper.GetSpdySessionCount());
3215   EXPECT_FALSE(helper.session()->spdy_session_pool()->FindAvailableSession(
3216       key2, true /* enable_ip_based_pooling */, false /* is_websocket */,
3217       NetLogWithSource()));
3218   EXPECT_TRUE(helper.session()
3219                   ->spdy_session_pool()
3220                   ->GetDnsAliasesForSessionKey(key2)
3221                   .empty());
3222   EXPECT_TRUE(helper.session()->spdy_session_pool()->FindAvailableSession(
3223       key3, true /* enable_ip_based_pooling */, false /* is_websocket */,
3224       NetLogWithSource()));
3225   EXPECT_EQ(
3226       dns_aliases2,
3227       helper.session()->spdy_session_pool()->GetDnsAliasesForSessionKey(key3));
3228 
3229   response = trans3->GetResponseInfo();
3230   ASSERT_TRUE(response);
3231   ASSERT_TRUE(response->headers);
3232   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
3233   EXPECT_TRUE(response->was_fetched_via_spdy);
3234   EXPECT_TRUE(response->was_alpn_negotiated);
3235   ASSERT_THAT(ReadTransaction(trans3.get(), &response_data), IsOk());
3236   EXPECT_EQ("hello!", response_data);
3237 
3238   trans3.reset();
3239 
3240   HttpRequestInfo request4;
3241   request4.socket_tag = socket_tag_2;
3242   request4.method = "GET";
3243   request4.url = url1;
3244   request4.load_flags = 0;
3245   request4.traffic_annotation =
3246       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3247   SpdySessionKey key4(HostPortPair(url1.host(), 443), ProxyServer::Direct(),
3248                       PRIVACY_MODE_DISABLED,
3249                       SpdySessionKey::IsProxySession::kFalse, socket_tag_2,
3250                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
3251   auto trans4 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
3252                                                          helper.session());
3253   TestCompletionCallback callback4;
3254   EXPECT_THAT(
3255       trans4->Start(&request4, callback4.callback(), NetLogWithSource()),
3256       IsError(ERR_IO_PENDING));
3257 
3258   // Wait for the third request to get headers.  It should have reused the
3259   // first session but changed the socket tag.
3260   EXPECT_THAT(callback4.WaitForResult(), IsOk());
3261 
3262   EXPECT_EQ(1u, helper.GetSpdySessionCount());
3263   EXPECT_FALSE(helper.session()->spdy_session_pool()->FindAvailableSession(
3264       key1, true /* enable_ip_based_pooling */, false /* is_websocket */,
3265       NetLogWithSource()));
3266   EXPECT_TRUE(helper.session()
3267                   ->spdy_session_pool()
3268                   ->GetDnsAliasesForSessionKey(key1)
3269                   .empty());
3270   EXPECT_TRUE(helper.session()->spdy_session_pool()->FindAvailableSession(
3271       key4, true /* enable_ip_based_pooling */, false /* is_websocket */,
3272       NetLogWithSource()));
3273   EXPECT_EQ(
3274       dns_aliases1,
3275       helper.session()->spdy_session_pool()->GetDnsAliasesForSessionKey(key4));
3276 
3277   response = trans4->GetResponseInfo();
3278   ASSERT_TRUE(response);
3279   ASSERT_TRUE(response->headers);
3280   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
3281   EXPECT_TRUE(response->was_fetched_via_spdy);
3282   EXPECT_TRUE(response->was_alpn_negotiated);
3283   ASSERT_THAT(ReadTransaction(trans4.get(), &response_data), IsOk());
3284   EXPECT_EQ("hello!", response_data);
3285 
3286   helper.VerifyDataConsumed();
3287 }
3288 
3289 #endif  // BUILDFLAG(IS_ANDROID)
3290 
3291 // Verify that various response headers parse correctly through the HTTP layer.
TEST_F(SpdyNetworkTransactionTest,ResponseHeaders)3292 TEST_F(SpdyNetworkTransactionTest, ResponseHeaders) {
3293   struct ResponseHeadersTests {
3294     int extra_header_count;
3295     const char* extra_headers[4];
3296     size_t expected_header_count;
3297     base::StringPiece expected_headers[8];
3298   } test_cases[] = {
3299       // No extra headers.
3300       {0, {}, 1, {"hello", "bye"}},
3301       // Comma-separated header value.
3302       {1,
3303        {"cookie", "val1, val2"},
3304        2,
3305        {"hello", "bye", "cookie", "val1, val2"}},
3306       // Multiple headers are preserved: they are joined with \0 separator in
3307       // spdy::Http2HeaderBlock.AppendValueOrAddHeader(), then split up in
3308       // HpackEncoder, then joined with \0 separator when
3309       // spdy::HpackDecoderAdapter::ListenerAdapter::OnHeader() calls
3310       // spdy::Http2HeaderBlock.AppendValueOrAddHeader(), then split up again in
3311       // HttpResponseHeaders.
3312       {2,
3313        {"content-encoding", "val1", "content-encoding", "val2"},
3314        3,
3315        {"hello", "bye", "content-encoding", "val1", "content-encoding",
3316         "val2"}},
3317       // Cookie header is not split up by HttpResponseHeaders.
3318       {2,
3319        {"cookie", "val1", "cookie", "val2"},
3320        2,
3321        {"hello", "bye", "cookie", "val1; val2"}}};
3322 
3323   for (size_t i = 0; i < std::size(test_cases); ++i) {
3324     SCOPED_TRACE(i);
3325     SpdyTestUtil spdy_test_util;
3326     spdy::SpdySerializedFrame req(
3327         spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
3328     MockWrite writes[] = {CreateMockWrite(req, 0)};
3329 
3330     spdy::SpdySerializedFrame resp(spdy_test_util.ConstructSpdyGetReply(
3331         test_cases[i].extra_headers, test_cases[i].extra_header_count, 1));
3332     spdy::SpdySerializedFrame body(
3333         spdy_test_util.ConstructSpdyDataFrame(1, true));
3334     MockRead reads[] = {
3335         CreateMockRead(resp, 1), CreateMockRead(body, 2),
3336         MockRead(ASYNC, 0, 3)  // EOF
3337     };
3338 
3339     SequencedSocketData data(reads, writes);
3340     NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
3341                                        nullptr);
3342     helper.RunToCompletion(&data);
3343     TransactionHelperResult out = helper.output();
3344 
3345     EXPECT_THAT(out.rv, IsOk());
3346     EXPECT_EQ("HTTP/1.1 200", out.status_line);
3347     EXPECT_EQ("hello!", out.response_data);
3348 
3349     scoped_refptr<HttpResponseHeaders> headers = out.response_info.headers;
3350     ASSERT_TRUE(headers);
3351     EXPECT_EQ("HTTP/1.1 200", headers->GetStatusLine());
3352     size_t iter = 0;
3353     std::string name, value;
3354     size_t expected_header_index = 0;
3355     while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
3356       ASSERT_LT(expected_header_index, test_cases[i].expected_header_count);
3357       EXPECT_EQ(name,
3358                 test_cases[i].expected_headers[2 * expected_header_index]);
3359       EXPECT_EQ(value,
3360                 test_cases[i].expected_headers[2 * expected_header_index + 1]);
3361       ++expected_header_index;
3362     }
3363     EXPECT_EQ(expected_header_index, test_cases[i].expected_header_count);
3364   }
3365 }
3366 
3367 // Verify that we don't crash on invalid response headers.
TEST_F(SpdyNetworkTransactionTest,InvalidResponseHeaders)3368 TEST_F(SpdyNetworkTransactionTest, InvalidResponseHeaders) {
3369   struct InvalidResponseHeadersTests {
3370     int num_headers;
3371     const char* headers[10];
3372   } test_cases[] = {// Response headers missing status header
3373                     {2, {"cookie", "val1", "cookie", "val2", nullptr}},
3374                     // Response headers with no headers
3375                     {0, {nullptr}}};
3376 
3377   for (size_t i = 0; i < std::size(test_cases); ++i) {
3378     SCOPED_TRACE(i);
3379     SpdyTestUtil spdy_test_util;
3380 
3381     spdy::SpdySerializedFrame req(
3382         spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
3383     spdy::SpdySerializedFrame rst(spdy_test_util.ConstructSpdyRstStream(
3384         1, spdy::ERROR_CODE_PROTOCOL_ERROR));
3385     MockWrite writes[] = {
3386         CreateMockWrite(req, 0),
3387         CreateMockWrite(rst, 2),
3388     };
3389 
3390     // Construct the reply.
3391     spdy::Http2HeaderBlock reply_headers;
3392     AppendToHeaderBlock(test_cases[i].headers, test_cases[i].num_headers,
3393                         &reply_headers);
3394     spdy::SpdySerializedFrame resp(
3395         spdy_test_util.ConstructSpdyReply(1, std::move(reply_headers)));
3396     MockRead reads[] = {
3397         CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3)  // EOF
3398     };
3399 
3400     SequencedSocketData data(reads, writes);
3401     NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
3402                                        nullptr);
3403     helper.RunToCompletion(&data);
3404     TransactionHelperResult out = helper.output();
3405     EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
3406   }
3407 }
3408 
TEST_F(SpdyNetworkTransactionTest,CorruptFrameSessionError)3409 TEST_F(SpdyNetworkTransactionTest, CorruptFrameSessionError) {
3410   spdy::SpdySerializedFrame req(
3411       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
3412   spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
3413       0, spdy::ERROR_CODE_COMPRESSION_ERROR,
3414       "Framer error: 24 (HPACK_TRUNCATED_BLOCK)."));
3415   MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(goaway, 2)};
3416 
3417   // This is the length field that's too short.
3418   spdy::SpdySerializedFrame reply_wrong_length(
3419       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
3420   size_t right_size = reply_wrong_length.size() - spdy::kFrameHeaderSize;
3421   size_t wrong_size = right_size - 4;
3422   spdy::test::SetFrameLength(&reply_wrong_length, wrong_size);
3423 
3424   MockRead reads[] = {
3425       MockRead(ASYNC, reply_wrong_length.data(), reply_wrong_length.size() - 4,
3426                1),
3427   };
3428 
3429   SequencedSocketData data(reads, writes);
3430   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
3431   helper.RunToCompletion(&data);
3432   TransactionHelperResult out = helper.output();
3433   EXPECT_THAT(out.rv, IsError(ERR_HTTP2_COMPRESSION_ERROR));
3434 }
3435 
TEST_F(SpdyNetworkTransactionTest,GoAwayOnDecompressionFailure)3436 TEST_F(SpdyNetworkTransactionTest, GoAwayOnDecompressionFailure) {
3437   spdy::SpdySerializedFrame req(
3438       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
3439   spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
3440       0, spdy::ERROR_CODE_COMPRESSION_ERROR,
3441       "Framer error: 24 (HPACK_TRUNCATED_BLOCK)."));
3442   MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(goaway, 2)};
3443 
3444   // Read HEADERS with corrupted payload.
3445   spdy::SpdySerializedFrame resp(
3446       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
3447   memset(resp.data() + 12, 0xcf, resp.size() - 12);
3448   MockRead reads[] = {CreateMockRead(resp, 1)};
3449 
3450   SequencedSocketData data(reads, writes);
3451   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
3452   helper.RunToCompletion(&data);
3453   TransactionHelperResult out = helper.output();
3454   EXPECT_THAT(out.rv, IsError(ERR_HTTP2_COMPRESSION_ERROR));
3455 }
3456 
TEST_F(SpdyNetworkTransactionTest,GoAwayOnFrameSizeError)3457 TEST_F(SpdyNetworkTransactionTest, GoAwayOnFrameSizeError) {
3458   spdy::SpdySerializedFrame req(
3459       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
3460   spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
3461       0, spdy::ERROR_CODE_FRAME_SIZE_ERROR,
3462       "Framer error: 9 (INVALID_CONTROL_FRAME_SIZE)."));
3463   MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(goaway, 2)};
3464 
3465   // Read WINDOW_UPDATE with incorrectly-sized payload.
3466   spdy::SpdySerializedFrame bad_window_update(
3467       spdy_util_.ConstructSpdyWindowUpdate(1, 1));
3468   spdy::test::SetFrameLength(&bad_window_update, bad_window_update.size() - 1);
3469   MockRead reads[] = {CreateMockRead(bad_window_update, 1)};
3470 
3471   SequencedSocketData data(reads, writes);
3472   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
3473   helper.RunToCompletion(&data);
3474   TransactionHelperResult out = helper.output();
3475   EXPECT_THAT(out.rv, IsError(ERR_HTTP2_FRAME_SIZE_ERROR));
3476 }
3477 
3478 // Test that we shutdown correctly on write errors.
TEST_F(SpdyNetworkTransactionTest,WriteError)3479 TEST_F(SpdyNetworkTransactionTest, WriteError) {
3480   spdy::SpdySerializedFrame req(
3481       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
3482   MockWrite writes[] = {
3483       // We'll write 10 bytes successfully
3484       MockWrite(ASYNC, req.data(), 10, 1),
3485       // Followed by ERROR!
3486       MockWrite(ASYNC, ERR_FAILED, 2),
3487       // Session drains and attempts to write a GOAWAY: Another ERROR!
3488       MockWrite(ASYNC, ERR_FAILED, 3),
3489   };
3490 
3491   MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
3492 
3493   SequencedSocketData data(reads, writes);
3494 
3495   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
3496   helper.RunPreTestSetup();
3497   helper.AddData(&data);
3498   EXPECT_TRUE(helper.StartDefaultTest());
3499   helper.FinishDefaultTest();
3500   EXPECT_TRUE(data.AllWriteDataConsumed());
3501   EXPECT_TRUE(data.AllReadDataConsumed());
3502   TransactionHelperResult out = helper.output();
3503   EXPECT_THAT(out.rv, IsError(ERR_FAILED));
3504 }
3505 
3506 // Test that partial writes work.
TEST_F(SpdyNetworkTransactionTest,PartialWrite)3507 TEST_F(SpdyNetworkTransactionTest, PartialWrite) {
3508   // Chop the HEADERS frame into 5 chunks.
3509   spdy::SpdySerializedFrame req(
3510       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
3511   const size_t kChunks = 5u;
3512   std::unique_ptr<MockWrite[]> writes = ChopWriteFrame(req, kChunks);
3513   for (size_t i = 0; i < kChunks; ++i) {
3514     writes[i].sequence_number = i;
3515   }
3516 
3517   spdy::SpdySerializedFrame resp(
3518       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
3519   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
3520   MockRead reads[] = {
3521       CreateMockRead(resp, kChunks), CreateMockRead(body, kChunks + 1),
3522       MockRead(ASYNC, 0, kChunks + 2)  // EOF
3523   };
3524 
3525   SequencedSocketData data(reads, base::make_span(writes.get(), kChunks));
3526   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
3527   helper.RunToCompletion(&data);
3528   TransactionHelperResult out = helper.output();
3529   EXPECT_THAT(out.rv, IsOk());
3530   EXPECT_EQ("HTTP/1.1 200", out.status_line);
3531   EXPECT_EQ("hello!", out.response_data);
3532 }
3533 
3534 // Test that the NetLog contains good data for a simple GET request.
TEST_F(SpdyNetworkTransactionTest,NetLog)3535 TEST_F(SpdyNetworkTransactionTest, NetLog) {
3536   static const char* const kExtraHeaders[] = {
3537       "user-agent",
3538       "Chrome",
3539   };
3540   spdy::SpdySerializedFrame req(
3541       spdy_util_.ConstructSpdyGet(kExtraHeaders, 1, 1, LOWEST));
3542   MockWrite writes[] = {CreateMockWrite(req, 0)};
3543 
3544   spdy::SpdySerializedFrame resp(
3545       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
3546   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
3547   MockRead reads[] = {
3548       CreateMockRead(resp, 1), CreateMockRead(body, 2),
3549       MockRead(ASYNC, 0, 3)  // EOF
3550   };
3551 
3552   RecordingNetLogObserver net_log_observer;
3553 
3554   SequencedSocketData data(reads, writes);
3555   request_.extra_headers.SetHeader("User-Agent", "Chrome");
3556   NormalSpdyTransactionHelper helper(
3557       request_, DEFAULT_PRIORITY,
3558       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
3559   helper.RunToCompletion(&data);
3560   TransactionHelperResult out = helper.output();
3561   EXPECT_THAT(out.rv, IsOk());
3562   EXPECT_EQ("HTTP/1.1 200", out.status_line);
3563   EXPECT_EQ("hello!", out.response_data);
3564 
3565   // Check that the NetLog was filled reasonably.
3566   // This test is intentionally non-specific about the exact ordering of the
3567   // log; instead we just check to make sure that certain events exist, and that
3568   // they are in the right order.
3569   auto entries = net_log_observer.GetEntries();
3570 
3571   EXPECT_LT(0u, entries.size());
3572   int pos = 0;
3573   pos = ExpectLogContainsSomewhere(
3574       entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST,
3575       NetLogEventPhase::BEGIN);
3576   pos = ExpectLogContainsSomewhere(
3577       entries, pos + 1, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST,
3578       NetLogEventPhase::END);
3579   pos = ExpectLogContainsSomewhere(
3580       entries, pos + 1, NetLogEventType::HTTP_TRANSACTION_READ_HEADERS,
3581       NetLogEventPhase::BEGIN);
3582   pos = ExpectLogContainsSomewhere(
3583       entries, pos + 1, NetLogEventType::HTTP_TRANSACTION_READ_HEADERS,
3584       NetLogEventPhase::END);
3585   pos = ExpectLogContainsSomewhere(entries, pos + 1,
3586                                    NetLogEventType::HTTP_TRANSACTION_READ_BODY,
3587                                    NetLogEventPhase::BEGIN);
3588   pos = ExpectLogContainsSomewhere(entries, pos + 1,
3589                                    NetLogEventType::HTTP_TRANSACTION_READ_BODY,
3590                                    NetLogEventPhase::END);
3591 
3592   // Check that we logged all the headers correctly
3593   pos = ExpectLogContainsSomewhere(entries, 0,
3594                                    NetLogEventType::HTTP2_SESSION_SEND_HEADERS,
3595                                    NetLogEventPhase::NONE);
3596 
3597   ASSERT_TRUE(entries[pos].HasParams());
3598   auto* header_list = entries[pos].params.FindList("headers");
3599   ASSERT_TRUE(header_list);
3600   ASSERT_EQ(5u, header_list->size());
3601 
3602   ASSERT_TRUE((*header_list)[0].is_string());
3603   EXPECT_EQ(":method: GET", (*header_list)[0].GetString());
3604 
3605   ASSERT_TRUE((*header_list)[1].is_string());
3606   EXPECT_EQ(":authority: www.example.org", (*header_list)[1].GetString());
3607 
3608   ASSERT_TRUE((*header_list)[2].is_string());
3609   EXPECT_EQ(":scheme: https", (*header_list)[2].GetString());
3610 
3611   ASSERT_TRUE((*header_list)[3].is_string());
3612   EXPECT_EQ(":path: /", (*header_list)[3].GetString());
3613 
3614   ASSERT_TRUE((*header_list)[4].is_string());
3615   EXPECT_EQ("user-agent: Chrome", (*header_list)[4].GetString());
3616 }
3617 
3618 // Since we buffer the IO from the stream to the renderer, this test verifies
3619 // that when we read out the maximum amount of data (e.g. we received 50 bytes
3620 // on the network, but issued a Read for only 5 of those bytes) that the data
3621 // flow still works correctly.
TEST_F(SpdyNetworkTransactionTest,BufferFull)3622 TEST_F(SpdyNetworkTransactionTest, BufferFull) {
3623   spdy::SpdySerializedFrame req(
3624       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
3625   MockWrite writes[] = {CreateMockWrite(req, 0)};
3626 
3627   // 2 data frames in a single read.
3628   spdy::SpdySerializedFrame data_frame_1(
3629       spdy_util_.ConstructSpdyDataFrame(1, "goodby", /*fin=*/false));
3630   spdy::SpdySerializedFrame data_frame_2(
3631       spdy_util_.ConstructSpdyDataFrame(1, "e worl", /*fin=*/false));
3632   spdy::SpdySerializedFrame combined_data_frames =
3633       CombineFrames({&data_frame_1, &data_frame_2});
3634 
3635   spdy::SpdySerializedFrame last_frame(
3636       spdy_util_.ConstructSpdyDataFrame(1, "d", /*fin=*/true));
3637 
3638   spdy::SpdySerializedFrame resp(
3639       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
3640   MockRead reads[] = {
3641       CreateMockRead(resp, 1),
3642       MockRead(ASYNC, ERR_IO_PENDING, 2),  // Force a pause
3643       CreateMockRead(combined_data_frames, 3),
3644       MockRead(ASYNC, ERR_IO_PENDING, 4),  // Force a pause
3645       CreateMockRead(last_frame, 5),
3646       MockRead(ASYNC, 0, 6)  // EOF
3647   };
3648 
3649   SequencedSocketData data(reads, writes);
3650 
3651   TestCompletionCallback callback;
3652 
3653   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
3654   helper.RunPreTestSetup();
3655   helper.AddData(&data);
3656   HttpNetworkTransaction* trans = helper.trans();
3657   int rv = trans->Start(&request_, callback.callback(), log_);
3658   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3659 
3660   TransactionHelperResult out = helper.output();
3661   out.rv = callback.WaitForResult();
3662   EXPECT_EQ(out.rv, OK);
3663 
3664   const HttpResponseInfo* response = trans->GetResponseInfo();
3665   EXPECT_TRUE(response->headers);
3666   EXPECT_TRUE(response->was_fetched_via_spdy);
3667   out.status_line = response->headers->GetStatusLine();
3668   out.response_info = *response;  // Make a copy so we can verify.
3669 
3670   // Read Data
3671   TestCompletionCallback read_callback;
3672 
3673   std::string content;
3674   do {
3675     // Read small chunks at a time.
3676     const int kSmallReadSize = 3;
3677     scoped_refptr<IOBuffer> buf =
3678         base::MakeRefCounted<IOBuffer>(kSmallReadSize);
3679     rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback());
3680     if (rv == ERR_IO_PENDING) {
3681       data.Resume();
3682       rv = read_callback.WaitForResult();
3683     }
3684     if (rv > 0) {
3685       content.append(buf->data(), rv);
3686     } else if (rv < 0) {
3687       NOTREACHED();
3688     }
3689   } while (rv > 0);
3690 
3691   out.response_data.swap(content);
3692 
3693   // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
3694   // MockClientSocketFactory) are still alive.
3695   base::RunLoop().RunUntilIdle();
3696 
3697   // Verify that we consumed all test data.
3698   helper.VerifyDataConsumed();
3699 
3700   EXPECT_THAT(out.rv, IsOk());
3701   EXPECT_EQ("HTTP/1.1 200", out.status_line);
3702   EXPECT_EQ("goodbye world", out.response_data);
3703 }
3704 
3705 // Verify that basic buffering works; when multiple data frames arrive
3706 // at the same time, ensure that we don't notify a read completion for
3707 // each data frame individually.
TEST_F(SpdyNetworkTransactionTest,Buffering)3708 TEST_F(SpdyNetworkTransactionTest, Buffering) {
3709   spdy::SpdySerializedFrame req(
3710       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
3711   MockWrite writes[] = {CreateMockWrite(req, 0)};
3712 
3713   // 4 data frames in a single read.
3714   spdy::SpdySerializedFrame data_frame(
3715       spdy_util_.ConstructSpdyDataFrame(1, "message", /*fin=*/false));
3716   spdy::SpdySerializedFrame data_frame_fin(
3717       spdy_util_.ConstructSpdyDataFrame(1, "message", /*fin=*/true));
3718   spdy::SpdySerializedFrame combined_data_frames =
3719       CombineFrames({&data_frame, &data_frame, &data_frame, &data_frame_fin});
3720 
3721   spdy::SpdySerializedFrame resp(
3722       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
3723   MockRead reads[] = {
3724       CreateMockRead(resp, 1),
3725       MockRead(ASYNC, ERR_IO_PENDING, 2),  // Force a pause
3726       CreateMockRead(combined_data_frames, 3), MockRead(ASYNC, 0, 4)  // EOF
3727   };
3728 
3729   SequencedSocketData data(reads, writes);
3730 
3731   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
3732   helper.RunPreTestSetup();
3733   helper.AddData(&data);
3734   HttpNetworkTransaction* trans = helper.trans();
3735 
3736   TestCompletionCallback callback;
3737   int rv = trans->Start(&request_, callback.callback(), log_);
3738   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3739 
3740   TransactionHelperResult out = helper.output();
3741   out.rv = callback.WaitForResult();
3742   EXPECT_EQ(out.rv, OK);
3743 
3744   const HttpResponseInfo* response = trans->GetResponseInfo();
3745   EXPECT_TRUE(response->headers);
3746   EXPECT_TRUE(response->was_fetched_via_spdy);
3747   out.status_line = response->headers->GetStatusLine();
3748   out.response_info = *response;  // Make a copy so we can verify.
3749 
3750   // Read Data
3751   TestCompletionCallback read_callback;
3752 
3753   std::string content;
3754   int reads_completed = 0;
3755   do {
3756     // Read small chunks at a time.
3757     const int kSmallReadSize = 14;
3758     scoped_refptr<IOBuffer> buf =
3759         base::MakeRefCounted<IOBuffer>(kSmallReadSize);
3760     rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback());
3761     if (rv == ERR_IO_PENDING) {
3762       data.Resume();
3763       rv = read_callback.WaitForResult();
3764     }
3765     if (rv > 0) {
3766       EXPECT_EQ(kSmallReadSize, rv);
3767       content.append(buf->data(), rv);
3768     } else if (rv < 0) {
3769       FAIL() << "Unexpected read error: " << rv;
3770     }
3771     reads_completed++;
3772   } while (rv > 0);
3773 
3774   EXPECT_EQ(3, reads_completed);  // Reads are: 14 bytes, 14 bytes, 0 bytes.
3775 
3776   out.response_data.swap(content);
3777 
3778   // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
3779   // MockClientSocketFactory) are still alive.
3780   base::RunLoop().RunUntilIdle();
3781 
3782   // Verify that we consumed all test data.
3783   helper.VerifyDataConsumed();
3784 
3785   EXPECT_THAT(out.rv, IsOk());
3786   EXPECT_EQ("HTTP/1.1 200", out.status_line);
3787   EXPECT_EQ("messagemessagemessagemessage", out.response_data);
3788 }
3789 
3790 // Verify the case where we buffer data but read it after it has been buffered.
TEST_F(SpdyNetworkTransactionTest,BufferedAll)3791 TEST_F(SpdyNetworkTransactionTest, BufferedAll) {
3792   spdy::SpdySerializedFrame req(
3793       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
3794   MockWrite writes[] = {CreateMockWrite(req, 0)};
3795 
3796   // 5 data frames in a single read.
3797   spdy::SpdySerializedFrame reply(
3798       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
3799   spdy::SpdySerializedFrame data_frame(
3800       spdy_util_.ConstructSpdyDataFrame(1, "message", /*fin=*/false));
3801   spdy::SpdySerializedFrame data_frame_fin(
3802       spdy_util_.ConstructSpdyDataFrame(1, "message", /*fin=*/true));
3803   spdy::SpdySerializedFrame combined_frames = CombineFrames(
3804       {&reply, &data_frame, &data_frame, &data_frame, &data_frame_fin});
3805 
3806   MockRead reads[] = {
3807       CreateMockRead(combined_frames, 1), MockRead(ASYNC, 0, 2)  // EOF
3808   };
3809 
3810   SequencedSocketData data(reads, writes);
3811 
3812   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
3813   helper.RunPreTestSetup();
3814   helper.AddData(&data);
3815   HttpNetworkTransaction* trans = helper.trans();
3816 
3817   TestCompletionCallback callback;
3818   int rv = trans->Start(&request_, callback.callback(), log_);
3819   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3820 
3821   TransactionHelperResult out = helper.output();
3822   out.rv = callback.WaitForResult();
3823   EXPECT_EQ(out.rv, OK);
3824 
3825   const HttpResponseInfo* response = trans->GetResponseInfo();
3826   EXPECT_TRUE(response->headers);
3827   EXPECT_TRUE(response->was_fetched_via_spdy);
3828   out.status_line = response->headers->GetStatusLine();
3829   out.response_info = *response;  // Make a copy so we can verify.
3830 
3831   // Read Data
3832   TestCompletionCallback read_callback;
3833 
3834   std::string content;
3835   int reads_completed = 0;
3836   do {
3837     // Read small chunks at a time.
3838     const int kSmallReadSize = 14;
3839     scoped_refptr<IOBuffer> buf =
3840         base::MakeRefCounted<IOBuffer>(kSmallReadSize);
3841     rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback());
3842     if (rv > 0) {
3843       EXPECT_EQ(kSmallReadSize, rv);
3844       content.append(buf->data(), rv);
3845     } else if (rv < 0) {
3846       FAIL() << "Unexpected read error: " << rv;
3847     }
3848     reads_completed++;
3849   } while (rv > 0);
3850 
3851   EXPECT_EQ(3, reads_completed);
3852 
3853   out.response_data.swap(content);
3854 
3855   // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
3856   // MockClientSocketFactory) are still alive.
3857   base::RunLoop().RunUntilIdle();
3858 
3859   // Verify that we consumed all test data.
3860   helper.VerifyDataConsumed();
3861 
3862   EXPECT_THAT(out.rv, IsOk());
3863   EXPECT_EQ("HTTP/1.1 200", out.status_line);
3864   EXPECT_EQ("messagemessagemessagemessage", out.response_data);
3865 }
3866 
3867 // Verify the case where we buffer data and close the connection.
TEST_F(SpdyNetworkTransactionTest,BufferedClosed)3868 TEST_F(SpdyNetworkTransactionTest, BufferedClosed) {
3869   spdy::SpdySerializedFrame req(
3870       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
3871   MockWrite writes[] = {CreateMockWrite(req, 0)};
3872 
3873   // All data frames in a single read.
3874   // NOTE: We don't FIN the stream.
3875   spdy::SpdySerializedFrame data_frame(
3876       spdy_util_.ConstructSpdyDataFrame(1, "message", /*fin=*/false));
3877   spdy::SpdySerializedFrame combined_data_frames =
3878       CombineFrames({&data_frame, &data_frame, &data_frame, &data_frame});
3879   spdy::SpdySerializedFrame resp(
3880       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
3881   MockRead reads[] = {
3882       CreateMockRead(resp, 1),
3883       MockRead(ASYNC, ERR_IO_PENDING, 2),  // Force a wait
3884       CreateMockRead(combined_data_frames, 3), MockRead(ASYNC, 0, 4)  // EOF
3885   };
3886 
3887   SequencedSocketData data(reads, writes);
3888 
3889   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
3890   helper.RunPreTestSetup();
3891   helper.AddData(&data);
3892   HttpNetworkTransaction* trans = helper.trans();
3893 
3894   TestCompletionCallback callback;
3895 
3896   int rv = trans->Start(&request_, callback.callback(), log_);
3897   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3898 
3899   TransactionHelperResult out = helper.output();
3900   rv = callback.WaitForResult();
3901   EXPECT_EQ(rv, OK);
3902 
3903   const HttpResponseInfo* response = trans->GetResponseInfo();
3904   EXPECT_TRUE(response->headers);
3905   EXPECT_TRUE(response->was_fetched_via_spdy);
3906 
3907   // Read Data
3908   TestCompletionCallback read_callback;
3909 
3910   std::string content;
3911   int reads_completed = 0;
3912   do {
3913     // Allocate a large buffer to allow buffering. If a single read fills the
3914     // buffer, no buffering happens.
3915     const int kLargeReadSize = 1000;
3916     scoped_refptr<IOBuffer> buf =
3917         base::MakeRefCounted<IOBuffer>(kLargeReadSize);
3918     rv = trans->Read(buf.get(), kLargeReadSize, read_callback.callback());
3919     if (rv == ERR_IO_PENDING) {
3920       data.Resume();
3921       rv = read_callback.WaitForResult();
3922     }
3923 
3924     if (rv < 0) {
3925       // This test intentionally closes the connection, and will get an error.
3926       EXPECT_THAT(rv, IsError(ERR_CONNECTION_CLOSED));
3927       break;
3928     }
3929     reads_completed++;
3930   } while (rv > 0);
3931 
3932   EXPECT_EQ(0, reads_completed);
3933 
3934   // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
3935   // MockClientSocketFactory) are still alive.
3936   base::RunLoop().RunUntilIdle();
3937 
3938   // Verify that we consumed all test data.
3939   helper.VerifyDataConsumed();
3940 }
3941 
3942 // Verify the case where we buffer data and cancel the transaction.
TEST_F(SpdyNetworkTransactionTest,BufferedCancelled)3943 TEST_F(SpdyNetworkTransactionTest, BufferedCancelled) {
3944   spdy::SpdySerializedFrame req(
3945       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
3946   spdy::SpdySerializedFrame rst(
3947       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
3948   MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(rst, 4)};
3949 
3950   // NOTE: We don't FIN the stream.
3951   spdy::SpdySerializedFrame data_frame(
3952       spdy_util_.ConstructSpdyDataFrame(1, "message", /*fin=*/false));
3953 
3954   spdy::SpdySerializedFrame resp(
3955       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
3956   MockRead reads[] = {
3957       CreateMockRead(resp, 1),
3958       MockRead(ASYNC, ERR_IO_PENDING, 2),                   // Force a wait
3959       CreateMockRead(data_frame, 3), MockRead(ASYNC, 0, 5)  // EOF
3960   };
3961 
3962   SequencedSocketData data(reads, writes);
3963 
3964   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
3965   helper.RunPreTestSetup();
3966   helper.AddData(&data);
3967   HttpNetworkTransaction* trans = helper.trans();
3968   TestCompletionCallback callback;
3969 
3970   int rv = trans->Start(&request_, callback.callback(), log_);
3971   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3972 
3973   TransactionHelperResult out = helper.output();
3974   out.rv = callback.WaitForResult();
3975   EXPECT_EQ(out.rv, OK);
3976 
3977   const HttpResponseInfo* response = trans->GetResponseInfo();
3978   EXPECT_TRUE(response->headers);
3979   EXPECT_TRUE(response->was_fetched_via_spdy);
3980   out.status_line = response->headers->GetStatusLine();
3981   out.response_info = *response;  // Make a copy so we can verify.
3982 
3983   // Read Data
3984   TestCompletionCallback read_callback;
3985 
3986   const int kReadSize = 256;
3987   scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(kReadSize);
3988   rv = trans->Read(buf.get(), kReadSize, read_callback.callback());
3989   ASSERT_EQ(ERR_IO_PENDING, rv) << "Unexpected read: " << rv;
3990 
3991   // Complete the read now, which causes buffering to start.
3992   data.Resume();
3993   base::RunLoop().RunUntilIdle();
3994   // Destroy the transaction, causing the stream to get cancelled
3995   // and orphaning the buffered IO task.
3996   helper.ResetTrans();
3997 
3998   // Flush the MessageLoop; this will cause the buffered IO task
3999   // to run for the final time.
4000   base::RunLoop().RunUntilIdle();
4001 
4002   // Verify that we consumed all test data.
4003   helper.VerifyDataConsumed();
4004 }
4005 
4006 // Request should fail upon receiving a GOAWAY frame
4007 // with Last-Stream-ID lower than the stream id corresponding to the request
4008 // and with error code other than NO_ERROR.
TEST_F(SpdyNetworkTransactionTest,FailOnGoAway)4009 TEST_F(SpdyNetworkTransactionTest, FailOnGoAway) {
4010   spdy::SpdySerializedFrame req(
4011       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
4012   MockWrite writes[] = {CreateMockWrite(req, 0)};
4013 
4014   spdy::SpdySerializedFrame go_away(
4015       spdy_util_.ConstructSpdyGoAway(0, spdy::ERROR_CODE_INTERNAL_ERROR, ""));
4016   MockRead reads[] = {
4017       CreateMockRead(go_away, 1),
4018   };
4019 
4020   SequencedSocketData data(reads, writes);
4021   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
4022   helper.RunToCompletion(&data);
4023   TransactionHelperResult out = helper.output();
4024   EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
4025 }
4026 
4027 // Request should be retried on a new connection upon receiving a GOAWAY frame
4028 // with Last-Stream-ID lower than the stream id corresponding to the request
4029 // and with error code NO_ERROR.
TEST_F(SpdyNetworkTransactionTest,RetryOnGoAway)4030 TEST_F(SpdyNetworkTransactionTest, RetryOnGoAway) {
4031   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
4032 
4033   // First connection.
4034   spdy::SpdySerializedFrame req(
4035       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
4036   MockWrite writes1[] = {CreateMockWrite(req, 0)};
4037   spdy::SpdySerializedFrame go_away(
4038       spdy_util_.ConstructSpdyGoAway(0, spdy::ERROR_CODE_NO_ERROR, ""));
4039   MockRead reads1[] = {CreateMockRead(go_away, 1)};
4040   SequencedSocketData data1(reads1, writes1);
4041   helper.AddData(&data1);
4042 
4043   // Second connection.
4044   MockWrite writes2[] = {CreateMockWrite(req, 0)};
4045   spdy::SpdySerializedFrame resp(
4046       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
4047   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
4048   MockRead reads2[] = {CreateMockRead(resp, 1), CreateMockRead(body, 2),
4049                        MockRead(ASYNC, 0, 3)};
4050   SequencedSocketData data2(reads2, writes2);
4051   helper.AddData(&data2);
4052 
4053   helper.RunPreTestSetup();
4054   helper.RunDefaultTest();
4055 
4056   TransactionHelperResult out = helper.output();
4057   EXPECT_THAT(out.rv, IsOk());
4058 
4059   helper.VerifyDataConsumed();
4060 }
4061 
4062 // A server can gracefully shut down by sending a GOAWAY frame
4063 // with maximum last-stream-id value.
4064 // Transactions started before receiving such a GOAWAY frame should succeed,
4065 // but SpdySession should be unavailable for new streams.
TEST_F(SpdyNetworkTransactionTest,GracefulGoaway)4066 TEST_F(SpdyNetworkTransactionTest, GracefulGoaway) {
4067   spdy::SpdySerializedFrame req1(
4068       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
4069   spdy_util_.UpdateWithStreamDestruction(1);
4070   spdy::SpdySerializedFrame req2(
4071       spdy_util_.ConstructSpdyGet("https://www.example.org/foo", 3, LOWEST));
4072   MockWrite writes[] = {CreateMockWrite(req1, 0), CreateMockWrite(req2, 3)};
4073 
4074   spdy::SpdySerializedFrame resp1(
4075       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
4076   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
4077   spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
4078       0x7fffffff, spdy::ERROR_CODE_NO_ERROR, "Graceful shutdown."));
4079   spdy::SpdySerializedFrame resp2(
4080       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
4081   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
4082   MockRead reads[] = {CreateMockRead(resp1, 1),  CreateMockRead(body1, 2),
4083                       CreateMockRead(goaway, 4), CreateMockRead(resp2, 5),
4084                       CreateMockRead(body2, 6),  MockRead(ASYNC, 0, 7)};
4085 
4086   // Run first transaction.
4087   SequencedSocketData data(reads, writes);
4088   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
4089   helper.RunPreTestSetup();
4090   helper.AddData(&data);
4091   helper.RunDefaultTest();
4092 
4093   // Verify first response.
4094   TransactionHelperResult out = helper.output();
4095   EXPECT_THAT(out.rv, IsOk());
4096   EXPECT_EQ("HTTP/1.1 200", out.status_line);
4097   EXPECT_EQ("hello!", out.response_data);
4098 
4099   // GOAWAY frame has not yet been received, SpdySession should be available.
4100   SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
4101   SpdySessionKey key(host_port_pair_, ProxyServer::Direct(),
4102                      PRIVACY_MODE_DISABLED,
4103                      SpdySessionKey::IsProxySession::kFalse, SocketTag(),
4104                      NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
4105   EXPECT_TRUE(
4106       spdy_session_pool->HasAvailableSession(key, /* is_websocket = */ false));
4107   base::WeakPtr<SpdySession> spdy_session =
4108       spdy_session_pool->FindAvailableSession(
4109           key, /* enable_ip_based_pooling = */ true,
4110           /* is_websocket = */ false, log_);
4111   EXPECT_TRUE(spdy_session);
4112 
4113   // Start second transaction.
4114   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
4115   TestCompletionCallback callback;
4116   HttpRequestInfo request2;
4117   request2.method = "GET";
4118   request2.url = GURL("https://www.example.org/foo");
4119   request2.traffic_annotation =
4120       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4121   int rv = trans2.Start(&request2, callback.callback(), log_);
4122   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4123   rv = callback.WaitForResult();
4124   EXPECT_THAT(rv, IsOk());
4125 
4126   // Verify second response.
4127   const HttpResponseInfo* response = trans2.GetResponseInfo();
4128   ASSERT_TRUE(response);
4129   EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2, response->connection_info);
4130   ASSERT_TRUE(response->headers);
4131   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
4132   EXPECT_TRUE(response->was_fetched_via_spdy);
4133   EXPECT_TRUE(response->was_alpn_negotiated);
4134   EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
4135   EXPECT_EQ(443, response->remote_endpoint.port());
4136   std::string response_data;
4137   rv = ReadTransaction(&trans2, &response_data);
4138   EXPECT_THAT(rv, IsOk());
4139   EXPECT_EQ("hello!", response_data);
4140 
4141   // Graceful GOAWAY was received, SpdySession should be unavailable.
4142   EXPECT_FALSE(
4143       spdy_session_pool->HasAvailableSession(key, /* is_websocket = */ false));
4144   spdy_session = spdy_session_pool->FindAvailableSession(
4145       key, /* enable_ip_based_pooling = */ true,
4146       /* is_websocket = */ false, log_);
4147   EXPECT_FALSE(spdy_session);
4148 
4149   helper.VerifyDataConsumed();
4150 }
4151 
4152 // Verify that an active stream with ID not exceeding the Last-Stream-ID field
4153 // of the incoming GOAWAY frame can receive data both before and after the
4154 // GOAWAY frame.
TEST_F(SpdyNetworkTransactionTest,ActiveStreamWhileGoingAway)4155 TEST_F(SpdyNetworkTransactionTest, ActiveStreamWhileGoingAway) {
4156   spdy::SpdySerializedFrame req(
4157       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
4158   MockWrite writes[] = {CreateMockWrite(req, 0)};
4159 
4160   spdy::SpdySerializedFrame resp(
4161       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
4162   spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
4163       /* last_good_stream_id = */ 1, spdy::ERROR_CODE_NO_ERROR,
4164       "Graceful shutdown."));
4165   spdy::SpdySerializedFrame body1(
4166       spdy_util_.ConstructSpdyDataFrame(1, "foo", false));
4167   spdy::SpdySerializedFrame body2(
4168       spdy_util_.ConstructSpdyDataFrame(1, "bar", true));
4169   MockRead reads[] = {CreateMockRead(resp, 1), CreateMockRead(body1, 2),
4170                       CreateMockRead(goaway, 3), CreateMockRead(body2, 4),
4171                       MockRead(ASYNC, 0, 5)};
4172 
4173   SequencedSocketData data(reads, writes);
4174   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
4175   helper.AddData(&data);
4176 
4177   HttpNetworkTransaction trans(DEFAULT_PRIORITY, helper.session());
4178   TestCompletionCallback callback;
4179   int rv = trans.Start(&request_, callback.callback(), log_);
4180   EXPECT_THAT(callback.GetResult(rv), IsOk());
4181 
4182   base::RunLoop().RunUntilIdle();
4183   helper.VerifyDataConsumed();
4184 
4185   const HttpResponseInfo* response = trans.GetResponseInfo();
4186   ASSERT_TRUE(response);
4187   EXPECT_TRUE(response->was_fetched_via_spdy);
4188 
4189   ASSERT_TRUE(response->headers);
4190   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
4191 
4192   std::string response_data;
4193   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
4194   EXPECT_EQ("foobar", response_data);
4195 }
4196 
TEST_F(SpdyNetworkTransactionTest,CloseWithActiveStream)4197 TEST_F(SpdyNetworkTransactionTest, CloseWithActiveStream) {
4198   spdy::SpdySerializedFrame req(
4199       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
4200   MockWrite writes[] = {CreateMockWrite(req, 0)};
4201 
4202   spdy::SpdySerializedFrame resp(
4203       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
4204   MockRead reads[] = {
4205       CreateMockRead(resp, 1), MockRead(SYNCHRONOUS, 0, 2)  // EOF
4206   };
4207 
4208   SequencedSocketData data(reads, writes);
4209 
4210   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
4211   helper.RunPreTestSetup();
4212   helper.AddData(&data);
4213   helper.StartDefaultTest();
4214   EXPECT_THAT(helper.output().rv, IsError(ERR_IO_PENDING));
4215 
4216   helper.WaitForCallbackToComplete();
4217   EXPECT_THAT(helper.output().rv, IsError(ERR_CONNECTION_CLOSED));
4218 
4219   const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
4220   EXPECT_TRUE(response->headers);
4221   EXPECT_TRUE(response->was_fetched_via_spdy);
4222 
4223   // Verify that we consumed all test data.
4224   helper.VerifyDataConsumed();
4225 }
4226 
TEST_F(SpdyNetworkTransactionTest,GoAwayImmediately)4227 TEST_F(SpdyNetworkTransactionTest, GoAwayImmediately) {
4228   spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(1));
4229   MockRead reads[] = {CreateMockRead(goaway, 0, SYNCHRONOUS)};
4230   SequencedSocketData data(reads, base::span<MockWrite>());
4231 
4232   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
4233   helper.RunPreTestSetup();
4234   helper.AddData(&data);
4235   helper.StartDefaultTest();
4236   EXPECT_THAT(helper.output().rv, IsError(ERR_IO_PENDING));
4237 
4238   helper.WaitForCallbackToComplete();
4239   EXPECT_THAT(helper.output().rv, IsError(ERR_CONNECTION_CLOSED));
4240 
4241   const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
4242   EXPECT_FALSE(response->headers);
4243   EXPECT_TRUE(response->was_fetched_via_spdy);
4244 
4245   // Verify that we consumed all test data.
4246   helper.VerifyDataConsumed();
4247 }
4248 
4249 // Retry with HTTP/1.1 when receiving HTTP_1_1_REQUIRED.  Note that no actual
4250 // protocol negotiation happens, instead this test forces protocols for both
4251 // sockets.
TEST_F(SpdyNetworkTransactionTest,HTTP11RequiredRetry)4252 TEST_F(SpdyNetworkTransactionTest, HTTP11RequiredRetry) {
4253   request_.method = "GET";
4254   // Do not force SPDY so that second socket can negotiate HTTP/1.1.
4255   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
4256 
4257   // First socket: HTTP/2 request rejected with HTTP_1_1_REQUIRED.
4258   spdy::Http2HeaderBlock headers(
4259       spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
4260   spdy::SpdySerializedFrame req(
4261       spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
4262   MockWrite writes0[] = {CreateMockWrite(req, 0)};
4263   spdy::SpdySerializedFrame rst(
4264       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
4265   MockRead reads0[] = {CreateMockRead(rst, 1)};
4266   SequencedSocketData data0(reads0, writes0);
4267 
4268   auto ssl_provider0 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
4269   // Expect HTTP/2 protocols too in SSLConfig.
4270   ssl_provider0->next_protos_expected_in_ssl_config =
4271       NextProtoVector{kProtoHTTP2, kProtoHTTP11};
4272   // Force SPDY.
4273   ssl_provider0->next_proto = kProtoHTTP2;
4274   helper.AddDataWithSSLSocketDataProvider(&data0, std::move(ssl_provider0));
4275 
4276   // Second socket: falling back to HTTP/1.1.
4277   MockWrite writes1[] = {MockWrite(ASYNC, 0,
4278                                    "GET / HTTP/1.1\r\n"
4279                                    "Host: www.example.org\r\n"
4280                                    "Connection: keep-alive\r\n\r\n")};
4281   MockRead reads1[] = {MockRead(ASYNC, 1,
4282                                 "HTTP/1.1 200 OK\r\n"
4283                                 "Content-Length: 5\r\n\r\n"
4284                                 "hello")};
4285   SequencedSocketData data1(reads1, writes1);
4286 
4287   auto ssl_provider1 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
4288   // Expect only HTTP/1.1 protocol in SSLConfig.
4289   ssl_provider1->next_protos_expected_in_ssl_config =
4290       NextProtoVector{kProtoHTTP11};
4291   // Force HTTP/1.1.
4292   ssl_provider1->next_proto = kProtoHTTP11;
4293   helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1));
4294 
4295   HttpServerProperties* http_server_properties =
4296       helper.session()->spdy_session_pool()->http_server_properties();
4297   EXPECT_FALSE(http_server_properties->RequiresHTTP11(
4298       url::SchemeHostPort(request_.url), NetworkAnonymizationKey()));
4299 
4300   helper.RunPreTestSetup();
4301   helper.StartDefaultTest();
4302   helper.FinishDefaultTestWithoutVerification();
4303   helper.VerifyDataConsumed();
4304   EXPECT_TRUE(http_server_properties->RequiresHTTP11(
4305       url::SchemeHostPort(request_.url), NetworkAnonymizationKey()));
4306 
4307   const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
4308   ASSERT_TRUE(response);
4309   ASSERT_TRUE(response->headers);
4310   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4311   EXPECT_FALSE(response->was_fetched_via_spdy);
4312   EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
4313             response->connection_info);
4314   EXPECT_TRUE(response->was_alpn_negotiated);
4315   EXPECT_TRUE(request_.url.SchemeIs("https"));
4316   EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
4317   EXPECT_EQ(443, response->remote_endpoint.port());
4318   std::string response_data;
4319   ASSERT_THAT(ReadTransaction(helper.trans(), &response_data), IsOk());
4320   EXPECT_EQ("hello", response_data);
4321 }
4322 
4323 // Same as above test, but checks that NetworkAnonymizationKeys are respected.
TEST_F(SpdyNetworkTransactionTest,HTTP11RequiredRetryWithNetworkAnonymizationKey)4324 TEST_F(SpdyNetworkTransactionTest,
4325        HTTP11RequiredRetryWithNetworkAnonymizationKey) {
4326   const SchemefulSite kSite1(GURL("https://foo.test/"));
4327   const SchemefulSite kSite2(GURL("https://bar.test/"));
4328   const NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
4329   const NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
4330 
4331   const NetworkIsolationKey kNetworkIsolationKeys[] = {
4332       kNetworkIsolationKey1, kNetworkIsolationKey2, NetworkIsolationKey()};
4333 
4334   base::test::ScopedFeatureList feature_list;
4335   feature_list.InitWithFeatures(
4336       // enabled_features
4337       {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4338        // Need to partition connections by NetworkAnonymizationKey for
4339        // SpdySessionKeys to include NetworkAnonymizationKeys.
4340        features::kPartitionConnectionsByNetworkIsolationKey},
4341       // disabled_features
4342       {});
4343 
4344   // Do not force SPDY so that sockets can negotiate HTTP/1.1.
4345   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
4346 
4347   // For each server, set up and tear down a QUIC session cleanly, and check
4348   // that stats have been added to HttpServerProperties using the correct
4349   // NetworkAnonymizationKey.
4350   for (size_t i = 0; i < std::size(kNetworkIsolationKeys); ++i) {
4351     SCOPED_TRACE(i);
4352 
4353     request_.method = "GET";
4354     request_.network_isolation_key = kNetworkIsolationKeys[i];
4355     request_.network_anonymization_key =
4356         net::NetworkAnonymizationKey::CreateFromNetworkIsolationKey(
4357             kNetworkIsolationKeys[i]);
4358 
4359     // First socket: HTTP/2 request rejected with HTTP_1_1_REQUIRED.
4360     SpdyTestUtil spdy_util;
4361     spdy::Http2HeaderBlock headers(
4362         spdy_util.ConstructGetHeaderBlock(kDefaultUrl));
4363     spdy::SpdySerializedFrame req(
4364         spdy_util.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
4365     MockWrite writes0[] = {CreateMockWrite(req, 0)};
4366     spdy::SpdySerializedFrame rst(spdy_util.ConstructSpdyRstStream(
4367         1, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
4368     MockRead reads0[] = {CreateMockRead(rst, 1)};
4369     SequencedSocketData data0(reads0, writes0);
4370 
4371     auto ssl_provider0 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
4372     // Expect HTTP/2 protocols too in SSLConfig.
4373     ssl_provider0->next_protos_expected_in_ssl_config =
4374         NextProtoVector{kProtoHTTP2, kProtoHTTP11};
4375     // Force SPDY.
4376     ssl_provider0->next_proto = kProtoHTTP2;
4377     helper.AddDataWithSSLSocketDataProvider(&data0, std::move(ssl_provider0));
4378 
4379     // Second socket: falling back to HTTP/1.1.
4380     MockWrite writes1[] = {MockWrite(ASYNC, 0,
4381                                      "GET / HTTP/1.1\r\n"
4382                                      "Host: www.example.org\r\n"
4383                                      "Connection: keep-alive\r\n\r\n")};
4384     MockRead reads1[] = {MockRead(ASYNC, 1,
4385                                   "HTTP/1.1 200 OK\r\n"
4386                                   "Content-Length: 5\r\n\r\n"
4387                                   "hello")};
4388     SequencedSocketData data1(reads1, writes1);
4389 
4390     auto ssl_provider1 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
4391     // Expect only HTTP/1.1 protocol in SSLConfig.
4392     ssl_provider1->next_protos_expected_in_ssl_config =
4393         NextProtoVector{kProtoHTTP11};
4394     // Force HTTP/1.1.
4395     ssl_provider1->next_proto = kProtoHTTP11;
4396     helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1));
4397 
4398     HttpServerProperties* http_server_properties =
4399         helper.session()->spdy_session_pool()->http_server_properties();
4400     EXPECT_FALSE(http_server_properties->RequiresHTTP11(
4401         url::SchemeHostPort(request_.url),
4402         net::NetworkAnonymizationKey::CreateFromNetworkIsolationKey(
4403             kNetworkIsolationKeys[i])));
4404 
4405     HttpNetworkTransaction trans(DEFAULT_PRIORITY, helper.session());
4406 
4407     TestCompletionCallback callback;
4408     int rv = trans.Start(&request_, callback.callback(), log_);
4409     EXPECT_THAT(callback.GetResult(rv), IsOk());
4410 
4411     const HttpResponseInfo* response = trans.GetResponseInfo();
4412     ASSERT_TRUE(response);
4413     ASSERT_TRUE(response->headers);
4414     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4415     EXPECT_FALSE(response->was_fetched_via_spdy);
4416     EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
4417               response->connection_info);
4418     EXPECT_TRUE(response->was_alpn_negotiated);
4419     EXPECT_TRUE(request_.url.SchemeIs("https"));
4420     EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
4421     EXPECT_EQ(443, response->remote_endpoint.port());
4422     std::string response_data;
4423     ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
4424     EXPECT_EQ("hello", response_data);
4425 
4426     for (size_t j = 0; j < std::size(kNetworkIsolationKeys); ++j) {
4427       // NetworkAnonymizationKeys up to kNetworkIsolationKeys[j] are known
4428       // to require HTTP/1.1, others are not.
4429       if (j <= i) {
4430         EXPECT_TRUE(http_server_properties->RequiresHTTP11(
4431             url::SchemeHostPort(request_.url),
4432             net::NetworkAnonymizationKey::CreateFromNetworkIsolationKey(
4433                 kNetworkIsolationKeys[j])));
4434       } else {
4435         EXPECT_FALSE(http_server_properties->RequiresHTTP11(
4436             url::SchemeHostPort(request_.url),
4437             net::NetworkAnonymizationKey::CreateFromNetworkIsolationKey(
4438                 kNetworkIsolationKeys[j])));
4439       }
4440     }
4441   }
4442 }
4443 
4444 // Retry with HTTP/1.1 to the proxy when receiving HTTP_1_1_REQUIRED from the
4445 // proxy.  Note that no actual protocol negotiation happens, instead this test
4446 // forces protocols for both sockets.
TEST_F(SpdyNetworkTransactionTest,HTTP11RequiredProxyRetry)4447 TEST_F(SpdyNetworkTransactionTest, HTTP11RequiredProxyRetry) {
4448   request_.method = "GET";
4449   auto session_deps = std::make_unique<SpdySessionDependencies>(
4450       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
4451           "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
4452   // Do not force SPDY so that second socket can negotiate HTTP/1.1.
4453   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
4454                                      std::move(session_deps));
4455 
4456   // First socket: HTTP/2 CONNECT rejected with HTTP_1_1_REQUIRED.
4457   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
4458       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
4459       HostPortPair("www.example.org", 443)));
4460   MockWrite writes0[] = {CreateMockWrite(req, 0)};
4461   spdy::SpdySerializedFrame rst(
4462       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
4463   MockRead reads0[] = {CreateMockRead(rst, 1)};
4464   SequencedSocketData data0(reads0, writes0);
4465 
4466   auto ssl_provider0 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
4467   // Expect HTTP/2 protocols too in SSLConfig.
4468   ssl_provider0->next_protos_expected_in_ssl_config =
4469       NextProtoVector{kProtoHTTP2, kProtoHTTP11};
4470   // Force SPDY.
4471   ssl_provider0->next_proto = kProtoHTTP2;
4472   helper.AddDataWithSSLSocketDataProvider(&data0, std::move(ssl_provider0));
4473 
4474   // Second socket: retry using HTTP/1.1.
4475   MockWrite writes1[] = {
4476       MockWrite(ASYNC, 0,
4477                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
4478                 "Host: www.example.org:443\r\n"
4479                 "Proxy-Connection: keep-alive\r\n\r\n"),
4480       MockWrite(ASYNC, 2,
4481                 "GET / HTTP/1.1\r\n"
4482                 "Host: www.example.org\r\n"
4483                 "Connection: keep-alive\r\n\r\n"),
4484   };
4485 
4486   MockRead reads1[] = {
4487       MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
4488       MockRead(ASYNC, 3,
4489                "HTTP/1.1 200 OK\r\n"
4490                "Content-Length: 5\r\n\r\n"
4491                "hello"),
4492   };
4493   SequencedSocketData data1(reads1, writes1);
4494 
4495   auto ssl_provider1 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
4496   // Expect only HTTP/1.1 protocol in SSLConfig.
4497   ssl_provider1->next_protos_expected_in_ssl_config =
4498       NextProtoVector{kProtoHTTP11};
4499   // Force HTTP/1.1.
4500   ssl_provider1->next_proto = kProtoHTTP11;
4501   helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1));
4502 
4503   // A third socket is needed for the tunnelled connection.
4504   auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
4505   helper.session_deps()->socket_factory->AddSSLSocketDataProvider(
4506       ssl_provider2.get());
4507 
4508   HttpServerProperties* http_server_properties =
4509       helper.session()->spdy_session_pool()->http_server_properties();
4510   url::SchemeHostPort proxy_scheme_host_port(url::kHttpsScheme, "myproxy", 70);
4511   EXPECT_FALSE(http_server_properties->RequiresHTTP11(
4512       proxy_scheme_host_port, NetworkAnonymizationKey()));
4513 
4514   helper.RunPreTestSetup();
4515   helper.StartDefaultTest();
4516   helper.FinishDefaultTestWithoutVerification();
4517   helper.VerifyDataConsumed();
4518   EXPECT_TRUE(http_server_properties->RequiresHTTP11(
4519       proxy_scheme_host_port, NetworkAnonymizationKey()));
4520 
4521   const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
4522   ASSERT_TRUE(response);
4523   ASSERT_TRUE(response->headers);
4524   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4525   EXPECT_FALSE(response->was_fetched_via_spdy);
4526   EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
4527             response->connection_info);
4528   EXPECT_FALSE(response->was_alpn_negotiated);
4529   EXPECT_TRUE(request_.url.SchemeIs("https"));
4530   EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
4531   EXPECT_EQ(70, response->remote_endpoint.port());
4532   std::string response_data;
4533   ASSERT_THAT(ReadTransaction(helper.trans(), &response_data), IsOk());
4534   EXPECT_EQ("hello", response_data);
4535 }
4536 
4537 // Same as above, but also test that NetworkAnonymizationKeys are respected.
TEST_F(SpdyNetworkTransactionTest,HTTP11RequiredProxyRetryWithNetworkAnonymizationKey)4538 TEST_F(SpdyNetworkTransactionTest,
4539        HTTP11RequiredProxyRetryWithNetworkAnonymizationKey) {
4540   const SchemefulSite kSite1(GURL("https://foo.test/"));
4541   const SchemefulSite kSite2(GURL("https://bar.test/"));
4542   const auto kNetworkAnonymizationKey1 =
4543       NetworkAnonymizationKey::CreateSameSite(kSite1);
4544   const auto kNetworkAnonymizationKey2 =
4545       NetworkAnonymizationKey::CreateSameSite(kSite2);
4546   const NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
4547   const NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
4548 
4549   const NetworkAnonymizationKey kNetworkAnonymizationKeys[] = {
4550       kNetworkAnonymizationKey1, kNetworkAnonymizationKey2,
4551       NetworkAnonymizationKey()};
4552   const NetworkIsolationKey kNetworkIsolationKeys[] = {
4553       kNetworkIsolationKey1, kNetworkIsolationKey2, NetworkIsolationKey()};
4554 
4555   base::test::ScopedFeatureList feature_list;
4556   feature_list.InitWithFeatures(
4557       // enabled_features
4558       {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4559        // Need to partition connections by NetworkAnonymizationKey for
4560        // SpdySessionKeys to include NetworkAnonymizationKeys.
4561        features::kPartitionConnectionsByNetworkIsolationKey},
4562       // disabled_features
4563       {});
4564 
4565   request_.method = "GET";
4566   auto session_deps = std::make_unique<SpdySessionDependencies>(
4567       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
4568           "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
4569   // Do not force SPDY so that second socket can negotiate HTTP/1.1.
4570   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
4571                                      std::move(session_deps));
4572   helper.RunPreTestSetup();
4573 
4574   for (size_t i = 0; i < std::size(kNetworkAnonymizationKeys); ++i) {
4575     // First socket: HTTP/2 CONNECT rejected with HTTP_1_1_REQUIRED.
4576 
4577     SpdyTestUtil spdy_util;
4578     spdy::SpdySerializedFrame req(spdy_util.ConstructSpdyConnect(
4579         nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
4580         HostPortPair("www.example.org", 443)));
4581     MockWrite writes0[] = {CreateMockWrite(req, 0)};
4582     spdy::SpdySerializedFrame rst(spdy_util.ConstructSpdyRstStream(
4583         1, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
4584     MockRead reads0[] = {CreateMockRead(rst, 1)};
4585     SequencedSocketData data0(reads0, writes0);
4586 
4587     auto ssl_provider0 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
4588     // Expect HTTP/2 protocols too in SSLConfig.
4589     ssl_provider0->next_protos_expected_in_ssl_config =
4590         NextProtoVector{kProtoHTTP2, kProtoHTTP11};
4591     // Force SPDY.
4592     ssl_provider0->next_proto = kProtoHTTP2;
4593     helper.AddDataWithSSLSocketDataProvider(&data0, std::move(ssl_provider0));
4594 
4595     // Second socket: retry using HTTP/1.1.
4596     MockWrite writes1[] = {
4597         MockWrite(ASYNC, 0,
4598                   "CONNECT www.example.org:443 HTTP/1.1\r\n"
4599                   "Host: www.example.org:443\r\n"
4600                   "Proxy-Connection: keep-alive\r\n\r\n"),
4601         MockWrite(ASYNC, 2,
4602                   "GET / HTTP/1.1\r\n"
4603                   "Host: www.example.org\r\n"
4604                   "Connection: keep-alive\r\n\r\n"),
4605     };
4606 
4607     MockRead reads1[] = {
4608         MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
4609         MockRead(ASYNC, 3,
4610                  "HTTP/1.1 200 OK\r\n"
4611                  "Content-Length: 5\r\n\r\n"
4612                  "hello"),
4613     };
4614     SequencedSocketData data1(reads1, writes1);
4615 
4616     auto ssl_provider1 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
4617     // Expect only HTTP/1.1 protocol in SSLConfig.
4618     ssl_provider1->next_protos_expected_in_ssl_config =
4619         NextProtoVector{kProtoHTTP11};
4620     // Force HTTP/1.1.
4621     ssl_provider1->next_proto = kProtoHTTP11;
4622     helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1));
4623 
4624     // A third socket is needed for the tunnelled connection.
4625     auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
4626     helper.session_deps()->socket_factory->AddSSLSocketDataProvider(
4627         ssl_provider2.get());
4628 
4629     HttpServerProperties* http_server_properties =
4630         helper.session()->spdy_session_pool()->http_server_properties();
4631     url::SchemeHostPort proxy_scheme_host_port(url::kHttpsScheme, "myproxy",
4632                                                70);
4633     EXPECT_FALSE(http_server_properties->RequiresHTTP11(
4634         proxy_scheme_host_port, kNetworkAnonymizationKeys[i]));
4635 
4636     request_.network_isolation_key = kNetworkIsolationKeys[i];
4637     request_.network_anonymization_key = kNetworkAnonymizationKeys[i];
4638     HttpNetworkTransaction trans(DEFAULT_PRIORITY, helper.session());
4639     TestCompletionCallback callback;
4640     int rv = trans.Start(&request_, callback.callback(), log_);
4641     EXPECT_THAT(callback.GetResult(rv), IsOk());
4642     helper.VerifyDataConsumed();
4643 
4644     const HttpResponseInfo* response = trans.GetResponseInfo();
4645     ASSERT_TRUE(response);
4646     ASSERT_TRUE(response->headers);
4647     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4648     EXPECT_FALSE(response->was_fetched_via_spdy);
4649     EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
4650               response->connection_info);
4651     EXPECT_FALSE(response->was_alpn_negotiated);
4652     EXPECT_TRUE(request_.url.SchemeIs("https"));
4653     EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
4654     EXPECT_EQ(70, response->remote_endpoint.port());
4655     std::string response_data;
4656     ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
4657     EXPECT_EQ("hello", response_data);
4658 
4659     for (size_t j = 0; j < std::size(kNetworkAnonymizationKeys); ++j) {
4660       // The proxy SchemeHostPort URL should not be marked as requiring HTTP/1.1
4661       // using the current NetworkAnonymizationKey, and the state of others
4662       // should be unchanged since the last loop iteration..
4663       if (j <= i) {
4664         EXPECT_TRUE(http_server_properties->RequiresHTTP11(
4665             proxy_scheme_host_port, kNetworkAnonymizationKeys[j]));
4666       } else {
4667         EXPECT_FALSE(http_server_properties->RequiresHTTP11(
4668             proxy_scheme_host_port, kNetworkAnonymizationKeys[j]));
4669       }
4670     }
4671 
4672     // The destination SchemeHostPort should not be marked as requiring
4673     // HTTP/1.1.
4674     EXPECT_FALSE(http_server_properties->RequiresHTTP11(
4675         url::SchemeHostPort(request_.url), kNetworkAnonymizationKeys[i]));
4676   }
4677 }
4678 
4679 // Test to make sure we can correctly connect through a proxy.
TEST_F(SpdyNetworkTransactionTest,ProxyConnect)4680 TEST_F(SpdyNetworkTransactionTest, ProxyConnect) {
4681   auto session_deps = std::make_unique<SpdySessionDependencies>(
4682       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
4683           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
4684   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
4685                                      std::move(session_deps));
4686   helper.RunPreTestSetup();
4687   HttpNetworkTransaction* trans = helper.trans();
4688 
4689   const char kConnect443[] = {
4690       "CONNECT www.example.org:443 HTTP/1.1\r\n"
4691       "Host: www.example.org:443\r\n"
4692       "Proxy-Connection: keep-alive\r\n\r\n"};
4693   const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"};
4694   spdy::SpdySerializedFrame req(
4695       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
4696   spdy::SpdySerializedFrame resp(
4697       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
4698   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
4699 
4700   MockWrite writes[] = {
4701       MockWrite(SYNCHRONOUS, kConnect443, std::size(kConnect443) - 1, 0),
4702       CreateMockWrite(req, 2),
4703   };
4704   MockRead reads[] = {
4705       MockRead(SYNCHRONOUS, kHTTP200, std::size(kHTTP200) - 1, 1),
4706       CreateMockRead(resp, 3),
4707       CreateMockRead(body, 4),
4708       MockRead(ASYNC, nullptr, 0, 5),
4709   };
4710   SequencedSocketData data(reads, writes);
4711 
4712   helper.AddData(&data);
4713   TestCompletionCallback callback;
4714 
4715   int rv = trans->Start(&request_, callback.callback(), log_);
4716   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4717 
4718   rv = callback.WaitForResult();
4719   EXPECT_EQ(0, rv);
4720 
4721   // Verify the response headers.
4722   HttpResponseInfo response = *trans->GetResponseInfo();
4723   ASSERT_TRUE(response.headers);
4724   EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
4725 
4726   std::string response_data;
4727   ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
4728   EXPECT_EQ("hello!", response_data);
4729   helper.VerifyDataConsumed();
4730 }
4731 
4732 // Test to make sure we can correctly connect through a proxy to
4733 // www.example.org, if there already exists a direct spdy connection to
4734 // www.example.org. See https://crbug.com/49874.
TEST_F(SpdyNetworkTransactionTest,DirectConnectProxyReconnect)4735 TEST_F(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) {
4736   // Use a proxy service which returns a proxy fallback list from DIRECT to
4737   // myproxy:70. For this test there will be no fallback, so it is equivalent
4738   // to simply DIRECT. The reason for appending the second proxy is to verify
4739   // that the session pool key used does is just "DIRECT".
4740   auto session_deps = std::make_unique<SpdySessionDependencies>(
4741       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
4742           "DIRECT; PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
4743   // When setting up the first transaction, we store the SpdySessionPool so that
4744   // we can use the same pool in the second transaction.
4745   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
4746                                      std::move(session_deps));
4747 
4748   SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
4749   helper.RunPreTestSetup();
4750 
4751   // Construct and send a simple GET request.
4752   spdy::SpdySerializedFrame req(
4753       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
4754   MockWrite writes[] = {
4755       CreateMockWrite(req, 0),
4756   };
4757 
4758   spdy::SpdySerializedFrame resp(
4759       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
4760   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
4761   MockRead reads[] = {
4762       CreateMockRead(resp, 1), CreateMockRead(body, 2),
4763       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),  // Force a pause
4764   };
4765   SequencedSocketData data(reads, writes);
4766   helper.AddData(&data);
4767   HttpNetworkTransaction* trans = helper.trans();
4768 
4769   TestCompletionCallback callback;
4770   TransactionHelperResult out;
4771   out.rv = trans->Start(&request_, callback.callback(), log_);
4772 
4773   EXPECT_EQ(out.rv, ERR_IO_PENDING);
4774   out.rv = callback.WaitForResult();
4775   EXPECT_EQ(out.rv, OK);
4776 
4777   const HttpResponseInfo* response = trans->GetResponseInfo();
4778   EXPECT_TRUE(response->headers);
4779   EXPECT_TRUE(response->was_fetched_via_spdy);
4780   out.rv = ReadTransaction(trans, &out.response_data);
4781   EXPECT_THAT(out.rv, IsOk());
4782   out.status_line = response->headers->GetStatusLine();
4783   EXPECT_EQ("HTTP/1.1 200", out.status_line);
4784   EXPECT_EQ("hello!", out.response_data);
4785 
4786   // Check that the SpdySession is still in the SpdySessionPool.
4787   SpdySessionKey session_pool_key_direct(
4788       host_port_pair_, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
4789       SpdySessionKey::IsProxySession::kFalse, SocketTag(),
4790       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
4791   EXPECT_TRUE(HasSpdySession(spdy_session_pool, session_pool_key_direct));
4792   SpdySessionKey session_pool_key_proxy(
4793       host_port_pair_,
4794       ProxyUriToProxyServer("www.foo.com", ProxyServer::SCHEME_HTTP),
4795       PRIVACY_MODE_DISABLED, SpdySessionKey::IsProxySession::kFalse,
4796       SocketTag(), NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
4797   EXPECT_FALSE(HasSpdySession(spdy_session_pool, session_pool_key_proxy));
4798 
4799   // New SpdyTestUtil instance for the session that will be used for the
4800   // proxy connection.
4801   SpdyTestUtil spdy_util_2;
4802 
4803   // Set up data for the proxy connection.
4804   const char kConnect443[] = {
4805       "CONNECT www.example.org:443 HTTP/1.1\r\n"
4806       "Host: www.example.org:443\r\n"
4807       "Proxy-Connection: keep-alive\r\n\r\n"};
4808   const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"};
4809   spdy::SpdySerializedFrame req2(
4810       spdy_util_2.ConstructSpdyGet(kPushedUrl, 1, LOWEST));
4811   spdy::SpdySerializedFrame resp2(
4812       spdy_util_2.ConstructSpdyGetReply(nullptr, 0, 1));
4813   spdy::SpdySerializedFrame body2(spdy_util_2.ConstructSpdyDataFrame(1, true));
4814 
4815   MockWrite writes2[] = {
4816       MockWrite(SYNCHRONOUS, kConnect443, std::size(kConnect443) - 1, 0),
4817       CreateMockWrite(req2, 2),
4818   };
4819   MockRead reads2[] = {
4820       MockRead(SYNCHRONOUS, kHTTP200, std::size(kHTTP200) - 1, 1),
4821       CreateMockRead(resp2, 3), CreateMockRead(body2, 4),
4822       MockRead(ASYNC, 0, 5)  // EOF
4823   };
4824 
4825   SequencedSocketData data_proxy(reads2, writes2);
4826 
4827   // Create another request to www.example.org, but this time through a proxy.
4828   request_.method = "GET";
4829   request_.url = GURL(kPushedUrl);
4830   auto session_deps_proxy = std::make_unique<SpdySessionDependencies>(
4831       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
4832           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
4833   NormalSpdyTransactionHelper helper_proxy(request_, DEFAULT_PRIORITY, log_,
4834                                            std::move(session_deps_proxy));
4835 
4836   helper_proxy.RunPreTestSetup();
4837   helper_proxy.AddData(&data_proxy);
4838 
4839   HttpNetworkTransaction* trans_proxy = helper_proxy.trans();
4840   TestCompletionCallback callback_proxy;
4841   int rv = trans_proxy->Start(&request_, callback_proxy.callback(), log_);
4842   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4843   rv = callback_proxy.WaitForResult();
4844   EXPECT_EQ(0, rv);
4845 
4846   HttpResponseInfo response_proxy = *trans_proxy->GetResponseInfo();
4847   ASSERT_TRUE(response_proxy.headers);
4848   EXPECT_EQ("HTTP/1.1 200", response_proxy.headers->GetStatusLine());
4849 
4850   std::string response_data;
4851   ASSERT_THAT(ReadTransaction(trans_proxy, &response_data), IsOk());
4852   EXPECT_EQ("hello!", response_data);
4853 
4854   helper_proxy.VerifyDataConsumed();
4855 }
4856 
4857 // When we get a TCP-level RST, we need to retry a HttpNetworkTransaction
4858 // on a new connection, if the connection was previously known to be good.
4859 // This can happen when a server reboots without saying goodbye, or when
4860 // we're behind a NAT that masked the RST.
TEST_F(SpdyNetworkTransactionTest,VerifyRetryOnConnectionReset)4861 TEST_F(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) {
4862   spdy::SpdySerializedFrame resp(
4863       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
4864   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
4865   MockRead reads[] = {
4866       CreateMockRead(resp, 1),
4867       CreateMockRead(body, 2),
4868       MockRead(ASYNC, ERR_IO_PENDING, 3),
4869       MockRead(ASYNC, ERR_CONNECTION_RESET, 4),
4870   };
4871 
4872   MockRead reads2[] = {
4873       CreateMockRead(resp, 1), CreateMockRead(body, 2),
4874       MockRead(ASYNC, 0, 3)  // EOF
4875   };
4876 
4877   spdy::SpdySerializedFrame req(
4878       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
4879   // In all cases the connection will be reset before req3 can be
4880   // dispatched, destroying both streams.
4881   spdy_util_.UpdateWithStreamDestruction(1);
4882   spdy::SpdySerializedFrame req3(
4883       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
4884   MockWrite writes1[] = {CreateMockWrite(req, 0), CreateMockWrite(req3, 5)};
4885   MockWrite writes2[] = {CreateMockWrite(req, 0)};
4886 
4887   // This test has a couple of variants.
4888   enum {
4889     // Induce the RST while waiting for our transaction to send.
4890     VARIANT_RST_DURING_SEND_COMPLETION = 0,
4891     // Induce the RST while waiting for our transaction to read.
4892     // In this case, the send completed - everything copied into the SNDBUF.
4893     VARIANT_RST_DURING_READ_COMPLETION = 1
4894   };
4895 
4896   for (int variant = VARIANT_RST_DURING_SEND_COMPLETION;
4897        variant <= VARIANT_RST_DURING_READ_COMPLETION; ++variant) {
4898     SequencedSocketData data1(reads,
4899                               base::make_span(writes1).first(1 + variant));
4900 
4901     SequencedSocketData data2(reads2, writes2);
4902 
4903     NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
4904                                        nullptr);
4905     helper.AddData(&data1);
4906     helper.AddData(&data2);
4907     helper.RunPreTestSetup();
4908 
4909     for (int i = 0; i < 2; ++i) {
4910       HttpNetworkTransaction trans(DEFAULT_PRIORITY, helper.session());
4911 
4912       TestCompletionCallback callback;
4913       int rv = trans.Start(&request_, callback.callback(), log_);
4914       EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4915       // On the second transaction, we trigger the RST.
4916       if (i == 1) {
4917         if (variant == VARIANT_RST_DURING_READ_COMPLETION) {
4918           // Writes to the socket complete asynchronously on SPDY by running
4919           // through the message loop.  Complete the write here.
4920           base::RunLoop().RunUntilIdle();
4921         }
4922 
4923         // Now schedule the ERR_CONNECTION_RESET.
4924         data1.Resume();
4925       }
4926       rv = callback.WaitForResult();
4927       EXPECT_THAT(rv, IsOk());
4928 
4929       const HttpResponseInfo* response = trans.GetResponseInfo();
4930       ASSERT_TRUE(response);
4931       EXPECT_TRUE(response->headers);
4932       EXPECT_TRUE(response->was_fetched_via_spdy);
4933       std::string response_data;
4934       rv = ReadTransaction(&trans, &response_data);
4935       EXPECT_THAT(rv, IsOk());
4936       EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
4937       EXPECT_EQ("hello!", response_data);
4938       base::RunLoop().RunUntilIdle();
4939     }
4940 
4941     helper.VerifyDataConsumed();
4942     base::RunLoop().RunUntilIdle();
4943   }
4944 }
4945 
4946 // Tests that Basic authentication works over SPDY
TEST_F(SpdyNetworkTransactionTest,SpdyBasicAuth)4947 TEST_F(SpdyNetworkTransactionTest, SpdyBasicAuth) {
4948   // The first request will be a bare GET, the second request will be a
4949   // GET with an Authorization header.
4950   spdy::SpdySerializedFrame req_get(
4951       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
4952   // Will be refused for lack of auth.
4953   spdy_util_.UpdateWithStreamDestruction(1);
4954   const char* const kExtraAuthorizationHeaders[] = {"authorization",
4955                                                     "Basic Zm9vOmJhcg=="};
4956   spdy::SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
4957       kExtraAuthorizationHeaders, std::size(kExtraAuthorizationHeaders) / 2, 3,
4958       LOWEST));
4959   MockWrite spdy_writes[] = {
4960       CreateMockWrite(req_get, 0),
4961       CreateMockWrite(req_get_authorization, 3),
4962   };
4963 
4964   // The first response is a 401 authentication challenge, and the second
4965   // response will be a 200 response since the second request includes a valid
4966   // Authorization header.
4967   const char* const kExtraAuthenticationHeaders[] = {"www-authenticate",
4968                                                      "Basic realm=\"MyRealm\""};
4969   spdy::SpdySerializedFrame resp_authentication(
4970       spdy_util_.ConstructSpdyReplyError(
4971           "401", kExtraAuthenticationHeaders,
4972           std::size(kExtraAuthenticationHeaders) / 2, 1));
4973   spdy::SpdySerializedFrame body_authentication(
4974       spdy_util_.ConstructSpdyDataFrame(1, true));
4975   spdy::SpdySerializedFrame resp_data(
4976       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
4977   spdy::SpdySerializedFrame body_data(
4978       spdy_util_.ConstructSpdyDataFrame(3, true));
4979 
4980   MockRead spdy_reads[] = {
4981       CreateMockRead(resp_authentication, 1),
4982       CreateMockRead(body_authentication, 2, SYNCHRONOUS),
4983       CreateMockRead(resp_data, 4),
4984       CreateMockRead(body_data, 5),
4985       MockRead(ASYNC, 0, 6),
4986   };
4987 
4988   SequencedSocketData data(spdy_reads, spdy_writes);
4989   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
4990 
4991   helper.RunPreTestSetup();
4992   helper.AddData(&data);
4993   helper.StartDefaultTest();
4994   EXPECT_THAT(helper.output().rv, IsError(ERR_IO_PENDING));
4995 
4996   helper.WaitForCallbackToComplete();
4997   EXPECT_THAT(helper.output().rv, IsOk());
4998 
4999   // Make sure the response has an auth challenge.
5000   HttpNetworkTransaction* trans = helper.trans();
5001   const HttpResponseInfo* const response_start = trans->GetResponseInfo();
5002   ASSERT_TRUE(response_start);
5003   ASSERT_TRUE(response_start->headers);
5004   EXPECT_EQ(401, response_start->headers->response_code());
5005   EXPECT_TRUE(response_start->was_fetched_via_spdy);
5006   const absl::optional<AuthChallengeInfo>& auth_challenge =
5007       response_start->auth_challenge;
5008   ASSERT_TRUE(auth_challenge);
5009   EXPECT_FALSE(auth_challenge->is_proxy);
5010   EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
5011   EXPECT_EQ("MyRealm", auth_challenge->realm);
5012 
5013   // Restart with a username/password.
5014   AuthCredentials credentials(u"foo", u"bar");
5015   TestCompletionCallback callback_restart;
5016   const int rv_restart =
5017       trans->RestartWithAuth(credentials, callback_restart.callback());
5018   EXPECT_THAT(rv_restart, IsError(ERR_IO_PENDING));
5019   const int rv_restart_complete = callback_restart.WaitForResult();
5020   EXPECT_THAT(rv_restart_complete, IsOk());
5021   // TODO(cbentzel): This is actually the same response object as before, but
5022   // data has changed.
5023   const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
5024   ASSERT_TRUE(response_restart);
5025   ASSERT_TRUE(response_restart->headers);
5026   EXPECT_EQ(200, response_restart->headers->response_code());
5027   EXPECT_FALSE(response_restart->auth_challenge);
5028 }
5029 
TEST_F(SpdyNetworkTransactionTest,ResponseHeadersTwice)5030 TEST_F(SpdyNetworkTransactionTest, ResponseHeadersTwice) {
5031   spdy::SpdySerializedFrame req(
5032       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
5033   spdy::SpdySerializedFrame rst(
5034       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
5035   MockWrite writes[] = {
5036       CreateMockWrite(req, 0),
5037       CreateMockWrite(rst, 4),
5038   };
5039 
5040   spdy::SpdySerializedFrame stream1_reply(
5041       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
5042 
5043   spdy::Http2HeaderBlock late_headers;
5044   late_headers["hello"] = "bye";
5045   spdy::SpdySerializedFrame stream1_headers(
5046       spdy_util_.ConstructSpdyResponseHeaders(1, std::move(late_headers),
5047                                               false));
5048   spdy::SpdySerializedFrame stream1_body(
5049       spdy_util_.ConstructSpdyDataFrame(1, true));
5050   MockRead reads[] = {
5051       CreateMockRead(stream1_reply, 1), CreateMockRead(stream1_headers, 2),
5052       CreateMockRead(stream1_body, 3), MockRead(ASYNC, 0, 5)  // EOF
5053   };
5054 
5055   SequencedSocketData data(reads, writes);
5056   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
5057   helper.RunToCompletion(&data);
5058   TransactionHelperResult out = helper.output();
5059   EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
5060 }
5061 
5062 // Tests that receiving HEADERS, DATA, HEADERS, and DATA in that sequence will
5063 // trigger a ERR_HTTP2_PROTOCOL_ERROR because trailing HEADERS must not be
5064 // followed by any DATA frames.
TEST_F(SpdyNetworkTransactionTest,SyncReplyDataAfterTrailers)5065 TEST_F(SpdyNetworkTransactionTest, SyncReplyDataAfterTrailers) {
5066   spdy::SpdySerializedFrame req(
5067       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
5068   spdy::SpdySerializedFrame rst(
5069       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
5070   MockWrite writes[] = {
5071       CreateMockWrite(req, 0),
5072       CreateMockWrite(rst, 5),
5073   };
5074 
5075   spdy::SpdySerializedFrame stream1_reply(
5076       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
5077   spdy::SpdySerializedFrame stream1_body(
5078       spdy_util_.ConstructSpdyDataFrame(1, false));
5079 
5080   spdy::Http2HeaderBlock late_headers;
5081   late_headers["hello"] = "bye";
5082   spdy::SpdySerializedFrame stream1_headers(
5083       spdy_util_.ConstructSpdyResponseHeaders(1, std::move(late_headers),
5084                                               false));
5085   spdy::SpdySerializedFrame stream1_body2(
5086       spdy_util_.ConstructSpdyDataFrame(1, true));
5087   MockRead reads[] = {
5088       CreateMockRead(stream1_reply, 1), CreateMockRead(stream1_body, 2),
5089       CreateMockRead(stream1_headers, 3), CreateMockRead(stream1_body2, 4),
5090       MockRead(ASYNC, 0, 6)  // EOF
5091   };
5092 
5093   SequencedSocketData data(reads, writes);
5094   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
5095   helper.RunToCompletion(&data);
5096   TransactionHelperResult out = helper.output();
5097   EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
5098 }
5099 
TEST_F(SpdyNetworkTransactionTest,RetryAfterRefused)5100 TEST_F(SpdyNetworkTransactionTest, RetryAfterRefused) {
5101   // Construct the request.
5102   spdy::SpdySerializedFrame req(
5103       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
5104   // Will be destroyed by the RST before stream 3 starts.
5105   spdy_util_.UpdateWithStreamDestruction(1);
5106   spdy::SpdySerializedFrame req2(
5107       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
5108   MockWrite writes[] = {
5109       CreateMockWrite(req, 0), CreateMockWrite(req2, 2),
5110   };
5111 
5112   spdy::SpdySerializedFrame refused(
5113       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_REFUSED_STREAM));
5114   spdy::SpdySerializedFrame resp(
5115       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
5116   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(3, true));
5117   MockRead reads[] = {
5118       CreateMockRead(refused, 1), CreateMockRead(resp, 3),
5119       CreateMockRead(body, 4), MockRead(ASYNC, 0, 5)  // EOF
5120   };
5121 
5122   SequencedSocketData data(reads, writes);
5123   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
5124 
5125   helper.RunPreTestSetup();
5126   helper.AddData(&data);
5127 
5128   HttpNetworkTransaction* trans = helper.trans();
5129 
5130   // Start the transaction with basic parameters.
5131   TestCompletionCallback callback;
5132   int rv = trans->Start(&request_, callback.callback(), log_);
5133   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5134   rv = callback.WaitForResult();
5135   EXPECT_THAT(rv, IsOk());
5136 
5137   // Finish async network reads.
5138   base::RunLoop().RunUntilIdle();
5139 
5140   // Verify that we consumed all test data.
5141   EXPECT_TRUE(data.AllReadDataConsumed());
5142   EXPECT_TRUE(data.AllWriteDataConsumed());
5143 
5144   // Verify the response headers.
5145   HttpResponseInfo response = *trans->GetResponseInfo();
5146   EXPECT_TRUE(response.headers);
5147   EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
5148 }
5149 
TEST_F(SpdyNetworkTransactionTest,OutOfOrderHeaders)5150 TEST_F(SpdyNetworkTransactionTest, OutOfOrderHeaders) {
5151   // This first request will start to establish the SpdySession.
5152   // Then we will start the second (MEDIUM priority) and then third
5153   // (HIGHEST priority) request in such a way that the third will actually
5154   // start before the second, causing the second to be numbered differently
5155   // than the order they were created.
5156   //
5157   // Note that the requests and responses created below are expectations
5158   // of what the above will produce on the wire, and hence are in the
5159   // initial->HIGHEST->LOWEST priority.
5160   //
5161   // Frames are created by SpdySession just before the write associated
5162   // with the frame is attempted, so stream dependencies will be based
5163   // on the streams alive at the point of the request write attempt.  Thus
5164   // req1 is alive when req2 is attempted (during but not after the
5165   // |data.RunFor(2);| statement below) but not when req3 is attempted.
5166   // The call to spdy_util_.UpdateWithStreamDestruction() reflects this.
5167   spdy::SpdySerializedFrame req1(
5168       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
5169   spdy::SpdySerializedFrame req2(
5170       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, HIGHEST));
5171   spdy_util_.UpdateWithStreamDestruction(1);
5172   spdy::SpdySerializedFrame req3(
5173       spdy_util_.ConstructSpdyGet(nullptr, 0, 5, MEDIUM));
5174   MockWrite writes[] = {
5175       MockWrite(ASYNC, ERR_IO_PENDING, 0), CreateMockWrite(req1, 1),
5176       CreateMockWrite(req2, 5), CreateMockWrite(req3, 6),
5177   };
5178 
5179   spdy::SpdySerializedFrame resp1(
5180       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
5181   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
5182   spdy::SpdySerializedFrame resp2(
5183       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
5184   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
5185   spdy::SpdySerializedFrame resp3(
5186       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 5));
5187   spdy::SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(5, true));
5188   MockRead reads[] = {
5189       CreateMockRead(resp1, 2),  MockRead(ASYNC, ERR_IO_PENDING, 3),
5190       CreateMockRead(body1, 4),  CreateMockRead(resp2, 7),
5191       CreateMockRead(body2, 8),  CreateMockRead(resp3, 9),
5192       CreateMockRead(body3, 10), MockRead(ASYNC, 0, 11)  // EOF
5193   };
5194 
5195   SequencedSocketData data(reads, writes);
5196   NormalSpdyTransactionHelper helper(request_, LOWEST, log_, nullptr);
5197   helper.RunPreTestSetup();
5198   helper.AddData(&data);
5199 
5200   // Start the first transaction to set up the SpdySession
5201   HttpNetworkTransaction* trans = helper.trans();
5202   TestCompletionCallback callback;
5203   int rv = trans->Start(&request_, callback.callback(), log_);
5204   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5205 
5206   // Run the message loop, but do not allow the write to complete.
5207   // This leaves the SpdySession with a write pending, which prevents
5208   // SpdySession from attempting subsequent writes until this write completes.
5209   base::RunLoop().RunUntilIdle();
5210 
5211   // Now, start both new transactions
5212   TestCompletionCallback callback2;
5213   HttpNetworkTransaction trans2(MEDIUM, helper.session());
5214   rv = trans2.Start(&request_, callback2.callback(), log_);
5215   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5216   base::RunLoop().RunUntilIdle();
5217 
5218   TestCompletionCallback callback3;
5219   HttpNetworkTransaction trans3(HIGHEST, helper.session());
5220   rv = trans3.Start(&request_, callback3.callback(), log_);
5221   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5222   base::RunLoop().RunUntilIdle();
5223 
5224   // We now have two HEADERS frames queued up which will be
5225   // dequeued only once the first write completes, which we
5226   // now allow to happen.
5227   ASSERT_TRUE(data.IsPaused());
5228   data.Resume();
5229   EXPECT_THAT(callback.WaitForResult(), IsOk());
5230 
5231   // And now we can allow everything else to run to completion.
5232   data.Resume();
5233   base::RunLoop().RunUntilIdle();
5234   EXPECT_THAT(callback2.WaitForResult(), IsOk());
5235   EXPECT_THAT(callback3.WaitForResult(), IsOk());
5236 
5237   helper.VerifyDataConsumed();
5238 
5239   // At this point the test is completed and we need to safely destroy
5240   // all allocated structures. Helper stores a transaction that has a
5241   // reference to a stack allocated request, which has a short lifetime,
5242   // and is accessed during the transaction destruction. We need to delete
5243   // the transaction while the request is still a valid object.
5244   helper.ResetTrans();
5245 }
5246 
5247 // Test that sent data frames and received WINDOW_UPDATE frames change
5248 // the send_window_size_ correctly.
5249 
5250 // WINDOW_UPDATE is different than most other frames in that it can arrive
5251 // while the client is still sending the request body.  In order to enforce
5252 // this scenario, we feed a couple of dummy frames and give a delay of 0 to
5253 // socket data provider, so that initial read that is done as soon as the
5254 // stream is created, succeeds and schedules another read.  This way reads
5255 // and writes are interleaved; after doing a full frame write, SpdyStream
5256 // will break out of DoLoop and will read and process a WINDOW_UPDATE.
5257 // Once our WINDOW_UPDATE is read, we cannot send HEADERS right away
5258 // since request has not been completely written, therefore we feed
5259 // enough number of WINDOW_UPDATEs to finish the first read and cause a
5260 // write, leading to a complete write of request body; after that we send
5261 // a reply with a body, to cause a graceful shutdown.
5262 
5263 // TODO(agayev): develop a socket data provider where both, reads and
5264 // writes are ordered so that writing tests like these are easy and rewrite
5265 // all these tests using it.  Right now we are working around the
5266 // limitations as described above and it's not deterministic, tests may
5267 // fail under specific circumstances.
TEST_F(SpdyNetworkTransactionTest,WindowUpdateReceived)5268 TEST_F(SpdyNetworkTransactionTest, WindowUpdateReceived) {
5269   static int kFrameCount = 2;
5270   std::string content(kMaxSpdyFrameChunkSize, 'a');
5271   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
5272       kDefaultUrl, 1, kMaxSpdyFrameChunkSize * kFrameCount, LOWEST, nullptr,
5273       0));
5274   spdy::SpdySerializedFrame body(
5275       spdy_util_.ConstructSpdyDataFrame(1, content, false));
5276   spdy::SpdySerializedFrame body_end(
5277       spdy_util_.ConstructSpdyDataFrame(1, content, true));
5278 
5279   MockWrite writes[] = {
5280       CreateMockWrite(req, 0), CreateMockWrite(body, 1),
5281       CreateMockWrite(body_end, 2),
5282   };
5283 
5284   static const int32_t kDeltaWindowSize = 0xff;
5285   static const int kDeltaCount = 4;
5286   spdy::SpdySerializedFrame window_update(
5287       spdy_util_.ConstructSpdyWindowUpdate(1, kDeltaWindowSize));
5288   spdy::SpdySerializedFrame window_update_dummy(
5289       spdy_util_.ConstructSpdyWindowUpdate(2, kDeltaWindowSize));
5290   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
5291   MockRead reads[] = {
5292       CreateMockRead(window_update_dummy, 3),
5293       CreateMockRead(window_update_dummy, 4),
5294       CreateMockRead(window_update_dummy, 5),
5295       CreateMockRead(window_update, 6),  // Four updates, therefore window
5296       CreateMockRead(window_update, 7),  // size should increase by
5297       CreateMockRead(window_update, 8),  // kDeltaWindowSize * 4
5298       CreateMockRead(window_update, 9),
5299       CreateMockRead(resp, 10),
5300       MockRead(ASYNC, ERR_IO_PENDING, 11),
5301       CreateMockRead(body_end, 12),
5302       MockRead(ASYNC, 0, 13)  // EOF
5303   };
5304 
5305   SequencedSocketData data(reads, writes);
5306 
5307   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
5308   for (int i = 0; i < kFrameCount; ++i) {
5309     element_readers.push_back(std::make_unique<UploadBytesElementReader>(
5310         content.data(), content.size()));
5311   }
5312   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
5313 
5314   // Setup the request.
5315   request_.method = "POST";
5316   request_.upload_data_stream = &upload_data_stream;
5317 
5318   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
5319   helper.AddData(&data);
5320   helper.RunPreTestSetup();
5321 
5322   HttpNetworkTransaction* trans = helper.trans();
5323 
5324   TestCompletionCallback callback;
5325   int rv = trans->Start(&request_, callback.callback(), log_);
5326 
5327   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5328 
5329   data.RunUntilPaused();
5330   base::RunLoop().RunUntilIdle();
5331 
5332   SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
5333   ASSERT_TRUE(stream);
5334   ASSERT_TRUE(stream->stream());
5335   EXPECT_EQ(static_cast<int>(kDefaultInitialWindowSize) +
5336                 kDeltaWindowSize * kDeltaCount -
5337                 kMaxSpdyFrameChunkSize * kFrameCount,
5338             stream->stream()->send_window_size());
5339 
5340   data.Resume();
5341   base::RunLoop().RunUntilIdle();
5342 
5343   rv = callback.WaitForResult();
5344   EXPECT_THAT(rv, IsOk());
5345 
5346   helper.VerifyDataConsumed();
5347 }
5348 
5349 // Test that received data frames and sent WINDOW_UPDATE frames change
5350 // the recv_window_size_ correctly.
TEST_F(SpdyNetworkTransactionTest,WindowUpdateSent)5351 TEST_F(SpdyNetworkTransactionTest, WindowUpdateSent) {
5352   // Session level maximum window size that is more than twice the default
5353   // initial window size so that an initial window update is sent.
5354   const int32_t session_max_recv_window_size = 5 * 64 * 1024;
5355   ASSERT_LT(2 * kDefaultInitialWindowSize, session_max_recv_window_size);
5356   // Stream level maximum window size that is less than the session level
5357   // maximum window size so that we test for confusion between the two.
5358   const int32_t stream_max_recv_window_size = 4 * 64 * 1024;
5359   ASSERT_GT(session_max_recv_window_size, stream_max_recv_window_size);
5360   // Size of body to be sent.  Has to be less than or equal to both window sizes
5361   // so that we do not run out of receiving window.  Also has to be greater than
5362   // half of them so that it triggers both a session level and a stream level
5363   // window update frame.
5364   const int32_t kTargetSize = 3 * 64 * 1024;
5365   ASSERT_GE(session_max_recv_window_size, kTargetSize);
5366   ASSERT_GE(stream_max_recv_window_size, kTargetSize);
5367   ASSERT_LT(session_max_recv_window_size / 2, kTargetSize);
5368   ASSERT_LT(stream_max_recv_window_size / 2, kTargetSize);
5369   // Size of each DATA frame.
5370   const int32_t kChunkSize = 4096;
5371   // Size of window updates.
5372   ASSERT_EQ(0, session_max_recv_window_size / 2 % kChunkSize);
5373   const int32_t session_window_update_delta =
5374       session_max_recv_window_size / 2 + kChunkSize;
5375   ASSERT_EQ(0, stream_max_recv_window_size / 2 % kChunkSize);
5376   const int32_t stream_window_update_delta =
5377       stream_max_recv_window_size / 2 + kChunkSize;
5378 
5379   spdy::SpdySerializedFrame preface(
5380       const_cast<char*>(spdy::kHttp2ConnectionHeaderPrefix),
5381       spdy::kHttp2ConnectionHeaderPrefixSize,
5382       /* owns_buffer = */ false);
5383 
5384   spdy::SettingsMap initial_settings;
5385   initial_settings[spdy::SETTINGS_HEADER_TABLE_SIZE] = kSpdyMaxHeaderTableSize;
5386   initial_settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] =
5387       kSpdyMaxConcurrentPushedStreams;
5388   initial_settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] =
5389       stream_max_recv_window_size;
5390   initial_settings[spdy::SETTINGS_MAX_HEADER_LIST_SIZE] =
5391       kSpdyMaxHeaderListSize;
5392   initial_settings[spdy::SETTINGS_ENABLE_PUSH] = 0;
5393   spdy::SpdySerializedFrame initial_settings_frame(
5394       spdy_util_.ConstructSpdySettings(initial_settings));
5395 
5396   spdy::SpdySerializedFrame initial_window_update(
5397       spdy_util_.ConstructSpdyWindowUpdate(
5398           spdy::kSessionFlowControlStreamId,
5399           session_max_recv_window_size - kDefaultInitialWindowSize));
5400 
5401   spdy::SpdySerializedFrame combined_frames = CombineFrames(
5402       {&preface, &initial_settings_frame, &initial_window_update});
5403 
5404   std::vector<MockWrite> writes;
5405   writes.push_back(CreateMockWrite(combined_frames));
5406 
5407   spdy::SpdySerializedFrame req(
5408       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
5409   writes.push_back(CreateMockWrite(req, writes.size()));
5410 
5411   std::vector<MockRead> reads;
5412   spdy::SpdySerializedFrame resp(
5413       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
5414   reads.push_back(CreateMockRead(resp, writes.size() + reads.size()));
5415 
5416   std::vector<spdy::SpdySerializedFrame> body_frames;
5417   const std::string body_data(kChunkSize, 'x');
5418   for (size_t remaining = kTargetSize; remaining != 0;) {
5419     size_t frame_size = std::min(remaining, body_data.size());
5420     body_frames.push_back(spdy_util_.ConstructSpdyDataFrame(
5421         1, base::StringPiece(body_data.data(), frame_size), false));
5422     reads.push_back(
5423         CreateMockRead(body_frames.back(), writes.size() + reads.size()));
5424     remaining -= frame_size;
5425   }
5426   // Yield.
5427   reads.emplace_back(SYNCHRONOUS, ERR_IO_PENDING, writes.size() + reads.size());
5428 
5429   spdy::SpdySerializedFrame session_window_update(
5430       spdy_util_.ConstructSpdyWindowUpdate(0, session_window_update_delta));
5431   writes.push_back(
5432       CreateMockWrite(session_window_update, writes.size() + reads.size()));
5433   spdy::SpdySerializedFrame stream_window_update(
5434       spdy_util_.ConstructSpdyWindowUpdate(1, stream_window_update_delta));
5435   writes.push_back(
5436       CreateMockWrite(stream_window_update, writes.size() + reads.size()));
5437 
5438   SequencedSocketData data(reads, writes);
5439 
5440   auto session_deps = std::make_unique<SpdySessionDependencies>();
5441   session_deps->session_max_recv_window_size = session_max_recv_window_size;
5442   session_deps->http2_settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] =
5443       stream_max_recv_window_size;
5444 
5445   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
5446                                      std::move(session_deps));
5447   helper.AddData(&data);
5448   helper.RunPreTestSetup();
5449 
5450   SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
5451   SpdySessionPoolPeer pool_peer(spdy_session_pool);
5452   pool_peer.SetEnableSendingInitialData(true);
5453 
5454   HttpNetworkTransaction* trans = helper.trans();
5455   TestCompletionCallback callback;
5456   int rv = trans->Start(&request_, callback.callback(), log_);
5457 
5458   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5459   rv = callback.WaitForResult();
5460   EXPECT_THAT(rv, IsOk());
5461 
5462   // Finish async network reads.
5463   base::RunLoop().RunUntilIdle();
5464 
5465   SpdyHttpStream* stream =
5466       static_cast<SpdyHttpStream*>(trans->stream_.get());
5467   ASSERT_TRUE(stream);
5468   ASSERT_TRUE(stream->stream());
5469 
5470   // All data has been read, but not consumed. The window reflects this.
5471   EXPECT_EQ(static_cast<int>(stream_max_recv_window_size - kTargetSize),
5472             stream->stream()->recv_window_size());
5473 
5474   const HttpResponseInfo* response = trans->GetResponseInfo();
5475   ASSERT_TRUE(response);
5476   ASSERT_TRUE(response->headers);
5477   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
5478   EXPECT_TRUE(response->was_fetched_via_spdy);
5479 
5480   // Issue a read which will cause a WINDOW_UPDATE to be sent and window
5481   // size increased to default.
5482   scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(kTargetSize);
5483   EXPECT_EQ(static_cast<int>(kTargetSize),
5484             trans->Read(buf.get(), kTargetSize, CompletionOnceCallback()));
5485   EXPECT_EQ(static_cast<int>(stream_max_recv_window_size),
5486             stream->stream()->recv_window_size());
5487   EXPECT_THAT(base::StringPiece(buf->data(), kTargetSize), Each(Eq('x')));
5488 
5489   // Allow scheduled WINDOW_UPDATE frames to write.
5490   base::RunLoop().RunUntilIdle();
5491   helper.VerifyDataConsumed();
5492 }
5493 
5494 // Test that WINDOW_UPDATE frame causing overflow is handled correctly.
TEST_F(SpdyNetworkTransactionTest,WindowUpdateOverflow)5495 TEST_F(SpdyNetworkTransactionTest, WindowUpdateOverflow) {
5496   // Number of full frames we hope to write (but will not, used to
5497   // set content-length header correctly)
5498   static int kFrameCount = 3;
5499 
5500   std::string content(kMaxSpdyFrameChunkSize, 'a');
5501   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
5502       kDefaultUrl, 1, kMaxSpdyFrameChunkSize * kFrameCount, LOWEST, nullptr,
5503       0));
5504   spdy::SpdySerializedFrame body(
5505       spdy_util_.ConstructSpdyDataFrame(1, content, false));
5506   spdy::SpdySerializedFrame rst(spdy_util_.ConstructSpdyRstStream(
5507       1, spdy::ERROR_CODE_FLOW_CONTROL_ERROR));
5508 
5509   // We're not going to write a data frame with FIN, we'll receive a bad
5510   // WINDOW_UPDATE while sending a request and will send a RST_STREAM frame.
5511   MockWrite writes[] = {
5512       CreateMockWrite(req, 0), CreateMockWrite(body, 2),
5513       CreateMockWrite(rst, 3),
5514   };
5515 
5516   static const int32_t kDeltaWindowSize = 0x7fffffff;  // cause an overflow
5517   spdy::SpdySerializedFrame window_update(
5518       spdy_util_.ConstructSpdyWindowUpdate(1, kDeltaWindowSize));
5519   MockRead reads[] = {
5520       CreateMockRead(window_update, 1), MockRead(ASYNC, 0, 4)  // EOF
5521   };
5522 
5523   SequencedSocketData data(reads, writes);
5524 
5525   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
5526   for (int i = 0; i < kFrameCount; ++i) {
5527     element_readers.push_back(std::make_unique<UploadBytesElementReader>(
5528         content.data(), content.size()));
5529   }
5530   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
5531 
5532   // Setup the request.
5533   request_.method = "POST";
5534   request_.upload_data_stream = &upload_data_stream;
5535 
5536   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
5537   helper.RunPreTestSetup();
5538   helper.AddData(&data);
5539   HttpNetworkTransaction* trans = helper.trans();
5540 
5541   TestCompletionCallback callback;
5542   int rv = trans->Start(&request_, callback.callback(), log_);
5543   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
5544 
5545   base::RunLoop().RunUntilIdle();
5546   ASSERT_TRUE(callback.have_result());
5547   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_HTTP2_FLOW_CONTROL_ERROR));
5548   helper.VerifyDataConsumed();
5549 }
5550 
5551 // Regression test for https://crbug.com/732019.
5552 // RFC7540 Section 6.9.2: A spdy::SETTINGS_INITIAL_WINDOW_SIZE change that
5553 // causes any stream flow control window to overflow MUST be treated as a
5554 // connection error.
TEST_F(SpdyNetworkTransactionTest,InitialWindowSizeOverflow)5555 TEST_F(SpdyNetworkTransactionTest, InitialWindowSizeOverflow) {
5556   spdy::SpdySerializedFrame window_update(
5557       spdy_util_.ConstructSpdyWindowUpdate(1, 0x60000000));
5558   spdy::SettingsMap settings;
5559   settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] = 0x60000000;
5560   spdy::SpdySerializedFrame settings_frame(
5561       spdy_util_.ConstructSpdySettings(settings));
5562   MockRead reads[] = {CreateMockRead(window_update, 1),
5563                       CreateMockRead(settings_frame, 2)};
5564 
5565   spdy::SpdySerializedFrame req(
5566       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
5567   spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
5568   spdy::SpdySerializedFrame goaway(
5569       spdy_util_.ConstructSpdyGoAway(0, spdy::ERROR_CODE_FLOW_CONTROL_ERROR,
5570                                      "New spdy::SETTINGS_INITIAL_WINDOW_SIZE "
5571                                      "value overflows flow control window of "
5572                                      "stream 1."));
5573   MockWrite writes[] = {CreateMockWrite(req, 0),
5574                         CreateMockWrite(settings_ack, 3),
5575                         CreateMockWrite(goaway, 4)};
5576 
5577   SequencedSocketData data(reads, writes);
5578   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
5579   helper.RunToCompletion(&data);
5580   TransactionHelperResult out = helper.output();
5581   EXPECT_THAT(out.rv, IsError(ERR_HTTP2_FLOW_CONTROL_ERROR));
5582 }
5583 
5584 // Tests that we close the connection if we try to enqueue more frames than
5585 // the cap allows.
TEST_F(SpdyNetworkTransactionTest,SessionMaxQueuedCappedFramesExceeded)5586 TEST_F(SpdyNetworkTransactionTest, SessionMaxQueuedCappedFramesExceeded) {
5587   const int kTestSessionMaxQueuedCappedFrames = 5;
5588   const int kTestNumPings = kTestSessionMaxQueuedCappedFrames + 1;
5589   spdy::SettingsMap settings;
5590   settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] = 0xffff;
5591   spdy::SpdySerializedFrame settings_frame(
5592       spdy_util_.ConstructSpdySettings(settings));
5593   std::vector<spdy::SpdySerializedFrame> ping_frames;
5594 
5595   spdy::SpdySerializedFrame req(
5596       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
5597   spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
5598 
5599   std::vector<MockWrite> writes;
5600   std::vector<MockRead> reads;
5601   // Send request, receive SETTINGS and send a SETTINGS ACK.
5602   writes.push_back(CreateMockWrite(req, writes.size() + reads.size()));
5603   reads.push_back(CreateMockRead(settings_frame, writes.size() + reads.size()));
5604   writes.push_back(CreateMockWrite(settings_ack, writes.size() + reads.size()));
5605   // Receive more pings than our limit allows.
5606   for (int i = 1; i <= kTestNumPings; ++i) {
5607     ping_frames.push_back(
5608         spdy_util_.ConstructSpdyPing(/*ping_id=*/i, /*is_ack=*/false));
5609     reads.push_back(
5610         CreateMockRead(ping_frames.back(), writes.size() + reads.size()));
5611   }
5612   // Only write PING ACKs after receiving all of them to ensure they are all in
5613   // the write queue.
5614   for (int i = 1; i <= kTestNumPings; ++i) {
5615     ping_frames.push_back(
5616         spdy_util_.ConstructSpdyPing(/*ping_id=*/i, /*is_ack=*/true));
5617     writes.push_back(
5618         CreateMockWrite(ping_frames.back(), writes.size() + reads.size()));
5619   }
5620   // Stop reading.
5621   reads.emplace_back(ASYNC, 0, writes.size() + reads.size());
5622 
5623   SequencedSocketData data(reads, writes);
5624   auto session_deps = std::make_unique<SpdySessionDependencies>();
5625   session_deps->session_max_queued_capped_frames =
5626       kTestSessionMaxQueuedCappedFrames;
5627   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
5628                                      std::move(session_deps));
5629   helper.RunToCompletion(&data);
5630   TransactionHelperResult out = helper.output();
5631   EXPECT_THAT(out.rv, IsError(ERR_CONNECTION_CLOSED));
5632 }
5633 
5634 // Test that after hitting a send window size of 0, the write process
5635 // stalls and upon receiving WINDOW_UPDATE frame write resumes.
5636 
5637 // This test constructs a POST request followed by enough data frames
5638 // containing 'a' that would make the window size 0, followed by another
5639 // data frame containing default content (which is "hello!") and this frame
5640 // also contains a FIN flag.  SequencedSocketData is used to enforce all
5641 // writes, save the last, go through before a read could happen.  The last frame
5642 // ("hello!") is not permitted to go through since by the time its turn
5643 // arrives, window size is 0.  At this point MessageLoop::Run() called via
5644 // callback would block.  Therefore we call MessageLoop::RunUntilIdle()
5645 // which returns after performing all possible writes.  We use DCHECKS to
5646 // ensure that last data frame is still there and stream has stalled.
5647 // After that, next read is artifically enforced, which causes a
5648 // WINDOW_UPDATE to be read and I/O process resumes.
TEST_F(SpdyNetworkTransactionTest,FlowControlStallResume)5649 TEST_F(SpdyNetworkTransactionTest, FlowControlStallResume) {
5650   const int32_t initial_window_size = kDefaultInitialWindowSize;
5651   // Number of upload data buffers we need to send to zero out the window size
5652   // is the minimal number of upload buffers takes to be bigger than
5653   // |initial_window_size|.
5654   size_t num_upload_buffers =
5655       ceil(static_cast<double>(initial_window_size) / kBufferSize);
5656   // Each upload data buffer consists of |num_frames_in_one_upload_buffer|
5657   // frames, each with |kMaxSpdyFrameChunkSize| bytes except the last frame,
5658   // which has kBufferSize % kMaxSpdyChunkSize bytes.
5659   size_t num_frames_in_one_upload_buffer =
5660       ceil(static_cast<double>(kBufferSize) / kMaxSpdyFrameChunkSize);
5661 
5662   // Construct content for a data frame of maximum size.
5663   std::string content(kMaxSpdyFrameChunkSize, 'a');
5664 
5665   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
5666       kDefaultUrl, 1,
5667       /*content_length=*/kBufferSize * num_upload_buffers + kUploadDataSize,
5668       LOWEST, nullptr, 0));
5669 
5670   // Full frames.
5671   spdy::SpdySerializedFrame body1(
5672       spdy_util_.ConstructSpdyDataFrame(1, content, false));
5673 
5674   // Last frame in each upload data buffer.
5675   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(
5676       1,
5677       base::StringPiece(content.data(), kBufferSize % kMaxSpdyFrameChunkSize),
5678       false));
5679 
5680   // The very last frame before the stalled frames.
5681   spdy::SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(
5682       1,
5683       base::StringPiece(content.data(), initial_window_size % kBufferSize %
5684                                             kMaxSpdyFrameChunkSize),
5685       false));
5686 
5687   // Data frames to be sent once WINDOW_UPDATE frame is received.
5688 
5689   // If kBufferSize * num_upload_buffers > initial_window_size,
5690   // we need one additional frame to send the rest of 'a'.
5691   std::string last_body(kBufferSize * num_upload_buffers - initial_window_size,
5692                         'a');
5693   spdy::SpdySerializedFrame body4(
5694       spdy_util_.ConstructSpdyDataFrame(1, last_body, false));
5695 
5696   // Also send a "hello!" after WINDOW_UPDATE.
5697   spdy::SpdySerializedFrame body5(spdy_util_.ConstructSpdyDataFrame(1, true));
5698 
5699   // Fill in mock writes.
5700   size_t i = 0;
5701   std::vector<MockWrite> writes;
5702   writes.push_back(CreateMockWrite(req, i++));
5703   for (size_t j = 0; j < num_upload_buffers; j++) {
5704     for (size_t k = 0; k < num_frames_in_one_upload_buffer; k++) {
5705       if (j == num_upload_buffers - 1 &&
5706           (initial_window_size % kBufferSize != 0)) {
5707         writes.push_back(CreateMockWrite(body3, i++));
5708       } else if (k == num_frames_in_one_upload_buffer - 1 &&
5709                  kBufferSize % kMaxSpdyFrameChunkSize != 0) {
5710         writes.push_back(CreateMockWrite(body2, i++));
5711       } else {
5712         writes.push_back(CreateMockWrite(body1, i++));
5713       }
5714     }
5715   }
5716 
5717   // Fill in mock reads.
5718   std::vector<MockRead> reads;
5719   // Force a pause.
5720   reads.emplace_back(ASYNC, ERR_IO_PENDING, i++);
5721   // Construct read frame for window updates that gives enough space to upload
5722   // the rest of the data.
5723   spdy::SpdySerializedFrame session_window_update(
5724       spdy_util_.ConstructSpdyWindowUpdate(0,
5725                                            kUploadDataSize + last_body.size()));
5726   spdy::SpdySerializedFrame window_update(spdy_util_.ConstructSpdyWindowUpdate(
5727       1, kUploadDataSize + last_body.size()));
5728 
5729   reads.push_back(CreateMockRead(session_window_update, i++));
5730   reads.push_back(CreateMockRead(window_update, i++));
5731 
5732   // Stalled frames which can be sent after receiving window updates.
5733   if (last_body.size() > 0)
5734     writes.push_back(CreateMockWrite(body4, i++));
5735   writes.push_back(CreateMockWrite(body5, i++));
5736 
5737   spdy::SpdySerializedFrame reply(
5738       spdy_util_.ConstructSpdyPostReply(nullptr, 0));
5739   reads.push_back(CreateMockRead(reply, i++));
5740   reads.push_back(CreateMockRead(body2, i++));
5741   reads.push_back(CreateMockRead(body5, i++));
5742   reads.emplace_back(ASYNC, 0, i++);  // EOF
5743 
5744   SequencedSocketData data(reads, writes);
5745 
5746   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
5747   std::string upload_data_string(kBufferSize * num_upload_buffers, 'a');
5748   upload_data_string.append(kUploadData, kUploadDataSize);
5749   element_readers.push_back(std::make_unique<UploadBytesElementReader>(
5750       upload_data_string.c_str(), upload_data_string.size()));
5751   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
5752 
5753   request_.method = "POST";
5754   request_.upload_data_stream = &upload_data_stream;
5755   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
5756 
5757   helper.AddData(&data);
5758   helper.RunPreTestSetup();
5759 
5760   HttpNetworkTransaction* trans = helper.trans();
5761 
5762   TestCompletionCallback callback;
5763   int rv = trans->Start(&request_, callback.callback(), log_);
5764   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5765 
5766   base::RunLoop().RunUntilIdle();  // Write as much as we can.
5767 
5768   SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
5769   ASSERT_TRUE(stream);
5770   ASSERT_TRUE(stream->stream());
5771   EXPECT_EQ(0, stream->stream()->send_window_size());
5772   if (initial_window_size % kBufferSize != 0) {
5773     // If it does not take whole number of full upload buffer to zero out
5774     // initial window size, then the upload data is not at EOF, because the
5775     // last read must be stalled.
5776     EXPECT_FALSE(upload_data_stream.IsEOF());
5777   } else {
5778     // All the body data should have been read.
5779     // TODO(satorux): This is because of the weirdness in reading the request
5780     // body in OnSendBodyComplete(). See crbug.com/113107.
5781     EXPECT_TRUE(upload_data_stream.IsEOF());
5782   }
5783   // But the body is not yet fully sent (kUploadData is not yet sent)
5784   // since we're send-stalled.
5785   EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
5786 
5787   data.Resume();  // Read in WINDOW_UPDATE frame.
5788   rv = callback.WaitForResult();
5789   EXPECT_THAT(rv, IsOk());
5790 
5791   // Finish async network reads.
5792   base::RunLoop().RunUntilIdle();
5793   helper.VerifyDataConsumed();
5794 }
5795 
5796 // Test we correctly handle the case where the SETTINGS frame results in
5797 // unstalling the send window.
TEST_F(SpdyNetworkTransactionTest,FlowControlStallResumeAfterSettings)5798 TEST_F(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) {
5799   const int32_t initial_window_size = kDefaultInitialWindowSize;
5800   // Number of upload data buffers we need to send to zero out the window size
5801   // is the minimal number of upload buffers takes to be bigger than
5802   // |initial_window_size|.
5803   size_t num_upload_buffers =
5804       ceil(static_cast<double>(initial_window_size) / kBufferSize);
5805   // Each upload data buffer consists of |num_frames_in_one_upload_buffer|
5806   // frames, each with |kMaxSpdyFrameChunkSize| bytes except the last frame,
5807   // which has kBufferSize % kMaxSpdyChunkSize bytes.
5808   size_t num_frames_in_one_upload_buffer =
5809       ceil(static_cast<double>(kBufferSize) / kMaxSpdyFrameChunkSize);
5810 
5811   // Construct content for a data frame of maximum size.
5812   std::string content(kMaxSpdyFrameChunkSize, 'a');
5813 
5814   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
5815       kDefaultUrl, 1,
5816       /*content_length=*/kBufferSize * num_upload_buffers + kUploadDataSize,
5817       LOWEST, nullptr, 0));
5818 
5819   // Full frames.
5820   spdy::SpdySerializedFrame body1(
5821       spdy_util_.ConstructSpdyDataFrame(1, content, false));
5822 
5823   // Last frame in each upload data buffer.
5824   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(
5825       1,
5826       base::StringPiece(content.data(), kBufferSize % kMaxSpdyFrameChunkSize),
5827       false));
5828 
5829   // The very last frame before the stalled frames.
5830   spdy::SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(
5831       1,
5832       base::StringPiece(content.data(), initial_window_size % kBufferSize %
5833                                             kMaxSpdyFrameChunkSize),
5834       false));
5835 
5836   // Data frames to be sent once WINDOW_UPDATE frame is received.
5837 
5838   // If kBufferSize * num_upload_buffers > initial_window_size,
5839   // we need one additional frame to send the rest of 'a'.
5840   std::string last_body(kBufferSize * num_upload_buffers - initial_window_size,
5841                         'a');
5842   spdy::SpdySerializedFrame body4(
5843       spdy_util_.ConstructSpdyDataFrame(1, last_body, false));
5844 
5845   // Also send a "hello!" after WINDOW_UPDATE.
5846   spdy::SpdySerializedFrame body5(spdy_util_.ConstructSpdyDataFrame(1, true));
5847 
5848   // Fill in mock writes.
5849   size_t i = 0;
5850   std::vector<MockWrite> writes;
5851   writes.push_back(CreateMockWrite(req, i++));
5852   for (size_t j = 0; j < num_upload_buffers; j++) {
5853     for (size_t k = 0; k < num_frames_in_one_upload_buffer; k++) {
5854       if (j == num_upload_buffers - 1 &&
5855           (initial_window_size % kBufferSize != 0)) {
5856         writes.push_back(CreateMockWrite(body3, i++));
5857       } else if (k == num_frames_in_one_upload_buffer - 1 &&
5858                  kBufferSize % kMaxSpdyFrameChunkSize != 0) {
5859         writes.push_back(CreateMockWrite(body2, i++));
5860       } else {
5861         writes.push_back(CreateMockWrite(body1, i++));
5862       }
5863     }
5864   }
5865 
5866   // Fill in mock reads.
5867   std::vector<MockRead> reads;
5868   // Force a pause.
5869   reads.emplace_back(ASYNC, ERR_IO_PENDING, i++);
5870 
5871   // Construct read frame for SETTINGS that gives enough space to upload the
5872   // rest of the data.
5873   spdy::SettingsMap settings;
5874   settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] = initial_window_size * 2;
5875   spdy::SpdySerializedFrame settings_frame_large(
5876       spdy_util_.ConstructSpdySettings(settings));
5877 
5878   reads.push_back(CreateMockRead(settings_frame_large, i++));
5879 
5880   spdy::SpdySerializedFrame session_window_update(
5881       spdy_util_.ConstructSpdyWindowUpdate(0,
5882                                            last_body.size() + kUploadDataSize));
5883   reads.push_back(CreateMockRead(session_window_update, i++));
5884 
5885   spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
5886   writes.push_back(CreateMockWrite(settings_ack, i++));
5887 
5888   // Stalled frames which can be sent after |settings_ack|.
5889   if (last_body.size() > 0)
5890     writes.push_back(CreateMockWrite(body4, i++));
5891   writes.push_back(CreateMockWrite(body5, i++));
5892 
5893   spdy::SpdySerializedFrame reply(
5894       spdy_util_.ConstructSpdyPostReply(nullptr, 0));
5895   reads.push_back(CreateMockRead(reply, i++));
5896   reads.push_back(CreateMockRead(body2, i++));
5897   reads.push_back(CreateMockRead(body5, i++));
5898   reads.emplace_back(ASYNC, 0, i++);  // EOF
5899 
5900   // Force all writes to happen before any read, last write will not
5901   // actually queue a frame, due to window size being 0.
5902   SequencedSocketData data(reads, writes);
5903 
5904   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
5905   std::string upload_data_string(kBufferSize * num_upload_buffers, 'a');
5906   upload_data_string.append(kUploadData, kUploadDataSize);
5907   element_readers.push_back(std::make_unique<UploadBytesElementReader>(
5908       upload_data_string.c_str(), upload_data_string.size()));
5909   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
5910 
5911   request_.method = "POST";
5912   request_.upload_data_stream = &upload_data_stream;
5913   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
5914 
5915   helper.RunPreTestSetup();
5916   helper.AddData(&data);
5917 
5918   HttpNetworkTransaction* trans = helper.trans();
5919 
5920   TestCompletionCallback callback;
5921   int rv = trans->Start(&request_, callback.callback(), log_);
5922   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5923 
5924   data.RunUntilPaused();  // Write as much as we can.
5925   base::RunLoop().RunUntilIdle();
5926 
5927   SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
5928   ASSERT_TRUE(stream);
5929   ASSERT_TRUE(stream->stream());
5930   EXPECT_EQ(0, stream->stream()->send_window_size());
5931 
5932   if (initial_window_size % kBufferSize != 0) {
5933     // If it does not take whole number of full upload buffer to zero out
5934     // initial window size, then the upload data is not at EOF, because the
5935     // last read must be stalled.
5936     EXPECT_FALSE(upload_data_stream.IsEOF());
5937   } else {
5938     // All the body data should have been read.
5939     // TODO(satorux): This is because of the weirdness in reading the request
5940     // body in OnSendBodyComplete(). See crbug.com/113107.
5941     EXPECT_TRUE(upload_data_stream.IsEOF());
5942   }
5943   // But the body is not yet fully sent (kUploadData is not yet sent)
5944   // since we're send-stalled.
5945   EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
5946 
5947   // Read in SETTINGS frame to unstall.
5948   data.Resume();
5949   base::RunLoop().RunUntilIdle();
5950 
5951   rv = callback.WaitForResult();
5952   helper.VerifyDataConsumed();
5953   // If stream is nullptr, that means it was unstalled and closed.
5954   EXPECT_TRUE(stream->stream() == nullptr);
5955 }
5956 
5957 // Test we correctly handle the case where the SETTINGS frame results in a
5958 // negative send window size.
TEST_F(SpdyNetworkTransactionTest,FlowControlNegativeSendWindowSize)5959 TEST_F(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) {
5960   const int32_t initial_window_size = kDefaultInitialWindowSize;
5961   // Number of upload data buffers we need to send to zero out the window size
5962   // is the minimal number of upload buffers takes to be bigger than
5963   // |initial_window_size|.
5964   size_t num_upload_buffers =
5965       ceil(static_cast<double>(initial_window_size) / kBufferSize);
5966   // Each upload data buffer consists of |num_frames_in_one_upload_buffer|
5967   // frames, each with |kMaxSpdyFrameChunkSize| bytes except the last frame,
5968   // which has kBufferSize % kMaxSpdyChunkSize bytes.
5969   size_t num_frames_in_one_upload_buffer =
5970       ceil(static_cast<double>(kBufferSize) / kMaxSpdyFrameChunkSize);
5971 
5972   // Construct content for a data frame of maximum size.
5973   std::string content(kMaxSpdyFrameChunkSize, 'a');
5974 
5975   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
5976       kDefaultUrl, 1,
5977       /*content_length=*/kBufferSize * num_upload_buffers + kUploadDataSize,
5978       LOWEST, nullptr, 0));
5979 
5980   // Full frames.
5981   spdy::SpdySerializedFrame body1(
5982       spdy_util_.ConstructSpdyDataFrame(1, content, false));
5983 
5984   // Last frame in each upload data buffer.
5985   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(
5986       1,
5987       base::StringPiece(content.data(), kBufferSize % kMaxSpdyFrameChunkSize),
5988       false));
5989 
5990   // The very last frame before the stalled frames.
5991   spdy::SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(
5992       1,
5993       base::StringPiece(content.data(), initial_window_size % kBufferSize %
5994                                             kMaxSpdyFrameChunkSize),
5995       false));
5996 
5997   // Data frames to be sent once WINDOW_UPDATE frame is received.
5998 
5999   // If kBufferSize * num_upload_buffers > initial_window_size,
6000   // we need one additional frame to send the rest of 'a'.
6001   std::string last_body(kBufferSize * num_upload_buffers - initial_window_size,
6002                         'a');
6003   spdy::SpdySerializedFrame body4(
6004       spdy_util_.ConstructSpdyDataFrame(1, last_body, false));
6005 
6006   // Also send a "hello!" after WINDOW_UPDATE.
6007   spdy::SpdySerializedFrame body5(spdy_util_.ConstructSpdyDataFrame(1, true));
6008 
6009   // Fill in mock writes.
6010   size_t i = 0;
6011   std::vector<MockWrite> writes;
6012   writes.push_back(CreateMockWrite(req, i++));
6013   for (size_t j = 0; j < num_upload_buffers; j++) {
6014     for (size_t k = 0; k < num_frames_in_one_upload_buffer; k++) {
6015       if (j == num_upload_buffers - 1 &&
6016           (initial_window_size % kBufferSize != 0)) {
6017         writes.push_back(CreateMockWrite(body3, i++));
6018       } else if (k == num_frames_in_one_upload_buffer - 1 &&
6019                  kBufferSize % kMaxSpdyFrameChunkSize != 0) {
6020         writes.push_back(CreateMockWrite(body2, i++));
6021       } else {
6022         writes.push_back(CreateMockWrite(body1, i++));
6023       }
6024     }
6025   }
6026 
6027   // Fill in mock reads.
6028   std::vector<MockRead> reads;
6029   // Force a pause.
6030   reads.emplace_back(ASYNC, ERR_IO_PENDING, i++);
6031   // Construct read frame for SETTINGS that makes the send_window_size
6032   // negative.
6033   spdy::SettingsMap new_settings;
6034   new_settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] = initial_window_size / 2;
6035   spdy::SpdySerializedFrame settings_frame_small(
6036       spdy_util_.ConstructSpdySettings(new_settings));
6037   // Construct read frames for WINDOW_UPDATE that makes the send_window_size
6038   // positive.
6039   spdy::SpdySerializedFrame session_window_update_init_size(
6040       spdy_util_.ConstructSpdyWindowUpdate(0, initial_window_size));
6041   spdy::SpdySerializedFrame window_update_init_size(
6042       spdy_util_.ConstructSpdyWindowUpdate(1, initial_window_size));
6043 
6044   reads.push_back(CreateMockRead(settings_frame_small, i++));
6045   reads.push_back(CreateMockRead(session_window_update_init_size, i++));
6046   reads.push_back(CreateMockRead(window_update_init_size, i++));
6047 
6048   spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
6049   writes.push_back(CreateMockWrite(settings_ack, i++));
6050 
6051   // Stalled frames which can be sent after |settings_ack|.
6052   if (last_body.size() > 0)
6053     writes.push_back(CreateMockWrite(body4, i++));
6054   writes.push_back(CreateMockWrite(body5, i++));
6055 
6056   spdy::SpdySerializedFrame reply(
6057       spdy_util_.ConstructSpdyPostReply(nullptr, 0));
6058   reads.push_back(CreateMockRead(reply, i++));
6059   reads.push_back(CreateMockRead(body2, i++));
6060   reads.push_back(CreateMockRead(body5, i++));
6061   reads.emplace_back(ASYNC, 0, i++);  // EOF
6062 
6063   // Force all writes to happen before any read, last write will not
6064   // actually queue a frame, due to window size being 0.
6065   SequencedSocketData data(reads, writes);
6066 
6067   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
6068   std::string upload_data_string(kBufferSize * num_upload_buffers, 'a');
6069   upload_data_string.append(kUploadData, kUploadDataSize);
6070   element_readers.push_back(std::make_unique<UploadBytesElementReader>(
6071       upload_data_string.c_str(), upload_data_string.size()));
6072   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
6073 
6074   request_.method = "POST";
6075   request_.upload_data_stream = &upload_data_stream;
6076   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
6077 
6078   helper.RunPreTestSetup();
6079   helper.AddData(&data);
6080 
6081   HttpNetworkTransaction* trans = helper.trans();
6082 
6083   TestCompletionCallback callback;
6084   int rv = trans->Start(&request_, callback.callback(), log_);
6085   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6086 
6087   data.RunUntilPaused();  // Write as much as we can.
6088   base::RunLoop().RunUntilIdle();
6089 
6090   SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
6091   ASSERT_TRUE(stream);
6092   ASSERT_TRUE(stream->stream());
6093   EXPECT_EQ(0, stream->stream()->send_window_size());
6094 
6095   if (initial_window_size % kBufferSize != 0) {
6096     // If it does not take whole number of full upload buffer to zero out
6097     // initial window size, then the upload data is not at EOF, because the
6098     // last read must be stalled.
6099     EXPECT_FALSE(upload_data_stream.IsEOF());
6100   } else {
6101     // All the body data should have been read.
6102     // TODO(satorux): This is because of the weirdness in reading the request
6103     // body in OnSendBodyComplete(). See crbug.com/113107.
6104     EXPECT_TRUE(upload_data_stream.IsEOF());
6105   }
6106 
6107   // Read in WINDOW_UPDATE or SETTINGS frame.
6108   data.Resume();
6109   base::RunLoop().RunUntilIdle();
6110   rv = callback.WaitForResult();
6111   helper.VerifyDataConsumed();
6112 }
6113 
TEST_F(SpdyNetworkTransactionTest,ResetPush)6114 TEST_F(SpdyNetworkTransactionTest, ResetPush) {
6115   base::HistogramTester histogram_tester;
6116 
6117   spdy::Http2HeaderBlock push_headers;
6118   spdy_util_.AddUrlToHeaderBlock("http://www.example.org/a.dat", &push_headers);
6119   spdy::SpdySerializedFrame push(
6120       spdy_util_.ConstructSpdyPushPromise(1, 2, std::move(push_headers)));
6121   spdy::SpdySerializedFrame resp(
6122       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6123   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
6124   MockRead reads[] = {CreateMockRead(push, 1), CreateMockRead(resp, 3),
6125                       CreateMockRead(body, 4), MockRead(ASYNC, 0, 5)};
6126 
6127   spdy::SpdySerializedFrame req(
6128       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
6129   spdy::SpdySerializedFrame rst(
6130       spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
6131   MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(rst, 2)};
6132 
6133   SequencedSocketData data(reads, writes);
6134 
6135   auto session_deps = std::make_unique<SpdySessionDependencies>();
6136   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
6137                                      std::move(session_deps));
6138   helper.RunToCompletion(&data);
6139   TransactionHelperResult out = helper.output();
6140   EXPECT_THAT(out.rv, IsOk());
6141 
6142   histogram_tester.ExpectBucketCount(
6143       "Net.SpdyPushedStreamFate",
6144       static_cast<int>(SpdyPushedStreamFate::kPushDisabled), 1);
6145   histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
6146 }
6147 
6148 // Push streams must have even stream IDs. Test that an incoming push stream
6149 // with odd ID is reset the same way as one with even ID.
TEST_F(SpdyNetworkTransactionTest,ResetPushWithOddStreamId)6150 TEST_F(SpdyNetworkTransactionTest, ResetPushWithOddStreamId) {
6151   base::HistogramTester histogram_tester;
6152 
6153   spdy::Http2HeaderBlock push_headers;
6154   spdy_util_.AddUrlToHeaderBlock("http://www.example.org/a.dat", &push_headers);
6155   spdy::SpdySerializedFrame push(
6156       spdy_util_.ConstructSpdyPushPromise(1, 3, std::move(push_headers)));
6157   spdy::SpdySerializedFrame resp(
6158       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6159   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
6160   MockRead reads[] = {CreateMockRead(push, 1), CreateMockRead(resp, 3),
6161                       CreateMockRead(body, 4), MockRead(ASYNC, 0, 5)};
6162 
6163   spdy::SpdySerializedFrame req(
6164       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
6165   spdy::SpdySerializedFrame rst(
6166       spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_REFUSED_STREAM));
6167   MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(rst, 2)};
6168 
6169   SequencedSocketData data(reads, writes);
6170 
6171   auto session_deps = std::make_unique<SpdySessionDependencies>();
6172   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
6173                                      std::move(session_deps));
6174   helper.RunToCompletion(&data);
6175   TransactionHelperResult out = helper.output();
6176   EXPECT_THAT(out.rv, IsOk());
6177 
6178   histogram_tester.ExpectBucketCount(
6179       "Net.SpdyPushedStreamFate",
6180       static_cast<int>(SpdyPushedStreamFate::kPushDisabled), 1);
6181   histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
6182 }
6183 
6184 // Regression test for https://crbug.com/493348: request header exceeds 16 kB
6185 // and thus sent in multiple frames when using HTTP/2.
TEST_F(SpdyNetworkTransactionTest,LargeRequest)6186 TEST_F(SpdyNetworkTransactionTest, LargeRequest) {
6187   const std::string kKey("foo");
6188   const std::string kValue(1 << 15, 'z');
6189 
6190   request_.extra_headers.SetHeader(kKey, kValue);
6191 
6192   spdy::Http2HeaderBlock headers(
6193       spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
6194   headers[kKey] = kValue;
6195   spdy::SpdySerializedFrame req(
6196       spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
6197   MockWrite writes[] = {
6198       CreateMockWrite(req, 0),
6199   };
6200 
6201   spdy::SpdySerializedFrame resp(
6202       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6203   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
6204   MockRead reads[] = {
6205       CreateMockRead(resp, 1), CreateMockRead(body, 2),
6206       MockRead(ASYNC, 0, 3)  // EOF
6207   };
6208 
6209   SequencedSocketData data(reads, writes);
6210   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
6211   helper.RunToCompletion(&data);
6212   TransactionHelperResult out = helper.output();
6213 
6214   EXPECT_THAT(out.rv, IsOk());
6215   EXPECT_EQ("HTTP/1.1 200", out.status_line);
6216   EXPECT_EQ("hello!", out.response_data);
6217 }
6218 
6219 // Regression test for https://crbug.com/535629: response header exceeds 16 kB.
TEST_F(SpdyNetworkTransactionTest,LargeResponseHeader)6220 TEST_F(SpdyNetworkTransactionTest, LargeResponseHeader) {
6221   spdy::Http2HeaderBlock headers(
6222       spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
6223   spdy::SpdySerializedFrame req(
6224       spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
6225   MockWrite writes[] = {
6226       CreateMockWrite(req, 0),
6227   };
6228 
6229   // HPACK decoder implementation limits string literal length to 16 kB.
6230   const char* response_headers[2];
6231   const std::string kKey(16 * 1024, 'a');
6232   response_headers[0] = kKey.data();
6233   const std::string kValue(16 * 1024, 'b');
6234   response_headers[1] = kValue.data();
6235 
6236   spdy::SpdySerializedFrame resp(
6237       spdy_util_.ConstructSpdyGetReply(response_headers, 1, 1));
6238   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
6239   MockRead reads[] = {
6240       CreateMockRead(resp, 1), CreateMockRead(body, 2),
6241       MockRead(ASYNC, 0, 3)  // EOF
6242   };
6243 
6244   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
6245 
6246   SequencedSocketData data(reads, writes);
6247   helper.RunToCompletion(&data);
6248   TransactionHelperResult out = helper.output();
6249 
6250   EXPECT_THAT(out.rv, IsOk());
6251   EXPECT_EQ("HTTP/1.1 200", out.status_line);
6252   EXPECT_EQ("hello!", out.response_data);
6253   ASSERT_TRUE(out.response_info.headers->HasHeaderValue(kKey, kValue));
6254 }
6255 
6256 // End of line delimiter is forbidden according to RFC 7230 Section 3.2.
TEST_F(SpdyNetworkTransactionTest,CRLFInHeaderValue)6257 TEST_F(SpdyNetworkTransactionTest, CRLFInHeaderValue) {
6258   spdy::SpdySerializedFrame req(
6259       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
6260   spdy::SpdySerializedFrame rst(
6261       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
6262   MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(rst, 2)};
6263 
6264   const char* response_headers[] = {"folded", "foo\r\nbar"};
6265   spdy::SpdySerializedFrame resp(
6266       spdy_util_.ConstructSpdyGetReply(response_headers, 1, 1));
6267   MockRead reads[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3)};
6268 
6269   SequencedSocketData data(reads, writes);
6270 
6271   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
6272   helper.RunToCompletion(&data);
6273   TransactionHelperResult out = helper.output();
6274 
6275   EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
6276 }
6277 
6278 // Regression test for https://crbug.com/603182.
6279 // No response headers received before RST_STREAM: error.
TEST_F(SpdyNetworkTransactionTest,RstStreamNoError)6280 TEST_F(SpdyNetworkTransactionTest, RstStreamNoError) {
6281   spdy::SpdySerializedFrame req(
6282       spdy_util_.ConstructChunkedSpdyPost(nullptr, 0));
6283   MockWrite writes[] = {CreateMockWrite(req, 0, ASYNC)};
6284 
6285   spdy::SpdySerializedFrame rst(
6286       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_NO_ERROR));
6287   MockRead reads[] = {CreateMockRead(rst, 1), MockRead(ASYNC, 0, 2)};
6288 
6289   SequencedSocketData data(reads, writes);
6290   UseChunkedPostRequest();
6291   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
6292   helper.RunToCompletion(&data);
6293   TransactionHelperResult out = helper.output();
6294   EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
6295 }
6296 
6297 // Regression test for https://crbug.com/603182.
6298 // Response headers and data, then RST_STREAM received,
6299 // before request body is sent: success.
TEST_F(SpdyNetworkTransactionTest,RstStreamNoErrorAfterResponse)6300 TEST_F(SpdyNetworkTransactionTest, RstStreamNoErrorAfterResponse) {
6301   spdy::SpdySerializedFrame req(
6302       spdy_util_.ConstructChunkedSpdyPost(nullptr, 0));
6303   MockWrite writes[] = {CreateMockWrite(req, 0, ASYNC)};
6304 
6305   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
6306   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
6307   spdy::SpdySerializedFrame rst(
6308       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_NO_ERROR));
6309   MockRead reads[] = {CreateMockRead(resp, 1), CreateMockRead(body, 2),
6310                       CreateMockRead(rst, 3), MockRead(ASYNC, 0, 4)};
6311 
6312   SequencedSocketData data(reads, writes);
6313   UseChunkedPostRequest();
6314   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
6315   helper.RunToCompletion(&data);
6316   TransactionHelperResult out = helper.output();
6317   EXPECT_THAT(out.rv, IsOk());
6318   EXPECT_EQ("HTTP/1.1 200", out.status_line);
6319   EXPECT_EQ("hello!", out.response_data);
6320 }
6321 
6322 TEST_F(SpdyNetworkTransactionTest, 100Continue) {
6323   spdy::SpdySerializedFrame req(
6324       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
6325   MockWrite writes[] = {CreateMockWrite(req, 0)};
6326 
6327   spdy::Http2HeaderBlock informational_headers;
6328   informational_headers[spdy::kHttp2StatusHeader] = "100";
6329   spdy::SpdySerializedFrame informational_response(
6330       spdy_util_.ConstructSpdyReply(1, std::move(informational_headers)));
6331   spdy::SpdySerializedFrame resp(
6332       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6333   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
6334   MockRead reads[] = {
6335       CreateMockRead(informational_response, 1), CreateMockRead(resp, 2),
6336       CreateMockRead(body, 3), MockRead(ASYNC, 0, 4)  // EOF
6337   };
6338 
6339   SequencedSocketData data(reads, writes);
6340   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
6341   helper.RunToCompletion(&data);
6342   TransactionHelperResult out = helper.output();
6343   EXPECT_THAT(out.rv, IsOk());
6344   EXPECT_EQ("HTTP/1.1 200", out.status_line);
6345   EXPECT_EQ("hello!", out.response_data);
6346 }
6347 
6348 // "A server can send a complete response prior to the client sending an entire
6349 // request if the response does not depend on any portion of the request that
6350 // has not been sent and received."  (RFC7540 Section 8.1)
6351 // Regression test for https://crbug.com/606990.  Server responds before POST
6352 // data are sent and closes connection: this must result in
6353 // ERR_CONNECTION_CLOSED (as opposed to ERR_HTTP2_PROTOCOL_ERROR).
TEST_F(SpdyNetworkTransactionTest,ResponseBeforePostDataSent)6354 TEST_F(SpdyNetworkTransactionTest, ResponseBeforePostDataSent) {
6355   spdy::SpdySerializedFrame req(
6356       spdy_util_.ConstructChunkedSpdyPost(nullptr, 0));
6357   MockWrite writes[] = {CreateMockWrite(req, 0)};
6358 
6359   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
6360   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
6361   MockRead reads[] = {CreateMockRead(resp, 1), CreateMockRead(body, 2),
6362                       MockRead(ASYNC, 0, 3)};
6363 
6364   SequencedSocketData data(reads, writes);
6365   UseChunkedPostRequest();
6366   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
6367 
6368   helper.RunPreTestSetup();
6369   helper.AddData(&data);
6370   helper.StartDefaultTest();
6371   EXPECT_THAT(helper.output().rv, IsError(ERR_IO_PENDING));
6372   helper.WaitForCallbackToComplete();
6373   EXPECT_THAT(helper.output().rv, IsError(ERR_CONNECTION_CLOSED));
6374 }
6375 
6376 // Regression test for https://crbug.com/606990.
6377 // Server responds before POST data are sent and resets stream with NO_ERROR.
TEST_F(SpdyNetworkTransactionTest,ResponseAndRstStreamBeforePostDataSent)6378 TEST_F(SpdyNetworkTransactionTest, ResponseAndRstStreamBeforePostDataSent) {
6379   spdy::SpdySerializedFrame req(
6380       spdy_util_.ConstructChunkedSpdyPost(nullptr, 0));
6381   MockWrite writes[] = {CreateMockWrite(req, 0)};
6382 
6383   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
6384   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
6385   spdy::SpdySerializedFrame rst(
6386       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_NO_ERROR));
6387   MockRead reads[] = {CreateMockRead(resp, 1), CreateMockRead(body, 2),
6388                       CreateMockRead(rst, 3), MockRead(ASYNC, 0, 4)};
6389 
6390   SequencedSocketData data(reads, writes);
6391   UseChunkedPostRequest();
6392   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
6393 
6394   helper.RunToCompletion(&data);
6395 
6396   TransactionHelperResult out = helper.output();
6397   EXPECT_THAT(out.rv, IsOk());
6398   EXPECT_EQ("HTTP/1.1 200", out.status_line);
6399   EXPECT_EQ("hello!", out.response_data);
6400 }
6401 
6402 // Unsupported frames must be ignored.  This is especially important for frame
6403 // type 0xb, which used to be the BLOCKED frame in previous versions of SPDY,
6404 // but is going to be used for the ORIGIN frame.
6405 // TODO(bnc): Implement ORIGIN frame support.  https://crbug.com/697333
TEST_F(SpdyNetworkTransactionTest,IgnoreUnsupportedOriginFrame)6406 TEST_F(SpdyNetworkTransactionTest, IgnoreUnsupportedOriginFrame) {
6407   spdy::SpdySerializedFrame req(
6408       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
6409   MockWrite writes[] = {CreateMockWrite(req, 0)};
6410 
6411   const char origin_frame_on_stream_zero[] = {
6412       0x00, 0x00, 0x05,        // Length
6413       0x0b,                    // Type
6414       0x00,                    // Flags
6415       0x00, 0x00, 0x00, 0x00,  // Stream ID
6416       0x00, 0x03,              // Origin-Len
6417       'f',  'o',  'o'          // ASCII-Origin
6418   };
6419 
6420   const char origin_frame_on_stream_one[] = {
6421       0x00, 0x00, 0x05,        // Length
6422       0x0b,                    // Type
6423       0x00,                    // Flags
6424       0x00, 0x00, 0x00, 0x01,  // Stream ID
6425       0x00, 0x03,              // Origin-Len
6426       'b',  'a',  'r'          // ASCII-Origin
6427   };
6428 
6429   spdy::SpdySerializedFrame resp(
6430       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6431   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
6432   MockRead reads[] = {MockRead(ASYNC, origin_frame_on_stream_zero,
6433                                std::size(origin_frame_on_stream_zero), 1),
6434                       CreateMockRead(resp, 2),
6435                       MockRead(ASYNC, origin_frame_on_stream_one,
6436                                std::size(origin_frame_on_stream_one), 3),
6437                       CreateMockRead(body, 4), MockRead(ASYNC, 0, 5)};
6438 
6439   SequencedSocketData data(reads, writes);
6440   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
6441   helper.RunToCompletion(&data);
6442   TransactionHelperResult out = helper.output();
6443   EXPECT_THAT(out.rv, IsOk());
6444   EXPECT_EQ("HTTP/1.1 200", out.status_line);
6445   EXPECT_EQ("hello!", out.response_data);
6446 }
6447 
6448 class SpdyNetworkTransactionTLSUsageCheckTest
6449     : public SpdyNetworkTransactionTest {
6450  protected:
RunTLSUsageCheckTest(std::unique_ptr<SSLSocketDataProvider> ssl_provider)6451   void RunTLSUsageCheckTest(
6452       std::unique_ptr<SSLSocketDataProvider> ssl_provider) {
6453     spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
6454         0, spdy::ERROR_CODE_INADEQUATE_SECURITY, ""));
6455     MockWrite writes[] = {CreateMockWrite(goaway)};
6456 
6457     StaticSocketDataProvider data(base::span<MockRead>(), writes);
6458     NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
6459                                        nullptr);
6460     helper.RunToCompletionWithSSLData(&data, std::move(ssl_provider));
6461     TransactionHelperResult out = helper.output();
6462     EXPECT_THAT(out.rv, IsError(ERR_HTTP2_INADEQUATE_TRANSPORT_SECURITY));
6463   }
6464 };
6465 
TEST_F(SpdyNetworkTransactionTLSUsageCheckTest,TLSVersionTooOld)6466 TEST_F(SpdyNetworkTransactionTLSUsageCheckTest, TLSVersionTooOld) {
6467   auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
6468   SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_SSL3,
6469                                 &ssl_provider->ssl_info.connection_status);
6470 
6471   RunTLSUsageCheckTest(std::move(ssl_provider));
6472 }
6473 
TEST_F(SpdyNetworkTransactionTLSUsageCheckTest,TLSCipherSuiteSucky)6474 TEST_F(SpdyNetworkTransactionTLSUsageCheckTest, TLSCipherSuiteSucky) {
6475   auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
6476   // Set to TLS_RSA_WITH_NULL_MD5
6477   SSLConnectionStatusSetCipherSuite(0x1,
6478                                     &ssl_provider->ssl_info.connection_status);
6479 
6480   RunTLSUsageCheckTest(std::move(ssl_provider));
6481 }
6482 
6483 // Regression test for https://crbug.com/737143.
6484 // This test sets up an old TLS version just like in TLSVersionTooOld,
6485 // and makes sure that it results in an spdy::ERROR_CODE_INADEQUATE_SECURITY
6486 // even for a non-secure request URL.
TEST_F(SpdyNetworkTransactionTest,InsecureUrlCreatesSecureSpdySession)6487 TEST_F(SpdyNetworkTransactionTest, InsecureUrlCreatesSecureSpdySession) {
6488   auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
6489   SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_SSL3,
6490                                 &ssl_provider->ssl_info.connection_status);
6491 
6492   spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
6493       0, spdy::ERROR_CODE_INADEQUATE_SECURITY, ""));
6494   MockWrite writes[] = {CreateMockWrite(goaway)};
6495   StaticSocketDataProvider data(base::span<MockRead>(), writes);
6496 
6497   request_.url = GURL("http://www.example.org/");
6498 
6499   // Need secure proxy so that insecure URL can use HTTP/2.
6500   auto session_deps = std::make_unique<SpdySessionDependencies>(
6501       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
6502           "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
6503   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
6504                                      std::move(session_deps));
6505 
6506   helper.RunToCompletionWithSSLData(&data, std::move(ssl_provider));
6507   TransactionHelperResult out = helper.output();
6508   EXPECT_THAT(out.rv, IsError(ERR_HTTP2_INADEQUATE_TRANSPORT_SECURITY));
6509 }
6510 
TEST_F(SpdyNetworkTransactionTest,RequestHeadersCallback)6511 TEST_F(SpdyNetworkTransactionTest, RequestHeadersCallback) {
6512   spdy::SpdySerializedFrame req(
6513       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, DEFAULT_PRIORITY));
6514   MockWrite writes[] = {CreateMockWrite(req, 0)};
6515 
6516   spdy::SpdySerializedFrame resp(
6517       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6518   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
6519   MockRead reads[] = {
6520       CreateMockRead(resp, 1), CreateMockRead(body, 2),
6521       MockRead(ASYNC, 0, 3)  // EOF
6522   };
6523 
6524   HttpRawRequestHeaders raw_headers;
6525 
6526   SequencedSocketData data(reads, writes);
6527   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
6528   helper.RunPreTestSetup();
6529   helper.AddData(&data);
6530   helper.trans()->SetRequestHeadersCallback(base::BindRepeating(
6531       &HttpRawRequestHeaders::Assign, base::Unretained(&raw_headers)));
6532   helper.StartDefaultTest();
6533   helper.FinishDefaultTestWithoutVerification();
6534   EXPECT_FALSE(raw_headers.headers().empty());
6535   std::string value;
6536   EXPECT_TRUE(raw_headers.FindHeaderForTest(":path", &value));
6537   EXPECT_EQ("/", value);
6538   EXPECT_TRUE(raw_headers.FindHeaderForTest(":method", &value));
6539   EXPECT_EQ("GET", value);
6540   EXPECT_TRUE(raw_headers.request_line().empty());
6541 }
6542 
6543 #if BUILDFLAG(ENABLE_WEBSOCKETS)
6544 
TEST_F(SpdyNetworkTransactionTest,WebSocketOpensNewConnection)6545 TEST_F(SpdyNetworkTransactionTest, WebSocketOpensNewConnection) {
6546   base::HistogramTester histogram_tester;
6547   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
6548   helper.RunPreTestSetup();
6549 
6550   // First request opens up an HTTP/2 connection.
6551   spdy::SpdySerializedFrame req(
6552       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, DEFAULT_PRIORITY));
6553   MockWrite writes1[] = {CreateMockWrite(req, 0)};
6554 
6555   spdy::SpdySerializedFrame resp(
6556       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6557   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
6558   MockRead reads1[] = {CreateMockRead(resp, 1), CreateMockRead(body, 2),
6559                        MockRead(ASYNC, ERR_IO_PENDING, 3),
6560                        MockRead(ASYNC, 0, 4)};
6561 
6562   SequencedSocketData data1(reads1, writes1);
6563   helper.AddData(&data1);
6564 
6565   // WebSocket request opens a new connection with HTTP/2 disabled.
6566   MockWrite writes2[] = {
6567       MockWrite("GET / HTTP/1.1\r\n"
6568                 "Host: www.example.org\r\n"
6569                 "Connection: Upgrade\r\n"
6570                 "Upgrade: websocket\r\n"
6571                 "Origin: http://www.example.org\r\n"
6572                 "Sec-WebSocket-Version: 13\r\n"
6573                 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
6574                 "Sec-WebSocket-Extensions: permessage-deflate; "
6575                 "client_max_window_bits\r\n\r\n")};
6576 
6577   MockRead reads2[] = {
6578       MockRead("HTTP/1.1 101 Switching Protocols\r\n"
6579                "Upgrade: websocket\r\n"
6580                "Connection: Upgrade\r\n"
6581                "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
6582 
6583   StaticSocketDataProvider data2(reads2, writes2);
6584 
6585   auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
6586   // Test that the request has HTTP/2 disabled.
6587   ssl_provider2->next_protos_expected_in_ssl_config = {kProtoHTTP11};
6588   // Force socket to use HTTP/1.1, the default protocol without ALPN.
6589   ssl_provider2->next_proto = kProtoHTTP11;
6590   ssl_provider2->ssl_info.cert =
6591       ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
6592   helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2));
6593 
6594   TestCompletionCallback callback1;
6595   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
6596   int rv = trans1.Start(&request_, callback1.callback(), log_);
6597   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
6598   rv = callback1.WaitForResult();
6599   ASSERT_THAT(rv, IsOk());
6600 
6601   const HttpResponseInfo* response = trans1.GetResponseInfo();
6602   ASSERT_TRUE(response->headers);
6603   EXPECT_TRUE(response->was_fetched_via_spdy);
6604   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6605 
6606   std::string response_data;
6607   rv = ReadTransaction(&trans1, &response_data);
6608   EXPECT_THAT(rv, IsOk());
6609   EXPECT_EQ("hello!", response_data);
6610 
6611   SpdySessionKey key(HostPortPair::FromURL(request_.url), ProxyServer::Direct(),
6612                      PRIVACY_MODE_DISABLED,
6613                      SpdySessionKey::IsProxySession::kFalse, SocketTag(),
6614                      NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
6615   base::WeakPtr<SpdySession> spdy_session =
6616       helper.session()->spdy_session_pool()->FindAvailableSession(
6617           key, /* enable_ip_based_pooling = */ true,
6618           /* is_websocket = */ false, log_);
6619   ASSERT_TRUE(spdy_session);
6620   EXPECT_FALSE(spdy_session->support_websocket());
6621 
6622   HttpRequestInfo request2;
6623   request2.method = "GET";
6624   request2.url = GURL("wss://www.example.org/");
6625   request2.traffic_annotation =
6626       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6627   EXPECT_TRUE(HostPortPair::FromURL(request_.url)
6628                   .Equals(HostPortPair::FromURL(request2.url)));
6629   request2.extra_headers.SetHeader("Connection", "Upgrade");
6630   request2.extra_headers.SetHeader("Upgrade", "websocket");
6631   request2.extra_headers.SetHeader("Origin", "http://www.example.org");
6632   request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
6633 
6634   TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
6635 
6636   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
6637   trans2.SetWebSocketHandshakeStreamCreateHelper(
6638       &websocket_stream_create_helper);
6639 
6640   TestCompletionCallback callback2;
6641   rv = trans2.Start(&request2, callback2.callback(), log_);
6642   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
6643   rv = callback2.WaitForResult();
6644   ASSERT_THAT(rv, IsOk());
6645 
6646   // HTTP/2 connection is still open, but WebSocket request did not pool to it.
6647   ASSERT_TRUE(spdy_session);
6648 
6649   data1.Resume();
6650   base::RunLoop().RunUntilIdle();
6651   helper.VerifyDataConsumed();
6652 
6653   // Server did not advertise WebSocket support.
6654   histogram_tester.ExpectUniqueSample("Net.SpdySession.ServerSupportsWebSocket",
6655                                       /* support_websocket = false */ 0,
6656                                       /* expected_count = */ 1);
6657 }
6658 
6659 // Make sure that a WebSocket job doesn't pick up a newly created SpdySession
6660 // that doesn't support WebSockets through
6661 // HttpStreamFactory::Job::OnSpdySessionAvailable().
TEST_F(SpdyNetworkTransactionTest,WebSocketDoesUseNewH2SessionWithoutWebSocketSupport)6662 TEST_F(SpdyNetworkTransactionTest,
6663        WebSocketDoesUseNewH2SessionWithoutWebSocketSupport) {
6664   base::HistogramTester histogram_tester;
6665   auto session_deps = std::make_unique<SpdySessionDependencies>();
6666   NormalSpdyTransactionHelper helper(request_, HIGHEST, log_,
6667                                      std::move(session_deps));
6668   helper.RunPreTestSetup();
6669 
6670   spdy::SpdySerializedFrame req(
6671       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
6672 
6673   MockWrite writes[] = {CreateMockWrite(req, 0)};
6674 
6675   spdy::SpdySerializedFrame resp1(
6676       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6677   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
6678   MockRead reads[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
6679                       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
6680 
6681   SequencedSocketData data(
6682       // Just as with other operations, this means to pause during connection
6683       // establishment.
6684       MockConnect(ASYNC, ERR_IO_PENDING), reads, writes);
6685   helper.AddData(&data);
6686 
6687   MockWrite writes2[] = {
6688       MockWrite(SYNCHRONOUS, 0,
6689                 "GET / HTTP/1.1\r\n"
6690                 "Host: www.example.org\r\n"
6691                 "Connection: Upgrade\r\n"
6692                 "Upgrade: websocket\r\n"
6693                 "Origin: http://www.example.org\r\n"
6694                 "Sec-WebSocket-Version: 13\r\n"
6695                 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
6696                 "Sec-WebSocket-Extensions: permessage-deflate; "
6697                 "client_max_window_bits\r\n\r\n")};
6698 
6699   MockRead reads2[] = {
6700       MockRead(SYNCHRONOUS, 1,
6701                "HTTP/1.1 101 Switching Protocols\r\n"
6702                "Upgrade: websocket\r\n"
6703                "Connection: Upgrade\r\n"
6704                "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
6705   SequencedSocketData data2(MockConnect(ASYNC, ERR_IO_PENDING), reads2,
6706                             writes2);
6707   auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
6708   // Test that the request has HTTP/2 disabled.
6709   ssl_provider2->next_protos_expected_in_ssl_config = {kProtoHTTP11};
6710   // Force socket to use HTTP/1.1, the default protocol without ALPN.
6711   ssl_provider2->next_proto = kProtoHTTP11;
6712   helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2));
6713 
6714   TestCompletionCallback callback1;
6715   int rv = helper.trans()->Start(&request_, callback1.callback(), log_);
6716   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
6717 
6718   // Create HTTP/2 connection.
6719   base::RunLoop().RunUntilIdle();
6720 
6721   HttpRequestInfo request2;
6722   request2.method = "GET";
6723   request2.url = GURL("wss://www.example.org/");
6724   request2.traffic_annotation =
6725       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6726   EXPECT_TRUE(HostPortPair::FromURL(request_.url)
6727                   .Equals(HostPortPair::FromURL(request2.url)));
6728   request2.extra_headers.SetHeader("Connection", "Upgrade");
6729   request2.extra_headers.SetHeader("Upgrade", "websocket");
6730   request2.extra_headers.SetHeader("Origin", "http://www.example.org");
6731   request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
6732 
6733   TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
6734 
6735   HttpNetworkTransaction trans2(MEDIUM, helper.session());
6736   trans2.SetWebSocketHandshakeStreamCreateHelper(
6737       &websocket_stream_create_helper);
6738 
6739   TestCompletionCallback callback2;
6740   rv = trans2.Start(&request2, callback2.callback(), log_);
6741   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
6742 
6743   // Run until waiting on both connections.
6744   base::RunLoop().RunUntilIdle();
6745 
6746   // The H2 connection completes.
6747   data.socket()->OnConnectComplete(MockConnect(SYNCHRONOUS, OK));
6748   EXPECT_EQ(OK, callback1.WaitForResult());
6749   const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
6750   ASSERT_TRUE(response->headers);
6751   EXPECT_TRUE(response->was_fetched_via_spdy);
6752   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6753   std::string response_data;
6754   rv = ReadTransaction(helper.trans(), &response_data);
6755   EXPECT_THAT(rv, IsOk());
6756   EXPECT_EQ("hello!", response_data);
6757 
6758   SpdySessionKey key(HostPortPair::FromURL(request_.url), ProxyServer::Direct(),
6759                      PRIVACY_MODE_DISABLED,
6760                      SpdySessionKey::IsProxySession::kFalse, SocketTag(),
6761                      NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
6762 
6763   base::WeakPtr<SpdySession> spdy_session =
6764       helper.session()->spdy_session_pool()->FindAvailableSession(
6765           key, /* enable_ip_based_pooling = */ true,
6766           /* is_websocket = */ false, log_);
6767   ASSERT_TRUE(spdy_session);
6768   EXPECT_FALSE(spdy_session->support_websocket());
6769 
6770   EXPECT_FALSE(callback2.have_result());
6771 
6772   // Create WebSocket stream.
6773   data2.socket()->OnConnectComplete(MockConnect(SYNCHRONOUS, OK));
6774 
6775   rv = callback2.WaitForResult();
6776   ASSERT_THAT(rv, IsOk());
6777   helper.VerifyDataConsumed();
6778 }
6779 
TEST_F(SpdyNetworkTransactionTest,WebSocketOverHTTP2)6780 TEST_F(SpdyNetworkTransactionTest, WebSocketOverHTTP2) {
6781   base::HistogramTester histogram_tester;
6782   auto session_deps = std::make_unique<SpdySessionDependencies>();
6783   NormalSpdyTransactionHelper helper(request_, HIGHEST, log_,
6784                                      std::move(session_deps));
6785   helper.RunPreTestSetup();
6786 
6787   spdy::SpdySerializedFrame req(
6788       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
6789   spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
6790 
6791   spdy::Http2HeaderBlock websocket_request_headers;
6792   websocket_request_headers[spdy::kHttp2MethodHeader] = "CONNECT";
6793   websocket_request_headers[spdy::kHttp2AuthorityHeader] = "www.example.org";
6794   websocket_request_headers[spdy::kHttp2SchemeHeader] = "https";
6795   websocket_request_headers[spdy::kHttp2PathHeader] = "/";
6796   websocket_request_headers[spdy::kHttp2ProtocolHeader] = "websocket";
6797   websocket_request_headers["origin"] = "http://www.example.org";
6798   websocket_request_headers["sec-websocket-version"] = "13";
6799   websocket_request_headers["sec-websocket-extensions"] =
6800       "permessage-deflate; client_max_window_bits";
6801   spdy::SpdySerializedFrame websocket_request(spdy_util_.ConstructSpdyHeaders(
6802       3, std::move(websocket_request_headers), MEDIUM, false));
6803 
6804   spdy::SpdySerializedFrame priority1(
6805       spdy_util_.ConstructSpdyPriority(3, 0, MEDIUM, true));
6806   spdy::SpdySerializedFrame priority2(
6807       spdy_util_.ConstructSpdyPriority(1, 3, LOWEST, true));
6808 
6809   MockWrite writes[] = {
6810       CreateMockWrite(req, 0), CreateMockWrite(settings_ack, 2),
6811       CreateMockWrite(websocket_request, 4), CreateMockWrite(priority1, 5),
6812       CreateMockWrite(priority2, 6)};
6813 
6814   spdy::SettingsMap settings;
6815   settings[spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
6816   spdy::SpdySerializedFrame settings_frame(
6817       spdy_util_.ConstructSpdySettings(settings));
6818   spdy::SpdySerializedFrame resp1(
6819       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6820   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
6821   spdy::SpdySerializedFrame websocket_response(
6822       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
6823   MockRead reads[] = {CreateMockRead(settings_frame, 1),
6824                       CreateMockRead(resp1, 3), CreateMockRead(body1, 7),
6825                       CreateMockRead(websocket_response, 8),
6826                       MockRead(ASYNC, 0, 9)};
6827 
6828   SequencedSocketData data(reads, writes);
6829   helper.AddData(&data);
6830 
6831   TestCompletionCallback callback1;
6832   int rv = helper.trans()->Start(&request_, callback1.callback(), log_);
6833   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
6834 
6835   // Create HTTP/2 connection.
6836   base::RunLoop().RunUntilIdle();
6837 
6838   SpdySessionKey key(HostPortPair::FromURL(request_.url), ProxyServer::Direct(),
6839                      PRIVACY_MODE_DISABLED,
6840                      SpdySessionKey::IsProxySession::kFalse, SocketTag(),
6841                      NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
6842   base::WeakPtr<SpdySession> spdy_session =
6843       helper.session()->spdy_session_pool()->FindAvailableSession(
6844           key, /* enable_ip_based_pooling = */ true,
6845           /* is_websocket = */ true, log_);
6846   ASSERT_TRUE(spdy_session);
6847   EXPECT_TRUE(spdy_session->support_websocket());
6848 
6849   HttpRequestInfo request2;
6850   request2.method = "GET";
6851   request2.url = GURL("wss://www.example.org/");
6852   request2.traffic_annotation =
6853       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6854   EXPECT_TRUE(HostPortPair::FromURL(request_.url)
6855                   .Equals(HostPortPair::FromURL(request2.url)));
6856   request2.extra_headers.SetHeader("Origin", "http://www.example.org");
6857   request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
6858   // The following two headers must be removed by WebSocketHttp2HandshakeStream.
6859   request2.extra_headers.SetHeader("Connection", "Upgrade");
6860   request2.extra_headers.SetHeader("Upgrade", "websocket");
6861 
6862   TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
6863 
6864   HttpNetworkTransaction trans2(MEDIUM, helper.session());
6865   trans2.SetWebSocketHandshakeStreamCreateHelper(
6866       &websocket_stream_create_helper);
6867 
6868   TestCompletionCallback callback2;
6869   rv = trans2.Start(&request2, callback2.callback(), log_);
6870   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
6871 
6872   // Create WebSocket stream.
6873   base::RunLoop().RunUntilIdle();
6874   ASSERT_TRUE(spdy_session);
6875 
6876   // First request has HIGHEST priority, WebSocket request has MEDIUM priority.
6877   // Changing the priority of the first request to LOWEST changes their order,
6878   // and therefore triggers sending PRIORITY frames.
6879   helper.trans()->SetPriority(LOWEST);
6880 
6881   rv = callback1.WaitForResult();
6882   ASSERT_THAT(rv, IsOk());
6883 
6884   const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
6885   ASSERT_TRUE(response->headers);
6886   EXPECT_TRUE(response->was_fetched_via_spdy);
6887   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6888 
6889   std::string response_data;
6890   rv = ReadTransaction(helper.trans(), &response_data);
6891   EXPECT_THAT(rv, IsOk());
6892   EXPECT_EQ("hello!", response_data);
6893 
6894   rv = callback2.WaitForResult();
6895   ASSERT_THAT(rv, IsOk());
6896 
6897   helper.VerifyDataConsumed();
6898 
6899   // Server advertised WebSocket support.
6900   histogram_tester.ExpectUniqueSample("Net.SpdySession.ServerSupportsWebSocket",
6901                                       /* support_websocket = true */ 1,
6902                                       /* expected_count = */ 1);
6903 }
6904 
6905 // Make sure that a WebSocket job doesn't pick up a newly created SpdySession
6906 // that supports WebSockets through an HTTPS proxy when an H2 server doesn't
6907 // support websockets. See https://crbug.com/1010491.
TEST_F(SpdyNetworkTransactionTest,WebSocketDoesNotUseNewH2SessionWithoutWebSocketSupportOverHttpsProxy)6908 TEST_F(SpdyNetworkTransactionTest,
6909        WebSocketDoesNotUseNewH2SessionWithoutWebSocketSupportOverHttpsProxy) {
6910   auto session_deps = std::make_unique<SpdySessionDependencies>(
6911       ConfiguredProxyResolutionService::CreateFixedForTest(
6912           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
6913 
6914   NormalSpdyTransactionHelper helper(request_, HIGHEST, log_,
6915                                      std::move(session_deps));
6916   helper.RunPreTestSetup();
6917 
6918   spdy::SpdySerializedFrame req(
6919       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
6920 
6921   MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0,
6922                                   "CONNECT www.example.org:443 HTTP/1.1\r\n"
6923                                   "Host: www.example.org:443\r\n"
6924                                   "Proxy-Connection: keep-alive\r\n\r\n"),
6925                         CreateMockWrite(req, 2)};
6926 
6927   spdy::SpdySerializedFrame resp1(
6928       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6929   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
6930   MockRead reads[] = {MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n\r\n"),
6931                       CreateMockRead(resp1, 3), CreateMockRead(body1, 4),
6932                       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5)};
6933 
6934   // SSL data for the proxy.
6935   SSLSocketDataProvider tunnel_ssl_data(ASYNC, OK);
6936   helper.session_deps()->socket_factory->AddSSLSocketDataProvider(
6937       &tunnel_ssl_data);
6938 
6939   SequencedSocketData data(
6940       // Just as with other operations, this means to pause during connection
6941       // establishment.
6942       MockConnect(ASYNC, ERR_IO_PENDING), reads, writes);
6943   helper.AddData(&data);
6944 
6945   MockWrite writes2[] = {
6946       MockWrite(SYNCHRONOUS, 0,
6947                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6948                 "Host: www.example.org:443\r\n"
6949                 "Proxy-Connection: keep-alive\r\n\r\n"),
6950       MockWrite(SYNCHRONOUS, 2,
6951                 "GET / HTTP/1.1\r\n"
6952                 "Host: www.example.org\r\n"
6953                 "Connection: Upgrade\r\n"
6954                 "Upgrade: websocket\r\n"
6955                 "Origin: http://www.example.org\r\n"
6956                 "Sec-WebSocket-Version: 13\r\n"
6957                 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
6958                 "Sec-WebSocket-Extensions: permessage-deflate; "
6959                 "client_max_window_bits\r\n\r\n")};
6960 
6961   MockRead reads2[] = {
6962       MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n\r\n"),
6963       MockRead(SYNCHRONOUS, 3,
6964                "HTTP/1.1 101 Switching Protocols\r\n"
6965                "Upgrade: websocket\r\n"
6966                "Connection: Upgrade\r\n"
6967                "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
6968   SequencedSocketData data2(MockConnect(ASYNC, ERR_IO_PENDING), reads2,
6969                             writes2);
6970 
6971   // SSL data for the proxy.
6972   SSLSocketDataProvider tunnel_ssl_data2(ASYNC, OK);
6973   helper.session_deps()->socket_factory->AddSSLSocketDataProvider(
6974       &tunnel_ssl_data2);
6975 
6976   auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
6977   // Test that the request has HTTP/2 disabled.
6978   ssl_provider2->next_protos_expected_in_ssl_config = {kProtoHTTP11};
6979   // Force socket to use HTTP/1.1, the default protocol without ALPN.
6980   ssl_provider2->next_proto = kProtoHTTP11;
6981   helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2));
6982 
6983   TestCompletionCallback callback1;
6984   int rv = helper.trans()->Start(&request_, callback1.callback(), log_);
6985   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
6986 
6987   // Create HTTP/2 connection.
6988   base::RunLoop().RunUntilIdle();
6989 
6990   HttpRequestInfo request2;
6991   request2.method = "GET";
6992   request2.url = GURL("wss://www.example.org/");
6993   request2.traffic_annotation =
6994       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6995   EXPECT_TRUE(HostPortPair::FromURL(request_.url)
6996                   .Equals(HostPortPair::FromURL(request2.url)));
6997   request2.extra_headers.SetHeader("Connection", "Upgrade");
6998   request2.extra_headers.SetHeader("Upgrade", "websocket");
6999   request2.extra_headers.SetHeader("Origin", "http://www.example.org");
7000   request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
7001 
7002   TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
7003 
7004   HttpNetworkTransaction trans2(MEDIUM, helper.session());
7005   trans2.SetWebSocketHandshakeStreamCreateHelper(
7006       &websocket_stream_create_helper);
7007 
7008   TestCompletionCallback callback2;
7009   rv = trans2.Start(&request2, callback2.callback(), log_);
7010   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
7011 
7012   // Run until waiting on both connections.
7013   base::RunLoop().RunUntilIdle();
7014 
7015   // The H2 connection completes.
7016   data.socket()->OnConnectComplete(MockConnect(SYNCHRONOUS, OK));
7017   EXPECT_EQ(OK, callback1.WaitForResult());
7018   const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
7019   ASSERT_TRUE(response->headers);
7020   EXPECT_TRUE(response->was_fetched_via_spdy);
7021   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
7022   std::string response_data;
7023   rv = ReadTransaction(helper.trans(), &response_data);
7024   EXPECT_THAT(rv, IsOk());
7025   EXPECT_EQ("hello!", response_data);
7026 
7027   SpdySessionKey key(
7028       HostPortPair::FromURL(request_.url),
7029       ProxyUriToProxyServer("https://proxy:70", ProxyServer::SCHEME_HTTPS),
7030       PRIVACY_MODE_DISABLED, SpdySessionKey::IsProxySession::kFalse,
7031       SocketTag(), NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
7032 
7033   base::WeakPtr<SpdySession> spdy_session =
7034       helper.session()->spdy_session_pool()->FindAvailableSession(
7035           key, /* enable_ip_based_pooling = */ true,
7036           /* is_websocket = */ false, log_);
7037   ASSERT_TRUE(spdy_session);
7038   EXPECT_FALSE(spdy_session->support_websocket());
7039 
7040   EXPECT_FALSE(callback2.have_result());
7041 
7042   // Create WebSocket stream.
7043   data2.socket()->OnConnectComplete(MockConnect(SYNCHRONOUS, OK));
7044 
7045   rv = callback2.WaitForResult();
7046   ASSERT_THAT(rv, IsOk());
7047   helper.VerifyDataConsumed();
7048 }
7049 
7050 // Same as above, but checks that a WebSocket connection avoids creating a new
7051 // socket if it detects an H2 session when host resolution completes, and
7052 // requests also use different hostnames.
TEST_F(SpdyNetworkTransactionTest,WebSocketOverHTTP2DetectsNewSessionWithAliasing)7053 TEST_F(SpdyNetworkTransactionTest,
7054        WebSocketOverHTTP2DetectsNewSessionWithAliasing) {
7055   base::HistogramTester histogram_tester;
7056   auto session_deps = std::make_unique<SpdySessionDependencies>();
7057   session_deps->host_resolver->set_ondemand_mode(true);
7058   NormalSpdyTransactionHelper helper(request_, HIGHEST, log_,
7059                                      std::move(session_deps));
7060   helper.RunPreTestSetup();
7061 
7062   spdy::SpdySerializedFrame req(
7063       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
7064   spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
7065 
7066   spdy::Http2HeaderBlock websocket_request_headers;
7067   websocket_request_headers[spdy::kHttp2MethodHeader] = "CONNECT";
7068   websocket_request_headers[spdy::kHttp2AuthorityHeader] = "example.test";
7069   websocket_request_headers[spdy::kHttp2SchemeHeader] = "https";
7070   websocket_request_headers[spdy::kHttp2PathHeader] = "/";
7071   websocket_request_headers[spdy::kHttp2ProtocolHeader] = "websocket";
7072   websocket_request_headers["origin"] = "http://example.test";
7073   websocket_request_headers["sec-websocket-version"] = "13";
7074   websocket_request_headers["sec-websocket-extensions"] =
7075       "permessage-deflate; client_max_window_bits";
7076   spdy::SpdySerializedFrame websocket_request(spdy_util_.ConstructSpdyHeaders(
7077       3, std::move(websocket_request_headers), MEDIUM, false));
7078 
7079   spdy::SpdySerializedFrame priority1(
7080       spdy_util_.ConstructSpdyPriority(3, 0, MEDIUM, true));
7081   spdy::SpdySerializedFrame priority2(
7082       spdy_util_.ConstructSpdyPriority(1, 3, LOWEST, true));
7083 
7084   MockWrite writes[] = {
7085       CreateMockWrite(req, 0), CreateMockWrite(settings_ack, 2),
7086       CreateMockWrite(websocket_request, 4), CreateMockWrite(priority1, 5),
7087       CreateMockWrite(priority2, 6)};
7088 
7089   spdy::SettingsMap settings;
7090   settings[spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
7091   spdy::SpdySerializedFrame settings_frame(
7092       spdy_util_.ConstructSpdySettings(settings));
7093   spdy::SpdySerializedFrame resp1(
7094       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
7095   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
7096   spdy::SpdySerializedFrame websocket_response(
7097       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
7098   MockRead reads[] = {CreateMockRead(settings_frame, 1),
7099                       CreateMockRead(resp1, 3), CreateMockRead(body1, 7),
7100                       CreateMockRead(websocket_response, 8),
7101                       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 9)};
7102 
7103   SequencedSocketData data(reads, writes);
7104   helper.AddData(&data);
7105 
7106   TestCompletionCallback callback1;
7107   int rv = helper.trans()->Start(&request_, callback1.callback(), log_);
7108   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
7109 
7110   HttpRequestInfo request2;
7111   request2.method = "GET";
7112   request2.url = GURL("wss://example.test/");
7113   request2.traffic_annotation =
7114       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7115   request2.extra_headers.SetHeader("Origin", "http://example.test");
7116   request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
7117   // The following two headers must be removed by WebSocketHttp2HandshakeStream.
7118   request2.extra_headers.SetHeader("Connection", "Upgrade");
7119   request2.extra_headers.SetHeader("Upgrade", "websocket");
7120 
7121   TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
7122 
7123   HttpNetworkTransaction trans2(MEDIUM, helper.session());
7124   trans2.SetWebSocketHandshakeStreamCreateHelper(
7125       &websocket_stream_create_helper);
7126 
7127   TestCompletionCallback callback2;
7128   rv = trans2.Start(&request2, callback2.callback(), log_);
7129   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
7130 
7131   // Make sure both requests are blocked on host resolution.
7132   base::RunLoop().RunUntilIdle();
7133 
7134   EXPECT_TRUE(helper.session_deps()->host_resolver->has_pending_requests());
7135   // Complete the first DNS lookup, which should result in the first transaction
7136   // creating an H2 session (And completing successfully).
7137   helper.session_deps()->host_resolver->ResolveNow(1);
7138   base::RunLoop().RunUntilIdle();
7139 
7140   SpdySessionKey key1(HostPortPair::FromURL(request_.url),
7141                       ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
7142                       SpdySessionKey::IsProxySession::kFalse, SocketTag(),
7143                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
7144   EXPECT_TRUE(helper.session()->spdy_session_pool()->HasAvailableSession(
7145       key1, /* is_websocket = */ false));
7146   base::WeakPtr<SpdySession> spdy_session1 =
7147       helper.session()->spdy_session_pool()->FindAvailableSession(
7148           key1, /* enable_ip_based_pooling = */ true,
7149           /* is_websocket = */ false, log_);
7150   ASSERT_TRUE(spdy_session1);
7151   EXPECT_TRUE(spdy_session1->support_websocket());
7152 
7153   // Second DNS lookup completes, which results in creating a WebSocket stream.
7154   helper.session_deps()->host_resolver->ResolveNow(2);
7155   ASSERT_TRUE(spdy_session1);
7156 
7157   SpdySessionKey key2(HostPortPair::FromURL(request2.url),
7158                       ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
7159                       SpdySessionKey::IsProxySession::kFalse, SocketTag(),
7160                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
7161   EXPECT_TRUE(helper.session()->spdy_session_pool()->HasAvailableSession(
7162       key2, /* is_websocket = */ true));
7163   base::WeakPtr<SpdySession> spdy_session2 =
7164       helper.session()->spdy_session_pool()->FindAvailableSession(
7165           key1, /* enable_ip_based_pooling = */ true,
7166           /* is_websocket = */ true, log_);
7167   ASSERT_TRUE(spdy_session2);
7168   EXPECT_EQ(spdy_session1.get(), spdy_session2.get());
7169 
7170   base::RunLoop().RunUntilIdle();
7171 
7172   // First request has HIGHEST priority, WebSocket request has MEDIUM priority.
7173   // Changing the priority of the first request to LOWEST changes their order,
7174   // and therefore triggers sending PRIORITY frames.
7175   helper.trans()->SetPriority(LOWEST);
7176 
7177   rv = callback1.WaitForResult();
7178   ASSERT_THAT(rv, IsOk());
7179 
7180   const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
7181   ASSERT_TRUE(response->headers);
7182   EXPECT_TRUE(response->was_fetched_via_spdy);
7183   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
7184 
7185   std::string response_data;
7186   rv = ReadTransaction(helper.trans(), &response_data);
7187   EXPECT_THAT(rv, IsOk());
7188   EXPECT_EQ("hello!", response_data);
7189 
7190   rv = callback2.WaitForResult();
7191   ASSERT_THAT(rv, IsOk());
7192 
7193   helper.VerifyDataConsumed();
7194 }
7195 
7196 // Same as above, but the SpdySession is closed just before use, so the
7197 // WebSocket is sent over a new HTTP/1.x connection instead.
TEST_F(SpdyNetworkTransactionTest,WebSocketOverDetectsNewSessionWithAliasingButClosedBeforeUse)7198 TEST_F(SpdyNetworkTransactionTest,
7199        WebSocketOverDetectsNewSessionWithAliasingButClosedBeforeUse) {
7200   base::HistogramTester histogram_tester;
7201   auto session_deps = std::make_unique<SpdySessionDependencies>();
7202   session_deps->host_resolver->set_ondemand_mode(true);
7203   NormalSpdyTransactionHelper helper(request_, HIGHEST, log_,
7204                                      std::move(session_deps));
7205   helper.RunPreTestSetup();
7206 
7207   spdy::SpdySerializedFrame req(
7208       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
7209   spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
7210 
7211   MockWrite writes[] = {CreateMockWrite(req, 0),
7212                         CreateMockWrite(settings_ack, 2)};
7213 
7214   spdy::SettingsMap settings;
7215   settings[spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
7216   spdy::SpdySerializedFrame settings_frame(
7217       spdy_util_.ConstructSpdySettings(settings));
7218   spdy::SpdySerializedFrame resp1(
7219       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
7220   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
7221   MockRead reads[] = {CreateMockRead(settings_frame, 1),
7222                       CreateMockRead(resp1, 3), CreateMockRead(body1, 4),
7223                       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5)};
7224 
7225   SequencedSocketData data(reads, writes);
7226   helper.AddData(&data);
7227 
7228   MockWrite writes2[] = {
7229       MockWrite("GET / HTTP/1.1\r\n"
7230                 "Host: example.test\r\n"
7231                 "Connection: Upgrade\r\n"
7232                 "Upgrade: websocket\r\n"
7233                 "Origin: http://example.test\r\n"
7234                 "Sec-WebSocket-Version: 13\r\n"
7235                 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
7236                 "Sec-WebSocket-Extensions: permessage-deflate; "
7237                 "client_max_window_bits\r\n\r\n")};
7238   MockRead reads2[] = {
7239       MockRead("HTTP/1.1 101 Switching Protocols\r\n"
7240                "Upgrade: websocket\r\n"
7241                "Connection: Upgrade\r\n"
7242                "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
7243   StaticSocketDataProvider data2(reads2, writes2);
7244   auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
7245   // Test that the request has HTTP/2 disabled.
7246   ssl_provider2->next_protos_expected_in_ssl_config = {kProtoHTTP11};
7247   // Force socket to use HTTP/1.1, the default protocol without ALPN.
7248   ssl_provider2->next_proto = kProtoHTTP11;
7249   ssl_provider2->ssl_info.cert =
7250       ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
7251   helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2));
7252 
7253   TestCompletionCallback callback1;
7254   int rv = helper.trans()->Start(&request_, callback1.callback(), log_);
7255   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
7256 
7257   HttpRequestInfo request2;
7258   request2.method = "GET";
7259   request2.url = GURL("wss://example.test/");
7260   request2.traffic_annotation =
7261       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7262   request2.extra_headers.SetHeader("Connection", "Upgrade");
7263   request2.extra_headers.SetHeader("Upgrade", "websocket");
7264   request2.extra_headers.SetHeader("Origin", "http://example.test");
7265   request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
7266 
7267   TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
7268 
7269   HttpNetworkTransaction trans2(MEDIUM, helper.session());
7270   trans2.SetWebSocketHandshakeStreamCreateHelper(
7271       &websocket_stream_create_helper);
7272 
7273   TestCompletionCallback callback2;
7274   rv = trans2.Start(&request2, callback2.callback(), log_);
7275   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
7276 
7277   // Make sure both requests are blocked on host resolution.
7278   base::RunLoop().RunUntilIdle();
7279 
7280   EXPECT_TRUE(helper.session_deps()->host_resolver->has_pending_requests());
7281   // Complete the first DNS lookup, which should result in the first transaction
7282   // creating an H2 session (And completing successfully).
7283   helper.session_deps()->host_resolver->ResolveNow(1);
7284 
7285   // Complete first request.
7286   rv = callback1.WaitForResult();
7287   ASSERT_THAT(rv, IsOk());
7288   const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
7289   ASSERT_TRUE(response->headers);
7290   EXPECT_TRUE(response->was_fetched_via_spdy);
7291   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
7292   std::string response_data;
7293   rv = ReadTransaction(helper.trans(), &response_data);
7294   EXPECT_THAT(rv, IsOk());
7295   EXPECT_EQ("hello!", response_data);
7296 
7297   SpdySessionKey key1(HostPortPair::FromURL(request_.url),
7298                       ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
7299                       SpdySessionKey::IsProxySession::kFalse, SocketTag(),
7300                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
7301   base::WeakPtr<SpdySession> spdy_session1 =
7302       helper.session()->spdy_session_pool()->FindAvailableSession(
7303           key1, /* enable_ip_based_pooling = */ true,
7304           /* is_websocket = */ false, log_);
7305   ASSERT_TRUE(spdy_session1);
7306   EXPECT_TRUE(spdy_session1->support_websocket());
7307 
7308   // Second DNS lookup completes, which results in creating an alias for the
7309   // SpdySession immediately, and a task is posted asynchronously to use the
7310   // alias..
7311   helper.session_deps()->host_resolver->ResolveNow(2);
7312 
7313   SpdySessionKey key2(HostPortPair::FromURL(request2.url),
7314                       ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
7315                       SpdySessionKey::IsProxySession::kFalse, SocketTag(),
7316                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
7317   base::WeakPtr<SpdySession> spdy_session2 =
7318       helper.session()->spdy_session_pool()->FindAvailableSession(
7319           key1, /* enable_ip_based_pooling = */ true,
7320           /* is_websocket = */ true, log_);
7321   ASSERT_TRUE(spdy_session2);
7322   EXPECT_EQ(spdy_session1.get(), spdy_session2.get());
7323 
7324   // But the session is closed before it can be used.
7325   helper.session()->spdy_session_pool()->CloseAllSessions();
7326 
7327   // The second request establishes another connection (without even doing
7328   // another DNS lookup) instead, and uses HTTP/1.x.
7329   rv = callback2.WaitForResult();
7330   ASSERT_THAT(rv, IsOk());
7331 
7332   helper.VerifyDataConsumed();
7333 }
7334 
TEST_F(SpdyNetworkTransactionTest,WebSocketNegotiatesHttp2)7335 TEST_F(SpdyNetworkTransactionTest, WebSocketNegotiatesHttp2) {
7336   HttpRequestInfo request;
7337   request.method = "GET";
7338   request.url = GURL("wss://www.example.org/");
7339   request.traffic_annotation =
7340       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7341   EXPECT_TRUE(HostPortPair::FromURL(request_.url)
7342                   .Equals(HostPortPair::FromURL(request.url)));
7343   request.extra_headers.SetHeader("Connection", "Upgrade");
7344   request.extra_headers.SetHeader("Upgrade", "websocket");
7345   request.extra_headers.SetHeader("Origin", "http://www.example.org");
7346   request.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
7347 
7348   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
7349   helper.RunPreTestSetup();
7350 
7351   StaticSocketDataProvider data;
7352 
7353   auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
7354   // Test that the request has HTTP/2 disabled.
7355   ssl_provider->next_protos_expected_in_ssl_config = {kProtoHTTP11};
7356   // Force socket to use HTTP/2, which should never happen (TLS implementation
7357   // should fail TLS handshake if server chooses HTTP/2 without client
7358   // advertising support).
7359   ssl_provider->next_proto = kProtoHTTP2;
7360   ssl_provider->ssl_info.cert =
7361       ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
7362   helper.AddDataWithSSLSocketDataProvider(&data, std::move(ssl_provider));
7363 
7364   HttpNetworkTransaction* trans = helper.trans();
7365   TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
7366   trans->SetWebSocketHandshakeStreamCreateHelper(
7367       &websocket_stream_create_helper);
7368 
7369   TestCompletionCallback callback;
7370   int rv = trans->Start(&request, callback.callback(), log_);
7371   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
7372   rv = callback.WaitForResult();
7373   ASSERT_THAT(rv, IsError(ERR_NOT_IMPLEMENTED));
7374 
7375   helper.VerifyDataConsumed();
7376 }
7377 
TEST_F(SpdyNetworkTransactionTest,WebSocketHttp11Required)7378 TEST_F(SpdyNetworkTransactionTest, WebSocketHttp11Required) {
7379   base::HistogramTester histogram_tester;
7380   auto session_deps = std::make_unique<SpdySessionDependencies>();
7381   NormalSpdyTransactionHelper helper(request_, HIGHEST, log_,
7382                                      std::move(session_deps));
7383   helper.RunPreTestSetup();
7384 
7385   spdy::SpdySerializedFrame req(
7386       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
7387   spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
7388 
7389   spdy::Http2HeaderBlock websocket_request_headers;
7390   websocket_request_headers[spdy::kHttp2MethodHeader] = "CONNECT";
7391   websocket_request_headers[spdy::kHttp2AuthorityHeader] = "www.example.org";
7392   websocket_request_headers[spdy::kHttp2SchemeHeader] = "https";
7393   websocket_request_headers[spdy::kHttp2PathHeader] = "/";
7394   websocket_request_headers[spdy::kHttp2ProtocolHeader] = "websocket";
7395   websocket_request_headers["origin"] = "http://www.example.org";
7396   websocket_request_headers["sec-websocket-version"] = "13";
7397   websocket_request_headers["sec-websocket-extensions"] =
7398       "permessage-deflate; client_max_window_bits";
7399   spdy::SpdySerializedFrame websocket_request(spdy_util_.ConstructSpdyHeaders(
7400       3, std::move(websocket_request_headers), MEDIUM, false));
7401 
7402   spdy::SpdySerializedFrame priority1(
7403       spdy_util_.ConstructSpdyPriority(3, 0, MEDIUM, true));
7404   spdy::SpdySerializedFrame priority2(
7405       spdy_util_.ConstructSpdyPriority(1, 3, LOWEST, true));
7406 
7407   MockWrite writes1[] = {CreateMockWrite(req, 0),
7408                          CreateMockWrite(settings_ack, 2),
7409                          CreateMockWrite(websocket_request, 4)};
7410 
7411   spdy::SettingsMap settings;
7412   settings[spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
7413   spdy::SpdySerializedFrame settings_frame(
7414       spdy_util_.ConstructSpdySettings(settings));
7415   spdy::SpdySerializedFrame resp1(
7416       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
7417   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
7418   spdy::SpdySerializedFrame websocket_response_http11_required(
7419       spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
7420   MockRead reads1[] = {CreateMockRead(settings_frame, 1),
7421                        CreateMockRead(resp1, 3),
7422                        CreateMockRead(websocket_response_http11_required, 5)};
7423 
7424   SequencedSocketData data1(reads1, writes1);
7425   helper.AddData(&data1);
7426 
7427   MockWrite writes2[] = {
7428       MockWrite("GET / HTTP/1.1\r\n"
7429                 "Host: www.example.org\r\n"
7430                 "Connection: Upgrade\r\n"
7431                 "Origin: http://www.example.org\r\n"
7432                 "Sec-WebSocket-Version: 13\r\n"
7433                 "Upgrade: websocket\r\n"
7434                 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
7435                 "Sec-WebSocket-Extensions: permessage-deflate; "
7436                 "client_max_window_bits\r\n\r\n")};
7437   MockRead reads2[] = {
7438       MockRead("HTTP/1.1 101 Switching Protocols\r\n"
7439                "Upgrade: websocket\r\n"
7440                "Connection: Upgrade\r\n"
7441                "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
7442   StaticSocketDataProvider data2(reads2, writes2);
7443   auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
7444   // Test that the request has HTTP/2 disabled.
7445   ssl_provider2->next_protos_expected_in_ssl_config = {kProtoHTTP11};
7446   // Force socket to use HTTP/1.1, the default protocol without ALPN.
7447   ssl_provider2->next_proto = kProtoHTTP11;
7448   ssl_provider2->ssl_info.cert =
7449       ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
7450   helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2));
7451 
7452   // Create HTTP/2 connection.
7453   TestCompletionCallback callback1;
7454   int rv = helper.trans()->Start(&request_, callback1.callback(), log_);
7455   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
7456 
7457   // Create HTTP/2 connection.
7458   base::RunLoop().RunUntilIdle();
7459 
7460   SpdySessionKey key(HostPortPair::FromURL(request_.url), ProxyServer::Direct(),
7461                      PRIVACY_MODE_DISABLED,
7462                      SpdySessionKey::IsProxySession::kFalse, SocketTag(),
7463                      NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
7464   base::WeakPtr<SpdySession> spdy_session =
7465       helper.session()->spdy_session_pool()->FindAvailableSession(
7466           key, /* enable_ip_based_pooling = */ true,
7467           /* is_websocket = */ true, log_);
7468   ASSERT_TRUE(spdy_session);
7469   EXPECT_TRUE(spdy_session->support_websocket());
7470 
7471   HttpRequestInfo request2;
7472   request2.method = "GET";
7473   request2.url = GURL("wss://www.example.org/");
7474   request2.traffic_annotation =
7475       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7476   EXPECT_TRUE(HostPortPair::FromURL(request_.url)
7477                   .Equals(HostPortPair::FromURL(request2.url)));
7478   request2.extra_headers.SetHeader("Origin", "http://www.example.org");
7479   request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
7480   // The following two headers must be removed by WebSocketHttp2HandshakeStream.
7481   request2.extra_headers.SetHeader("Connection", "Upgrade");
7482   request2.extra_headers.SetHeader("Upgrade", "websocket");
7483 
7484   TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
7485 
7486   HttpNetworkTransaction trans2(MEDIUM, helper.session());
7487   trans2.SetWebSocketHandshakeStreamCreateHelper(
7488       &websocket_stream_create_helper);
7489 
7490   TestCompletionCallback callback2;
7491   rv = trans2.Start(&request2, callback2.callback(), log_);
7492   EXPECT_THAT(callback2.GetResult(rv), IsOk());
7493 
7494   helper.VerifyDataConsumed();
7495 
7496   // Server advertised WebSocket support.
7497   histogram_tester.ExpectUniqueSample("Net.SpdySession.ServerSupportsWebSocket",
7498                                       /* support_websocket = true */ 1,
7499                                       /* expected_count = */ 1);
7500 }
7501 
7502 // When using an HTTP(S) proxy, plaintext WebSockets use CONNECT tunnels. This
7503 // should work for HTTP/2 proxies.
TEST_F(SpdyNetworkTransactionTest,PlaintextWebSocketOverHttp2Proxy)7504 TEST_F(SpdyNetworkTransactionTest, PlaintextWebSocketOverHttp2Proxy) {
7505   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
7506       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
7507       HostPortPair("www.example.org", 80)));
7508   const char kWebSocketRequest[] =
7509       "GET / HTTP/1.1\r\n"
7510       "Host: www.example.org\r\n"
7511       "Connection: Upgrade\r\n"
7512       "Upgrade: websocket\r\n"
7513       "Origin: http://www.example.org\r\n"
7514       "Sec-WebSocket-Version: 13\r\n"
7515       "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
7516       "Sec-WebSocket-Extensions: permessage-deflate; "
7517       "client_max_window_bits\r\n\r\n";
7518   spdy::SpdySerializedFrame websocket_request(spdy_util_.ConstructSpdyDataFrame(
7519       /*stream_id=*/1, kWebSocketRequest, /*fin=*/false));
7520   MockWrite writes[] = {CreateMockWrite(req, 0),
7521                         CreateMockWrite(websocket_request, 2)};
7522 
7523   spdy::SpdySerializedFrame connect_response(
7524       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
7525   const char kWebSocketResponse[] =
7526       "HTTP/1.1 101 Switching Protocols\r\n"
7527       "Upgrade: websocket\r\n"
7528       "Connection: Upgrade\r\n"
7529       "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n";
7530   spdy::SpdySerializedFrame websocket_response(
7531       spdy_util_.ConstructSpdyDataFrame(/*stream_id=*/1, kWebSocketResponse,
7532                                         /*fin=*/false));
7533   MockRead reads[] = {CreateMockRead(connect_response, 1),
7534                       CreateMockRead(websocket_response, 3),
7535                       MockRead(ASYNC, 0, 4)};
7536 
7537   SequencedSocketData data(reads, writes);
7538 
7539   request_.url = GURL("ws://www.example.org/");
7540   request_.extra_headers.SetHeader("Connection", "Upgrade");
7541   request_.extra_headers.SetHeader("Upgrade", "websocket");
7542   request_.extra_headers.SetHeader("Origin", "http://www.example.org");
7543   request_.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
7544   auto session_deps = std::make_unique<SpdySessionDependencies>(
7545       ConfiguredProxyResolutionService::CreateFixedForTest(
7546           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
7547   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
7548                                      std::move(session_deps));
7549   helper.RunPreTestSetup();
7550   helper.AddData(&data);
7551 
7552   HttpNetworkTransaction* trans = helper.trans();
7553   TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
7554   trans->SetWebSocketHandshakeStreamCreateHelper(
7555       &websocket_stream_create_helper);
7556 
7557   EXPECT_TRUE(helper.StartDefaultTest());
7558   helper.WaitForCallbackToComplete();
7559   EXPECT_THAT(helper.output().rv, IsOk());
7560 
7561   base::RunLoop().RunUntilIdle();
7562   helper.VerifyDataConsumed();
7563 }
7564 
TEST_F(SpdyNetworkTransactionTest,SecureWebSocketOverHttp2Proxy)7565 TEST_F(SpdyNetworkTransactionTest, SecureWebSocketOverHttp2Proxy) {
7566   spdy::SpdySerializedFrame connect_request(spdy_util_.ConstructSpdyConnect(
7567       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
7568       HostPortPair("www.example.org", 443)));
7569   const char kWebSocketRequest[] =
7570       "GET / HTTP/1.1\r\n"
7571       "Host: www.example.org\r\n"
7572       "Connection: Upgrade\r\n"
7573       "Upgrade: websocket\r\n"
7574       "Origin: http://www.example.org\r\n"
7575       "Sec-WebSocket-Version: 13\r\n"
7576       "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
7577       "Sec-WebSocket-Extensions: permessage-deflate; "
7578       "client_max_window_bits\r\n\r\n";
7579   spdy::SpdySerializedFrame websocket_request(
7580       spdy_util_.ConstructSpdyDataFrame(1, kWebSocketRequest, false));
7581   MockWrite writes[] = {CreateMockWrite(connect_request, 0),
7582                         CreateMockWrite(websocket_request, 2)};
7583 
7584   spdy::SpdySerializedFrame connect_response(
7585       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
7586   const char kWebSocketResponse[] =
7587       "HTTP/1.1 101 Switching Protocols\r\n"
7588       "Upgrade: websocket\r\n"
7589       "Connection: Upgrade\r\n"
7590       "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n";
7591   spdy::SpdySerializedFrame websocket_response(
7592       spdy_util_.ConstructSpdyDataFrame(1, kWebSocketResponse, false));
7593   MockRead reads[] = {CreateMockRead(connect_response, 1),
7594                       CreateMockRead(websocket_response, 3),
7595                       MockRead(ASYNC, 0, 4)};
7596 
7597   SequencedSocketData data(reads, writes);
7598 
7599   request_.url = GURL("wss://www.example.org/");
7600   request_.extra_headers.SetHeader("Connection", "Upgrade");
7601   request_.extra_headers.SetHeader("Upgrade", "websocket");
7602   request_.extra_headers.SetHeader("Origin", "http://www.example.org");
7603   request_.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
7604   auto session_deps = std::make_unique<SpdySessionDependencies>(
7605       ConfiguredProxyResolutionService::CreateFixedForTest(
7606           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
7607   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
7608                                      std::move(session_deps));
7609   helper.RunPreTestSetup();
7610   helper.AddData(&data);
7611 
7612   // Add SSL data for the tunneled connection.
7613   SSLSocketDataProvider ssl_provider(ASYNC, OK);
7614   ssl_provider.ssl_info.cert =
7615       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
7616   // A WebSocket request should not advertise HTTP/2 support.
7617   ssl_provider.next_protos_expected_in_ssl_config = {kProtoHTTP11};
7618   // This test uses WebSocket over HTTP/1.1.
7619   ssl_provider.next_proto = kProtoHTTP11;
7620   helper.session_deps()->socket_factory->AddSSLSocketDataProvider(
7621       &ssl_provider);
7622 
7623   HttpNetworkTransaction* trans = helper.trans();
7624   TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
7625   trans->SetWebSocketHandshakeStreamCreateHelper(
7626       &websocket_stream_create_helper);
7627 
7628   EXPECT_TRUE(helper.StartDefaultTest());
7629   helper.WaitForCallbackToComplete();
7630   EXPECT_THAT(helper.output().rv, IsOk());
7631   const HttpResponseInfo* response = trans->GetResponseInfo();
7632   ASSERT_TRUE(response);
7633   EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
7634             response->connection_info);
7635   EXPECT_TRUE(response->was_alpn_negotiated);
7636   EXPECT_FALSE(response->was_fetched_via_spdy);
7637   EXPECT_EQ(70, response->remote_endpoint.port());
7638   ASSERT_TRUE(response->headers);
7639   EXPECT_EQ("HTTP/1.1 101 Switching Protocols",
7640             response->headers->GetStatusLine());
7641 
7642   base::RunLoop().RunUntilIdle();
7643   helper.VerifyDataConsumed();
7644 }
7645 
7646 // Regression test for https://crbug.com/828865.
TEST_F(SpdyNetworkTransactionTest,SecureWebSocketOverHttp2ProxyNegotiatesHttp2)7647 TEST_F(SpdyNetworkTransactionTest,
7648        SecureWebSocketOverHttp2ProxyNegotiatesHttp2) {
7649   spdy::SpdySerializedFrame connect_request(spdy_util_.ConstructSpdyConnect(
7650       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
7651       HostPortPair("www.example.org", 443)));
7652   MockWrite writes[] = {CreateMockWrite(connect_request, 0)};
7653   spdy::SpdySerializedFrame connect_response(
7654       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
7655   MockRead reads[] = {CreateMockRead(connect_response, 1),
7656                       MockRead(ASYNC, 0, 2)};
7657   SequencedSocketData data(reads, writes);
7658 
7659   request_.url = GURL("wss://www.example.org/");
7660   request_.extra_headers.SetHeader("Connection", "Upgrade");
7661   request_.extra_headers.SetHeader("Upgrade", "websocket");
7662   request_.extra_headers.SetHeader("Origin", "http://www.example.org");
7663   request_.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
7664   auto session_deps = std::make_unique<SpdySessionDependencies>(
7665       ConfiguredProxyResolutionService::CreateFixedForTest(
7666           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
7667   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
7668                                      std::move(session_deps));
7669   helper.RunPreTestSetup();
7670   helper.AddData(&data);
7671 
7672   // Add SSL data for the tunneled connection.
7673   SSLSocketDataProvider ssl_provider(ASYNC, OK);
7674   ssl_provider.ssl_info.cert =
7675       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
7676   // A WebSocket request should not advertise HTTP/2 support.
7677   ssl_provider.next_protos_expected_in_ssl_config = {kProtoHTTP11};
7678   // The server should not negotiate HTTP/2 over the tunnelled connection,
7679   // but it must be handled gracefully if it does.
7680   ssl_provider.next_proto = kProtoHTTP2;
7681   helper.session_deps()->socket_factory->AddSSLSocketDataProvider(
7682       &ssl_provider);
7683 
7684   HttpNetworkTransaction* trans = helper.trans();
7685   TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
7686   trans->SetWebSocketHandshakeStreamCreateHelper(
7687       &websocket_stream_create_helper);
7688 
7689   EXPECT_TRUE(helper.StartDefaultTest());
7690   helper.WaitForCallbackToComplete();
7691   EXPECT_THAT(helper.output().rv, IsError(ERR_NOT_IMPLEMENTED));
7692 
7693   base::RunLoop().RunUntilIdle();
7694   helper.VerifyDataConsumed();
7695 }
7696 
7697 #endif  // BUILDFLAG(ENABLE_WEBSOCKETS)
7698 
TEST_F(SpdyNetworkTransactionTest,ZeroRTTDoesntConfirm)7699 TEST_F(SpdyNetworkTransactionTest, ZeroRTTDoesntConfirm) {
7700   static const base::TimeDelta kDelay = base::Milliseconds(10);
7701   spdy::SpdySerializedFrame req(
7702       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
7703   MockWrite writes[] = {CreateMockWrite(req, 0)};
7704 
7705   spdy::SpdySerializedFrame resp(
7706       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
7707   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
7708   MockRead reads[] = {
7709       CreateMockRead(resp, 1), CreateMockRead(body, 2),
7710       MockRead(ASYNC, 0, 3)  // EOF
7711   };
7712 
7713   SequencedSocketData data(reads, writes);
7714   auto session_deps = std::make_unique<SpdySessionDependencies>();
7715   session_deps->enable_early_data = true;
7716   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
7717                                      std::move(session_deps));
7718   auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
7719   ssl_provider->connect_callback = FastForwardByCallback(kDelay);
7720   // Configure |ssl_provider| to fail if ConfirmHandshake is called. The request
7721   // should still succeed.
7722   ssl_provider->confirm = MockConfirm(SYNCHRONOUS, ERR_SSL_PROTOCOL_ERROR);
7723   ssl_provider->confirm_callback = FastForwardByCallback(kDelay);
7724   base::TimeTicks start_time = base::TimeTicks::Now();
7725   helper.RunToCompletionWithSSLData(&data, std::move(ssl_provider));
7726   TransactionHelperResult out = helper.output();
7727   EXPECT_THAT(out.rv, IsOk());
7728   EXPECT_EQ("HTTP/1.1 200", out.status_line);
7729   EXPECT_EQ("hello!", out.response_data);
7730 
7731   // The handshake time should include the time it took to run Connect(), but
7732   // not ConfirmHandshake().
7733   LoadTimingInfo load_timing_info;
7734   EXPECT_TRUE(helper.trans()->GetLoadTimingInfo(&load_timing_info));
7735   EXPECT_EQ(load_timing_info.connect_timing.connect_start, start_time);
7736   EXPECT_EQ(load_timing_info.connect_timing.ssl_start, start_time);
7737   EXPECT_EQ(load_timing_info.connect_timing.ssl_end, start_time + kDelay);
7738   EXPECT_EQ(load_timing_info.connect_timing.connect_end, start_time + kDelay);
7739 }
7740 
7741 // Run multiple concurrent streams that don't require handshake confirmation.
TEST_F(SpdyNetworkTransactionTest,ZeroRTTNoConfirmMultipleStreams)7742 TEST_F(SpdyNetworkTransactionTest, ZeroRTTNoConfirmMultipleStreams) {
7743   spdy::SpdySerializedFrame req1(
7744       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
7745   spdy::SpdySerializedFrame req2(
7746       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
7747   MockWrite writes1[] = {CreateMockWrite(req1, 0), CreateMockWrite(req2, 3)};
7748 
7749   spdy::SpdySerializedFrame resp1(
7750       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
7751   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
7752   spdy::SpdySerializedFrame resp2(
7753       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
7754   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
7755   MockRead reads1[] = {
7756       CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
7757       CreateMockRead(resp2, 4), CreateMockRead(body2, 5),
7758       MockRead(ASYNC, 0, 6)  // EOF
7759   };
7760 
7761   SequencedSocketData data1(reads1, writes1);
7762   SequencedSocketData data2({}, {});
7763   auto session_deps = std::make_unique<SpdySessionDependencies>();
7764   session_deps->enable_early_data = true;
7765   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
7766                                      std::move(session_deps));
7767   auto ssl_provider1 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
7768   ssl_provider1->confirm = MockConfirm(SYNCHRONOUS, ERR_SSL_PROTOCOL_ERROR);
7769   auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
7770   ssl_provider2->confirm = MockConfirm(SYNCHRONOUS, ERR_SSL_PROTOCOL_ERROR);
7771 
7772   helper.RunPreTestSetup();
7773   helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1));
7774   helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2));
7775   EXPECT_TRUE(helper.StartDefaultTest());
7776 
7777   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
7778   HttpRequestInfo request2;
7779   request2.method = "GET";
7780   request2.url = GURL(kDefaultUrl);
7781   request2.traffic_annotation =
7782       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7783   TestCompletionCallback callback2;
7784   int rv = trans2.Start(&request2, callback2.callback(), log_);
7785   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7786 
7787   helper.FinishDefaultTest();
7788   EXPECT_THAT(callback2.GetResult(ERR_IO_PENDING), IsOk());
7789   helper.VerifyDataConsumed();
7790 
7791   TransactionHelperResult out = helper.output();
7792   EXPECT_THAT(out.rv, IsOk());
7793   EXPECT_EQ("HTTP/1.1 200", out.status_line);
7794   EXPECT_EQ("hello!", out.response_data);
7795 }
7796 
7797 // Run multiple concurrent streams that require handshake confirmation.
TEST_F(SpdyNetworkTransactionTest,ZeroRTTConfirmMultipleStreams)7798 TEST_F(SpdyNetworkTransactionTest, ZeroRTTConfirmMultipleStreams) {
7799   spdy::Http2HeaderBlock req_block1(
7800       spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, 0));
7801   spdy::SpdySerializedFrame req1(
7802       spdy_util_.ConstructSpdyHeaders(1, std::move(req_block1), LOWEST, true));
7803   spdy::Http2HeaderBlock req_block2(
7804       spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, 0));
7805   spdy::SpdySerializedFrame req2(
7806       spdy_util_.ConstructSpdyHeaders(3, std::move(req_block2), LOWEST, true));
7807   MockWrite writes[] = {
7808       CreateMockWrite(req1, 0),
7809       CreateMockWrite(req2, 3),
7810   };
7811   spdy::SpdySerializedFrame resp1(
7812       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
7813   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
7814   spdy::SpdySerializedFrame resp2(
7815       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
7816   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
7817   MockRead reads[] = {
7818       CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
7819       CreateMockRead(resp2, 4), CreateMockRead(body2, 5),
7820       MockRead(ASYNC, 0, 6)  // EOF
7821   };
7822 
7823   SequencedSocketData data1(reads, writes);
7824   SequencedSocketData data2({}, {});
7825   UsePostRequest();
7826   auto session_deps = std::make_unique<SpdySessionDependencies>();
7827   session_deps->enable_early_data = true;
7828   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
7829                                      std::move(session_deps));
7830   auto ssl_provider1 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
7831   ssl_provider1->confirm = MockConfirm(ASYNC, OK);
7832   auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
7833   ssl_provider2->confirm = MockConfirm(ASYNC, OK);
7834 
7835   helper.RunPreTestSetup();
7836   helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1));
7837   helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2));
7838 
7839   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
7840   HttpRequestInfo request1;
7841   request1.method = "POST";
7842   request1.url = GURL(kDefaultUrl);
7843   request1.traffic_annotation =
7844       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7845   TestCompletionCallback callback1;
7846   int rv = trans1.Start(&request1, callback1.callback(), log_);
7847   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7848 
7849   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
7850   HttpRequestInfo request2;
7851   request2.method = "POST";
7852   request2.url = GURL(kDefaultUrl);
7853   request2.traffic_annotation =
7854       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7855   TestCompletionCallback callback2;
7856   rv = trans2.Start(&request2, callback2.callback(), log_);
7857   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7858 
7859   EXPECT_THAT(callback1.GetResult(ERR_IO_PENDING), IsOk());
7860   EXPECT_THAT(callback2.GetResult(ERR_IO_PENDING), IsOk());
7861 
7862   const HttpResponseInfo* response1 = trans1.GetResponseInfo();
7863   ASSERT_TRUE(response1);
7864   ASSERT_TRUE(response1->headers);
7865   EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
7866             response1->connection_info);
7867   EXPECT_EQ("HTTP/1.1 200", response1->headers->GetStatusLine());
7868   std::string response_data;
7869   ReadTransaction(&trans1, &response_data);
7870   EXPECT_EQ("hello!", response_data);
7871 
7872   const HttpResponseInfo* response2 = trans2.GetResponseInfo();
7873   ASSERT_TRUE(response2);
7874   ASSERT_TRUE(response2->headers);
7875   EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
7876             response2->connection_info);
7877   EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
7878   ReadTransaction(&trans2, &response_data);
7879   EXPECT_EQ("hello!", response_data);
7880 
7881   helper.VerifyDataConsumed();
7882 }
7883 
7884 // Run multiple concurrent streams, the first require a confirmation and the
7885 // second not requiring confirmation.
TEST_F(SpdyNetworkTransactionTest,ZeroRTTConfirmNoConfirmStreams)7886 TEST_F(SpdyNetworkTransactionTest, ZeroRTTConfirmNoConfirmStreams) {
7887   // This test orders the writes such that the GET (no confirmation) is written
7888   // before the POST (confirmation required).
7889   spdy::Http2HeaderBlock req_block1(
7890       spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
7891   spdy::SpdySerializedFrame req1(
7892       spdy_util_.ConstructSpdyHeaders(1, std::move(req_block1), LOWEST, true));
7893   spdy::Http2HeaderBlock req_block2(
7894       spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, 0));
7895   spdy::SpdySerializedFrame req2(
7896       spdy_util_.ConstructSpdyHeaders(3, std::move(req_block2), LOWEST, true));
7897   MockWrite writes[] = {
7898       CreateMockWrite(req1, 0),
7899       CreateMockWrite(req2, 3),
7900   };
7901   spdy::SpdySerializedFrame resp1(
7902       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
7903   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
7904   spdy::SpdySerializedFrame resp2(
7905       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
7906   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
7907   MockRead reads[] = {
7908       CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
7909       CreateMockRead(resp2, 4), CreateMockRead(body2, 5),
7910       MockRead(ASYNC, 0, 6)  // EOF
7911   };
7912 
7913   SequencedSocketData data1(reads, writes);
7914   SequencedSocketData data2({}, {});
7915   UsePostRequest();
7916   auto session_deps = std::make_unique<SpdySessionDependencies>();
7917   session_deps->enable_early_data = true;
7918   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
7919                                      std::move(session_deps));
7920   auto ssl_provider1 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
7921   ssl_provider1->confirm = MockConfirm(ASYNC, OK);
7922   auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
7923   ssl_provider2->confirm = MockConfirm(ASYNC, OK);
7924 
7925   helper.RunPreTestSetup();
7926   helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1));
7927   helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2));
7928 
7929   // TODO(https://crbug.com/949724): Explicitly verify the ordering of
7930   // ConfirmHandshake and the second stream.
7931 
7932   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
7933   HttpRequestInfo request1;
7934   request1.method = "POST";
7935   request1.url = GURL(kDefaultUrl);
7936   request1.traffic_annotation =
7937       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7938   TestCompletionCallback callback1;
7939   int rv = trans1.Start(&request1, callback1.callback(), log_);
7940   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7941 
7942   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
7943   HttpRequestInfo request2;
7944   request2.method = "GET";
7945   request2.url = GURL(kDefaultUrl);
7946   request2.traffic_annotation =
7947       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7948   TestCompletionCallback callback2;
7949   rv = trans2.Start(&request2, callback2.callback(), log_);
7950   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7951 
7952   EXPECT_THAT(callback1.GetResult(ERR_IO_PENDING), IsOk());
7953   EXPECT_THAT(callback2.GetResult(ERR_IO_PENDING), IsOk());
7954 
7955   const HttpResponseInfo* response1 = trans1.GetResponseInfo();
7956   ASSERT_TRUE(response1);
7957   ASSERT_TRUE(response1->headers);
7958   EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
7959             response1->connection_info);
7960   EXPECT_EQ("HTTP/1.1 200", response1->headers->GetStatusLine());
7961   std::string response_data;
7962   ReadTransaction(&trans1, &response_data);
7963   EXPECT_EQ("hello!", response_data);
7964 
7965   const HttpResponseInfo* response2 = trans2.GetResponseInfo();
7966   ASSERT_TRUE(response2);
7967   ASSERT_TRUE(response2->headers);
7968   EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
7969             response2->connection_info);
7970   EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
7971   ReadTransaction(&trans2, &response_data);
7972   EXPECT_EQ("hello!", response_data);
7973 
7974   helper.VerifyDataConsumed();
7975 }
7976 
7977 // Run multiple concurrent streams, the first not requiring confirmation and the
7978 // second requiring confirmation.
TEST_F(SpdyNetworkTransactionTest,ZeroRTTNoConfirmConfirmStreams)7979 TEST_F(SpdyNetworkTransactionTest, ZeroRTTNoConfirmConfirmStreams) {
7980   // This test orders the writes such that the GET (no confirmation) is written
7981   // before the POST (confirmation required).
7982   spdy::Http2HeaderBlock req_block1(
7983       spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
7984   spdy::SpdySerializedFrame req1(
7985       spdy_util_.ConstructSpdyHeaders(1, std::move(req_block1), LOWEST, true));
7986   spdy::Http2HeaderBlock req_block2(
7987       spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, 0));
7988   spdy::SpdySerializedFrame req2(
7989       spdy_util_.ConstructSpdyHeaders(3, std::move(req_block2), LOWEST, true));
7990   MockWrite writes[] = {
7991       CreateMockWrite(req1, 0),
7992       CreateMockWrite(req2, 3),
7993   };
7994   spdy::SpdySerializedFrame resp1(
7995       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
7996   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
7997   spdy::SpdySerializedFrame resp2(
7998       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
7999   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
8000   MockRead reads[] = {
8001       CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
8002       CreateMockRead(resp2, 4), CreateMockRead(body2, 5),
8003       MockRead(ASYNC, 0, 6)  // EOF
8004   };
8005 
8006   SequencedSocketData data1(reads, writes);
8007   SequencedSocketData data2({}, {});
8008   UsePostRequest();
8009   auto session_deps = std::make_unique<SpdySessionDependencies>();
8010   session_deps->enable_early_data = true;
8011   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
8012                                      std::move(session_deps));
8013   auto ssl_provider1 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
8014   ssl_provider1->confirm = MockConfirm(ASYNC, OK);
8015   auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
8016   ssl_provider2->confirm = MockConfirm(ASYNC, OK);
8017 
8018   helper.RunPreTestSetup();
8019   helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1));
8020   helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2));
8021 
8022   // TODO(https://crbug.com/949724): Explicitly verify the ordering of
8023   // ConfirmHandshake and the second stream.
8024 
8025   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
8026   HttpRequestInfo request1;
8027   request1.method = "GET";
8028   request1.url = GURL(kDefaultUrl);
8029   request1.traffic_annotation =
8030       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8031   TestCompletionCallback callback1;
8032   int rv = trans1.Start(&request1, callback1.callback(), log_);
8033   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8034 
8035   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
8036   HttpRequestInfo request2;
8037   request2.method = "POST";
8038   request2.url = GURL(kDefaultUrl);
8039   request2.traffic_annotation =
8040       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8041   TestCompletionCallback callback2;
8042   rv = trans2.Start(&request2, callback2.callback(), log_);
8043   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8044 
8045   EXPECT_THAT(callback1.GetResult(ERR_IO_PENDING), IsOk());
8046   EXPECT_THAT(callback2.GetResult(ERR_IO_PENDING), IsOk());
8047 
8048   const HttpResponseInfo* response1 = trans1.GetResponseInfo();
8049   ASSERT_TRUE(response1);
8050   ASSERT_TRUE(response1->headers);
8051   EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
8052             response1->connection_info);
8053   EXPECT_EQ("HTTP/1.1 200", response1->headers->GetStatusLine());
8054   std::string response_data;
8055   ReadTransaction(&trans1, &response_data);
8056   EXPECT_EQ("hello!", response_data);
8057 
8058   const HttpResponseInfo* response2 = trans2.GetResponseInfo();
8059   ASSERT_TRUE(response2);
8060   ASSERT_TRUE(response2->headers);
8061   EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
8062             response2->connection_info);
8063   EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
8064   ReadTransaction(&trans2, &response_data);
8065   EXPECT_EQ("hello!", response_data);
8066 
8067   helper.VerifyDataConsumed();
8068 }
8069 
TEST_F(SpdyNetworkTransactionTest,ZeroRTTSyncConfirmSyncWrite)8070 TEST_F(SpdyNetworkTransactionTest, ZeroRTTSyncConfirmSyncWrite) {
8071   static const base::TimeDelta kDelay = base::Milliseconds(10);
8072   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
8073       kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
8074   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
8075   MockWrite writes[] = {
8076       CreateMockWrite(req, 0, SYNCHRONOUS),
8077       CreateMockWrite(body, 1),  // POST upload frame
8078   };
8079 
8080   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
8081   MockRead reads[] = {
8082       CreateMockRead(resp, 2), CreateMockRead(body, 3),
8083       MockRead(ASYNC, 0, 4)  // EOF
8084   };
8085 
8086   SequencedSocketData data(reads, writes);
8087   UsePostRequest();
8088   auto session_deps = std::make_unique<SpdySessionDependencies>();
8089   session_deps->enable_early_data = true;
8090   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
8091                                      std::move(session_deps));
8092   auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
8093   ssl_provider->connect_callback = FastForwardByCallback(kDelay);
8094   ssl_provider->confirm = MockConfirm(SYNCHRONOUS, OK);
8095   ssl_provider->confirm_callback = FastForwardByCallback(kDelay);
8096   base::TimeTicks start_time = base::TimeTicks::Now();
8097   helper.RunToCompletionWithSSLData(&data, std::move(ssl_provider));
8098   TransactionHelperResult out = helper.output();
8099   EXPECT_THAT(out.rv, IsOk());
8100   EXPECT_EQ("HTTP/1.1 200", out.status_line);
8101   EXPECT_EQ("hello!", out.response_data);
8102 
8103   // The handshake time should include the time it took to run Connect(), but
8104   // not ConfirmHandshake(). If ConfirmHandshake() returns synchronously, we
8105   // assume the connection did not negotiate 0-RTT or the handshake was already
8106   // confirmed.
8107   LoadTimingInfo load_timing_info;
8108   EXPECT_TRUE(helper.trans()->GetLoadTimingInfo(&load_timing_info));
8109   EXPECT_EQ(load_timing_info.connect_timing.connect_start, start_time);
8110   EXPECT_EQ(load_timing_info.connect_timing.ssl_start, start_time);
8111   EXPECT_EQ(load_timing_info.connect_timing.ssl_end, start_time + kDelay);
8112   EXPECT_EQ(load_timing_info.connect_timing.connect_end, start_time + kDelay);
8113 }
8114 
TEST_F(SpdyNetworkTransactionTest,ZeroRTTSyncConfirmAsyncWrite)8115 TEST_F(SpdyNetworkTransactionTest, ZeroRTTSyncConfirmAsyncWrite) {
8116   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
8117       kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
8118   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
8119   MockWrite writes[] = {
8120       CreateMockWrite(req, 0, ASYNC),
8121       CreateMockWrite(body, 1),  // POST upload frame
8122   };
8123 
8124   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
8125   MockRead reads[] = {
8126       CreateMockRead(resp, 2), CreateMockRead(body, 3),
8127       MockRead(ASYNC, 0, 4)  // EOF
8128   };
8129 
8130   SequencedSocketData data(reads, writes);
8131   UsePostRequest();
8132   auto session_deps = std::make_unique<SpdySessionDependencies>();
8133   session_deps->enable_early_data = true;
8134   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
8135                                      std::move(session_deps));
8136   auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
8137   ssl_provider->confirm = MockConfirm(SYNCHRONOUS, OK);
8138   helper.RunToCompletionWithSSLData(&data, std::move(ssl_provider));
8139   TransactionHelperResult out = helper.output();
8140   EXPECT_THAT(out.rv, IsOk());
8141   EXPECT_EQ("HTTP/1.1 200", out.status_line);
8142   EXPECT_EQ("hello!", out.response_data);
8143 }
8144 
TEST_F(SpdyNetworkTransactionTest,ZeroRTTAsyncConfirmSyncWrite)8145 TEST_F(SpdyNetworkTransactionTest, ZeroRTTAsyncConfirmSyncWrite) {
8146   static const base::TimeDelta kDelay = base::Milliseconds(10);
8147   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
8148       kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
8149   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
8150   MockWrite writes[] = {
8151       CreateMockWrite(req, 0, SYNCHRONOUS),
8152       CreateMockWrite(body, 1),  // POST upload frame
8153   };
8154 
8155   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
8156   MockRead reads[] = {
8157       CreateMockRead(resp, 2), CreateMockRead(body, 3),
8158       MockRead(ASYNC, 0, 4)  // EOF
8159   };
8160 
8161   SequencedSocketData data(reads, writes);
8162   UsePostRequest();
8163   auto session_deps = std::make_unique<SpdySessionDependencies>();
8164   session_deps->enable_early_data = true;
8165   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
8166                                      std::move(session_deps));
8167   auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
8168   ssl_provider->connect_callback = FastForwardByCallback(kDelay);
8169   ssl_provider->confirm = MockConfirm(ASYNC, OK);
8170   ssl_provider->confirm_callback = FastForwardByCallback(kDelay);
8171   base::TimeTicks start_time = base::TimeTicks::Now();
8172   helper.RunToCompletionWithSSLData(&data, std::move(ssl_provider));
8173   TransactionHelperResult out = helper.output();
8174   EXPECT_THAT(out.rv, IsOk());
8175   EXPECT_EQ("HTTP/1.1 200", out.status_line);
8176   EXPECT_EQ("hello!", out.response_data);
8177 
8178   // The handshake time should include the time it took to run Connect() and
8179   // ConfirmHandshake().
8180   LoadTimingInfo load_timing_info;
8181   EXPECT_TRUE(helper.trans()->GetLoadTimingInfo(&load_timing_info));
8182   EXPECT_EQ(load_timing_info.connect_timing.connect_start, start_time);
8183   EXPECT_EQ(load_timing_info.connect_timing.ssl_start, start_time);
8184   EXPECT_EQ(load_timing_info.connect_timing.ssl_end, start_time + 2 * kDelay);
8185   EXPECT_EQ(load_timing_info.connect_timing.connect_end,
8186             start_time + 2 * kDelay);
8187 }
8188 
TEST_F(SpdyNetworkTransactionTest,ZeroRTTAsyncConfirmAsyncWrite)8189 TEST_F(SpdyNetworkTransactionTest, ZeroRTTAsyncConfirmAsyncWrite) {
8190   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
8191       kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
8192   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
8193   MockWrite writes[] = {
8194       CreateMockWrite(req, 0, ASYNC),
8195       CreateMockWrite(body, 1),  // POST upload frame
8196   };
8197 
8198   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
8199   MockRead reads[] = {
8200       CreateMockRead(resp, 2), CreateMockRead(body, 3),
8201       MockRead(ASYNC, 0, 4)  // EOF
8202   };
8203 
8204   SequencedSocketData data(reads, writes);
8205   UsePostRequest();
8206   auto session_deps = std::make_unique<SpdySessionDependencies>();
8207   session_deps->enable_early_data = true;
8208   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
8209                                      std::move(session_deps));
8210   auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
8211   ssl_provider->confirm = MockConfirm(ASYNC, OK);
8212   helper.RunToCompletionWithSSLData(&data, std::move(ssl_provider));
8213   TransactionHelperResult out = helper.output();
8214   EXPECT_THAT(out.rv, IsOk());
8215   EXPECT_EQ("HTTP/1.1 200", out.status_line);
8216   EXPECT_EQ("hello!", out.response_data);
8217 }
8218 
TEST_F(SpdyNetworkTransactionTest,ZeroRTTConfirmErrorSync)8219 TEST_F(SpdyNetworkTransactionTest, ZeroRTTConfirmErrorSync) {
8220   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
8221       kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
8222   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
8223   MockWrite writes[] = {
8224       CreateMockWrite(req, 0), CreateMockWrite(body, 1),  // POST upload frame
8225   };
8226 
8227   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
8228   MockRead reads[] = {
8229       CreateMockRead(resp, 2), CreateMockRead(body, 3),
8230       MockRead(ASYNC, 0, 4)  // EOF
8231   };
8232 
8233   SequencedSocketData data(reads, writes);
8234   UsePostRequest();
8235   auto session_deps = std::make_unique<SpdySessionDependencies>();
8236   session_deps->enable_early_data = true;
8237   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
8238                                      std::move(session_deps));
8239   auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
8240   ssl_provider->confirm = MockConfirm(SYNCHRONOUS, ERR_SSL_PROTOCOL_ERROR);
8241   helper.RunPreTestSetup();
8242   helper.AddDataWithSSLSocketDataProvider(&data, std::move(ssl_provider));
8243   helper.RunDefaultTest();
8244   TransactionHelperResult out = helper.output();
8245   EXPECT_THAT(out.rv, IsError(ERR_SSL_PROTOCOL_ERROR));
8246 }
8247 
TEST_F(SpdyNetworkTransactionTest,ZeroRTTConfirmErrorAsync)8248 TEST_F(SpdyNetworkTransactionTest, ZeroRTTConfirmErrorAsync) {
8249   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
8250       kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
8251   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
8252   MockWrite writes[] = {
8253       CreateMockWrite(req, 0), CreateMockWrite(body, 1),  // POST upload frame
8254   };
8255 
8256   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
8257   MockRead reads[] = {
8258       CreateMockRead(resp, 2), CreateMockRead(body, 3),
8259       MockRead(ASYNC, 0, 4)  // EOF
8260   };
8261 
8262   SequencedSocketData data(reads, writes);
8263   UsePostRequest();
8264   auto session_deps = std::make_unique<SpdySessionDependencies>();
8265   session_deps->enable_early_data = true;
8266   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
8267                                      std::move(session_deps));
8268   auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
8269   ssl_provider->confirm = MockConfirm(ASYNC, ERR_SSL_PROTOCOL_ERROR);
8270   helper.RunPreTestSetup();
8271   helper.AddDataWithSSLSocketDataProvider(&data, std::move(ssl_provider));
8272   helper.RunDefaultTest();
8273   TransactionHelperResult out = helper.output();
8274   EXPECT_THAT(out.rv, IsError(ERR_SSL_PROTOCOL_ERROR));
8275 }
8276 
TEST_F(SpdyNetworkTransactionTest,GreaseSettings)8277 TEST_F(SpdyNetworkTransactionTest, GreaseSettings) {
8278   RecordingNetLogObserver net_log_observer;
8279 
8280   auto session_deps = std::make_unique<SpdySessionDependencies>();
8281   session_deps->enable_http2_settings_grease = true;
8282   NormalSpdyTransactionHelper helper(
8283       request_, DEFAULT_PRIORITY,
8284       NetLogWithSource::Make(NetLogSourceType::NONE), std::move(session_deps));
8285 
8286   SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
8287   SpdySessionPoolPeer pool_peer(spdy_session_pool);
8288   pool_peer.SetEnableSendingInitialData(true);
8289 
8290   // Greased setting parameter is random.  Hang writes instead of trying to
8291   // construct matching mock data.  Extra write and read is needed because mock
8292   // data cannot end on ERR_IO_PENDING.  Writes or reads will not actually be
8293   // resumed.
8294   MockWrite writes[] = {MockWrite(ASYNC, ERR_IO_PENDING, 0),
8295                         MockWrite(ASYNC, OK, 1)};
8296   MockRead reads[] = {MockRead(ASYNC, ERR_IO_PENDING, 2),
8297                       MockRead(ASYNC, OK, 3)};
8298   SequencedSocketData data(reads, writes);
8299   helper.RunPreTestSetup();
8300   helper.AddData(&data);
8301 
8302   int rv = helper.trans()->Start(&request_, CompletionOnceCallback{}, log_);
8303   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8304 
8305   base::RunLoop().RunUntilIdle();
8306 
8307   helper.ResetTrans();
8308 
8309   EXPECT_FALSE(data.AllReadDataConsumed());
8310   EXPECT_FALSE(data.AllWriteDataConsumed());
8311 
8312   const auto entries = net_log_observer.GetEntries();
8313 
8314   size_t pos = ExpectLogContainsSomewhere(
8315       entries, 0, NetLogEventType::HTTP2_SESSION_SEND_SETTINGS,
8316       NetLogEventPhase::NONE);
8317   ASSERT_LT(pos, entries.size());
8318 
8319   const base::Value::Dict& params = entries[pos].params;
8320   const base::Value::List* const settings = params.FindList("settings");
8321   ASSERT_TRUE(settings);
8322 
8323   ASSERT_FALSE(settings->empty());
8324   // Get last setting parameter.
8325   const base::Value& greased_setting = (*settings)[settings->size() - 1];
8326   ASSERT_TRUE(greased_setting.is_string());
8327   base::StringPiece greased_setting_string(greased_setting.GetString());
8328 
8329   const std::string kExpectedPrefix = "[id:";
8330   EXPECT_EQ(kExpectedPrefix,
8331             greased_setting_string.substr(0, kExpectedPrefix.size()));
8332   int setting_identifier = 0;
8333   base::StringToInt(greased_setting_string.substr(kExpectedPrefix.size()),
8334                     &setting_identifier);
8335   // The setting identifier must be of format 0x?a?a.
8336   EXPECT_EQ(0xa, setting_identifier % 16);
8337   EXPECT_EQ(0xa, (setting_identifier / 256) % 16);
8338 }
8339 
8340 // If |http2_end_stream_with_data_frame| is false, then the HEADERS frame of a
8341 // GET request will close the stream using the END_STREAM flag.  Test that
8342 // |greased_http2_frame| is ignored and no reserved frames are sent on a closed
8343 // stream.
TEST_F(SpdyNetworkTransactionTest,DoNotGreaseFrameTypeWithGetRequestIfHeadersFrameClosesStream)8344 TEST_F(SpdyNetworkTransactionTest,
8345        DoNotGreaseFrameTypeWithGetRequestIfHeadersFrameClosesStream) {
8346   auto session_deps = std::make_unique<SpdySessionDependencies>();
8347 
8348   const uint8_t type = 0x0b;
8349   const uint8_t flags = 0xcc;
8350   const std::string payload("foo");
8351   session_deps->greased_http2_frame =
8352       absl::optional<net::SpdySessionPool::GreasedHttp2Frame>(
8353           {type, flags, payload});
8354   session_deps->http2_end_stream_with_data_frame = false;
8355 
8356   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
8357                                      std::move(session_deps));
8358 
8359   spdy::SpdySerializedFrame req(
8360       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, DEFAULT_PRIORITY));
8361   MockWrite writes[] = {CreateMockWrite(req, 0)};
8362 
8363   spdy::SpdySerializedFrame resp(
8364       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
8365   spdy::SpdySerializedFrame response_body(
8366       spdy_util_.ConstructSpdyDataFrame(1, true));
8367 
8368   MockRead reads[] = {CreateMockRead(resp, 1), CreateMockRead(response_body, 2),
8369                       MockRead(ASYNC, 0, 3)};
8370 
8371   SequencedSocketData data(reads, writes);
8372   helper.RunPreTestSetup();
8373   helper.AddData(&data);
8374 
8375   TestCompletionCallback callback;
8376   int rv = helper.trans()->Start(&request_, callback.callback(), log_);
8377   EXPECT_THAT(callback.GetResult(rv), IsOk());
8378 
8379   base::RunLoop().RunUntilIdle();
8380 
8381   helper.VerifyDataConsumed();
8382 }
8383 
8384 // Test that if |http2_end_stream_with_data_frame| and |greased_http2_frame| are
8385 // both set, then the HEADERS frame does not have the END_STREAM flag set, it is
8386 // followed by a greased frame, and then by an empty DATA frame with END_STREAM
8387 // set.
TEST_F(SpdyNetworkTransactionTest,GreaseFrameTypeWithGetRequest)8388 TEST_F(SpdyNetworkTransactionTest, GreaseFrameTypeWithGetRequest) {
8389   auto session_deps = std::make_unique<SpdySessionDependencies>();
8390 
8391   const uint8_t type = 0x0b;
8392   const uint8_t flags = 0xcc;
8393   const std::string payload("foo");
8394   session_deps->greased_http2_frame =
8395       absl::optional<net::SpdySessionPool::GreasedHttp2Frame>(
8396           {type, flags, payload});
8397   session_deps->http2_end_stream_with_data_frame = true;
8398 
8399   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
8400                                      std::move(session_deps));
8401 
8402   spdy::Http2HeaderBlock headers(
8403       spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
8404   spdy::SpdySerializedFrame req(
8405       spdy_util_.ConstructSpdyHeaders(1, std::move(headers), DEFAULT_PRIORITY,
8406                                       /* fin = */ false));
8407 
8408   uint8_t kRawFrameData[] = {
8409       0x00, 0x00, 0x03,        // length
8410       0x0b,                    // type
8411       0xcc,                    // flags
8412       0x00, 0x00, 0x00, 0x01,  // stream ID
8413       'f',  'o',  'o'          // payload
8414   };
8415   spdy::SpdySerializedFrame grease(reinterpret_cast<char*>(kRawFrameData),
8416                                    std::size(kRawFrameData),
8417                                    /* owns_buffer = */ false);
8418   spdy::SpdySerializedFrame empty_body(
8419       spdy_util_.ConstructSpdyDataFrame(1, "", true));
8420 
8421   MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(grease, 1),
8422                         CreateMockWrite(empty_body, 2)};
8423 
8424   spdy::SpdySerializedFrame resp(
8425       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
8426   spdy::SpdySerializedFrame response_body(
8427       spdy_util_.ConstructSpdyDataFrame(1, true));
8428 
8429   MockRead reads[] = {CreateMockRead(resp, 3), CreateMockRead(response_body, 4),
8430                       MockRead(ASYNC, 0, 5)};
8431 
8432   SequencedSocketData data(reads, writes);
8433   helper.RunPreTestSetup();
8434   helper.AddData(&data);
8435 
8436   TestCompletionCallback callback;
8437   int rv = helper.trans()->Start(&request_, callback.callback(), log_);
8438   EXPECT_THAT(callback.GetResult(rv), IsOk());
8439 
8440   base::RunLoop().RunUntilIdle();
8441 
8442   helper.VerifyDataConsumed();
8443 }
8444 
8445 // Test sending a greased frame before DATA frame that closes the stream when
8446 // |http2_end_stream_with_data_frame| is false.
TEST_F(SpdyNetworkTransactionTest,GreaseFrameTypeWithPostRequestWhenHeadersFrameClosesStream)8447 TEST_F(SpdyNetworkTransactionTest,
8448        GreaseFrameTypeWithPostRequestWhenHeadersFrameClosesStream) {
8449   UsePostRequest();
8450 
8451   auto session_deps = std::make_unique<SpdySessionDependencies>();
8452 
8453   const uint8_t type = 0x0b;
8454   const uint8_t flags = 0xcc;
8455   const std::string payload("foo");
8456   session_deps->greased_http2_frame =
8457       absl::optional<net::SpdySessionPool::GreasedHttp2Frame>(
8458           {type, flags, payload});
8459   session_deps->http2_end_stream_with_data_frame = true;
8460 
8461   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
8462                                      std::move(session_deps));
8463 
8464   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
8465       kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
8466 
8467   uint8_t kRawFrameData[] = {
8468       0x00, 0x00, 0x03,        // length
8469       0x0b,                    // type
8470       0xcc,                    // flags
8471       0x00, 0x00, 0x00, 0x01,  // stream ID
8472       'f',  'o',  'o'          // payload
8473   };
8474   spdy::SpdySerializedFrame grease(reinterpret_cast<char*>(kRawFrameData),
8475                                    std::size(kRawFrameData),
8476                                    /* owns_buffer = */ false);
8477   spdy::SpdySerializedFrame request_body(
8478       spdy_util_.ConstructSpdyDataFrame(1, true));
8479 
8480   MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(grease, 1),
8481                         CreateMockWrite(request_body, 2)};
8482 
8483   spdy::SpdySerializedFrame resp(
8484       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
8485   spdy::SpdySerializedFrame response_body(
8486       spdy_util_.ConstructSpdyDataFrame(1, true));
8487 
8488   MockRead reads[] = {CreateMockRead(resp, 3), CreateMockRead(response_body, 4),
8489                       MockRead(ASYNC, 0, 5)};
8490 
8491   SequencedSocketData data(reads, writes);
8492   helper.RunPreTestSetup();
8493   helper.AddData(&data);
8494 
8495   TestCompletionCallback callback;
8496   int rv = helper.trans()->Start(&request_, callback.callback(), log_);
8497   EXPECT_THAT(callback.GetResult(rv), IsOk());
8498 
8499   base::RunLoop().RunUntilIdle();
8500 
8501   helper.VerifyDataConsumed();
8502 }
8503 
8504 // Test sending a greased frame before DATA frame that closes the stream.
8505 // |http2_end_stream_with_data_frame| is true but should make no difference,
8506 // because the stream is already closed by a DATA frame.
TEST_F(SpdyNetworkTransactionTest,GreaseFrameTypeWithPostRequestWhenEmptyDataFrameClosesStream)8507 TEST_F(SpdyNetworkTransactionTest,
8508        GreaseFrameTypeWithPostRequestWhenEmptyDataFrameClosesStream) {
8509   UsePostRequest();
8510 
8511   auto session_deps = std::make_unique<SpdySessionDependencies>();
8512 
8513   const uint8_t type = 0x0b;
8514   const uint8_t flags = 0xcc;
8515   const std::string payload("foo");
8516   session_deps->greased_http2_frame =
8517       absl::optional<net::SpdySessionPool::GreasedHttp2Frame>(
8518           {type, flags, payload});
8519   session_deps->http2_end_stream_with_data_frame = true;
8520 
8521   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
8522                                      std::move(session_deps));
8523 
8524   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
8525       kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
8526 
8527   uint8_t kRawFrameData[] = {
8528       0x00, 0x00, 0x03,        // length
8529       0x0b,                    // type
8530       0xcc,                    // flags
8531       0x00, 0x00, 0x00, 0x01,  // stream ID
8532       'f',  'o',  'o'          // payload
8533   };
8534   spdy::SpdySerializedFrame grease(reinterpret_cast<char*>(kRawFrameData),
8535                                    std::size(kRawFrameData),
8536                                    /* owns_buffer = */ false);
8537   spdy::SpdySerializedFrame request_body(
8538       spdy_util_.ConstructSpdyDataFrame(1, true));
8539 
8540   MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(grease, 1),
8541                         CreateMockWrite(request_body, 2)};
8542 
8543   spdy::SpdySerializedFrame resp(
8544       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
8545   spdy::SpdySerializedFrame response_body(
8546       spdy_util_.ConstructSpdyDataFrame(1, true));
8547 
8548   MockRead reads[] = {CreateMockRead(resp, 3), CreateMockRead(response_body, 4),
8549                       MockRead(ASYNC, 0, 5)};
8550 
8551   SequencedSocketData data(reads, writes);
8552   helper.RunPreTestSetup();
8553   helper.AddData(&data);
8554 
8555   TestCompletionCallback callback;
8556   int rv = helper.trans()->Start(&request_, callback.callback(), log_);
8557   EXPECT_THAT(callback.GetResult(rv), IsOk());
8558 
8559   base::RunLoop().RunUntilIdle();
8560 
8561   helper.VerifyDataConsumed();
8562 }
8563 
8564 // According to https://httpwg.org/specs/rfc7540.html#CONNECT, "frame types
8565 // other than DATA or stream management frames (RST_STREAM, WINDOW_UPDATE, and
8566 // PRIORITY) MUST NOT be sent on a connected stream".
8567 // Also test that |http2_end_stream_with_data_frame| has no effect on proxy
8568 // streams.
TEST_F(SpdyNetworkTransactionTest,DoNotGreaseFrameTypeWithConnect)8569 TEST_F(SpdyNetworkTransactionTest, DoNotGreaseFrameTypeWithConnect) {
8570   auto session_deps = std::make_unique<SpdySessionDependencies>(
8571       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
8572           "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
8573 
8574   const uint8_t type = 0x0b;
8575   const uint8_t flags = 0xcc;
8576   const std::string payload("foo");
8577   session_deps->greased_http2_frame =
8578       absl::optional<net::SpdySessionPool::GreasedHttp2Frame>(
8579           {type, flags, payload});
8580   session_deps->http2_end_stream_with_data_frame = true;
8581 
8582   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
8583                                      std::move(session_deps));
8584 
8585   // CONNECT to proxy.
8586   spdy::SpdySerializedFrame connect_req(spdy_util_.ConstructSpdyConnect(
8587       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
8588       HostPortPair("www.example.org", 443)));
8589   spdy::SpdySerializedFrame connect_response(
8590       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
8591 
8592   // Tunneled transaction wrapped in DATA frames.
8593   const char req[] =
8594       "GET / HTTP/1.1\r\n"
8595       "Host: www.example.org\r\n"
8596       "Connection: keep-alive\r\n\r\n";
8597   spdy::SpdySerializedFrame tunneled_req(
8598       spdy_util_.ConstructSpdyDataFrame(1, req, false));
8599 
8600   const char resp[] =
8601       "HTTP/1.1 200 OK\r\n"
8602       "Content-Length: 5\r\n\r\n"
8603       "hello";
8604   spdy::SpdySerializedFrame tunneled_response(
8605       spdy_util_.ConstructSpdyDataFrame(1, resp, false));
8606 
8607   MockWrite writes[] = {CreateMockWrite(connect_req, 0),
8608                         CreateMockWrite(tunneled_req, 2)};
8609 
8610   MockRead reads[] = {CreateMockRead(connect_response, 1),
8611                       CreateMockRead(tunneled_response, 3),
8612                       MockRead(ASYNC, 0, 4)};
8613 
8614   SequencedSocketData data0(reads, writes);
8615 
8616   // HTTP/2 connection to proxy.
8617   auto ssl_provider0 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
8618   ssl_provider0->next_proto = kProtoHTTP2;
8619   helper.AddDataWithSSLSocketDataProvider(&data0, std::move(ssl_provider0));
8620 
8621   // HTTP/1.1 to destination.
8622   SSLSocketDataProvider ssl_provider1(ASYNC, OK);
8623   ssl_provider1.next_proto = kProtoHTTP11;
8624   helper.session_deps()->socket_factory->AddSSLSocketDataProvider(
8625       &ssl_provider1);
8626 
8627   helper.RunPreTestSetup();
8628   helper.StartDefaultTest();
8629   helper.FinishDefaultTestWithoutVerification();
8630   helper.VerifyDataConsumed();
8631 
8632   const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
8633   ASSERT_TRUE(response);
8634   ASSERT_TRUE(response->headers);
8635   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8636   EXPECT_FALSE(response->was_fetched_via_spdy);
8637   EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
8638             response->connection_info);
8639   EXPECT_TRUE(response->was_alpn_negotiated);
8640   EXPECT_TRUE(request_.url.SchemeIs("https"));
8641   EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
8642   EXPECT_EQ(70, response->remote_endpoint.port());
8643   std::string response_data;
8644   ASSERT_THAT(ReadTransaction(helper.trans(), &response_data), IsOk());
8645   EXPECT_EQ("hello", response_data);
8646 }
8647 
8648 // Regression test for https://crbug.com/1081955.
8649 // Greasing frame types is enabled, the outgoing HEADERS frame is followed by a
8650 // frame of reserved type, then an empty DATA frame to close the stream.
8651 // Response arrives before reserved frame and DATA frame can be sent.
8652 // SpdyHttpStream::OnDataSent() must not crash.
TEST_F(SpdyNetworkTransactionTest,OnDataSentDoesNotCrashWithGreasedFrameType)8653 TEST_F(SpdyNetworkTransactionTest, OnDataSentDoesNotCrashWithGreasedFrameType) {
8654   auto session_deps = std::make_unique<SpdySessionDependencies>();
8655 
8656   const uint8_t type = 0x0b;
8657   const uint8_t flags = 0xcc;
8658   const std::string payload("foo");
8659   session_deps->greased_http2_frame =
8660       absl::optional<net::SpdySessionPool::GreasedHttp2Frame>(
8661           {type, flags, payload});
8662   session_deps->http2_end_stream_with_data_frame = true;
8663 
8664   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
8665                                      std::move(session_deps));
8666 
8667   spdy::Http2HeaderBlock headers(
8668       spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
8669   spdy::SpdySerializedFrame req(
8670       spdy_util_.ConstructSpdyHeaders(1, std::move(headers), DEFAULT_PRIORITY,
8671                                       /* fin = */ false));
8672 
8673   uint8_t kRawFrameData[] = {
8674       0x00, 0x00, 0x03,        // length
8675       0x0b,                    // type
8676       0xcc,                    // flags
8677       0x00, 0x00, 0x00, 0x01,  // stream ID
8678       'f',  'o',  'o'          // payload
8679   };
8680   spdy::SpdySerializedFrame grease(reinterpret_cast<char*>(kRawFrameData),
8681                                    std::size(kRawFrameData),
8682                                    /* owns_buffer = */ false);
8683   spdy::SpdySerializedFrame empty_body(
8684       spdy_util_.ConstructSpdyDataFrame(1, "", true));
8685 
8686   MockWrite writes[] = {
8687       CreateMockWrite(req, 0), MockWrite(ASYNC, ERR_IO_PENDING, 2),
8688       CreateMockWrite(grease, 3), CreateMockWrite(empty_body, 4)};
8689 
8690   spdy::SpdySerializedFrame resp(
8691       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
8692   spdy::SpdySerializedFrame response_body(
8693       spdy_util_.ConstructSpdyDataFrame(1, true));
8694 
8695   MockRead reads[] = {CreateMockRead(resp, 1), CreateMockRead(response_body, 5),
8696                       MockRead(ASYNC, 0, 6)};
8697 
8698   SequencedSocketData data(reads, writes);
8699   helper.RunPreTestSetup();
8700   helper.AddData(&data);
8701 
8702   TestCompletionCallback callback;
8703   int rv = helper.trans()->Start(&request_, callback.callback(), log_);
8704   base::RunLoop().RunUntilIdle();
8705 
8706   // Response headers received.  Resume sending |grease| and |empty_body|.
8707   data.Resume();
8708   EXPECT_THAT(callback.GetResult(rv), IsOk());
8709 
8710   base::RunLoop().RunUntilIdle();
8711 
8712   helper.VerifyDataConsumed();
8713 }
8714 
TEST_F(SpdyNetworkTransactionTest,NotAllowHTTP1NotBlockH2Post)8715 TEST_F(SpdyNetworkTransactionTest, NotAllowHTTP1NotBlockH2Post) {
8716   spdy::SpdySerializedFrame req(
8717       spdy_util_.ConstructChunkedSpdyPost(nullptr, 0));
8718   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
8719   MockWrite writes[] = {
8720       CreateMockWrite(req, 0), CreateMockWrite(body, 1),  // POST upload frame
8721   };
8722   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
8723   MockRead reads[] = {
8724       CreateMockRead(resp, 2), CreateMockRead(body, 3),
8725       MockRead(ASYNC, 0, 4)  // EOF
8726   };
8727   SequencedSocketData data(reads, writes);
8728 
8729   request_.method = "POST";
8730   UploadDataStreamNotAllowHTTP1 upload_data(kUploadData);
8731   request_.upload_data_stream = &upload_data;
8732 
8733   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
8734   helper.RunToCompletion(&data);
8735   TransactionHelperResult out = helper.output();
8736   EXPECT_THAT(out.rv, IsOk());
8737   EXPECT_EQ("HTTP/1.1 200", out.status_line);
8738   EXPECT_EQ("hello!", out.response_data);
8739 }
8740 
TEST_F(SpdyNetworkTransactionTest,AlpsFramingError)8741 TEST_F(SpdyNetworkTransactionTest, AlpsFramingError) {
8742   base::HistogramTester histogram_tester;
8743 
8744   spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
8745       0, spdy::ERROR_CODE_PROTOCOL_ERROR, "Error parsing ALPS: 3"));
8746   MockWrite writes[] = {CreateMockWrite(goaway, 0)};
8747   SequencedSocketData data(base::span<MockRead>(), writes);
8748 
8749   auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
8750   // Not a complete HTTP/2 frame.
8751   ssl_provider->peer_application_settings = "boo";
8752 
8753   NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
8754   helper.RunToCompletionWithSSLData(&data, std::move(ssl_provider));
8755 
8756   TransactionHelperResult out = helper.output();
8757   EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
8758 
8759   histogram_tester.ExpectUniqueSample(
8760       "Net.SpdySession.AlpsDecoderStatus",
8761       static_cast<int>(AlpsDecoder::Error::kNotOnFrameBoundary), 1);
8762   histogram_tester.ExpectTotalCount("Net.SpdySession.AlpsAcceptChEntries", 0);
8763   histogram_tester.ExpectTotalCount("Net.SpdySession.AlpsSettingParameterCount",
8764                                     0);
8765 }
8766 
8767 }  // namespace net
8768