Index: third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp |
diff --git a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp |
index dfb5ce59509f161261dc51ded2e76f08d5467cf9..b23c717a45f319e27090a277e3120d419010aff0 100644 |
--- a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp |
+++ b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp |
@@ -107,39 +107,45 @@ static const int kMaxCORSRedirects = 20; |
void DocumentThreadableLoader::loadResourceSynchronously(Document& document, const ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions) |
{ |
// The loader will be deleted as soon as this function exits. |
- RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoader(document, &client, LoadSynchronously, request, options, resourceLoaderOptions)); |
+ RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoader(document, &client, LoadSynchronously, options, resourceLoaderOptions)); |
+ loader->start(request); |
ASSERT(loader->hasOneRef()); |
} |
-PassRefPtr<DocumentThreadableLoader> DocumentThreadableLoader::create(Document& document, ThreadableLoaderClient* client, const ResourceRequest& request, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions) |
+PassRefPtr<DocumentThreadableLoader> DocumentThreadableLoader::create(Document& document, ThreadableLoaderClient* client, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions) |
{ |
- RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoader(document, client, LoadAsynchronously, request, options, resourceLoaderOptions)); |
- if (!loader->resource()) |
- loader = nullptr; |
- return loader.release(); |
+ return adoptRef(new DocumentThreadableLoader(document, client, LoadAsynchronously, options, resourceLoaderOptions)); |
} |
-DocumentThreadableLoader::DocumentThreadableLoader(Document& document, ThreadableLoaderClient* client, BlockingBehavior blockingBehavior, const ResourceRequest& request, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions) |
+DocumentThreadableLoader::DocumentThreadableLoader(Document& document, ThreadableLoaderClient* client, BlockingBehavior blockingBehavior, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions) |
: m_client(client) |
, m_document(&document) |
, m_options(options) |
, m_resourceLoaderOptions(resourceLoaderOptions) |
, m_forceDoNotAllowStoredCredentials(false) |
, m_securityOrigin(m_resourceLoaderOptions.securityOrigin) |
- , m_sameOriginRequest(securityOrigin()->canRequestNoSuborigin(request.url())) |
+ , m_sameOriginRequest(false) |
, m_crossOriginNonSimpleRequest(false) |
, m_isUsingDataConsumerHandle(false) |
, m_async(blockingBehavior == LoadAsynchronously) |
- , m_requestContext(request.requestContext()) |
+ , m_requestContext(WebURLRequest::RequestContextUnspecified) |
, m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout) |
, m_requestStartedSeconds(0.0) |
, m_corsRedirectLimit(kMaxCORSRedirects) |
- , m_redirectMode(request.fetchRedirectMode()) |
+ , m_redirectMode(WebURLRequest::FetchRedirectModeFollow) |
{ |
ASSERT(client); |
+} |
+ |
+void DocumentThreadableLoader::start(const ResourceRequest& request) |
+{ |
// Setting an outgoing referer is only supported in the async code path. |
ASSERT(m_async || request.httpReferrer().isEmpty()); |
+ m_sameOriginRequest = securityOrigin()->canRequestNoSuborigin(request.url()); |
+ m_requestContext = request.requestContext(); |
+ m_redirectMode = request.fetchRedirectMode(); |
+ |
if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == DenyCrossOriginRequests) { |
ThreadableLoaderClient* client = m_client; |
clear(); |
@@ -177,13 +183,13 @@ DocumentThreadableLoader::DocumentThreadableLoader(Document& document, Threadabl |
// - Some non-script initiated fetches such as WorkerScriptLoader also use |
// ThreadableLoader, but they are guaranteed to use GET method. |
if (request.httpMethod() != HTTPNames::GET) { |
- if (Page* page = document.page()) |
+ if (Page* page = m_document->page()) |
page->chromeClient().didObserveNonGetFetchFromScript(); |
} |
// We assume that ServiceWorker is skipped for sync requests and unsupported |
// protocol requests by content/ code. |
- if (m_async && !request.skipServiceWorker() && SchemeRegistry::shouldTreatURLSchemeAsAllowingServiceWorkers(request.url().protocol()) && document.fetcher()->isControlledByServiceWorker()) { |
+ if (m_async && !request.skipServiceWorker() && SchemeRegistry::shouldTreatURLSchemeAsAllowingServiceWorkers(request.url().protocol()) && m_document->fetcher()->isControlledByServiceWorker()) { |
ResourceRequest newRequest(request); |
const WebURLRequest::RequestContext requestContext(request.requestContext()); |
if (requestContext != WebURLRequest::RequestContextFetch) { |
@@ -198,7 +204,7 @@ DocumentThreadableLoader::DocumentThreadableLoader(Document& document, Threadabl |
newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeSameOrigin); |
break; |
case UseAccessControl: |
- if (options.preflightPolicy == ForcePreflight) |
+ if (m_options.preflightPolicy == ForcePreflight) |
newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeCORSWithForcedPreflight); |
else |
newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeCORS); |
@@ -220,6 +226,7 @@ DocumentThreadableLoader::DocumentThreadableLoader(Document& document, Threadabl |
} |
loadRequest(newRequest, m_resourceLoaderOptions); |
+ // |this| may be dead here. |
return; |
} |
@@ -231,6 +238,7 @@ void DocumentThreadableLoader::dispatchInitialRequest(const ResourceRequest& req |
{ |
if (m_sameOriginRequest || m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) { |
loadRequest(request, m_resourceLoaderOptions); |
+ // |this| may be dead here in async mode. |
return; |
} |
@@ -270,6 +278,7 @@ void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceReques |
// FIXME: We should set it in the caller of DocumentThreadableLoader. |
crossOriginRequest.setFetchCredentialsMode(effectiveAllowCredentials() == AllowStoredCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRequest::FetchCredentialsModeOmit); |
loadRequest(crossOriginRequest, crossOriginOptions); |
+ // |this| may be dead here in async mode. |
} else { |
m_crossOriginNonSimpleRequest = true; |
@@ -287,12 +296,14 @@ void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceReques |
bool canSkipPreflight = CrossOriginPreflightResultCache::shared().canSkipPreflight(securityOrigin()->toString(), m_actualRequest.url(), effectiveAllowCredentials(), m_actualRequest.httpMethod(), m_actualRequest.httpHeaderFields()); |
if (canSkipPreflight && !shouldForcePreflight) { |
loadActualRequest(); |
+ // |this| may be dead here in async mode. |
} else { |
ResourceRequest preflightRequest = createAccessControlPreflightRequest(m_actualRequest, securityOrigin()); |
// Create a ResourceLoaderOptions for preflight. |
ResourceLoaderOptions preflightOptions = m_actualOptions; |
preflightOptions.allowCredentials = DoNotAllowStoredCredentials; |
loadRequest(preflightRequest, preflightOptions); |
+ // |this| may be dead here in async mode. |
} |
} |
} |
@@ -715,6 +726,7 @@ void DocumentThreadableLoader::handleSuccessfulFinish(unsigned long identifier, |
ASSERT(!m_sameOriginRequest); |
ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); |
loadActualRequest(); |
+ // |this| may be dead here in async mode. |
return; |
} |
@@ -764,6 +776,7 @@ void DocumentThreadableLoader::loadActualRequest() |
clearResource(); |
loadRequest(actualRequest, actualOptions); |
+ // |this| may be dead here in async mode. |
} |
void DocumentThreadableLoader::handlePreflightFailure(const String& url, const String& errorDescription) |
@@ -814,13 +827,23 @@ void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, Resou |
if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) |
newRequest.setOriginRestriction(FetchRequest::NoOriginRestriction); |
ASSERT(!resource()); |
+ |
if (request.requestContext() == WebURLRequest::RequestContextVideo || request.requestContext() == WebURLRequest::RequestContextAudio) |
setResource(RawResource::fetchMedia(newRequest, document().fetcher())); |
else if (request.requestContext() == WebURLRequest::RequestContextManifest) |
setResource(RawResource::fetchManifest(newRequest, document().fetcher())); |
else |
setResource(RawResource::fetch(newRequest, document().fetcher())); |
- if (resource() && resource()->loader()) { |
+ |
+ if (!resource()) { |
+ ThreadableLoaderClient* client = m_client; |
+ clear(); |
+ client->didFail(ResourceError(errorDomainBlinkInternal, 0, requestURL.string(), "Failed to start loading.")); |
+ // |this| may be dead here. |
+ return; |
+ } |
+ |
+ if (resource()->loader()) { |
unsigned long identifier = resource()->identifier(); |
InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(m_document, identifier, m_client); |
} |