Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |