/*
 * Copyright (C) 2003, 2006 Apple Computer, Inc.  All rights reserved.
 * Copyright (C) 2009, 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "platform/loader/fetch/ResourceRequest.h"

#include <memory>
#include "platform/HTTPNames.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "platform/network/NetworkUtils.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "platform/wtf/PtrUtil.h"
#include "public/platform/WebAddressSpace.h"
#include "public/platform/WebCachePolicy.h"
#include "public/platform/WebURLRequest.h"

namespace blink {

double ResourceRequest::default_timeout_interval_ = INT_MAX;

ResourceRequest::ResourceRequest() : ResourceRequest(KURL()) {}

ResourceRequest::ResourceRequest(const String& url_string)
    : ResourceRequest(KURL(kParsedURLString, url_string)) {}

ResourceRequest::ResourceRequest(const KURL& url)
    : url_(url),
      cache_policy_(WebCachePolicy::kUseProtocolCachePolicy),
      timeout_interval_(default_timeout_interval_),
      requestor_origin_(SecurityOrigin::CreateUnique()),
      http_method_(HTTPNames::GET),
      allow_stored_credentials_(true),
      report_upload_progress_(false),
      report_raw_headers_(false),
      has_user_gesture_(false),
      download_to_file_(false),
      use_stream_on_response_(false),
      should_reset_app_cache_(false),
      service_worker_mode_(WebURLRequest::ServiceWorkerMode::kAll),
      priority_(kResourceLoadPriorityLowest),
      intra_priority_value_(0),
      requestor_id_(0),
      requestor_process_id_(0),
      app_cache_host_id_(0),
      request_context_(WebURLRequest::kRequestContextUnspecified),
      frame_type_(WebURLRequest::kFrameTypeNone),
      fetch_request_mode_(WebURLRequest::kFetchRequestModeNoCORS),
      fetch_credentials_mode_(WebURLRequest::kFetchCredentialsModeInclude),
      fetch_redirect_mode_(WebURLRequest::kFetchRedirectModeFollow),
      previews_state_(WebURLRequest::kPreviewsUnspecified),
      referrer_policy_(kReferrerPolicyDefault),
      did_set_http_referrer_(false),
      check_for_browser_side_navigation_(true),
      ui_start_time_(0),
      is_external_request_(false),
      loading_ipc_type_(RuntimeEnabledFeatures::loadingWithMojoEnabled()
                            ? WebURLRequest::LoadingIPCType::kMojo
                            : WebURLRequest::LoadingIPCType::kChromeIPC),
      is_same_document_navigation_(false),
      input_perf_metric_report_policy_(
          InputToLoadPerfMetricReportPolicy::kNoReport),
      redirect_status_(RedirectStatus::kNoRedirect) {}

ResourceRequest::ResourceRequest(CrossThreadResourceRequestData* data)
    : ResourceRequest(data->url_) {
  SetCachePolicy(data->cache_policy_);
  SetTimeoutInterval(data->timeout_interval_);
  SetFirstPartyForCookies(data->first_party_for_cookies_);
  SetRequestorOrigin(data->requestor_origin_);
  SetHTTPMethod(AtomicString(data->http_method_));
  SetPriority(data->priority_, data->intra_priority_value_);

  http_header_fields_.Adopt(std::move(data->http_headers_));

  SetHTTPBody(data->http_body_);
  SetAttachedCredential(data->attached_credential_);
  SetAllowStoredCredentials(data->allow_stored_credentials_);
  SetReportUploadProgress(data->report_upload_progress_);
  SetHasUserGesture(data->has_user_gesture_);
  SetDownloadToFile(data->download_to_file_);
  SetUseStreamOnResponse(data->use_stream_on_response_);
  SetServiceWorkerMode(data->service_worker_mode_);
  SetShouldResetAppCache(data->should_reset_app_cache_);
  SetRequestorID(data->requestor_id_);
  SetRequestorProcessID(data->requestor_process_id_);
  SetAppCacheHostID(data->app_cache_host_id_);
  SetRequestContext(data->request_context_);
  SetFrameType(data->frame_type_);
  SetFetchRequestMode(data->fetch_request_mode_);
  SetFetchCredentialsMode(data->fetch_credentials_mode_);
  SetFetchRedirectMode(data->fetch_redirect_mode_);
  SetPreviewsState(data->previews_state_);
  referrer_policy_ = data->referrer_policy_;
  did_set_http_referrer_ = data->did_set_http_referrer_;
  check_for_browser_side_navigation_ = data->check_for_browser_side_navigation_;
  ui_start_time_ = data->ui_start_time_;
  is_external_request_ = data->is_external_request_;
  loading_ipc_type_ = data->loading_ipc_type_;
  input_perf_metric_report_policy_ = data->input_perf_metric_report_policy_;
  redirect_status_ = data->redirect_status_;
}

ResourceRequest::ResourceRequest(const ResourceRequest&) = default;

ResourceRequest& ResourceRequest::operator=(const ResourceRequest&) = default;

std::unique_ptr<CrossThreadResourceRequestData> ResourceRequest::CopyData()
    const {
  std::unique_ptr<CrossThreadResourceRequestData> data =
      WTF::MakeUnique<CrossThreadResourceRequestData>();
  data->url_ = Url().Copy();
  data->cache_policy_ = GetCachePolicy();
  data->timeout_interval_ = TimeoutInterval();
  data->first_party_for_cookies_ = FirstPartyForCookies().Copy();
  data->requestor_origin_ =
      RequestorOrigin() ? RequestorOrigin()->IsolatedCopy() : nullptr;
  data->http_method_ = HttpMethod().GetString().IsolatedCopy();
  data->http_headers_ = HttpHeaderFields().CopyData();
  data->priority_ = Priority();
  data->intra_priority_value_ = intra_priority_value_;

  if (http_body_)
    data->http_body_ = http_body_->DeepCopy();
  if (attached_credential_)
    data->attached_credential_ = attached_credential_->DeepCopy();
  data->allow_stored_credentials_ = allow_stored_credentials_;
  data->report_upload_progress_ = report_upload_progress_;
  data->has_user_gesture_ = has_user_gesture_;
  data->download_to_file_ = download_to_file_;
  data->use_stream_on_response_ = use_stream_on_response_;
  data->service_worker_mode_ = service_worker_mode_;
  data->should_reset_app_cache_ = should_reset_app_cache_;
  data->requestor_id_ = requestor_id_;
  data->requestor_process_id_ = requestor_process_id_;
  data->app_cache_host_id_ = app_cache_host_id_;
  data->request_context_ = request_context_;
  data->frame_type_ = frame_type_;
  data->fetch_request_mode_ = fetch_request_mode_;
  data->fetch_credentials_mode_ = fetch_credentials_mode_;
  data->fetch_redirect_mode_ = fetch_redirect_mode_;
  data->previews_state_ = previews_state_;
  data->referrer_policy_ = referrer_policy_;
  data->did_set_http_referrer_ = did_set_http_referrer_;
  data->check_for_browser_side_navigation_ = check_for_browser_side_navigation_;
  data->ui_start_time_ = ui_start_time_;
  data->is_external_request_ = is_external_request_;
  data->loading_ipc_type_ = loading_ipc_type_;
  data->input_perf_metric_report_policy_ = input_perf_metric_report_policy_;
  data->redirect_status_ = redirect_status_;
  return data;
}

bool ResourceRequest::IsEmpty() const {
  return url_.IsEmpty();
}

bool ResourceRequest::IsNull() const {
  return url_.IsNull();
}

const KURL& ResourceRequest::Url() const {
  return url_;
}

void ResourceRequest::SetURL(const KURL& url) {
  url_ = url;
}

void ResourceRequest::RemoveUserAndPassFromURL() {
  if (url_.User().IsEmpty() && url_.Pass().IsEmpty())
    return;

  url_.SetUser(String());
  url_.SetPass(String());
}

WebCachePolicy ResourceRequest::GetCachePolicy() const {
  return cache_policy_;
}

void ResourceRequest::SetCachePolicy(WebCachePolicy cache_policy) {
  cache_policy_ = cache_policy;
}

double ResourceRequest::TimeoutInterval() const {
  return timeout_interval_;
}

void ResourceRequest::SetTimeoutInterval(double timout_interval_seconds) {
  timeout_interval_ = timout_interval_seconds;
}

const KURL& ResourceRequest::FirstPartyForCookies() const {
  return first_party_for_cookies_;
}

void ResourceRequest::SetFirstPartyForCookies(
    const KURL& first_party_for_cookies) {
  first_party_for_cookies_ = first_party_for_cookies;
}

PassRefPtr<SecurityOrigin> ResourceRequest::RequestorOrigin() const {
  return requestor_origin_;
}

void ResourceRequest::SetRequestorOrigin(
    PassRefPtr<SecurityOrigin> requestor_origin) {
  requestor_origin_ = std::move(requestor_origin);
}

const AtomicString& ResourceRequest::HttpMethod() const {
  return http_method_;
}

void ResourceRequest::SetHTTPMethod(const AtomicString& http_method) {
  http_method_ = http_method;
}

const HTTPHeaderMap& ResourceRequest::HttpHeaderFields() const {
  return http_header_fields_;
}

const AtomicString& ResourceRequest::HttpHeaderField(
    const AtomicString& name) const {
  return http_header_fields_.Get(name);
}

void ResourceRequest::SetHTTPHeaderField(const AtomicString& name,
                                         const AtomicString& value) {
  http_header_fields_.Set(name, value);
}

void ResourceRequest::SetHTTPReferrer(const Referrer& referrer) {
  if (referrer.referrer.IsEmpty())
    http_header_fields_.Remove(HTTPNames::Referer);
  else
    SetHTTPHeaderField(HTTPNames::Referer, referrer.referrer);
  referrer_policy_ = referrer.referrer_policy;
  did_set_http_referrer_ = true;
}

void ResourceRequest::ClearHTTPReferrer() {
  http_header_fields_.Remove(HTTPNames::Referer);
  referrer_policy_ = kReferrerPolicyDefault;
  did_set_http_referrer_ = false;
}

void ResourceRequest::SetHTTPOrigin(const SecurityOrigin* origin) {
  SetHTTPHeaderField(HTTPNames::Origin, origin->ToAtomicString());
  if (origin->HasSuborigin()) {
    SetHTTPHeaderField(HTTPNames::Suborigin,
                       AtomicString(origin->GetSuborigin()->GetName()));
  }
}

void ResourceRequest::ClearHTTPOrigin() {
  http_header_fields_.Remove(HTTPNames::Origin);
  http_header_fields_.Remove(HTTPNames::Suborigin);
}

void ResourceRequest::AddHTTPOriginIfNeeded(const SecurityOrigin* origin) {
  if (NeedsHTTPOrigin())
    SetHTTPOrigin(origin);
}

void ResourceRequest::AddHTTPOriginIfNeeded(const String& origin_string) {
  if (NeedsHTTPOrigin())
    SetHTTPOrigin(SecurityOrigin::CreateFromString(origin_string).Get());
}

void ResourceRequest::ClearHTTPUserAgent() {
  http_header_fields_.Remove(HTTPNames::User_Agent);
}

EncodedFormData* ResourceRequest::HttpBody() const {
  return http_body_.Get();
}

void ResourceRequest::SetHTTPBody(PassRefPtr<EncodedFormData> http_body) {
  http_body_ = std::move(http_body);
}

EncodedFormData* ResourceRequest::AttachedCredential() const {
  return attached_credential_.Get();
}

void ResourceRequest::SetAttachedCredential(
    PassRefPtr<EncodedFormData> attached_credential) {
  attached_credential_ = std::move(attached_credential);
}

bool ResourceRequest::AllowStoredCredentials() const {
  return allow_stored_credentials_;
}

void ResourceRequest::SetAllowStoredCredentials(bool allow_credentials) {
  allow_stored_credentials_ = allow_credentials;
}

ResourceLoadPriority ResourceRequest::Priority() const {
  return priority_;
}

void ResourceRequest::SetPriority(ResourceLoadPriority priority,
                                  int intra_priority_value) {
  priority_ = priority;
  intra_priority_value_ = intra_priority_value;
}

void ResourceRequest::AddHTTPHeaderField(const AtomicString& name,
                                         const AtomicString& value) {
  HTTPHeaderMap::AddResult result = http_header_fields_.Add(name, value);
  if (!result.is_new_entry)
    result.stored_value->value = result.stored_value->value + ", " + value;
}

void ResourceRequest::AddHTTPHeaderFields(const HTTPHeaderMap& header_fields) {
  HTTPHeaderMap::const_iterator end = header_fields.end();
  for (HTTPHeaderMap::const_iterator it = header_fields.begin(); it != end;
       ++it)
    AddHTTPHeaderField(it->key, it->value);
}

void ResourceRequest::ClearHTTPHeaderField(const AtomicString& name) {
  http_header_fields_.Remove(name);
}

void ResourceRequest::SetExternalRequestStateFromRequestorAddressSpace(
    WebAddressSpace requestor_space) {
  static_assert(kWebAddressSpaceLocal < kWebAddressSpacePrivate,
                "Local is inside Private");
  static_assert(kWebAddressSpaceLocal < kWebAddressSpacePublic,
                "Local is inside Public");
  static_assert(kWebAddressSpacePrivate < kWebAddressSpacePublic,
                "Private is inside Public");

  // TODO(mkwst): This only checks explicit IP addresses. We'll have to move all
  // this up to //net and //content in order to have any real impact on gateway
  // attacks. That turns out to be a TON of work. https://crbug.com/378566
  if (!RuntimeEnabledFeatures::corsRFC1918Enabled()) {
    is_external_request_ = false;
    return;
  }

  WebAddressSpace target_space = kWebAddressSpacePublic;
  if (NetworkUtils::IsReservedIPAddress(url_.Host()))
    target_space = kWebAddressSpacePrivate;
  if (SecurityOrigin::Create(url_)->IsLocalhost())
    target_space = kWebAddressSpaceLocal;

  is_external_request_ = requestor_space > target_space;
}

void ResourceRequest::SetNavigationStartTime(double navigation_start) {
  navigation_start_ = navigation_start;
}

bool ResourceRequest::IsConditional() const {
  return (http_header_fields_.Contains(HTTPNames::If_Match) ||
          http_header_fields_.Contains(HTTPNames::If_Modified_Since) ||
          http_header_fields_.Contains(HTTPNames::If_None_Match) ||
          http_header_fields_.Contains(HTTPNames::If_Range) ||
          http_header_fields_.Contains(HTTPNames::If_Unmodified_Since));
}

void ResourceRequest::SetHasUserGesture(bool has_user_gesture) {
  has_user_gesture_ |= has_user_gesture;
}

const CacheControlHeader& ResourceRequest::GetCacheControlHeader() const {
  if (!cache_control_header_cache_.parsed) {
    cache_control_header_cache_ = ParseCacheControlDirectives(
        http_header_fields_.Get(HTTPNames::Cache_Control),
        http_header_fields_.Get(HTTPNames::Pragma));
  }
  return cache_control_header_cache_;
}

bool ResourceRequest::CacheControlContainsNoCache() const {
  return GetCacheControlHeader().contains_no_cache;
}

bool ResourceRequest::CacheControlContainsNoStore() const {
  return GetCacheControlHeader().contains_no_store;
}

bool ResourceRequest::HasCacheValidatorFields() const {
  return !http_header_fields_.Get(HTTPNames::Last_Modified).IsEmpty() ||
         !http_header_fields_.Get(HTTPNames::ETag).IsEmpty();
}

bool ResourceRequest::NeedsHTTPOrigin() const {
  if (!HttpOrigin().IsEmpty())
    return false;  // Request already has an Origin header.

  // Don't send an Origin header for GET or HEAD to avoid privacy issues.
  // For example, if an intranet page has a hyperlink to an external web
  // site, we don't want to include the Origin of the request because it
  // will leak the internal host name. Similar privacy concerns have lead
  // to the widespread suppression of the Referer header at the network
  // layer.
  if (HttpMethod() == HTTPNames::GET || HttpMethod() == HTTPNames::HEAD)
    return false;

  // For non-GET and non-HEAD methods, always send an Origin header so the
  // server knows we support this feature.
  return true;
}

}  // namespace blink
