| 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 <stddef.h> | 8 #include <stddef.h> |
| 9 #include <string.h> | 9 #include <string.h> |
| 10 #include <iostream> | 10 #include <iostream> |
| (...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 base::Bind(&ArgumentCopyingWebSocketStreamCreator::Create, | 745 base::Bind(&ArgumentCopyingWebSocketStreamCreator::Create, |
| 746 base::Unretained(&connect_data_.creator))); | 746 base::Unretained(&connect_data_.creator))); |
| 747 } | 747 } |
| 748 | 748 |
| 749 // Same as CreateChannelAndConnect(), but calls the on_success callback as | 749 // Same as CreateChannelAndConnect(), but calls the on_success callback as |
| 750 // well. This method is virtual so that subclasses can also set the stream. | 750 // well. This method is virtual so that subclasses can also set the stream. |
| 751 virtual void CreateChannelAndConnectSuccessfully() { | 751 virtual void CreateChannelAndConnectSuccessfully() { |
| 752 CreateChannelAndConnect(); | 752 CreateChannelAndConnect(); |
| 753 // Most tests aren't concerned with flow control from the renderer, so allow | 753 // Most tests aren't concerned with flow control from the renderer, so allow |
| 754 // MAX_INT quota units. | 754 // MAX_INT quota units. |
| 755 channel_->SendFlowControl(kPlentyOfQuota); | 755 EXPECT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(kPlentyOfQuota)); |
| 756 connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_)); | 756 connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_)); |
| 757 } | 757 } |
| 758 | 758 |
| 759 // Returns a WebSocketEventInterface to be passed to the WebSocketChannel. | 759 // Returns a WebSocketEventInterface to be passed to the WebSocketChannel. |
| 760 // This implementation returns a newly-created fake. Subclasses may return a | 760 // This implementation returns a newly-created fake. Subclasses may return a |
| 761 // mock instead. | 761 // mock instead. |
| 762 virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() { | 762 virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() { |
| 763 return scoped_ptr<WebSocketEventInterface>(new FakeWebSocketEventInterface); | 763 return scoped_ptr<WebSocketEventInterface>(new FakeWebSocketEventInterface); |
| 764 } | 764 } |
| 765 | 765 |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 969 }; | 969 }; |
| 970 | 970 |
| 971 // Fixture for tests which test use of receive quota from the renderer. | 971 // Fixture for tests which test use of receive quota from the renderer. |
| 972 class WebSocketChannelFlowControlTest | 972 class WebSocketChannelFlowControlTest |
| 973 : public WebSocketChannelEventInterfaceTest { | 973 : public WebSocketChannelEventInterfaceTest { |
| 974 protected: | 974 protected: |
| 975 // Tests using this fixture should use CreateChannelAndConnectWithQuota() | 975 // Tests using this fixture should use CreateChannelAndConnectWithQuota() |
| 976 // instead of CreateChannelAndConnectSuccessfully(). | 976 // instead of CreateChannelAndConnectSuccessfully(). |
| 977 void CreateChannelAndConnectWithQuota(int64_t quota) { | 977 void CreateChannelAndConnectWithQuota(int64_t quota) { |
| 978 CreateChannelAndConnect(); | 978 CreateChannelAndConnect(); |
| 979 channel_->SendFlowControl(quota); | 979 EXPECT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(quota)); |
| 980 connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_)); | 980 connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_)); |
| 981 } | 981 } |
| 982 | 982 |
| 983 virtual void CreateChannelAndConnectSuccesfully() { NOTREACHED(); } | 983 virtual void CreateChannelAndConnectSuccesfully() { NOTREACHED(); } |
| 984 }; | 984 }; |
| 985 | 985 |
| 986 // Fixture for tests which test UTF-8 validation of received Text frames using a | 986 // Fixture for tests which test UTF-8 validation of received Text frames using a |
| 987 // mock WebSocketStream. | 987 // mock WebSocketStream. |
| 988 class WebSocketChannelReceiveUtf8Test : public WebSocketChannelStreamTest { | 988 class WebSocketChannelReceiveUtf8Test : public WebSocketChannelStreamTest { |
| 989 public: | 989 public: |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1012 EXPECT_EQ(connect_data_.requested_subprotocols, | 1012 EXPECT_EQ(connect_data_.requested_subprotocols, |
| 1013 actual.requested_subprotocols); | 1013 actual.requested_subprotocols); |
| 1014 EXPECT_EQ(connect_data_.origin.Serialize(), actual.origin.Serialize()); | 1014 EXPECT_EQ(connect_data_.origin.Serialize(), actual.origin.Serialize()); |
| 1015 } | 1015 } |
| 1016 | 1016 |
| 1017 // Verify that calling SendFlowControl before the connection is established does | 1017 // Verify that calling SendFlowControl before the connection is established does |
| 1018 // not cause a crash. | 1018 // not cause a crash. |
| 1019 TEST_F(WebSocketChannelTest, SendFlowControlDuringHandshakeOkay) { | 1019 TEST_F(WebSocketChannelTest, SendFlowControlDuringHandshakeOkay) { |
| 1020 CreateChannelAndConnect(); | 1020 CreateChannelAndConnect(); |
| 1021 ASSERT_TRUE(channel_); | 1021 ASSERT_TRUE(channel_); |
| 1022 channel_->SendFlowControl(65536); | 1022 ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(65536)); |
| 1023 } | 1023 } |
| 1024 | 1024 |
| 1025 // Any WebSocketEventInterface methods can delete the WebSocketChannel and | 1025 // Any WebSocketEventInterface methods can delete the WebSocketChannel and |
| 1026 // return CHANNEL_DELETED. The WebSocketChannelDeletingTests are intended to | 1026 // return CHANNEL_DELETED. The WebSocketChannelDeletingTests are intended to |
| 1027 // verify that there are no use-after-free bugs when this happens. Problems will | 1027 // verify that there are no use-after-free bugs when this happens. Problems will |
| 1028 // probably only be found when running under Address Sanitizer or a similar | 1028 // probably only be found when running under Address Sanitizer or a similar |
| 1029 // tool. | 1029 // tool. |
| 1030 TEST_F(WebSocketChannelDeletingTest, OnAddChannelResponseFail) { | 1030 TEST_F(WebSocketChannelDeletingTest, OnAddChannelResponseFail) { |
| 1031 CreateChannelAndConnect(); | 1031 CreateChannelAndConnect(); |
| 1032 EXPECT_TRUE(channel_); | 1032 EXPECT_TRUE(channel_); |
| (...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1827 { | 1827 { |
| 1828 InSequence s; | 1828 InSequence s; |
| 1829 EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _)); | 1829 EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _)); |
| 1830 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1830 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
| 1831 EXPECT_CALL(*event_interface_, | 1831 EXPECT_CALL(*event_interface_, |
| 1832 OnDropChannel(true, kWebSocketNormalClosure, "Fred")); | 1832 OnDropChannel(true, kWebSocketNormalClosure, "Fred")); |
| 1833 } | 1833 } |
| 1834 | 1834 |
| 1835 CreateChannelAndConnectSuccessfully(); | 1835 CreateChannelAndConnectSuccessfully(); |
| 1836 | 1836 |
| 1837 channel_->StartClosingHandshake(kWebSocketNormalClosure, "Fred"); | 1837 ASSERT_EQ(CHANNEL_ALIVE, |
| 1838 channel_->StartClosingHandshake(kWebSocketNormalClosure, "Fred")); |
| 1838 base::MessageLoop::current()->RunUntilIdle(); | 1839 base::MessageLoop::current()->RunUntilIdle(); |
| 1839 } | 1840 } |
| 1840 | 1841 |
| 1841 // StartClosingHandshake() also works before connection completes, and calls | 1842 // StartClosingHandshake() also works before connection completes, and calls |
| 1842 // OnDropChannel. | 1843 // OnDropChannel. |
| 1843 TEST_F(WebSocketChannelEventInterfaceTest, CloseDuringConnection) { | 1844 TEST_F(WebSocketChannelEventInterfaceTest, CloseDuringConnection) { |
| 1844 EXPECT_CALL(*event_interface_, | 1845 EXPECT_CALL(*event_interface_, |
| 1845 OnDropChannel(false, kWebSocketErrorAbnormalClosure, "")); | 1846 OnDropChannel(false, kWebSocketErrorAbnormalClosure, "")); |
| 1846 | 1847 |
| 1847 CreateChannelAndConnect(); | 1848 CreateChannelAndConnect(); |
| 1848 channel_->StartClosingHandshake(kWebSocketNormalClosure, "Joe"); | 1849 ASSERT_EQ(CHANNEL_DELETED, |
| 1850 channel_->StartClosingHandshake(kWebSocketNormalClosure, "Joe")); |
| 1849 } | 1851 } |
| 1850 | 1852 |
| 1851 // OnDropChannel() is only called once when a write() on the socket triggers a | 1853 // OnDropChannel() is only called once when a write() on the socket triggers a |
| 1852 // connection reset. | 1854 // connection reset. |
| 1853 TEST_F(WebSocketChannelEventInterfaceTest, OnDropChannelCalledOnce) { | 1855 TEST_F(WebSocketChannelEventInterfaceTest, OnDropChannelCalledOnce) { |
| 1854 set_stream(make_scoped_ptr(new ResetOnWriteFakeWebSocketStream)); | 1856 set_stream(make_scoped_ptr(new ResetOnWriteFakeWebSocketStream)); |
| 1855 EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _)); | 1857 EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _)); |
| 1856 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1858 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
| 1857 | 1859 |
| 1858 EXPECT_CALL(*event_interface_, | 1860 EXPECT_CALL(*event_interface_, |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2141 .WillOnce(InvokeClosureReturnDeleted(completion.closure())); | 2143 .WillOnce(InvokeClosureReturnDeleted(completion.closure())); |
| 2142 } | 2144 } |
| 2143 CreateChannelAndConnectSuccessfully(); | 2145 CreateChannelAndConnectSuccessfully(); |
| 2144 // OneShotTimer is not very friendly to testing; there is no apparent way to | 2146 // OneShotTimer is not very friendly to testing; there is no apparent way to |
| 2145 // set an expectation on it. Instead the tests need to infer that the timeout | 2147 // set an expectation on it. Instead the tests need to infer that the timeout |
| 2146 // was fired by the behaviour of the WebSocketChannel object. | 2148 // was fired by the behaviour of the WebSocketChannel object. |
| 2147 channel_->SetClosingHandshakeTimeoutForTesting( | 2149 channel_->SetClosingHandshakeTimeoutForTesting( |
| 2148 TimeDelta::FromMilliseconds(kVeryTinyTimeoutMillis)); | 2150 TimeDelta::FromMilliseconds(kVeryTinyTimeoutMillis)); |
| 2149 channel_->SetUnderlyingConnectionCloseTimeoutForTesting( | 2151 channel_->SetUnderlyingConnectionCloseTimeoutForTesting( |
| 2150 TimeDelta::FromMilliseconds(kVeryBigTimeoutMillis)); | 2152 TimeDelta::FromMilliseconds(kVeryBigTimeoutMillis)); |
| 2151 channel_->StartClosingHandshake(kWebSocketNormalClosure, ""); | 2153 ASSERT_EQ(CHANNEL_ALIVE, |
| 2154 channel_->StartClosingHandshake(kWebSocketNormalClosure, "")); |
| 2152 checkpoint.Call(1); | 2155 checkpoint.Call(1); |
| 2153 completion.WaitForResult(); | 2156 completion.WaitForResult(); |
| 2154 } | 2157 } |
| 2155 | 2158 |
| 2156 // The closing handshake times out and sends an OnDropChannel event if a Close | 2159 // The closing handshake times out and sends an OnDropChannel event if a Close |
| 2157 // message is received but the connection isn't closed by the remote host. | 2160 // message is received but the connection isn't closed by the remote host. |
| 2158 TEST_F(WebSocketChannelEventInterfaceTest, | 2161 TEST_F(WebSocketChannelEventInterfaceTest, |
| 2159 ServerInitiatedClosingHandshakeTimesOut) { | 2162 ServerInitiatedClosingHandshakeTimesOut) { |
| 2160 scoped_ptr<ReadableFakeWebSocketStream> stream( | 2163 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 2161 new ReadableFakeWebSocketStream); | 2164 new ReadableFakeWebSocketStream); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2194 { | 2197 { |
| 2195 InSequence s; | 2198 InSequence s; |
| 2196 EXPECT_CALL(checkpoint, Call(1)); | 2199 EXPECT_CALL(checkpoint, Call(1)); |
| 2197 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) | 2200 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
| 2198 .WillOnce(Return(ERR_IO_PENDING)); | 2201 .WillOnce(Return(ERR_IO_PENDING)); |
| 2199 EXPECT_CALL(checkpoint, Call(2)); | 2202 EXPECT_CALL(checkpoint, Call(2)); |
| 2200 } | 2203 } |
| 2201 | 2204 |
| 2202 set_stream(std::move(mock_stream_)); | 2205 set_stream(std::move(mock_stream_)); |
| 2203 CreateChannelAndConnect(); | 2206 CreateChannelAndConnect(); |
| 2204 channel_->SendFlowControl(kPlentyOfQuota); | 2207 ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(kPlentyOfQuota)); |
| 2205 checkpoint.Call(1); | 2208 checkpoint.Call(1); |
| 2206 connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_)); | 2209 connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_)); |
| 2207 checkpoint.Call(2); | 2210 checkpoint.Call(2); |
| 2208 } | 2211 } |
| 2209 | 2212 |
| 2210 // If for some reason the connect succeeds before the renderer sends us quota, | 2213 // If for some reason the connect succeeds before the renderer sends us quota, |
| 2211 // we shouldn't call ReadFrames() immediately. | 2214 // we shouldn't call ReadFrames() immediately. |
| 2212 // TODO(ricea): Actually we should call ReadFrames() with a small limit so we | 2215 // TODO(ricea): Actually we should call ReadFrames() with a small limit so we |
| 2213 // can still handle control frames. This should be done once we have any API to | 2216 // can still handle control frames. This should be done once we have any API to |
| 2214 // expose quota to the lower levels. | 2217 // expose quota to the lower levels. |
| 2215 TEST_F(WebSocketChannelStreamTest, FlowControlLate) { | 2218 TEST_F(WebSocketChannelStreamTest, FlowControlLate) { |
| 2216 Checkpoint checkpoint; | 2219 Checkpoint checkpoint; |
| 2217 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); | 2220 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| 2218 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); | 2221 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); |
| 2219 { | 2222 { |
| 2220 InSequence s; | 2223 InSequence s; |
| 2221 EXPECT_CALL(checkpoint, Call(1)); | 2224 EXPECT_CALL(checkpoint, Call(1)); |
| 2222 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) | 2225 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
| 2223 .WillOnce(Return(ERR_IO_PENDING)); | 2226 .WillOnce(Return(ERR_IO_PENDING)); |
| 2224 EXPECT_CALL(checkpoint, Call(2)); | 2227 EXPECT_CALL(checkpoint, Call(2)); |
| 2225 } | 2228 } |
| 2226 | 2229 |
| 2227 set_stream(std::move(mock_stream_)); | 2230 set_stream(std::move(mock_stream_)); |
| 2228 CreateChannelAndConnect(); | 2231 CreateChannelAndConnect(); |
| 2229 connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_)); | 2232 connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_)); |
| 2230 checkpoint.Call(1); | 2233 checkpoint.Call(1); |
| 2231 channel_->SendFlowControl(kPlentyOfQuota); | 2234 ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(kPlentyOfQuota)); |
| 2232 checkpoint.Call(2); | 2235 checkpoint.Call(2); |
| 2233 } | 2236 } |
| 2234 | 2237 |
| 2235 // We should stop calling ReadFrames() when all quota is used. | 2238 // We should stop calling ReadFrames() when all quota is used. |
| 2236 TEST_F(WebSocketChannelStreamTest, FlowControlStopsReadFrames) { | 2239 TEST_F(WebSocketChannelStreamTest, FlowControlStopsReadFrames) { |
| 2237 static const InitFrame frames[] = { | 2240 static const InitFrame frames[] = { |
| 2238 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "FOUR"}}; | 2241 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "FOUR"}}; |
| 2239 | 2242 |
| 2240 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); | 2243 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| 2241 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); | 2244 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); |
| 2242 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) | 2245 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
| 2243 .WillOnce(ReturnFrames(&frames)); | 2246 .WillOnce(ReturnFrames(&frames)); |
| 2244 | 2247 |
| 2245 set_stream(std::move(mock_stream_)); | 2248 set_stream(std::move(mock_stream_)); |
| 2246 CreateChannelAndConnect(); | 2249 CreateChannelAndConnect(); |
| 2247 channel_->SendFlowControl(4); | 2250 ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(4)); |
| 2248 connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_)); | 2251 connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_)); |
| 2249 } | 2252 } |
| 2250 | 2253 |
| 2251 // Providing extra quota causes ReadFrames() to be called again. | 2254 // Providing extra quota causes ReadFrames() to be called again. |
| 2252 TEST_F(WebSocketChannelStreamTest, FlowControlStartsWithMoreQuota) { | 2255 TEST_F(WebSocketChannelStreamTest, FlowControlStartsWithMoreQuota) { |
| 2253 static const InitFrame frames[] = { | 2256 static const InitFrame frames[] = { |
| 2254 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "FOUR"}}; | 2257 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "FOUR"}}; |
| 2255 Checkpoint checkpoint; | 2258 Checkpoint checkpoint; |
| 2256 | 2259 |
| 2257 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); | 2260 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| 2258 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); | 2261 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); |
| 2259 { | 2262 { |
| 2260 InSequence s; | 2263 InSequence s; |
| 2261 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) | 2264 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
| 2262 .WillOnce(ReturnFrames(&frames)); | 2265 .WillOnce(ReturnFrames(&frames)); |
| 2263 EXPECT_CALL(checkpoint, Call(1)); | 2266 EXPECT_CALL(checkpoint, Call(1)); |
| 2264 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) | 2267 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
| 2265 .WillOnce(Return(ERR_IO_PENDING)); | 2268 .WillOnce(Return(ERR_IO_PENDING)); |
| 2266 } | 2269 } |
| 2267 | 2270 |
| 2268 set_stream(std::move(mock_stream_)); | 2271 set_stream(std::move(mock_stream_)); |
| 2269 CreateChannelAndConnect(); | 2272 CreateChannelAndConnect(); |
| 2270 channel_->SendFlowControl(4); | 2273 ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(4)); |
| 2271 connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_)); | 2274 connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_)); |
| 2272 checkpoint.Call(1); | 2275 checkpoint.Call(1); |
| 2273 channel_->SendFlowControl(4); | 2276 ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(4)); |
| 2274 } | 2277 } |
| 2275 | 2278 |
| 2276 // ReadFrames() isn't called again until all pending data has been passed to | 2279 // ReadFrames() isn't called again until all pending data has been passed to |
| 2277 // the renderer. | 2280 // the renderer. |
| 2278 TEST_F(WebSocketChannelStreamTest, ReadFramesNotCalledUntilQuotaAvailable) { | 2281 TEST_F(WebSocketChannelStreamTest, ReadFramesNotCalledUntilQuotaAvailable) { |
| 2279 static const InitFrame frames[] = { | 2282 static const InitFrame frames[] = { |
| 2280 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "FOUR"}}; | 2283 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "FOUR"}}; |
| 2281 Checkpoint checkpoint; | 2284 Checkpoint checkpoint; |
| 2282 | 2285 |
| 2283 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); | 2286 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| 2284 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); | 2287 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); |
| 2285 { | 2288 { |
| 2286 InSequence s; | 2289 InSequence s; |
| 2287 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) | 2290 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
| 2288 .WillOnce(ReturnFrames(&frames)); | 2291 .WillOnce(ReturnFrames(&frames)); |
| 2289 EXPECT_CALL(checkpoint, Call(1)); | 2292 EXPECT_CALL(checkpoint, Call(1)); |
| 2290 EXPECT_CALL(checkpoint, Call(2)); | 2293 EXPECT_CALL(checkpoint, Call(2)); |
| 2291 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) | 2294 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
| 2292 .WillOnce(Return(ERR_IO_PENDING)); | 2295 .WillOnce(Return(ERR_IO_PENDING)); |
| 2293 } | 2296 } |
| 2294 | 2297 |
| 2295 set_stream(std::move(mock_stream_)); | 2298 set_stream(std::move(mock_stream_)); |
| 2296 CreateChannelAndConnect(); | 2299 CreateChannelAndConnect(); |
| 2297 channel_->SendFlowControl(2); | 2300 ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(2)); |
| 2298 connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_)); | 2301 connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_)); |
| 2299 checkpoint.Call(1); | 2302 checkpoint.Call(1); |
| 2300 channel_->SendFlowControl(2); | 2303 ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(2)); |
| 2301 checkpoint.Call(2); | 2304 checkpoint.Call(2); |
| 2302 channel_->SendFlowControl(2); | 2305 ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(2)); |
| 2303 } | 2306 } |
| 2304 | 2307 |
| 2305 // A message that needs to be split into frames to fit within quota should | 2308 // A message that needs to be split into frames to fit within quota should |
| 2306 // maintain correct semantics. | 2309 // maintain correct semantics. |
| 2307 TEST_F(WebSocketChannelFlowControlTest, SingleFrameMessageSplitSync) { | 2310 TEST_F(WebSocketChannelFlowControlTest, SingleFrameMessageSplitSync) { |
| 2308 scoped_ptr<ReadableFakeWebSocketStream> stream( | 2311 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 2309 new ReadableFakeWebSocketStream); | 2312 new ReadableFakeWebSocketStream); |
| 2310 static const InitFrame frames[] = { | 2313 static const InitFrame frames[] = { |
| 2311 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "FOUR"}}; | 2314 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "FOUR"}}; |
| 2312 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); | 2315 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); |
| 2313 set_stream(std::move(stream)); | 2316 set_stream(std::move(stream)); |
| 2314 { | 2317 { |
| 2315 InSequence s; | 2318 InSequence s; |
| 2316 EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _)); | 2319 EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _)); |
| 2317 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 2320 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
| 2318 EXPECT_CALL( | 2321 EXPECT_CALL( |
| 2319 *event_interface_, | 2322 *event_interface_, |
| 2320 OnDataFrame(false, WebSocketFrameHeader::kOpCodeText, AsVector("FO"))); | 2323 OnDataFrame(false, WebSocketFrameHeader::kOpCodeText, AsVector("FO"))); |
| 2321 EXPECT_CALL( | 2324 EXPECT_CALL( |
| 2322 *event_interface_, | 2325 *event_interface_, |
| 2323 OnDataFrame( | 2326 OnDataFrame( |
| 2324 false, WebSocketFrameHeader::kOpCodeContinuation, AsVector("U"))); | 2327 false, WebSocketFrameHeader::kOpCodeContinuation, AsVector("U"))); |
| 2325 EXPECT_CALL( | 2328 EXPECT_CALL( |
| 2326 *event_interface_, | 2329 *event_interface_, |
| 2327 OnDataFrame( | 2330 OnDataFrame( |
| 2328 true, WebSocketFrameHeader::kOpCodeContinuation, AsVector("R"))); | 2331 true, WebSocketFrameHeader::kOpCodeContinuation, AsVector("R"))); |
| 2329 } | 2332 } |
| 2330 | 2333 |
| 2331 CreateChannelAndConnectWithQuota(2); | 2334 CreateChannelAndConnectWithQuota(2); |
| 2332 channel_->SendFlowControl(1); | 2335 ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(1)); |
| 2333 channel_->SendFlowControl(1); | 2336 ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(1)); |
| 2334 } | 2337 } |
| 2335 | 2338 |
| 2336 // The code path for async messages is slightly different, so test it | 2339 // The code path for async messages is slightly different, so test it |
| 2337 // separately. | 2340 // separately. |
| 2338 TEST_F(WebSocketChannelFlowControlTest, SingleFrameMessageSplitAsync) { | 2341 TEST_F(WebSocketChannelFlowControlTest, SingleFrameMessageSplitAsync) { |
| 2339 scoped_ptr<ReadableFakeWebSocketStream> stream( | 2342 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 2340 new ReadableFakeWebSocketStream); | 2343 new ReadableFakeWebSocketStream); |
| 2341 static const InitFrame frames[] = { | 2344 static const InitFrame frames[] = { |
| 2342 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "FOUR"}}; | 2345 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "FOUR"}}; |
| 2343 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); | 2346 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2360 EXPECT_CALL( | 2363 EXPECT_CALL( |
| 2361 *event_interface_, | 2364 *event_interface_, |
| 2362 OnDataFrame( | 2365 OnDataFrame( |
| 2363 true, WebSocketFrameHeader::kOpCodeContinuation, AsVector("R"))); | 2366 true, WebSocketFrameHeader::kOpCodeContinuation, AsVector("R"))); |
| 2364 } | 2367 } |
| 2365 | 2368 |
| 2366 CreateChannelAndConnectWithQuota(2); | 2369 CreateChannelAndConnectWithQuota(2); |
| 2367 checkpoint.Call(1); | 2370 checkpoint.Call(1); |
| 2368 base::MessageLoop::current()->RunUntilIdle(); | 2371 base::MessageLoop::current()->RunUntilIdle(); |
| 2369 checkpoint.Call(2); | 2372 checkpoint.Call(2); |
| 2370 channel_->SendFlowControl(1); | 2373 ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(1)); |
| 2371 checkpoint.Call(3); | 2374 checkpoint.Call(3); |
| 2372 channel_->SendFlowControl(1); | 2375 ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(1)); |
| 2373 } | 2376 } |
| 2374 | 2377 |
| 2375 // A message split into multiple frames which is further split due to quota | 2378 // A message split into multiple frames which is further split due to quota |
| 2376 // restrictions should stil be correct. | 2379 // restrictions should stil be correct. |
| 2377 // TODO(ricea): The message ends up split into more frames than are strictly | 2380 // TODO(ricea): The message ends up split into more frames than are strictly |
| 2378 // necessary. The complexity/performance tradeoffs here need further | 2381 // necessary. The complexity/performance tradeoffs here need further |
| 2379 // examination. | 2382 // examination. |
| 2380 TEST_F(WebSocketChannelFlowControlTest, MultipleFrameSplit) { | 2383 TEST_F(WebSocketChannelFlowControlTest, MultipleFrameSplit) { |
| 2381 scoped_ptr<ReadableFakeWebSocketStream> stream( | 2384 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 2382 new ReadableFakeWebSocketStream); | 2385 new ReadableFakeWebSocketStream); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2408 EXPECT_CALL(*event_interface_, | 2411 EXPECT_CALL(*event_interface_, |
| 2409 OnDataFrame(false, | 2412 OnDataFrame(false, |
| 2410 WebSocketFrameHeader::kOpCodeContinuation, | 2413 WebSocketFrameHeader::kOpCodeContinuation, |
| 2411 AsVector("FINAL "))); | 2414 AsVector("FINAL "))); |
| 2412 EXPECT_CALL(*event_interface_, | 2415 EXPECT_CALL(*event_interface_, |
| 2413 OnDataFrame(true, | 2416 OnDataFrame(true, |
| 2414 WebSocketFrameHeader::kOpCodeContinuation, | 2417 WebSocketFrameHeader::kOpCodeContinuation, |
| 2415 AsVector("FRAME IS 24 BYTES."))); | 2418 AsVector("FRAME IS 24 BYTES."))); |
| 2416 } | 2419 } |
| 2417 CreateChannelAndConnectWithQuota(14); | 2420 CreateChannelAndConnectWithQuota(14); |
| 2418 channel_->SendFlowControl(43); | 2421 ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(43)); |
| 2419 channel_->SendFlowControl(32); | 2422 ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(32)); |
| 2420 } | 2423 } |
| 2421 | 2424 |
| 2422 // An empty message handled when we are out of quota must not be delivered | 2425 // An empty message handled when we are out of quota must not be delivered |
| 2423 // out-of-order with respect to other messages. | 2426 // out-of-order with respect to other messages. |
| 2424 TEST_F(WebSocketChannelFlowControlTest, EmptyMessageNoQuota) { | 2427 TEST_F(WebSocketChannelFlowControlTest, EmptyMessageNoQuota) { |
| 2425 scoped_ptr<ReadableFakeWebSocketStream> stream( | 2428 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 2426 new ReadableFakeWebSocketStream); | 2429 new ReadableFakeWebSocketStream); |
| 2427 static const InitFrame frames[] = { | 2430 static const InitFrame frames[] = { |
| 2428 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, | 2431 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, |
| 2429 NOT_MASKED, "FIRST MESSAGE"}, | 2432 NOT_MASKED, "FIRST MESSAGE"}, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2449 OnDataFrame(true, | 2452 OnDataFrame(true, |
| 2450 WebSocketFrameHeader::kOpCodeText, | 2453 WebSocketFrameHeader::kOpCodeText, |
| 2451 AsVector(""))); | 2454 AsVector(""))); |
| 2452 EXPECT_CALL(*event_interface_, | 2455 EXPECT_CALL(*event_interface_, |
| 2453 OnDataFrame(true, | 2456 OnDataFrame(true, |
| 2454 WebSocketFrameHeader::kOpCodeText, | 2457 WebSocketFrameHeader::kOpCodeText, |
| 2455 AsVector("THIRD MESSAGE"))); | 2458 AsVector("THIRD MESSAGE"))); |
| 2456 } | 2459 } |
| 2457 | 2460 |
| 2458 CreateChannelAndConnectWithQuota(6); | 2461 CreateChannelAndConnectWithQuota(6); |
| 2459 channel_->SendFlowControl(128); | 2462 ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(128)); |
| 2463 } |
| 2464 |
| 2465 // A close frame should not overtake data frames. |
| 2466 TEST_F(WebSocketChannelFlowControlTest, CloseFrameShouldNotOvertakeDataFrames) { |
| 2467 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 2468 new ReadableFakeWebSocketStream); |
| 2469 static const InitFrame frames[] = { |
| 2470 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, |
| 2471 "FIRST "}, |
| 2472 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, NOT_MASKED, |
| 2473 "MESSAGE"}, |
| 2474 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, |
| 2475 "SECOND "}, |
| 2476 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, |
| 2477 CLOSE_DATA(NORMAL_CLOSURE, "GOOD BYE")}, |
| 2478 }; |
| 2479 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); |
| 2480 set_stream(std::move(stream)); |
| 2481 Checkpoint checkpoint; |
| 2482 InSequence s; |
| 2483 EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _)); |
| 2484 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
| 2485 EXPECT_CALL(*event_interface_, |
| 2486 OnDataFrame(false, WebSocketFrameHeader::kOpCodeText, |
| 2487 AsVector("FIRST "))); |
| 2488 EXPECT_CALL(checkpoint, Call(1)); |
| 2489 EXPECT_CALL(*event_interface_, |
| 2490 OnDataFrame(false, WebSocketFrameHeader::kOpCodeContinuation, |
| 2491 AsVector("MESSAG"))); |
| 2492 EXPECT_CALL(checkpoint, Call(2)); |
| 2493 EXPECT_CALL(*event_interface_, |
| 2494 OnDataFrame(true, WebSocketFrameHeader::kOpCodeContinuation, |
| 2495 AsVector("E"))); |
| 2496 EXPECT_CALL( |
| 2497 *event_interface_, |
| 2498 OnDataFrame(false, WebSocketFrameHeader::kOpCodeText, AsVector("SECON"))); |
| 2499 EXPECT_CALL(checkpoint, Call(3)); |
| 2500 EXPECT_CALL(*event_interface_, |
| 2501 OnDataFrame(false, WebSocketFrameHeader::kOpCodeContinuation, |
| 2502 AsVector("D "))); |
| 2503 EXPECT_CALL(*event_interface_, OnClosingHandshake()); |
| 2504 EXPECT_CALL(checkpoint, Call(4)); |
| 2505 |
| 2506 CreateChannelAndConnectWithQuota(6); |
| 2507 checkpoint.Call(1); |
| 2508 ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(6)); |
| 2509 checkpoint.Call(2); |
| 2510 ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(6)); |
| 2511 checkpoint.Call(3); |
| 2512 ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(6)); |
| 2513 checkpoint.Call(4); |
| 2460 } | 2514 } |
| 2461 | 2515 |
| 2462 // RFC6455 5.1 "a client MUST mask all frames that it sends to the server". | 2516 // RFC6455 5.1 "a client MUST mask all frames that it sends to the server". |
| 2463 // WebSocketChannel actually only sets the mask bit in the header, it doesn't | 2517 // WebSocketChannel actually only sets the mask bit in the header, it doesn't |
| 2464 // perform masking itself (not all transports actually use masking). | 2518 // perform masking itself (not all transports actually use masking). |
| 2465 TEST_F(WebSocketChannelStreamTest, SentFramesAreMasked) { | 2519 TEST_F(WebSocketChannelStreamTest, SentFramesAreMasked) { |
| 2466 static const InitFrame expected[] = { | 2520 static const InitFrame expected[] = { |
| 2467 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, | 2521 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, |
| 2468 MASKED, "NEEDS MASKING"}}; | 2522 MASKED, "NEEDS MASKING"}}; |
| 2469 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); | 2523 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2483 static const InitFrame expected[] = { | 2537 static const InitFrame expected[] = { |
| 2484 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, | 2538 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
| 2485 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Success")}}; | 2539 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Success")}}; |
| 2486 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); | 2540 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| 2487 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); | 2541 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); |
| 2488 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); | 2542 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); |
| 2489 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) | 2543 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) |
| 2490 .WillOnce(Return(OK)); | 2544 .WillOnce(Return(OK)); |
| 2491 | 2545 |
| 2492 CreateChannelAndConnectSuccessfully(); | 2546 CreateChannelAndConnectSuccessfully(); |
| 2493 channel_->StartClosingHandshake(1000, "Success"); | 2547 ASSERT_EQ(CHANNEL_ALIVE, channel_->StartClosingHandshake(1000, "Success")); |
| 2494 channel_->SendFrame( | 2548 channel_->SendFrame( |
| 2495 true, WebSocketFrameHeader::kOpCodeText, AsVector("SHOULD BE IGNORED")); | 2549 true, WebSocketFrameHeader::kOpCodeText, AsVector("SHOULD BE IGNORED")); |
| 2496 } | 2550 } |
| 2497 | 2551 |
| 2498 // RFC6455 5.5.1 "If an endpoint receives a Close frame and did not previously | 2552 // RFC6455 5.5.1 "If an endpoint receives a Close frame and did not previously |
| 2499 // send a Close frame, the endpoint MUST send a Close frame in response." | 2553 // send a Close frame, the endpoint MUST send a Close frame in response." |
| 2500 TEST_F(WebSocketChannelStreamTest, CloseIsEchoedBack) { | 2554 TEST_F(WebSocketChannelStreamTest, CloseIsEchoedBack) { |
| 2501 static const InitFrame frames[] = { | 2555 static const InitFrame frames[] = { |
| 2502 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, | 2556 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
| 2503 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; | 2557 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2548 EXPECT_CALL(checkpoint, Call(2)); | 2602 EXPECT_CALL(checkpoint, Call(2)); |
| 2549 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) | 2603 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
| 2550 .WillOnce(Return(ERR_IO_PENDING)); | 2604 .WillOnce(Return(ERR_IO_PENDING)); |
| 2551 EXPECT_CALL(checkpoint, Call(3)); | 2605 EXPECT_CALL(checkpoint, Call(3)); |
| 2552 // WriteFrames() must not be called again. GoogleMock will ensure that the | 2606 // WriteFrames() must not be called again. GoogleMock will ensure that the |
| 2553 // test fails if it is. | 2607 // test fails if it is. |
| 2554 } | 2608 } |
| 2555 | 2609 |
| 2556 CreateChannelAndConnectSuccessfully(); | 2610 CreateChannelAndConnectSuccessfully(); |
| 2557 checkpoint.Call(1); | 2611 checkpoint.Call(1); |
| 2558 channel_->StartClosingHandshake(kWebSocketNormalClosure, "Close"); | 2612 ASSERT_EQ(CHANNEL_ALIVE, |
| 2613 channel_->StartClosingHandshake(kWebSocketNormalClosure, "Close")); |
| 2559 checkpoint.Call(2); | 2614 checkpoint.Call(2); |
| 2560 | 2615 |
| 2561 *frames = CreateFrameVector(frames_init); | 2616 *frames = CreateFrameVector(frames_init); |
| 2562 read_callback.Run(OK); | 2617 read_callback.Run(OK); |
| 2563 checkpoint.Call(3); | 2618 checkpoint.Call(3); |
| 2564 } | 2619 } |
| 2565 | 2620 |
| 2566 // Invalid close status codes should not be sent on the network. | 2621 // Invalid close status codes should not be sent on the network. |
| 2567 TEST_F(WebSocketChannelStreamTest, InvalidCloseStatusCodeNotSent) { | 2622 TEST_F(WebSocketChannelStreamTest, InvalidCloseStatusCodeNotSent) { |
| 2568 static const InitFrame expected[] = { | 2623 static const InitFrame expected[] = { |
| 2569 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, | 2624 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
| 2570 MASKED, CLOSE_DATA(SERVER_ERROR, "")}}; | 2625 MASKED, CLOSE_DATA(SERVER_ERROR, "")}}; |
| 2571 | 2626 |
| 2572 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); | 2627 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| 2573 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); | 2628 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); |
| 2574 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) | 2629 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
| 2575 .WillOnce(Return(ERR_IO_PENDING)); | 2630 .WillOnce(Return(ERR_IO_PENDING)); |
| 2576 | 2631 |
| 2577 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)); | 2632 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)); |
| 2578 | 2633 |
| 2579 CreateChannelAndConnectSuccessfully(); | 2634 CreateChannelAndConnectSuccessfully(); |
| 2580 channel_->StartClosingHandshake(999, ""); | 2635 ASSERT_EQ(CHANNEL_ALIVE, channel_->StartClosingHandshake(999, "")); |
| 2581 } | 2636 } |
| 2582 | 2637 |
| 2583 // A Close frame with a reason longer than 123 bytes cannot be sent on the | 2638 // A Close frame with a reason longer than 123 bytes cannot be sent on the |
| 2584 // network. | 2639 // network. |
| 2585 TEST_F(WebSocketChannelStreamTest, LongCloseReasonNotSent) { | 2640 TEST_F(WebSocketChannelStreamTest, LongCloseReasonNotSent) { |
| 2586 static const InitFrame expected[] = { | 2641 static const InitFrame expected[] = { |
| 2587 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, | 2642 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
| 2588 MASKED, CLOSE_DATA(SERVER_ERROR, "")}}; | 2643 MASKED, CLOSE_DATA(SERVER_ERROR, "")}}; |
| 2589 | 2644 |
| 2590 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); | 2645 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| 2591 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); | 2646 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); |
| 2592 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) | 2647 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
| 2593 .WillOnce(Return(ERR_IO_PENDING)); | 2648 .WillOnce(Return(ERR_IO_PENDING)); |
| 2594 | 2649 |
| 2595 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)); | 2650 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)); |
| 2596 | 2651 |
| 2597 CreateChannelAndConnectSuccessfully(); | 2652 CreateChannelAndConnectSuccessfully(); |
| 2598 channel_->StartClosingHandshake(1000, std::string(124, 'A')); | 2653 ASSERT_EQ(CHANNEL_ALIVE, |
| 2654 channel_->StartClosingHandshake(1000, std::string(124, 'A'))); |
| 2599 } | 2655 } |
| 2600 | 2656 |
| 2601 // We generate code 1005, kWebSocketErrorNoStatusReceived, when there is no | 2657 // We generate code 1005, kWebSocketErrorNoStatusReceived, when there is no |
| 2602 // status in the Close message from the other side. Code 1005 is not allowed to | 2658 // status in the Close message from the other side. Code 1005 is not allowed to |
| 2603 // appear on the wire, so we should not echo it back. See test | 2659 // appear on the wire, so we should not echo it back. See test |
| 2604 // CloseWithNoPayloadGivesStatus1005, above, for confirmation that code 1005 is | 2660 // CloseWithNoPayloadGivesStatus1005, above, for confirmation that code 1005 is |
| 2605 // correctly generated internally. | 2661 // correctly generated internally. |
| 2606 TEST_F(WebSocketChannelStreamTest, Code1005IsNotEchoed) { | 2662 TEST_F(WebSocketChannelStreamTest, Code1005IsNotEchoed) { |
| 2607 static const InitFrame frames[] = { | 2663 static const InitFrame frames[] = { |
| 2608 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, ""}}; | 2664 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, ""}}; |
| (...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3299 } | 3355 } |
| 3300 | 3356 |
| 3301 // Set the closing handshake timeout to a very tiny value before connecting. | 3357 // Set the closing handshake timeout to a very tiny value before connecting. |
| 3302 class WebSocketChannelStreamTimeoutTest : public WebSocketChannelStreamTest { | 3358 class WebSocketChannelStreamTimeoutTest : public WebSocketChannelStreamTest { |
| 3303 protected: | 3359 protected: |
| 3304 WebSocketChannelStreamTimeoutTest() {} | 3360 WebSocketChannelStreamTimeoutTest() {} |
| 3305 | 3361 |
| 3306 void CreateChannelAndConnectSuccessfully() override { | 3362 void CreateChannelAndConnectSuccessfully() override { |
| 3307 set_stream(std::move(mock_stream_)); | 3363 set_stream(std::move(mock_stream_)); |
| 3308 CreateChannelAndConnect(); | 3364 CreateChannelAndConnect(); |
| 3309 channel_->SendFlowControl(kPlentyOfQuota); | 3365 ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(kPlentyOfQuota)); |
| 3310 channel_->SetClosingHandshakeTimeoutForTesting( | 3366 channel_->SetClosingHandshakeTimeoutForTesting( |
| 3311 TimeDelta::FromMilliseconds(kVeryTinyTimeoutMillis)); | 3367 TimeDelta::FromMilliseconds(kVeryTinyTimeoutMillis)); |
| 3312 channel_->SetUnderlyingConnectionCloseTimeoutForTesting( | 3368 channel_->SetUnderlyingConnectionCloseTimeoutForTesting( |
| 3313 TimeDelta::FromMilliseconds(kVeryTinyTimeoutMillis)); | 3369 TimeDelta::FromMilliseconds(kVeryTinyTimeoutMillis)); |
| 3314 connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_)); | 3370 connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_)); |
| 3315 } | 3371 } |
| 3316 }; | 3372 }; |
| 3317 | 3373 |
| 3318 // In this case the server initiates the closing handshake with a Close | 3374 // In this case the server initiates the closing handshake with a Close |
| 3319 // message. WebSocketChannel responds with a matching Close message, and waits | 3375 // message. WebSocketChannel responds with a matching Close message, and waits |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3363 TestClosure completion; | 3419 TestClosure completion; |
| 3364 { | 3420 { |
| 3365 InSequence s; | 3421 InSequence s; |
| 3366 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) | 3422 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) |
| 3367 .WillOnce(Return(OK)); | 3423 .WillOnce(Return(OK)); |
| 3368 EXPECT_CALL(*mock_stream_, Close()) | 3424 EXPECT_CALL(*mock_stream_, Close()) |
| 3369 .WillOnce(InvokeClosure(completion.closure())); | 3425 .WillOnce(InvokeClosure(completion.closure())); |
| 3370 } | 3426 } |
| 3371 | 3427 |
| 3372 CreateChannelAndConnectSuccessfully(); | 3428 CreateChannelAndConnectSuccessfully(); |
| 3373 channel_->StartClosingHandshake(kWebSocketNormalClosure, "OK"); | 3429 ASSERT_EQ(CHANNEL_ALIVE, |
| 3430 channel_->StartClosingHandshake(kWebSocketNormalClosure, "OK")); |
| 3374 completion.WaitForResult(); | 3431 completion.WaitForResult(); |
| 3375 } | 3432 } |
| 3376 | 3433 |
| 3377 // In this case the client initiates the closing handshake and the server | 3434 // In this case the client initiates the closing handshake and the server |
| 3378 // responds with a matching Close message. WebSocketChannel waits for the server | 3435 // responds with a matching Close message. WebSocketChannel waits for the server |
| 3379 // to close the TCP/IP connection, but it never does. The closing handshake | 3436 // to close the TCP/IP connection, but it never does. The closing handshake |
| 3380 // times out and WebSocketChannel closes the connection. | 3437 // times out and WebSocketChannel closes the connection. |
| 3381 TEST_F(WebSocketChannelStreamTimeoutTest, ConnectionCloseTimesOut) { | 3438 TEST_F(WebSocketChannelStreamTimeoutTest, ConnectionCloseTimesOut) { |
| 3382 static const InitFrame expected[] = { | 3439 static const InitFrame expected[] = { |
| 3383 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, | 3440 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 3406 // point. ReadFrames is called again by WebSocketChannel, waiting for | 3463 // point. ReadFrames is called again by WebSocketChannel, waiting for |
| 3407 // ERR_CONNECTION_CLOSED. | 3464 // ERR_CONNECTION_CLOSED. |
| 3408 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) | 3465 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
| 3409 .WillOnce(Return(ERR_IO_PENDING)); | 3466 .WillOnce(Return(ERR_IO_PENDING)); |
| 3410 // The timeout happens and so WebSocketChannel closes the stream. | 3467 // The timeout happens and so WebSocketChannel closes the stream. |
| 3411 EXPECT_CALL(*mock_stream_, Close()) | 3468 EXPECT_CALL(*mock_stream_, Close()) |
| 3412 .WillOnce(InvokeClosure(completion.closure())); | 3469 .WillOnce(InvokeClosure(completion.closure())); |
| 3413 } | 3470 } |
| 3414 | 3471 |
| 3415 CreateChannelAndConnectSuccessfully(); | 3472 CreateChannelAndConnectSuccessfully(); |
| 3416 channel_->StartClosingHandshake(kWebSocketNormalClosure, "OK"); | 3473 ASSERT_EQ(CHANNEL_ALIVE, |
| 3474 channel_->StartClosingHandshake(kWebSocketNormalClosure, "OK")); |
| 3417 ASSERT_TRUE(read_frames); | 3475 ASSERT_TRUE(read_frames); |
| 3418 // Provide the "Close" message from the server. | 3476 // Provide the "Close" message from the server. |
| 3419 *read_frames = CreateFrameVector(frames); | 3477 *read_frames = CreateFrameVector(frames); |
| 3420 read_callback.Run(OK); | 3478 read_callback.Run(OK); |
| 3421 completion.WaitForResult(); | 3479 completion.WaitForResult(); |
| 3422 } | 3480 } |
| 3423 | 3481 |
| 3424 // Verify that current_send_quota() returns a non-zero value for a newly | 3482 // Verify that current_send_quota() returns a non-zero value for a newly |
| 3425 // connected channel. | 3483 // connected channel. |
| 3426 TEST_F(WebSocketChannelTest, CurrentSendQuotaNonZero) { | 3484 TEST_F(WebSocketChannelTest, CurrentSendQuotaNonZero) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3439 | 3497 |
| 3440 channel_->SendFrame( | 3498 channel_->SendFrame( |
| 3441 true, WebSocketFrameHeader::kOpCodeText, | 3499 true, WebSocketFrameHeader::kOpCodeText, |
| 3442 std::vector<char>(static_cast<size_t>(kMessageSize), 'a')); | 3500 std::vector<char>(static_cast<size_t>(kMessageSize), 'a')); |
| 3443 int new_send_quota = channel_->current_send_quota(); | 3501 int new_send_quota = channel_->current_send_quota(); |
| 3444 EXPECT_EQ(kMessageSize, initial_send_quota - new_send_quota); | 3502 EXPECT_EQ(kMessageSize, initial_send_quota - new_send_quota); |
| 3445 } | 3503 } |
| 3446 | 3504 |
| 3447 } // namespace | 3505 } // namespace |
| 3448 } // namespace net | 3506 } // namespace net |
| OLD | NEW |