Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4655)

Unified Diff: chrome/browser/plugin_download_helper.cc

Issue 3453025: Relanding this patch with the compile fix for Visual studio 2005. The compile... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/plugin_download_helper.h ('k') | chrome/browser/plugin_process_host.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/plugin_download_helper.cc
===================================================================
--- chrome/browser/plugin_download_helper.cc (revision 0)
+++ chrome/browser/plugin_download_helper.cc (revision 0)
@@ -0,0 +1,190 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/plugin_download_helper.h"
+
+#if defined(OS_WIN)
+#include <windows.h>
+
+#include "base/file_util.h"
+#include "chrome/browser/net/url_request_tracking.h"
+#include "net/base/io_buffer.h"
+
+PluginDownloadUrlHelper::PluginDownloadUrlHelper(
+ const std::string& download_url,
+ int source_child_unique_id,
+ gfx::NativeWindow caller_window,
+ PluginDownloadUrlHelper::DownloadDelegate* delegate)
+ : 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),
+ delegate_(delegate) {
+ 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(
+ URLRequestContext* request_context) {
+ 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(request_context);
+ 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();
+ }
+
+ if (success) {
+ FilePath new_download_file_path =
+ download_file_path_.DirName().AppendASCII(
+ download_file_request_->url().ExtractFileName());
+
+ file_util::Delete(new_download_file_path, false);
+
+ if (!file_util::ReplaceFileW(download_file_path_,
+ new_download_file_path)) {
+ DLOG(ERROR) << "Failed to rename file:"
+ << download_file_path_.value()
+ << " to file:"
+ << new_download_file_path.value();
+ } else {
+ download_file_path_ = new_download_file_path;
+ }
+ }
+
+ if (delegate_) {
+ delegate_->OnDownloadCompleted(download_file_path_, success);
+ } else {
+ 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;
+}
+
+#endif // OS_WIN
+
+
+
+
Property changes on: chrome\browser\plugin_download_helper.cc
___________________________________________________________________
Added: svn:eol-style
+ LF
« no previous file with comments | « chrome/browser/plugin_download_helper.h ('k') | chrome/browser/plugin_process_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698