// Copyright 2012 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.

#import "ios/net/protocol_handler_util.h"

#include <memory>
#include <utility>

#include "base/mac/scoped_nsobject.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/sys_string_conversions.h"
#include "net/base/elements_upload_data_stream.h"
#import "net/base/mac/url_conversions.h"
#include "net/base/upload_bytes_element_reader.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/data_protocol_handler.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_job_factory.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gtest_mac.h"
#include "url/gurl.h"

// When C++ exceptions are disabled, the C++ library defines |try| and
// |catch| so as to allow exception-expecting C++ code to build properly when
// language support for exceptions is not present.  These macros interfere
// with the use of |@try| and |@catch| in Objective-C files such as this one.
// Undefine these macros here, after everything has been #included, since
// there will be no C++ uses and only Objective-C uses from this point on.
#undef try
#undef catch

namespace net {
namespace {

const int kResponseCode = 200;
const char* kTextHtml = "text/html";
const char* kTextPlain = "text/plain";
const char* kAscii = "US-ASCII";

class HeadersURLRequestJob : public URLRequestJob {
 public:
  HeadersURLRequestJob(URLRequest* request)
      : URLRequestJob(request, nullptr) {}

  void Start() override {
    // Fills response headers and returns immediately.
    NotifyHeadersComplete();
  }

  bool GetMimeType(std::string* mime_type) const override {
    *mime_type = GetContentTypeValue();
    return true;
  }

  void GetResponseInfo(HttpResponseInfo* info) override {
    // This is called by NotifyHeadersComplete().
    std::string header_string("HTTP/1.0 200 OK");
    header_string.push_back('\0');
    header_string += std::string("Cache-Control: max-age=600");
    header_string.push_back('\0');
    if (request()->url().DomainIs("multiplecontenttype")) {
      header_string += std::string(
          "coNteNt-tYPe: text/plain; charset=iso-8859-4, image/png");
      header_string.push_back('\0');
    }
    header_string += std::string("Content-Type: ") + GetContentTypeValue();
    header_string.push_back('\0');
    header_string += std::string("Foo: A");
    header_string.push_back('\0');
    header_string += std::string("Bar: B");
    header_string.push_back('\0');
    header_string += std::string("Baz: C");
    header_string.push_back('\0');
    header_string += std::string("Foo: D");
    header_string.push_back('\0');
    header_string += std::string("Foo: E");
    header_string.push_back('\0');
    header_string += std::string("Bar: F");
    header_string.push_back('\0');
    info->headers = new HttpResponseHeaders(header_string);
  }

  int GetResponseCode() const override {
    return kResponseCode;
  }
 protected:
  ~HeadersURLRequestJob() override {}

