diff options
author | dilmah@chromium.org <dilmah@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-14 17:48:07 +0000 |
---|---|---|
committer | dilmah@chromium.org <dilmah@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-14 17:48:07 +0000 |
commit | 5ddffb822144de64aa36bd1aa4fc0aad634a3454 (patch) | |
tree | 1319b6250421e165159e82288df605ae7d245b5c /chrome/browser/extensions | |
parent | 3b99e2ef219b43cdc51a3313268e6c9a27aa1be9 (diff) | |
download | chromium_src-5ddffb822144de64aa36bd1aa4fc0aad634a3454.zip chromium_src-5ddffb822144de64aa36bd1aa4fc0aad634a3454.tar.gz chromium_src-5ddffb822144de64aa36bd1aa4fc0aad634a3454.tar.bz2 |
Support SSL connections in websocket-to-TCP proxy.
For historical reasons current implementation of WS-to-TCP proxy was implemented as standalone libevent-based server.
Then it was integrated into chromium as is.
In order to support SSL we need to connect libevent-based proxy with MessageLoopForIO-based chromium network stack.
We do it using pipes.
It is intended as temporary solution until we will have
new shiny implementation of WS-to-TCP proxy integrated into network stack.
BUG=chromium-os:15533
TEST=Manual
Review URL: http://codereview.chromium.org/8087001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@105515 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
4 files changed, 140 insertions, 30 deletions
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc index 7247753..cc47aff 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.cc +++ b/chrome/browser/extensions/extension_function_dispatcher.cc @@ -415,6 +415,7 @@ void FactoryRegistry::ResetFunctions() { // Websocket to TCP proxy. Currently noop on anything other than ChromeOS. RegisterFunction<WebSocketProxyPrivateGetPassportForTCPFunction>(); + RegisterFunction<WebSocketProxyPrivateGetURLForTCPFunction>(); // Debugger RegisterFunction<AttachDebuggerFunction>(); diff --git a/chrome/browser/extensions/extension_web_socket_proxy_private_api.cc b/chrome/browser/extensions/extension_web_socket_proxy_private_api.cc index 9b38568..b952511 100644 --- a/chrome/browser/extensions/extension_web_socket_proxy_private_api.cc +++ b/chrome/browser/extensions/extension_web_socket_proxy_private_api.cc @@ -10,18 +10,60 @@ #include "chrome/browser/internal_auth.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/extensions/extension.h" +#include "content/common/notification_details.h" #include "content/common/notification_service.h" +#include "net/base/escape.h" #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/web_socket_proxy_controller.h" #endif -WebSocketProxyPrivateGetPassportForTCPFunction:: - WebSocketProxyPrivateGetPassportForTCPFunction() : is_finalized_(false) { +WebSocketProxyPrivate::WebSocketProxyPrivate() + : is_finalized_(false), listening_port_(-1) { +} + +WebSocketProxyPrivate::~WebSocketProxyPrivate() { +} + +void WebSocketProxyPrivate::Observe( + int type, const NotificationSource& source, + const NotificationDetails& details) { +#if defined(OS_CHROMEOS) + DCHECK_EQ(chrome::NOTIFICATION_WEB_SOCKET_PROXY_STARTED, type); +#else + NOTREACHED(); +#endif + timer_.Stop(); // Cancel timeout timer. + Finalize(); +} + +void WebSocketProxyPrivate::Finalize() { + if (is_finalized_) + return; + is_finalized_ = true; + SendResponse(true); + Release(); } WebSocketProxyPrivateGetPassportForTCPFunction:: - ~WebSocketProxyPrivateGetPassportForTCPFunction() { + WebSocketProxyPrivateGetPassportForTCPFunction() { + // This obsolete API uses fixed port to listen websocket connections. + listening_port_ = 10101; +} + +void WebSocketProxyPrivateGetURLForTCPFunction::Observe( + int type, const NotificationSource& source, + const NotificationDetails& details) { + listening_port_ = *Details<int>(details).ptr(); + WebSocketProxyPrivate::Observe(type, source, details); +} + +void WebSocketProxyPrivateGetURLForTCPFunction::Finalize() { + StringValue* url = Value::CreateStringValue(std::string( + "ws://127.0.0.1:" + base::IntToString(listening_port_) + + "/tcpproxy?" + query_)); + result_.reset(url); + WebSocketProxyPrivate::Finalize(); } bool WebSocketProxyPrivateGetPassportForTCPFunction::RunImpl() { @@ -67,25 +109,58 @@ bool WebSocketProxyPrivateGetPassportForTCPFunction::RunImpl() { return true; } -void WebSocketProxyPrivateGetPassportForTCPFunction::Observe( - int type, const NotificationSource& source, - const NotificationDetails& details) { +bool WebSocketProxyPrivateGetURLForTCPFunction::RunImpl() { + AddRef(); + bool delay_response = false; + result_.reset(Value::CreateStringValue("")); + #if defined(OS_CHROMEOS) - DCHECK(type == chrome::NOTIFICATION_WEB_SOCKET_PROXY_STARTED); -#else - NOTREACHED(); -#endif - timer_.Stop(); // Cancel timeout timer. - Finalize(); -} + std::string hostname; + EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &hostname)); + int port = -1; + EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(1, &port)); + bool do_tls = false; + DictionaryValue* qualification = NULL; + if (args_->GetDictionary(2, &qualification)) { + const char kTlsOption[] = "tls"; + if (qualification->HasKey(kTlsOption)) { + EXTENSION_FUNCTION_VALIDATE(qualification->GetBoolean( + kTlsOption, &do_tls)); + } + } + if (chromeos::WebSocketProxyController::CheckCredentials( + extension_id(), hostname, port, + do_tls ? chromeos::WebSocketProxyController::TLS_OVER_TCP : + chromeos::WebSocketProxyController::PLAIN_TCP)) { + if (!chromeos::WebSocketProxyController::IsInitiated()) { + delay_response = true; + registrar_.Add( + this, chrome::NOTIFICATION_WEB_SOCKET_PROXY_STARTED, + NotificationService::AllSources()); + chromeos::WebSocketProxyController::Initiate(); + } -void WebSocketProxyPrivateGetPassportForTCPFunction::Finalize() { - if (is_finalized_) { - NOTREACHED(); - return; + std::map<std::string, std::string> map; + map["hostname"] = hostname; + map["port"] = base::IntToString(port); + map["extension_id"] = extension_id(); + map["tls"] = do_tls ? "true" : "false"; + std::string passport = browser::InternalAuthGeneration::GeneratePassport( + "web_socket_proxy", map); + query_ = std::string("hostname=") + + net::EscapeQueryParamValue(hostname, false) + "&port=" + map["port"] + + "&tls=" + map["tls"] + "&passport=" + + net::EscapeQueryParamValue(passport, false); } - is_finalized_ = true; - SendResponse(true); - Release(); +#endif // defined(OS_CHROMEOS) + + if (delay_response) { + const int kTimeout = 3; + timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(kTimeout), + this, &WebSocketProxyPrivate::Finalize); + } else { + Finalize(); + } + return true; } diff --git a/chrome/browser/extensions/extension_web_socket_proxy_private_api.h b/chrome/browser/extensions/extension_web_socket_proxy_private_api.h index ece09a4..7a75137 100644 --- a/chrome/browser/extensions/extension_web_socket_proxy_private_api.h +++ b/chrome/browser/extensions/extension_web_socket_proxy_private_api.h @@ -11,34 +11,64 @@ #include "content/common/notification_registrar.h" #include "chrome/browser/extensions/extension_function.h" -class WebSocketProxyPrivateGetPassportForTCPFunction +class WebSocketProxyPrivate : public AsyncExtensionFunction, public NotificationObserver { public: - WebSocketProxyPrivateGetPassportForTCPFunction(); + WebSocketProxyPrivate(); - virtual ~WebSocketProxyPrivateGetPassportForTCPFunction(); + virtual ~WebSocketProxyPrivate(); - private: - // ExtensionFunction implementation. - virtual bool RunImpl() OVERRIDE; + // Finalizes async operation. + virtual void Finalize(); + protected: // NotificationObserver implementation. virtual void Observe( int type, const NotificationSource& source, const NotificationDetails& details) OVERRIDE; - // Finalizes async operation. - void Finalize(); - // Whether already finalized. bool is_finalized_; // Used to signal timeout (when waiting for proxy initial launch). - base::OneShotTimer<WebSocketProxyPrivateGetPassportForTCPFunction> timer_; + base::OneShotTimer<WebSocketProxyPrivate> timer_; NotificationRegistrar registrar_; + // Proxy listens incoming websocket connection on this port. + int listening_port_; +}; + +class WebSocketProxyPrivateGetPassportForTCPFunction + : public WebSocketProxyPrivate { + public: + WebSocketProxyPrivateGetPassportForTCPFunction(); + + private: + // ExtensionFunction implementation. + virtual bool RunImpl() OVERRIDE; + DECLARE_EXTENSION_FUNCTION_NAME("webSocketProxyPrivate.getPassportForTCP") }; +class WebSocketProxyPrivateGetURLForTCPFunction + : public WebSocketProxyPrivate { + private: + // ExtensionFunction implementation. + virtual bool RunImpl() OVERRIDE; + + // NotificationObserver implementation. + virtual void Observe( + int type, const NotificationSource& source, + const NotificationDetails& details) OVERRIDE; + + // Finalizes async operation. + virtual void Finalize() OVERRIDE; + + // Query component of resulting URL. + std::string query_; + + DECLARE_EXTENSION_FUNCTION_NAME("webSocketProxyPrivate.getURLForTCP") +}; + #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_WEB_SOCKET_PROXY_PRIVATE_API_H_ diff --git a/chrome/browser/extensions/extension_web_socket_proxy_private_apitest.cc b/chrome/browser/extensions/extension_web_socket_proxy_private_apitest.cc index ef2afd6..8d6d12d 100644 --- a/chrome/browser/extensions/extension_web_socket_proxy_private_apitest.cc +++ b/chrome/browser/extensions/extension_web_socket_proxy_private_apitest.cc @@ -14,6 +14,10 @@ class ExtensionWebSocketProxyPrivateApiTest : public ExtensionApiTest { }; IN_PROC_BROWSER_TEST_F(ExtensionWebSocketProxyPrivateApiTest, Pass) { + // Currently WebSocket-to-TCP proxy is operational only on ChromeOS platform. +#if defined(OS_CHROMEOS) + ASSERT_TRUE(StartTestServer()); ASSERT_TRUE(RunExtensionTest("web_socket_proxy_private")) << message_; +#endif } |