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