Commit 1031e329 authored by Adam Rice's avatar Adam Rice Committed by Commit Bot

WebSocket over HTTP/2 clean close fix

If an HTTP/2 WebSocket server closed a stream with no error there it
would trigger a DCHECK in WebSocketSpdyStreamAdapter::OnClose, due to an
assumption that this method would not be called with an OK status.

Accept the OK status and translate it into an ERR_CONNECTION_CLOSED.

Also add a unit test for this condition.

BUG=1139140

Change-Id: Iaa25ba45606f388d15b377154a6d2273d006fb01
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2489104
Commit-Queue: Adam Rice <ricea@chromium.org>
Reviewed-by: default avatarBence Béky <bnc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#819714}
parent c0346dd0
......@@ -154,7 +154,12 @@ void WebSocketSpdyStreamAdapter::OnTrailers(
const spdy::SpdyHeaderBlock& trailers) {}
void WebSocketSpdyStreamAdapter::OnClose(int status) {
DCHECK_GT(ERR_IO_PENDING, status);
DCHECK_NE(ERR_IO_PENDING, status);
DCHECK_LE(status, 0);
if (status == OK) {
status = ERR_CONNECTION_CLOSED;
}
stream_error_ = status;
stream_ = nullptr;
......
......@@ -963,6 +963,44 @@ TEST_F(WebSocketSpdyStreamAdapterTest, WriteCallbackDestroysAdapter) {
EXPECT_TRUE(data.AllWriteDataConsumed());
}
TEST_F(WebSocketSpdyStreamAdapterTest,
OnCloseOkShouldBeTranslatedToConnectionClose) {
spdy::SpdySerializedFrame response_headers(
spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
spdy::SpdySerializedFrame close(
spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_NO_ERROR));
MockRead reads[] = {CreateMockRead(response_headers, 1),
CreateMockRead(close, 2), MockRead(ASYNC, 0, 3)};
spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
1, RequestHeaders(), DEFAULT_PRIORITY, false));
MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
SequencedSocketData data(reads, writes);
AddSocketData(&data);
AddSSLSocketData();
EXPECT_CALL(mock_delegate_, OnHeadersSent());
EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
base::WeakPtr<SpdySession> session = CreateSpdySession();
base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_,
NetLogWithSource());
EXPECT_TRUE(adapter.is_initialized());
EXPECT_CALL(mock_delegate_, OnClose(ERR_CONNECTION_CLOSED));
int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
const int kReadBufSize = 1024;
auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
TestCompletionCallback callback;
rv = adapter.Read(read_buf.get(), kReadBufSize, callback.callback());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rv = callback.WaitForResult();
ASSERT_EQ(ERR_CONNECTION_CLOSED, rv);
}
} // namespace test
} // namespace net
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment