Evict resources from resource pool after timeout
[chromium-blink-merge.git] / net / url_request / url_fetcher_response_writer.cc
blobfcc8cbf38ffc4129245cd2cf2ceb63466e112a67
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/url_request/url_fetcher_response_writer.h"
7 #include "base/files/file_util.h"
8 #include "base/location.h"
9 #include "base/sequenced_task_runner.h"
10 #include "base/task_runner_util.h"
11 #include "net/base/file_stream.h"
12 #include "net/base/io_buffer.h"
13 #include "net/base/net_errors.h"
15 namespace net {
17 URLFetcherStringWriter* URLFetcherResponseWriter::AsStringWriter() {
18 return NULL;
21 URLFetcherFileWriter* URLFetcherResponseWriter::AsFileWriter() {
22 return NULL;
25 URLFetcherStringWriter::URLFetcherStringWriter() {
28 URLFetcherStringWriter::~URLFetcherStringWriter() {
31 int URLFetcherStringWriter::Initialize(const CompletionCallback& callback) {
32 data_.clear();
33 return OK;
36 int URLFetcherStringWriter::Write(IOBuffer* buffer,
37 int num_bytes,
38 const CompletionCallback& callback) {
39 data_.append(buffer->data(), num_bytes);
40 return num_bytes;
43 int URLFetcherStringWriter::Finish(const CompletionCallback& callback) {
44 // Do nothing.
45 return OK;
48 URLFetcherStringWriter* URLFetcherStringWriter::AsStringWriter() {
49 return this;
52 URLFetcherFileWriter::URLFetcherFileWriter(
53 scoped_refptr<base::SequencedTaskRunner> file_task_runner,
54 const base::FilePath& file_path)
55 : file_task_runner_(file_task_runner),
56 file_path_(file_path),
57 owns_file_(false),
58 weak_factory_(this) {
59 DCHECK(file_task_runner_.get());
62 URLFetcherFileWriter::~URLFetcherFileWriter() {
63 CloseAndDeleteFile();
66 int URLFetcherFileWriter::Initialize(const CompletionCallback& callback) {
67 file_stream_.reset(new FileStream(file_task_runner_));
69 int result = ERR_IO_PENDING;
70 if (file_path_.empty()) {
71 base::FilePath* temp_file_path = new base::FilePath;
72 base::PostTaskAndReplyWithResult(
73 file_task_runner_.get(),
74 FROM_HERE,
75 base::Bind(&base::CreateTemporaryFile, temp_file_path),
76 base::Bind(&URLFetcherFileWriter::DidCreateTempFile,
77 weak_factory_.GetWeakPtr(),
78 callback,
79 base::Owned(temp_file_path)));
80 } else {
81 result = file_stream_->Open(
82 file_path_,
83 base::File::FLAG_WRITE | base::File::FLAG_ASYNC |
84 base::File::FLAG_CREATE_ALWAYS,
85 base::Bind(&URLFetcherFileWriter::DidOpenFile,
86 weak_factory_.GetWeakPtr(),
87 callback));
88 DCHECK_NE(OK, result);
90 return result;
93 int URLFetcherFileWriter::Write(IOBuffer* buffer,
94 int num_bytes,
95 const CompletionCallback& callback) {
96 DCHECK(file_stream_);
97 DCHECK(owns_file_);
99 int result = file_stream_->Write(buffer, num_bytes,
100 base::Bind(&URLFetcherFileWriter::DidWrite,
101 weak_factory_.GetWeakPtr(),
102 callback));
103 if (result < 0 && result != ERR_IO_PENDING)
104 CloseAndDeleteFile();
106 return result;
109 int URLFetcherFileWriter::Finish(const CompletionCallback& callback) {
110 // If the file_stream_ still exists at this point, close it.
111 if (file_stream_) {
112 int result = file_stream_->Close(base::Bind(
113 &URLFetcherFileWriter::CloseComplete,
114 weak_factory_.GetWeakPtr(), callback));
115 if (result != ERR_IO_PENDING)
116 file_stream_.reset();
117 return result;
119 return OK;
122 URLFetcherFileWriter* URLFetcherFileWriter::AsFileWriter() {
123 return this;
126 void URLFetcherFileWriter::DisownFile() {
127 // Disowning is done by the delegate's OnURLFetchComplete method.
128 // The file should be closed by the time that method is called.
129 DCHECK(!file_stream_);
131 owns_file_ = false;
134 void URLFetcherFileWriter::DidWrite(const CompletionCallback& callback,
135 int result) {
136 if (result < 0)
137 CloseAndDeleteFile();
139 callback.Run(result);
142 void URLFetcherFileWriter::CloseAndDeleteFile() {
143 if (!owns_file_)
144 return;
146 file_stream_.reset();
147 DisownFile();
148 file_task_runner_->PostTask(FROM_HERE,
149 base::Bind(base::IgnoreResult(&base::DeleteFile),
150 file_path_,
151 false /* recursive */));
154 void URLFetcherFileWriter::DidCreateTempFile(const CompletionCallback& callback,
155 base::FilePath* temp_file_path,
156 bool success) {
157 if (!success) {
158 callback.Run(ERR_FILE_NOT_FOUND);
159 return;
161 file_path_ = *temp_file_path;
162 owns_file_ = true;
163 const int result = file_stream_->Open(
164 file_path_,
165 base::File::FLAG_WRITE | base::File::FLAG_ASYNC |
166 base::File::FLAG_OPEN,
167 base::Bind(&URLFetcherFileWriter::DidOpenFile,
168 weak_factory_.GetWeakPtr(),
169 callback));
170 if (result != ERR_IO_PENDING)
171 DidOpenFile(callback, result);
174 void URLFetcherFileWriter::DidOpenFile(const CompletionCallback& callback,
175 int result) {
176 if (result == OK)
177 owns_file_ = true;
178 else
179 CloseAndDeleteFile();
181 callback.Run(result);
184 void URLFetcherFileWriter::CloseComplete(const CompletionCallback& callback,
185 int result) {
186 // Destroy |file_stream_| whether or not the close succeeded.
187 file_stream_.reset();
188 callback.Run(result);
191 } // namespace net