Chromium Code Reviews| Index: net/base/force_tls_state.cc |
| diff --git a/net/base/force_tls_state.cc b/net/base/force_tls_state.cc |
| index ea2e2f85c123e76564b6a6b86e9771de621cf25c..6ac32b54abaef17f06cad2edc947c37e27a2ae8c 100644 |
| --- a/net/base/force_tls_state.cc |
| +++ b/net/base/force_tls_state.cc |
| @@ -4,33 +4,64 @@ |
| #include "net/base/force_tls_state.h" |
| +#include "base/json_reader.h" |
| +#include "base/json_writer.h" |
| #include "base/logging.h" |
| +#include "base/scoped_ptr.h" |
| #include "base/string_tokenizer.h" |
| #include "base/string_util.h" |
| +#include "base/values.h" |
| #include "googleurl/src/gurl.h" |
| #include "net/base/registry_controlled_domain.h" |
| namespace net { |
| -ForceTLSState::ForceTLSState() { |
| +ForceTLSState::ForceTLSState() |
| + : callback_(NULL) { |
| } |
| void ForceTLSState::DidReceiveHeader(const GURL& url, |
| const std::string& value) { |
| - // TODO(abarth): Actually parse |value| once the spec settles down. |
| - EnableHost(url.host()); |
| + int max_age; |
| + bool include_subdomains; |
| + |
| + if (!ParseHeader(value, &max_age, &include_subdomains)) |
| + return; |
| + |
| + base::Time current_time(base::Time::Now()); |
| + base::TimeDelta max_age_delta = base::TimeDelta::FromSeconds(max_age); |
| + base::Time expiry = current_time + max_age_delta; |
| + |
| + EnableHost(url.host(), expiry, include_subdomains); |
| } |
| -void ForceTLSState::EnableHost(const std::string& host) { |
| +void ForceTLSState::EnableHost(const std::string& host, base::Time expiry, |
| + bool include_subdomains) { |
| // TODO(abarth): Canonicalize host. |
| AutoLock lock(lock_); |
| - enabled_hosts_.insert(host); |
| + |
| + State state = {expiry, include_subdomains}; |
| + enabled_hosts_[host] = state; |
| + DirtyNotify(); |
| } |
| bool ForceTLSState::IsEnabledForHost(const std::string& host) { |
| // TODO(abarth): Canonicalize host. |
| + // TODO: check for subdomains too. |
| + |
| AutoLock lock(lock_); |
| - return enabled_hosts_.find(host) != enabled_hosts_.end(); |
| + std::map<std::string, State>::iterator i = enabled_hosts_.find(host); |
| + if (i == enabled_hosts_.end()) |
| + return false; |
| + |
| + base::Time current_time(base::Time::Now()); |
| + if (current_time > i->second.expiry) { |
| + enabled_hosts_.erase(i); |
| + DirtyNotify(); |
| + return false; |
| + } |
| + |
| + return true; |
| } |
| // "X-Force-TLS" ":" "max-age" "=" delta-seconds *1INCLUDESUBDOMAINS |
| @@ -130,4 +161,72 @@ bool ForceTLSState::ParseHeader(const std::string& value, |
| } |
| } |
| +void ForceTLSState::SetDirtyCallback(void (*callback) (void*), void* userdata) { |
| + AutoLock lock(lock_); |
| + |
| + callback_ = callback; |
| + callback_userdata_ = userdata; |
| +} |
| + |
| +bool ForceTLSState::Serialise(std::string* output) { |
| + AutoLock lock(lock_); |
| + |
| + DictionaryValue toplevel; |
| + for (std::map<std::string, State>::const_iterator |
| + i = enabled_hosts_.begin(); i != enabled_hosts_.end(); ++i) { |
| + DictionaryValue* state = new DictionaryValue; |
| + state->SetBoolean(L"include_subdomains", i->second.include_subdomains); |
| + state->SetReal(L"expiry", i->second.expiry.ToDoubleT()); |
| + |
| + toplevel.Set(ASCIIToWide(i->first), state); |
| + } |
| + |
| + JSONWriter::Write(&toplevel, true /* pretty print */, output); |
| + return true; |
| +} |
| + |
| +bool ForceTLSState::Deserialise(const std::string& input) { |
| + AutoLock lock(lock_); |
| + |
| + enabled_hosts_.clear(); |
| + |
| + scoped_ptr<Value> value( |
| + JSONReader::Read(input, false /* do not allow trailing commas */)); |
| + if (!value.get() || !value->IsType(Value::TYPE_DICTIONARY)) |
| + return false; |
| + |
| + DictionaryValue* dict_value = reinterpret_cast<DictionaryValue*>(value.get()); |
| + const base::Time current_time(base::Time::Now()); |
| + |
| + for (DictionaryValue::key_iterator |
| + i = dict_value->begin_keys(); i != dict_value->end_keys(); ++i) { |
| + DictionaryValue* state; |
| + if (!dict_value->GetDictionary(*i, &state)) |
| + continue; |
| + |
| + const std::string host = WideToASCII(*i); |
| + bool include_subdomains; |
| + double expiry; |
| + |
| + if (!state->GetBoolean(L"include_subdomains", &include_subdomains) || |
| + !state->GetReal(L"expiry", &expiry)) { |
| + continue; |
| + } |
| + |
| + base::Time expiry_time = base::Time::FromDoubleT(expiry); |
| + if (expiry_time <= current_time) |
| + continue; |
|
abarth-chromium
2009/09/02 21:02:10
You didn't mark us dirty, which means we won't flu
|
| + |
| + State new_state = { expiry_time, include_subdomains }; |
| + enabled_hosts_[host] = new_state; |
| + } |
| + |
| + return enabled_hosts_.size(); |
| +} |
| + |
| +void ForceTLSState::DirtyNotify() { |
| + if (callback_) |
| + callback_(callback_userdata_); |
| +} |
| + |
| } // namespace |