void Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& serveLowerPriority) { while (!requestsPending.isEmpty()) { Request* request = requestsPending.first(); DocLoader* docLoader = request->docLoader(); bool resourceIsCacheValidator = request->cachedResource()->isCacheValidator(); // For named hosts - which are only http(s) hosts - we should always enforce the connection limit. // For non-named hosts - everything but http(s) - we should only enforce the limit if the document isn't done parsing // and we don't know all stylesheets yet. bool shouldLimitRequests = !m_name.isNull() || docLoader->doc()->parsing() || !docLoader->doc()->haveStylesheetsLoaded(); if (shouldLimitRequests && m_requestsLoading.size() + m_nonCachedRequestsInFlight >= m_maxRequestsInFlight) { serveLowerPriority = false; cache()->loader()->scheduleServePendingRequests(); return; } requestsPending.removeFirst(); ResourceRequest resourceRequest(request->cachedResource()->url()); resourceRequest.setTargetType(cachedResourceTypeToTargetType(request->cachedResource()->type())); if (!request->cachedResource()->accept().isEmpty()) resourceRequest.setHTTPAccept(request->cachedResource()->accept()); // Do not set the referrer or HTTP origin here. That's handled by SubresourceLoader::create. if (resourceIsCacheValidator) { CachedResource* resourceToRevalidate = request->cachedResource()->resourceToRevalidate(); ASSERT(resourceToRevalidate->canUseCacheValidator()); ASSERT(resourceToRevalidate->isLoaded()); const String& lastModified = resourceToRevalidate->response().httpHeaderField("Last-Modified"); const String& eTag = resourceToRevalidate->response().httpHeaderField("ETag"); if (!lastModified.isEmpty() || !eTag.isEmpty()) { ASSERT(docLoader->cachePolicy() != CachePolicyReload); if (docLoader->cachePolicy() == CachePolicyRevalidate) resourceRequest.setHTTPHeaderField("Cache-Control", "max-age=0"); if (!lastModified.isEmpty()) resourceRequest.setHTTPHeaderField("If-Modified-Since", lastModified); if (!eTag.isEmpty()) resourceRequest.setHTTPHeaderField("If-None-Match", eTag); } } RefPtr<SubresourceLoader> loader = SubresourceLoader::create(docLoader->doc()->frame(), this, resourceRequest, request->shouldDoSecurityCheck(), request->sendResourceLoadCallbacks()); if (loader) { m_requestsLoading.add(loader.release(), request); request->cachedResource()->setRequestedFromNetworkingLayer(); #if REQUEST_DEBUG printf("HOST %s COUNT %d LOADING %s\n", resourceRequest.url().host().latin1().data(), m_requestsLoading.size(), request->cachedResource()->url().latin1().data()); #endif } else { docLoader->decrementRequestCount(); docLoader->setLoadInProgress(true); request->cachedResource()->error(); docLoader->setLoadInProgress(false); delete request; } } }
void CachedResource::load(CachedResourceLoader* cachedResourceLoader, const ResourceLoaderOptions& options) { if (!cachedResourceLoader->frame()) { failBeforeStarting(); return; } m_options = options; m_loading = true; if (!accept().isEmpty()) m_resourceRequest.setHTTPAccept(accept()); if (isCacheValidator()) { CachedResource* resourceToRevalidate = m_resourceToRevalidate; ASSERT(resourceToRevalidate->canUseCacheValidator()); ASSERT(resourceToRevalidate->isLoaded()); const String& lastModified = resourceToRevalidate->response().httpHeaderField("Last-Modified"); const String& eTag = resourceToRevalidate->response().httpHeaderField("ETag"); if (!lastModified.isEmpty() || !eTag.isEmpty()) { ASSERT(cachedResourceLoader->cachePolicy(type()) != CachePolicyReload); if (cachedResourceLoader->cachePolicy(type()) == CachePolicyRevalidate) m_resourceRequest.setHTTPHeaderField("Cache-Control", "max-age=0"); if (!lastModified.isEmpty()) m_resourceRequest.setHTTPHeaderField("If-Modified-Since", lastModified); if (!eTag.isEmpty()) m_resourceRequest.setHTTPHeaderField("If-None-Match", eTag); } } if (type() == CachedResource::LinkPrefetch || type() == CachedResource::LinkSubresource) m_resourceRequest.setHTTPHeaderField("Purpose", "prefetch"); m_resourceRequest.setPriority(loadPriority()); // FIXME: It's unfortunate that the cache layer and below get to know anything about fragment identifiers. // We should look into removing the expectation of that knowledge from the platform network stacks. ResourceRequest request(m_resourceRequest); if (!m_fragmentIdentifierForRequest.isNull()) { KURL url = request.url(); url.setFragmentIdentifier(m_fragmentIdentifierForRequest); request.setURL(url); m_fragmentIdentifierForRequest = String(); } m_loader = ResourceLoader::create(cachedResourceLoader->frame(), this, request, options); if (!m_loader) { failBeforeStarting(); return; } m_status = Pending; }
PassOwnPtr<CachedResourceRequest> CachedResourceRequest::load(CachedResourceLoader* cachedResourceLoader, CachedResource* resource, bool incremental, SecurityCheckPolicy securityCheck, const ResourceLoaderOptions& options) { OwnPtr<CachedResourceRequest> request = adoptPtr(new CachedResourceRequest(cachedResourceLoader, resource, incremental)); ResourceRequest resourceRequest = resource->resourceRequest(); #if PLATFORM(CHROMIUM) resourceRequest.setTargetType(cachedResourceTypeToTargetType(resource->type())); #endif if (!resource->accept().isEmpty()) resourceRequest.setHTTPAccept(resource->accept()); if (resource->isCacheValidator()) { CachedResource* resourceToRevalidate = resource->resourceToRevalidate(); ASSERT(resourceToRevalidate->canUseCacheValidator()); ASSERT(resourceToRevalidate->isLoaded()); const String& lastModified = resourceToRevalidate->response().httpHeaderField("Last-Modified"); const String& eTag = resourceToRevalidate->response().httpHeaderField("ETag"); if (!lastModified.isEmpty() || !eTag.isEmpty()) { ASSERT(cachedResourceLoader->cachePolicy() != CachePolicyReload); if (cachedResourceLoader->cachePolicy() == CachePolicyRevalidate) resourceRequest.setHTTPHeaderField("Cache-Control", "max-age=0"); if (!lastModified.isEmpty()) resourceRequest.setHTTPHeaderField("If-Modified-Since", lastModified); if (!eTag.isEmpty()) resourceRequest.setHTTPHeaderField("If-None-Match", eTag); } } #if ENABLE(LINK_PREFETCH) if (resource->type() == CachedResource::LinkPrefetch || resource->type() == CachedResource::LinkPrerender || resource->type() == CachedResource::LinkSubresource) resourceRequest.setHTTPHeaderField("Purpose", "prefetch"); #endif ResourceLoadPriority priority = resource->loadPriority(); resourceRequest.setPriority(priority); RefPtr<SubresourceLoader> loader = resourceLoadScheduler()->scheduleSubresourceLoad(cachedResourceLoader->document()->frame(), request.get(), resourceRequest, priority, securityCheck, options); if (!loader || loader->reachedTerminalState()) { // FIXME: What if resources in other frames were waiting for this revalidation? LOG(ResourceLoading, "Cannot start loading '%s'", resource->url().string().latin1().data()); if (resource->resourceToRevalidate()) memoryCache()->revalidationFailed(resource); resource->error(CachedResource::LoadError); //+EAWebKitChange //10/19/2012 return PassOwnPtr<CachedResourceRequest>(std::nullptr_t()) ; //-EAWebKitChange } request->m_loader = loader; return request.release(); }
void CachedResource::load(CachedResourceLoader* cachedResourceLoader, const ResourceLoaderOptions& options) { if (!cachedResourceLoader->frame()) { failBeforeStarting(); return; } FrameLoader& frameLoader = cachedResourceLoader->frame()->loader(); if (options.securityCheck() == DoSecurityCheck && (frameLoader.state() == FrameStateProvisional || !frameLoader.activeDocumentLoader() || frameLoader.activeDocumentLoader()->isStopping())) { failBeforeStarting(); return; } m_options = options; m_loading = true; #if USE(QUICK_LOOK) if (!m_resourceRequest.isNull() && m_resourceRequest.url().protocolIs(QLPreviewProtocol())) { // When QuickLook is invoked to convert a document, it returns a unique URL in the // NSURLReponse for the main document. To make safeQLURLForDocumentURLAndResourceURL() // work, we need to use the QL URL not the original URL. const URL& documentURL = cachedResourceLoader->frame() ? cachedResourceLoader->frame()->loader().documentLoader()->response().url() : cachedResourceLoader->document()->url(); m_resourceRequest.setURL(safeQLURLForDocumentURLAndResourceURL(documentURL, url())); } #endif if (!accept().isEmpty()) m_resourceRequest.setHTTPAccept(accept()); if (isCacheValidator()) { CachedResource* resourceToRevalidate = m_resourceToRevalidate; ASSERT(resourceToRevalidate->canUseCacheValidator()); ASSERT(resourceToRevalidate->isLoaded()); const String& lastModified = resourceToRevalidate->response().httpHeaderField(HTTPHeaderName::LastModified); const String& eTag = resourceToRevalidate->response().httpHeaderField(HTTPHeaderName::ETag); if (!lastModified.isEmpty() || !eTag.isEmpty()) { ASSERT(cachedResourceLoader->cachePolicy(type()) != CachePolicyReload); if (cachedResourceLoader->cachePolicy(type()) == CachePolicyRevalidate) m_resourceRequest.setHTTPHeaderField(HTTPHeaderName::CacheControl, "max-age=0"); if (!lastModified.isEmpty()) m_resourceRequest.setHTTPHeaderField(HTTPHeaderName::IfModifiedSince, lastModified); if (!eTag.isEmpty()) m_resourceRequest.setHTTPHeaderField(HTTPHeaderName::IfNoneMatch, eTag); } } #if ENABLE(LINK_PREFETCH) if (type() == CachedResource::LinkPrefetch || type() == CachedResource::LinkSubresource) m_resourceRequest.setHTTPHeaderField(HTTPHeaderName::Purpose, "prefetch"); #endif m_resourceRequest.setPriority(loadPriority()); if (type() != MainResource) addAdditionalRequestHeaders(cachedResourceLoader); // FIXME: It's unfortunate that the cache layer and below get to know anything about fragment identifiers. // We should look into removing the expectation of that knowledge from the platform network stacks. ResourceRequest request(m_resourceRequest); if (!m_fragmentIdentifierForRequest.isNull()) { URL url = request.url(); url.setFragmentIdentifier(m_fragmentIdentifierForRequest); request.setURL(url); m_fragmentIdentifierForRequest = String(); } m_loader = platformStrategies()->loaderStrategy()->resourceLoadScheduler()->scheduleSubresourceLoad(cachedResourceLoader->frame(), this, request, request.priority(), options); if (!m_loader) { failBeforeStarting(); return; } m_status = Pending; }
void Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& serveLowerPriority) { while (!requestsPending.isEmpty()) { Request* request = requestsPending.first(); DocLoader* docLoader = request->docLoader(); bool resourceIsCacheValidator = request->cachedResource()->isCacheValidator(); // If the document is fully parsed and there are no pending stylesheets there won't be any more // resources that we would want to push to the front of the queue. Just hand off the remaining resources // to the networking layer. bool parsedAndStylesheetsKnown = !docLoader->doc()->parsing() && docLoader->doc()->haveStylesheetsLoaded(); if (!parsedAndStylesheetsKnown && !resourceIsCacheValidator && m_requestsLoading.size() >= m_maxRequestsInFlight) { serveLowerPriority = false; return; } requestsPending.removeFirst(); ResourceRequest resourceRequest(request->cachedResource()->url()); if (!request->cachedResource()->accept().isEmpty()) resourceRequest.setHTTPAccept(request->cachedResource()->accept()); KURL referrer = docLoader->doc()->url(); if ((referrer.protocolIs("http") || referrer.protocolIs("https")) && referrer.path().isEmpty()) referrer.setPath("/"); resourceRequest.setHTTPReferrer(referrer.string()); FrameLoader::addHTTPOriginIfNeeded(resourceRequest, docLoader->doc()->securityOrigin()->toString()); if (resourceIsCacheValidator) { CachedResource* resourceToRevalidate = request->cachedResource()->resourceToRevalidate(); ASSERT(resourceToRevalidate->canUseCacheValidator()); ASSERT(resourceToRevalidate->isLoaded()); const String& lastModified = resourceToRevalidate->response().httpHeaderField("Last-Modified"); const String& eTag = resourceToRevalidate->response().httpHeaderField("ETag"); if (!lastModified.isEmpty() || !eTag.isEmpty()) { ASSERT(docLoader->cachePolicy() != CachePolicyReload); if (docLoader->cachePolicy() == CachePolicyRevalidate) resourceRequest.setHTTPHeaderField("Cache-Control", "max-age=0"); if (!lastModified.isEmpty()) resourceRequest.setHTTPHeaderField("If-Modified-Since", lastModified); if (!eTag.isEmpty()) resourceRequest.setHTTPHeaderField("If-None-Match", eTag); } } RefPtr<SubresourceLoader> loader = SubresourceLoader::create(docLoader->doc()->frame(), this, resourceRequest, request->shouldSkipCanLoadCheck(), request->sendResourceLoadCallbacks()); if (loader) { m_requestsLoading.add(loader.release(), request); request->cachedResource()->setRequestedFromNetworkingLayer(); #if REQUEST_DEBUG printf("HOST %s COUNT %d LOADING %s\n", resourceRequest.url().host().latin1().data(), m_requestsLoading.size(), request->cachedResource()->url().latin1().data()); #endif } else { docLoader->decrementRequestCount(); docLoader->setLoadInProgress(true); request->cachedResource()->error(); docLoader->setLoadInProgress(false); delete request; } } }
void CachedResource::load(CachedResourceLoader* cachedResourceLoader, const ResourceLoaderOptions& options) { if (!cachedResourceLoader->frame()) { failBeforeStarting(); return; } FrameLoader* frameLoader = cachedResourceLoader->frame()->loader(); if (options.securityCheck == DoSecurityCheck && (frameLoader->state() == FrameStateProvisional || !frameLoader->activeDocumentLoader() || frameLoader->activeDocumentLoader()->isStopping())) { failBeforeStarting(); return; } m_options = options; m_loading = true; #if PLATFORM(CHROMIUM) || PLATFORM(BLACKBERRY) if (m_resourceRequest.targetType() == ResourceRequest::TargetIsUnspecified) m_resourceRequest.setTargetType(cachedResourceTypeToTargetType(type())); #endif if (!accept().isEmpty()) m_resourceRequest.setHTTPAccept(accept()); if (isCacheValidator()) { CachedResource* resourceToRevalidate = m_resourceToRevalidate; ASSERT(resourceToRevalidate->canUseCacheValidator()); ASSERT(resourceToRevalidate->isLoaded()); const String& lastModified = resourceToRevalidate->response().httpHeaderField("Last-Modified"); const String& eTag = resourceToRevalidate->response().httpHeaderField("ETag"); if (!lastModified.isEmpty() || !eTag.isEmpty()) { ASSERT(cachedResourceLoader->cachePolicy() != CachePolicyReload); if (cachedResourceLoader->cachePolicy() == CachePolicyRevalidate) m_resourceRequest.setHTTPHeaderField("Cache-Control", "max-age=0"); if (!lastModified.isEmpty()) m_resourceRequest.setHTTPHeaderField("If-Modified-Since", lastModified); if (!eTag.isEmpty()) m_resourceRequest.setHTTPHeaderField("If-None-Match", eTag); } } #if ENABLE(LINK_PREFETCH) if (type() == CachedResource::LinkPrefetch || type() == CachedResource::LinkSubresource) m_resourceRequest.setHTTPHeaderField("Purpose", "prefetch"); #endif m_resourceRequest.setPriority(loadPriority()); if (type() != MainResource) addAdditionalRequestHeaders(cachedResourceLoader); // FIXME: It's unfortunate that the cache layer and below get to know anything about fragment identifiers. // We should look into removing the expectation of that knowledge from the platform network stacks. ResourceRequest request(m_resourceRequest); if (!m_fragmentIdentifierForRequest.isNull()) { KURL url = request.url(); url.setFragmentIdentifier(m_fragmentIdentifierForRequest); request.setURL(url); m_fragmentIdentifierForRequest = String(); } #if USE(PLATFORM_STRATEGIES) m_loader = platformStrategies()->loaderStrategy()->resourceLoadScheduler()->scheduleSubresourceLoad(cachedResourceLoader->frame(), this, request, request.priority(), options); #else m_loader = resourceLoadScheduler()->scheduleSubresourceLoad(cachedResourceLoader->frame(), this, request, request.priority(), options); #endif if (!m_loader) { failBeforeStarting(); return; } m_status = Pending; }
void CachedResource::load(CachedResourceLoader& cachedResourceLoader) { if (!cachedResourceLoader.frame()) { RELEASE_LOG_IF_ALLOWED("load: No associated frame"); failBeforeStarting(); return; } Frame& frame = *cachedResourceLoader.frame(); // Prevent new loads if we are in the PageCache or being added to the PageCache. // We query the top document because new frames may be created in pagehide event handlers // and their pageCacheState will not reflect the fact that they are about to enter page // cache. if (auto* topDocument = frame.mainFrame().document()) { if (topDocument->pageCacheState() != Document::NotInPageCache) { RELEASE_LOG_IF_ALLOWED("load: Already in page cache or being added to it (frame = %p)", &frame); failBeforeStarting(); return; } } FrameLoader& frameLoader = frame.loader(); if (m_options.securityCheck == DoSecurityCheck && (frameLoader.state() == FrameStateProvisional || !frameLoader.activeDocumentLoader() || frameLoader.activeDocumentLoader()->isStopping())) { if (frameLoader.state() == FrameStateProvisional) RELEASE_LOG_IF_ALLOWED("load: Failed security check -- state is provisional (frame = %p)", &frame); else if (!frameLoader.activeDocumentLoader()) RELEASE_LOG_IF_ALLOWED("load: Failed security check -- not active document (frame = %p)", &frame); else if (frameLoader.activeDocumentLoader()->isStopping()) RELEASE_LOG_IF_ALLOWED("load: Failed security check -- active loader is stopping (frame = %p)", &frame); failBeforeStarting(); return; } m_loading = true; #if USE(QUICK_LOOK) if (!m_resourceRequest.isNull() && m_resourceRequest.url().protocolIs(QLPreviewProtocol())) { // When QuickLook is invoked to convert a document, it returns a unique URL in the // NSURLReponse for the main document. To make safeQLURLForDocumentURLAndResourceURL() // work, we need to use the QL URL not the original URL. const URL& documentURL = frameLoader.documentLoader()->response().url(); m_resourceRequest.setURL(safeQLURLForDocumentURLAndResourceURL(documentURL, url())); } #endif if (isCacheValidator()) { CachedResource* resourceToRevalidate = m_resourceToRevalidate; ASSERT(resourceToRevalidate->canUseCacheValidator()); ASSERT(resourceToRevalidate->isLoaded()); const String& lastModified = resourceToRevalidate->response().httpHeaderField(HTTPHeaderName::LastModified); const String& eTag = resourceToRevalidate->response().httpHeaderField(HTTPHeaderName::ETag); if (!lastModified.isEmpty() || !eTag.isEmpty()) { ASSERT(cachedResourceLoader.cachePolicy(type()) != CachePolicyReload); if (cachedResourceLoader.cachePolicy(type()) == CachePolicyRevalidate) m_resourceRequest.setHTTPHeaderField(HTTPHeaderName::CacheControl, "max-age=0"); if (!lastModified.isEmpty()) m_resourceRequest.setHTTPHeaderField(HTTPHeaderName::IfModifiedSince, lastModified); if (!eTag.isEmpty()) m_resourceRequest.setHTTPHeaderField(HTTPHeaderName::IfNoneMatch, eTag); } } #if ENABLE(LINK_PREFETCH) if (type() == CachedResource::LinkPrefetch || type() == CachedResource::LinkSubresource) m_resourceRequest.setHTTPHeaderField(HTTPHeaderName::Purpose, "prefetch"); #endif m_resourceRequest.setPriority(loadPriority()); // Navigation algorithm is setting up the request before sending it to CachedResourceLoader?CachedResource. // So no need for extra fields for MainResource. if (type() != CachedResource::MainResource) frameLoader.addExtraFieldsToSubresourceRequest(m_resourceRequest); // FIXME: It's unfortunate that the cache layer and below get to know anything about fragment identifiers. // We should look into removing the expectation of that knowledge from the platform network stacks. ResourceRequest request(m_resourceRequest); if (!m_fragmentIdentifierForRequest.isNull()) { URL url = request.url(); url.setFragmentIdentifier(m_fragmentIdentifierForRequest); request.setURL(url); m_fragmentIdentifierForRequest = String(); } m_loader = platformStrategies()->loaderStrategy()->loadResource(frame, *this, request, m_options); if (!m_loader) { RELEASE_LOG_IF_ALLOWED("load: Unable to create SubresourceLoader (frame = %p)", &frame); failBeforeStarting(); return; } m_status = Pending; }