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