OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate. h" | 5 #include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate. h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/base64.h" | 10 #include "base/base64.h" |
11 #include "base/guid.h" | |
11 #include "base/logging.h" | 12 #include "base/logging.h" |
12 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
13 #include "chrome/browser/chrome_notification_types.h" | 14 #include "chrome/browser/chrome_notification_types.h" |
14 #include "chrome/browser/component_updater/component_updater_service.h" | 15 #include "chrome/browser/component_updater/component_updater_service.h" |
15 #include "chrome/browser/component_updater/pnacl/pnacl_component_installer.h" | 16 #include "chrome/browser/component_updater/pnacl/pnacl_component_installer.h" |
16 #include "chrome/browser/content_settings/host_content_settings_map.h" | 17 #include "chrome/browser/content_settings/host_content_settings_map.h" |
17 #include "chrome/browser/download/download_request_limiter.h" | 18 #include "chrome/browser/download/download_request_limiter.h" |
18 #include "chrome/browser/download/download_resource_throttle.h" | 19 #include "chrome/browser/download/download_resource_throttle.h" |
19 #include "chrome/browser/extensions/api/streams_private/streams_private_api.h" | 20 #include "chrome/browser/extensions/api/streams_private/streams_private_api.h" |
20 #include "chrome/browser/extensions/extension_renderer_state.h" | 21 #include "chrome/browser/extensions/extension_renderer_state.h" |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
149 if (prerender_contents) | 150 if (prerender_contents) |
150 prerender_contents->AddNetworkBytes(bytes); | 151 prerender_contents->AddNetworkBytes(bytes); |
151 | 152 |
152 prerender::PrerenderManager* prerender_manager = | 153 prerender::PrerenderManager* prerender_manager = |
153 GetPrerenderManager(render_process_id, render_view_id); | 154 GetPrerenderManager(render_process_id, render_view_id); |
154 if (prerender_manager) | 155 if (prerender_manager) |
155 prerender_manager->AddProfileNetworkBytesIfEnabled(bytes); | 156 prerender_manager->AddProfileNetworkBytesIfEnabled(bytes); |
156 } | 157 } |
157 | 158 |
158 #if !defined(OS_ANDROID) | 159 #if !defined(OS_ANDROID) |
159 // Goes through the extension's file browser handlers and checks if there is one | |
160 // that can handle the |mime_type|. | |
161 // |extension| must not be NULL. | |
162 bool ExtensionCanHandleMimeType(const Extension* extension, | |
163 const std::string& mime_type) { | |
164 MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension); | |
165 if (!handler) | |
166 return false; | |
167 | |
168 return handler->CanHandleMIMEType(mime_type); | |
169 } | |
170 | |
171 void SendExecuteMimeTypeHandlerEvent(scoped_ptr<content::StreamHandle> stream, | 160 void SendExecuteMimeTypeHandlerEvent(scoped_ptr<content::StreamHandle> stream, |
172 int64 expected_content_size, | 161 int64 expected_content_size, |
173 int render_process_id, | 162 int render_process_id, |
174 int render_view_id, | 163 int render_view_id, |
175 const std::string& extension_id) { | 164 const std::string& extension_id, |
165 const std::string& view_id) { | |
176 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 166 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
177 | 167 |
168 content::RenderViewHost* render_view_host = | |
169 content::RenderViewHost::FromID(render_process_id, render_view_id); | |
170 if (!render_view_host) | |
171 return; | |
172 | |
178 content::WebContents* web_contents = | 173 content::WebContents* web_contents = |
179 tab_util::GetWebContentsByID(render_process_id, render_view_id); | 174 tab_util::GetWebContentsByID(render_process_id, render_view_id); |
180 if (!web_contents) | 175 if (!web_contents) |
181 return; | 176 return; |
182 | 177 |
183 // If the request was for a prerender, abort the prerender and do not | 178 // If the request was for a prerender, abort the prerender and do not |
184 // continue. | 179 // continue. |
185 prerender::PrerenderContents* prerender_contents = | 180 prerender::PrerenderContents* prerender_contents = |
186 prerender::PrerenderContents::FromWebContents(web_contents); | 181 prerender::PrerenderContents::FromWebContents(web_contents); |
187 if (prerender_contents) { | 182 if (prerender_contents) { |
188 prerender_contents->Destroy(prerender::FINAL_STATUS_DOWNLOAD); | 183 prerender_contents->Destroy(prerender::FINAL_STATUS_DOWNLOAD); |
189 return; | 184 return; |
190 } | 185 } |
191 | 186 |
192 Profile* profile = | 187 Profile* profile = |
193 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 188 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
194 | 189 |
195 StreamsPrivateAPI* streams_private = StreamsPrivateAPI::Get(profile); | 190 StreamsPrivateAPI* streams_private = StreamsPrivateAPI::Get(profile); |
196 if (!streams_private) | 191 if (!streams_private) |
197 return; | 192 return; |
198 streams_private->ExecuteMimeTypeHandler( | 193 streams_private->ExecuteMimeTypeHandler( |
199 extension_id, web_contents, stream.Pass(), expected_content_size); | 194 extension_id, web_contents, stream.Pass(), view_id, |
195 expected_content_size); | |
200 } | 196 } |
201 | 197 |
202 void LaunchURL(const GURL& url, int render_process_id, int render_view_id, | 198 void LaunchURL(const GURL& url, int render_process_id, int render_view_id, |
203 bool user_gesture) { | 199 bool user_gesture) { |
204 // If there is no longer a WebContents, the request may have raced with tab | 200 // If there is no longer a WebContents, the request may have raced with tab |
205 // closing. Don't fire the external request. (It may have been a prerender.) | 201 // closing. Don't fire the external request. (It may have been a prerender.) |
206 content::WebContents* web_contents = | 202 content::WebContents* web_contents = |
207 tab_util::GetWebContentsByID(render_process_id, render_view_id); | 203 tab_util::GetWebContentsByID(render_process_id, render_view_id); |
208 if (!web_contents) | 204 if (!web_contents) |
209 return; | 205 return; |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
542 } | 538 } |
543 #endif | 539 #endif |
544 | 540 |
545 bool ChromeResourceDispatcherHostDelegate::ShouldForceDownloadResource( | 541 bool ChromeResourceDispatcherHostDelegate::ShouldForceDownloadResource( |
546 const GURL& url, const std::string& mime_type) { | 542 const GURL& url, const std::string& mime_type) { |
547 // Special-case user scripts to get downloaded instead of viewed. | 543 // Special-case user scripts to get downloaded instead of viewed. |
548 return extensions::UserScript::IsURLUserScript(url, mime_type); | 544 return extensions::UserScript::IsURLUserScript(url, mime_type); |
549 } | 545 } |
550 | 546 |
551 bool ChromeResourceDispatcherHostDelegate::ShouldInterceptResourceAsStream( | 547 bool ChromeResourceDispatcherHostDelegate::ShouldInterceptResourceAsStream( |
548 net::URLRequest* request, | |
552 content::ResourceContext* resource_context, | 549 content::ResourceContext* resource_context, |
553 const GURL& url, | |
554 const std::string& mime_type, | 550 const std::string& mime_type, |
555 GURL* origin, | 551 GURL* origin, |
556 std::string* target_id) { | 552 std::string* payload) { |
557 #if !defined(OS_ANDROID) | 553 #if !defined(OS_ANDROID) |
558 ProfileIOData* io_data = | 554 ProfileIOData* io_data = |
559 ProfileIOData::FromResourceContext(resource_context); | 555 ProfileIOData::FromResourceContext(resource_context); |
560 bool profile_is_off_the_record = io_data->IsOffTheRecord(); | 556 bool profile_is_off_the_record = io_data->IsOffTheRecord(); |
561 const scoped_refptr<const extensions::InfoMap> extension_info_map( | 557 const scoped_refptr<const extensions::InfoMap> extension_info_map( |
562 io_data->GetExtensionInfoMap()); | 558 io_data->GetExtensionInfoMap()); |
563 std::vector<std::string> whitelist = MimeTypesHandler::GetMIMETypeWhitelist(); | 559 std::vector<std::string> whitelist = MimeTypesHandler::GetMIMETypeWhitelist(); |
564 // Go through the white-listed extensions and try to use them to intercept | 560 // Go through the white-listed extensions and try to use them to intercept |
565 // the URL request. | 561 // the URL request. |
566 for (size_t i = 0; i < whitelist.size(); ++i) { | 562 for (size_t i = 0; i < whitelist.size(); ++i) { |
567 const char* extension_id = whitelist[i].c_str(); | 563 const char* extension_id = whitelist[i].c_str(); |
568 const Extension* extension = | 564 const Extension* extension = |
569 extension_info_map->extensions().GetByID(extension_id); | 565 extension_info_map->extensions().GetByID(extension_id); |
570 // The white-listed extension may not be installed, so we have to NULL check | 566 // The white-listed extension may not be installed, so we have to NULL check |
571 // |extension|. | 567 // |extension|. |
572 if (!extension || | 568 if (!extension || |
573 (profile_is_off_the_record && | 569 (profile_is_off_the_record && |
574 !extension_info_map->IsIncognitoEnabled(extension_id))) { | 570 !extension_info_map->IsIncognitoEnabled(extension_id))) { |
575 continue; | 571 continue; |
576 } | 572 } |
577 | 573 |
578 if (ExtensionCanHandleMimeType(extension, mime_type)) { | 574 MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension); |
575 if (handler && handler->CanHandleMIMEType(mime_type)) { | |
576 StreamTargetInfo target_info; | |
579 *origin = Extension::GetBaseURLFromExtensionId(extension_id); | 577 *origin = Extension::GetBaseURLFromExtensionId(extension_id); |
580 *target_id = extension_id; | 578 target_info.extension_id = extension_id; |
579 if (!handler->handler_url().empty()) { | |
580 target_info.view_id = base::GenerateGUID(); | |
581 *payload = origin->spec() + handler->handler_url() + | |
582 "?id=" + target_info.view_id; | |
583 } | |
584 stream_target_info_[request] = target_info; | |
jam
2014/06/06 15:00:40
nit: check in the destructor of this class that th
Zachary Kuznia
2014/06/07 01:45:36
Done.
| |
581 return true; | 585 return true; |
582 } | 586 } |
583 } | 587 } |
584 #endif | 588 #endif |
585 return false; | 589 return false; |
586 } | 590 } |
587 | 591 |
588 void ChromeResourceDispatcherHostDelegate::OnStreamCreated( | 592 void ChromeResourceDispatcherHostDelegate::OnStreamCreated( |
593 net::URLRequest* request, | |
589 content::ResourceContext* resource_context, | 594 content::ResourceContext* resource_context, |
590 int render_process_id, | 595 int render_process_id, |
591 int render_view_id, | 596 int render_view_id, |
592 const std::string& target_id, | 597 scoped_ptr<content::StreamHandle> stream) { |
593 scoped_ptr<content::StreamHandle> stream, | |
594 int64 expected_content_size) { | |
595 #if !defined(OS_ANDROID) | 598 #if !defined(OS_ANDROID) |
599 std::map<net::URLRequest*, StreamTargetInfo>::iterator ix = | |
600 stream_target_info_.find(request); | |
601 CHECK(ix != stream_target_info_.end()); | |
596 content::BrowserThread::PostTask( | 602 content::BrowserThread::PostTask( |
597 content::BrowserThread::UI, FROM_HERE, | 603 content::BrowserThread::UI, FROM_HERE, |
598 base::Bind(&SendExecuteMimeTypeHandlerEvent, base::Passed(&stream), | 604 base::Bind(&SendExecuteMimeTypeHandlerEvent, base::Passed(&stream), |
599 expected_content_size, render_process_id, render_view_id, | 605 request->GetExpectedContentSize(), render_process_id, |
jam
2014/06/06 15:00:40
nit: once you don't take in the render_process_id
Zachary Kuznia
2014/06/07 01:45:36
Done.
| |
600 target_id)); | 606 render_view_id, |
607 ix->second.extension_id, ix->second.view_id)); | |
608 stream_target_info_.erase(request); | |
601 #endif | 609 #endif |
602 } | 610 } |
603 | 611 |
604 void ChromeResourceDispatcherHostDelegate::OnResponseStarted( | 612 void ChromeResourceDispatcherHostDelegate::OnResponseStarted( |
605 net::URLRequest* request, | 613 net::URLRequest* request, |
606 content::ResourceContext* resource_context, | 614 content::ResourceContext* resource_context, |
607 content::ResourceResponse* response, | 615 content::ResourceResponse* response, |
608 IPC::Sender* sender) { | 616 IPC::Sender* sender) { |
609 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); | 617 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); |
610 | 618 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
709 url_request->GetTotalReceivedBytes())); | 717 url_request->GetTotalReceivedBytes())); |
710 } | 718 } |
711 } | 719 } |
712 | 720 |
713 // static | 721 // static |
714 void ChromeResourceDispatcherHostDelegate:: | 722 void ChromeResourceDispatcherHostDelegate:: |
715 SetExternalProtocolHandlerDelegateForTesting( | 723 SetExternalProtocolHandlerDelegateForTesting( |
716 ExternalProtocolHandler::Delegate* delegate) { | 724 ExternalProtocolHandler::Delegate* delegate) { |
717 g_external_protocol_handler_delegate = delegate; | 725 g_external_protocol_handler_delegate = delegate; |
718 } | 726 } |
OLD | NEW |