// Copyright (c) 2011 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/base/gzip_filter.h"

#if defined(USE_SYSTEM_ZLIB)
#include <zlib.h>
#else
#include "third_party/zlib/zlib.h"
#endif

#include "base/logging.h"
#include "net/base/gzip_header.h"

namespace net {

GZipFilter::GZipFilter()
    : decoding_status_(DECODING_UNINITIALIZED),
      decoding_mode_(DECODE_MODE_UNKNOWN),
      gzip_header_status_(GZIP_CHECK_HEADER_IN_PROGRESS),
      zlib_header_added_(false),
      gzip_footer_bytes_(0),
      possible_sdch_pass_through_(false) {
}

GZipFilter::~GZipFilter() {
  if (decoding_status_ != DECODING_UNINITIALIZED) {
    inflateEnd(zlib_stream_.get());
  }
}

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

  // Initialize zlib control block
  zlib_stream_.reset(new z_stream);
  if (!zlib_stream_.get())
    return false;
  memset(zlib_stream_.get(), 0, sizeof(z_stream));

  // Set decoding mode
  switch (filter_type) {
    case Filter::FILTER_TYPE_DEFLATE: {
      if (inflateInit(zlib_stream_.get()) != Z_OK)
        return false;
      decoding_mode_ = DECODE_MODE_DEFLATE;
      break;
    }
    case Filter::FILTER_TYPE_GZIP_HELPING_SDCH:
      possible_sdch_pass_through_ =  true;  // Needed to optionally help sdch.
      // Fall through to GZIP case.
    case Filter::FILTER_TYPE_GZIP: {
      gzip_header_.reset(new GZipHeader());
      if (!gzip_header_.get())
        return false;
      if (inflateInit2(zlib_stream_.get(), -MAX_WBITS) != Z_OK)
        return false;
      decoding_mode_ = DECODE_MODE_GZIP;
      break;
    }
    default: {
      return false;
    }
  }

  decoding_status_ = DECODING_IN_PROGRESS;
  return true;
}

Filter::FilterStatus GZipFilter::ReadFilteredData(char* dest_buffer,
                                                  int* dest_len) {
  if (!dest_buffer || !dest_len || *dest_len <= 0)
    return Filter::FILTER_ERROR;

  if (decoding_status_ == DECODING_DONE) {
    if (GZIP_GET_INVALID_HEADER != gzip_header_status_)
      SkipGZipFooter();
    // Some server might send extra data after the gzip footer. We just copy
    // them out. Mozilla does this too.
    return CopyOut(dest_buffer, dest_len);
  }

  if (decoding_status_ != DECODING_IN_PROGRESS)
    return Filter::FILTER_ERROR;

  Filter::FilterStatus status;

  if (decoding_mode_ == DECODE_MODE_GZIP &&
      gzip_header_status_ == GZIP_CHECK_HEADER_IN_PROGRESS) {
    // With gzip encoding the content is wrapped with a gzip header.
    // We need to parse and verify the header first.
    status = CheckGZipHeader();
    switch (status) {
      case Filter::FILTER_NEED_MORE_DATA: {
        // We have consumed all input data, either getting a complete header or
        // a partial header. Return now to get more data.
        *dest_len = 0;
        // Partial header means it can't be an SDCH header.
        // Reason: SDCH *always* starts with 8 printable characters [a-zA-Z/_].
        // Gzip always starts with two non-printable characters.  Hence even a
        // single character (partial header) means that this can't be an SDCH
        // encoded body masquerading as a GZIP body.
        possible_sdch_pass_through_ = false;
        return status;
      }
      case Filter::FILTER_OK: {
        // The header checking succeeds, and there are more data in the input.
        // We must have got a complete header here.
        DCHECK_EQ(gzip_header_status_, GZIP_GET_COMPLETE_HEADER);
        break;
      }
      case Filter::FILTER_ERROR: {
        if (possible_sdch_pass_through_ &&
            GZIP_GET_INVALID_HEADER == gzip_header_status_) {
          decoding_status_ = DECODING_DONE;  // Become a pass through filter.
          return CopyOut(dest_buffer, dest_len);
        }
        decoding_status_ = DECODING_ERROR;
        return status;
      }
      default: {
        status = Filter::FILTER_ERROR;    // Unexpected.
        decoding_status_ = DECODING_ERROR;
        return status;
      }
    }
  }

  int dest_orig_size = *dest_len;
  status = DoInflate(dest_buffer, dest_len);

  if (decoding_mode_ == DECODE_MODE_DEFLATE && status == Filter::FILTER_ERROR) {
    // As noted in Mozilla implementation, some servers such as Apache with
    // mod_deflate don't generate zlib headers.
    // See 677409 for instances where this work around is needed.
    // Insert a dummy zlib header and try again.
    if (InsertZlibHeader()) {
      *dest_len = dest_orig_size;
      status = DoInflate(dest_buffer, dest_len);
    }
  }

  if (status == Filter::FILTER_DONE) {
    decoding_status_ = DECODING_DONE;
  } else if (status == Filter::FILTER_ERROR) {
    decoding_status_ = DECODING_ERROR;
  }

  return status;
}

