// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome_frame/urlmon_url_request.h"

#include <urlmon.h>
#include <wininet.h>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread.h"
#include "chrome/common/automation_messages.h"
#include "chrome_frame/bind_context_info.h"
#include "chrome_frame/chrome_frame_activex_base.h"
#include "chrome_frame/extra_system_apis.h"
#include "chrome_frame/html_utils.h"
#include "chrome_frame/urlmon_upload_data_stream.h"
#include "chrome_frame/urlmon_url_request_private.h"
#include "chrome_frame/utils.h"
#include "net/base/load_flags.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"

#define IS_HTTP_SUCCESS_CODE(code) (code >= 200 && code <= 299)

UrlmonUrlRequest::UrlmonUrlRequest()
    : pending_read_size_(0),
      headers_received_(false),
      calling_delegate_(0),
      thread_(NULL),
      parent_window_(NULL),
      privileged_mode_(false),
      pending_(false),
      is_expecting_download_(true),
      cleanup_transaction_(false) {
  DVLOG(1) << __FUNCTION__ << me();
}

UrlmonUrlRequest::~UrlmonUrlRequest() {
  DVLOG(1) << __FUNCTION__ << me();
}

std::string UrlmonUrlRequest::me() const {
  return base::StringPrintf(" id: %i Obj: %X ", id(), this);
}

bool UrlmonUrlRequest::Start() {
  DVLOG(1) << __FUNCTION__ << me() << url();
  DCHECK(thread_ == 0 || thread_ == base::PlatformThread::CurrentId());
  thread_ = base::PlatformThread::CurrentId();
  status_.Start();
  // Initialize the net::HostPortPair structure from the url initially. We may
  // not receive the ip address of the host if the request is satisfied from
  // the cache.
  socket_address_ = net::HostPortPair::FromURL(GURL(url()));
  // The UrlmonUrlRequest instance can get destroyed in the context of
  // StartAsyncDownload if BindToStorage finishes synchronously with an error.
  // Grab a reference to protect against this.
  scoped_refptr<UrlmonUrlRequest> ref(this);
  HRESULT hr = StartAsyncDownload();
  if (FAILED(hr) && status_.get_state() != UrlmonUrlRequest::Status::DONE) {
    status_.Done();
    status_.set_result(net::URLRequestStatus::FAILED, HresultToNetError(hr));
    NotifyDelegateAndDie();
  }
  return true;
}

void UrlmonUrlRequest::Stop() {
  DCHECK_EQ(thread_, base::PlatformThread::CurrentId());
  DCHECK((status_.get_state() != Status::DONE) == (binding_ != NULL));
  Status::State state = status_.get_state();
  delegate_ = NULL;

  // If DownloadInHost is already requested, we will quit soon anyway.
  if (terminate_requested())
    return;

  switch (state) {
    case Status::WORKING:
      status_.Cancel();
      if (binding_)
        binding_->Abort();
      break;

    case Status::ABORTING:
      status_.Cancel();
      break;

    case Status::DONE:
      status_.Cancel();
      NotifyDelegateAndDie();
      break;
  }
}

bool UrlmonUrlRequest::Read(int bytes_to_read) {
  DCHECK_EQ(thread_, base::PlatformThread::CurrentId());
  DCHECK_GE(bytes_to_read, 0);
  DCHECK_EQ(0, calling_delegate_);
  DVLOG(1) << __FUNCTION__ << me();

  is_expecting_download_ = false;

  // Re-entrancy check. Thou shall not call Read() while process OnReadComplete!
  DCHECK_EQ(0u, pending_read_size_);
  if (pending_read_size_ != 0)
    return false;

  DCHECK((status_.get_state() != Status::DONE) == (binding_ != NULL));
  if (status_.get_state() == Status::ABORTING)
    return true;

  // Send data if available.
  size_t bytes_copied = 0;
  if ((bytes_copied = SendDataToDelegate(bytes_to_read))) {
    DVLOG(1) << __FUNCTION__ << me() << " bytes read: " << bytes_copied;
    return true;
  }

  if (status_.get_state() == Status::WORKING) {
    DVLOG(1) << __FUNCTION__ << me() << " pending: " << bytes_to_read;
    pending_read_size_ = bytes_to_read;
  } else {
    DVLOG(1) << __FUNCTION__ << me() << " Response finished.";
    NotifyDelegateAndDie();
  }

  return true;
}

HRESULT UrlmonUrlRequest::InitPending(const GURL& url, IMoniker* moniker,
                                      IBindCtx* bind_context,
                                      bool enable_frame_busting,
                                      bool privileged_mode,
                                      HWND notification_window,
                                      IStream* cache) {
  DVLOG(1) << __FUNCTION__ << me() << url.spec();
  DCHECK(bind_context_ == NULL);
  DCHECK(moniker_ == NULL);
  DCHECK(cache_ == NULL);
  DCHECK(thread_ == 0 || thread_ == base::PlatformThread::CurrentId());
  thread_ = base::PlatformThread::CurrentId();
  bind_context_ = bind_context;
  moniker_ = moniker;
  enable_frame_busting_ = enable_frame_busting;
  privileged_mode_ = privileged_mode;
  parent_window_ = notification_window;
  cache_ = cache;
  set_url(url.spec());
  set_pending(true);

  // Request has already started and data is fetched. We will get the
  // GetBindInfo call as per contract but the return values are
  // ignored. So just set "get" as a method to make our GetBindInfo
  // implementation happy.
  method_ = "get";
  return S_OK;
}

void UrlmonUrlRequest::TerminateBind(const TerminateBindCallback& callback) {
  DCHECK_EQ(thread_, base::PlatformThread::CurrentId());
  DVLOG(1) << __FUNCTION__ << me();
  cleanup_transaction_ = false;
  if (status_.get_state() == Status::DONE) {
    // Binding is stopped. Note result could be an error.
    callback.Run(moniker_, bind_context_, upload_data_,
                 request_headers_.c_str());
  } else {
    // WORKING (ABORTING?). Save the callback.
    // Now we will return INET_TERMINATE_BIND from ::OnDataAvailable() and in
    // ::OnStopBinding will invoke the callback passing our moniker and
    // bind context.
    terminate_bind_callback_ = callback;
    if (pending_data_) {
      // For downloads to work correctly, we must induce a call to
      // OnDataAvailable so that we can download INET_E_TERMINATED_BIND and
      // get IE into the correct state.
      // To accomplish this we read everything that's readily available in
      // the current stream.  Once we've reached the end of the stream we
      // should get E_PENDING back and then later we'll get that call
      // to OnDataAvailable.
      std::string data;
      base::win::ScopedComPtr<IStream> read_stream(pending_data_);
      HRESULT hr;
      while ((hr = ReadStream(read_stream, 0xffff, &data)) == S_OK) {
        // Just drop the data.
      }
      DLOG_IF(WARNING, hr != E_PENDING) << __FUNCTION__ <<
          base::StringPrintf(" expected E_PENDING but got 0x%08X", hr);
    }
  }
}

