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