diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.cpp')
-rw-r--r-- | Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.cpp | 187 |
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 |