// Copyright 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Author: jmarantz@google.com (Joshua Marantz)

// Unit-test InflatingFetch.

#include <cstddef>

#include "net/instaweb/http/public/inflating_fetch.h"

#include "net/instaweb/http/public/async_fetch.h"  // for StringAsyncFetch
#include "net/instaweb/http/public/http_value.h"
#include "net/instaweb/http/public/request_context.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/google_message_handler.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/base/thread_system.h"
#include "pagespeed/kernel/http/http_names.h"
#include "pagespeed/kernel/http/request_headers.h"
#include "pagespeed/kernel/http/response_headers.h"
#include "pagespeed/kernel/util/platform.h"

namespace {

const char kClearData[] = "Hello";

// This was generated with 'xxd -i hello.gz' after gzipping a file with "Hello".
const unsigned char kGzippedData[] = {
  0x1f, 0x8b, 0x08, 0x08, 0x3b, 0x3a, 0xf3, 0x4e, 0x00, 0x03, 0x68, 0x65,
  0x6c, 0x6c, 0x6f, 0x00, 0xf3, 0x48, 0xcd, 0xc9, 0xc9, 0x07, 0x00, 0x82,
  0x89, 0xd1, 0xf7, 0x05, 0x00, 0x00, 0x00
};

bool binary_data_same(const void* left, size_t left_len,
                      const void* right, size_t right_len) {
  return left_len == right_len && memcmp(left, right, left_len) == 0;
}

}  // namespace

namespace net_instaweb {

class MockFetch : public StringAsyncFetch {
 public:
  explicit MockFetch(const RequestContextPtr& ctx) : StringAsyncFetch(ctx) {}
  virtual ~MockFetch() {}

  void ExpectAcceptEncoding(const StringPiece& encoding) {
    encoding.CopyToString(&accept_encoding_);
  }

  virtual void HandleHeadersComplete() {
    if (!accept_encoding_.empty()) {
      EXPECT_TRUE(request_headers()->HasValue(
          HttpAttributes::kAcceptEncoding, accept_encoding_));
    }
    StringAsyncFetch::HandleHeadersComplete();
  }

 private:
  // If non-empty, EXPECT that each request must accept this encoding.
  GoogleString accept_encoding_;

  DISALLOW_COPY_AND_ASSIGN(MockFetch);
};

class InflatingFetchTest : public testing::Test {
 protected:
  InflatingFetchTest()
      : inflating_fetch_(NULL),
        gzipped_data_(reinterpret_cast<const char*>(kGzippedData),
                      STATIC_STRLEN(kGzippedData)),
        thread_system_(Platform::CreateThreadSystem()) {
  }

  virtual void SetUp() {
    mock_fetch_.reset(new MockFetch(
        RequestContext::NewTestRequestContext(thread_system_.get())));
    inflating_fetch_ = new InflatingFetch(mock_fetch_.get());
  }

