// Copyright 2015 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 "cobalt/xhr/xml_http_request.h"

#include <algorithm>
#include <memory>
#include <utility>

#include "base/compiler_specific.h"
#include "base/rand_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/task_runner.h"
#include "base/time/time.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/base/source_location.h"
#include "cobalt/base/tokens.h"
#include "cobalt/dom/dom_settings.h"
#include "cobalt/dom/performance.h"
#include "cobalt/dom/progress_event.h"
#include "cobalt/dom/window.h"
#include "cobalt/dom/xml_document.h"
#include "cobalt/dom_parser/xml_decoder.h"
#include "cobalt/loader/cors_preflight.h"
#include "cobalt/loader/fetcher_factory.h"
#include "cobalt/loader/url_fetcher_string_writer.h"
#include "cobalt/script/global_environment.h"
#include "cobalt/script/javascript_engine.h"
#include "cobalt/web/context.h"
#include "cobalt/web/csp_delegate.h"
#include "cobalt/web/environment_settings.h"
#include "cobalt/xhr/global_stats.h"
#include "cobalt/xhr/xhr_modify_headers.h"
#include "nb/memory_scope.h"
#include "net/http/http_util.h"

namespace cobalt {
namespace xhr {

using web::DOMException;

namespace {

// How many milliseconds must elapse between each progress event notification.
const int kProgressPeriodMs = 50;

const char* kResponseTypes[] = {
    "",             // kDefault
    "text",         // kText
    "json",         // kJson
    "document",     // kDocument
    "blob",         // kBlob
    "arraybuffer",  // kArrayBuffer
};

const char* kForbiddenMethods[] = {
    "connect", "trace", "track",
};

// https://www.w3.org/TR/resource-timing-1/#dom-performanceresourcetiming-initiatortype
const char* kPerformanceResourceTimingInitiatorType = "xmlhttprequest";

bool MethodNameToRequestType(const std::string& method,
                             net::URLFetcher::RequestType* request_type) {
  if (base::LowerCaseEqualsASCII(method, "get")) {
    *request_type = net::URLFetcher::GET;
  } else if (base::LowerCaseEqualsASCII(method, "post")) {
    *request_type = net::URLFetcher::POST;
  } else if (base::LowerCaseEqualsASCII(method, "head")) {
    *request_type = net::URLFetcher::HEAD;
  } else if (base::LowerCaseEqualsASCII(method, "delete")) {
    *request_type = net::URLFetcher::DELETE_REQUEST;
  } else if (base::LowerCaseEqualsASCII(method, "put")) {
    *request_type = net::URLFetcher::PUT;
  } else {
    return false;
  }
  return true;
}

#if !defined(COBALT_BUILD_TYPE_GOLD)
const char* kStateNames[] = {"Unsent", "Opened", "HeadersReceived", "Loading",
                             "Done"};
const char* kMethodNames[] = {"GET", "POST", "HEAD", "DELETE", "PUT"};

#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 "";
  }
}

const char* StateName(XMLHttpRequest::State state) {
  if (state >= 0 && state < arraysize(kStateNames)) {
    return kStateNames[state];
  } else {
    NOTREACHED();
    return "";
  }
}
#if __clang__
#pragma clang diagnostic push
#endif
#endif  // defined(COBALT_BUILD_TYPE_GOLD)

bool IsForbiddenMethod(const std::string& method) {
  for (size_t i = 0; i < arraysize(kForbiddenMethods); ++i) {
    if (base::LowerCaseEqualsASCII(method, kForbiddenMethods[i])) {
      return true;
    }
  }
  return false;
}

base::Token RequestErrorTypeName(XMLHttpRequest::RequestErrorType type) {
  switch (type) {
    case XMLHttpRequest::kNetworkError:
      return base::Tokens::error();
    case XMLHttpRequest::kTimeoutError:
      return base::Tokens::timeout();
    case XMLHttpRequest::kAbortError:
      return base::Tokens::abort();
  }
  NOTREACHED();
  return base::Token();
}

void FireProgressEvent(XMLHttpRequestEventTarget* target,
                       base::Token event_name) {
  if (!target) {
    return;
  }
  target->DispatchEvent(new dom::ProgressEvent(event_name));
}

void FireProgressEvent(XMLHttpRequestEventTarget* target,
                       base::Token event_name, uint64 loaded, uint64 total,
                       bool length_computable) {
  if (!target) {
    return;
  }
  target->DispatchEvent(
      new dom::ProgressEvent(event_name, loaded, total, length_computable));
}

#if !defined(COBALT_BUILD_TYPE_GOLD)
int s_xhr_sequence_num_ = 0;
#endif  // !defined(COBALT_BUILD_TYPE_GOLD)
// https://fetch.spec.whatwg.org/#concept-http-redirect-fetch
// 5. If request's redirect count is twenty, return a network error.
const int kRedirectLimit = 20;

}  // namespace

bool XMLHttpRequestImpl::verbose_ = false;

XMLHttpRequest::XMLHttpRequest(script::EnvironmentSettings* settings)
    : XMLHttpRequestEventTarget(settings) {
  // Determine which implementation of XHR to use based on being in a window or
  // worker.
  if (environment_settings()
          ->context()
          ->GetWindowOrWorkerGlobalScope()
          ->IsWindow()) {
    xhr_impl_ = std::make_unique<DOMXMLHttpRequestImpl>(this);
  } else if (environment_settings()
                 ->context()
                 ->GetWindowOrWorkerGlobalScope()
                 ->IsDedicatedWorker() ||
             environment_settings()
                 ->context()
                 ->GetWindowOrWorkerGlobalScope()
                 ->IsServiceWorker()) {
    xhr_impl_ = std::make_unique<XMLHttpRequestImpl>(this);
  }
  xhr::GlobalStats::GetInstance()->Add(this);
#if !defined(COBALT_BUILD_TYPE_GOLD)
  xhr_id_ = ++s_xhr_sequence_num_;
#endif  // !defined(COBALT_BUILD_TYPE_GOLD)
}

XMLHttpRequest::~XMLHttpRequest() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  xhr::GlobalStats::GetInstance()->Remove(this);
}

void XMLHttpRequest::Abort() { xhr_impl_->Abort(); }
void XMLHttpRequest::Open(const std::string& method, const std::string& url,
                          bool async,
                          const base::Optional<std::string>& username,
                          const base::Optional<std::string>& password,
                          script::ExceptionState* exception_state) {
  xhr_impl_->Open(method, url, async, username, password, exception_state);
}

// Must be called after open(), but before send().
void XMLHttpRequest::SetRequestHeader(const std::string& header,
                                      const std::string& value,
                                      script::ExceptionState* exception_state) {
  xhr_impl_->SetRequestHeader(header, value, exception_state);
}

// Override the MIME type returned by the server.
// Call before Send(), otherwise throws InvalidStateError.
void XMLHttpRequest::OverrideMimeType(const std::string& mime_type,
                                      script::ExceptionState* exception_state) {
  xhr_impl_->OverrideMimeType(mime_type, exception_state);
}

void XMLHttpRequest::Send(const base::Optional<RequestBodyType>& request_body,
                          script::ExceptionState* exception_state) {
  xhr_impl_->Send(request_body, exception_state);
}

void XMLHttpRequest::Fetch(const FetchUpdateCallbackArg& fetch_callback,
                           const FetchModeCallbackArg& fetch_mode_callback,
                           const base::Optional<RequestBodyType>& request_body,
                           script::ExceptionState* exception_state) {
  xhr_impl_->Fetch(fetch_callback, fetch_mode_callback, request_body,
                   exception_state);
}

