diff options
-rw-r--r-- | chrome/browser/automation/automation_provider.cc | 98 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider.h | 1 | ||||
-rw-r--r-- | chrome/chrome.gyp | 2 | ||||
-rw-r--r-- | chrome/common/automation_constants.cc | 15 | ||||
-rw-r--r-- | chrome/common/automation_constants.h | 19 | ||||
-rw-r--r-- | chrome/common/common.vcproj | 8 | ||||
-rw-r--r-- | chrome/test/automation/automation_constants.h | 4 | ||||
-rw-r--r-- | chrome/test/automation/automation_messages_internal.h | 7 | ||||
-rw-r--r-- | chrome/test/automation/automation_proxy.cc | 4 | ||||
-rw-r--r-- | chrome/test/automation/automation_proxy.h | 4 | ||||
-rw-r--r-- | net/proxy/proxy_service.cc | 6 | ||||
-rw-r--r-- | net/proxy/proxy_service.h | 7 | ||||
-rw-r--r-- | net/proxy/proxy_service_unittest.cc | 50 |
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()); +} |