/*
 * Copyright 2013 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: hujie@google.com (Jie Hu)

#include "net/instaweb/http/public/mock_url_fetcher.h"
#include "net/instaweb/http/public/request_context.h"
#include "net/instaweb/rewriter/public/mock_resource_callback.h"
#include "net/instaweb/rewriter/public/resource.h"  // for Resource, etc
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_test_base.h"
#include "net/instaweb/rewriter/public/test_rewrite_driver_factory.h"
#include "net/instaweb/rewriter/public/url_input_resource.h"
#include "pagespeed/kernel/base/basictypes.h"  // for arraysize
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/ref_counted_ptr.h"
#include "pagespeed/kernel/base/string.h"  // for GoogleString
#include "pagespeed/kernel/base/string_util.h"  // for StrCat, etc
#include "pagespeed/kernel/html/html_parse_test_base.h"
#include "pagespeed/kernel/http/content_type.h"
#include "pagespeed/kernel/http/google_url.h"
#include "pagespeed/kernel/http/http_names.h"
#include "pagespeed/kernel/http/request_headers.h"
#include "pagespeed/kernel/http/response_headers.h"

namespace net_instaweb {

class UrlInputResourceTest : public RewriteTestBase {
 protected:
  // A const used for all tests that don't care about is_auth_domain_expected
  // in the CheckResourceFetchHasReferer calls.
  static const bool kUnusedBoolArg = true;

  // Helper method that does all the verification wrt creation of an input
  // resource with the given "url" argument. fetch_url indicates the URL to
  // use for setting up fetch responses. Note that fetch_url is almost always
  // the same as url, except when standard port numbers  (80 for http and 443
  // for https) are used, in which case the fetch_url drops these port numbers.
  // base_url is the URL of the page wrt which this resource URL is being
  // created.
  // is_authorized_domain indicates whether the URL corresponds to an explicitly
  // authorized domain or not. is_auth_domain_expected is only used when
  // is_authorized_domain is false, and it indicates whether the fetched URL's
  // domain is to be considered authorized after input resource creation or not.
  void ResourceFetchHelper(const GoogleString& url,
                           const GoogleString& fetch_url,
                           const GoogleString& base_url,
                           bool is_background_fetch,
                           bool is_authorized_domain,
                           bool is_auth_domain_expected,
                           const ResourcePtr& resource,
                           const GoogleString& expected_cache_key,
                           const GoogleString& expected_referer,
                           const RequestContextPtr& request_context) {
    SetBaseUrlForFetch(base_url);
    EXPECT_STREQ(url, resource->url());
    EXPECT_STREQ(expected_cache_key, resource->cache_key());
    resource->set_is_background_fetch(is_background_fetch);
    MockResourceCallback cb(resource, factory()->thread_system());
    resource->LoadAsync(Resource::kLoadEvenIfNotCacheable, request_context,
                        &cb);
    cb.Wait();
    ASSERT_TRUE(cb.done());
    ASSERT_TRUE(cb.success());
    EXPECT_STREQ(expected_referer, mock_url_fetcher()->last_referer());
  }

  void CheckResourceFetchHasReferer(const GoogleString& url,
                                    const GoogleString& fetch_url,
                                    const GoogleString& base_url,
                                    bool is_background_fetch,
                                    bool is_authorized_domain,
                                    bool is_auth_domain_expected,
                                    const GoogleString& expected_cache_key,
                                    const GoogleString& expected_referer) {
    PrepareResourceFetch(fetch_url);
    ResourcePtr resource(MakeUrlInputResource(url, is_authorized_domain));
    RequestContextPtr request_context(
        RequestContext::NewTestRequestContext(factory()->thread_system()));
    ResourceFetchHelper(url, fetch_url, base_url, is_background_fetch,
                        is_authorized_domain, is_auth_domain_expected,
                        resource, expected_cache_key, expected_referer,
                        request_context);
    EXPECT_STREQ(expected_referer, mock_url_fetcher()->last_referer());
    if (!is_authorized_domain) {
      GoogleUrl tmp_url(fetch_url);
      EXPECT_EQ(is_auth_domain_expected,
                request_context->IsSessionAuthorizedFetchOrigin(
                    tmp_url.Origin().as_string()));
    }
  }

  void CheckExtractedGzippedResource(const GoogleString& url,
                                     const GoogleString& fetch_url,
                                     const GoogleString& base_url,
                                     bool is_background_fetch,
                                     bool is_authorized_domain,
                                     bool is_auth_domain_expected,
                                     const GoogleString& expected_cache_key,
                                     const GoogleString& expected_referer) {
    const char kHello[] = "hello";
    const char kHelloGzip[] =
        "\x1f\x8b\x08\x08\x64\x7d\x33\x56\x00\x03\x68\x65\x6c\x6c\x6f\x00\xcb"
        "\x48\xcd\xc9\xc9\x07\x00\x86\xa6\x10\x36\x05\x00\x00\x00";
    StringPiece payload(kHelloGzip, sizeof(kHelloGzip));
    PrepareGzippedResourceFetch(fetch_url, payload);
    ResourcePtr resource(MakeUrlInputResource(url, is_authorized_domain));
    RequestContextPtr request_context(
        RequestContext::NewTestRequestContext(factory()->thread_system()));
     ResourceFetchHelper(
        url, fetch_url, base_url, is_background_fetch, is_authorized_domain,
        is_auth_domain_expected, resource, expected_cache_key, expected_referer,
        request_context);
    EXPECT_STREQ(kHello, resource->ExtractUncompressedContents());
  }

  UrlInputResource* MakeUrlInputResource(const GoogleString& url,
                                         bool is_authorized_domain) {
    return new UrlInputResource(rewrite_driver(), &kContentTypeJpeg, url,
                                is_authorized_domain);
  }

  void PrepareResourceFetch(const GoogleString& resource_url) {
    mock_url_fetcher()->set_verify_pagespeed_header_off(true);
    ResponseHeaders response_headers;
    DefaultResponseHeaders(kContentTypeJpeg, 100, &response_headers);
    SetFetchResponse(AbsolutifyUrl(resource_url), response_headers, "payload");
  }

  void PrepareGzippedResourceFetch(const GoogleString& resource_url,
                                   StringPiece payload) {
    mock_url_fetcher()->set_verify_pagespeed_header_off(true);
    ResponseHeaders response_headers;
    DefaultResponseHeaders(kContentTypeJpeg, 100, &response_headers);
    response_headers.Add(HttpAttributes::kContentEncoding,
                         HttpAttributes::kGzip);
    SetFetchResponse(AbsolutifyUrl(resource_url), response_headers, payload);
  }
};




// Test of referer (BackgroundFetch): When the resource fetching request header
// misses referer, we set the referer for it. Base url and resource url are
// same.
TEST_F(UrlInputResourceTest, TestBackgroundFetchRefererSameDomain) {
  GoogleString url = StrCat(kTestDomain, "1.jpg");
  CheckResourceFetchHasReferer(url, url, kTestDomain,
                               true, true, kUnusedBoolArg,
                               url, kTestDomain);
}

// Test extraction of gzipped resource.
TEST_F(UrlInputResourceTest, TestExtractGzippedResource) {
  GoogleString url = "http://other.com/1.txt";
  CheckExtractedGzippedResource(
      url, url, kTestDomain, true /* is_background_fetch */,
      false /* is_authorized_domain */, true /* is_auth_domain_expected */,
      "unauth://other.com/1.txt", kTestDomain);
}

