| // Copyright 2012 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef NET_HTTP_HTTP_VARY_DATA_H_ |
| #define NET_HTTP_HTTP_VARY_DATA_H_ |
| |
| #include <array> |
| #include <cstdint> |
| #include <string_view> |
| #include <variant> |
| |
| #include "base/check.h" |
| #include "crypto/hash.h" |
| #include "crypto/obsolete/md5.h" |
| #include "net/base/net_export.h" |
| |
| namespace base { |
| class Pickle; |
| class PickleIterator; |
| } // namespace base |
| |
| namespace net { |
| |
| struct HttpRequestInfo; |
| class HttpResponseHeaders; |
| |
| using Md5Hash = std::array<uint8_t, crypto::obsolete::Md5::kSize>; |
| using Sha256Hash = std::array<uint8_t, crypto::hash::kSha256Size>; |
| |
| // Used to implement the HTTP/1.1 Vary header. This class contains a |
| // cryptographic hash over the request headers indicated by a Vary header. |
| // |
| // While RFC 2616 requires strict request header comparisons, it is much |
| // cheaper to store a hash, which should be sufficient. Storing a hash also |
| // avoids messy privacy issues as some of the request headers could hold |
| // sensitive data (e.g., cookies). |
| // |
| // This class supports both SHA-256 and the legacy MD5 hash algorithms. New |
| // entries use SHA-256. |
| |
| // NOTE: This class does not hold onto the contents of the Vary header. |
| // Instead, it relies on the consumer to store that and to supply it again to |
| // the MatchesRequest function for comparing against future HTTP requests. |
| // |
| class NET_EXPORT_PRIVATE HttpVaryData { |
| public: |
| // The hash algorithm used for the digest. These values are persisted to disk |
| // and should not be changed. |
| enum class HashType { |
| kMD5 = 0, |
| kSHA256 = 1, |
| }; |
| |
| HttpVaryData(); |
| |
| bool is_valid() const { return is_valid_; } |
| |
| // Initialize from a request and its corresponding response headers. |
| // |
| // Returns true if a Vary header was found in the response headers and that |
| // Vary header was not empty. Upon success, the object is also marked as valid |
| // such that is_valid() will return true. Otherwise, false is returned to |
| // indicate that this object is marked as invalid. |
| // New entries are created with SHA256. |
| bool Init(const HttpRequestInfo& request_info, |
| const HttpResponseHeaders& response_headers, |
| HashType hash_type = HashType::kSHA256); |
| |
| // Initialize from a pickle that contains data generated by a call to the |
| // vary data's Persist method. |
| // |
| // Upon success, true is returned and the object is marked as valid such that |
| // is_valid() will return true. Otherwise, false is returned to indicate |
| // that this object is marked as invalid. |
| // |
| bool InitFromPickle(base::PickleIterator* pickle_iter); |
| // Call this method to persist the vary data. Illegal to call this on an |
| // invalid object. |
| void Persist(base::Pickle* pickle) const; |
| |
| // Call this method to test if the given request matches the previous request |
| // with which this vary data corresponds. The |cached_response_headers| must |
| // be the same response headers used to generate this vary data. |
| bool MatchesRequest(const HttpRequestInfo& request_info, |
| const HttpResponseHeaders& cached_response_headers) const; |
| |
| HashType hash_type() const { |
| if (std::holds_alternative<Md5Hash>(hash_)) { |
| return HashType::kMD5; |
| } |
| CHECK(std::holds_alternative<Sha256Hash>(hash_)); |
| return HashType::kSHA256; |
| } |
| |
| private: |
| // A variant to hold either a SHA-256 or MD5 hash of the request headers. |
| std::variant<Md5Hash, Sha256Hash> hash_; |
| // True when `hash_` contains meaningful data. |
| bool is_valid_ = false; |
| }; |
| |
| } // namespace net |
| |
| #endif // NET_HTTP_HTTP_VARY_DATA_H_ |