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 <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include <iostream> | 9 #include <iostream> |
10 #include <string> | 10 #include <string> |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 | 135 |
136 // This mock is for testing expectations about how the EventInterface is used. | 136 // This mock is for testing expectations about how the EventInterface is used. |
137 class MockWebSocketEventInterface : public WebSocketEventInterface { | 137 class MockWebSocketEventInterface : public WebSocketEventInterface { |
138 public: | 138 public: |
139 MOCK_METHOD2(OnAddChannelResponse, | 139 MOCK_METHOD2(OnAddChannelResponse, |
140 ChannelState(bool, const std::string&)); // NOLINT | 140 ChannelState(bool, const std::string&)); // NOLINT |
141 MOCK_METHOD3(OnDataFrame, | 141 MOCK_METHOD3(OnDataFrame, |
142 ChannelState(bool, | 142 ChannelState(bool, |
143 WebSocketMessageType, | 143 WebSocketMessageType, |
144 const std::vector<char>&)); // NOLINT | 144 const std::vector<char>&)); // NOLINT |
145 MOCK_METHOD1(OnFlowControl, ChannelState(int64)); // NOLINT | 145 MOCK_METHOD1(OnFlowControl, ChannelState(int64)); // NOLINT |
146 MOCK_METHOD0(OnClosingHandshake, ChannelState(void)); // NOLINT | 146 MOCK_METHOD0(OnClosingHandshake, ChannelState(void)); // NOLINT |
| 147 MOCK_METHOD1(OnFailChannel, ChannelState(const std::string&)); // NOLINT |
147 MOCK_METHOD2(OnDropChannel, | 148 MOCK_METHOD2(OnDropChannel, |
148 ChannelState(uint16, const std::string&)); // NOLINT | 149 ChannelState(uint16, const std::string&)); // NOLINT |
149 }; | 150 }; |
150 | 151 |
151 // This fake EventInterface is for tests which need a WebSocketEventInterface | 152 // This fake EventInterface is for tests which need a WebSocketEventInterface |
152 // implementation but are not verifying how it is used. | 153 // implementation but are not verifying how it is used. |
153 class FakeWebSocketEventInterface : public WebSocketEventInterface { | 154 class FakeWebSocketEventInterface : public WebSocketEventInterface { |
154 virtual ChannelState OnAddChannelResponse( | 155 virtual ChannelState OnAddChannelResponse( |
155 bool fail, | 156 bool fail, |
156 const std::string& selected_protocol) OVERRIDE { | 157 const std::string& selected_protocol) OVERRIDE { |
157 return fail ? CHANNEL_DELETED : CHANNEL_ALIVE; | 158 return fail ? CHANNEL_DELETED : CHANNEL_ALIVE; |
158 } | 159 } |
159 virtual ChannelState OnDataFrame(bool fin, | 160 virtual ChannelState OnDataFrame(bool fin, |
160 WebSocketMessageType type, | 161 WebSocketMessageType type, |
161 const std::vector<char>& data) OVERRIDE { | 162 const std::vector<char>& data) OVERRIDE { |
162 return CHANNEL_ALIVE; | 163 return CHANNEL_ALIVE; |
163 } | 164 } |
164 virtual ChannelState OnFlowControl(int64 quota) OVERRIDE { | 165 virtual ChannelState OnFlowControl(int64 quota) OVERRIDE { |
165 return CHANNEL_ALIVE; | 166 return CHANNEL_ALIVE; |
166 } | 167 } |
167 virtual ChannelState OnClosingHandshake() OVERRIDE { return CHANNEL_ALIVE; } | 168 virtual ChannelState OnClosingHandshake() OVERRIDE { return CHANNEL_ALIVE; } |
| 169 virtual ChannelState OnFailChannel(const std::string& message) OVERRIDE { |
| 170 return CHANNEL_DELETED; |
| 171 } |
168 virtual ChannelState OnDropChannel(uint16 code, | 172 virtual ChannelState OnDropChannel(uint16 code, |
169 const std::string& reason) OVERRIDE { | 173 const std::string& reason) OVERRIDE { |
170 return CHANNEL_DELETED; | 174 return CHANNEL_DELETED; |
171 } | 175 } |
172 }; | 176 }; |
173 | 177 |
174 // This fake WebSocketStream is for tests that require a WebSocketStream but are | 178 // This fake WebSocketStream is for tests that require a WebSocketStream but are |
175 // not testing the way it is used. It has minimal functionality to return | 179 // not testing the way it is used. It has minimal functionality to return |
176 // the |protocol| and |extensions| that it was constructed with. | 180 // the |protocol| and |extensions| that it was constructed with. |
177 class FakeWebSocketStream : public WebSocketStream { | 181 class FakeWebSocketStream : public WebSocketStream { |
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 scoped_ptr<WebSocketStream> stream_; | 758 scoped_ptr<WebSocketStream> stream_; |
755 }; | 759 }; |
756 | 760 |
757 // enum of WebSocketEventInterface calls. These are intended to be or'd together | 761 // enum of WebSocketEventInterface calls. These are intended to be or'd together |
758 // in order to instruct WebSocketChannelDeletingTest when it should fail. | 762 // in order to instruct WebSocketChannelDeletingTest when it should fail. |
759 enum EventInterfaceCall { | 763 enum EventInterfaceCall { |
760 EVENT_ON_ADD_CHANNEL_RESPONSE = 0x1, | 764 EVENT_ON_ADD_CHANNEL_RESPONSE = 0x1, |
761 EVENT_ON_DATA_FRAME = 0x2, | 765 EVENT_ON_DATA_FRAME = 0x2, |
762 EVENT_ON_FLOW_CONTROL = 0x4, | 766 EVENT_ON_FLOW_CONTROL = 0x4, |
763 EVENT_ON_CLOSING_HANDSHAKE = 0x8, | 767 EVENT_ON_CLOSING_HANDSHAKE = 0x8, |
764 EVENT_ON_DROP_CHANNEL = 0x10, | 768 EVENT_ON_FAIL_CHANNEL = 0x10, |
| 769 EVENT_ON_DROP_CHANNEL = 0x20, |
765 }; | 770 }; |
766 | 771 |
767 class WebSocketChannelDeletingTest : public WebSocketChannelTest { | 772 class WebSocketChannelDeletingTest : public WebSocketChannelTest { |
768 public: | 773 public: |
769 ChannelState DeleteIfDeleting(EventInterfaceCall call) { | 774 ChannelState DeleteIfDeleting(EventInterfaceCall call) { |
770 if (deleting_ & call) { | 775 if (deleting_ & call) { |
771 channel_.reset(); | 776 channel_.reset(); |
772 return CHANNEL_DELETED; | 777 return CHANNEL_DELETED; |
773 } else { | 778 } else { |
774 return CHANNEL_ALIVE; | 779 return CHANNEL_ALIVE; |
775 } | 780 } |
776 } | 781 } |
777 | 782 |
778 protected: | 783 protected: |
779 WebSocketChannelDeletingTest() | 784 WebSocketChannelDeletingTest() |
780 : deleting_(EVENT_ON_ADD_CHANNEL_RESPONSE | EVENT_ON_DATA_FRAME | | 785 : deleting_(EVENT_ON_ADD_CHANNEL_RESPONSE | EVENT_ON_DATA_FRAME | |
781 EVENT_ON_FLOW_CONTROL | | 786 EVENT_ON_FLOW_CONTROL | |
782 EVENT_ON_CLOSING_HANDSHAKE | | 787 EVENT_ON_CLOSING_HANDSHAKE | |
| 788 EVENT_ON_FAIL_CHANNEL | |
783 EVENT_ON_DROP_CHANNEL) {} | 789 EVENT_ON_DROP_CHANNEL) {} |
784 // Create a ChannelDeletingFakeWebSocketEventInterface. Defined out-of-line to | 790 // Create a ChannelDeletingFakeWebSocketEventInterface. Defined out-of-line to |
785 // avoid circular dependency. | 791 // avoid circular dependency. |
786 virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() OVERRIDE; | 792 virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() OVERRIDE; |
787 | 793 |
788 // Tests can set deleting_ to a bitmap of EventInterfaceCall members that they | 794 // Tests can set deleting_ to a bitmap of EventInterfaceCall members that they |
789 // want to cause Channel deletion. The default is for all calls to cause | 795 // want to cause Channel deletion. The default is for all calls to cause |
790 // deletion. | 796 // deletion. |
791 int deleting_; | 797 int deleting_; |
792 }; | 798 }; |
(...skipping 20 matching lines...) Expand all Loading... |
813 } | 819 } |
814 | 820 |
815 virtual ChannelState OnFlowControl(int64 quota) OVERRIDE { | 821 virtual ChannelState OnFlowControl(int64 quota) OVERRIDE { |
816 return fixture_->DeleteIfDeleting(EVENT_ON_FLOW_CONTROL); | 822 return fixture_->DeleteIfDeleting(EVENT_ON_FLOW_CONTROL); |
817 } | 823 } |
818 | 824 |
819 virtual ChannelState OnClosingHandshake() OVERRIDE { | 825 virtual ChannelState OnClosingHandshake() OVERRIDE { |
820 return fixture_->DeleteIfDeleting(EVENT_ON_CLOSING_HANDSHAKE); | 826 return fixture_->DeleteIfDeleting(EVENT_ON_CLOSING_HANDSHAKE); |
821 } | 827 } |
822 | 828 |
| 829 virtual ChannelState OnFailChannel(const std::string& message) OVERRIDE { |
| 830 return fixture_->DeleteIfDeleting(EVENT_ON_FAIL_CHANNEL); |
| 831 } |
| 832 |
823 virtual ChannelState OnDropChannel(uint16 code, | 833 virtual ChannelState OnDropChannel(uint16 code, |
824 const std::string& reason) OVERRIDE { | 834 const std::string& reason) OVERRIDE { |
825 return fixture_->DeleteIfDeleting(EVENT_ON_DROP_CHANNEL); | 835 return fixture_->DeleteIfDeleting(EVENT_ON_DROP_CHANNEL); |
826 } | 836 } |
827 | 837 |
828 private: | 838 private: |
829 // A pointer to the test fixture. Owned by the test harness; this object will | 839 // A pointer to the test fixture. Owned by the test harness; this object will |
830 // be deleted before it is. | 840 // be deleted before it is. |
831 WebSocketChannelDeletingTest* fixture_; | 841 WebSocketChannelDeletingTest* fixture_; |
832 }; | 842 }; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 } | 918 } |
909 | 919 |
910 // Any WebSocketEventInterface methods can delete the WebSocketChannel and | 920 // Any WebSocketEventInterface methods can delete the WebSocketChannel and |
911 // return CHANNEL_DELETED. The WebSocketChannelDeletingTests are intended to | 921 // return CHANNEL_DELETED. The WebSocketChannelDeletingTests are intended to |
912 // verify that there are no use-after-free bugs when this happens. Problems will | 922 // verify that there are no use-after-free bugs when this happens. Problems will |
913 // probably only be found when running under Address Sanitizer or a similar | 923 // probably only be found when running under Address Sanitizer or a similar |
914 // tool. | 924 // tool. |
915 TEST_F(WebSocketChannelDeletingTest, OnAddChannelResponseFail) { | 925 TEST_F(WebSocketChannelDeletingTest, OnAddChannelResponseFail) { |
916 CreateChannelAndConnect(); | 926 CreateChannelAndConnect(); |
917 EXPECT_TRUE(channel_); | 927 EXPECT_TRUE(channel_); |
918 connect_data_.creator.connect_delegate->OnFailure( | 928 connect_data_.creator.connect_delegate->OnFailure("bye"); |
919 kWebSocketErrorNoStatusReceived); | |
920 EXPECT_EQ(NULL, channel_.get()); | 929 EXPECT_EQ(NULL, channel_.get()); |
921 } | 930 } |
922 | 931 |
923 // Deletion is possible (due to IPC failure) even if the connect succeeds. | 932 // Deletion is possible (due to IPC failure) even if the connect succeeds. |
924 TEST_F(WebSocketChannelDeletingTest, OnAddChannelResponseSuccess) { | 933 TEST_F(WebSocketChannelDeletingTest, OnAddChannelResponseSuccess) { |
925 CreateChannelAndConnectSuccessfully(); | 934 CreateChannelAndConnectSuccessfully(); |
926 EXPECT_EQ(NULL, channel_.get()); | 935 EXPECT_EQ(NULL, channel_.get()); |
927 } | 936 } |
928 | 937 |
929 TEST_F(WebSocketChannelDeletingTest, OnDataFrameSync) { | 938 TEST_F(WebSocketChannelDeletingTest, OnDataFrameSync) { |
(...skipping 27 matching lines...) Expand all Loading... |
957 TEST_F(WebSocketChannelDeletingTest, OnFlowControlAfterConnect) { | 966 TEST_F(WebSocketChannelDeletingTest, OnFlowControlAfterConnect) { |
958 deleting_ = EVENT_ON_FLOW_CONTROL; | 967 deleting_ = EVENT_ON_FLOW_CONTROL; |
959 | 968 |
960 CreateChannelAndConnectSuccessfully(); | 969 CreateChannelAndConnectSuccessfully(); |
961 EXPECT_EQ(NULL, channel_.get()); | 970 EXPECT_EQ(NULL, channel_.get()); |
962 } | 971 } |
963 | 972 |
964 TEST_F(WebSocketChannelDeletingTest, OnFlowControlAfterSend) { | 973 TEST_F(WebSocketChannelDeletingTest, OnFlowControlAfterSend) { |
965 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); | 974 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); |
966 // Avoid deleting the channel yet. | 975 // Avoid deleting the channel yet. |
967 deleting_ = EVENT_ON_DROP_CHANNEL; | 976 deleting_ = EVENT_ON_FAIL_CHANNEL | EVENT_ON_DROP_CHANNEL; |
968 CreateChannelAndConnectSuccessfully(); | 977 CreateChannelAndConnectSuccessfully(); |
969 ASSERT_TRUE(channel_); | 978 ASSERT_TRUE(channel_); |
970 deleting_ = EVENT_ON_FLOW_CONTROL; | 979 deleting_ = EVENT_ON_FLOW_CONTROL; |
971 channel_->SendFrame(true, | 980 channel_->SendFrame(true, |
972 WebSocketFrameHeader::kOpCodeText, | 981 WebSocketFrameHeader::kOpCodeText, |
973 std::vector<char>(kDefaultInitialQuota, 'B')); | 982 std::vector<char>(kDefaultInitialQuota, 'B')); |
974 EXPECT_EQ(NULL, channel_.get()); | 983 EXPECT_EQ(NULL, channel_.get()); |
975 } | 984 } |
976 | 985 |
977 TEST_F(WebSocketChannelDeletingTest, OnClosingHandshakeSync) { | 986 TEST_F(WebSocketChannelDeletingTest, OnClosingHandshakeSync) { |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1149 // OnFlowControl is always called immediately after connect to provide initial | 1158 // OnFlowControl is always called immediately after connect to provide initial |
1150 // quota to the renderer. | 1159 // quota to the renderer. |
1151 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1160 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
1152 | 1161 |
1153 CreateChannelAndConnect(); | 1162 CreateChannelAndConnect(); |
1154 | 1163 |
1155 connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass()); | 1164 connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass()); |
1156 } | 1165 } |
1157 | 1166 |
1158 TEST_F(WebSocketChannelEventInterfaceTest, ConnectFailureReported) { | 1167 TEST_F(WebSocketChannelEventInterfaceTest, ConnectFailureReported) { |
1159 // true means failure. | 1168 EXPECT_CALL(*event_interface_, OnFailChannel("hello")); |
1160 EXPECT_CALL(*event_interface_, OnAddChannelResponse(true, "")); | |
1161 | 1169 |
1162 CreateChannelAndConnect(); | 1170 CreateChannelAndConnect(); |
1163 | 1171 |
1164 connect_data_.creator.connect_delegate->OnFailure( | 1172 connect_data_.creator.connect_delegate->OnFailure("hello"); |
1165 kWebSocketErrorNoStatusReceived); | |
1166 } | 1173 } |
1167 | 1174 |
1168 TEST_F(WebSocketChannelEventInterfaceTest, NonWebSocketSchemeRejected) { | 1175 TEST_F(WebSocketChannelEventInterfaceTest, NonWebSocketSchemeRejected) { |
1169 EXPECT_CALL(*event_interface_, OnAddChannelResponse(true, "")); | 1176 EXPECT_CALL(*event_interface_, OnAddChannelResponse(true, "")); |
1170 connect_data_.socket_url = GURL("http://www.google.com/"); | 1177 connect_data_.socket_url = GURL("http://www.google.com/"); |
1171 CreateChannelAndConnect(); | 1178 CreateChannelAndConnect(); |
1172 } | 1179 } |
1173 | 1180 |
1174 TEST_F(WebSocketChannelEventInterfaceTest, ProtocolPassed) { | 1181 TEST_F(WebSocketChannelEventInterfaceTest, ProtocolPassed) { |
1175 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, "Bob")); | 1182 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, "Bob")); |
(...skipping 1201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2377 channel_->StartClosingHandshake(kWebSocketNormalClosure, "OK"); | 2384 channel_->StartClosingHandshake(kWebSocketNormalClosure, "OK"); |
2378 ASSERT_TRUE(read_frames); | 2385 ASSERT_TRUE(read_frames); |
2379 // Provide the "Close" message from the server. | 2386 // Provide the "Close" message from the server. |
2380 *read_frames = CreateFrameVector(frames); | 2387 *read_frames = CreateFrameVector(frames); |
2381 read_callback.Run(OK); | 2388 read_callback.Run(OK); |
2382 completion.WaitForResult(); | 2389 completion.WaitForResult(); |
2383 } | 2390 } |
2384 | 2391 |
2385 } // namespace | 2392 } // namespace |
2386 } // namespace net | 2393 } // namespace net |
OLD | NEW |