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

Side by Side Diff: chrome/browser/renderer_host/redirect_to_file_resource_handler.cc

Issue 3396029: Flesh out URLLoader's download_to_file function.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 2 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/renderer_host/redirect_to_file_resource_handler.h" 5 #include "chrome/browser/renderer_host/redirect_to_file_resource_handler.h"
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/file_util_proxy.h" 8 #include "base/file_util_proxy.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/platform_file.h" 10 #include "base/platform_file.h"
11 #include "base/task.h" 11 #include "base/task.h"
12 #include "chrome/browser/child_process_security_policy.h" 12 #include "chrome/browser/child_process_security_policy.h"
13 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" 13 #include "chrome/browser/renderer_host/resource_dispatcher_host.h"
14 #include "chrome/common/resource_response.h" 14 #include "chrome/common/resource_response.h"
15 #include "net/base/file_stream.h" 15 #include "net/base/file_stream.h"
16 #include "net/base/io_buffer.h" 16 #include "net/base/io_buffer.h"
17 #include "net/base/mime_sniffer.h" 17 #include "net/base/mime_sniffer.h"
18 #include "net/base/net_errors.h" 18 #include "net/base/net_errors.h"
19 #include "webkit/blob/deletable_file_reference.h"
20
21 using webkit_blob::DeletableFileReference;
19 22
20 // TODO(darin): Use the buffer sizing algorithm from AsyncResourceHandler. 23 // TODO(darin): Use the buffer sizing algorithm from AsyncResourceHandler.
21 static const int kReadBufSize = 32768; 24 static const int kReadBufSize = 32768;
22 25
23 RedirectToFileResourceHandler::RedirectToFileResourceHandler( 26 RedirectToFileResourceHandler::RedirectToFileResourceHandler(
24 ResourceHandler* next_handler, 27 ResourceHandler* next_handler,
25 int process_id, 28 int process_id,
26 ResourceDispatcherHost* host) 29 ResourceDispatcherHost* host)
27 : callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 30 : callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
28 host_(host), 31 host_(host),
(...skipping 20 matching lines...) Expand all
49 ResourceResponse* response, 52 ResourceResponse* response,
50 bool* defer) { 53 bool* defer) {
51 return next_handler_->OnRequestRedirected(request_id, new_url, response, 54 return next_handler_->OnRequestRedirected(request_id, new_url, response,
52 defer); 55 defer);
53 } 56 }
54 57
55 bool RedirectToFileResourceHandler::OnResponseStarted( 58 bool RedirectToFileResourceHandler::OnResponseStarted(
56 int request_id, 59 int request_id,
57 ResourceResponse* response) { 60 ResourceResponse* response) {
58 if (response->response_head.status.is_success()) { 61 if (response->response_head.status.is_success()) {
59 DCHECK(!file_path_.empty()); 62 DCHECK(deletable_file_ && !deletable_file_->path().empty());
60 response->response_head.download_file_path = file_path_; 63 response->response_head.download_file_path = deletable_file_->path();
61 } 64 }
62 return next_handler_->OnResponseStarted(request_id, response); 65 return next_handler_->OnResponseStarted(request_id, response);
63 } 66 }
64 67
65 bool RedirectToFileResourceHandler::OnWillStart(int request_id, 68 bool RedirectToFileResourceHandler::OnWillStart(int request_id,
66 const GURL& url, 69 const GURL& url,
67 bool* defer) { 70 bool* defer) {
68 request_id_ = request_id; 71 request_id_ = request_id;
69 if (file_path_.empty()) { 72 if (!deletable_file_) {
70 // Defer starting the request until we have created the temporary file. 73 // Defer starting the request until we have created the temporary file.
71 // TODO(darin): This is sub-optimal. We should not delay starting the 74 // TODO(darin): This is sub-optimal. We should not delay starting the
72 // network request like this. 75 // network request like this.
73 *defer = true; 76 *defer = true;
74 base::FileUtilProxy::CreateTemporary( 77 base::FileUtilProxy::CreateTemporary(
75 ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE), 78 ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE),
76 callback_factory_.NewCallback( 79 callback_factory_.NewCallback(
77 &RedirectToFileResourceHandler::DidCreateTemporaryFile)); 80 &RedirectToFileResourceHandler::DidCreateTemporaryFile));
78 return true; 81 return true;
79 } 82 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 119
117 // We use the buffer's offset field to record the end of the buffer. 120 // We use the buffer's offset field to record the end of the buffer.
118 121
119 int new_offset = buf_->offset() + *bytes_read; 122 int new_offset = buf_->offset() + *bytes_read;
120 DCHECK(new_offset <= buf_->capacity()); 123 DCHECK(new_offset <= buf_->capacity());
121 buf_->set_offset(new_offset); 124 buf_->set_offset(new_offset);
122 125
123 if (BufIsFull()) 126 if (BufIsFull())
124 host_->PauseRequest(process_id_, request_id, true); 127 host_->PauseRequest(process_id_, request_id, true);
125 128
129 if (*bytes_read > 0)
130 next_handler_->OnDataDownloaded(request_id, *bytes_read);
131
126 return WriteMore(); 132 return WriteMore();
127 } 133 }
128 134
129 bool RedirectToFileResourceHandler::OnResponseCompleted( 135 bool RedirectToFileResourceHandler::OnResponseCompleted(
130 int request_id, 136 int request_id,
131 const URLRequestStatus& status, 137 const URLRequestStatus& status,
132 const std::string& security_info) { 138 const std::string& security_info) {
133 return next_handler_->OnResponseCompleted(request_id, status, security_info); 139 return next_handler_->OnResponseCompleted(request_id, status, security_info);
134 } 140 }
135 141
136 void RedirectToFileResourceHandler::OnRequestClosed() { 142 void RedirectToFileResourceHandler::OnRequestClosed() {
137 next_handler_->OnRequestClosed();
138
139 // The renderer no longer has a WebURLLoader open to this request, so we can
140 // close and unlink the file.
141
142 // We require this explicit call to Close since file_stream_ was constructed 143 // We require this explicit call to Close since file_stream_ was constructed
143 // directly from a PlatformFile. 144 // directly from a PlatformFile.
144 file_stream_->Close(); 145 file_stream_->Close();
145 file_stream_.reset(); 146 file_stream_.reset();
147 deletable_file_ = NULL;
146 148
147 // TODO(dumi): delete the temp file when it's no longer needed. 149 next_handler_->OnRequestClosed();
148 // TODO(dumi): revoke the privilege to upload this file.
149 // base::FileUtilProxy::Delete(
150 // ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE),
151 // file_path_, NULL);
152 } 150 }
153 151
154 RedirectToFileResourceHandler::~RedirectToFileResourceHandler() { 152 RedirectToFileResourceHandler::~RedirectToFileResourceHandler() {
155 DCHECK(!file_stream_.get()); 153 DCHECK(!file_stream_.get());
156 } 154 }
157 155
158 void RedirectToFileResourceHandler::DidCreateTemporaryFile( 156 void RedirectToFileResourceHandler::DidCreateTemporaryFile(
159 base::PlatformFileError /*error_code*/, 157 base::PlatformFileError /*error_code*/,
160 base::PassPlatformFile file_handle, 158 base::PassPlatformFile file_handle,
161 FilePath file_path) { 159 FilePath file_path) {
162 file_path_ = file_path; 160 deletable_file_ = DeletableFileReference::GetOrCreate(
161 file_path,
162 ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE));
163 file_stream_.reset(new net::FileStream(file_handle.ReleaseValue(), 163 file_stream_.reset(new net::FileStream(file_handle.ReleaseValue(),
164 base::PLATFORM_FILE_WRITE | 164 base::PLATFORM_FILE_WRITE |
165 base::PLATFORM_FILE_ASYNC)); 165 base::PLATFORM_FILE_ASYNC));
166 ChildProcessSecurityPolicy::GetInstance()->GrantReadFile( 166 host_->RegisterDownloadedTempFile(
167 process_id_, file_path); 167 process_id_, request_id_, deletable_file_.get());
168 host_->StartDeferredRequest(process_id_, request_id_); 168 host_->StartDeferredRequest(process_id_, request_id_);
169 } 169 }
170 170
171 void RedirectToFileResourceHandler::DidWriteToFile(int result) { 171 void RedirectToFileResourceHandler::DidWriteToFile(int result) {
172 write_callback_pending_ = false; 172 write_callback_pending_ = false;
173 173
174 bool failed = false; 174 bool failed = false;
175 if (result > 0) { 175 if (result > 0) {
176 write_cursor_ += result; 176 write_cursor_ += result;
177 failed = !WriteMore(); 177 failed = !WriteMore();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 } 213 }
214 } 214 }
215 215
216 bool RedirectToFileResourceHandler::BufIsFull() const { 216 bool RedirectToFileResourceHandler::BufIsFull() const {
217 // This is a hack to workaround BufferedResourceHandler's inability to 217 // This is a hack to workaround BufferedResourceHandler's inability to
218 // deal with a ResourceHandler that returns a buffer size of less than 218 // deal with a ResourceHandler that returns a buffer size of less than
219 // 2 * net::kMaxBytesToSniff from its OnWillRead method. 219 // 2 * net::kMaxBytesToSniff from its OnWillRead method.
220 // TODO(darin): Fix this retardation! 220 // TODO(darin): Fix this retardation!
221 return buf_->RemainingCapacity() <= (2 * net::kMaxBytesToSniff); 221 return buf_->RemainingCapacity() <= (2 * net::kMaxBytesToSniff);
222 } 222 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698