/*
 * Copyright 2017 The Cobalt Authors. All Rights Reserved.
 *
 * 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.
 */

#include <algorithm>
#include <cstring>
#include <iterator>
#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "cobalt/loader/cors_preflight.h"
#include "starboard/common/string.h"

namespace cobalt {
namespace loader {

namespace {
// definition of the following headers can be found at:
// https://fetch.spec.whatwg.org/#http-access-control-allow-origin
const char* kOriginheadername = "Origin: ";
const char* kAccessControlRequestMethod = "Access-Control-Request-Method: ";
const char* kAccessControlRequestHeaders = "Access-Control-Request-Headers: ";
const char* kAccessControlAllowOrigin = "Access-Control-Allow-Origin";
const char* kAccessControlAllowMethod = "Access-Control-Allow-Methods";
const char* kAccessControlAllowHeaders = "Access-Control-Allow-Headers";
const char* kAccessControlAllowCredentials = "Access-Control-Allow-Credentials";
const char* kAccessControlMaxAge = "Access-Control-Max-Age";
// https://fetch.spec.whatwg.org/#http-access-control-expose-headers
const char* kAccessControlExposeHeaders = "Access-Control-Expose-Headers";

// The following constants are used to decide if a request or response header is
// safe or not.
const char* kCORSSafelistedRequestHeaders[] = {"accept", "accept-language",
                                               "content-language"};
const char* kAllowedMIMEType[] = {"application/x-www-form-urlencoded",
                                  "multipart/form-data", "text/plain"};
const char* kSafelistedHeadernofail[] = {"dpr", "downlink", "save-data",
                                         "viewport-width", "width"};
const char* kContentType = "content-type";
const char* kAuthorization = "authorization";
const char* kMethodNames[] = {"GET",    "POST", "HEAD",
                              "DELETE", "PUT",  "OPTIONS"};
const char* kCORSSafelistedResponseHeaders[] = {
    "cache-control", "content-language", "content-type",
    "expires",       "last-modified",    "pragma"};
const char* kForbiddenHeaders[] = {"accept-charset",
                                   "accept-encoding",
                                   "access-control-request-headers",
                                   "access-control-request-method",
                                   "connection",
                                   "content-length",
                                   "cookie",
                                   "cookie2",
                                   "date",
                                   "dnt",
                                   "expect",
                                   "host",
                                   "keep-alive",
                                   "origin",
                                   "referer",
                                   "te",
                                   "trailer",
                                   "transfer-encoding",
                                   "upgrade",
                                   "via"};

// Returns true if input method is a CORS-safelisted method.
bool IsCORSSafelistedMethod(net::URLFetcher::RequestType input_type) {
  if (input_type == net::URLFetcher::GET ||
      input_type == net::URLFetcher::HEAD ||
      input_type == net::URLFetcher::POST) {
    return true;
  }
  return false;
}

#if __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
const char* RequestTypeToMethodName(net::URLFetcher::RequestType request_type) {
  if (request_type >= 0 && request_type < arraysize(kMethodNames)) {
    return kMethodNames[request_type];
  } else {
    NOTREACHED();
    return "";
  }
}
#if __clang__
#pragma clang diagnostic push
#endif

// This constant is an imposed limit on the time an entry can be alive in
// the preflight cache if the provided max-age value is even greater.
// The number is the same as the limit in WebKit.
const int kPreflightCacheMaxAgeLimit = 600;

// This helper function checks if 'input_str' is in 'array' up to 'size'.
bool IsInArray(const char* input_str, const char* array[], size_t size) {
  if (!input_str || *input_str == '\0') {
    return false;
  }
  for (size_t i = 0; i < size; ++i) {
    if (SbStringCompareNoCase(input_str, array[i]) == 0) {
      return true;
    }
  }
  return false;
}

// Returns true if there is a case-insensitive match of 'find_value_name' in
// 'field_values'.
bool HasFieldValue(const std::vector<std::string>& field_values,
                   const std::string& find_value_name) {
  for (size_t i = 0; i < field_values.size(); i++) {
    if (field_values[i].empty()) {
      continue;
    }
    if (SbStringCompareNoCase(field_values[i].c_str(),
                              find_value_name.c_str()) == 0) {
      return true;
    }
  }
  return false;
}
}  // namespace

CORSPreflight::CORSPreflight(GURL url, net::URLFetcher::RequestType method,
                             const network::NetworkModule* network_module,
                             base::Closure success_callback, std::string origin,
                             base::Closure error_callback,
                             scoped_refptr<CORSPreflightCache> preflight_cache)
    : credentials_mode_is_include_(false),
      force_preflight_(false),
      url_(url),
      method_(method),
      network_module_(network_module),
      origin_(origin),
      error_callback_(error_callback),
      success_callback_(success_callback),
      preflight_cache_(preflight_cache) {
  DCHECK(!url_.is_empty());
  DCHECK(preflight_cache);
}

// https://fetch.spec.whatwg.org/#cors-safelisted-request-header
bool CORSPreflight::IsSafeRequestHeader(const std::string& name,
                                        const std::string& value) {
  // All comparison are case-insensitive.
  // Header is safe if it's CORS-safelisted request-header.
  if (IsInArray(name.c_str(), kCORSSafelistedRequestHeaders,
                arraysize(kCORSSafelistedRequestHeaders))) {
    return true;
  }

  // Safe if header name is 'Content-Type' and value is a match of
  // kAllowedMIMEType.
  if (SbStringCompareNoCase(name.c_str(), kContentType) == 0) {
    std::vector<std::string> content_type_split = base::SplitString(
        value, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
    auto begin_iter = content_type_split[0].cbegin();
    auto end_iter = content_type_split[0].cend();
    net::HttpUtil::TrimLWS(&begin_iter, &end_iter);
    std::string content_type_no_space(begin_iter, end_iter);
    if (IsInArray(content_type_no_space.c_str(), kAllowedMIMEType,
                  arraysize(kAllowedMIMEType))) {
      return true;
    }
  }
  // Safe if name is a match for kSafelistedHeadernofail and whose value, once
  // extracted, is not failure.
  if (IsInArray(name.c_str(), kSafelistedHeadernofail,
                arraysize(kSafelistedHeadernofail))) {
    // TODO: The extracting and verify result is not failure is not done yet.
    // https://fetch.spec.whatwg.org/#extract-header-values
    return true;
  }
  return false;
}

// https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name
bool CORSPreflight::IsSafeResponseHeader(
    const std::string& name,
    const std::vector<std::string>& CORS_exposed_header_name_list,
    bool credentials_mode_is_include) {
  // Every check in this function is case-insensitive comparison.
  // Header is safe if it's CORS-safelisted repsonse-header name.
  if (IsInArray(name.c_str(), kCORSSafelistedResponseHeaders,
                arraysize(kCORSSafelistedResponseHeaders))) {
    return true;
  }
  // It's not safe if it's a forbidden header name.
  if (IsInArray(name.c_str(), kForbiddenHeaders,
                arraysize(kForbiddenHeaders))) {
    return false;
  }
  // The following two steps checks if given header name is in CORS-exposed
  // header-name list. If Access-Control-Expose-Headers header is '*', all
  // header names in reponse should be in CORS-exposed header-name list.
  if (CORS_exposed_header_name_list.size() == 1 &&
      CORS_exposed_header_name_list.at(0) == "*" &&
      !credentials_mode_is_include) {
    return true;
  }

  for (size_t i = 0; i < CORS_exposed_header_name_list.size(); i++) {
    if (SbStringCompareNoCase(CORS_exposed_header_name_list.at(i).c_str(),
                              name.c_str()) == 0) {
      return true;
    }
  }
  return false;
}

void CORSPreflight::GetServerAllowedHeaders(
    const net::HttpResponseHeaders& response_headers,
    std::vector<std::string>* expose_headers) {
  size_t iter = 0;
  std::string exposable_header;
  while (response_headers.EnumerateHeader(&iter, kAccessControlExposeHeaders,
                                          &exposable_header)) {
    expose_headers->push_back(exposable_header);
  }
}

bool CORSPreflight::IsPreflightNeeded() {
  // Send preflight if force_preflight flag is on.
  if (force_preflight_) {
    return true;
  }
  // Preflight is not needed if the request method is CORS-safelisted request
  // method and all headers are CORS-safelisted request-header.
  std::vector<std::string> unsafe_headers;
  if (method_ == net::URLFetcher::GET || method_ == net::URLFetcher::HEAD ||
      method_ == net::URLFetcher::POST) {
    net::HttpRequestHeaders::Iterator it(headers_);
    while (it.GetNext()) {
      if (!IsSafeRequestHeader(it.name(), it.value())) {
        unsafe_headers.push_back(it.name());
      }
    }
    if (unsafe_headers.empty()) {
      return false;
    }
  }
  // Check preflight cache for match.
  return !preflight_cache_->HaveEntry(url_.spec(), origin_,
                                      credentials_mode_is_include_, method_,
                                      unsafe_headers);
}

bool CORSPreflight::Send() {
  if (!IsPreflightNeeded()) {
    return false;
  }
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  // https://fetch.spec.whatwg.org/#cors-preflight-fetch-0

  // 1. Let preflight be a new request whose method is 'OPTIONS', url is
  //    request's current url, initiator is request's initiator, type is
  //    request's type, destination is request's destination, origin is
  //    request's origin, referrer is request's referrer, and referrer
  //    policy is request's referrer policy.
  url_fetcher_ = net::URLFetcher::Create(url_, net::URLFetcher::OPTIONS, this);
  url_fetcher_->SetRequestContext(
      network_module_->url_request_context_getter().get());
  url_fetcher_->AddExtraRequestHeader(kOriginheadername + origin_);
  // 3. Let headers be the names of request's header list's headers,
  //    excluding CORS-safelisted request-headers and duplicates, sorted
  //    lexicographically, and byte-lowercased.
  // 4. If headers is not empty, then:
  //    Let value be the items in headers separated from each other
  //    by `,`. Set `Access-Control-Request-Headers` to value in
  //    preflight's header list.
  if (!headers_.IsEmpty()) {
    net::HttpRequestHeaders::Iterator it(headers_);
    std::string headers_string;
    while (it.GetNext()) {
      if (!headers_string.empty()) {
        headers_string += ',';
      }
      headers_string += it.name();
    }
    url_fetcher_->AddExtraRequestHeader(kAccessControlRequestHeaders +
                                        headers_string);
  }
  // 2. Set `Access-Control-Request-Method` to request's method in
  //    preflight's header list.
  url_fetcher_->AddExtraRequestHeader(std::string(kAccessControlRequestMethod) +
                                      RequestTypeToMethodName(method_));
  // 5. Let response be the result of performing an HTTP-network-or-
  //    cache fetch using preflight.
  Start();
  return true;
}

void CORSPreflight::Start() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  // Preflight does not allow redirect, status 300+ should not fail
  url_fetcher_->SetStopOnRedirect(true);
  url_fetcher_->Start();
}

void CORSPreflight::OnURLFetchComplete(const net::URLFetcher* source) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  if (source->GetStatus().status() != net::URLRequestStatus::SUCCESS) {
    error_callback_.Run();
    return;
  }

