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/strings/string_number_conversions.h" 13 #include "base/strings/string_split.h" 14 #include "content/browser/browser_thread_impl.h" 15 #include "content/browser/child_process_security_policy_impl.h" 16 #include "content/browser/loader/resource_dispatcher_host_impl.h" 17 #include "content/browser/loader/resource_message_filter.h" 18 #include "content/browser/worker_host/worker_service_impl.h" 19 #include "content/common/child_process_host_impl.h" 20 #include "content/common/resource_messages.h" 21 #include "content/common/view_messages.h" 22 #include "content/public/browser/global_request_id.h" 23 #include "content/public/browser/resource_context.h" 24 #include "content/public/browser/resource_dispatcher_host_delegate.h" 25 #include "content/public/browser/resource_throttle.h" 26 #include "content/public/common/process_type.h" 27 #include "content/public/common/resource_response.h" 28 #include "content/public/test/test_browser_context.h" 29 #include "content/test/test_content_browser_client.h" 30 #include "net/base/net_errors.h" 31 #include "net/base/upload_bytes_element_reader.h" 32 #include "net/base/upload_data_stream.h" 33 #include "net/http/http_util.h" 34 #include "net/url_request/url_request.h" 35 #include "net/url_request/url_request_context.h" 36 #include "net/url_request/url_request_job.h" 37 #include "net/url_request/url_request_simple_job.h" 38 #include "net/url_request/url_request_test_job.h" 39 #include "testing/gtest/include/gtest/gtest.h" 40 #include "webkit/common/appcache/appcache_interfaces.h" 41 42 // TODO(eroman): Write unit tests for SafeBrowsing that exercise 43 // SafeBrowsingResourceHandler. 44 45 namespace content { 46 47 namespace { 48 49 // Returns the resource response header structure for this request. 50 void GetResponseHead(const std::vector<IPC::Message>& messages, 51 ResourceResponseHead* response_head) { 52 ASSERT_GE(messages.size(), 2U); 53 54 // The first messages should be received response. 55 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type()); 56 57 PickleIterator iter(messages[0]); 58 int request_id; 59 ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, &request_id)); 60 ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, response_head)); 61 } 62 63 void GenerateIPCMessage( 64 scoped_refptr<ResourceMessageFilter> filter, 65 scoped_ptr<IPC::Message> message) { 66 bool msg_is_ok; 67 ResourceDispatcherHostImpl::Get()->OnMessageReceived( 68 *message, filter.get(), &msg_is_ok); 69 } 70 71 } // namespace 72 73 static int RequestIDForMessage(const IPC::Message& msg) { 74 int request_id = -1; 75 switch (msg.type()) { 76 case ResourceMsg_UploadProgress::ID: 77 case ResourceMsg_ReceivedResponse::ID: 78 case ResourceMsg_ReceivedRedirect::ID: 79 case ResourceMsg_SetDataBuffer::ID: 80 case ResourceMsg_DataReceived::ID: 81 case ResourceMsg_RequestComplete::ID: { 82 bool result = PickleIterator(msg).ReadInt(&request_id); 83 DCHECK(result); 84 break; 85 } 86 } 87 return request_id; 88 } 89 90 static ResourceHostMsg_Request CreateResourceRequest( 91 const char* method, 92 ResourceType::Type type, 93 const GURL& url) { 94 ResourceHostMsg_Request request; 95 request.method = std::string(method); 96 request.url = url; 97 request.first_party_for_cookies = url; // bypass third-party cookie blocking 98 request.referrer_policy = WebKit::WebReferrerPolicyDefault; 99 request.load_flags = 0; 100 request.origin_pid = 0; 101 request.resource_type = type; 102 request.request_context = 0; 103 request.appcache_host_id = appcache::kNoHostId; 104 request.download_to_file = false; 105 request.is_main_frame = true; 106 request.frame_id = 0; 107 request.parent_is_main_frame = false; 108 request.parent_frame_id = -1; 109 request.transition_type = PAGE_TRANSITION_LINK; 110 request.allow_download = true; 111 return request; 112 } 113 114 // Spin up the message loop to kick off the request. 115 static void KickOffRequest() { 116 base::MessageLoop::current()->RunUntilIdle(); 117 } 118 119 // We may want to move this to a shared space if it is useful for something else 120 class ResourceIPCAccumulator { 121 public: 122 void AddMessage(const IPC::Message& msg) { 123 messages_.push_back(msg); 124 } 125 126 // This groups the messages by their request ID. The groups will be in order 127 // that the first message for each request ID was received, and the messages 128 // within the groups will be in the order that they appeared. 129 // Note that this clears messages_. 130 typedef std::vector< std::vector<IPC::Message> > ClassifiedMessages; 131 void GetClassifiedMessages(ClassifiedMessages* msgs); 132 133 private: 134 std::vector<IPC::Message> messages_; 135 }; 136 137 // This is very inefficient as a result of repeatedly extracting the ID, use 138 // only for tests! 139 void ResourceIPCAccumulator::GetClassifiedMessages(ClassifiedMessages* msgs) { 140 while (!messages_.empty()) { 141 // Ignore unknown message types as it is valid for code to generated other 142 // IPCs as side-effects that we are not testing here. 143 int cur_id = RequestIDForMessage(messages_[0]); 144 if (cur_id != -1) { 145 std::vector<IPC::Message> cur_requests; 146 cur_requests.push_back(messages_[0]); 147 // find all other messages with this ID 148 for (int i = 1; i < static_cast<int>(messages_.size()); i++) { 149 int id = RequestIDForMessage(messages_[i]); 150 if (id == cur_id) { 151 cur_requests.push_back(messages_[i]); 152 messages_.erase(messages_.begin() + i); 153 i--; 154 } 155 } 156 msgs->push_back(cur_requests); 157 } 158 messages_.erase(messages_.begin()); 159 } 160 } 161 162 class MockURLRequestContextSelector 163 : public ResourceMessageFilter::URLRequestContextSelector { 164 public: 165 explicit MockURLRequestContextSelector( 166 net::URLRequestContext* request_context) 167 : request_context_(request_context) {} 168 169 virtual net::URLRequestContext* GetRequestContext( 170 ResourceType::Type request_type) OVERRIDE { 171 return request_context_; 172 } 173 174 private: 175 net::URLRequestContext* const request_context_; 176 }; 177 178 // This class forwards the incoming messages to the ResourceDispatcherHostTest. 179 // This is used to emulate different sub-processes, since this filter will 180 // have a different ID than the original. For the test, we want all the incoming 181 // messages to go to the same place, which is why this forwards. 182 class ForwardingFilter : public ResourceMessageFilter { 183 public: 184 explicit ForwardingFilter(IPC::Sender* dest, 185 ResourceContext* resource_context) 186 : ResourceMessageFilter( 187 ChildProcessHostImpl::GenerateChildProcessUniqueId(), 188 PROCESS_TYPE_RENDERER, 189 resource_context, NULL, NULL, NULL, 190 new MockURLRequestContextSelector( 191 resource_context->GetRequestContext())), 192 dest_(dest) { 193 OnChannelConnected(base::GetCurrentProcId()); 194 } 195 196 // ResourceMessageFilter override 197 virtual bool Send(IPC::Message* msg) OVERRIDE { 198 if (!dest_) 199 return false; 200 return dest_->Send(msg); 201 } 202 203 protected: 204 virtual ~ForwardingFilter() {} 205 206 private: 207 IPC::Sender* dest_; 208 209 DISALLOW_COPY_AND_ASSIGN(ForwardingFilter); 210 }; 211 212 // This class is a variation on URLRequestTestJob in that it does 213 // not complete start upon entry, only when specifically told to. 214 class URLRequestTestDelayedStartJob : public net::URLRequestTestJob { 215 public: 216 URLRequestTestDelayedStartJob(net::URLRequest* request, 217 net::NetworkDelegate* network_delegate) 218 : net::URLRequestTestJob(request, network_delegate) { 219 Init(); 220 } 221 URLRequestTestDelayedStartJob(net::URLRequest* request, 222 net::NetworkDelegate* network_delegate, 223 bool auto_advance) 224 : net::URLRequestTestJob(request, network_delegate, auto_advance) { 225 Init(); 226 } 227 URLRequestTestDelayedStartJob(net::URLRequest* request, 228 net::NetworkDelegate* network_delegate, 229 const std::string& response_headers, 230 const std::string& response_data, 231 bool auto_advance) 232 : net::URLRequestTestJob(request, 233 network_delegate, 234 response_headers, 235 response_data, 236 auto_advance) { 237 Init(); 238 } 239 240 // Do nothing until you're told to. 241 virtual void Start() OVERRIDE {} 242 243 // Finish starting a URL request whose job is an instance of 244 // URLRequestTestDelayedStartJob. It is illegal to call this routine 245 // with a URLRequest that does not use URLRequestTestDelayedStartJob. 246 static void CompleteStart(net::URLRequest* request) { 247 for (URLRequestTestDelayedStartJob* job = list_head_; 248 job; 249 job = job->next_) { 250 if (job->request() == request) { 251 job->net::URLRequestTestJob::Start(); 252 return; 253 } 254 } 255 NOTREACHED(); 256 } 257 258 static bool DelayedStartQueueEmpty() { 259 return !list_head_; 260 } 261 262 static void ClearQueue() { 263 if (list_head_) { 264 LOG(ERROR) 265 << "Unreleased entries on URLRequestTestDelayedStartJob delay queue" 266 << "; may result in leaks."; 267 list_head_ = NULL; 268 } 269 } 270 271 protected: 272 virtual ~URLRequestTestDelayedStartJob() { 273 for (URLRequestTestDelayedStartJob** job = &list_head_; *job; 274 job = &(*job)->next_) { 275 if (*job == this) { 276 *job = (*job)->next_; 277 return; 278 } 279 } 280 NOTREACHED(); 281 } 282 283 private: 284 void Init() { 285 next_ = list_head_; 286 list_head_ = this; 287 } 288 289 static URLRequestTestDelayedStartJob* list_head_; 290 URLRequestTestDelayedStartJob* next_; 291 }; 292 293 URLRequestTestDelayedStartJob* 294 URLRequestTestDelayedStartJob::list_head_ = NULL; 295 296 // This class is a variation on URLRequestTestJob in that it 297 // returns IO_pending errors before every read, not just the first one. 298 class URLRequestTestDelayedCompletionJob : public net::URLRequestTestJob { 299 public: 300 URLRequestTestDelayedCompletionJob(net::URLRequest* request, 301 net::NetworkDelegate* network_delegate) 302 : net::URLRequestTestJob(request, network_delegate) {} 303 URLRequestTestDelayedCompletionJob(net::URLRequest* request, 304 net::NetworkDelegate* network_delegate, 305 bool auto_advance) 306 : net::URLRequestTestJob(request, network_delegate, auto_advance) {} 307 URLRequestTestDelayedCompletionJob(net::URLRequest* request, 308 net::NetworkDelegate* network_delegate, 309 const std::string& response_headers, 310 const std::string& response_data, 311 bool auto_advance) 312 : net::URLRequestTestJob(request, 313 network_delegate, 314 response_headers, 315 response_data, 316 auto_advance) {} 317 318 protected: 319 virtual ~URLRequestTestDelayedCompletionJob() {} 320 321 private: 322 virtual bool NextReadAsync() OVERRIDE { return true; } 323 }; 324 325 class URLRequestBigJob : public net::URLRequestSimpleJob { 326 public: 327 URLRequestBigJob(net::URLRequest* request, 328 net::NetworkDelegate* network_delegate) 329 : net::URLRequestSimpleJob(request, network_delegate) { 330 } 331 332 virtual int GetData(std::string* mime_type, 333 std::string* charset, 334 std::string* data, 335 const net::CompletionCallback& callback) const OVERRIDE { 336 *mime_type = "text/plain"; 337 *charset = "UTF-8"; 338 339 std::string text; 340 int count; 341 if (!ParseURL(request_->url(), &text, &count)) 342 return net::ERR_INVALID_URL; 343 344 data->reserve(text.size() * count); 345 for (int i = 0; i < count; ++i) 346 data->append(text); 347 348 return net::OK; 349 } 350 351 private: 352 virtual ~URLRequestBigJob() {} 353 354 // big-job:substring,N 355 static bool ParseURL(const GURL& url, std::string* text, int* count) { 356 std::vector<std::string> parts; 357 base::SplitString(url.path(), ',', &parts); 358 359 if (parts.size() != 2) 360 return false; 361 362 *text = parts[0]; 363 return base::StringToInt(parts[1], count); 364 } 365 }; 366 367 // Associated with an URLRequest to determine if the URLRequest gets deleted. 368 class TestUserData : public base::SupportsUserData::Data { 369 public: 370 explicit TestUserData(bool* was_deleted) 371 : was_deleted_(was_deleted) { 372 } 373 374 virtual ~TestUserData() { 375 *was_deleted_ = true; 376 } 377 378 private: 379 bool* was_deleted_; 380 }; 381 382 class TransfersAllNavigationsContentBrowserClient 383 : public TestContentBrowserClient { 384 public: 385 virtual bool ShouldSwapProcessesForRedirect(ResourceContext* resource_context, 386 const GURL& current_url, 387 const GURL& new_url) OVERRIDE { 388 return true; 389 } 390 }; 391 392 enum GenericResourceThrottleFlags { 393 NONE = 0, 394 DEFER_STARTING_REQUEST = 1 << 0, 395 DEFER_PROCESSING_RESPONSE = 1 << 1, 396 CANCEL_BEFORE_START = 1 << 2 397 }; 398 399 // Throttle that tracks the current throttle blocking a request. Only one 400 // can throttle any request at a time. 401 class GenericResourceThrottle : public ResourceThrottle { 402 public: 403 // The value is used to indicate that the throttle should not provide 404 // a error code when cancelling a request. net::OK is used, because this 405 // is not an error code. 406 static const int USE_DEFAULT_CANCEL_ERROR_CODE = net::OK; 407 408 GenericResourceThrottle(int flags, int code) 409 : flags_(flags), 410 error_code_for_cancellation_(code) { 411 } 412 413 virtual ~GenericResourceThrottle() { 414 if (active_throttle_ == this) 415 active_throttle_ = NULL; 416 } 417 418 // ResourceThrottle implementation: 419 virtual void WillStartRequest(bool* defer) OVERRIDE { 420 ASSERT_EQ(NULL, active_throttle_); 421 if (flags_ & DEFER_STARTING_REQUEST) { 422 active_throttle_ = this; 423 *defer = true; 424 } 425 426 if (flags_ & CANCEL_BEFORE_START) { 427 if (error_code_for_cancellation_ == USE_DEFAULT_CANCEL_ERROR_CODE) { 428 controller()->Cancel(); 429 } else { 430 controller()->CancelWithError(error_code_for_cancellation_); 431 } 432 } 433 } 434 435 virtual void WillProcessResponse(bool* defer) OVERRIDE { 436 ASSERT_EQ(NULL, active_throttle_); 437 if (flags_ & DEFER_PROCESSING_RESPONSE) { 438 active_throttle_ = this; 439 *defer = true; 440 } 441 } 442 443 void Resume() { 444 ASSERT_TRUE(this == active_throttle_); 445 active_throttle_ = NULL; 446 controller()->Resume(); 447 } 448 449 static GenericResourceThrottle* active_throttle() { 450 return active_throttle_; 451 } 452 453 private: 454 int flags_; // bit-wise union of GenericResourceThrottleFlags. 455 int error_code_for_cancellation_; 456 457 // The currently active throttle, if any. 458 static GenericResourceThrottle* active_throttle_; 459 }; 460 // static 461 GenericResourceThrottle* GenericResourceThrottle::active_throttle_ = NULL; 462 463 class TestResourceDispatcherHostDelegate 464 : public ResourceDispatcherHostDelegate { 465 public: 466 TestResourceDispatcherHostDelegate() 467 : create_two_throttles_(false), 468 flags_(NONE), 469 error_code_for_cancellation_( 470 GenericResourceThrottle::USE_DEFAULT_CANCEL_ERROR_CODE) { 471 } 472 473 void set_url_request_user_data(base::SupportsUserData::Data* user_data) { 474 user_data_.reset(user_data); 475 } 476 477 void set_flags(int value) { 478 flags_ = value; 479 } 480 481 void set_error_code_for_cancellation(int code) { 482 error_code_for_cancellation_ = code; 483 } 484 485 void set_create_two_throttles(bool create_two_throttles) { 486 create_two_throttles_ = create_two_throttles; 487 } 488 489 // ResourceDispatcherHostDelegate implementation: 490 491 virtual void RequestBeginning( 492 net::URLRequest* request, 493 ResourceContext* resource_context, 494 appcache::AppCacheService* appcache_service, 495 ResourceType::Type resource_type, 496 int child_id, 497 int route_id, 498 bool is_continuation_of_transferred_request, 499 ScopedVector<ResourceThrottle>* throttles) OVERRIDE { 500 if (user_data_) { 501 const void* key = user_data_.get(); 502 request->SetUserData(key, user_data_.release()); 503 } 504 505 if (flags_ != NONE) { 506 throttles->push_back(new GenericResourceThrottle( 507 flags_, error_code_for_cancellation_)); 508 if (create_two_throttles_) 509 throttles->push_back(new GenericResourceThrottle( 510 flags_, error_code_for_cancellation_)); 511 } 512 } 513 514 private: 515 bool create_two_throttles_; 516 int flags_; 517 int error_code_for_cancellation_; 518 scoped_ptr<base::SupportsUserData::Data> user_data_; 519 }; 520 521 class ResourceDispatcherHostTest : public testing::Test, 522 public IPC::Sender { 523 public: 524 ResourceDispatcherHostTest() 525 : ui_thread_(BrowserThread::UI, &message_loop_), 526 file_thread_(BrowserThread::FILE_USER_BLOCKING, &message_loop_), 527 cache_thread_(BrowserThread::CACHE, &message_loop_), 528 io_thread_(BrowserThread::IO, &message_loop_), 529 old_factory_(NULL), 530 resource_type_(ResourceType::SUB_RESOURCE), 531 send_data_received_acks_(false) { 532 browser_context_.reset(new TestBrowserContext()); 533 BrowserContext::EnsureResourceContextInitialized(browser_context_.get()); 534 message_loop_.RunUntilIdle(); 535 filter_ = new ForwardingFilter( 536 this, browser_context_->GetResourceContext()); 537 } 538 539 virtual ~ResourceDispatcherHostTest() { 540 for (std::set<int>::iterator it = child_ids_.begin(); 541 it != child_ids_.end(); ++it) { 542 host_.CancelRequestsForProcess(*it); 543 } 544 } 545 546 // IPC::Sender implementation 547 virtual bool Send(IPC::Message* msg) OVERRIDE { 548 accum_.AddMessage(*msg); 549 550 if (send_data_received_acks_ && 551 msg->type() == ResourceMsg_DataReceived::ID) { 552 GenerateDataReceivedACK(*msg); 553 } 554 555 delete msg; 556 return true; 557 } 558 559 protected: 560 // testing::Test 561 virtual void SetUp() { 562 DCHECK(!test_fixture_); 563 test_fixture_ = this; 564 ChildProcessSecurityPolicyImpl::GetInstance()->Add(0); 565 net::URLRequest::Deprecated::RegisterProtocolFactory( 566 "test", 567 &ResourceDispatcherHostTest::Factory); 568 EnsureTestSchemeIsAllowed(); 569 delay_start_ = false; 570 delay_complete_ = false; 571 url_request_jobs_created_count_ = 0; 572 } 573 574 virtual void TearDown() { 575 net::URLRequest::Deprecated::RegisterProtocolFactory("test", NULL); 576 if (!scheme_.empty()) 577 net::URLRequest::Deprecated::RegisterProtocolFactory( 578 scheme_, old_factory_); 579 580 EXPECT_TRUE(URLRequestTestDelayedStartJob::DelayedStartQueueEmpty()); 581 URLRequestTestDelayedStartJob::ClearQueue(); 582 583 DCHECK(test_fixture_ == this); 584 test_fixture_ = NULL; 585 586 host_.Shutdown(); 587 588 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(0); 589 590 // Flush the message loop to make application verifiers happy. 591 if (ResourceDispatcherHostImpl::Get()) 592 ResourceDispatcherHostImpl::Get()->CancelRequestsForContext( 593 browser_context_->GetResourceContext()); 594 595 WorkerServiceImpl::GetInstance()->PerformTeardownForTesting(); 596 597 browser_context_.reset(); 598 message_loop_.RunUntilIdle(); 599 } 600 601 // Creates a request using the current test object as the filter. 602 void MakeTestRequest(int render_view_id, 603 int request_id, 604 const GURL& url); 605 606 // Generates a request using the given filter. This will probably be a 607 // ForwardingFilter. 608 void MakeTestRequest(ResourceMessageFilter* filter, 609 int render_view_id, 610 int request_id, 611 const GURL& url); 612 613 void CancelRequest(int request_id); 614 615 void CompleteStartRequest(int request_id); 616 void CompleteStartRequest(ResourceMessageFilter* filter, int request_id); 617 618 void EnsureSchemeIsAllowed(const std::string& scheme) { 619 ChildProcessSecurityPolicyImpl* policy = 620 ChildProcessSecurityPolicyImpl::GetInstance(); 621 if (!policy->IsWebSafeScheme(scheme)) 622 policy->RegisterWebSafeScheme(scheme); 623 } 624 625 void EnsureTestSchemeIsAllowed() { 626 EnsureSchemeIsAllowed("test"); 627 } 628 629 // Sets a particular response for any request from now on. To switch back to 630 // the default bahavior, pass an empty |headers|. |headers| should be raw- 631 // formatted (NULLs instead of EOLs). 632 void SetResponse(const std::string& headers, const std::string& data) { 633 response_headers_ = net::HttpUtil::AssembleRawHeaders(headers.data(), 634 headers.size()); 635 response_data_ = data; 636 } 637 void SetResponse(const std::string& headers) { 638 SetResponse(headers, std::string()); 639 } 640 641 // Sets a particular resource type for any request from now on. 642 void SetResourceType(ResourceType::Type type) { 643 resource_type_ = type; 644 } 645 646 void SendDataReceivedACKs(bool send_acks) { 647 send_data_received_acks_ = send_acks; 648 } 649 650 // Intercepts requests for the given protocol. 651 void HandleScheme(const std::string& scheme) { 652 DCHECK(scheme_.empty()); 653 DCHECK(!old_factory_); 654 scheme_ = scheme; 655 old_factory_ = net::URLRequest::Deprecated::RegisterProtocolFactory( 656 scheme_, &ResourceDispatcherHostTest::Factory); 657 EnsureSchemeIsAllowed(scheme); 658 } 659 660 // Our own net::URLRequestJob factory. 661 static net::URLRequestJob* Factory(net::URLRequest* request, 662 net::NetworkDelegate* network_delegate, 663 const std::string& scheme) { 664 url_request_jobs_created_count_++; 665 if (test_fixture_->response_headers_.empty()) { 666 if (delay_start_) { 667 return new URLRequestTestDelayedStartJob(request, network_delegate); 668 } else if (delay_complete_) { 669 return new URLRequestTestDelayedCompletionJob(request, 670 network_delegate); 671 } else if (scheme == "big-job") { 672 return new URLRequestBigJob(request, network_delegate); 673 } else { 674 return new net::URLRequestTestJob(request, network_delegate); 675 } 676 } else { 677 if (delay_start_) { 678 return new URLRequestTestDelayedStartJob( 679 request, network_delegate, 680 test_fixture_->response_headers_, test_fixture_->response_data_, 681 false); 682 } else if (delay_complete_) { 683 return new URLRequestTestDelayedCompletionJob( 684 request, network_delegate, 685 test_fixture_->response_headers_, test_fixture_->response_data_, 686 false); 687 } else { 688 return new net::URLRequestTestJob( 689 request, network_delegate, 690 test_fixture_->response_headers_, test_fixture_->response_data_, 691 false); 692 } 693 } 694 } 695 696 void SetDelayedStartJobGeneration(bool delay_job_start) { 697 delay_start_ = delay_job_start; 698 } 699 700 void SetDelayedCompleteJobGeneration(bool delay_job_complete) { 701 delay_complete_ = delay_job_complete; 702 } 703 704 void GenerateDataReceivedACK(const IPC::Message& msg) { 705 EXPECT_EQ(ResourceMsg_DataReceived::ID, msg.type()); 706 707 int request_id = -1; 708 bool result = PickleIterator(msg).ReadInt(&request_id); 709 DCHECK(result); 710 scoped_ptr<IPC::Message> ack( 711 new ResourceHostMsg_DataReceived_ACK(msg.routing_id(), request_id)); 712 713 base::MessageLoop::current()->PostTask( 714 FROM_HERE, 715 base::Bind(&GenerateIPCMessage, filter_, base::Passed(&ack))); 716 } 717 718 base::MessageLoopForIO message_loop_; 719 BrowserThreadImpl ui_thread_; 720 BrowserThreadImpl file_thread_; 721 BrowserThreadImpl cache_thread_; 722 BrowserThreadImpl io_thread_; 723 scoped_ptr<TestBrowserContext> browser_context_; 724 scoped_refptr<ForwardingFilter> filter_; 725 ResourceDispatcherHostImpl host_; 726 ResourceIPCAccumulator accum_; 727 std::string response_headers_; 728 std::string response_data_; 729 std::string scheme_; 730 net::URLRequest::ProtocolFactory* old_factory_; 731 ResourceType::Type resource_type_; 732 bool send_data_received_acks_; 733 std::set<int> child_ids_; 734 static ResourceDispatcherHostTest* test_fixture_; 735 static bool delay_start_; 736 static bool delay_complete_; 737 static int url_request_jobs_created_count_; 738 }; 739 // Static. 740 ResourceDispatcherHostTest* ResourceDispatcherHostTest::test_fixture_ = NULL; 741 bool ResourceDispatcherHostTest::delay_start_ = false; 742 bool ResourceDispatcherHostTest::delay_complete_ = false; 743 int ResourceDispatcherHostTest::url_request_jobs_created_count_ = 0; 744 745 void ResourceDispatcherHostTest::MakeTestRequest(int render_view_id, 746 int request_id, 747 const GURL& url) { 748 MakeTestRequest(filter_.get(), render_view_id, request_id, url); 749 } 750 751 void ResourceDispatcherHostTest::MakeTestRequest( 752 ResourceMessageFilter* filter, 753 int render_view_id, 754 int request_id, 755 const GURL& url) { 756 // If it's already there, this'll be dropped on the floor, which is fine. 757 child_ids_.insert(filter->child_id()); 758 759 ResourceHostMsg_Request request = 760 CreateResourceRequest("GET", resource_type_, url); 761 ResourceHostMsg_RequestResource msg(render_view_id, request_id, request); 762 bool msg_was_ok; 763 host_.OnMessageReceived(msg, filter, &msg_was_ok); 764 KickOffRequest(); 765 } 766 767 void ResourceDispatcherHostTest::CancelRequest(int request_id) { 768 host_.CancelRequest(filter_->child_id(), request_id, false); 769 } 770 771 void ResourceDispatcherHostTest::CompleteStartRequest(int request_id) { 772 CompleteStartRequest(filter_.get(), request_id); 773 } 774 775 void ResourceDispatcherHostTest::CompleteStartRequest( 776 ResourceMessageFilter* filter, 777 int request_id) { 778 GlobalRequestID gid(filter->child_id(), request_id); 779 net::URLRequest* req = host_.GetURLRequest(gid); 780 EXPECT_TRUE(req); 781 if (req) 782 URLRequestTestDelayedStartJob::CompleteStart(req); 783 } 784 785 void CheckSuccessfulRequest(const std::vector<IPC::Message>& messages, 786 const std::string& reference_data) { 787 // A successful request will have received 4 messages: 788 // ReceivedResponse (indicates headers received) 789 // SetDataBuffer (contains shared memory handle) 790 // DataReceived (data offset and length into shared memory) 791 // RequestComplete (request is done) 792 // 793 // This function verifies that we received 4 messages and that they 794 // are appropriate. 795 ASSERT_EQ(4U, messages.size()); 796 797 // The first messages should be received response 798 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type()); 799 800 ASSERT_EQ(ResourceMsg_SetDataBuffer::ID, messages[1].type()); 801 802 PickleIterator iter(messages[1]); 803 int request_id; 804 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &request_id)); 805 base::SharedMemoryHandle shm_handle; 806 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_handle)); 807 int shm_size; 808 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_size)); 809 810 // Followed by the data, currently we only do the data in one chunk, but 811 // should probably test multiple chunks later 812 ASSERT_EQ(ResourceMsg_DataReceived::ID, messages[2].type()); 813 814 PickleIterator iter2(messages[2]); 815 ASSERT_TRUE(IPC::ReadParam(&messages[2], &iter2, &request_id)); 816 int data_offset; 817 ASSERT_TRUE(IPC::ReadParam(&messages[2], &iter2, &data_offset)); 818 int data_length; 819 ASSERT_TRUE(IPC::ReadParam(&messages[2], &iter2, &data_length)); 820 821 ASSERT_EQ(reference_data.size(), static_cast<size_t>(data_length)); 822 ASSERT_GE(shm_size, data_length); 823 824 base::SharedMemory shared_mem(shm_handle, true); // read only 825 shared_mem.Map(data_length); 826 const char* data = static_cast<char*>(shared_mem.memory()) + data_offset; 827 ASSERT_EQ(0, memcmp(reference_data.c_str(), data, data_length)); 828 829 // The last message should be all data received. 830 ASSERT_EQ(ResourceMsg_RequestComplete::ID, messages[3].type()); 831 } 832 833 void CheckFailedRequest(const std::vector<IPC::Message>& messages, 834 const std::string& reference_data, 835 int expected_error) { 836 ASSERT_LT(0U, messages.size()); 837 ASSERT_GE(2U, messages.size()); 838 size_t failure_index = messages.size() - 1; 839 840 if (messages.size() == 2) { 841 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type()); 842 } 843 EXPECT_EQ(ResourceMsg_RequestComplete::ID, messages[failure_index].type()); 844 845 int request_id; 846 int error_code; 847 848 PickleIterator iter(messages[failure_index]); 849 EXPECT_TRUE(IPC::ReadParam(&messages[failure_index], &iter, &request_id)); 850 EXPECT_TRUE(IPC::ReadParam(&messages[failure_index], &iter, &error_code)); 851 EXPECT_EQ(expected_error, error_code); 852 } 853 854 // Tests whether many messages get dispatched properly. 855 TEST_F(ResourceDispatcherHostTest, TestMany) { 856 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); 857 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2()); 858 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3()); 859 860 // flush all the pending requests 861 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 862 863 // sorts out all the messages we saw by request 864 ResourceIPCAccumulator::ClassifiedMessages msgs; 865 accum_.GetClassifiedMessages(&msgs); 866 867 // there are three requests, so we should have gotten them classified as such 868 ASSERT_EQ(3U, msgs.size()); 869 870 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); 871 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_2()); 872 CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3()); 873 } 874 875 void CheckCancelledRequestCompleteMessage(const IPC::Message& message) { 876 ASSERT_EQ(ResourceMsg_RequestComplete::ID, message.type()); 877 878 int request_id; 879 int error_code; 880 881 PickleIterator iter(message); 882 ASSERT_TRUE(IPC::ReadParam(&message, &iter, &request_id)); 883 ASSERT_TRUE(IPC::ReadParam(&message, &iter, &error_code)); 884 885 EXPECT_EQ(net::ERR_ABORTED, error_code); 886 } 887 888 // Tests whether messages get canceled properly. We issue three requests, 889 // cancel one of them, and make sure that each sent the proper notifications. 890 TEST_F(ResourceDispatcherHostTest, Cancel) { 891 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); 892 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2()); 893 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3()); 894 CancelRequest(2); 895 896 // flush all the pending requests 897 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 898 base::MessageLoop::current()->RunUntilIdle(); 899 900 ResourceIPCAccumulator::ClassifiedMessages msgs; 901 accum_.GetClassifiedMessages(&msgs); 902 903 // there are three requests, so we should have gotten them classified as such 904 ASSERT_EQ(3U, msgs.size()); 905 906 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); 907 CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3()); 908 909 // Check that request 2 got canceled. 910 ASSERT_EQ(2U, msgs[1].size()); 911 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type()); 912 CheckCancelledRequestCompleteMessage(msgs[1][1]); 913 } 914 915 TEST_F(ResourceDispatcherHostTest, CancelWhileStartIsDeferred) { 916 bool was_deleted = false; 917 918 // Arrange to have requests deferred before starting. 919 TestResourceDispatcherHostDelegate delegate; 920 delegate.set_flags(DEFER_STARTING_REQUEST); 921 delegate.set_url_request_user_data(new TestUserData(&was_deleted)); 922 host_.SetDelegate(&delegate); 923 924 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); 925 CancelRequest(1); 926 927 // Our TestResourceThrottle should not have been deleted yet. This is to 928 // ensure that destruction of the URLRequest happens asynchronously to 929 // calling CancelRequest. 930 EXPECT_FALSE(was_deleted); 931 932 // flush all the pending requests 933 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 934 base::MessageLoop::current()->RunUntilIdle(); 935 936 EXPECT_TRUE(was_deleted); 937 } 938 939 // Tests if cancel is called in ResourceThrottle::WillStartRequest, then the 940 // URLRequest will not be started. 941 TEST_F(ResourceDispatcherHostTest, CancelInResourceThrottleWillStartRequest) { 942 TestResourceDispatcherHostDelegate delegate; 943 delegate.set_flags(CANCEL_BEFORE_START); 944 host_.SetDelegate(&delegate); 945 946 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); 947 948 // flush all the pending requests 949 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 950 base::MessageLoop::current()->RunUntilIdle(); 951 952 ResourceIPCAccumulator::ClassifiedMessages msgs; 953 accum_.GetClassifiedMessages(&msgs); 954 955 // Check that request got canceled. 956 ASSERT_EQ(1U, msgs[0].size()); 957 CheckCancelledRequestCompleteMessage(msgs[0][0]); 958 959 // Make sure URLRequest is never started. 960 EXPECT_EQ(0, url_request_jobs_created_count_); 961 } 962 963 TEST_F(ResourceDispatcherHostTest, PausedStartError) { 964 // Arrange to have requests deferred before processing response headers. 965 TestResourceDispatcherHostDelegate delegate; 966 delegate.set_flags(DEFER_PROCESSING_RESPONSE); 967 host_.SetDelegate(&delegate); 968 969 SetDelayedStartJobGeneration(true); 970 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_error()); 971 CompleteStartRequest(1); 972 973 // flush all the pending requests 974 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 975 base::MessageLoop::current()->RunUntilIdle(); 976 977 EXPECT_EQ(0, host_.pending_requests()); 978 } 979 980 TEST_F(ResourceDispatcherHostTest, ThrottleAndResumeTwice) { 981 // Arrange to have requests deferred before starting. 982 TestResourceDispatcherHostDelegate delegate; 983 delegate.set_flags(DEFER_STARTING_REQUEST); 984 delegate.set_create_two_throttles(true); 985 host_.SetDelegate(&delegate); 986 987 // Make sure the first throttle blocked the request, and then resume. 988 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); 989 GenericResourceThrottle* first_throttle = 990 GenericResourceThrottle::active_throttle(); 991 ASSERT_TRUE(first_throttle); 992 first_throttle->Resume(); 993 994 // Make sure the second throttle blocked the request, and then resume. 995 ASSERT_TRUE(GenericResourceThrottle::active_throttle()); 996 ASSERT_NE(first_throttle, GenericResourceThrottle::active_throttle()); 997 GenericResourceThrottle::active_throttle()->Resume(); 998 999 ASSERT_FALSE(GenericResourceThrottle::active_throttle()); 1000 1001 // The request is started asynchronously. 1002 base::MessageLoop::current()->RunUntilIdle(); 1003 1004 // Flush all the pending requests. 1005 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1006 1007 EXPECT_EQ(0, host_.pending_requests()); 1008 1009 // Make sure the request completed successfully. 1010 ResourceIPCAccumulator::ClassifiedMessages msgs; 1011 accum_.GetClassifiedMessages(&msgs); 1012 ASSERT_EQ(1U, msgs.size()); 1013 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); 1014 } 1015 1016 1017 // Tests that the delegate can cancel a request and provide a error code. 1018 TEST_F(ResourceDispatcherHostTest, CancelInDelegate) { 1019 TestResourceDispatcherHostDelegate delegate; 1020 delegate.set_flags(CANCEL_BEFORE_START); 1021 delegate.set_error_code_for_cancellation(net::ERR_ACCESS_DENIED); 1022 host_.SetDelegate(&delegate); 1023 1024 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); 1025 // The request will get cancelled by the throttle. 1026 1027 // flush all the pending requests 1028 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1029 base::MessageLoop::current()->RunUntilIdle(); 1030 1031 ResourceIPCAccumulator::ClassifiedMessages msgs; 1032 accum_.GetClassifiedMessages(&msgs); 1033 1034 // Check the cancellation 1035 ASSERT_EQ(1U, msgs.size()); 1036 ASSERT_EQ(1U, msgs[0].size()); 1037 ASSERT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type()); 1038 1039 int request_id; 1040 int error_code; 1041 1042 PickleIterator iter(msgs[0][0]); 1043 ASSERT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &request_id)); 1044 ASSERT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &error_code)); 1045 1046 EXPECT_EQ(net::ERR_ACCESS_DENIED, error_code); 1047 } 1048 1049 // The host delegate acts as a second one so we can have some requests 1050 // pending and some canceled. 1051 class TestFilter : public ForwardingFilter { 1052 public: 1053 explicit TestFilter(ResourceContext* resource_context) 1054 : ForwardingFilter(NULL, resource_context), 1055 has_canceled_(false), 1056 received_after_canceled_(0) { 1057 } 1058 1059 // ForwardingFilter override 1060 virtual bool Send(IPC::Message* msg) OVERRIDE { 1061 // no messages should be received when the process has been canceled 1062 if (has_canceled_) 1063 received_after_canceled_++; 1064 delete msg; 1065 return true; 1066 } 1067 1068 bool has_canceled_; 1069 int received_after_canceled_; 1070 1071 private: 1072 virtual ~TestFilter() {} 1073 }; 1074 1075 // Tests CancelRequestsForProcess 1076 TEST_F(ResourceDispatcherHostTest, TestProcessCancel) { 1077 scoped_refptr<TestFilter> test_filter = new TestFilter( 1078 browser_context_->GetResourceContext()); 1079 1080 // request 1 goes to the test delegate 1081 ResourceHostMsg_Request request = CreateResourceRequest( 1082 "GET", ResourceType::SUB_RESOURCE, net::URLRequestTestJob::test_url_1()); 1083 1084 MakeTestRequest(test_filter.get(), 0, 1, 1085 net::URLRequestTestJob::test_url_1()); 1086 1087 // request 2 goes to us 1088 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2()); 1089 1090 // request 3 goes to the test delegate 1091 MakeTestRequest(test_filter.get(), 0, 3, 1092 net::URLRequestTestJob::test_url_3()); 1093 1094 // Make sure all requests have finished stage one. test_url_1 will have 1095 // finished. 1096 base::MessageLoop::current()->RunUntilIdle(); 1097 1098 // TODO(mbelshe): 1099 // Now that the async IO path is in place, the IO always completes on the 1100 // initial call; so the requests have already completed. This basically 1101 // breaks the whole test. 1102 //EXPECT_EQ(3, host_.pending_requests()); 1103 1104 // Process each request for one level so one callback is called. 1105 for (int i = 0; i < 2; i++) 1106 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage()); 1107 1108 // Cancel the requests to the test process. 1109 host_.CancelRequestsForProcess(filter_->child_id()); 1110 test_filter->has_canceled_ = true; 1111 1112 // Flush all the pending requests. 1113 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1114 1115 EXPECT_EQ(0, host_.pending_requests()); 1116 1117 // The test delegate should not have gotten any messages after being canceled. 1118 ASSERT_EQ(0, test_filter->received_after_canceled_); 1119 1120 // We should have gotten exactly one result. 1121 ResourceIPCAccumulator::ClassifiedMessages msgs; 1122 accum_.GetClassifiedMessages(&msgs); 1123 ASSERT_EQ(1U, msgs.size()); 1124 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2()); 1125 } 1126 1127 // Tests blocking and resuming requests. 1128 TEST_F(ResourceDispatcherHostTest, TestBlockingResumingRequests) { 1129 host_.BlockRequestsForRoute(filter_->child_id(), 1); 1130 host_.BlockRequestsForRoute(filter_->child_id(), 2); 1131 host_.BlockRequestsForRoute(filter_->child_id(), 3); 1132 1133 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); 1134 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2()); 1135 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3()); 1136 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1()); 1137 MakeTestRequest(2, 5, net::URLRequestTestJob::test_url_2()); 1138 MakeTestRequest(3, 6, net::URLRequestTestJob::test_url_3()); 1139 1140 // Flush all the pending requests 1141 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1142 1143 // Sort out all the messages we saw by request 1144 ResourceIPCAccumulator::ClassifiedMessages msgs; 1145 accum_.GetClassifiedMessages(&msgs); 1146 1147 // All requests but the 2 for the RVH 0 should have been blocked. 1148 ASSERT_EQ(2U, msgs.size()); 1149 1150 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); 1151 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3()); 1152 1153 // Resume requests for RVH 1 and flush pending requests. 1154 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 1); 1155 KickOffRequest(); 1156 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1157 1158 msgs.clear(); 1159 accum_.GetClassifiedMessages(&msgs); 1160 ASSERT_EQ(2U, msgs.size()); 1161 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2()); 1162 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_1()); 1163 1164 // Test that new requests are not blocked for RVH 1. 1165 MakeTestRequest(1, 7, net::URLRequestTestJob::test_url_1()); 1166 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1167 msgs.clear(); 1168 accum_.GetClassifiedMessages(&msgs); 1169 ASSERT_EQ(1U, msgs.size()); 1170 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); 1171 1172 // Now resumes requests for all RVH (2 and 3). 1173 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 2); 1174 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 3); 1175 KickOffRequest(); 1176 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1177 1178 msgs.clear(); 1179 accum_.GetClassifiedMessages(&msgs); 1180 ASSERT_EQ(2U, msgs.size()); 1181 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2()); 1182 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3()); 1183 } 1184 1185 // Tests blocking and canceling requests. 1186 TEST_F(ResourceDispatcherHostTest, TestBlockingCancelingRequests) { 1187 host_.BlockRequestsForRoute(filter_->child_id(), 1); 1188 1189 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); 1190 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2()); 1191 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3()); 1192 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1()); 1193 1194 // Flush all the pending requests. 1195 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1196 1197 // Sort out all the messages we saw by request. 1198 ResourceIPCAccumulator::ClassifiedMessages msgs; 1199 accum_.GetClassifiedMessages(&msgs); 1200 1201 // The 2 requests for the RVH 0 should have been processed. 1202 ASSERT_EQ(2U, msgs.size()); 1203 1204 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); 1205 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3()); 1206 1207 // Cancel requests for RVH 1. 1208 host_.CancelBlockedRequestsForRoute(filter_->child_id(), 1); 1209 KickOffRequest(); 1210 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1211 1212 msgs.clear(); 1213 accum_.GetClassifiedMessages(&msgs); 1214 ASSERT_EQ(0U, msgs.size()); 1215 } 1216 1217 // Tests that blocked requests are canceled if their associated process dies. 1218 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) { 1219 // This second filter is used to emulate a second process. 1220 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( 1221 this, browser_context_->GetResourceContext()); 1222 1223 host_.BlockRequestsForRoute(second_filter->child_id(), 0); 1224 1225 MakeTestRequest(filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1()); 1226 MakeTestRequest(second_filter.get(), 0, 2, 1227 net::URLRequestTestJob::test_url_2()); 1228 MakeTestRequest(filter_.get(), 0, 3, net::URLRequestTestJob::test_url_3()); 1229 MakeTestRequest(second_filter.get(), 0, 4, 1230 net::URLRequestTestJob::test_url_1()); 1231 1232 // Simulate process death. 1233 host_.CancelRequestsForProcess(second_filter->child_id()); 1234 1235 // Flush all the pending requests. 1236 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1237 1238 // Sort out all the messages we saw by request. 1239 ResourceIPCAccumulator::ClassifiedMessages msgs; 1240 accum_.GetClassifiedMessages(&msgs); 1241 1242 // The 2 requests for the RVH 0 should have been processed. 1243 ASSERT_EQ(2U, msgs.size()); 1244 1245 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); 1246 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3()); 1247 1248 EXPECT_TRUE(host_.blocked_loaders_map_.empty()); 1249 } 1250 1251 // Tests that blocked requests don't leak when the ResourceDispatcherHost goes 1252 // away. Note that we rely on Purify for finding the leaks if any. 1253 // If this test turns the Purify bot red, check the ResourceDispatcherHost 1254 // destructor to make sure the blocked requests are deleted. 1255 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) { 1256 // This second filter is used to emulate a second process. 1257 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( 1258 this, browser_context_->GetResourceContext()); 1259 1260 host_.BlockRequestsForRoute(filter_->child_id(), 1); 1261 host_.BlockRequestsForRoute(filter_->child_id(), 2); 1262 host_.BlockRequestsForRoute(second_filter->child_id(), 1); 1263 1264 MakeTestRequest(filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1()); 1265 MakeTestRequest(filter_.get(), 1, 2, net::URLRequestTestJob::test_url_2()); 1266 MakeTestRequest(filter_.get(), 0, 3, net::URLRequestTestJob::test_url_3()); 1267 MakeTestRequest(second_filter.get(), 1, 4, 1268 net::URLRequestTestJob::test_url_1()); 1269 MakeTestRequest(filter_.get(), 2, 5, net::URLRequestTestJob::test_url_2()); 1270 MakeTestRequest(filter_.get(), 2, 6, net::URLRequestTestJob::test_url_3()); 1271 1272 host_.CancelRequestsForProcess(filter_->child_id()); 1273 host_.CancelRequestsForProcess(second_filter->child_id()); 1274 1275 // Flush all the pending requests. 1276 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1277 } 1278 1279 // Test the private helper method "CalculateApproximateMemoryCost()". 1280 TEST_F(ResourceDispatcherHostTest, CalculateApproximateMemoryCost) { 1281 net::URLRequestContext context; 1282 net::URLRequest req(GURL("http://www.google.com"), NULL, &context); 1283 EXPECT_EQ(4427, 1284 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req)); 1285 1286 // Add 9 bytes of referrer. 1287 req.SetReferrer("123456789"); 1288 EXPECT_EQ(4436, 1289 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req)); 1290 1291 // Add 33 bytes of upload content. 1292 std::string upload_content; 1293 upload_content.resize(33); 1294 std::fill(upload_content.begin(), upload_content.end(), 'x'); 1295 scoped_ptr<net::UploadElementReader> reader(new net::UploadBytesElementReader( 1296 upload_content.data(), upload_content.size())); 1297 req.set_upload(make_scoped_ptr( 1298 net::UploadDataStream::CreateWithReader(reader.Pass(), 0))); 1299 1300 // Since the upload throttling is disabled, this has no effect on the cost. 1301 EXPECT_EQ(4436, 1302 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req)); 1303 } 1304 1305 // Test that too much memory for outstanding requests for a particular 1306 // render_process_host_id causes requests to fail. 1307 TEST_F(ResourceDispatcherHostTest, TooMuchOutstandingRequestsMemory) { 1308 // Expected cost of each request as measured by 1309 // ResourceDispatcherHost::CalculateApproximateMemoryCost(). 1310 int kMemoryCostOfTest2Req = 1311 ResourceDispatcherHostImpl::kAvgBytesPerOutstandingRequest + 1312 std::string("GET").size() + 1313 net::URLRequestTestJob::test_url_2().spec().size(); 1314 1315 // Tighten the bound on the ResourceDispatcherHost, to speed things up. 1316 int kMaxCostPerProcess = 440000; 1317 host_.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess); 1318 1319 // Determine how many instance of test_url_2() we can request before 1320 // throttling kicks in. 1321 size_t kMaxRequests = kMaxCostPerProcess / kMemoryCostOfTest2Req; 1322 1323 // This second filter is used to emulate a second process. 1324 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( 1325 this, browser_context_->GetResourceContext()); 1326 1327 // Saturate the number of outstanding requests for our process. 1328 for (size_t i = 0; i < kMaxRequests; ++i) { 1329 MakeTestRequest(filter_.get(), 0, i + 1, 1330 net::URLRequestTestJob::test_url_2()); 1331 } 1332 1333 // Issue two more requests for our process -- these should fail immediately. 1334 MakeTestRequest(filter_.get(), 0, kMaxRequests + 1, 1335 net::URLRequestTestJob::test_url_2()); 1336 MakeTestRequest(filter_.get(), 0, kMaxRequests + 2, 1337 net::URLRequestTestJob::test_url_2()); 1338 1339 // Issue two requests for the second process -- these should succeed since 1340 // it is just process 0 that is saturated. 1341 MakeTestRequest(second_filter.get(), 0, kMaxRequests + 3, 1342 net::URLRequestTestJob::test_url_2()); 1343 MakeTestRequest(second_filter.get(), 0, kMaxRequests + 4, 1344 net::URLRequestTestJob::test_url_2()); 1345 1346 // Flush all the pending requests. 1347 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1348 base::MessageLoop::current()->RunUntilIdle(); 1349 1350 // Sorts out all the messages we saw by request. 1351 ResourceIPCAccumulator::ClassifiedMessages msgs; 1352 accum_.GetClassifiedMessages(&msgs); 1353 1354 // We issued (kMaxRequests + 4) total requests. 1355 ASSERT_EQ(kMaxRequests + 4, msgs.size()); 1356 1357 // Check that the first kMaxRequests succeeded. 1358 for (size_t i = 0; i < kMaxRequests; ++i) 1359 CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2()); 1360 1361 // Check that the subsequent two requests (kMaxRequests + 1) and 1362 // (kMaxRequests + 2) were failed, since the per-process bound was reached. 1363 for (int i = 0; i < 2; ++i) { 1364 // Should have sent a single RequestComplete message. 1365 int index = kMaxRequests + i; 1366 CheckFailedRequest(msgs[index], net::URLRequestTestJob::test_data_2(), 1367 net::ERR_INSUFFICIENT_RESOURCES); 1368 } 1369 1370 // The final 2 requests should have succeeded. 1371 CheckSuccessfulRequest(msgs[kMaxRequests + 2], 1372 net::URLRequestTestJob::test_data_2()); 1373 CheckSuccessfulRequest(msgs[kMaxRequests + 3], 1374 net::URLRequestTestJob::test_data_2()); 1375 } 1376 1377 // Test that when too many requests are outstanding for a particular 1378 // render_process_host_id, any subsequent request from it fails. Also verify 1379 // that the global limit is honored. 1380 TEST_F(ResourceDispatcherHostTest, TooManyOutstandingRequests) { 1381 // Tighten the bound on the ResourceDispatcherHost, to speed things up. 1382 const size_t kMaxRequestsPerProcess = 2; 1383 host_.set_max_num_in_flight_requests_per_process(kMaxRequestsPerProcess); 1384 const size_t kMaxRequests = 3; 1385 host_.set_max_num_in_flight_requests(kMaxRequests); 1386 1387 // Needed to emulate additional processes. 1388 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( 1389 this, browser_context_->GetResourceContext()); 1390 scoped_refptr<ForwardingFilter> third_filter = new ForwardingFilter( 1391 this, browser_context_->GetResourceContext()); 1392 1393 // Saturate the number of outstanding requests for our process. 1394 for (size_t i = 0; i < kMaxRequestsPerProcess; ++i) { 1395 MakeTestRequest(filter_.get(), 0, i + 1, 1396 net::URLRequestTestJob::test_url_2()); 1397 } 1398 1399 // Issue another request for our process -- this should fail immediately. 1400 MakeTestRequest(filter_.get(), 0, kMaxRequestsPerProcess + 1, 1401 net::URLRequestTestJob::test_url_2()); 1402 1403 // Issue a request for the second process -- this should succeed, because it 1404 // is just process 0 that is saturated. 1405 MakeTestRequest(second_filter.get(), 0, kMaxRequestsPerProcess + 2, 1406 net::URLRequestTestJob::test_url_2()); 1407 1408 // Issue a request for the third process -- this should fail, because the 1409 // global limit has been reached. 1410 MakeTestRequest(third_filter.get(), 0, kMaxRequestsPerProcess + 3, 1411 net::URLRequestTestJob::test_url_2()); 1412 1413 // Flush all the pending requests. 1414 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1415 base::MessageLoop::current()->RunUntilIdle(); 1416 1417 // Sorts out all the messages we saw by request. 1418 ResourceIPCAccumulator::ClassifiedMessages msgs; 1419 accum_.GetClassifiedMessages(&msgs); 1420 1421 // The processes issued the following requests: 1422 // #1 issued kMaxRequestsPerProcess that passed + 1 that failed 1423 // #2 issued 1 request that passed 1424 // #3 issued 1 request that failed 1425 ASSERT_EQ((kMaxRequestsPerProcess + 1) + 1 + 1, msgs.size()); 1426 1427 for (size_t i = 0; i < kMaxRequestsPerProcess; ++i) 1428 CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2()); 1429 1430 CheckFailedRequest(msgs[kMaxRequestsPerProcess + 0], 1431 net::URLRequestTestJob::test_data_2(), 1432 net::ERR_INSUFFICIENT_RESOURCES); 1433 CheckSuccessfulRequest(msgs[kMaxRequestsPerProcess + 1], 1434 net::URLRequestTestJob::test_data_2()); 1435 CheckFailedRequest(msgs[kMaxRequestsPerProcess + 2], 1436 net::URLRequestTestJob::test_data_2(), 1437 net::ERR_INSUFFICIENT_RESOURCES); 1438 } 1439 1440 // Tests that we sniff the mime type for a simple request. 1441 TEST_F(ResourceDispatcherHostTest, MimeSniffed) { 1442 std::string raw_headers("HTTP/1.1 200 OK\n\n"); 1443 std::string response_data("<html><title>Test One</title></html>"); 1444 SetResponse(raw_headers, response_data); 1445 1446 HandleScheme("http"); 1447 MakeTestRequest(0, 1, GURL("http:bla")); 1448 1449 // Flush all pending requests. 1450 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1451 1452 // Sorts out all the messages we saw by request. 1453 ResourceIPCAccumulator::ClassifiedMessages msgs; 1454 accum_.GetClassifiedMessages(&msgs); 1455 ASSERT_EQ(1U, msgs.size()); 1456 1457 ResourceResponseHead response_head; 1458 GetResponseHead(msgs[0], &response_head); 1459 ASSERT_EQ("text/html", response_head.mime_type); 1460 } 1461 1462 // Tests that we don't sniff the mime type when the server provides one. 1463 TEST_F(ResourceDispatcherHostTest, MimeNotSniffed) { 1464 std::string raw_headers("HTTP/1.1 200 OK\n" 1465 "Content-type: image/jpeg\n\n"); 1466 std::string response_data("<html><title>Test One</title></html>"); 1467 SetResponse(raw_headers, response_data); 1468 1469 HandleScheme("http"); 1470 MakeTestRequest(0, 1, GURL("http:bla")); 1471 1472 // Flush all pending requests. 1473 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1474 1475 // Sorts out all the messages we saw by request. 1476 ResourceIPCAccumulator::ClassifiedMessages msgs; 1477 accum_.GetClassifiedMessages(&msgs); 1478 ASSERT_EQ(1U, msgs.size()); 1479 1480 ResourceResponseHead response_head; 1481 GetResponseHead(msgs[0], &response_head); 1482 ASSERT_EQ("image/jpeg", response_head.mime_type); 1483 } 1484 1485 // Tests that we don't sniff the mime type when there is no message body. 1486 TEST_F(ResourceDispatcherHostTest, MimeNotSniffed2) { 1487 SetResponse("HTTP/1.1 304 Not Modified\n\n"); 1488 1489 HandleScheme("http"); 1490 MakeTestRequest(0, 1, GURL("http:bla")); 1491 1492 // Flush all pending requests. 1493 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1494 1495 // Sorts out all the messages we saw by request. 1496 ResourceIPCAccumulator::ClassifiedMessages msgs; 1497 accum_.GetClassifiedMessages(&msgs); 1498 ASSERT_EQ(1U, msgs.size()); 1499 1500 ResourceResponseHead response_head; 1501 GetResponseHead(msgs[0], &response_head); 1502 ASSERT_EQ("", response_head.mime_type); 1503 } 1504 1505 TEST_F(ResourceDispatcherHostTest, MimeSniff204) { 1506 SetResponse("HTTP/1.1 204 No Content\n\n"); 1507 1508 HandleScheme("http"); 1509 MakeTestRequest(0, 1, GURL("http:bla")); 1510 1511 // Flush all pending requests. 1512 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1513 1514 // Sorts out all the messages we saw by request. 1515 ResourceIPCAccumulator::ClassifiedMessages msgs; 1516 accum_.GetClassifiedMessages(&msgs); 1517 ASSERT_EQ(1U, msgs.size()); 1518 1519 ResourceResponseHead response_head; 1520 GetResponseHead(msgs[0], &response_head); 1521 ASSERT_EQ("text/plain", response_head.mime_type); 1522 } 1523 1524 TEST_F(ResourceDispatcherHostTest, MimeSniffEmpty) { 1525 SetResponse("HTTP/1.1 200 OK\n\n"); 1526 1527 HandleScheme("http"); 1528 MakeTestRequest(0, 1, GURL("http:bla")); 1529 1530 // Flush all pending requests. 1531 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1532 1533 // Sorts out all the messages we saw by request. 1534 ResourceIPCAccumulator::ClassifiedMessages msgs; 1535 accum_.GetClassifiedMessages(&msgs); 1536 ASSERT_EQ(1U, msgs.size()); 1537 1538 ResourceResponseHead response_head; 1539 GetResponseHead(msgs[0], &response_head); 1540 ASSERT_EQ("text/plain", response_head.mime_type); 1541 } 1542 1543 // Tests for crbug.com/31266 (Non-2xx + application/octet-stream). 1544 TEST_F(ResourceDispatcherHostTest, ForbiddenDownload) { 1545 std::string raw_headers("HTTP/1.1 403 Forbidden\n" 1546 "Content-disposition: attachment; filename=blah\n" 1547 "Content-type: application/octet-stream\n\n"); 1548 std::string response_data("<html><title>Test One</title></html>"); 1549 SetResponse(raw_headers, response_data); 1550 1551 // Only MAIN_FRAMEs can trigger a download. 1552 SetResourceType(ResourceType::MAIN_FRAME); 1553 1554 HandleScheme("http"); 1555 MakeTestRequest(0, 1, GURL("http:bla")); 1556 1557 // Flush all pending requests. 1558 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1559 1560 // Sorts out all the messages we saw by request. 1561 ResourceIPCAccumulator::ClassifiedMessages msgs; 1562 accum_.GetClassifiedMessages(&msgs); 1563 1564 // We should have gotten one RequestComplete message. 1565 ASSERT_EQ(1U, msgs[0].size()); 1566 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type()); 1567 1568 // The RequestComplete message should have had the error code of 1569 // ERR_FILE_NOT_FOUND. 1570 int request_id; 1571 int error_code; 1572 1573 PickleIterator iter(msgs[0][0]); 1574 EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &request_id)); 1575 EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &error_code)); 1576 1577 EXPECT_EQ(1, request_id); 1578 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, error_code); 1579 } 1580 1581 // Test for http://crbug.com/76202 . We don't want to destroy a 1582 // download request prematurely when processing a cancellation from 1583 // the renderer. 1584 TEST_F(ResourceDispatcherHostTest, IgnoreCancelForDownloads) { 1585 EXPECT_EQ(0, host_.pending_requests()); 1586 1587 int render_view_id = 0; 1588 int request_id = 1; 1589 1590 std::string raw_headers("HTTP\n" 1591 "Content-disposition: attachment; filename=foo\n\n"); 1592 std::string response_data("01234567890123456789\x01foobar"); 1593 1594 // Get past sniffing metrics in the BufferedResourceHandler. Note that 1595 // if we don't get past the sniffing metrics, the result will be that 1596 // the BufferedResourceHandler won't have figured out that it's a download, 1597 // won't have constructed a DownloadResourceHandler, and and the request 1598 // will be successfully canceled below, failing the test. 1599 response_data.resize(1025, ' '); 1600 1601 SetResponse(raw_headers, response_data); 1602 SetResourceType(ResourceType::MAIN_FRAME); 1603 SetDelayedCompleteJobGeneration(true); 1604 HandleScheme("http"); 1605 1606 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); 1607 // Return some data so that the request is identified as a download 1608 // and the proper resource handlers are created. 1609 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage()); 1610 1611 // And now simulate a cancellation coming from the renderer. 1612 ResourceHostMsg_CancelRequest msg(filter_->child_id(), request_id); 1613 bool msg_was_ok; 1614 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok); 1615 1616 // Since the request had already started processing as a download, 1617 // the cancellation above should have been ignored and the request 1618 // should still be alive. 1619 EXPECT_EQ(1, host_.pending_requests()); 1620 1621 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1622 } 1623 1624 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContext) { 1625 EXPECT_EQ(0, host_.pending_requests()); 1626 1627 int render_view_id = 0; 1628 int request_id = 1; 1629 1630 std::string raw_headers("HTTP\n" 1631 "Content-disposition: attachment; filename=foo\n\n"); 1632 std::string response_data("01234567890123456789\x01foobar"); 1633 // Get past sniffing metrics. 1634 response_data.resize(1025, ' '); 1635 1636 SetResponse(raw_headers, response_data); 1637 SetResourceType(ResourceType::MAIN_FRAME); 1638 SetDelayedCompleteJobGeneration(true); 1639 HandleScheme("http"); 1640 1641 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); 1642 // Return some data so that the request is identified as a download 1643 // and the proper resource handlers are created. 1644 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage()); 1645 1646 // And now simulate a cancellation coming from the renderer. 1647 ResourceHostMsg_CancelRequest msg(filter_->child_id(), request_id); 1648 bool msg_was_ok; 1649 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok); 1650 1651 // Since the request had already started processing as a download, 1652 // the cancellation above should have been ignored and the request 1653 // should still be alive. 1654 EXPECT_EQ(1, host_.pending_requests()); 1655 1656 // Cancelling by other methods shouldn't work either. 1657 host_.CancelRequestsForProcess(render_view_id); 1658 EXPECT_EQ(1, host_.pending_requests()); 1659 1660 // Cancelling by context should work. 1661 host_.CancelRequestsForContext(filter_->resource_context()); 1662 EXPECT_EQ(0, host_.pending_requests()); 1663 } 1664 1665 // Test the cancelling of requests that are being transferred to a new renderer 1666 // due to a redirection. 1667 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextTransferred) { 1668 EXPECT_EQ(0, host_.pending_requests()); 1669 1670 int render_view_id = 0; 1671 int request_id = 1; 1672 1673 std::string raw_headers("HTTP/1.1 200 OK\n" 1674 "Content-Type: text/html; charset=utf-8\n\n"); 1675 std::string response_data("<html>foobar</html>"); 1676 1677 SetResponse(raw_headers, response_data); 1678 SetResourceType(ResourceType::MAIN_FRAME); 1679 HandleScheme("http"); 1680 1681 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); 1682 1683 GlobalRequestID global_request_id(filter_->child_id(), request_id); 1684 host_.MarkAsTransferredNavigation(global_request_id, 1685 GURL("http://example.com/blah")); 1686 1687 // And now simulate a cancellation coming from the renderer. 1688 ResourceHostMsg_CancelRequest msg(filter_->child_id(), request_id); 1689 bool msg_was_ok; 1690 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok); 1691 1692 // Since the request is marked as being transferred, 1693 // the cancellation above should have been ignored and the request 1694 // should still be alive. 1695 EXPECT_EQ(1, host_.pending_requests()); 1696 1697 // Cancelling by other methods shouldn't work either. 1698 host_.CancelRequestsForProcess(render_view_id); 1699 EXPECT_EQ(1, host_.pending_requests()); 1700 1701 // Cancelling by context should work. 1702 host_.CancelRequestsForContext(filter_->resource_context()); 1703 EXPECT_EQ(0, host_.pending_requests()); 1704 } 1705 1706 TEST_F(ResourceDispatcherHostTest, TransferNavigation) { 1707 EXPECT_EQ(0, host_.pending_requests()); 1708 1709 int render_view_id = 0; 1710 int request_id = 1; 1711 1712 // Configure initial request. 1713 SetResponse("HTTP/1.1 302 Found\n" 1714 "Location: http://other.com/blech\n\n"); 1715 1716 SetResourceType(ResourceType::MAIN_FRAME); 1717 HandleScheme("http"); 1718 1719 // Temporarily replace ContentBrowserClient with one that will trigger the 1720 // transfer navigation code paths. 1721 TransfersAllNavigationsContentBrowserClient new_client; 1722 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client); 1723 1724 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); 1725 1726 // Restore. 1727 SetBrowserClientForTesting(old_client); 1728 1729 // This second filter is used to emulate a second process. 1730 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( 1731 this, browser_context_->GetResourceContext()); 1732 1733 int new_render_view_id = 1; 1734 int new_request_id = 2; 1735 1736 const std::string kResponseBody = "hello world"; 1737 SetResponse("HTTP/1.1 200 OK\n" 1738 "Content-Type: text/plain\n\n", 1739 kResponseBody); 1740 1741 ResourceHostMsg_Request request = 1742 CreateResourceRequest("GET", ResourceType::MAIN_FRAME, 1743 GURL("http://other.com/blech")); 1744 request.transferred_request_child_id = filter_->child_id(); 1745 request.transferred_request_request_id = request_id; 1746 1747 // For cleanup. 1748 child_ids_.insert(second_filter->child_id()); 1749 ResourceHostMsg_RequestResource transfer_request_msg( 1750 new_render_view_id, new_request_id, request); 1751 bool msg_was_ok; 1752 host_.OnMessageReceived( 1753 transfer_request_msg, second_filter.get(), &msg_was_ok); 1754 base::MessageLoop::current()->RunUntilIdle(); 1755 1756 // Flush all the pending requests. 1757 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1758 1759 // Check generated messages. 1760 ResourceIPCAccumulator::ClassifiedMessages msgs; 1761 accum_.GetClassifiedMessages(&msgs); 1762 1763 ASSERT_EQ(1U, msgs.size()); 1764 CheckSuccessfulRequest(msgs[0], kResponseBody); 1765 } 1766 1767 TEST_F(ResourceDispatcherHostTest, TransferNavigationAndThenRedirect) { 1768 EXPECT_EQ(0, host_.pending_requests()); 1769 1770 int render_view_id = 0; 1771 int request_id = 1; 1772 1773 // Configure initial request. 1774 SetResponse("HTTP/1.1 302 Found\n" 1775 "Location: http://other.com/blech\n\n"); 1776 1777 SetResourceType(ResourceType::MAIN_FRAME); 1778 HandleScheme("http"); 1779 1780 // Temporarily replace ContentBrowserClient with one that will trigger the 1781 // transfer navigation code paths. 1782 TransfersAllNavigationsContentBrowserClient new_client; 1783 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client); 1784 1785 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); 1786 1787 // Restore. 1788 SetBrowserClientForTesting(old_client); 1789 1790 // This second filter is used to emulate a second process. 1791 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( 1792 this, browser_context_->GetResourceContext()); 1793 1794 int new_render_view_id = 1; 1795 int new_request_id = 2; 1796 1797 // Delay the start of the next request so that we can setup the response for 1798 // the next URL. 1799 SetDelayedStartJobGeneration(true); 1800 1801 SetResponse("HTTP/1.1 302 Found\n" 1802 "Location: http://other.com/blerg\n\n"); 1803 1804 ResourceHostMsg_Request request = 1805 CreateResourceRequest("GET", ResourceType::MAIN_FRAME, 1806 GURL("http://other.com/blech")); 1807 request.transferred_request_child_id = filter_->child_id(); 1808 request.transferred_request_request_id = request_id; 1809 1810 // For cleanup. 1811 child_ids_.insert(second_filter->child_id()); 1812 ResourceHostMsg_RequestResource transfer_request_msg( 1813 new_render_view_id, new_request_id, request); 1814 bool msg_was_ok; 1815 host_.OnMessageReceived( 1816 transfer_request_msg, second_filter.get(), &msg_was_ok); 1817 base::MessageLoop::current()->RunUntilIdle(); 1818 1819 // Response data for "http://other.com/blerg": 1820 const std::string kResponseBody = "hello world"; 1821 SetResponse("HTTP/1.1 200 OK\n" 1822 "Content-Type: text/plain\n\n", 1823 kResponseBody); 1824 1825 // OK, let the redirect happen. 1826 SetDelayedStartJobGeneration(false); 1827 CompleteStartRequest(second_filter.get(), new_request_id); 1828 base::MessageLoop::current()->RunUntilIdle(); 1829 1830 // Flush all the pending requests. 1831 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1832 1833 // Now, simulate the renderer choosing to follow the redirect. 1834 ResourceHostMsg_FollowRedirect redirect_msg( 1835 new_render_view_id, new_request_id, false, GURL()); 1836 host_.OnMessageReceived(redirect_msg, second_filter.get(), &msg_was_ok); 1837 base::MessageLoop::current()->RunUntilIdle(); 1838 1839 // Flush all the pending requests. 1840 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1841 1842 // Check generated messages. 1843 ResourceIPCAccumulator::ClassifiedMessages msgs; 1844 accum_.GetClassifiedMessages(&msgs); 1845 1846 ASSERT_EQ(1U, msgs.size()); 1847 1848 // We should have received a redirect followed by a "normal" payload. 1849 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type()); 1850 msgs[0].erase(msgs[0].begin()); 1851 CheckSuccessfulRequest(msgs[0], kResponseBody); 1852 } 1853 1854 TEST_F(ResourceDispatcherHostTest, UnknownURLScheme) { 1855 EXPECT_EQ(0, host_.pending_requests()); 1856 1857 SetResourceType(ResourceType::MAIN_FRAME); 1858 HandleScheme("http"); 1859 1860 MakeTestRequest(0, 1, GURL("foo://bar")); 1861 1862 // Flush all pending requests. 1863 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} 1864 1865 // Sort all the messages we saw by request. 1866 ResourceIPCAccumulator::ClassifiedMessages msgs; 1867 accum_.GetClassifiedMessages(&msgs); 1868 1869 // We should have gotten one RequestComplete message. 1870 ASSERT_EQ(1U, msgs[0].size()); 1871 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type()); 1872 1873 // The RequestComplete message should have the error code of 1874 // ERR_UNKNOWN_URL_SCHEME. 1875 int request_id; 1876 int error_code; 1877 1878 PickleIterator iter(msgs[0][0]); 1879 EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &request_id)); 1880 EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &error_code)); 1881 1882 EXPECT_EQ(1, request_id); 1883 EXPECT_EQ(net::ERR_UNKNOWN_URL_SCHEME, error_code); 1884 } 1885 1886 TEST_F(ResourceDispatcherHostTest, DataReceivedACKs) { 1887 EXPECT_EQ(0, host_.pending_requests()); 1888 1889 SendDataReceivedACKs(true); 1890 1891 HandleScheme("big-job"); 1892 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000")); 1893 1894 // Sort all the messages we saw by request. 1895 ResourceIPCAccumulator::ClassifiedMessages msgs; 1896 accum_.GetClassifiedMessages(&msgs); 1897 1898 size_t size = msgs[0].size(); 1899 1900 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type()); 1901 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type()); 1902 for (size_t i = 2; i < size - 1; ++i) 1903 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type()); 1904 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][size - 1].type()); 1905 } 1906 1907 TEST_F(ResourceDispatcherHostTest, DelayedDataReceivedACKs) { 1908 EXPECT_EQ(0, host_.pending_requests()); 1909 1910 HandleScheme("big-job"); 1911 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000")); 1912 1913 // Sort all the messages we saw by request. 1914 ResourceIPCAccumulator::ClassifiedMessages msgs; 1915 accum_.GetClassifiedMessages(&msgs); 1916 1917 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages. 1918 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type()); 1919 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type()); 1920 for (size_t i = 2; i < msgs[0].size(); ++i) 1921 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type()); 1922 1923 // NOTE: If we fail the above checks then it means that we probably didn't 1924 // load a big enough response to trigger the delay mechanism we are trying to 1925 // test! 1926 1927 msgs[0].erase(msgs[0].begin()); 1928 msgs[0].erase(msgs[0].begin()); 1929 1930 // ACK all DataReceived messages until we find a RequestComplete message. 1931 bool complete = false; 1932 while (!complete) { 1933 for (size_t i = 0; i < msgs[0].size(); ++i) { 1934 if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) { 1935 complete = true; 1936 break; 1937 } 1938 1939 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type()); 1940 1941 ResourceHostMsg_DataReceived_ACK msg(0, 1); 1942 bool msg_was_ok; 1943 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok); 1944 } 1945 1946 base::MessageLoop::current()->RunUntilIdle(); 1947 1948 msgs.clear(); 1949 accum_.GetClassifiedMessages(&msgs); 1950 } 1951 } 1952 1953 // Flakyness of this test might indicate memory corruption issues with 1954 // for example the ResourceBuffer of AsyncResourceHandler. 1955 TEST_F(ResourceDispatcherHostTest, DataReceivedUnexpectedACKs) { 1956 EXPECT_EQ(0, host_.pending_requests()); 1957 1958 HandleScheme("big-job"); 1959 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000")); 1960 1961 // Sort all the messages we saw by request. 1962 ResourceIPCAccumulator::ClassifiedMessages msgs; 1963 accum_.GetClassifiedMessages(&msgs); 1964 1965 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages. 1966 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type()); 1967 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type()); 1968 for (size_t i = 2; i < msgs[0].size(); ++i) 1969 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type()); 1970 1971 // NOTE: If we fail the above checks then it means that we probably didn't 1972 // load a big enough response to trigger the delay mechanism. 1973 1974 // Send some unexpected ACKs. 1975 for (size_t i = 0; i < 128; ++i) { 1976 ResourceHostMsg_DataReceived_ACK msg(0, 1); 1977 bool msg_was_ok; 1978 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok); 1979 } 1980 1981 msgs[0].erase(msgs[0].begin()); 1982 msgs[0].erase(msgs[0].begin()); 1983 1984 // ACK all DataReceived messages until we find a RequestComplete message. 1985 bool complete = false; 1986 while (!complete) { 1987 for (size_t i = 0; i < msgs[0].size(); ++i) { 1988 if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) { 1989 complete = true; 1990 break; 1991 } 1992 1993 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type()); 1994 1995 ResourceHostMsg_DataReceived_ACK msg(0, 1); 1996 bool msg_was_ok; 1997 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok); 1998 } 1999 2000 base::MessageLoop::current()->RunUntilIdle(); 2001 2002 msgs.clear(); 2003 accum_.GetClassifiedMessages(&msgs); 2004 } 2005 } 2006 2007 } // namespace content 2008