summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/automation/automation_provider.cc98
-rw-r--r--chrome/browser/automation/automation_provider.h1
-rw-r--r--chrome/chrome.gyp2
-rw-r--r--chrome/common/automation_constants.cc15
-rw-r--r--chrome/common/automation_constants.h19
-rw-r--r--chrome/common/common.vcproj8
-rw-r--r--chrome/test/automation/automation_constants.h4
-rw-r--r--chrome/test/automation/automation_messages_internal.h7
-rw-r--r--chrome/test/automation/automation_proxy.cc4
-rw-r--r--chrome/test/automation/automation_proxy.h4
-rw-r--r--net/proxy/proxy_service.cc6
-rw-r--r--net/proxy/proxy_service.h7
-rw-r--r--net/proxy/proxy_service_unittest.cc50
13 files changed, 222 insertions, 3 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index 641e883..0923492 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -11,6 +11,7 @@
#include "base/stl_util-inl.h"
#include "base/string_util.h"
#include "base/thread.h"
+#include "base/values.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/app_modal_dialog.h"
#include "chrome/browser/app_modal_dialog_queue.h"
@@ -27,17 +28,22 @@
#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/find_notification_details.h"
#include "chrome/browser/location_bar.h"
+#include "chrome/browser/profile_manager.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/ssl/ssl_manager.h"
#include "chrome/browser/ssl/ssl_blocking_page.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_contents_view.h"
+#include "chrome/common/automation_constants.h"
#include "chrome/common/chrome_paths.h"
+#include "chrome/common/json_value_serializer.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/platform_util.h"
#include "chrome/common/pref_service.h"
#include "chrome/test/automation/automation_messages.h"
#include "net/base/cookie_monster.h"
+#include "net/proxy/proxy_service.h"
+#include "net/proxy/proxy_config_service_fixed.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_filter.h"
@@ -992,6 +998,7 @@ void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
HandleInspectElementRequest)
IPC_MESSAGE_HANDLER(AutomationMsg_SetFilteredInet, SetFilteredInet)
IPC_MESSAGE_HANDLER(AutomationMsg_DownloadDirectory, GetDownloadDirectory)
+ IPC_MESSAGE_HANDLER(AutomationMsg_SetProxyConfig, SetProxyConfig);
IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindow,
OpenNewBrowserWindow)
IPC_MESSAGE_HANDLER(AutomationMsg_WindowForBrowser, GetWindowForBrowser)
@@ -2160,6 +2167,97 @@ void AutomationProvider::SetFilteredInet(const IPC::Message& message,
new SetFilteredInetTask(enabled));
}
+class SetProxyConfigTask : public Task {
+ public:
+ explicit SetProxyConfigTask(net::ProxyService* proxy_service,
+ const std::string& new_proxy_config)
+ : proxy_service_(proxy_service), proxy_config_(new_proxy_config) {}
+ virtual void Run() {
+ // First, deserialize the JSON string. If this fails, log and bail.
+ JSONStringValueSerializer deserializer(proxy_config_);
+ std::string error_message;
+ scoped_ptr<Value> root(deserializer.Deserialize(&error_message));
+ if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) {
+ DLOG(WARNING) << "Received bad JSON string for ProxyConfig: "
+ << error_message;
+ return;
+ }
+
+ scoped_ptr<DictionaryValue> dict(
+ static_cast<DictionaryValue*>(root.release()));
+ // Now put together a proxy configuration from the deserialized string.
+ net::ProxyConfig pc;
+ PopulateProxyConfig(*dict.get(), &pc);
+
+ DCHECK(proxy_service_);
+ scoped_ptr<net::ProxyConfigService> proxy_config_service(
+ new net::ProxyConfigServiceFixed(pc));
+ proxy_service_->ResetConfigService(proxy_config_service.release());
+ }
+
+ void PopulateProxyConfig(const DictionaryValue& dict, net::ProxyConfig* pc) {
+ DCHECK(pc);
+ bool no_proxy = false;
+ if (dict.GetBoolean(automation::kJSONProxyNoProxy, &no_proxy)) {
+ // Make no changes to the ProxyConfig.
+ return;
+ }
+ bool auto_config;
+ if (dict.GetBoolean(automation::kJSONProxyAutoconfig, &auto_config)) {
+ pc->auto_detect = true;
+ }
+ std::string pac_url;
+ if (dict.GetString(automation::kJSONProxyPacUrl, &pac_url)) {
+ pc->pac_url = GURL(pac_url);
+ }
+ std::string proxy_bypass_list;
+ if (dict.GetString(automation::kJSONProxyBypassList, &proxy_bypass_list)) {
+ pc->ParseNoProxyList(proxy_bypass_list);
+ }
+ std::string proxy_server;
+ if (dict.GetString(automation::kJSONProxyServer, &proxy_server)) {
+ pc->proxy_rules.ParseFromString(proxy_server);
+ }
+ }
+
+ private:
+ net::ProxyService* proxy_service_;
+ std::string proxy_config_;
+};
+
+
+void AutomationProvider::SetProxyConfig(const std::string& new_proxy_config) {
+ URLRequestContext* context = Profile::GetDefaultRequestContext();
+ // If we don't have a default request context yet then we have to create
+ // one.
+ bool run_on_ui_thread = false;
+ if (!context) {
+ FilePath user_data_dir;
+ PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
+ ProfileManager* profile_manager = g_browser_process->profile_manager();
+ DCHECK(profile_manager);
+ Profile* profile = profile_manager->GetDefaultProfile(user_data_dir);
+ DCHECK(profile);
+ context = profile->GetRequestContext();
+ run_on_ui_thread = true;
+ }
+ DCHECK(context);
+ // Every URLRequestContext should have a proxy service.
+ net::ProxyService* proxy_service = context->proxy_service();
+ DCHECK(proxy_service);
+
+ // If we just now created the URLRequestContext then we can immediately
+ // set the proxy settings on this (the UI) thread. If there was already
+ // a URLRequestContext, then run the reset on the IO thread.
+ if (run_on_ui_thread) {
+ SetProxyConfigTask set_proxy_config_task(proxy_service, new_proxy_config);
+ set_proxy_config_task.Run();
+ } else {
+ g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
+ new SetProxyConfigTask(proxy_service, new_proxy_config));
+ }
+}
+
void AutomationProvider::GetDownloadDirectory(
int handle, std::wstring* download_directory) {
DLOG(INFO) << "Handling download directory request";
diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h
index d90e2dc29..9de02a6 100644
--- a/chrome/browser/automation/automation_provider.h
+++ b/chrome/browser/automation/automation_provider.h
@@ -211,6 +211,7 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
IPC::Message* reply_message);
void GetShelfVisibility(int handle, bool* visible);
void SetFilteredInet(const IPC::Message& message, bool enabled);
+ void SetProxyConfig(const std::string& new_proxy_config);
#if defined(OS_WIN)
// TODO(port): Replace POINT.
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index b53df23..edc0e8a 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -255,6 +255,8 @@
'common/app_cache/app_cache_dispatcher.h',
'common/app_cache/app_cache_dispatcher_host.cc',
'common/app_cache/app_cache_dispatcher_host.h',
+ 'common/automation_constants.cc',
+ 'common/automation_constants.h',
'common/bindings_policy.h',
'common/child_process.cc',
'common/child_process.h',
diff --git a/chrome/common/automation_constants.cc b/chrome/common/automation_constants.cc
new file mode 100644
index 0000000..185d57b
--- /dev/null
+++ b/chrome/common/automation_constants.cc
@@ -0,0 +1,15 @@
+// Copyright (c) 2006-2009 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/common/automation_constants.h"
+
+namespace automation {
+// JSON value labels for proxy settings that are passed in via
+// AutomationMsg_SetProxyConfig.
+const wchar_t kJSONProxyAutoconfig[] = L"proxy.autoconfig";
+const wchar_t kJSONProxyNoProxy[] = L"proxy.no_proxy";
+const wchar_t kJSONProxyPacUrl[] = L"proxy.pac_url";
+const wchar_t kJSONProxyBypassList[] = L"proxy.bypass_list";
+const wchar_t kJSONProxyServer[] = L"proxy.server";
+}
diff --git a/chrome/common/automation_constants.h b/chrome/common/automation_constants.h
new file mode 100644
index 0000000..9c31bd1
--- /dev/null
+++ b/chrome/common/automation_constants.h
@@ -0,0 +1,19 @@
+// Copyright (c) 2006-2009 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.
+
+#ifndef CHROME_COMMON_AUTOMATION_CONSTANTS_H__
+#define CHROME_COMMON_AUTOMATION_CONSTANTS_H__
+
+namespace automation {
+// JSON value labels for proxy settings that are passed in via
+// AutomationMsg_SetProxyConfig. These are here since they are used by both
+// AutomationProvider and AutomationProxy.
+extern const wchar_t kJSONProxyAutoconfig[];
+extern const wchar_t kJSONProxyNoProxy[];
+extern const wchar_t kJSONProxyPacUrl[];
+extern const wchar_t kJSONProxyBypassList[];
+extern const wchar_t kJSONProxyServer[];
+}
+
+#endif // CHROME_COMMON_AUTOMATION_CONSTANTS_H__
diff --git a/chrome/common/common.vcproj b/chrome/common/common.vcproj
index 25b8b16..216a551 100644
--- a/chrome/common/common.vcproj
+++ b/chrome/common/common.vcproj
@@ -306,6 +306,14 @@
</File>
</Filter>
<File
+ RelativePath=".\automation_constants.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\automation_constants.h"
+ >
+ </File>
+ <File
RelativePath=".\bindings_policy.h"
>
</File>
diff --git a/chrome/test/automation/automation_constants.h b/chrome/test/automation/automation_constants.h
index 06d13e0..b08836d 100644
--- a/chrome/test/automation/automation_constants.h
+++ b/chrome/test/automation/automation_constants.h
@@ -6,8 +6,8 @@
#define CHROME_TEST_AUTOMATION_AUTOMATION_CONSTANTS_H__
namespace automation {
- // Amount of time to wait before querying the browser.
- static const int kSleepTime = 250;
+// Amount of time to wait before querying the browser.
+static const int kSleepTime = 250;
}
// Used by AutomationProxy, declared here so that other headers don't need
diff --git a/chrome/test/automation/automation_messages_internal.h b/chrome/test/automation/automation_messages_internal.h
index eaf5c4a..3922869 100644
--- a/chrome/test/automation/automation_messages_internal.h
+++ b/chrome/test/automation/automation_messages_internal.h
@@ -754,7 +754,7 @@ IPC_BEGIN_MESSAGES(Automation)
// A message for an external host.
IPC_MESSAGE_ROUTED4(AutomationMsg_ForwardMessageToExternalHost,
- int, // handle
+ int, /* handle */
std::string /* message */,
std::string /* origin */,
std::string /* target */)
@@ -921,5 +921,10 @@ IPC_BEGIN_MESSAGES(Automation)
IPC_SYNC_MESSAGE_ROUTED1_0(AutomationMsg_SetEnableExtensionAutomation,
bool /* true to enable extension automation */)
+ // This message tells the browser to start using the new proxy configuration
+ // represented by the given JSON string. The parameters used in the JSON
+ // string are defined in automation_constants.h.
+ IPC_SYNC_MESSAGE_ROUTED1_0(AutomationMsg_SetProxyConfig,
+ std::string /* proxy_config_json_string */)
IPC_END_MESSAGES(Automation)
diff --git a/chrome/test/automation/automation_proxy.cc b/chrome/test/automation/automation_proxy.cc
index 3f6508b..9fc8193 100644
--- a/chrome/test/automation/automation_proxy.cc
+++ b/chrome/test/automation/automation_proxy.cc
@@ -370,6 +370,10 @@ bool AutomationProxy::SetFilteredInet(bool enabled) {
return Send(new AutomationMsg_SetFilteredInet(0, enabled));
}
+bool AutomationProxy::SendProxyConfig(const std::string& new_proxy_config) {
+ return Send(new AutomationMsg_SetProxyConfig(0, new_proxy_config));
+}
+
void AutomationProxy::Disconnect() {
channel_.reset();
}
diff --git a/chrome/test/automation/automation_proxy.h b/chrome/test/automation/automation_proxy.h
index 0b8ad57..75c76cd 100644
--- a/chrome/test/automation/automation_proxy.h
+++ b/chrome/test/automation/automation_proxy.h
@@ -145,6 +145,10 @@ class AutomationProxy : public IPC::Channel::Listener,
// false if the message fails to send to the browser.
bool SetFilteredInet(bool enabled);
+ // Sends the browser a new proxy configuration to start using. Returns true
+ // if the proxy config was successfully sent, false otherwise.
+ bool SendProxyConfig(const std::string& new_proxy_config);
+
// These methods are intended to be called by the background thread
// to signal that the given event has occurred, and that any corresponding
// Wait... function can return.
diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc
index a827389..65db636 100644
--- a/net/proxy/proxy_service.cc
+++ b/net/proxy/proxy_service.cc
@@ -518,6 +518,12 @@ void ProxyService::SetProxyScriptFetcher(
proxy_script_fetcher_.reset(proxy_script_fetcher);
}
+void ProxyService::ResetConfigService(
+ ProxyConfigService* new_proxy_config_service) {
+ config_service_.reset(new_proxy_config_service);
+ UpdateConfig();
+}
+
void ProxyService::DidCompletePacRequest(int config_id, int result_code) {
// If we get an error that indicates a bad PAC config, then we should
// remember that, and not try the PAC config again for a while.
diff --git a/net/proxy/proxy_service.h b/net/proxy/proxy_service.h
index dc0c455..e12892e 100644
--- a/net/proxy/proxy_service.h
+++ b/net/proxy/proxy_service.h
@@ -86,6 +86,13 @@ class ProxyService {
// |proxy_script_fetcher|.
void SetProxyScriptFetcher(ProxyScriptFetcher* proxy_script_fetcher);
+ // Tells this ProxyService to start using a new ProxyConfigService to
+ // retrieve its ProxyConfig from. The new ProxyConfigService will immediately
+ // be queried for new config info which will be used for all subsequent
+ // ResolveProxy calls. ProxyService takes ownership of
+ // |new_proxy_config_service|.
+ void ResetConfigService(ProxyConfigService* new_proxy_config_service);
+
// Creates a proxy service using the specified settings. If |pc| is NULL then
// the system's default proxy settings will be used (on Windows this will
// use IE's settings).
diff --git a/net/proxy/proxy_service_unittest.cc b/net/proxy/proxy_service_unittest.cc
index a2b33d4..a33dfce 100644
--- a/net/proxy/proxy_service_unittest.cc
+++ b/net/proxy/proxy_service_unittest.cc
@@ -138,6 +138,14 @@ class ResultFuture : public base::RefCountedThreadSafe<ResultFuture> {
started_.Wait();
}
+ void StartResetConfigService(
+ net::ProxyConfigService* new_proxy_config_service) {
+ DCHECK(MessageLoop::current() != io_message_loop_);
+ io_message_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &ResultFuture::DoResetConfigService, new_proxy_config_service));
+ started_.Wait();
+ }
+
// Called on |io_message_loop_|.
void DoStartRequest(const GURL& url, RequestMethod method) {
DCHECK(MessageLoop::current() == io_message_loop_);
@@ -150,6 +158,14 @@ class ResultFuture : public base::RefCountedThreadSafe<ResultFuture> {
}
// Called on |io_message_loop_|.
+ void DoResetConfigService(net::ProxyConfigService* new_proxy_config_service) {
+ DCHECK(MessageLoop::current() == io_message_loop_);
+ service_->ResetConfigService(new_proxy_config_service);
+ started_.Signal();
+ OnCompletion(0);
+ }
+
+ // Called on |io_message_loop_|.
void DoCancel() {
DCHECK(MessageLoop::current() == io_message_loop_);
if (!did_complete_)
@@ -230,6 +246,13 @@ class ProxyServiceWithFutures {
(*result)->StartReconsider(url, proxy_info);
}
+ void ResetConfigService(scoped_refptr<ResultFuture>* result,
+ net::ProxyConfigService* new_proxy_config_service) {
+ *result = new ResultFuture(io_thread_.message_loop(),
+ io_thread_state_->service);
+ (*result)->StartResetConfigService(new_proxy_config_service);
+ }
+
void SetProxyScriptFetcher(net::ProxyScriptFetcher* proxy_script_fetcher) {
io_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
io_thread_state_.get(), &IOThreadState::DoSetProxyScriptFetcher,
@@ -292,6 +315,12 @@ class SyncProxyService {
return result->GetResultCode();
}
+ int ResetConfigService(net::ProxyConfigService* new_proxy_config_service) {
+ scoped_refptr<ResultFuture> result;
+ service_.ResetConfigService(&result, new_proxy_config_service);
+ return result->GetResultCode();
+ }
+
private:
ProxyServiceWithFutures service_;
};
@@ -1096,3 +1125,24 @@ TEST(ProxyServiceTest, CancelWhilePACFetching) {
EXPECT_EQ("pac-v1.request3:80",
result3->GetProxyInfo().proxy_server().ToURI());
}
+
+TEST(ProxyServiceTest, ResetProxyConfigService) {
+ net::ProxyConfig config1;
+ config1.proxy_rules.ParseFromString("foopy1:8080");
+ config1.auto_detect = false;
+ scoped_ptr<SyncProxyService> service(
+ new SyncProxyService(new MockProxyConfigService(config1),
+ new MockProxyResolverWithoutFetch));
+
+ net::ProxyInfo info;
+ service->ResolveProxy(GURL("http://request1"), &info);
+ EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
+
+ net::ProxyConfig config2;
+ config2.proxy_rules.ParseFromString("foopy2:8080");
+ config2.auto_detect = false;
+ int result = service->ResetConfigService(new MockProxyConfigService(config2));
+ DCHECK(result == 0);
+ service->ResolveProxy(GURL("http://request2"), &info);
+ EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI());
+}