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