base::Optional<std::string> XMLHttpRequest::GetResponseHeader(
    const std::string& header) {
  return xhr_impl_->GetResponseHeader(header);
}
std::string XMLHttpRequest::GetAllResponseHeaders() {
  return xhr_impl_->GetAllResponseHeaders();
}

const std::string& XMLHttpRequest::response_text(
    script::ExceptionState* exception_state) {
  return xhr_impl_->response_text(exception_state);
}
scoped_refptr<dom::Document> XMLHttpRequest::response_xml(
    script::ExceptionState* exception_state) {
  return xhr_impl_->response_xml(exception_state);
}
base::Optional<XMLHttpRequest::ResponseType> XMLHttpRequest::response(
    script::ExceptionState* exception_state) {
  return xhr_impl_->response(exception_state);
}

int XMLHttpRequest::ready_state() const { return xhr_impl_->ready_state(); }
int XMLHttpRequest::status() const { return xhr_impl_->status(); }
std::string XMLHttpRequest::status_text() { return xhr_impl_->status_text(); }
void XMLHttpRequest::set_response_type(
    const std::string& response_type, script::ExceptionState* exception_state) {
  xhr_impl_->set_response_type(response_type, exception_state);
}
std::string XMLHttpRequest::response_type(
    script::ExceptionState* exception_state) const {
  return xhr_impl_->response_type(exception_state);
}

uint32 XMLHttpRequest::timeout() const { return xhr_impl_->timeout(); }
void XMLHttpRequest::set_timeout(uint32 timeout) {
  xhr_impl_->set_timeout(timeout);
}
bool XMLHttpRequest::with_credentials(
    script::ExceptionState* exception_state) const {
  return xhr_impl_->with_credentials(exception_state);
}
void XMLHttpRequest::set_with_credentials(
    bool b, script::ExceptionState* exception_state) {
  xhr_impl_->set_with_credentials(b, exception_state);
}

scoped_refptr<XMLHttpRequestUpload> XMLHttpRequest::upload() {
  return xhr_impl_->upload();
}

void XMLHttpRequest::set_verbose(bool verbose) {
  XMLHttpRequestImpl::set_verbose(verbose);
}
bool XMLHttpRequest::verbose() { return XMLHttpRequestImpl::verbose(); }

// net::URLFetcherDelegate interface
void XMLHttpRequest::OnURLFetchResponseStarted(const net::URLFetcher* source) {
  xhr_impl_->OnURLFetchResponseStarted(source);
}
void XMLHttpRequest::OnURLFetchDownloadProgress(const net::URLFetcher* source,
                                                int64_t current, int64_t total,
                                                int64_t current_network_bytes) {
  xhr_impl_->OnURLFetchDownloadProgress(source, current, total,
                                        current_network_bytes);
}
void XMLHttpRequest::OnURLFetchComplete(const net::URLFetcher* source) {
  xhr_impl_->OnURLFetchComplete(source);
}

void XMLHttpRequest::OnURLFetchUploadProgress(const net::URLFetcher* source,
                                              int64 current, int64 total) {
  xhr_impl_->OnURLFetchUploadProgress(source, current, total);
}
void XMLHttpRequest::OnRedirect(const net::HttpResponseHeaders& headers) {
  xhr_impl_->OnRedirect(headers);
}

// Called from bindings layer to tie objects' lifetimes to this XHR instance.
XMLHttpRequestUpload* XMLHttpRequest::upload_or_null() {
  return xhr_impl_->upload_or_null();
}

void XMLHttpRequest::ReportLoadTimingInfo(
    const net::LoadTimingInfo& timing_info) {
  xhr_impl_->ReportLoadTimingInfo(timing_info);
}
// Create Performance Resource Timing entry for XMLHttpRequest.
void XMLHttpRequest::GetLoadTimingInfoAndCreateResourceTiming() {
  xhr_impl_->GetLoadTimingInfoAndCreateResourceTiming();
}

void XMLHttpRequest::TraceMembers(script::Tracer* tracer) {
  XMLHttpRequestEventTarget::TraceMembers(tracer);
  xhr_impl_->TraceMembers(tracer);
}

XMLHttpRequestImpl::XMLHttpRequestImpl(XMLHttpRequest* xhr)
    : error_(false),
      is_cross_origin_(false),
      is_data_url_(false),
      is_redirect_(false),
      method_(net::URLFetcher::GET),
      response_body_(new URLFetcherResponseWriter::Buffer(
          URLFetcherResponseWriter::Buffer::kString)),
      response_type_(XMLHttpRequest::kDefault),
      state_(XMLHttpRequest::kUnsent),
      upload_listener_(false),
      with_credentials_(false),
      xhr_(xhr),
      active_requests_count_(0),
      http_status_(0),
      redirect_times_(0),
      sent_(false),
      settings_(xhr->environment_settings()),
      stop_timeout_(false),
      timeout_ms_(0),
      upload_complete_(false) {
  DCHECK(settings_);
}

void XMLHttpRequestImpl::Abort() {
  // https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#the-abort()-method
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  // Cancel any in-flight request and set error flag.
  TerminateRequest();
  bool abort_is_no_op = state_ == XMLHttpRequest::kUnsent ||
                        state_ == XMLHttpRequest::kDone ||
                        (state_ == XMLHttpRequest::kOpened && !sent_);
  if (!abort_is_no_op) {
    sent_ = false;
    HandleRequestError(XMLHttpRequest::kAbortError);
  }
  ChangeState(XMLHttpRequest::kUnsent);

  response_body_->Clear();
  response_array_buffer_reference_.reset();
}

// https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#the-open()-method
void XMLHttpRequestImpl::Open(const std::string& method, const std::string& url,
                              bool async,
                              const base::Optional<std::string>& username,
                              const base::Optional<std::string>& password,
                              script::ExceptionState* exception_state) {
  TRACK_MEMORY_SCOPE("XHR");

  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  XMLHttpRequest::State previous_state = state_;

  // Cancel any outstanding request.
  TerminateRequest();
  state_ = XMLHttpRequest::kUnsent;

  if (!async) {
    DLOG(ERROR) << "synchronous XHR is not supported";
    web::DOMException::Raise(web::DOMException::kInvalidStateErr,
                             exception_state);
    return;
  }

  base_url_ = settings_->base_url();

  if (IsForbiddenMethod(method)) {
    web::DOMException::Raise(web::DOMException::kSecurityErr, exception_state);
    return;
  }

  if (!MethodNameToRequestType(method, &method_)) {
    web::DOMException::Raise(web::DOMException::kSyntaxErr, exception_state);
    return;
  }

  request_url_ = base_url_.Resolve(url);
  if (!request_url_.is_valid()) {
    web::DOMException::Raise(web::DOMException::kSyntaxErr, exception_state);
    return;
  }

  web::CspDelegate* csp = this->csp_delegate();
  if (csp && !csp->CanLoad(web::CspDelegate::kXhr, request_url_, false)) {
    web::DOMException::Raise(web::DOMException::kSecurityErr, exception_state);
    return;
  }

  sent_ = false;
  stop_timeout_ = false;

  PrepareForNewRequest();

  // Check previous state to avoid dispatching readyState event when calling
  // open several times in a row.
  if (previous_state != XMLHttpRequest::kOpened) {
    ChangeState(XMLHttpRequest::kOpened);
  } else {
    state_ = XMLHttpRequest::kOpened;
  }
}

