<commit_before>// Copyright (c) 2011 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/browser/chromeos/dbus/proxy_resolution_service_provider.h"

#include "base/bind.h"
#include "base/threading/platform_thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/exported_object.h"
#include "net/base/net_errors.h"
#include "net/proxy/proxy_service.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

namespace chromeos {

// The ProxyResolverInterface implementation used in production.
class ProxyResolverImpl : public ProxyResolverInterface {
 public:
  // Data being used in one proxy resolution.
  class Request {
   public:
    explicit Request(const std::string& source_url)
        : ALLOW_THIS_IN_INITIALIZER_LIST(
            completion_callback_(this, &Request::OnCompletion)),
          source_url_(source_url),
          result_(net::ERR_FAILED) {
    }

    virtual ~Request() {}

    // Callback on IO thread for when net::ProxyService::ResolveProxy
    // completes, synchronously or asynchronously.
    void OnCompletion(int result) {
      DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
      result_ = result;
      // Generate the error message if the error message is not yet set,
      // and there was an error.
      if (error_.empty() && result_ != net::OK)
        error_ = net::ErrorToString(result_);
      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, notify_task_);
    }

    net::OldCompletionCallbackImpl<Request> completion_callback_;

    std::string source_url_;  // URL being resolved.
    int result_;  // Result of proxy resolution.
    net::ProxyInfo proxy_info_;  // ProxyInfo resolved for source_url_.
    std::string error_;  // Error from proxy resolution.
    base::Closure notify_task_;  // Task to notify of resolution result.

   private:
    DISALLOW_COPY_AND_ASSIGN(Request);
  };

  ProxyResolverImpl()
      : origin_thread_id_(base::PlatformThread::CurrentId()) {
  }

  virtual ~ProxyResolverImpl() {
    base::AutoLock lock(data_lock_);
    while (!all_requests_.empty()) {
      LOG(WARNING) << "Pending request for "
                   << all_requests_.back()->source_url_;
      delete all_requests_.back();
      all_requests_.pop_back();
    }
  }

  // ProxyResolverInterface override.
  virtual void ResolveProxy(
      const std::string& source_url,
      const std::string& signal_interface,
      const std::string& signal_name,
      scoped_refptr<dbus::ExportedObject> exported_object) {
    DCHECK(OnOriginThread());

    // GetDefaultProfile() must be called on UI thread.
    Profile* profile = ProfileManager::GetDefaultProfile();
    BrowserThread::PostTask(
        BrowserThread::IO, FROM_HERE,
        base::Bind(&ProxyResolverImpl::ResolveProxyInternal,
                   this,
                   profile,
                   source_url,
                   signal_interface,
                   signal_name,
                   exported_object));
  }

