Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2017 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2017 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/http/broken_alternative_services.h" | 5 #include "net/http/broken_alternative_services.h" |
| 6 | 6 |
| 7 #include "base/memory/singleton.h" | 7 #include "base/memory/singleton.h" |
| 8 #include "base/time/tick_clock.h" | 8 #include "base/time/tick_clock.h" |
| 9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
| 10 #include "net/http/http_server_properties_impl.h" | 10 #include "net/http/http_server_properties_impl.h" |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 107 broken_alternative_service_list_.erase(map_it->second); | 107 broken_alternative_service_list_.erase(map_it->second); |
| 108 broken_alternative_service_map_.erase(map_it); | 108 broken_alternative_service_map_.erase(map_it); |
| 109 } | 109 } |
| 110 | 110 |
| 111 auto it = recently_broken_alternative_services_.Get(alternative_service); | 111 auto it = recently_broken_alternative_services_.Get(alternative_service); |
| 112 if (it != recently_broken_alternative_services_.end()) { | 112 if (it != recently_broken_alternative_services_.end()) { |
| 113 recently_broken_alternative_services_.Erase(it); | 113 recently_broken_alternative_services_.Erase(it); |
| 114 } | 114 } |
| 115 } | 115 } |
| 116 | 116 |
| 117 const BrokenAlternativeServiceList& | |
| 118 BrokenAlternativeServices::broken_alternative_service_list() const { | |
| 119 return broken_alternative_service_list_; | |
| 120 } | |
| 121 | |
| 122 const RecentlyBrokenAlternativeServices& | |
| 123 BrokenAlternativeServices::recently_broken_alternative_services() const { | |
| 124 return recently_broken_alternative_services_; | |
| 125 } | |
| 126 | |
| 127 void BrokenAlternativeServices::AddBrokenAndRecentlyBrokenAlternativeServices( | |
| 128 std::unique_ptr<BrokenAlternativeServiceList> | |
| 129 broken_alternative_service_list, | |
| 130 std::unique_ptr<RecentlyBrokenAlternativeServices> | |
| 131 recently_broken_alternative_services) { | |
| 132 // Make sure all alt svcs in |broken_alternative_service_list| has an entry | |
| 133 // in |recently_broken_alternative_services| | |
| 134 for (const auto& pair : *broken_alternative_service_list) { | |
| 135 DCHECK(recently_broken_alternative_services->Peek(pair.first) != | |
| 136 recently_broken_alternative_services->end()); | |
| 137 } | |
|
Zhongyi Shi
2017/06/02 18:19:44
|recently_broken_alternative_services| is an MRUCa
wangyix1
2017/06/05 19:16:25
No, Peek() does not modify the recency list, unlik
Zhongyi Shi
2017/06/06 22:17:49
I miss-read the code, yeah, Peek() should be fine.
wangyix1
2017/06/09 19:26:40
Acknowledged.
| |
| 138 | |
| 139 recently_broken_alternative_services_.Swap( | |
| 140 *recently_broken_alternative_services); | |
| 141 // Add back all existing recently broken alt svcs to cache so they're at | |
| 142 // front of recency list. | |
|
Zhongyi Shi
2017/06/02 18:19:44
I might lose some context but why those existing r
wangyix1
2017/06/05 19:16:24
It's not clear from the name, but this method will
| |
| 143 for (auto it = recently_broken_alternative_services->rbegin(); | |
| 144 it != recently_broken_alternative_services->rend(); ++it) { | |
| 145 if (recently_broken_alternative_services_.Get(it->first) == | |
| 146 recently_broken_alternative_services_.end()) { | |
| 147 recently_broken_alternative_services_.Put(it->first, it->second); | |
| 148 } | |
| 149 } | |
| 150 | |
| 151 // Add broken alt svcs to |broken_alternative_service_map_|. Remove all | |
| 152 // that already exist in the map. | |
| 153 auto it = broken_alternative_service_list->begin(); | |
| 154 while (it != broken_alternative_service_list->end()) { | |
| 155 const AlternativeService& alternative_service = it->first; | |
| 156 if (broken_alternative_service_map_.find(alternative_service) == | |
| 157 broken_alternative_service_map_.end()) { | |
| 158 broken_alternative_service_map_.insert( | |
| 159 std::make_pair(alternative_service, it)); | |
| 160 ++it; | |
| 161 } else { | |
| 162 broken_alternative_service_list->erase(it++); | |
| 163 } | |
| 164 } | |
| 165 | |
| 166 // Merge |broken_alternative_service_list| with | |
| 167 // |broken_alternative_service_list_|. Both should already be sorted by | |
| 168 // expiration time. | |
| 169 bool schedule_expiration = | |
| 170 (!broken_alternative_service_list->empty() && | |
| 171 (broken_alternative_service_list_.empty() || | |
| 172 broken_alternative_service_list->front().second < | |
| 173 broken_alternative_service_list_.front().second)); | |
| 174 | |
| 175 broken_alternative_service_list_.merge( | |
| 176 *broken_alternative_service_list, | |
| 177 [](const std::pair<AlternativeService, base::TimeTicks>& lhs, | |
| 178 const std::pair<AlternativeService, base::TimeTicks>& rhs) -> bool { | |
| 179 return lhs.second < rhs.second; | |
| 180 }); | |
| 181 | |
| 182 if (schedule_expiration) | |
| 183 ScheduleBrokenAlternateProtocolMappingsExpiration(); | |
| 184 } | |
| 185 | |
| 117 bool BrokenAlternativeServices::AddToBrokenAlternativeServiceListAndMap( | 186 bool BrokenAlternativeServices::AddToBrokenAlternativeServiceListAndMap( |
| 118 const AlternativeService& alternative_service, | 187 const AlternativeService& alternative_service, |
| 119 base::TimeTicks expiration, | 188 base::TimeTicks expiration, |
| 120 BrokenAlternativeServiceList::iterator* it) { | 189 BrokenAlternativeServiceList::iterator* it) { |
| 121 DCHECK(it); | 190 DCHECK(it); |
| 122 | 191 |
| 123 auto map_it = broken_alternative_service_map_.find(alternative_service); | 192 auto map_it = broken_alternative_service_map_.find(alternative_service); |
| 124 if (map_it != broken_alternative_service_map_.end()) | 193 if (map_it != broken_alternative_service_map_.end()) |
| 125 return false; | 194 return false; |
| 126 | 195 |
| 127 // Iterate from end of |broken_alternative_service_list_| to find where to | 196 // Iterate from end of |broken_alternative_service_list_| to find where to |
| 128 // insert it to keep the list sorted by expiration time. | 197 // insert it to keep the list sorted by expiration time. |
| 129 auto list_it = broken_alternative_service_list_.end(); | 198 auto list_it = broken_alternative_service_list_.end(); |
| 130 while (list_it != broken_alternative_service_list_.begin()) { | 199 while (list_it != broken_alternative_service_list_.begin()) { |
| 131 --list_it; | 200 --list_it; |
| 132 if (list_it->expiration <= expiration) { | 201 if (list_it->second <= expiration) { |
| 133 ++list_it; | 202 ++list_it; |
| 134 break; | 203 break; |
| 135 } | 204 } |
| 136 } | 205 } |
| 137 | 206 |
| 138 // Insert |alternative_service| into the list and the map | 207 // Insert |alternative_service| into the list and the map |
| 139 list_it = broken_alternative_service_list_.insert( | 208 list_it = broken_alternative_service_list_.insert( |
| 140 list_it, BrokenAltSvcExpireInfo(alternative_service, expiration)); | 209 list_it, std::make_pair(alternative_service, expiration)); |
| 141 broken_alternative_service_map_.insert( | 210 broken_alternative_service_map_.insert( |
| 142 std::make_pair(alternative_service, list_it)); | 211 std::make_pair(alternative_service, list_it)); |
| 143 | 212 |
| 144 *it = list_it; | 213 *it = list_it; |
| 145 return true; | 214 return true; |
| 146 } | 215 } |
| 147 | 216 |
| 148 void BrokenAlternativeServices::ExpireBrokenAlternateProtocolMappings() { | 217 void BrokenAlternativeServices::ExpireBrokenAlternateProtocolMappings() { |
| 149 base::TimeTicks now = clock_->NowTicks(); | 218 base::TimeTicks now = clock_->NowTicks(); |
| 150 | 219 |
| 151 while (!broken_alternative_service_list_.empty()) { | 220 while (!broken_alternative_service_list_.empty()) { |
| 152 auto it = broken_alternative_service_list_.begin(); | 221 auto it = broken_alternative_service_list_.begin(); |
| 153 if (now < it->expiration) { | 222 if (now < it->second) { |
| 154 break; | 223 break; |
| 155 } | 224 } |
| 156 | 225 |
| 157 delegate_->OnExpireBrokenAlternativeService(it->alternative_service); | 226 delegate_->OnExpireBrokenAlternativeService(it->first); |
| 158 | 227 |
| 159 broken_alternative_service_map_.erase(it->alternative_service); | 228 broken_alternative_service_map_.erase(it->first); |
| 160 broken_alternative_service_list_.erase(it); | 229 broken_alternative_service_list_.erase(it); |
| 161 } | 230 } |
| 162 | 231 |
| 163 if (!broken_alternative_service_list_.empty()) | 232 if (!broken_alternative_service_list_.empty()) |
| 164 ScheduleBrokenAlternateProtocolMappingsExpiration(); | 233 ScheduleBrokenAlternateProtocolMappingsExpiration(); |
| 165 } | 234 } |
| 166 | 235 |
| 167 void BrokenAlternativeServices :: | 236 void BrokenAlternativeServices :: |
| 168 ScheduleBrokenAlternateProtocolMappingsExpiration() { | 237 ScheduleBrokenAlternateProtocolMappingsExpiration() { |
| 169 DCHECK(!broken_alternative_service_list_.empty()); | 238 DCHECK(!broken_alternative_service_list_.empty()); |
| 170 base::TimeTicks now = clock_->NowTicks(); | 239 base::TimeTicks now = clock_->NowTicks(); |
| 171 base::TimeTicks when = broken_alternative_service_list_.front().expiration; | 240 base::TimeTicks when = broken_alternative_service_list_.front().second; |
| 172 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); | 241 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); |
| 173 expiration_timer_.Stop(); | 242 expiration_timer_.Stop(); |
| 174 expiration_timer_.Start( | 243 expiration_timer_.Start( |
| 175 FROM_HERE, delay, | 244 FROM_HERE, delay, |
| 176 base::Bind( | 245 base::Bind( |
| 177 &BrokenAlternativeServices ::ExpireBrokenAlternateProtocolMappings, | 246 &BrokenAlternativeServices ::ExpireBrokenAlternateProtocolMappings, |
| 178 weak_ptr_factory_.GetWeakPtr())); | 247 weak_ptr_factory_.GetWeakPtr())); |
| 179 } | 248 } |
| 180 | 249 |
| 181 } // namespace net | 250 } // namespace net |
| OLD | NEW |