Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(206)

Side by Side Diff: services/url_response_disk_cache/url_response_disk_cache_impl.cc

Issue 1133283002: Android handler: Fix name collision. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Validate entry, also move version in first position so that we can completely change the entry defi… Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "services/url_response_disk_cache/url_response_disk_cache_impl.h" 5 #include "services/url_response_disk_cache/url_response_disk_cache_impl.h"
6 6
7 #include <type_traits>
8
7 #include "base/bind.h" 9 #include "base/bind.h"
8 #include "base/files/file_util.h" 10 #include "base/files/file_util.h"
9 #include "base/files/important_file_writer.h" 11 #include "base/files/important_file_writer.h"
10 #include "base/location.h" 12 #include "base/location.h"
11 #include "base/logging.h" 13 #include "base/logging.h"
12 #include "base/strings/string_util.h" 14 #include "base/strings/string_util.h"
13 #include "base/strings/stringprintf.h" 15 #include "base/strings/stringprintf.h"
14 #include "mojo/common/data_pipe_utils.h" 16 #include "mojo/common/data_pipe_utils.h"
15 #include "mojo/public/cpp/application/application_connection.h" 17 #include "mojo/public/cpp/application/application_connection.h"
16 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h" 18 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
17 #include "services/url_response_disk_cache/url_response_disk_cache_entry.mojom.h " 19 #include "services/url_response_disk_cache/url_response_disk_cache_entry.mojom.h "
18 #include "third_party/zlib/google/zip_reader.h" 20 #include "third_party/zlib/google/zip_reader.h"
19 #include "url/gurl.h" 21 #include "url/gurl.h"
20 22
21 namespace mojo { 23 namespace mojo {
22 24
23 namespace { 25 namespace {
24 26
27 // The current version of the cache. This should only be incremented. When this
28 // is incremented, all current cache entries will be invalidated.
29 const uint32_t kCurrentVersion = 1;
30
25 const char kEtagHeader[] = "etag"; 31 const char kEtagHeader[] = "etag";
26 32
27 template <typename T> 33 template <typename T>
28 void Serialize(T input, std::string* output) { 34 void Serialize(T input, std::string* output) {
29 typedef typename mojo::internal::WrapperTraits<T>::DataType DataType; 35 typedef typename mojo::internal::WrapperTraits<T>::DataType DataType;
30 size_t size = GetSerializedSize_(input); 36 size_t size = GetSerializedSize_(input);
31 mojo::internal::FixedBuffer buf(size); 37 mojo::internal::FixedBuffer buf(size);
32 DataType data_type; 38 DataType data_type;
33 Serialize_(input.Pass(), &buf, &data_type); 39 Serialize_(input.Pass(), &buf, &data_type);
34 std::vector<Handle> handles; 40 std::vector<Handle> handles;
35 data_type->EncodePointersAndHandles(&handles); 41 data_type->EncodePointersAndHandles(&handles);
36 void* serialized_data = buf.Leak(); 42 void* serialized_data = buf.Leak();
37 *output = std::string(static_cast<char*>(serialized_data), size); 43 *output = std::string(static_cast<char*>(serialized_data), size);
38 free(serialized_data); 44 free(serialized_data);
39 } 45 }
40 46
41 template <typename T> 47 template <typename T>
42 void Deserialize(std::string input, T* output) { 48 bool Deserialize(std::string input, T* output) {
43 typedef typename mojo::internal::WrapperTraits<T>::DataType DataType; 49 typedef typename mojo::internal::WrapperTraits<T>::DataType DataType;
50 mojo::internal::BoundsChecker bounds_checker(&input[0], input.size(), 0);
51 if (!std::remove_pointer<DataType>::type::Validate(&input[0],
blundell 2015/05/13 09:16:43 What exactly is this doing?
qsr 2015/05/13 09:32:05 This is using the generated validate method to che
52 &bounds_checker)) {
53 return false;
54 }
44 DataType data_type = reinterpret_cast<DataType>(&input[0]); 55 DataType data_type = reinterpret_cast<DataType>(&input[0]);
45 std::vector<Handle> handles; 56 std::vector<Handle> handles;
46 data_type->DecodePointersAndHandles(&handles); 57 data_type->DecodePointersAndHandles(&handles);
47 Deserialize_(data_type, output); 58 Deserialize_(data_type, output);
59 return true;
48 } 60 }
49 61
50 Array<uint8_t> PathToArray(const base::FilePath& path) { 62 Array<uint8_t> PathToArray(const base::FilePath& path) {
51 if (path.empty()) 63 if (path.empty())
52 return Array<uint8_t>(); 64 return Array<uint8_t>();
53 const std::string& string = path.value(); 65 const std::string& string = path.value();
54 Array<uint8_t> result(string.size()); 66 Array<uint8_t> result(string.size());
55 memcpy(&result.front(), string.data(), string.size()); 67 memcpy(&result.front(), string.data(), string.size());
56 return result.Pass(); 68 return result.Pass();
57 } 69 }
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 URLResponse* response, 174 URLResponse* response,
163 CacheEntryPtr* output) { 175 CacheEntryPtr* output) {
164 // Find the entry file, and deserialize it. 176 // Find the entry file, and deserialize it.
165 base::FilePath entry_path = dir.Append("entry"); 177 base::FilePath entry_path = dir.Append("entry");
166 if (!base::PathExists(entry_path)) 178 if (!base::PathExists(entry_path))
167 return false; 179 return false;
168 std::string serialized_entry; 180 std::string serialized_entry;
169 if (!ReadFileToString(entry_path, &serialized_entry)) 181 if (!ReadFileToString(entry_path, &serialized_entry))
170 return false; 182 return false;
171 CacheEntryPtr entry; 183 CacheEntryPtr entry;
172 Deserialize(serialized_entry, &entry); 184 if (!Deserialize(serialized_entry, &entry))
185 return false;
186
187 // Obsolete entry are invalidated.
blundell 2015/05/13 09:16:43 nit: s/entry/entries
qsr 2015/05/13 09:32:05 Done.
188 if (entry->version != kCurrentVersion)
189 return false;
173 190
174 // If |entry| or |response| has not headers, it is not possible to check if 191 // If |entry| or |response| has not headers, it is not possible to check if
175 // the entry is valid, so returns |false|. 192 // the entry is valid, so returns |false|.
176 if (entry->headers.is_null() || response->headers.is_null()) 193 if (entry->headers.is_null() || response->headers.is_null())
177 return false; 194 return false;
178 195
179 // Only handle etag for the moment. 196 // Only handle etag for the moment.
180 std::string etag_header_name = kEtagHeader; 197 std::string etag_header_name = kEtagHeader;
181 std::vector<std::string> entry_etags = 198 std::vector<std::string> entry_etags =
182 GetHeaderValues(etag_header_name, entry->headers); 199 GetHeaderValues(etag_header_name, entry->headers);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 if (IsCacheEntryValid(dir, response.get(), nullptr) && 246 if (IsCacheEntryValid(dir, response.get(), nullptr) &&
230 PathExists(GetExtractedSentinel(dir))) { 247 PathExists(GetExtractedSentinel(dir))) {
231 callback.Run(PathToArray(extracted_dir), PathToArray(dir)); 248 callback.Run(PathToArray(extracted_dir), PathToArray(dir));
232 return; 249 return;
233 } 250 }
234 251
235 GetFileInternal( 252 GetFileInternal(
236 response.Pass(), 253 response.Pass(),
237 base::Bind(&URLResponseDiskCacheImpl::GetExtractedContentInternal, 254 base::Bind(&URLResponseDiskCacheImpl::GetExtractedContentInternal,
238 base::Unretained(this), base::Bind(&RunMojoCallback, callback), 255 base::Unretained(this), base::Bind(&RunMojoCallback, callback),
239 extracted_dir)); 256 dir, extracted_dir));
240 } 257 }
241 258
242 void URLResponseDiskCacheImpl::GetFileInternal( 259 void URLResponseDiskCacheImpl::GetFileInternal(
243 URLResponsePtr response, 260 URLResponsePtr response,
244 const FilePathPairCallback& callback) { 261 const FilePathPairCallback& callback) {
245 base::FilePath dir = GetDirName(base_directory_, response->url); 262 base::FilePath dir = GetDirName(base_directory_, response->url);
246 263
247 // Check if the response is cached and valid. If that's the case, returns the 264 // Check if the response is cached and valid. If that's the case, returns the
248 // cached value. 265 // cached value.
249 CacheEntryPtr entry; 266 CacheEntryPtr entry;
(...skipping 23 matching lines...) Expand all
273 nullptr)) { 290 nullptr)) {
274 callback.Run(base::FilePath(), base::FilePath()); 291 callback.Run(base::FilePath(), base::FilePath());
275 return; 292 return;
276 } 293 }
277 294
278 // Fill the entry values for the request. 295 // Fill the entry values for the request.
279 base::FilePath entry_path = dir.Append("entry"); 296 base::FilePath entry_path = dir.Append("entry");
280 base::FilePath content; 297 base::FilePath content;
281 CHECK(CreateTemporaryFileInDir(dir, &content)); 298 CHECK(CreateTemporaryFileInDir(dir, &content));
282 entry = CacheEntry::New(); 299 entry = CacheEntry::New();
300 entry->version = kCurrentVersion;
283 entry->url = response->url; 301 entry->url = response->url;
284 entry->content_path = content.value(); 302 entry->content_path = content.value();
285 entry->headers = response->headers.Pass(); 303 entry->headers = response->headers.Pass();
286 // Asynchronously copy the response body to the cached file. The entry is send 304 // Asynchronously copy the response body to the cached file. The entry is send
287 // to the callback so that it is saved on disk only if the copy of the body 305 // to the callback so that it is saved on disk only if the copy of the body
288 // succeded. 306 // succeded.
289 common::CopyToFile(response->body.Pass(), content, worker_pool_.get(), 307 common::CopyToFile(response->body.Pass(), content, worker_pool_.get(),
290 base::Bind(&RunCallbackWithSuccess, callback, content, 308 base::Bind(&RunCallbackWithSuccess, callback, content,
291 GetConsumerCacheDirectory(dir), entry_path, 309 GetConsumerCacheDirectory(dir), entry_path,
292 base::Passed(entry.Pass()))); 310 base::Passed(entry.Pass())));
293 } 311 }
294 312
295 void URLResponseDiskCacheImpl::GetExtractedContentInternal( 313 void URLResponseDiskCacheImpl::GetExtractedContentInternal(
296 const FilePathPairCallback& callback, 314 const FilePathPairCallback& callback,
315 const base::FilePath& base_dir,
297 const base::FilePath& extracted_dir, 316 const base::FilePath& extracted_dir,
298 const base::FilePath& content, 317 const base::FilePath& content,
299 const base::FilePath& dir) { 318 const base::FilePath& cache_dir) {
300 // If it is not possible to get the cached file, returns an error. 319 // If it is not possible to get the cached file, returns an error.
301 if (content.empty()) { 320 if (content.empty()) {
302 callback.Run(base::FilePath(), base::FilePath()); 321 callback.Run(base::FilePath(), base::FilePath());
303 return; 322 return;
304 } 323 }
305 324
306 // Unzip the content to the extracted directory. In case of any error, returns 325 // Unzip the content to the extracted directory. In case of any error, returns
307 // an error. 326 // an error.
308 zip::ZipReader reader; 327 zip::ZipReader reader;
309 if (!reader.Open(content)) { 328 if (!reader.Open(content)) {
310 callback.Run(base::FilePath(), base::FilePath()); 329 callback.Run(base::FilePath(), base::FilePath());
311 return; 330 return;
312 } 331 }
313 while (reader.HasMore()) { 332 while (reader.HasMore()) {
314 bool success = reader.OpenCurrentEntryInZip(); 333 bool success = reader.OpenCurrentEntryInZip();
315 success = success && reader.ExtractCurrentEntryIntoDirectory(extracted_dir); 334 success = success && reader.ExtractCurrentEntryIntoDirectory(extracted_dir);
316 success = success && reader.AdvanceToNextEntry(); 335 success = success && reader.AdvanceToNextEntry();
317 if (!success) { 336 if (!success) {
318 callback.Run(base::FilePath(), base::FilePath()); 337 callback.Run(base::FilePath(), base::FilePath());
319 return; 338 return;
320 } 339 }
321 } 340 }
322 // We can ignore write error, as it will just force to clear the cache on the 341 // We can ignore write error, as it will just force to clear the cache on the
323 // next request. 342 // next request.
324 WriteFile(GetExtractedSentinel(dir), nullptr, 0); 343 WriteFile(GetExtractedSentinel(base_dir), nullptr, 0);
blundell 2015/05/13 09:16:43 Am I understanding correctly that this code was pr
qsr 2015/05/13 09:32:05 It was only doing so when sending the cache_dir, s
325 callback.Run(extracted_dir, GetConsumerCacheDirectory(dir)); 344 callback.Run(extracted_dir, cache_dir);
326 } 345 }
327 346
328 } // namespace mojo 347 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698