OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/plugin_process_host.h" | 5 #include "chrome/browser/plugin_process_host.h" |
6 | 6 |
7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
8 #include <windows.h> | 8 #include <windows.h> |
9 #elif defined(OS_POSIX) | 9 #elif defined(OS_POSIX) |
10 #include <utility> // for pair<> | 10 #include <utility> // for pair<> |
11 #endif | 11 #endif |
12 | 12 |
13 #include <vector> | 13 #include <vector> |
14 | 14 |
15 #include "app/app_switches.h" | 15 #include "app/app_switches.h" |
16 #include "base/command_line.h" | 16 #include "base/command_line.h" |
17 #include "base/file_path.h" | 17 #include "base/file_path.h" |
18 #include "base/file_util.h" | 18 #include "base/file_util.h" |
19 #include "base/logging.h" | 19 #include "base/logging.h" |
20 #include "base/path_service.h" | 20 #include "base/path_service.h" |
21 #include "base/string_util.h" | 21 #include "base/string_util.h" |
22 #include "base/utf_string_conversions.h" | 22 #include "base/utf_string_conversions.h" |
23 #include "chrome/browser/child_process_security_policy.h" | 23 #include "chrome/browser/child_process_security_policy.h" |
24 #include "chrome/browser/chrome_plugin_browsing_context.h" | 24 #include "chrome/browser/chrome_plugin_browsing_context.h" |
25 #include "chrome/browser/chrome_thread.h" | 25 #include "chrome/browser/chrome_thread.h" |
26 #include "chrome/browser/net/url_request_tracking.h" | 26 #include "chrome/browser/net/url_request_tracking.h" |
| 27 #include "chrome/browser/plugin_download_helper.h" |
27 #include "chrome/browser/plugin_service.h" | 28 #include "chrome/browser/plugin_service.h" |
28 #include "chrome/browser/profile.h" | 29 #include "chrome/browser/profile.h" |
29 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" | 30 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" |
30 #include "chrome/common/chrome_paths.h" | 31 #include "chrome/common/chrome_paths.h" |
31 #include "chrome/common/chrome_plugin_lib.h" | 32 #include "chrome/common/chrome_plugin_lib.h" |
32 #include "chrome/common/chrome_switches.h" | 33 #include "chrome/common/chrome_switches.h" |
33 #include "chrome/common/logging_chrome.h" | 34 #include "chrome/common/logging_chrome.h" |
34 #include "chrome/common/net/url_request_context_getter.h" | 35 #include "chrome/common/net/url_request_context_getter.h" |
35 #include "chrome/common/plugin_messages.h" | 36 #include "chrome/common/plugin_messages.h" |
36 #include "chrome/common/render_messages.h" | 37 #include "chrome/common/render_messages.h" |
37 #include "gfx/native_widget_types.h" | 38 #include "gfx/native_widget_types.h" |
38 #include "ipc/ipc_switches.h" | 39 #include "ipc/ipc_switches.h" |
39 #include "net/base/cookie_store.h" | 40 #include "net/base/cookie_store.h" |
40 #include "net/base/file_stream.h" | |
41 #include "net/base/io_buffer.h" | 41 #include "net/base/io_buffer.h" |
42 #include "net/url_request/url_request.h" | 42 #include "net/url_request/url_request.h" |
43 #include "net/url_request/url_request_context.h" | 43 #include "net/url_request/url_request_context.h" |
44 | 44 |
45 #if defined(USE_X11) | 45 #if defined(USE_X11) |
46 #include "gfx/gtk_native_view_id_manager.h" | 46 #include "gfx/gtk_native_view_id_manager.h" |
47 #endif | 47 #endif |
48 | 48 |
49 #if defined(OS_MACOSX) | 49 #if defined(OS_MACOSX) |
50 #include "base/mac_util.h" | 50 #include "base/mac_util.h" |
51 #include "chrome/common/plugin_carbon_interpose_constants_mac.h" | 51 #include "chrome/common/plugin_carbon_interpose_constants_mac.h" |
52 #include "gfx/rect.h" | 52 #include "gfx/rect.h" |
53 #endif | 53 #endif |
54 | 54 |
55 static const char kDefaultPluginFinderURL[] = | 55 static const char kDefaultPluginFinderURL[] = |
56 "https://dl-ssl.google.com/edgedl/chrome/plugins/plugins2.xml"; | 56 "https://dl-ssl.google.com/edgedl/chrome/plugins/plugins2.xml"; |
57 | 57 |
58 #if defined(OS_WIN) | 58 #if defined(OS_WIN) |
59 | |
60 // The PluginDownloadUrlHelper is used to handle one download URL request | |
61 // from the plugin. Each download request is handled by a new instance | |
62 // of this class. | |
63 class PluginDownloadUrlHelper : public URLRequest::Delegate { | |
64 static const int kDownloadFileBufferSize = 32768; | |
65 public: | |
66 PluginDownloadUrlHelper(const std::string& download_url, | |
67 int source_pid, gfx::NativeWindow caller_window); | |
68 ~PluginDownloadUrlHelper(); | |
69 | |
70 void InitiateDownload(); | |
71 | |
72 // URLRequest::Delegate | |
73 virtual void OnAuthRequired(URLRequest* request, | |
74 net::AuthChallengeInfo* auth_info); | |
75 virtual void OnSSLCertificateError(URLRequest* request, | |
76 int cert_error, | |
77 net::X509Certificate* cert); | |
78 virtual void OnResponseStarted(URLRequest* request); | |
79 virtual void OnReadCompleted(URLRequest* request, int bytes_read); | |
80 | |
81 void OnDownloadCompleted(URLRequest* request); | |
82 | |
83 protected: | |
84 void DownloadCompletedHelper(bool success); | |
85 | |
86 // The download file request initiated by the plugin. | |
87 URLRequest* download_file_request_; | |
88 // Handle to the downloaded file. | |
89 scoped_ptr<net::FileStream> download_file_; | |
90 // The full path of the downloaded file. | |
91 FilePath download_file_path_; | |
92 // The buffer passed off to URLRequest::Read. | |
93 scoped_refptr<net::IOBuffer> download_file_buffer_; | |
94 // TODO(port): this comment doesn't describe the situation on Posix. | |
95 // The window handle for sending the WM_COPYDATA notification, | |
96 // indicating that the download completed. | |
97 gfx::NativeWindow download_file_caller_window_; | |
98 | |
99 std::string download_url_; | |
100 int download_source_child_unique_id_; | |
101 | |
102 DISALLOW_COPY_AND_ASSIGN(PluginDownloadUrlHelper); | |
103 }; | |
104 | |
105 PluginDownloadUrlHelper::PluginDownloadUrlHelper( | |
106 const std::string& download_url, | |
107 int source_child_unique_id, | |
108 gfx::NativeWindow caller_window) | |
109 : download_file_request_(NULL), | |
110 download_file_buffer_(new net::IOBuffer(kDownloadFileBufferSize)), | |
111 download_file_caller_window_(caller_window), | |
112 download_url_(download_url), | |
113 download_source_child_unique_id_(source_child_unique_id) { | |
114 DCHECK(::IsWindow(caller_window)); | |
115 memset(download_file_buffer_->data(), 0, kDownloadFileBufferSize); | |
116 download_file_.reset(new net::FileStream()); | |
117 } | |
118 | |
119 PluginDownloadUrlHelper::~PluginDownloadUrlHelper() { | |
120 if (download_file_request_) { | |
121 delete download_file_request_; | |
122 download_file_request_ = NULL; | |
123 } | |
124 } | |
125 | |
126 void PluginDownloadUrlHelper::InitiateDownload() { | |
127 download_file_request_ = new URLRequest(GURL(download_url_), this); | |
128 chrome_browser_net::SetOriginProcessUniqueIDForRequest( | |
129 download_source_child_unique_id_, download_file_request_); | |
130 download_file_request_->set_context( | |
131 Profile::GetDefaultRequestContext()->GetURLRequestContext()); | |
132 download_file_request_->Start(); | |
133 } | |
134 | |
135 void PluginDownloadUrlHelper::OnAuthRequired( | |
136 URLRequest* request, | |
137 net::AuthChallengeInfo* auth_info) { | |
138 URLRequest::Delegate::OnAuthRequired(request, auth_info); | |
139 DownloadCompletedHelper(false); | |
140 } | |
141 | |
142 void PluginDownloadUrlHelper::OnSSLCertificateError( | |
143 URLRequest* request, | |
144 int cert_error, | |
145 net::X509Certificate* cert) { | |
146 URLRequest::Delegate::OnSSLCertificateError(request, cert_error, cert); | |
147 DownloadCompletedHelper(false); | |
148 } | |
149 | |
150 void PluginDownloadUrlHelper::OnResponseStarted(URLRequest* request) { | |
151 if (!download_file_->IsOpen()) { | |
152 // This is safe because once the temp file has been safely created, an | |
153 // attacker can't drop a symlink etc into place. | |
154 file_util::CreateTemporaryFile(&download_file_path_); | |
155 download_file_->Open(download_file_path_, | |
156 base::PLATFORM_FILE_CREATE_ALWAYS | | |
157 base::PLATFORM_FILE_READ | base::PLATFORM_FILE_WRITE); | |
158 if (!download_file_->IsOpen()) { | |
159 NOTREACHED(); | |
160 OnDownloadCompleted(request); | |
161 return; | |
162 } | |
163 } | |
164 if (!request->status().is_success()) { | |
165 OnDownloadCompleted(request); | |
166 } else { | |
167 // Initiate a read. | |
168 int bytes_read = 0; | |
169 if (!request->Read(download_file_buffer_, kDownloadFileBufferSize, | |
170 &bytes_read)) { | |
171 // If the error is not an IO pending, then we're done | |
172 // reading. | |
173 if (!request->status().is_io_pending()) { | |
174 OnDownloadCompleted(request); | |
175 } | |
176 } else if (bytes_read == 0) { | |
177 OnDownloadCompleted(request); | |
178 } else { | |
179 OnReadCompleted(request, bytes_read); | |
180 } | |
181 } | |
182 } | |
183 | |
184 void PluginDownloadUrlHelper::OnReadCompleted(URLRequest* request, | |
185 int bytes_read) { | |
186 DCHECK(download_file_->IsOpen()); | |
187 | |
188 if (bytes_read == 0) { | |
189 OnDownloadCompleted(request); | |
190 return; | |
191 } | |
192 | |
193 int request_bytes_read = bytes_read; | |
194 | |
195 while (request->status().is_success()) { | |
196 int bytes_written = download_file_->Write(download_file_buffer_->data(), | |
197 request_bytes_read, NULL); | |
198 DCHECK((bytes_written < 0) || (bytes_written == request_bytes_read)); | |
199 | |
200 if ((bytes_written < 0) || (bytes_written != request_bytes_read)) { | |
201 DownloadCompletedHelper(false); | |
202 break; | |
203 } | |
204 | |
205 // Start reading | |
206 request_bytes_read = 0; | |
207 if (!request->Read(download_file_buffer_, kDownloadFileBufferSize, | |
208 &request_bytes_read)) { | |
209 if (!request->status().is_io_pending()) { | |
210 // If the error is not an IO pending, then we're done | |
211 // reading. | |
212 OnDownloadCompleted(request); | |
213 } | |
214 break; | |
215 } else if (request_bytes_read == 0) { | |
216 OnDownloadCompleted(request); | |
217 break; | |
218 } | |
219 } | |
220 } | |
221 | |
222 void PluginDownloadUrlHelper::OnDownloadCompleted(URLRequest* request) { | |
223 bool success = true; | |
224 if (!request->status().is_success()) { | |
225 success = false; | |
226 } else if (!download_file_->IsOpen()) { | |
227 success = false; | |
228 } | |
229 | |
230 DownloadCompletedHelper(success); | |
231 } | |
232 | |
233 void PluginDownloadUrlHelper::DownloadCompletedHelper(bool success) { | |
234 if (download_file_->IsOpen()) { | |
235 download_file_.reset(); | |
236 } | |
237 | |
238 std::wstring path = download_file_path_.value(); | |
239 COPYDATASTRUCT download_file_data = {0}; | |
240 download_file_data.cbData = | |
241 static_cast<unsigned long>((path.length() + 1) * sizeof(wchar_t)); | |
242 download_file_data.lpData = const_cast<wchar_t *>(path.c_str()); | |
243 download_file_data.dwData = success; | |
244 | |
245 if (::IsWindow(download_file_caller_window_)) { | |
246 ::SendMessage(download_file_caller_window_, WM_COPYDATA, NULL, | |
247 reinterpret_cast<LPARAM>(&download_file_data)); | |
248 } | |
249 | |
250 // Don't access any members after this. | |
251 delete this; | |
252 } | |
253 | |
254 void PluginProcessHost::OnPluginWindowDestroyed(HWND window, HWND parent) { | 59 void PluginProcessHost::OnPluginWindowDestroyed(HWND window, HWND parent) { |
255 // The window is destroyed at this point, we just care about its parent, which | 60 // The window is destroyed at this point, we just care about its parent, which |
256 // is the intermediate window we created. | 61 // is the intermediate window we created. |
257 std::set<HWND>::iterator window_index = | 62 std::set<HWND>::iterator window_index = |
258 plugin_parent_windows_set_.find(parent); | 63 plugin_parent_windows_set_.find(parent); |
259 if (window_index == plugin_parent_windows_set_.end()) | 64 if (window_index == plugin_parent_windows_set_.end()) |
260 return; | 65 return; |
261 | 66 |
262 plugin_parent_windows_set_.erase(window_index); | 67 plugin_parent_windows_set_.erase(window_index); |
263 PostMessage(parent, WM_CLOSE, 0, 0); | 68 PostMessage(parent, WM_CLOSE, 0, 0); |
264 } | 69 } |
265 | 70 |
266 void PluginProcessHost::OnDownloadUrl(const std::string& url, | 71 void PluginProcessHost::OnDownloadUrl(const std::string& url, |
267 int source_pid, | 72 int source_pid, |
268 gfx::NativeWindow caller_window) { | 73 gfx::NativeWindow caller_window) { |
269 PluginDownloadUrlHelper* download_url_helper = | 74 PluginDownloadUrlHelper* download_url_helper = |
270 new PluginDownloadUrlHelper(url, source_pid, caller_window); | 75 new PluginDownloadUrlHelper(url, source_pid, caller_window, NULL); |
271 download_url_helper->InitiateDownload(); | 76 download_url_helper->InitiateDownload( |
| 77 Profile::GetDefaultRequestContext()->GetURLRequestContext()); |
272 } | 78 } |
273 | 79 |
274 void PluginProcessHost::AddWindow(HWND window) { | 80 void PluginProcessHost::AddWindow(HWND window) { |
275 plugin_parent_windows_set_.insert(window); | 81 plugin_parent_windows_set_.insert(window); |
276 } | 82 } |
277 | 83 |
278 #endif // defined(OS_WIN) | 84 #endif // defined(OS_WIN) |
279 | 85 |
280 #if defined(TOOLKIT_USES_GTK) | 86 #if defined(TOOLKIT_USES_GTK) |
281 void PluginProcessHost::OnMapNativeViewId(gfx::NativeViewId id, | 87 void PluginProcessHost::OnMapNativeViewId(gfx::NativeViewId id, |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 const std::vector<uint8>& data) { | 466 const std::vector<uint8>& data) { |
661 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); | 467 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
662 | 468 |
663 ChromePluginLib *chrome_plugin = ChromePluginLib::Find(info_.path); | 469 ChromePluginLib *chrome_plugin = ChromePluginLib::Find(info_.path); |
664 if (chrome_plugin) { | 470 if (chrome_plugin) { |
665 void *data_ptr = const_cast<void*>(reinterpret_cast<const void*>(&data[0])); | 471 void *data_ptr = const_cast<void*>(reinterpret_cast<const void*>(&data[0])); |
666 uint32 data_len = static_cast<uint32>(data.size()); | 472 uint32 data_len = static_cast<uint32>(data.size()); |
667 chrome_plugin->functions().on_message(data_ptr, data_len); | 473 chrome_plugin->functions().on_message(data_ptr, data_len); |
668 } | 474 } |
669 } | 475 } |
OLD | NEW |