// 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 <utility>

#include "base/compiler_specific.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/time.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/base/source_location.h"
#include "cobalt/base/tokens.h"
#include "cobalt/dom/csp_delegate.h"
#include "cobalt/dom/dom_settings.h"
#include "cobalt/dom/global_stats.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/script/global_environment.h"
#include "cobalt/script/javascript_engine.h"
#include "cobalt/xhr/xhr_modify_headers.h"
#include "nb/memory_scope.h"
#include "net/http/http_util.h"

namespace cobalt {
namespace xhr {

using dom::DOMException;

namespace {

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

// Allocate 64KB on receiving the first chunk to avoid allocating small buffer
// too many times.
const size_t kInitialReceivingBufferSize = 64 * 1024;

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

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

bool MethodNameToRequestType(const std::string& method,
                             net::URLFetcher::RequestType* request_type) {
  if (LowerCaseEqualsASCII(method, "get")) {
    *request_type = net::URLFetcher::GET;
  } else if (LowerCaseEqualsASCII(method, "post")) {
    *request_type = net::URLFetcher::POST;
  } else if (LowerCaseEqualsASCII(method, "head")) {
    *request_type = net::URLFetcher::HEAD;
  } else if (LowerCaseEqualsASCII(method, "delete")) {
    *request_type = net::URLFetcher::DELETE_REQUEST;
  } else if (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 (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));
}

int s_xhr_sequence_num_ = 0;
// 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 XMLHttpRequest::verbose_ = false;

XMLHttpRequest::XMLHttpRequest(script::EnvironmentSettings* settings)
    : settings_(base::polymorphic_downcast<dom::DOMSettings*>(settings)),
      state_(kUnsent),
      response_type_(kDefault),
      timeout_ms_(0),
      method_(net::URLFetcher::GET),
      http_status_(0),
      with_credentials_(false),
      error_(false),
      sent_(false),
      stop_timeout_(false),
      upload_complete_(false),
      active_requests_count_(0),
      upload_listener_(false),
      is_cross_origin_(false),
      is_redirect_(false),
      redirect_times_(0),
      is_data_url_(false) {
  DCHECK(settings_);
  dom::GlobalStats::GetInstance()->Add(this);
  xhr_id_ = ++s_xhr_sequence_num_;
}

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

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

// https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#the-open()-method
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) {
  TRACK_MEMORY_SCOPE("XHR");
  UNREFERENCED_PARAMETER(username);
  UNREFERENCED_PARAMETER(password);

  DCHECK(thread_checker_.CalledOnValidThread());

  State previous_state = state_;

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

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

  base_url_ = settings_->base_url();

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

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

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

  dom::CspDelegate* csp = csp_delegate();
  if (csp && !csp->CanLoad(dom::CspDelegate::kXhr, request_url_, false)) {
    DOMException::Raise(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 != kOpened) {
    ChangeState(kOpened);
  } else {
    state_ = kOpened;
  }
}

void XMLHttpRequest::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_ != kOpened || sent_) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    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 XMLHttpRequest::OverrideMimeType(const std::string& override_mime,
                                      script::ExceptionState* exception_state) {
  // https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#dom-xmlhttprequest-overridemimetype
  DCHECK(thread_checker_.CalledOnValidThread());
  if (state_ == kLoading || state_ == kDone) {
    DOMException::Raise(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()) {
    DOMException::Raise(DOMException::kSyntaxErr, exception_state);
    return;
  }
  mime_type_override_ = mime_type;
}

void XMLHttpRequest::Send(script::ExceptionState* exception_state) {
  Send(base::nullopt, exception_state);
}

void XMLHttpRequest::Send(const base::optional<RequestBodyType>& request_body,
                          script::ExceptionState* exception_state) {
  TRACK_MEMORY_SCOPE("XHR");
  // https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#the-send()-method
  DCHECK(thread_checker_.CalledOnValidThread());
  // Step 1
  if (state_ != kOpened) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return;
  }
  // Step 2
  if (sent_) {
    DOMException::Raise(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_ = settings_->document_origin();
  // 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(this, 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_ == kOpened && sent_) {
    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 XMLHttpRequest::Fetch(const FetchUpdateCallbackArg& fetch_callback,
                           const FetchModeCallbackArg& fetch_mode_callback,
                           const base::optional<RequestBodyType>& request_body,
                           script::ExceptionState* exception_state) {
  fetch_callback_.reset(
      new FetchUpdateCallbackArg::Reference(this, fetch_callback));
  fetch_mode_callback_.reset(
      new FetchModeCallbackArg::Reference(this, fetch_mode_callback));
  Send(request_body, exception_state);
}

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

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

  // Set-Cookie should be stripped from the response headers in OnDone().
  if (LowerCaseEqualsASCII(header, "set-cookie") ||
      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 XMLHttpRequest::GetAllResponseHeaders() {
  // https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#the-getallresponseheaders()-method
  DCHECK(thread_checker_.CalledOnValidThread());
  std::string output;

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

  void* iter = NULL;
  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& XMLHttpRequest::response_text(
    script::ExceptionState* exception_state) {
  // https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#the-responsetext-attribute
  if (response_type_ != kDefault && response_type_ != kText) {
    dom::DOMException::Raise(dom::DOMException::kInvalidStateErr,
                             exception_state);
  }
  if (error_ || (state_ != kLoading && state_ != kDone)) {
    return EmptyString();
  }

  return response_body_.string();
}

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

  // 2. If the state is not DONE, return null.
  if (state_ != 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();
}

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

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

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

  return http_response_headers_->GetStatusText();
}

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

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

std::string XMLHttpRequest::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 XMLHttpRequest::set_timeout(uint32 timeout) {
  // https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#the-timeout-attribute
  DCHECK(thread_checker_.CalledOnValidThread());

  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 XMLHttpRequest::with_credentials(
    script::ExceptionState* /*unused*/) const {
  return with_credentials_;
}

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

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

void XMLHttpRequest::OnURLFetchResponseStarted(const net::URLFetcher* source) {
  DCHECK(thread_checker_.CalledOnValidThread());

  http_status_ = source->GetResponseCode();
  // Don't handle a response without headers.
  if (!source->GetResponseHeaders()) {
    HandleRequestError(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(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_);
  }

  // Reserve space for the content in the case of a regular XHR request.
  DCHECK_EQ(response_body_.size(), 0);
  if (!fetch_callback_) {
    const int64 content_length = http_response_headers_->GetContentLength();

    // If we know the eventual content length, allocate the total response body.
    // Otherwise just reserve a reasonably large initial chunk.
    size_t bytes_to_reserve = content_length > 0
                                  ? static_cast<size_t>(content_length)
                                  : kInitialReceivingBufferSize;
    response_body_.Reserve(bytes_to_reserve);
  }

  // Further filter response headers as XHR's mode is cors
  if (is_cross_origin_) {
    void* iter = NULL;
    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_) {
    void* iter = NULL;
    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(kHeadersReceived);

  UpdateProgress();
}

void XMLHttpRequest::OnURLFetchDownloadData(
    const net::URLFetcher* source, scoped_ptr<std::string> download_data) {
  TRACK_MEMORY_SCOPE("XHR");
  UNREFERENCED_PARAMETER(source);
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_NE(state_, kDone);
  ChangeState(kLoading);

  // Preserve the response body only for regular XHR requests. Fetch requests
  // process the response in pieces, so do not need to keep the whole response.
  if (!fetch_callback_) {
    response_body_.Append(reinterpret_cast<const uint8*>(download_data->data()),
                          download_data->size());
  }

  if (fetch_callback_) {
    script::Handle<script::Uint8Array> data =
        script::Uint8Array::New(settings_->global_environment(),
                                download_data->data(), download_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;
    UpdateProgress();
  }
}

void XMLHttpRequest::OnURLFetchComplete(const net::URLFetcher* source) {
  DCHECK(thread_checker_.CalledOnValidThread());
  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;
    }
  }
  fetch_callback_.reset();
  fetch_mode_callback_.reset();
  const net::URLRequestStatus& status = source->GetStatus();
  if (status.is_success()) {
    stop_timeout_ = true;
    if (error_) {
      return;
    }

    ChangeState(kDone);
    UpdateProgress();
    // Undo the ref we added in Send()
    DecrementActiveRequests();
  } else {
    HandleRequestError(kNetworkError);
  }
}

// Reset some variables in case the XHR object is reused.
void XMLHttpRequest::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 XMLHttpRequest::OnURLFetchUploadProgress(const net::URLFetcher* source,
                                              int64 current_val,
                                              int64 total_val) {
  TRACK_MEMORY_SCOPE("XHR");
  UNREFERENCED_PARAMETER(source);
  DCHECK(thread_checker_.CalledOnValidThread());
  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
  // transmiteted 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 XMLHttpRequest::OnRedirect(const net::HttpResponseHeaders& headers) {
  DCHECK(thread_checker_.CalledOnValidThread());
  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(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(kNetworkError);
      return;
    } else if (is_cross_origin_) {
      DLOG(INFO) << "XHR is redirected with credentials and cors_flag set, "
                    "aborting request for security reasons.";
      HandleRequestError(kNetworkError);
      return;
    }
  }
  if (!new_url.is_valid()) {
    HandleRequestError(kNetworkError);
    return;
  }
  // This is a redirect. Re-check the CSP.
  if (!csp_delegate()->CanLoad(dom::CspDelegate::kXhr, new_url,
                               true /* is_redirect */)) {
    HandleRequestError(kNetworkError);
    return;
  }
  // CORS check for the received resposne
  if (is_cross_origin_) {
    if (!loader::CORSPreflight::CORSCheck(headers, origin_.SerializedOrigin(),
                                          with_credentials_)) {
      HandleRequestError(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_++;
  StartRequest(request_body_text_);
}

void XMLHttpRequest::TraceMembers(script::Tracer* tracer) {
  XMLHttpRequestEventTarget::TraceMembers(tracer);

  tracer->Trace(upload_);
}

XMLHttpRequest::~XMLHttpRequest() {
  DCHECK(thread_checker_.CalledOnValidThread());
  dom::GlobalStats::GetInstance()->Remove(this);
}

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

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

void XMLHttpRequest::HandleRequestError(
    XMLHttpRequest::RequestErrorType request_error_type) {
  // https://www.w3.org/TR/XMLHttpRequest/#timeout-error
  DCHECK(thread_checker_.CalledOnValidThread());
  DLOG_IF(INFO, verbose())
      << __FUNCTION__ << " (" << RequestErrorTypeName(request_error_type)
      << ") " << *this << std::endl
      << script::StackTraceToString(
             settings_->global_environment()->GetStackTrace(0 /*max_frames*/));
  stop_timeout_ = true;
  // Step 1
  TerminateRequest();
  // Steps 2-4
  // Change state and fire readystatechange event.
  ChangeState(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(this, base::Tokens::progress());
  FireProgressEvent(this, error_name);
  FireProgressEvent(this, base::Tokens::loadend());

  fetch_callback_.reset();
  DecrementActiveRequests();
}

void XMLHttpRequest::OnTimeout() {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (!stop_timeout_) {
    HandleRequestError(kTimeoutError);
  }
}

void XMLHttpRequest::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, &XMLHttpRequest::OnTimeout);
}

void XMLHttpRequest::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 != kLoading) {
    return;
  }

  state_ = new_state;
  if (state_ != kUnsent) {
    DispatchEvent(new dom::Event(base::Tokens::readystatechange()));
  }
}

script::Handle<script::ArrayBuffer> XMLHttpRequest::response_array_buffer() {
  TRACK_MEMORY_SCOPE("XHR");
  // https://www.w3.org/TR/XMLHttpRequest/#response-entity-body
  if (error_ || state_ != 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.
    auto array_buffer =
        script::ArrayBuffer::New(settings_->global_environment(),
                                 response_body_.data(), response_body_.size());
    response_array_buffer_reference_.reset(
        new script::ScriptValue<script::ArrayBuffer>::Reference(this,
                                                                array_buffer));
    response_body_.Clear();
    return array_buffer;
  } else {
    return script::Handle<script::ArrayBuffer>(
        *response_array_buffer_reference_);
  }
}

void XMLHttpRequest::UpdateProgress() {
  DCHECK(http_response_headers_);
  const int64 content_length = http_response_headers_->GetContentLength();
  const int64 received_length = static_cast<int64>(response_body_.size());
  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 << ") " << *this;

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

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

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

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

    prevent_gc_until_send_complete_.reset();
  }
}

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

  response_body_.Clear();
  response_array_buffer_reference_.reset();

  network::NetworkModule* network_module =
      settings_->fetcher_factory()->network_module();
  url_fetcher_.reset(net::URLFetcher::Create(request_url_, method_, this));
  url_fetcher_->SetRequestContext(network_module->url_request_context_getter());
  // Don't cache the response, just send it to us in OnURLFetchDownloadData().
  url_fetcher_->DiscardResponse();
  // 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(&XMLHttpRequest::CORSPreflightSuccessCallback,
                   base::Unretained(this)),
        origin_.SerializedOrigin(),
        base::Bind(&XMLHttpRequest::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__ << *this;
  if (!dopreflight) {
    url_fetcher_->Start();
  }
}

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

void XMLHttpRequest::CORSPreflightSuccessCallback() {
  if (url_fetcher_) {
    url_fetcher_->Start();
  }
}

std::ostream& operator<<(std::ostream& out, const XMLHttpRequest& xhr) {
#if !defined(COBALT_BUILD_TYPE_GOLD)
  base::StringPiece response_text("");
  if ((xhr.state_ == XMLHttpRequest::kDone) &&
      (xhr.response_type_ == XMLHttpRequest::kDefault ||
       xhr.response_type_ == XMLHttpRequest::kText)) {
    size_t kMaxSize = 4096;
    response_text = base::StringPiece(
        reinterpret_cast<const char*>(xhr.response_body_.data()),
        std::min(kMaxSize, xhr.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.request_url_.spec().c_str(), StateName(xhr.state_),
      xhr.response_type(NULL).c_str(), xhr.timeout_ms_,
      RequestTypeToMethodName(xhr.method_), xhr.http_status_,
      xhr.with_credentials_ ? "true" : "false", xhr.error_ ? "true" : "false",
      xhr.sent_ ? "true" : "false", xhr.stop_timeout_ ? "true" : "false",
      response_text.as_string().c_str());
  out << xhr_out;
#else
  UNREFERENCED_PARAMETER(xhr);
#endif
  return out;
}

// https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#document-response-entity-body
scoped_refptr<dom::Document> XMLHttpRequest::GetDocumentResponseEntityBody() {
  // 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::Closure(),
      base::Bind(&XMLHttpRequest::XMLDecoderLoadCompleteCallback,
                 base::Unretained(this)));
  has_xml_decoder_error_ = false;
  xml_decoder.DecodeChunk(response_body_.string().c_str(),
                          response_body_.string().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 XMLHttpRequest::XMLDecoderLoadCompleteCallback(
    const base::optional<std::string>& error) {
  if (error) has_xml_decoder_error_ = true;
}

}  // namespace xhr
}  // namespace cobalt