size_t UrlmonUrlRequest::SendDataToDelegate(size_t bytes_to_read) {
  DCHECK_EQ(thread_, base::PlatformThread::CurrentId());
  DCHECK_NE(id(), -1);
  DCHECK_GT(bytes_to_read, 0U);
  size_t bytes_copied = 0;
  if (delegate_) {
    std::string read_data;
    if (cache_) {
      HRESULT hr = ReadStream(cache_, bytes_to_read, &read_data);
      if (hr == S_FALSE || read_data.length() < bytes_to_read) {
        DVLOG(1) << __FUNCTION__ << me() << "all cached data read";
        cache_.Release();
      }
    }

    if (read_data.empty() && pending_data_) {
      size_t pending_data_read_save = pending_read_size_;
      pending_read_size_ = 0;

      // AddRef the stream while we call Read to avoid a potential issue
      // where we can get a call to OnDataAvailable while inside Read and
      // in our OnDataAvailable call, we can release the stream object
      // while still using it.
      base::win::ScopedComPtr<IStream> pending(pending_data_);
      HRESULT hr = ReadStream(pending, bytes_to_read, &read_data);
      if (read_data.empty())
        pending_read_size_ = pending_data_read_save;
      // If we received S_FALSE it indicates that there is no more data in the
      // stream. Clear it to ensure that OnStopBinding correctly sends over the
      // response end notification to chrome.
      if (hr == S_FALSE)
        pending_data_.Release();
    }

    bytes_copied = read_data.length();

    if (bytes_copied) {
      ++calling_delegate_;
      DCHECK_NE(id(), -1);
      // The delegate can go away in the middle of ReadStream
      if (delegate_)
        delegate_->OnReadComplete(id(), read_data);
      --calling_delegate_;
    }
  } else {
    DLOG(ERROR) << __FUNCTION__ << me() << "no delegate";
  }

  return bytes_copied;
}

STDMETHODIMP UrlmonUrlRequest::OnStartBinding(DWORD reserved,
                                              IBinding* binding) {
  DCHECK_EQ(thread_, base::PlatformThread::CurrentId());
  binding_ = binding;
  if (pending_) {
    response_headers_ = GetHttpHeadersFromBinding(binding_);
    DCHECK(!response_headers_.empty());
  }
  return S_OK;
}

STDMETHODIMP UrlmonUrlRequest::GetPriority(LONG *priority) {
  if (!priority)
    return E_POINTER;
  *priority = THREAD_PRIORITY_NORMAL;
  return S_OK;
}

STDMETHODIMP UrlmonUrlRequest::OnLowResource(DWORD reserved) {
  return S_OK;
}

STDMETHODIMP UrlmonUrlRequest::OnProgress(ULONG progress, ULONG max_progress,
    ULONG status_code, LPCWSTR status_text) {
  DCHECK_EQ(thread_, base::PlatformThread::CurrentId());

  if (status_.get_state() != Status::WORKING)
    return S_OK;

  // Ignore any notifications received while we are in the pending state
  // waiting for the request to be initiated by Chrome.
  if (pending_ && status_code != BINDSTATUS_REDIRECTING)
    return S_OK;

  if (!delegate_) {
    DVLOG(1) << "Invalid delegate";
    return S_OK;
  }

  switch (status_code) {
    case BINDSTATUS_CONNECTING: {
      if (status_text) {
        socket_address_.set_host(WideToUTF8(status_text));
      }
      break;
    }

    case BINDSTATUS_REDIRECTING: {
      // If we receive a redirect for the initial pending request initiated
      // when our document loads we should stash it away and inform Chrome
      // accordingly when it requests data for the original URL.
      base::win::ScopedComPtr<BindContextInfo> info;
      BindContextInfo::FromBindContext(bind_context_, info.Receive());
      DCHECK(info);
      GURL previously_redirected(info ? info->GetUrl() : std::wstring());
      if (GURL(status_text) != previously_redirected) {
        DVLOG(1) << __FUNCTION__ << me() << "redirect from " << url()
                 << " to " << status_text;
        // Fetch the redirect status as they aren't all equal (307 in particular
        // retains the HTTP request verb).
        int http_code = GetHttpResponseStatusFromBinding(binding_);
        status_.SetRedirected(http_code, WideToUTF8(status_text));
        // Abort. We will inform Chrome in OnStopBinding callback.
        binding_->Abort();
        return E_ABORT;
      }
      break;
    }

    case BINDSTATUS_COOKIE_SENT:
      delegate_->AddPrivacyDataForUrl(url(), "", COOKIEACTION_READ);
      break;

    case BINDSTATUS_COOKIE_SUPPRESSED:
      delegate_->AddPrivacyDataForUrl(url(), "", COOKIEACTION_SUPPRESS);
      break;

    case BINDSTATUS_COOKIE_STATE_ACCEPT:
      delegate_->AddPrivacyDataForUrl(url(), "", COOKIEACTION_ACCEPT);
      break;

    case BINDSTATUS_COOKIE_STATE_REJECT:
      delegate_->AddPrivacyDataForUrl(url(), "", COOKIEACTION_REJECT);
      break;

    case BINDSTATUS_COOKIE_STATE_LEASH:
      delegate_->AddPrivacyDataForUrl(url(), "", COOKIEACTION_LEASH);
      break;

    case BINDSTATUS_COOKIE_STATE_DOWNGRADE:
      delegate_->AddPrivacyDataForUrl(url(), "", COOKIEACTION_DOWNGRADE);
      break;

    case BINDSTATUS_COOKIE_STATE_UNKNOWN:
      NOTREACHED() << L"Unknown cookie state received";
      break;

    default:
      DVLOG(1) << __FUNCTION__ << me()
               << base::StringPrintf(L"code: %i status: %ls", status_code,
                                     status_text);
      break;
  }

  return S_OK;
}

