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

Side by Side Diff: third_party/WebKit/Source/core/loader/CrossOriginPreflightResultCache.cpp

Issue 2700073002: core/loader: create private directory to store private classes (Closed)
Patch Set: Created 3 years, 10 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 /*
2 * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 */
26
27 #include "core/loader/CrossOriginPreflightResultCache.h"
28
29 #include "platform/HTTPNames.h"
30 #include "platform/loader/fetch/FetchUtils.h"
31 #include "platform/network/ResourceResponse.h"
32 #include "wtf/CurrentTime.h"
33 #include "wtf/StdLibExtras.h"
34 #include <memory>
35
36 namespace blink {
37
38 // These values are at the discretion of the user agent.
39
40 static const unsigned defaultPreflightCacheTimeoutSeconds = 5;
41
42 // Should be short enough to minimize the risk of using a poisoned cache after
43 // switching to a secure network.
44 static const unsigned maxPreflightCacheTimeoutSeconds = 600;
45
46 static bool parseAccessControlMaxAge(const String& string,
47 unsigned& expiryDelta) {
48 // FIXME: this will not do the correct thing for a number starting with a '+'
49 bool ok = false;
50 expiryDelta = string.toUIntStrict(&ok);
51 return ok;
52 }
53
54 template <class HashType>
55 static void addToAccessControlAllowList(const String& string,
56 unsigned start,
57 unsigned end,
58 HashSet<String, HashType>& set) {
59 StringImpl* stringImpl = string.impl();
60 if (!stringImpl)
61 return;
62
63 // Skip white space from start.
64 while (start <= end && isSpaceOrNewline((*stringImpl)[start]))
65 ++start;
66
67 // only white space
68 if (start > end)
69 return;
70
71 // Skip white space from end.
72 while (end && isSpaceOrNewline((*stringImpl)[end]))
73 --end;
74
75 set.insert(string.substring(start, end - start + 1));
76 }
77
78 template <class HashType>
79 static bool parseAccessControlAllowList(const String& string,
80 HashSet<String, HashType>& set) {
81 unsigned start = 0;
82 size_t end;
83 while ((end = string.find(',', start)) != kNotFound) {
84 if (start != end)
85 addToAccessControlAllowList(string, start, end - 1, set);
86 start = end + 1;
87 }
88 if (start != string.length())
89 addToAccessControlAllowList(string, start, string.length() - 1, set);
90
91 return true;
92 }
93
94 bool CrossOriginPreflightResultCacheItem::parse(
95 const ResourceResponse& response,
96 String& errorDescription) {
97 m_methods.clear();
98 if (!parseAccessControlAllowList(
99 response.httpHeaderField(HTTPNames::Access_Control_Allow_Methods),
100 m_methods)) {
101 errorDescription =
102 "Cannot parse Access-Control-Allow-Methods response header field in "
103 "preflight response.";
104 return false;
105 }
106
107 m_headers.clear();
108 if (!parseAccessControlAllowList(
109 response.httpHeaderField(HTTPNames::Access_Control_Allow_Headers),
110 m_headers)) {
111 errorDescription =
112 "Cannot parse Access-Control-Allow-Headers response header field in "
113 "preflight response.";
114 return false;
115 }
116
117 unsigned expiryDelta;
118 if (parseAccessControlMaxAge(
119 response.httpHeaderField(HTTPNames::Access_Control_Max_Age),
120 expiryDelta)) {
121 if (expiryDelta > maxPreflightCacheTimeoutSeconds)
122 expiryDelta = maxPreflightCacheTimeoutSeconds;
123 } else {
124 expiryDelta = defaultPreflightCacheTimeoutSeconds;
125 }
126
127 m_absoluteExpiryTime = currentTime() + expiryDelta;
128 return true;
129 }
130
131 bool CrossOriginPreflightResultCacheItem::allowsCrossOriginMethod(
132 const String& method,
133 String& errorDescription) const {
134 if (m_methods.contains(method) || FetchUtils::isSimpleMethod(method))
135 return true;
136
137 errorDescription =
138 "Method " + method +
139 " is not allowed by Access-Control-Allow-Methods in preflight response.";
140 return false;
141 }
142
143 bool CrossOriginPreflightResultCacheItem::allowsCrossOriginHeaders(
144 const HTTPHeaderMap& requestHeaders,
145 String& errorDescription) const {
146 for (const auto& header : requestHeaders) {
147 if (!m_headers.contains(header.key) &&
148 !FetchUtils::isSimpleHeader(header.key, header.value) &&
149 !FetchUtils::isForbiddenHeaderName(header.key)) {
150 errorDescription = "Request header field " + header.key.getString() +
151 " is not allowed by Access-Control-Allow-Headers in "
152 "preflight response.";
153 return false;
154 }
155 }
156 return true;
157 }
158
159 bool CrossOriginPreflightResultCacheItem::allowsRequest(
160 StoredCredentials includeCredentials,
161 const String& method,
162 const HTTPHeaderMap& requestHeaders) const {
163 String ignoredExplanation;
164 if (m_absoluteExpiryTime < currentTime())
165 return false;
166 if (includeCredentials == AllowStoredCredentials &&
167 m_credentials == DoNotAllowStoredCredentials)
168 return false;
169 if (!allowsCrossOriginMethod(method, ignoredExplanation))
170 return false;
171 if (!allowsCrossOriginHeaders(requestHeaders, ignoredExplanation))
172 return false;
173 return true;
174 }
175
176 CrossOriginPreflightResultCache& CrossOriginPreflightResultCache::shared() {
177 DEFINE_STATIC_LOCAL(CrossOriginPreflightResultCache, cache, ());
178 DCHECK(isMainThread());
179 return cache;
180 }
181
182 void CrossOriginPreflightResultCache::appendEntry(
183 const String& origin,
184 const KURL& url,
185 std::unique_ptr<CrossOriginPreflightResultCacheItem> preflightResult) {
186 DCHECK(isMainThread());
187 m_preflightHashMap.set(std::make_pair(origin, url),
188 std::move(preflightResult));
189 }
190
191 bool CrossOriginPreflightResultCache::canSkipPreflight(
192 const String& origin,
193 const KURL& url,
194 StoredCredentials includeCredentials,
195 const String& method,
196 const HTTPHeaderMap& requestHeaders) {
197 DCHECK(isMainThread());
198 CrossOriginPreflightResultHashMap::iterator cacheIt =
199 m_preflightHashMap.find(std::make_pair(origin, url));
200 if (cacheIt == m_preflightHashMap.end())
201 return false;
202
203 if (cacheIt->value->allowsRequest(includeCredentials, method, requestHeaders))
204 return true;
205
206 m_preflightHashMap.remove(cacheIt);
207 return false;
208 }
209
210 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698