summaryrefslogtreecommitdiff
path: root/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.cpp')
-rw-r--r--Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.cpp187
1 files changed, 187 insertions, 0 deletions
diff --git a/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.cpp b/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.cpp
new file mode 100644
index 000000000..cce50a7d0
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.cpp
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NetworkCacheKey.h"
+
+#if ENABLE(NETWORK_CACHE)
+
+#include "NetworkCacheCoders.h"
+#include <wtf/ASCIICType.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/persistence/Decoder.h>
+#include <wtf/persistence/Encoder.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/StringBuilder.h>
+
+namespace WebKit {
+namespace NetworkCache {
+
+Key::Key(const Key& o)
+ : m_partition(o.m_partition.isolatedCopy())
+ , m_type(o.m_type.isolatedCopy())
+ , m_identifier(o.m_identifier.isolatedCopy())
+ , m_range(o.m_range.isolatedCopy())
+ , m_hash(o.m_hash)
+ , m_partitionHash(o.m_partitionHash)
+{
+}
+
+Key::Key(const String& partition, const String& type, const String& range, const String& identifier, const Salt& salt)
+ : m_partition(partition)
+ , m_type(type)
+ , m_identifier(identifier)
+ , m_range(range)
+ , m_hash(computeHash(salt))
+ , m_partitionHash(computePartitionHash(salt))
+{
+}
+
+Key::Key(WTF::HashTableDeletedValueType)
+ : m_identifier(WTF::HashTableDeletedValue)
+{
+}
+
+Key::Key(const DataKey& dataKey, const Salt& salt)
+ : m_partition(dataKey.partition)
+ , m_type(dataKey.type)
+ , m_identifier(hashAsString(dataKey.identifier))
+ , m_hash(computeHash(salt))
+ , m_partitionHash(computePartitionHash(salt))
+{
+}
+
+Key& Key::operator=(const Key& other)
+{
+ m_partition = other.m_partition.isolatedCopy();
+ m_type = other.m_type.isolatedCopy();
+ m_identifier = other.m_identifier.isolatedCopy();
+ m_range = other.m_range.isolatedCopy();
+ m_hash = other.m_hash;
+ m_partitionHash = other.m_partitionHash;
+ return *this;
+}
+
+static void hashString(SHA1& sha1, const String& string)
+{
+ if (string.isNull())
+ return;
+
+ if (string.is8Bit() && string.containsOnlyASCII()) {
+ const uint8_t nullByte = 0;
+ sha1.addBytes(string.characters8(), string.length());
+ sha1.addBytes(&nullByte, 1);
+ return;
+ }
+ auto cString = string.utf8();
+ // Include terminating null byte.
+ sha1.addBytes(reinterpret_cast<const uint8_t*>(cString.data()), cString.length() + 1);
+}
+
+Key::HashType Key::computeHash(const Salt& salt) const
+{
+ // We don't really need a cryptographic hash. The key is always verified against the entry header.
+ // SHA1 just happens to be suitably sized, fast and available.
+ SHA1 sha1;
+ sha1.addBytes(salt.data(), salt.size());
+
+ hashString(sha1, m_partition);
+ hashString(sha1, m_type);
+ hashString(sha1, m_identifier);
+ hashString(sha1, m_range);
+
+ SHA1::Digest hash;
+ sha1.computeHash(hash);
+ return hash;
+}
+
+Key::HashType Key::computePartitionHash(const Salt& salt) const
+{
+ SHA1 sha1;
+ sha1.addBytes(salt.data(), salt.size());
+
+ hashString(sha1, m_partition);
+
+ SHA1::Digest hash;
+ sha1.computeHash(hash);
+ return hash;
+}
+
+String Key::hashAsString(const HashType& hash)
+{
+ StringBuilder builder;
+ builder.reserveCapacity(hashStringLength());
+ for (auto byte : hash) {
+ builder.append(upperNibbleToASCIIHexDigit(byte));
+ builder.append(lowerNibbleToASCIIHexDigit(byte));
+ }
+ return builder.toString();
+}
+
+template <typename CharType> bool hexDigitsToHash(CharType* characters, Key::HashType& hash)
+{
+ for (unsigned i = 0; i < sizeof(hash); ++i) {
+ auto high = characters[2 * i];
+ auto low = characters[2 * i + 1];
+ if (!isASCIIHexDigit(high) || !isASCIIHexDigit(low))
+ return false;
+ hash[i] = toASCIIHexValue(high, low);
+ }
+ return true;
+}
+
+bool Key::stringToHash(const String& string, HashType& hash)
+{
+ if (string.length() != hashStringLength())
+ return false;
+ if (string.is8Bit())
+ return hexDigitsToHash(string.characters8(), hash);
+ return hexDigitsToHash(string.characters16(), hash);
+}
+
+bool Key::operator==(const Key& other) const
+{
+ return m_hash == other.m_hash && m_partition == other.m_partition && m_type == other.m_type && m_identifier == other.m_identifier && m_range == other.m_range;
+}
+
+void Key::encode(WTF::Persistence::Encoder& encoder) const
+{
+ encoder << m_partition;
+ encoder << m_type;
+ encoder << m_identifier;
+ encoder << m_range;
+ encoder << m_hash;
+ encoder << m_partitionHash;
+}
+
+bool Key::decode(WTF::Persistence::Decoder& decoder, Key& key)
+{
+ return decoder.decode(key.m_partition) && decoder.decode(key.m_type) && decoder.decode(key.m_identifier) && decoder.decode(key.m_range) && decoder.decode(key.m_hash) && decoder.decode(key.m_partitionHash);
+}
+
+}
+}
+
+#endif