STDMETHODIMP UrlmonUrlRequest::OnStopBinding(HRESULT result, LPCWSTR error) {
  DCHECK_EQ(thread_, base::PlatformThread::CurrentId());
  DVLOG(1) << __FUNCTION__ << me()
           << "- Request stopped, Result: " << std::hex << result;
  DCHECK(status_.get_state() == Status::WORKING ||
         status_.get_state() == Status::ABORTING);

  Status::State state = status_.get_state();

  // Mark we a are done.
  status_.Done();

  if (result == INET_E_TERMINATED_BIND) {
    if (terminate_requested()) {
      terminate_bind_callback_.Run(moniker_, bind_context_, upload_data_,
                                   request_headers_.c_str());
    } else {
      cleanup_transaction_ = true;
    }
    // We may have returned INET_E_TERMINATED_BIND from OnDataAvailable.
    result = S_OK;
  }

  if (state == Status::WORKING) {
    status_.set_result(result);

    if (FAILED(result)) {
      int http_code = GetHttpResponseStatusFromBinding(binding_);
      // For certain requests like empty POST requests the server can return
      // back a HTTP success code in the range 200 to 299. We need to flag
      // these requests as succeeded.
      if (IS_HTTP_SUCCESS_CODE(http_code)) {
        // If this DCHECK fires it means that the server returned a HTTP
        // success code outside the standard range 200-206. We need to confirm
        // if the following code path is correct.
        DCHECK_LE(http_code, 206);
        status_.set_result(S_OK);
        std::string headers = GetHttpHeadersFromBinding(binding_);
        OnResponse(0, UTF8ToWide(headers).c_str(), NULL, NULL);
      } else if (net::HttpResponseHeaders::IsRedirectResponseCode(http_code) &&
                 result == E_ACCESSDENIED) {
        // Special case. If the last request was a redirect and the current OS
        // error value is E_ACCESSDENIED, that means an unsafe redirect was
        // attempted. In that case, correct the OS error value to be the more
        // specific ERR_UNSAFE_REDIRECT error value.
        status_.set_result(net::URLRequestStatus::FAILED,
                           net::ERR_UNSAFE_REDIRECT);
      }
    }

    // The code below seems easy but it is not. :)
    // The network policy in Chrome network is that error code/end_of_stream
    // should be returned only as a result of read (or start) request.
    // Here are the possible cases:
    // pending_data_|pending_read
    //     FALSE  |FALSE   => EndRequest if no headers, otherwise wait for Read.
    //     FALSE  |TRUE    => EndRequest.
    //     TRUE   |FALSE   => Wait for Read.
    //     TRUE   |TRUE    => Something went wrong!!

    if (pending_data_) {
      DCHECK_EQ(pending_read_size_, 0UL);
      ReleaseBindings();
      return S_OK;
    }

    if (headers_received_ && pending_read_size_ == 0) {
      ReleaseBindings();
      return S_OK;
    }

    // No headers or there is a pending read from Chrome.
    NotifyDelegateAndDie();
    return S_OK;
  }

  // Status::ABORTING
  if (status_.was_redirected()) {
    // Just release bindings here. Chrome will issue EndRequest(request_id)
    // after processing headers we had provided.
    if (!pending_) {
      std::string headers = GetHttpHeadersFromBinding(binding_);
      OnResponse(0, UTF8ToWide(headers).c_str(), NULL, NULL);
    }
    ReleaseBindings();
    return S_OK;
  }

  // Stop invoked.
  NotifyDelegateAndDie();
  return S_OK;
}

STDMETHODIMP UrlmonUrlRequest::GetBindInfo(DWORD* bind_flags,
                                           BINDINFO* bind_info) {
  if ((bind_info == NULL) || (bind_info->cbSize == 0) || (bind_flags == NULL))
    return E_INVALIDARG;

  *bind_flags = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;

  bind_info->dwOptionsFlags = INTERNET_FLAG_NO_AUTO_REDIRECT;
  bind_info->dwOptions = BINDINFO_OPTIONS_WININETFLAG;

  // TODO(ananta)
  // Look into whether the other load flags need to be supported in chrome
  // frame.
  if (load_flags_ & net::LOAD_VALIDATE_CACHE)
    *bind_flags |= BINDF_RESYNCHRONIZE;

  if (load_flags_ & net::LOAD_BYPASS_CACHE)
    *bind_flags |= BINDF_GETNEWESTVERSION;

  if (LowerCaseEqualsASCII(method(), "get")) {
    bind_info->dwBindVerb = BINDVERB_GET;
  } else if (LowerCaseEqualsASCII(method(), "post")) {
    bind_info->dwBindVerb = BINDVERB_POST;
  } else if (LowerCaseEqualsASCII(method(), "put")) {
    bind_info->dwBindVerb = BINDVERB_PUT;
  } else {
    std::wstring verb(ASCIIToWide(StringToUpperASCII(method())));
    bind_info->dwBindVerb = BINDVERB_CUSTOM;
    bind_info->szCustomVerb = reinterpret_cast<wchar_t*>(
        ::CoTaskMemAlloc((verb.length() + 1) * sizeof(wchar_t)));
    lstrcpyW(bind_info->szCustomVerb, verb.c_str());
  }

  if (bind_info->dwBindVerb == BINDVERB_POST ||
      bind_info->dwBindVerb == BINDVERB_PUT ||
      post_data_len() > 0) {
    // Bypass caching proxies on upload requests and avoid writing responses to
    // the browser's cache.
    *bind_flags |= BINDF_GETNEWESTVERSION | BINDF_PRAGMA_NO_CACHE;

    // Attempt to avoid storing the response for upload requests.
    // See http://crbug.com/55918
    if (resource_type_ != ResourceType::MAIN_FRAME)
      *bind_flags |= BINDF_NOWRITECACHE;

    // Initialize the STGMEDIUM.
    memset(&bind_info->stgmedData, 0, sizeof(STGMEDIUM));
    bind_info->grfBindInfoF = 0;

    if (bind_info->dwBindVerb != BINDVERB_CUSTOM)
      bind_info->szCustomVerb = NULL;

    if ((post_data_len() || is_chunked_upload()) &&
        get_upload_data(&bind_info->stgmedData.pstm) == S_OK) {
      bind_info->stgmedData.tymed = TYMED_ISTREAM;
      if (!is_chunked_upload()) {
        bind_info->cbstgmedData = static_cast<DWORD>(post_data_len());
      }
      DVLOG(1) << __FUNCTION__ << me() << method()
               << " request with " << base::Int64ToString(post_data_len())
               << " bytes. url=" << url();
    } else {
      DVLOG(1) << __FUNCTION__ << me() << "POST request with no data!";
    }
  }
  return S_OK;
}