void XMLHttpRequestImpl::SetRequestHeader(
    const std::string& header, const std::string& value,
    script::ExceptionState* exception_state) {
  TRACK_MEMORY_SCOPE("XHR");
  // https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#dom-xmlhttprequest-setrequestheader
  if (state_ != XMLHttpRequest::kOpened || sent_) {
    web::DOMException::Raise(web::DOMException::kInvalidStateErr,
                             exception_state);
    return;
  }

  if (!net::HttpUtil::IsValidHeaderName(header) ||
      !net::HttpUtil::IsValidHeaderValue(value)) {
    DLOG(WARNING) << "Rejecting invalid header " << header << " : " << value;
    return;
  }

  if (!net::HttpUtil::IsSafeHeader(header)) {
    DLOG(WARNING) << "Rejecting unsafe header " << header;
    return;
  }

  // Write the header if it is not set.
  // If it is, append it to the existing one.
  std::string cur_value;
  if (request_headers_.GetHeader(header, &cur_value)) {
    cur_value += ", " + value;
    request_headers_.SetHeader(header, cur_value);
  } else {
    request_headers_.SetHeader(header, value);
  }
}

void XMLHttpRequestImpl::OverrideMimeType(
    const std::string& override_mime, script::ExceptionState* exception_state) {
  // https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#dom-xmlhttprequest-overridemimetype
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  if (state_ == XMLHttpRequest::kLoading || state_ == XMLHttpRequest::kDone) {
    web::DOMException::Raise(web::DOMException::kInvalidStateErr,
                             exception_state);
    return;
  }

  // Try to parse the given override. If it fails, throw an exception.
  // Otherwise, we'll replace the content-type header in the response headers
  // once we have them.
  std::string mime_type;
  std::string charset;
  bool had_charset = false;
  net::HttpUtil::ParseContentType(override_mime, &mime_type, &charset,
                                  &had_charset, NULL);
  if (!mime_type.length()) {
    web::DOMException::Raise(web::DOMException::kSyntaxErr, exception_state);
    return;
  }
  mime_type_override_ = mime_type;
}

void XMLHttpRequestImpl::Send(
    const base::Optional<XMLHttpRequest::RequestBodyType>& request_body,
    script::ExceptionState* exception_state) {
  TRACK_MEMORY_SCOPE("XHR");
  // https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#the-send()-method
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  // Step 1
  if (state_ != XMLHttpRequest::kOpened) {
    web::DOMException::Raise(web::DOMException::kInvalidStateErr,
                             exception_state);
    return;
  }
  // Step 2
  if (sent_) {
    web::DOMException::Raise(web::DOMException::kInvalidStateErr,
                             exception_state);
    return;
  }

  // Step 3 - 7
  error_ = false;
  upload_complete_ = false;

#if defined(COBALT_ENABLE_XHR_HEADER_FILTERING)
  CobaltXhrModifyHeader(request_url_, &request_headers_);
#endif

  // Add request body, if appropriate.
  if ((method_ == net::URLFetcher::POST || method_ == net::URLFetcher::PUT) &&
      request_body) {
    bool has_content_type =
        request_headers_.HasHeader(net::HttpRequestHeaders::kContentType);
    if (request_body->IsType<std::string>()) {
      request_body_text_.assign(request_body->AsType<std::string>());
      if (!has_content_type) {
        // We're assuming that request_body is UTF-8 encoded.
        request_headers_.SetHeader(net::HttpRequestHeaders::kContentType,
                                   "text/plain;charset=UTF-8");
      }
    } else if (request_body
                   ->IsType<script::Handle<script::ArrayBufferView> >()) {
      script::Handle<script::ArrayBufferView> view =
          request_body->AsType<script::Handle<script::ArrayBufferView> >();
      if (view->ByteLength()) {
        const char* start = reinterpret_cast<const char*>(view->RawData());
        request_body_text_.assign(start + view->ByteOffset(),
                                  view->ByteLength());
      }
    } else if (request_body->IsType<script::Handle<script::ArrayBuffer> >()) {
      script::Handle<script::ArrayBuffer> array_buffer =
          request_body->AsType<script::Handle<script::ArrayBuffer> >();
      if (array_buffer->ByteLength()) {
        const char* start = reinterpret_cast<const char*>(array_buffer->Data());
        request_body_text_.assign(start, array_buffer->ByteLength());
      }
    }
  } else {
    upload_complete_ = true;
  }
  // Step 8
  if (upload_) {
    upload_listener_ = upload_->HasOneOrMoreAttributeEventListener();
  }
  origin_ = loader::Origin(settings_->GetOrigin());
  // Step 9
  sent_ = true;
  // Now that a send is happening, prevent this object
  // from being collected until it's complete or aborted
  // if no currently active request has called it before.
  IncrementActiveRequests();
  FireProgressEvent(xhr_, base::Tokens::loadstart());
  if (!upload_complete_) {
    FireProgressEvent(upload_, base::Tokens::loadstart());
  }

  // The loadstart callback may abort or modify the XHR request in some way.
  // 11.3. If state is not opened or the send() flag is unset, then return.
  if (state_ == XMLHttpRequest::kOpened && sent_) {
    this->StartRequest(request_body_text_);

    // Start the timeout timer running, if applicable.
    send_start_time_ = base::TimeTicks::Now();
    if (timeout_ms_) {
      StartTimer(base::TimeDelta());
    }
    // Timer for throttling progress events.
    upload_last_progress_time_ = base::TimeTicks();
    last_progress_time_ = base::TimeTicks();
  }
}

void XMLHttpRequestImpl::Fetch(
    const FetchUpdateCallbackArg& fetch_callback,
    const FetchModeCallbackArg& fetch_mode_callback,
    const base::Optional<XMLHttpRequest::RequestBodyType>& request_body,
    script::ExceptionState* exception_state) {
  fetch_callback_.reset(
      new FetchUpdateCallbackArg::Reference(xhr_, fetch_callback));
  fetch_mode_callback_.reset(
      new FetchModeCallbackArg::Reference(xhr_, fetch_mode_callback));
  Send(request_body, exception_state);
}

base::Optional<std::string> XMLHttpRequestImpl::GetResponseHeader(
    const std::string& header) {
  // https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#the-getresponseheader()-method
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  if (state_ == XMLHttpRequest::kUnsent || state_ == XMLHttpRequest::kOpened ||
      error_) {
    return base::nullopt;
  }

  // Set-Cookie should be stripped from the response headers in OnDone().
  if (base::LowerCaseEqualsASCII(header, "set-cookie") ||
      base::LowerCaseEqualsASCII(header, "set-cookie2")) {
    return base::nullopt;
  }

  bool found;
  std::string value;
  if (net::HttpUtil::IsNonCoalescingHeader(header)) {
    // A non-coalescing header may contain commas in the value, e.g. Date:
    found = http_response_headers_->EnumerateHeader(NULL, header, &value);
  } else {
    found = http_response_headers_->GetNormalizedHeader(header, &value);
  }
  return found ? base::make_optional(value) : base::nullopt;
}

std::string XMLHttpRequestImpl::GetAllResponseHeaders() {
  // https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#the-getallresponseheaders()-method
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  std::string output;

  if (state_ == XMLHttpRequest::kUnsent || state_ == XMLHttpRequest::kOpened ||
      error_) {
    return output;
  }

  size_t iter = 0;
  std::string name;
  std::string value;

  while (http_response_headers_->EnumerateHeaderLines(&iter, &name, &value)) {
    output += name;
    output += ": ";
    output += value;
    output += "\r\n";
  }
  return output;
}

