#include "core/frame/LocalFrame.h"
#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorTraceEvents.h"
#include "core/loader/CrossOriginPreflightResultCache.h"
#include "core/loader/DocumentThreadableLoaderClient.h"
#include "core/loader/FrameLoader.h"
namespace WebCore {
-void DocumentThreadableLoader::loadResourceSynchronously(Document* document, const ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options)
+void DocumentThreadableLoader::loadResourceSynchronously(Document& document, const ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options)
{
// The loader will be deleted as soon as this function exits.
RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoader(document, &client, LoadSynchronously, request, options));
ASSERT(loader->hasOneRef());
}
-PassRefPtr<DocumentThreadableLoader> DocumentThreadableLoader::create(Document* document, ThreadableLoaderClient* client, const ResourceRequest& request, const ThreadableLoaderOptions& options)
+PassRefPtr<DocumentThreadableLoader> DocumentThreadableLoader::create(Document& document, ThreadableLoaderClient* client, const ResourceRequest& request, const ThreadableLoaderOptions& options)
{
RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoader(document, client, LoadAsynchronously, request, options));
if (!loader->resource())
return loader.release();
}
-DocumentThreadableLoader::DocumentThreadableLoader(Document* document, ThreadableLoaderClient* client, BlockingBehavior blockingBehavior, const ResourceRequest& request, const ThreadableLoaderOptions& options)
+DocumentThreadableLoader::DocumentThreadableLoader(Document& document, ThreadableLoaderClient* client, BlockingBehavior blockingBehavior, const ResourceRequest& request, const ThreadableLoaderOptions& options)
: m_client(client)
, m_document(document)
, m_options(options)
, m_async(blockingBehavior == LoadAsynchronously)
, m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout)
{
- ASSERT(document);
ASSERT(client);
// Setting an outgoing referer is only supported in the async code path.
ASSERT(m_async || request.httpReferrer().isEmpty());
+ // Save any CORS simple headers on the request here. If this request redirects cross-origin, we cancel the old request
+ // create a new one, and copy these headers.
+ const HTTPHeaderMap& headerMap = request.httpHeaderFields();
+ HTTPHeaderMap::const_iterator end = headerMap.end();
+ for (HTTPHeaderMap::const_iterator it = headerMap.begin(); it != end; ++it) {
+ if (isOnAccessControlSimpleRequestHeaderWhitelist(it->key, it->value))
+ m_simpleRequestHeaders.add(it->key, it->value);
+ }
+
if (m_sameOriginRequest || m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) {
loadRequest(request);
return;
// original request was not same-origin.
if (m_options.crossOriginRequestPolicy == UseAccessControl) {
- InspectorInstrumentation::didReceiveCORSRedirectResponse(m_document->frame(), resource->identifier(), m_document->frame()->loader().documentLoader(), redirectResponse, 0);
+ InspectorInstrumentation::didReceiveCORSRedirectResponse(m_document.frame(), resource->identifier(), m_document.frame()->loader().documentLoader(), redirectResponse, 0);
bool allowRedirect = false;
String accessControlErrorDescription;
m_options.allowCredentials = DoNotAllowStoredCredentials;
// Remove any headers that may have been added by the network layer that cause access control to fail.
- request.clearHTTPContentType();
request.clearHTTPReferrer();
request.clearHTTPOrigin();
request.clearHTTPUserAgent();
- request.clearHTTPAccept();
+ // Add any CORS simple request headers which we previously saved from the original request.
+ HTTPHeaderMap::const_iterator end = m_simpleRequestHeaders.end();
+ for (HTTPHeaderMap::const_iterator it = m_simpleRequestHeaders.begin(); it != end; ++it) {
+ request.setHTTPHeaderField(it->key, it->value);
+ }
makeCrossOriginAccessRequest(request);
return;
}
// cause the underlying ResourceLoader to be cancelled before it tells the inspector about the response.
// In that case, if we don't tell the inspector about the response now, the resource type in the inspector
// will default to "other" instead of something more descriptive.
- DocumentLoader* loader = m_document->frame()->loader().documentLoader();
- InspectorInstrumentation::didReceiveResourceResponse(m_document->frame(), identifier, loader, response, resource() ? resource()->loader() : 0);
+ DocumentLoader* loader = m_document.frame()->loader().documentLoader();
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ResourceReceiveResponse", "data", InspectorReceiveResponseEvent::data(identifier, m_document.frame(), response));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentation::didReceiveResourceResponse(m_document.frame(), identifier, loader, response, resource() ? resource()->loader() : 0);
if (!passesAccessControlCheck(response, m_options.allowCredentials, securityOrigin(), accessControlErrorDescription)) {
preflightFailure(response.url().string(), accessControlErrorDescription);
FetchRequest newRequest(request, m_options.initiator, options);
ASSERT(!resource());
- setResource(m_document->fetcher()->fetchRawResource(newRequest));
+ if (request.targetType() == ResourceRequest::TargetIsMedia)
+ setResource(m_document.fetcher()->fetchMedia(newRequest));
+ else
+ setResource(m_document.fetcher()->fetchRawResource(newRequest));
if (resource() && resource()->loader()) {
unsigned long identifier = resource()->identifier();
- InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(m_document, identifier, m_client);
+ InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(&m_document, identifier, m_client);
}
return;
}
FetchRequest fetchRequest(request, m_options.initiator, options);
- ResourcePtr<Resource> resource = m_document->fetcher()->fetchSynchronously(fetchRequest);
+ ResourcePtr<Resource> resource = m_document.fetcher()->fetchSynchronously(fetchRequest);
ResourceResponse response = resource ? resource->response() : ResourceResponse();
unsigned long identifier = resource ? resource->identifier() : std::numeric_limits<unsigned long>::max();
ResourceError error = resource ? resource->resourceError() : ResourceError();
- InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(m_document, identifier, m_client);
+ InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(&m_document, identifier, m_client);
if (!resource) {
m_client->didFail(error);
{
if (m_options.contentSecurityPolicyEnforcement != EnforceConnectSrcDirective)
return true;
- return m_document->contentSecurityPolicy()->allowConnectToSource(url);
+ return m_document.contentSecurityPolicy()->allowConnectToSource(url);
}
SecurityOrigin* DocumentThreadableLoader::securityOrigin() const
{
- return m_options.securityOrigin ? m_options.securityOrigin.get() : m_document->securityOrigin();
+ return m_options.securityOrigin ? m_options.securityOrigin.get() : m_document.securityOrigin();
}
} // namespace WebCore