void Loader::didFail(SubresourceLoader* loader, bool cancelled) { RequestMap::iterator i = m_requestsLoading.find(loader); if (i == m_requestsLoading.end()) return; Request* req = i->second; m_requestsLoading.remove(i); DocLoader* docLoader = req->docLoader(); if (!req->isMultipart()) docLoader->decrementRequestCount(); CachedResource* object = req->cachedResource(); if (!cancelled) { docLoader->setLoadInProgress(true); object->error(); } docLoader->setLoadInProgress(false); cache()->remove(object); delete req; servePendingRequests(); }
void Loader::Host::didFail(SubresourceLoader* loader, bool cancelled) { loader->clearClient(); RequestMap::iterator i = m_requestsLoading.find(loader); if (i == m_requestsLoading.end()) return; Request* request = i->second; m_requestsLoading.remove(i); DocLoader* docLoader = request->docLoader(); if (!request->isMultipart()) docLoader->decrementRequestCount(); CachedResource* resource = request->cachedResource(); if (!cancelled) { docLoader->setLoadInProgress(true); resource->error(); } docLoader->setLoadInProgress(false); if (cancelled || !resource->isPreloaded()) cache()->remove(resource); delete request; servePendingRequests(); }
void Loader::Host::didFinishLoading(SubresourceLoader* loader) { RequestMap::iterator i = m_requestsLoading.find(loader); if (i == m_requestsLoading.end()) return; Request* request = i->second; m_requestsLoading.remove(i); DocLoader* docLoader = request->docLoader(); if (!request->isMultipart()) docLoader->decrementRequestCount(); CachedResource* resource = request->cachedResource(); // If we got a 4xx response, we're pretending to have received a network // error, so we can't send the successful data() and finish() callbacks. if (!resource->errorOccurred()) { docLoader->setLoadInProgress(true); resource->data(loader->resourceData(), true); resource->finish(); } delete request; docLoader->setLoadInProgress(false); #if REQUEST_DEBUG KURL u(resource->url()); printf("HOST %s COUNT %d RECEIVED %s\n", u.host().latin1().data(), m_requestsLoading.size(), resource->url().latin1().data()); #endif servePendingRequests(); }
void Loader::Host::servePendingRequests(RequestQueue& requestsPending) { while (m_requestsLoading.size() < m_maxRequestsInFlight && !requestsPending.isEmpty()) { Request* request = requestsPending.first(); requestsPending.removeFirst(); DocLoader* docLoader = request->docLoader(); 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()); 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 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 Loader::Host::didFinishLoading(SubresourceLoader* loader) { RefPtr<Host> myProtector(this); RequestMap::iterator i = m_requestsLoading.find(loader); if (i == m_requestsLoading.end()) return; Request* request = i->second; m_requestsLoading.remove(i); DocLoader* docLoader = request->docLoader(); // Prevent the document from being destroyed before we are done with // the docLoader that it will delete when the document gets deleted. RefPtr<Document> protector(docLoader->doc()); if (!request->isMultipart()) docLoader->decrementRequestCount(); CachedResource* resource = request->cachedResource(); ASSERT(!resource->resourceToRevalidate()); // If we got a 4xx response, we're pretending to have received a network // error, so we can't send the successful data() and finish() callbacks. if (!resource->errorOccurred()) { docLoader->setLoadInProgress(true); resource->data(loader->resourceData(), true); resource->finish(); } delete request; docLoader->setLoadInProgress(false); docLoader->checkForPendingPreloads(); #if REQUEST_DEBUG KURL u(ParsedURLString, resource->url()); printf("HOST %s COUNT %d RECEIVED %s\n", u.host().latin1().data(), m_requestsLoading.size(), resource->url().latin1().data()); #endif servePendingRequests(); }
void Loader::Host::didFail(SubresourceLoader* loader, bool cancelled) { RefPtr<Host> myProtector(this); loader->clearClient(); RequestMap::iterator i = m_requestsLoading.find(loader); if (i == m_requestsLoading.end()) return; Request* request = i->second; m_requestsLoading.remove(i); DocLoader* docLoader = request->docLoader(); // Prevent the document from being destroyed before we are done with // the docLoader that it will delete when the document gets deleted. RefPtr<Document> protector(docLoader->doc()); if (!request->isMultipart()) docLoader->decrementRequestCount(); CachedResource* resource = request->cachedResource(); if (resource->resourceToRevalidate()) cache()->revalidationFailed(resource); if (!cancelled) { docLoader->setLoadInProgress(true); resource->error(); } docLoader->setLoadInProgress(false); if (cancelled || !resource->isPreloaded()) cache()->remove(resource); delete request; docLoader->checkForPendingPreloads(); servePendingRequests(); }
void Loader::didFinishLoading(SubresourceLoader* loader) { RequestMap::iterator i = m_requestsLoading.find(loader); if (i == m_requestsLoading.end()) return; Request* req = i->second; m_requestsLoading.remove(i); DocLoader* docLoader = req->docLoader(); if (!req->isMultipart()) docLoader->decrementRequestCount(); CachedResource* object = req->cachedResource(); docLoader->setLoadInProgress(true); object->data(loader->resourceData(), true); docLoader->setLoadInProgress(false); object->finish(); delete req; servePendingRequests(); }
void Loader::servePendingRequests() { while (!m_requestsPending.isEmpty()) { // get the first pending request Request* req = m_requestsPending.take(0); DocLoader* dl = req->docLoader(); dl->decrementRequestCount(); ResourceRequest request(req->cachedResource()->url()); if (!req->cachedResource()->accept().isEmpty()) request.setHTTPAccept(req->cachedResource()->accept()); KURL r = dl->doc()->URL(); if (r.protocol().startsWith("http") && r.path().isEmpty()) r.setPath("/"); request.setHTTPReferrer(r.url()); DeprecatedString domain = r.host(); if (dl->doc()->isHTMLDocument()) domain = static_cast<HTMLDocument*>(dl->doc())->domain().deprecatedString(); RefPtr<SubresourceLoader> loader = SubresourceLoader::create(dl->doc()->frame(), this, request, req->shouldSkipCanLoadCheck(), req->sendResourceLoadCallbacks()); if (loader) { m_requestsLoading.add(loader.release(), req); dl->incrementRequestCount(); break; } dl->setLoadInProgress(true); req->cachedResource()->error(); dl->setLoadInProgress(false); delete req; } }
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; } } }