Disable NaClBrowserTestPnacl.Crash on Linux due to flakiness
[chromium-blink-merge.git] / net / url_request / url_fetcher_response_writer.cc
blob7f162aec893f46e244997909d76e4474ac555686
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/profiler/scoped_tracker.h"
10 #include "base/sequenced_task_runner.h"
11 #include "base/task_runner_util.h"
12 #include "net/base/file_stream.h"
13 #include "net/base/io_buffer.h"
14 #include "net/base/net_errors.h"
16 namespace net {
18 URLFetcherStringWriter* URLFetcherResponseWriter::AsStringWriter() {
19 return NULL;
22 URLFetcherFileWriter* URLFetcherResponseWriter::AsFileWriter() {
23 return NULL;
26 URLFetcherStringWriter::URLFetcherStringWriter() {
29 URLFetcherStringWriter::~URLFetcherStringWriter() {
32 int URLFetcherStringWriter::Initialize(const CompletionCallback& callback) {
33 data_.clear();
34 return OK;
37 int URLFetcherStringWriter::Write(IOBuffer* buffer,
38 int num_bytes,
39 const CompletionCallback& callback) {
40 data_.append(buffer->data(), num_bytes);
41 return num_bytes;
44 int URLFetcherStringWriter::Finish(const CompletionCallback& callback) {
45 // Do nothing.
46 return OK;
49 URLFetcherStringWriter* URLFetcherStringWriter::AsStringWriter() {
50 return this;
53 URLFetcherFileWriter::URLFetcherFileWriter(
54 scoped_refptr<base::SequencedTaskRunner> file_task_runner,
55 const base::FilePath& file_path)
56 : file_task_runner_(file_task_runner),
57 file_path_(file_path),
58 owns_file_(false),
59 weak_factory_(this) {
60 DCHECK(file_task_runner_.get());
63 URLFetcherFileWriter::~URLFetcherFileWriter() {
64 CloseAndDeleteFile();
67 int URLFetcherFileWriter::Initialize(const CompletionCallback& callback) {
68 file_stream_.reset(new FileStream(file_task_runner_));
70 int result = ERR_IO_PENDING;
71 if (file_path_.empty()) {
72 base::FilePath* temp_file_path = new base::FilePath;
73 base::PostTaskAndReplyWithResult(
74 file_task_runner_.get(),
75 FROM_HERE,
76 base::Bind(&base::CreateTemporaryFile, temp_file_path),
77 base::Bind(&URLFetcherFileWriter::DidCreateTempFile,
78 weak_factory_.GetWeakPtr(),
79 callback,
80 base::Owned(temp_file_path)));
81 } else {
82 result = file_stream_->Open(
83 file_path_,
84 base::File::FLAG_WRITE | base::File::FLAG_ASYNC |
85 base::File::FLAG_CREATE_ALWAYS,
86 base::Bind(&URLFetcherFileWriter::DidOpenFile,
87 weak_factory_.GetWeakPtr(),
88 callback));
89 DCHECK_NE(OK, result);
91 return result;
94 int URLFetcherFileWriter::Write(IOBuffer* buffer,
95 int num_bytes,
96 const CompletionCallback& callback) {
97 DCHECK(file_stream_);
98 DCHECK(owns_file_);
100 int result = file_stream_->Write(buffer, num_bytes,
101 base::Bind(&URLFetcherFileWriter::DidWrite,
102 weak_factory_.GetWeakPtr(),
103 callback));
104 if (result < 0 && result != ERR_IO_PENDING)
105 CloseAndDeleteFile();
107 return result;
110 int URLFetcherFileWriter::Finish(const CompletionCallback& callback) {
111 // If the file_stream_ still exists at this point, close it.
112 if (file_stream_) {
113 int result = file_stream_->Close(base::Bind(
114 &URLFetcherFileWriter::CloseComplete,
115 weak_factory_.GetWeakPtr(), callback));
116 if (result != ERR_IO_PENDING)
117 file_stream_.reset();
118 return result;
120 return OK;
123 URLFetcherFileWriter* URLFetcherFileWriter::AsFileWriter() {
124 return this;
127 void URLFetcherFileWriter::DisownFile() {
128 // Disowning is done by the delegate's OnURLFetchComplete method.
129 // The file should be closed by the time that method is called.
130 DCHECK(!file_stream_);
132 owns_file_ = false;
135 void URLFetcherFileWriter::DidWrite(const CompletionCallback& callback,
136 int result) {
137 if (result < 0)
138 CloseAndDeleteFile();
140 callback.Run(result);
143 void URLFetcherFileWriter::CloseAndDeleteFile() {
144 if (!owns_file_)
145 return;
147 file_stream_.reset();
148 DisownFile();
149 file_task_runner_->PostTask(FROM_HERE,
150 base::Bind(base::IgnoreResult(&base::DeleteFile),
151 file_path_,
152 false /* recursive */));
155 void URLFetcherFileWriter::DidCreateTempFile(const CompletionCallback& callback,
156 base::FilePath* temp_file_path,
157 bool success) {
158 if (!success) {
159 callback.Run(ERR_FILE_NOT_FOUND);
160 return;
162 file_path_ = *temp_file_path;
163 owns_file_ = true;
164 const int result = file_stream_->Open(
165 file_path_,
166 base::File::FLAG_WRITE | base::File::FLAG_ASYNC |
167 base::File::FLAG_OPEN,
168 base::Bind(&URLFetcherFileWriter::DidOpenFile,
169 weak_factory_.GetWeakPtr(),
170 callback));
171 if (result != ERR_IO_PENDING)
172 DidOpenFile(callback, result);
175 void URLFetcherFileWriter::DidOpenFile(const CompletionCallback& callback,
176 int result) {
177 // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
178 tracked_objects::ScopedTracker tracking_profile(
179 FROM_HERE_WITH_EXPLICIT_FUNCTION(
180 "423948 URLFetcherFileWriter::DidOpenFile"));
182 if (result == OK)
183 owns_file_ = true;
184 else
185 CloseAndDeleteFile();
187 callback.Run(result);
190 void URLFetcherFileWriter::CloseComplete(const CompletionCallback& callback,
191 int result) {
192 // Destroy |file_stream_| whether or not the close succeeded.
193 file_stream_.reset();
194 callback.Run(result);
197 } // namespace net