1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NET_HTTP_HTTP_RESPONSE_HEADERS_H_ 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NET_HTTP_HTTP_RESPONSE_HEADERS_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string> 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <vector> 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/basictypes.h" 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/hash_tables.h" 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h" 152557749644f9d25af9721533322db19197c49b49Kristian Monsen#include "net/base/net_export.h" 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_version.h" 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass Pickle; 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace base { 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass Time; 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass TimeDelta; 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net { 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// HttpResponseHeaders: parses and holds HTTP response headers. 282557749644f9d25af9721533322db19197c49b49Kristian Monsenclass NET_EXPORT HttpResponseHeaders 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : public base::RefCountedThreadSafe<HttpResponseHeaders> { 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Persist options. 323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen typedef int PersistOptions; 333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen static const PersistOptions PERSIST_RAW = -1; // Raw, unparsed headers. 343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen static const PersistOptions PERSIST_ALL = 0; // Parsed headers. 353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen static const PersistOptions PERSIST_SANS_COOKIES = 1 << 0; 363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen static const PersistOptions PERSIST_SANS_CHALLENGES = 1 << 1; 373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen static const PersistOptions PERSIST_SANS_HOP_BY_HOP = 1 << 2; 383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen static const PersistOptions PERSIST_SANS_NON_CACHEABLE = 1 << 3; 393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen static const PersistOptions PERSIST_SANS_RANGES = 1 << 4; 403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Parses the given raw_headers. raw_headers should be formatted thus: 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // includes the http status response line, each line is \0-terminated, and 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // it's terminated by an empty line (ie, 2 \0s in a row). 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // (Note that line continuations should have already been joined; 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // see HttpUtil::AssembleRawHeaders) 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // NOTE: For now, raw_headers is not really 'raw' in that this constructor is 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // called with a 'NativeMB' string on Windows because WinHTTP does not allow 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // us to access the raw byte sequence as sent by a web server. In any case, 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // HttpResponseHeaders does not perform any encoding changes on the input. 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit HttpResponseHeaders(const std::string& raw_headers); 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Initializes from the representation stored in the given pickle. The data 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // for this object is found relative to the given pickle_iter, which should 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // be passed to the pickle's various Read* methods. 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpResponseHeaders(const Pickle& pickle, void** pickle_iter); 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Appends a representation of this object to the given pickle. 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The options argument can be a combination of PersistOptions. 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Persist(Pickle* pickle, PersistOptions options); 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Performs header merging as described in 13.5.3 of RFC 2616. 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Update(const HttpResponseHeaders& new_headers); 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Removes all instances of a particular header. 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void RemoveHeader(const std::string& name); 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Adds a particular header. |header| has to be a single header without any 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // EOL termination, just [<header-name>: <header-values>] 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If a header with the same name is already stored, the two headers are not 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // merged together by this method; the one provided is simply put at the 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // end of the list. 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void AddHeader(const std::string& header); 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Replaces the current status line with the provided one (|new_status| should 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // not have any EOL). 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void ReplaceStatusLine(const std::string& new_status); 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Creates a normalized header string. The output will be formatted exactly 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // like so: 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // HTTP/<version> <status_code> <status_text>\n 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // [<header-name>: <header-values>\n]* 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // meaning, each line is \n-terminated, and there is no extra whitespace 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // beyond the single space separators shown (of course, values can contain 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // whitespace within them). If a given header-name appears more than once 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // in the set of headers, they are combined into a single line like so: 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // <header-name>: <header-value1>, <header-value2>, ...<header-valueN>\n 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // DANGER: For some headers (e.g., "Set-Cookie"), the normalized form can be 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // a lossy format. This is due to the fact that some servers generate 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Set-Cookie headers that contain unquoted commas (usually as part of the 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // value of an "expires" attribute). So, use this function with caution. Do 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // not expect to be able to re-parse Set-Cookie headers from this output. 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // NOTE: Do not make any assumptions about the encoding of this output 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // string. It may be non-ASCII, and the encoding used by the server is not 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // necessarily known to us. Do not assume that this output is UTF-8! 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // TODO(darin): remove this method 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void GetNormalizedHeaders(std::string* output) const; 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Fetch the "normalized" value of a single header, where all values for the 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // header name are separated by commas. See the GetNormalizedHeaders for 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // format details. Returns false if this header wasn't found. 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // NOTE: Do not make any assumptions about the encoding of this output 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // string. It may be non-ASCII, and the encoding used by the server is not 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // necessarily known to us. Do not assume that this output is UTF-8! 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // TODO(darin): remove this method 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool GetNormalizedHeader(const std::string& name, std::string* value) const; 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns the normalized status line. For HTTP/0.9 responses (i.e., 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // responses that lack a status line), this is the manufactured string 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // "HTTP/0.9 200 OK". 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string GetStatusLine() const; 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Get the HTTP version of the normalized status line. 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpVersion GetHttpVersion() const { 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return http_version_; 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Get the HTTP version determined while parsing; or (0,0) if parsing failed 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpVersion GetParsedHttpVersion() const { 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return parsed_http_version_; 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Get the HTTP status text of the normalized status line. 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string GetStatusText() const; 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Enumerate the "lines" of the response headers. This skips over the status 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // line. Use GetStatusLine if you are interested in that. Note that this 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // method returns the un-coalesced response header lines, so if a response 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // header appears on multiple lines, then it will appear multiple times in 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // this enumeration (in the order the header lines were received from the 1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // server). Also, a given header might have an empty value. Initialize a 1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // 'void*' variable to NULL and pass it by address to EnumerateHeaderLines. 1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Call EnumerateHeaderLines repeatedly until it returns false. The 1423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // out-params 'name' and 'value' are set upon success. 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool EnumerateHeaderLines(void** iter, 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string* name, 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string* value) const; 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Enumerate the values of the specified header. If you are only interested 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // in the first header, then you can pass NULL for the 'iter' parameter. 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Otherwise, to iterate across all values for the specified header, 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // initialize a 'void*' variable to NULL and pass it by address to 1513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // EnumerateHeader. Note that a header might have an empty value. Call 1523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // EnumerateHeader repeatedly until it returns false. 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool EnumerateHeader(void** iter, 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string& name, 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string* value) const; 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true if the response contains the specified header-value pair. 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Both name and value are compared case insensitively. 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool HasHeaderValue(const std::string& name, const std::string& value) const; 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns true if the response contains the specified header. 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The name is compared case insensitively. 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool HasHeader(const std::string& name) const; 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Get the mime type and charset values in lower case form from the headers. 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Empty strings are returned if the values are not present. 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void GetMimeTypeAndCharset(std::string* mime_type, 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string* charset) const; 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Get the mime type in lower case from the headers. If there's no mime 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // type, returns false. 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool GetMimeType(std::string* mime_type) const; 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Get the charset in lower case from the headers. If there's no charset, 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // returns false. 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool GetCharset(std::string* charset) const; 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true if this response corresponds to a redirect. The target 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // location of the redirect is optionally returned if location is non-null. 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool IsRedirect(std::string* location) const; 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true if the HTTP response code passed in corresponds to a 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // redirect. 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static bool IsRedirectResponseCode(int response_code); 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true if the response cannot be reused without validation. The 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // result is relative to the current_time parameter, which is a parameter to 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // support unit testing. The request_time parameter indicates the time at 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // which the request was made that resulted in this response, which was 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // received at response_time. 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool RequiresValidation(const base::Time& request_time, 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const base::Time& response_time, 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const base::Time& current_time) const; 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns the amount of time the server claims the response is fresh from 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the time the response was generated. See section 13.2.4 of RFC 2616. See 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // RequiresValidation for a description of the response_time parameter. 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::TimeDelta GetFreshnessLifetime(const base::Time& response_time) const; 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns the age of the response. See section 13.2.3 of RFC 2616. 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // See RequiresValidation for a description of this method's parameters. 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::TimeDelta GetCurrentAge(const base::Time& request_time, 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const base::Time& response_time, 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const base::Time& current_time) const; 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The following methods extract values from the response headers. If a 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // value is not present, then false is returned. Otherwise, true is returned 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // and the out param is assigned to the corresponding value. 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool GetMaxAgeValue(base::TimeDelta* value) const; 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool GetAgeValue(base::TimeDelta* value) const; 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool GetDateValue(base::Time* value) const; 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool GetLastModifiedValue(base::Time* value) const; 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool GetExpiresValue(base::Time* value) const; 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Extracts the time value of a particular header. This method looks for the 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // first matching header value and parses its value as a HTTP-date. 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool GetTimeValuedHeader(const std::string& name, base::Time* result) const; 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Determines if this response indicates a keep-alive connection. 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool IsKeepAlive() const; 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true if this response has a strong etag or last-modified header. 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // See section 13.3.3 of RFC 2616. 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool HasStrongValidators() const; 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Extracts the value of the Content-Length header or returns -1 if there is 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // no such header in the response. 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 GetContentLength() const; 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Extracts the values in a Content-Range header and returns true if they are 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // valid for a 206 response; otherwise returns false. 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The following values will be outputted: 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |*first_byte_position| = inclusive position of the first byte of the range 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |*last_byte_position| = inclusive position of the last byte of the range 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |*instance_length| = size in bytes of the object requested 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If any of the above values is unknown, its value will be -1. 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool GetContentRange(int64* first_byte_position, 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64* last_byte_position, 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64* instance_length) const; 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns the HTTP response code. This is 0 if the response code text seems 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // to exist but could not be parsed. Otherwise, it defaults to 200 if the 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // response code is not found in the raw headers. 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int response_code() const { return response_code_; } 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns the raw header string. 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string& raw_headers() const { return raw_headers_; } 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott friend class base::RefCountedThreadSafe<HttpResponseHeaders>; 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef base::hash_set<std::string> HeaderSet; 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2543f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // The members of this structure point into raw_headers_. 25572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen struct ParsedHeader; 2563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen typedef std::vector<ParsedHeader> HeaderList; 2573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 2583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseHeaders(); 2593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ~HttpResponseHeaders(); 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Initializes from the given raw headers. 262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Parse(const std::string& raw_input); 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Helper function for ParseStatusLine. 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Tries to extract the "HTTP/X.Y" from a status line formatted like: 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // HTTP/1.1 200 OK 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // with line_begin and end pointing at the begin and end of this line. If the 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // status line is malformed, returns HttpVersion(0,0). 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static HttpVersion ParseVersion(std::string::const_iterator line_begin, 270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string::const_iterator line_end); 271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Tries to extract the status line from a header block, given the first 273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // line of said header block. If the status line is malformed, we'll 274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // construct a valid one. Example input: 275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // HTTP/1.1 200 OK 276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // with line_begin and end pointing at the begin and end of this line. 277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Output will be a normalized version of this, with a trailing \n. 278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void ParseStatusLine(std::string::const_iterator line_begin, 279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string::const_iterator line_end, 280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool has_headers); 281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Find the header in our list (case-insensitive) starting with parsed_ at 283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // index |from|. Returns string::npos if not found. 284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t FindHeader(size_t from, const std::string& name) const; 285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Add a header->value pair to our list. If we already have header in our 287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // list, append the value to it. 288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void AddHeader(std::string::const_iterator name_begin, 289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string::const_iterator name_end, 290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string::const_iterator value_begin, 291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string::const_iterator value_end); 292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Add to parsed_ given the fields of a ParsedHeader object. 294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void AddToParsed(std::string::const_iterator name_begin, 295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string::const_iterator name_end, 296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string::const_iterator value_begin, 297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string::const_iterator value_end); 298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Replaces the current headers with the merged version of |raw_headers| and 300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the current headers without the headers in |headers_to_remove|. Note that 301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |headers_to_remove| are removed from the current headers (before the 302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // merge), not after the merge. 303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void MergeWithHeaders(const std::string& raw_headers, 304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HeaderSet& headers_to_remove); 305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Adds the values from any 'cache-control: no-cache="foo,bar"' headers. 307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void AddNonCacheableHeaders(HeaderSet* header_names) const; 308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Adds the set of header names that contain cookie values. 310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static void AddSensitiveHeaders(HeaderSet* header_names); 311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Adds the set of rfc2616 hop-by-hop response headers. 313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static void AddHopByHopHeaders(HeaderSet* header_names); 314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Adds the set of challenge response headers. 316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static void AddChallengeHeaders(HeaderSet* header_names); 317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Adds the set of cookie response headers. 319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static void AddCookieHeaders(HeaderSet* header_names); 320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Adds the set of content range response headers. 322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static void AddHopContentRangeHeaders(HeaderSet* header_names); 323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We keep a list of ParsedHeader objects. These tell us where to locate the 325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // header-value pairs within raw_headers_. 326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HeaderList parsed_; 327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The raw_headers_ consists of the normalized status line (terminated with a 329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // null byte) and then followed by the raw null-terminated headers from the 330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // input that was passed to our constructor. We preserve the input [*] to 331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // maintain as much ancillary fidelity as possible (since it is sometimes 332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // hard to tell what may matter down-stream to a consumer of XMLHttpRequest). 333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // [*] The status line may be modified. 334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string raw_headers_; 335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This is the parsed HTTP response code. 337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int response_code_; 338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The normalized http version (consistent with what GetStatusLine() returns). 340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpVersion http_version_; 341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The parsed http version number (not normalized). 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpVersion parsed_http_version_; 344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(HttpResponseHeaders); 346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace net 349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // NET_HTTP_HTTP_RESPONSE_HEADERS_H_ 351