summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbashi@chromium.org <bashi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-13 00:53:58 +0000
committerbashi@chromium.org <bashi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-13 00:53:58 +0000
commitaa28181ebb378bdb9d7161d9414b3003b7bf118a (patch)
treecb3f94dbad59bd32c78945e181e61c6fb0fc1f27
parent1075a530e0efc3a86ed6213c9b5a65a3d6cd74da (diff)
downloadchromium_src-aa28181ebb378bdb9d7161d9414b3003b7bf118a.zip
chromium_src-aa28181ebb378bdb9d7161d9414b3003b7bf118a.tar.gz
chromium_src-aa28181ebb378bdb9d7161d9414b3003b7bf118a.tar.bz2
Adds NetworkDelegate::NotifyBeforeSocketStreamConnect()
This function will be called before an WebSocket tries to connect. This function can do extra work such as policy checks to prevent the connect. ChromeNetworkDelegate implements the function to check URL blacklist. BUG=131046 TEST=net_unittests Review URL: https://chromiumcodereview.appspot.com/10541046 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@141816 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/net/chrome_network_delegate.cc18
-rw-r--r--chrome/browser/net/chrome_network_delegate.h3
-rw-r--r--chrome/browser/policy/url_blacklist_manager.cc6
-rw-r--r--chrome/browser/policy/url_blacklist_manager.h6
-rw-r--r--chrome/browser/policy/url_blacklist_manager_unittest.cc21
-rw-r--r--content/shell/shell_network_delegate.cc6
-rw-r--r--content/shell/shell_network_delegate.h3
-rw-r--r--net/base/network_delegate.cc9
-rw-r--r--net/base/network_delegate.h8
-rw-r--r--net/proxy/network_delegate_error_observer_unittest.cc5
-rw-r--r--net/proxy/proxy_script_fetcher_impl_unittest.cc6
-rw-r--r--net/socket_stream/socket_stream.cc33
-rw-r--r--net/socket_stream/socket_stream.h5
-rw-r--r--net/socket_stream/socket_stream_unittest.cc48
-rw-r--r--net/url_request/url_request_context_builder.cc6
-rw-r--r--net/url_request/url_request_test_util.cc6
-rw-r--r--net/url_request/url_request_test_util.h3
-rw-r--r--webkit/tools/test_shell/simple_resource_loader_bridge.cc5
18 files changed, 191 insertions, 6 deletions
diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc
index 6ea4eb8..e22fb88 100644
--- a/chrome/browser/net/chrome_network_delegate.cc
+++ b/chrome/browser/net/chrome_network_delegate.cc
@@ -28,6 +28,7 @@
#include "net/cookies/cookie_monster.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
+#include "net/socket_stream/socket_stream.h"
#include "net/url_request/url_request.h"
#if defined(OS_CHROMEOS)
@@ -370,3 +371,20 @@ bool ChromeNetworkDelegate::OnCanThrottleRequest(
return request.first_party_for_cookies().scheme() !=
chrome::kExtensionScheme;
}
+
+int ChromeNetworkDelegate::OnBeforeSocketStreamConnect(
+ net::SocketStream* socket,
+ const net::CompletionCallback& callback) {
+#if defined(ENABLE_CONFIGURATION_POLICY)
+ if (url_blacklist_manager_ &&
+ url_blacklist_manager_->IsURLBlocked(socket->url())) {
+ // URL access blocked by policy.
+ scoped_refptr<net::NetLog::EventParameters> params;
+ params = new net::NetLogStringParameter("url", socket->url().spec());
+ socket->net_log()->AddEvent(
+ net::NetLog::TYPE_CHROME_POLICY_ABORTED_REQUEST, params);
+ return net::ERR_NETWORK_ACCESS_DENIED;
+ }
+#endif
+ return net::OK;
+}
diff --git a/chrome/browser/net/chrome_network_delegate.h b/chrome/browser/net/chrome_network_delegate.h
index 2ff6843..bd106f8 100644
--- a/chrome/browser/net/chrome_network_delegate.h
+++ b/chrome/browser/net/chrome_network_delegate.h
@@ -93,6 +93,9 @@ class ChromeNetworkDelegate : public net::NetworkDelegate {
const FilePath& path) const OVERRIDE;
virtual bool OnCanThrottleRequest(
const net::URLRequest& request) const OVERRIDE;
+ virtual int OnBeforeSocketStreamConnect(
+ net::SocketStream* stream,
+ const net::CompletionCallback& callback) OVERRIDE;
scoped_refptr<ExtensionEventRouterForwarder> event_router_;
void* profile_;
diff --git a/chrome/browser/policy/url_blacklist_manager.cc b/chrome/browser/policy/url_blacklist_manager.cc
index 63ccdde..e553d75 100644
--- a/chrome/browser/policy/url_blacklist_manager.cc
+++ b/chrome/browser/policy/url_blacklist_manager.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// 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.
@@ -206,6 +206,10 @@ bool URLBlacklist::SchemeToFlag(const std::string& scheme, SchemeFlag* flag) {
*flag = SCHEME_HTTPS;
} else if (scheme == "ftp") {
*flag = SCHEME_FTP;
+ } else if (scheme == "ws") {
+ *flag = SCHEME_WS;
+ } else if (scheme == "wss") {
+ *flag = SCHEME_WSS;
} else {
return false;
}
diff --git a/chrome/browser/policy/url_blacklist_manager.h b/chrome/browser/policy/url_blacklist_manager.h
index 8233b37..c0b7ab6 100644
--- a/chrome/browser/policy/url_blacklist_manager.h
+++ b/chrome/browser/policy/url_blacklist_manager.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// 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.
@@ -32,8 +32,10 @@ class URLBlacklist {
SCHEME_HTTP = 1 << 0,
SCHEME_HTTPS = 1 << 1,
SCHEME_FTP = 1 << 2,
+ SCHEME_WS = 1 << 3,
+ SCHEME_WSS = 1 << 4,
- SCHEME_ALL = (1 << 3) - 1,
+ SCHEME_ALL = (1 << 5) - 1,
};
URLBlacklist();
diff --git a/chrome/browser/policy/url_blacklist_manager_unittest.cc b/chrome/browser/policy/url_blacklist_manager_unittest.cc
index da1760a..4dd3ca6 100644
--- a/chrome/browser/policy/url_blacklist_manager_unittest.cc
+++ b/chrome/browser/policy/url_blacklist_manager_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// 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.
@@ -250,6 +250,10 @@ TEST_F(URLBlacklistManagerTest, SchemeToFlag) {
EXPECT_EQ(URLBlacklist::SCHEME_HTTPS, flag);
EXPECT_TRUE(URLBlacklist::SchemeToFlag("ftp", &flag));
EXPECT_EQ(URLBlacklist::SCHEME_FTP, flag);
+ EXPECT_TRUE(URLBlacklist::SchemeToFlag("ws", &flag));
+ EXPECT_EQ(URLBlacklist::SCHEME_WS, flag);
+ EXPECT_TRUE(URLBlacklist::SchemeToFlag("wss", &flag));
+ EXPECT_EQ(URLBlacklist::SCHEME_WSS, flag);
EXPECT_TRUE(URLBlacklist::SchemeToFlag("", &flag));
EXPECT_EQ(URLBlacklist::SCHEME_ALL, flag);
EXPECT_FALSE(URLBlacklist::SchemeToFlag("wtf", &flag));
@@ -300,15 +304,19 @@ TEST_F(URLBlacklistManagerTest, Filtering) {
EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://x.y.google.com/a/b")));
EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube.com/")));
- // Filter only http and ftp schemes.
+ // Filter only http, ftp and ws schemes.
blacklist.Block("http://secure.com");
blacklist.Block("ftp://secure.com");
+ blacklist.Block("ws://secure.com");
EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://secure.com")));
EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://secure.com/whatever")));
EXPECT_TRUE(blacklist.IsURLBlocked(GURL("ftp://secure.com/")));
+ EXPECT_TRUE(blacklist.IsURLBlocked(GURL("ws://secure.com")));
EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://secure.com/")));
+ EXPECT_FALSE(blacklist.IsURLBlocked(GURL("wss://secure.com")));
EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://www.secure.com")));
EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://www.secure.com")));
+ EXPECT_FALSE(blacklist.IsURLBlocked(GURL("wss://www.secure.com")));
// Filter only a certain path prefix.
blacklist.Block("path.to/ruin");
@@ -329,6 +337,15 @@ TEST_F(URLBlacklistManagerTest, Filtering) {
EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://s.aaa.com/bbb")));
EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://s.aaa.com/")));
+ // Filter only ws and wss schemes.
+ blacklist.Block("ws://ws.aaa.com");
+ blacklist.Block("wss://ws.aaa.com");
+ EXPECT_TRUE(blacklist.IsURLBlocked(GURL("ws://ws.aaa.com")));
+ EXPECT_TRUE(blacklist.IsURLBlocked(GURL("wss://ws.aaa.com")));
+ EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://ws.aaa.com")));
+ EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://ws.aaa.com")));
+ EXPECT_FALSE(blacklist.IsURLBlocked(GURL("ftp://ws.aaa.com")));
+
// Test exceptions to path prefixes, and most specific matches.
blacklist.Block("s.xxx.com/a");
blacklist.Allow("s.xxx.com/a/b");
diff --git a/content/shell/shell_network_delegate.cc b/content/shell/shell_network_delegate.cc
index 66f6600..1bf35fb 100644
--- a/content/shell/shell_network_delegate.cc
+++ b/content/shell/shell_network_delegate.cc
@@ -91,4 +91,10 @@ bool ShellNetworkDelegate::OnCanThrottleRequest(
return false;
}
+int ShellNetworkDelegate::OnBeforeSocketStreamConnect(
+ net::SocketStream* socket,
+ const net::CompletionCallback& callback) {
+ return net::OK;
+}
+
} // namespace content
diff --git a/content/shell/shell_network_delegate.h b/content/shell/shell_network_delegate.h
index d08d5cf..6740e216 100644
--- a/content/shell/shell_network_delegate.h
+++ b/content/shell/shell_network_delegate.h
@@ -56,6 +56,9 @@ class ShellNetworkDelegate : public net::NetworkDelegate {
const FilePath& path) const OVERRIDE;
virtual bool OnCanThrottleRequest(
const net::URLRequest& request) const OVERRIDE;
+ virtual int OnBeforeSocketStreamConnect(
+ net::SocketStream* stream,
+ const net::CompletionCallback& callback) OVERRIDE;
DISALLOW_COPY_AND_ASSIGN(ShellNetworkDelegate);
};
diff --git a/net/base/network_delegate.cc b/net/base/network_delegate.cc
index c3fd9e6..96e9a23 100644
--- a/net/base/network_delegate.cc
+++ b/net/base/network_delegate.cc
@@ -118,4 +118,13 @@ bool NetworkDelegate::CanThrottleRequest(const URLRequest& request) const {
return OnCanThrottleRequest(request);
}
+int NetworkDelegate::NotifyBeforeSocketStreamConnect(
+ SocketStream* socket,
+ const CompletionCallback& callback) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(socket);
+ DCHECK(!callback.is_null());
+ return OnBeforeSocketStreamConnect(socket, callback);
+}
+
} // namespace net
diff --git a/net/base/network_delegate.h b/net/base/network_delegate.h
index 4d56e3f..ed6a7fa 100644
--- a/net/base/network_delegate.h
+++ b/net/base/network_delegate.h
@@ -33,6 +33,7 @@ class CookieList;
class CookieOptions;
class HttpRequestHeaders;
class HttpResponseHeaders;
+class SocketStream;
class URLRequest;
class NetworkDelegate : public base::NonThreadSafe {
@@ -87,6 +88,9 @@ class NetworkDelegate : public base::NonThreadSafe {
const FilePath& path) const;
bool CanThrottleRequest(const URLRequest& request) const;
+ int NotifyBeforeSocketStreamConnect(SocketStream* socket,
+ const CompletionCallback& callback);
+
private:
// This is the interface for subclasses of NetworkDelegate to implement. These
// member functions will be called by the respective public notification
@@ -207,6 +211,10 @@ class NetworkDelegate : public base::NonThreadSafe {
// URLRequestThrottlerManager believes the server servicing the
// request is overloaded or down.
virtual bool OnCanThrottleRequest(const URLRequest& request) const = 0;
+
+ // Called before a SocketStream tries to connect.
+ virtual int OnBeforeSocketStreamConnect(
+ SocketStream* socket, const CompletionCallback& callback) = 0;
};
} // namespace net
diff --git a/net/proxy/network_delegate_error_observer_unittest.cc b/net/proxy/network_delegate_error_observer_unittest.cc
index 882fba9..b8084e0 100644
--- a/net/proxy/network_delegate_error_observer_unittest.cc
+++ b/net/proxy/network_delegate_error_observer_unittest.cc
@@ -79,6 +79,11 @@ class TestNetworkDelegate : public net::NetworkDelegate {
virtual bool OnCanThrottleRequest(const URLRequest& request) const OVERRIDE {
return false;
}
+ virtual int OnBeforeSocketStreamConnect(
+ SocketStream* stream,
+ const CompletionCallback& callback) OVERRIDE {
+ return OK;
+ }
bool got_pac_error_;
};
diff --git a/net/proxy/proxy_script_fetcher_impl_unittest.cc b/net/proxy/proxy_script_fetcher_impl_unittest.cc
index 8a3673d..74e37ae 100644
--- a/net/proxy/proxy_script_fetcher_impl_unittest.cc
+++ b/net/proxy/proxy_script_fetcher_impl_unittest.cc
@@ -187,6 +187,12 @@ class BasicNetworkDelegate : public NetworkDelegate {
return false;
}
+ virtual int OnBeforeSocketStreamConnect(
+ SocketStream* stream,
+ const CompletionCallback& callback) OVERRIDE {
+ return OK;
+ }
+
DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate);
};
diff --git a/net/socket_stream/socket_stream.cc b/net/socket_stream/socket_stream.cc
index e704e9f..f4d8c56 100644
--- a/net/socket_stream/socket_stream.cc
+++ b/net/socket_stream/socket_stream.cc
@@ -147,7 +147,7 @@ void SocketStream::Connect() {
AddRef(); // Released in Finish()
// Open a connection asynchronously, so that delegate won't be called
// back before returning Connect().
- next_state_ = STATE_RESOLVE_PROXY;
+ next_state_ = STATE_BEFORE_CONNECT;
net_log_.BeginEvent(
NetLog::TYPE_SOCKET_STREAM_CONNECT,
make_scoped_refptr(
@@ -410,6 +410,13 @@ void SocketStream::DoLoop(int result) {
State state = next_state_;
next_state_ = STATE_NONE;
switch (state) {
+ case STATE_BEFORE_CONNECT:
+ DCHECK_EQ(OK, result);
+ result = DoBeforeConnect();
+ break;
+ case STATE_BEFORE_CONNECT_COMPLETE:
+ result = DoBeforeConnectComplete(result);
+ break;
case STATE_RESOLVE_PROXY:
DCHECK_EQ(OK, result);
result = DoResolveProxy();
@@ -511,6 +518,30 @@ void SocketStream::DoLoop(int result) {
} while (result != ERR_IO_PENDING);
}
+int SocketStream::DoBeforeConnect() {
+ next_state_ = STATE_BEFORE_CONNECT_COMPLETE;
+ if (!context_ || !context_->network_delegate())
+ return OK;
+
+ int result = context_->network_delegate()->NotifyBeforeSocketStreamConnect(
+ this, io_callback_);
+ if (result != OK && result != ERR_IO_PENDING)
+ next_state_ = STATE_CLOSE;
+
+ return result;
+}
+
+int SocketStream::DoBeforeConnectComplete(int result) {
+ DCHECK_NE(ERR_IO_PENDING, result);
+
+ if (result == OK)
+ next_state_ = STATE_RESOLVE_PROXY;
+ else
+ next_state_ = STATE_CLOSE;
+
+ return result;
+}
+
int SocketStream::DoResolveProxy() {
DCHECK(!pac_request_);
next_state_ = STATE_RESOLVE_PROXY_COMPLETE;
diff --git a/net/socket_stream/socket_stream.h b/net/socket_stream/socket_stream.h
index 18c4d36..9d22fde 100644
--- a/net/socket_stream/socket_stream.h
+++ b/net/socket_stream/socket_stream.h
@@ -25,6 +25,7 @@
#include "net/http/http_auth_handler.h"
#include "net/proxy/proxy_service.h"
#include "net/socket/tcp_client_socket.h"
+#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
namespace net {
@@ -231,6 +232,8 @@ class NET_EXPORT SocketStream
enum State {
STATE_NONE,
+ STATE_BEFORE_CONNECT,
+ STATE_BEFORE_CONNECT_COMPLETE,
STATE_RESOLVE_PROXY,
STATE_RESOLVE_PROXY_COMPLETE,
STATE_RESOLVE_HOST,
@@ -287,6 +290,8 @@ class NET_EXPORT SocketStream
void DoLoop(int result);
+ int DoBeforeConnect();
+ int DoBeforeConnectComplete(int result);
int DoResolveProxy();
int DoResolveProxyComplete(int result);
int DoResolveHost();
diff --git a/net/socket_stream/socket_stream_unittest.cc b/net/socket_stream/socket_stream_unittest.cc
index 76bb379..cc93035 100644
--- a/net/socket_stream/socket_stream_unittest.cc
+++ b/net/socket_stream/socket_stream_unittest.cc
@@ -188,6 +188,26 @@ class TestURLRequestContextWithProxy : public TestURLRequestContext {
virtual ~TestURLRequestContextWithProxy() {}
};
+class TestSocketStreamNetworkDelegate : public TestNetworkDelegate {
+ public:
+ TestSocketStreamNetworkDelegate()
+ : before_connect_result_(net::OK) {}
+ virtual ~TestSocketStreamNetworkDelegate() {}
+
+ virtual int OnBeforeSocketStreamConnect(
+ net::SocketStream* stream,
+ const net::CompletionCallback& callback) OVERRIDE {
+ return before_connect_result_;
+ }
+
+ void SetBeforeConnectResult(int result) {
+ before_connect_result_ = result;
+ }
+
+ private:
+ int before_connect_result_;
+};
+
} // namespace
namespace net {
@@ -646,4 +666,32 @@ TEST_F(SocketStreamTest, SecureProxyConnect) {
EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[3].event_type);
}
+TEST_F(SocketStreamTest, BeforeConnectFailed) {
+ TestCompletionCallback test_callback;
+
+ scoped_ptr<SocketStreamEventRecorder> delegate(
+ new SocketStreamEventRecorder(test_callback.callback()));
+
+ TestURLRequestContext context;
+ TestSocketStreamNetworkDelegate network_delegate;
+ network_delegate.SetBeforeConnectResult(ERR_ACCESS_DENIED);
+ context.set_network_delegate(&network_delegate);
+
+ scoped_refptr<SocketStream> socket_stream(
+ new SocketStream(GURL("ws://example.com/demo"), delegate.get()));
+
+ socket_stream->set_context(&context);
+
+ socket_stream->Connect();
+
+ test_callback.WaitForResult();
+
+ const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
+ ASSERT_EQ(2U, events.size());
+
+ EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[0].event_type);
+ EXPECT_EQ(net::ERR_ACCESS_DENIED, events[0].error_code);
+ EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[1].event_type);
+}
+
} // namespace net
diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc
index 23820d8..07b0d00 100644
--- a/net/url_request/url_request_context_builder.cc
+++ b/net/url_request/url_request_context_builder.cc
@@ -105,6 +105,12 @@ class BasicNetworkDelegate : public NetworkDelegate {
return false;
}
+ virtual int OnBeforeSocketStreamConnect(
+ SocketStream* stream,
+ const CompletionCallback& callback) OVERRIDE {
+ return OK;
+ }
+
DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate);
};
diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc
index 6374bda..de814ef 100644
--- a/net/url_request/url_request_test_util.cc
+++ b/net/url_request/url_request_test_util.cc
@@ -498,6 +498,12 @@ bool TestNetworkDelegate::OnCanThrottleRequest(
return true;
}
+int TestNetworkDelegate::OnBeforeSocketStreamConnect(
+ net::SocketStream* socket,
+ const net::CompletionCallback& callback) {
+ return net::OK;
+}
+
// static
std::string ScopedCustomUrlRequestTestHttpHost::value_("127.0.0.1");
diff --git a/net/url_request/url_request_test_util.h b/net/url_request/url_request_test_util.h
index 90a074b..2035fdf 100644
--- a/net/url_request/url_request_test_util.h
+++ b/net/url_request/url_request_test_util.h
@@ -246,6 +246,9 @@ class TestNetworkDelegate : public net::NetworkDelegate {
const FilePath& path) const OVERRIDE;
virtual bool OnCanThrottleRequest(
const net::URLRequest& request) const OVERRIDE;
+ virtual int OnBeforeSocketStreamConnect(
+ net::SocketStream* stream,
+ const net::CompletionCallback& callback) OVERRIDE;
void InitRequestStatesIfNew(int request_id);
diff --git a/webkit/tools/test_shell/simple_resource_loader_bridge.cc b/webkit/tools/test_shell/simple_resource_loader_bridge.cc
index 3847ff2..4821a22 100644
--- a/webkit/tools/test_shell/simple_resource_loader_bridge.cc
+++ b/webkit/tools/test_shell/simple_resource_loader_bridge.cc
@@ -182,6 +182,11 @@ class TestShellNetworkDelegate : public net::NetworkDelegate {
return false;
}
+ virtual int OnBeforeSocketStreamConnect(
+ net::SocketStream* stream,
+ const net::CompletionCallback& callback) OVERRIDE {
+ return net::OK;
+ }
};
TestShellRequestContextParams* g_request_context_params = NULL;