KoOdfLoadingContext::KoOdfLoadingContext(KoOdfStylesReader &stylesReader, KoStore* store, const KComponentData &componentData)
        : d(new Private(stylesReader, store))
{
    // Ideally this should be done by KoDocument and passed as argument here...
    KoOdfReadStore oasisStore(store);
    QString dummy;
    (void)oasisStore.loadAndParse("tar:/META-INF/manifest.xml", d->manifestDoc, dummy);

    if (componentData.isValid()) {
        QString fileName( KStandardDirs::locate( "styles", "defaultstyles.xml", componentData ) );
        if ( ! fileName.isEmpty() ) {
            QFile file( fileName );
            QString errorMessage;
            if ( KoOdfReadStore::loadAndParse( &file, d->doc, errorMessage, fileName ) ) {
                d->defaultStylesReader.createStyleMap( d->doc, true );
            }
            else {
                kWarning(30010) << "reading of defaultstyles.xml failed:" << errorMessage;
            }
        }
        else {
            kWarning(30010) << "defaultstyles.xml not found";
        }
    }

    if (!parseManifest(d->manifestDoc)) {
        kWarning(30010) << "could not parse manifest document";
    }
}
InitsBundle::InitsBundle( const QString& path, QObject* parent )
    : QObject(parent)
    , m_path( path )
{

    parseManifest(path);
}
void AssetsManager::update()
{
    if (!_localManifest->isLoaded())
    {
        CCLOG("AssetsManager : No local manifest file found error.\n");
        dispatchUpdateEvent(EventAssetsManager::EventCode::ERROR_NO_LOCAL_MANIFEST);
        return;
    }

    _waitToUpdate = true;

    switch (_updateState) {
        case State::UNCHECKED:
        {
            _updateState = State::PREDOWNLOAD_VERSION;
        }
        case State::PREDOWNLOAD_VERSION:
        {
            downloadVersion();
        }
            break;
        case State::VERSION_LOADED:
        {
            parseVersion();
        }
            break;
        case State::PREDOWNLOAD_MANIFEST:
        {
            downloadManifest();
        }
            break;
        case State::MANIFEST_LOADED:
        {
            parseManifest();
        }
            break;
        case State::FAIL_TO_UPDATE:
        case State::NEED_UPDATE:
        {
            // Manifest not loaded yet
            if (!_remoteManifest->isLoaded())
            {
                _waitToUpdate = true;
                _updateState = State::PREDOWNLOAD_MANIFEST;
                downloadManifest();
            }
            else
            {
                startUpdate();
            }
        }
            break;
        case State::UP_TO_DATE:
        case State::UPDATING:
            _waitToUpdate = false;
            break;
        default:
            break;
    }
}
void KoOdfLoadingContext::setManifestFile(const QString& fileName) {
    KoOdfReadStore oasisStore(d->store);
    QString dummy;
    (void)oasisStore.loadAndParse(fileName, d->manifestDoc, dummy);
    if (!parseManifest(d->manifestDoc)) {
        kWarning(30010) << "could not parse manifest document";
    }
}
void WidgetParseManifest::execute()
{
    WidgetErrorType error = parseManifest();
    
    if( error == EErrorNone )
        emit completed();
    else
        emit aborted( error );
    
    return;

}
bool ProviderWithChecksum::openArchive(const UString &path, bool write)
{

	if (!inner->openArchive(path, write))
	{
		return false;
	}

	UString result;
	if (!inner->readDocument("checksum.xml", result))
	{
		LogInfo("Missing manifest file in \"%s\"", path.cStr());
		return true;
	}
	parseManifest(result.str());
	return true;
}
bool ManifestParser::parse(const Source& source, const std::shared_ptr<XmlPullParser>& parser,
                           AppInfo* outInfo) {
    SourceLogger logger = { source };

    int depth = 0;
    while (XmlPullParser::isGoodEvent(parser->next())) {
        XmlPullParser::Event event = parser->getEvent();
        if (event == XmlPullParser::Event::kEndElement) {
            depth--;
            continue;
        } else if (event != XmlPullParser::Event::kStartElement) {
            continue;
        }

        depth++;

        const std::u16string& element = parser->getElementName();
        if (depth == 1) {
            if (element == u"manifest") {
                if (!parseManifest(logger, parser, outInfo)) {
                    return false;
                }
            } else {
                logger.error()
                        << "unexpected top-level element '"
                        << element
                        << "'."
                        << std::endl;
                return false;
            }
        } else {
            XmlPullParser::skipCurrentElement(parser.get());
        }
    }

    if (parser->getEvent() == XmlPullParser::Event::kBadDocument) {
            logger.error(parser->getLineNumber())
                << "failed to parse manifest: "
                << parser->getLastError()
                << "."
                << std::endl;
        return false;
    }
    return true;
}
void PAAlternativeLauncher::manifestFinished()
{
	QNetworkReply *reply = dynamic_cast<QNetworkReply *>(sender());
	if(reply)
	{
		if(reply->error() == QNetworkReply::NoError)
		{
			int res = inflateEnd(&mZstream);
			if(res != Z_OK && res != Z_STREAM_END)
			{
				info.warning("ZLib 2", mZstream.msg, false);
				return;
			}

			delete[] mBuffer;
			mBuffer = NULL;

			QVariantMap object = mStreamsComboBox->currentData().toMap();
			QString downloadurl = object["DownloadUrl"].toString();
			QString titlefolder = object["TitleFolder"].toString();
			QString authsuffix = object["AuthSuffix"].toString();

			mNetworkAccessManager->deleteLater();

			mPatcher = new Patcher;
			mPatcher->moveToThread(&mPatcherThread);

			mPatcher->setInstallPath(mInstallPathLineEdit->text());
			mPatcher->setDownloadUrl(downloadurl + "/" + titlefolder + "/hashed/%1" + authsuffix);
			mPatcher->giveJsonData(mManifestJson.buffer());
			mManifestJson.close();

			connect(mPatcher, SIGNAL(done()), this, SLOT(patcherDone()));
			connect(mPatcher, SIGNAL(error(QString)), this, SLOT(patcherError(QString)));
			connect(mPatcher, SIGNAL(progress(int)), this, SLOT(patcherProgress(int)));
			connect(mPatcher, SIGNAL(stateChange(QString)), this, SLOT(patcherStateChange(QString)));
			connect(&mPatcherThread, SIGNAL(finished()), mPatcher, SLOT(deleteLater()));
			connect(&mPatcherThread, SIGNAL(started()), mPatcher, SLOT(parseManifest()));

			mPatcherThread.start();
		}
		else
		{
			if(reply->error() == QNetworkReply::AuthenticationRequiredError)
void AssetsManagerEx::onSuccess(const std::string &/*srcUrl*/, const std::string &storagePath, const std::string &customId)
{
    if (customId == VERSION_ID)
    {
        _updateState = State::VERSION_LOADED;
        parseVersion();
    }
    else if (customId == MANIFEST_ID)
    {
        _updateState = State::MANIFEST_LOADED;
        parseManifest();
    }
    else
    {
        bool ok = true;
        auto &assets = _remoteManifest->getAssets();
        auto assetIt = assets.find(customId);
        if (assetIt != assets.end())
        {
            Manifest::Asset asset = assetIt->second;
            if (_verifyCallback != nullptr)
            {
                ok = _verifyCallback(storagePath, asset);
            }
        }
        
        if (ok)
        {
            bool compressed = assetIt != assets.end() ? assetIt->second.compressed : false;
            if (compressed)
            {
                decompressDownloadedZip(customId, storagePath);
            }
            else
            {
                fileSuccess(customId, storagePath);
            }
        }
        else
        {
            fileError(customId, "Asset file verification failed after downloaded");
        }
    }
}
void ModuleMgr::update()
{
    _waitToUpdate = true;

    switch (_updateState) {
        case State::UNCHECKED:
        {
            _updateState = State::PREDOWNLOAD_MANIFEST;
        }
        case State::PREDOWNLOAD_MANIFEST:
        {
            downloadManifest();
        }
            break;
        case State::MANIFEST_LOADED:
        {
            parseManifest();
        }
            break;
        case State::FAIL_TO_UPDATE:
        case State::NEED_UPDATE:
        {
            // Manifest not loaded yet
            if (!_remoteManifest->isLoaded())
            {
                _waitToUpdate = true;
                _updateState = State::PREDOWNLOAD_MANIFEST;
                downloadManifest();
            }
            else
            {
                startUpdate();
            }
        }
            break;
        case State::UP_TO_DATE:
        case State::UPDATING:
            _waitToUpdate = false;
            break;
        default:
            break;
    }
}
void ApplicationCacheGroup::didFinishLoadingManifest()
{
    bool isUpgradeAttempt = m_newestCache;

    if (!isUpgradeAttempt && !m_manifestResource) {
        // The server returned 304 Not Modified even though we didn't send a conditional request.
        cacheUpdateFailed();
        return;
    }

    m_manifestHandle = 0;

    // Check if the manifest was not modified.
    if (isUpgradeAttempt) {
        ApplicationCacheResource* newestManifest = m_newestCache->manifestResource();
        ASSERT(newestManifest);
    
        if (!m_manifestResource || // The resource will be null if HTTP response was 304 Not Modified.
            (newestManifest->data()->size() == m_manifestResource->data()->size() && !memcmp(newestManifest->data()->data(), m_manifestResource->data()->data(), newestManifest->data()->size()))) {

            m_completionType = NoUpdate;
            m_manifestResource = 0;
            deliverDelayedMainResources();

            return;
        }
    }
    
    Manifest manifest;
    if (!parseManifest(m_manifestURL, m_manifestResource->data()->data(), m_manifestResource->data()->size(), manifest)) {
        cacheUpdateFailed();
        return;
    }

    ASSERT(!m_cacheBeingUpdated);
    m_cacheBeingUpdated = ApplicationCache::create();
    m_cacheBeingUpdated->setGroup(this);

    HashSet<DocumentLoader*>::const_iterator masterEnd = m_pendingMasterResourceLoaders.end();
    for (HashSet<DocumentLoader*>::const_iterator iter = m_pendingMasterResourceLoaders.begin(); iter != masterEnd; ++iter)
        associateDocumentLoaderWithCache(*iter, m_cacheBeingUpdated.get());

    // We have the manifest, now download the resources.
    setUpdateStatus(Downloading);
    
    postListenerTask(ApplicationCacheHost::DOWNLOADING_EVENT, m_associatedDocumentLoaders);

    ASSERT(m_pendingEntries.isEmpty());

    if (isUpgradeAttempt) {
        ApplicationCache::ResourceMap::const_iterator end = m_newestCache->end();
        for (ApplicationCache::ResourceMap::const_iterator it = m_newestCache->begin(); it != end; ++it) {
            unsigned type = it->second->type();
            if (type & ApplicationCacheResource::Master)
                addEntry(it->first, type);
        }
    }
    
    HashSet<String>::const_iterator end = manifest.explicitURLs.end();
    for (HashSet<String>::const_iterator it = manifest.explicitURLs.begin(); it != end; ++it)
        addEntry(*it, ApplicationCacheResource::Explicit);

    size_t fallbackCount = manifest.fallbackURLs.size();
    for (size_t i = 0; i  < fallbackCount; ++i)
        addEntry(manifest.fallbackURLs[i].second, ApplicationCacheResource::Fallback);
    
    m_cacheBeingUpdated->setOnlineWhitelist(manifest.onlineWhitelistedURLs);
    m_cacheBeingUpdated->setFallbackURLs(manifest.fallbackURLs);
    m_cacheBeingUpdated->setAllowsAllNetworkRequests(manifest.allowAllNetworkRequests);

    m_progressTotal = m_pendingEntries.size();
    m_progressDone = 0;

    startLoadingEntry();
}
Beispiel #12
0
int main(int argc, char* argv[]) {
	init_libxpwn(&argc, argv);

	OutputState *outputState;
	size_t fileLength;

	AbstractFile *signFile;
	Dictionary *signDict = NULL;
	DataValue *ticket;
	Dictionary *dict;

	AbstractFile *manifestFile;
	Dictionary* manifest;
	struct component_t *array;

	char *plist;
	int i, j, n;
	int rv, error = 0;

	X509 *x0, *y1, *y2;
	uint64_t savecid = 0;
	const unsigned char *p;

	int verbose = FALSE;
	int fromzip = FALSE;

	if (argc < 3) {
		XLOG(0, "usage %s file.shsh BuildManifest.plist [-v] [-z]\n", argv[0]);
		return 0;
	}

	for (i = 3; i < argc; i++) {
		if (!strcmp(argv[i], "-v")) {
			verbose = TRUE;
			continue;
		}

		if (!strcmp(argv[i], "-z")) {
			fromzip = TRUE;
			continue;
		}
	}

	// XXX handle gzip/bplist files
	signFile = createAbstractFileFromFile(fopen(argv[1], "rb"));
	if (!signFile) {
		XLOG(0, "FATAL: cannot open %s\n", argv[1]);
		exit(1);
	}

	fileLength = signFile->getLength(signFile);
	plist = malloc(fileLength);
	signFile->read(signFile, plist, fileLength);
	signFile->close(signFile);
	signDict = createRoot(plist);
	free(plist);

	if (!signDict) {
		XLOG(0, "FATAL: cannot parse %s\n", argv[1]);
		exit(1);
	}

	MaxLoadZipSize = 128 * 1024;
	if (fromzip) {
		outputState = loadZip2(argv[2], TRUE); // XXX ASSERT
		manifestFile = getFileFromOutputState(&outputState, "BuildManifest.plist");
	} else {
		outputState = NULL;
		manifestFile = createAbstractFileFromFile(fopen(argv[2], "rb"));
	}
	if (!manifestFile) {
		XLOG(0, "FATAL: cannot open %s\n", argv[2]);
		exit(1);
	}

	fileLength = manifestFile->getLength(manifestFile);
	plist = malloc(fileLength);
	manifestFile->read(manifestFile, plist, fileLength);
	manifestFile->close(manifestFile);
	manifest = createRoot(plist);
	free(plist);

	if (!manifest) {
		XLOG(0, "FATAL: cannot parse %s\n", argv[2]);
		exit(1);
	}

	releaseOutput(&outputState);

	array = parseManifest(manifest, &n);
	if (!array) {
		XLOG(0, "FATAL: cannot parse manifest\n");
		exit(1);
	}

	OPENSSL_add_all_algorithms_noconf();
	p = cerb;
	x0 = d2i_X509(NULL, &p, cerb_len);
	if (!x0) {
		XLOG(0, "FATAL: cannot load root CA\n");
		exit(1);
	}

	ticket = (DataValue *)getValueByKey(signDict, "APTicket");
	if (ticket) {
		p = ticket->value;
		rv = asn1_parse2(&p, ticket->len, 0, 0);
		if (!rv || !apcert.value || !rsasig.value || !theset.value) {
			XLOG(0, "FATAL: cannot parse ticket\n");
			exit(1);
		}
		if (clen > 0 && contarray->len == 8) {
			savecid = getECID(contarray->value);
		}
		if (!savecid) {
			printf("ERROR: bad, bad ECID\n");
			error = 1;
		}

		rv = extract2Certs(apcert.value, apcert.len, &y1, &y2);
		if (rv == 0) {
			rv = cryptoMagic(x0, y1, y2, theset.value, theset.len, (unsigned char *)rsasig.value, rsasig.len, NULL);
			X509_free(y1);
			X509_free(y2);
		}
		if (rv) {
			printf("ERROR: APTicket failed crypto\n");
			error = 1;
		}
	} else {
		VERBOSE("WARNING: cannot find ticket in %s\n", argv[1]);
	}

	dict = (Dictionary *)signDict->values;
	while (dict) {
		DataValue *blob = NULL;
		DataValue *partialDigest = NULL;
		if (dict->dValue.type == DictionaryType) {
			blob = (DataValue *)getValueByKey(dict, "Blob");
			partialDigest = (DataValue *)getValueByKey(dict, "PartialDigest");
		}
		if (blob && partialDigest) {
			const char *diag = checkBlob(x0, blob, partialDigest, &savecid);
			if (diag) {
				printf("ERROR: Blob for %s is invalid (%s)\n", dict->dValue.key, diag);
				error = 1;
			} else {
				for (i = 0; i < n; i++) {
					struct component_t *centry = array + i;
					if (centry->partial &&
					    partialDigest->len == centry->partial->len &&
					    !memcmp(partialDigest->value, centry->partial->value, partialDigest->len)) {
						array[i].blob = blob;
					}
				}
			}
		}
		dict = (Dictionary *)dict->dValue.next;
	}

	if (!ticket && !savecid) {
		printf("ERROR: bad, bad ECID\n");
		error = 1;
	}

	for (i = 0; i < n; i++) {
		struct component_t *centry = array + i;
		int found = FALSE;
		for (j = 0; j < clen; j++) {
			struct tuple_t *tentry = contarray + j;
			if (tentry->len == centry->digest->len && !memcmp(tentry->value, centry->digest->value, tentry->len)) {
				found = TRUE;
			}
		}
		if (!found) {
			if (centry->blob) {
				VERBOSE("WARNING: no digest for %s (%s), but it has blob\n", centry->key, centry->path);
			} else if (!centry->required) {
				VERBOSE("WARNING: no digest for %s (%s), but it is not critical\n", centry->key, centry->path);
			} else {
				printf("ERROR: no digest for %s (%s) and no blob found\n", centry->key, centry->path);
				error = 1;
			}
		} else {
			VERBOSE("INFO: %s (%s) is signed by APTicket%s\n", centry->key, centry->path, centry->blob ? " and blob" : "");
		}
	}
	free(array);
	free(contarray);

	releaseDictionary(manifest);
	releaseDictionary(signDict);

	if (error) {
		printf("%s is BROKEN\n", argv[1]);
	} else {
		printf("%s seems usable for ECID 0x%016llX\n", argv[1], savecid);
	}

	X509_free(x0);

	EVP_cleanup();
	ERR_remove_state(0);
	CRYPTO_cleanup_all_ex_data();
	return error;
}
Beispiel #13
0
void ApplicationCacheGroup::didFinishLoadingManifest()
{
    bool isUpgradeAttempt = m_newestCache;

    if (!isUpgradeAttempt && !m_manifestResource) {
        // The server returned 304 Not Modified even though we didn't send a conditional request.
        m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, ASCIILiteral("Application Cache manifest could not be fetched because of an unexpected 304 Not Modified server response."));
        cacheUpdateFailed();
        return;
    }

    m_manifestHandle = nullptr;

    // Check if the manifest was not modified.
    if (isUpgradeAttempt) {
        ApplicationCacheResource* newestManifest = m_newestCache->manifestResource();
        ASSERT(newestManifest);
    
        if (!m_manifestResource || // The resource will be null if HTTP response was 304 Not Modified.
            (newestManifest->data().size() == m_manifestResource->data().size() && !memcmp(newestManifest->data().data(), m_manifestResource->data().data(), newestManifest->data().size()))) {

            m_completionType = NoUpdate;
            m_manifestResource = nullptr;
            deliverDelayedMainResources();

            return;
        }
    }
    
    Manifest manifest;
    if (!parseManifest(m_manifestURL, m_manifestResource->data().data(), m_manifestResource->data().size(), manifest)) {
        // At the time of this writing, lack of "CACHE MANIFEST" signature is the only reason for parseManifest to fail.
        m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, ASCIILiteral("Application Cache manifest could not be parsed. Does it start with CACHE MANIFEST?"));
        cacheUpdateFailed();
        return;
    }

    ASSERT(!m_cacheBeingUpdated);
    m_cacheBeingUpdated = ApplicationCache::create();
    m_cacheBeingUpdated->setGroup(this);

    for (auto& loader : m_pendingMasterResourceLoaders)
        associateDocumentLoaderWithCache(loader, m_cacheBeingUpdated.get());

    // We have the manifest, now download the resources.
    setUpdateStatus(Downloading);
    
    postListenerTask(ApplicationCacheHost::DOWNLOADING_EVENT, m_associatedDocumentLoaders);

    ASSERT(m_pendingEntries.isEmpty());

    if (isUpgradeAttempt) {
        for (const auto& urlAndResource : m_newestCache->resources()) {
            unsigned type = urlAndResource.value->type();
            if (type & ApplicationCacheResource::Master)
                addEntry(urlAndResource.key, type);
        }
    }
    
    for (const auto& explicitURL : manifest.explicitURLs)
        addEntry(explicitURL, ApplicationCacheResource::Explicit);

    for (auto& fallbackURL : manifest.fallbackURLs)
        addEntry(fallbackURL.second, ApplicationCacheResource::Fallback);
    
    m_cacheBeingUpdated->setOnlineWhitelist(manifest.onlineWhitelistedURLs);
    m_cacheBeingUpdated->setFallbackURLs(manifest.fallbackURLs);
    m_cacheBeingUpdated->setAllowsAllNetworkRequests(manifest.allowAllNetworkRequests);

    m_progressTotal = m_pendingEntries.size();
    m_progressDone = 0;

    recalculateAvailableSpaceInQuota();

    startLoadingEntry();
}
void AssetsManagerEx::update()
{
    if (_updateEntry != UpdateEntry::NONE)
    {
        CCLOGERROR("AssetsManagerEx::update, updateEntry isn't NONE");
        return;
    }

    if (!_inited){
        CCLOG("AssetsManagerEx : Manifests uninited.\n");
        dispatchUpdateEvent(EventAssetsManagerEx::EventCode::ERROR_NO_LOCAL_MANIFEST);
        return;
    }
    if (!_localManifest->isLoaded())
    {
        CCLOG("AssetsManagerEx : No local manifest file found error.\n");
        dispatchUpdateEvent(EventAssetsManagerEx::EventCode::ERROR_NO_LOCAL_MANIFEST);
        return;
    }

    _updateEntry = UpdateEntry::DO_UPDATE;

    switch (_updateState) {
        case State::UNCHECKED:
        {
            _updateState = State::PREDOWNLOAD_VERSION;
        }
        case State::PREDOWNLOAD_VERSION:
        {
            downloadVersion();
        }
            break;
        case State::VERSION_LOADED:
        {
            parseVersion();
        }
            break;
        case State::PREDOWNLOAD_MANIFEST:
        {
            downloadManifest();
        }
            break;
        case State::MANIFEST_LOADED:
        {
            parseManifest();
        }
            break;
        case State::FAIL_TO_UPDATE:
        case State::NEED_UPDATE:
        {
            // Manifest not loaded yet
            if (!_remoteManifest->isLoaded())
            {
                _updateState = State::PREDOWNLOAD_MANIFEST;
                downloadManifest();
            }
            else
            {
                startUpdate();
            }
        }
            break;
        case State::UP_TO_DATE:
        case State::UPDATING:
        case State::UNZIPPING:
            _updateEntry = UpdateEntry::NONE;
            break;
        default:
            break;
    }
}
void ApplicationCacheGroup::didFinishLoadingManifest()
{
    bool isUpgradeAttempt = m_newestCache;

    if (!isUpgradeAttempt && !m_manifestResource) {
        // The server returned 304 Not Modified even though we didn't send a conditional request.
        m_frame->document()->addConsoleMessage(OtherMessageSource, ErrorMessageLevel, "Application Cache manifest could not be fetched because of an unexpected 304 Not Modified server response.");
        cacheUpdateFailed();
        return;
    }

    m_manifestHandle = 0;

    // Check if the manifest was not modified.
    if (isUpgradeAttempt) {
        ApplicationCacheResource* newestManifest = m_newestCache->manifestResource();
        ASSERT(newestManifest);

        if (!m_manifestResource || // The resource will be null if HTTP response was 304 Not Modified.
                (newestManifest->data()->size() == m_manifestResource->data()->size() && !memcmp(newestManifest->data()->data(), m_manifestResource->data()->data(), newestManifest->data()->size()))) {

            m_completionType = NoUpdate;
            m_manifestResource = 0;
            deliverDelayedMainResources();

            return;
        }
    }

    Manifest manifest;
    if (!parseManifest(m_manifestURL, m_manifestResource->data()->data(), m_manifestResource->data()->size(), manifest)) {
        // At the time of this writing, lack of "CACHE MANIFEST" signature is the only reason for parseManifest to fail.
        m_frame->document()->addConsoleMessage(OtherMessageSource, ErrorMessageLevel, "Application Cache manifest could not be parsed. Does it start with CACHE MANIFEST?");
        cacheUpdateFailed();
        return;
    }

    ASSERT(!m_cacheBeingUpdated);
    m_cacheBeingUpdated = ApplicationCache::create();
    m_cacheBeingUpdated->setGroup(this);

    HashSet<DocumentLoader*>::const_iterator masterEnd = m_pendingMasterResourceLoaders.end();
    for (HashSet<DocumentLoader*>::const_iterator iter = m_pendingMasterResourceLoaders.begin(); iter != masterEnd; ++iter)
        associateDocumentLoaderWithCache(*iter, m_cacheBeingUpdated.get());

    // We have the manifest, now download the resources.
    setUpdateStatus(Downloading);

    postListenerTask(ApplicationCacheHost::DOWNLOADING_EVENT, m_associatedDocumentLoaders);

    ASSERT(m_pendingEntries.isEmpty());

    if (isUpgradeAttempt) {
        ApplicationCache::ResourceMap::const_iterator end = m_newestCache->end();
        for (ApplicationCache::ResourceMap::const_iterator it = m_newestCache->begin(); it != end; ++it) {
            unsigned type = it->value->type();
            if (type & ApplicationCacheResource::Master)
                addEntry(it->key, type);
        }
    }

    HashSet<String>::const_iterator end = manifest.explicitURLs.end();
    for (HashSet<String>::const_iterator it = manifest.explicitURLs.begin(); it != end; ++it)
        addEntry(*it, ApplicationCacheResource::Explicit);

    size_t fallbackCount = manifest.fallbackURLs.size();
    for (size_t i = 0; i  < fallbackCount; ++i)
        addEntry(manifest.fallbackURLs[i].second, ApplicationCacheResource::Fallback);

    m_cacheBeingUpdated->setOnlineWhitelist(manifest.onlineWhitelistedURLs);
    m_cacheBeingUpdated->setFallbackURLs(manifest.fallbackURLs);
    m_cacheBeingUpdated->setAllowsAllNetworkRequests(manifest.allowAllNetworkRequests);

    m_progressTotal = m_pendingEntries.size();
    m_progressDone = 0;

    recalculateAvailableSpaceInQuota();

    startLoadingEntry();
}
Beispiel #16
0
void ApplicationCacheGroup::didFinishLoadingManifest()
{
    if (!m_manifestResource) {
        didFailToLoadManifest();
        return;
    }

    bool isUpgradeAttempt = m_newestCache;
    
    m_manifestHandle = 0;

    // Check if the manifest is byte-for-byte identical.
    if (isUpgradeAttempt) {
        ApplicationCacheResource* newestManifest = m_newestCache->manifestResource();
        ASSERT(newestManifest);
    
        if (newestManifest->data()->size() == m_manifestResource->data()->size() &&
            !memcmp(newestManifest->data()->data(), m_manifestResource->data()->data(), newestManifest->data()->size())) {
            
            callListenersOnAssociatedDocuments(&DOMApplicationCache::callNoUpdateListener);
         
            m_status = Idle;
            m_frame = 0;
            m_manifestResource = 0;
            return;
        }
    }
    
    Manifest manifest;
    if (!parseManifest(m_manifestURL, m_manifestResource->data()->data(), m_manifestResource->data()->size(), manifest)) {
        didFailToLoadManifest();
        return;
    }
        
    // We have the manifest, now download the resources.
    m_status = Downloading;
    
    callListenersOnAssociatedDocuments(&DOMApplicationCache::callDownloadingListener);

#ifndef NDEBUG
    // We should only have implicit entries.
    {
        EntryMap::const_iterator end = m_pendingEntries.end();
        for (EntryMap::const_iterator it = m_pendingEntries.begin(); it != end; ++it)
            ASSERT(it->second & ApplicationCacheResource::Implicit);
    }
#endif
    
    if (isUpgradeAttempt) {
        ASSERT(!m_cacheBeingUpdated);
        
        m_cacheBeingUpdated = ApplicationCache::create();
        
        ApplicationCache::ResourceMap::const_iterator end = m_newestCache->end();
        for (ApplicationCache::ResourceMap::const_iterator it = m_newestCache->begin(); it != end; ++it) {
            unsigned type = it->second->type();
            if (type & (ApplicationCacheResource::Implicit | ApplicationCacheResource::Dynamic))
                addEntry(it->first, type);
        }
    }
    
    HashSet<String>::const_iterator end = manifest.explicitURLs.end();
    for (HashSet<String>::const_iterator it = manifest.explicitURLs.begin(); it != end; ++it)
        addEntry(*it, ApplicationCacheResource::Explicit);

    size_t fallbackCount = manifest.fallbackURLs.size();
    for (size_t i = 0; i  < fallbackCount; ++i)
        addEntry(manifest.fallbackURLs[i].second, ApplicationCacheResource::Fallback);
    
    m_cacheBeingUpdated->setOnlineWhitelist(manifest.onlineWhitelistedURLs);
    m_cacheBeingUpdated->setFallbackURLs(manifest.fallbackURLs);
    
    startLoadingEntry();
}
void ModuleMgr::onSuccess(const std::string &srcUrl, const std::string &storagePath, const std::string &customId)
{
    CCLOG("ModuleMgr::onSuccess: %s %s", customId.c_str(), storagePath.c_str());
    if (customId == MANIFEST_ID)
    {
        _updateState = State::MANIFEST_LOADED;
        parseManifest();
    }
    else if (customId == BATCH_UPDATE_ID)
    {
        // Finished with error check
        if (_failedUnits.size() > 0 || _totalWaitToDownload > 0)
        {
            // Save current download manifest information for resuming
            //_tempManifest->saveToFile(_tempManifestPath);
            
            decompressDownloadedZip();
            
            _updateState = State::FAIL_TO_UPDATE;
            dispatchUpdateEvent(ModuleMgrEvent::EventCode::UPDATE_FAILED);
        }
        else
        {
            updateSucceed();
        }
    }
    else
    {
        auto assets = _remoteManifest->getAssets();
        auto assetIt = assets.find(customId);
        if (assetIt != assets.end())
        {
            // Set download state to SUCCESSED
            _remoteManifest->setAssetDownloadState(customId, ModuleManifest::DownloadState::SUCCESSED);
            
            // Add file to need decompress list
            if (assetIt->second.compressed) {
                _compressedFiles.push_back(storagePath);
            }
        }
        
        auto unitIt = _downloadUnits.find(customId);
        if (unitIt != _downloadUnits.end())
        {
            // Reduce count only when unit found in _downloadUnits
            _totalWaitToDownload--;
            
            _percentByFile = 100 * (float)(_totalToDownload - _totalWaitToDownload) / _totalToDownload;
            // Notify progression event
            dispatchUpdateEvent(ModuleMgrEvent::EventCode::UPDATE_PROGRESSION, "");
        }
        // Notify asset updated event
        dispatchUpdateEvent(ModuleMgrEvent::EventCode::ASSET_UPDATED, customId);
        
        unitIt = _failedUnits.find(customId);
        // Found unit and delete it
        if (unitIt != _failedUnits.end())
        {
            // Remove from failed units list
            _failedUnits.erase(unitIt);
        }
    }
}