const std::string& XMLHttpRequestImpl::response_text(
    script::ExceptionState* exception_state) {
  // https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#the-responsetext-attribute
  if (response_type_ != XMLHttpRequest::kDefault &&
      response_type_ != XMLHttpRequest::kText) {
    web::DOMException::Raise(web::DOMException::kInvalidStateErr,
                             exception_state);
  }
  if (error_ ||
      (state_ != XMLHttpRequest::kLoading && state_ != XMLHttpRequest::kDone)) {
    return base::EmptyString();
  }

  // Note that the conversion from |response_body_| to std::string when |state_|
  // isn't kDone isn't efficient for large responses.  Fortunately this feature
  // is rarely used.
  if (state_ == XMLHttpRequest::kLoading) {
    LOG_ONCE(WARNING)
        << "Retrieving responseText while loading can be inefficient.";
    return response_body_->GetTemporaryReferenceOfString();
  }
  return response_body_->GetReferenceOfStringAndSeal();
}

// https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#the-responsexml-attribute
scoped_refptr<dom::Document> XMLHttpRequestImpl::response_xml(
    script::ExceptionState* exception_state) {
  // Workers don't have access to DOM APIs, including Document objects. Nothing
  // to do.
  // https://www.w3.org/TR/2012/CR-workers-20120501/#apis-available-to-workers
  return NULL;
}

base::Optional<XMLHttpRequest::ResponseType> XMLHttpRequestImpl::response(
    script::ExceptionState* exception_state) {
  // https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#response
  switch (response_type_) {
    case XMLHttpRequest::kDefault:
    case XMLHttpRequest::kText:
      return XMLHttpRequest::ResponseType(response_text(exception_state));
    case XMLHttpRequest::kArrayBuffer: {
      script::Handle<script::ArrayBuffer> maybe_array_buffer_response =
          response_array_buffer();
      if (maybe_array_buffer_response.IsEmpty()) {
        return base::nullopt;
      }
      return XMLHttpRequest::ResponseType(maybe_array_buffer_response);
    }
    case XMLHttpRequest::kJson:
    case XMLHttpRequest::kDocument:
    case XMLHttpRequest::kBlob:
    case XMLHttpRequest::kResponseTypeCodeMax:
      NOTIMPLEMENTED() << "Unsupported response_type_ "
                       << response_type(exception_state);
  }
  return base::nullopt;
}

int XMLHttpRequestImpl::status() const {
  // https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#the-status-attribute
  if (state_ == XMLHttpRequest::kUnsent || state_ == XMLHttpRequest::kOpened ||
      error_) {
    return 0;
  } else {
    return http_status_;
  }
}

std::string XMLHttpRequestImpl::status_text() {
  // https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#the-statustext-attribute
  if (state_ == XMLHttpRequest::kUnsent || state_ == XMLHttpRequest::kOpened ||
      error_) {
    return std::string();
  }

  return http_response_headers_->GetStatusText();
}

void XMLHttpRequestImpl::set_response_type(
    const std::string& response_type, script::ExceptionState* exception_state) {
  if (state_ == XMLHttpRequest::kLoading || state_ == XMLHttpRequest::kDone) {
    web::DOMException::Raise(web::DOMException::kInvalidStateErr,
                             exception_state);
    return;
  }
  for (size_t i = 0; i < arraysize(kResponseTypes); ++i) {
    if (response_type == kResponseTypes[i]) {
      DCHECK_LT(i, XMLHttpRequest::kResponseTypeCodeMax);
      response_type_ = static_cast<XMLHttpRequest::ResponseTypeCode>(i);
      return;
    }
  }

  DLOG(WARNING) << "Unexpected response type " << response_type;
}

std::string XMLHttpRequestImpl::response_type(
    script::ExceptionState* unused) const {
  // https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#the-responsetype-attribute
  DCHECK_LT(response_type_, arraysize(kResponseTypes));
  return kResponseTypes[response_type_];
}

void XMLHttpRequestImpl::set_timeout(uint32 timeout) {
  // https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#the-timeout-attribute
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  timeout_ms_ = timeout;
  if (timeout_ms_ == 0) {
    stop_timeout_ = true;
    timer_.Stop();
  } else if (sent_) {
    // Timeout was set while request was in flight. Timeout is relative to
    // the start of the request.
    StartTimer(base::TimeTicks::Now() - send_start_time_);
  }
}

bool XMLHttpRequestImpl::with_credentials(
    script::ExceptionState* unused) const {
  return with_credentials_;
}

void XMLHttpRequestImpl::set_with_credentials(
    bool with_credentials, script::ExceptionState* exception_state) {
  // https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#the-withcredentials-attribute
  if ((state_ != XMLHttpRequest::kUnsent &&
       state_ != XMLHttpRequest::kOpened) ||
      sent_) {
    web::DOMException::Raise(web::DOMException::kInvalidStateErr,
                             exception_state);
    return;
  }
  with_credentials_ = with_credentials;
}

scoped_refptr<XMLHttpRequestUpload> XMLHttpRequestImpl::upload() {
  if (!upload_) {
    upload_ = new XMLHttpRequestUpload(settings_);
  }
  return upload_;
}

void XMLHttpRequestImpl::OnURLFetchResponseStarted(
    const net::URLFetcher* source) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  http_status_ = source->GetResponseCode();
  // Don't handle a response without headers.
  if (!source->GetResponseHeaders()) {
    HandleRequestError(XMLHttpRequest::kNetworkError);
    return;
  }
  // Copy the response headers from the fetcher. It's not safe for us to
  // modify the existing ones as they may be in use on the network thread.
  http_response_headers_ =
      new net::HttpResponseHeaders(source->GetResponseHeaders()->raw_headers());

  // Perform a CORS Check on response headers at their arrival and raise
  // Network Error when the Check fails.
  if (is_cross_origin_) {
    if (!loader::CORSPreflight::CORSCheck(*http_response_headers_,
                                          origin_.SerializedOrigin(),
                                          with_credentials_)) {
      HandleRequestError(XMLHttpRequest::kNetworkError);
      return;
    }
  }

  // Discard these as required by XHR spec.
  http_response_headers_->RemoveHeader("Set-Cookie2");
  http_response_headers_->RemoveHeader("Set-Cookie");

  http_response_headers_->GetMimeType(&response_mime_type_);

  if (mime_type_override_.length()) {
    http_response_headers_->RemoveHeader("Content-Type");
    http_response_headers_->AddHeader(std::string("Content-Type: ") +
                                      mime_type_override_);
  }

  if (fetch_mode_callback_) {
    fetch_mode_callback_->value().Run(is_cross_origin_);
  }

  // Further filter response headers as XHR's mode is cors
  if (is_cross_origin_) {
    size_t iter = 0;
    std::string name, value;
    std::vector<std::pair<std::string, std::string> > header_names_to_discard;
    std::vector<std::string> expose_headers;
    loader::CORSPreflight::GetServerAllowedHeaders(*http_response_headers_,
                                                   &expose_headers);
    while (http_response_headers_->EnumerateHeaderLines(&iter, &name, &value)) {
      if (!loader::CORSPreflight::IsSafeResponseHeader(name, expose_headers,
                                                       with_credentials_)) {
        header_names_to_discard.push_back(std::make_pair(name, value));
      }
    }
    for (const auto& header : header_names_to_discard) {
      http_response_headers_->RemoveHeaderLine(header.first, header.second);
    }
  }

  if (is_data_url_) {
    size_t iter = 0;
    std::string name, value;
    std::vector<std::pair<std::string, std::string> > header_names_to_discard;
    while (http_response_headers_->EnumerateHeaderLines(&iter, &name, &value)) {
      if (name != net::HttpRequestHeaders::kContentType) {
        header_names_to_discard.push_back(std::make_pair(name, value));
      }
    }
    for (const auto& header : header_names_to_discard) {
      http_response_headers_->RemoveHeaderLine(header.first, header.second);
    }
  }

  ChangeState(XMLHttpRequest::kHeadersReceived);

  UpdateProgress(0);
}

