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

Side by Side Diff: components/safe_browsing_db/v4_store.cc

Issue 2066083002: SafeBrowising: Read and write V4Store from/to disk (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@01_UpdateDbAndStores
Patch Set: Nit: Make store creation and use more consistent. Created 4 years, 5 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "base/base64.h" 5 #include "base/base64.h"
6 #include "base/bind.h" 6 #include "base/bind.h"
7 #include "base/files/file_util.h"
8 #include "base/metrics/histogram_macros.h"
9 #include "base/metrics/sparse_histogram.h"
7 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
8 #include "components/safe_browsing_db/v4_store.h" 11 #include "components/safe_browsing_db/v4_store.h"
12 #include "components/safe_browsing_db/v4_store.pb.h"
9 13
10 namespace safe_browsing { 14 namespace safe_browsing {
11 15
16 namespace {
17 const uint32_t kFileMagic = 0x600D71FE;
18
19 const uint32_t kFileVersion = 9;
20
21 void RecordStoreReadResult(StoreReadResult result) {
22 UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.V4StoreReadResult", result,
23 STORE_READ_RESULT_MAX);
24 }
25
26 void RecordStoreWriteResult(StoreWriteResult result) {
27 UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.V4StoreWriteResult", result,
28 STORE_WRITE_RESULT_MAX);
29 }
30
31 // Returns the name of the temporary file used to buffer data for
32 // |filename|. Exported for unit tests.
33 const base::FilePath TemporaryFileForFilename(const base::FilePath& filename) {
34 return base::FilePath(filename.value() + FILE_PATH_LITERAL("_new"));
35 }
36
37 } // namespace
38
12 std::ostream& operator<<(std::ostream& os, const V4Store& store) { 39 std::ostream& operator<<(std::ostream& os, const V4Store& store) {
13 os << store.DebugString(); 40 os << store.DebugString();
14 return os; 41 return os;
15 } 42 }
16 43
17 V4Store* V4StoreFactory::CreateV4Store( 44 V4Store* V4StoreFactory::CreateV4Store(
18 const scoped_refptr<base::SequencedTaskRunner>& task_runner, 45 const scoped_refptr<base::SequencedTaskRunner>& task_runner,
19 const base::FilePath& store_path) { 46 const base::FilePath& store_path) {
20 return new V4Store(task_runner, store_path); 47 V4Store* new_store = new V4Store(task_runner, store_path);
48 new_store->Initialize();
49 return new_store;
50 }
51
52 void V4Store::Initialize() {
53 // If a state already exists, don't re-initilize.
54 DCHECK(state_.empty());
55
56 StoreReadResult store_read_result = ReadFromDisk();
57 RecordStoreReadResult(store_read_result);
21 } 58 }
22 59
23 V4Store::V4Store(const scoped_refptr<base::SequencedTaskRunner>& task_runner, 60 V4Store::V4Store(const scoped_refptr<base::SequencedTaskRunner>& task_runner,
24 const base::FilePath& store_path) 61 const base::FilePath& store_path)
25 : store_path_(store_path), task_runner_(task_runner) {} 62 : store_path_(store_path), task_runner_(task_runner) {}
26 63
27 V4Store::~V4Store() {} 64 V4Store::~V4Store() {}
28 65
29 std::string V4Store::DebugString() const { 66 std::string V4Store::DebugString() const {
30 std::string state_base64; 67 std::string state_base64;
(...skipping 12 matching lines...) Expand all
43 void V4Store::ApplyUpdate( 80 void V4Store::ApplyUpdate(
44 const ListUpdateResponse& response, 81 const ListUpdateResponse& response,
45 const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner, 82 const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner,
46 UpdatedStoreReadyCallback callback) { 83 UpdatedStoreReadyCallback callback) {
47 std::unique_ptr<V4Store> new_store( 84 std::unique_ptr<V4Store> new_store(
48 new V4Store(this->task_runner_, this->store_path_)); 85 new V4Store(this->task_runner_, this->store_path_));
49 86
50 // TODO(vakh): The new store currently only picks up the new state. Do more. 87 // TODO(vakh): The new store currently only picks up the new state. Do more.
51 new_store->state_ = response.new_client_state(); 88 new_store->state_ = response.new_client_state();
52 89
90 // TODO(vakh): Merge the old store and the new update in new_store.
91 // Then, create a ListUpdateResponse containing RICE encoded hash-prefixes and
92 // response_type as FULL_UPDATE, and write that to disk.
93 StoreWriteResult result = new_store->WriteToDisk(response);
94 RecordStoreWriteResult(result);
95
53 // new_store is done updating, pass it to the callback. 96 // new_store is done updating, pass it to the callback.
54 callback_task_runner->PostTask( 97 callback_task_runner->PostTask(
55 FROM_HERE, base::Bind(callback, base::Passed(&new_store))); 98 FROM_HERE, base::Bind(callback, base::Passed(&new_store)));
56 } 99 }
57 100
101 StoreReadResult V4Store::ReadFromDisk() {
102 DCHECK(task_runner_->RunsTasksOnCurrentThread());
103
104 std::string contents;
105 bool read_success = base::ReadFileToString(store_path_, &contents);
106 if (!read_success) {
107 return FILE_UNREADABLE_FAILURE;
108 }
109
110 if (contents.empty()) {
111 return FILE_EMPTY_FAILURE;
112 }
113
114 V4StoreFileFormat file_format;
115 if (!file_format.ParseFromString(contents)) {
116 return PROTO_PARSING_FAILURE;
117 }
118
119 if (file_format.magic_number() != kFileMagic) {
120 DVLOG(1) << "Unexpected magic number found in file: "
121 << file_format.magic_number();
122 return UNEXPECTED_MAGIC_NUMBER_FAILURE;
123 }
124
125 UMA_HISTOGRAM_SPARSE_SLOWLY("SafeBrowsing.V4StoreVersionRead",
126 file_format.version_number());
127 if (file_format.version_number() != kFileVersion) {
128 DVLOG(1) << "File version incompatible: " << file_format.version_number()
129 << "; expected: " << kFileVersion;
130 return FILE_VERSION_INCOMPATIBLE_FAILURE;
131 }
132
133 if (!file_format.has_list_update_response()) {
134 return HASH_PREFIX_INFO_MISSING_FAILURE;
135 }
136
137 ListUpdateResponse list_update_response = file_format.list_update_response();
138 state_ = list_update_response.new_client_state();
139 // TODO(vakh): Do more with what's read from the disk.
140
141 return READ_SUCCESS;
142 }
143
144 StoreWriteResult V4Store::WriteToDisk(
145 const ListUpdateResponse& response) const {
146 // Do not write partial updates to the disk.
147 // After merging the updates, the ListUpdateResponse passed to this method
148 // should be a FULL_UPDATE.
149 if (!response.has_response_type() ||
150 response.response_type() != ListUpdateResponse::FULL_UPDATE) {
151 DVLOG(1) << "response.has_response_type(): "
152 << response.has_response_type();
153 DVLOG(1) << "response.response_type(): " << response.response_type();
154 return INVALID_RESPONSE_TYPE_FAILURE;
155 }
156
157 // Attempt writing to a temporary file first and at the end, swap the files.
158 const base::FilePath new_filename = TemporaryFileForFilename(store_path_);
159
160 V4StoreFileFormat file_format;
161 file_format.set_magic_number(kFileMagic);
162 file_format.set_version_number(kFileVersion);
163 ListUpdateResponse* response_to_write =
164 file_format.mutable_list_update_response();
165 *response_to_write = response;
166 std::string file_format_string;
167 file_format.SerializeToString(&file_format_string);
168 size_t written = base::WriteFile(new_filename, file_format_string.data(),
169 file_format_string.size());
170 DCHECK_EQ(file_format_string.size(), written);
171
172 if (!base::Move(new_filename, store_path_)) {
173 DVLOG(1) << "store_path_: " << store_path_.value();
174 return UNABLE_TO_RENAME_FAILURE;
175 }
176
177 return WRITE_SUCCESS;
178 }
179
58 } // namespace safe_browsing 180 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698