Index: content/common/net/url_fetcher_impl.cc |
diff --git a/content/common/net/url_fetcher_impl.cc b/content/common/net/url_fetcher_impl.cc |
index be442898bdd0e5ee55900bcb1948c63207ad150f..5cadf800f7eebba0fdea9d1b9f2610627bbbfef7 100644 |
--- a/content/common/net/url_fetcher_impl.cc |
+++ b/content/common/net/url_fetcher_impl.cc |
@@ -100,7 +100,8 @@ class URLFetcherImpl::Core |
}; |
// Class FileWriter encapsulates all state involved in writing response bytes |
- // to a file. It is only used if |Core::response_destination_| == FILE. |
+ // to a file. It is only used if |Core::response_destination_| == TEMP_FILE || |
+ // |Core::response_destination_| == PERMANENT_FILE. |
// Each instance of FileWriter is owned by a URLFetcher::Core, which manages |
// its lifetime and never transfers ownership. While writing to |
// a file, all function calls happen on the IO thread. |
@@ -110,10 +111,8 @@ class URLFetcherImpl::Core |
scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy); |
~FileWriter(); |
+ void CreateFileAtPath(const FilePath& file_path); |
void CreateTempFile(); |
- void DidCreateTempFile(base::PlatformFileError error_code, |
- base::PassPlatformFile file_handle, |
- const FilePath& file_path); |
// Record |num_bytes_| response bytes in |core_->buffer_| to the file. |
void WriteBuffer(int num_bytes); |
@@ -137,6 +136,20 @@ class URLFetcherImpl::Core |
base::PlatformFileError error_code() const { return error_code_; } |
private: |
+ // Callback which gets the result of a permanent file creation. |
+ void DidCreateFile(const FilePath& file_path, |
+ base::PlatformFileError error_code, |
+ base::PassPlatformFile file_handle, |
+ bool created); |
+ // Callback which gets the result of a temporary file creation. |
+ void DidCreateTempFile(base::PlatformFileError error_code, |
+ base::PassPlatformFile file_handle, |
+ const FilePath& file_path); |
+ // This method is used to implement DidCreateFile and DidCreateTempFile. |
+ void DidCreateFileInternal(const FilePath& file_path, |
+ base::PlatformFileError error_code, |
+ base::PassPlatformFile file_handle); |
+ |
// Callback which gets the result of closing the file. |
void DidCloseFile(base::PlatformFileError error); |
@@ -282,6 +295,9 @@ class URLFetcherImpl::Core |
// Where should responses be saved? |
ResponseDestinationType response_destination_; |
+ // Path to the file where the response is written. |
+ FilePath response_destination_file_path_; |
+ |
// If |automatically_retry_on_5xx_| is false, 5xx responses will be |
// propagated to the observer, if it is true URLFetcher will automatically |
// re-execute the request, after the back-off delay has expired. |
@@ -339,6 +355,19 @@ URLFetcherImpl::Core::FileWriter::~FileWriter() { |
RemoveFile(); |
} |
+void URLFetcherImpl::Core::FileWriter::CreateFileAtPath( |
+ const FilePath& file_path) { |
+ DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); |
+ DCHECK(file_message_loop_proxy_.get()); |
+ base::FileUtilProxy::CreateOrOpen( |
+ file_message_loop_proxy_, |
+ file_path, |
+ base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE, |
+ base::Bind(&URLFetcherImpl::Core::FileWriter::DidCreateFile, |
+ weak_factory_.GetWeakPtr(), |
+ file_path)); |
+} |
+ |
void URLFetcherImpl::Core::FileWriter::CreateTempFile() { |
DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); |
DCHECK(file_message_loop_proxy_.get()); |
@@ -349,28 +378,6 @@ void URLFetcherImpl::Core::FileWriter::CreateTempFile() { |
weak_factory_.GetWeakPtr())); |
} |
-void URLFetcherImpl::Core::FileWriter::DidCreateTempFile( |
- base::PlatformFileError error_code, |
- base::PassPlatformFile file_handle, |
- const FilePath& file_path) { |
- DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); |
- |
- if (base::PLATFORM_FILE_OK != error_code) { |
- error_code_ = error_code; |
- RemoveFile(); |
- core_->delegate_loop_proxy_->PostTask( |
- FROM_HERE, base::Bind(&Core::InformDelegateFetchIsComplete, core_)); |
- return; |
- } |
- |
- file_path_ = file_path; |
- file_handle_ = file_handle.ReleaseValue(); |
- total_bytes_written_ = 0; |
- |
- core_->io_message_loop_proxy_->PostTask( |
- FROM_HERE, base::Bind(&Core::StartURLRequestWhenAppropriate, core_)); |
-} |
- |
void URLFetcherImpl::Core::FileWriter::WriteBuffer(int num_bytes) { |
DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); |
@@ -450,6 +457,43 @@ void URLFetcherImpl::Core::FileWriter::CloseFileAndCompleteRequest() { |
} |
} |
+void URLFetcherImpl::Core::FileWriter::DidCreateFile( |
+ const FilePath& file_path, |
+ base::PlatformFileError error_code, |
+ base::PassPlatformFile file_handle, |
+ bool created) { |
+ DidCreateFileInternal(file_path, error_code, file_handle); |
+} |
+ |
+void URLFetcherImpl::Core::FileWriter::DidCreateTempFile( |
+ base::PlatformFileError error_code, |
+ base::PassPlatformFile file_handle, |
+ const FilePath& file_path) { |
+ DidCreateFileInternal(file_path, error_code, file_handle); |
+} |
+ |
+void URLFetcherImpl::Core::FileWriter::DidCreateFileInternal( |
+ const FilePath& file_path, |
+ base::PlatformFileError error_code, |
+ base::PassPlatformFile file_handle) { |
+ DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); |
+ |
+ if (base::PLATFORM_FILE_OK != error_code) { |
+ error_code_ = error_code; |
+ RemoveFile(); |
+ core_->delegate_loop_proxy_->PostTask( |
+ FROM_HERE, base::Bind(&Core::InformDelegateFetchIsComplete, core_)); |
+ return; |
+ } |
+ |
+ file_path_ = file_path; |
+ file_handle_ = file_handle.ReleaseValue(); |
+ total_bytes_written_ = 0; |
+ |
+ core_->io_message_loop_proxy_->PostTask( |
+ FROM_HERE, base::Bind(&Core::StartURLRequestWhenAppropriate, core_)); |
+} |
+ |
void URLFetcherImpl::Core::FileWriter::DidCloseFile( |
base::PlatformFileError error_code) { |
DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); |
@@ -583,16 +627,25 @@ void URLFetcherImpl::Core::StartOnIOThread() { |
StartURLRequestWhenAppropriate(); |
break; |
- case FILE: |
+ case PERMANENT_FILE: |
+ case TEMP_FILE: |
DCHECK(file_message_loop_proxy_.get()) |
<< "Need to set the file message loop proxy."; |
- file_writer_.reset( |
- new FileWriter(this, file_message_loop_proxy_)); |
+ file_writer_.reset(new FileWriter(this, file_message_loop_proxy_)); |
- // If the temp file is successfully created, |
+ // If the file is successfully created, |
// Core::StartURLRequestWhenAppropriate() will be called. |
- file_writer_->CreateTempFile(); |
+ switch (response_destination_) { |
+ case PERMANENT_FILE: |
+ file_writer_->CreateFileAtPath(response_destination_file_path_); |
+ break; |
+ case TEMP_FILE: |
+ file_writer_->CreateTempFile(); |
+ break; |
+ default: |
+ NOTREACHED(); |
+ } |
break; |
default: |
@@ -669,7 +722,8 @@ bool URLFetcherImpl::Core::WriteBuffer(int num_bytes) { |
write_complete = true; |
break; |
- case FILE: |
+ case PERMANENT_FILE: |
+ case TEMP_FILE: |
file_writer_->WriteBuffer(num_bytes); |
// WriteBuffer() sends a request the file thread. |
// The write is not done yet. |
@@ -1032,10 +1086,20 @@ base::TimeDelta URLFetcherImpl::GetBackoffDelay() const { |
return core_->backoff_delay_; |
} |
+void URLFetcherImpl::SaveResponseToFileAtPath( |
+ const FilePath& file_path, |
+ scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy) { |
+ DCHECK(core_->delegate_loop_proxy_->BelongsToCurrentThread()); |
+ core_->file_message_loop_proxy_ = file_message_loop_proxy; |
+ core_->response_destination_ = PERMANENT_FILE; |
+ core_->response_destination_file_path_ = file_path; |
+} |
+ |
void URLFetcherImpl::SaveResponseToTemporaryFile( |
scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy) { |
+ DCHECK(core_->delegate_loop_proxy_->BelongsToCurrentThread()); |
core_->file_message_loop_proxy_ = file_message_loop_proxy; |
- core_->response_destination_ = FILE; |
+ core_->response_destination_ = TEMP_FILE; |
} |
net::HttpResponseHeaders* URLFetcherImpl::GetResponseHeaders() const { |
@@ -1126,7 +1190,9 @@ bool URLFetcherImpl::GetResponseAsString( |
bool URLFetcherImpl::GetResponseAsFilePath(bool take_ownership, |
FilePath* out_response_path) const { |
DCHECK(core_->delegate_loop_proxy_->BelongsToCurrentThread()); |
- if (core_->response_destination_ != FILE || !core_->file_writer_.get()) |
+ const bool destination_is_file = core_->response_destination_ == TEMP_FILE || |
+ core_->response_destination_ == PERMANENT_FILE; |
+ if (!destination_is_file || !core_->file_writer_.get()) |
return false; |
*out_response_path = core_->file_writer_->file_path(); |