STDMETHODIMP UrlmonUrlRequest::OnDataAvailable(DWORD flags, DWORD size,
                                               FORMATETC* formatetc,
                                               STGMEDIUM* storage) {
  DCHECK_EQ(thread_, base::PlatformThread::CurrentId());
  DVLOG(1) << __FUNCTION__ << me() << "bytes available: " << size;

  if (terminate_requested()) {
    DVLOG(1) << " Download requested. INET_E_TERMINATED_BIND returned";
    return INET_E_TERMINATED_BIND;
  }

  if (!storage || (storage->tymed != TYMED_ISTREAM)) {
    NOTREACHED();
    return E_INVALIDARG;
  }

  IStream* read_stream = storage->pstm;
  if (!read_stream) {
    NOTREACHED();
    return E_UNEXPECTED;
  }

  // Some requests such as HEAD have zero data.
  if (size > 0)
    pending_data_ = read_stream;

  if (pending_read_size_) {
    size_t bytes_copied = SendDataToDelegate(pending_read_size_);
    DVLOG(1) << __FUNCTION__ << me() << "size read: " << bytes_copied;
  } else {
    DVLOG(1) << __FUNCTION__ << me() << "- waiting for remote read";
  }

  if (BSCF_LASTDATANOTIFICATION & flags) {
    if (!is_expecting_download_ || pending()) {
      DVLOG(1) << __FUNCTION__ << me() << "EOF";
      return S_OK;
    }
    // Always return INET_E_TERMINATED_BIND to allow bind context reuse
    // if DownloadToHost is suddenly requested.
    DVLOG(1) << __FUNCTION__ << " EOF: INET_E_TERMINATED_BIND returned";
    return INET_E_TERMINATED_BIND;
  }
  return S_OK;
}

STDMETHODIMP UrlmonUrlRequest::OnObjectAvailable(REFIID iid, IUnknown* object) {
  // We are calling BindToStorage on the moniker we should always get called
  // back on OnDataAvailable and should never get OnObjectAvailable
  NOTREACHED();
  return E_NOTIMPL;
}

STDMETHODIMP UrlmonUrlRequest::BeginningTransaction(const wchar_t* url,
    const wchar_t* current_headers, DWORD reserved,
    wchar_t** additional_headers) {
  DCHECK_EQ(thread_, base::PlatformThread::CurrentId());
  if (!additional_headers) {
    NOTREACHED();
    return E_POINTER;
  }

  DVLOG(1) << __FUNCTION__ << me() << "headers: \n" << current_headers;

  if (status_.get_state() == Status::ABORTING) {
    // At times the BINDSTATUS_REDIRECTING notification which is sent to the
    // IBindStatusCallback interface does not have an accompanying HTTP
    // redirect status code, i.e. the attempt to query the HTTP status code
    // from the binding returns 0, 200, etc which are invalid redirect codes.
    // We don't want urlmon to follow redirects. We return E_ABORT in our
    // IBindStatusCallback::OnProgress function and also abort the binding.
    // However urlmon still tries to establish a transaction with the
    // redirected URL which confuses the web server.
    // Fix is to abort the attempted transaction.
    DLOG(WARNING) << __FUNCTION__ << me()
                  << ": Aborting connection to URL:"
                  << url
                  << " as the binding has been aborted";
    return E_ABORT;
  }

  HRESULT hr = S_OK;

  std::string new_headers;
  if (is_chunked_upload()) {
    new_headers = base::StringPrintf("Transfer-Encoding: chunked\r\n");
  }

  if (!extra_headers().empty()) {
    // TODO(robertshield): We may need to sanitize headers on POST here.
    new_headers += extra_headers();
  }

  if (!referrer().empty()) {
    // Referrer is famously misspelled in HTTP:
    new_headers += base::StringPrintf("Referer: %s\r\n", referrer().c_str());
  }

  // In the rare case if "User-Agent" string is already in |current_headers|.
  // We send Chrome's user agent in requests initiated within ChromeFrame to
  // enable third party content in pages rendered in ChromeFrame to correctly
  // send content for Chrome as the third party content may not be equipped to
  // identify chromeframe as the user agent. This also ensures that the user
  // agent reported in scripts in chrome frame is consistent with that sent
  // in outgoing requests.
  std::string user_agent = http_utils::AddChromeFrameToUserAgentValue(
      http_utils::GetChromeUserAgent());
  new_headers += ReplaceOrAddUserAgent(current_headers, user_agent);

  if (!new_headers.empty()) {
    *additional_headers = reinterpret_cast<wchar_t*>(
        CoTaskMemAlloc((new_headers.size() + 1) * sizeof(wchar_t)));

    if (*additional_headers == NULL) {
      NOTREACHED();
      hr = E_OUTOFMEMORY;
    } else {
      lstrcpynW(*additional_headers, ASCIIToWide(new_headers).c_str(),
                new_headers.size());
    }
  }
  request_headers_ = new_headers;
  return hr;
}

STDMETHODIMP UrlmonUrlRequest::OnResponse(DWORD dwResponseCode,
    const wchar_t* response_headers, const wchar_t* request_headers,
    wchar_t** additional_headers) {
  DCHECK_EQ(thread_, base::PlatformThread::CurrentId());
  DVLOG(1) << __FUNCTION__ << me() << "headers: \n"
           << (response_headers == NULL ? L"EMPTY" : response_headers);

  if (!delegate_) {
    DLOG(WARNING) << "Invalid delegate";
    return S_OK;
  }

  delegate_->AddPrivacyDataForUrl(url(), "", 0);

  std::string raw_headers;
  if (response_headers)
    raw_headers = WideToUTF8(response_headers);

  // Security check for frame busting headers. We don't honor the headers
  // as-such, but instead simply kill requests which we've been asked to
  // look for if they specify a value for "X-Frame-Options" other than
  // "ALLOWALL" (the others are "deny" and "sameorigin"). This puts the onus
  // on the user of the UrlRequest to specify whether or not requests should
  // be inspected. For ActiveDocuments, the answer is "no", since WebKit's
  // detection/handling is sufficient and since ActiveDocuments cannot be
  // hosted as iframes. For NPAPI and ActiveX documents, the Initialize()
  // function of the PluginUrlRequest object allows them to specify how they'd
  // like requests handled. Both should set enable_frame_busting_ to true to
  // avoid CSRF attacks. Should WebKit's handling of this ever change, we will
  // need to re-visit how and when frames are killed to better mirror a policy
  // which may do something other than kill the sub-document outright.

  // NOTE(slightlyoff): We don't use net::HttpResponseHeaders here because
  //    of lingering ICU/base_noicu issues.
  if (enable_frame_busting_) {
    if (http_utils::HasFrameBustingHeader(raw_headers)) {
      DLOG(ERROR) << "X-Frame-Options header other than ALLOWALL " <<
          "detected, navigation canceled";
      return E_FAIL;
    }
  }

  DVLOG(1) << __FUNCTION__ << me() << "Calling OnResponseStarted";

  // Inform the delegate.
  headers_received_ = true;
  DCHECK_NE(id(), -1);
  delegate_->OnResponseStarted(id(),
                               "",                   // mime_type
                               raw_headers.c_str(),  // headers
                               0,                    // size
                               base::Time(),         // last_modified
                               status_.get_redirection().utf8_url,
                               status_.get_redirection().http_code,
                               socket_address_,
                               post_data_len());
  return S_OK;
}

