| 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/files/file_util.h" | 8 #include "base/files/file_util.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/profiler/scoped_tracker.h" | 10 #include "base/profiler/scoped_tracker.h" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 return this; | 47 return this; |
| 48 } | 48 } |
| 49 | 49 |
| 50 int UploadFileElementReader::Init(const CompletionCallback& callback) { | 50 int UploadFileElementReader::Init(const CompletionCallback& callback) { |
| 51 DCHECK(!callback.is_null()); | 51 DCHECK(!callback.is_null()); |
| 52 Reset(); | 52 Reset(); |
| 53 | 53 |
| 54 file_stream_.reset(new FileStream(task_runner_.get())); | 54 file_stream_.reset(new FileStream(task_runner_.get())); |
| 55 int result = file_stream_->Open( | 55 int result = file_stream_->Open( |
| 56 path_, | 56 path_, |
| 57 base::File::FLAG_OPEN | base::File::FLAG_READ | | 57 base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_ASYNC, |
| 58 base::File::FLAG_ASYNC, | |
| 59 base::Bind(&UploadFileElementReader::OnOpenCompleted, | 58 base::Bind(&UploadFileElementReader::OnOpenCompleted, |
| 60 weak_ptr_factory_.GetWeakPtr(), | 59 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 61 callback)); | |
| 62 DCHECK_GT(0, result); | 60 DCHECK_GT(0, result); |
| 63 return result; | 61 return result; |
| 64 } | 62 } |
| 65 | 63 |
| 66 uint64 UploadFileElementReader::GetContentLength() const { | 64 uint64 UploadFileElementReader::GetContentLength() const { |
| 67 if (overriding_content_length) | 65 if (overriding_content_length) |
| 68 return overriding_content_length; | 66 return overriding_content_length; |
| 69 return content_length_; | 67 return content_length_; |
| 70 } | 68 } |
| 71 | 69 |
| 72 uint64 UploadFileElementReader::BytesRemaining() const { | 70 uint64 UploadFileElementReader::BytesRemaining() const { |
| 73 return bytes_remaining_; | 71 return bytes_remaining_; |
| 74 } | 72 } |
| 75 | 73 |
| 76 int UploadFileElementReader::Read(IOBuffer* buf, | 74 int UploadFileElementReader::Read(IOBuffer* buf, |
| 77 int buf_length, | 75 int buf_length, |
| 78 const CompletionCallback& callback) { | 76 const CompletionCallback& callback) { |
| 79 DCHECK(!callback.is_null()); | 77 DCHECK(!callback.is_null()); |
| 80 | 78 |
| 81 uint64 num_bytes_to_read = | 79 uint64 num_bytes_to_read = |
| 82 std::min(BytesRemaining(), static_cast<uint64>(buf_length)); | 80 std::min(BytesRemaining(), static_cast<uint64>(buf_length)); |
| 83 if (num_bytes_to_read == 0) | 81 if (num_bytes_to_read == 0) |
| 84 return 0; | 82 return 0; |
| 85 | 83 |
| 86 int result = file_stream_->Read( | 84 int result = file_stream_->Read( |
| 87 buf, num_bytes_to_read, | 85 buf, num_bytes_to_read, |
| 88 base::Bind(base::IgnoreResult(&UploadFileElementReader::OnReadCompleted), | 86 base::Bind(base::IgnoreResult(&UploadFileElementReader::OnReadCompleted), |
| 89 weak_ptr_factory_.GetWeakPtr(), | 87 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 90 callback)); | |
| 91 // Even in async mode, FileStream::Read() may return the result synchronously. | 88 // Even in async mode, FileStream::Read() may return the result synchronously. |
| 92 if (result != ERR_IO_PENDING) | 89 if (result != ERR_IO_PENDING) |
| 93 return OnReadCompleted(CompletionCallback(), result); | 90 return OnReadCompleted(CompletionCallback(), result); |
| 94 return ERR_IO_PENDING; | 91 return ERR_IO_PENDING; |
| 95 } | 92 } |
| 96 | 93 |
| 97 void UploadFileElementReader::Reset() { | 94 void UploadFileElementReader::Reset() { |
| 98 weak_ptr_factory_.InvalidateWeakPtrs(); | 95 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 99 bytes_remaining_ = 0; | 96 bytes_remaining_ = 0; |
| 100 content_length_ = 0; | 97 content_length_ = 0; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 115 DLOG(WARNING) << "Failed to open \"" << path_.value() | 112 DLOG(WARNING) << "Failed to open \"" << path_.value() |
| 116 << "\" for reading: " << result; | 113 << "\" for reading: " << result; |
| 117 callback.Run(result); | 114 callback.Run(result); |
| 118 return; | 115 return; |
| 119 } | 116 } |
| 120 | 117 |
| 121 if (range_offset_) { | 118 if (range_offset_) { |
| 122 int result = file_stream_->Seek( | 119 int result = file_stream_->Seek( |
| 123 base::File::FROM_BEGIN, range_offset_, | 120 base::File::FROM_BEGIN, range_offset_, |
| 124 base::Bind(&UploadFileElementReader::OnSeekCompleted, | 121 base::Bind(&UploadFileElementReader::OnSeekCompleted, |
| 125 weak_ptr_factory_.GetWeakPtr(), | 122 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 126 callback)); | |
| 127 DCHECK_GT(0, result); | 123 DCHECK_GT(0, result); |
| 128 if (result != ERR_IO_PENDING) | 124 if (result != ERR_IO_PENDING) |
| 129 callback.Run(result); | 125 callback.Run(result); |
| 130 } else { | 126 } else { |
| 131 OnSeekCompleted(callback, OK); | 127 OnSeekCompleted(callback, OK); |
| 132 } | 128 } |
| 133 } | 129 } |
| 134 | 130 |
| 135 void UploadFileElementReader::OnSeekCompleted( | 131 void UploadFileElementReader::OnSeekCompleted( |
| 136 const CompletionCallback& callback, | 132 const CompletionCallback& callback, |
| 137 int64 result) { | 133 int64 result) { |
| 138 DCHECK(!callback.is_null()); | 134 DCHECK(!callback.is_null()); |
| 139 | 135 |
| 140 if (result < 0) { | 136 if (result < 0) { |
| 141 DLOG(WARNING) << "Failed to seek \"" << path_.value() | 137 DLOG(WARNING) << "Failed to seek \"" << path_.value() |
| 142 << "\" to offset: " << range_offset_ << " (" << result << ")"; | 138 << "\" to offset: " << range_offset_ << " (" << result << ")"; |
| 143 callback.Run(result); | 139 callback.Run(result); |
| 144 return; | 140 return; |
| 145 } | 141 } |
| 146 | 142 |
| 147 base::File::Info* file_info = new base::File::Info; | 143 base::File::Info* file_info = new base::File::Info; |
| 148 bool posted = base::PostTaskAndReplyWithResult( | 144 bool posted = base::PostTaskAndReplyWithResult( |
| 149 task_runner_.get(), | 145 task_runner_.get(), FROM_HERE, |
| 150 FROM_HERE, | |
| 151 base::Bind(&base::GetFileInfo, path_, file_info), | 146 base::Bind(&base::GetFileInfo, path_, file_info), |
| 152 base::Bind(&UploadFileElementReader::OnGetFileInfoCompleted, | 147 base::Bind(&UploadFileElementReader::OnGetFileInfoCompleted, |
| 153 weak_ptr_factory_.GetWeakPtr(), | 148 weak_ptr_factory_.GetWeakPtr(), callback, |
| 154 callback, | |
| 155 base::Owned(file_info))); | 149 base::Owned(file_info))); |
| 156 DCHECK(posted); | 150 DCHECK(posted); |
| 157 } | 151 } |
| 158 | 152 |
| 159 void UploadFileElementReader::OnGetFileInfoCompleted( | 153 void UploadFileElementReader::OnGetFileInfoCompleted( |
| 160 const CompletionCallback& callback, | 154 const CompletionCallback& callback, |
| 161 base::File::Info* file_info, | 155 base::File::Info* file_info, |
| 162 bool result) { | 156 bool result) { |
| 163 DCHECK(!callback.is_null()); | 157 DCHECK(!callback.is_null()); |
| 164 if (!result) { | 158 if (!result) { |
| 165 DLOG(WARNING) << "Failed to get file info of \"" << path_.value() << "\""; | 159 DLOG(WARNING) << "Failed to get file info of \"" << path_.value() << "\""; |
| 166 callback.Run(ERR_FILE_NOT_FOUND); | 160 callback.Run(ERR_FILE_NOT_FOUND); |
| 167 return; | 161 return; |
| 168 } | 162 } |
| 169 | 163 |
| 170 int64 length = file_info->size; | 164 int64 length = file_info->size; |
| 171 if (range_offset_ < static_cast<uint64>(length)) { | 165 if (range_offset_ < static_cast<uint64>(length)) { |
| 172 // Compensate for the offset. | 166 // Compensate for the offset. |
| 173 length = std::min(length - range_offset_, range_length_); | 167 length = std::min(length - range_offset_, range_length_); |
| 174 } | 168 } |
| 175 | 169 |
| 176 // If the underlying file has been changed and the expected file modification | 170 // If the underlying file has been changed and the expected file modification |
| 177 // time is set, treat it as error. Note that the expected modification time | 171 // time is set, treat it as error. Note that the expected modification time |
| 178 // from WebKit is based on time_t precision. So we have to convert both to | 172 // from WebKit is based on time_t precision. So we have to convert both to |
| 179 // time_t to compare. This check is used for sliced files. | 173 // time_t to compare. This check is used for sliced files. |
| 180 if (!expected_modification_time_.is_null() && | 174 if (!expected_modification_time_.is_null() && |
| 181 expected_modification_time_.ToTimeT() != | 175 expected_modification_time_.ToTimeT() != |
| 182 file_info->last_modified.ToTimeT()) { | 176 file_info->last_modified.ToTimeT()) { |
| 183 callback.Run(ERR_UPLOAD_FILE_CHANGED); | 177 callback.Run(ERR_UPLOAD_FILE_CHANGED); |
| 184 return; | 178 return; |
| 185 } | 179 } |
| 186 | 180 |
| 187 content_length_ = length; | 181 content_length_ = length; |
| 188 bytes_remaining_ = GetContentLength(); | 182 bytes_remaining_ = GetContentLength(); |
| 189 callback.Run(OK); | 183 callback.Run(OK); |
| 190 } | 184 } |
| 191 | 185 |
| 192 int UploadFileElementReader::OnReadCompleted( | 186 int UploadFileElementReader::OnReadCompleted(const CompletionCallback& callback, |
| 193 const CompletionCallback& callback, | 187 int result) { |
| 194 int result) { | |
| 195 if (result == 0) // Reached end-of-file earlier than expected. | 188 if (result == 0) // Reached end-of-file earlier than expected. |
| 196 result = ERR_UPLOAD_FILE_CHANGED; | 189 result = ERR_UPLOAD_FILE_CHANGED; |
| 197 | 190 |
| 198 if (result > 0) { | 191 if (result > 0) { |
| 199 DCHECK_GE(bytes_remaining_, static_cast<uint64>(result)); | 192 DCHECK_GE(bytes_remaining_, static_cast<uint64>(result)); |
| 200 bytes_remaining_ -= result; | 193 bytes_remaining_ -= result; |
| 201 } | 194 } |
| 202 | 195 |
| 203 if (!callback.is_null()) | 196 if (!callback.is_null()) |
| 204 callback.Run(result); | 197 callback.Run(result); |
| 205 return result; | 198 return result; |
| 206 } | 199 } |
| 207 | 200 |
| 208 UploadFileElementReader::ScopedOverridingContentLengthForTests:: | 201 UploadFileElementReader::ScopedOverridingContentLengthForTests:: |
| 209 ScopedOverridingContentLengthForTests(uint64 value) { | 202 ScopedOverridingContentLengthForTests(uint64 value) { |
| 210 overriding_content_length = value; | 203 overriding_content_length = value; |
| 211 } | 204 } |
| 212 | 205 |
| 213 UploadFileElementReader::ScopedOverridingContentLengthForTests:: | 206 UploadFileElementReader::ScopedOverridingContentLengthForTests:: |
| 214 ~ScopedOverridingContentLengthForTests() { | 207 ~ScopedOverridingContentLengthForTests() { |
| 215 overriding_content_length = 0; | 208 overriding_content_length = 0; |
| 216 } | 209 } |
| 217 | 210 |
| 218 } // namespace net | 211 } // namespace net |
| OLD | NEW |