// Test of referer (BackgroundFetch): When the resource fetching request header
// misses referer, we set the referer for it. Base url and resource url are
// different.
TEST_F(UrlInputResourceTest, TestBackgroundFetchRefererDomain) {
  GoogleString url = "http://other.com/1.jpg";
  CheckResourceFetchHasReferer(url, url, kTestDomain, true, true,
                               kUnusedBoolArg, url,
                               kTestDomain);
}

// Test of referer (NonBackgroundFetch): When the resource fetching request
// header misses referer, we check if there is any referer from the original
// request header. If that referer is empty, No referer would be set for this
// fetching request.
TEST_F(UrlInputResourceTest, TestNonBackgroundFetchWithRefererMissing) {
  GoogleString url = "http://other.com/1.jpg";
  RequestHeaders headers;
  rewrite_driver()->SetRequestHeaders(headers);
  CheckResourceFetchHasReferer(url, url, kTestDomain,
                               false, true, kUnusedBoolArg,
                               url, "");
}

// Test of referer (NonBackgroundFetch): When the resource fetching request
// header misses referer, we set the referer for it from the original request
// header.
TEST_F(UrlInputResourceTest, TestNonBackgroundFetchWithReferer) {
  GoogleString url = "http://other.com/1.jpg";
  RequestHeaders headers;
  headers.Add(HttpAttributes::kReferer, kTestDomain);
  rewrite_driver()->SetRequestHeaders(headers);
  CheckResourceFetchHasReferer(url, url, kTestDomain,
                               false, true, kUnusedBoolArg,
                               url, kTestDomain);
}

/* Tests related to unauthorized http domains. */

// Test that unauthorized resources are created correctly with http protocol.
TEST_F(UrlInputResourceTest, TestUnauthorizedDomainHttp) {
  GoogleString url = "http://other.com/1.jpg";
  CheckResourceFetchHasReferer(url, url, kTestDomain,
                               true, false, true,
                               "unauth://other.com/1.jpg", kTestDomain);
}

