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