  // Preflight response check:
  // Procedure 6 of https://fetch.spec.whatwg.org/#cors-preflight-fetch-0

  if (source->GetResponseHeaders()) {
    net::HttpResponseHeaders* response_headers = source->GetResponseHeaders();
    std::string methods, headernames;
    // If status is not ok status, return network error
    if (!CORSCheck(*response_headers, origin_, credentials_mode_is_include_) ||
        source->GetResponseCode() < 200 || source->GetResponseCode() > 299) {
      error_callback_.Run();
      return;
    }
    // 3. Let headerNames be the result of extracting header list values given
    // `Access-Control-Allow-Headers` and response's header list.
    if (!response_headers->GetNormalizedHeader(kAccessControlAllowMethod,
                                               &methods)) {
      // 6. If methods is null and request's use-CORS-preflight flag is set,
      //    then set methods to a new list containing request's method.
      if (force_preflight_) {
        methods = RequestTypeToMethodName(method_);
      }
    }
    response_headers->GetNormalizedHeader(kAccessControlAllowHeaders,
                                          &headernames);
    // 5. If methods or headerNames contains `*`, and request's credentials mode
    //    is "include", then return a network error.
    std::vector<std::string> methods_vec = base::SplitString(
        methods, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
    std::vector<std::string> headernames_vec = base::SplitString(
        headernames, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
    if ((HasFieldValue(methods_vec, "*") ||
         HasFieldValue(headernames_vec, "*")) &&
        credentials_mode_is_include_) {
      error_callback_.Run();
      return;
    }  // 7. If request's method is not in methods, is not a CORS-safelisted
    //    method, and methods does not contain `*`, then return a network error.
    if (!HasFieldValue(methods_vec, RequestTypeToMethodName(method_)) &&
        !IsCORSSafelistedMethod(method_) && !HasFieldValue(methods_vec, "*")) {
      error_callback_.Run();
      return;
    }
    // 8. If one of request's header list's names is a CORS non-wildcard
    //    request-header name and is not a byte-case-insensitive match for an
    //    item in headerNames, then return a network error.
    // 9. If one of request's header list' names is not a byte-case-insensitive
    //    match for an item in headerNames, its corresponding header is not a
    //    CORS-safelisted request-header, and headerNames does not contain `*`,
    //    then return a network error.
    net::HttpRequestHeaders::Iterator it(headers_);
    while (it.GetNext()) {
      if (HasFieldValue(headernames_vec, it.name())) {
        continue;
      }
      if (SbStringCompareNoCase(it.name().c_str(), kAuthorization) == 0 ||
          (!HasFieldValue(headernames_vec, "*") &&
           !IsSafeRequestHeader(it.name(), it.value()))) {
        error_callback_.Run();
        return;
      }
    }
    // step 10-18 for adding entry to preflight cache.
    std::string max_age_str;
    int max_age = 0;
    if (response_headers->GetNormalizedHeader(kAccessControlMaxAge,
                                              &max_age_str)) {
      max_age = std::min(SbStringAToI(max_age_str.c_str()),
                         kPreflightCacheMaxAgeLimit);
    }
    preflight_cache_->AppendEntry(source->GetURL().spec(), origin_, max_age,
                                  credentials_mode_is_include_, methods_vec,
                                  headernames_vec);
  } else {
    DLOG(ERROR) << "CORS preflight did not get response headers";
    error_callback_.Run();
  }

  success_callback_.Run();
}

// https://fetch.spec.whatwg.org/#concept-cors-check
bool CORSPreflight::CORSCheck(const net::HttpResponseHeaders& response_headers,
                              const std::string& serialized_origin,
                              bool credentials_mode_is_include) {
  // 1. Let origin be the result of extracting header list values given `Access-
  //    Control-Allow-Origin` and response's header list.
  std::string allowed_origin, empty_container, allow_credentials;
  size_t iter = 0;
  if (!response_headers.EnumerateHeader(&iter, kAccessControlAllowOrigin,
                                        &allowed_origin)) {
    DLOG(WARNING) << "Insecure cross-origin network request returned response "
                     "with no Access-Control-Allow-Origin header. Request "
                     "aborted.";
    return false;
  }
  DCHECK(iter);
  if (response_headers.EnumerateHeader(&iter, kAccessControlAllowOrigin,
                                       &empty_container)) {
    DLOG(WARNING) << "Insecure cross-origin network request returned response "
                     "with multiple Access-Control-Allow-Origin headers. "
                     "Behavior disallowed and request aborted";
    return false;
  }
  // 3. If request's credentials mode is not "include" and origin is `*`, return
  //    success.
  if (!credentials_mode_is_include && allowed_origin == "*") {
    return true;
  }
  // 2. If origin is null or failure, return failure.
  if (allowed_origin.empty()) {
    return false;
  }
  // 4. If request's origin, serialized and UTF-8 encoded, is not origin, return
  //    failure.
  if (allowed_origin != serialized_origin) {
    DLOG(WARNING) << "Network request origin is not allowed by server's "
                     "Access-Control-Allow-Origin header, request aborted.";
    return false;
  }
  // 5. If request's credentials mode is not "include", return success.
  if (!credentials_mode_is_include) {
    return true;
  }
  // 6. Let credentials be the result of extracting header list values given
  //    `Access-Control-Allow-Credentials` and response's header list.
  if (response_headers.GetNormalizedHeader(kAccessControlAllowCredentials,
                                           &allow_credentials)) {
    // 7. If credentials is `true`, return success.
    if (allow_credentials != "true") {
      DLOG(WARNING)
          << "Network request failed because request want to include credential"
             "but server disallow it.";
      return false;
    } else {
      return true;
    }
  }
  return false;
}

}  // namespace loader
}  // namespace cobalt