// Test that unauthorized resources are not created with wrong protocol.
TEST_F(UrlInputResourceTest, TestUnauthorizedDomainWrongProtocol) {
  GoogleString url = "ftp://other.com/1.jpg";
  PrepareResourceFetch(url);;
  SetBaseUrlForFetch(kTestDomain);
  ASSERT_DEATH(MakeUrlInputResource(url, false), "");
}

// Test that unauthorized resources are not created with a relative URL.
TEST_F(UrlInputResourceTest, TestUnauthorizedDomainRelativeURL) {
  GoogleString url = "/1.jpg";
  PrepareResourceFetch(url);;
  SetBaseUrlForFetch(kTestDomain);
  ASSERT_DEATH(MakeUrlInputResource(url, false), "");
}

// Test that unauthorized resources are created when a standard (80) port is
// specified for http.
TEST_F(UrlInputResourceTest, TestUnauthorizedDomainHttpWithCorrectPort) {
  GoogleString url = "http://other.com:80/1.jpg";
  CheckResourceFetchHasReferer(url, "http://other.com/1.jpg", kTestDomain,
                               true, false, true,
                               "unauth://other.com/1.jpg", kTestDomain);
}

// Test that unauthorized resources are not created when a non-standard port
// is specified for http.
TEST_F(UrlInputResourceTest, TestNoUnauthorizedDomainHttpWithWrongPort) {
  GoogleString url = "http://other.com:1234/1.jpg";
  CheckResourceFetchHasReferer(url, url, kTestDomain,
                               true, false, false,
                               "unauth://other.com:1234/1.jpg", kTestDomain);
}

// Test that unauthorized resources are not created when a https (443) port is
// specified for http.
TEST_F(UrlInputResourceTest, TestNoUnauthorizedDomainHttpWithHttpsPort) {
  GoogleString url = "http://other.com:443/1.jpg";
  CheckResourceFetchHasReferer(url, url, kTestDomain,
                               true, false, false,
                               "unauth://other.com:443/1.jpg", kTestDomain);
}

/* Tests related to unauthorized https domains. */

// Test that unauthorized resources are created correctly with https protocol.
TEST_F(UrlInputResourceTest, TestUnauthorizedDomainHttps) {
  GoogleString url = "https://other.com/1.jpg";
  CheckResourceFetchHasReferer(url, url, kTestDomain,
                               true, false, true,
                               "unauths://other.com/1.jpg", kTestDomain);
}

// Test that unauthorized resources are created when a standard (443) port is
// specified for https.
TEST_F(UrlInputResourceTest, TestUnauthorizedDomainHttpsWithCorrectPort) {
  GoogleString url = "https://other.com:443/1.jpg";
  CheckResourceFetchHasReferer(url, "https://other.com/1.jpg", kTestDomain,
                               true, false, true,
                               "unauths://other.com/1.jpg", kTestDomain);
}

// Test that unauthorized resources are not created when a non-standard port
// is specified for https.
TEST_F(UrlInputResourceTest, TestNoUnauthorizedDomainHttpsWithWrongPort) {
  GoogleString url = "https://other.com:1234/1.jpg";
  CheckResourceFetchHasReferer(url, url, kTestDomain,
                               true, false, false,
                               "unauths://other.com:1234/1.jpg", kTestDomain);
}

// Test that unauthorized resources are not created when a http (80) port is
// specified for https.
TEST_F(UrlInputResourceTest, TestNoUnauthorizedDomainHttpsWithHttpPort) {
  GoogleString url = "https://other.com:80/1.jpg";
  CheckResourceFetchHasReferer(url, url, kTestDomain,
                               true, false, false,
                               "unauths://other.com:80/1.jpg", kTestDomain);
}

struct PortTest {
  const char* spec;
  int expected_int_port;
  int int_port;
};

// Test that verifies that standard port numbers are treated as PORT_UNSPECIFIED
// by GoogleUrl.
TEST_F(UrlInputResourceTest, IntPort) {
  const PortTest port_tests[] = {
    // http
    {"http://www.google.com/", 80, url::PORT_UNSPECIFIED},
    {"http://www.google.com:80/", 80, url::PORT_UNSPECIFIED},
    {"http://www.google.com:443/", 443, 443},
    {"http://www.google.com:1234/", 1234, 1234},

    // https
    {"https://www.google.com/", 443, url::PORT_UNSPECIFIED},
    {"https://www.google.com:443/", 443, url::PORT_UNSPECIFIED},
    {"https://www.google.com:80/", 80, 80},
    {"https://www.google.com:1234/", 1234, 1234},
  };

  for (int i = 0; i < arraysize(port_tests); ++i) {
    GoogleUrl url(port_tests[i].spec);
    EXPECT_TRUE(url.IsWebValid());
    EXPECT_EQ(port_tests[i].expected_int_port, url.EffectiveIntPort());
    EXPECT_EQ(port_tests[i].int_port, url.IntPort());
  }
}

}  // namespace net_instaweb