  std::string GetContentTypeValue() const {
    if (request()->url().DomainIs("badcontenttype"))
      return "\xff";
    return kTextHtml;
  }
};

class NetProtocolHandler : public URLRequestJobFactory::ProtocolHandler {
 public:
  URLRequestJob* MaybeCreateJob(
      URLRequest* request,
      NetworkDelegate* network_delegate) const override {
    return new HeadersURLRequestJob(request);
  }
};

class ProtocolHandlerUtilTest : public testing::Test,
                                public URLRequest::Delegate {
 public:
  ProtocolHandlerUtilTest() : request_context_(new TestURLRequestContext) {
    // Ownership of the protocol handlers is transferred to the factory.
    job_factory_.SetProtocolHandler("http",
                                    base::WrapUnique(new NetProtocolHandler));
    job_factory_.SetProtocolHandler("data",
                                    base::WrapUnique(new DataProtocolHandler));
    request_context_->set_job_factory(&job_factory_);
  }

  NSURLResponse* BuildDataURLResponse(const std::string& mime_type,
                                      const std::string& encoding,
                                      const std::string& content) {
    // Build an URL in the form "data:<mime_type>;charset=<encoding>,<content>"
    // The ';' is removed if mime_type or charset is empty.
    std::string url_string = std::string("data:") + mime_type;
    if (!encoding.empty())
      url_string += ";charset=" + encoding;
    url_string += ",";
    GURL url(url_string);

    std::unique_ptr<URLRequest> request(
        request_context_->CreateRequest(url, DEFAULT_PRIORITY, this));
    request->Start();
    base::RunLoop loop;
    loop.RunUntilIdle();
    return GetNSURLResponseForRequest(request.get());
  }

  void CheckDataResponse(NSURLResponse* response,
                         const std::string& mime_type,
                         const std::string& encoding) {
    EXPECT_NSEQ(base::SysUTF8ToNSString(mime_type), [response MIMEType]);
    EXPECT_NSEQ(base::SysUTF8ToNSString(encoding), [response textEncodingName]);
    // The response class must be NSURLResponse (and not NSHTTPURLResponse) when
    // the scheme is "data".
    EXPECT_TRUE([response isMemberOfClass:[NSURLResponse class]]);
  }

  void OnResponseStarted(URLRequest* request, int net_error) override {}
  void OnReadCompleted(URLRequest* request, int bytes_read) override {}

 protected:
  base::MessageLoop loop_;
  URLRequestJobFactoryImpl job_factory_;
  std::unique_ptr<URLRequestContext> request_context_;
};

}  // namespace

TEST_F(ProtocolHandlerUtilTest, GetResponseDataSchemeTest) {
  NSURLResponse* response;
  // MIME type and charset are correctly carried over.
  response = BuildDataURLResponse("#mime=type'", "$(charset-*", "content");
  CheckDataResponse(response, "#mime=type'", "$(charset-*");
  // Missing values are treated as default values.
  response = BuildDataURLResponse("", "", "content");
  CheckDataResponse(response, kTextPlain, kAscii);
}

TEST_F(ProtocolHandlerUtilTest, GetResponseHttpTest) {
  // Create a request.
  GURL url(std::string("http://url"));
  std::unique_ptr<URLRequest> request(
      request_context_->CreateRequest(url, DEFAULT_PRIORITY, this));
  request->Start();
  // Create a response from the request.
  NSURLResponse* response = GetNSURLResponseForRequest(request.get());
  EXPECT_NSEQ([NSString stringWithUTF8String:kTextHtml], [response MIMEType]);
  ASSERT_TRUE([response isKindOfClass:[NSHTTPURLResponse class]]);
  NSHTTPURLResponse* http_response = (NSHTTPURLResponse*)response;
  NSDictionary* headers = [http_response allHeaderFields];
  // Check the headers, duplicates must be appended.
  EXPECT_EQ(5u, [headers count]);
  NSString* foo_header = [headers objectForKey:@"Foo"];
  EXPECT_NSEQ(@"A,D,E", foo_header);
  NSString* bar_header = [headers objectForKey:@"Bar"];
  EXPECT_NSEQ(@"B,F", bar_header);
  NSString* baz_header = [headers objectForKey:@"Baz"];
  EXPECT_NSEQ(@"C", baz_header);
  NSString* cache_header = [headers objectForKey:@"Cache-Control"];
  EXPECT_NSEQ(@"no-store", cache_header);  // Cache-Control is overridden.
  // Check the status.
  EXPECT_EQ(request->GetResponseCode(), [http_response statusCode]);
}

TEST_F(ProtocolHandlerUtilTest, BadHttpContentType) {
  // Create a request using the magic domain that triggers a garbage
  // content-type in the test framework.
  GURL url(std::string("http://badcontenttype"));
  std::unique_ptr<URLRequest> request(
      request_context_->CreateRequest(url, DEFAULT_PRIORITY, this));
  request->Start();
  // Create a response from the request.
  @try {
    GetNSURLResponseForRequest(request.get());
  }
  @catch (id exception) {
    FAIL() << "Exception while creating response";
  }
}

TEST_F(ProtocolHandlerUtilTest, MultipleHttpContentType) {
  // Create a request using the magic domain that triggers a garbage
  // content-type in the test framework.
  GURL url(std::string("http://multiplecontenttype"));
  std::unique_ptr<URLRequest> request(
      request_context_->CreateRequest(url, DEFAULT_PRIORITY, this));
  request->Start();
  // Create a response from the request.
  NSURLResponse* response = GetNSURLResponseForRequest(request.get());
  EXPECT_NSEQ(@"text/plain", [response MIMEType]);
  EXPECT_NSEQ(@"iso-8859-4", [response textEncodingName]);
  NSHTTPURLResponse* http_response = (NSHTTPURLResponse*)response;
  NSDictionary* headers = [http_response allHeaderFields];
  NSString* content_type_header = [headers objectForKey:@"Content-Type"];
  EXPECT_NSEQ(@"text/plain; charset=iso-8859-4", content_type_header);
}

TEST_F(ProtocolHandlerUtilTest, CopyHttpHeaders) {
  GURL url(std::string("http://url"));
  base::scoped_nsobject<NSMutableURLRequest> in_request(
      [[NSMutableURLRequest alloc] initWithURL:NSURLWithGURL(url)]);
  [in_request setAllHTTPHeaderFields:@{
      @"Referer" : @"referrer",
      @"User-Agent" : @"secret",
      @"Accept" : @"money/cash",
      @"Foo" : @"bar",
  }];
  std::unique_ptr<URLRequest> out_request(
      request_context_->CreateRequest(url, DEFAULT_PRIORITY, nullptr));
  CopyHttpHeaders(in_request, out_request.get());

  EXPECT_EQ("referrer", out_request->referrer());
  const HttpRequestHeaders& headers = out_request->extra_request_headers();
  EXPECT_FALSE(headers.HasHeader("User-Agent"));    // User agent is not copied.
  EXPECT_FALSE(headers.HasHeader("Content-Type"));  // Only in POST requests.
  std::string header;
  EXPECT_TRUE(headers.GetHeader("Accept", &header));
  EXPECT_EQ("money/cash", header);
  EXPECT_TRUE(headers.GetHeader("Foo", &header));
  EXPECT_EQ("bar", header);
}

TEST_F(ProtocolHandlerUtilTest, AddMissingHeaders) {
  GURL url(std::string("http://url"));
  base::scoped_nsobject<NSMutableURLRequest> in_request(
      [[NSMutableURLRequest alloc] initWithURL:NSURLWithGURL(url)]);
  std::unique_ptr<URLRequest> out_request(
      request_context_->CreateRequest(url, DEFAULT_PRIORITY, nullptr));
  out_request->set_method("POST");
  std::unique_ptr<UploadElementReader> reader(
      new UploadBytesElementReader(nullptr, 0));
  out_request->set_upload(
      ElementsUploadDataStream::CreateWithReader(std::move(reader), 0));
  CopyHttpHeaders(in_request, out_request.get());

  // Some headers are added by default if missing.
  const HttpRequestHeaders& headers = out_request->extra_request_headers();
  std::string header;
  EXPECT_TRUE(headers.GetHeader("Accept", &header));
  EXPECT_EQ("*/*", header);
  EXPECT_TRUE(headers.GetHeader("Content-Type", &header));
  EXPECT_EQ("application/x-www-form-urlencoded", header);
}

}  // namespace net
