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

Side by Side Diff: content/common/net/url_fetcher_impl.cc

Issue 9585009: Add URLFetcher::SaveResponseToFileAtPath (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: _ Created 8 years, 9 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/common/net/url_fetcher_impl.h" 5 #include "content/common/net/url_fetcher_impl.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 // to a file. It is only used if |Core::response_destination_| == FILE. 103 // to a file. It is only used if |Core::response_destination_| == FILE.
104 // Each instance of FileWriter is owned by a URLFetcher::Core, which manages 104 // Each instance of FileWriter is owned by a URLFetcher::Core, which manages
105 // its lifetime and never transfers ownership. While writing to 105 // its lifetime and never transfers ownership. While writing to
106 // a file, all function calls happen on the IO thread. 106 // a file, all function calls happen on the IO thread.
107 class FileWriter { 107 class FileWriter {
108 public: 108 public:
109 FileWriter(URLFetcherImpl::Core* core, 109 FileWriter(URLFetcherImpl::Core* core,
110 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy); 110 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy);
111 111
112 ~FileWriter(); 112 ~FileWriter();
113 void CreateFile(const FilePath& file_path);
114 void DidCreateFile(const FilePath& file_path,
115 base::PlatformFileError error_code,
116 base::PassPlatformFile file_handle,
117 bool created);
113 void CreateTempFile(); 118 void CreateTempFile();
114 void DidCreateTempFile(base::PlatformFileError error_code, 119 void DidCreateTempFile(base::PlatformFileError error_code,
115 base::PassPlatformFile file_handle, 120 base::PassPlatformFile file_handle,
116 const FilePath& file_path); 121 const FilePath& file_path);
117 122
118 // Record |num_bytes_| response bytes in |core_->buffer_| to the file. 123 // Record |num_bytes_| response bytes in |core_->buffer_| to the file.
119 void WriteBuffer(int num_bytes); 124 void WriteBuffer(int num_bytes);
120 125
121 // Called when a write has been done. Continues writing if there are 126 // Called when a write has been done. Continues writing if there are
122 // any more bytes to write. Otherwise, initiates a read in core_. 127 // any more bytes to write. Otherwise, initiates a read in core_.
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 // True if the URLFetcher has been cancelled. 280 // True if the URLFetcher has been cancelled.
276 bool was_cancelled_; 281 bool was_cancelled_;
277 282
278 // If writing results to a file, |file_writer_| will manage creation, 283 // If writing results to a file, |file_writer_| will manage creation,
279 // writing, and destruction of that file. 284 // writing, and destruction of that file.
280 scoped_ptr<FileWriter> file_writer_; 285 scoped_ptr<FileWriter> file_writer_;
281 286
282 // Where should responses be saved? 287 // Where should responses be saved?
283 ResponseDestinationType response_destination_; 288 ResponseDestinationType response_destination_;
284 289
290 // Path to the file where the response is written.
291 // We create a temporary file when the path is empty.
292 FilePath response_destination_file_path_;
293
285 // If |automatically_retry_on_5xx_| is false, 5xx responses will be 294 // If |automatically_retry_on_5xx_| is false, 5xx responses will be
286 // propagated to the observer, if it is true URLFetcher will automatically 295 // propagated to the observer, if it is true URLFetcher will automatically
287 // re-execute the request, after the back-off delay has expired. 296 // re-execute the request, after the back-off delay has expired.
288 // true by default. 297 // true by default.
289 bool automatically_retry_on_5xx_; 298 bool automatically_retry_on_5xx_;
290 // Maximum retries allowed. 299 // Maximum retries allowed.
291 int max_retries_; 300 int max_retries_;
292 // Back-off time delay. 0 by default. 301 // Back-off time delay. 0 by default.
293 base::TimeDelta backoff_delay_; 302 base::TimeDelta backoff_delay_;
294 303
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 error_code_(base::PLATFORM_FILE_OK), 341 error_code_(base::PLATFORM_FILE_OK),
333 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), 342 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
334 file_message_loop_proxy_(file_message_loop_proxy), 343 file_message_loop_proxy_(file_message_loop_proxy),
335 file_handle_(base::kInvalidPlatformFileValue) { 344 file_handle_(base::kInvalidPlatformFileValue) {
336 } 345 }
337 346
338 URLFetcherImpl::Core::FileWriter::~FileWriter() { 347 URLFetcherImpl::Core::FileWriter::~FileWriter() {
339 RemoveFile(); 348 RemoveFile();
340 } 349 }
341 350
342 void URLFetcherImpl::Core::FileWriter::CreateTempFile() { 351 void URLFetcherImpl::Core::FileWriter::CreateFile(const FilePath& file_path) {
343 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); 352 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread());
344 DCHECK(file_message_loop_proxy_.get()); 353 DCHECK(file_message_loop_proxy_.get());
345 base::FileUtilProxy::CreateTemporary( 354 base::FileUtilProxy::CreateOrOpen(
346 file_message_loop_proxy_, 355 file_message_loop_proxy_,
347 0, // No additional file flags. 356 file_path,
348 base::Bind(&URLFetcherImpl::Core::FileWriter::DidCreateTempFile, 357 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE,
willchan no longer on Chromium 2012/03/06 02:33:04 Just doublechecking...is this what we want? We alw
hashimoto 2012/03/06 10:16:01 I think this is OK because zip::ZipReader is doing
349 weak_factory_.GetWeakPtr())); 358 base::Bind(&URLFetcherImpl::Core::FileWriter::DidCreateFile,
359 weak_factory_.GetWeakPtr(),
360 file_path));
350 } 361 }
351 362
352 void URLFetcherImpl::Core::FileWriter::DidCreateTempFile( 363 void URLFetcherImpl::Core::FileWriter::DidCreateFile(
364 const FilePath& file_path,
353 base::PlatformFileError error_code, 365 base::PlatformFileError error_code,
354 base::PassPlatformFile file_handle, 366 base::PassPlatformFile file_handle,
355 const FilePath& file_path) { 367 bool created) {
356 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); 368 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread());
357 369
358 if (base::PLATFORM_FILE_OK != error_code) { 370 if (base::PLATFORM_FILE_OK != error_code) {
359 error_code_ = error_code; 371 error_code_ = error_code;
360 RemoveFile(); 372 RemoveFile();
361 core_->delegate_loop_proxy_->PostTask( 373 core_->delegate_loop_proxy_->PostTask(
362 FROM_HERE, base::Bind(&Core::InformDelegateFetchIsComplete, core_)); 374 FROM_HERE, base::Bind(&Core::InformDelegateFetchIsComplete, core_));
363 return; 375 return;
364 } 376 }
365 377
366 file_path_ = file_path; 378 file_path_ = file_path;
367 file_handle_ = file_handle.ReleaseValue(); 379 file_handle_ = file_handle.ReleaseValue();
368 total_bytes_written_ = 0; 380 total_bytes_written_ = 0;
369 381
370 core_->io_message_loop_proxy_->PostTask( 382 core_->io_message_loop_proxy_->PostTask(
371 FROM_HERE, base::Bind(&Core::StartURLRequestWhenAppropriate, core_)); 383 FROM_HERE, base::Bind(&Core::StartURLRequestWhenAppropriate, core_));
372 } 384 }
373 385
386 void URLFetcherImpl::Core::FileWriter::CreateTempFile() {
387 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread());
388 DCHECK(file_message_loop_proxy_.get());
389 base::FileUtilProxy::CreateTemporary(
390 file_message_loop_proxy_,
391 0, // No additional file flags.
392 base::Bind(&URLFetcherImpl::Core::FileWriter::DidCreateTempFile,
393 weak_factory_.GetWeakPtr()));
394 }
395
396 void URLFetcherImpl::Core::FileWriter::DidCreateTempFile(
397 base::PlatformFileError error_code,
398 base::PassPlatformFile file_handle,
399 const FilePath& file_path) {
400 const bool created = true;
401 DidCreateFile(file_path, error_code, file_handle, created);
402 }
403
374 void URLFetcherImpl::Core::FileWriter::WriteBuffer(int num_bytes) { 404 void URLFetcherImpl::Core::FileWriter::WriteBuffer(int num_bytes) {
375 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); 405 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread());
376 406
377 // Start writing to the file by setting the initial state 407 // Start writing to the file by setting the initial state
378 // of |pending_bytes_| and |buffer_offset_| to indicate that the 408 // of |pending_bytes_| and |buffer_offset_| to indicate that the
379 // entire buffer has not yet been written. 409 // entire buffer has not yet been written.
380 pending_bytes_ = num_bytes; 410 pending_bytes_ = num_bytes;
381 buffer_offset_ = 0; 411 buffer_offset_ = 0;
382 ContinueWrite(base::PLATFORM_FILE_OK, 0); 412 ContinueWrite(base::PLATFORM_FILE_OK, 0);
383 } 413 }
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 StartURLRequestWhenAppropriate(); 613 StartURLRequestWhenAppropriate();
584 break; 614 break;
585 615
586 case FILE: 616 case FILE:
587 DCHECK(file_message_loop_proxy_.get()) 617 DCHECK(file_message_loop_proxy_.get())
588 << "Need to set the file message loop proxy."; 618 << "Need to set the file message loop proxy.";
589 619
590 file_writer_.reset( 620 file_writer_.reset(
591 new FileWriter(this, file_message_loop_proxy_)); 621 new FileWriter(this, file_message_loop_proxy_));
592 622
593 // If the temp file is successfully created, 623 // If the file is successfully created,
594 // Core::StartURLRequestWhenAppropriate() will be called. 624 // Core::StartURLRequestWhenAppropriate() will be called.
595 file_writer_->CreateTempFile(); 625 if (!response_destination_file_path_.empty())
Sam Kerner (Chrome) 2012/03/06 00:23:06 Looks like the signal that you want a specific fil
hashimoto 2012/03/06 10:16:01 Sounds good, done.
626 file_writer_->CreateFile(response_destination_file_path_);
627 else
628 file_writer_->CreateTempFile();
596 break; 629 break;
597 630
598 default: 631 default:
599 NOTREACHED(); 632 NOTREACHED();
600 } 633 }
601 } 634 }
602 635
603 void URLFetcherImpl::Core::Stop() { 636 void URLFetcherImpl::Core::Stop() {
604 if (delegate_loop_proxy_) // May be NULL in tests. 637 if (delegate_loop_proxy_) // May be NULL in tests.
605 DCHECK(delegate_loop_proxy_->BelongsToCurrentThread()); 638 DCHECK(delegate_loop_proxy_->BelongsToCurrentThread());
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
1025 1058
1026 int URLFetcherImpl::GetMaxRetries() const { 1059 int URLFetcherImpl::GetMaxRetries() const {
1027 return core_->max_retries_; 1060 return core_->max_retries_;
1028 } 1061 }
1029 1062
1030 1063
1031 base::TimeDelta URLFetcherImpl::GetBackoffDelay() const { 1064 base::TimeDelta URLFetcherImpl::GetBackoffDelay() const {
1032 return core_->backoff_delay_; 1065 return core_->backoff_delay_;
1033 } 1066 }
1034 1067
1068 void URLFetcherImpl::SaveResponseToFile(
Sam Kerner (Chrome) 2012/03/06 00:23:06 The name of this method should distinguish it from
hashimoto 2012/03/06 10:16:01 Sounds good, done.
1069 const FilePath& file_path,
1070 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy) {
1071 core_->file_message_loop_proxy_ = file_message_loop_proxy;
1072 core_->response_destination_ = FILE;
Sam Kerner (Chrome) 2012/03/06 00:23:06 Here is another example where adding a new enum va
hashimoto 2012/03/06 10:16:01 Done.
1073 core_->response_destination_file_path_ = file_path;
1074 }
1075
1035 void URLFetcherImpl::SaveResponseToTemporaryFile( 1076 void URLFetcherImpl::SaveResponseToTemporaryFile(
1036 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy) { 1077 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy) {
1037 core_->file_message_loop_proxy_ = file_message_loop_proxy; 1078 core_->file_message_loop_proxy_ = file_message_loop_proxy;
1038 core_->response_destination_ = FILE; 1079 core_->response_destination_ = FILE;
1080 core_->response_destination_file_path_.clear();
1039 } 1081 }
1040 1082
1041 net::HttpResponseHeaders* URLFetcherImpl::GetResponseHeaders() const { 1083 net::HttpResponseHeaders* URLFetcherImpl::GetResponseHeaders() const {
1042 return core_->response_headers_; 1084 return core_->response_headers_;
1043 } 1085 }
1044 1086
1045 void URLFetcherImpl::set_response_headers( 1087 void URLFetcherImpl::set_response_headers(
1046 scoped_refptr<net::HttpResponseHeaders> headers) { 1088 scoped_refptr<net::HttpResponseHeaders> headers) {
1047 core_->response_headers_ = headers; 1089 core_->response_headers_ = headers;
1048 } 1090 }
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 1196
1155 // static 1197 // static
1156 content::URLFetcherFactory* URLFetcherImpl::factory() { 1198 content::URLFetcherFactory* URLFetcherImpl::factory() {
1157 return g_factory; 1199 return g_factory;
1158 } 1200 }
1159 1201
1160 // static 1202 // static
1161 void URLFetcherImpl::set_factory(content::URLFetcherFactory* factory) { 1203 void URLFetcherImpl::set_factory(content::URLFetcherFactory* factory) {
1162 g_factory = factory; 1204 g_factory = factory;
1163 } 1205 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698