Print Preview: Changing displayed error message when PDF Viewer is missing.
[chromium-blink-merge.git] / chrome / browser / plugin_download_helper.cc
bloba22a944e95e022f2529f85770542a08fdf1e8fca
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
3 // found in the LICENSE file.
5 #include "chrome/browser/plugin_download_helper.h"
7 #if defined(OS_WIN)
8 #include <windows.h>
10 #include "base/file_util.h"
11 #include "net/base/io_buffer.h"
13 PluginDownloadUrlHelper::PluginDownloadUrlHelper(
14 const std::string& download_url,
15 gfx::NativeWindow caller_window,
16 PluginDownloadUrlHelper::DownloadDelegate* delegate)
17 : download_file_request_(NULL),
18 download_file_buffer_(new net::IOBuffer(kDownloadFileBufferSize)),
19 download_file_caller_window_(caller_window),
20 download_url_(download_url),
21 delegate_(delegate) {
22 memset(download_file_buffer_->data(), 0, kDownloadFileBufferSize);
23 download_file_.reset(new net::FileStream());
26 PluginDownloadUrlHelper::~PluginDownloadUrlHelper() {
27 if (download_file_request_) {
28 delete download_file_request_;
29 download_file_request_ = NULL;
33 void PluginDownloadUrlHelper::InitiateDownload(
34 net::URLRequestContext* request_context) {
35 download_file_request_ = new net::URLRequest(GURL(download_url_), this);
36 download_file_request_->set_context(request_context);
37 download_file_request_->Start();
40 void PluginDownloadUrlHelper::OnAuthRequired(
41 net::URLRequest* request,
42 net::AuthChallengeInfo* auth_info) {
43 net::URLRequest::Delegate::OnAuthRequired(request, auth_info);
44 DownloadCompletedHelper(false);
47 void PluginDownloadUrlHelper::OnSSLCertificateError(
48 net::URLRequest* request,
49 int cert_error,
50 net::X509Certificate* cert) {
51 net::URLRequest::Delegate::OnSSLCertificateError(request, cert_error, cert);
52 DownloadCompletedHelper(false);
55 void PluginDownloadUrlHelper::OnResponseStarted(net::URLRequest* request) {
56 if (!download_file_->IsOpen()) {
57 // This is safe because once the temp file has been safely created, an
58 // attacker can't drop a symlink etc into place.
59 file_util::CreateTemporaryFile(&download_file_path_);
60 download_file_->Open(download_file_path_,
61 base::PLATFORM_FILE_CREATE_ALWAYS |
62 base::PLATFORM_FILE_READ | base::PLATFORM_FILE_WRITE);
63 if (!download_file_->IsOpen()) {
64 NOTREACHED();
65 OnDownloadCompleted(request);
66 return;
69 if (!request->status().is_success()) {
70 OnDownloadCompleted(request);
71 } else {
72 // Initiate a read.
73 int bytes_read = 0;
74 if (!request->Read(download_file_buffer_, kDownloadFileBufferSize,
75 &bytes_read)) {
76 // If the error is not an IO pending, then we're done
77 // reading.
78 if (!request->status().is_io_pending()) {
79 OnDownloadCompleted(request);
81 } else if (bytes_read == 0) {
82 OnDownloadCompleted(request);
83 } else {
84 OnReadCompleted(request, bytes_read);
89 void PluginDownloadUrlHelper::OnReadCompleted(net::URLRequest* request,
90 int bytes_read) {
91 DCHECK(download_file_->IsOpen());
93 if (bytes_read == 0) {
94 OnDownloadCompleted(request);
95 return;
98 int request_bytes_read = bytes_read;
100 while (request->status().is_success()) {
101 int bytes_written = download_file_->Write(download_file_buffer_->data(),
102 request_bytes_read, NULL);
103 DCHECK((bytes_written < 0) || (bytes_written == request_bytes_read));
105 if ((bytes_written < 0) || (bytes_written != request_bytes_read)) {
106 DownloadCompletedHelper(false);
107 break;
110 // Start reading
111 request_bytes_read = 0;
112 if (!request->Read(download_file_buffer_, kDownloadFileBufferSize,
113 &request_bytes_read)) {
114 if (!request->status().is_io_pending()) {
115 // If the error is not an IO pending, then we're done
116 // reading.
117 OnDownloadCompleted(request);
119 break;
120 } else if (request_bytes_read == 0) {
121 OnDownloadCompleted(request);
122 break;
127 void PluginDownloadUrlHelper::OnDownloadCompleted(net::URLRequest* request) {
128 bool success = true;
129 if (!request->status().is_success()) {
130 success = false;
131 } else if (!download_file_->IsOpen()) {
132 success = false;
135 DownloadCompletedHelper(success);
138 void PluginDownloadUrlHelper::DownloadCompletedHelper(bool success) {
139 if (download_file_->IsOpen()) {
140 download_file_.reset();
143 if (success) {
144 FilePath new_download_file_path =
145 download_file_path_.DirName().AppendASCII(
146 download_file_request_->url().ExtractFileName());
148 file_util::Delete(new_download_file_path, false);
150 if (!file_util::ReplaceFileW(download_file_path_,
151 new_download_file_path)) {
152 DLOG(ERROR) << "Failed to rename file:"
153 << download_file_path_.value()
154 << " to file:"
155 << new_download_file_path.value();
156 } else {
157 download_file_path_ = new_download_file_path;
161 if (delegate_) {
162 delegate_->OnDownloadCompleted(download_file_path_, success);
163 } else {
164 std::wstring path = download_file_path_.value();
165 COPYDATASTRUCT download_file_data = {0};
166 download_file_data.cbData =
167 static_cast<unsigned long>((path.length() + 1) * sizeof(wchar_t));
168 download_file_data.lpData = const_cast<wchar_t *>(path.c_str());
169 download_file_data.dwData = success;
171 if (::IsWindow(download_file_caller_window_)) {
172 ::SendMessage(download_file_caller_window_, WM_COPYDATA, NULL,
173 reinterpret_cast<LPARAM>(&download_file_data));
177 // Don't access any members after this.
178 delete this;
181 #endif // OS_WIN