Index: chrome/browser/plugin_process_host.cc |
=================================================================== |
--- chrome/browser/plugin_process_host.cc (revision 60575) |
+++ chrome/browser/plugin_process_host.cc (working copy) |
@@ -24,6 +24,7 @@ |
#include "chrome/browser/chrome_plugin_browsing_context.h" |
#include "chrome/browser/chrome_thread.h" |
#include "chrome/browser/net/url_request_tracking.h" |
+#include "chrome/browser/plugin_download_helper.h" |
#include "chrome/browser/plugin_service.h" |
#include "chrome/browser/profile.h" |
#include "chrome/browser/renderer_host/resource_dispatcher_host.h" |
@@ -37,7 +38,6 @@ |
#include "gfx/native_widget_types.h" |
#include "ipc/ipc_switches.h" |
#include "net/base/cookie_store.h" |
-#include "net/base/file_stream.h" |
#include "net/base/io_buffer.h" |
#include "net/url_request/url_request.h" |
#include "net/url_request/url_request_context.h" |
@@ -56,201 +56,6 @@ |
"https://dl-ssl.google.com/edgedl/chrome/plugins/plugins2.xml"; |
#if defined(OS_WIN) |
- |
-// The PluginDownloadUrlHelper is used to handle one download URL request |
-// from the plugin. Each download request is handled by a new instance |
-// of this class. |
-class PluginDownloadUrlHelper : public URLRequest::Delegate { |
- static const int kDownloadFileBufferSize = 32768; |
- public: |
- PluginDownloadUrlHelper(const std::string& download_url, |
- int source_pid, gfx::NativeWindow caller_window); |
- ~PluginDownloadUrlHelper(); |
- |
- void InitiateDownload(); |
- |
- // URLRequest::Delegate |
- virtual void OnAuthRequired(URLRequest* request, |
- net::AuthChallengeInfo* auth_info); |
- virtual void OnSSLCertificateError(URLRequest* request, |
- int cert_error, |
- net::X509Certificate* cert); |
- virtual void OnResponseStarted(URLRequest* request); |
- virtual void OnReadCompleted(URLRequest* request, int bytes_read); |
- |
- void OnDownloadCompleted(URLRequest* request); |
- |
- protected: |
- void DownloadCompletedHelper(bool success); |
- |
- // The download file request initiated by the plugin. |
- URLRequest* download_file_request_; |
- // Handle to the downloaded file. |
- scoped_ptr<net::FileStream> download_file_; |
- // The full path of the downloaded file. |
- FilePath download_file_path_; |
- // The buffer passed off to URLRequest::Read. |
- scoped_refptr<net::IOBuffer> download_file_buffer_; |
- // TODO(port): this comment doesn't describe the situation on Posix. |
- // The window handle for sending the WM_COPYDATA notification, |
- // indicating that the download completed. |
- gfx::NativeWindow download_file_caller_window_; |
- |
- std::string download_url_; |
- int download_source_child_unique_id_; |
- |
- DISALLOW_COPY_AND_ASSIGN(PluginDownloadUrlHelper); |
-}; |
- |
-PluginDownloadUrlHelper::PluginDownloadUrlHelper( |
- const std::string& download_url, |
- int source_child_unique_id, |
- gfx::NativeWindow caller_window) |
- : download_file_request_(NULL), |
- download_file_buffer_(new net::IOBuffer(kDownloadFileBufferSize)), |
- download_file_caller_window_(caller_window), |
- download_url_(download_url), |
- download_source_child_unique_id_(source_child_unique_id) { |
- DCHECK(::IsWindow(caller_window)); |
- memset(download_file_buffer_->data(), 0, kDownloadFileBufferSize); |
- download_file_.reset(new net::FileStream()); |
-} |
- |
-PluginDownloadUrlHelper::~PluginDownloadUrlHelper() { |
- if (download_file_request_) { |
- delete download_file_request_; |
- download_file_request_ = NULL; |
- } |
-} |
- |
-void PluginDownloadUrlHelper::InitiateDownload() { |
- download_file_request_ = new URLRequest(GURL(download_url_), this); |
- chrome_browser_net::SetOriginProcessUniqueIDForRequest( |
- download_source_child_unique_id_, download_file_request_); |
- download_file_request_->set_context( |
- Profile::GetDefaultRequestContext()->GetURLRequestContext()); |
- download_file_request_->Start(); |
-} |
- |
-void PluginDownloadUrlHelper::OnAuthRequired( |
- URLRequest* request, |
- net::AuthChallengeInfo* auth_info) { |
- URLRequest::Delegate::OnAuthRequired(request, auth_info); |
- DownloadCompletedHelper(false); |
-} |
- |
-void PluginDownloadUrlHelper::OnSSLCertificateError( |
- URLRequest* request, |
- int cert_error, |
- net::X509Certificate* cert) { |
- URLRequest::Delegate::OnSSLCertificateError(request, cert_error, cert); |
- DownloadCompletedHelper(false); |
-} |
- |
-void PluginDownloadUrlHelper::OnResponseStarted(URLRequest* request) { |
- if (!download_file_->IsOpen()) { |
- // This is safe because once the temp file has been safely created, an |
- // attacker can't drop a symlink etc into place. |
- file_util::CreateTemporaryFile(&download_file_path_); |
- download_file_->Open(download_file_path_, |
- base::PLATFORM_FILE_CREATE_ALWAYS | |
- base::PLATFORM_FILE_READ | base::PLATFORM_FILE_WRITE); |
- if (!download_file_->IsOpen()) { |
- NOTREACHED(); |
- OnDownloadCompleted(request); |
- return; |
- } |
- } |
- if (!request->status().is_success()) { |
- OnDownloadCompleted(request); |
- } else { |
- // Initiate a read. |
- int bytes_read = 0; |
- if (!request->Read(download_file_buffer_, kDownloadFileBufferSize, |
- &bytes_read)) { |
- // If the error is not an IO pending, then we're done |
- // reading. |
- if (!request->status().is_io_pending()) { |
- OnDownloadCompleted(request); |
- } |
- } else if (bytes_read == 0) { |
- OnDownloadCompleted(request); |
- } else { |
- OnReadCompleted(request, bytes_read); |
- } |
- } |
-} |
- |
-void PluginDownloadUrlHelper::OnReadCompleted(URLRequest* request, |
- int bytes_read) { |
- DCHECK(download_file_->IsOpen()); |
- |
- if (bytes_read == 0) { |
- OnDownloadCompleted(request); |
- return; |
- } |
- |
- int request_bytes_read = bytes_read; |
- |
- while (request->status().is_success()) { |
- int bytes_written = download_file_->Write(download_file_buffer_->data(), |
- request_bytes_read, NULL); |
- DCHECK((bytes_written < 0) || (bytes_written == request_bytes_read)); |
- |
- if ((bytes_written < 0) || (bytes_written != request_bytes_read)) { |
- DownloadCompletedHelper(false); |
- break; |
- } |
- |
- // Start reading |
- request_bytes_read = 0; |
- if (!request->Read(download_file_buffer_, kDownloadFileBufferSize, |
- &request_bytes_read)) { |
- if (!request->status().is_io_pending()) { |
- // If the error is not an IO pending, then we're done |
- // reading. |
- OnDownloadCompleted(request); |
- } |
- break; |
- } else if (request_bytes_read == 0) { |
- OnDownloadCompleted(request); |
- break; |
- } |
- } |
-} |
- |
-void PluginDownloadUrlHelper::OnDownloadCompleted(URLRequest* request) { |
- bool success = true; |
- if (!request->status().is_success()) { |
- success = false; |
- } else if (!download_file_->IsOpen()) { |
- success = false; |
- } |
- |
- DownloadCompletedHelper(success); |
-} |
- |
-void PluginDownloadUrlHelper::DownloadCompletedHelper(bool success) { |
- if (download_file_->IsOpen()) { |
- download_file_.reset(); |
- } |
- |
- std::wstring path = download_file_path_.value(); |
- COPYDATASTRUCT download_file_data = {0}; |
- download_file_data.cbData = |
- static_cast<unsigned long>((path.length() + 1) * sizeof(wchar_t)); |
- download_file_data.lpData = const_cast<wchar_t *>(path.c_str()); |
- download_file_data.dwData = success; |
- |
- if (::IsWindow(download_file_caller_window_)) { |
- ::SendMessage(download_file_caller_window_, WM_COPYDATA, NULL, |
- reinterpret_cast<LPARAM>(&download_file_data)); |
- } |
- |
- // Don't access any members after this. |
- delete this; |
-} |
- |
void PluginProcessHost::OnPluginWindowDestroyed(HWND window, HWND parent) { |
// The window is destroyed at this point, we just care about its parent, which |
// is the intermediate window we created. |
@@ -267,8 +72,9 @@ |
int source_pid, |
gfx::NativeWindow caller_window) { |
PluginDownloadUrlHelper* download_url_helper = |
- new PluginDownloadUrlHelper(url, source_pid, caller_window); |
- download_url_helper->InitiateDownload(); |
+ new PluginDownloadUrlHelper(url, source_pid, caller_window, NULL); |
+ download_url_helper->InitiateDownload( |
+ Profile::GetDefaultRequestContext()->GetURLRequestContext()); |
} |
void PluginProcessHost::AddWindow(HWND window) { |