 private:
  // Helper function for ResolveProxy().
  void ResolveProxyInternal(
      Profile* profile,
      const std::string& source_url,
      const std::string& signal_interface,
      const std::string& signal_name,
      scoped_refptr<dbus::ExportedObject> exported_object) {
    // Make sure we're running on IO thread.
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));

    // Create a request slot for this proxy resolution request.
    Request* request = new Request(source_url);
    request->notify_task_ = base::Bind(
        &ProxyResolverImpl::NotifyProxyResolved,
        this,
        signal_interface,
        signal_name,
        exported_object,
        request);
    // Queue request slot.
    {
      base::AutoLock lock(data_lock_);
      all_requests_.push_back(request);
    }

    // Check if we have the URLRequestContextGetter.
    scoped_refptr<net::URLRequestContextGetter> getter =
        profile->GetRequestContext();
    if (!getter) {
      request->error_ = "No URLRequestContextGetter";
      request->OnCompletion(net::ERR_UNEXPECTED);
      return;
    }

    // Retrieve ProxyService from profile's request context.
    net::ProxyService* proxy_service =
        getter->GetURLRequestContext()->proxy_service();
    if (!proxy_service) {
      request->error_ = "No proxy service in chrome";
      request->OnCompletion(net::ERR_UNEXPECTED);
      return;
    }

    VLOG(1) << "Starting network proxy resolution for "
            << request->source_url_;
    request->result_ = proxy_service->ResolveProxy(<commit_msg>Fix yet another crash in ProxyResolutionService with debug build.<commit_after>// Copyright (c) 2011 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/browser/chromeos/dbus/proxy_resolution_service_provider.h"

#include "base/bind.h"
#include "base/threading/platform_thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/exported_object.h"
#include "net/base/net_errors.h"
#include "net/proxy/proxy_service.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

namespace chromeos {

// The ProxyResolverInterface implementation used in production.
class ProxyResolverImpl : public ProxyResolverInterface {
 public:
  // Data being used in one proxy resolution.
  class Request {
   public:
    explicit Request(const std::string& source_url)
        : ALLOW_THIS_IN_INITIALIZER_LIST(
            completion_callback_(this, &Request::OnCompletion)),
          source_url_(source_url),
          result_(net::ERR_FAILED) {
    }

    virtual ~Request() {}

    // Callback on IO thread for when net::ProxyService::ResolveProxy
    // completes, synchronously or asynchronously.
    void OnCompletion(int result) {
      DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
      result_ = result;
      // Generate the error message if the error message is not yet set,
      // and there was an error.
      if (error_.empty() && result_ != net::OK)
        error_ = net::ErrorToString(result_);
      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, notify_task_);
    }

    net::OldCompletionCallbackImpl<Request> completion_callback_;

    std::string source_url_;  // URL being resolved.
    int result_;  // Result of proxy resolution.
    net::ProxyInfo proxy_info_;  // ProxyInfo resolved for source_url_.
    std::string error_;  // Error from proxy resolution.
    base::Closure notify_task_;  // Task to notify of resolution result.

   private:
    DISALLOW_COPY_AND_ASSIGN(Request);
  };

  ProxyResolverImpl()
      : origin_thread_id_(base::PlatformThread::CurrentId()) {
  }

  virtual ~ProxyResolverImpl() {
    base::AutoLock lock(data_lock_);
    while (!all_requests_.empty()) {
      LOG(WARNING) << "Pending request for "
                   << all_requests_.back()->source_url_;
      delete all_requests_.back();
      all_requests_.pop_back();
    }
  }

  // ProxyResolverInterface override.
  virtual void ResolveProxy(
      const std::string& source_url,
      const std::string& signal_interface,
      const std::string& signal_name,
      scoped_refptr<dbus::ExportedObject> exported_object) {
    DCHECK(OnOriginThread());

    // GetDefaultProfile() and GetRequestContext() must be called on UI
    // thread.
    Profile* profile = ProfileManager::GetDefaultProfile();
    scoped_refptr<net::URLRequestContextGetter> getter =
        profile->GetRequestContext();

    BrowserThread::PostTask(
        BrowserThread::IO, FROM_HERE,
        base::Bind(&ProxyResolverImpl::ResolveProxyInternal,
                   this,
                   getter,
                   source_url,
                   signal_interface,
                   signal_name,
                   exported_object));
  }

 private:
  // Helper function for ResolveProxy().
  void ResolveProxyInternal(
      scoped_refptr<net::URLRequestContextGetter> getter,
      const std::string& source_url,
      const std::string& signal_interface,
      const std::string& signal_name,
      scoped_refptr<dbus::ExportedObject> exported_object) {
    // Make sure we're running on IO thread.
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));

    // Create a request slot for this proxy resolution request.
    Request* request = new Request(source_url);
    request->notify_task_ = base::Bind(
        &ProxyResolverImpl::NotifyProxyResolved,
        this,
        signal_interface,
        signal_name,
        exported_object,
        request);
    // Queue request slot.
    {
      base::AutoLock lock(data_lock_);
      all_requests_.push_back(request);
    }

    // Check if we have the URLRequestContextGetter.
    if (!getter) {
      request->error_ = "No URLRequestContextGetter";
      request->OnCompletion(net::ERR_UNEXPECTED);
      return;
    }

    // Retrieve ProxyService from profile's request context.
    net::ProxyService* proxy_service =
        getter->GetURLRequestContext()->proxy_service();
    if (!proxy_service) {
      request->error_ = "No proxy service in chrome";
      request->OnCompletion(net::ERR_UNEXPECTED);
      return;
    }

    VLOG(1) << "Starting network proxy resolution for "
            << request->source_url_;
    request->result_ = proxy_service->ResolveProxy(
{'fraction_non_alphanumeric': 0.10416030922591801, 'fraction_numerical': 0.0010171905197843556, 'mean_word_length': 3.2306368330464714, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 36, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6345797', 'n_tokens_mistral': 2837, 'n_tokens_neox': 2779, 'n_words': 647}