// 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/md5.h"
#include "net/base/net_export.h"

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 and did not contain the '*' value.  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(PickleIterator* pickle_iter);

  // Call this method to persist the vary data. Illegal to call this on an
  // invalid object.
  void Persist(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_
