void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, ResourceLoaderOptions resourceLoaderOptions) { // Any credential should have been removed from the cross-site requests. const KURL& requestURL = request.url(); ASSERT(m_sameOriginRequest || requestURL.user().isEmpty()); ASSERT(m_sameOriginRequest || requestURL.pass().isEmpty()); // Update resourceLoaderOptions with enforced values. if (m_forceDoNotAllowStoredCredentials) resourceLoaderOptions.allowCredentials = DoNotAllowStoredCredentials; resourceLoaderOptions.securityOrigin = m_securityOrigin; if (m_async) { if (!m_actualRequest.isNull()) resourceLoaderOptions.dataBufferingPolicy = BufferData; if (m_options.timeoutMilliseconds > 0) m_timeoutTimer.startOneShot(m_options.timeoutMilliseconds / 1000.0, BLINK_FROM_HERE); FetchRequest newRequest(request, m_options.initiator, resourceLoaderOptions); 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()) { unsigned long identifier = resource()->identifier(); InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(m_document, identifier, m_client); } return; } FetchRequest fetchRequest(request, m_options.initiator, resourceLoaderOptions); if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) fetchRequest.setOriginRestriction(FetchRequest::NoOriginRestriction); ResourcePtr<Resource> resource = RawResource::fetchSynchronously(fetchRequest, document().fetcher()); 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); if (!resource) { m_client->didFail(error); return; } // No exception for file:/// resources, see <rdar://problem/4962298>. // Also, if we have an HTTP response, then it wasn't a network error in fact. if (!error.isNull() && !requestURL.isLocalFile() && response.httpStatusCode() <= 0) { m_client->didFail(error); return; } // FIXME: A synchronous request does not tell us whether a redirect happened or not, so we guess by comparing the // request and response URLs. This isn't a perfect test though, since a server can serve a redirect to the same URL that was // requested. Also comparing the request and response URLs as strings will fail if the requestURL still has its credentials. if (requestURL != response.url() && (!isAllowedByContentSecurityPolicy(response.url(), ContentSecurityPolicy::DidRedirect) || !isAllowedRedirect(response.url()))) { m_client->didFailRedirectCheck(); return; } handleResponse(identifier, response, nullptr); // handleResponse() may detect an error. In such a case (check |m_client| // as it gets reset by clear() call), skip the rest. // // |this| is alive here since loadResourceSynchronously() keeps it alive // until the end of the function. if (!m_client) return; SharedBuffer* data = resource->resourceBuffer(); if (data) handleReceivedData(data->data(), data->size()); // The client may cancel this loader in handleReceivedData(). In such a // case, skip the rest. if (!m_client) return; handleSuccessfulFinish(identifier, 0.0); }
void DocumentThreadableLoader::loadRequest(const ResourceRequest& request) { // Any credential should have been removed from the cross-site requests. const KURL& requestURL = request.url(); ASSERT(m_sameOriginRequest || requestURL.user().isEmpty()); ASSERT(m_sameOriginRequest || requestURL.pass().isEmpty()); ThreadableLoaderOptions options = m_options; if (m_async) { if (m_actualRequest) { options.sniffContent = DoNotSniffContent; options.dataBufferingPolicy = BufferData; } if (m_options.timeoutMilliseconds > 0) m_timeoutTimer.startOneShot(m_options.timeoutMilliseconds / 1000.0); FetchRequest newRequest(request, m_options.initiator, options); ASSERT(!resource()); setResource(m_document->fetcher()->fetchRawResource(newRequest)); if (resource() && resource()->loader()) { unsigned long identifier = resource()->identifier(); InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(m_document, identifier, m_client); } return; } FetchRequest fetchRequest(request, m_options.initiator, options); 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); if (!resource) { m_client->didFail(error); return; } // No exception for file:/// resources, see <rdar://problem/4962298>. // Also, if we have an HTTP response, then it wasn't a network error in fact. if (!error.isNull() && !requestURL.isLocalFile() && response.httpStatusCode() <= 0) { m_client->didFail(error); return; } // FIXME: A synchronous request does not tell us whether a redirect happened or not, so we guess by comparing the // request and response URLs. This isn't a perfect test though, since a server can serve a redirect to the same URL that was // requested. Also comparing the request and response URLs as strings will fail if the requestURL still has its credentials. if (requestURL != response.url() && (!isAllowedByPolicy(response.url()) || !isAllowedRedirect(response.url()))) { m_client->didFailRedirectCheck(); return; } didReceiveResponse(identifier, response); SharedBuffer* data = resource->resourceBuffer(); if (data) didReceiveData(data->data(), data->size()); didFinishLoading(identifier, 0.0); }