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