| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/websockets/websocket_channel.h" | 5 #include "net/websockets/websocket_channel.h" |
| 6 | 6 |
| 7 #include <limits.h> | 7 #include <limits.h> |
| 8 #include <string.h> | 8 #include <string.h> |
| 9 | 9 |
| 10 #include <iostream> | 10 #include <iostream> |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 } | 90 } |
| 91 | 91 |
| 92 namespace { | 92 namespace { |
| 93 | 93 |
| 94 using ::base::TimeDelta; | 94 using ::base::TimeDelta; |
| 95 | 95 |
| 96 using ::testing::AnyNumber; | 96 using ::testing::AnyNumber; |
| 97 using ::testing::DefaultValue; | 97 using ::testing::DefaultValue; |
| 98 using ::testing::InSequence; | 98 using ::testing::InSequence; |
| 99 using ::testing::MockFunction; | 99 using ::testing::MockFunction; |
| 100 using ::testing::NotNull; |
| 100 using ::testing::Return; | 101 using ::testing::Return; |
| 101 using ::testing::SaveArg; | 102 using ::testing::SaveArg; |
| 102 using ::testing::StrictMock; | 103 using ::testing::StrictMock; |
| 103 using ::testing::_; | 104 using ::testing::_; |
| 104 | 105 |
| 105 // A selection of characters that have traditionally been mangled in some | 106 // A selection of characters that have traditionally been mangled in some |
| 106 // environment or other, for testing 8-bit cleanliness. | 107 // environment or other, for testing 8-bit cleanliness. |
| 107 const char kBinaryBlob[] = {'\n', '\r', // BACKWARDS CRNL | 108 const char kBinaryBlob[] = {'\n', '\r', // BACKWARDS CRNL |
| 108 '\0', // nul | 109 '\0', // nul |
| 109 '\x7F', // DEL | 110 '\x7F', // DEL |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 ChannelState OnStartOpeningHandshake( | 165 ChannelState OnStartOpeningHandshake( |
| 165 scoped_ptr<WebSocketHandshakeRequestInfo>) OVERRIDE { | 166 scoped_ptr<WebSocketHandshakeRequestInfo>) OVERRIDE { |
| 166 OnStartOpeningHandshakeCalled(); | 167 OnStartOpeningHandshakeCalled(); |
| 167 return CHANNEL_ALIVE; | 168 return CHANNEL_ALIVE; |
| 168 } | 169 } |
| 169 ChannelState OnFinishOpeningHandshake( | 170 ChannelState OnFinishOpeningHandshake( |
| 170 scoped_ptr<WebSocketHandshakeResponseInfo>) OVERRIDE { | 171 scoped_ptr<WebSocketHandshakeResponseInfo>) OVERRIDE { |
| 171 OnFinishOpeningHandshakeCalled(); | 172 OnFinishOpeningHandshakeCalled(); |
| 172 return CHANNEL_ALIVE; | 173 return CHANNEL_ALIVE; |
| 173 } | 174 } |
| 175 virtual ChannelState OnSSLCertificateError( |
| 176 scoped_ptr<SSLErrorCallbacks> ssl_error_callbacks, |
| 177 const GURL& url, |
| 178 const SSLInfo& ssl_info, |
| 179 bool fatal) OVERRIDE { |
| 180 OnSSLCertificateErrorCalled( |
| 181 ssl_error_callbacks.get(), url, ssl_info, fatal); |
| 182 return CHANNEL_ALIVE; |
| 183 } |
| 174 | 184 |
| 175 MOCK_METHOD0(OnStartOpeningHandshakeCalled, void()); // NOLINT | 185 MOCK_METHOD0(OnStartOpeningHandshakeCalled, void()); // NOLINT |
| 176 MOCK_METHOD0(OnFinishOpeningHandshakeCalled, void()); // NOLINT | 186 MOCK_METHOD0(OnFinishOpeningHandshakeCalled, void()); // NOLINT |
| 187 MOCK_METHOD4( |
| 188 OnSSLCertificateErrorCalled, |
| 189 void(SSLErrorCallbacks*, const GURL&, const SSLInfo&, bool)); // NOLINT |
| 177 }; | 190 }; |
| 178 | 191 |
| 179 // This fake EventInterface is for tests which need a WebSocketEventInterface | 192 // This fake EventInterface is for tests which need a WebSocketEventInterface |
| 180 // implementation but are not verifying how it is used. | 193 // implementation but are not verifying how it is used. |
| 181 class FakeWebSocketEventInterface : public WebSocketEventInterface { | 194 class FakeWebSocketEventInterface : public WebSocketEventInterface { |
| 182 virtual ChannelState OnAddChannelResponse( | 195 virtual ChannelState OnAddChannelResponse( |
| 183 bool fail, | 196 bool fail, |
| 184 const std::string& selected_protocol, | 197 const std::string& selected_protocol, |
| 185 const std::string& extensions) OVERRIDE { | 198 const std::string& extensions) OVERRIDE { |
| 186 return fail ? CHANNEL_DELETED : CHANNEL_ALIVE; | 199 return fail ? CHANNEL_DELETED : CHANNEL_ALIVE; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 203 return CHANNEL_DELETED; | 216 return CHANNEL_DELETED; |
| 204 } | 217 } |
| 205 virtual ChannelState OnStartOpeningHandshake( | 218 virtual ChannelState OnStartOpeningHandshake( |
| 206 scoped_ptr<WebSocketHandshakeRequestInfo> request) OVERRIDE { | 219 scoped_ptr<WebSocketHandshakeRequestInfo> request) OVERRIDE { |
| 207 return CHANNEL_ALIVE; | 220 return CHANNEL_ALIVE; |
| 208 } | 221 } |
| 209 virtual ChannelState OnFinishOpeningHandshake( | 222 virtual ChannelState OnFinishOpeningHandshake( |
| 210 scoped_ptr<WebSocketHandshakeResponseInfo> response) OVERRIDE { | 223 scoped_ptr<WebSocketHandshakeResponseInfo> response) OVERRIDE { |
| 211 return CHANNEL_ALIVE; | 224 return CHANNEL_ALIVE; |
| 212 } | 225 } |
| 226 virtual ChannelState OnSSLCertificateError( |
| 227 scoped_ptr<SSLErrorCallbacks> ssl_error_callbacks, |
| 228 const GURL& url, |
| 229 const SSLInfo& ssl_info, |
| 230 bool fatal) OVERRIDE { |
| 231 return CHANNEL_ALIVE; |
| 232 } |
| 213 }; | 233 }; |
| 214 | 234 |
| 215 // This fake WebSocketStream is for tests that require a WebSocketStream but are | 235 // This fake WebSocketStream is for tests that require a WebSocketStream but are |
| 216 // not testing the way it is used. It has minimal functionality to return | 236 // not testing the way it is used. It has minimal functionality to return |
| 217 // the |protocol| and |extensions| that it was constructed with. | 237 // the |protocol| and |extensions| that it was constructed with. |
| 218 class FakeWebSocketStream : public WebSocketStream { | 238 class FakeWebSocketStream : public WebSocketStream { |
| 219 public: | 239 public: |
| 220 // Constructs with empty protocol and extensions. | 240 // Constructs with empty protocol and extensions. |
| 221 FakeWebSocketStream() {} | 241 FakeWebSocketStream() {} |
| 222 | 242 |
| (...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 706 scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate; | 726 scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate; |
| 707 }; | 727 }; |
| 708 | 728 |
| 709 // Converts a std::string to a std::vector<char>. For test purposes, it is | 729 // Converts a std::string to a std::vector<char>. For test purposes, it is |
| 710 // convenient to be able to specify data as a string, but the | 730 // convenient to be able to specify data as a string, but the |
| 711 // WebSocketEventInterface requires the vector<char> type. | 731 // WebSocketEventInterface requires the vector<char> type. |
| 712 std::vector<char> AsVector(const std::string& s) { | 732 std::vector<char> AsVector(const std::string& s) { |
| 713 return std::vector<char>(s.begin(), s.end()); | 733 return std::vector<char>(s.begin(), s.end()); |
| 714 } | 734 } |
| 715 | 735 |
| 736 class FakeSSLErrorCallbacks |
| 737 : public WebSocketEventInterface::SSLErrorCallbacks { |
| 738 public: |
| 739 virtual void CancelSSLRequest(int error, const SSLInfo* ssl_info) OVERRIDE {} |
| 740 virtual void ContinueSSLRequest() OVERRIDE {} |
| 741 }; |
| 742 |
| 716 // Base class for all test fixtures. | 743 // Base class for all test fixtures. |
| 717 class WebSocketChannelTest : public ::testing::Test { | 744 class WebSocketChannelTest : public ::testing::Test { |
| 718 protected: | 745 protected: |
| 719 WebSocketChannelTest() : stream_(new FakeWebSocketStream) {} | 746 WebSocketChannelTest() : stream_(new FakeWebSocketStream) {} |
| 720 | 747 |
| 721 // Creates a new WebSocketChannel and connects it, using the settings stored | 748 // Creates a new WebSocketChannel and connects it, using the settings stored |
| 722 // in |connect_data_|. | 749 // in |connect_data_|. |
| 723 void CreateChannelAndConnect() { | 750 void CreateChannelAndConnect() { |
| 724 channel_.reset(new WebSocketChannel(CreateEventInterface(), | 751 channel_.reset(new WebSocketChannel(CreateEventInterface(), |
| 725 &connect_data_.url_request_context)); | 752 &connect_data_.url_request_context)); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 790 // in order to instruct WebSocketChannelDeletingTest when it should fail. | 817 // in order to instruct WebSocketChannelDeletingTest when it should fail. |
| 791 enum EventInterfaceCall { | 818 enum EventInterfaceCall { |
| 792 EVENT_ON_ADD_CHANNEL_RESPONSE = 0x1, | 819 EVENT_ON_ADD_CHANNEL_RESPONSE = 0x1, |
| 793 EVENT_ON_DATA_FRAME = 0x2, | 820 EVENT_ON_DATA_FRAME = 0x2, |
| 794 EVENT_ON_FLOW_CONTROL = 0x4, | 821 EVENT_ON_FLOW_CONTROL = 0x4, |
| 795 EVENT_ON_CLOSING_HANDSHAKE = 0x8, | 822 EVENT_ON_CLOSING_HANDSHAKE = 0x8, |
| 796 EVENT_ON_FAIL_CHANNEL = 0x10, | 823 EVENT_ON_FAIL_CHANNEL = 0x10, |
| 797 EVENT_ON_DROP_CHANNEL = 0x20, | 824 EVENT_ON_DROP_CHANNEL = 0x20, |
| 798 EVENT_ON_START_OPENING_HANDSHAKE = 0x40, | 825 EVENT_ON_START_OPENING_HANDSHAKE = 0x40, |
| 799 EVENT_ON_FINISH_OPENING_HANDSHAKE = 0x80, | 826 EVENT_ON_FINISH_OPENING_HANDSHAKE = 0x80, |
| 827 EVENT_ON_SSL_CERTIFICATE_ERROR = 0x100, |
| 800 }; | 828 }; |
| 801 | 829 |
| 802 class WebSocketChannelDeletingTest : public WebSocketChannelTest { | 830 class WebSocketChannelDeletingTest : public WebSocketChannelTest { |
| 803 public: | 831 public: |
| 804 ChannelState DeleteIfDeleting(EventInterfaceCall call) { | 832 ChannelState DeleteIfDeleting(EventInterfaceCall call) { |
| 805 if (deleting_ & call) { | 833 if (deleting_ & call) { |
| 806 channel_.reset(); | 834 channel_.reset(); |
| 807 return CHANNEL_DELETED; | 835 return CHANNEL_DELETED; |
| 808 } else { | 836 } else { |
| 809 return CHANNEL_ALIVE; | 837 return CHANNEL_ALIVE; |
| 810 } | 838 } |
| 811 } | 839 } |
| 812 | 840 |
| 813 protected: | 841 protected: |
| 814 WebSocketChannelDeletingTest() | 842 WebSocketChannelDeletingTest() |
| 815 : deleting_(EVENT_ON_ADD_CHANNEL_RESPONSE | EVENT_ON_DATA_FRAME | | 843 : deleting_(EVENT_ON_ADD_CHANNEL_RESPONSE | EVENT_ON_DATA_FRAME | |
| 816 EVENT_ON_FLOW_CONTROL | | 844 EVENT_ON_FLOW_CONTROL | |
| 817 EVENT_ON_CLOSING_HANDSHAKE | | 845 EVENT_ON_CLOSING_HANDSHAKE | |
| 818 EVENT_ON_FAIL_CHANNEL | | 846 EVENT_ON_FAIL_CHANNEL | |
| 819 EVENT_ON_DROP_CHANNEL | | 847 EVENT_ON_DROP_CHANNEL | |
| 820 EVENT_ON_START_OPENING_HANDSHAKE | | 848 EVENT_ON_START_OPENING_HANDSHAKE | |
| 821 EVENT_ON_FINISH_OPENING_HANDSHAKE) {} | 849 EVENT_ON_FINISH_OPENING_HANDSHAKE | |
| 850 EVENT_ON_SSL_CERTIFICATE_ERROR) {} |
| 822 // Create a ChannelDeletingFakeWebSocketEventInterface. Defined out-of-line to | 851 // Create a ChannelDeletingFakeWebSocketEventInterface. Defined out-of-line to |
| 823 // avoid circular dependency. | 852 // avoid circular dependency. |
| 824 virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() OVERRIDE; | 853 virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() OVERRIDE; |
| 825 | 854 |
| 826 // Tests can set deleting_ to a bitmap of EventInterfaceCall members that they | 855 // Tests can set deleting_ to a bitmap of EventInterfaceCall members that they |
| 827 // want to cause Channel deletion. The default is for all calls to cause | 856 // want to cause Channel deletion. The default is for all calls to cause |
| 828 // deletion. | 857 // deletion. |
| 829 int deleting_; | 858 int deleting_; |
| 830 }; | 859 }; |
| 831 | 860 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 870 } | 899 } |
| 871 | 900 |
| 872 virtual ChannelState OnStartOpeningHandshake( | 901 virtual ChannelState OnStartOpeningHandshake( |
| 873 scoped_ptr<WebSocketHandshakeRequestInfo> request) OVERRIDE { | 902 scoped_ptr<WebSocketHandshakeRequestInfo> request) OVERRIDE { |
| 874 return fixture_->DeleteIfDeleting(EVENT_ON_START_OPENING_HANDSHAKE); | 903 return fixture_->DeleteIfDeleting(EVENT_ON_START_OPENING_HANDSHAKE); |
| 875 } | 904 } |
| 876 virtual ChannelState OnFinishOpeningHandshake( | 905 virtual ChannelState OnFinishOpeningHandshake( |
| 877 scoped_ptr<WebSocketHandshakeResponseInfo> response) OVERRIDE { | 906 scoped_ptr<WebSocketHandshakeResponseInfo> response) OVERRIDE { |
| 878 return fixture_->DeleteIfDeleting(EVENT_ON_FINISH_OPENING_HANDSHAKE); | 907 return fixture_->DeleteIfDeleting(EVENT_ON_FINISH_OPENING_HANDSHAKE); |
| 879 } | 908 } |
| 909 virtual ChannelState OnSSLCertificateError( |
| 910 scoped_ptr<SSLErrorCallbacks> ssl_error_callbacks, |
| 911 const GURL& url, |
| 912 const SSLInfo& ssl_info, |
| 913 bool fatal) OVERRIDE { |
| 914 return fixture_->DeleteIfDeleting(EVENT_ON_SSL_CERTIFICATE_ERROR); |
| 915 } |
| 880 | 916 |
| 881 private: | 917 private: |
| 882 // A pointer to the test fixture. Owned by the test harness; this object will | 918 // A pointer to the test fixture. Owned by the test harness; this object will |
| 883 // be deleted before it is. | 919 // be deleted before it is. |
| 884 WebSocketChannelDeletingTest* fixture_; | 920 WebSocketChannelDeletingTest* fixture_; |
| 885 }; | 921 }; |
| 886 | 922 |
| 887 scoped_ptr<WebSocketEventInterface> | 923 scoped_ptr<WebSocketEventInterface> |
| 888 WebSocketChannelDeletingTest::CreateEventInterface() { | 924 WebSocketChannelDeletingTest::CreateEventInterface() { |
| 889 return scoped_ptr<WebSocketEventInterface>( | 925 return scoped_ptr<WebSocketEventInterface>( |
| (...skipping 2312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3202 | 3238 |
| 3203 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); | 3239 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); |
| 3204 EXPECT_CALL(*event_interface_, OnFlowControl(kDefaultInitialQuota)); | 3240 EXPECT_CALL(*event_interface_, OnFlowControl(kDefaultInitialQuota)); |
| 3205 EXPECT_CALL( | 3241 EXPECT_CALL( |
| 3206 *event_interface_, | 3242 *event_interface_, |
| 3207 OnDataFrame(true, WebSocketFrameHeader::kOpCodeText, AsVector(""))); | 3243 OnDataFrame(true, WebSocketFrameHeader::kOpCodeText, AsVector(""))); |
| 3208 | 3244 |
| 3209 CreateChannelAndConnectSuccessfully(); | 3245 CreateChannelAndConnectSuccessfully(); |
| 3210 } | 3246 } |
| 3211 | 3247 |
| 3248 // Calls to OnSSLCertificateError() must be passed through to the event |
| 3249 // interface with the correct URL attached. |
| 3250 TEST_F(WebSocketChannelEventInterfaceTest, OnSSLCertificateErrorCalled) { |
| 3251 const GURL wss_url("wss://example.com/sslerror"); |
| 3252 connect_data_.socket_url = wss_url; |
| 3253 const SSLInfo ssl_info; |
| 3254 const bool fatal = true; |
| 3255 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks> fake_callbacks( |
| 3256 new FakeSSLErrorCallbacks); |
| 3257 |
| 3258 EXPECT_CALL(*event_interface_, |
| 3259 OnSSLCertificateErrorCalled(NotNull(), wss_url, _, fatal)); |
| 3260 |
| 3261 CreateChannelAndConnect(); |
| 3262 connect_data_.creator.connect_delegate->OnSSLCertificateError( |
| 3263 fake_callbacks.Pass(), ssl_info, fatal); |
| 3264 } |
| 3265 |
| 3212 // If we receive another frame after Close, it is not valid. It is not | 3266 // If we receive another frame after Close, it is not valid. It is not |
| 3213 // completely clear what behaviour is required from the standard in this case, | 3267 // completely clear what behaviour is required from the standard in this case, |
| 3214 // but the current implementation fails the connection. Since a Close has | 3268 // but the current implementation fails the connection. Since a Close has |
| 3215 // already been sent, this just means closing the connection. | 3269 // already been sent, this just means closing the connection. |
| 3216 TEST_F(WebSocketChannelStreamTest, PingAfterCloseIsRejected) { | 3270 TEST_F(WebSocketChannelStreamTest, PingAfterCloseIsRejected) { |
| 3217 static const InitFrame frames[] = { | 3271 static const InitFrame frames[] = { |
| 3218 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, | 3272 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
| 3219 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}, | 3273 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}, |
| 3220 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, | 3274 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, |
| 3221 NOT_MASKED, "Ping body"}}; | 3275 NOT_MASKED, "Ping body"}}; |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3374 channel_->StartClosingHandshake(kWebSocketNormalClosure, "OK"); | 3428 channel_->StartClosingHandshake(kWebSocketNormalClosure, "OK"); |
| 3375 ASSERT_TRUE(read_frames); | 3429 ASSERT_TRUE(read_frames); |
| 3376 // Provide the "Close" message from the server. | 3430 // Provide the "Close" message from the server. |
| 3377 *read_frames = CreateFrameVector(frames); | 3431 *read_frames = CreateFrameVector(frames); |
| 3378 read_callback.Run(OK); | 3432 read_callback.Run(OK); |
| 3379 completion.WaitForResult(); | 3433 completion.WaitForResult(); |
| 3380 } | 3434 } |
| 3381 | 3435 |
| 3382 } // namespace | 3436 } // namespace |
| 3383 } // namespace net | 3437 } // namespace net |
| OLD | NEW |