STDMETHODIMP UrlmonUrlRequest::GetWindow(const GUID& guid_reason,
                                         HWND* parent_window) {
  if (!parent_window)
    return E_INVALIDARG;

#ifndef NDEBUG
  wchar_t guid[40] = {0};
  ::StringFromGUID2(guid_reason, guid, arraysize(guid));
  const wchar_t* str = guid;
  if (guid_reason == IID_IAuthenticate)
    str = L"IAuthenticate";
  else if (guid_reason == IID_IHttpSecurity)
    str = L"IHttpSecurity";
  else if (guid_reason == IID_IWindowForBindingUI)
    str = L"IWindowForBindingUI";
  DVLOG(1) << __FUNCTION__ << me() << "GetWindow: " << str;
#endif
  // We should return a non-NULL HWND as parent. Otherwise no dialog is shown.
  // TODO(iyengar): This hits when running the URL request tests.
  DLOG_IF(WARNING, !::IsWindow(parent_window_))
      << "UrlmonUrlRequest::GetWindow - no window!";
  *parent_window = parent_window_;
  return S_OK;
}

STDMETHODIMP UrlmonUrlRequest::Authenticate(HWND* parent_window,
                                            LPWSTR* user_name,
                                            LPWSTR* password) {
  if (!parent_window)
    return E_INVALIDARG;

  if (privileged_mode_)
    return E_ACCESSDENIED;

  DCHECK(::IsWindow(parent_window_));
  *parent_window = parent_window_;
  return S_OK;
}

STDMETHODIMP UrlmonUrlRequest::OnSecurityProblem(DWORD problem) {
  // Urlmon notifies the client of authentication problems, certificate
  // errors, etc by querying the object implementing the IBindStatusCallback
  // interface for the IHttpSecurity interface. If this interface is not
  // implemented then Urlmon checks for the problem codes defined below
  // and performs actions as defined below:-
  // It invokes the ReportProgress method of the protocol sink with
  // these problem codes and eventually invokes the ReportResult method
  // on the protocol sink which ends up in a call to the OnStopBinding
  // method of the IBindStatusCallBack interface.

  // MSHTML's implementation of the IBindStatusCallback interface does not
  // implement the IHttpSecurity interface. However it handles the
  // OnStopBinding call with a HRESULT of 0x800c0019 and navigates to
  // an interstitial page which presents the user with a choice of whether
  // to abort the navigation.

  // In our OnStopBinding implementation we stop the navigation and inform
  // Chrome about the result. Ideally Chrome should behave in a manner similar
  // to IE, i.e. display the SSL error interstitial page and if the user
  // decides to proceed anyway we would turn off SSL warnings for that
  // particular navigation and allow IE to download the content.
  // We would need to return the certificate information to Chrome for display
  // purposes. Currently we only return a dummy certificate to Chrome.
  // At this point we decided that it is a lot of work at this point and
  // decided to go with the easier option of implementing the IHttpSecurity
  // interface and replicating the checks performed by Urlmon. This
  // causes Urlmon to display a dialog box on the same lines as IE6.
  DVLOG(1) << __FUNCTION__ << me() << "Security problem : " << problem;

  // On IE6 the default IBindStatusCallback interface does not implement the
  // IHttpSecurity interface and thus causes IE to put up a certificate error
  // dialog box. We need to emulate this behavior for sites with mismatched
  // certificates to work.
  if (GetIEVersion() == IE_6)
    return S_FALSE;

  HRESULT hr = E_ABORT;

  switch (problem) {
    case ERROR_INTERNET_SEC_CERT_REV_FAILED: {
      hr = RPC_E_RETRY;
      break;
    }

    case ERROR_INTERNET_SEC_CERT_DATE_INVALID:
    case ERROR_INTERNET_SEC_CERT_CN_INVALID:
    case ERROR_INTERNET_INVALID_CA: {
      hr = S_FALSE;
      break;
    }

    default: {
      NOTREACHED() << "Unhandled security problem : " << problem;
      break;
    }
  }
  return hr;
}

HRESULT UrlmonUrlRequest::StartAsyncDownload() {
  DVLOG(1) << __FUNCTION__ << me() << url();
  HRESULT hr = E_FAIL;
  DCHECK((moniker_ && bind_context_) || (!moniker_ && !bind_context_));

  if (!moniker_.get()) {
    std::wstring wide_url = UTF8ToWide(url());
    hr = CreateURLMonikerEx(NULL, wide_url.c_str(), moniker_.Receive(),
                            URL_MK_UNIFORM);
    if (FAILED(hr)) {
      NOTREACHED() << "CreateURLMonikerEx failed. Error: " << hr;
      return hr;
    }
  }

  if (bind_context_.get() == NULL)  {
    hr = ::CreateAsyncBindCtxEx(NULL, 0, this, NULL,
                                bind_context_.Receive(), 0);
    DCHECK(SUCCEEDED(hr)) << "CreateAsyncBindCtxEx failed. Error: " << hr;
  } else {
    // Use existing bind context.
    hr = ::RegisterBindStatusCallback(bind_context_, this, NULL, 0);
    DCHECK(SUCCEEDED(hr)) << "RegisterBindStatusCallback failed. Error: " << hr;
  }

  if (SUCCEEDED(hr)) {
    base::win::ScopedComPtr<IStream> stream;

    // BindToStorage may complete synchronously.
    // We still get all the callbacks - OnStart/StopBinding, this may result
    // in destruction of our object. It's fine but we access some members
    // below for debug info. :)
    base::win::ScopedComPtr<IHttpSecurity> self(this);

    // Inform our moniker patch this binding should not be tortured.
    base::win::ScopedComPtr<BindContextInfo> info;
    BindContextInfo::FromBindContext(bind_context_, info.Receive());
    DCHECK(info);
    if (info)
      info->set_chrome_request(true);

    hr = moniker_->BindToStorage(bind_context_, NULL, __uuidof(IStream),
                                 reinterpret_cast<void**>(stream.Receive()));
    if (hr == S_OK)
      DCHECK(binding_ != NULL || status_.get_state() == Status::DONE);

    if (FAILED(hr)) {
      // TODO(joshia): Look into. This currently fails for:
      // http://user2:secret@localhost:1337/auth-basic?set-cookie-if-challenged
      // when running the UrlRequest unit tests.
      DLOG(ERROR) << __FUNCTION__ << me() <<
          base::StringPrintf("IUrlMoniker::BindToStorage failed 0x%08X.", hr);
      // In most cases we'll get a MK_E_SYNTAX error here but if we abort
      // the navigation ourselves such as in the case of seeing something
      // else than ALLOWALL in X-Frame-Options.
    }
  }

  DLOG_IF(ERROR, FAILED(hr)) << me() <<
      base::StringPrintf(L"StartAsyncDownload failed: 0x%08X", hr);

  return hr;
}

