Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Side by Side Diff: content/browser/renderer_host/resource_dispatcher_host_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698