Filter::FilterStatus GZipFilter::CheckGZipHeader() {
  DCHECK_EQ(gzip_header_status_, GZIP_CHECK_HEADER_IN_PROGRESS);

  // Check input data in pre-filter buffer.
  if (!next_stream_data_ || stream_data_len_ <= 0)
    return Filter::FILTER_ERROR;

  const char* header_end = NULL;
  GZipHeader::Status header_status;
  header_status = gzip_header_->ReadMore(next_stream_data_, stream_data_len_,
                                         &header_end);

  switch (header_status) {
    case GZipHeader::INCOMPLETE_HEADER: {
      // We read all the data but only got a partial header.
      next_stream_data_ = NULL;
      stream_data_len_ = 0;
      return Filter::FILTER_NEED_MORE_DATA;
    }
    case GZipHeader::COMPLETE_HEADER: {
      // We have a complete header. Check whether there are more data.
      int num_chars_left = static_cast<int>(stream_data_len_ -
                                            (header_end - next_stream_data_));
      gzip_header_status_ = GZIP_GET_COMPLETE_HEADER;

      if (num_chars_left > 0) {
        next_stream_data_ = const_cast<char*>(header_end);
        stream_data_len_ = num_chars_left;
        return Filter::FILTER_OK;
      } else {
        next_stream_data_ = NULL;
        stream_data_len_ = 0;
        return Filter::FILTER_NEED_MORE_DATA;
      }
    }
    case GZipHeader::INVALID_HEADER: {
      gzip_header_status_ = GZIP_GET_INVALID_HEADER;
      return Filter::FILTER_ERROR;
    }
    default: {
      break;
    }
  }

  return Filter::FILTER_ERROR;
}

Filter::FilterStatus GZipFilter::DoInflate(char* dest_buffer, int* dest_len) {
  // Make sure we have both valid input data and output buffer.
  if (!dest_buffer || !dest_len || *dest_len <= 0)  // output
    return Filter::FILTER_ERROR;

  if (!next_stream_data_ || stream_data_len_ <= 0) {  // input
    *dest_len = 0;
    return Filter::FILTER_NEED_MORE_DATA;
  }

  // Fill in zlib control block
  zlib_stream_.get()->next_in = bit_cast<Bytef*>(next_stream_data_);
  zlib_stream_.get()->avail_in = stream_data_len_;
  zlib_stream_.get()->next_out = bit_cast<Bytef*>(dest_buffer);
  zlib_stream_.get()->avail_out = *dest_len;

  int inflate_code = inflate(zlib_stream_.get(), Z_NO_FLUSH);
  int bytesWritten = *dest_len - zlib_stream_.get()->avail_out;

  Filter::FilterStatus status;

  switch (inflate_code) {
    case Z_STREAM_END: {
      *dest_len = bytesWritten;

      stream_data_len_ = zlib_stream_.get()->avail_in;
      next_stream_data_ = bit_cast<char*>(zlib_stream_.get()->next_in);

      SkipGZipFooter();

      status = Filter::FILTER_DONE;
      break;
    }
    case Z_BUF_ERROR: {
      // According to zlib documentation, when calling inflate with Z_NO_FLUSH,
      // getting Z_BUF_ERROR means no progress is possible. Neither processing
      // more input nor producing more output can be done.
      // Since we have checked both input data and output buffer before calling
      // inflate, this result is unexpected.
      status = Filter::FILTER_ERROR;
      break;
    }
    case Z_OK: {
      // Some progress has been made (more input processed or more output
      // produced).
      *dest_len = bytesWritten;

      // Check whether we have consumed all input data.
      stream_data_len_ = zlib_stream_.get()->avail_in;
      if (stream_data_len_ == 0) {
        next_stream_data_ = NULL;
        status = Filter::FILTER_NEED_MORE_DATA;
      } else {
        next_stream_data_ = bit_cast<char*>(zlib_stream_.get()->next_in);
        status = Filter::FILTER_OK;
      }
      break;
    }
    default: {
      status = Filter::FILTER_ERROR;
      break;
    }
  }

  return status;
}

bool GZipFilter::InsertZlibHeader() {
  static char dummy_head[2] = { 0x78, 0x1 };

  char dummy_output[4];

  // We only try add additional header once.
  if (zlib_header_added_)
    return false;

  inflateReset(zlib_stream_.get());
  zlib_stream_.get()->next_in = bit_cast<Bytef*>(&dummy_head[0]);
  zlib_stream_.get()->avail_in = sizeof(dummy_head);
  zlib_stream_.get()->next_out = bit_cast<Bytef*>(&dummy_output[0]);
  zlib_stream_.get()->avail_out = sizeof(dummy_output);

  int code = inflate(zlib_stream_.get(), Z_NO_FLUSH);
  zlib_header_added_ = true;

  return (code == Z_OK);
}


void GZipFilter::SkipGZipFooter() {
  int footer_bytes_expected = kGZipFooterSize - gzip_footer_bytes_;
  if (footer_bytes_expected > 0) {
    int footer_byte_avail = std::min(footer_bytes_expected, stream_data_len_);
    stream_data_len_ -= footer_byte_avail;
    next_stream_data_ += footer_byte_avail;
    gzip_footer_bytes_ += footer_byte_avail;

    if (stream_data_len_ == 0)
      next_stream_data_ = NULL;
  }
}

}  // namespace net
