OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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/file_path.h" | |
8 #include "base/message_loop.h" | |
9 #include "base/process_util.h" | |
10 #include "chrome/browser/browser_thread.h" | |
11 #include "chrome/browser/child_process_security_policy.h" | |
12 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" | |
13 #include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h" | |
14 #include "chrome/browser/renderer_host/resource_handler.h" | |
15 #include "chrome/browser/renderer_host/resource_message_filter.h" | |
16 #include "chrome/common/chrome_plugin_lib.h" | |
17 #include "chrome/common/render_messages.h" | |
18 #include "chrome/common/render_messages_params.h" | |
19 #include "chrome/common/resource_response.h" | |
20 #include "net/base/net_errors.h" | |
21 #include "net/base/upload_data.h" | |
22 #include "net/http/http_util.h" | |
23 #include "net/url_request/url_request.h" | |
24 #include "net/url_request/url_request_job.h" | |
25 #include "net/url_request/url_request_test_job.h" | |
26 #include "testing/gtest/include/gtest/gtest.h" | |
27 #include "webkit/appcache/appcache_interfaces.h" | |
28 | |
29 // TODO(eroman): Write unit tests for SafeBrowsing that exercise | |
30 // SafeBrowsingResourceHandler. | |
31 | |
32 namespace { | |
33 | |
34 // Returns the resource response header structure for this request. | |
35 void GetResponseHead(const std::vector<IPC::Message>& messages, | |
36 ResourceResponseHead* response_head) { | |
37 ASSERT_GE(messages.size(), 2U); | |
38 | |
39 // The first messages should be received response. | |
40 ASSERT_EQ(ViewMsg_Resource_ReceivedResponse::ID, messages[0].type()); | |
41 | |
42 void* iter = NULL; | |
43 int request_id; | |
44 ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, &request_id)); | |
45 ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, response_head)); | |
46 } | |
47 | |
48 } // namespace | |
49 | |
50 static int RequestIDForMessage(const IPC::Message& msg) { | |
51 int request_id = -1; | |
52 switch (msg.type()) { | |
53 case ViewMsg_Resource_UploadProgress::ID: | |
54 case ViewMsg_Resource_ReceivedResponse::ID: | |
55 case ViewMsg_Resource_ReceivedRedirect::ID: | |
56 case ViewMsg_Resource_DataReceived::ID: | |
57 case ViewMsg_Resource_RequestComplete::ID: | |
58 request_id = IPC::MessageIterator(msg).NextInt(); | |
59 break; | |
60 } | |
61 return request_id; | |
62 } | |
63 | |
64 static ViewHostMsg_Resource_Request CreateResourceRequest( | |
65 const char* method, | |
66 ResourceType::Type type, | |
67 const GURL& url) { | |
68 ViewHostMsg_Resource_Request request; | |
69 request.method = std::string(method); | |
70 request.url = url; | |
71 request.first_party_for_cookies = url; // bypass third-party cookie blocking | |
72 request.load_flags = 0; | |
73 request.origin_pid = 0; | |
74 request.resource_type = type; | |
75 request.request_context = 0; | |
76 request.appcache_host_id = appcache::kNoHostId; | |
77 request.download_to_file = false; | |
78 request.host_renderer_id = -1; | |
79 request.host_render_view_id = -1; | |
80 return request; | |
81 } | |
82 | |
83 // Spin up the message loop to kick off the request. | |
84 static void KickOffRequest() { | |
85 MessageLoop::current()->RunAllPending(); | |
86 } | |
87 | |
88 // We may want to move this to a shared space if it is useful for something else | |
89 class ResourceIPCAccumulator { | |
90 public: | |
91 void AddMessage(const IPC::Message& msg) { | |
92 messages_.push_back(msg); | |
93 } | |
94 | |
95 // This groups the messages by their request ID. The groups will be in order | |
96 // that the first message for each request ID was received, and the messages | |
97 // within the groups will be in the order that they appeared. | |
98 // Note that this clears messages_. | |
99 typedef std::vector< std::vector<IPC::Message> > ClassifiedMessages; | |
100 void GetClassifiedMessages(ClassifiedMessages* msgs); | |
101 | |
102 std::vector<IPC::Message> messages_; | |
103 }; | |
104 | |
105 // This is very inefficient as a result of repeatedly extracting the ID, use | |
106 // only for tests! | |
107 void ResourceIPCAccumulator::GetClassifiedMessages(ClassifiedMessages* msgs) { | |
108 while (!messages_.empty()) { | |
109 std::vector<IPC::Message> cur_requests; | |
110 cur_requests.push_back(messages_[0]); | |
111 int cur_id = RequestIDForMessage(messages_[0]); | |
112 | |
113 // find all other messages with this ID | |
114 for (int i = 1; i < static_cast<int>(messages_.size()); i++) { | |
115 int id = RequestIDForMessage(messages_[i]); | |
116 if (id == cur_id) { | |
117 cur_requests.push_back(messages_[i]); | |
118 messages_.erase(messages_.begin() + i); | |
119 i--; | |
120 } | |
121 } | |
122 messages_.erase(messages_.begin()); | |
123 msgs->push_back(cur_requests); | |
124 } | |
125 } | |
126 | |
127 // This class forwards the incoming messages to the ResourceDispatcherHostTest. | |
128 // This is used to emulate different sub-processes, since this filter will | |
129 // have a different ID than the original. For the test, we want all the incoming | |
130 // messages to go to the same place, which is why this forwards. | |
131 class ForwardingFilter : public ResourceMessageFilter { | |
132 public: | |
133 explicit ForwardingFilter(IPC::Message::Sender* dest) | |
134 : ResourceMessageFilter(ChildProcessInfo::GenerateChildProcessUniqueId(), | |
135 ChildProcessInfo::RENDER_PROCESS, | |
136 NULL), | |
137 dest_(dest) { | |
138 OnChannelConnected(base::GetCurrentProcId()); | |
139 } | |
140 | |
141 // ResourceMessageFilter override | |
142 virtual bool Send(IPC::Message* msg) { | |
143 if (!dest_) | |
144 return false; | |
145 return dest_->Send(msg); | |
146 } | |
147 | |
148 private: | |
149 IPC::Message::Sender* dest_; | |
150 | |
151 DISALLOW_COPY_AND_ASSIGN(ForwardingFilter); | |
152 }; | |
153 | |
154 class ResourceDispatcherHostTest : public testing::Test, | |
155 public IPC::Message::Sender { | |
156 public: | |
157 ResourceDispatcherHostTest() | |
158 : ALLOW_THIS_IN_INITIALIZER_LIST(filter_(new ForwardingFilter(this))), | |
159 ui_thread_(BrowserThread::UI, &message_loop_), | |
160 io_thread_(BrowserThread::IO, &message_loop_), | |
161 old_factory_(NULL), | |
162 resource_type_(ResourceType::SUB_RESOURCE) { | |
163 } | |
164 // IPC::Message::Sender implementation | |
165 virtual bool Send(IPC::Message* msg) { | |
166 accum_.AddMessage(*msg); | |
167 delete msg; | |
168 return true; | |
169 } | |
170 | |
171 protected: | |
172 // testing::Test | |
173 virtual void SetUp() { | |
174 DCHECK(!test_fixture_); | |
175 test_fixture_ = this; | |
176 ChildProcessSecurityPolicy::GetInstance()->Add(0); | |
177 net::URLRequest::RegisterProtocolFactory( | |
178 "test", | |
179 &ResourceDispatcherHostTest::Factory); | |
180 EnsureTestSchemeIsAllowed(); | |
181 } | |
182 | |
183 virtual void TearDown() { | |
184 net::URLRequest::RegisterProtocolFactory("test", NULL); | |
185 if (!scheme_.empty()) | |
186 net::URLRequest::RegisterProtocolFactory(scheme_, old_factory_); | |
187 | |
188 DCHECK(test_fixture_ == this); | |
189 test_fixture_ = NULL; | |
190 | |
191 host_.Shutdown(); | |
192 | |
193 ChildProcessSecurityPolicy::GetInstance()->Remove(0); | |
194 | |
195 // The plugin lib is automatically loaded during these test | |
196 // and we want a clean environment for other tests. | |
197 ChromePluginLib::UnloadAllPlugins(); | |
198 | |
199 // Flush the message loop to make Purify happy. | |
200 message_loop_.RunAllPending(); | |
201 } | |
202 | |
203 // Creates a request using the current test object as the filter. | |
204 void MakeTestRequest(int render_view_id, | |
205 int request_id, | |
206 const GURL& url); | |
207 | |
208 // Generates a request using the given filter. This will probably be a | |
209 // ForwardingFilter. | |
210 void MakeTestRequest(ResourceMessageFilter* filter, | |
211 int render_view_id, | |
212 int request_id, | |
213 const GURL& url); | |
214 | |
215 void MakeCancelRequest(int request_id); | |
216 | |
217 void EnsureTestSchemeIsAllowed() { | |
218 static bool have_white_listed_test_scheme = false; | |
219 | |
220 if (!have_white_listed_test_scheme) { | |
221 ChildProcessSecurityPolicy::GetInstance()->RegisterWebSafeScheme("test"); | |
222 have_white_listed_test_scheme = true; | |
223 } | |
224 } | |
225 | |
226 // Sets a particular response for any request from now on. To switch back to | |
227 // the default bahavior, pass an empty |headers|. |headers| should be raw- | |
228 // formatted (NULLs instead of EOLs). | |
229 void SetResponse(const std::string& headers, const std::string& data) { | |
230 response_headers_ = headers; | |
231 response_data_ = data; | |
232 } | |
233 | |
234 // Sets a particular resource type for any request from now on. | |
235 void SetResourceType(ResourceType::Type type) { | |
236 resource_type_ = type; | |
237 } | |
238 | |
239 // Intercepts requests for the given protocol. | |
240 void HandleScheme(const std::string& scheme) { | |
241 DCHECK(scheme_.empty()); | |
242 DCHECK(!old_factory_); | |
243 scheme_ = scheme; | |
244 old_factory_ = net::URLRequest::RegisterProtocolFactory( | |
245 scheme_, &ResourceDispatcherHostTest::Factory); | |
246 } | |
247 | |
248 // Our own net::URLRequestJob factory. | |
249 static net::URLRequestJob* Factory(net::URLRequest* request, | |
250 const std::string& scheme) { | |
251 if (test_fixture_->response_headers_.empty()) { | |
252 return new net::URLRequestTestJob(request); | |
253 } else { | |
254 return new net::URLRequestTestJob(request, | |
255 test_fixture_->response_headers_, | |
256 test_fixture_->response_data_, | |
257 false); | |
258 } | |
259 } | |
260 | |
261 scoped_refptr<ForwardingFilter> filter_; | |
262 MessageLoopForIO message_loop_; | |
263 BrowserThread ui_thread_; | |
264 BrowserThread io_thread_; | |
265 ResourceDispatcherHost host_; | |
266 ResourceIPCAccumulator accum_; | |
267 std::string response_headers_; | |
268 std::string response_data_; | |
269 std::string scheme_; | |
270 net::URLRequest::ProtocolFactory* old_factory_; | |
271 ResourceType::Type resource_type_; | |
272 static ResourceDispatcherHostTest* test_fixture_; | |
273 }; | |
274 // Static. | |
275 ResourceDispatcherHostTest* ResourceDispatcherHostTest::test_fixture_ = NULL; | |
276 | |
277 void ResourceDispatcherHostTest::MakeTestRequest(int render_view_id, | |
278 int request_id, | |
279 const GURL& url) { | |
280 MakeTestRequest(filter_.get(), render_view_id, request_id, url); | |
281 } | |
282 | |
283 void ResourceDispatcherHostTest::MakeTestRequest( | |
284 ResourceMessageFilter* filter, | |
285 int render_view_id, | |
286 int request_id, | |
287 const GURL& url) { | |
288 ViewHostMsg_Resource_Request request = | |
289 CreateResourceRequest("GET", resource_type_, url); | |
290 ViewHostMsg_RequestResource msg(render_view_id, request_id, request); | |
291 bool msg_was_ok; | |
292 host_.OnMessageReceived(msg, filter, &msg_was_ok); | |
293 KickOffRequest(); | |
294 } | |
295 | |
296 void ResourceDispatcherHostTest::MakeCancelRequest(int request_id) { | |
297 host_.CancelRequest(filter_->child_id(), request_id, false); | |
298 } | |
299 | |
300 void CheckSuccessfulRequest(const std::vector<IPC::Message>& messages, | |
301 const std::string& reference_data) { | |
302 // A successful request will have received 4 messages: | |
303 // ReceivedResponse (indicates headers received) | |
304 // DataReceived (data) | |
305 // XXX DataReceived (0 bytes remaining from a read) | |
306 // RequestComplete (request is done) | |
307 // | |
308 // This function verifies that we received 4 messages and that they | |
309 // are appropriate. | |
310 ASSERT_EQ(3U, messages.size()); | |
311 | |
312 // The first messages should be received response | |
313 ASSERT_EQ(ViewMsg_Resource_ReceivedResponse::ID, messages[0].type()); | |
314 | |
315 // followed by the data, currently we only do the data in one chunk, but | |
316 // should probably test multiple chunks later | |
317 ASSERT_EQ(ViewMsg_Resource_DataReceived::ID, messages[1].type()); | |
318 | |
319 void* iter = NULL; | |
320 int request_id; | |
321 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &request_id)); | |
322 base::SharedMemoryHandle shm_handle; | |
323 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_handle)); | |
324 uint32 data_len; | |
325 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &data_len)); | |
326 | |
327 ASSERT_EQ(reference_data.size(), data_len); | |
328 base::SharedMemory shared_mem(shm_handle, true); // read only | |
329 shared_mem.Map(data_len); | |
330 const char* data = static_cast<char*>(shared_mem.memory()); | |
331 ASSERT_EQ(0, memcmp(reference_data.c_str(), data, data_len)); | |
332 | |
333 // followed by a 0-byte read | |
334 //ASSERT_EQ(ViewMsg_Resource_DataReceived::ID, messages[2].type()); | |
335 | |
336 // the last message should be all data received | |
337 ASSERT_EQ(ViewMsg_Resource_RequestComplete::ID, messages[2].type()); | |
338 } | |
339 | |
340 // Tests whether many messages get dispatched properly. | |
341 TEST_F(ResourceDispatcherHostTest, TestMany) { | |
342 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); | |
343 | |
344 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); | |
345 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2()); | |
346 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3()); | |
347 | |
348 // flush all the pending requests | |
349 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | |
350 | |
351 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); | |
352 | |
353 // sorts out all the messages we saw by request | |
354 ResourceIPCAccumulator::ClassifiedMessages msgs; | |
355 accum_.GetClassifiedMessages(&msgs); | |
356 | |
357 // there are three requests, so we should have gotten them classified as such | |
358 ASSERT_EQ(3U, msgs.size()); | |
359 | |
360 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); | |
361 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_2()); | |
362 CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3()); | |
363 } | |
364 | |
365 // Tests whether messages get canceled properly. We issue three requests, | |
366 // cancel one of them, and make sure that each sent the proper notifications. | |
367 TEST_F(ResourceDispatcherHostTest, Cancel) { | |
368 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); | |
369 | |
370 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); | |
371 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2()); | |
372 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3()); | |
373 MakeCancelRequest(2); | |
374 | |
375 // flush all the pending requests | |
376 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | |
377 MessageLoop::current()->RunAllPending(); | |
378 | |
379 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); | |
380 | |
381 ResourceIPCAccumulator::ClassifiedMessages msgs; | |
382 accum_.GetClassifiedMessages(&msgs); | |
383 | |
384 // there are three requests, so we should have gotten them classified as such | |
385 ASSERT_EQ(3U, msgs.size()); | |
386 | |
387 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); | |
388 CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3()); | |
389 | |
390 // Check that request 2 got canceled. | |
391 ASSERT_EQ(2U, msgs[1].size()); | |
392 ASSERT_EQ(ViewMsg_Resource_ReceivedResponse::ID, msgs[1][0].type()); | |
393 ASSERT_EQ(ViewMsg_Resource_RequestComplete::ID, msgs[1][1].type()); | |
394 | |
395 int request_id; | |
396 net::URLRequestStatus status; | |
397 | |
398 void* iter = NULL; | |
399 ASSERT_TRUE(IPC::ReadParam(&msgs[1][1], &iter, &request_id)); | |
400 ASSERT_TRUE(IPC::ReadParam(&msgs[1][1], &iter, &status)); | |
401 | |
402 EXPECT_EQ(net::URLRequestStatus::CANCELED, status.status()); | |
403 } | |
404 | |
405 // The host delegate acts as a second one so we can have some requests | |
406 // pending and some canceled. | |
407 class TestFilter : public ForwardingFilter { | |
408 public: | |
409 TestFilter() | |
410 : ForwardingFilter(NULL), | |
411 has_canceled_(false), | |
412 received_after_canceled_(0) { | |
413 } | |
414 | |
415 // ForwardingFilter override | |
416 virtual bool Send(IPC::Message* msg) { | |
417 // no messages should be received when the process has been canceled | |
418 if (has_canceled_) | |
419 received_after_canceled_++; | |
420 delete msg; | |
421 return true; | |
422 } | |
423 bool has_canceled_; | |
424 int received_after_canceled_; | |
425 }; | |
426 | |
427 // Tests CancelRequestsForProcess | |
428 TEST_F(ResourceDispatcherHostTest, TestProcessCancel) { | |
429 scoped_refptr<TestFilter> test_filter = new TestFilter(); | |
430 | |
431 // request 1 goes to the test delegate | |
432 ViewHostMsg_Resource_Request request = CreateResourceRequest( | |
433 "GET", ResourceType::SUB_RESOURCE, net::URLRequestTestJob::test_url_1()); | |
434 | |
435 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); | |
436 | |
437 MakeTestRequest(test_filter.get(), 0, 1, | |
438 net::URLRequestTestJob::test_url_1()); | |
439 | |
440 // request 2 goes to us | |
441 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2()); | |
442 | |
443 // request 3 goes to the test delegate | |
444 MakeTestRequest(test_filter.get(), 0, 3, | |
445 net::URLRequestTestJob::test_url_3()); | |
446 | |
447 // TODO(mbelshe): | |
448 // Now that the async IO path is in place, the IO always completes on the | |
449 // initial call; so the requests have already completed. This basically | |
450 // breaks the whole test. | |
451 //EXPECT_EQ(3, host_.pending_requests()); | |
452 | |
453 // Process each request for one level so one callback is called. | |
454 for (int i = 0; i < 3; i++) | |
455 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage()); | |
456 | |
457 // Cancel the requests to the test process. | |
458 host_.CancelRequestsForProcess(filter_->child_id()); | |
459 test_filter->has_canceled_ = true; | |
460 | |
461 // Flush all the pending requests. | |
462 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | |
463 | |
464 EXPECT_EQ(0, host_.pending_requests()); | |
465 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); | |
466 | |
467 // The test delegate should not have gotten any messages after being canceled. | |
468 ASSERT_EQ(0, test_filter->received_after_canceled_); | |
469 | |
470 // We should have gotten exactly one result. | |
471 ResourceIPCAccumulator::ClassifiedMessages msgs; | |
472 accum_.GetClassifiedMessages(&msgs); | |
473 ASSERT_EQ(1U, msgs.size()); | |
474 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2()); | |
475 } | |
476 | |
477 // Tests blocking and resuming requests. | |
478 TEST_F(ResourceDispatcherHostTest, TestBlockingResumingRequests) { | |
479 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); | |
480 | |
481 host_.BlockRequestsForRoute(filter_->child_id(), 1); | |
482 host_.BlockRequestsForRoute(filter_->child_id(), 2); | |
483 host_.BlockRequestsForRoute(filter_->child_id(), 3); | |
484 | |
485 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); | |
486 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2()); | |
487 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3()); | |
488 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1()); | |
489 MakeTestRequest(2, 5, net::URLRequestTestJob::test_url_2()); | |
490 MakeTestRequest(3, 6, net::URLRequestTestJob::test_url_3()); | |
491 | |
492 // Flush all the pending requests | |
493 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | |
494 | |
495 // Sort out all the messages we saw by request | |
496 ResourceIPCAccumulator::ClassifiedMessages msgs; | |
497 accum_.GetClassifiedMessages(&msgs); | |
498 | |
499 // All requests but the 2 for the RVH 0 should have been blocked. | |
500 ASSERT_EQ(2U, msgs.size()); | |
501 | |
502 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); | |
503 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3()); | |
504 | |
505 // Resume requests for RVH 1 and flush pending requests. | |
506 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 1); | |
507 KickOffRequest(); | |
508 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | |
509 | |
510 msgs.clear(); | |
511 accum_.GetClassifiedMessages(&msgs); | |
512 ASSERT_EQ(2U, msgs.size()); | |
513 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2()); | |
514 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_1()); | |
515 | |
516 // Test that new requests are not blocked for RVH 1. | |
517 MakeTestRequest(1, 7, net::URLRequestTestJob::test_url_1()); | |
518 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | |
519 msgs.clear(); | |
520 accum_.GetClassifiedMessages(&msgs); | |
521 ASSERT_EQ(1U, msgs.size()); | |
522 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); | |
523 | |
524 // Now resumes requests for all RVH (2 and 3). | |
525 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 2); | |
526 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 3); | |
527 KickOffRequest(); | |
528 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | |
529 | |
530 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); | |
531 | |
532 msgs.clear(); | |
533 accum_.GetClassifiedMessages(&msgs); | |
534 ASSERT_EQ(2U, msgs.size()); | |
535 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2()); | |
536 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3()); | |
537 } | |
538 | |
539 // Tests blocking and canceling requests. | |
540 TEST_F(ResourceDispatcherHostTest, TestBlockingCancelingRequests) { | |
541 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); | |
542 | |
543 host_.BlockRequestsForRoute(filter_->child_id(), 1); | |
544 | |
545 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); | |
546 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2()); | |
547 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3()); | |
548 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1()); | |
549 | |
550 // Flush all the pending requests. | |
551 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | |
552 | |
553 // Sort out all the messages we saw by request. | |
554 ResourceIPCAccumulator::ClassifiedMessages msgs; | |
555 accum_.GetClassifiedMessages(&msgs); | |
556 | |
557 // The 2 requests for the RVH 0 should have been processed. | |
558 ASSERT_EQ(2U, msgs.size()); | |
559 | |
560 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); | |
561 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3()); | |
562 | |
563 // Cancel requests for RVH 1. | |
564 host_.CancelBlockedRequestsForRoute(filter_->child_id(), 1); | |
565 KickOffRequest(); | |
566 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | |
567 | |
568 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); | |
569 | |
570 msgs.clear(); | |
571 accum_.GetClassifiedMessages(&msgs); | |
572 ASSERT_EQ(0U, msgs.size()); | |
573 } | |
574 | |
575 // Tests that blocked requests are canceled if their associated process dies. | |
576 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) { | |
577 // This second filter is used to emulate a second process. | |
578 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(this); | |
579 | |
580 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); | |
581 EXPECT_EQ(0, | |
582 host_.GetOutstandingRequestsMemoryCost(second_filter->child_id())); | |
583 | |
584 host_.BlockRequestsForRoute(second_filter->child_id(), 0); | |
585 | |
586 MakeTestRequest(filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1()); | |
587 MakeTestRequest(second_filter.get(), 0, 2, | |
588 net::URLRequestTestJob::test_url_2()); | |
589 MakeTestRequest(filter_.get(), 0, 3, net::URLRequestTestJob::test_url_3()); | |
590 MakeTestRequest(second_filter.get(), 0, 4, | |
591 net::URLRequestTestJob::test_url_1()); | |
592 | |
593 // Simulate process death. | |
594 host_.CancelRequestsForProcess(second_filter->child_id()); | |
595 | |
596 // Flush all the pending requests. | |
597 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | |
598 | |
599 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); | |
600 EXPECT_EQ(0, | |
601 host_.GetOutstandingRequestsMemoryCost(second_filter->child_id())); | |
602 | |
603 // Sort out all the messages we saw by request. | |
604 ResourceIPCAccumulator::ClassifiedMessages msgs; | |
605 accum_.GetClassifiedMessages(&msgs); | |
606 | |
607 // The 2 requests for the RVH 0 should have been processed. | |
608 ASSERT_EQ(2U, msgs.size()); | |
609 | |
610 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); | |
611 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3()); | |
612 | |
613 EXPECT_TRUE(host_.blocked_requests_map_.empty()); | |
614 } | |
615 | |
616 // Tests that blocked requests don't leak when the ResourceDispatcherHost goes | |
617 // away. Note that we rely on Purify for finding the leaks if any. | |
618 // If this test turns the Purify bot red, check the ResourceDispatcherHost | |
619 // destructor to make sure the blocked requests are deleted. | |
620 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) { | |
621 // This second filter is used to emulate a second process. | |
622 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(this); | |
623 | |
624 host_.BlockRequestsForRoute(filter_->child_id(), 1); | |
625 host_.BlockRequestsForRoute(filter_->child_id(), 2); | |
626 host_.BlockRequestsForRoute(second_filter->child_id(), 1); | |
627 | |
628 MakeTestRequest(filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1()); | |
629 MakeTestRequest(filter_.get(), 1, 2, net::URLRequestTestJob::test_url_2()); | |
630 MakeTestRequest(filter_.get(), 0, 3, net::URLRequestTestJob::test_url_3()); | |
631 MakeTestRequest(second_filter.get(), 1, 4, | |
632 net::URLRequestTestJob::test_url_1()); | |
633 MakeTestRequest(filter_.get(), 2, 5, net::URLRequestTestJob::test_url_2()); | |
634 MakeTestRequest(filter_.get(), 2, 6, net::URLRequestTestJob::test_url_3()); | |
635 | |
636 // Flush all the pending requests. | |
637 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | |
638 } | |
639 | |
640 // Test the private helper method "CalculateApproximateMemoryCost()". | |
641 TEST_F(ResourceDispatcherHostTest, CalculateApproximateMemoryCost) { | |
642 net::URLRequest req(GURL("http://www.google.com"), NULL); | |
643 EXPECT_EQ(4427, ResourceDispatcherHost::CalculateApproximateMemoryCost(&req)); | |
644 | |
645 // Add 9 bytes of referrer. | |
646 req.set_referrer("123456789"); | |
647 EXPECT_EQ(4436, ResourceDispatcherHost::CalculateApproximateMemoryCost(&req)); | |
648 | |
649 // Add 33 bytes of upload content. | |
650 std::string upload_content; | |
651 upload_content.resize(33); | |
652 std::fill(upload_content.begin(), upload_content.end(), 'x'); | |
653 req.AppendBytesToUpload(upload_content.data(), upload_content.size()); | |
654 | |
655 // Since the upload throttling is disabled, this has no effect on the cost. | |
656 EXPECT_EQ(4436, ResourceDispatcherHost::CalculateApproximateMemoryCost(&req)); | |
657 | |
658 // Add a file upload -- should have no effect. | |
659 req.AppendFileToUpload(FilePath(FILE_PATH_LITERAL("does-not-exist.png"))); | |
660 EXPECT_EQ(4436, ResourceDispatcherHost::CalculateApproximateMemoryCost(&req)); | |
661 } | |
662 | |
663 // Test the private helper method "IncrementOutstandingRequestsMemoryCost()". | |
664 TEST_F(ResourceDispatcherHostTest, IncrementOutstandingRequestsMemoryCost) { | |
665 // Add some counts for render_process_host=7 | |
666 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(7)); | |
667 EXPECT_EQ(1, host_.IncrementOutstandingRequestsMemoryCost(1, 7)); | |
668 EXPECT_EQ(2, host_.IncrementOutstandingRequestsMemoryCost(1, 7)); | |
669 EXPECT_EQ(3, host_.IncrementOutstandingRequestsMemoryCost(1, 7)); | |
670 | |
671 // Add some counts for render_process_host=3 | |
672 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(3)); | |
673 EXPECT_EQ(1, host_.IncrementOutstandingRequestsMemoryCost(1, 3)); | |
674 EXPECT_EQ(2, host_.IncrementOutstandingRequestsMemoryCost(1, 3)); | |
675 | |
676 // Remove all the counts for render_process_host=7 | |
677 EXPECT_EQ(3, host_.GetOutstandingRequestsMemoryCost(7)); | |
678 EXPECT_EQ(2, host_.IncrementOutstandingRequestsMemoryCost(-1, 7)); | |
679 EXPECT_EQ(1, host_.IncrementOutstandingRequestsMemoryCost(-1, 7)); | |
680 EXPECT_EQ(0, host_.IncrementOutstandingRequestsMemoryCost(-1, 7)); | |
681 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(7)); | |
682 | |
683 // Remove all the counts for render_process_host=3 | |
684 EXPECT_EQ(2, host_.GetOutstandingRequestsMemoryCost(3)); | |
685 EXPECT_EQ(1, host_.IncrementOutstandingRequestsMemoryCost(-1, 3)); | |
686 EXPECT_EQ(0, host_.IncrementOutstandingRequestsMemoryCost(-1, 3)); | |
687 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(3)); | |
688 | |
689 // When an entry reaches 0, it should be deleted. | |
690 EXPECT_TRUE(host_.outstanding_requests_memory_cost_map_.end() == | |
691 host_.outstanding_requests_memory_cost_map_.find(7)); | |
692 EXPECT_TRUE(host_.outstanding_requests_memory_cost_map_.end() == | |
693 host_.outstanding_requests_memory_cost_map_.find(3)); | |
694 } | |
695 | |
696 // Test that when too many requests are outstanding for a particular | |
697 // render_process_host_id, any subsequent request from it fails. | |
698 TEST_F(ResourceDispatcherHostTest, TooManyOutstandingRequests) { | |
699 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); | |
700 | |
701 // Expected cost of each request as measured by | |
702 // ResourceDispatcherHost::CalculateApproximateMemoryCost(). | |
703 int kMemoryCostOfTest2Req = | |
704 ResourceDispatcherHost::kAvgBytesPerOutstandingRequest + | |
705 std::string("GET").size() + | |
706 net::URLRequestTestJob::test_url_2().spec().size(); | |
707 | |
708 // Tighten the bound on the ResourceDispatcherHost, to speed things up. | |
709 int kMaxCostPerProcess = 440000; | |
710 host_.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess); | |
711 | |
712 // Determine how many instance of test_url_2() we can request before | |
713 // throttling kicks in. | |
714 size_t kMaxRequests = kMaxCostPerProcess / kMemoryCostOfTest2Req; | |
715 | |
716 // This second filter is used to emulate a second process. | |
717 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(this); | |
718 | |
719 // Saturate the number of outstanding requests for our process. | |
720 for (size_t i = 0; i < kMaxRequests; ++i) { | |
721 MakeTestRequest(filter_.get(), 0, i + 1, | |
722 net::URLRequestTestJob::test_url_2()); | |
723 } | |
724 | |
725 // Issue two more requests for our process -- these should fail immediately. | |
726 MakeTestRequest(filter_.get(), 0, kMaxRequests + 1, | |
727 net::URLRequestTestJob::test_url_2()); | |
728 MakeTestRequest(filter_.get(), 0, kMaxRequests + 2, | |
729 net::URLRequestTestJob::test_url_2()); | |
730 | |
731 // Issue two requests for the second process -- these should succeed since | |
732 // it is just process 0 that is saturated. | |
733 MakeTestRequest(second_filter.get(), 0, kMaxRequests + 3, | |
734 net::URLRequestTestJob::test_url_2()); | |
735 MakeTestRequest(second_filter.get(), 0, kMaxRequests + 4, | |
736 net::URLRequestTestJob::test_url_2()); | |
737 | |
738 // Flush all the pending requests. | |
739 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | |
740 MessageLoop::current()->RunAllPending(); | |
741 | |
742 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); | |
743 | |
744 // Sorts out all the messages we saw by request. | |
745 ResourceIPCAccumulator::ClassifiedMessages msgs; | |
746 accum_.GetClassifiedMessages(&msgs); | |
747 | |
748 // We issued (kMaxRequests + 4) total requests. | |
749 ASSERT_EQ(kMaxRequests + 4, msgs.size()); | |
750 | |
751 // Check that the first kMaxRequests succeeded. | |
752 for (size_t i = 0; i < kMaxRequests; ++i) | |
753 CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2()); | |
754 | |
755 // Check that the subsequent two requests (kMaxRequests + 1) and | |
756 // (kMaxRequests + 2) were failed, since the per-process bound was reached. | |
757 for (int i = 0; i < 2; ++i) { | |
758 // Should have sent a single RequestComplete message. | |
759 int index = kMaxRequests + i; | |
760 EXPECT_EQ(1U, msgs[index].size()); | |
761 EXPECT_EQ(ViewMsg_Resource_RequestComplete::ID, msgs[index][0].type()); | |
762 | |
763 // The RequestComplete message should have had status | |
764 // (CANCELLED, ERR_INSUFFICIENT_RESOURCES). | |
765 int request_id; | |
766 net::URLRequestStatus status; | |
767 | |
768 void* iter = NULL; | |
769 EXPECT_TRUE(IPC::ReadParam(&msgs[index][0], &iter, &request_id)); | |
770 EXPECT_TRUE(IPC::ReadParam(&msgs[index][0], &iter, &status)); | |
771 | |
772 EXPECT_EQ(index + 1, request_id); | |
773 EXPECT_EQ(net::URLRequestStatus::CANCELED, status.status()); | |
774 EXPECT_EQ(net::ERR_INSUFFICIENT_RESOURCES, status.os_error()); | |
775 } | |
776 | |
777 // The final 2 requests should have succeeded. | |
778 CheckSuccessfulRequest(msgs[kMaxRequests + 2], | |
779 net::URLRequestTestJob::test_data_2()); | |
780 CheckSuccessfulRequest(msgs[kMaxRequests + 3], | |
781 net::URLRequestTestJob::test_data_2()); | |
782 } | |
783 | |
784 // Tests that we sniff the mime type for a simple request. | |
785 TEST_F(ResourceDispatcherHostTest, MimeSniffed) { | |
786 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); | |
787 | |
788 std::string response("HTTP/1.1 200 OK\n\n"); | |
789 std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(), | |
790 response.size())); | |
791 std::string response_data("<html><title>Test One</title></html>"); | |
792 SetResponse(raw_headers, response_data); | |
793 | |
794 HandleScheme("http"); | |
795 MakeTestRequest(0, 1, GURL("http:bla")); | |
796 | |
797 // Flush all pending requests. | |
798 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | |
799 | |
800 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); | |
801 | |
802 // Sorts out all the messages we saw by request. | |
803 ResourceIPCAccumulator::ClassifiedMessages msgs; | |
804 accum_.GetClassifiedMessages(&msgs); | |
805 ASSERT_EQ(1U, msgs.size()); | |
806 | |
807 ResourceResponseHead response_head; | |
808 GetResponseHead(msgs[0], &response_head); | |
809 ASSERT_EQ("text/html", response_head.mime_type); | |
810 } | |
811 | |
812 // Tests that we don't sniff the mime type when the server provides one. | |
813 TEST_F(ResourceDispatcherHostTest, MimeNotSniffed) { | |
814 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); | |
815 | |
816 std::string response("HTTP/1.1 200 OK\n" | |
817 "Content-type: image/jpeg\n\n"); | |
818 std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(), | |
819 response.size())); | |
820 std::string response_data("<html><title>Test One</title></html>"); | |
821 SetResponse(raw_headers, response_data); | |
822 | |
823 HandleScheme("http"); | |
824 MakeTestRequest(0, 1, GURL("http:bla")); | |
825 | |
826 // Flush all pending requests. | |
827 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | |
828 | |
829 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); | |
830 | |
831 // Sorts out all the messages we saw by request. | |
832 ResourceIPCAccumulator::ClassifiedMessages msgs; | |
833 accum_.GetClassifiedMessages(&msgs); | |
834 ASSERT_EQ(1U, msgs.size()); | |
835 | |
836 ResourceResponseHead response_head; | |
837 GetResponseHead(msgs[0], &response_head); | |
838 ASSERT_EQ("image/jpeg", response_head.mime_type); | |
839 } | |
840 | |
841 // Tests that we don't sniff the mime type when there is no message body. | |
842 TEST_F(ResourceDispatcherHostTest, MimeNotSniffed2) { | |
843 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); | |
844 | |
845 std::string response("HTTP/1.1 304 Not Modified\n\n"); | |
846 std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(), | |
847 response.size())); | |
848 std::string response_data; | |
849 SetResponse(raw_headers, response_data); | |
850 | |
851 HandleScheme("http"); | |
852 MakeTestRequest(0, 1, GURL("http:bla")); | |
853 | |
854 // Flush all pending requests. | |
855 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | |
856 | |
857 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); | |
858 | |
859 // Sorts out all the messages we saw by request. | |
860 ResourceIPCAccumulator::ClassifiedMessages msgs; | |
861 accum_.GetClassifiedMessages(&msgs); | |
862 ASSERT_EQ(1U, msgs.size()); | |
863 | |
864 ResourceResponseHead response_head; | |
865 GetResponseHead(msgs[0], &response_head); | |
866 ASSERT_EQ("", response_head.mime_type); | |
867 } | |
868 | |
869 TEST_F(ResourceDispatcherHostTest, MimeSniff204) { | |
870 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); | |
871 | |
872 std::string response("HTTP/1.1 204 No Content\n\n"); | |
873 std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(), | |
874 response.size())); | |
875 std::string response_data; | |
876 SetResponse(raw_headers, response_data); | |
877 | |
878 HandleScheme("http"); | |
879 MakeTestRequest(0, 1, GURL("http:bla")); | |
880 | |
881 // Flush all pending requests. | |
882 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | |
883 | |
884 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); | |
885 | |
886 // Sorts out all the messages we saw by request. | |
887 ResourceIPCAccumulator::ClassifiedMessages msgs; | |
888 accum_.GetClassifiedMessages(&msgs); | |
889 ASSERT_EQ(1U, msgs.size()); | |
890 | |
891 ResourceResponseHead response_head; | |
892 GetResponseHead(msgs[0], &response_head); | |
893 ASSERT_EQ("text/plain", response_head.mime_type); | |
894 } | |
895 | |
896 // Tests for crbug.com/31266 (Non-2xx + application/octet-stream). | |
897 TEST_F(ResourceDispatcherHostTest, ForbiddenDownload) { | |
898 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); | |
899 | |
900 std::string response("HTTP/1.1 403 Forbidden\n" | |
901 "Content-disposition: attachment; filename=blah\n" | |
902 "Content-type: application/octet-stream\n\n"); | |
903 std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(), | |
904 response.size())); | |
905 std::string response_data("<html><title>Test One</title></html>"); | |
906 SetResponse(raw_headers, response_data); | |
907 | |
908 // Only MAIN_FRAMEs can trigger a download. | |
909 SetResourceType(ResourceType::MAIN_FRAME); | |
910 | |
911 HandleScheme("http"); | |
912 MakeTestRequest(0, 1, GURL("http:bla")); | |
913 | |
914 // Flush all pending requests. | |
915 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | |
916 | |
917 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); | |
918 | |
919 // Sorts out all the messages we saw by request. | |
920 ResourceIPCAccumulator::ClassifiedMessages msgs; | |
921 accum_.GetClassifiedMessages(&msgs); | |
922 | |
923 // We should have gotten one RequestComplete message. | |
924 ASSERT_EQ(1U, msgs[0].size()); | |
925 EXPECT_EQ(ViewMsg_Resource_RequestComplete::ID, msgs[0][0].type()); | |
926 | |
927 // The RequestComplete message should have had status | |
928 // (CANCELED, ERR_FILE_NOT_FOUND). | |
929 int request_id; | |
930 net::URLRequestStatus status; | |
931 | |
932 void* iter = NULL; | |
933 EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &request_id)); | |
934 EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &status)); | |
935 | |
936 EXPECT_EQ(1, request_id); | |
937 EXPECT_EQ(net::URLRequestStatus::CANCELED, status.status()); | |
938 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, status.os_error()); | |
939 } | |
940 | |
941 class DummyResourceHandler : public ResourceHandler { | |
942 public: | |
943 DummyResourceHandler() {} | |
944 | |
945 // Called as upload progress is made. | |
946 bool OnUploadProgress(int request_id, uint64 position, uint64 size) { | |
947 return true; | |
948 } | |
949 | |
950 bool OnRequestRedirected(int request_id, const GURL& url, | |
951 ResourceResponse* response, bool* defer) { | |
952 return true; | |
953 } | |
954 | |
955 bool OnResponseStarted(int request_id, ResourceResponse* response) { | |
956 return true; | |
957 } | |
958 | |
959 bool OnWillStart(int request_id, const GURL& url, bool* defer) { | |
960 return true; | |
961 } | |
962 | |
963 bool OnWillRead( | |
964 int request_id, net::IOBuffer** buf, int* buf_size, int min_size) { | |
965 return true; | |
966 } | |
967 | |
968 bool OnReadCompleted(int request_id, int* bytes_read) { return true; } | |
969 | |
970 bool OnResponseCompleted( | |
971 int request_id, | |
972 const net::URLRequestStatus& status, | |
973 const std::string& info) { | |
974 return true; | |
975 } | |
976 | |
977 void OnRequestClosed() {} | |
978 | |
979 private: | |
980 DISALLOW_COPY_AND_ASSIGN(DummyResourceHandler); | |
981 }; | |
982 | |
983 class ApplyExtensionLocalizationFilterTest : public testing::Test { | |
984 protected: | |
985 void SetUp() { | |
986 url_.reset(new GURL( | |
987 "chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/popup.html")); | |
988 resource_type_ = ResourceType::STYLESHEET; | |
989 resource_handler_.reset(new DummyResourceHandler()); | |
990 request_info_.reset(CreateNewResourceRequestInfo()); | |
991 } | |
992 | |
993 ResourceDispatcherHostRequestInfo* CreateNewResourceRequestInfo() { | |
994 return new ResourceDispatcherHostRequestInfo( | |
995 resource_handler_.get(), ChildProcessInfo::RENDER_PROCESS, 0, 0, 0, | |
996 ResourceType::STYLESHEET, 0U, false, false, false, -1, -1); | |
997 } | |
998 | |
999 scoped_ptr<GURL> url_; | |
1000 ResourceType::Type resource_type_; | |
1001 scoped_ptr<DummyResourceHandler> resource_handler_; | |
1002 scoped_ptr<ResourceDispatcherHostRequestInfo> request_info_; | |
1003 }; | |
1004 | |
1005 TEST_F(ApplyExtensionLocalizationFilterTest, WrongScheme) { | |
1006 url_.reset(new GURL("html://behllobkkfkfnphdnhnkndlbkcpglgmj/popup.html")); | |
1007 ResourceDispatcherHost::ApplyExtensionLocalizationFilter(*url_, | |
1008 resource_type_, request_info_.get()); | |
1009 | |
1010 EXPECT_FALSE(request_info_->replace_extension_localization_templates()); | |
1011 } | |
1012 | |
1013 TEST_F(ApplyExtensionLocalizationFilterTest, GoodScheme) { | |
1014 ResourceDispatcherHost::ApplyExtensionLocalizationFilter(*url_, | |
1015 resource_type_, request_info_.get()); | |
1016 | |
1017 EXPECT_TRUE(request_info_->replace_extension_localization_templates()); | |
1018 } | |
1019 | |
1020 TEST_F(ApplyExtensionLocalizationFilterTest, GoodSchemeWrongResourceType) { | |
1021 resource_type_ = ResourceType::MAIN_FRAME; | |
1022 ResourceDispatcherHost::ApplyExtensionLocalizationFilter(*url_, | |
1023 resource_type_, request_info_.get()); | |
1024 | |
1025 EXPECT_FALSE(request_info_->replace_extension_localization_templates()); | |
1026 } | |
OLD | NEW |