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(¤t_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(¤t_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