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