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

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: Incorporated comments. 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
« no previous file with comments | « net/base/sdch_dictionary.h ('k') | net/base/sdch_dictionary_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
76 * was not 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 "/"
150 * or the character following P2 in P1 is "/".
151 */
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
« no previous file with comments | « net/base/sdch_dictionary.h ('k') | net/base/sdch_dictionary_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698