void UrlmonUrlRequest::NotifyDelegateAndDie() {
  DCHECK_EQ(thread_, base::PlatformThread::CurrentId());
  DVLOG(1) << __FUNCTION__ << me();

  PluginUrlRequestDelegate* delegate = delegate_;
  delegate_ = NULL;
  ReleaseBindings();
  TerminateTransaction();
  if (delegate && id() != -1) {
    net::URLRequestStatus result = status_.get_result();
    delegate->OnResponseEnd(id(), result);
  } else {
    DLOG(WARNING) << __FUNCTION__ << me() << "no delegate";
  }
}

void UrlmonUrlRequest::TerminateTransaction() {
  if (cleanup_transaction_ && bind_context_ && moniker_) {
    // We return INET_E_TERMINATED_BIND from our OnDataAvailable implementation
    // to ensure that the transaction stays around if Chrome decides to issue
    // a download request when it finishes inspecting the headers received in
    // OnResponse. However this causes the urlmon transaction object to leak.
    // To workaround this we save away the IInternetProtocol interface which is
    // implemented by the urlmon CTransaction object in our BindContextInfo
    // instance which is maintained per bind context. Invoking Terminate
    // on this with the special flags 0x2000000 cleanly releases the
    // transaction.
    static const int kUrlmonTerminateTransactionFlags = 0x2000000;
    base::win::ScopedComPtr<BindContextInfo> info;
    BindContextInfo::FromBindContext(bind_context_, info.Receive());
    DCHECK(info);
    if (info && info->protocol()) {
      info->protocol()->Terminate(kUrlmonTerminateTransactionFlags);
    }
  }
  bind_context_.Release();
}

void UrlmonUrlRequest::ReleaseBindings() {
  binding_.Release();
  // Do not release bind_context here!
  // We may get DownloadToHost request and therefore we want the bind_context
  // to be available.
  if (bind_context_)
    ::RevokeBindStatusCallback(bind_context_, this);
}

net::Error UrlmonUrlRequest::HresultToNetError(HRESULT hr) {
  const int kInvalidHostName = 0x8007007b;
  // Useful reference:
  // http://msdn.microsoft.com/en-us/library/ms775145(VS.85).aspx

  net::Error ret = net::ERR_UNEXPECTED;

  switch (hr) {
    case S_OK:
      ret = net::OK;
      break;

    case MK_E_SYNTAX:
      ret = net::ERR_INVALID_URL;
      break;

    case INET_E_CANNOT_CONNECT:
      ret = net::ERR_CONNECTION_FAILED;
      break;

    case INET_E_DOWNLOAD_FAILURE:
    case INET_E_CONNECTION_TIMEOUT:
    case E_ABORT:
      ret = net::ERR_CONNECTION_ABORTED;
      break;

    case INET_E_DATA_NOT_AVAILABLE:
      ret = net::ERR_EMPTY_RESPONSE;
      break;

    case INET_E_RESOURCE_NOT_FOUND:
      // To behave more closely to the chrome network stack, we translate this
      // error value as tunnel connection failed.  This error value is tested
      // in the ProxyTunnelRedirectTest and UnexpectedServerAuthTest tests.
      ret = net::ERR_TUNNEL_CONNECTION_FAILED;
      break;

    // The following error codes can be returned while processing an invalid
    // url. http://msdn.microsoft.com/en-us/library/bb250493(v=vs.85).aspx
    case INET_E_INVALID_URL:
    case INET_E_UNKNOWN_PROTOCOL:
    case INET_E_REDIRECT_FAILED:
    case INET_E_SECURITY_PROBLEM:
    case kInvalidHostName:
    case E_INVALIDARG:
    case E_OUTOFMEMORY:
      ret = net::ERR_INVALID_URL;
      break;

    case INET_E_INVALID_CERTIFICATE:
      ret = net::ERR_CERT_INVALID;
      break;

    case E_ACCESSDENIED:
      ret = net::ERR_ACCESS_DENIED;
      break;

    default:
      DLOG(WARNING)
          << base::StringPrintf("TODO: translate HRESULT 0x%08X to net::Error",
                                hr);
      break;
  }
  return ret;
}


PluginUrlRequestManager::ThreadSafeFlags
    UrlmonUrlRequestManager::GetThreadSafeFlags() {
  return PluginUrlRequestManager::NOT_THREADSAFE;
}

void UrlmonUrlRequestManager::SetInfoForUrl(const std::wstring& url,
                                            IMoniker* moniker, LPBC bind_ctx) {
  CComObject<UrlmonUrlRequest>* new_request = NULL;
  CComObject<UrlmonUrlRequest>::CreateInstance(&new_request);
  if (new_request) {
    GURL start_url(url);
    DCHECK(start_url.is_valid());
    DCHECK(pending_request_ == NULL);

    base::win::ScopedComPtr<BindContextInfo> info;
    BindContextInfo::FromBindContext(bind_ctx, info.Receive());
    DCHECK(info);
    IStream* cache = info ? info->cache() : NULL;
    pending_request_ = new_request;
    pending_request_->InitPending(start_url, moniker, bind_ctx,
                                  enable_frame_busting_, privileged_mode_,
                                  notification_window_, cache);
    // Start the request
    bool is_started = pending_request_->Start();
    DCHECK(is_started);
  }
}

void UrlmonUrlRequestManager::StartRequest(int request_id,
    const AutomationURLRequest& request_info) {
  DVLOG(1) << __FUNCTION__ << " id: " << request_id;

  if (stopping_) {
    DLOG(WARNING) << __FUNCTION__ << " request not started (stopping)";
    return;
  }

  DCHECK(request_map_.find(request_id) == request_map_.end());
#ifndef NDEBUG
  if (background_worker_thread_enabled_) {
    base::AutoLock lock(background_resource_map_lock_);
    DCHECK(background_request_map_.find(request_id) ==
           background_request_map_.end());
  }
#endif  // NDEBUG
  DCHECK(GURL(request_info.url).is_valid());

  // Non frame requests like sub resources, images, etc are handled on the
  // background thread.
  if (background_worker_thread_enabled_ &&
      !ResourceType::IsFrame(
          static_cast<ResourceType::Type>(request_info.resource_type))) {
    DLOG(INFO) << "Downloading resource type "
               << request_info.resource_type
               << " on background thread";
    background_thread_->message_loop()->PostTask(
        FROM_HERE,
        base::Bind(&UrlmonUrlRequestManager::StartRequestHelper,
                   base::Unretained(this), request_id, request_info,
                   &background_request_map_, &background_resource_map_lock_));
    return;
  }
  StartRequestHelper(request_id, request_info, &request_map_, NULL);
}

