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 |