12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_fetcher_response_writer.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/location.h" 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/sequenced_task_runner.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/task_runner_util.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/base/file_stream.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/io_buffer.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_errors.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net { 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)URLFetcherStringWriter* URLFetcherResponseWriter::AsStringWriter() { 184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return NULL; 194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)URLFetcherFileWriter* URLFetcherResponseWriter::AsFileWriter() { 224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return NULL; 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)URLFetcherStringWriter::URLFetcherStringWriter() { 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)URLFetcherStringWriter::~URLFetcherStringWriter() { 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int URLFetcherStringWriter::Initialize(const CompletionCallback& callback) { 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) data_.clear(); 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return OK; 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int URLFetcherStringWriter::Write(IOBuffer* buffer, 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_bytes, 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CompletionCallback& callback) { 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) data_.append(buffer->data(), num_bytes); 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return num_bytes; 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int URLFetcherStringWriter::Finish(const CompletionCallback& callback) { 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Do nothing. 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return OK; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)URLFetcherStringWriter* URLFetcherStringWriter::AsStringWriter() { 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return this; 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)URLFetcherFileWriter::URLFetcherFileWriter( 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> file_task_runner, 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const base::FilePath& file_path) 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : file_task_runner_(file_task_runner), 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) file_path_(file_path), 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) owns_file_(false), 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) weak_factory_(this) { 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(file_task_runner_.get()); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)URLFetcherFileWriter::~URLFetcherFileWriter() { 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloseAndDeleteFile(); 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int URLFetcherFileWriter::Initialize(const CompletionCallback& callback) { 675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu file_stream_.reset(new FileStream(file_task_runner_)); 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int result = ERR_IO_PENDING; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (file_path_.empty()) { 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath* temp_file_path = new base::FilePath; 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PostTaskAndReplyWithResult( 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_task_runner_.get(), 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&base::CreateTemporaryFile, temp_file_path), 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&URLFetcherFileWriter::DidCreateTempFile, 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_factory_.GetWeakPtr(), 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback, 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Owned(temp_file_path))); 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result = file_stream_->Open( 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_path_, 8323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::File::FLAG_WRITE | base::File::FLAG_ASYNC | 8423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::File::FLAG_CREATE_ALWAYS, 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&URLFetcherFileWriter::DidOpenFile, 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_factory_.GetWeakPtr(), 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback)); 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_NE(OK, result); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return result; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int URLFetcherFileWriter::Write(IOBuffer* buffer, 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_bytes, 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CompletionCallback& callback) { 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(file_stream_); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(owns_file_); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int result = file_stream_->Write(buffer, num_bytes, 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&URLFetcherFileWriter::DidWrite, 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) weak_factory_.GetWeakPtr(), 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback)); 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (result < 0 && result != ERR_IO_PENDING) 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CloseAndDeleteFile(); 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return result; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int URLFetcherFileWriter::Finish(const CompletionCallback& callback) { 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If the file_stream_ still exists at this point, close it. 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (file_stream_) { 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int result = file_stream_->Close(base::Bind( 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &URLFetcherFileWriter::CloseComplete, 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) weak_factory_.GetWeakPtr(), callback)); 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (result != ERR_IO_PENDING) 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) file_stream_.reset(); 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return result; 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return OK; 12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)URLFetcherFileWriter* URLFetcherFileWriter::AsFileWriter() { 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return this; 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLFetcherFileWriter::DisownFile() { 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Disowning is done by the delegate's OnURLFetchComplete method. 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The file should be closed by the time that method is called. 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!file_stream_); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) owns_file_ = false; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void URLFetcherFileWriter::DidWrite(const CompletionCallback& callback, 1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int result) { 1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (result < 0) 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CloseAndDeleteFile(); 1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) callback.Run(result); 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLFetcherFileWriter::CloseAndDeleteFile() { 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!owns_file_) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_stream_.reset(); 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DisownFile(); 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_task_runner_->PostTask(FROM_HERE, 1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(base::IgnoreResult(&base::DeleteFile), 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_path_, 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false /* recursive */)); 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void URLFetcherFileWriter::DidCreateTempFile(const CompletionCallback& callback, 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath* temp_file_path, 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool success) { 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!success) { 1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) callback.Run(ERR_FILE_NOT_FOUND); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_path_ = *temp_file_path; 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) owns_file_ = true; 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int result = file_stream_->Open( 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_path_, 16523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::File::FLAG_WRITE | base::File::FLAG_ASYNC | 16623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::File::FLAG_OPEN, 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&URLFetcherFileWriter::DidOpenFile, 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_.GetWeakPtr(), 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback)); 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (result != ERR_IO_PENDING) 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DidOpenFile(callback, result); 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void URLFetcherFileWriter::DidOpenFile(const CompletionCallback& callback, 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int result) { 1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (result == OK) 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) owns_file_ = true; 1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) else 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloseAndDeleteFile(); 1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) callback.Run(result); 1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void URLFetcherFileWriter::CloseComplete(const CompletionCallback& callback, 1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int result) { 1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Destroy |file_stream_| whether or not the close succeeded. 1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) file_stream_.reset(); 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(result); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace net 192