| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/base/upload_file_element_reader.h" | 5 #include "net/base/upload_file_element_reader.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/task_runner_util.h" | 10 #include "base/task_runner_util.h" |
| 11 #include "base/threading/worker_pool.h" | |
| 12 #include "net/base/file_stream.h" | 11 #include "net/base/file_stream.h" |
| 13 #include "net/base/io_buffer.h" | 12 #include "net/base/io_buffer.h" |
| 14 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
| 15 | 14 |
| 16 namespace net { | 15 namespace net { |
| 17 | 16 |
| 18 namespace { | 17 namespace { |
| 19 | 18 |
| 20 // In tests, this value is used to override the return value of | 19 // In tests, this value is used to override the return value of |
| 21 // UploadFileElementReader::GetContentLength() when set to non-zero. | 20 // UploadFileElementReader::GetContentLength() when set to non-zero. |
| 22 uint64 overriding_content_length = 0; | 21 uint64 overriding_content_length = 0; |
| 23 | 22 |
| 24 // This function is used to implement Init(). | 23 // This function is used to implement Init(). |
| 24 template<typename FileStreamDeleter> |
| 25 int InitInternal(const FilePath& path, | 25 int InitInternal(const FilePath& path, |
| 26 uint64 range_offset, | 26 uint64 range_offset, |
| 27 uint64 range_length, | 27 uint64 range_length, |
| 28 const base::Time& expected_modification_time, | 28 const base::Time& expected_modification_time, |
| 29 UploadFileElementReader::ScopedFileStreamPtr* out_file_stream, | 29 scoped_ptr<FileStream, FileStreamDeleter>* out_file_stream, |
| 30 uint64* out_content_length) { | 30 uint64* out_content_length) { |
| 31 scoped_ptr<FileStream> file_stream(new FileStream(NULL)); | 31 scoped_ptr<FileStream> file_stream(new FileStream(NULL)); |
| 32 int64 rv = file_stream->OpenSync( | 32 int64 rv = file_stream->OpenSync( |
| 33 path, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ); | 33 path, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ); |
| 34 if (rv != OK) { | 34 if (rv != OK) { |
| 35 // If the file can't be opened, we'll just upload an empty file. | 35 // If the file can't be opened, we'll just upload an empty file. |
| 36 DLOG(WARNING) << "Failed to open \"" << path.value() | 36 DLOG(WARNING) << "Failed to open \"" << path.value() |
| 37 << "\" for reading: " << rv; | 37 << "\" for reading: " << rv; |
| 38 file_stream.reset(); | 38 file_stream.reset(); |
| 39 } else if (range_offset) { | 39 } else if (range_offset) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 DCHECK(file_stream); // file_stream is non-null if content_length_ > 0. | 85 DCHECK(file_stream); // file_stream is non-null if content_length_ > 0. |
| 86 result = file_stream->ReadSync(buf->data(), num_bytes_to_read); | 86 result = file_stream->ReadSync(buf->data(), num_bytes_to_read); |
| 87 if (result == 0) // Reached end-of-file earlier than expected. | 87 if (result == 0) // Reached end-of-file earlier than expected. |
| 88 result = ERR_UPLOAD_FILE_CHANGED; | 88 result = ERR_UPLOAD_FILE_CHANGED; |
| 89 } | 89 } |
| 90 return result; | 90 return result; |
| 91 } | 91 } |
| 92 | 92 |
| 93 } // namespace | 93 } // namespace |
| 94 | 94 |
| 95 UploadFileElementReader::FileStreamDeleter::FileStreamDeleter( |
| 96 base::TaskRunner* task_runner) : task_runner_(task_runner) { |
| 97 DCHECK(task_runner_); |
| 98 } |
| 99 |
| 100 UploadFileElementReader::FileStreamDeleter::~FileStreamDeleter() {} |
| 101 |
| 95 void UploadFileElementReader::FileStreamDeleter::operator() ( | 102 void UploadFileElementReader::FileStreamDeleter::operator() ( |
| 96 FileStream* file_stream) const { | 103 FileStream* file_stream) const { |
| 97 if (file_stream) { | 104 if (file_stream) { |
| 98 base::WorkerPool::PostTask(FROM_HERE, | 105 task_runner_->PostTask(FROM_HERE, |
| 99 base::Bind(&base::DeletePointer<FileStream>, | 106 base::Bind(&base::DeletePointer<FileStream>, |
| 100 file_stream), | 107 file_stream)); |
| 101 true /* task_is_slow */); | |
| 102 } | 108 } |
| 103 } | 109 } |
| 104 | 110 |
| 105 UploadFileElementReader::UploadFileElementReader( | 111 UploadFileElementReader::UploadFileElementReader( |
| 112 base::TaskRunner* task_runner, |
| 106 const FilePath& path, | 113 const FilePath& path, |
| 107 uint64 range_offset, | 114 uint64 range_offset, |
| 108 uint64 range_length, | 115 uint64 range_length, |
| 109 const base::Time& expected_modification_time) | 116 const base::Time& expected_modification_time) |
| 110 : path_(path), | 117 : task_runner_(task_runner), |
| 118 path_(path), |
| 111 range_offset_(range_offset), | 119 range_offset_(range_offset), |
| 112 range_length_(range_length), | 120 range_length_(range_length), |
| 113 expected_modification_time_(expected_modification_time), | 121 expected_modification_time_(expected_modification_time), |
| 122 file_stream_(NULL, FileStreamDeleter(task_runner_)), |
| 114 content_length_(0), | 123 content_length_(0), |
| 115 bytes_remaining_(0), | 124 bytes_remaining_(0), |
| 116 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | 125 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
| 126 DCHECK(task_runner_); |
| 117 } | 127 } |
| 118 | 128 |
| 119 UploadFileElementReader::~UploadFileElementReader() { | 129 UploadFileElementReader::~UploadFileElementReader() { |
| 120 } | 130 } |
| 121 | 131 |
| 122 const UploadFileElementReader* UploadFileElementReader::AsFileReader() const { | 132 const UploadFileElementReader* UploadFileElementReader::AsFileReader() const { |
| 123 return this; | 133 return this; |
| 124 } | 134 } |
| 125 | 135 |
| 126 int UploadFileElementReader::Init(const CompletionCallback& callback) { | 136 int UploadFileElementReader::Init(const CompletionCallback& callback) { |
| 127 DCHECK(!callback.is_null()); | 137 DCHECK(!callback.is_null()); |
| 128 Reset(); | 138 Reset(); |
| 129 | 139 |
| 130 ScopedFileStreamPtr* file_stream = new ScopedFileStreamPtr; | 140 ScopedFileStreamPtr* file_stream = |
| 141 new ScopedFileStreamPtr(NULL, FileStreamDeleter(task_runner_)); |
| 131 uint64* content_length = new uint64; | 142 uint64* content_length = new uint64; |
| 132 const bool posted = base::PostTaskAndReplyWithResult( | 143 const bool posted = base::PostTaskAndReplyWithResult( |
| 133 base::WorkerPool::GetTaskRunner(true /* task_is_slow */), | 144 task_runner_, |
| 134 FROM_HERE, | 145 FROM_HERE, |
| 135 base::Bind(&InitInternal, | 146 base::Bind(&InitInternal<FileStreamDeleter>, |
| 136 path_, | 147 path_, |
| 137 range_offset_, | 148 range_offset_, |
| 138 range_length_, | 149 range_length_, |
| 139 expected_modification_time_, | 150 expected_modification_time_, |
| 140 file_stream, | 151 file_stream, |
| 141 content_length), | 152 content_length), |
| 142 base::Bind(&UploadFileElementReader::OnInitCompleted, | 153 base::Bind(&UploadFileElementReader::OnInitCompleted, |
| 143 weak_ptr_factory_.GetWeakPtr(), | 154 weak_ptr_factory_.GetWeakPtr(), |
| 144 base::Owned(file_stream), | 155 base::Owned(file_stream), |
| 145 base::Owned(content_length), | 156 base::Owned(content_length), |
| (...skipping 18 matching lines...) Expand all Loading... |
| 164 DCHECK(!callback.is_null()); | 175 DCHECK(!callback.is_null()); |
| 165 | 176 |
| 166 if (BytesRemaining() == 0) | 177 if (BytesRemaining() == 0) |
| 167 return 0; | 178 return 0; |
| 168 | 179 |
| 169 // Save the value of file_stream_.get() before base::Passed() invalidates it. | 180 // Save the value of file_stream_.get() before base::Passed() invalidates it. |
| 170 FileStream* file_stream_ptr = file_stream_.get(); | 181 FileStream* file_stream_ptr = file_stream_.get(); |
| 171 // Pass the ownership of file_stream_ to the worker pool to safely perform | 182 // Pass the ownership of file_stream_ to the worker pool to safely perform |
| 172 // operation even when |this| is destructed before the read completes. | 183 // operation even when |this| is destructed before the read completes. |
| 173 const bool posted = base::PostTaskAndReplyWithResult( | 184 const bool posted = base::PostTaskAndReplyWithResult( |
| 174 base::WorkerPool::GetTaskRunner(true /* task_is_slow */), | 185 task_runner_, |
| 175 FROM_HERE, | 186 FROM_HERE, |
| 176 base::Bind(&ReadInternal, | 187 base::Bind(&ReadInternal, |
| 177 scoped_refptr<IOBuffer>(buf), | 188 scoped_refptr<IOBuffer>(buf), |
| 178 buf_length, | 189 buf_length, |
| 179 BytesRemaining(), | 190 BytesRemaining(), |
| 180 file_stream_ptr), | 191 file_stream_ptr), |
| 181 base::Bind(&UploadFileElementReader::OnReadCompleted, | 192 base::Bind(&UploadFileElementReader::OnReadCompleted, |
| 182 weak_ptr_factory_.GetWeakPtr(), | 193 weak_ptr_factory_.GetWeakPtr(), |
| 183 base::Passed(&file_stream_), | 194 base::Passed(&file_stream_), |
| 184 callback)); | 195 callback)); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 } | 253 } |
| 243 | 254 |
| 244 UploadFileElementReaderSync::~UploadFileElementReaderSync() { | 255 UploadFileElementReaderSync::~UploadFileElementReaderSync() { |
| 245 } | 256 } |
| 246 | 257 |
| 247 int UploadFileElementReaderSync::Init(const CompletionCallback& callback) { | 258 int UploadFileElementReaderSync::Init(const CompletionCallback& callback) { |
| 248 bytes_remaining_ = 0; | 259 bytes_remaining_ = 0; |
| 249 content_length_ = 0; | 260 content_length_ = 0; |
| 250 file_stream_.reset(); | 261 file_stream_.reset(); |
| 251 | 262 |
| 252 UploadFileElementReader::ScopedFileStreamPtr file_stream; | |
| 253 | |
| 254 const int result = InitInternal(path_, range_offset_, range_length_, | 263 const int result = InitInternal(path_, range_offset_, range_length_, |
| 255 expected_modification_time_, | 264 expected_modification_time_, |
| 256 &file_stream, &content_length_); | 265 &file_stream_, &content_length_); |
| 257 file_stream_.reset(file_stream.release()); | |
| 258 bytes_remaining_ = GetContentLength(); | 266 bytes_remaining_ = GetContentLength(); |
| 259 return result; | 267 return result; |
| 260 } | 268 } |
| 261 | 269 |
| 262 uint64 UploadFileElementReaderSync::GetContentLength() const { | 270 uint64 UploadFileElementReaderSync::GetContentLength() const { |
| 263 return content_length_; | 271 return content_length_; |
| 264 } | 272 } |
| 265 | 273 |
| 266 uint64 UploadFileElementReaderSync::BytesRemaining() const { | 274 uint64 UploadFileElementReaderSync::BytesRemaining() const { |
| 267 return bytes_remaining_; | 275 return bytes_remaining_; |
| 268 } | 276 } |
| 269 | 277 |
| 270 int UploadFileElementReaderSync::Read(IOBuffer* buf, | 278 int UploadFileElementReaderSync::Read(IOBuffer* buf, |
| 271 int buf_length, | 279 int buf_length, |
| 272 const CompletionCallback& callback) { | 280 const CompletionCallback& callback) { |
| 273 const int result = ReadInternal(buf, buf_length, BytesRemaining(), | 281 const int result = ReadInternal(buf, buf_length, BytesRemaining(), |
| 274 file_stream_.get()); | 282 file_stream_.get()); |
| 275 if (result > 0) { | 283 if (result > 0) { |
| 276 DCHECK_GE(static_cast<int>(bytes_remaining_), result); | 284 DCHECK_GE(static_cast<int>(bytes_remaining_), result); |
| 277 bytes_remaining_ -= result; | 285 bytes_remaining_ -= result; |
| 278 } | 286 } |
| 279 return result; | 287 return result; |
| 280 } | 288 } |
| 281 | 289 |
| 282 } // namespace net | 290 } // namespace net |
| OLD | NEW |