OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <memory> | 5 #include <memory> |
6 #include <utility> | 6 #include <utility> |
7 | 7 |
8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 | 378 |
379 // Behavior during blocked stages. During other stages, just | 379 // Behavior during blocked stages. During other stages, just |
380 // returns OK or NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION. | 380 // returns OK or NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION. |
381 enum BlockMode { | 381 enum BlockMode { |
382 SYNCHRONOUS, // No callback, returns specified return values. | 382 SYNCHRONOUS, // No callback, returns specified return values. |
383 AUTO_CALLBACK, // |this| posts a task to run the callback using the | 383 AUTO_CALLBACK, // |this| posts a task to run the callback using the |
384 // specified return codes. | 384 // specified return codes. |
385 USER_CALLBACK, // User takes care of doing a callback. |retval_| and | 385 USER_CALLBACK, // User takes care of doing a callback. |retval_| and |
386 // |auth_retval_| are ignored. In every blocking stage the | 386 // |auth_retval_| are ignored. In every blocking stage the |
387 // message loop is quit. | 387 // message loop is quit. |
| 388 USER_NOTIFY, // User is notified by a provided callback of the |
| 389 // blocking, and synchronously returns instructions |
| 390 // for handling it. |
388 }; | 391 }; |
389 | 392 |
| 393 using NotificationCallback = |
| 394 base::Callback<Error(const CompletionCallback&, const URLRequest*)>; |
| 395 |
| 396 using NotificationAuthCallback = |
| 397 base::Callback<NetworkDelegate::AuthRequiredResponse(const AuthCallback&, |
| 398 const URLRequest*)>; |
| 399 |
390 // Creates a delegate which does not block at all. | 400 // Creates a delegate which does not block at all. |
391 explicit BlockingNetworkDelegate(BlockMode block_mode); | 401 explicit BlockingNetworkDelegate(BlockMode block_mode); |
392 | 402 |
393 // For users to trigger a callback returning |response|. | 403 // For users to trigger a callback returning |response|. |
394 // Side-effects: resets |stage_blocked_for_callback_| and stored callbacks. | 404 // Side-effects: resets |stage_blocked_for_callback_| and stored callbacks. |
395 // Only call if |block_mode_| == USER_CALLBACK. | 405 // Only call if |block_mode_| == USER_CALLBACK. |
396 void DoCallback(int response); | 406 void DoCallback(int response); |
397 void DoAuthCallback(NetworkDelegate::AuthRequiredResponse response); | 407 void DoAuthCallback(NetworkDelegate::AuthRequiredResponse response); |
398 | 408 |
399 // Setters. | 409 // Setters. |
(...skipping 16 matching lines...) Expand all Loading... |
416 } | 426 } |
417 | 427 |
418 void set_redirect_url(const GURL& url) { | 428 void set_redirect_url(const GURL& url) { |
419 redirect_url_ = url; | 429 redirect_url_ = url; |
420 } | 430 } |
421 | 431 |
422 void set_block_on(int block_on) { | 432 void set_block_on(int block_on) { |
423 block_on_ = block_on; | 433 block_on_ = block_on; |
424 } | 434 } |
425 | 435 |
| 436 // Only valid if |block_mode_| == USER_NOTIFY |
| 437 void set_notification_callback( |
| 438 const NotificationCallback& notification_callback) { |
| 439 notification_callback_ = notification_callback; |
| 440 } |
| 441 |
| 442 void set_notification_auth_callback( |
| 443 const NotificationAuthCallback& notification_auth_callback) { |
| 444 notification_auth_callback_ = notification_auth_callback; |
| 445 } |
| 446 |
426 // Allows the user to check in which state did we block. | 447 // Allows the user to check in which state did we block. |
427 Stage stage_blocked_for_callback() const { | 448 Stage stage_blocked_for_callback() const { |
428 EXPECT_EQ(USER_CALLBACK, block_mode_); | 449 EXPECT_EQ(USER_CALLBACK, block_mode_); |
429 return stage_blocked_for_callback_; | 450 return stage_blocked_for_callback_; |
430 } | 451 } |
431 | 452 |
432 private: | 453 private: |
433 void RunCallback(int response, const CompletionCallback& callback); | 454 void RunCallback(int response, const CompletionCallback& callback); |
434 void RunAuthCallback(AuthRequiredResponse response, | 455 void RunAuthCallback(AuthRequiredResponse response, |
435 const AuthCallback& callback); | 456 const AuthCallback& callback); |
(...skipping 18 matching lines...) Expand all Loading... |
454 URLRequest* request, | 475 URLRequest* request, |
455 const AuthChallengeInfo& auth_info, | 476 const AuthChallengeInfo& auth_info, |
456 const AuthCallback& callback, | 477 const AuthCallback& callback, |
457 AuthCredentials* credentials) override; | 478 AuthCredentials* credentials) override; |
458 | 479 |
459 // Resets the callbacks and |stage_blocked_for_callback_|. | 480 // Resets the callbacks and |stage_blocked_for_callback_|. |
460 void Reset(); | 481 void Reset(); |
461 | 482 |
462 // Checks whether we should block in |stage|. If yes, returns an error code | 483 // Checks whether we should block in |stage|. If yes, returns an error code |
463 // and optionally sets up callback based on |block_mode_|. If no, returns OK. | 484 // and optionally sets up callback based on |block_mode_|. If no, returns OK. |
464 int MaybeBlockStage(Stage stage, const CompletionCallback& callback); | 485 int MaybeBlockStage(Stage stage, |
| 486 const URLRequest* request, |
| 487 const CompletionCallback& callback); |
465 | 488 |
466 // Configuration parameters, can be adjusted by public methods: | 489 // Configuration parameters, can be adjusted by public methods: |
467 const BlockMode block_mode_; | 490 const BlockMode block_mode_; |
468 | 491 |
469 // Values returned on blocking stages when mode is SYNCHRONOUS or | 492 // Values returned on blocking stages when mode is SYNCHRONOUS or |
470 // AUTO_CALLBACK. For USER_CALLBACK these are set automatically to IO_PENDING. | 493 // AUTO_CALLBACK. For USER_CALLBACK these are set automatically to IO_PENDING. |
471 int retval_; // To be returned in non-auth stages. | 494 int retval_; // To be returned in non-auth stages. |
472 AuthRequiredResponse auth_retval_; | 495 AuthRequiredResponse auth_retval_; |
473 | 496 |
474 GURL redirect_url_; // Used if non-empty during OnBeforeURLRequest. | 497 GURL redirect_url_; // Used if non-empty during OnBeforeURLRequest. |
475 int block_on_; // Bit mask: in which stages to block. | 498 int block_on_; // Bit mask: in which stages to block. |
476 | 499 |
477 // |auth_credentials_| will be copied to |*target_auth_credential_| on | 500 // |auth_credentials_| will be copied to |*target_auth_credential_| on |
478 // callback. | 501 // callback. |
479 AuthCredentials auth_credentials_; | 502 AuthCredentials auth_credentials_; |
480 AuthCredentials* target_auth_credentials_; | 503 AuthCredentials* target_auth_credentials_; |
481 | 504 |
482 // Internal variables, not set by not the user: | 505 // Internal variables, not set by not the user: |
483 // Last blocked stage waiting for user callback (unused if |block_mode_| != | 506 // Last blocked stage waiting for user callback (unused if |block_mode_| != |
484 // USER_CALLBACK). | 507 // USER_CALLBACK). |
485 Stage stage_blocked_for_callback_; | 508 Stage stage_blocked_for_callback_; |
486 | 509 |
487 // Callback objects stored during blocking stages. | 510 // Callback objects stored during blocking stages. |
488 CompletionCallback callback_; | 511 CompletionCallback callback_; |
489 AuthCallback auth_callback_; | 512 AuthCallback auth_callback_; |
490 | 513 |
| 514 // Callback to request user instructions for blocking. |
| 515 NotificationCallback notification_callback_; |
| 516 NotificationAuthCallback notification_auth_callback_; |
| 517 |
491 base::WeakPtrFactory<BlockingNetworkDelegate> weak_factory_; | 518 base::WeakPtrFactory<BlockingNetworkDelegate> weak_factory_; |
492 | 519 |
493 DISALLOW_COPY_AND_ASSIGN(BlockingNetworkDelegate); | 520 DISALLOW_COPY_AND_ASSIGN(BlockingNetworkDelegate); |
494 }; | 521 }; |
495 | 522 |
496 BlockingNetworkDelegate::BlockingNetworkDelegate(BlockMode block_mode) | 523 BlockingNetworkDelegate::BlockingNetworkDelegate(BlockMode block_mode) |
497 : block_mode_(block_mode), | 524 : block_mode_(block_mode), |
498 retval_(OK), | 525 retval_(OK), |
499 auth_retval_(AUTH_REQUIRED_RESPONSE_NO_ACTION), | 526 auth_retval_(AUTH_REQUIRED_RESPONSE_NO_ACTION), |
500 block_on_(0), | 527 block_on_(0), |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 const CompletionCallback& callback, | 567 const CompletionCallback& callback, |
541 GURL* new_url) { | 568 GURL* new_url) { |
542 if (redirect_url_ == request->url()) | 569 if (redirect_url_ == request->url()) |
543 return OK; // We've already seen this request and redirected elsewhere. | 570 return OK; // We've already seen this request and redirected elsewhere. |
544 | 571 |
545 TestNetworkDelegate::OnBeforeURLRequest(request, callback, new_url); | 572 TestNetworkDelegate::OnBeforeURLRequest(request, callback, new_url); |
546 | 573 |
547 if (!redirect_url_.is_empty()) | 574 if (!redirect_url_.is_empty()) |
548 *new_url = redirect_url_; | 575 *new_url = redirect_url_; |
549 | 576 |
550 return MaybeBlockStage(ON_BEFORE_URL_REQUEST, callback); | 577 return MaybeBlockStage(ON_BEFORE_URL_REQUEST, request, callback); |
551 } | 578 } |
552 | 579 |
553 int BlockingNetworkDelegate::OnBeforeStartTransaction( | 580 int BlockingNetworkDelegate::OnBeforeStartTransaction( |
554 URLRequest* request, | 581 URLRequest* request, |
555 const CompletionCallback& callback, | 582 const CompletionCallback& callback, |
556 HttpRequestHeaders* headers) { | 583 HttpRequestHeaders* headers) { |
557 TestNetworkDelegate::OnBeforeStartTransaction(request, callback, headers); | 584 TestNetworkDelegate::OnBeforeStartTransaction(request, callback, headers); |
558 | 585 |
559 return MaybeBlockStage(ON_BEFORE_SEND_HEADERS, callback); | 586 return MaybeBlockStage(ON_BEFORE_SEND_HEADERS, request, callback); |
560 } | 587 } |
561 | 588 |
562 int BlockingNetworkDelegate::OnHeadersReceived( | 589 int BlockingNetworkDelegate::OnHeadersReceived( |
563 URLRequest* request, | 590 URLRequest* request, |
564 const CompletionCallback& callback, | 591 const CompletionCallback& callback, |
565 const HttpResponseHeaders* original_response_headers, | 592 const HttpResponseHeaders* original_response_headers, |
566 scoped_refptr<HttpResponseHeaders>* override_response_headers, | 593 scoped_refptr<HttpResponseHeaders>* override_response_headers, |
567 GURL* allowed_unsafe_redirect_url) { | 594 GURL* allowed_unsafe_redirect_url) { |
568 TestNetworkDelegate::OnHeadersReceived(request, | 595 TestNetworkDelegate::OnHeadersReceived(request, |
569 callback, | 596 callback, |
570 original_response_headers, | 597 original_response_headers, |
571 override_response_headers, | 598 override_response_headers, |
572 allowed_unsafe_redirect_url); | 599 allowed_unsafe_redirect_url); |
573 | 600 |
574 return MaybeBlockStage(ON_HEADERS_RECEIVED, callback); | 601 return MaybeBlockStage(ON_HEADERS_RECEIVED, request, callback); |
575 } | 602 } |
576 | 603 |
577 NetworkDelegate::AuthRequiredResponse BlockingNetworkDelegate::OnAuthRequired( | 604 NetworkDelegate::AuthRequiredResponse BlockingNetworkDelegate::OnAuthRequired( |
578 URLRequest* request, | 605 URLRequest* request, |
579 const AuthChallengeInfo& auth_info, | 606 const AuthChallengeInfo& auth_info, |
580 const AuthCallback& callback, | 607 const AuthCallback& callback, |
581 AuthCredentials* credentials) { | 608 AuthCredentials* credentials) { |
582 TestNetworkDelegate::OnAuthRequired(request, auth_info, callback, | 609 TestNetworkDelegate::OnAuthRequired(request, auth_info, callback, |
583 credentials); | 610 credentials); |
584 // Check that the user has provided callback for the previous blocked stage. | 611 // Check that the user has provided callback for the previous blocked stage. |
(...skipping 17 matching lines...) Expand all Loading... |
602 base::Bind(&BlockingNetworkDelegate::RunAuthCallback, | 629 base::Bind(&BlockingNetworkDelegate::RunAuthCallback, |
603 weak_factory_.GetWeakPtr(), auth_retval_, callback)); | 630 weak_factory_.GetWeakPtr(), auth_retval_, callback)); |
604 return AUTH_REQUIRED_RESPONSE_IO_PENDING; | 631 return AUTH_REQUIRED_RESPONSE_IO_PENDING; |
605 | 632 |
606 case USER_CALLBACK: | 633 case USER_CALLBACK: |
607 auth_callback_ = callback; | 634 auth_callback_ = callback; |
608 stage_blocked_for_callback_ = ON_AUTH_REQUIRED; | 635 stage_blocked_for_callback_ = ON_AUTH_REQUIRED; |
609 base::ThreadTaskRunnerHandle::Get()->PostTask( | 636 base::ThreadTaskRunnerHandle::Get()->PostTask( |
610 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); | 637 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); |
611 return AUTH_REQUIRED_RESPONSE_IO_PENDING; | 638 return AUTH_REQUIRED_RESPONSE_IO_PENDING; |
| 639 |
| 640 case USER_NOTIFY: |
| 641 // If the callback returns ERR_IO_PENDING, the user has accepted |
| 642 // responsibility for running the callback in the future. |
| 643 return notification_auth_callback_.Run(callback, request); |
612 } | 644 } |
613 NOTREACHED(); | 645 NOTREACHED(); |
614 return AUTH_REQUIRED_RESPONSE_NO_ACTION; // Dummy value. | 646 return AUTH_REQUIRED_RESPONSE_NO_ACTION; // Dummy value. |
615 } | 647 } |
616 | 648 |
617 void BlockingNetworkDelegate::Reset() { | 649 void BlockingNetworkDelegate::Reset() { |
618 EXPECT_NE(NOT_BLOCKED, stage_blocked_for_callback_); | 650 EXPECT_NE(NOT_BLOCKED, stage_blocked_for_callback_); |
619 stage_blocked_for_callback_ = NOT_BLOCKED; | 651 stage_blocked_for_callback_ = NOT_BLOCKED; |
620 callback_.Reset(); | 652 callback_.Reset(); |
621 auth_callback_.Reset(); | 653 auth_callback_.Reset(); |
622 } | 654 } |
623 | 655 |
624 int BlockingNetworkDelegate::MaybeBlockStage( | 656 int BlockingNetworkDelegate::MaybeBlockStage( |
625 BlockingNetworkDelegate::Stage stage, | 657 BlockingNetworkDelegate::Stage stage, |
| 658 const URLRequest* request, |
626 const CompletionCallback& callback) { | 659 const CompletionCallback& callback) { |
627 // Check that the user has provided callback for the previous blocked stage. | 660 // Check that the user has provided callback for the previous blocked stage. |
628 EXPECT_EQ(NOT_BLOCKED, stage_blocked_for_callback_); | 661 EXPECT_EQ(NOT_BLOCKED, stage_blocked_for_callback_); |
629 | 662 |
630 if ((block_on_ & stage) == 0) { | 663 if ((block_on_ & stage) == 0) { |
631 return OK; | 664 return OK; |
632 } | 665 } |
633 | 666 |
634 switch (block_mode_) { | 667 switch (block_mode_) { |
635 case SYNCHRONOUS: | 668 case SYNCHRONOUS: |
636 EXPECT_NE(OK, retval_); | 669 EXPECT_NE(OK, retval_); |
637 return retval_; | 670 return retval_; |
638 | 671 |
639 case AUTO_CALLBACK: | 672 case AUTO_CALLBACK: |
640 base::ThreadTaskRunnerHandle::Get()->PostTask( | 673 base::ThreadTaskRunnerHandle::Get()->PostTask( |
641 FROM_HERE, base::Bind(&BlockingNetworkDelegate::RunCallback, | 674 FROM_HERE, base::Bind(&BlockingNetworkDelegate::RunCallback, |
642 weak_factory_.GetWeakPtr(), retval_, callback)); | 675 weak_factory_.GetWeakPtr(), retval_, callback)); |
643 return ERR_IO_PENDING; | 676 return ERR_IO_PENDING; |
644 | 677 |
645 case USER_CALLBACK: | 678 case USER_CALLBACK: |
646 callback_ = callback; | 679 callback_ = callback; |
647 stage_blocked_for_callback_ = stage; | 680 stage_blocked_for_callback_ = stage; |
648 base::ThreadTaskRunnerHandle::Get()->PostTask( | 681 base::ThreadTaskRunnerHandle::Get()->PostTask( |
649 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); | 682 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); |
650 return ERR_IO_PENDING; | 683 return ERR_IO_PENDING; |
| 684 |
| 685 case USER_NOTIFY: |
| 686 // If the callback returns ERR_IO_PENDING, the user has accepted |
| 687 // responsibility for running the callback in the future. |
| 688 return notification_callback_.Run(callback, request); |
651 } | 689 } |
652 NOTREACHED(); | 690 NOTREACHED(); |
653 return 0; | 691 return 0; |
654 } | 692 } |
655 | 693 |
656 class TestURLRequestContextWithProxy : public TestURLRequestContext { | 694 class TestURLRequestContextWithProxy : public TestURLRequestContext { |
657 public: | 695 public: |
658 // Does not own |delegate|. | 696 // Does not own |delegate|. |
659 TestURLRequestContextWithProxy(const std::string& proxy, | 697 TestURLRequestContextWithProxy(const std::string& proxy, |
660 NetworkDelegate* delegate) | 698 NetworkDelegate* delegate) |
(...skipping 7175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7836 std::unique_ptr<URLRequest> req( | 7874 std::unique_ptr<URLRequest> req( |
7837 default_context_.CreateRequest(test_url, DEFAULT_PRIORITY, &d)); | 7875 default_context_.CreateRequest(test_url, DEFAULT_PRIORITY, &d)); |
7838 req->SetLoadFlags(LOAD_ONLY_FROM_CACHE); | 7876 req->SetLoadFlags(LOAD_ONLY_FROM_CACHE); |
7839 | 7877 |
7840 req->Start(); | 7878 req->Start(); |
7841 base::RunLoop().Run(); | 7879 base::RunLoop().Run(); |
7842 | 7880 |
7843 EXPECT_FALSE(req->response_info().network_accessed); | 7881 EXPECT_FALSE(req->response_info().network_accessed); |
7844 } | 7882 } |
7845 | 7883 |
7846 // Test that a single job with a throttled priority completes | 7884 // Test that a single job with a THROTTLED priority completes |
7847 // correctly in the absence of contention. | 7885 // correctly in the absence of contention. |
7848 TEST_F(URLRequestTestHTTP, ThrottledPriority) { | 7886 TEST_F(URLRequestTestHTTP, ThrottledPriority) { |
7849 ASSERT_TRUE(http_test_server()->Start()); | 7887 ASSERT_TRUE(http_test_server()->Start()); |
7850 | 7888 |
7851 TestDelegate d; | 7889 TestDelegate d; |
7852 GURL test_url(http_test_server()->GetURL("/")); | 7890 GURL test_url(http_test_server()->GetURL("/")); |
7853 std::unique_ptr<URLRequest> req( | 7891 std::unique_ptr<URLRequest> req( |
7854 default_context_.CreateRequest(test_url, THROTTLED, &d)); | 7892 default_context_.CreateRequest(test_url, THROTTLED, &d)); |
7855 req->Start(); | 7893 req->Start(); |
7856 base::RunLoop().Run(); | 7894 base::RunLoop().Run(); |
7857 | 7895 |
7858 EXPECT_TRUE(req->status().is_success()); | 7896 EXPECT_TRUE(req->status().is_success()); |
7859 } | 7897 } |
7860 | 7898 |
| 7899 // A class to hold state for responding to USER_NOTIFY callbacks from |
| 7900 // BlockingNetworkDelegate. It also accepts a RunLoop that will be |
| 7901 // signaled via QuitWhenIdle() when any request is blocked. |
| 7902 // |
| 7903 class NotificationCallbackHandler { |
| 7904 public: |
| 7905 // Default constructed object doesn't block anything. |
| 7906 NotificationCallbackHandler() : run_loop_(nullptr) {} |
| 7907 |
| 7908 void AddURLRequestToBlockList(const URLRequest* request) { |
| 7909 requests_to_block_.insert(request); |
| 7910 } |
| 7911 |
| 7912 Error ShouldBlockRequest(const CompletionCallback& callback, |
| 7913 const URLRequest* request) { |
| 7914 if (requests_to_block_.find(request) == requests_to_block_.end()) { |
| 7915 return OK; |
| 7916 } |
| 7917 |
| 7918 DCHECK(blocked_callbacks_.find(request) == blocked_callbacks_.end()); |
| 7919 blocked_callbacks_[request] = callback; |
| 7920 if (run_loop_) |
| 7921 run_loop_->QuitWhenIdle(); |
| 7922 return ERR_IO_PENDING; |
| 7923 } |
| 7924 |
| 7925 // Erases object's memory of blocked callbacks as a side effect. |
| 7926 void GetBlockedCallbacks( |
| 7927 std::map<const URLRequest*, CompletionCallback>* blocked_callbacks) { |
| 7928 blocked_callbacks_.swap(*blocked_callbacks); |
| 7929 } |
| 7930 |
| 7931 // Set a RunLoop that, if non-null, will be signaled if any request |
| 7932 // is blocked. It is the callers responsibility to make sure the |
| 7933 // passed object lives past the destruction of this class or |
| 7934 // next call to SetRunLoop(). |
| 7935 void SetRunLoop(base::RunLoop* run_loop) { run_loop_ = run_loop; } |
| 7936 |
| 7937 private: |
| 7938 std::set<const URLRequest*> requests_to_block_; |
| 7939 std::map<const URLRequest*, CompletionCallback> blocked_callbacks_; |
| 7940 |
| 7941 base::RunLoop* run_loop_; |
| 7942 |
| 7943 DISALLOW_COPY_AND_ASSIGN(NotificationCallbackHandler); |
| 7944 }; |
| 7945 |
| 7946 TEST_F(URLRequestTestHTTP, MultiThrottledPriority) { |
| 7947 ASSERT_TRUE(http_test_server()->Start()); |
| 7948 |
| 7949 base::RunLoop run_until_request_blocked; |
| 7950 |
| 7951 NotificationCallbackHandler notification_handler; |
| 7952 notification_handler.SetRunLoop(&run_until_request_blocked); |
| 7953 BlockingNetworkDelegate network_delegate( |
| 7954 BlockingNetworkDelegate::USER_NOTIFY); |
| 7955 network_delegate.set_block_on(BlockingNetworkDelegate::ON_HEADERS_RECEIVED); |
| 7956 network_delegate.set_notification_callback( |
| 7957 base::Bind(&NotificationCallbackHandler::ShouldBlockRequest, |
| 7958 // Both objects are owned by this function, and |
| 7959 // |*network_delegate| will be destroyed first, so |
| 7960 // it's safe to pass it an unretained pointer. |
| 7961 base::Unretained(¬ification_handler))); |
| 7962 |
| 7963 TestURLRequestContext context(true); |
| 7964 context.set_network_delegate(&network_delegate); |
| 7965 context.Init(); |
| 7966 |
| 7967 // Use different test URLs to make sure all three requests turn into |
| 7968 // HttpNetworkTransacations. Use different URLRequest::Delegates so that |
| 7969 // the requests may be waited on separately. |
| 7970 TestDelegate d1; |
| 7971 std::unique_ptr<URLRequest> req1(context.CreateRequest( |
| 7972 http_test_server()->GetURL("/echoall/l"), THROTTLED, &d1)); |
| 7973 notification_handler.AddURLRequestToBlockList(req1.get()); |
| 7974 |
| 7975 TestDelegate d2; |
| 7976 std::unique_ptr<URLRequest> req2(context.CreateRequest( |
| 7977 http_test_server()->GetURL("/echoall/2"), THROTTLED, &d2)); |
| 7978 notification_handler.AddURLRequestToBlockList(req2.get()); |
| 7979 |
| 7980 TestDelegate d3; |
| 7981 std::unique_ptr<URLRequest> req3(context.CreateRequest( |
| 7982 http_test_server()->GetURL("/echoall/3"), THROTTLED, &d3)); |
| 7983 req1->Start(); |
| 7984 req2->Start(); |
| 7985 req3->Start(); |
| 7986 run_until_request_blocked.Run(); |
| 7987 notification_handler.SetRunLoop(nullptr); |
| 7988 |
| 7989 // The first two requests should be blocked based on the notification |
| 7990 // callback, and their status should have blocked the third request |
| 7991 // through throttling. |
| 7992 EXPECT_TRUE(req1->status().is_io_pending()); |
| 7993 EXPECT_TRUE(req2->status().is_io_pending()); |
| 7994 EXPECT_TRUE(req3->status().is_io_pending()); |
| 7995 |
| 7996 std::map<const URLRequest*, CompletionCallback> blocked_callbacks; |
| 7997 notification_handler.GetBlockedCallbacks(&blocked_callbacks); |
| 7998 ASSERT_EQ(2u, blocked_callbacks.size()); |
| 7999 ASSERT_TRUE(blocked_callbacks.find(req1.get()) != blocked_callbacks.end()); |
| 8000 ASSERT_TRUE(blocked_callbacks.find(req2.get()) != blocked_callbacks.end()); |
| 8001 |
| 8002 // Unblocking one of the requests blocked on the notification callback |
| 8003 // should let it completely, which should then let the third request |
| 8004 // complete. Unblock the second request, then wait for the third |
| 8005 // request to complete. |
| 8006 // TODO(rdsmith): Find something to wait on other than the third |
| 8007 // requests completion; if there's a bug in throttling, that will |
| 8008 // result in this test hanging rather than failing quickly. |
| 8009 d1.set_quit_on_complete(false); |
| 8010 d2.set_quit_on_complete(false); |
| 8011 d3.set_quit_on_complete(true); |
| 8012 blocked_callbacks[req2.get()].Run(OK); |
| 8013 base::RunLoop().Run(); |
| 8014 |
| 8015 notification_handler.GetBlockedCallbacks(&blocked_callbacks); |
| 8016 EXPECT_EQ(0u, blocked_callbacks.size()); |
| 8017 EXPECT_TRUE(req1->status().is_io_pending()); |
| 8018 EXPECT_EQ(URLRequestStatus::SUCCESS, req2->status().status()); |
| 8019 EXPECT_EQ(URLRequestStatus::SUCCESS, req3->status().status()); |
| 8020 } |
| 8021 |
7861 TEST_F(URLRequestTestHTTP, RawBodyBytesNoContentEncoding) { | 8022 TEST_F(URLRequestTestHTTP, RawBodyBytesNoContentEncoding) { |
7862 ASSERT_TRUE(http_test_server()->Start()); | 8023 ASSERT_TRUE(http_test_server()->Start()); |
7863 | 8024 |
7864 TestDelegate d; | 8025 TestDelegate d; |
7865 std::unique_ptr<URLRequest> req(default_context().CreateRequest( | 8026 std::unique_ptr<URLRequest> req(default_context().CreateRequest( |
7866 http_test_server()->GetURL("/simple.html"), DEFAULT_PRIORITY, &d)); | 8027 http_test_server()->GetURL("/simple.html"), DEFAULT_PRIORITY, &d)); |
7867 req->Start(); | 8028 req->Start(); |
7868 base::RunLoop().Run(); | 8029 base::RunLoop().Run(); |
7869 | 8030 |
7870 EXPECT_EQ(5, req->GetRawBodyBytes()); | 8031 EXPECT_EQ(5, req->GetRawBodyBytes()); |
(...skipping 2398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10269 AddTestInterceptor()->set_main_intercept_job(std::move(job)); | 10430 AddTestInterceptor()->set_main_intercept_job(std::move(job)); |
10270 | 10431 |
10271 req->Start(); | 10432 req->Start(); |
10272 req->Cancel(); | 10433 req->Cancel(); |
10273 base::RunLoop().RunUntilIdle(); | 10434 base::RunLoop().RunUntilIdle(); |
10274 EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status()); | 10435 EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status()); |
10275 EXPECT_EQ(0, d.received_redirect_count()); | 10436 EXPECT_EQ(0, d.received_redirect_count()); |
10276 } | 10437 } |
10277 | 10438 |
10278 } // namespace net | 10439 } // namespace net |
OLD | NEW |