  scoped_ptr<MockFetch> mock_fetch_;
  // Self-deletes in Done(), so no need to deallocate.
  InflatingFetch* inflating_fetch_;
  GoogleMessageHandler message_handler_;
  StringPiece gzipped_data_;
  scoped_ptr<ThreadSystem> thread_system_;
};

// Tests that if we ask for clear text & get it, we pass through the data
// unchanged.
TEST_F(InflatingFetchTest, ClearRequestResponse) {
  inflating_fetch_->response_headers()->SetStatusAndReason(HttpStatus::kOK);
  inflating_fetch_->Write(kClearData, &message_handler_);
  inflating_fetch_->Done(true);
  EXPECT_EQ(kClearData, mock_fetch_->buffer());
  EXPECT_TRUE(mock_fetch_->done());
  EXPECT_TRUE(mock_fetch_->success());
}

// Tests that if we ask for clear text, and get a response that claims to
// be gzipped but is actually garbage, our mock callback gets HandleDone(false)
// called, despite the fact that the fetcher (mocked by this code below) called
// Done(true).
TEST_F(InflatingFetchTest, AutoInflateGarbage) {
  inflating_fetch_->response_headers()->Add(
      HttpAttributes::kContentEncoding, HttpAttributes::kGzip);
  inflating_fetch_->response_headers()->SetStatusAndReason(HttpStatus::kOK);
  inflating_fetch_->Write("this garbage won't inflate", &message_handler_);
  inflating_fetch_->Done(true);
  EXPECT_TRUE(mock_fetch_->done());
  EXPECT_FALSE(mock_fetch_->success());
}

// Tests that if we ask for clear text but get a properly compressed buffer,
// that our inflating-fetch will make this transparent to our Expect callback.
TEST_F(InflatingFetchTest, AutoInflate) {
  inflating_fetch_->response_headers()->Add(
      HttpAttributes::kContentEncoding, HttpAttributes::kGzip);
  inflating_fetch_->response_headers()->SetStatusAndReason(HttpStatus::kOK);
  inflating_fetch_->Write(gzipped_data_, &message_handler_);
  inflating_fetch_->Done(true);
  EXPECT_EQ(kClearData, mock_fetch_->buffer())
      << "data should be auto-inflated.";
  EXPECT_TRUE(mock_fetch_->response_headers()->Lookup1(
      HttpAttributes::kContentEncoding) == NULL)
      << "Content encoding should be stripped since we inflated the data.";
  EXPECT_TRUE(mock_fetch_->done());
  EXPECT_TRUE(mock_fetch_->success());
}

// Tests that if we asked for a gzipped response in the first place that
// we don't inflate or strip the content-encoding header.
TEST_F(InflatingFetchTest, ExpectGzipped) {
  inflating_fetch_->request_headers()->Add(
      HttpAttributes::kAcceptEncoding, HttpAttributes::kGzip);
  inflating_fetch_->response_headers()->Add(
      HttpAttributes::kContentEncoding, HttpAttributes::kGzip);
  inflating_fetch_->response_headers()->SetStatusAndReason(HttpStatus::kOK);
  inflating_fetch_->Write(gzipped_data_, &message_handler_);
  inflating_fetch_->Done(true);
  EXPECT_TRUE(
      binary_data_same(
          gzipped_data_.data(), gzipped_data_.length(),
          mock_fetch_->buffer().data(), mock_fetch_->buffer().size()))
          << "data should be untouched.";
  EXPECT_STREQ(HttpAttributes::kGzip, mock_fetch_->response_headers()->Lookup1(
      HttpAttributes::kContentEncoding)) << "content-encoding not stripped.";
  EXPECT_TRUE(mock_fetch_->done());
  EXPECT_TRUE(mock_fetch_->success());
}

// Check that empty blacklist is processed correctly and everything is inflated.
// The blacklist feature has been removed since after this test was written,
// but behavior should be unchanged.
TEST_F(InflatingFetchTest, ExpectUnGzippedOnEmptyBlacklist) {
  inflating_fetch_->response_headers()->Add(
      HttpAttributes::kContentEncoding, HttpAttributes::kGzip);

  // We need to set Content-Type to one of the octet-streams types.
  inflating_fetch_->response_headers()->Add(HttpAttributes::kContentType,
                                            "binary/octet-stream");
  inflating_fetch_->response_headers()->SetStatusAndReason(HttpStatus::kOK);
  inflating_fetch_->Write(gzipped_data_, &message_handler_);
  inflating_fetch_->Done(true);
  EXPECT_STREQ(kClearData, mock_fetch_->buffer())
      << "data should be uncompressed when blacklist filter is empty.";
  EXPECT_FALSE(
      mock_fetch_->response_headers()->Has(HttpAttributes::kContentEncoding))
          << "content-encoding is not stripped.";
  EXPECT_TRUE(mock_fetch_->done());
  EXPECT_TRUE(mock_fetch_->success());

  // Check some other type.
  mock_fetch_->Reset();
  inflating_fetch_ = new InflatingFetch(mock_fetch_.get());

  inflating_fetch_->response_headers()->Add(
      HttpAttributes::kContentEncoding, HttpAttributes::kGzip);
  inflating_fetch_->response_headers()->Add(HttpAttributes::kContentType,
                                            "image/gif");
  inflating_fetch_->response_headers()->SetStatusAndReason(HttpStatus::kOK);
  inflating_fetch_->Write(gzipped_data_, &message_handler_);
  inflating_fetch_->Done(true);
  EXPECT_STREQ(kClearData, mock_fetch_->buffer())
      << "data should be inflated when content-type is not in blacklist.";
  EXPECT_FALSE(
      mock_fetch_->response_headers()->Has(HttpAttributes::kContentEncoding))
          << "content-encoding is not stripped.";
  EXPECT_TRUE(mock_fetch_->done());
  EXPECT_TRUE(mock_fetch_->success());
}

TEST_F(InflatingFetchTest, ContentGzipAndDeflatedButWantClear) {
  inflating_fetch_->response_headers()->Add(
      HttpAttributes::kContentEncoding, HttpAttributes::kDeflate);

  // Apply gzip second so that it gets decoded first as we want to decode
  // in reverse order to how the encoding was done.
  inflating_fetch_->response_headers()->Add(
      HttpAttributes::kContentEncoding, HttpAttributes::kGzip);
  inflating_fetch_->response_headers()->SetStatusAndReason(HttpStatus::kOK);
  inflating_fetch_->Write(gzipped_data_, &message_handler_);
  inflating_fetch_->Done(true);
  EXPECT_EQ(kClearData, mock_fetch_->buffer())
      << "data should be auto-unzipped but deflate is not attempted.";
  EXPECT_STREQ(HttpAttributes::kDeflate,
               mock_fetch_->response_headers()->Lookup1(
                   HttpAttributes::kContentEncoding))
      << "deflate encoding remains though gzip encoding is stripped.";
  EXPECT_TRUE(mock_fetch_->done());
  EXPECT_TRUE(mock_fetch_->success());
}

// Tests that content that was first gzipped, and then encoded with
// some encoder ("frob") unknown to our system does not get touched.
// We should not attempt to gunzip the 'frob' data.
TEST_F(InflatingFetchTest, GzippedAndFrobbedNotChanged) {
  inflating_fetch_->response_headers()->Add(
      HttpAttributes::kContentEncoding, HttpAttributes::kGzip);
  inflating_fetch_->response_headers()->Add(
      HttpAttributes::kContentEncoding, "frob");
  inflating_fetch_->response_headers()->SetStatusAndReason(HttpStatus::kOK);
  inflating_fetch_->Write(gzipped_data_, &message_handler_);
  inflating_fetch_->Done(true);

  EXPECT_EQ(gzipped_data_, mock_fetch_->buffer())
      << "data should be not be altered (even though it happens to be gzipped)";
  ConstStringStarVector encodings;
  ASSERT_TRUE(mock_fetch_->response_headers()->Lookup(
      HttpAttributes::kContentEncoding, &encodings))
      << "deflate encoding remains though gzip encoding is stripped.";
  ASSERT_EQ(2, encodings.size());
  EXPECT_STREQ(HttpAttributes::kGzip, *encodings[0]);
  EXPECT_STREQ("frob", *encodings[1]);
}

TEST_F(InflatingFetchTest, TestEnableGzipFromBackend) {
  mock_fetch_->ExpectAcceptEncoding(HttpAttributes::kGzip);
  inflating_fetch_->EnableGzipFromBackend();
  inflating_fetch_->response_headers()->Add(
      HttpAttributes::kContentEncoding, HttpAttributes::kGzip);
  inflating_fetch_->response_headers()->SetStatusAndReason(HttpStatus::kOK);
  inflating_fetch_->Write(gzipped_data_, &message_handler_);
  inflating_fetch_->Done(true);
  EXPECT_EQ(kClearData, mock_fetch_->buffer())
      << "data should be auto-inflated.";
  EXPECT_TRUE(mock_fetch_->response_headers()->Lookup1(
      HttpAttributes::kContentEncoding) == NULL)
      << "Content encoding should be stripped since we inflated the data.";
  EXPECT_TRUE(mock_fetch_->done());
  EXPECT_TRUE(mock_fetch_->success());
}

TEST_F(InflatingFetchTest, TestEnableGzipFromBackendWithCleartext) {
  mock_fetch_->ExpectAcceptEncoding(HttpAttributes::kGzip);
  inflating_fetch_->EnableGzipFromBackend();

  // We are going to ask the mock server for gzip, but we'll get cleartext.
  inflating_fetch_->response_headers()->SetStatusAndReason(HttpStatus::kOK);
  inflating_fetch_->Write(kClearData, &message_handler_);
  inflating_fetch_->Done(true);
  EXPECT_EQ(kClearData, mock_fetch_->buffer());
  EXPECT_TRUE(mock_fetch_->done());
  EXPECT_TRUE(mock_fetch_->success());
}

TEST_F(InflatingFetchTest, TestEnableGzipFromBackendExpectingGzip) {
  inflating_fetch_->request_headers()->Add(
      HttpAttributes::kAcceptEncoding, HttpAttributes::kGzip);
  inflating_fetch_->response_headers()->Add(
      HttpAttributes::kContentEncoding, HttpAttributes::kGzip);

  // Calling EnableGzipFromBackend here has no effect in this case,
  // because above we declare that we want to see gzipped data coming
  // into our Write methods.
  inflating_fetch_->EnableGzipFromBackend();
  mock_fetch_->ExpectAcceptEncoding(HttpAttributes::kGzip);

  inflating_fetch_->response_headers()->SetStatusAndReason(HttpStatus::kOK);
  inflating_fetch_->Write(gzipped_data_, &message_handler_);
  inflating_fetch_->Done(true);
  EXPECT_TRUE(
      binary_data_same(
          gzipped_data_.data(), gzipped_data_.length(),
          mock_fetch_->buffer().data(), mock_fetch_->buffer().size()))
          << "data should be untouched.";
  EXPECT_STREQ(HttpAttributes::kGzip, mock_fetch_->response_headers()->Lookup1(
      HttpAttributes::kContentEncoding)) << "content-encoding not stripped.";
  EXPECT_TRUE(mock_fetch_->done());
  EXPECT_TRUE(mock_fetch_->success());
}

TEST(StaticInflatingFetchTest, CompressUncompressValue) {
  static const char kHello[] = "hello";
  GoogleMessageHandler handler;
  HTTPValue value;
  value.Write(kHello, &handler);
  ResponseHeaders headers;
  headers.Add(HttpAttributes::kContentType, "text/html");
  value.SetHeaders(&headers);
  HTTPValue compressed_value;
  EXPECT_TRUE(InflatingFetch::GzipValue(9, value, &compressed_value, &headers,
                                        &handler));
  StringPiece contents;
  compressed_value.ExtractContents(&contents);
  // Extract the compressed version, it shouldn't be the same as the initial
  // text.
  EXPECT_NE(kHello, contents);
  EXPECT_STREQ(HttpAttributes::kGzip,
               headers.Lookup1(HttpAttributes::kContentEncoding));
  compressed_value.ExtractHeaders(&headers, &handler);
  HTTPValue uncompressed_value;
  ResponseHeaders temp_headers;
  temp_headers.Add("a", "b");
  uncompressed_value.SetHeaders(&temp_headers);
  ASSERT_TRUE(InflatingFetch::UnGzipValueIfCompressed(
      compressed_value, &headers, &uncompressed_value, &handler));
  uncompressed_value.ExtractContents(&contents);
  // We've unzipped the compressed value, it should now say "hello".
  EXPECT_EQ(kHello, contents);
}

// TODO(jmarantz): test 'deflate' without gzip

}  // namespace net_instaweb
