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 3 // found in the LICENSE file. 4 5 #include <vector> 6 7 #include "base/bind.h" 8 #include "base/files/file_path.h" 9 #include "base/memory/scoped_vector.h" 10 #include "base/message_loop/message_loop.h" 11 #include "base/pickle.h" 12 #include "base/run_loop.h" 13 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_split.h" 15 #include "content/browser/browser_thread_impl.h" 16 #include "content/browser/child_process_security_policy_impl.h" 17 #include "content/browser/loader/detachable_resource_handler.h" 18 #include "content/browser/loader/resource_dispatcher_host_impl.h" 19 #include "content/browser/loader/resource_loader.h" 20 #include "content/browser/loader/resource_message_filter.h" 21 #include "content/browser/loader/resource_request_info_impl.h" 22 #include "content/browser/worker_host/worker_service_impl.h" 23 #include "content/common/child_process_host_impl.h" 24 #include "content/common/resource_messages.h" 25 #include "content/common/view_messages.h" 26 #include "content/public/browser/global_request_id.h" 27 #include "content/public/browser/resource_context.h" 28 #include "content/public/browser/resource_dispatcher_host_delegate.h" 29 #include "content/public/browser/resource_request_info.h" 30 #include "content/public/browser/resource_throttle.h" 31 #include "content/public/common/process_type.h" 32 #include "content/public/common/resource_response.h" 33 #include "content/public/test/test_browser_context.h" 34 #include "content/test/test_content_browser_client.h" 35 #include "net/base/net_errors.h" 36 #include "net/base/request_priority.h" 37 #include "net/base/upload_bytes_element_reader.h" 38 #include "net/base/upload_data_stream.h" 39 #include "net/http/http_util.h" 40 #include "net/url_request/url_request.h" 41 #include "net/url_request/url_request_context.h" 42 #include "net/url_request/url_request_job.h" 43 #include "net/url_request/url_request_simple_job.h" 44 #include "net/url_request/url_request_test_job.h" 45 #include "net/url_request/url_request_test_util.h" 46 #include "testing/gtest/include/gtest/gtest.h" 47 #include "webkit/common/appcache/appcache_interfaces.h" 48 49 // TODO(eroman): Write unit tests for SafeBrowsing that exercise 50 // SafeBrowsingResourceHandler. 51 52 namespace content { 53 54 namespace { 55 56 // Returns the resource response header structure for this request. 57 void GetResponseHead(const std::vector<IPC::Message>& messages, 58 ResourceResponseHead* response_head) { 59 ASSERT_GE(messages.size(), 2U); 60 61 // The first messages should be received response. 62 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type()); 63 64 PickleIterator iter(messages[0]); 65 int request_id; 66 ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, &request_id)); 67 ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, response_head)); 68 } 69 70 void GenerateIPCMessage( 71 scoped_refptr<ResourceMessageFilter> filter, 72 scoped_ptr<IPC::Message> message) { 73 bool msg_is_ok; 74 ResourceDispatcherHostImpl::Get()->OnMessageReceived( 75 *message, filter.get(), &msg_is_ok); 76 } 77 78 } // namespace 79 80 static int RequestIDForMessage(const IPC::Message& msg) { 81 int request_id = -1; 82 switch (msg.type()) { 83 case ResourceMsg_UploadProgress::ID: 84 case ResourceMsg_ReceivedResponse::ID: 85 case ResourceMsg_ReceivedRedirect::ID: 86 case ResourceMsg_SetDataBuffer::ID: 87 case ResourceMsg_DataReceived::ID: 88 case ResourceMsg_RequestComplete::ID: { 89 bool result = PickleIterator(msg).ReadInt(&request_id); 90 DCHECK(result); 91 break; 92 } 93 } 94 return request_id; 95 } 96 97 static ResourceHostMsg_Request CreateResourceRequest( 98 const char* method, 99 ResourceType::Type type, 100 const GURL& url) { 101 ResourceHostMsg_Request request; 102 request.method = std::string(method); 103 request.url = url; 104 request.first_party_for_cookies = url; // bypass third-party cookie blocking 105 request.referrer_policy = blink::WebReferrerPolicyDefault; 106 request.load_flags = 0; 107 request.origin_pid = 0; 108 request.resource_type = type; 109 request.request_context = 0; 110 request.appcache_host_id = appcache::kNoHostId; 111 request.download_to_file = false; 112 request.is_main_frame = true; 113 request.frame_id = 0; 114 request.parent_is_main_frame = false; 115 request.parent_frame_id = -1; 116 request.transition_type = PAGE_TRANSITION_LINK; 117 request.allow_download = true; 118 return request; 119 } 120 121 // Spin up the message loop to kick off the request. 122 static void KickOffRequest() { 123 base::MessageLoop::current()->RunUntilIdle(); 124 } 125 126 // We may want to move this to a shared space if it is useful for something else 127 class ResourceIPCAccumulator { 128 public: 129 void AddMessage(const IPC::Message& msg) { 130 messages_.push_back(msg); 131 } 132 133 // This groups the messages by their request ID. The groups will be in order 134 // that the first message for each request ID was received, and the messages 135 // within the groups will be in the order that they appeared. 136 // Note that this clears messages_. 137 typedef std::vector< std::vector<IPC::Message> > ClassifiedMessages; 138 void GetClassifiedMessages(ClassifiedMessages* msgs); 139 140 private: 141 std::vector<IPC::Message> messages_; 142 }; 143 144 // This is very inefficient as a result of repeatedly extracting the ID, use 145 // only for tests! 146 void ResourceIPCAccumulator::GetClassifiedMessages(ClassifiedMessages* msgs) { 147 while (!messages_.empty()) { 148 // Ignore unknown message types as it is valid for code to generated other 149 // IPCs as side-effects that we are not testing here. 150 int cur_id = RequestIDForMessage(messages_[0]); 151 if (cur_id != -1) { 152 std::vector<IPC::Message> cur_requests; 153 cur_requests.push_back(messages_[0]); 154 // find all other messages with this ID 155 for (int i = 1; i < static_cast<int>(messages_.size()); i++) { 156 int id = RequestIDForMessage(messages_[i]); 157 if (id == cur_id) { 158 cur_requests.push_back(messages_[i]); 159 messages_.erase(messages_.begin() + i); 160 i--; 161 } 162 } 163 msgs->push_back(cur_requests); 164 } 165 messages_.erase(messages_.begin()); 166 } 167 } 168 169 // This class forwards the incoming messages to the ResourceDispatcherHostTest. 170 // This is used to emulate different sub-processes, since this filter will 171 // have a different ID than the original. For the test, we want all the incoming 172 // messages to go to the same place, which is why this forwards. 173 class ForwardingFilter : public ResourceMessageFilter { 174 public: 175 explicit ForwardingFilter(IPC::Sender* dest, 176 ResourceContext* resource_context) 177 : ResourceMessageFilter( 178 ChildProcessHostImpl::GenerateChildProcessUniqueId(), 179 PROCESS_TYPE_RENDERER, NULL, NULL, NULL, 180 base::Bind(&ForwardingFilter::GetContexts, 181 base::Unretained(this))), 182 dest_(dest), 183 resource_context_(resource_context) { 184 set_peer_pid_for_testing(base::GetCurrentProcId()); 185 } 186 187 // ResourceMessageFilter override 188 virtual bool Send(IPC::Message* msg) OVERRIDE { 189 if (!dest_) 190 return false; 191 return dest_->Send(msg); 192 } 193 194 ResourceContext* resource_context() { return resource_context_; } 195 196 protected: 197 virtual ~ForwardingFilter() {} 198 199 private: 200 void GetContexts(const ResourceHostMsg_Request& request, 201 ResourceContext** resource_context, 202 net::URLRequestContext** request_context) { 203 *resource_context = resource_context_; 204 *request_context = resource_context_->GetRequestContext(); 205 } 206 207 IPC::Sender* dest_; 208 ResourceContext* resource_context_; 209 210 DISALLOW_COPY_AND_ASSIGN(ForwardingFilter); 211 }; 212 213 // This class is a variation on URLRequestTestJob in that it does 214 // not complete start upon entry, only when specifically told to. 215 class URLRequestTestDelayedStartJob : public net::URLRequestTestJob { 216 public: 217 URLRequestTestDelayedStartJob(net::URLRequest* request, 218 net::NetworkDelegate* network_delegate) 219 : net::URLRequestTestJob(request, network_delegate) { 220 Init(); 221 } 222 URLRequestTestDelayedStartJob(net::URLRequest* request, 223 net::NetworkDelegate* network_delegate, 224 bool auto_advance) 225 : net::URLRequestTestJob(request, network_delegate, auto_advance) { 226 Init(); 227 } 228 URLRequestTestDelayedStartJob(net::URLRequest* request, 229 net::NetworkDelegate* network_delegate, 230 const std::string& response_headers, 231 const std::string& response_data, 232 bool auto_advance) 233 : net::URLRequestTestJob(request, 234 network_delegate, 235 response_headers, 236 response_data, 237 auto_advance) { 238 Init(); 239 } 240 241 // Do nothing until you're told to. 242 virtual void Start() OVERRIDE {} 243 244 // Finish starting a URL request whose job is an instance of 245 // URLRequestTestDelayedStartJob. It is illegal to call this routine 246 // with a URLRequest that does not use URLRequestTestDelayedStartJob. 247 static void CompleteStart(net::URLRequest* request) { 248 for (URLRequestTestDelayedStartJob* job = list_head_; 249 job; 250 job = job->next_) { 251 if (job->request() == request) { 252 job->net::URLRequestTestJob::Start(); 253 return; 254 } 255 } 256 NOTREACHED(); 257 } 258 259 static bool DelayedStartQueueEmpty() { 260 return !list_head_; 261 } 262 263 static void ClearQueue() { 264 if (list_head_) { 265 LOG(ERROR) 266 << "Unreleased entries on URLRequestTestDelayedStartJob delay queue" 267 << "; may result in leaks."; 268 list_head_ = NULL; 269 } 270 } 271 272 protected: 273 virtual ~URLRequestTestDelayedStartJob() { 274 for (URLRequestTestDelayedStartJob** job = &list_head_; *job; 275 job = &(*job)->next_) { 276 if (*job == this) { 277 *job = (*job)->next_; 278 return; 279 } 280 } 281 NOTREACHED(); 282 } 283 284 private: 285 void Init() { 286 next_ = list_head_; 287 list_head_ = this; 288 } 289 290 static URLRequestTestDelayedStartJob* list_head_; 291 URLRequestTestDelayedStartJob* next_; 292 }; 293 294 URLRequestTestDelayedStartJob* 295 URLRequestTestDelayedStartJob::list_head_ = NULL; 296 297 // This class is a variation on URLRequestTestJob in that it 298 // returns IO_pending errors before every read, not just the first one. 299 class URLRequestTestDelayedCompletionJob : public net::URLRequestTestJob { 300 public: 301 URLRequestTestDelayedCompletionJob(net::URLRequest* request, 302 net::NetworkDelegate* network_delegate) 303 : net::URLRequestTestJob(request, network_delegate) {} 304 URLRequestTestDelayedCompletionJob(net::URLRequest* request, 305 net::NetworkDelegate* network_delegate, 306 bool auto_advance) 307 : net::URLRequestTestJob(request, network_delegate, auto_advance) {} 308 URLRequestTestDelayedCompletionJob(net::URLRequest* request, 309 net::NetworkDelegate* network_delegate, 310 const std::string& response_headers, 311 const std::string& response_data, 312 bool auto_advance) 313 : net::URLRequestTestJob(request, 314 network_delegate, 315 response_headers, 316 response_data, 317 auto_advance) {} 318 319 protected: 320 virtual ~URLRequestTestDelayedCompletionJob() {} 321 322 private: 323 virtual bool NextReadAsync() OVERRIDE { return true; } 324 }; 325 326 class URLRequestBigJob : public net::URLRequestSimpleJob { 327 public: 328 URLRequestBigJob(net::URLRequest* request, 329 net::NetworkDelegate* network_delegate) 330 : net::URLRequestSimpleJob(request, network_delegate) { 331 } 332 333 virtual int GetData(std::string* mime_type, 334 std::string* charset, 335 std::string* data, 336 const net::CompletionCallback& callback) const OVERRIDE { 337 *mime_type = "text/plain"; 338 *charset = "UTF-8"; 339 340 std::string text; 341 int count; 342 if (!ParseURL(request_->url(), &text, &count)) 343 return net::ERR_INVALID_URL; 344 345 data->reserve(text.size() * count); 346 for (int i = 0; i < count; ++i) 347 data->append(text); 348 349 return net::OK; 350 } 351 352 private: 353 virtual ~URLRequestBigJob() {} 354 355 // big-job:substring,N 356 static bool ParseURL(const GURL& url, std::string* text, int* count) { 357 std::vector<std::string> parts; 358 base::SplitString(url.path(), ',', &parts); 359 360 if (parts.size() != 2) 361 return false; 362 363 *text = parts[0]; 364 return base::StringToInt(parts[1], count); 365 } 366 }; 367 368 // Associated with an URLRequest to determine if the URLRequest gets deleted. 369 class TestUserData : public base::SupportsUserData::Data { 370 public: 371 explicit TestUserData(bool* was_deleted) 372 : was_deleted_(was_deleted) { 373 } 374 375 virtual ~TestUserData() { 376 *was_deleted_ = true; 377 } 378 379 private: 380 bool* was_deleted_; 381 }; 382 383 class TransfersAllNavigationsContentBrowserClient 384 : public TestContentBrowserClient { 385 public: 386 virtual bool ShouldSwapProcessesForRedirect(ResourceContext* resource_context, 387 const GURL& current_url, 388 const GURL& new_url) OVERRIDE { 389 return true; 390 } 391 }; 392 393 enum GenericResourceThrottleFlags { 394 NONE = 0, 395 DEFER_STARTING_REQUEST = 1 << 0, 396 DEFER_PROCESSING_RESPONSE = 1 << 1, 397 CANCEL_BEFORE_START = 1 << 2 398 }; 399 400 // Throttle that tracks the current throttle blocking a request. Only one 401 // can throttle any request at a time. 402 class GenericResourceThrottle : public ResourceThrottle { 403 public: 404 // The value is used to indicate that the throttle should not provide 405 // a error code when cancelling a request. net::OK is used, because this 406 // is not an error code. 407 static const int USE_DEFAULT_CANCEL_ERROR_CODE = net::OK; 408 409 GenericResourceThrottle(int flags, int code) 410 : flags_(flags), 411 error_code_for_cancellation_(code) { 412 } 413 414 virtual ~GenericResourceThrottle() { 415 if (active_throttle_ == this) 416 active_throttle_ = NULL; 417 } 418 419 // ResourceThrottle implementation: 420 virtual void WillStartRequest(bool* defer) OVERRIDE { 421 ASSERT_EQ(NULL, active_throttle_); 422 if (flags_ & DEFER_STARTING_REQUEST) { 423 active_throttle_ = this; 424 *defer = true; 425 } 426 427 if (flags_ & CANCEL_BEFORE_START) { 428 if (error_code_for_cancellation_ == USE_DEFAULT_CANCEL_ERROR_CODE) { 429 controller()->Cancel(); 430 } else { 431 controller()->CancelWithError(error_code_for_cancellation_); 432 } 433 } 434 } 435 436 virtual void WillProcessResponse(bool* defer) OVERRIDE { 437 ASSERT_EQ(NULL, active_throttle_); 438 if (flags_ & DEFER_PROCESSING_RESPONSE) { 439 active_throttle_ = this; 440 *defer = true; 441 } 442 } 443 444 virtual const char* GetNameForLogging() const OVERRIDE { 445 return "GenericResourceThrottle"; 446 } 447 448 void Resume() { 449 ASSERT_TRUE(this == active_throttle_); 450 active_throttle_ = NULL; 451 controller()->Resume(); 452 } 453 454 static GenericResourceThrottle* active_throttle() { 455 return active_throttle_; 456 } 457 458 private: 459 int flags_; // bit-wise union of GenericResourceThrottleFlags. 460 int error_code_for_cancellation_; 461 462 // The currently active throttle, if any. 463 static GenericResourceThrottle* active_throttle_; 464 }; 465 // static 466 GenericResourceThrottle* GenericResourceThrottle::active_throttle_ = NULL; 467 468 class TestResourceDispatcherHostDelegate 469 : public ResourceDispatcherHostDelegate { 470 public: 471 TestResourceDispatcherHostDelegate() 472 : create_two_throttles_(false), 473 flags_(NONE), 474 error_code_for_cancellation_( 475 GenericResourceThrottle::USE_DEFAULT_CANCEL_ERROR_CODE) { 476 } 477 478 void set_url_request_user_data(base::SupportsUserData::Data* user_data) { 479 user_data_.reset(user_data); 480 } 481 482 void set_flags(int value) { 483 flags_ = value; 484 } 485 486 void set_error_code_for_cancellation(int code) { 487 error_code_for_cancellation_ = code; 488 } 489 490 void set_create_two_throttles(bool create_two_throttles) { 491 create_two_throttles_ = create_two_throttles; 492 } 493 494 // ResourceDispatcherHostDelegate implementation: 495 496 virtual void RequestBeginning( 497 net::URLRequest* request, 498 ResourceContext* resource_context, 499 appcache::AppCacheService* appcache_service, 500 ResourceType::Type resource_type, 501 int child_id, 502 int route_id, 503 ScopedVector<ResourceThrottle>* throttles) OVERRIDE { 504 if (user_data_) { 505 const void* key = user_data_.get(); 506 request->SetUserData(key, user_data_.release()); 507 } 508 509 if (flags_ != NONE) { 510 throttles->push_back(new GenericResourceThrottle( 511 flags_, error_code_for_cancellation_)); 512 if (create_two_throttles_) 513 throttles->push_back(new GenericResourceThrottle( 514 flags_, error_code_for_cancellation_)); 515 } 516 } 517 518 private: 519 bool create_two_throttles_; 520 int flags_; 521 int error_code_for_cancellation_; 522 scoped_ptr<base::SupportsUserData::Data> user_data_; 523 }; 524 525 class ResourceDispatcherHostTest : public testing::Test, 526 public IPC::Sender { 527 public: 528 ResourceDispatcherHostTest() 529 : ui_thread_(BrowserThread::UI, &message_loop_), 530 file_thread_(BrowserThread::FILE_USER_BLOCKING, &message_loop_), 531 cache_thread_(BrowserThread::CACHE, &message_loop_), 532 io_thread_(BrowserThread::IO, &message_loop_), 533 old_factory_(NULL), 534 send_data_received_acks_(false) { 535 browser_context_.reset(new TestBrowserContext()); 536 BrowserContext::EnsureResourceContextInitialized(browser_context_.get()); 537 message_loop_.RunUntilIdle(); 538 ResourceContext* resource_context = browser_context_->GetResourceContext(); 539 filter_ = new ForwardingFilter(this, resource_context); 540 resource_context->GetRequestContext()->set_network_delegate( 541 &network_delegate_); 542 } 543 544 virtual ~ResourceDispatcherHostTest() { 545 for (std::set<int>::iterator it = child_ids_.begin(); 546 it != child_ids_.end(); ++it) { 547 host_.CancelRequestsForProcess(*it); 548 } 549 } 550 551 // IPC::Sender implementation 552 virtual bool Send(IPC::Message* msg) OVERRIDE { 553 accum_.AddMessage(*msg); 554 555 if (send_data_received_acks_ && 556 msg->type() == ResourceMsg_DataReceived::ID) { 557 GenerateDataReceivedACK(*msg); 558 } 559 560 delete msg; 561 return true; 562 } 563 564 protected: 565 // testing::Test 566 virtual void SetUp() { 567 DCHECK(!test_fixture_); 568 test_fixture_ = this; 569 ChildProcessSecurityPolicyImpl::GetInstance()->Add(0); 570 net::URLRequest::Deprecated::RegisterProtocolFactory( 571 "test", 572 &ResourceDispatcherHostTest::Factory); 573 EnsureTestSchemeIsAllowed(); 574 delay_start_ = false; 575 delay_complete_ = false; 576 url_request_jobs_created_count_ = 0; 577 } 578 579 virtual void TearDown() { 580 net::URLRequest::Deprecated::RegisterProtocolFactory("test", NULL); 581 if (!scheme_.empty()) 582 net::URLRequest::Deprecated::RegisterProtocolFactory( 583 scheme_, old_factory_); 584 585 EXPECT_TRUE(URLRequestTestDelayedStartJob::DelayedStartQueueEmpty()); 586 URLRequestTestDelayedStartJob::ClearQueue(); 587 588 DCHECK(test_fixture_ == this); 589 test_fixture_ = NULL; 590 591 host_.Shutdown(); 592 593 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(0); 594 595 // Flush the message loop to make application verifiers happy. 596 if (ResourceDispatcherHostImpl::Get()) 597 ResourceDispatcherHostImpl::Get()->CancelRequestsForContext( 598 browser_context_->GetResourceContext()); 599 600 WorkerServiceImpl::GetInstance()->PerformTeardownForTesting(); 601 602 browser_context_.reset(); 603 message_loop_.RunUntilIdle(); 604 } 605 606 // Creates a request using the current test object as the filter and 607 // SubResource as the resource type. 608 void MakeTestRequest(int render_view_id, 609 int request_id, 610 const GURL& url); 611 612 // Generates a request using the given filter and resource type. 613 void MakeTestRequestWithResourceType(ResourceMessageFilter* filter, 614 int render_view_id, int request_id, 615 const GURL& url, 616 ResourceType::Type type); 617 618 void CancelRequest(int request_id); 619 620 void CompleteStartRequest(int request_id); 621 void CompleteStartRequest(ResourceMessageFilter* filter, int request_id); 622 623 net::TestNetworkDelegate* network_delegate() { return &network_delegate_; } 624 625 void EnsureSchemeIsAllowed(const std::string& scheme) { 626 ChildProcessSecurityPolicyImpl* policy = 627 ChildProcessSecurityPolicyImpl::GetInstance(); 628 if (!policy->IsWebSafeScheme(scheme)) 629 policy->RegisterWebSafeScheme(scheme); 630 } 631 632 void EnsureTestSchemeIsAllowed() { 633 EnsureSchemeIsAllowed("test"); 634 } 635 636 // Sets a particular response for any request from now on. To switch back to 637 // the default bahavior, pass an empty |headers|. |headers| should be raw- 638 // formatted (NULLs instead of EOLs). 639 void SetResponse(const std::string& headers, const std::string& data) { 640 response_headers_ = net::HttpUtil::AssembleRawHeaders(headers.data(), 641 headers.size()); 642 response_data_ = data; 643 } 644 void SetResponse(const std::string& headers) { 645 SetResponse(headers, std::string()); 646 } 647 648 void SendDataReceivedACKs(bool send_acks) { 649 send_data_received_acks_ = send_acks; 650 } 651 652 // Intercepts requests for the given protocol. 653 void HandleScheme(const std::string& scheme) { 654 DCHECK(scheme_.empty()); 655 DCHECK(!old_factory_); 656 scheme_ = scheme; 657 old_factory_ = net::URLRequest::Deprecated::RegisterProtocolFactory( 658 scheme_, &ResourceDispatcherHostTest::Factory); 659 EnsureSchemeIsAllowed(scheme); 660 } 661 662 // Our own net::URLRequestJob factory. 663 static net::URLRequestJob* Factory(net::URLRequest* request, 664 net::NetworkDelegate* network_delegate, 665 const std::string& scheme) { 666 url_request_jobs_created_count_++; 667 if (test_fixture_->response_headers_.empty()) { 668 if (delay_start_) { 669 return new URLRequestTestDelayedStartJob(request, network_delegate); 670 } else if (delay_complete_) { 671 return new URLRequestTestDelayedCompletionJob(request, 672 network_delegate); 673 } else if (scheme == "big-job") { 674 return new URLRequestBigJob(request, network_delegate); 675 } else { 676 return new net::URLRequestTestJob(request, network_delegate); 677 } 678 } else { 679 if (delay_start_) { 680 return new URLRequestTestDelayedStartJob( 681 request, network_delegate, 682 test_fixture_->response_headers_, test_fixture_->response_data_, 683 false); 684 } else if (delay_complete_) { 685 return new URLRequestTestDelayedCompletionJob( 686 request, network_delegate, 687 test_fixture_->response_headers_, test_fixture_->response_data_, 688 false); 689 } else { 690 return new net::URLRequestTestJob( 691 request, network_delegate, 692 test_fixture_->response_headers_, test_fixture_->response_data_, 693 false); 694 } 695 } 696 } 697 698 void SetDelayedStartJobGeneration(bool delay_job_start) { 699 delay_start_ = delay_job_start; 700 } 701 702 void SetDelayedCompleteJobGeneration(bool delay_job_complete) { 703 delay_complete_ = delay_job_complete; 704 } 705 706 void GenerateDataReceivedACK(const IPC::Message& msg) { 707 EXPECT_EQ(ResourceMsg_DataReceived::ID, msg.type()); 708 709 int request_id = -1; 710 bool result = PickleIterator(msg).ReadInt(&request_id); 711 DCHECK(result); 712 scoped_ptr<IPC::Message> ack( 713 new ResourceHostMsg_DataReceived_ACK(request_id)); 714 715 base::MessageLoop::current()->PostTask( 716 FROM_HERE, 717 base::Bind(&GenerateIPCMessage, filter_, base::Passed(&ack))); 718 } 719 720 base::MessageLoopForIO message_loop_; 721 BrowserThreadImpl ui_thread_; 722 BrowserThreadImpl file_thread_; 723 BrowserThreadImpl cache_thread_; 724 BrowserThreadImpl io_thread_; 725 scoped_ptr<TestBrowserContext> browser_context_; 726 scoped_refptr<ForwardingFilter> filter_; 727 net::TestNetworkDelegate network_delegate_; 728 ResourceDispatcherHostImpl host_; 729 ResourceIPCAccumulator accum_; 730 std::string response_headers_; 731 std::string response_data_; 732 std::string scheme_; 733 net::URLRequest::ProtocolFactory* old_factory_; 734 bool send_data_received_acks_; 735 std::set<int> child_ids_; 736 static ResourceDispatcherHostTest* test_fixture_; 737 static bool delay_start_; 738 static bool delay_complete_; 739 static int url_request_jobs_created_count_; 740 }; 741 // Static. 742 ResourceDispatcherHostTest* ResourceDispatcherHostTest::test_fixture_ = NULL; 743 bool ResourceDispatcherHostTest::delay_start_ = false; 744 bool ResourceDispatcherHostTest::delay_complete_ = false; 745 int ResourceDispatcherHostTest::url_request_jobs_created_count_ = 0; 746 747 void ResourceDispatcherHostTest::MakeTestRequest(int render_view_id, 748 int request_id, 749 const GURL& url) { 750 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, 751 url, ResourceType::SUB_RESOURCE); 752 } 753 754 void ResourceDispatcherHostTest::MakeTestRequestWithResourceType( 755 ResourceMessageFilter* filter, 756 int render_view_id, 757 int request_id, 758 const GURL& url, 759 ResourceType::Type type) { 760 // If it's already there, this'll be dropped on the floor, which is fine. 761 child_ids_.insert(filter->child_id()); 762 763 ResourceHostMsg_Request request = 764 CreateResourceRequest("GET", type, url); 765 ResourceHostMsg_RequestResource msg(render_view_id, request_id, request); 766 bool msg_was_ok; 767 host_.OnMessageReceived(msg, filter, &msg_was_ok); 768 KickOffRequest(); 769 } 770 771 void ResourceDispatcherHostTest::CancelRequest(int request_id) { 772 host_.CancelRequest(filter_->child_id(), request_id, false); 773 } 774 775 void ResourceDispatcherHostTest::CompleteStartRequest(int request_id) { 776 CompleteStartRequest(filter_.get(), request_id); 777 } 778 779 void ResourceDispatcherHostTest::CompleteStartRequest( 780 ResourceMessageFilter* filter, 781 int request_id) { 782 GlobalRequestID gid(filter->child_id(), request_id); 783 net::URLRequest* req = host_.GetURLRequest(gid); 784 EXPECT_TRUE(req); 785 if (req) 786 URLRequestTestDelayedStartJob::CompleteStart(req); 787 } 788 789 void CheckRequestCompleteErrorCode(const IPC::Message& message, 790 int expected_error_code) { 791 // Verify the expected error code was received. 792 int request_id; 793 int error_code; 794 795 ASSERT_EQ(ResourceMsg_RequestComplete::ID, message.type()); 796 797 PickleIterator iter(message); 798 ASSERT_TRUE(IPC::ReadParam(&message, &iter, &request_id)); 799 ASSERT_TRUE(IPC::ReadParam(&message, &iter, &error_code)); 800 ASSERT_EQ(expected_error_code, error_code); 801 } 802 803 testing::AssertionResult ExtractDataOffsetAndLength(const IPC::Message& message, 804 int* data_offset, 805 int* data_length) { 806 PickleIterator iter(message); 807 int request_id; 808 if (!IPC::ReadParam(&message, &iter, &request_id)) 809 return testing::AssertionFailure() << "Could not read request_id"; 810 if (!IPC::ReadParam(&message, &iter, data_offset)) 811 return testing::AssertionFailure() << "Could not read data_offset"; 812 if (!IPC::ReadParam(&message, &iter, data_length)) 813 return testing::AssertionFailure() << "Could not read data_length"; 814 return testing::AssertionSuccess(); 815 } 816 817 void CheckSuccessfulRequestWithErrorCode( 818 const std::vector<IPC::Message>& messages, 819 const std::string& reference_data, 820 int expected_error) { 821 // A successful request will have received 4 messages: 822 // ReceivedResponse (indicates headers received) 823 // SetDataBuffer (contains shared memory handle) 824 // DataReceived (data offset and length into shared memory) 825 // RequestComplete (request is done) 826 // 827 // This function verifies that we received 4 messages and that they are 828 // appropriate. It allows for an error code other than net::OK if the request 829 // should successfully receive data and then abort, e.g., on cancel. 830 ASSERT_EQ(4U, messages.size()); 831 832 // The first messages should be received response 833 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type()); 834 835 ASSERT_EQ(ResourceMsg_SetDataBuffer::ID, messages[1].type()); 836 837 PickleIterator iter(messages[1]); 838 int request_id; 839 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &request_id)); 840 base::SharedMemoryHandle shm_handle; 841 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_handle)); 842 int shm_size; 843 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_size)); 844 845 // Followed by the data, currently we only do the data in one chunk, but 846 // should probably test multiple chunks later 847 ASSERT_EQ(ResourceMsg_DataReceived::ID, messages[2].type()); 848 849 int data_offset; 850 int data_length; 851 ASSERT_TRUE( 852 ExtractDataOffsetAndLength(messages[2], &data_offset, &data_length)); 853 854 ASSERT_EQ(reference_data.size(), static_cast<size_t>(data_length)); 855 ASSERT_GE(shm_size, data_length); 856 857 base::SharedMemory shared_mem(shm_handle, true); // read only 858 shared_mem.Map(data_length); 859 const char* data = static_cast<char*>(shared_mem.memory()) + data_offset; 860 ASSERT_EQ(0, memcmp(reference_data.c_str(), data, data_length)); 861 862 // The last message should be all data received. 863 CheckRequestCompleteErrorCode(messages[3], expected_error); 864 } 865 866 void CheckSuccessfulRequest(const std::vector<IPC::Message>& messages, 867 const std::string& reference_data) { 868 CheckSuccessfulRequestWithErrorCode(messages, reference_data, net::OK); 869 } 870 871 void CheckSuccessfulRedirect(const std::vector<IPC::Message>& messages, 872 const std::string& reference_data) { 873 ASSERT_EQ(5U, messages.size()); 874 ASSERT_EQ(ResourceMsg_ReceivedRedirect::ID, messages[0].type()); 875 876 const std::vector<IPC::Message> second_req_msgs = 877 std::vector<IPC::Message>(messages.begin() + 1, messages.end()); 878 CheckSuccessfulRequest(second_req_msgs, reference_data); 879 } 880 881 void CheckFailedRequest(const std::vector<IPC::Message>& messages, 882 const std::string& reference_data, 883 int expected_error) { 884 ASSERT_LT(0U, messages.size()); 885 ASSERT_GE(2U, messages.size()); 886 size_t failure_index = messages.size() - 1; 887 888 if (messages.size() == 2) { 889 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type()); 890 } 891 892 CheckRequestCompleteErrorCode(messages[failure_index], expected_error); 893 } 894 895 // Tests whether many messages get dispatched properly. 896 TEST_F(ResourceDispatcherHostTest, TestMany) { 897 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); 898 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2()); 899 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3()); 900 MakeTestRequestWithResourceType(filter_.get(), 0, 4, 901 net::URLRequestTestJob::test_url_4(), 902 ResourceType::PREFETCH); // detachable type 903 MakeTestRequest(0, 5, net::URLRequestTestJob::test_url_redirect_to_url_2()); 904 905 // Finish the redirection 906 ResourceHostMsg_FollowRedirect redirect_msg(5, false, GURL()); 907 bool msg_was_ok; 908 host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok); 909 base::MessageLoop::current()->RunUntilIdle(); 910 911 // flush all the pending requests 912 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 913 914 // sorts out all the messages we saw by request 915 ResourceIPCAccumulator::ClassifiedMessages msgs; 916 accum_.GetClassifiedMessages(&msgs); 917 918 // there are five requests, so we should have gotten them classified as such 919 ASSERT_EQ(5U, msgs.size()); 920 921 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); 922 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_2()); 923 CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3()); 924 CheckSuccessfulRequest(msgs[3], net::URLRequestTestJob::test_data_4()); 925 CheckSuccessfulRedirect(msgs[4], net::URLRequestTestJob::test_data_2()); 926 } 927 928 // Tests whether messages get canceled properly. We issue four requests, 929 // cancel two of them, and make sure that each sent the proper notifications. 930 TEST_F(ResourceDispatcherHostTest, Cancel) { 931 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); 932 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2()); 933 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3()); 934 935 MakeTestRequestWithResourceType(filter_.get(), 0, 4, 936 net::URLRequestTestJob::test_url_4(), 937 ResourceType::PREFETCH); // detachable type 938 939 CancelRequest(2); 940 941 // Cancel request must come from the renderer for a detachable resource to 942 // delay. 943 host_.CancelRequest(filter_->child_id(), 4, true); 944 945 // The handler should have been detached now. 946 GlobalRequestID global_request_id(filter_->child_id(), 4); 947 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest( 948 host_.GetURLRequest(global_request_id)); 949 ASSERT_TRUE(info->detachable_handler()->is_detached()); 950 951 // flush all the pending requests 952 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 953 base::MessageLoop::current()->RunUntilIdle(); 954 955 // Everything should be out now. 956 EXPECT_EQ(0, host_.pending_requests()); 957 958 ResourceIPCAccumulator::ClassifiedMessages msgs; 959 accum_.GetClassifiedMessages(&msgs); 960 961 // there are four requests, so we should have gotten them classified as such 962 ASSERT_EQ(4U, msgs.size()); 963 964 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); 965 CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3()); 966 967 // Check that request 2 and 4 got canceled, as far as the renderer is 968 // concerned. 969 ASSERT_EQ(2U, msgs[1].size()); 970 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type()); 971 CheckRequestCompleteErrorCode(msgs[1][1], net::ERR_ABORTED); 972 973 ASSERT_EQ(2U, msgs[3].size()); 974 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[3][0].type()); 975 CheckRequestCompleteErrorCode(msgs[1][1], net::ERR_ABORTED); 976 977 // However, request 4 should have actually gone to completion. (Only request 2 978 // was canceled.) 979 EXPECT_EQ(4, network_delegate()->completed_requests()); 980 EXPECT_EQ(1, network_delegate()->canceled_requests()); 981 EXPECT_EQ(0, network_delegate()->error_count()); 982 } 983 984 // Shows that detachable requests will timeout if the request takes too long to 985 // complete. 986 TEST_F(ResourceDispatcherHostTest, DetachedResourceTimesOut) { 987 MakeTestRequestWithResourceType(filter_.get(), 0, 1, 988 net::URLRequestTestJob::test_url_2(), 989 ResourceType::PREFETCH); // detachable type 990 GlobalRequestID global_request_id(filter_->child_id(), 1); 991 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest( 992 host_.GetURLRequest(global_request_id)); 993 ASSERT_TRUE(info->detachable_handler()); 994 info->detachable_handler()->set_cancel_delay( 995 base::TimeDelta::FromMilliseconds(200)); 996 base::MessageLoop::current()->RunUntilIdle(); 997 host_.CancelRequest(filter_->child_id(), 1, true); 998 999 // From the renderer's perspective, the request was cancelled. 1000 ResourceIPCAccumulator::ClassifiedMessages msgs; 1001 accum_.GetClassifiedMessages(&msgs); 1002 ASSERT_EQ(1U, msgs.size()); 1003 ASSERT_EQ(2U, msgs[0].size()); 1004 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type()); 1005 CheckRequestCompleteErrorCode(msgs[0][1], net::ERR_ABORTED); 1006 1007 // But it continues detached. 1008 EXPECT_EQ(1, host_.pending_requests()); 1009 EXPECT_TRUE(info->detachable_handler()->is_detached()); 1010 1011 // Wait until after the delay timer times out before we start processing any 1012 // messages. 1013 base::OneShotTimer<base::MessageLoop> timer; 1014 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(210), 1015 base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle); 1016 base::MessageLoop::current()->Run(); 1017 1018 // The prefetch should be cancelled by now. 1019 EXPECT_EQ(0, host_.pending_requests()); 1020 EXPECT_EQ(1, network_delegate()->completed_requests()); 1021 EXPECT_EQ(1, network_delegate()->canceled_requests()); 1022 EXPECT_EQ(0, network_delegate()->error_count()); 1023 } 1024 1025 // If the filter has disappeared then detachable resources should continue to 1026 // load. 1027 TEST_F(ResourceDispatcherHostTest, DeletedFilterDetached) { 1028 // test_url_1's data is available synchronously, so use 2 and 3. 1029 ResourceHostMsg_Request request_prefetch = CreateResourceRequest( 1030 "GET", ResourceType::PREFETCH, net::URLRequestTestJob::test_url_2()); 1031 ResourceHostMsg_Request request_ping = CreateResourceRequest( 1032 "GET", ResourceType::PING, net::URLRequestTestJob::test_url_3()); 1033 1034 bool msg_was_ok; 1035 ResourceHostMsg_RequestResource msg_prefetch(0, 1, request_prefetch); 1036 host_.OnMessageReceived(msg_prefetch, filter_, &msg_was_ok); 1037 ResourceHostMsg_RequestResource msg_ping(0, 2, request_ping); 1038 host_.OnMessageReceived(msg_ping, filter_, &msg_was_ok); 1039 1040 // Remove the filter before processing the requests by simulating channel 1041 // closure. 1042 ResourceRequestInfoImpl* info_prefetch = ResourceRequestInfoImpl::ForRequest( 1043 host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1))); 1044 ResourceRequestInfoImpl* info_ping = ResourceRequestInfoImpl::ForRequest( 1045 host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 2))); 1046 DCHECK_EQ(filter_.get(), info_prefetch->filter()); 1047 DCHECK_EQ(filter_.get(), info_ping->filter()); 1048 filter_->OnChannelClosing(); 1049 info_prefetch->filter_.reset(); 1050 info_ping->filter_.reset(); 1051 1052 // From the renderer's perspective, the requests were cancelled. 1053 ResourceIPCAccumulator::ClassifiedMessages msgs; 1054 accum_.GetClassifiedMessages(&msgs); 1055 ASSERT_EQ(2U, msgs.size()); 1056 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED); 1057 CheckRequestCompleteErrorCode(msgs[1][0], net::ERR_ABORTED); 1058 1059 // But it continues detached. 1060 EXPECT_EQ(2, host_.pending_requests()); 1061 EXPECT_TRUE(info_prefetch->detachable_handler()->is_detached()); 1062 EXPECT_TRUE(info_ping->detachable_handler()->is_detached()); 1063 1064 KickOffRequest(); 1065 1066 // Make sure the requests weren't canceled early. 1067 EXPECT_EQ(2, host_.pending_requests()); 1068 1069 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1070 base::MessageLoop::current()->RunUntilIdle(); 1071 1072 EXPECT_EQ(0, host_.pending_requests()); 1073 EXPECT_EQ(2, network_delegate()->completed_requests()); 1074 EXPECT_EQ(0, network_delegate()->canceled_requests()); 1075 EXPECT_EQ(0, network_delegate()->error_count()); 1076 } 1077 1078 // If the filter has disappeared (original process dies) then detachable 1079 // resources should continue to load, even when redirected. 1080 TEST_F(ResourceDispatcherHostTest, DeletedFilterDetachedRedirect) { 1081 ResourceHostMsg_Request request = CreateResourceRequest( 1082 "GET", ResourceType::PREFETCH, 1083 net::URLRequestTestJob::test_url_redirect_to_url_2()); 1084 1085 ResourceHostMsg_RequestResource msg(0, 1, request); 1086 bool msg_was_ok; 1087 host_.OnMessageReceived(msg, filter_, &msg_was_ok); 1088 1089 // Remove the filter before processing the request by simulating channel 1090 // closure. 1091 GlobalRequestID global_request_id(filter_->child_id(), 1); 1092 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest( 1093 host_.GetURLRequest(global_request_id)); 1094 info->filter_->OnChannelClosing(); 1095 info->filter_.reset(); 1096 1097 // From the renderer's perspective, the request was cancelled. 1098 ResourceIPCAccumulator::ClassifiedMessages msgs; 1099 accum_.GetClassifiedMessages(&msgs); 1100 ASSERT_EQ(1U, msgs.size()); 1101 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED); 1102 1103 // But it continues detached. 1104 EXPECT_EQ(1, host_.pending_requests()); 1105 EXPECT_TRUE(info->detachable_handler()->is_detached()); 1106 1107 // Verify no redirects before resetting the filter. 1108 net::URLRequest* url_request = host_.GetURLRequest(global_request_id); 1109 EXPECT_EQ(1u, url_request->url_chain().size()); 1110 KickOffRequest(); 1111 1112 // Verify that a redirect was followed. 1113 EXPECT_EQ(2u, url_request->url_chain().size()); 1114 1115 // Make sure the request wasn't canceled early. 1116 EXPECT_EQ(1, host_.pending_requests()); 1117 1118 // Finish up the request. 1119 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1120 base::MessageLoop::current()->RunUntilIdle(); 1121 1122 EXPECT_EQ(0, host_.pending_requests()); 1123 EXPECT_EQ(1, network_delegate()->completed_requests()); 1124 EXPECT_EQ(0, network_delegate()->canceled_requests()); 1125 EXPECT_EQ(0, network_delegate()->error_count()); 1126 } 1127 1128 TEST_F(ResourceDispatcherHostTest, CancelWhileStartIsDeferred) { 1129 bool was_deleted = false; 1130 1131 // Arrange to have requests deferred before starting. 1132 TestResourceDispatcherHostDelegate delegate; 1133 delegate.set_flags(DEFER_STARTING_REQUEST); 1134 delegate.set_url_request_user_data(new TestUserData(&was_deleted)); 1135 host_.SetDelegate(&delegate); 1136 1137 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); 1138 CancelRequest(1); 1139 1140 // Our TestResourceThrottle should not have been deleted yet. This is to 1141 // ensure that destruction of the URLRequest happens asynchronously to 1142 // calling CancelRequest. 1143 EXPECT_FALSE(was_deleted); 1144 1145 base::MessageLoop::current()->RunUntilIdle(); 1146 1147 EXPECT_TRUE(was_deleted); 1148 } 1149 1150 TEST_F(ResourceDispatcherHostTest, DetachWhileStartIsDeferred) { 1151 bool was_deleted = false; 1152 1153 // Arrange to have requests deferred before starting. 1154 TestResourceDispatcherHostDelegate delegate; 1155 delegate.set_flags(DEFER_STARTING_REQUEST); 1156 delegate.set_url_request_user_data(new TestUserData(&was_deleted)); 1157 host_.SetDelegate(&delegate); 1158 1159 MakeTestRequestWithResourceType(filter_.get(), 0, 1, 1160 net::URLRequestTestJob::test_url_1(), 1161 ResourceType::PREFETCH); // detachable type 1162 // Cancel request must come from the renderer for a detachable resource to 1163 // detach. 1164 host_.CancelRequest(filter_->child_id(), 1, true); 1165 1166 // Even after driving the event loop, the request has not been deleted. 1167 EXPECT_FALSE(was_deleted); 1168 1169 // However, it is still throttled because the defer happened above the 1170 // DetachableResourceHandler. 1171 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1172 base::MessageLoop::current()->RunUntilIdle(); 1173 EXPECT_FALSE(was_deleted); 1174 1175 // Resume the request. 1176 GenericResourceThrottle* throttle = 1177 GenericResourceThrottle::active_throttle(); 1178 ASSERT_TRUE(throttle); 1179 throttle->Resume(); 1180 1181 // Now, the request completes. 1182 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1183 base::MessageLoop::current()->RunUntilIdle(); 1184 EXPECT_TRUE(was_deleted); 1185 EXPECT_EQ(1, network_delegate()->completed_requests()); 1186 EXPECT_EQ(0, network_delegate()->canceled_requests()); 1187 EXPECT_EQ(0, network_delegate()->error_count()); 1188 } 1189 1190 // Tests if cancel is called in ResourceThrottle::WillStartRequest, then the 1191 // URLRequest will not be started. 1192 TEST_F(ResourceDispatcherHostTest, CancelInResourceThrottleWillStartRequest) { 1193 TestResourceDispatcherHostDelegate delegate; 1194 delegate.set_flags(CANCEL_BEFORE_START); 1195 host_.SetDelegate(&delegate); 1196 1197 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); 1198 1199 // flush all the pending requests 1200 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1201 base::MessageLoop::current()->RunUntilIdle(); 1202 1203 ResourceIPCAccumulator::ClassifiedMessages msgs; 1204 accum_.GetClassifiedMessages(&msgs); 1205 1206 // Check that request got canceled. 1207 ASSERT_EQ(1U, msgs[0].size()); 1208 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED); 1209 1210 // Make sure URLRequest is never started. 1211 EXPECT_EQ(0, url_request_jobs_created_count_); 1212 } 1213 1214 TEST_F(ResourceDispatcherHostTest, PausedStartError) { 1215 // Arrange to have requests deferred before processing response headers. 1216 TestResourceDispatcherHostDelegate delegate; 1217 delegate.set_flags(DEFER_PROCESSING_RESPONSE); 1218 host_.SetDelegate(&delegate); 1219 1220 SetDelayedStartJobGeneration(true); 1221 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_error()); 1222 CompleteStartRequest(1); 1223 1224 // flush all the pending requests 1225 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1226 base::MessageLoop::current()->RunUntilIdle(); 1227 1228 EXPECT_EQ(0, host_.pending_requests()); 1229 } 1230 1231 TEST_F(ResourceDispatcherHostTest, ThrottleAndResumeTwice) { 1232 // Arrange to have requests deferred before starting. 1233 TestResourceDispatcherHostDelegate delegate; 1234 delegate.set_flags(DEFER_STARTING_REQUEST); 1235 delegate.set_create_two_throttles(true); 1236 host_.SetDelegate(&delegate); 1237 1238 // Make sure the first throttle blocked the request, and then resume. 1239 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); 1240 GenericResourceThrottle* first_throttle = 1241 GenericResourceThrottle::active_throttle(); 1242 ASSERT_TRUE(first_throttle); 1243 first_throttle->Resume(); 1244 1245 // Make sure the second throttle blocked the request, and then resume. 1246 ASSERT_TRUE(GenericResourceThrottle::active_throttle()); 1247 ASSERT_NE(first_throttle, GenericResourceThrottle::active_throttle()); 1248 GenericResourceThrottle::active_throttle()->Resume(); 1249 1250 ASSERT_FALSE(GenericResourceThrottle::active_throttle()); 1251 1252 // The request is started asynchronously. 1253 base::MessageLoop::current()->RunUntilIdle(); 1254 1255 // Flush all the pending requests. 1256 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1257 1258 EXPECT_EQ(0, host_.pending_requests()); 1259 1260 // Make sure the request completed successfully. 1261 ResourceIPCAccumulator::ClassifiedMessages msgs; 1262 accum_.GetClassifiedMessages(&msgs); 1263 ASSERT_EQ(1U, msgs.size()); 1264 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); 1265 } 1266 1267 1268 // Tests that the delegate can cancel a request and provide a error code. 1269 TEST_F(ResourceDispatcherHostTest, CancelInDelegate) { 1270 TestResourceDispatcherHostDelegate delegate; 1271 delegate.set_flags(CANCEL_BEFORE_START); 1272 delegate.set_error_code_for_cancellation(net::ERR_ACCESS_DENIED); 1273 host_.SetDelegate(&delegate); 1274 1275 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); 1276 // The request will get cancelled by the throttle. 1277 1278 // flush all the pending requests 1279 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1280 base::MessageLoop::current()->RunUntilIdle(); 1281 1282 ResourceIPCAccumulator::ClassifiedMessages msgs; 1283 accum_.GetClassifiedMessages(&msgs); 1284 1285 // Check the cancellation 1286 ASSERT_EQ(1U, msgs.size()); 1287 ASSERT_EQ(1U, msgs[0].size()); 1288 1289 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ACCESS_DENIED); 1290 } 1291 1292 // The host delegate acts as a second one so we can have some requests 1293 // pending and some canceled. 1294 class TestFilter : public ForwardingFilter { 1295 public: 1296 explicit TestFilter(ResourceContext* resource_context) 1297 : ForwardingFilter(NULL, resource_context), 1298 has_canceled_(false), 1299 received_after_canceled_(0) { 1300 } 1301 1302 // ForwardingFilter override 1303 virtual bool Send(IPC::Message* msg) OVERRIDE { 1304 // no messages should be received when the process has been canceled 1305 if (has_canceled_) 1306 received_after_canceled_++; 1307 delete msg; 1308 return true; 1309 } 1310 1311 bool has_canceled_; 1312 int received_after_canceled_; 1313 1314 private: 1315 virtual ~TestFilter() {} 1316 }; 1317 1318 // Tests CancelRequestsForProcess 1319 TEST_F(ResourceDispatcherHostTest, TestProcessCancel) { 1320 scoped_refptr<TestFilter> test_filter = new TestFilter( 1321 browser_context_->GetResourceContext()); 1322 1323 // request 1 goes to the test delegate 1324 ResourceHostMsg_Request request = CreateResourceRequest( 1325 "GET", ResourceType::SUB_RESOURCE, net::URLRequestTestJob::test_url_1()); 1326 1327 MakeTestRequestWithResourceType(test_filter.get(), 0, 1, 1328 net::URLRequestTestJob::test_url_1(), 1329 ResourceType::SUB_RESOURCE); 1330 1331 // request 2 goes to us 1332 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2()); 1333 1334 // request 3 goes to the test delegate 1335 MakeTestRequestWithResourceType(test_filter.get(), 0, 3, 1336 net::URLRequestTestJob::test_url_3(), 1337 ResourceType::SUB_RESOURCE); 1338 1339 // request 4 goes to us 1340 MakeTestRequestWithResourceType(filter_.get(), 0, 4, 1341 net::URLRequestTestJob::test_url_4(), 1342 ResourceType::PREFETCH); // detachable type 1343 1344 1345 // Make sure all requests have finished stage one. test_url_1 will have 1346 // finished. 1347 base::MessageLoop::current()->RunUntilIdle(); 1348 1349 // TODO(mbelshe): 1350 // Now that the async IO path is in place, the IO always completes on the 1351 // initial call; so the requests have already completed. This basically 1352 // breaks the whole test. 1353 //EXPECT_EQ(3, host_.pending_requests()); 1354 1355 // Process test_url_2 and test_url_3 for one level so one callback is called. 1356 // We'll cancel test_url_4 (detachable) before processing it to verify that it 1357 // delays the cancel. 1358 for (int i = 0; i < 2; i++) 1359 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage()); 1360 1361 // Cancel the requests to the test process. 1362 host_.CancelRequestsForProcess(filter_->child_id()); 1363 test_filter->has_canceled_ = true; 1364 1365 // The requests should all be cancelled, except request 4, which is detached. 1366 EXPECT_EQ(1, host_.pending_requests()); 1367 GlobalRequestID global_request_id(filter_->child_id(), 4); 1368 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest( 1369 host_.GetURLRequest(global_request_id)); 1370 ASSERT_TRUE(info->detachable_handler()->is_detached()); 1371 1372 // Flush all the pending requests. 1373 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1374 1375 EXPECT_EQ(0, host_.pending_requests()); 1376 1377 // The test delegate should not have gotten any messages after being canceled. 1378 ASSERT_EQ(0, test_filter->received_after_canceled_); 1379 1380 // There should be two results. 1381 ResourceIPCAccumulator::ClassifiedMessages msgs; 1382 accum_.GetClassifiedMessages(&msgs); 1383 ASSERT_EQ(2U, msgs.size()); 1384 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2()); 1385 // The detachable request was cancelled by the renderer before it 1386 // finished. From the perspective of the renderer, it should have cancelled. 1387 ASSERT_EQ(2U, msgs[1].size()); 1388 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type()); 1389 CheckRequestCompleteErrorCode(msgs[1][1], net::ERR_ABORTED); 1390 // But it completed anyway. For the network stack, no requests were canceled. 1391 EXPECT_EQ(4, network_delegate()->completed_requests()); 1392 EXPECT_EQ(0, network_delegate()->canceled_requests()); 1393 EXPECT_EQ(0, network_delegate()->error_count()); 1394 } 1395 1396 TEST_F(ResourceDispatcherHostTest, TestProcessCancelDetachedTimesOut) { 1397 MakeTestRequestWithResourceType(filter_.get(), 0, 1, 1398 net::URLRequestTestJob::test_url_4(), 1399 ResourceType::PREFETCH); // detachable type 1400 GlobalRequestID global_request_id(filter_->child_id(), 1); 1401 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest( 1402 host_.GetURLRequest(global_request_id)); 1403 ASSERT_TRUE(info->detachable_handler()); 1404 info->detachable_handler()->set_cancel_delay( 1405 base::TimeDelta::FromMilliseconds(200)); 1406 base::MessageLoop::current()->RunUntilIdle(); 1407 1408 // Cancel the requests to the test process. 1409 host_.CancelRequestsForProcess(filter_->child_id()); 1410 EXPECT_EQ(1, host_.pending_requests()); 1411 1412 // Wait until after the delay timer times out before we start processing any 1413 // messages. 1414 base::OneShotTimer<base::MessageLoop> timer; 1415 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(210), 1416 base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle); 1417 base::MessageLoop::current()->Run(); 1418 1419 // The prefetch should be cancelled by now. 1420 EXPECT_EQ(0, host_.pending_requests()); 1421 1422 // In case any messages are still to be processed. 1423 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1424 base::MessageLoop::current()->RunUntilIdle(); 1425 1426 ResourceIPCAccumulator::ClassifiedMessages msgs; 1427 accum_.GetClassifiedMessages(&msgs); 1428 1429 ASSERT_EQ(1U, msgs.size()); 1430 1431 // The request should have cancelled. 1432 ASSERT_EQ(2U, msgs[0].size()); 1433 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type()); 1434 CheckRequestCompleteErrorCode(msgs[0][1], net::ERR_ABORTED); 1435 // And not run to completion. 1436 EXPECT_EQ(1, network_delegate()->completed_requests()); 1437 EXPECT_EQ(1, network_delegate()->canceled_requests()); 1438 EXPECT_EQ(0, network_delegate()->error_count()); 1439 } 1440 1441 // Tests blocking and resuming requests. 1442 TEST_F(ResourceDispatcherHostTest, TestBlockingResumingRequests) { 1443 host_.BlockRequestsForRoute(filter_->child_id(), 1); 1444 host_.BlockRequestsForRoute(filter_->child_id(), 2); 1445 host_.BlockRequestsForRoute(filter_->child_id(), 3); 1446 1447 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); 1448 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2()); 1449 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3()); 1450 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1()); 1451 MakeTestRequest(2, 5, net::URLRequestTestJob::test_url_2()); 1452 MakeTestRequest(3, 6, net::URLRequestTestJob::test_url_3()); 1453 1454 // Flush all the pending requests 1455 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1456 1457 // Sort out all the messages we saw by request 1458 ResourceIPCAccumulator::ClassifiedMessages msgs; 1459 accum_.GetClassifiedMessages(&msgs); 1460 1461 // All requests but the 2 for the RVH 0 should have been blocked. 1462 ASSERT_EQ(2U, msgs.size()); 1463 1464 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); 1465 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3()); 1466 1467 // Resume requests for RVH 1 and flush pending requests. 1468 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 1); 1469 KickOffRequest(); 1470 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1471 1472 msgs.clear(); 1473 accum_.GetClassifiedMessages(&msgs); 1474 ASSERT_EQ(2U, msgs.size()); 1475 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2()); 1476 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_1()); 1477 1478 // Test that new requests are not blocked for RVH 1. 1479 MakeTestRequest(1, 7, net::URLRequestTestJob::test_url_1()); 1480 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1481 msgs.clear(); 1482 accum_.GetClassifiedMessages(&msgs); 1483 ASSERT_EQ(1U, msgs.size()); 1484 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); 1485 1486 // Now resumes requests for all RVH (2 and 3). 1487 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 2); 1488 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 3); 1489 KickOffRequest(); 1490 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1491 1492 msgs.clear(); 1493 accum_.GetClassifiedMessages(&msgs); 1494 ASSERT_EQ(2U, msgs.size()); 1495 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2()); 1496 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3()); 1497 } 1498 1499 // Tests blocking and canceling requests. 1500 TEST_F(ResourceDispatcherHostTest, TestBlockingCancelingRequests) { 1501 host_.BlockRequestsForRoute(filter_->child_id(), 1); 1502 1503 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); 1504 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2()); 1505 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3()); 1506 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1()); 1507 // Blocked detachable resources should not delay cancellation. 1508 MakeTestRequestWithResourceType(filter_.get(), 1, 5, 1509 net::URLRequestTestJob::test_url_4(), 1510 ResourceType::PREFETCH); // detachable type 1511 1512 // Flush all the pending requests. 1513 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1514 1515 // Sort out all the messages we saw by request. 1516 ResourceIPCAccumulator::ClassifiedMessages msgs; 1517 accum_.GetClassifiedMessages(&msgs); 1518 1519 // The 2 requests for the RVH 0 should have been processed. 1520 ASSERT_EQ(2U, msgs.size()); 1521 1522 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); 1523 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3()); 1524 1525 // Cancel requests for RVH 1. 1526 host_.CancelBlockedRequestsForRoute(filter_->child_id(), 1); 1527 KickOffRequest(); 1528 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1529 1530 msgs.clear(); 1531 accum_.GetClassifiedMessages(&msgs); 1532 ASSERT_EQ(0U, msgs.size()); 1533 } 1534 1535 // Tests that blocked requests are canceled if their associated process dies. 1536 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) { 1537 // This second filter is used to emulate a second process. 1538 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( 1539 this, browser_context_->GetResourceContext()); 1540 1541 host_.BlockRequestsForRoute(second_filter->child_id(), 0); 1542 1543 MakeTestRequestWithResourceType(filter_.get(), 0, 1, 1544 net::URLRequestTestJob::test_url_1(), 1545 ResourceType::SUB_RESOURCE); 1546 MakeTestRequestWithResourceType(second_filter.get(), 0, 2, 1547 net::URLRequestTestJob::test_url_2(), 1548 ResourceType::SUB_RESOURCE); 1549 MakeTestRequestWithResourceType(filter_.get(), 0, 3, 1550 net::URLRequestTestJob::test_url_3(), 1551 ResourceType::SUB_RESOURCE); 1552 MakeTestRequestWithResourceType(second_filter.get(), 0, 4, 1553 net::URLRequestTestJob::test_url_1(), 1554 ResourceType::SUB_RESOURCE); 1555 MakeTestRequestWithResourceType(second_filter.get(), 0, 5, 1556 net::URLRequestTestJob::test_url_4(), 1557 ResourceType::PREFETCH); // detachable type 1558 1559 // Simulate process death. 1560 host_.CancelRequestsForProcess(second_filter->child_id()); 1561 1562 // Flush all the pending requests. 1563 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1564 1565 // Sort out all the messages we saw by request. 1566 ResourceIPCAccumulator::ClassifiedMessages msgs; 1567 accum_.GetClassifiedMessages(&msgs); 1568 1569 // The 2 requests for the RVH 0 should have been processed. Note that 1570 // blocked detachable requests are canceled without delay. 1571 ASSERT_EQ(2U, msgs.size()); 1572 1573 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); 1574 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3()); 1575 1576 EXPECT_TRUE(host_.blocked_loaders_map_.empty()); 1577 } 1578 1579 // Tests that blocked requests don't leak when the ResourceDispatcherHost goes 1580 // away. Note that we rely on Purify for finding the leaks if any. 1581 // If this test turns the Purify bot red, check the ResourceDispatcherHost 1582 // destructor to make sure the blocked requests are deleted. 1583 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) { 1584 // This second filter is used to emulate a second process. 1585 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( 1586 this, browser_context_->GetResourceContext()); 1587 1588 host_.BlockRequestsForRoute(filter_->child_id(), 1); 1589 host_.BlockRequestsForRoute(filter_->child_id(), 2); 1590 host_.BlockRequestsForRoute(second_filter->child_id(), 1); 1591 1592 MakeTestRequestWithResourceType(filter_.get(), 0, 1, 1593 net::URLRequestTestJob::test_url_1(), 1594 ResourceType::SUB_RESOURCE); 1595 MakeTestRequestWithResourceType(filter_.get(), 1, 2, 1596 net::URLRequestTestJob::test_url_2(), 1597 ResourceType::SUB_RESOURCE); 1598 MakeTestRequestWithResourceType(filter_.get(), 0, 3, 1599 net::URLRequestTestJob::test_url_3(), 1600 ResourceType::SUB_RESOURCE); 1601 MakeTestRequestWithResourceType(second_filter.get(), 1, 4, 1602 net::URLRequestTestJob::test_url_1(), 1603 ResourceType::SUB_RESOURCE); 1604 MakeTestRequestWithResourceType(filter_.get(), 2, 5, 1605 net::URLRequestTestJob::test_url_2(), 1606 ResourceType::SUB_RESOURCE); 1607 MakeTestRequestWithResourceType(filter_.get(), 2, 6, 1608 net::URLRequestTestJob::test_url_3(), 1609 ResourceType::SUB_RESOURCE); 1610 MakeTestRequestWithResourceType(filter_.get(), 0, 7, 1611 net::URLRequestTestJob::test_url_4(), 1612 ResourceType::PREFETCH); // detachable type 1613 MakeTestRequestWithResourceType(second_filter.get(), 1, 8, 1614 net::URLRequestTestJob::test_url_4(), 1615 ResourceType::PREFETCH); // detachable type 1616 1617 host_.CancelRequestsForProcess(filter_->child_id()); 1618 host_.CancelRequestsForProcess(second_filter->child_id()); 1619 1620 // Flush all the pending requests. 1621 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1622 } 1623 1624 // Test the private helper method "CalculateApproximateMemoryCost()". 1625 TEST_F(ResourceDispatcherHostTest, CalculateApproximateMemoryCost) { 1626 net::URLRequestContext context; 1627 net::URLRequest req( 1628 GURL("http://www.google.com"), net::DEFAULT_PRIORITY, NULL, &context); 1629 EXPECT_EQ(4427, 1630 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req)); 1631 1632 // Add 9 bytes of referrer. 1633 req.SetReferrer("123456789"); 1634 EXPECT_EQ(4436, 1635 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req)); 1636 1637 // Add 33 bytes of upload content. 1638 std::string upload_content; 1639 upload_content.resize(33); 1640 std::fill(upload_content.begin(), upload_content.end(), 'x'); 1641 scoped_ptr<net::UploadElementReader> reader(new net::UploadBytesElementReader( 1642 upload_content.data(), upload_content.size())); 1643 req.set_upload(make_scoped_ptr( 1644 net::UploadDataStream::CreateWithReader(reader.Pass(), 0))); 1645 1646 // Since the upload throttling is disabled, this has no effect on the cost. 1647 EXPECT_EQ(4436, 1648 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req)); 1649 } 1650 1651 // Test that too much memory for outstanding requests for a particular 1652 // render_process_host_id causes requests to fail. 1653 TEST_F(ResourceDispatcherHostTest, TooMuchOutstandingRequestsMemory) { 1654 // Expected cost of each request as measured by 1655 // ResourceDispatcherHost::CalculateApproximateMemoryCost(). 1656 int kMemoryCostOfTest2Req = 1657 ResourceDispatcherHostImpl::kAvgBytesPerOutstandingRequest + 1658 std::string("GET").size() + 1659 net::URLRequestTestJob::test_url_2().spec().size(); 1660 1661 // Tighten the bound on the ResourceDispatcherHost, to speed things up. 1662 int kMaxCostPerProcess = 440000; 1663 host_.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess); 1664 1665 // Determine how many instance of test_url_2() we can request before 1666 // throttling kicks in. 1667 size_t kMaxRequests = kMaxCostPerProcess / kMemoryCostOfTest2Req; 1668 1669 // This second filter is used to emulate a second process. 1670 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( 1671 this, browser_context_->GetResourceContext()); 1672 1673 // Saturate the number of outstanding requests for our process. 1674 for (size_t i = 0; i < kMaxRequests; ++i) { 1675 MakeTestRequestWithResourceType(filter_.get(), 0, i + 1, 1676 net::URLRequestTestJob::test_url_2(), 1677 ResourceType::SUB_RESOURCE); 1678 } 1679 1680 // Issue two more requests for our process -- these should fail immediately. 1681 MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequests + 1, 1682 net::URLRequestTestJob::test_url_2(), 1683 ResourceType::SUB_RESOURCE); 1684 MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequests + 2, 1685 net::URLRequestTestJob::test_url_2(), 1686 ResourceType::SUB_RESOURCE); 1687 1688 // Issue two requests for the second process -- these should succeed since 1689 // it is just process 0 that is saturated. 1690 MakeTestRequestWithResourceType(second_filter.get(), 0, kMaxRequests + 3, 1691 net::URLRequestTestJob::test_url_2(), 1692 ResourceType::SUB_RESOURCE); 1693 MakeTestRequestWithResourceType(second_filter.get(), 0, kMaxRequests + 4, 1694 net::URLRequestTestJob::test_url_2(), 1695 ResourceType::SUB_RESOURCE); 1696 1697 // Flush all the pending requests. 1698 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1699 base::MessageLoop::current()->RunUntilIdle(); 1700 1701 // Sorts out all the messages we saw by request. 1702 ResourceIPCAccumulator::ClassifiedMessages msgs; 1703 accum_.GetClassifiedMessages(&msgs); 1704 1705 // We issued (kMaxRequests + 4) total requests. 1706 ASSERT_EQ(kMaxRequests + 4, msgs.size()); 1707 1708 // Check that the first kMaxRequests succeeded. 1709 for (size_t i = 0; i < kMaxRequests; ++i) 1710 CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2()); 1711 1712 // Check that the subsequent two requests (kMaxRequests + 1) and 1713 // (kMaxRequests + 2) were failed, since the per-process bound was reached. 1714 for (int i = 0; i < 2; ++i) { 1715 // Should have sent a single RequestComplete message. 1716 int index = kMaxRequests + i; 1717 CheckFailedRequest(msgs[index], net::URLRequestTestJob::test_data_2(), 1718 net::ERR_INSUFFICIENT_RESOURCES); 1719 } 1720 1721 // The final 2 requests should have succeeded. 1722 CheckSuccessfulRequest(msgs[kMaxRequests + 2], 1723 net::URLRequestTestJob::test_data_2()); 1724 CheckSuccessfulRequest(msgs[kMaxRequests + 3], 1725 net::URLRequestTestJob::test_data_2()); 1726 } 1727 1728 // Test that when too many requests are outstanding for a particular 1729 // render_process_host_id, any subsequent request from it fails. Also verify 1730 // that the global limit is honored. 1731 TEST_F(ResourceDispatcherHostTest, TooManyOutstandingRequests) { 1732 // Tighten the bound on the ResourceDispatcherHost, to speed things up. 1733 const size_t kMaxRequestsPerProcess = 2; 1734 host_.set_max_num_in_flight_requests_per_process(kMaxRequestsPerProcess); 1735 const size_t kMaxRequests = 3; 1736 host_.set_max_num_in_flight_requests(kMaxRequests); 1737 1738 // Needed to emulate additional processes. 1739 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( 1740 this, browser_context_->GetResourceContext()); 1741 scoped_refptr<ForwardingFilter> third_filter = new ForwardingFilter( 1742 this, browser_context_->GetResourceContext()); 1743 1744 // Saturate the number of outstanding requests for our process. 1745 for (size_t i = 0; i < kMaxRequestsPerProcess; ++i) { 1746 MakeTestRequestWithResourceType(filter_.get(), 0, i + 1, 1747 net::URLRequestTestJob::test_url_2(), 1748 ResourceType::SUB_RESOURCE); 1749 } 1750 1751 // Issue another request for our process -- this should fail immediately. 1752 MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequestsPerProcess + 1, 1753 net::URLRequestTestJob::test_url_2(), 1754 ResourceType::SUB_RESOURCE); 1755 1756 // Issue a request for the second process -- this should succeed, because it 1757 // is just process 0 that is saturated. 1758 MakeTestRequestWithResourceType( 1759 second_filter.get(), 0, kMaxRequestsPerProcess + 2, 1760 net::URLRequestTestJob::test_url_2(), ResourceType::SUB_RESOURCE); 1761 1762 // Issue a request for the third process -- this should fail, because the 1763 // global limit has been reached. 1764 MakeTestRequestWithResourceType( 1765 third_filter.get(), 0, kMaxRequestsPerProcess + 3, 1766 net::URLRequestTestJob::test_url_2(), ResourceType::SUB_RESOURCE); 1767 1768 // Flush all the pending requests. 1769 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1770 base::MessageLoop::current()->RunUntilIdle(); 1771 1772 // Sorts out all the messages we saw by request. 1773 ResourceIPCAccumulator::ClassifiedMessages msgs; 1774 accum_.GetClassifiedMessages(&msgs); 1775 1776 // The processes issued the following requests: 1777 // #1 issued kMaxRequestsPerProcess that passed + 1 that failed 1778 // #2 issued 1 request that passed 1779 // #3 issued 1 request that failed 1780 ASSERT_EQ((kMaxRequestsPerProcess + 1) + 1 + 1, msgs.size()); 1781 1782 for (size_t i = 0; i < kMaxRequestsPerProcess; ++i) 1783 CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2()); 1784 1785 CheckFailedRequest(msgs[kMaxRequestsPerProcess + 0], 1786 net::URLRequestTestJob::test_data_2(), 1787 net::ERR_INSUFFICIENT_RESOURCES); 1788 CheckSuccessfulRequest(msgs[kMaxRequestsPerProcess + 1], 1789 net::URLRequestTestJob::test_data_2()); 1790 CheckFailedRequest(msgs[kMaxRequestsPerProcess + 2], 1791 net::URLRequestTestJob::test_data_2(), 1792 net::ERR_INSUFFICIENT_RESOURCES); 1793 } 1794 1795 // Tests that we sniff the mime type for a simple request. 1796 TEST_F(ResourceDispatcherHostTest, MimeSniffed) { 1797 std::string raw_headers("HTTP/1.1 200 OK\n\n"); 1798 std::string response_data("<html><title>Test One</title></html>"); 1799 SetResponse(raw_headers, response_data); 1800 1801 HandleScheme("http"); 1802 MakeTestRequest(0, 1, GURL("http:bla")); 1803 1804 // Flush all pending requests. 1805 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1806 1807 // Sorts out all the messages we saw by request. 1808 ResourceIPCAccumulator::ClassifiedMessages msgs; 1809 accum_.GetClassifiedMessages(&msgs); 1810 ASSERT_EQ(1U, msgs.size()); 1811 1812 ResourceResponseHead response_head; 1813 GetResponseHead(msgs[0], &response_head); 1814 ASSERT_EQ("text/html", response_head.mime_type); 1815 } 1816 1817 // Tests that we don't sniff the mime type when the server provides one. 1818 TEST_F(ResourceDispatcherHostTest, MimeNotSniffed) { 1819 std::string raw_headers("HTTP/1.1 200 OK\n" 1820 "Content-type: image/jpeg\n\n"); 1821 std::string response_data("<html><title>Test One</title></html>"); 1822 SetResponse(raw_headers, response_data); 1823 1824 HandleScheme("http"); 1825 MakeTestRequest(0, 1, GURL("http:bla")); 1826 1827 // Flush all pending requests. 1828 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1829 1830 // Sorts out all the messages we saw by request. 1831 ResourceIPCAccumulator::ClassifiedMessages msgs; 1832 accum_.GetClassifiedMessages(&msgs); 1833 ASSERT_EQ(1U, msgs.size()); 1834 1835 ResourceResponseHead response_head; 1836 GetResponseHead(msgs[0], &response_head); 1837 ASSERT_EQ("image/jpeg", response_head.mime_type); 1838 } 1839 1840 // Tests that we don't sniff the mime type when there is no message body. 1841 TEST_F(ResourceDispatcherHostTest, MimeNotSniffed2) { 1842 SetResponse("HTTP/1.1 304 Not Modified\n\n"); 1843 1844 HandleScheme("http"); 1845 MakeTestRequest(0, 1, GURL("http:bla")); 1846 1847 // Flush all pending requests. 1848 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1849 1850 // Sorts out all the messages we saw by request. 1851 ResourceIPCAccumulator::ClassifiedMessages msgs; 1852 accum_.GetClassifiedMessages(&msgs); 1853 ASSERT_EQ(1U, msgs.size()); 1854 1855 ResourceResponseHead response_head; 1856 GetResponseHead(msgs[0], &response_head); 1857 ASSERT_EQ("", response_head.mime_type); 1858 } 1859 1860 TEST_F(ResourceDispatcherHostTest, MimeSniff204) { 1861 SetResponse("HTTP/1.1 204 No Content\n\n"); 1862 1863 HandleScheme("http"); 1864 MakeTestRequest(0, 1, GURL("http:bla")); 1865 1866 // Flush all pending requests. 1867 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1868 1869 // Sorts out all the messages we saw by request. 1870 ResourceIPCAccumulator::ClassifiedMessages msgs; 1871 accum_.GetClassifiedMessages(&msgs); 1872 ASSERT_EQ(1U, msgs.size()); 1873 1874 ResourceResponseHead response_head; 1875 GetResponseHead(msgs[0], &response_head); 1876 ASSERT_EQ("text/plain", response_head.mime_type); 1877 } 1878 1879 TEST_F(ResourceDispatcherHostTest, MimeSniffEmpty) { 1880 SetResponse("HTTP/1.1 200 OK\n\n"); 1881 1882 HandleScheme("http"); 1883 MakeTestRequest(0, 1, GURL("http:bla")); 1884 1885 // Flush all pending requests. 1886 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1887 1888 // Sorts out all the messages we saw by request. 1889 ResourceIPCAccumulator::ClassifiedMessages msgs; 1890 accum_.GetClassifiedMessages(&msgs); 1891 ASSERT_EQ(1U, msgs.size()); 1892 1893 ResourceResponseHead response_head; 1894 GetResponseHead(msgs[0], &response_head); 1895 ASSERT_EQ("text/plain", response_head.mime_type); 1896 } 1897 1898 // Tests for crbug.com/31266 (Non-2xx + application/octet-stream). 1899 TEST_F(ResourceDispatcherHostTest, ForbiddenDownload) { 1900 std::string raw_headers("HTTP/1.1 403 Forbidden\n" 1901 "Content-disposition: attachment; filename=blah\n" 1902 "Content-type: application/octet-stream\n\n"); 1903 std::string response_data("<html><title>Test One</title></html>"); 1904 SetResponse(raw_headers, response_data); 1905 1906 HandleScheme("http"); 1907 1908 // Only MAIN_FRAMEs can trigger a download. 1909 MakeTestRequestWithResourceType(filter_.get(), 0, 1, GURL("http:bla"), 1910 ResourceType::MAIN_FRAME); 1911 1912 // Flush all pending requests. 1913 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1914 1915 // Sorts out all the messages we saw by request. 1916 ResourceIPCAccumulator::ClassifiedMessages msgs; 1917 accum_.GetClassifiedMessages(&msgs); 1918 1919 // We should have gotten one RequestComplete message. 1920 ASSERT_EQ(1U, msgs[0].size()); 1921 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type()); 1922 1923 // The RequestComplete message should have had the error code of 1924 // ERR_FILE_NOT_FOUND. 1925 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_FILE_NOT_FOUND); 1926 } 1927 1928 // Test for http://crbug.com/76202 . We don't want to destroy a 1929 // download request prematurely when processing a cancellation from 1930 // the renderer. 1931 TEST_F(ResourceDispatcherHostTest, IgnoreCancelForDownloads) { 1932 EXPECT_EQ(0, host_.pending_requests()); 1933 1934 int render_view_id = 0; 1935 int request_id = 1; 1936 1937 std::string raw_headers("HTTP\n" 1938 "Content-disposition: attachment; filename=foo\n\n"); 1939 std::string response_data("01234567890123456789\x01foobar"); 1940 1941 // Get past sniffing metrics in the BufferedResourceHandler. Note that 1942 // if we don't get past the sniffing metrics, the result will be that 1943 // the BufferedResourceHandler won't have figured out that it's a download, 1944 // won't have constructed a DownloadResourceHandler, and and the request 1945 // will be successfully canceled below, failing the test. 1946 response_data.resize(1025, ' '); 1947 1948 SetResponse(raw_headers, response_data); 1949 SetDelayedCompleteJobGeneration(true); 1950 HandleScheme("http"); 1951 1952 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, 1953 GURL("http://example.com/blah"), 1954 ResourceType::MAIN_FRAME); 1955 // Return some data so that the request is identified as a download 1956 // and the proper resource handlers are created. 1957 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage()); 1958 1959 // And now simulate a cancellation coming from the renderer. 1960 ResourceHostMsg_CancelRequest msg(request_id); 1961 bool msg_was_ok; 1962 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok); 1963 1964 // Since the request had already started processing as a download, 1965 // the cancellation above should have been ignored and the request 1966 // should still be alive. 1967 EXPECT_EQ(1, host_.pending_requests()); 1968 1969 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1970 } 1971 1972 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContext) { 1973 EXPECT_EQ(0, host_.pending_requests()); 1974 1975 int render_view_id = 0; 1976 int request_id = 1; 1977 1978 std::string raw_headers("HTTP\n" 1979 "Content-disposition: attachment; filename=foo\n\n"); 1980 std::string response_data("01234567890123456789\x01foobar"); 1981 // Get past sniffing metrics. 1982 response_data.resize(1025, ' '); 1983 1984 SetResponse(raw_headers, response_data); 1985 SetDelayedCompleteJobGeneration(true); 1986 HandleScheme("http"); 1987 1988 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, 1989 GURL("http://example.com/blah"), 1990 ResourceType::MAIN_FRAME); 1991 // Return some data so that the request is identified as a download 1992 // and the proper resource handlers are created. 1993 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage()); 1994 1995 // And now simulate a cancellation coming from the renderer. 1996 ResourceHostMsg_CancelRequest msg(request_id); 1997 bool msg_was_ok; 1998 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok); 1999 2000 // Since the request had already started processing as a download, 2001 // the cancellation above should have been ignored and the request 2002 // should still be alive. 2003 EXPECT_EQ(1, host_.pending_requests()); 2004 2005 // Cancelling by other methods shouldn't work either. 2006 host_.CancelRequestsForProcess(render_view_id); 2007 EXPECT_EQ(1, host_.pending_requests()); 2008 2009 // Cancelling by context should work. 2010 host_.CancelRequestsForContext(filter_->resource_context()); 2011 EXPECT_EQ(0, host_.pending_requests()); 2012 } 2013 2014 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextDetached) { 2015 EXPECT_EQ(0, host_.pending_requests()); 2016 2017 int render_view_id = 0; 2018 int request_id = 1; 2019 2020 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, 2021 net::URLRequestTestJob::test_url_4(), 2022 ResourceType::PREFETCH); // detachable type 2023 2024 // Simulate a cancel coming from the renderer. 2025 host_.CancelRequest(filter_->child_id(), request_id, true); 2026 2027 // Since the request had already started processing as detachable, 2028 // the cancellation above should have been ignored and the request 2029 // should have been detached. 2030 EXPECT_EQ(1, host_.pending_requests()); 2031 2032 // Cancelling by other methods should also leave it detached. 2033 host_.CancelRequestsForProcess(render_view_id); 2034 EXPECT_EQ(1, host_.pending_requests()); 2035 2036 // Cancelling by context should work. 2037 host_.CancelRequestsForContext(filter_->resource_context()); 2038 EXPECT_EQ(0, host_.pending_requests()); 2039 } 2040 2041 // Test the cancelling of requests that are being transferred to a new renderer 2042 // due to a redirection. 2043 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextTransferred) { 2044 EXPECT_EQ(0, host_.pending_requests()); 2045 2046 int render_view_id = 0; 2047 int request_id = 1; 2048 2049 std::string raw_headers("HTTP/1.1 200 OK\n" 2050 "Content-Type: text/html; charset=utf-8\n\n"); 2051 std::string response_data("<html>foobar</html>"); 2052 2053 SetResponse(raw_headers, response_data); 2054 HandleScheme("http"); 2055 2056 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, 2057 GURL("http://example.com/blah"), 2058 ResourceType::MAIN_FRAME); 2059 2060 2061 GlobalRequestID global_request_id(filter_->child_id(), request_id); 2062 host_.MarkAsTransferredNavigation(global_request_id, 2063 GURL("http://example.com/blah")); 2064 2065 // And now simulate a cancellation coming from the renderer. 2066 ResourceHostMsg_CancelRequest msg(request_id); 2067 bool msg_was_ok; 2068 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok); 2069 2070 // Since the request is marked as being transferred, 2071 // the cancellation above should have been ignored and the request 2072 // should still be alive. 2073 EXPECT_EQ(1, host_.pending_requests()); 2074 2075 // Cancelling by other methods shouldn't work either. 2076 host_.CancelRequestsForProcess(render_view_id); 2077 EXPECT_EQ(1, host_.pending_requests()); 2078 2079 // Cancelling by context should work. 2080 host_.CancelRequestsForContext(filter_->resource_context()); 2081 EXPECT_EQ(0, host_.pending_requests()); 2082 } 2083 2084 // Test transferred navigations with text/html, which doesn't trigger any 2085 // content sniffing. 2086 TEST_F(ResourceDispatcherHostTest, TransferNavigationHtml) { 2087 EXPECT_EQ(0, host_.pending_requests()); 2088 2089 int render_view_id = 0; 2090 int request_id = 1; 2091 2092 // Configure initial request. 2093 SetResponse("HTTP/1.1 302 Found\n" 2094 "Location: http://other.com/blech\n\n"); 2095 2096 HandleScheme("http"); 2097 2098 // Temporarily replace ContentBrowserClient with one that will trigger the 2099 // transfer navigation code paths. 2100 TransfersAllNavigationsContentBrowserClient new_client; 2101 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client); 2102 2103 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, 2104 GURL("http://example.com/blah"), 2105 ResourceType::MAIN_FRAME); 2106 2107 // Now that we're blocked on the redirect, update the response and unblock by 2108 // telling the AsyncResourceHandler to follow the redirect. 2109 const std::string kResponseBody = "hello world"; 2110 SetResponse("HTTP/1.1 200 OK\n" 2111 "Content-Type: text/html\n\n", 2112 kResponseBody); 2113 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL()); 2114 bool msg_was_ok; 2115 host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok); 2116 base::MessageLoop::current()->RunUntilIdle(); 2117 2118 // Flush all the pending requests to get the response through the 2119 // BufferedResourceHandler. 2120 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 2121 2122 // Restore, now that we've set up a transfer. 2123 SetBrowserClientForTesting(old_client); 2124 2125 // This second filter is used to emulate a second process. 2126 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( 2127 this, browser_context_->GetResourceContext()); 2128 2129 int new_render_view_id = 1; 2130 int new_request_id = 2; 2131 2132 ResourceHostMsg_Request request = 2133 CreateResourceRequest("GET", ResourceType::MAIN_FRAME, 2134 GURL("http://other.com/blech")); 2135 request.transferred_request_child_id = filter_->child_id(); 2136 request.transferred_request_request_id = request_id; 2137 2138 // For cleanup. 2139 child_ids_.insert(second_filter->child_id()); 2140 ResourceHostMsg_RequestResource transfer_request_msg( 2141 new_render_view_id, new_request_id, request); 2142 host_.OnMessageReceived( 2143 transfer_request_msg, second_filter.get(), &msg_was_ok); 2144 base::MessageLoop::current()->RunUntilIdle(); 2145 2146 // Check generated messages. 2147 ResourceIPCAccumulator::ClassifiedMessages msgs; 2148 accum_.GetClassifiedMessages(&msgs); 2149 2150 ASSERT_EQ(2U, msgs.size()); 2151 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type()); 2152 CheckSuccessfulRequest(msgs[1], kResponseBody); 2153 } 2154 2155 // Test transferred navigations with text/plain, which causes 2156 // BufferedResourceHandler to buffer the response to sniff the content 2157 // before the transfer occurs. 2158 TEST_F(ResourceDispatcherHostTest, TransferNavigationText) { 2159 EXPECT_EQ(0, host_.pending_requests()); 2160 2161 int render_view_id = 0; 2162 int request_id = 1; 2163 2164 // Configure initial request. 2165 SetResponse("HTTP/1.1 302 Found\n" 2166 "Location: http://other.com/blech\n\n"); 2167 2168 HandleScheme("http"); 2169 2170 // Temporarily replace ContentBrowserClient with one that will trigger the 2171 // transfer navigation code paths. 2172 TransfersAllNavigationsContentBrowserClient new_client; 2173 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client); 2174 2175 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, 2176 GURL("http://example.com/blah"), 2177 ResourceType::MAIN_FRAME); 2178 2179 // Now that we're blocked on the redirect, update the response and unblock by 2180 // telling the AsyncResourceHandler to follow the redirect. Use a text/plain 2181 // MIME type, which causes BufferedResourceHandler to buffer it before the 2182 // transfer occurs. 2183 const std::string kResponseBody = "hello world"; 2184 SetResponse("HTTP/1.1 200 OK\n" 2185 "Content-Type: text/plain\n\n", 2186 kResponseBody); 2187 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL()); 2188 bool msg_was_ok; 2189 host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok); 2190 base::MessageLoop::current()->RunUntilIdle(); 2191 2192 // Flush all the pending requests to get the response through the 2193 // BufferedResourceHandler. 2194 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 2195 2196 // Restore, now that we've set up a transfer. 2197 SetBrowserClientForTesting(old_client); 2198 2199 // This second filter is used to emulate a second process. 2200 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( 2201 this, browser_context_->GetResourceContext()); 2202 2203 int new_render_view_id = 1; 2204 int new_request_id = 2; 2205 2206 ResourceHostMsg_Request request = 2207 CreateResourceRequest("GET", ResourceType::MAIN_FRAME, 2208 GURL("http://other.com/blech")); 2209 request.transferred_request_child_id = filter_->child_id(); 2210 request.transferred_request_request_id = request_id; 2211 2212 // For cleanup. 2213 child_ids_.insert(second_filter->child_id()); 2214 ResourceHostMsg_RequestResource transfer_request_msg( 2215 new_render_view_id, new_request_id, request); 2216 host_.OnMessageReceived( 2217 transfer_request_msg, second_filter.get(), &msg_was_ok); 2218 base::MessageLoop::current()->RunUntilIdle(); 2219 2220 // Check generated messages. 2221 ResourceIPCAccumulator::ClassifiedMessages msgs; 2222 accum_.GetClassifiedMessages(&msgs); 2223 2224 ASSERT_EQ(2U, msgs.size()); 2225 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type()); 2226 CheckSuccessfulRequest(msgs[1], kResponseBody); 2227 } 2228 2229 TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) { 2230 EXPECT_EQ(0, host_.pending_requests()); 2231 2232 int render_view_id = 0; 2233 int request_id = 1; 2234 int first_child_id = -1; 2235 2236 // Configure initial request. 2237 SetResponse("HTTP/1.1 302 Found\n" 2238 "Location: http://other.com/blech\n\n"); 2239 const std::string kResponseBody = "hello world"; 2240 2241 HandleScheme("http"); 2242 2243 // Temporarily replace ContentBrowserClient with one that will trigger the 2244 // transfer navigation code paths. 2245 TransfersAllNavigationsContentBrowserClient new_client; 2246 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client); 2247 2248 // Create a first filter that can be deleted before the second one starts. 2249 { 2250 scoped_refptr<ForwardingFilter> first_filter = new ForwardingFilter( 2251 this, browser_context_->GetResourceContext()); 2252 first_child_id = first_filter->child_id(); 2253 2254 ResourceHostMsg_Request first_request = 2255 CreateResourceRequest("GET", ResourceType::MAIN_FRAME, 2256 GURL("http://example.com/blah")); 2257 2258 // For cleanup. 2259 child_ids_.insert(first_child_id); 2260 ResourceHostMsg_RequestResource first_request_msg( 2261 render_view_id, request_id, first_request); 2262 bool msg_was_ok; 2263 host_.OnMessageReceived( 2264 first_request_msg, first_filter.get(), &msg_was_ok); 2265 base::MessageLoop::current()->RunUntilIdle(); 2266 2267 // Now that we're blocked on the redirect, update the response and unblock 2268 // by telling the AsyncResourceHandler to follow the redirect. 2269 SetResponse("HTTP/1.1 200 OK\n" 2270 "Content-Type: text/html\n\n", 2271 kResponseBody); 2272 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL()); 2273 host_.OnMessageReceived(redirect_msg, first_filter.get(), &msg_was_ok); 2274 base::MessageLoop::current()->RunUntilIdle(); 2275 2276 // Flush all the pending requests to get the response through the 2277 // BufferedResourceHandler. 2278 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 2279 } 2280 // The first filter is now deleted, as if the child process died. 2281 2282 // Restore. 2283 SetBrowserClientForTesting(old_client); 2284 2285 // Make sure we don't hold onto the ResourceMessageFilter after it is deleted. 2286 GlobalRequestID first_global_request_id(first_child_id, request_id); 2287 2288 // This second filter is used to emulate a second process. 2289 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( 2290 this, browser_context_->GetResourceContext()); 2291 2292 int new_render_view_id = 1; 2293 int new_request_id = 2; 2294 2295 ResourceHostMsg_Request request = 2296 CreateResourceRequest("GET", ResourceType::MAIN_FRAME, 2297 GURL("http://other.com/blech")); 2298 request.transferred_request_child_id = first_child_id; 2299 request.transferred_request_request_id = request_id; 2300 2301 // For cleanup. 2302 child_ids_.insert(second_filter->child_id()); 2303 ResourceHostMsg_RequestResource transfer_request_msg( 2304 new_render_view_id, new_request_id, request); 2305 bool msg_was_ok; 2306 host_.OnMessageReceived( 2307 transfer_request_msg, second_filter.get(), &msg_was_ok); 2308 base::MessageLoop::current()->RunUntilIdle(); 2309 2310 // Check generated messages. 2311 ResourceIPCAccumulator::ClassifiedMessages msgs; 2312 accum_.GetClassifiedMessages(&msgs); 2313 2314 ASSERT_EQ(2U, msgs.size()); 2315 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type()); 2316 CheckSuccessfulRequest(msgs[1], kResponseBody); 2317 } 2318 2319 TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) { 2320 EXPECT_EQ(0, host_.pending_requests()); 2321 2322 int render_view_id = 0; 2323 int request_id = 1; 2324 2325 // Configure initial request. 2326 SetResponse("HTTP/1.1 302 Found\n" 2327 "Location: http://other.com/blech\n\n"); 2328 2329 HandleScheme("http"); 2330 2331 // Temporarily replace ContentBrowserClient with one that will trigger the 2332 // transfer navigation code paths. 2333 TransfersAllNavigationsContentBrowserClient new_client; 2334 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client); 2335 2336 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, 2337 GURL("http://example.com/blah"), 2338 ResourceType::MAIN_FRAME); 2339 2340 // Now that we're blocked on the redirect, simulate hitting another redirect. 2341 SetResponse("HTTP/1.1 302 Found\n" 2342 "Location: http://other.com/blerg\n\n"); 2343 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL()); 2344 bool msg_was_ok; 2345 host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok); 2346 base::MessageLoop::current()->RunUntilIdle(); 2347 2348 // Now that we're blocked on the second redirect, update the response and 2349 // unblock by telling the AsyncResourceHandler to follow the redirect. 2350 // Again, use text/plain to force BufferedResourceHandler to buffer before 2351 // the transfer. 2352 const std::string kResponseBody = "hello world"; 2353 SetResponse("HTTP/1.1 200 OK\n" 2354 "Content-Type: text/plain\n\n", 2355 kResponseBody); 2356 ResourceHostMsg_FollowRedirect redirect_msg2(request_id, false, GURL()); 2357 host_.OnMessageReceived(redirect_msg2, filter_.get(), &msg_was_ok); 2358 base::MessageLoop::current()->RunUntilIdle(); 2359 2360 // Flush all the pending requests to get the response through the 2361 // BufferedResourceHandler. 2362 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 2363 2364 // Restore. 2365 SetBrowserClientForTesting(old_client); 2366 2367 // This second filter is used to emulate a second process. 2368 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( 2369 this, browser_context_->GetResourceContext()); 2370 2371 int new_render_view_id = 1; 2372 int new_request_id = 2; 2373 2374 ResourceHostMsg_Request request = 2375 CreateResourceRequest("GET", ResourceType::MAIN_FRAME, 2376 GURL("http://other.com/blech")); 2377 request.transferred_request_child_id = filter_->child_id(); 2378 request.transferred_request_request_id = request_id; 2379 2380 // For cleanup. 2381 child_ids_.insert(second_filter->child_id()); 2382 ResourceHostMsg_RequestResource transfer_request_msg( 2383 new_render_view_id, new_request_id, request); 2384 host_.OnMessageReceived( 2385 transfer_request_msg, second_filter.get(), &msg_was_ok); 2386 2387 // Verify that we update the ResourceRequestInfo. 2388 GlobalRequestID global_request_id(second_filter->child_id(), new_request_id); 2389 const ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest( 2390 host_.GetURLRequest(global_request_id)); 2391 EXPECT_EQ(second_filter->child_id(), info->GetChildID()); 2392 EXPECT_EQ(new_render_view_id, info->GetRouteID()); 2393 EXPECT_EQ(new_request_id, info->GetRequestID()); 2394 EXPECT_EQ(second_filter, info->filter()); 2395 2396 // Let request complete. 2397 base::MessageLoop::current()->RunUntilIdle(); 2398 2399 // Check generated messages. 2400 ResourceIPCAccumulator::ClassifiedMessages msgs; 2401 accum_.GetClassifiedMessages(&msgs); 2402 2403 ASSERT_EQ(2U, msgs.size()); 2404 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type()); 2405 CheckSuccessfulRequest(msgs[1], kResponseBody); 2406 } 2407 2408 TEST_F(ResourceDispatcherHostTest, UnknownURLScheme) { 2409 EXPECT_EQ(0, host_.pending_requests()); 2410 2411 HandleScheme("http"); 2412 2413 MakeTestRequestWithResourceType(filter_.get(), 0, 1, GURL("foo://bar"), 2414 ResourceType::MAIN_FRAME); 2415 2416 // Flush all pending requests. 2417 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 2418 2419 // Sort all the messages we saw by request. 2420 ResourceIPCAccumulator::ClassifiedMessages msgs; 2421 accum_.GetClassifiedMessages(&msgs); 2422 2423 // We should have gotten one RequestComplete message. 2424 ASSERT_EQ(1U, msgs[0].size()); 2425 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type()); 2426 2427 // The RequestComplete message should have the error code of 2428 // ERR_UNKNOWN_URL_SCHEME. 2429 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_UNKNOWN_URL_SCHEME); 2430 } 2431 2432 TEST_F(ResourceDispatcherHostTest, DataReceivedACKs) { 2433 EXPECT_EQ(0, host_.pending_requests()); 2434 2435 SendDataReceivedACKs(true); 2436 2437 HandleScheme("big-job"); 2438 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000")); 2439 2440 // Sort all the messages we saw by request. 2441 ResourceIPCAccumulator::ClassifiedMessages msgs; 2442 accum_.GetClassifiedMessages(&msgs); 2443 2444 size_t size = msgs[0].size(); 2445 2446 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type()); 2447 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type()); 2448 for (size_t i = 2; i < size - 1; ++i) 2449 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type()); 2450 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][size - 1].type()); 2451 } 2452 2453 // Request a very large detachable resource and cancel part way. Some of the 2454 // data should have been sent to the renderer, but not all. 2455 TEST_F(ResourceDispatcherHostTest, DataSentBeforeDetach) { 2456 EXPECT_EQ(0, host_.pending_requests()); 2457 2458 int render_view_id = 0; 2459 int request_id = 1; 2460 2461 std::string raw_headers("HTTP\n" 2462 "Content-type: image/jpeg\n\n"); 2463 std::string response_data("01234567890123456789\x01foobar"); 2464 2465 // Create a response larger than kMaxAllocationSize (currently 32K). Note 2466 // that if this increase beyond 512K we'll need to make the response longer. 2467 const int kAllocSize = 1024*512; 2468 response_data.resize(kAllocSize, ' '); 2469 2470 SetResponse(raw_headers, response_data); 2471 SetDelayedCompleteJobGeneration(true); 2472 HandleScheme("http"); 2473 2474 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, 2475 GURL("http://example.com/blah"), 2476 ResourceType::PREFETCH); 2477 2478 // Get a bit of data before cancelling. 2479 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage()); 2480 2481 // Simulate a cancellation coming from the renderer. 2482 ResourceHostMsg_CancelRequest msg(request_id); 2483 bool msg_was_ok; 2484 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok); 2485 2486 EXPECT_EQ(1, host_.pending_requests()); 2487 2488 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 2489 2490 // Sort all the messages we saw by request. 2491 ResourceIPCAccumulator::ClassifiedMessages msgs; 2492 accum_.GetClassifiedMessages(&msgs); 2493 2494 EXPECT_EQ(4U, msgs[0].size()); 2495 2496 // Figure out how many bytes were received by the renderer. 2497 int data_offset; 2498 int data_length; 2499 ASSERT_TRUE( 2500 ExtractDataOffsetAndLength(msgs[0][2], &data_offset, &data_length)); 2501 EXPECT_LT(0, data_length); 2502 EXPECT_GT(kAllocSize, data_length); 2503 2504 // Verify the data that was received before cancellation. The request should 2505 // have appeared to cancel, however. 2506 CheckSuccessfulRequestWithErrorCode( 2507 msgs[0], 2508 std::string(response_data.begin(), response_data.begin() + data_length), 2509 net::ERR_ABORTED); 2510 } 2511 2512 TEST_F(ResourceDispatcherHostTest, DelayedDataReceivedACKs) { 2513 EXPECT_EQ(0, host_.pending_requests()); 2514 2515 HandleScheme("big-job"); 2516 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000")); 2517 2518 // Sort all the messages we saw by request. 2519 ResourceIPCAccumulator::ClassifiedMessages msgs; 2520 accum_.GetClassifiedMessages(&msgs); 2521 2522 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages. 2523 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type()); 2524 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type()); 2525 for (size_t i = 2; i < msgs[0].size(); ++i) 2526 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type()); 2527 2528 // NOTE: If we fail the above checks then it means that we probably didn't 2529 // load a big enough response to trigger the delay mechanism we are trying to 2530 // test! 2531 2532 msgs[0].erase(msgs[0].begin()); 2533 msgs[0].erase(msgs[0].begin()); 2534 2535 // ACK all DataReceived messages until we find a RequestComplete message. 2536 bool complete = false; 2537 while (!complete) { 2538 for (size_t i = 0; i < msgs[0].size(); ++i) { 2539 if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) { 2540 complete = true; 2541 break; 2542 } 2543 2544 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type()); 2545 2546 ResourceHostMsg_DataReceived_ACK msg(1); 2547 bool msg_was_ok; 2548 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok); 2549 } 2550 2551 base::MessageLoop::current()->RunUntilIdle(); 2552 2553 msgs.clear(); 2554 accum_.GetClassifiedMessages(&msgs); 2555 } 2556 } 2557 2558 // Flakyness of this test might indicate memory corruption issues with 2559 // for example the ResourceBuffer of AsyncResourceHandler. 2560 TEST_F(ResourceDispatcherHostTest, DataReceivedUnexpectedACKs) { 2561 EXPECT_EQ(0, host_.pending_requests()); 2562 2563 HandleScheme("big-job"); 2564 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000")); 2565 2566 // Sort all the messages we saw by request. 2567 ResourceIPCAccumulator::ClassifiedMessages msgs; 2568 accum_.GetClassifiedMessages(&msgs); 2569 2570 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages. 2571 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type()); 2572 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type()); 2573 for (size_t i = 2; i < msgs[0].size(); ++i) 2574 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type()); 2575 2576 // NOTE: If we fail the above checks then it means that we probably didn't 2577 // load a big enough response to trigger the delay mechanism. 2578 2579 // Send some unexpected ACKs. 2580 for (size_t i = 0; i < 128; ++i) { 2581 ResourceHostMsg_DataReceived_ACK msg(1); 2582 bool msg_was_ok; 2583 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok); 2584 } 2585 2586 msgs[0].erase(msgs[0].begin()); 2587 msgs[0].erase(msgs[0].begin()); 2588 2589 // ACK all DataReceived messages until we find a RequestComplete message. 2590 bool complete = false; 2591 while (!complete) { 2592 for (size_t i = 0; i < msgs[0].size(); ++i) { 2593 if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) { 2594 complete = true; 2595 break; 2596 } 2597 2598 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type()); 2599 2600 ResourceHostMsg_DataReceived_ACK msg(1); 2601 bool msg_was_ok; 2602 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok); 2603 } 2604 2605 base::MessageLoop::current()->RunUntilIdle(); 2606 2607 msgs.clear(); 2608 accum_.GetClassifiedMessages(&msgs); 2609 } 2610 } 2611 2612 } // namespace content 2613