void XMLHttpRequestImpl::OnURLFetchDownloadProgress(
    const net::URLFetcher* source, int64_t current, int64_t total,
    int64_t current_network_bytes) {
  TRACK_MEMORY_SCOPE("XHR");
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK_NE(state_, XMLHttpRequest::kDone);

  if (response_body_->HasProgressSinceLastGetAndReset() == 0) {
    return;
  }

  // Signal to JavaScript that new data is now available.
  ChangeState(XMLHttpRequest::kLoading);

  if (fetch_callback_) {
    std::string downloaded_data;
    response_body_->GetAndResetDataAndDownloadProgress(&downloaded_data);
    script::Handle<script::Uint8Array> data =
        script::Uint8Array::New(settings_->context()->global_environment(),
                                downloaded_data.data(), downloaded_data.size());
    fetch_callback_->value().Run(data);
  }

  // Send a progress notification if at least 50ms have elapsed.
  const base::TimeTicks now = base::TimeTicks::Now();
  const base::TimeDelta elapsed(now - last_progress_time_);
  if (elapsed > base::TimeDelta::FromMilliseconds(kProgressPeriodMs)) {
    last_progress_time_ = now;
    if (fetch_callback_) {
      // TODO: Investigate if we have to fire progress event with 0 loaded bytes
      //       when used as Fetch API.
      UpdateProgress(0);
    } else {
      UpdateProgress(response_body_->GetAndResetDownloadProgress());
    }
  }
}


void XMLHttpRequestImpl::OnURLFetchComplete(const net::URLFetcher* source) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  if (source->GetResponseHeaders()) {
    if (source->GetResponseHeaders()->IsRedirect(NULL)) {
      // To do CORS Check and Send potential preflight, we used
      // SetStopOnRedirect to terminate request on redirect and OnRedict
      // function will deal with the early termination and send preflight if
      // needed.
      OnRedirect(*source->GetResponseHeaders());
      return;
    }
    // Create Performance Resource Timing entry after fetch complete.
    this->GetLoadTimingInfoAndCreateResourceTiming();
  }

  const net::URLRequestStatus& status = source->GetStatus();
  if (status.is_success()) {
    stop_timeout_ = true;
    if (error_) {
      // Ensure the fetch callbacks are reset when URL fetch is complete,
      // regardless of error status.
      fetch_callback_.reset();
      fetch_mode_callback_.reset();
      return;
    }

    // Ensure all fetched data is read and transferred to this XHR. This should
    // only be done for successful and error-free fetches.
    OnURLFetchDownloadProgress(source, 0, 0, 0);

    // The request may have completed too quickly, before URLFetcher's upload
    // progress timer had a chance to inform us upload is finished.
    if (!upload_complete_ && upload_listener_) {
      upload_complete_ = true;
      FireProgressEvent(upload_, base::Tokens::progress());
      FireProgressEvent(upload_, base::Tokens::load());
      FireProgressEvent(upload_, base::Tokens::loadend());
    }
    ChangeState(XMLHttpRequest::kDone);
    UpdateProgress(response_body_->GetAndResetDownloadProgress());
    // Undo the ref we added in Send()
    DecrementActiveRequests();
  } else {
    HandleRequestError(XMLHttpRequest::kNetworkError);
  }

  fetch_callback_.reset();
  fetch_mode_callback_.reset();
}

void XMLHttpRequestImpl::OnURLFetchUploadProgress(const net::URLFetcher* source,
                                                  int64 current_val,
                                                  int64 total_val) {
  TRACK_MEMORY_SCOPE("XHR");
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  if (upload_complete_) {
    return;
  }

  uint64 current = static_cast<uint64>(current_val);
  uint64 total = static_cast<uint64>(total_val);
  if (current == total) {
    upload_complete_ = true;
  }

  // Fire a progress event if either the upload just completed, or if enough
  // time has elapsed since we sent the last one.

  // https://xhr.spec.whatwg.org/#dom-xmlhttprequest-send step 11.4.
  // To process request body for request, run these subsubsteps:
  // 1.not roughly 50ms have passed since these subsubsteps were last invoked,
  // terminate these subsubsteps.
  // 2. If upload listener flag is set, then fire a progress event named
  // progress on the XMLHttpRequestUpload object with request's body's
  // transmitted bytes and request's body's total bytes.
  if (!upload_listener_) {
    return;
  }
  const base::TimeTicks now = base::TimeTicks::Now();
  const base::TimeDelta elapsed(now - upload_last_progress_time_);
  if (upload_complete_ ||
      (elapsed > base::TimeDelta::FromMilliseconds(kProgressPeriodMs))) {
    FireProgressEvent(upload_, base::Tokens::progress(), current, total,
                      total != 0);
    upload_last_progress_time_ = now;
  }

  // To process request end-of-body for request, run these subsubsteps:
  // 2. if upload listener flag is unset, then terminate these subsubsteps.
  if (upload_complete_) {
    FireProgressEvent(upload_, base::Tokens::load(), current, total,
                      total != 0);
    FireProgressEvent(upload_, base::Tokens::loadend(), current, total,
                      total != 0);
  }
}

void XMLHttpRequestImpl::OnRedirect(const net::HttpResponseHeaders& headers) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  GURL new_url = url_fetcher_->GetURL();
  // Since we moved redirect from url_request to here, we also need to
  // handle redirecting too many times.
  if (redirect_times_ >= kRedirectLimit) {
    DLOG(INFO) << "XHR's redirect times hit limit, aborting request.";
    HandleRequestError(XMLHttpRequest::kNetworkError);
    return;
  }

  // This function is designed to be called by url_fetcher_core::
  // OnReceivedRedirect
  // https://fetch.spec.whatwg.org/#concept-http-redirect-fetch
  // 7. If request’s mode is "cors", request’s origin is not same origin
  // with actualResponse’s location URL’s origin, and actualResponse’s
  // location URL includes credentials, then return a network error.
  // 8. If CORS flag is set and actualResponse’s location URL includes
  // credentials, then return a network error.
  if (new_url.has_username() || new_url.has_password()) {
    if (loader::Origin(new_url) != loader::Origin(request_url_)) {
      DLOG(INFO) << "XHR is redirected to cross-origin url with credentials, "
                    "aborting request for security reasons.";
      HandleRequestError(XMLHttpRequest::kNetworkError);
      return;
    } else if (is_cross_origin_) {
      DLOG(INFO) << "XHR is redirected with credentials and cors_flag set, "
                    "aborting request for security reasons.";
      HandleRequestError(XMLHttpRequest::kNetworkError);
      return;
    }
  }
  if (!new_url.is_valid()) {
    HandleRequestError(XMLHttpRequest::kNetworkError);
    return;
  }
  // This is a redirect. Re-check the CSP.
  web::CspDelegate* csp = this->csp_delegate();
  if (csp &&
      !csp->CanLoad(web::CspDelegate::kXhr, new_url, true /* is_redirect */)) {
    HandleRequestError(XMLHttpRequest::kNetworkError);
    return;
  }
  // CORS check for the received response
  if (is_cross_origin_) {
    if (!loader::CORSPreflight::CORSCheck(headers, origin_.SerializedOrigin(),
                                          with_credentials_)) {
      HandleRequestError(XMLHttpRequest::kNetworkError);
      return;
    }
  }
  is_redirect_ = true;
  // If CORS flag is set and actualResponse’s location URL’s origin is not
  // same origin with request’s current url’s origin, then set request’s
  // origin to a unique opaque origin.
  if (loader::Origin(new_url) != loader::Origin(request_url_)) {
    if (is_cross_origin_) {
      origin_ = loader::Origin();
    } else {
      origin_ = loader::Origin(request_url_);
      is_cross_origin_ = true;
    }
  }
  // Send out preflight if needed
  int http_status_code = headers.response_code();
  if ((http_status_code == 303) ||
      ((http_status_code == 301 || http_status_code == 302) &&
       (method_ == net::URLFetcher::POST))) {
    method_ = net::URLFetcher::GET;
    request_body_text_.clear();
  }
  request_url_ = new_url;
  redirect_times_++;
  this->StartRequest(request_body_text_);
}

