OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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/renderer/chrome_content_renderer_client.h" | 5 #include "chrome/renderer/chrome_content_renderer_client.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
12 #include "base/path_service.h" | 12 #include "base/path_service.h" |
13 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
14 #include "base/values.h" | 14 #include "base/values.h" |
15 #include "chrome/common/child_process_logging.h" | 15 #include "chrome/common/child_process_logging.h" |
16 #include "chrome/common/chrome_paths.h" | 16 #include "chrome/common/chrome_paths.h" |
17 #include "chrome/common/chrome_switches.h" | 17 #include "chrome/common/chrome_switches.h" |
18 #include "chrome/common/extensions/extension.h" | 18 #include "chrome/common/extensions/extension.h" |
19 #include "chrome/common/extensions/extension_constants.h" | 19 #include "chrome/common/extensions/extension_constants.h" |
20 #include "chrome/common/extensions/extension_localization_peer.h" | |
21 #include "chrome/common/extensions/extension_set.h" | 20 #include "chrome/common/extensions/extension_set.h" |
22 #include "chrome/common/jstemplate_builder.h" | 21 #include "chrome/common/jstemplate_builder.h" |
23 #include "chrome/common/render_messages.h" | 22 #include "chrome/common/render_messages.h" |
24 #include "chrome/common/url_constants.h" | 23 #include "chrome/common/url_constants.h" |
25 #include "chrome/renderer/autofill/autofill_agent.h" | 24 #include "chrome/renderer/autofill/autofill_agent.h" |
26 #include "chrome/renderer/autofill/form_manager.h" | 25 #include "chrome/renderer/autofill/form_manager.h" |
27 #include "chrome/renderer/autofill/password_autofill_manager.h" | 26 #include "chrome/renderer/autofill/password_autofill_manager.h" |
28 #include "chrome/renderer/automation/automation_renderer_helper.h" | 27 #include "chrome/renderer/automation/automation_renderer_helper.h" |
29 #include "chrome/renderer/automation/dom_automation_v8_extension.h" | 28 #include "chrome/renderer/automation/dom_automation_v8_extension.h" |
30 #include "chrome/renderer/blocked_plugin.h" | 29 #include "chrome/renderer/blocked_plugin.h" |
(...skipping 15 matching lines...) Expand all Loading... |
46 #include "chrome/renderer/net/renderer_net_predictor.h" | 45 #include "chrome/renderer/net/renderer_net_predictor.h" |
47 #include "chrome/renderer/page_click_tracker.h" | 46 #include "chrome/renderer/page_click_tracker.h" |
48 #include "chrome/renderer/page_load_histograms.h" | 47 #include "chrome/renderer/page_load_histograms.h" |
49 #include "chrome/renderer/print_web_view_helper.h" | 48 #include "chrome/renderer/print_web_view_helper.h" |
50 #include "chrome/renderer/renderer_histogram_snapshots.h" | 49 #include "chrome/renderer/renderer_histogram_snapshots.h" |
51 #include "chrome/renderer/safe_browsing/malware_dom_details.h" | 50 #include "chrome/renderer/safe_browsing/malware_dom_details.h" |
52 #include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h" | 51 #include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h" |
53 #include "chrome/renderer/search_extension.h" | 52 #include "chrome/renderer/search_extension.h" |
54 #include "chrome/renderer/searchbox.h" | 53 #include "chrome/renderer/searchbox.h" |
55 #include "chrome/renderer/searchbox_extension.h" | 54 #include "chrome/renderer/searchbox_extension.h" |
56 #include "chrome/renderer/security_filter_peer.h" | |
57 #include "chrome/renderer/spellchecker/spellcheck.h" | 55 #include "chrome/renderer/spellchecker/spellcheck.h" |
58 #include "chrome/renderer/spellchecker/spellcheck_provider.h" | 56 #include "chrome/renderer/spellchecker/spellcheck_provider.h" |
59 #include "chrome/renderer/translate_helper.h" | 57 #include "chrome/renderer/translate_helper.h" |
60 #include "chrome/renderer/visitedlink_slave.h" | 58 #include "chrome/renderer/visitedlink_slave.h" |
61 #include "content/common/resource_dispatcher.h" | |
62 #include "content/common/view_messages.h" | 59 #include "content/common/view_messages.h" |
63 #include "content/renderer/render_thread.h" | 60 #include "content/renderer/render_thread.h" |
64 #include "content/renderer/render_view.h" | 61 #include "content/renderer/render_view.h" |
65 #include "grit/generated_resources.h" | 62 #include "grit/generated_resources.h" |
66 #include "grit/locale_settings.h" | 63 #include "grit/locale_settings.h" |
67 #include "grit/renderer_resources.h" | 64 #include "grit/renderer_resources.h" |
68 #include "net/base/net_errors.h" | 65 #include "net/base/net_errors.h" |
69 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCache.h" | 66 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCache.h" |
70 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h" | 67 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h" |
71 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 68 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
72 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginParams.h" | 69 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginParams.h" |
73 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityPolicy.h" | 70 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityPolicy.h" |
74 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h" | 71 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h" |
75 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h" | 72 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h" |
76 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h" | 73 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h" |
77 #include "ui/base/l10n/l10n_util.h" | 74 #include "ui/base/l10n/l10n_util.h" |
78 #include "ui/base/resource/resource_bundle.h" | 75 #include "ui/base/resource/resource_bundle.h" |
79 #include "webkit/plugins/npapi/plugin_list.h" | 76 #include "webkit/plugins/npapi/plugin_list.h" |
80 #include "webkit/plugins/ppapi/plugin_module.h" | 77 #include "webkit/plugins/ppapi/plugin_module.h" |
81 | 78 |
82 #if defined(OS_MACOSX) | |
83 #include "chrome/app/breakpad_mac.h" | |
84 #endif | |
85 | |
86 using autofill::AutofillAgent; | 79 using autofill::AutofillAgent; |
87 using autofill::FormManager; | 80 using autofill::FormManager; |
88 using autofill::PasswordAutofillManager; | 81 using autofill::PasswordAutofillManager; |
89 using WebKit::WebCache; | 82 using WebKit::WebCache; |
90 using WebKit::WebDataSource; | 83 using WebKit::WebDataSource; |
91 using WebKit::WebFrame; | 84 using WebKit::WebFrame; |
92 using WebKit::WebPlugin; | 85 using WebKit::WebPlugin; |
93 using WebKit::WebPluginParams; | 86 using WebKit::WebPluginParams; |
94 using WebKit::WebSecurityPolicy; | 87 using WebKit::WebSecurityPolicy; |
95 using WebKit::WebString; | 88 using WebKit::WebString; |
96 using WebKit::WebURLError; | 89 using WebKit::WebURLError; |
97 using WebKit::WebURLRequest; | 90 using WebKit::WebURLRequest; |
98 using WebKit::WebURLResponse; | 91 using WebKit::WebURLResponse; |
99 using WebKit::WebVector; | 92 using WebKit::WebVector; |
100 | 93 |
101 namespace { | 94 namespace { |
102 | 95 |
103 static const unsigned int kCacheStatsDelayMS = 2000 /* milliseconds */; | |
104 | |
105 #if defined(OS_POSIX) | |
106 class SuicideOnChannelErrorFilter : public IPC::ChannelProxy::MessageFilter { | |
107 void OnChannelError() { | |
108 // On POSIX, at least, one can install an unload handler which loops | |
109 // forever and leave behind a renderer process which eats 100% CPU forever. | |
110 // | |
111 // This is because the terminate signals (ViewMsg_ShouldClose and the error | |
112 // from the IPC channel) are routed to the main message loop but never | |
113 // processed (because that message loop is stuck in V8). | |
114 // | |
115 // One could make the browser SIGKILL the renderers, but that leaves open a | |
116 // large window where a browser failure (or a user, manually terminating | |
117 // the browser because "it's stuck") will leave behind a process eating all | |
118 // the CPU. | |
119 // | |
120 // So, we install a filter on the channel so that we can process this event | |
121 // here and kill the process. | |
122 | |
123 #if defined(OS_MACOSX) | |
124 // TODO(viettrungluu): crbug.com/28547: The following is needed, as a | |
125 // stopgap, to avoid leaking due to not releasing Breakpad properly. | |
126 // TODO(viettrungluu): Investigate why this is being called. | |
127 if (IsCrashReporterEnabled()) { | |
128 VLOG(1) << "Cleaning up Breakpad."; | |
129 DestructCrashReporter(); | |
130 } else { | |
131 VLOG(1) << "Breakpad not enabled; no clean-up needed."; | |
132 } | |
133 #endif // OS_MACOSX | |
134 | |
135 _exit(0); | |
136 } | |
137 }; | |
138 #endif | |
139 | |
140 class RenderResourceObserver : public ResourceDispatcher::Observer { | |
141 public: | |
142 RenderResourceObserver() | |
143 : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { | |
144 } | |
145 | |
146 virtual webkit_glue::ResourceLoaderBridge::Peer* OnRequestComplete( | |
147 webkit_glue::ResourceLoaderBridge::Peer* current_peer, | |
148 ResourceType::Type resource_type, | |
149 const net::URLRequestStatus& status) { | |
150 // Update the browser about our cache. | |
151 // Rate limit informing the host of our cache stats. | |
152 if (method_factory_.empty()) { | |
153 MessageLoop::current()->PostDelayedTask( | |
154 FROM_HERE, | |
155 method_factory_.NewRunnableMethod( | |
156 &RenderResourceObserver::InformHostOfCacheStats), | |
157 kCacheStatsDelayMS); | |
158 } | |
159 | |
160 if (status.status() != net::URLRequestStatus::CANCELED || | |
161 status.os_error() == net::ERR_ABORTED) { | |
162 return NULL; | |
163 } | |
164 | |
165 // Resource canceled with a specific error are filtered. | |
166 return SecurityFilterPeer::CreateSecurityFilterPeerForDeniedRequest( | |
167 resource_type, current_peer, status.os_error()); | |
168 } | |
169 | |
170 virtual webkit_glue::ResourceLoaderBridge::Peer* OnReceivedResponse( | |
171 webkit_glue::ResourceLoaderBridge::Peer* current_peer, | |
172 const std::string& mime_type, | |
173 const GURL& url) { | |
174 return ExtensionLocalizationPeer::CreateExtensionLocalizationPeer( | |
175 current_peer, RenderThread::current(), mime_type, url); | |
176 } | |
177 | |
178 private: | |
179 void InformHostOfCacheStats() { | |
180 WebCache::UsageStats stats; | |
181 WebCache::getUsageStats(&stats); | |
182 RenderThread::current()->Send(new ViewHostMsg_UpdatedCacheStats(stats)); | |
183 } | |
184 | |
185 ScopedRunnableMethodFactory<RenderResourceObserver> method_factory_; | |
186 | |
187 DISALLOW_COPY_AND_ASSIGN(RenderResourceObserver); | |
188 }; | |
189 | |
190 static void AppendParams(const std::vector<string16>& additional_names, | 96 static void AppendParams(const std::vector<string16>& additional_names, |
191 const std::vector<string16>& additional_values, | 97 const std::vector<string16>& additional_values, |
192 WebVector<WebString>* existing_names, | 98 WebVector<WebString>* existing_names, |
193 WebVector<WebString>* existing_values) { | 99 WebVector<WebString>* existing_values) { |
194 DCHECK(additional_names.size() == additional_values.size()); | 100 DCHECK(additional_names.size() == additional_values.size()); |
195 DCHECK(existing_names->size() == existing_values->size()); | 101 DCHECK(existing_names->size() == existing_values->size()); |
196 | 102 |
197 size_t existing_size = existing_names->size(); | 103 size_t existing_size = existing_names->size(); |
198 size_t total_size = existing_size + additional_names.size(); | 104 size_t total_size = existing_size + additional_names.size(); |
199 | 105 |
(...skipping 28 matching lines...) Expand all Loading... |
228 chrome_observer_.reset(new ChromeRenderProcessObserver()); | 134 chrome_observer_.reset(new ChromeRenderProcessObserver()); |
229 extension_dispatcher_.reset(new ExtensionDispatcher()); | 135 extension_dispatcher_.reset(new ExtensionDispatcher()); |
230 histogram_snapshots_.reset(new RendererHistogramSnapshots()); | 136 histogram_snapshots_.reset(new RendererHistogramSnapshots()); |
231 net_predictor_.reset(new RendererNetPredictor()); | 137 net_predictor_.reset(new RendererNetPredictor()); |
232 spellcheck_.reset(new SpellCheck()); | 138 spellcheck_.reset(new SpellCheck()); |
233 visited_link_slave_.reset(new VisitedLinkSlave()); | 139 visited_link_slave_.reset(new VisitedLinkSlave()); |
234 phishing_classifier_.reset(new safe_browsing::PhishingClassifierFilter); | 140 phishing_classifier_.reset(new safe_browsing::PhishingClassifierFilter); |
235 | 141 |
236 RenderThread* thread = RenderThread::current(); | 142 RenderThread* thread = RenderThread::current(); |
237 thread->AddFilter(new DevToolsAgentFilter()); | 143 thread->AddFilter(new DevToolsAgentFilter()); |
238 #if defined(OS_POSIX) | |
239 thread->AddFilter(new SuicideOnChannelErrorFilter()); | |
240 #endif | |
241 | 144 |
242 thread->AddObserver(chrome_observer_.get()); | 145 thread->AddObserver(chrome_observer_.get()); |
243 thread->AddObserver(extension_dispatcher_.get()); | 146 thread->AddObserver(extension_dispatcher_.get()); |
244 thread->AddObserver(histogram_snapshots_.get()); | 147 thread->AddObserver(histogram_snapshots_.get()); |
245 thread->AddObserver(phishing_classifier_.get()); | 148 thread->AddObserver(phishing_classifier_.get()); |
246 thread->AddObserver(spellcheck_.get()); | 149 thread->AddObserver(spellcheck_.get()); |
247 thread->AddObserver(visited_link_slave_.get()); | 150 thread->AddObserver(visited_link_slave_.get()); |
248 | 151 |
249 thread->RegisterExtension(extensions_v8::ExternalExtension::Get()); | 152 thread->RegisterExtension(extensions_v8::ExternalExtension::Get()); |
250 thread->RegisterExtension(extensions_v8::LoadTimesExtension::Get()); | 153 thread->RegisterExtension(extensions_v8::LoadTimesExtension::Get()); |
251 thread->RegisterExtension(extensions_v8::SearchBoxExtension::Get()); | 154 thread->RegisterExtension(extensions_v8::SearchBoxExtension::Get()); |
252 v8::Extension* search_extension = extensions_v8::SearchExtension::Get(); | 155 v8::Extension* search_extension = extensions_v8::SearchExtension::Get(); |
253 // search_extension is null if not enabled. | 156 // search_extension is null if not enabled. |
254 if (search_extension) | 157 if (search_extension) |
255 thread->RegisterExtension(search_extension); | 158 thread->RegisterExtension(search_extension); |
256 | 159 |
257 if (CommandLine::ForCurrentProcess()->HasSwitch( | 160 if (CommandLine::ForCurrentProcess()->HasSwitch( |
258 switches::kDomAutomationController)) { | 161 switches::kDomAutomationController)) { |
259 thread->RegisterExtension(DomAutomationV8Extension::Get()); | 162 thread->RegisterExtension(DomAutomationV8Extension::Get()); |
260 } | 163 } |
261 | 164 |
262 thread->resource_dispatcher()->set_observer(new RenderResourceObserver()); | |
263 | |
264 // chrome: pages should not be accessible by normal content, and should | 165 // chrome: pages should not be accessible by normal content, and should |
265 // also be unable to script anything but themselves (to help limit the damage | 166 // also be unable to script anything but themselves (to help limit the damage |
266 // that a corrupt chrome: page could cause). | 167 // that a corrupt chrome: page could cause). |
267 WebString chrome_ui_scheme(ASCIIToUTF16(chrome::kChromeUIScheme)); | 168 WebString chrome_ui_scheme(ASCIIToUTF16(chrome::kChromeUIScheme)); |
268 WebSecurityPolicy::registerURLSchemeAsDisplayIsolated(chrome_ui_scheme); | 169 WebSecurityPolicy::registerURLSchemeAsDisplayIsolated(chrome_ui_scheme); |
269 | 170 |
270 // chrome-extension: resources shouldn't trigger insecure content warnings. | 171 // chrome-extension: resources shouldn't trigger insecure content warnings. |
271 WebString extension_scheme(ASCIIToUTF16(chrome::kExtensionScheme)); | 172 WebString extension_scheme(ASCIIToUTF16(chrome::kExtensionScheme)); |
272 WebSecurityPolicy::registerURLSchemeAsSecure(extension_scheme); | 173 WebSecurityPolicy::registerURLSchemeAsSecure(extension_scheme); |
273 } | 174 } |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 if (old_url.is_empty() && frame->opener()) | 543 if (old_url.is_empty() && frame->opener()) |
643 old_url = frame->opener()->url(); | 544 old_url = frame->opener()->url(); |
644 | 545 |
645 bool old_url_is_hosted_app = extensions->GetByURL(old_url) && | 546 bool old_url_is_hosted_app = extensions->GetByURL(old_url) && |
646 !extensions->GetByURL(old_url)->web_extent().is_empty(); | 547 !extensions->GetByURL(old_url)->web_extent().is_empty(); |
647 return !extensions->InSameExtent(old_url, new_url) && | 548 return !extensions->InSameExtent(old_url, new_url) && |
648 !old_url_is_hosted_app; | 549 !old_url_is_hosted_app; |
649 } | 550 } |
650 | 551 |
651 } // namespace chrome | 552 } // namespace chrome |
OLD | NEW |