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