void UrlmonUrlRequestManager::StartRequestHelper(
    int request_id,
    const AutomationURLRequest& request_info,
    RequestMap* request_map,
    base::Lock* request_map_lock) {
  DCHECK(request_map);
  scoped_refptr<UrlmonUrlRequest> new_request;
  bool is_started = false;
  if (pending_request_) {
    if (pending_request_->url() != request_info.url) {
      DLOG(INFO) << __FUNCTION__
                 << "Received url request for url:"
                 << request_info.url
                 << ". Stopping pending url request for url:"
                 << pending_request_->url();
      pending_request_->Stop();
      pending_request_ = NULL;
    } else {
      new_request.swap(pending_request_);
      is_started = true;
      DVLOG(1) << __FUNCTION__ << new_request->me()
               << " assigned id " << request_id;
    }
  }

  if (!is_started) {
    CComObject<UrlmonUrlRequest>* created_request = NULL;
    CComObject<UrlmonUrlRequest>::CreateInstance(&created_request);
    new_request = created_request;
  }

  // Format upload data if it's chunked.
  if (request_info.upload_data && request_info.upload_data->is_chunked()) {
    ScopedVector<net::UploadElement>* elements =
        request_info.upload_data->elements_mutable();
    for (size_t i = 0; i < elements->size(); ++i) {
      net::UploadElement* element = (*elements)[i];
      DCHECK(element->type() == net::UploadElement::TYPE_BYTES);
      std::string chunk_length = base::StringPrintf(
          "%X\r\n", static_cast<unsigned int>(element->bytes_length()));
      std::vector<char> bytes;
      bytes.insert(bytes.end(), chunk_length.data(),
                   chunk_length.data() + chunk_length.length());
      const char* data = element->bytes();
      bytes.insert(bytes.end(), data, data + element->bytes_length());
      const char* crlf = "\r\n";
      bytes.insert(bytes.end(), crlf, crlf + strlen(crlf));
      if (i == elements->size() - 1) {
        const char* end_of_data = "0\r\n\r\n";
        bytes.insert(bytes.end(), end_of_data,
                     end_of_data + strlen(end_of_data));
      }
      element->SetToBytes(&bytes[0], static_cast<int>(bytes.size()));
    }
  }

  new_request->Initialize(static_cast<PluginUrlRequestDelegate*>(this),
      request_id,
      request_info.url,
      request_info.method,
      request_info.referrer,
      request_info.extra_request_headers,
      request_info.upload_data,
      static_cast<ResourceType::Type>(request_info.resource_type),
      enable_frame_busting_,
      request_info.load_flags);
  new_request->set_parent_window(notification_window_);
  new_request->set_privileged_mode(privileged_mode_);

  if (request_map_lock)
    request_map_lock->Acquire();

  (*request_map)[request_id] = new_request;

  if (request_map_lock)
    request_map_lock->Release();

  if (!is_started) {
    // Freshly created, start now.
    new_request->Start();
  } else {
    // Request is already underway, call OnResponse so that the
    // other side can start reading.
    DCHECK(!new_request->response_headers().empty());
    new_request->OnResponse(
        0, UTF8ToWide(new_request->response_headers()).c_str(), NULL, NULL);
  }
}

void UrlmonUrlRequestManager::ReadRequest(int request_id, int bytes_to_read) {
  DVLOG(1) << __FUNCTION__ << " id: " << request_id;
  // if we fail to find the request in the normal map and the background
  // request map, it may mean that the request could have failed with a
  // network error.
  scoped_refptr<UrlmonUrlRequest> request = LookupRequest(request_id,
                                                          &request_map_);
  if (request) {
    request->Read(bytes_to_read);
  } else if (background_worker_thread_enabled_) {
    base::AutoLock lock(background_resource_map_lock_);
    request = LookupRequest(request_id, &background_request_map_);
    if (request) {
      background_thread_->message_loop()->PostTask(
          FROM_HERE, base::Bind(base::IgnoreResult(&UrlmonUrlRequest::Read),
                                request.get(), bytes_to_read));
    }
  }
  if (!request)
    DLOG(ERROR) << __FUNCTION__ << " no request found for " << request_id;
}

void UrlmonUrlRequestManager::DownloadRequestInHost(int request_id) {
  DVLOG(1) << __FUNCTION__ << " " << request_id;
  if (!IsWindow(notification_window_)) {
    NOTREACHED() << "Cannot handle download if we don't have anyone to hand it "
                    "to.";
    return;
  }

  scoped_refptr<UrlmonUrlRequest> request(LookupRequest(request_id,
                                                        &request_map_));
  if (request) {
    DownloadRequestInHostHelper(request);
  } else if (background_worker_thread_enabled_) {
    base::AutoLock lock(background_resource_map_lock_);
    request = LookupRequest(request_id, &background_request_map_);
    if (request) {
      background_thread_->message_loop()->PostTask(
          FROM_HERE,
          base::Bind(&UrlmonUrlRequestManager::DownloadRequestInHostHelper,
                     base::Unretained(this), request.get()));
    }
  }
  if (!request)
    DLOG(ERROR) << __FUNCTION__ << " no request found for " << request_id;
}

void UrlmonUrlRequestManager::DownloadRequestInHostHelper(
    UrlmonUrlRequest* request) {
  DCHECK(request);
  UrlmonUrlRequest::TerminateBindCallback callback =
      base::Bind(&UrlmonUrlRequestManager::BindTerminated,
                 base::Unretained(this));
  request->TerminateBind(callback);
}

void UrlmonUrlRequestManager::BindTerminated(IMoniker* moniker,
                                             IBindCtx* bind_ctx,
                                             IStream* post_data,
                                             const char* request_headers) {
  DownloadInHostParams* download_params = new DownloadInHostParams;
  download_params->bind_ctx = bind_ctx;
  download_params->moniker = moniker;
  download_params->post_data = post_data;
  if (request_headers) {
    download_params->request_headers = request_headers;
  }
  ::PostMessage(notification_window_, WM_DOWNLOAD_IN_HOST,
        reinterpret_cast<WPARAM>(download_params), 0);
}

