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

Unified Diff: Source/core/fetch/CrossOriginAccessControl.cpp

Issue 379113002: Move fetch-related predicates to core/fetch. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: rebase Created 6 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: Source/core/fetch/CrossOriginAccessControl.cpp
diff --git a/Source/core/fetch/CrossOriginAccessControl.cpp b/Source/core/fetch/CrossOriginAccessControl.cpp
index 03e120eb3fbc08395ee2d537a09e2c6efc77e3ad..9b2f366c6946a253cd649adaeae987f0e1bbfde9 100644
--- a/Source/core/fetch/CrossOriginAccessControl.cpp
+++ b/Source/core/fetch/CrossOriginAccessControl.cpp
@@ -40,45 +40,69 @@
namespace WebCore {
-bool isOnAccessControlSimpleRequestMethodWhitelist(const String& method)
-{
- return method == "GET" || method == "HEAD" || method == "POST";
-}
+namespace {
+
+struct ForbiddenHeaderNames {
+ WTF_MAKE_NONCOPYABLE(ForbiddenHeaderNames); WTF_MAKE_FAST_ALLOCATED;
+public:
+ ForbiddenHeaderNames();
+ bool has(const String& name) const
+ {
+ return m_fixedNames.contains(name)
+ || name.startsWith(m_proxyHeaderPrefix, false)
+ || name.startsWith(m_secHeaderPrefix, false);
+ }
+
+private:
+ String m_proxyHeaderPrefix;
+ String m_secHeaderPrefix;
+ HashSet<String, CaseFoldingHash> m_fixedNames;
+};
-bool isOnAccessControlSimpleRequestHeaderWhitelist(const AtomicString& name, const AtomicString& value)
+ForbiddenHeaderNames::ForbiddenHeaderNames()
+ : m_proxyHeaderPrefix("proxy-")
+ , m_secHeaderPrefix("sec-")
{
- if (equalIgnoringCase(name, "accept")
- || equalIgnoringCase(name, "accept-language")
- || equalIgnoringCase(name, "content-language")
- || equalIgnoringCase(name, "origin")
- || equalIgnoringCase(name, "referer"))
- return true;
+ m_fixedNames.add("accept-charset");
+ m_fixedNames.add("accept-encoding");
+ m_fixedNames.add("access-control-request-headers");
+ m_fixedNames.add("access-control-request-method");
+ m_fixedNames.add("connection");
+ m_fixedNames.add("content-length");
+ m_fixedNames.add("cookie");
+ m_fixedNames.add("cookie2");
+ m_fixedNames.add("date");
+ m_fixedNames.add("dnt");
+ m_fixedNames.add("expect");
+ m_fixedNames.add("host");
+ m_fixedNames.add("keep-alive");
+ m_fixedNames.add("origin");
+ m_fixedNames.add("referer");
+ m_fixedNames.add("te");
+ m_fixedNames.add("trailer");
+ m_fixedNames.add("transfer-encoding");
+ m_fixedNames.add("upgrade");
+ m_fixedNames.add("user-agent");
+ m_fixedNames.add("via");
+}
- // Preflight is required for MIME types that can not be sent via form submission.
- if (equalIgnoringCase(name, "content-type")) {
- AtomicString mimeType = extractMIMETypeFromMediaType(value);
- return equalIgnoringCase(mimeType, "application/x-www-form-urlencoded")
- || equalIgnoringCase(mimeType, "multipart/form-data")
- || equalIgnoringCase(mimeType, "text/plain");
- }
+static const ForbiddenHeaderNames* forbiddenHeaderNames = nullptr;
- return false;
+static const ForbiddenHeaderNames* createForbiddenHeaderNames()
+{
+ forbiddenHeaderNames = new ForbiddenHeaderNames;
+ return forbiddenHeaderNames;
}
-bool isSimpleCrossOriginAccessRequest(const String& method, const HTTPHeaderMap& headerMap)
+static const ForbiddenHeaderNames* initializeForbiddenHeaderNames()
sof 2014/07/17 08:18:09 Unless there are reasons not to, should we move th
yhirano 2014/08/06 08:48:03 Done.
{
- if (!isOnAccessControlSimpleRequestMethodWhitelist(method))
- return false;
-
- HTTPHeaderMap::const_iterator end = headerMap.end();
- for (HTTPHeaderMap::const_iterator it = headerMap.begin(); it != end; ++it) {
- if (!isOnAccessControlSimpleRequestHeaderWhitelist(it->key, it->value))
- return false;
- }
-
- return true;
+ // Uses dummy to avoid warnings about an unused variable.
sof 2014/07/17 08:18:09 I know this is code that you moved into here, but
yhirano 2014/08/06 08:48:03 Done.
+ AtomicallyInitializedStatic(const ForbiddenHeaderNames*, dummy = createForbiddenHeaderNames());
+ return dummy;
}
+} // namespace
+
static PassOwnPtr<HTTPHeaderSet> createAllowedCrossOriginResponseHeadersSet()
{
OwnPtr<HTTPHeaderSet> headerSet = adoptPtr(new HashSet<String, CaseFoldingHash>);
@@ -284,4 +308,94 @@ bool CrossOriginAccessControl::handleRedirect(Resource* resource, SecurityOrigin
return true;
}
+bool CrossOriginAccessControl::isSimpleMethod(const String& method)
+{
+ // "A simple method is a method that is `GET`, `HEAD`, or `POST`."
sof 2014/07/17 08:18:09 Anchor this with a spec href?
yhirano 2014/08/06 08:48:02 Done.
+ return method == "GET" || method == "HEAD" || method == "POST";
+}
+
+bool CrossOriginAccessControl::isSimpleHeader(const AtomicString& name, const AtomicString& value)
+{
+ // "A simple header is a header whose name is either one of `Accept`,
sof 2014/07/17 08:18:09 This is also something with a settled spec referen
yhirano 2014/08/06 08:48:03 Done.
+ // `Accept-Language`, and `Content-Language`, or whose name is
+ // `Content-Type` and value, once parsed, is one of
+ // `application/x-www-form-urlencoded`, `multipart/form-data`, and
+ // `text/plain`."
+
+ if (equalIgnoringCase(name, "accept")
+ || equalIgnoringCase(name, "accept-language")
+ || equalIgnoringCase(name, "content-language"))
+ return true;
+
+ // Preflight is required for MIME types that can not be sent via form submission.
+ if (equalIgnoringCase(name, "content-type")) {
+ AtomicString mimeType = extractMIMETypeFromMediaType(value);
+ return equalIgnoringCase(mimeType, "application/x-www-form-urlencoded")
+ || equalIgnoringCase(mimeType, "multipart/form-data")
+ || equalIgnoringCase(mimeType, "text/plain");
+ }
+
+ return false;
+}
+
+bool CrossOriginAccessControl::isSimpleRequest(const String& method, const HTTPHeaderMap& headerMap)
+{
+ if (!isSimpleMethod(method))
+ return false;
+
+ HTTPHeaderMap::const_iterator end = headerMap.end();
+ for (HTTPHeaderMap::const_iterator it = headerMap.begin(); it != end; ++it) {
+ if (!isSimpleHeader(it->key, it->value))
+ return false;
+ }
+
+ return true;
+}
+
+bool CrossOriginAccessControl::isForbiddenMethod(const String& method)
+{
+ // "A forbidden method is a method that is a byte case-insensitive match"
sof 2014/07/17 08:18:09 I think it is a good idea to share definitions lik
yhirano 2014/08/06 08:48:02 I didn't come up with a great name, but moved thes
sof 2014/08/06 19:48:15 Yes, "Utils" classes can grow to become a disparat
+ // for one of `CONNECT`, `TRACE`, and `TRACK`."
+ return equalIgnoringCase(method, "TRACE")
+ || equalIgnoringCase(method, "TRACK")
+ || equalIgnoringCase(method, "CONNECT");
+}
+
+bool CrossOriginAccessControl::isForbiddenHeaderName(const String& name)
+{
+ // "A forbidden header name is a header names that is one of:
+ // `Accept-Charset`, `Accept-Encoding`, `Access-Control-Request-Headers`,
+ // `Access-Control-Request-Method`, `Connection`,
+ // `Content-Length, Cookie`, `Cookie2`, `Date`, `DNT`, `Expect`, `Host`,
+ // `Keep-Alive`, `Origin`, `Referer`, `TE`, `Trailer`,
+ // `Transfer-Encoding`, `Upgrade`, `User-Agent`, `Via`
+ // or starts with `Proxy-` or `Sec-` (including when it is just `Proxy-` or
+ // `Sec-`)."
+
+ initializeForbiddenHeaderNames();
+ return forbiddenHeaderNames->has(name);
+}
+
+bool CrossOriginAccessControl::isForbiddenResponseHeaderName(const String& name)
+{
+ // "A forbidden response header name is a header name that is one of:
+ // `Set-Cookie`, `Set-Cookie2`"
+
+ return equalIgnoringCase(name, "set-cookie") || equalIgnoringCase(name, "set-cookie2");
+}
+
+bool CrossOriginAccessControl::isSimpleOrForbiddenRequest(const String& method, const HTTPHeaderMap& headerMap)
+{
+ if (!isSimpleMethod(method))
+ return false;
+
+ HTTPHeaderMap::const_iterator end = headerMap.end();
+ for (HTTPHeaderMap::const_iterator it = headerMap.begin(); it != end; ++it) {
+ if (!isSimpleHeader(it->key, it->value) && !isForbiddenHeaderName(it->key))
+ return false;
+ }
+
+ return true;
+}
+
} // namespace WebCore

Powered by Google App Engine
This is Rietveld 408576698