1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// HttpRequestHeaders manages the request headers.
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// It maintains these in a vector of header key/value pairs, thereby maintaining
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the order of the headers.  This means that any lookups are linear time
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// operations.
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef NET_HTTP_HTTP_REQUEST_HEADERS_H_
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define NET_HTTP_HTTP_REQUEST_HEADERS_H_
123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_piece.h"
182557749644f9d25af9721533322db19197c49b49Kristian Monsen#include "net/base/net_export.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace net {
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
222557749644f9d25af9721533322db19197c49b49Kristian Monsenclass NET_EXPORT HttpRequestHeaders {
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct HeaderKeyValuePair {
253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    HeaderKeyValuePair();
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HeaderKeyValuePair(const base::StringPiece& key,
273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       const base::StringPiece& value);
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string key;
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string value;
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef std::vector<HeaderKeyValuePair> HeaderVector;
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  class Iterator {
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   public:
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    explicit Iterator(const HttpRequestHeaders& headers);
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ~Iterator();
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Advances the iterator to the next header, if any.  Returns true if there
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // is a next header.  Use name() and value() methods to access the resultant
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // header name and value.
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool GetNext();
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // These two accessors are only valid if GetNext() returned true.
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& name() const { return curr_->key; }
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& value() const { return curr_->value; }
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   private:
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool started_;
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HttpRequestHeaders::HeaderVector::const_iterator curr_;
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const HttpRequestHeaders::HeaderVector::const_iterator end_;
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DISALLOW_COPY_AND_ASSIGN(Iterator);
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char kGetMethod[];
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char kAcceptCharset[];
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char kAcceptEncoding[];
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char kAcceptLanguage[];
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char kCacheControl[];
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char kConnection[];
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char kContentType[];
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char kCookie[];
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char kContentLength[];
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char kHost[];
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char kIfModifiedSince[];
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char kIfNoneMatch[];
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char kIfRange[];
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char kOrigin[];
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char kPragma[];
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char kProxyConnection[];
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char kRange[];
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char kReferer[];
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char kUserAgent[];
7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  static const char kTransferEncoding[];
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HttpRequestHeaders();
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~HttpRequestHeaders();
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool IsEmpty() const { return headers_.empty(); }
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool HasHeader(const base::StringPiece& key) const {
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return FindHeader(key) != headers_.end();
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Gets the first header that matches |key|.  If found, returns true and
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // writes the value to |out|.
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool GetHeader(const base::StringPiece& key, std::string* out) const;
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Clears all the headers.
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Clear();
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Sets the header value pair for |key| and |value|.  If |key| already exists,
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // then the header value is modified, but the key is untouched, and the order
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // in the vector remains the same.  When comparing |key|, case is ignored.
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void SetHeader(const base::StringPiece& key, const base::StringPiece& value);
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Sets the header value pair for |key| and |value|, if |key| does not exist.
10172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // If |key| already exists, the call is a no-op.
10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // When comparing |key|, case is ignored.
10372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void SetHeaderIfMissing(const base::StringPiece& key,
10472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          const base::StringPiece& value);
10572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Removes the first header that matches (case insensitive) |key|.
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void RemoveHeader(const base::StringPiece& key);
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Parses the header from a string and calls SetHeader() with it.  This string
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // should not contain any CRLF.  As per RFC2616, the format is:
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // message-header = field-name ":" [ field-value ]
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // field-name     = token
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // field-value    = *( field-content | LWS )
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // field-content  = <the OCTETs making up the field-value
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //                  and consisting of either *TEXT or combinations
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //                  of token, separators, and quoted-string>
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // AddHeaderFromString() will trim any LWS surrounding the
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // field-content.
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void AddHeaderFromString(const base::StringPiece& header_line);
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Same thing as AddHeaderFromString() except that |headers| is a "\r\n"
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // delimited string of header lines.  It will split up the string by "\r\n"
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // and call AddHeaderFromString() on each.
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void AddHeadersFromString(const base::StringPiece& headers);
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Calls SetHeader() on each header from |other|, maintaining order.
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void MergeFrom(const HttpRequestHeaders& other);
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Copies from |other| to |this|.
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void CopyFrom(const HttpRequestHeaders& other) {
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *this = other;
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Serializes HttpRequestHeaders to a string representation.  Joins all the
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // header keys and values with ": ", and inserts "\r\n" between each header
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // line, and adds the trailing "\r\n".
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string ToString() const;
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HeaderVector::iterator FindHeader(const base::StringPiece& key);
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HeaderVector::const_iterator FindHeader(const base::StringPiece& key) const;
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HeaderVector headers_;
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Allow the copy construction and operator= to facilitate copying in
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // HttpRequestInfo.
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(willchan): Investigate to see if we can remove the need to copy
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // HttpRequestInfo.
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // DISALLOW_COPY_AND_ASSIGN(HttpRequestHeaders);
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace net
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // NET_HTTP_HTTP_REQUEST_HEADERS_H_
157