// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// 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 "base/hash/md5.h"
#include "net/base/net_export.h"

namespace base {
class Pickle;
class PickleIterator;
}

namespace net {

struct HttpRequestInfo;
class HttpResponseHeaders;

// Used to implement the HTTP/1.1 Vary header.  This class contains a MD5 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 MD5 sum, 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).
//
// 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:
  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.
  //
  bool Init(const HttpRequestInfo& request_info,
            const HttpResponseHeaders& response_headers);

  // 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;

 private:
  // Returns the corresponding request header value.
  static std::string GetRequestValue(const HttpRequestInfo& request_info,
                                     const std::string& request_header);

  // Append to the MD5 context for the given request header.
  static void AddField(const HttpRequestInfo& request_info,
                       const std::string& request_header,
                       base::MD5Context* context);

  // A digested version of the request headers corresponding to the Vary header.
  base::MD5Digest request_digest_;

  // True when request_digest_ contains meaningful data.
  bool is_valid_;
};

}  // namespace net

#endif  // NET_HTTP_HTTP_VARY_DATA_H_