void XMLHttpRequestImpl::ReportLoadTimingInfo(
    const net::LoadTimingInfo& timing_info) {
  load_timing_info_ = timing_info;
}

void XMLHttpRequestImpl::GetLoadTimingInfoAndCreateResourceTiming() {
  // Performance info is only available through window currently. Not available
  // in workers.
  return;
}

void XMLHttpRequestImpl::TraceMembers(script::Tracer* tracer) {
  tracer->Trace(upload_);
}

web::CspDelegate* XMLHttpRequestImpl::csp_delegate() const {
  // TODO (b/239733363): csp_delegate is currently available through window.
  // Refactor to make it available outside of window then implement this. At
  // that point, there should be no more need to override this function in
  // DOMXMLHttpRequestImpl.
  return NULL;
}

void XMLHttpRequestImpl::TerminateRequest() {
  error_ = true;
  corspreflight_.reset(NULL);
  url_fetcher_.reset(NULL);
}

void XMLHttpRequestImpl::HandleRequestError(
    XMLHttpRequest::RequestErrorType request_error_type) {
  // https://www.w3.org/TR/XMLHttpRequest/#timeout-error
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DLOG_IF(INFO, verbose())
      << __FUNCTION__ << " (" << RequestErrorTypeName(request_error_type)
      << ") " << *xhr_ << std::endl
      << script::StackTraceToString(
             settings_->context()->global_environment()->GetStackTrace(
                 0 /*max_frames*/));
  stop_timeout_ = true;
  // Step 1
  TerminateRequest();
  // Steps 2-4
  // Change state and fire readystatechange event.
  ChangeState(XMLHttpRequest::kDone);

  base::Token error_name = RequestErrorTypeName(request_error_type);
  // Step 5
  if (!upload_complete_) {
    upload_complete_ = true;
    FireProgressEvent(upload_, base::Tokens::progress());
    FireProgressEvent(upload_, error_name);
    FireProgressEvent(upload_, base::Tokens::loadend());
  }

  // Steps 6-8
  FireProgressEvent(xhr_, base::Tokens::progress());
  FireProgressEvent(xhr_, error_name);
  FireProgressEvent(xhr_, base::Tokens::loadend());

  fetch_callback_.reset();
  fetch_mode_callback_.reset();
  DecrementActiveRequests();
}

void XMLHttpRequestImpl::OnTimeout() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  if (!stop_timeout_) {
    HandleRequestError(XMLHttpRequest::kTimeoutError);
  }
}

void XMLHttpRequestImpl::StartTimer(base::TimeDelta time_since_send) {
  // Subtract any time that has already elapsed from the timeout.
  // This is in case the user has set a timeout after send() was already in
  // flight.
  base::TimeDelta delay = std::max(
      base::TimeDelta(),
      base::TimeDelta::FromMilliseconds(timeout_ms_) - time_since_send);

  // Queue the callback even if delay ends up being zero, to preserve the
  // previous semantics.
  timer_.Start(FROM_HERE, delay, this, &XMLHttpRequestImpl::OnTimeout);
}

void XMLHttpRequestImpl::ChangeState(XMLHttpRequest::State new_state) {
  // Always dispatch state change events for LOADING, also known as
  // INTERACTIVE, so that clients can get partial data (XHR streaming).
  // This is to match the behavior of Chrome (which took it from Firefox).
  if (state_ == new_state && new_state != XMLHttpRequest::kLoading) {
    return;
  }

  state_ = new_state;
  if (state_ != XMLHttpRequest::kUnsent) {
    xhr_->DispatchEvent(new web::Event(base::Tokens::readystatechange()));
  }
}

script::Handle<script::ArrayBuffer>
XMLHttpRequestImpl::response_array_buffer() {
  TRACK_MEMORY_SCOPE("XHR");
  // https://www.w3.org/TR/XMLHttpRequest/#response-entity-body
  if (error_ || state_ != XMLHttpRequest::kDone) {
    // Return a handle holding a nullptr.
    return script::Handle<script::ArrayBuffer>();
  }
  if (!response_array_buffer_reference_) {
    // The request is done so it is safe to only keep the ArrayBuffer and clear
    // |response_body_|.  As |response_body_| will not be used unless the
    // request is re-opened.
    std::unique_ptr<script::PreallocatedArrayBufferData> downloaded_data(
        new script::PreallocatedArrayBufferData());
    response_body_->GetAndResetData(downloaded_data.get());
    auto array_buffer = script::ArrayBuffer::New(
        settings_->context()->global_environment(), std::move(downloaded_data));
    response_array_buffer_reference_.reset(
        new script::ScriptValue<script::ArrayBuffer>::Reference(xhr_,
                                                                array_buffer));
    return array_buffer;
  } else {
    return script::Handle<script::ArrayBuffer>(
        *response_array_buffer_reference_);
  }
}

void XMLHttpRequestImpl::UpdateProgress(int64_t received_length) {
  DCHECK(http_response_headers_);
  const int64 content_length = http_response_headers_->GetContentLength();
  const bool length_computable =
      content_length > 0 && received_length <= content_length;
  const uint64 total =
      length_computable ? static_cast<uint64>(content_length) : 0;

  DLOG_IF(INFO, verbose()) << __FUNCTION__ << " (" << received_length << " / "
                           << total << ") " << *xhr_;

  if (state_ == XMLHttpRequest::kDone) {
    FireProgressEvent(xhr_, base::Tokens::load(),
                      static_cast<uint64>(received_length), total,
                      length_computable);
    FireProgressEvent(xhr_, base::Tokens::loadend(),
                      static_cast<uint64>(received_length), total,
                      length_computable);
  } else {
    FireProgressEvent(xhr_, base::Tokens::progress(),
                      static_cast<uint64>(received_length), total,
                      length_computable);
  }
}

