bool Request::addTarget(const BinaryString &target, bool finished) { if(mPath.empty() || target.empty()) return false; String prefix = mPath; if(prefix.size() >= 2 && prefix[prefix.size()-1] == '/') prefix.resize(prefix.size()-1); mFinishedAfterTarget|= finished; return incoming(Network::Locator(prefix, "/", link()) , target); }
String Cache::path(const BinaryString &digest) const { Assert(!digest.empty()); return mDirectory + Directory::Separator + digest.toString(); }
void Resource::process(const String &filename, const String &name, const String &type, const String &secret) { BinaryString salt; // If secret is not empty then this is an encrypted resource if(!secret.empty()) { // Generate salt from plaintext // Because we need to be able to recognize data is identical even when encrypted BinaryString digest; File file(filename, File::Read); Sha256().compute(file, digest); Sha256().pbkdf2_hmac(digest, type, salt, 32, 100000); Assert(!salt.empty()); } // Fill index record delete mIndexRecord; int64_t size = File::Size(filename); mIndexRecord = new Resource::IndexRecord; mIndexRecord->name = name; mIndexRecord->type = type; mIndexRecord->size = size; mIndexRecord->salt = salt; mIndexRecord->blockDigests.reserve(size/Block::Size); // Process blocks File file(filename, File::Read); BinaryString blockDigest; if(!secret.empty()) { BinaryString key; Sha256().pbkdf2_hmac(secret, salt, key, 32, 100000); uint64_t i = 0; while(true) { BinaryString subsalt; subsalt.writeBinary(i); // Generate subkey BinaryString subkey; Sha256().pbkdf2_hmac(key, subsalt, subkey, 32, 100); // Generate iv BinaryString iv; Sha256().pbkdf2_hmac(salt, subsalt, iv, 16, 100); if(!Block::EncryptFile(file, subkey, iv, blockDigest)) break; mIndexRecord->blockDigests.append(blockDigest); ++i; } } else { while(Block::ProcessFile(file, blockDigest)) mIndexRecord->blockDigests.append(blockDigest); } // Create index String tempFileName = File::TempName(); File tempFile(tempFileName, File::Truncate); BinarySerializer serializer(&tempFile); serializer.write(mIndexRecord); tempFile.close(); String indexFilePath = Cache::Instance->move(tempFileName); // Create index block delete mIndexBlock; mIndexBlock = new Block(indexFilePath); }