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 <string> 14 #include <vector> 15 16 #include "base/basictypes.h" 17 #include "base/strings/string_piece.h" 18 #include "net/base/net_export.h" 19 #include "net/base/net_log.h" 20 21 namespace net { 22 23 class NET_EXPORT HttpRequestHeaders { 24 public: 25 struct HeaderKeyValuePair { 26 HeaderKeyValuePair(); 27 HeaderKeyValuePair(const base::StringPiece& key, 28 const base::StringPiece& value); 29 30 std::string key; 31 std::string value; 32 }; 33 34 typedef std::vector<HeaderKeyValuePair> HeaderVector; 35 36 class NET_EXPORT Iterator { 37 public: 38 explicit Iterator(const HttpRequestHeaders& headers); 39 ~Iterator(); 40 41 // Advances the iterator to the next header, if any. Returns true if there 42 // is a next header. Use name() and value() methods to access the resultant 43 // header name and value. 44 bool GetNext(); 45 46 // These two accessors are only valid if GetNext() returned true. 47 const std::string& name() const { return curr_->key; } 48 const std::string& value() const { return curr_->value; } 49 50 private: 51 bool started_; 52 HttpRequestHeaders::HeaderVector::const_iterator curr_; 53 const HttpRequestHeaders::HeaderVector::const_iterator end_; 54 55 DISALLOW_COPY_AND_ASSIGN(Iterator); 56 }; 57 58 static const char kGetMethod[]; 59 60 static const char kAcceptCharset[]; 61 static const char kAcceptEncoding[]; 62 static const char kAcceptLanguage[]; 63 static const char kAuthorization[]; 64 static const char kCacheControl[]; 65 static const char kConnection[]; 66 static const char kContentType[]; 67 static const char kCookie[]; 68 static const char kContentLength[]; 69 static const char kHost[]; 70 static const char kIfModifiedSince[]; 71 static const char kIfNoneMatch[]; 72 static const char kIfRange[]; 73 static const char kOrigin[]; 74 static const char kPragma[]; 75 static const char kProxyAuthorization[]; 76 static const char kProxyConnection[]; 77 static const char kRange[]; 78 static const char kReferer[]; 79 static const char kUserAgent[]; 80 static const char kTransferEncoding[]; 81 82 HttpRequestHeaders(); 83 ~HttpRequestHeaders(); 84 85 bool IsEmpty() const { return headers_.empty(); } 86 87 bool HasHeader(const base::StringPiece& key) const { 88 return FindHeader(key) != headers_.end(); 89 } 90 91 // Gets the first header that matches |key|. If found, returns true and 92 // writes the value to |out|. 93 bool GetHeader(const base::StringPiece& key, std::string* out) const; 94 95 // Clears all the headers. 96 void Clear(); 97 98 // Sets the header value pair for |key| and |value|. If |key| already exists, 99 // then the header value is modified, but the key is untouched, and the order 100 // in the vector remains the same. When comparing |key|, case is ignored. 101 void SetHeader(const base::StringPiece& key, const base::StringPiece& value); 102 103 // Sets the header value pair for |key| and |value|, if |key| does not exist. 104 // If |key| already exists, the call is a no-op. 105 // When comparing |key|, case is ignored. 106 void SetHeaderIfMissing(const base::StringPiece& key, 107 const base::StringPiece& value); 108 109 // Removes the first header that matches (case insensitive) |key|. 110 void RemoveHeader(const base::StringPiece& key); 111 112 // Parses the header from a string and calls SetHeader() with it. This string 113 // should not contain any CRLF. As per RFC2616, the format is: 114 // 115 // message-header = field-name ":" [ field-value ] 116 // field-name = token 117 // field-value = *( field-content | LWS ) 118 // field-content = <the OCTETs making up the field-value 119 // and consisting of either *TEXT or combinations 120 // of token, separators, and quoted-string> 121 // 122 // AddHeaderFromString() will trim any LWS surrounding the 123 // field-content. 124 void AddHeaderFromString(const base::StringPiece& header_line); 125 126 // Same thing as AddHeaderFromString() except that |headers| is a "\r\n" 127 // delimited string of header lines. It will split up the string by "\r\n" 128 // and call AddHeaderFromString() on each. 129 void AddHeadersFromString(const base::StringPiece& headers); 130 131 // Calls SetHeader() on each header from |other|, maintaining order. 132 void MergeFrom(const HttpRequestHeaders& other); 133 134 // Copies from |other| to |this|. 135 void CopyFrom(const HttpRequestHeaders& other) { 136 *this = other; 137 } 138 139 void Swap(HttpRequestHeaders* other) { 140 headers_.swap(other->headers_); 141 } 142 143 // Serializes HttpRequestHeaders to a string representation. Joins all the 144 // header keys and values with ": ", and inserts "\r\n" between each header 145 // line, and adds the trailing "\r\n". 146 std::string ToString() const; 147 148 // Takes in the request line and returns a Value for use with the NetLog 149 // containing both the request line and all headers fields. 150 base::Value* NetLogCallback(const std::string* request_line, 151 NetLog::LogLevel log_level) const; 152 153 // Takes in a Value created by the above function, and attempts to extract the 154 // request line and create a copy of the original headers. Returns true on 155 // success. On failure, clears |headers| and |request_line|. 156 // TODO(mmenke): Long term, we want to remove this, and migrate external 157 // consumers to be NetworkDelegates. 158 static bool FromNetLogParam(const base::Value* event_param, 159 HttpRequestHeaders* headers, 160 std::string* request_line); 161 162 private: 163 HeaderVector::iterator FindHeader(const base::StringPiece& key); 164 HeaderVector::const_iterator FindHeader(const base::StringPiece& key) const; 165 166 HeaderVector headers_; 167 168 // Allow the copy construction and operator= to facilitate copying in 169 // HttpRequestHeaders. 170 // TODO(willchan): Investigate to see if we can remove the need to copy 171 // HttpRequestHeaders. 172 // DISALLOW_COPY_AND_ASSIGN(HttpRequestHeaders); 173 }; 174 175 } // namespace net 176 177 #endif // NET_HTTP_HTTP_REQUEST_HEADERS_H_ 178