void UrlmonUrlRequestManager::EndRequest(int request_id) {
  DVLOG(1) << __FUNCTION__ << " id: " << request_id;
  scoped_refptr<UrlmonUrlRequest> request = LookupRequest(request_id,
                                                          &request_map_);
  if (request) {
    request_map_.erase(request_id);
    request->Stop();
  } else if (background_worker_thread_enabled_) {
    base::AutoLock lock(background_resource_map_lock_);
    request = LookupRequest(request_id, &background_request_map_);
    if (request) {
      background_request_map_.erase(request_id);
      background_thread_->message_loop()->PostTask(
          FROM_HERE, base::Bind(&UrlmonUrlRequest::Stop, request.get()));
    }
  }
  if (!request)
    DLOG(ERROR) << __FUNCTION__ << " no request found for " << request_id;
}

void UrlmonUrlRequestManager::StopAll() {
  DVLOG(1) << __FUNCTION__;
  if (stopping_)
    return;

  stopping_ = true;

  DVLOG(1) << __FUNCTION__ << " stopping " << request_map_.size()
           << " requests";

  StopAllRequestsHelper(&request_map_, NULL);

  if (background_worker_thread_enabled_) {
    DCHECK(background_thread_.get());
    background_thread_->message_loop()->PostTask(
        FROM_HERE, base::Bind(&UrlmonUrlRequestManager::StopAllRequestsHelper,
                              base::Unretained(this), &background_request_map_,
                              &background_resource_map_lock_));
    background_thread_->Stop();
    background_thread_.reset();
  }
}

void UrlmonUrlRequestManager::StopAllRequestsHelper(
    RequestMap* request_map,
    base::Lock* request_map_lock) {
  DCHECK(request_map);

  DVLOG(1) << __FUNCTION__ << " stopping " << request_map->size()
           << " requests";

  if (request_map_lock)
    request_map_lock->Acquire();

  for (RequestMap::iterator it = request_map->begin();
       it != request_map->end(); ++it) {
    DCHECK(it->second != NULL);
    it->second->Stop();
  }
  request_map->clear();

  if (request_map_lock)
    request_map_lock->Release();
}

void UrlmonUrlRequestManager::OnResponseStarted(
    int request_id, const char* mime_type, const char* headers, int size,
    base::Time last_modified, const std::string& redirect_url,
    int redirect_status, const net::HostPortPair& socket_address,
    uint64 upload_size) {
  DCHECK_NE(request_id, -1);
  DVLOG(1) << __FUNCTION__;

#ifndef NDEBUG
  scoped_refptr<UrlmonUrlRequest> request = LookupRequest(request_id,
                                                          &request_map_);
  if (request == NULL && background_worker_thread_enabled_) {
    base::AutoLock lock(background_resource_map_lock_);
    request = LookupRequest(request_id, &background_request_map_);
  }
  DCHECK(request != NULL);
#endif  // NDEBUG
  delegate_->OnResponseStarted(
      request_id, mime_type, headers, size, last_modified, redirect_url,
      redirect_status, socket_address, upload_size);
}

void UrlmonUrlRequestManager::OnReadComplete(int request_id,
                                             const std::string& data) {
  DCHECK_NE(request_id, -1);
  DVLOG(1) << __FUNCTION__ << " id: " << request_id;
#ifndef NDEBUG
  scoped_refptr<UrlmonUrlRequest> request = LookupRequest(request_id,
                                                          &request_map_);
  if (request == NULL && background_worker_thread_enabled_) {
    base::AutoLock lock(background_resource_map_lock_);
    request = LookupRequest(request_id, &background_request_map_);
  }
  DCHECK(request != NULL);
#endif  // NDEBUG
  delegate_->OnReadComplete(request_id, data);
  DVLOG(1) << __FUNCTION__ << " done id: " << request_id;
}

void UrlmonUrlRequestManager::OnResponseEnd(
    int request_id,
    const net::URLRequestStatus& status) {
  DCHECK_NE(request_id, -1);
  DVLOG(1) << __FUNCTION__;
  DCHECK(status.status() != net::URLRequestStatus::CANCELED);
  RequestMap::size_type erased_count = request_map_.erase(request_id);
  if (erased_count != 1u && background_worker_thread_enabled_) {
    base::AutoLock lock(background_resource_map_lock_);
    erased_count = background_request_map_.erase(request_id);
    if (erased_count != 1u) {
      DLOG(WARNING) << __FUNCTION__
                    << " Failed to find request id:"
                    << request_id;
    }
  }
  delegate_->OnResponseEnd(request_id, status);
}

scoped_refptr<UrlmonUrlRequest> UrlmonUrlRequestManager::LookupRequest(
    int request_id, RequestMap* request_map) {
  RequestMap::iterator it = request_map->find(request_id);
  if (request_map->end() != it)
    return it->second;
  return NULL;
}

UrlmonUrlRequestManager::UrlmonUrlRequestManager()
    : stopping_(false), notification_window_(NULL),
      privileged_mode_(false),
      container_(NULL),
      background_worker_thread_enabled_(true) {
  background_thread_.reset(new base::Thread("cf_iexplore_background_thread"));
  background_thread_->init_com_with_mta(false);
  background_worker_thread_enabled_ =
      GetConfigBool(true, kUseBackgroundThreadForSubResources);
  if (background_worker_thread_enabled_) {
    base::Thread::Options options;
    options.message_loop_type = base::MessageLoop::TYPE_UI;
    background_thread_->StartWithOptions(options);
  }
}

UrlmonUrlRequestManager::~UrlmonUrlRequestManager() {
  StopAll();
}

void UrlmonUrlRequestManager::AddPrivacyDataForUrl(
    const std::string& url, const std::string& policy_ref,
    int32 flags) {
  DCHECK(!url.empty());

  bool fire_privacy_event = false;

  if (privacy_info_.privacy_records.empty())
    flags |= PRIVACY_URLISTOPLEVEL;

  if (!privacy_info_.privacy_impacted) {
    if (flags & (COOKIEACTION_ACCEPT | COOKIEACTION_REJECT |
                 COOKIEACTION_DOWNGRADE)) {
      privacy_info_.privacy_impacted = true;
      fire_privacy_event = true;
    }
  }

  PrivacyInfo::PrivacyEntry& privacy_entry =
      privacy_info_.privacy_records[UTF8ToWide(url)];

  privacy_entry.flags |= flags;
  privacy_entry.policy_ref = UTF8ToWide(policy_ref);

  if (fire_privacy_event && IsWindow(notification_window_)) {
    PostMessage(notification_window_, WM_FIRE_PRIVACY_CHANGE_NOTIFICATION, 1,
                0);
  }
}
