15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NET_HTTP_HTTP_RESPONSE_HEADERS_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_HTTP_HTTP_RESPONSE_HEADERS_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/containers/hash_tables.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/strings/string_piece.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_export.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_version.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Pickle; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PickleIterator; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Time; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TimeDelta; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HttpResponseHeaders: parses and holds HTTP response headers. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT HttpResponseHeaders 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public base::RefCountedThreadSafe<HttpResponseHeaders> { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Persist options. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef int PersistOptions; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const PersistOptions PERSIST_RAW = -1; // Raw, unparsed headers. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const PersistOptions PERSIST_ALL = 0; // Parsed headers. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const PersistOptions PERSIST_SANS_COOKIES = 1 << 0; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const PersistOptions PERSIST_SANS_CHALLENGES = 1 << 1; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const PersistOptions PERSIST_SANS_HOP_BY_HOP = 1 << 2; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const PersistOptions PERSIST_SANS_NON_CACHEABLE = 1 << 3; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const PersistOptions PERSIST_SANS_RANGES = 1 << 4; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const PersistOptions PERSIST_SANS_SECURITY_STATE = 1 << 5; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parses the given raw_headers. raw_headers should be formatted thus: 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // includes the http status response line, each line is \0-terminated, and 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it's terminated by an empty line (ie, 2 \0s in a row). 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (Note that line continuations should have already been joined; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // see HttpUtil::AssembleRawHeaders) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // HttpResponseHeaders does not perform any encoding changes on the input. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit HttpResponseHeaders(const std::string& raw_headers); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes from the representation stored in the given pickle. The data 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for this object is found relative to the given pickle_iter, which should 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be passed to the pickle's various Read* methods. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpResponseHeaders(const Pickle& pickle, PickleIterator* pickle_iter); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Appends a representation of this object to the given pickle. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The options argument can be a combination of PersistOptions. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Persist(Pickle* pickle, PersistOptions options); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Performs header merging as described in 13.5.3 of RFC 2616. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Update(const HttpResponseHeaders& new_headers); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Removes all instances of a particular header. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RemoveHeader(const std::string& name); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Removes a particular header line. The header name is compared 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // case-insensitively. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RemoveHeaderLine(const std::string& name, const std::string& value); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds a particular header. |header| has to be a single header without any 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // EOL termination, just [<header-name>: <header-values>] 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If a header with the same name is already stored, the two headers are not 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // merged together by this method; the one provided is simply put at the 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // end of the list. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddHeader(const std::string& header); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Replaces the current status line with the provided one (|new_status| should 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not have any EOL). 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReplaceStatusLine(const std::string& new_status); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a normalized header string. The output will be formatted exactly 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // like so: 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // HTTP/<version> <status_code> <status_text>\n 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // [<header-name>: <header-values>\n]* 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // meaning, each line is \n-terminated, and there is no extra whitespace 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // beyond the single space separators shown (of course, values can contain 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // whitespace within them). If a given header-name appears more than once 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the set of headers, they are combined into a single line like so: 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // <header-name>: <header-value1>, <header-value2>, ...<header-valueN>\n 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DANGER: For some headers (e.g., "Set-Cookie"), the normalized form can be 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a lossy format. This is due to the fact that some servers generate 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set-Cookie headers that contain unquoted commas (usually as part of the 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // value of an "expires" attribute). So, use this function with caution. Do 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not expect to be able to re-parse Set-Cookie headers from this output. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: Do not make any assumptions about the encoding of this output 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // string. It may be non-ASCII, and the encoding used by the server is not 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // necessarily known to us. Do not assume that this output is UTF-8! 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(darin): remove this method 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void GetNormalizedHeaders(std::string* output) const; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fetch the "normalized" value of a single header, where all values for the 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // header name are separated by commas. See the GetNormalizedHeaders for 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // format details. Returns false if this header wasn't found. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: Do not make any assumptions about the encoding of this output 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // string. It may be non-ASCII, and the encoding used by the server is not 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // necessarily known to us. Do not assume that this output is UTF-8! 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(darin): remove this method 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetNormalizedHeader(const std::string& name, std::string* value) const; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the normalized status line. For HTTP/0.9 responses (i.e., 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // responses that lack a status line), this is the manufactured string 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "HTTP/0.9 200 OK". 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string GetStatusLine() const; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the HTTP version of the normalized status line. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpVersion GetHttpVersion() const { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return http_version_; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the HTTP version determined while parsing; or (0,0) if parsing failed 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpVersion GetParsedHttpVersion() const { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return parsed_http_version_; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the HTTP status text of the normalized status line. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string GetStatusText() const; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enumerate the "lines" of the response headers. This skips over the status 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // line. Use GetStatusLine if you are interested in that. Note that this 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // method returns the un-coalesced response header lines, so if a response 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // header appears on multiple lines, then it will appear multiple times in 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this enumeration (in the order the header lines were received from the 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // server). Also, a given header might have an empty value. Initialize a 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 'void*' variable to NULL and pass it by address to EnumerateHeaderLines. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Call EnumerateHeaderLines repeatedly until it returns false. The 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // out-params 'name' and 'value' are set upon success. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool EnumerateHeaderLines(void** iter, 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* name, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* value) const; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enumerate the values of the specified header. If you are only interested 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the first header, then you can pass NULL for the 'iter' parameter. 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise, to iterate across all values for the specified header, 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initialize a 'void*' variable to NULL and pass it by address to 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // EnumerateHeader. Note that a header might have an empty value. Call 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // EnumerateHeader repeatedly until it returns false. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool EnumerateHeader(void** iter, 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::StringPiece& name, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* value) const; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the response contains the specified header-value pair. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Both name and value are compared case insensitively. 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool HasHeaderValue(const base::StringPiece& name, 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::StringPiece& value) const; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the response contains the specified header. 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The name is compared case insensitively. 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool HasHeader(const base::StringPiece& name) const; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the mime type and charset values in lower case form from the headers. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Empty strings are returned if the values are not present. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void GetMimeTypeAndCharset(std::string* mime_type, 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* charset) const; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the mime type in lower case from the headers. If there's no mime 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // type, returns false. 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetMimeType(std::string* mime_type) const; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the charset in lower case from the headers. If there's no charset, 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returns false. 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetCharset(std::string* charset) const; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if this response corresponds to a redirect. The target 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // location of the redirect is optionally returned if location is non-null. 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsRedirect(std::string* location) const; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the HTTP response code passed in corresponds to a 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // redirect. 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool IsRedirectResponseCode(int response_code); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the response cannot be reused without validation. The 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // result is relative to the current_time parameter, which is a parameter to 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // support unit testing. The request_time parameter indicates the time at 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which the request was made that resulted in this response, which was 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // received at response_time. 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool RequiresValidation(const base::Time& request_time, 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Time& response_time, 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Time& current_time) const; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the amount of time the server claims the response is fresh from 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the time the response was generated. See section 13.2.4 of RFC 2616. See 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RequiresValidation for a description of the response_time parameter. 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta GetFreshnessLifetime(const base::Time& response_time) const; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the age of the response. See section 13.2.3 of RFC 2616. 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See RequiresValidation for a description of this method's parameters. 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta GetCurrentAge(const base::Time& request_time, 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Time& response_time, 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Time& current_time) const; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The following methods extract values from the response headers. If a 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // value is not present, then false is returned. Otherwise, true is returned 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and the out param is assigned to the corresponding value. 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetMaxAgeValue(base::TimeDelta* value) const; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetAgeValue(base::TimeDelta* value) const; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetDateValue(base::Time* value) const; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetLastModifiedValue(base::Time* value) const; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetExpiresValue(base::Time* value) const; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extracts the time value of a particular header. This method looks for the 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // first matching header value and parses its value as a HTTP-date. 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetTimeValuedHeader(const std::string& name, base::Time* result) const; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Determines if this response indicates a keep-alive connection. 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsKeepAlive() const; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if this response has a strong etag or last-modified header. 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See section 13.3.3 of RFC 2616. 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HasStrongValidators() const; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extracts the value of the Content-Length header or returns -1 if there is 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // no such header in the response. 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 GetContentLength() const; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extracts the value of the specified header or returns -1 if there is no 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // such header in the response. 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 GetInt64HeaderValue(const std::string& header) const; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extracts the values in a Content-Range header and returns true if they are 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // valid for a 206 response; otherwise returns false. 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The following values will be outputted: 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |*first_byte_position| = inclusive position of the first byte of the range 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |*last_byte_position| = inclusive position of the last byte of the range 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |*instance_length| = size in bytes of the object requested 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If any of the above values is unknown, its value will be -1. 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetContentRange(int64* first_byte_position, 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64* last_byte_position, 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64* instance_length) const; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the response is chunk-encoded. 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsChunkEncoded() const; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a Value for use with the NetLog containing the response headers. 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Value* NetLogCallback(NetLog::LogLevel log_level) const; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Takes in a Value created by the above function, and attempts to create a 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // copy of the original headers. Returns true on success. On failure, 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // clears |http_response_headers|. 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mmenke): Long term, we want to remove this, and migrate external 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // consumers to be NetworkDelegates. 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool FromNetLogParam( 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Value* event_param, 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<HttpResponseHeaders>* http_response_headers); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the HTTP response code. This is 0 if the response code text seems 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to exist but could not be parsed. Otherwise, it defaults to 200 if the 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // response code is not found in the raw headers. 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int response_code() const { return response_code_; } 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the raw header string. 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& raw_headers() const { return raw_headers_; } 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCountedThreadSafe<HttpResponseHeaders>; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef base::hash_set<std::string> HeaderSet; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The members of this structure point into raw_headers_. 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ParsedHeader; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::vector<ParsedHeader> HeaderList; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpResponseHeaders(); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~HttpResponseHeaders(); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes from the given raw headers. 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Parse(const std::string& raw_input); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper function for ParseStatusLine. 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tries to extract the "HTTP/X.Y" from a status line formatted like: 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // HTTP/1.1 200 OK 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with line_begin and end pointing at the begin and end of this line. If the 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // status line is malformed, returns HttpVersion(0,0). 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static HttpVersion ParseVersion(std::string::const_iterator line_begin, 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator line_end); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tries to extract the status line from a header block, given the first 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // line of said header block. If the status line is malformed, we'll 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // construct a valid one. Example input: 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // HTTP/1.1 200 OK 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with line_begin and end pointing at the begin and end of this line. 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Output will be a normalized version of this. 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ParseStatusLine(std::string::const_iterator line_begin, 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator line_end, 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_headers); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the header in our list (case-insensitive) starting with parsed_ at 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // index |from|. Returns string::npos if not found. 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t FindHeader(size_t from, const base::StringPiece& name) const; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add a header->value pair to our list. If we already have header in our 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // list, append the value to it. 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddHeader(std::string::const_iterator name_begin, 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator name_end, 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator value_begin, 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator value_end); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add to parsed_ given the fields of a ParsedHeader object. 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddToParsed(std::string::const_iterator name_begin, 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator name_end, 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator value_begin, 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator value_end); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Replaces the current headers with the merged version of |raw_headers| and 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the current headers without the headers in |headers_to_remove|. Note that 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |headers_to_remove| are removed from the current headers (before the 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // merge), not after the merge. 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void MergeWithHeaders(const std::string& raw_headers, 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderSet& headers_to_remove); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds the values from any 'cache-control: no-cache="foo,bar"' headers. 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddNonCacheableHeaders(HeaderSet* header_names) const; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds the set of header names that contain cookie values. 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void AddSensitiveHeaders(HeaderSet* header_names); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds the set of rfc2616 hop-by-hop response headers. 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void AddHopByHopHeaders(HeaderSet* header_names); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds the set of challenge response headers. 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void AddChallengeHeaders(HeaderSet* header_names); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds the set of cookie response headers. 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void AddCookieHeaders(HeaderSet* header_names); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds the set of content range response headers. 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void AddHopContentRangeHeaders(HeaderSet* header_names); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds the set of transport security state headers. 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void AddSecurityStateHeaders(HeaderSet* header_names); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We keep a list of ParsedHeader objects. These tell us where to locate the 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // header-value pairs within raw_headers_. 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeaderList parsed_; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The raw_headers_ consists of the normalized status line (terminated with a 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // null byte) and then followed by the raw null-terminated headers from the 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // input that was passed to our constructor. We preserve the input [*] to 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // maintain as much ancillary fidelity as possible (since it is sometimes 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // hard to tell what may matter down-stream to a consumer of XMLHttpRequest). 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // [*] The status line may be modified. 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string raw_headers_; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the parsed HTTP response code. 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int response_code_; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The normalized http version (consistent with what GetStatusLine() returns). 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpVersion http_version_; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The parsed http version number (not normalized). 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpVersion parsed_http_version_; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(HttpResponseHeaders); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // NET_HTTP_HTTP_RESPONSE_HEADERS_H_ 378