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)#include "net/http/http_request_headers.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h"
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h"
107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/stringprintf.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
1223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "net/http/http_log_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_util.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kGetMethod[] = "GET";
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kAcceptCharset[] = "Accept-Charset";
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kAcceptEncoding[] = "Accept-Encoding";
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kAcceptLanguage[] = "Accept-Language";
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kAuthorization[] = "Authorization";
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kCacheControl[] = "Cache-Control";
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kConnection[] = "Connection";
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kContentLength[] = "Content-Length";
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kContentType[] = "Content-Type";
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kCookie[] = "Cookie";
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kHost[] = "Host";
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kIfModifiedSince[] = "If-Modified-Since";
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kIfNoneMatch[] = "If-None-Match";
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kIfRange[] = "If-Range";
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kOrigin[] = "Origin";
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kPragma[] = "Pragma";
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kProxyAuthorization[] = "Proxy-Authorization";
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kProxyConnection[] = "Proxy-Connection";
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kRange[] = "Range";
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kReferer[] = "Referer";
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kUserAgent[] = "User-Agent";
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char HttpRequestHeaders::kTransferEncoding[] = "Transfer-Encoding";
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpRequestHeaders::HeaderKeyValuePair::HeaderKeyValuePair() {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpRequestHeaders::HeaderKeyValuePair::HeaderKeyValuePair(
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::StringPiece& key, const base::StringPiece& value)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : key(key.data(), key.size()), value(value.data(), value.size()) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpRequestHeaders::Iterator::Iterator(const HttpRequestHeaders& headers)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : started_(false),
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      curr_(headers.headers_.begin()),
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      end_(headers.headers_.end()) {}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpRequestHeaders::Iterator::~Iterator() {}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpRequestHeaders::Iterator::GetNext() {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!started_) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    started_ = true;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return curr_ != end_;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (curr_ == end_)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++curr_;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return curr_ != end_;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpRequestHeaders::HttpRequestHeaders() {}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpRequestHeaders::~HttpRequestHeaders() {}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpRequestHeaders::GetHeader(const base::StringPiece& key,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   std::string* out) const {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HeaderVector::const_iterator it = FindHeader(key);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it == headers_.end())
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out->assign(it->value);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpRequestHeaders::Clear() {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers_.clear();
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpRequestHeaders::SetHeader(const base::StringPiece& key,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const base::StringPiece& value) {
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(HttpUtil::IsValidHeaderName(key.as_string()));
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(HttpUtil::IsValidHeaderValue(value.as_string()));
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HeaderVector::iterator it = FindHeader(key);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it != headers_.end())
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    it->value.assign(value.data(), value.size());
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    headers_.push_back(HeaderKeyValuePair(key, value));
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpRequestHeaders::SetHeaderIfMissing(const base::StringPiece& key,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const base::StringPiece& value) {
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(HttpUtil::IsValidHeaderName(key.as_string()));
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(HttpUtil::IsValidHeaderValue(value.as_string()));
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HeaderVector::iterator it = FindHeader(key);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it == headers_.end())
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    headers_.push_back(HeaderKeyValuePair(key, value));
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpRequestHeaders::RemoveHeader(const base::StringPiece& key) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HeaderVector::iterator it = FindHeader(key);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it != headers_.end())
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers_.erase(it);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpRequestHeaders::AddHeaderFromString(
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::StringPiece& header_line) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(std::string::npos, header_line.find("\r\n"))
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << "\"" << header_line << "\" contains CRLF.";
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string::size_type key_end_index = header_line.find(":");
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (key_end_index == std::string::npos) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(DFATAL) << "\"" << header_line << "\" is missing colon delimiter.";
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (key_end_index == 0) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(DFATAL) << "\"" << header_line << "\" is missing header key.";
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::StringPiece header_key(header_line.data(), key_end_index);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string::size_type value_index = key_end_index + 1;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value_index < header_line.size()) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string header_value(header_line.data() + value_index,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             header_line.size() - value_index);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string::const_iterator header_value_begin =
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        header_value.begin();
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string::const_iterator header_value_end =
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        header_value.end();
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpUtil::TrimLWS(&header_value_begin, &header_value_end);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (header_value_begin == header_value_end) {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Value was all LWS.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetHeader(header_key, "");
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetHeader(header_key,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                base::StringPiece(&*header_value_begin,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  header_value_end - header_value_begin));
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (value_index == header_line.size()) {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetHeader(header_key, "");
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpRequestHeaders::AddHeadersFromString(
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::StringPiece& headers) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(willchan): Consider adding more StringPiece support in string_util.h
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to eliminate copies.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> header_line_vector;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::SplitStringUsingSubstr(headers.as_string(), "\r\n",
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &header_line_vector);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<std::string>::const_iterator it = header_line_vector.begin();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != header_line_vector.end(); ++it) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!it->empty())
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AddHeaderFromString(*it);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpRequestHeaders::MergeFrom(const HttpRequestHeaders& other) {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (HeaderVector::const_iterator it = other.headers_.begin();
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != other.headers_.end(); ++it ) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetHeader(it->key, it->value);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string HttpRequestHeaders::ToString() const {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string output;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (HeaderVector::const_iterator it = headers_.begin();
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != headers_.end(); ++it) {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!it->value.empty()) {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::StringAppendF(&output, "%s: %s\r\n",
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          it->key.c_str(), it->value.c_str());
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::StringAppendF(&output, "%s:\r\n", it->key.c_str());
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  output.append("\r\n");
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return output;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)base::Value* HttpRequestHeaders::NetLogCallback(
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string* request_line,
19323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    NetLog::LogLevel log_level) const {
1947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::DictionaryValue* dict = new base::DictionaryValue();
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dict->SetString("line", *request_line);
1967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::ListValue* headers = new base::ListValue();
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (HeaderVector::const_iterator it = headers_.begin();
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != headers_.end(); ++it) {
19923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    std::string log_value = ElideHeaderValueForNetLog(
20023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        log_level, it->key, it->value);
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    headers->Append(new base::StringValue(
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::StringPrintf("%s: %s",
20323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                           it->key.c_str(), log_value.c_str())));
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dict->Set("headers", headers);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return dict;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpRequestHeaders::FromNetLogParam(const base::Value* event_param,
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         HttpRequestHeaders* headers,
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         std::string* request_line) {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers->Clear();
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *request_line = "";
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::DictionaryValue* dict = NULL;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::ListValue* header_list = NULL;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!event_param ||
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !event_param->GetAsDictionary(&dict) ||
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !dict->GetList("headers", &header_list) ||
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !dict->GetString("line", request_line)) {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (base::ListValue::const_iterator it = header_list->begin();
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != header_list->end();
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++it) {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string header_line;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!(*it)->GetAsString(&header_line)) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      headers->Clear();
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *request_line = "";
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers->AddHeaderFromString(header_line);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpRequestHeaders::HeaderVector::iterator
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpRequestHeaders::FindHeader(const base::StringPiece& key) {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (HeaderVector::iterator it = headers_.begin();
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != headers_.end(); ++it) {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (key.length() == it->key.length() &&
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !base::strncasecmp(key.data(), it->key.data(), key.length()))
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return it;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return headers_.end();
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpRequestHeaders::HeaderVector::const_iterator
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpRequestHeaders::FindHeader(const base::StringPiece& key) const {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (HeaderVector::const_iterator it = headers_.begin();
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != headers_.end(); ++it) {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (key.length() == it->key.length() &&
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !base::strncasecmp(key.data(), it->key.data(), key.length()))
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return it;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return headers_.end();
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
265