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

Side by Side Diff: third_party/libaddressinput/chromium/cpp/src/retriever.cc

Issue 144353002: [rac] Use stale libaddressinput data if download fails (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 11 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (C) 2013 Google Inc. 1 // Copyright (C) 2013 Google Inc.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License. 4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and 12 // See the License for the specific language governing permissions and
13 // limitations under the License. 13 // limitations under the License.
14 14
15 #include "retriever.h" 15 #include "retriever.h"
16 16
17 #include <libaddressinput/callback.h> 17 #include <libaddressinput/callback.h>
18 #include <libaddressinput/downloader.h> 18 #include <libaddressinput/downloader.h>
19 #include <libaddressinput/storage.h> 19 #include <libaddressinput/storage.h>
20 #include <libaddressinput/util/basictypes.h> 20 #include <libaddressinput/util/basictypes.h>
21 #include <libaddressinput/util/scoped_ptr.h> 21 #include <libaddressinput/util/scoped_ptr.h>
22 22
23 #include <cassert> 23 #include <cassert>
24 #include <cstddef> 24 #include <cstddef>
25 #include <ctime>
25 #include <map> 26 #include <map>
26 #include <string> 27 #include <string>
27 #include <utility> 28 #include <utility>
28 29
29 #include "fallback_data_store.h" 30 #include "fallback_data_store.h"
30 #include "util/stl_util.h" 31 #include "util/stl_util.h"
32 #include "validating_util.h"
31 33
32 namespace i18n { 34 namespace i18n {
33 namespace addressinput { 35 namespace addressinput {
34 36
35 Retriever::Retriever(const std::string& validation_data_url, 37 Retriever::Retriever(const std::string& validation_data_url,
36 scoped_ptr<Downloader> downloader, 38 scoped_ptr<Downloader> downloader,
37 scoped_ptr<Storage> storage) 39 scoped_ptr<Storage> storage)
38 : validation_data_url_(validation_data_url), 40 : validation_data_url_(validation_data_url),
39 downloader_(downloader.Pass()), 41 downloader_(downloader.Pass()),
40 storage_(storage.Pass()) { 42 storage_(storage.Pass()),
43 stale_data_() {
41 assert(validation_data_url_.length() > 0); 44 assert(validation_data_url_.length() > 0);
42 assert(validation_data_url_[validation_data_url_.length() - 1] == '/'); 45 assert(validation_data_url_[validation_data_url_.length() - 1] == '/');
43 assert(storage_ != NULL); 46 assert(storage_ != NULL);
44 assert(downloader_ != NULL); 47 assert(downloader_ != NULL);
45 } 48 }
46 49
47 Retriever::~Retriever() { 50 Retriever::~Retriever() {
48 STLDeleteValues(&requests_); 51 STLDeleteValues(&requests_);
49 } 52 }
50 53
51 void Retriever::Retrieve(const std::string& key, 54 void Retriever::Retrieve(const std::string& key,
52 scoped_ptr<Callback> retrieved) { 55 scoped_ptr<Callback> retrieved) {
53 std::map<std::string, Callback*>::iterator request_it = 56 std::map<std::string, Callback*>::iterator request_it =
54 requests_.find(key); 57 requests_.find(key);
55 if (request_it != requests_.end()) { 58 if (request_it != requests_.end()) {
56 // Abandon a previous request. 59 // Abandon a previous request.
57 delete request_it->second; 60 delete request_it->second;
58 requests_.erase(request_it); 61 requests_.erase(request_it);
59 } 62 }
60 63
61 requests_[key] = retrieved.release(); 64 requests_[key] = retrieved.release();
62 storage_->Get(key, 65 storage_->Get(key,
63 BuildCallback(this, &Retriever::OnDataRetrievedFromStorage)); 66 BuildCallback(this, &Retriever::OnDataRetrievedFromStorage));
64 } 67 }
65 68
66 void Retriever::OnDataRetrievedFromStorage(bool success, 69 void Retriever::OnDataRetrievedFromStorage(bool success,
67 const std::string& key, 70 const std::string& key,
68 const std::string& stored_data) { 71 const std::string& stored_data) {
69 // TODO(rouslan): Add validation for data integrity and freshness. If a 72 std::string unwrapped = stored_data;
70 // download fails, then it's OK to use stale data. 73 ValidatingUtil::TimestampStatus timestamp_status =
71 if (success) { 74 ValidatingUtil::UnwrapTimestamp(&unwrapped, time(NULL));
75 bool checksum_valid = ValidatingUtil::UnwrapChecksum(&unwrapped);
76
77 if (success &&
78 timestamp_status == ValidatingUtil::TIMESTAMP_VALID &&
79 checksum_valid) {
72 scoped_ptr<Callback> retrieved = GetCallbackForKey(key); 80 scoped_ptr<Callback> retrieved = GetCallbackForKey(key);
73 if (retrieved != NULL) { 81 if (retrieved != NULL) {
74 (*retrieved)(success, key, stored_data); 82 (*retrieved)(success, key, unwrapped);
75 } 83 }
76 } else { 84 } else {
85 if (success &&
86 timestamp_status == ValidatingUtil::TIMESTAMP_STALE &&
87 checksum_valid) {
88 stale_data_[key] = unwrapped;
89 }
77 downloader_->Download(GetUrlForKey(key), 90 downloader_->Download(GetUrlForKey(key),
78 BuildCallback(this, &Retriever::OnDownloaded)); 91 BuildCallback(this, &Retriever::OnDownloaded));
79 } 92 }
80 } 93 }
81 94
82 void Retriever::OnDownloaded(bool success, 95 void Retriever::OnDownloaded(bool success,
83 const std::string& url, 96 const std::string& url,
84 const std::string& downloaded_data) { 97 const std::string& downloaded_data) {
85 const std::string& key = GetKeyForUrl(url); 98 const std::string& key = GetKeyForUrl(url);
86 std::string response; 99 std::string response;
100 std::map<std::string, std::string>::iterator stale_data_it =
101 stale_data_.find(key);
102
87 if (success) { 103 if (success) {
88 storage_->Put(key, downloaded_data); 104 storage_->Put(key, ValidatingUtil::Wrap(downloaded_data, time(NULL)));
89 response = downloaded_data; 105 response = downloaded_data;
106 } else if (stale_data_it != stale_data_.end()) {
107 success = true;
108 response = stale_data_it->second;
90 } else { 109 } else {
91 success = FallbackDataStore::Get(key, &response); 110 success = FallbackDataStore::Get(key, &response);
111 }
112
113 if (stale_data_it != stale_data_.end()) {
114 stale_data_.erase(stale_data_it);
92 } 115 }
93 116
94 scoped_ptr<Callback> retrieved = GetCallbackForKey(key); 117 scoped_ptr<Callback> retrieved = GetCallbackForKey(key);
95 if (retrieved != NULL) { 118 if (retrieved != NULL) {
96 (*retrieved)(success, key, response); 119 (*retrieved)(success, key, response);
97 } 120 }
98 } 121 }
99 122
100 std::string Retriever::GetUrlForKey(const std::string& key) const { 123 std::string Retriever::GetUrlForKey(const std::string& key) const {
101 return validation_data_url_ + key; 124 return validation_data_url_ + key;
(...skipping 19 matching lines...) Expand all
121 // An abandonened request. 144 // An abandonened request.
122 return scoped_ptr<Callback>(); 145 return scoped_ptr<Callback>();
123 } 146 }
124 scoped_ptr<Callback> callback(iter->second); 147 scoped_ptr<Callback> callback(iter->second);
125 requests_.erase(iter); 148 requests_.erase(iter);
126 return callback.Pass(); 149 return callback.Pass();
127 } 150 }
128 151
129 } // namespace addressinput 152 } // namespace addressinput
130 } // namespace i18n 153 } // namespace i18n
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698