void MainResourceLoader::handleDataLoadNow(Timer<MainResourceLoader>*) { RefPtr<MainResourceLoader> protect(this); ResourceResponse response(m_initialRequest.url(), m_substituteData.mimeType(), m_substituteData.content()->size(), m_substituteData.textEncoding(), ""); didReceiveResponse(response); }
void ResourceLoader::requestSynchronously() { OwnPtr<blink::WebURLLoader> loader = adoptPtr(blink::Platform::current()->createURLLoader()); ASSERT(loader); RefPtr<ResourceLoader> protect(this); RefPtr<ResourceLoaderHost> protectHost(m_host); ResourcePtr<Resource> protectResource(m_resource); RELEASE_ASSERT(m_connectionState == ConnectionStateNew); m_connectionState = ConnectionStateStarted; blink::WrappedResourceRequest requestIn(m_request); requestIn.setAllowStoredCredentials(m_options.allowCredentials == AllowStoredCredentials); blink::WebURLResponse responseOut; responseOut.initialize(); blink::WebURLError errorOut; blink::WebData dataOut; loader->loadSynchronously(requestIn, responseOut, errorOut, dataOut); if (errorOut.reason) { didFail(0, errorOut); return; } didReceiveResponse(0, responseOut); if (m_state == Terminated) return; RefPtr<ResourceLoadInfo> resourceLoadInfo = responseOut.toResourceResponse().resourceLoadInfo(); int64 encodedDataLength = resourceLoadInfo ? resourceLoadInfo->encodedDataLength : blink::WebURLLoaderClient::kUnknownEncodedDataLength; m_host->didReceiveData(m_resource, dataOut.data(), dataOut.size(), encodedDataLength); m_resource->setResourceBuffer(dataOut); didFinishLoading(0, monotonicallyIncreasingTime(), encodedDataLength); }
void ResourceLoader::requestSynchronously() { OwnPtr<WebKit::WebURLLoader> loader = adoptPtr(WebKit::Platform::current()->createURLLoader()); ASSERT(loader); RELEASE_ASSERT(m_connectionState == ConnectionStateNew); m_connectionState = ConnectionStateStarted; WebKit::WrappedResourceRequest requestIn(m_request); requestIn.setAllowStoredCredentials(m_options.allowCredentials == AllowStoredCredentials); WebKit::WebURLResponse responseOut; responseOut.initialize(); WebKit::WebURLError errorOut; WebKit::WebData dataOut; loader->loadSynchronously(requestIn, responseOut, errorOut, dataOut); if (errorOut.reason) { didFail(0, errorOut); return; } didReceiveResponse(0, responseOut); RefPtr<ResourceLoadInfo> resourceLoadInfo = responseOut.toResourceResponse().resourceLoadInfo(); m_host->didReceiveData(m_resource, dataOut.data(), dataOut.size(), resourceLoadInfo ? resourceLoadInfo->encodedDataLength : -1, m_options); m_resource->setResourceBuffer(dataOut); didFinishLoading(0, responseOut.responseTime()); }
void CurlDownload::didReceiveHeader(const String& header) { LockHolder locker(m_mutex); if (header == "\r\n" || header == "\n") { long httpCode = 0; CURLcode err = curl_easy_getinfo(m_curlHandle, CURLINFO_RESPONSE_CODE, &httpCode); if (httpCode >= 200 && httpCode < 300) { URL url = getCurlEffectiveURL(m_curlHandle); callOnMainThread([this, url = url.isolatedCopy(), protectedThis = makeRef(*this)] { m_response.setURL(url); m_response.setMimeType(extractMIMETypeFromMediaType(m_response.httpHeaderField(HTTPHeaderName::ContentType))); m_response.setTextEncodingName(extractCharsetFromMediaType(m_response.httpHeaderField(HTTPHeaderName::ContentType))); didReceiveResponse(); }); } } else { callOnMainThread([this, header = header.isolatedCopy(), protectedThis = makeRef(*this)] { int splitPos = header.find(":"); if (splitPos != -1) m_response.setHTTPHeaderField(header.left(splitPos), header.substring(splitPos + 1).stripWhiteSpace()); }); } }
void CurlDownload::didReceiveHeader(const String& header) { MutexLocker locker(m_mutex); if (header == "\r\n" || header == "\n") { long httpCode = 0; CURLcode err = curl_easy_getinfo(m_curlHandle, CURLINFO_RESPONSE_CODE, &httpCode); if (httpCode >= 200 && httpCode < 300) { const char* url = 0; err = curl_easy_getinfo(m_curlHandle, CURLINFO_EFFECTIVE_URL, &url); m_response.setURL(URL(ParsedURLString, url)); m_response.setMimeType(extractMIMETypeFromMediaType(m_response.httpHeaderField(HTTPHeaderName::ContentType))); m_response.setTextEncodingName(extractCharsetFromMediaType(m_response.httpHeaderField(HTTPHeaderName::ContentType))); callOnMainThread([this] { didReceiveResponse(); }); } } else { int splitPos = header.find(":"); if (splitPos != -1) m_response.setHTTPHeaderField(header.left(splitPos), header.substring(splitPos+1).stripWhiteSpace()); } }
void ResourceLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response) { #if ENABLE(OFFLINE_WEB_APPLICATIONS) if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForResponse(this, response)) return; #endif didReceiveResponse(response); }
void ResourceLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response) { #if ENABLE(OFFLINE_WEB_APPLICATIONS) if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForResponse(this, response)) return; #endif InspectorInstrumentationCookie cookie = InspectorInstrumentation::willReceiveResourceResponse(m_frame.get(), identifier(), response); didReceiveResponse(response); InspectorInstrumentation::didReceiveResourceResponse(cookie); }
void ResourceLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response) { #if ENABLE(OFFLINE_WEB_APPLICATIONS) if (response.httpStatusCode() / 100 == 4 || response.httpStatusCode() / 100 == 5) { if (scheduleLoadFallbackResourceFromApplicationCache()) return; } #endif didReceiveResponse(response); }
void MainResourceLoader::handleDataLoadNow(MainResourceLoaderTimer*) { RefPtr<MainResourceLoader> protect(this); KURL url = m_substituteData.responseURL(); if (url.isEmpty()) url = m_initialRequest.url(); ResourceResponse response(url, m_substituteData.mimeType(), m_substituteData.content()->size(), m_substituteData.textEncoding(), ""); didReceiveResponse(response); }
void MainResourceLoader::handleEmptyLoad(const KURL& url, bool forURLScheme) { String mimeType; if (forURLScheme) mimeType = frameLoader()->client()->generatedMIMETypeForURLScheme(url.protocol()); else mimeType = "text/html"; ResourceResponse response(url, mimeType, 0, String(), String()); didReceiveResponse(response); }
void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, SecurityCheckPolicy securityCheck) { // 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()); if (m_async) { // Don't sniff content or send load callbacks for the preflight request. bool sendLoadCallbacks = m_options.sendLoadCallbacks && !m_actualRequest; bool sniffContent = m_options.sniffContent && !m_actualRequest; // Keep buffering the data for the preflight request. bool shouldBufferData = m_options.shouldBufferData || m_actualRequest; // Clear the loader so that any callbacks from SubresourceLoader::create will not have the old loader. m_loader = 0; m_loader = resourceLoadScheduler()->scheduleSubresourceLoad(m_document->frame(), this, request, ResourceLoadPriorityMedium, securityCheck, sendLoadCallbacks, sniffContent, m_optionalOutgoingReferrer, shouldBufferData); return; } // FIXME: ThreadableLoaderOptions.sniffContent is not supported for synchronous requests. StoredCredentials storedCredentials = m_options.allowCredentials ? AllowStoredCredentials : DoNotAllowStoredCredentials; Vector<char> data; ResourceError error; ResourceResponse response; unsigned long identifier = std::numeric_limits<unsigned long>::max(); if (m_document->frame()) identifier = m_document->frame()->loader()->loadResourceSynchronously(request, storedCredentials, error, response, data); // 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: FrameLoader::loadSynchronously() 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() && !isAllowedRedirect(response.url())) { m_client->didFailRedirectCheck(); return; } didReceiveResponse(0, response); const char* bytes = static_cast<const char*>(data.data()); int len = static_cast<int>(data.size()); didReceiveData(0, bytes, len); didFinishLoading(identifier, 0.0); }
void MainResourceLoader::handleSubstituteDataLoadNow(MainResourceLoaderTimer*) { RefPtr<MainResourceLoader> protect(this); KURL url = m_substituteData.responseURL(); if (url.isEmpty()) url = m_initialRequest.url(); // Clear the initial request here so that subsequent entries into the // loader will not think there's still a deferred load left to do. m_initialRequest = ResourceRequest(); ResourceResponse response(url, m_substituteData.mimeType(), m_substituteData.content()->size(), m_substituteData.textEncoding(), ""); didReceiveResponse(response); }
void Downloader::performDownload() { long repCode = -1; CURLcode res = CURLE_OK; res = curl_easy_perform(m_curl); if ( CURLE_OK == res ) { curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, &repCode); //char buf[8]; //curl_easy_getinfo(m_curl, CURLINFO_CONTENT_TYPE, &buf); } didReceiveResponse(repCode); didFinishLoading(); }
void PluginStream::sendJavaScriptStream(const KURL& requestURL, const CString& resultString) { didReceiveResponse(0, ResourceResponse(requestURL, "text/plain", resultString.length(), "", "")); if (m_streamState == StreamStopped) return; if (!resultString.isNull()) { didReceiveData(0, resultString.data(), resultString.length()); if (m_streamState == StreamStopped) return; } m_loader = 0; destroyStream(resultString.isNull() ? NPRES_NETWORK_ERR : NPRES_DONE); }
void ResourceLoader::deliverResponseAndData(const ResourceResponse& response, RefPtr<SharedBuffer>&& buffer) { Ref<ResourceLoader> protect(*this); didReceiveResponse(response); if (reachedTerminalState()) return; if (buffer) { unsigned size = buffer->size(); didReceiveBuffer(buffer.release(), size, DataPayloadWholeResource); if (reachedTerminalState()) return; } didFinishLoading(0); }
void ResourceLoader::requestSynchronously() { OwnPtr<WebURLLoader> loader = adoptPtr(Platform::current()->createURLLoader()); ASSERT(loader); // downloadToFile is not supported for synchronous requests. ASSERT(!m_request.downloadToFile()); ResourcePtr<Resource> protectResource(m_resource); RELEASE_ASSERT(m_connectionState == ConnectionStateNew); m_connectionState = ConnectionStateStarted; WrappedResourceRequest requestIn(m_request); WebURLResponse responseOut; responseOut.initialize(); WebURLError errorOut; WebData dataOut; loader->loadSynchronously(requestIn, responseOut, errorOut, dataOut); if (errorOut.reason) { if (m_state == Terminated) { // A message dispatched while synchronously fetching the resource // can bring about the cancellation of this load. ASSERT(!m_resource); return; } didFail(0, errorOut); return; } didReceiveResponse(0, responseOut); if (m_state == Terminated) return; RefPtr<ResourceLoadInfo> resourceLoadInfo = responseOut.toResourceResponse().resourceLoadInfo(); int64_t encodedDataLength = resourceLoadInfo ? resourceLoadInfo->encodedDataLength : WebURLLoaderClient::kUnknownEncodedDataLength; // Follow the async case convention of not calling didReceiveData or // appending data to m_resource if the response body is empty. Copying the // empty buffer is a noop in most cases, but is destructive in the case of // a 304, where it will overwrite the cached data we should be reusing. if (dataOut.size()) { m_fetcher->didReceiveData(m_resource, dataOut.data(), dataOut.size(), encodedDataLength); m_resource->setResourceBuffer(dataOut); } didFinishLoading(0, monotonicallyIncreasingTime(), encodedDataLength); }
void NetworkDataTaskBlob::resume() { ASSERT(m_state != State::Running); if (m_state == State::Canceling || m_state == State::Completed) return; m_state = State::Running; if (m_scheduledFailureType != NoFailure) { ASSERT(m_failureTimer.isActive()); return; } RunLoop::main().dispatch([this, protectedThis = makeRef(*this)] { if (m_state == State::Canceling || m_state == State::Completed || !m_client) { clearStream(); return; } if (!equalLettersIgnoringASCIICase(m_firstRequest.httpMethod(), "get")) { didFail(Error::MethodNotAllowed); return; } // If the blob data is not found, fail now. if (!m_blobData) { didFail(Error::NotFoundError); return; } // Parse the "Range" header we care about. String range = m_firstRequest.httpHeaderField(HTTPHeaderName::Range); if (!range.isEmpty() && !parseRange(range, m_rangeOffset, m_rangeEnd, m_rangeSuffixLength)) { didReceiveResponse(Error::RangeError); return; } getSizeForNext(); }); }
void ResourceLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response) { #if ENABLE(INSPECTOR) if (InspectorTimelineAgent::instanceCount()) { InspectorTimelineAgent* timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0; if (timelineAgent) timelineAgent->willReceiveResourceResponse(identifier(), response); } #endif #if ENABLE(OFFLINE_WEB_APPLICATIONS) if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForResponse(this, response)) return; #endif didReceiveResponse(response); #if ENABLE(INSPECTOR) if (InspectorTimelineAgent::instanceCount()) { InspectorTimelineAgent* timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0; if (timelineAgent) timelineAgent->didReceiveResourceResponse(); } #endif }
void ResourceLoader::requestSynchronously(const ResourceRequest& request) { // downloadToFile is not supported for synchronous requests. DCHECK(!request.downloadToFile()); DCHECK(m_loader); DCHECK_EQ(request.priority(), ResourceLoadPriorityHighest); WrappedResourceRequest requestIn(request); WebURLResponse responseOut; WebURLError errorOut; WebData dataOut; int64_t encodedDataLength = WebURLLoaderClient::kUnknownEncodedDataLength; int64_t encodedBodyLength = 0; m_loader->loadSynchronously(requestIn, responseOut, errorOut, dataOut, encodedDataLength, encodedBodyLength); // A message dispatched while synchronously fetching the resource // can bring about the cancellation of this load. if (!m_loader) return; if (errorOut.reason) { didFail(errorOut, encodedDataLength, encodedBodyLength); return; } didReceiveResponse(responseOut); if (!m_loader) return; DCHECK_GE(responseOut.toResourceResponse().encodedBodyLength(), 0); // Follow the async case convention of not calling didReceiveData or // appending data to m_resource if the response body is empty. Copying the // empty buffer is a noop in most cases, but is destructive in the case of // a 304, where it will overwrite the cached data we should be reusing. if (dataOut.size()) { m_fetcher->didReceiveData(m_resource.get(), dataOut.data(), dataOut.size()); m_resource->setResourceBuffer(dataOut); } didFinishLoading(monotonicallyIncreasingTime(), encodedDataLength, encodedBodyLength); }
void ResourceLoader::requestSynchronously() { OwnPtr<WebURLLoader> loader = adoptPtr(Platform::current()->createURLLoader()); ASSERT(loader); // downloadToFile is not supported for synchronous requests. ASSERT(!m_request.downloadToFile()); ResourcePtr<Resource> protectResource(m_resource); RELEASE_ASSERT(m_connectionState == ConnectionStateNew); m_connectionState = ConnectionStateStarted; WrappedResourceRequest requestIn(m_request); WebURLResponse responseOut; responseOut.initialize(); WebURLError errorOut; WebData dataOut; loader->loadSynchronously(requestIn, responseOut, errorOut, dataOut); if (errorOut.reason) { if (m_state == Terminated) { // A message dispatched while synchronously fetching the resource // can bring about the cancellation of this load. ASSERT(!m_resource); return; } didFail(0, errorOut); return; } didReceiveResponse(0, responseOut); if (m_state == Terminated) return; RefPtr<ResourceLoadInfo> resourceLoadInfo = responseOut.toResourceResponse().resourceLoadInfo(); int64_t encodedDataLength = resourceLoadInfo ? resourceLoadInfo->encodedDataLength : WebURLLoaderClient::kUnknownEncodedDataLength; m_fetcher->didReceiveData(m_resource, dataOut.data(), dataOut.size(), encodedDataLength); m_resource->setResourceBuffer(dataOut); didFinishLoading(0, monotonicallyIncreasingTime(), encodedDataLength); }
void NetworkDataTaskBlob::getSizeForNext() { ASSERT(isMainThread()); // Do we finish validating and counting size for all items? if (m_sizeItemCount >= m_blobData->items().size()) { seek(); didReceiveResponse(); return; } const BlobDataItem& item = m_blobData->items().at(m_sizeItemCount); switch (item.type()) { case BlobDataItem::Type::Data: didGetSize(item.length()); break; case BlobDataItem::Type::File: // Files know their sizes, but asking the stream to verify that the file wasn't modified. m_stream->getSize(item.file()->path(), item.file()->expectedModificationTime()); break; default: ASSERT_NOT_REACHED(); } }
void handleResponse() { m_handleResponseLaterID = 0; didReceiveResponse(0, m_delayedResponse); }
bool MultipartHandle::processContent() { /* The allowed transitions between the states: Check Boundary | /-- In Boundary <----\ | | | | In Header | | | | | In Content | | | | | End Boundary ----/ | | \-----> End */ switch (m_state) { case CheckBoundary: { if (m_buffer.size() < m_boundaryLength) { // We don't have enough data, so just skip. return false; } // Check for the boundary string. size_t boundaryStart; size_t lastPartialMatch; if (!checkForBoundary(boundaryStart, lastPartialMatch) && boundaryStart == notFound) { // Did not find the boundary start in this chunk. // Skip ahead to the last valid looking boundary character and start again. m_buffer.remove(0, lastPartialMatch); return false; } // Found the boundary start. // Consume everything before that and also the boundary m_buffer.remove(0, boundaryStart + m_boundaryLength); m_state = InBoundary; } // Fallthrough. case InBoundary: { // Now the first two characters should be: \r\n if (m_buffer.size() < 2) return false; const char* content = m_buffer.data(); // By default we'll remove 2 characters at the end. // The \r and \n as stated in the multipart RFC. size_t removeCount = 2; if (content[0] != '\r' || content[1] != '\n') { // There should be a \r and a \n but it seems that's not the case. // So we'll check for a simple \n. Not really RFC compatible but servers do tricky things. if (content[0] != '\n') { // Also no \n so just go to the end. m_state = End; return false; } // Found a simple \n so remove just that. removeCount = 1; } // Consume the characters. m_buffer.remove(0, removeCount); m_headers.clear(); m_state = InHeader; } // Fallthrough. case InHeader: { // Process the headers. if (!parseHeadersIfPossible()) { // Parsing of headers failed, try again later. return false; } didReceiveResponse(); m_state = InContent; } // Fallthrough. case InContent: { if (m_buffer.isEmpty()) return false; size_t boundaryStart = notFound; size_t lastPartialMatch; if (!checkForBoundary(boundaryStart, lastPartialMatch) && boundaryStart == notFound) { // Did not find the boundary start, all data up to the lastPartialMatch is ok. didReceiveData(lastPartialMatch); m_buffer.remove(0, lastPartialMatch); return false; } // There was a boundary start (or end we'll check that later), push out part of the data. didReceiveData(boundaryStart); m_buffer.remove(0, boundaryStart + m_boundaryLength); m_state = EndBoundary; } // Fallthrough. case EndBoundary: { if (m_buffer.size() < 2) return false; // Not enough data to check. Return later when there is more data. // We'll decide if this is a closing boundary or an opening one. const char* content = m_buffer.data(); if (content[0] == '-' && content[1] == '-') { // This is a closing boundary. Close down the handler. m_state = End; return false; } // This was a simple content separator not a closing one. // Go to before the content processing. m_state = InBoundary; break; } case End: // We are done. Nothing to do anymore. return false; default: ASSERT_NOT_REACHED(); return false; } return true; // There are still things to process, so go for it. }
void ResourceLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response) { didReceiveResponse(response); }
void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, SecurityCheckPolicy securityCheck) { // Any credential should have been removed from the cross-site requests. const KURL& requestURL = request.url(); m_options.securityCheck = securityCheck; ASSERT(m_sameOriginRequest || requestURL.user().isEmpty()); ASSERT(m_sameOriginRequest || requestURL.pass().isEmpty()); if (m_async) { ThreadableLoaderOptions options = m_options; options.crossOriginCredentialPolicy = DoNotAskClientForCrossOriginCredentials; if (m_actualRequest) { // Don't sniff content or send load callbacks for the preflight request. options.sendLoadCallbacks = DoNotSendCallbacks; options.sniffContent = DoNotSniffContent; // Keep buffering the data for the preflight request. options.shouldBufferData = BufferData; } CachedResourceRequest newRequest(request, options); #if ENABLE(INSPECTOR) if (m_actualRequest) { // Because willSendRequest only gets called during redirects, we initialize the identifier and the first willSendRequest here. m_preflightRequestIdentifier = m_document->frame()->page()->progress()->createUniqueIdentifier(); ResourceResponse redirectResponse = ResourceResponse(); InspectorInstrumentation::willSendRequest(m_document->frame(), m_preflightRequestIdentifier, m_document->frame()->loader()->documentLoader(), newRequest.mutableResourceRequest(), redirectResponse); } #endif ASSERT(!m_resource); m_resource = m_document->cachedResourceLoader()->requestRawResource(newRequest); if (m_resource) { #if ENABLE(INSPECTOR) if (m_resource->loader()) { unsigned long identifier = m_actualRequest ? m_preflightRequestIdentifier : m_resource->loader()->identifier(); InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(m_document, identifier, m_client); } #endif m_resource->addClient(this); } return; } // FIXME: ThreadableLoaderOptions.sniffContent is not supported for synchronous requests. Vector<char> data; ResourceError error; ResourceResponse response; unsigned long identifier = std::numeric_limits<unsigned long>::max(); if (m_document->frame()) identifier = m_document->frame()->loader()->loadResourceSynchronously(request, m_options.allowCredentials, error, response, data); InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(m_document, identifier, m_client); // 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: FrameLoader::loadSynchronously() 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() && !isAllowedRedirect(response.url())) { m_client->didFailRedirectCheck(); return; } didReceiveResponse(identifier, response); const char* bytes = static_cast<const char*>(data.data()); int len = static_cast<int>(data.size()); dataReceived(0, bytes, len); didFinishLoading(identifier, 0.0); }
void ResourceLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response) { if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForResponse(this, response)) return; didReceiveResponse(response); }
void handleResponse() { didReceiveResponse(nullptr, m_delayedResponse); }
void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, SecurityCheckPolicy securityCheck) { // Any credential should have been removed from the cross-site requests. const URL& requestURL = request.url(); m_options.setSecurityCheck(securityCheck); ASSERT(m_sameOriginRequest || requestURL.user().isEmpty()); ASSERT(m_sameOriginRequest || requestURL.pass().isEmpty()); if (m_async) { ThreadableLoaderOptions options = m_options; options.setClientCredentialPolicy(DoNotAskClientForCrossOriginCredentials); if (m_actualRequest) { // Don't sniff content or send load callbacks for the preflight request. options.setSendLoadCallbacks(DoNotSendCallbacks); options.setSniffContent(DoNotSniffContent); // Keep buffering the data for the preflight request. options.setDataBufferingPolicy(BufferData); } CachedResourceRequest newRequest(request, options); if (RuntimeEnabledFeatures::sharedFeatures().resourceTimingEnabled()) newRequest.setInitiator(m_options.initiator); ASSERT(!m_resource); m_resource = m_document.cachedResourceLoader().requestRawResource(newRequest); if (m_resource) m_resource->addClient(this); return; } // FIXME: ThreadableLoaderOptions.sniffContent is not supported for synchronous requests. RefPtr<SharedBuffer> data; ResourceError error; ResourceResponse response; unsigned long identifier = std::numeric_limits<unsigned long>::max(); if (m_document.frame()) identifier = m_document.frame()->loader().loadResourceSynchronously(request, m_options.allowCredentials(), m_options.clientCredentialPolicy(), error, response, data); if (!error.isNull() && response.httpStatusCode() <= 0) { if (requestURL.isLocalFile()) { // We don't want XMLHttpRequest to raise an exception for file:// resources, see <rdar://problem/4962298>. // FIXME: XMLHttpRequest quirks should be in XMLHttpRequest code, not in DocumentThreadableLoader.cpp. didReceiveResponse(identifier, response); didFinishLoading(identifier, 0.0); return; } m_client->didFail(error); return; } // FIXME: FrameLoader::loadSynchronously() 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. bool didRedirect = requestURL != response.url(); if (didRedirect && (!isAllowedByContentSecurityPolicy(response.url(), didRedirect) || !isAllowedRedirect(response.url()))) { m_client->didFailRedirectCheck(); return; } didReceiveResponse(identifier, response); if (data) didReceiveData(identifier, data->data(), data->size()); didFinishLoading(identifier, 0.0); }
void DocumentThreadableLoader::responseReceived(CachedResource* resource, const ResourceResponse& response) { ASSERT_UNUSED(resource, resource == m_resource); didReceiveResponse(m_resource->identifier(), response); }
void ResourceLoader::didReceiveResponse(WebURLLoader* loader, const WebURLResponse& response) { didReceiveResponse(loader, response, nullptr); }