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 |