• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
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 
13 #include <memory>
14 #include <optional>
15 #include <string>
16 #include <string_view>
17 #include <vector>
18 
19 #include "base/containers/flat_set.h"
20 #include "base/values.h"
21 #include "net/base/net_export.h"
22 #include "net/filter/source_stream.h"
23 #include "net/log/net_log_capture_mode.h"
24 #include "url/gurl.h"
25 
26 namespace net {
27 
28 class NET_EXPORT HttpRequestHeaders {
29  public:
30   struct NET_EXPORT HeaderKeyValuePair {
31     HeaderKeyValuePair();
32     HeaderKeyValuePair(std::string_view key, std::string_view value);
33     HeaderKeyValuePair(std::string_view key, std::string&& value);
34     // Inline to take advantage of the std::string_view constructor being
35     // constexpr.
HeaderKeyValuePairHeaderKeyValuePair36     HeaderKeyValuePair(std::string_view key, const char* value)
37         : HeaderKeyValuePair(key, std::string_view(value)) {}
38 
39     bool operator==(const HeaderKeyValuePair& other) const = default;
40 
41     std::string key;
42     std::string value;
43   };
44 
45   typedef std::vector<HeaderKeyValuePair> HeaderVector;
46 
47   class NET_EXPORT Iterator {
48    public:
49     explicit Iterator(const HttpRequestHeaders& headers);
50 
51     Iterator(const Iterator&) = delete;
52     Iterator& operator=(const Iterator&) = delete;
53 
54     ~Iterator();
55 
56     // Advances the iterator to the next header, if any.  Returns true if there
57     // is a next header.  Use name() and value() methods to access the resultant
58     // header name and value.
59     bool GetNext();
60 
61     // These two accessors are only valid if GetNext() returned true.
name()62     const std::string& name() const { return curr_->key; }
value()63     const std::string& value() const { return curr_->value; }
64 
65    private:
66     bool started_ = false;
67     HttpRequestHeaders::HeaderVector::const_iterator curr_;
68     const HttpRequestHeaders::HeaderVector::const_iterator end_;
69   };
70 
71   static const char kConnectMethod[];
72   static const char kDeleteMethod[];
73   static const char kGetMethod[];
74   static const char kHeadMethod[];
75   static const char kOptionsMethod[];
76   static const char kPatchMethod[];
77   static const char kPostMethod[];
78   static const char kPutMethod[];
79   static const char kTraceMethod[];
80   static const char kTrackMethod[];
81 
82   static const char kAccept[];
83   static const char kAcceptCharset[];
84   static const char kAcceptEncoding[];
85   static const char kAcceptLanguage[];
86   static const char kAuthorization[];
87   static const char kCacheControl[];
88   static const char kConnection[];
89   static const char kContentType[];
90   static const char kCookie[];
91   static const char kContentLength[];
92   static const char kHost[];
93   static const char kIfMatch[];
94   static const char kIfModifiedSince[];
95   static const char kIfNoneMatch[];
96   static const char kIfRange[];
97   static const char kIfUnmodifiedSince[];
98   static const char kOrigin[];
99   static const char kPragma[];
100   static const char kPriority[];
101   static const char kProxyAuthorization[];
102   static const char kProxyConnection[];
103   static const char kRange[];
104   static const char kReferer[];
105   static const char kTransferEncoding[];
106   static const char kUserAgent[];
107 
108   HttpRequestHeaders();
109   HttpRequestHeaders(const HttpRequestHeaders& other);
110   HttpRequestHeaders(HttpRequestHeaders&& other);
111   ~HttpRequestHeaders();
112 
113   HttpRequestHeaders& operator=(const HttpRequestHeaders& other);
114   HttpRequestHeaders& operator=(HttpRequestHeaders&& other);
115 
IsEmpty()116   bool IsEmpty() const { return headers_.empty(); }
117 
HasHeader(std::string_view key)118   bool HasHeader(std::string_view key) const {
119     return FindHeader(key) != headers_.end();
120   }
121 
122   // Gets the first header that matches |key|, if one exists. If none exist,
123   // returns std::nullopt.
124   std::optional<std::string> GetHeader(std::string_view key) const;
125 
126   // Clears all the headers.
127   void Clear();
128 
129   // Sets the header value pair for |key| and |value|.  If |key| already exists,
130   // then the header value is modified, but the key is untouched, and the order
131   // in the vector remains the same.  When comparing |key|, case is ignored.
132   // The caller must ensure that |key| passes HttpUtil::IsValidHeaderName() and
133   // |value| passes HttpUtil::IsValidHeaderValue().
134   void SetHeader(std::string_view key, std::string_view value);
135   void SetHeader(std::string_view key, std::string&& value);
136   // Inline to take advantage of the std::string_view constructor being
137   // constexpr.
SetHeader(std::string_view key,const char * value)138   void SetHeader(std::string_view key, const char* value) {
139     SetHeader(key, std::string_view(value));
140   }
141 
142   // Does the same as above but without internal DCHECKs for validations.
143   void SetHeaderWithoutCheckForTesting(std::string_view key,
144                                        std::string_view value);
145 
146   // Sets the header value pair for |key| and |value|, if |key| does not exist.
147   // If |key| already exists, the call is a no-op.
148   // When comparing |key|, case is ignored.
149   //
150   // The caller must ensure that |key| passes HttpUtil::IsValidHeaderName() and
151   // |value| passes HttpUtil::IsValidHeaderValue().
152   void SetHeaderIfMissing(std::string_view key, std::string_view value);
153 
154   // Removes the first header that matches (case insensitive) |key|.
155   void RemoveHeader(std::string_view key);
156 
157   // Parses the header from a string and calls SetHeader() with it.  This string
158   // should not contain any CRLF.  As per RFC7230 Section 3.2, the format is:
159   //
160   // header-field   = field-name ":" OWS field-value OWS
161   //
162   // field-name     = token
163   // field-value    = *( field-content / obs-fold )
164   // field-content  = field-vchar [ 1*( SP / HTAB ) field-vchar ]
165   // field-vchar    = VCHAR / obs-text
166   //
167   // obs-fold       = CRLF 1*( SP / HTAB )
168   //                ; obsolete line folding
169   //                ; see Section 3.2.4
170   //
171   // AddHeaderFromString() will trim any LWS surrounding the
172   // field-content.
173   void AddHeaderFromString(std::string_view header_line);
174 
175   // Same thing as AddHeaderFromString() except that |headers| is a "\r\n"
176   // delimited string of header lines.  It will split up the string by "\r\n"
177   // and call AddHeaderFromString() on each.
178   void AddHeadersFromString(std::string_view headers);
179 
180   // Calls SetHeader() on each header from |other|, maintaining order.
181   void MergeFrom(const HttpRequestHeaders& other);
182 
Swap(HttpRequestHeaders * other)183   void Swap(HttpRequestHeaders* other) { headers_.swap(other->headers_); }
184 
185   // Serializes HttpRequestHeaders to a string representation.  Joins all the
186   // header keys and values with ": ", and inserts "\r\n" between each header
187   // line, and adds the trailing "\r\n".
188   std::string ToString() const;
189 
190   // Takes in the request line and returns a Value for use with the NetLog
191   // containing both the request line and all headers fields.
192   base::Value::Dict NetLogParams(const std::string& request_line,
193                                  NetLogCaptureMode capture_mode) const;
194 
GetHeaderVector()195   const HeaderVector& GetHeaderVector() const { return headers_; }
196 
197   // Sets Accept-Encoding header based on `url` and `accepted_stream_types`, if
198   // it does not exist. "br" is appended only when `enable_brotli` is true.
199   void SetAcceptEncodingIfMissing(
200       const GURL& url,
201       const std::optional<base::flat_set<SourceStream::SourceType>>&
202           accepted_stream_types,
203       bool enable_brotli,
204       bool enable_zstd);
205 
206  private:
207   HeaderVector::iterator FindHeader(std::string_view key);
208   HeaderVector::const_iterator FindHeader(std::string_view key) const;
209 
210   void SetHeaderInternal(std::string_view key, std::string&& value);
211 
212   HeaderVector headers_;
213 };
214 
215 }  // namespace net
216 
217 #endif  // NET_HTTP_HTTP_REQUEST_HEADERS_H_
218