void XMLHttpRequestImpl::StartRequest(const std::string& request_body) {
  TRACK_MEMORY_SCOPE("XHR");

  response_array_buffer_reference_.reset();

  network::NetworkModule* network_module =
      settings_->context()->fetcher_factory()->network_module();
  url_fetcher_ = net::URLFetcher::Create(request_url_, method_, xhr_);
  ++url_fetcher_generation_;
  url_fetcher_->SetRequestContext(network_module->url_request_context_getter());
  if (fetch_callback_) {
    response_body_ = new URLFetcherResponseWriter::Buffer(
        URLFetcherResponseWriter::Buffer::kString);
    response_body_->DisablePreallocate();
  } else {
    response_body_ = new URLFetcherResponseWriter::Buffer(
        response_type_ == XMLHttpRequest::kArrayBuffer
            ? URLFetcherResponseWriter::Buffer::kArrayBuffer
            : URLFetcherResponseWriter::Buffer::kString);
  }
  std::unique_ptr<net::URLFetcherResponseWriter> download_data_writer(
      new URLFetcherResponseWriter(response_body_));
  url_fetcher_->SaveResponseWithWriter(std::move(download_data_writer));
  // Don't retry, let the caller deal with it.
  url_fetcher_->SetAutomaticallyRetryOn5xx(false);
  url_fetcher_->SetExtraRequestHeaders(request_headers_.ToString());

  // We want to do cors check and preflight during redirects
  url_fetcher_->SetStopOnRedirect(true);

  if (request_body.size()) {
    // If applicable, the request body Content-Type is already set in
    // request_headers.
    url_fetcher_->SetUploadData("", request_body);
  }

  // We let data url fetch resources freely but with no response headers.
  is_data_url_ = is_data_url_ || request_url_.SchemeIs("data");
  is_cross_origin_ = (is_redirect_ && is_cross_origin_) ||
                     (origin_ != loader::Origin(request_url_) && !is_data_url_);
  is_redirect_ = false;
  // If the CORS flag is set, httpRequest’s method is neither `GET` nor `HEAD`
  // or httpRequest’s mode is "websocket", then append `Origin`/httpRequest’s
  // origin, serialized and UTF-8 encoded, to httpRequest’s header list.
  if (is_cross_origin_ ||
      (method_ != net::URLFetcher::GET && method_ != net::URLFetcher::HEAD)) {
    url_fetcher_->AddExtraRequestHeader("Origin:" + origin_.SerializedOrigin());
  }
  bool dopreflight = false;
  // TODO (b/239733363): Include CORS functionality once preflight cache is
  // accessible outside of window. At that point, there should be no more need
  // to override this function in DOMXMLHttpRequestImpl.
  DLOG_IF(INFO, verbose()) << __FUNCTION__ << *xhr_;
  if (!dopreflight) {
    DCHECK(settings_->context()->network_module());
    StartURLFetcher(settings_->context()->network_module()->max_network_delay(),
                    url_fetcher_generation_);
  }
}

void XMLHttpRequestImpl::IncrementActiveRequests() {
  if (active_requests_count_ == 0) {
    DCHECK(settings_);
    DCHECK(settings_->context());
    prevent_gc_until_send_complete_.reset(
        new script::GlobalEnvironment::ScopedPreventGarbageCollection(
            settings_->context()->global_environment(), xhr_));
  }
  active_requests_count_++;
}

void XMLHttpRequestImpl::DecrementActiveRequests() {
  DCHECK_GT(active_requests_count_, 0);
  active_requests_count_--;
  if (active_requests_count_ == 0) {
    bool is_active = (state_ == XMLHttpRequest::kOpened && sent_) ||
                     state_ == XMLHttpRequest::kHeadersReceived ||
                     state_ == XMLHttpRequest::kLoading;
    bool has_event_listeners =
        xhr_->GetAttributeEventListener(base::Tokens::readystatechange()) ||
        xhr_->GetAttributeEventListener(base::Tokens::progress()) ||
        xhr_->GetAttributeEventListener(base::Tokens::abort()) ||
        xhr_->GetAttributeEventListener(base::Tokens::error()) ||
        xhr_->GetAttributeEventListener(base::Tokens::load()) ||
        xhr_->GetAttributeEventListener(base::Tokens::timeout()) ||
        xhr_->GetAttributeEventListener(base::Tokens::loadend());

    DCHECK_EQ((is_active && has_event_listeners), false);

    prevent_gc_until_send_complete_.reset();
  }
}

// Reset some variables in case the XHR object is reused.
void XMLHttpRequestImpl::PrepareForNewRequest() {
  request_headers_.Clear();
  // Below are variables used for CORS.
  request_body_text_.clear();
  is_cross_origin_ = false;
  redirect_times_ = 0;
  is_data_url_ = false;
  upload_listener_ = false;
  is_redirect_ = false;
}

void XMLHttpRequestImpl::StartURLFetcher(const SbTime max_artificial_delay,
                                         const int url_fetcher_generation) {
  if (max_artificial_delay > 0) {
    base::MessageLoop::current()->task_runner()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&XMLHttpRequestImpl::StartURLFetcher, base::Unretained(this),
                   0, url_fetcher_generation_),
        base::TimeDelta::FromMicroseconds(base::RandUint64() %
                                          max_artificial_delay));
    return;
  }

  // Note: Checking that "url_fetcher_generation_" != "url_fetcher_generation"
  // is to verify the "url_fetcher_" is currently the same one that was present
  // upon a delayed url fetch. This works because the incoming parameter
  // "url_fetcher_generation" will hold the value at the time of the initial
  // call, and if a delayed binding has waited while a new "url_fetcher_" has
  // changed state, "url_fetcher_generation_" will have incremented.
  if (nullptr != url_fetcher_ &&
      url_fetcher_generation == url_fetcher_generation_) {
    url_fetcher_->Start();
  }
}

void XMLHttpRequestImpl::CORSPreflightErrorCallback() {
  HandleRequestError(XMLHttpRequest::kNetworkError);
}

void XMLHttpRequestImpl::CORSPreflightSuccessCallback() {
  DCHECK(settings_->context()->network_module());
  StartURLFetcher(settings_->context()->network_module()->max_network_delay(),
                  url_fetcher_generation_);
}

DOMXMLHttpRequestImpl::DOMXMLHttpRequestImpl(XMLHttpRequest* xhr)
    : XMLHttpRequestImpl(xhr),
      settings_(base::polymorphic_downcast<dom::DOMSettings*>(
          xhr->environment_settings())) {
  DCHECK(settings_);
}

// https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#the-responsexml-attribute
scoped_refptr<dom::Document> DOMXMLHttpRequestImpl::response_xml(
    script::ExceptionState* exception_state) {
  // 1. If responseType is not the empty string or "document", throw an
  // "InvalidStateError" exception.
  if (response_type_ != XMLHttpRequest::kDefault &&
      response_type_ != XMLHttpRequest::kDocument) {
    web::DOMException::Raise(web::DOMException::kInvalidStateErr,
                             exception_state);
    return NULL;
  }

  // 2. If the state is not DONE, return null.
  if (state_ != XMLHttpRequest::kDone) {
    return NULL;
  }

  // 3. If the error flag is set, return null.
  if (error_) {
    return NULL;
  }

  // 4. Return the document response entity body.
  return GetDocumentResponseEntityBody();
}

void DOMXMLHttpRequestImpl::GetLoadTimingInfoAndCreateResourceTiming() {
  if (settings_->window()->performance() == nullptr) return;
  settings_->window()->performance()->CreatePerformanceResourceTiming(
      load_timing_info_, kPerformanceResourceTimingInitiatorType,
      request_url_.spec());
}

web::CspDelegate* DOMXMLHttpRequestImpl::csp_delegate() const {
  DCHECK(settings_);
  if (settings_->window() && settings_->window()->document()) {
    return settings_->window()->document()->csp_delegate();
  } else {
    return NULL;
  }
}

