// 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/filter/sdch_filter.h"

#include <ctype.h>
#include <limits.h>
#include <algorithm>
#include <utility>

#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/values.h"
#include "net/base/sdch_manager.h"
#include "net/base/sdch_net_log_params.h"
#include "net/base/sdch_problem_codes.h"
#include "net/log/net_log_capture_mode.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_with_source.h"
#include "net/url_request/url_request_context.h"
#include "sdch/open-vcdiff/src/google/vcdecoder.h"

namespace net {

namespace {

const size_t kServerIdLength = 9;  // Dictionary hash plus null from server.

// Disambiguate various types of responses that trigger a meta-refresh,
// failure, or fallback to pass-through.
enum ResponseCorruptionDetectionCause {
  RESPONSE_NONE,

  // 404 Http Response Code
  RESPONSE_404 = 1,

  // Not a 200 Http Response Code
  RESPONSE_NOT_200 = 2,

  // Cached before dictionary retrieved.
  RESPONSE_OLD_UNENCODED = 3,

  // Speculative but incorrect SDCH filtering was added added.
  RESPONSE_TENTATIVE_SDCH = 4,

  // Missing correct dict for decoding.
  RESPONSE_NO_DICTIONARY = 5,

  // Not an SDCH response but should be.
  RESPONSE_CORRUPT_SDCH = 6,

  // No dictionary was advertised with the request, the server claims
  // to have encoded with SDCH anyway, but it isn't an SDCH response.
  RESPONSE_ENCODING_LIE = 7,

