summaryrefslogtreecommitdiffstats
path: root/net/socket_stream
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 /net/socket_stream
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
Diffstat (limited to 'net/socket_stream')
-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
3 files changed, 85 insertions, 1 deletions
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