/*
 * Copyright (C) 2009, 2012 Google Inc. All rights reserved.
 * Copyright (C) 2013, Intel Corporation
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "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 THE COPYRIGHT
 * OWNER 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.
 */

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_THREADABLE_LOADER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_THREADABLE_LOADER_H_

#include <memory>

#include "base/macros.h"
#include "services/network/public/mojom/fetch_api.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/cross_thread_copier.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/loader/fetch/raw_resource.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_error.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
#include "third_party/blink/renderer/platform/network/http_header_map.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/weborigin/referrer.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/time.h"

namespace blink {

class ExecutionContext;
class Document;
class KURL;
class ResourceRequest;
class SecurityOrigin;
class ThreadableLoaderClient;

// Useful for doing loader operations from any thread (not threadsafe, just able
// to run on threads other than the main thread).
//
// Can perform requests either synchronously or asynchronously. Requests are
// asynchronous by default, and this behavior can be controlled by passing
// a ResourceLoaderOptions with synchronous_policy == kRequestSynchronously to
// the constructor.
// In either case, Start() must be called to actaully begin the request.
class CORE_EXPORT ThreadableLoader final
    : public GarbageCollectedFinalized<ThreadableLoader>,
      private RawResourceClient {
  USING_GARBAGE_COLLECTED_MIXIN(ThreadableLoader);

 public:
  // ThreadableLoaderClient methods are never called before Start() call.
  //
  // Loading is separated into the constructor and the Start() method in order
  // to:
  // - reduce work done in a constructor
  // - not to ask the users to handle failures in the constructor and other
  //   async failures separately
  //
  // Loading completes when one of the following methods are called:
  // - DidFinishLoading()
  // - DidFail()
  // - DidFailAccessControlCheck()
  // - DidFailRedirectCheck()
  // After any of these methods is called, the loader won't call any of the
  // ThreadableLoaderClient methods.
  //
  // When ThreadableLoader::Cancel() is called,
  // ThreadableLoaderClient::DidFail() is called with a ResourceError
  // with IsCancellation() returning true, if any of DidFinishLoading()
  // or DidFail.*() methods have not been called yet. (DidFail() may be
  // called with a ResourceError with IsCancellation() returning true
  // also for cancellation happened inside the loader.)
  //
  // ThreadableLoaderClient methods may call Cancel().
  //
  // The specified ResourceFetcher if non-null, or otherwise
  // ExecutionContext::Fetcher() is used.
  ThreadableLoader(ExecutionContext&,
                   ThreadableLoaderClient*,
                   const ResourceLoaderOptions&,
                   ResourceFetcher* = nullptr);
  ~ThreadableLoader() override;

  // Exposed for testing. Code outside this class should not call this function.
  static std::unique_ptr<ResourceRequest>
  CreateAccessControlPreflightRequestForTesting(const ResourceRequest&);

  // Must be called to actually begin the request.
  void Start(const ResourceRequest&);

  // A ThreadableLoader may have a timeout specified. It is possible, in some
  // cases, for the timeout to be overridden after the request is sent (for
  // example, XMLHttpRequests may override their timeout setting after sending).
  //
  // If the request has already started, the new timeout will be relative to the
  // time the request started.
  //
  // Passing a timeout of zero means there should be no timeout.
  void SetTimeout(const TimeDelta& timeout);

  void Cancel();

  // Detach the loader from the request. This ffunction is for "keepalive"
  // requests. No notification will be sent to the client, but the request
  // will be processed.
  void Detach();

  void SetDefersLoading(bool);

  void Trace(blink::Visitor* visitor) override;

 private:
  class AssignOnScopeExit;
  class DetachedClient;

  static std::unique_ptr<ResourceRequest> CreateAccessControlPreflightRequest(
      const ResourceRequest&,
      const SecurityOrigin*);

  void Clear();

  // ResourceClient
  void NotifyFinished(Resource*) override;

  String DebugName() const override { return "ThreadableLoader"; }

  // RawResourceClient
  void DataSent(Resource*,
                unsigned long long bytes_sent,
                unsigned long long total_bytes_to_be_sent) override;
  void ResponseReceived(Resource*,
                        const ResourceResponse&,
                        std::unique_ptr<WebDataConsumerHandle>) override;
  void SetSerializedCachedMetadata(Resource*, const char*, size_t) override;
  void DataReceived(Resource*, const char* data, size_t data_length) override;
  bool RedirectReceived(Resource*,
                        const ResourceRequest&,
                        const ResourceResponse&) override;
  void RedirectBlocked() override;
  void DataDownloaded(Resource*, int) override;
  void DidReceiveResourceTiming(Resource*, const ResourceTimingInfo&) override;
  void DidDownloadToBlob(Resource*, scoped_refptr<BlobDataHandle>) override;

  // Notify Inspector and log to console about resource response. Use this
  // method if response is not going to be finished normally.
  void ReportResponseReceived(unsigned long identifier,
                              const ResourceResponse&);

  void DidTimeout(TimerBase*);
  // Calls the appropriate loading method according to policy and data about
  // origin. Only for handling the initial load (including fallback after
  // consulting ServiceWorker).
  void DispatchInitialRequest(ResourceRequest&);
  void MakeCrossOriginAccessRequest(const ResourceRequest&);

  // Loads m_fallbackRequestForServiceWorker.
  void LoadFallbackRequestForServiceWorker();
  // Issues a CORS preflight.
  void LoadPreflightRequest(const ResourceRequest&,
                            const ResourceLoaderOptions&);
  // Loads actual_request_.
  void LoadActualRequest();
  // Clears actual_request_ and reports access control check failure to
  // m_client.
  void HandlePreflightFailure(const KURL&, const network::CorsErrorStatus&);
  // Investigates the response for the preflight request. If successful,
  // the actual request will be made later in NotifyFinished().
  void HandlePreflightResponse(const ResourceResponse&);

  void DispatchDidFail(const ResourceError&);

  void PrepareCrossOriginRequest(ResourceRequest&) const;

  // This method modifies the ResourceRequest by calling
  // SetAllowStoredCredentials() on it based on same-origin-ness and the
  // credentials mode.
  //
  // This method configures the ResourceLoaderOptions so that the underlying
  // ResourceFetcher doesn't perform some part of the CORS logic since this
  // class performs it by itself.
  void LoadRequest(ResourceRequest&, ResourceLoaderOptions);

  const SecurityOrigin* GetSecurityOrigin() const;

  // Returns null if the loader is not associated with Document.
  // TODO(kinuko): Remove dependency to document.
  Document* GetDocument() const;

  Member<ThreadableLoaderClient> client_;
  Member<ExecutionContext> execution_context_;
  Member<ResourceFetcher> resource_fetcher_;

  TimeDelta timeout_;
  // Some items may be overridden by m_forceDoNotAllowStoredCredentials and
  // m_securityOrigin. In such a case, build a ResourceLoaderOptions with
  // up-to-date values from them and this variable, and use it.
  const ResourceLoaderOptions resource_loader_options_;

  // True when feature OutOfBlinkCors is enabled (https://crbug.com/736308).
  bool out_of_blink_cors_;

  // Corresponds to the CORS flag in the Fetch spec.
  bool cors_flag_ = false;
  scoped_refptr<const SecurityOrigin> security_origin_;
  scoped_refptr<const SecurityOrigin> original_security_origin_;

  // Set to true when the response data is given to a data consumer handle.
  bool is_using_data_consumer_handle_;

  const bool async_;

  // Holds the original request context (used for sanity checks).
  mojom::RequestContextType request_context_;

  // Saved so that we can use the original value for the modes in
  // ResponseReceived() where |resource| might be a reused one (e.g. preloaded
  // resource) which can have different modes.
  network::mojom::FetchRequestMode fetch_request_mode_;
  network::mojom::FetchCredentialsMode fetch_credentials_mode_;

  // Holds the original request for fallback in case the Service Worker
  // does not respond.
  ResourceRequest fallback_request_for_service_worker_;

  // Holds the original request and options for it during preflight request
  // handling phase.
  ResourceRequest actual_request_;
  ResourceLoaderOptions actual_options_;
  network::mojom::FetchResponseType response_tainting_ =
      network::mojom::FetchResponseType::kBasic;

  KURL initial_request_url_;
  KURL last_request_url_;

  // stores request headers in case of a cross-origin redirect.
  HTTPHeaderMap request_headers_;

  TaskRunnerTimer<ThreadableLoader> timeout_timer_;
  TimeTicks request_started_;  // Time an asynchronous fetch request is started

  // Max number of times that this ThreadableLoader can follow.
  int redirect_limit_;

  network::mojom::FetchRedirectMode redirect_mode_;

  // Holds the referrer after a redirect response was received. This referrer is
  // used to populate the HTTP Referer header when following the redirect.
  bool override_referrer_;
  bool report_upload_progress_ = false;
  Referrer referrer_after_redirect_;

  bool detached_ = false;

  RawResourceClientStateChecker checker_;

  DISALLOW_COPY_AND_ASSIGN(ThreadableLoader);
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_THREADABLE_LOADER_H_
