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 20 namespace net { 21 22 class 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