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