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