String JSDOMWindowBase::crossDomainAccessErrorMessage(const JSGlobalObject* other) const { KURL originURL = asJSDOMWindow(other)->impl()->url(); KURL targetURL = impl()->frame()->document()->url(); if (originURL.isNull() || targetURL.isNull()) return String(); // FIXME: this error message should contain more specifics of why the same origin check has failed. return String::format("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains, protocols and ports must match.\n", targetURL.string().utf8().data(), originURL.string().utf8().data()); }
void JSDOMWindow::setLocation(ExecState* exec, JSValue value) { Frame* lexicalFrame = toLexicalFrame(exec); if (!lexicalFrame) return; #if ENABLE(DASHBOARD_SUPPORT) // To avoid breaking old widgets, make "var location =" in a top-level frame create // a property named "location" instead of performing a navigation (<rdar://problem/5688039>). if (Settings* settings = lexicalFrame->settings()) { if (settings->usesDashboardBackwardCompatibilityMode() && !lexicalFrame->tree()->parent()) { if (allowsAccessFrom(exec)) putDirect(Identifier(exec, "location"), value); return; } } #endif Frame* frame = impl()->frame(); ASSERT(frame); KURL url = completeURL(exec, ustringToString(value.toString(exec))); if (url.isNull()) return; if (!shouldAllowNavigation(exec, frame)) return; if (!protocolIsJavaScript(url) || allowsAccessFrom(exec)) { // We want a new history item if this JS was called via a user gesture frame->redirectScheduler()->scheduleLocationChange(url, lexicalFrame->loader()->outgoingReferrer(), !lexicalFrame->script()->anyPageIsProcessingUserGesture(), false, processingUserGesture()); } }
void StyleRuleImport::setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CSSStyleSheetResource* cachedStyleSheet) { if (m_styleSheet) m_styleSheet->clearOwnerRule(); CSSParserContext context = m_parentStyleSheet ? m_parentStyleSheet->parserContext() : strictCSSParserContext(); context.setCharset(charset); Document* document = m_parentStyleSheet ? m_parentStyleSheet->singleOwnerDocument() : 0; if (!baseURL.isNull()) { context.setBaseURL(baseURL); if (document) context.setReferrer(Referrer(baseURL.strippedForUseAsReferrer(), document->referrerPolicy())); } m_styleSheet = StyleSheetContents::create(this, href, context); m_styleSheet->parseAuthorStyleSheet(cachedStyleSheet, document ? document->securityOrigin() : 0); m_loading = false; if (m_parentStyleSheet) { m_parentStyleSheet->notifyLoadedSheet(cachedStyleSheet); m_parentStyleSheet->checkLoaded(); } }
void SubresourceLoader::willSendRequest(ResourceRequest& newRequest, const ResourceResponse& redirectResponse) { // Store the previous URL because the call to ResourceLoader::willSendRequest will modify it. KURL previousURL = request().url(); RefPtr<SubresourceLoader> protect(this); ASSERT(!newRequest.isNull()); if (!previousURL.isNull() && previousURL != newRequest.url()) { if (!m_documentLoader->cachedResourceLoader()->canRequest(m_resource->type(), newRequest.url())) { cancel(); return; } if (m_resource->type() == CachedResource::ImageResource && m_documentLoader->cachedResourceLoader()->shouldDeferImageLoad(newRequest.url())) { cancel(); return; } m_resource->willSendRequest(newRequest, redirectResponse); } if (newRequest.isNull() || reachedTerminalState()) return; ResourceLoader::willSendRequest(newRequest, redirectResponse); if (newRequest.isNull()) cancel(); }
BString::BString(const KURL& url) { if (url.isNull()) m_bstr = 0; else m_bstr = SysAllocStringLen(url.string().characters(), url.string().length()); }
CSSParserContext::CSSParserContext(const Document& document, UseCounter* useCounter, const KURL& baseURL, const String& charset, SelectorProfile profile) : m_baseURL(baseURL.isNull() ? document.baseURL() : baseURL), m_charset(charset), m_mode(document.inQuirksMode() ? HTMLQuirksMode : HTMLStandardMode), m_profile(profile), m_referrer(m_baseURL.strippedForUseAsReferrer(), document.getReferrerPolicy()), m_isHTMLDocument(document.isHTMLDocument()), m_useLegacyBackgroundSizeShorthandBehavior( document.settings() ? document.settings()->useLegacyBackgroundSizeShorthandBehavior() : false), m_shouldCheckContentSecurityPolicy(DoNotCheckContentSecurityPolicy), m_useCounter(useCounter) { if (ContentSecurityPolicy::shouldBypassMainWorld(&document)) m_shouldCheckContentSecurityPolicy = DoNotCheckContentSecurityPolicy; else m_shouldCheckContentSecurityPolicy = CheckContentSecurityPolicy; if (HTMLImportsController* importsController = document.importsController()) m_matchMode = importsController->master()->inQuirksMode() ? HTMLQuirksMode : HTMLStandardMode; else m_matchMode = m_mode; }
void DocLoader::printAccessDeniedMessage(const KURL& url) const { if (url.isNull()) return; if (!frame()) return; Settings* settings = frame()->settings(); if (!settings || settings->privateBrowsingEnabled()) return; String message = m_doc->url().isNull() ? String::format("Unsafe attempt to load URL %s.", url.string().utf8().data()) : String::format("Unsafe attempt to load URL %s from frame with URL %s. " "Domains, protocols and ports must match.\n", url.string().utf8().data(), m_doc->url().string().utf8().data()); // FIXME: provide a real line number and source URL. #if ENABLE(INSPECTOR) frame()->domWindow()->console()->addMessage(OtherMessageSource, LogMessageType, ErrorMessageLevel, message, 1, String()); #endif }
void StyleRuleImport::setCSSStyleSheet(const String& url, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet*) { ASSERT(m_loadContext); ASSERT(!m_styleSheet); ASSERT(m_cachedSheet); OwnPtr<LoadContext> loadContext = m_loadContext.release(); CSSParserContext parserContext = loadContext->parentParserContext; if (!baseURL.isNull()) parserContext.baseURL = baseURL; parserContext.charset = charset; #if ENABLE(PARSED_STYLE_SHEET_CACHING) m_styleSheet = m_cachedSheet->restoreParsedStyleSheet(parserContext); #endif if (!m_styleSheet) { m_styleSheet = StyleSheetContents::create(url, parserContext); m_styleSheet->parseAuthorStyleSheet(m_cachedSheet.get(), loadContext->rootStyleSheet.get()); } loadContext->rootStyleSheet->contents()->checkLoadCompleted(); #if ENABLE(PARSED_STYLE_SHEET_CACHING) if (m_styleSheet->isCacheable()) m_cachedSheet->saveParsedStyleSheet(m_styleSheet); #endif }
void SubresourceLoader::willSendRequest(ResourceRequest& newRequest, const ResourceResponse& redirectResponse) { // Store the previous URL because the call to ResourceLoader::willSendRequest will modify it. KURL previousURL = request().url(); ResourceLoader::willSendRequest(newRequest, redirectResponse); if (!previousURL.isNull() && !newRequest.isNull() && previousURL != newRequest.url() && m_client) m_client->willSendRequest(this, newRequest, redirectResponse); }
PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(const String& markupString, Frame* frame, Vector<Node*>& nodes) { ASSERT(frame); const ResourceResponse& response = frame->loader()->documentLoader()->response(); KURL responseURL = response.url(); // it's possible to have a response without a URL here // <rdar://problem/5454935> if (responseURL.isNull()) responseURL = KURL(""); PassRefPtr<ArchiveResource> mainResource = ArchiveResource::create(utf8Buffer(markupString), responseURL, response.mimeType(), "UTF-8", frame->tree()->name()); Vector<PassRefPtr<LegacyWebArchive> > subframeArchives; Vector<PassRefPtr<ArchiveResource> > subresources; HashSet<String> uniqueSubresources; Vector<Node*>::iterator it = nodes.begin(); Vector<Node*>::iterator end = nodes.end(); for (; it != end; ++it) { Frame* childFrame; if (((*it)->hasTagName(HTMLNames::frameTag) || (*it)->hasTagName(HTMLNames::iframeTag) || (*it)->hasTagName(HTMLNames::objectTag)) && (childFrame = static_cast<HTMLFrameOwnerElement*>(*it)->contentFrame())) { RefPtr<LegacyWebArchive> subframeArchive; if (Document* document = childFrame->document()) subframeArchive = LegacyWebArchive::create(document); else subframeArchive = create(childFrame); if (subframeArchive) subframeArchives.append(subframeArchive); else LOG_ERROR("Unabled to archive subframe %s", childFrame->tree()->name().string().utf8().data()); } else { Vector<KURL> subresourceURLs; (*it)->getSubresourceURLs(subresourceURLs); DocumentLoader* documentLoader = frame->loader()->documentLoader(); for (unsigned i = 0; i < subresourceURLs.size(); ++i) { if (uniqueSubresources.contains(subresourceURLs[i].string())) continue; uniqueSubresources.add(subresourceURLs[i].string()); RefPtr<ArchiveResource> resource = documentLoader->subresource(subresourceURLs[i]); if (resource) subresources.append(resource.release()); else // FIXME: should do something better than spew to console here LOG_ERROR("Failed to archive subresource for %s", subresourceURLs[i].string().utf8().data()); } } } return create(mainResource, subresources, subframeArchives); }
bool ImageLoader::shouldLoadImmediately(const KURL& url) const { // We force any image loads which might require alt content through the asynchronous path so that we can add the shadow DOM // for the alt-text content when style recalc is over and DOM mutation is allowed again. if (!url.isNull()) { Resource* resource = memoryCache()->resourceForURL(url, m_element->document().fetcher()->getCacheIdentifier()); if (resource && !resource->errorOccurred()) return true; } return (m_loadingImageDocument || isHTMLObjectElement(m_element) || isHTMLEmbedElement(m_element) || url.protocolIsData()); }
void NotificationResourcesLoader::loadImage( ExecutionContext* executionContext, NotificationImageLoader::Type type, const KURL& url, std::unique_ptr<NotificationImageLoader::ImageCallback> imageCallback) { if (url.isNull() || url.isEmpty() || !url.isValid()) { didFinishRequest(); return; } NotificationImageLoader* imageLoader = new NotificationImageLoader(type); m_imageLoaders.append(imageLoader); imageLoader->start(executionContext, url, std::move(imageCallback)); }
void SubresourceLoader::willSendRequest(ResourceRequest& newRequest, const ResourceResponse& redirectResponse) { // Store the previous URL because the call to ResourceLoader::willSendRequest will modify it. KURL previousURL = request().url(); ResourceLoader::willSendRequest(newRequest, redirectResponse); if (!previousURL.isNull() && !newRequest.isNull() && previousURL != newRequest.url()) { if (!m_document->cachedResourceLoader()->canRequest(m_resource->type(), newRequest.url())) { cancel(); return; } m_resource->willSendRequest(newRequest, redirectResponse); } }
void JSLocation::setHref(ExecState* exec, JSValue value) { Frame* frame = impl()->frame(); ASSERT(frame); KURL url = completeURL(exec, value.toString(exec)); if (url.isNull()) return; if (!shouldAllowNavigation(exec, frame)) return; navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); }
void FrameFetchContext::printAccessDeniedMessage(const KURL& url) const { if (url.isNull()) return; String message; if (!m_document || m_document->url().isNull()) message = "Unsafe attempt to load URL " + url.elidedString() + '.'; else if (url.isLocalFile() || m_document->url().isLocalFile()) message = "Unsafe attempt to load URL " + url.elidedString() + " from frame with URL " + m_document->url().elidedString() + ". 'file:' URLs are treated as unique security origins.\n"; else message = "Unsafe attempt to load URL " + url.elidedString() + " from frame with URL " + m_document->url().elidedString() + ". Domains, protocols and ports must match.\n"; frame()->document()->addConsoleMessage(ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, message)); }
void V8DOMWindowShell::setLocation(DOMWindow* window, const String& relativeURL) { Frame* frame = window->frame(); if (!frame) return; KURL url = completeURL(relativeURL); if (url.isNull()) return; if (!shouldAllowNavigation(frame)) return; navigateIfAllowed(frame, url, false, false); }
void ResourceFetcher::printAccessDeniedMessage(const KURL& url) const { if (url.isNull()) return; if (!frame()) return; String message; if (!m_document || m_document->url().isNull()) message = "Unsafe attempt to load URL " + url.elidedString() + '.'; else message = "Unsafe attempt to load URL " + url.elidedString() + " from frame with URL " + m_document->url().elidedString() + ". Domains, protocols and ports must match.\n"; frame()->document()->addConsoleMessage(ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, message)); }
JSValue JSLocation::replace(ExecState* exec, const ArgList& args) { Frame* frame = impl()->frame(); if (!frame) return jsUndefined(); KURL url = completeURL(exec, args.at(0).toString(exec)); if (url.isNull()) return jsUndefined(); if (!shouldAllowNavigation(exec, frame)) return jsUndefined(); navigateIfAllowed(exec, frame, url, true, true); return jsUndefined(); }
JSValue JSLocation::assign(ExecState* exec, const ArgList& args) { Frame* frame = impl()->frame(); if (!frame) return jsUndefined(); KURL url = completeURL(exec, args.at(0).toString(exec)); if (url.isNull()) return jsUndefined(); if (!shouldAllowNavigation(exec, frame)) return jsUndefined(); // We want a new history item if this JS was called via a user gesture navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); return jsUndefined(); }
void StyleRuleImport::setCSSStyleSheet(const String& url, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet*) { ASSERT(m_loadContext); ASSERT(!m_styleSheet); ASSERT(m_cachedSheet); OwnPtr<LoadContext> loadContext = m_loadContext.release(); CSSParserContext parserContext = loadContext->parentParserContext; if (!baseURL.isNull()) parserContext.baseURL = baseURL; parserContext.charset = charset; m_styleSheet = StyleSheetContents::create(url, parserContext); m_styleSheet->parseAuthorStyleSheet(m_cachedSheet.get(), loadContext->rootStyleSheet.get()); loadContext->rootStyleSheet->contents()->checkLoadCompleted(); }
void CachedResourceLoader::printAccessDeniedMessage(const KURL& url) const { if (url.isNull()) return; if (!frame()) return; Settings* settings = frame()->settings(); if (!settings || settings->privateBrowsingEnabled()) return; String message = m_document->url().isNull() ? makeString("Unsafe attempt to load URL ", url.string(), '.') : makeString("Unsafe attempt to load URL ", url.string(), " from frame with URL ", m_document->url().string(), ". Domains, protocols and ports must match.\n"); // FIXME: provide a real line number and source URL. frame()->domWindow()->console()->addMessage(OtherMessageSource, LogMessageType, ErrorMessageLevel, message, 1, String()); }
void V8Location::hrefAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) { INC_STATS("DOM.Location.href._set"); v8::Handle<v8::Object> holder = info.Holder(); Location* imp = V8Location::toNative(holder); Frame* frame = imp->frame(); if (!frame) return; KURL url = completeURL(toWebCoreString(value)); if (url.isNull()) return; if (!shouldAllowNavigation(frame)) return; navigateIfAllowed(frame, url, false, false); }
v8::Handle<v8::Value> V8Location::assignCallback(const v8::Arguments& args) { INC_STATS("DOM.Location.assign"); v8::Handle<v8::Object> holder = args.Holder(); Location* imp = V8Location::toNative(holder); Frame* frame = imp->frame(); if (!frame) return v8::Undefined(); KURL url = completeURL(toWebCoreString(args[0])); if (url.isNull()) return v8::Undefined(); if (!shouldAllowNavigation(frame)) return v8::Undefined(); navigateIfAllowed(frame, url, false, false); return v8::Undefined(); }
PassRefPtr<Widget> FrameLoaderClientBlackBerry::createPlugin(const IntSize& pluginSize, HTMLPlugInElement* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeTypeIn, bool loadManually) { String mimeType(mimeTypeIn); if (mimeType.isEmpty()) { mimeType = MIMETypeRegistry::getMIMETypeForPath(url.path()); mimeType = MIMETypeRegistry::getNormalizedMIMEType(mimeType); if (mimeType != "application/x-shockwave-flash") mimeType = mimeTypeIn; } if (PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType)) return PluginView::create(m_frame, pluginSize, element, url, paramNames, paramValues, mimeType, loadManually); // If it's not the plugin type we support, try load directly from browser. if (m_frame->loader() && m_frame->loader()->subframeLoader() && !url.isNull()) m_frame->loader()->subframeLoader()->requestFrame(element, url, String()); return 0; }
static PassRefPtr<ArchiveResource> loadArchiveResource(xmlNodePtr resourceNode) { if (!xmlStrEqual(resourceNode->name, archiveResourceTag)) { LOGD("loadArchiveResource: Malformed resource."); return 0; } KURL url = loadArchiveResourceFieldURL(resourceNode, urlFieldTag); if (url.isNull()) { LOGD("loadArchiveResource: Failed to load resource."); return 0; } String mimeType = loadArchiveResourceFieldString(resourceNode, mimeFieldTag); if (mimeType.isNull()) { LOGD("loadArchiveResource: Failed to load resource."); return 0; } String textEncoding = loadArchiveResourceFieldString(resourceNode, encodingFieldTag); if (textEncoding.isNull()) { LOGD("loadArchiveResource: Failed to load resource."); return 0; } String frameName = loadArchiveResourceFieldString(resourceNode, frameFieldTag); if (frameName.isNull()) { LOGD("loadArchiveResource: Failed to load resource."); return 0; } PassRefPtr<SharedBuffer> data = loadArchiveResourceFieldBuffer(resourceNode, dataFieldTag); if (!data) { LOGD("loadArchiveResource: Failed to load resource."); return 0; } return ArchiveResource::create(data, url, mimeType, textEncoding, frameName); }
void StyleRuleImport::setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet* cachedStyleSheet) { if (m_styleSheet) m_styleSheet->clearOwnerRule(); CSSParserContext context = m_parentStyleSheet ? m_parentStyleSheet->parserContext() : CSSStrictMode; context.charset = charset; if (!baseURL.isNull()) context.baseURL = baseURL; m_styleSheet = StyleSheetContents::create(this, href, baseURL, context); Document* document = m_parentStyleSheet ? m_parentStyleSheet->singleOwnerDocument() : 0; m_styleSheet->parseAuthorStyleSheet(cachedStyleSheet, document ? document->securityOrigin() : 0); m_loading = false; if (m_parentStyleSheet) { m_parentStyleSheet->notifyLoadedSheet(cachedStyleSheet); m_parentStyleSheet->checkLoaded(); } }
void ImageLoader::updateFromElement(UpdateFromElementBehavior updateBehavior, LoadType loadType) { AtomicString imageSourceURL = m_element->imageSourceURL(); if (updateBehavior == UpdateIgnorePreviousError) clearFailedLoadURL(); if (!m_failedLoadURL.isEmpty() && imageSourceURL == m_failedLoadURL) return; // If we have a pending task, we have to clear it -- either we're // now loading immediately, or we need to reset the task's state. if (m_pendingTask) { m_pendingTask->clearLoader(); m_pendingTask.clear(); } KURL url = imageSourceToKURL(imageSourceURL); if (imageSourceURL.isNull() || url.isNull() || shouldLoadImmediately(url, loadType)) { doUpdateFromElement(updateBehavior); return; } enqueueImageLoadingMicroTask(updateBehavior); }
void ApplicationCacheGroup::selectCache(Frame* frame, const KURL& manifestURL) { ASSERT(frame && frame->page()); if (!frame->settings()->offlineWebApplicationCacheEnabled()) return; DocumentLoader* documentLoader = frame->loader()->documentLoader(); ASSERT(!documentLoader->applicationCache()); if (manifestURL.isNull()) { selectCacheWithoutManifestURL(frame); return; } ApplicationCache* mainResourceCache = documentLoader->mainResourceApplicationCache(); if (mainResourceCache) { if (manifestURL == mainResourceCache->group()->m_manifestURL) { mainResourceCache->group()->associateDocumentLoaderWithCache(documentLoader, mainResourceCache); mainResourceCache->group()->update(frame); } else { // The main resource was loaded from cache, so the cache must have an entry for it. Mark it as foreign. ApplicationCacheResource* resource = mainResourceCache->resourceForURL(documentLoader->url()); bool inStorage = resource->storageID(); resource->addType(ApplicationCacheResource::Foreign); if (inStorage) cacheStorage().storeUpdatedType(resource, mainResourceCache); // Restart the current navigation from the top of the navigation algorithm, undoing any changes that were made // as part of the initial load. // The navigation will not result in the same resource being loaded, because "foreign" entries are never picked during navigation. frame->loader()->scheduleLocationChange(documentLoader->url(), frame->loader()->referrer(), true); } return; } // The resource was loaded from the network, check if it is a HTTP/HTTPS GET. const ResourceRequest& request = frame->loader()->activeDocumentLoader()->request(); if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request)) { selectCacheWithoutManifestURL(frame); return; } // Check that the resource URL has the same scheme/host/port as the manifest URL. if (!protocolHostAndPortAreEqual(manifestURL, request.url())) { selectCacheWithoutManifestURL(frame); return; } ApplicationCacheGroup* group = cacheStorage().findOrCreateCacheGroup(manifestURL); if (ApplicationCache* cache = group->newestCache()) { ASSERT(cache->manifestResource()); group->associateDocumentLoaderWithCache(frame->loader()->documentLoader(), cache); if (!frame->loader()->documentLoader()->isLoadingMainResource()) group->finishedLoadingMainResource(frame->loader()->documentLoader()); group->update(frame); } else { bool isUpdating = group->m_cacheBeingUpdated; if (!isUpdating) group->m_cacheBeingUpdated = ApplicationCache::create(); documentLoader->setCandidateApplicationCacheGroup(group); group->m_cacheCandidates.add(documentLoader); const KURL& url = frame->loader()->documentLoader()->originalURL(); unsigned type = 0; // If the resource has already been downloaded, remove it so that it will be replaced with the implicit resource if (isUpdating) type = group->m_cacheBeingUpdated->removeResource(url); // Add the main resource URL as an implicit entry. group->addEntry(url, type | ApplicationCacheResource::Implicit); if (!frame->loader()->documentLoader()->isLoadingMainResource()) group->finishedLoadingMainResource(frame->loader()->documentLoader()); if (!isUpdating) group->update(frame); } }
String DOMURLUtilsReadOnly::origin(const KURL& kurl) { if (kurl.isNull()) return ""; return SecurityOrigin::create(kurl)->toString(); }
PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(const String& markupString, Frame* frame, const Vector<Node*>& nodes) { ASSERT(frame); const ResourceResponse& response = frame->loader()->documentLoader()->response(); KURL responseURL = response.url(); // it's possible to have a response without a URL here // <rdar://problem/5454935> if (responseURL.isNull()) responseURL = KURL(ParsedURLString, ""); PassRefPtr<ArchiveResource> mainResource = ArchiveResource::create(utf8Buffer(markupString), responseURL, response.mimeType(), "UTF-8", frame->tree()->uniqueName()); Vector<PassRefPtr<LegacyWebArchive> > subframeArchives; Vector<PassRefPtr<ArchiveResource> > subresources; HashSet<KURL> uniqueSubresources; size_t nodesSize = nodes.size(); for (size_t i = 0; i < nodesSize; ++i) { Node* node = nodes[i]; Frame* childFrame; if ((node->hasTagName(HTMLNames::frameTag) || node->hasTagName(HTMLNames::iframeTag) || node->hasTagName(HTMLNames::objectTag)) && (childFrame = static_cast<HTMLFrameOwnerElement*>(node)->contentFrame())) { RefPtr<LegacyWebArchive> subframeArchive = create(childFrame->document()); if (subframeArchive) subframeArchives.append(subframeArchive); else LOG_ERROR("Unabled to archive subframe %s", childFrame->tree()->uniqueName().string().utf8().data()); } else { ListHashSet<KURL> subresourceURLs; node->getSubresourceURLs(subresourceURLs); DocumentLoader* documentLoader = frame->loader()->documentLoader(); ListHashSet<KURL>::iterator iterEnd = subresourceURLs.end(); for (ListHashSet<KURL>::iterator iter = subresourceURLs.begin(); iter != iterEnd; ++iter) { const KURL& subresourceURL = *iter; if (uniqueSubresources.contains(subresourceURL)) continue; uniqueSubresources.add(subresourceURL); RefPtr<ArchiveResource> resource = documentLoader->subresource(subresourceURL); if (resource) { subresources.append(resource.release()); continue; } CachedResource* cachedResource = memoryCache()->resourceForURL(subresourceURL); if (cachedResource) { resource = ArchiveResource::create(cachedResource->data(), subresourceURL, cachedResource->response()); if (resource) { subresources.append(resource.release()); continue; } } // FIXME: should do something better than spew to console here LOG_ERROR("Failed to archive subresource for %s", subresourceURL.string().utf8().data()); } } } // Add favicon if one exists for this page, if we are archiving the entire page. if (nodesSize && nodes[0]->isDocumentNode() && iconDatabase().isEnabled()) { const String& iconURL = iconDatabase().synchronousIconURLForPageURL(responseURL); if (!iconURL.isEmpty() && iconDatabase().synchronousIconDataKnownForIconURL(iconURL)) { if (Image* iconImage = iconDatabase().synchronousIconForPageURL(responseURL, IntSize(16, 16))) { if (RefPtr<ArchiveResource> resource = ArchiveResource::create(iconImage->data(), KURL(ParsedURLString, iconURL), "image/x-icon", "", "")) subresources.append(resource.release()); } } } return create(mainResource, subresources, subframeArchives); }