Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/force_tls_state.h" | 5 #include "net/base/force_tls_state.h" |
| 6 | 6 |
| 7 #include "base/json_reader.h" | |
| 8 #include "base/json_writer.h" | |
| 7 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/scoped_ptr.h" | |
| 8 #include "base/string_tokenizer.h" | 11 #include "base/string_tokenizer.h" |
| 9 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #include "base/values.h" | |
| 10 #include "googleurl/src/gurl.h" | 14 #include "googleurl/src/gurl.h" |
| 11 #include "net/base/registry_controlled_domain.h" | 15 #include "net/base/registry_controlled_domain.h" |
| 12 | 16 |
| 13 namespace net { | 17 namespace net { |
| 14 | 18 |
| 15 ForceTLSState::ForceTLSState() { | 19 ForceTLSState::ForceTLSState() |
| 20 : callback_(NULL) { | |
| 16 } | 21 } |
| 17 | 22 |
| 18 void ForceTLSState::DidReceiveHeader(const GURL& url, | 23 void ForceTLSState::DidReceiveHeader(const GURL& url, |
| 19 const std::string& value) { | 24 const std::string& value) { |
| 20 // TODO(abarth): Actually parse |value| once the spec settles down. | 25 int max_age; |
| 21 EnableHost(url.host()); | 26 bool include_subdomains; |
| 27 | |
| 28 if (!ParseHeader(value, &max_age, &include_subdomains)) | |
| 29 return; | |
| 30 | |
| 31 base::Time current_time(base::Time::Now()); | |
| 32 base::TimeDelta max_age_delta = base::TimeDelta::FromSeconds(max_age); | |
| 33 base::Time expiry = current_time + max_age_delta; | |
| 34 | |
| 35 EnableHost(url.host(), expiry, include_subdomains); | |
| 22 } | 36 } |
| 23 | 37 |
| 24 void ForceTLSState::EnableHost(const std::string& host) { | 38 void ForceTLSState::EnableHost(const std::string& host, base::Time expiry, |
| 39 bool include_subdomains) { | |
| 25 // TODO(abarth): Canonicalize host. | 40 // TODO(abarth): Canonicalize host. |
| 26 AutoLock lock(lock_); | 41 AutoLock lock(lock_); |
| 27 enabled_hosts_.insert(host); | 42 |
| 43 State state = {expiry, include_subdomains}; | |
| 44 enabled_hosts_[host] = state; | |
| 45 DirtyNotify(); | |
| 28 } | 46 } |
| 29 | 47 |
| 30 bool ForceTLSState::IsEnabledForHost(const std::string& host) { | 48 bool ForceTLSState::IsEnabledForHost(const std::string& host) { |
| 31 // TODO(abarth): Canonicalize host. | 49 // TODO(abarth): Canonicalize host. |
| 50 // TODO: check for subdomains too. | |
| 51 | |
| 32 AutoLock lock(lock_); | 52 AutoLock lock(lock_); |
| 33 return enabled_hosts_.find(host) != enabled_hosts_.end(); | 53 std::map<std::string, State>::iterator i = enabled_hosts_.find(host); |
| 54 if (i == enabled_hosts_.end()) | |
| 55 return false; | |
| 56 | |
| 57 base::Time current_time(base::Time::Now()); | |
| 58 if (current_time > i->second.expiry) { | |
| 59 enabled_hosts_.erase(i); | |
| 60 DirtyNotify(); | |
| 61 return false; | |
| 62 } | |
| 63 | |
| 64 return true; | |
| 34 } | 65 } |
| 35 | 66 |
| 36 // "X-Force-TLS" ":" "max-age" "=" delta-seconds *1INCLUDESUBDOMAINS | 67 // "X-Force-TLS" ":" "max-age" "=" delta-seconds *1INCLUDESUBDOMAINS |
| 37 // INCLUDESUBDOMAINS = [ " includeSubDomains" ] | 68 // INCLUDESUBDOMAINS = [ " includeSubDomains" ] |
| 38 bool ForceTLSState::ParseHeader(const std::string& value, | 69 bool ForceTLSState::ParseHeader(const std::string& value, |
| 39 int* max_age, | 70 int* max_age, |
| 40 bool* include_subdomains) { | 71 bool* include_subdomains) { |
| 41 DCHECK(max_age); | 72 DCHECK(max_age); |
| 42 DCHECK(include_subdomains); | 73 DCHECK(include_subdomains); |
| 43 | 74 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 123 case AFTER_INCLUDE_SUBDOMAINS: | 154 case AFTER_INCLUDE_SUBDOMAINS: |
| 124 *max_age = max_age_candidate; | 155 *max_age = max_age_candidate; |
| 125 *include_subdomains = true; | 156 *include_subdomains = true; |
| 126 return true; | 157 return true; |
| 127 default: | 158 default: |
| 128 NOTREACHED(); | 159 NOTREACHED(); |
| 129 return false; | 160 return false; |
| 130 } | 161 } |
| 131 } | 162 } |
| 132 | 163 |
| 164 void ForceTLSState::SetDirtyCallback(void (*callback) (void*), void* userdata) { | |
| 165 AutoLock lock(lock_); | |
| 166 | |
| 167 callback_ = callback; | |
| 168 callback_userdata_ = userdata; | |
| 169 } | |
| 170 | |
| 171 bool ForceTLSState::Serialise(std::string* output) { | |
| 172 AutoLock lock(lock_); | |
| 173 | |
| 174 DictionaryValue toplevel; | |
| 175 for (std::map<std::string, State>::const_iterator | |
| 176 i = enabled_hosts_.begin(); i != enabled_hosts_.end(); ++i) { | |
| 177 DictionaryValue* state = new DictionaryValue; | |
| 178 state->SetBoolean(L"include_subdomains", i->second.include_subdomains); | |
| 179 state->SetReal(L"expiry", i->second.expiry.ToDoubleT()); | |
| 180 | |
| 181 toplevel.Set(ASCIIToWide(i->first), state); | |
| 182 } | |
| 183 | |
| 184 JSONWriter::Write(&toplevel, true /* pretty print */, output); | |
| 185 return true; | |
| 186 } | |
| 187 | |
| 188 bool ForceTLSState::Deserialise(const std::string& input) { | |
| 189 AutoLock lock(lock_); | |
| 190 | |
| 191 enabled_hosts_.clear(); | |
| 192 | |
| 193 scoped_ptr<Value> value( | |
| 194 JSONReader::Read(input, false /* do not allow trailing commas */)); | |
| 195 if (!value.get() || !value->IsType(Value::TYPE_DICTIONARY)) | |
| 196 return false; | |
| 197 | |
| 198 DictionaryValue* dict_value = reinterpret_cast<DictionaryValue*>(value.get()); | |
| 199 const base::Time current_time(base::Time::Now()); | |
| 200 | |
| 201 for (DictionaryValue::key_iterator | |
| 202 i = dict_value->begin_keys(); i != dict_value->end_keys(); ++i) { | |
| 203 DictionaryValue* state; | |
| 204 if (!dict_value->GetDictionary(*i, &state)) | |
| 205 continue; | |
| 206 | |
| 207 const std::string host = WideToASCII(*i); | |
| 208 bool include_subdomains; | |
| 209 double expiry; | |
| 210 | |
| 211 if (!state->GetBoolean(L"include_subdomains", &include_subdomains) || | |
| 212 !state->GetReal(L"expiry", &expiry)) { | |
| 213 continue; | |
| 214 } | |
| 215 | |
| 216 base::Time expiry_time = base::Time::FromDoubleT(expiry); | |
| 217 if (expiry_time <= current_time) | |
| 218 continue; | |
|
abarth-chromium
2009/09/02 21:02:10
You didn't mark us dirty, which means we won't flu
| |
| 219 | |
| 220 State new_state = { expiry_time, include_subdomains }; | |
| 221 enabled_hosts_[host] = new_state; | |
| 222 } | |
| 223 | |
| 224 return enabled_hosts_.size(); | |
| 225 } | |
| 226 | |
| 227 void ForceTLSState::DirtyNotify() { | |
| 228 if (callback_) | |
| 229 callback_(callback_userdata_); | |
| 230 } | |
| 231 | |
| 133 } // namespace | 232 } // namespace |
| OLD | NEW |