void DOMXMLHttpRequestImpl::StartRequest(const std::string& request_body) {
  TRACK_MEMORY_SCOPE("XHR");

  response_array_buffer_reference_.reset();

  network::NetworkModule* network_module =
      settings_->context()->fetcher_factory()->network_module();
  url_fetcher_ = net::URLFetcher::Create(request_url_, method_, xhr_);
  ++url_fetcher_generation_;
  url_fetcher_->SetRequestContext(network_module->url_request_context_getter());
  if (fetch_callback_) {
    response_body_ = new URLFetcherResponseWriter::Buffer(
        URLFetcherResponseWriter::Buffer::kString);
    response_body_->DisablePreallocate();
  } else {
    response_body_ = new URLFetcherResponseWriter::Buffer(
        response_type_ == XMLHttpRequest::kArrayBuffer
            ? URLFetcherResponseWriter::Buffer::kArrayBuffer
            : URLFetcherResponseWriter::Buffer::kString);
  }
  std::unique_ptr<net::URLFetcherResponseWriter> download_data_writer(
      new URLFetcherResponseWriter(response_body_));
  url_fetcher_->SaveResponseWithWriter(std::move(download_data_writer));
  // Don't retry, let the caller deal with it.
  url_fetcher_->SetAutomaticallyRetryOn5xx(false);
  url_fetcher_->SetExtraRequestHeaders(request_headers_.ToString());

  // We want to do cors check and preflight during redirects
  url_fetcher_->SetStopOnRedirect(true);

  if (request_body.size()) {
    // If applicable, the request body Content-Type is already set in
    // request_headers.
    url_fetcher_->SetUploadData("", request_body);
  }

  // We let data url fetch resources freely but with no response headers.
  is_data_url_ = is_data_url_ || request_url_.SchemeIs("data");
  is_cross_origin_ = (is_redirect_ && is_cross_origin_) ||
                     (origin_ != loader::Origin(request_url_) && !is_data_url_);
  is_redirect_ = false;
  // If the CORS flag is set, httpRequest’s method is neither `GET` nor `HEAD`
  // or httpRequest’s mode is "websocket", then append `Origin`/httpRequest’s
  // origin, serialized and UTF-8 encoded, to httpRequest’s header list.
  if (is_cross_origin_ ||
      (method_ != net::URLFetcher::GET && method_ != net::URLFetcher::HEAD)) {
    url_fetcher_->AddExtraRequestHeader("Origin:" + origin_.SerializedOrigin());
  }
  bool dopreflight = false;
  if (is_cross_origin_) {
    corspreflight_.reset(new cobalt::loader::CORSPreflight(
        request_url_, method_, network_module,
        base::Bind(&DOMXMLHttpRequestImpl::CORSPreflightSuccessCallback,
                   base::Unretained(this)),
        origin_.SerializedOrigin(),
        base::Bind(&DOMXMLHttpRequestImpl::CORSPreflightErrorCallback,
                   base::Unretained(this)),
        settings_->window()->get_preflight_cache()));
    corspreflight_->set_headers(request_headers_);
    // For cross-origin requests, don't send or save auth data / cookies unless
    // withCredentials was set.
    // To make a cross-origin request, add origin, referrer source, credentials,
    // omit credentials flag, force preflight flag
    if (!with_credentials_) {
      const uint32 kDisableCookiesLoadFlags =
          net::LOAD_NORMAL | net::LOAD_DO_NOT_SAVE_COOKIES |
          net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SEND_AUTH_DATA;
      url_fetcher_->SetLoadFlags(kDisableCookiesLoadFlags);
    } else {
      // For credentials mode: If the withCredentials attribute value is true,
      // "include", and "same-origin" otherwise.
      corspreflight_->set_credentials_mode_is_include(true);
    }
    corspreflight_->set_force_preflight(upload_listener_);
    dopreflight = corspreflight_->Send();
  }
  DLOG_IF(INFO, verbose()) << __FUNCTION__ << *xhr_;
  if (!dopreflight) {
    DCHECK(settings_->context()->network_module());
    StartURLFetcher(settings_->context()->network_module()->max_network_delay(),
                    url_fetcher_generation_);
  }
}

// https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#document-response-entity-body
scoped_refptr<dom::Document>
DOMXMLHttpRequestImpl::GetDocumentResponseEntityBody() {
  DCHECK_EQ(state_, XMLHttpRequest::kDone);

  // Step 1..5
  const std::string final_mime_type =
      mime_type_override_.empty() ? response_mime_type_ : mime_type_override_;
  if (final_mime_type != "text/xml" && final_mime_type != "application/xml") {
    return NULL;
  }

  // 6. Otherwise, let document be a document that represents the result of
  // parsing the response entity body following the rules set forth in the XML
  // specifications. If that fails (unsupported character encoding, namespace
  // well-formedness error, etc.), return null.
  scoped_refptr<dom::XMLDocument> xml_document =
      new dom::XMLDocument(settings_->window()->html_element_context());
  dom_parser::XMLDecoder xml_decoder(
      xml_document, xml_document, NULL, settings_->max_dom_element_depth(),
      base::SourceLocation("[object XMLHttpRequest]", 1, 1),
      base::Bind(&DOMXMLHttpRequestImpl::XMLDecoderLoadCompleteCallback,
                 base::Unretained(this)));
  has_xml_decoder_error_ = false;
  xml_decoder.DecodeChunk(response_body_->GetReferenceOfStringAndSeal().c_str(),
                          response_body_->GetReferenceOfStringAndSeal().size());
  xml_decoder.Finish();
  if (has_xml_decoder_error_) {
    return NULL;
  }

  // Step 7..11 Not needed by Cobalt.

  // 12. Return document.
  return xml_document;
}

void DOMXMLHttpRequestImpl::XMLDecoderLoadCompleteCallback(
    const base::Optional<std::string>& error) {
  if (error) has_xml_decoder_error_ = true;
}

std::ostream& operator<<(std::ostream& out, const XMLHttpRequest& xhr) {
#if !defined(COBALT_BUILD_TYPE_GOLD)
  base::StringPiece response_text("");
  if ((xhr.xhr_impl_->state_ == XMLHttpRequest::kDone) &&
      (xhr.xhr_impl_->response_type_ == XMLHttpRequest::kDefault ||
       xhr.xhr_impl_->response_type_ == XMLHttpRequest::kText)) {
    size_t kMaxSize = 4096;
    const auto& response_body =
        xhr.xhr_impl_->response_body_->GetTemporaryReferenceOfString();
    response_text =
        base::StringPiece(reinterpret_cast<const char*>(response_body.data()),
                          std::min(kMaxSize, response_body.size()));
  }

  std::string xhr_out = base::StringPrintf(
      " XHR:\n"
      "\tid:    %d\n"
      "\trequest_url: %s\n"
      "\tstate: %s\n"
      "\tresponse_type: %s\n"
      "\ttimeout_ms: %d\n"
      "\tmethod: %s\n"
      "\thttp_status: %d\n"
      "\twith_credentials: %s\n"
      "\terror: %s\n"
      "\tsent: %s\n"
      "\tstop_timeout: %s\n"
      "\tresponse_body: %s\n",
      xhr.xhr_id_, xhr.xhr_impl_->request_url_.spec().c_str(),
      StateName(xhr.xhr_impl_->state_), xhr.response_type(NULL).c_str(),
      xhr.xhr_impl_->timeout_ms_,
      RequestTypeToMethodName(xhr.xhr_impl_->method_),
      xhr.xhr_impl_->http_status_,
      xhr.xhr_impl_->with_credentials_ ? "true" : "false",
      xhr.xhr_impl_->error_ ? "true" : "false",
      xhr.xhr_impl_->sent_ ? "true" : "false",
      xhr.xhr_impl_->stop_timeout_ ? "true" : "false",
      response_text.as_string().c_str());
  out << xhr_out;
#else
#endif
  return out;
}

}  // namespace xhr
}  // namespace cobalt
