• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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 #ifdef UNSAFE_BUFFERS_BUILD
6 // TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
7 #pragma allow_unsafe_buffers
8 #endif
9 
10 #include "net/http/http_transaction_test_util.h"
11 
12 #include <algorithm>
13 #include <unordered_map>
14 #include <utility>
15 
16 #include "base/functional/bind.h"
17 #include "base/functional/callback_helpers.h"
18 #include "base/location.h"
19 #include "base/run_loop.h"
20 #include "base/strings/stringprintf.h"
21 #include "base/task/single_thread_task_runner.h"
22 #include "base/time/clock.h"
23 #include "base/time/time.h"
24 #include "net/base/ip_address.h"
25 #include "net/base/ip_endpoint.h"
26 #include "net/base/load_flags.h"
27 #include "net/base/load_timing_info.h"
28 #include "net/base/net_errors.h"
29 #include "net/base/network_isolation_key.h"
30 #include "net/base/proxy_chain.h"
31 #include "net/base/schemeful_site.h"
32 #include "net/cert/x509_certificate.h"
33 #include "net/disk_cache/disk_cache.h"
34 #include "net/http/http_cache.h"
35 #include "net/http/http_request_info.h"
36 #include "net/http/http_response_info.h"
37 #include "net/http/http_transaction.h"
38 #include "net/log/net_log.h"
39 #include "net/log/net_log_source.h"
40 #include "net/ssl/ssl_private_key.h"
41 #include "testing/gtest/include/gtest/gtest.h"
42 #include "url/gurl.h"
43 
44 namespace net {
45 
46 namespace {
47 using MockTransactionMap =
48     std::unordered_map<std::string, const MockTransaction*>;
49 static MockTransactionMap mock_transactions;
50 
AddMockTransaction(const MockTransaction * trans)51 void AddMockTransaction(const MockTransaction* trans) {
52   auto result =
53       mock_transactions.insert(std::make_pair(GURL(trans->url).spec(), trans));
54   CHECK(result.second) << "Transaction already exists: " << trans->url;
55 }
56 
RemoveMockTransaction(const MockTransaction * trans)57 void RemoveMockTransaction(const MockTransaction* trans) {
58   mock_transactions.erase(GURL(trans->url).spec());
59 }
60 
61 }  // namespace
62 
DefaultTransportInfo()63 TransportInfo DefaultTransportInfo() {
64   return TransportInfo(TransportType::kDirect,
65                        IPEndPoint(IPAddress::IPv4Localhost(), 80),
66                        /*accept_ch_frame_arg=*/"",
67                        /*cert_is_issued_by_known_root=*/false, kProtoUnknown);
68 }
69 
70 //-----------------------------------------------------------------------------
71 // mock transaction data
72 
73 const MockTransaction kSimpleGET_Transaction = {
74     "http://www.google.com/",
75     "GET",
76     base::Time(),
77     "",
78     LOAD_NORMAL,
79     DefaultTransportInfo(),
80     "HTTP/1.1 200 OK",
81     "Cache-Control: max-age=10000\n",
82     base::Time(),
83     "<html><body>Google Blah Blah</body></html>",
84     {},
85     std::nullopt,
86     std::nullopt,
87     TEST_MODE_NORMAL,
88     MockTransactionHandler(),
89     MockTransactionReadHandler(),
90     nullptr,
91     0,
92     0,
93     OK,
94     OK,
95 };
96 
97 const MockTransaction kSimplePOST_Transaction = {
98     "http://bugdatabase.com/edit",
99     "POST",
100     base::Time(),
101     "",
102     LOAD_NORMAL,
103     DefaultTransportInfo(),
104     "HTTP/1.1 200 OK",
105     "",
106     base::Time(),
107     "<html><body>Google Blah Blah</body></html>",
108     {},
109     std::nullopt,
110     std::nullopt,
111     TEST_MODE_NORMAL,
112     MockTransactionHandler(),
113     MockTransactionReadHandler(),
114     nullptr,
115     0,
116     0,
117     OK,
118     OK,
119 };
120 
121 const MockTransaction kTypicalGET_Transaction = {
122     "http://www.example.com/~foo/bar.html",
123     "GET",
124     base::Time(),
125     "",
126     LOAD_NORMAL,
127     DefaultTransportInfo(),
128     "HTTP/1.1 200 OK",
129     "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
130     "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n",
131     base::Time(),
132     "<html><body>Google Blah Blah</body></html>",
133     {},
134     std::nullopt,
135     std::nullopt,
136     TEST_MODE_NORMAL,
137     MockTransactionHandler(),
138     MockTransactionReadHandler(),
139     nullptr,
140     0,
141     0,
142     OK,
143     OK,
144 };
145 
146 const MockTransaction kETagGET_Transaction = {
147     "http://www.google.com/foopy",
148     "GET",
149     base::Time(),
150     "",
151     LOAD_NORMAL,
152     DefaultTransportInfo(),
153     "HTTP/1.1 200 OK",
154     "Cache-Control: max-age=10000\n"
155     "Etag: \"foopy\"\n",
156     base::Time(),
157     "<html><body>Google Blah Blah</body></html>",
158     {},
159     std::nullopt,
160     std::nullopt,
161     TEST_MODE_NORMAL,
162     MockTransactionHandler(),
163     MockTransactionReadHandler(),
164     nullptr,
165     0,
166     0,
167     OK,
168     OK,
169 };
170 
171 const MockTransaction kRangeGET_Transaction = {
172     "http://www.google.com/",
173     "GET",
174     base::Time(),
175     "Range: 0-100\r\n",
176     LOAD_NORMAL,
177     DefaultTransportInfo(),
178     "HTTP/1.1 200 OK",
179     "Cache-Control: max-age=10000\n",
180     base::Time(),
181     "<html><body>Google Blah Blah</body></html>",
182     {},
183     std::nullopt,
184     std::nullopt,
185     TEST_MODE_NORMAL,
186     MockTransactionHandler(),
187     MockTransactionReadHandler(),
188     nullptr,
189     0,
190     0,
191     OK,
192     OK,
193 };
194 
195 static const MockTransaction* const kBuiltinMockTransactions[] = {
196   &kSimpleGET_Transaction,
197   &kSimplePOST_Transaction,
198   &kTypicalGET_Transaction,
199   &kETagGET_Transaction,
200   &kRangeGET_Transaction
201 };
202 
FindMockTransaction(const GURL & url)203 const MockTransaction* FindMockTransaction(const GURL& url) {
204   // look for overrides:
205   MockTransactionMap::const_iterator it = mock_transactions.find(url.spec());
206   if (it != mock_transactions.end())
207     return it->second;
208 
209   // look for builtins:
210   for (const auto* transaction : kBuiltinMockTransactions) {
211     if (url == GURL(transaction->url))
212       return transaction;
213   }
214   return nullptr;
215 }
216 
ScopedMockTransaction(const char * url)217 ScopedMockTransaction::ScopedMockTransaction(const char* url)
218     : MockTransaction({nullptr}) {
219   CHECK(url);
220   this->url = url;
221   AddMockTransaction(this);
222 }
223 
ScopedMockTransaction(const MockTransaction & t,const char * url)224 ScopedMockTransaction::ScopedMockTransaction(const MockTransaction& t,
225                                              const char* url)
226     : MockTransaction(t) {
227   if (url) {
228     this->url = url;
229   }
230   AddMockTransaction(this);
231 }
232 
~ScopedMockTransaction()233 ScopedMockTransaction::~ScopedMockTransaction() {
234   RemoveMockTransaction(this);
235 }
236 
MockHttpRequest(const MockTransaction & t)237 MockHttpRequest::MockHttpRequest(const MockTransaction& t) {
238   url = GURL(t.url);
239   method = t.method;
240   extra_headers.AddHeadersFromString(t.request_headers);
241   load_flags = t.load_flags;
242   SchemefulSite site(url);
243   network_isolation_key = NetworkIsolationKey(site, site);
244   network_anonymization_key = NetworkAnonymizationKey::CreateSameSite(site);
245   frame_origin = url::Origin::Create(url);
246   fps_cache_filter = t.fps_cache_filter;
247   browser_run_id = t.browser_run_id;
248 }
249 
CacheKey()250 std::string MockHttpRequest::CacheKey() {
251   return *HttpCache::GenerateCacheKeyForRequest(this);
252 }
253 
254 //-----------------------------------------------------------------------------
255 
TestTransactionConsumer(RequestPriority priority,HttpTransactionFactory * factory)256 TestTransactionConsumer::TestTransactionConsumer(
257     RequestPriority priority,
258     HttpTransactionFactory* factory) {
259   // Disregard the error code.
260   factory->CreateTransaction(priority, &trans_);
261 }
262 
263 TestTransactionConsumer::~TestTransactionConsumer() = default;
264 
Start(const HttpRequestInfo * request,const NetLogWithSource & net_log)265 void TestTransactionConsumer::Start(const HttpRequestInfo* request,
266                                     const NetLogWithSource& net_log) {
267   state_ = State::kStarting;
268   int result =
269       trans_->Start(request,
270                     base::BindOnce(&TestTransactionConsumer::OnIOComplete,
271                                    base::Unretained(this)),
272                     net_log);
273   if (result != ERR_IO_PENDING)
274     DidStart(result);
275 
276   base::RunLoop loop;
277   quit_closure_ = loop.QuitClosure();
278   loop.Run();
279 }
280 
DidStart(int result)281 void TestTransactionConsumer::DidStart(int result) {
282   if (result != OK) {
283     DidFinish(result);
284   } else {
285     Read();
286   }
287 }
288 
DidRead(int result)289 void TestTransactionConsumer::DidRead(int result) {
290   if (result <= 0) {
291     DidFinish(result);
292   } else {
293     content_.append(read_buf_->data(), result);
294     Read();
295   }
296 }
297 
DidFinish(int result)298 void TestTransactionConsumer::DidFinish(int result) {
299   state_ = State::kDone;
300   error_ = result;
301   if (!quit_closure_.is_null()) {
302     std::move(quit_closure_).Run();
303   }
304 }
305 
Read()306 void TestTransactionConsumer::Read() {
307   state_ = State::kReading;
308   read_buf_ = base::MakeRefCounted<IOBufferWithSize>(1024);
309   int result =
310       trans_->Read(read_buf_.get(), 1024,
311                    base::BindOnce(&TestTransactionConsumer::OnIOComplete,
312                                   base::Unretained(this)));
313   if (result != ERR_IO_PENDING)
314     DidRead(result);
315 }
316 
OnIOComplete(int result)317 void TestTransactionConsumer::OnIOComplete(int result) {
318   switch (state_) {
319     case State::kStarting:
320       DidStart(result);
321       break;
322     case State::kReading:
323       DidRead(result);
324       break;
325     default:
326       NOTREACHED();
327   }
328 }
329 
MockNetworkTransaction(RequestPriority priority,MockNetworkLayer * factory)330 MockNetworkTransaction::MockNetworkTransaction(RequestPriority priority,
331                                                MockNetworkLayer* factory)
332     : priority_(priority), transaction_factory_(factory->AsWeakPtr()) {}
333 
~MockNetworkTransaction()334 MockNetworkTransaction::~MockNetworkTransaction() {
335   // Use `original_request_ptr_` as in ~HttpNetworkTransaction to make sure its
336   // valid and not already freed by the consumer. Only check till Read is
337   // invoked since HttpNetworkTransaction sets request_ to nullptr when Read is
338   // invoked. See crbug.com/734037.
339   if (original_request_ptr_ && !reading_) {
340     DCHECK(original_request_ptr_->load_flags >= 0);
341   }
342 }
343 
Start(const HttpRequestInfo * request,CompletionOnceCallback callback,const NetLogWithSource & net_log)344 int MockNetworkTransaction::Start(const HttpRequestInfo* request,
345                                   CompletionOnceCallback callback,
346                                   const NetLogWithSource& net_log) {
347   net_log_ = net_log;
348   CHECK(!original_request_ptr_);
349   original_request_ptr_ = request;
350   return StartInternal(*request, std::move(callback));
351 }
352 
RestartIgnoringLastError(CompletionOnceCallback callback)353 int MockNetworkTransaction::RestartIgnoringLastError(
354     CompletionOnceCallback callback) {
355   return ERR_FAILED;
356 }
357 
RestartWithCertificate(scoped_refptr<X509Certificate> client_cert,scoped_refptr<SSLPrivateKey> client_private_key,CompletionOnceCallback callback)358 int MockNetworkTransaction::RestartWithCertificate(
359     scoped_refptr<X509Certificate> client_cert,
360     scoped_refptr<SSLPrivateKey> client_private_key,
361     CompletionOnceCallback callback) {
362   return ERR_FAILED;
363 }
364 
RestartWithAuth(const AuthCredentials & credentials,CompletionOnceCallback callback)365 int MockNetworkTransaction::RestartWithAuth(const AuthCredentials& credentials,
366                                             CompletionOnceCallback callback) {
367   if (!IsReadyToRestartForAuth())
368     return ERR_FAILED;
369 
370   HttpRequestInfo auth_request_info = *original_request_ptr_;
371   auth_request_info.extra_headers.SetHeader("Authorization", "Bar");
372 
373   // Let the MockTransactionHandler worry about this: the only way for this
374   // test to succeed is by using an explicit handler for the transaction so
375   // that server behavior can be simulated.
376   return StartInternal(std::move(auth_request_info), std::move(callback));
377 }
378 
PopulateNetErrorDetails(NetErrorDetails *) const379 void MockNetworkTransaction::PopulateNetErrorDetails(
380     NetErrorDetails* /*details*/) const {
381   NOTIMPLEMENTED();
382 }
383 
IsReadyToRestartForAuth()384 bool MockNetworkTransaction::IsReadyToRestartForAuth() {
385   CHECK(original_request_ptr_);
386   if (!original_request_ptr_->extra_headers.HasHeader("X-Require-Mock-Auth")) {
387     return false;
388   }
389 
390   // Allow the mock server to decide whether authentication is required or not.
391   std::string status_line = response_.headers->GetStatusLine();
392   return status_line.find(" 401 ") != std::string::npos ||
393       status_line.find(" 407 ") != std::string::npos;
394 }
395 
Read(IOBuffer * buf,int buf_len,CompletionOnceCallback callback)396 int MockNetworkTransaction::Read(IOBuffer* buf,
397                                  int buf_len,
398                                  CompletionOnceCallback callback) {
399   const MockTransaction* t = FindMockTransaction(current_request_.url);
400   DCHECK(t);
401 
402   CHECK(!done_reading_called_);
403   reading_ = true;
404 
405   int num = t->read_return_code;
406 
407   if (OK == num) {
408     if (t->read_handler) {
409       num = t->read_handler.Run(content_length_, data_cursor_, buf, buf_len);
410       data_cursor_ += num;
411     } else {
412       int data_len = static_cast<int>(data_.size());
413       num = std::min(static_cast<int64_t>(buf_len), data_len - data_cursor_);
414       if (test_mode_ & TEST_MODE_SLOW_READ)
415         num = std::min(num, 1);
416       if (num) {
417         memcpy(buf->data(), data_.data() + data_cursor_, num);
418         data_cursor_ += num;
419       }
420     }
421   }
422 
423   if (test_mode_ & TEST_MODE_SYNC_NET_READ)
424     return num;
425 
426   CallbackLater(std::move(callback), num);
427   return ERR_IO_PENDING;
428 }
429 
StopCaching()430 void MockNetworkTransaction::StopCaching() {
431   if (transaction_factory_.get())
432     transaction_factory_->TransactionStopCaching();
433 }
434 
GetTotalReceivedBytes() const435 int64_t MockNetworkTransaction::GetTotalReceivedBytes() const {
436   return received_bytes_;
437 }
438 
GetTotalSentBytes() const439 int64_t MockNetworkTransaction::GetTotalSentBytes() const {
440   return sent_bytes_;
441 }
442 
GetReceivedBodyBytes() const443 int64_t MockNetworkTransaction::GetReceivedBodyBytes() const {
444   return received_body_bytes_;
445 }
446 
DoneReading()447 void MockNetworkTransaction::DoneReading() {
448   CHECK(!done_reading_called_);
449   done_reading_called_ = true;
450   if (transaction_factory_.get())
451     transaction_factory_->TransactionDoneReading();
452 }
453 
GetResponseInfo() const454 const HttpResponseInfo* MockNetworkTransaction::GetResponseInfo() const {
455   return &response_;
456 }
457 
GetLoadState() const458 LoadState MockNetworkTransaction::GetLoadState() const {
459   if (data_cursor_)
460     return LOAD_STATE_READING_RESPONSE;
461   return LOAD_STATE_IDLE;
462 }
463 
SetQuicServerInfo(QuicServerInfo * quic_server_info)464 void MockNetworkTransaction::SetQuicServerInfo(
465     QuicServerInfo* quic_server_info) {
466 }
467 
GetLoadTimingInfo(LoadTimingInfo * load_timing_info) const468 bool MockNetworkTransaction::GetLoadTimingInfo(
469     LoadTimingInfo* load_timing_info) const {
470   if (socket_log_id_ != NetLogSource::kInvalidId) {
471     // The minimal set of times for a request that gets a response, assuming it
472     // gets a new socket.
473     load_timing_info->socket_reused = false;
474     load_timing_info->socket_log_id = socket_log_id_;
475     load_timing_info->connect_timing.connect_start = base::TimeTicks::Now();
476     load_timing_info->connect_timing.connect_end = base::TimeTicks::Now();
477     load_timing_info->send_start = base::TimeTicks::Now();
478     load_timing_info->send_end = base::TimeTicks::Now();
479   } else {
480     // If there's no valid socket ID, just use the generic socket reused values.
481     // No tests currently depend on this, just should not match the values set
482     // by a cache hit.
483     load_timing_info->socket_reused = true;
484     load_timing_info->send_start = base::TimeTicks::Now();
485     load_timing_info->send_end = base::TimeTicks::Now();
486   }
487   return true;
488 }
489 
GetRemoteEndpoint(IPEndPoint * endpoint) const490 bool MockNetworkTransaction::GetRemoteEndpoint(IPEndPoint* endpoint) const {
491   *endpoint = IPEndPoint(IPAddress(127, 0, 0, 1), 80);
492   return true;
493 }
494 
SetPriority(RequestPriority priority)495 void MockNetworkTransaction::SetPriority(RequestPriority priority) {
496   priority_ = priority;
497 }
498 
SetWebSocketHandshakeStreamCreateHelper(WebSocketHandshakeStreamBase::CreateHelper * create_helper)499 void MockNetworkTransaction::SetWebSocketHandshakeStreamCreateHelper(
500     WebSocketHandshakeStreamBase::CreateHelper* create_helper) {
501   websocket_handshake_stream_create_helper_ = create_helper;
502 }
503 
504 // static
505 const int64_t MockNetworkTransaction::kTotalReceivedBytes = 1000;
506 
507 // static
508 const int64_t MockNetworkTransaction::kTotalSentBytes = 100;
509 
510 // static
511 const int64_t MockNetworkTransaction::kReceivedBodyBytes = 500;
512 
StartInternal(HttpRequestInfo request,CompletionOnceCallback callback)513 int MockNetworkTransaction::StartInternal(HttpRequestInfo request,
514                                           CompletionOnceCallback callback) {
515   current_request_ = std::move(request);
516   const MockTransaction* t = FindMockTransaction(current_request_.url);
517   if (!t) {
518     return ERR_FAILED;
519   }
520   test_mode_ = t->test_mode;
521 
522   // Return immediately if we're returning an error.
523   if (OK != t->start_return_code) {
524     if (test_mode_ & TEST_MODE_SYNC_NET_START) {
525       return t->start_return_code;
526     }
527     CallbackLater(std::move(callback), t->start_return_code);
528     return ERR_IO_PENDING;
529   }
530 
531   next_state_ = State::NOTIFY_BEFORE_CREATE_STREAM;
532   int rv = DoLoop(OK);
533   if (rv == ERR_IO_PENDING) {
534     callback_ = std::move(callback);
535   }
536   return rv;
537 }
538 
DoNotifyBeforeCreateStream()539 int MockNetworkTransaction::DoNotifyBeforeCreateStream() {
540   next_state_ = State::CREATE_STREAM;
541   bool defer = false;
542   if (!before_network_start_callback_.is_null()) {
543     std::move(before_network_start_callback_).Run(&defer);
544   }
545   if (!defer) {
546     return OK;
547   }
548   return ERR_IO_PENDING;
549 }
550 
DoCreateStream()551 int MockNetworkTransaction::DoCreateStream() {
552   next_state_ = State::CREATE_STREAM_COMPLETE;
553   if (test_mode_ & TEST_MODE_SYNC_NET_START) {
554     return OK;
555   }
556   base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
557       FROM_HERE, base::BindOnce(&MockNetworkTransaction::OnIOComplete,
558                                 weak_factory_.GetWeakPtr(), OK));
559   return ERR_IO_PENDING;
560 }
561 
DoCreateStreamComplete(int result)562 int MockNetworkTransaction::DoCreateStreamComplete(int result) {
563   // We don't have a logic which simulate stream creation
564   CHECK_EQ(OK, result);
565   next_state_ = State::CONNECTED_CALLBACK;
566   return OK;
567 }
568 
DoConnectedCallback()569 int MockNetworkTransaction::DoConnectedCallback() {
570   next_state_ = State::CONNECTED_CALLBACK_COMPLETE;
571   if (connected_callback_.is_null()) {
572     return OK;
573   }
574 
575   const MockTransaction* t = FindMockTransaction(current_request_.url);
576   CHECK(t);
577   return connected_callback_.Run(
578       t->transport_info, base::BindOnce(&MockNetworkTransaction::OnIOComplete,
579                                         weak_factory_.GetWeakPtr()));
580 }
581 
DoConnectedCallbackComplete(int result)582 int MockNetworkTransaction::DoConnectedCallbackComplete(int result) {
583   if (result != OK) {
584     return result;
585   }
586   next_state_ = State::BUILD_REQUEST;
587   return OK;
588 }
589 
DoBuildRequest()590 int MockNetworkTransaction::DoBuildRequest() {
591   next_state_ = State::BUILD_REQUEST_COMPLETE;
592   if (modify_request_headers_callback_) {
593     modify_request_headers_callback_.Run(&current_request_.extra_headers);
594   }
595   return OK;
596 }
597 
DoBuildRequestComplete(int result)598 int MockNetworkTransaction::DoBuildRequestComplete(int result) {
599   CHECK_EQ(OK, result);
600   next_state_ = State::SEND_REQUEST;
601   return OK;
602 }
603 
DoSendRequest()604 int MockNetworkTransaction::DoSendRequest() {
605   next_state_ = State::SEND_REQUEST_COMPLETE;
606 
607   sent_bytes_ = kTotalSentBytes;
608   received_bytes_ = kTotalReceivedBytes;
609   received_body_bytes_ = kReceivedBodyBytes;
610 
611   const MockTransaction* t = FindMockTransaction(current_request_.url);
612   CHECK(t);
613 
614   std::string resp_status = t->status;
615   std::string resp_headers = t->response_headers;
616   std::string resp_data = t->data;
617 
618   if (t->handler) {
619     t->handler.Run(&current_request_, &resp_status, &resp_headers, &resp_data);
620   }
621   std::string header_data =
622       base::StringPrintf("%s\n%s\n", resp_status.c_str(), resp_headers.c_str());
623   std::replace(header_data.begin(), header_data.end(), '\n', '\0');
624 
625   response_.request_time = transaction_factory_->Now();
626   if (!t->request_time.is_null())
627     response_.request_time = t->request_time;
628 
629   response_.was_cached = false;
630   response_.network_accessed = true;
631   response_.remote_endpoint = t->transport_info.endpoint;
632   if (t->transport_info.type == TransportType::kDirect) {
633     response_.proxy_chain = ProxyChain::Direct();
634   } else if (t->transport_info.type == TransportType::kProxied) {
635     response_.proxy_chain = ProxyChain::FromSchemeHostAndPort(
636         ProxyServer::SCHEME_HTTP,
637         t->transport_info.endpoint.ToStringWithoutPort(),
638         t->transport_info.endpoint.port());
639   }
640 
641   response_.response_time = transaction_factory_->Now();
642   if (!t->response_time.is_null()) {
643     response_.response_time = t->response_time;
644     response_.original_response_time = t->response_time;
645   }
646 
647   response_.headers = base::MakeRefCounted<HttpResponseHeaders>(header_data);
648   response_.ssl_info.cert = t->cert;
649   response_.ssl_info.cert_status = t->cert_status;
650   response_.ssl_info.connection_status = t->ssl_connection_status;
651   response_.dns_aliases = t->dns_aliases;
652   data_ = resp_data;
653   content_length_ = response_.headers->GetContentLength();
654 
655   if (net_log_.net_log()) {
656     socket_log_id_ = net_log_.net_log()->NextID();
657   }
658 
659   if (current_request_.load_flags & LOAD_PREFETCH) {
660     response_.unused_since_prefetch = true;
661   }
662 
663   if (current_request_.load_flags & LOAD_RESTRICTED_PREFETCH_FOR_MAIN_FRAME) {
664     DCHECK(response_.unused_since_prefetch);
665     response_.restricted_prefetch = true;
666   }
667   return OK;
668 }
669 
DoSendRequestComplete(int result)670 int MockNetworkTransaction::DoSendRequestComplete(int result) {
671   CHECK_EQ(OK, result);
672   next_state_ = State::READ_HEADERS;
673   return OK;
674 }
675 
DoReadHeaders()676 int MockNetworkTransaction::DoReadHeaders() {
677   next_state_ = State::READ_HEADERS_COMPLETE;
678   return OK;
679 }
680 
DoReadHeadersComplete(int result)681 int MockNetworkTransaction::DoReadHeadersComplete(int result) {
682   CHECK_EQ(OK, result);
683   return OK;
684 }
685 
DoLoop(int result)686 int MockNetworkTransaction::DoLoop(int result) {
687   CHECK(next_state_ != State::NONE);
688 
689   int rv = result;
690   do {
691     State state = next_state_;
692     next_state_ = State::NONE;
693     switch (state) {
694       case State::NOTIFY_BEFORE_CREATE_STREAM:
695         CHECK_EQ(OK, rv);
696         rv = DoNotifyBeforeCreateStream();
697         break;
698       case State::CREATE_STREAM:
699         CHECK_EQ(OK, rv);
700         rv = DoCreateStream();
701         break;
702       case State::CREATE_STREAM_COMPLETE:
703         rv = DoCreateStreamComplete(rv);
704         break;
705       case State::CONNECTED_CALLBACK:
706         rv = DoConnectedCallback();
707         break;
708       case State::CONNECTED_CALLBACK_COMPLETE:
709         rv = DoConnectedCallbackComplete(rv);
710         break;
711       case State::BUILD_REQUEST:
712         CHECK_EQ(OK, rv);
713         rv = DoBuildRequest();
714         break;
715       case State::BUILD_REQUEST_COMPLETE:
716         rv = DoBuildRequestComplete(rv);
717         break;
718       case State::SEND_REQUEST:
719         CHECK_EQ(OK, rv);
720         rv = DoSendRequest();
721         break;
722       case State::SEND_REQUEST_COMPLETE:
723         rv = DoSendRequestComplete(rv);
724         break;
725       case State::READ_HEADERS:
726         CHECK_EQ(OK, rv);
727         rv = DoReadHeaders();
728         break;
729       case State::READ_HEADERS_COMPLETE:
730         rv = DoReadHeadersComplete(rv);
731         break;
732       default:
733         NOTREACHED() << "bad state";
734     }
735   } while (rv != ERR_IO_PENDING && next_state_ != State::NONE);
736 
737   return rv;
738 }
739 
OnIOComplete(int result)740 void MockNetworkTransaction::OnIOComplete(int result) {
741   int rv = DoLoop(result);
742   if (rv != ERR_IO_PENDING) {
743     CHECK(callback_);
744     std::move(callback_).Run(rv);
745   }
746 }
747 
SetBeforeNetworkStartCallback(BeforeNetworkStartCallback callback)748 void MockNetworkTransaction::SetBeforeNetworkStartCallback(
749     BeforeNetworkStartCallback callback) {
750   before_network_start_callback_ = std::move(callback);
751 }
752 
SetModifyRequestHeadersCallback(base::RepeatingCallback<void (HttpRequestHeaders *)> callback)753 void MockNetworkTransaction::SetModifyRequestHeadersCallback(
754     base::RepeatingCallback<void(HttpRequestHeaders*)> callback) {
755   modify_request_headers_callback_ = std::move(callback);
756 }
757 
SetConnectedCallback(const ConnectedCallback & callback)758 void MockNetworkTransaction::SetConnectedCallback(
759     const ConnectedCallback& callback) {
760   connected_callback_ = callback;
761 }
762 
ResumeNetworkStart()763 int MockNetworkTransaction::ResumeNetworkStart() {
764   CHECK_EQ(next_state_, State::CREATE_STREAM);
765   return DoLoop(OK);
766 }
767 
GetConnectionAttempts() const768 ConnectionAttempts MockNetworkTransaction::GetConnectionAttempts() const {
769   // TODO(ricea): Replace this with a proper implementation if needed.
770   return {};
771 }
772 
CloseConnectionOnDestruction()773 void MockNetworkTransaction::CloseConnectionOnDestruction() {
774   NOTIMPLEMENTED();
775 }
776 
IsMdlMatchForMetrics() const777 bool MockNetworkTransaction::IsMdlMatchForMetrics() const {
778   return false;
779 }
780 
CallbackLater(CompletionOnceCallback callback,int result)781 void MockNetworkTransaction::CallbackLater(CompletionOnceCallback callback,
782                                            int result) {
783   base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
784       FROM_HERE,
785       base::BindOnce(&MockNetworkTransaction::RunCallback,
786                      weak_factory_.GetWeakPtr(), std::move(callback), result));
787 }
788 
RunCallback(CompletionOnceCallback callback,int result)789 void MockNetworkTransaction::RunCallback(CompletionOnceCallback callback,
790                                          int result) {
791   std::move(callback).Run(result);
792 }
793 
794 MockNetworkLayer::MockNetworkLayer() = default;
795 
796 MockNetworkLayer::~MockNetworkLayer() = default;
797 
TransactionDoneReading()798 void MockNetworkLayer::TransactionDoneReading() {
799   CHECK(!done_reading_called_);
800   done_reading_called_ = true;
801 }
802 
TransactionStopCaching()803 void MockNetworkLayer::TransactionStopCaching() {
804   stop_caching_called_ = true;
805 }
806 
ResetTransactionCount()807 void MockNetworkLayer::ResetTransactionCount() {
808   transaction_count_ = 0;
809 }
810 
CreateTransaction(RequestPriority priority,std::unique_ptr<HttpTransaction> * trans)811 int MockNetworkLayer::CreateTransaction(
812     RequestPriority priority,
813     std::unique_ptr<HttpTransaction>* trans) {
814   transaction_count_++;
815   last_create_transaction_priority_ = priority;
816   auto mock_transaction =
817       std::make_unique<MockNetworkTransaction>(priority, this);
818   last_transaction_ = mock_transaction->AsWeakPtr();
819   *trans = std::move(mock_transaction);
820   return OK;
821 }
822 
GetCache()823 HttpCache* MockNetworkLayer::GetCache() {
824   return nullptr;
825 }
826 
GetSession()827 HttpNetworkSession* MockNetworkLayer::GetSession() {
828   return nullptr;
829 }
830 
SetClock(base::Clock * clock)831 void MockNetworkLayer::SetClock(base::Clock* clock) {
832   DCHECK(!clock_);
833   clock_ = clock;
834 }
835 
Now()836 base::Time MockNetworkLayer::Now() {
837   if (clock_)
838     return clock_->Now();
839   return base::Time::Now();
840 }
841 
842 //-----------------------------------------------------------------------------
843 // helpers
844 
ReadTransaction(HttpTransaction * trans,std::string * result)845 int ReadTransaction(HttpTransaction* trans, std::string* result) {
846   int rv;
847 
848   std::string content;
849   do {
850     TestCompletionCallback callback;
851     auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
852     rv = trans->Read(buf.get(), 256, callback.callback());
853     if (rv == ERR_IO_PENDING) {
854       rv = callback.WaitForResult();
855       base::RunLoop().RunUntilIdle();
856     }
857 
858     if (rv > 0)
859       content.append(buf->data(), rv);
860     else if (rv < 0)
861       return rv;
862   } while (rv > 0);
863 
864   result->swap(content);
865   return OK;
866 }
867 
868 //-----------------------------------------------------------------------------
869 // connected callback handler
870 
871 ConnectedHandler::ConnectedHandler() = default;
872 ConnectedHandler::~ConnectedHandler() = default;
873 
874 ConnectedHandler::ConnectedHandler(const ConnectedHandler&) = default;
875 ConnectedHandler& ConnectedHandler::operator=(const ConnectedHandler&) =
876     default;
877 ConnectedHandler::ConnectedHandler(ConnectedHandler&&) = default;
878 ConnectedHandler& ConnectedHandler::operator=(ConnectedHandler&&) = default;
879 
OnConnected(const TransportInfo & info,CompletionOnceCallback callback)880 int ConnectedHandler::OnConnected(const TransportInfo& info,
881                                   CompletionOnceCallback callback) {
882   transports_.push_back(info);
883   if (run_callback_) {
884     base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
885         FROM_HERE, base::BindOnce(std::move(callback), result_));
886     return ERR_IO_PENDING;
887   }
888   return result_;
889 }
890 
891 }  // namespace net
892