  RESPONSE_MAX,
};

const char* ResponseCorruptionDetectionCauseToString(
    ResponseCorruptionDetectionCause cause) {
  const char* cause_string = "<unknown>";
  switch (cause) {
    case RESPONSE_NONE:
      cause_string = "NONE";
      break;
    case RESPONSE_404:
      cause_string = "404";
      break;
    case RESPONSE_NOT_200:
      cause_string = "NOT_200";
      break;
    case RESPONSE_OLD_UNENCODED:
      cause_string = "OLD_UNENCODED";
      break;
    case RESPONSE_TENTATIVE_SDCH:
      cause_string = "TENTATIVE_SDCH";
      break;
    case RESPONSE_NO_DICTIONARY:
      cause_string = "NO_DICTIONARY";
      break;
    case RESPONSE_CORRUPT_SDCH:
      cause_string = "CORRUPT_SDCH";
      break;
    case RESPONSE_ENCODING_LIE:
      cause_string = "ENCODING_LIE";
      break;
    case RESPONSE_MAX:
      cause_string = "<Error: max enum value>";
      break;
  }
  return cause_string;
}

std::unique_ptr<base::Value> NetLogSdchResponseCorruptionDetectionCallback(
    ResponseCorruptionDetectionCause cause,
    bool cached,
    NetLogCaptureMode capture_mode) {
  std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
  dict->SetString("cause", ResponseCorruptionDetectionCauseToString(cause));
  dict->SetBoolean("cached", cached);
  return std::move(dict);
}

}  // namespace

SdchFilter::SdchFilter(FilterType type, const FilterContext& filter_context)
    : Filter(type),
      filter_context_(filter_context),
      decoding_status_(DECODING_UNINITIALIZED),
      dictionary_hash_(),
      dictionary_hash_is_plausible_(false),
      url_request_context_(filter_context.GetURLRequestContext()),
      dest_buffer_excess_(),
      dest_buffer_excess_index_(0),
      source_bytes_(0),
      output_bytes_(0),
      possible_pass_through_(false) {
  bool success = filter_context.GetMimeType(&mime_type_);
  DCHECK(success);
  success = filter_context.GetURL(&url_);
  DCHECK(success);
  DCHECK(url_request_context_->sdch_manager());
}

SdchFilter::~SdchFilter() {
  // All code here is for gathering stats, and can be removed when SDCH is
  // considered stable.

  // References to filter_context_ and vcdiff_streaming_decoder_ (which
  // contains a reference to the dictionary text) are safe because
  // ~URLRequestHttpJob calls URLRequestJob::DestroyFilters, destroying
  // this object before the filter context in URLRequestHttpJob and its
  // members go out of scope.

  static int filter_use_count = 0;
  ++filter_use_count;
  if (META_REFRESH_RECOVERY == decoding_status_) {
    UMA_HISTOGRAM_COUNTS("Sdch3.FilterUseBeforeDisabling", filter_use_count);
  }

  if (vcdiff_streaming_decoder_.get()) {
    if (!vcdiff_streaming_decoder_->FinishDecoding()) {
      decoding_status_ = DECODING_ERROR;
      LogSdchProblem(SDCH_INCOMPLETE_SDCH_CONTENT);
      // Make it possible for the user to hit reload, and get non-sdch content.
      // Note this will "wear off" quickly enough, and is just meant to assure
      // in some rare case that the user is not stuck.
      url_request_context_->sdch_manager()->BlacklistDomain(
          url_, SDCH_INCOMPLETE_SDCH_CONTENT);
      UMA_HISTOGRAM_COUNTS("Sdch3.PartialBytesIn",
           static_cast<int>(filter_context_.GetByteReadCount()));
      UMA_HISTOGRAM_COUNTS("Sdch3.PartialVcdiffIn", source_bytes_);
      UMA_HISTOGRAM_COUNTS("Sdch3.PartialVcdiffOut", output_bytes_);
    }
  }

  if (!dest_buffer_excess_.empty()) {
    // Filter chaining error, or premature teardown.
    LogSdchProblem(SDCH_UNFLUSHED_CONTENT);
    UMA_HISTOGRAM_COUNTS("Sdch3.UnflushedBytesIn",
         static_cast<int>(filter_context_.GetByteReadCount()));
    UMA_HISTOGRAM_COUNTS("Sdch3.UnflushedBufferSize",
                         dest_buffer_excess_.size());
    UMA_HISTOGRAM_COUNTS("Sdch3.UnflushedVcdiffIn", source_bytes_);
    UMA_HISTOGRAM_COUNTS("Sdch3.UnflushedVcdiffOut", output_bytes_);
  }

  if (filter_context_.IsCachedContent()) {
    // Not a real error, but it is useful to have this tally.
    // TODO(jar): Remove this stat after SDCH stability is validated.
    LogSdchProblem(SDCH_CACHE_DECODED);
    return;  // We don't need timing stats, and we aready got ratios.
  }

  switch (decoding_status_) {
    case DECODING_IN_PROGRESS: {
      if (output_bytes_) {
        UMA_HISTOGRAM_PERCENTAGE("Sdch3.Network_Decode_Ratio_a",
            static_cast<int>(
                (filter_context_.GetByteReadCount() * 100) / output_bytes_));
        UMA_HISTOGRAM_COUNTS("Sdch3.NetworkBytesSavedByCompression",
            output_bytes_ - source_bytes_);
      }
      UMA_HISTOGRAM_COUNTS("Sdch3.Network_Decode_Bytes_VcdiffOut_a",
                           output_bytes_);
      filter_context_.RecordPacketStats(FilterContext::SDCH_DECODE);

      // Allow latency experiments to proceed.
      url_request_context_->sdch_manager()->SetAllowLatencyExperiment(
          url_, true);

      // Notify successful dictionary usage.
      url_request_context_->sdch_manager()->OnDictionaryUsed(
          std::string(dictionary_hash_, 0, kServerIdLength - 1));

      return;
    }
    case PASS_THROUGH: {
      filter_context_.RecordPacketStats(FilterContext::SDCH_PASSTHROUGH);
      return;
    }
    case DECODING_UNINITIALIZED: {
      LogSdchProblem(SDCH_UNINITIALIZED);
      return;
    }
    case WAITING_FOR_DICTIONARY_SELECTION: {
      LogSdchProblem(SDCH_PRIOR_TO_DICTIONARY);
      return;
    }
    case DECODING_ERROR: {
      LogSdchProblem(SDCH_DECODE_ERROR);
      return;
    }
    case META_REFRESH_RECOVERY: {
      // Already accounted for when set.
      return;
    }
  }  // end of switch.
}

bool SdchFilter::InitDecoding(Filter::FilterType filter_type) {
  if (decoding_status_ != DECODING_UNINITIALIZED)
    return false;

  // Handle case  where sdch filter is guessed, but not required.
  if (FILTER_TYPE_SDCH_POSSIBLE == filter_type)
    possible_pass_through_ = true;

  // Initialize decoder only after we have a dictionary in hand.
  decoding_status_ = WAITING_FOR_DICTIONARY_SELECTION;
  return true;
}

#ifndef NDEBUG
static const char* kDecompressionErrorHtml =
  "<head><META HTTP-EQUIV=\"Refresh\" CONTENT=\"0\"></head>"
  "<div style=\"position:fixed;top:0;left:0;width:100%;border-width:thin;"
  "border-color:black;border-style:solid;text-align:left;font-family:arial;"
  "font-size:10pt;foreground-color:black;background-color:white\">"
  "An error occurred. This page will be reloaded shortly. "
  "Or press the \"reload\" button now to reload it immediately."
  "</div>";
#else
static const char* kDecompressionErrorHtml =
  "<head><META HTTP-EQUIV=\"Refresh\" CONTENT=\"0\"></head>";
#endif

Filter::FilterStatus SdchFilter::ReadFilteredData(char* dest_buffer,
                                                  int* dest_len) {
  int available_space = *dest_len;
  *dest_len = 0;  // Nothing output yet.

  if (!dest_buffer || available_space <= 0)
    return FILTER_ERROR;

  if (WAITING_FOR_DICTIONARY_SELECTION == decoding_status_) {
    FilterStatus status = InitializeDictionary();
    if (FILTER_NEED_MORE_DATA == status)
      return FILTER_NEED_MORE_DATA;
    if (FILTER_ERROR == status) {
      DCHECK_EQ(DECODING_ERROR, decoding_status_);
      DCHECK_EQ(0u, dest_buffer_excess_index_);
      DCHECK(dest_buffer_excess_.empty());
      // This is where we try very hard to do error recovery, and make this
      // protocol robust in the face of proxies that do many different things.
      // If we decide that things are looking very bad (too hard to recover),
      // we may even issue a "meta-refresh" to reload the page without an SDCH
      // advertisement (so that we are sure we're not hurting anything).
      //
      // Watch out for an error page inserted by the proxy as part of a 40x
      // error response. When we see such content molestation, we certainly
      // need to fall into the meta-refresh case.
      ResponseCorruptionDetectionCause cause = RESPONSE_NONE;
      if (filter_context_.GetResponseCode() == 404) {
        // We could be more generous, but for now, only a "NOT FOUND" code will
        // cause a pass through. All other bad codes will fall into a
        // meta-refresh.
        LogSdchProblem(SDCH_PASS_THROUGH_404_CODE);
        cause = RESPONSE_404;
        decoding_status_ = PASS_THROUGH;
      } else if (filter_context_.GetResponseCode() != 200) {
        // We need to meta-refresh, with SDCH disabled.
        cause = RESPONSE_NOT_200;
      } else if (filter_context_.IsCachedContent()
                 && !dictionary_hash_is_plausible_) {
        // We must have hit the back button, and gotten content that was fetched
        // before we *really* advertised SDCH and a dictionary.
        LogSdchProblem(SDCH_PASS_THROUGH_OLD_CACHED);
        decoding_status_ = PASS_THROUGH;
        cause = RESPONSE_OLD_UNENCODED;
      } else if (possible_pass_through_) {
        // This is the potentially most graceful response. There really was no
        // error. We were just overly cautious when we added a TENTATIVE_SDCH.
        // We added the sdch coding tag, and it should not have been added.
        // This can happen in server experiments, where the server decides
        // not to use sdch, even though there is a dictionary. To be
        // conservative, we locally added the tentative sdch (fearing that a
        // proxy stripped it!) and we must now recant (pass through).
        //
        // However.... just to be sure we don't get burned by proxies that
        // re-compress with gzip or other system, we can sniff to see if this
        // is compressed data etc. For now, we do nothing, which gets us into
        // the meta-refresh result.
        // TODO(jar): Improve robustness by sniffing for valid text that we can
        // actual use re: decoding_status_ = PASS_THROUGH;
        cause = RESPONSE_TENTATIVE_SDCH;
      } else if (dictionary_hash_is_plausible_) {
        // We need a meta-refresh since we don't have the dictionary.
        // The common cause is a restart of the browser, where we try to render
        // cached content that was saved when we had a dictionary.
        cause = RESPONSE_NO_DICTIONARY;
      } else if (filter_context_.SdchDictionariesAdvertised()) {
        // This is a very corrupt SDCH request response. We can't decode it.
        // We'll use a meta-refresh, and get content without asking for SDCH.
        // This will also progressively disable SDCH for this domain.
        cause = RESPONSE_CORRUPT_SDCH;
      } else {
        // One of the first 9 bytes precluded consideration as a hash.
        // This can't be an SDCH payload, even though the server said it was.
        // This is a major error, as the server or proxy tagged this SDCH even
        // though it is not!
        // Meta-refresh won't help, as we didn't advertise an SDCH dictionary!!
        // Worse yet, meta-refresh could lead to an infinite refresh loop.
        LogSdchProblem(SDCH_PASSING_THROUGH_NON_SDCH);
        decoding_status_ = PASS_THROUGH;
        // ... but further back-off on advertising SDCH support.
        url_request_context_->sdch_manager()->BlacklistDomain(
            url_, SDCH_PASSING_THROUGH_NON_SDCH);
        cause = RESPONSE_ENCODING_LIE;
      }
      DCHECK_NE(RESPONSE_NONE, cause);

      // Use if statement rather than ?: because UMA_HISTOGRAM_ENUMERATION
      // caches the histogram name based on the call site.
      if (filter_context_.IsCachedContent()) {
        UMA_HISTOGRAM_ENUMERATION(
            "Sdch3.ResponseCorruptionDetection.Cached", cause, RESPONSE_MAX);
      } else {
        UMA_HISTOGRAM_ENUMERATION(
            "Sdch3.ResponseCorruptionDetection.Uncached", cause, RESPONSE_MAX);
      }
      filter_context_.GetNetLog().AddEvent(
          NetLogEventType::SDCH_RESPONSE_CORRUPTION_DETECTION,
          base::Bind(&NetLogSdchResponseCorruptionDetectionCallback, cause,
                     filter_context_.IsCachedContent()));

      if (decoding_status_ == PASS_THROUGH) {
        dest_buffer_excess_ = dictionary_hash_;  // Send what we scanned.
      } else {
        // This is where we try to do the expensive meta-refresh.
        if (std::string::npos == mime_type_.find("text/html")) {
          // Since we can't do a meta-refresh (along with an exponential
          // backoff), we'll just make sure this NEVER happens again.
          SdchProblemCode problem = (filter_context_.IsCachedContent()
                                         ? SDCH_CACHED_META_REFRESH_UNSUPPORTED
                                         : SDCH_META_REFRESH_UNSUPPORTED);
          url_request_context_->sdch_manager()->BlacklistDomainForever(
              url_, problem);
          LogSdchProblem(problem);
          return FILTER_ERROR;
        }
        // HTML content means we can issue a meta-refresh, and get the content
        // again, perhaps without SDCH (to be safe).
        if (filter_context_.IsCachedContent()) {
          // Cached content is probably a startup tab, so we'll just get fresh
          // content and try again, without disabling sdch.
          LogSdchProblem(SDCH_META_REFRESH_CACHED_RECOVERY);
        } else {
          // Since it wasn't in the cache, we definately need at least some
          // period of blacklisting to get the correct content.
          url_request_context_->sdch_manager()->BlacklistDomain(
              url_, SDCH_META_REFRESH_RECOVERY);
          LogSdchProblem(SDCH_META_REFRESH_RECOVERY);
        }
        decoding_status_ = META_REFRESH_RECOVERY;
        // Issue a meta redirect with SDCH disabled.
        dest_buffer_excess_ = kDecompressionErrorHtml;
      }
    } else {
      DCHECK_EQ(DECODING_IN_PROGRESS, decoding_status_);
    }
  }

  int amount = OutputBufferExcess(dest_buffer, available_space);
  *dest_len += amount;
  dest_buffer += amount;
  available_space -= amount;
  DCHECK_GE(available_space, 0);

  if (available_space <= 0)
    return FILTER_OK;
  DCHECK(dest_buffer_excess_.empty());
  DCHECK_EQ(0u, dest_buffer_excess_index_);

  if (decoding_status_ != DECODING_IN_PROGRESS) {
    if (META_REFRESH_RECOVERY == decoding_status_) {
      // Absorb all input data. We've already output page reload HTML.
      next_stream_data_ = NULL;
      stream_data_len_ = 0;
      return FILTER_NEED_MORE_DATA;
    }
    if (PASS_THROUGH == decoding_status_) {
      // We must pass in available_space, but it will be changed to bytes_used.
      FilterStatus result = CopyOut(dest_buffer, &available_space);
      // Accumulate the returned count of bytes_used (a.k.a., available_space).
      *dest_len += available_space;
      return result;
    }
    DCHECK(false);
    decoding_status_ = DECODING_ERROR;
    return FILTER_ERROR;
  }

  if (!next_stream_data_ || stream_data_len_ <= 0)
    return FILTER_NEED_MORE_DATA;

  // A note on accounting: DecodeChunk() appends to its output buffer, so any
  // preexisting data in |dest_buffer_excess_| could skew the value of
  // |output_bytes_|. However, OutputBufferExcess guarantees that it will
  // consume all of |dest_buffer_excess_| when called above unless the
  // destination buffer runs out of space, and if the destination buffer runs
  // out of space, this code returns FILTER_OK early above. Therefore, if
  // execution reaches this point, |dest_buffer_excess_| is empty, which is
  // DCHECKed above.
  bool ret = vcdiff_streaming_decoder_->DecodeChunk(
    next_stream_data_, stream_data_len_, &dest_buffer_excess_);
  // Assume all data was used in decoding.
  next_stream_data_ = NULL;
  source_bytes_ += stream_data_len_;
  stream_data_len_ = 0;
  output_bytes_ += dest_buffer_excess_.size();
  if (!ret) {
    vcdiff_streaming_decoder_.reset(NULL);  // Don't call it again.
    decoding_status_ = DECODING_ERROR;
    LogSdchProblem(SDCH_DECODE_BODY_ERROR);
    return FILTER_ERROR;
  }

  amount = OutputBufferExcess(dest_buffer, available_space);
  *dest_len += amount;
  dest_buffer += amount;
  available_space -= amount;
  if (0 == available_space && !dest_buffer_excess_.empty())
      return FILTER_OK;
  return FILTER_NEED_MORE_DATA;
}

Filter::FilterStatus SdchFilter::InitializeDictionary() {
  size_t bytes_needed = kServerIdLength - dictionary_hash_.size();
  DCHECK_GT(bytes_needed, 0u);
  if (!next_stream_data_)
    return FILTER_NEED_MORE_DATA;
  if (static_cast<size_t>(stream_data_len_) < bytes_needed) {
    dictionary_hash_.append(next_stream_data_, stream_data_len_);
    next_stream_data_ = NULL;
    stream_data_len_ = 0;
    return FILTER_NEED_MORE_DATA;
  }
  dictionary_hash_.append(next_stream_data_, bytes_needed);
  DCHECK(kServerIdLength == dictionary_hash_.size());
  stream_data_len_ -= bytes_needed;
  DCHECK_LE(0, stream_data_len_);
  if (stream_data_len_ > 0)
    next_stream_data_ += bytes_needed;
  else
    next_stream_data_ = NULL;

  const std::string* dictionary_text = nullptr;
  dictionary_hash_is_plausible_ = true;  // Assume plausible, but check.

  SdchProblemCode rv = SDCH_OK;
  if ('\0' == dictionary_hash_[kServerIdLength - 1]) {
    std::string server_hash(dictionary_hash_, 0, kServerIdLength - 1);
    SdchManager::DictionarySet* handle =
        filter_context_.SdchDictionariesAdvertised();
    if (handle)
      dictionary_text = handle->GetDictionaryText(server_hash);
    if (!dictionary_text) {
      // This is a hack. Naively, the dictionaries available for
      // decoding should be only the ones advertised. However, there are
      // cases, specifically resources encoded with old dictionaries living
      // in the cache, that mean the full set of dictionaries should be made
      // available for decoding. It's not known how often this happens;
      // if it happens rarely enough, this code can be removed.
      //
      // TODO(rdsmith): Long-term, a better solution is necessary, since
      // an entry in the cache being encoded with the dictionary doesn't
      // guarantee that the dictionary is present. That solution probably
      // involves storing unencoded resources in the cache, but might
      // involve evicting encoded resources on dictionary removal.
      // See http://crbug.com/383405.
      unexpected_dictionary_handle_ =
          url_request_context_->sdch_manager()->GetDictionarySetByHash(
              url_, server_hash, &rv);
      if (unexpected_dictionary_handle_) {
        dictionary_text =
            unexpected_dictionary_handle_->GetDictionaryText(server_hash);
        // Override SDCH_OK rv; this is still worth logging.
        rv = (filter_context_.IsCachedContent() ?
              SDCH_UNADVERTISED_DICTIONARY_USED_CACHED :
              SDCH_UNADVERTISED_DICTIONARY_USED);
      } else {
        // Since dictionary was not found, check to see if hash was
        // even plausible.
        DCHECK(dictionary_hash_.size() == kServerIdLength);
        rv = SDCH_DICTIONARY_HASH_NOT_FOUND;
        for (size_t i = 0; i < kServerIdLength - 1; ++i) {
          char base64_char = dictionary_hash_[i];
          if (!isalnum(base64_char) &&
              '-' != base64_char && '_' != base64_char) {
            dictionary_hash_is_plausible_ = false;
            rv = SDCH_DICTIONARY_HASH_MALFORMED;
            break;
          }
        }
      }
    }
  } else {
    dictionary_hash_is_plausible_ = false;
    rv = SDCH_DICTIONARY_HASH_MALFORMED;
  }

  if (rv != SDCH_OK)
    LogSdchProblem(rv);

  if (!dictionary_text) {
    decoding_status_ = DECODING_ERROR;
    return FILTER_ERROR;
  }

  vcdiff_streaming_decoder_.reset(new open_vcdiff::VCDiffStreamingDecoder);
  vcdiff_streaming_decoder_->SetAllowVcdTarget(false);

  // The validity of the dictionary_text pointer is guaranteed for the
  // lifetime of the SdchFilter by the ownership of the DictionarySet by
  // the FilterContext/URLRequestHttpJob.  All URLRequestJob filters are
  // torn down in ~URLRequestHttpJob by a call to
  // URLRequestJob::DestroyFilters.
  vcdiff_streaming_decoder_->StartDecoding(dictionary_text->data(),
                                           dictionary_text->size());
  decoding_status_ = DECODING_IN_PROGRESS;
  return FILTER_OK;
}

int SdchFilter::OutputBufferExcess(char* const dest_buffer,
                                   size_t available_space) {
  if (dest_buffer_excess_.empty())
    return 0;
  DCHECK(dest_buffer_excess_.size() > dest_buffer_excess_index_);
  size_t amount = std::min(available_space,
      dest_buffer_excess_.size() - dest_buffer_excess_index_);
  memcpy(dest_buffer, dest_buffer_excess_.data() + dest_buffer_excess_index_,
         amount);
  dest_buffer_excess_index_ += amount;
  if (dest_buffer_excess_.size() <= dest_buffer_excess_index_) {
    DCHECK(dest_buffer_excess_.size() == dest_buffer_excess_index_);
    dest_buffer_excess_.clear();
    dest_buffer_excess_index_ = 0;
  }
  return amount;
}

void SdchFilter::LogSdchProblem(SdchProblemCode problem) {
  SdchManager::SdchErrorRecovery(problem);
  filter_context_.GetNetLog().AddEvent(
      NetLogEventType::SDCH_DECODING_ERROR,
      base::Bind(&NetLogSdchResourceProblemCallback, problem));
}

}  // namespace net
