Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / net / url_request / url_fetcher_response_writer.cc
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.
4
5 #include "net/url_request/url_fetcher_response_writer.h"
6
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"
15
16 namespace net {
17
18 URLFetcherStringWriter* URLFetcherResponseWriter::AsStringWriter() {
19   return NULL;
20 }
21
22 URLFetcherFileWriter* URLFetcherResponseWriter::AsFileWriter() {
23   return NULL;
24 }
25
26 URLFetcherStringWriter::URLFetcherStringWriter() {
27 }
28
29 URLFetcherStringWriter::~URLFetcherStringWriter() {
30 }
31
32 int URLFetcherStringWriter::Initialize(const CompletionCallback& callback) {
33   data_.clear();
34   return OK;
35 }
36
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;
42 }
43
44 int URLFetcherStringWriter::Finish(const CompletionCallback& callback) {
45   // Do nothing.
46   return OK;
47 }
48
49 URLFetcherStringWriter* URLFetcherStringWriter::AsStringWriter() {
50   return this;
51 }
52
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());
61 }
62
63 URLFetcherFileWriter::~URLFetcherFileWriter() {
64   CloseAndDeleteFile();
65 }
66
67 int URLFetcherFileWriter::Initialize(const CompletionCallback& callback) {
68   file_stream_.reset(new FileStream(file_task_runner_));
69
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);
90   }
91   return result;
92 }
93
94 int URLFetcherFileWriter::Write(IOBuffer* buffer,
95                                 int num_bytes,
96                                 const CompletionCallback& callback) {
97   DCHECK(file_stream_);
98   DCHECK(owns_file_);
99
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();
106
107   return result;
108 }
109
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;
119   }
120   return OK;
121 }
122
123 URLFetcherFileWriter* URLFetcherFileWriter::AsFileWriter() {
124   return this;
125 }
126
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_);
131
132   owns_file_ = false;
133 }
134
135 void URLFetcherFileWriter::DidWrite(const CompletionCallback& callback,
136                                     int result) {
137   if (result < 0)
138     CloseAndDeleteFile();
139
140   callback.Run(result);
141 }
142
143 void URLFetcherFileWriter::CloseAndDeleteFile() {
144   if (!owns_file_)
145     return;
146
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 */));
153 }
154
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;
161   }
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);
173 }
174
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"));
181
182   if (result == OK)
183     owns_file_ = true;
184   else
185     CloseAndDeleteFile();
186
187   callback.Run(result);
188 }
189
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);
195 }
196
197 }  // namespace net