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