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

Side by Side Diff: net/base/sdch_dictionary.cc

Issue 1051933002: Split SdchManager::Dictionary out into separate class/file. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added unit tests. Created 5 years, 8 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
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/base/sdch_dictionary.h"
6
7 #include "base/time/clock.h"
8 #include "base/time/default_clock.h"
9 #include "base/values.h"
10 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
11
12 namespace {
13
14 bool DomainMatch(const GURL& gurl, const std::string& restriction) {
15 // TODO(jar): This is not precisely a domain match definition.
16 return gurl.DomainIs(restriction.data(), restriction.size());
17 }
18
19 } // namespace
20
21 namespace net {
22
23 SdchDictionary::SdchDictionary(const std::string& dictionary_text,
24 size_t offset,
25 const std::string& client_hash,
26 const std::string& server_hash,
27 const GURL& gurl,
28 const std::string& domain,
29 const std::string& path,
30 const base::Time& expiration,
31 const std::set<int>& ports)
32 : text_(dictionary_text, offset),
33 client_hash_(client_hash),
34 server_hash_(server_hash),
35 url_(gurl),
36 domain_(domain),
37 path_(path),
38 expiration_(expiration),
39 ports_(ports),
40 clock_(new base::DefaultClock) {
41 }
42
43 SdchDictionary::SdchDictionary(const SdchDictionary& rhs)
44 : text_(rhs.text_),
45 client_hash_(rhs.client_hash_),
46 server_hash_(rhs.server_hash_),
47 url_(rhs.url_),
48 domain_(rhs.domain_),
49 path_(rhs.path_),
50 expiration_(rhs.expiration_),
51 ports_(rhs.ports_),
52 clock_(new base::DefaultClock) {
53 }
54
55 SdchDictionary::~SdchDictionary() {
56 }
57
58 // Security functions restricting loads and use of dictionaries.
59
60 // static
61 SdchProblemCode SdchDictionary::CanSet(const std::string& domain,
62 const std::string& path,
63 const std::set<int>& ports,
64 const GURL& dictionary_url) {
65 /*
66 A dictionary is invalid and must not be stored if any of the following are
67 true:
68 1. The dictionary has no Domain attribute.
69 2. The effective host name that derives from the referer URL host name does
70 not domain-match the Domain attribute.
71 3. The Domain attribute is a top level domain.
72 4. The referer URL host is a host domain name (not IP address) and has the
73 form HD, where D is the value of the Domain attribute, and H is a string
74 that contains one or more dots.
75 5. If the dictionary has a Port attribute and the referer URL's port was not
76 in the list.
77 */
78
79 // TODO(jar): Redirects in dictionary fetches might plausibly be problematic,
80 // and hence the conservative approach is to not allow any redirects (if there
81 // were any... then don't allow the dictionary to be set).
82
83 if (domain.empty())
84 return SDCH_DICTIONARY_MISSING_DOMAIN_SPECIFIER; // Domain is required.
85
86 if (registry_controlled_domains::GetDomainAndRegistry(
87 domain, registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)
88 .empty()) {
89 return SDCH_DICTIONARY_SPECIFIES_TOP_LEVEL_DOMAIN; // domain was a TLD.
90 }
91
92 if (!DomainMatch(dictionary_url, domain))
93 return SDCH_DICTIONARY_DOMAIN_NOT_MATCHING_SOURCE_URL;
94
95 std::string referrer_url_host = dictionary_url.host();
96 size_t postfix_domain_index = referrer_url_host.rfind(domain);
97 // See if it is indeed a postfix, or just an internal string.
98 if (referrer_url_host.size() == postfix_domain_index + domain.size()) {
99 // It is a postfix... so check to see if there's a dot in the prefix.
100 size_t end_of_host_index = referrer_url_host.find_first_of('.');
101 if (referrer_url_host.npos != end_of_host_index &&
102 end_of_host_index < postfix_domain_index) {
103 return SDCH_DICTIONARY_REFERER_URL_HAS_DOT_IN_PREFIX;
104 }
105 }
106
107 if (!ports.empty() && 0 == ports.count(dictionary_url.EffectiveIntPort()))
108 return SDCH_DICTIONARY_PORT_NOT_MATCHING_SOURCE_URL;
109
110 return SDCH_OK;
111 }
112
113 SdchProblemCode SdchDictionary::CanUse(const GURL& target_url) const {
114 /*
115 1. The request URL's host name domain-matches the Domain attribute of the
116 dictionary.
117 2. If the dictionary has a Port attribute, the request port is one of the
118 ports listed in the Port attribute.
119 3. The request URL path-matches the path attribute of the dictionary.
120 We can override (ignore) item (4) only when we have explicitly enabled
121 HTTPS support AND the dictionary acquisition scheme matches the target
122 url scheme.
123 */
124 if (!DomainMatch(target_url, domain_))
125 return SDCH_DICTIONARY_FOUND_HAS_WRONG_DOMAIN;
126
127 if (!ports_.empty() && 0 == ports_.count(target_url.EffectiveIntPort()))
128 return SDCH_DICTIONARY_FOUND_HAS_WRONG_PORT_LIST;
129
130 if (path_.size() && !PathMatch(target_url.path(), path_))
131 return SDCH_DICTIONARY_FOUND_HAS_WRONG_PATH;
132
133 if (target_url.SchemeIsSecure() != url_.SchemeIsSecure())
134 return SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME;
135
136 // TODO(jar): Remove overly restrictive failsafe test (added per security
137 // review) when we have a need to be more general.
138 if (!target_url.SchemeIsHTTPOrHTTPS())
139 return SDCH_ATTEMPT_TO_DECODE_NON_HTTP_DATA;
140
141 return SDCH_OK;
142 }
143
144 // static
145 bool SdchDictionary::PathMatch(const std::string& path,
146 const std::string& restriction) {
147 /* Must be either:
148 1. P2 is equal to P1
149 2. P2 is a prefix of P1 and either the final character in P2 is "/" or the
150 character following P2 in P1 is "/".
151 */
Elly Fong-Jones 2015/04/08 16:25:33 indentation
Randy Smith (Not in Mondays) 2015/04/08 21:06:05 Reformatted to use /*\n*...\n*...\n*/ style. Did
152 if (path == restriction)
153 return true;
154 size_t prefix_length = restriction.size();
155 if (prefix_length > path.size())
156 return false; // Can't be a prefix.
157 if (0 != path.compare(0, prefix_length, restriction))
158 return false;
159 return restriction[prefix_length - 1] == '/' || path[prefix_length] == '/';
160 }
161
162 bool SdchDictionary::Expired() const {
163 return clock_->Now() > expiration_;
164 }
165
166 void SdchDictionary::SetClockForTesting(scoped_ptr<base::Clock> clock) {
167 clock_ = clock.Pass();
168 }
169
170 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698