// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/spdy/hpack_huffman_aggregator.h"

#include "base/metrics/bucket_ranges.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/metrics/sample_vector.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "net/base/load_flags.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_request_info.h"
#include "net/http/http_response_headers.h"
#include "net/spdy/hpack_encoder.h"
#include "net/spdy/spdy_http_utils.h"

namespace net {

namespace {

const char kHistogramName[] = "Net.SpdyHpackEncodedCharacterFrequency";

const size_t kTotalCountsPublishThreshold = 50000;

// Each encoder uses the default dynamic table size of 4096 total bytes.
const size_t kMaxEncoders = 20;

}  // namespace

HpackHuffmanAggregator::HpackHuffmanAggregator()
  : counts_(256, 0),
    total_counts_(0),
    max_encoders_(kMaxEncoders) {
}

HpackHuffmanAggregator::~HpackHuffmanAggregator() {
  STLDeleteContainerPairSecondPointers(encoders_.begin(), encoders_.end());
  encoders_.clear();
}

void HpackHuffmanAggregator::AggregateTransactionCharacterCounts(
    const HttpRequestInfo& request,
    const HttpRequestHeaders& request_headers,
    const ProxyServer& proxy,
    const HttpResponseHeaders& response_headers) {
  if (IsCrossOrigin(request)) {
    return;
  }
  HpackEncoder* encoder = ObtainEncoder(SpdySessionKey(
      HostPortPair::FromURL(request.url), proxy, request.privacy_mode));

  // Convert and encode the request and response header sets.
  {
    SpdyHeaderBlock headers;
    CreateSpdyHeadersFromHttpRequest(
        request, request_headers, SPDY4, false, &headers);

    std::string tmp_out;
    encoder->EncodeHeaderSet(headers, &tmp_out);
  }
  {
    SpdyHeaderBlock headers;
    CreateSpdyHeadersFromHttpResponse(response_headers, &headers);

    std::string tmp_out;
    encoder->EncodeHeaderSet(headers, &tmp_out);
  }
  if (total_counts_ >= kTotalCountsPublishThreshold) {
    PublishCounts();
  }
}

// static
bool HpackHuffmanAggregator::UseAggregator() {
  const std::string group_name =
      base::FieldTrialList::FindFullName("HpackHuffmanAggregator");
  if (group_name == "Enabled") {
    return true;
  }
  return false;
}

// static
void HpackHuffmanAggregator::CreateSpdyHeadersFromHttpResponse(
    const HttpResponseHeaders& headers,
    SpdyHeaderBlock* headers_out) {
  // Lower-case header names, and coalesce multiple values delimited by \0.
  // Also add the fixed status header.
  std::string name, value;
  void* it = NULL;
  while (headers.EnumerateHeaderLines(&it, &name, &value)) {
    base::StringToLowerASCII(&name);
    if (headers_out->find(name) == headers_out->end()) {
      (*headers_out)[name] = value;
    } else {
      (*headers_out)[name] += std::string(1, '\0') + value;
    }
  }
  (*headers_out)[":status"] = base::IntToString(headers.response_code());
}

// static
bool HpackHuffmanAggregator::IsCrossOrigin(const HttpRequestInfo& request) {
  // Require that the request is top-level, or that it shares
  // an origin with its referer.
  if ((request.load_flags & LOAD_MAIN_FRAME) == 0) {
    std::string referer_str;
    if (!request.extra_headers.GetHeader(HttpRequestHeaders::kReferer,
                                         &referer_str)) {
      // Require a referer.
      return true;
    }
    GURL referer(referer_str);
    if (!HostPortPair::FromURL(request.url).Equals(
        HostPortPair::FromURL(referer))) {
      // Cross-origin request.
      return true;
    }
  }
  return false;
}

HpackEncoder* HpackHuffmanAggregator::ObtainEncoder(const SpdySessionKey& key) {
  for (OriginEncoders::iterator it = encoders_.begin();
       it != encoders_.end(); ++it) {
    if (key.Equals(it->first)) {
      // Move to head of list and return.
      OriginEncoder origin_encoder = *it;
      encoders_.erase(it);
      encoders_.push_front(origin_encoder);
      return origin_encoder.second;
    }
  }
  // Not found. Create a new encoder, evicting one if needed.
  encoders_.push_front(std::make_pair(
      key, new HpackEncoder(ObtainHpackHuffmanTable())));
  if (encoders_.size() > max_encoders_) {
    delete encoders_.back().second;
    encoders_.pop_back();
  }
  encoders_.front().second->SetCharCountsStorage(&counts_, &total_counts_);
  return encoders_.front().second;
}

void HpackHuffmanAggregator::PublishCounts() {
  // base::Histogram requires that values be 1-indexed.
  const size_t kRangeMin = 1;
  const size_t kRangeMax = counts_.size() + 1;
  const size_t kBucketCount = kRangeMax + 1;

  base::BucketRanges ranges(kBucketCount + 1);
  for (size_t i = 0; i != ranges.size(); ++i) {
    ranges.set_range(i, i);
  }
  ranges.ResetChecksum();

  // Copy |counts_| into a SampleVector.
  base::SampleVector samples(&ranges);
  for (size_t i = 0; i != counts_.size(); ++i) {
    samples.Accumulate(i + 1, counts_[i]);
  }

  STATIC_HISTOGRAM_POINTER_BLOCK(
      kHistogramName,
      AddSamples(samples),
      base::LinearHistogram::FactoryGet(
          kHistogramName, kRangeMin, kRangeMax, kBucketCount,
          base::HistogramBase::kUmaTargetedHistogramFlag));

  // Clear counts.
  counts_.assign(counts_.size(), 0);
  total_counts_ = 0;
}

}  // namespace net
