summaryrefslogtreecommitdiffstats
path: root/WebCore/loader/CrossOriginPreflightResultCache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/loader/CrossOriginPreflightResultCache.cpp')
-rw-r--r--WebCore/loader/CrossOriginPreflightResultCache.cpp40
1 files changed, 29 insertions, 11 deletions
diff --git a/WebCore/loader/CrossOriginPreflightResultCache.cpp b/WebCore/loader/CrossOriginPreflightResultCache.cpp
index cea66b1..f0211af 100644
--- a/WebCore/loader/CrossOriginPreflightResultCache.cpp
+++ b/WebCore/loader/CrossOriginPreflightResultCache.cpp
@@ -35,6 +35,8 @@
namespace WebCore {
+using namespace std;
+
// These values are at the discretion of the user agent.
static const unsigned defaultPreflightCacheTimeoutSeconds = 5;
static const unsigned maxPreflightCacheTimeoutSeconds = 600; // Should be short enough to minimize the risk of using a poisoned cache after switching to a secure network.
@@ -87,15 +89,19 @@ static bool parseAccessControlAllowList(const String& string, HashSet<String, Ha
return true;
}
-bool CrossOriginPreflightResultCacheItem::parse(const ResourceResponse& response)
+bool CrossOriginPreflightResultCacheItem::parse(const ResourceResponse& response, String& errorDescription)
{
m_methods.clear();
- if (!parseAccessControlAllowList(response.httpHeaderField("Access-Control-Allow-Methods"), m_methods))
+ if (!parseAccessControlAllowList(response.httpHeaderField("Access-Control-Allow-Methods"), m_methods)) {
+ errorDescription = "Cannot parse Access-Control-Allow-Methods response header field.";
return false;
+ }
m_headers.clear();
- if (!parseAccessControlAllowList(response.httpHeaderField("Access-Control-Allow-Headers"), m_headers))
+ if (!parseAccessControlAllowList(response.httpHeaderField("Access-Control-Allow-Headers"), m_headers)) {
+ errorDescription = "Cannot parse Access-Control-Allow-Headers response header field.";
return false;
+ }
unsigned expiryDelta;
if (parseAccessControlMaxAge(response.httpHeaderField("Access-Control-Max-Age"), expiryDelta)) {
@@ -108,30 +114,37 @@ bool CrossOriginPreflightResultCacheItem::parse(const ResourceResponse& response
return true;
}
-bool CrossOriginPreflightResultCacheItem::allowsCrossOriginMethod(const String& method) const
+bool CrossOriginPreflightResultCacheItem::allowsCrossOriginMethod(const String& method, String& errorDescription) const
{
- return m_methods.contains(method) || isOnAccessControlSimpleRequestMethodWhitelist(method);
+ if (m_methods.contains(method) || isOnAccessControlSimpleRequestMethodWhitelist(method))
+ return true;
+
+ errorDescription = "Method " + method + " is not allowed by Access-Control-Allow-Methods.";
+ return false;
}
-bool CrossOriginPreflightResultCacheItem::allowsCrossOriginHeaders(const HTTPHeaderMap& requestHeaders) const
+bool CrossOriginPreflightResultCacheItem::allowsCrossOriginHeaders(const HTTPHeaderMap& requestHeaders, String& errorDescription) const
{
HTTPHeaderMap::const_iterator end = requestHeaders.end();
for (HTTPHeaderMap::const_iterator it = requestHeaders.begin(); it != end; ++it) {
- if (!m_headers.contains(it->first) && !isOnAccessControlSimpleRequestHeaderWhitelist(it->first, it->second))
+ if (!m_headers.contains(it->first) && !isOnAccessControlSimpleRequestHeaderWhitelist(it->first, it->second)) {
+ errorDescription = "Request header field " + it->first + " is not allowed by Access-Control-Allow-Headers.";
return false;
+ }
}
return true;
}
bool CrossOriginPreflightResultCacheItem::allowsRequest(bool includeCredentials, const String& method, const HTTPHeaderMap& requestHeaders) const
{
+ String ignoredExplanation;
if (m_absoluteExpiryTime < currentTime())
return false;
if (includeCredentials && !m_credentials)
return false;
- if (!allowsCrossOriginMethod(method))
+ if (!allowsCrossOriginMethod(method, ignoredExplanation))
return false;
- if (!allowsCrossOriginHeaders(requestHeaders))
+ if (!allowsCrossOriginHeaders(requestHeaders, ignoredExplanation))
return false;
return true;
}
@@ -143,10 +156,15 @@ CrossOriginPreflightResultCache& CrossOriginPreflightResultCache::shared()
return cache;
}
-void CrossOriginPreflightResultCache::appendEntry(const String& origin, const KURL& url, CrossOriginPreflightResultCacheItem* preflightResult)
+void CrossOriginPreflightResultCache::appendEntry(const String& origin, const KURL& url, PassOwnPtr<CrossOriginPreflightResultCacheItem> preflightResult)
{
ASSERT(isMainThread());
- m_preflightHashMap.set(std::make_pair(origin, url), preflightResult);
+ CrossOriginPreflightResultCacheItem* resultPtr = preflightResult.leakPtr();
+ pair<CrossOriginPreflightResultHashMap::iterator, bool> addResult = m_preflightHashMap.add(make_pair(origin, url), resultPtr);
+ if (!addResult.second) {
+ // FIXME: We need to delete the old value before replacing with the new one.
+ addResult.first->second = resultPtr;
+ }
}
bool CrossOriginPreflightResultCache::canSkipPreflight(const String& origin, const KURL& url, bool includeCredentials, const String& method, const HTTPHeaderMap& requestHeaders)