| 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);
|
| }
|
|
|