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