- Revision
- 86980
- Author
- [email protected]
- Date
- 2011-05-20 13:58:34 -0700 (Fri, 20 May 2011)
Log Message
2011-05-20 Adam Barth <[email protected]>
Reviewed by Alexey Proskuryakov.
Factor CORS request preparation out of DocumentThreadableLoader
https://bugs.webkit.org/show_bug.cgi?id=61209
DocumentThreadableLoader has two jobs:
1) Proxy loads between threads.
2) Run the CORS state machine.
This patch begins the work of separating those concerns, allowing CORS
to be used elsewhere in the loading pipeline. In particular, this
patch moves knowledge of how to prepare CORS requests out of
DocumentThreadableLoder.
* loader/CrossOriginAccessControl.cpp:
(WebCore::isOnAccessControlSimpleRequestHeaderWhitelist):
(WebCore::updateRequestForAccessControl):
(WebCore::createAccessControlPreflightRequest):
* loader/CrossOriginAccessControl.h:
* loader/DocumentThreadableLoader.cpp:
(WebCore::DocumentThreadableLoader::DocumentThreadableLoader):
(WebCore::DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest):
(WebCore::DocumentThreadableLoader::makeCrossOriginAccessRequestWithPreflight):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (86979 => 86980)
--- trunk/Source/WebCore/ChangeLog 2011-05-20 20:11:51 UTC (rev 86979)
+++ trunk/Source/WebCore/ChangeLog 2011-05-20 20:58:34 UTC (rev 86980)
@@ -1,3 +1,30 @@
+2011-05-20 Adam Barth <[email protected]>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Factor CORS request preparation out of DocumentThreadableLoader
+ https://bugs.webkit.org/show_bug.cgi?id=61209
+
+ DocumentThreadableLoader has two jobs:
+
+ 1) Proxy loads between threads.
+ 2) Run the CORS state machine.
+
+ This patch begins the work of separating those concerns, allowing CORS
+ to be used elsewhere in the loading pipeline. In particular, this
+ patch moves knowledge of how to prepare CORS requests out of
+ DocumentThreadableLoder.
+
+ * loader/CrossOriginAccessControl.cpp:
+ (WebCore::isOnAccessControlSimpleRequestHeaderWhitelist):
+ (WebCore::updateRequestForAccessControl):
+ (WebCore::createAccessControlPreflightRequest):
+ * loader/CrossOriginAccessControl.h:
+ * loader/DocumentThreadableLoader.cpp:
+ (WebCore::DocumentThreadableLoader::DocumentThreadableLoader):
+ (WebCore::DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest):
+ (WebCore::DocumentThreadableLoader::makeCrossOriginAccessRequestWithPreflight):
+
2011-05-20 Rob Buis <[email protected]>
Reviewed by Dirk Schulze.
Modified: trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp (86979 => 86980)
--- trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp 2011-05-20 20:11:51 UTC (rev 86979)
+++ trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp 2011-05-20 20:58:34 UTC (rev 86980)
@@ -43,7 +43,10 @@
bool isOnAccessControlSimpleRequestHeaderWhitelist(const String& name, const String& value)
{
- if (equalIgnoringCase(name, "accept") || equalIgnoringCase(name, "accept-language") || equalIgnoringCase(name, "content-language"))
+ if (equalIgnoringCase(name, "accept")
+ || equalIgnoringCase(name, "accept-language")
+ || equalIgnoringCase(name, "content-language")
+ || equalIgnoringCase(name, "origin"))
return true;
// Preflight is required for MIME types that can not be sent via form submission.
@@ -93,6 +96,42 @@
return allowedCrossOriginResponseHeaders->contains(name);
}
+void updateRequestForAccessControl(ResourceRequest& request, SecurityOrigin* securityOrigin, bool allowCredentials)
+{
+ request.removeCredentials();
+ request.setAllowCookies(allowCredentials);
+ request.setHTTPOrigin(securityOrigin->toString());
+}
+
+ResourceRequest createAccessControlPreflightRequest(const ResourceRequest& request, SecurityOrigin* securityOrigin, bool allowCredentials)
+{
+ ResourceRequest preflightRequest(request.url());
+ updateRequestForAccessControl(preflightRequest, securityOrigin, allowCredentials);
+ preflightRequest.setHTTPMethod("OPTIONS");
+ preflightRequest.setHTTPHeaderField("Access-Control-Request-Method", request.httpMethod());
+ preflightRequest.setPriority(request.priority());
+
+ const HTTPHeaderMap& requestHeaderFields = request.httpHeaderFields();
+
+ if (requestHeaderFields.size() > 0) {
+ Vector<UChar> headerBuffer;
+ HTTPHeaderMap::const_iterator it = requestHeaderFields.begin();
+ append(headerBuffer, it->first);
+ ++it;
+
+ HTTPHeaderMap::const_iterator end = requestHeaderFields.end();
+ for (; it != end; ++it) {
+ headerBuffer.append(',');
+ headerBuffer.append(' ');
+ append(headerBuffer, it->first);
+ }
+
+ preflightRequest.setHTTPHeaderField("Access-Control-Request-Headers", String::adopt(headerBuffer));
+ }
+
+ return preflightRequest;
+}
+
bool passesAccessControlCheck(const ResourceResponse& response, bool includeCredentials, SecurityOrigin* securityOrigin, String& errorDescription)
{
// A wildcard Access-Control-Allow-Origin can not be used if credentials are to be sent,
Modified: trunk/Source/WebCore/loader/CrossOriginAccessControl.h (86979 => 86980)
--- trunk/Source/WebCore/loader/CrossOriginAccessControl.h 2011-05-20 20:11:51 UTC (rev 86979)
+++ trunk/Source/WebCore/loader/CrossOriginAccessControl.h 2011-05-20 20:58:34 UTC (rev 86980)
@@ -27,21 +27,25 @@
#ifndef CrossOriginAccessControl_h
#define CrossOriginAccessControl_h
+#include "ResourceRequest.h"
#include <wtf/Forward.h>
namespace WebCore {
- class HTTPHeaderMap;
- class ResourceResponse;
- class SecurityOrigin;
+class HTTPHeaderMap;
+class ResourceResponse;
+class SecurityOrigin;
- bool isSimpleCrossOriginAccessRequest(const String& method, const HTTPHeaderMap&);
- bool isOnAccessControlSimpleRequestMethodWhitelist(const String&);
- bool isOnAccessControlSimpleRequestHeaderWhitelist(const String& name, const String& value);
- bool isOnAccessControlResponseHeaderWhitelist(const String&);
+bool isSimpleCrossOriginAccessRequest(const String& method, const HTTPHeaderMap&);
+bool isOnAccessControlSimpleRequestMethodWhitelist(const String&);
+bool isOnAccessControlSimpleRequestHeaderWhitelist(const String& name, const String& value);
+bool isOnAccessControlResponseHeaderWhitelist(const String&);
- bool passesAccessControlCheck(const ResourceResponse&, bool includeCredentials, SecurityOrigin*, String& errorDescription);
+void updateRequestForAccessControl(ResourceRequest&, SecurityOrigin*, bool allowCredentials);
+ResourceRequest createAccessControlPreflightRequest(const ResourceRequest&, SecurityOrigin*, bool allowCredentials);
+bool passesAccessControlCheck(const ResourceResponse&, bool includeCredentials, SecurityOrigin*, String& errorDescription);
+
} // namespace WebCore
#endif // CrossOriginAccessControl_h
Modified: trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp (86979 => 86980)
--- trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp 2011-05-20 20:11:51 UTC (rev 86979)
+++ trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp 2011-05-20 20:58:34 UTC (rev 86980)
@@ -89,8 +89,7 @@
ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl);
OwnPtr<ResourceRequest> crossOriginRequest = adoptPtr(new ResourceRequest(request));
- crossOriginRequest->removeCredentials();
- crossOriginRequest->setAllowCookies(m_options.allowCredentials);
+ updateRequestForAccessControl(*crossOriginRequest, m_document->securityOrigin(), m_options.allowCredentials);
if (!m_options.forcePreflight && isSimpleCrossOriginAccessRequest(crossOriginRequest->httpMethod(), crossOriginRequest->httpHeaderFields()))
makeSimpleCrossOriginAccessRequest(*crossOriginRequest);
@@ -109,47 +108,18 @@
ASSERT(isSimpleCrossOriginAccessRequest(request.httpMethod(), request.httpHeaderFields()));
// Cross-origin requests are only defined for HTTP. We would catch this when checking response headers later, but there is no reason to send a request that's guaranteed to be denied.
+ // FIXME: Consider allowing simple CORS requests to non-HTTP URLs.
if (!request.url().protocolInHTTPFamily()) {
m_client->didFail(ResourceError(errorDomainWebKitInternal, 0, request.url().string(), "Cross origin requests are only supported for HTTP."));
return;
}
- // Make a copy of the passed request so that we can modify some details.
- ResourceRequest crossOriginRequest(request);
- crossOriginRequest.setHTTPOrigin(m_document->securityOrigin()->toString());
-
- loadRequest(crossOriginRequest, DoSecurityCheck);
+ loadRequest(request, DoSecurityCheck);
}
void DocumentThreadableLoader::makeCrossOriginAccessRequestWithPreflight(const ResourceRequest& request)
{
- ResourceRequest preflightRequest(request.url());
- preflightRequest.removeCredentials();
- preflightRequest.setHTTPOrigin(m_document->securityOrigin()->toString());
- preflightRequest.setAllowCookies(m_options.allowCredentials);
- preflightRequest.setHTTPMethod("OPTIONS");
- preflightRequest.setHTTPHeaderField("Access-Control-Request-Method", request.httpMethod());
-
- const HTTPHeaderMap& requestHeaderFields = request.httpHeaderFields();
-
- if (requestHeaderFields.size() > 0) {
- Vector<UChar> headerBuffer;
- HTTPHeaderMap::const_iterator it = requestHeaderFields.begin();
- append(headerBuffer, it->first);
- ++it;
-
- HTTPHeaderMap::const_iterator end = requestHeaderFields.end();
- for (; it != end; ++it) {
- headerBuffer.append(',');
- headerBuffer.append(' ');
- append(headerBuffer, it->first);
- }
-
- preflightRequest.setHTTPHeaderField("Access-Control-Request-Headers", String::adopt(headerBuffer));
- }
-
- preflightRequest.setPriority(request.priority());
-
+ ResourceRequest preflightRequest = createAccessControlPreflightRequest(request, m_document->securityOrigin(), m_options.allowCredentials);
loadRequest(preflightRequest, DoSecurityCheck);
}