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