Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2438)

Unified Diff: net/spdy/spdy_stream_unittest.cc

Issue 2832973003: Split net/spdy into core and chromium subdirectories. (Closed)
Patch Set: Fix some more build rules. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/spdy/spdy_stream_test_util.cc ('k') | net/spdy/spdy_test_util_common.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/spdy/spdy_stream_unittest.cc
diff --git a/net/spdy/spdy_stream_unittest.cc b/net/spdy/spdy_stream_unittest.cc
deleted file mode 100644
index 50b2a1bd65d3948947d2d1400c7f5dd38358d915..0000000000000000000000000000000000000000
--- a/net/spdy/spdy_stream_unittest.cc
+++ /dev/null
@@ -1,1560 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/spdy/spdy_stream.h"
-
-#include <stdint.h>
-
-#include <algorithm>
-#include <cstddef>
-#include <limits>
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "base/memory/ref_counted.h"
-#include "base/run_loop.h"
-#include "net/base/completion_callback.h"
-#include "net/base/request_priority.h"
-#include "net/log/net_log_event_type.h"
-#include "net/log/test_net_log.h"
-#include "net/log/test_net_log_entry.h"
-#include "net/log/test_net_log_util.h"
-#include "net/socket/socket_test_util.h"
-#include "net/spdy/buffered_spdy_framer.h"
-#include "net/spdy/platform/api/spdy_string_piece.h"
-#include "net/spdy/spdy_http_utils.h"
-#include "net/spdy/spdy_protocol.h"
-#include "net/spdy/spdy_session.h"
-#include "net/spdy/spdy_stream_test_util.h"
-#include "net/spdy/spdy_test_util_common.h"
-#include "net/test/cert_test_util.h"
-#include "net/test/gtest_util.h"
-#include "net/test/test_data_directory.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-// TODO(ukai): factor out common part with spdy_http_stream_unittest.cc
-//
-namespace net {
-
-namespace test {
-
-namespace {
-
-const char kPushUrl[] = "https://www.example.org/push";
-const char kPostBody[] = "\0hello!\xff";
-const size_t kPostBodyLength = arraysize(kPostBody);
-const SpdyStringPiece kPostBodyStringPiece(kPostBody, kPostBodyLength);
-
-static base::TimeTicks g_time_now;
-
-base::TimeTicks InstantaneousReads() {
- return g_time_now;
-}
-
-} // namespace
-
-class SpdyStreamTest : public ::testing::Test {
- protected:
- // A function that takes a SpdyStream and the number of bytes which
- // will unstall the next frame completely.
- typedef base::Callback<void(const base::WeakPtr<SpdyStream>&, int32_t)>
- UnstallFunction;
-
- SpdyStreamTest()
- : url_(kDefaultUrl),
- session_(SpdySessionDependencies::SpdyCreateSession(&session_deps_)),
- offset_(0),
- ssl_(SYNCHRONOUS, OK) {}
-
- ~SpdyStreamTest() override {}
-
- base::WeakPtr<SpdySession> CreateDefaultSpdySession() {
- SpdySessionKey key(HostPortPair::FromURL(url_), ProxyServer::Direct(),
- PRIVACY_MODE_DISABLED);
- return CreateSecureSpdySession(session_.get(), key, NetLogWithSource());
- }
-
- void TearDown() override { base::RunLoop().RunUntilIdle(); }
-
- void RunResumeAfterUnstallRequestResponseTest(
- const UnstallFunction& unstall_function);
-
- void RunResumeAfterUnstallBidirectionalTest(
- const UnstallFunction& unstall_function);
-
- // Add{Read,Write}() populates lists that are eventually passed to a
- // SocketData class. |frame| must live for the whole test.
-
- void AddRead(const SpdySerializedFrame& frame) {
- reads_.push_back(CreateMockRead(frame, offset_++));
- }
-
- void AddWrite(const SpdySerializedFrame& frame) {
- writes_.push_back(CreateMockWrite(frame, offset_++));
- }
-
- void AddReadEOF() {
- reads_.push_back(MockRead(ASYNC, 0, offset_++));
- }
-
- void AddWritePause() {
- writes_.push_back(MockWrite(ASYNC, ERR_IO_PENDING, offset_++));
- }
-
- void AddReadPause() {
- reads_.push_back(MockRead(ASYNC, ERR_IO_PENDING, offset_++));
- }
-
- MockRead* GetReads() { return reads_.data(); }
-
- size_t GetNumReads() const {
- return reads_.size();
- }
-
- MockWrite* GetWrites() { return writes_.data(); }
-
- int GetNumWrites() const {
- return writes_.size();
- }
-
- void ActivatePushStream(SpdySession* session, SpdyStream* stream) {
- std::unique_ptr<SpdyStream> activated =
- session->ActivateCreatedStream(stream);
- activated->set_stream_id(2);
- session->InsertActivatedStream(std::move(activated));
- }
-
- void AddSSLSocketData() {
- // Load a cert that is valid for
- // www.example.org, mail.example.org, and mail.example.com.
- ssl_.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
- ASSERT_TRUE(ssl_.cert);
- session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
- }
-
- const GURL url_;
- SpdyTestUtil spdy_util_;
- SpdySessionDependencies session_deps_;
- std::unique_ptr<HttpNetworkSession> session_;
-
- private:
- // Used by Add{Read,Write}() above.
- std::vector<MockWrite> writes_;
- std::vector<MockRead> reads_;
- int offset_;
- SSLSocketDataProvider ssl_;
-};
-
-TEST_F(SpdyStreamTest, SendDataAfterOpen) {
- SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
- kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
- AddWrite(req);
-
- SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
- AddRead(resp);
-
- SpdySerializedFrame msg(
- spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, false));
- AddWrite(msg);
-
- SpdySerializedFrame echo(
- spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, false));
- AddRead(echo);
-
- AddReadEOF();
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
- ASSERT_TRUE(stream);
-
- StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
- SpdyHeaderBlock headers(
- spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
- EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
- IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
-
- EXPECT_TRUE(delegate.send_headers_completed());
- EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy_util_.GetStatusKey()));
- EXPECT_EQ(SpdyString(kPostBody, kPostBodyLength),
- delegate.TakeReceivedData());
- EXPECT_TRUE(data.AllWriteDataConsumed());
-}
-
-// Delegate that receives trailers.
-class StreamDelegateWithTrailers : public test::StreamDelegateWithBody {
- public:
- StreamDelegateWithTrailers(const base::WeakPtr<SpdyStream>& stream,
- SpdyStringPiece data)
- : StreamDelegateWithBody(stream, data) {}
-
- ~StreamDelegateWithTrailers() override {}
-
- void OnTrailers(const SpdyHeaderBlock& trailers) override {
- trailers_ = trailers.Clone();
- }
-
- const SpdyHeaderBlock& trailers() const { return trailers_; }
-
- private:
- SpdyHeaderBlock trailers_;
-};
-
-// Regression test for https://crbug.com/481033.
-TEST_F(SpdyStreamTest, Trailers) {
- SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
- kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
- AddWrite(req);
-
- SpdySerializedFrame msg(
- spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, true));
- AddWrite(msg);
-
- SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
- AddRead(resp);
-
- SpdySerializedFrame echo(
- spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, false));
- AddRead(echo);
-
- SpdyHeaderBlock late_headers;
- late_headers["foo"] = "bar";
- SpdySerializedFrame trailers(spdy_util_.ConstructSpdyResponseHeaders(
- 1, std::move(late_headers), false));
- AddRead(trailers);
-
- AddReadEOF();
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
- ASSERT_TRUE(stream);
-
- StreamDelegateWithTrailers delegate(stream, kPostBodyStringPiece);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
- SpdyHeaderBlock headers(
- spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
- EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
- IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
-
- EXPECT_TRUE(delegate.send_headers_completed());
- EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy_util_.GetStatusKey()));
- const SpdyHeaderBlock& received_trailers = delegate.trailers();
- SpdyHeaderBlock::const_iterator it = received_trailers.find("foo");
- EXPECT_EQ("bar", it->second);
- EXPECT_EQ(SpdyString(kPostBody, kPostBodyLength),
- delegate.TakeReceivedData());
- EXPECT_TRUE(data.AllWriteDataConsumed());
-}
-
-TEST_F(SpdyStreamTest, PushedStream) {
- SpdySerializedFrame req(
- spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
- AddWrite(req);
-
- SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
- AddRead(reply);
-
- SpdySerializedFrame push(
- spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushUrl));
- AddRead(push);
-
- SpdySerializedFrame priority(
- spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
- AddWrite(priority);
-
- AddReadPause();
-
- SpdyStringPiece pushed_msg("foo");
- SpdySerializedFrame pushed_body(spdy_util_.ConstructSpdyDataFrame(
- 2, pushed_msg.data(), pushed_msg.size(), true));
- AddRead(pushed_body);
-
- SpdyStringPiece msg("bar");
- SpdySerializedFrame body(
- spdy_util_.ConstructSpdyDataFrame(1, msg.data(), msg.size(), true));
- AddRead(body);
-
- AddReadEOF();
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- g_time_now = base::TimeTicks::Now();
- session_deps_.time_func = InstantaneousReads;
- session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
- ASSERT_TRUE(stream);
-
- StreamDelegateDoNothing delegate(stream);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
- SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
- EXPECT_THAT(
- stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
- IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- data.RunUntilPaused();
-
- SpdyStream* push_stream;
- EXPECT_THAT(session->GetPushStream(GURL(kPushUrl), IDLE, &push_stream,
- NetLogWithSource()),
- IsOk());
- ASSERT_TRUE(push_stream);
- EXPECT_EQ(kPushUrl, push_stream->GetUrlFromHeaders().spec());
-
- LoadTimingInfo load_timing_info;
- EXPECT_TRUE(push_stream->GetLoadTimingInfo(&load_timing_info));
- EXPECT_EQ(g_time_now, load_timing_info.push_start);
- EXPECT_TRUE(load_timing_info.push_end.is_null());
-
- StreamDelegateDoNothing push_delegate(push_stream->GetWeakPtr());
- push_stream->SetDelegate(&push_delegate);
-
- data.Resume();
-
- EXPECT_TRUE(push_stream->GetLoadTimingInfo(&load_timing_info));
- EXPECT_EQ(g_time_now, load_timing_info.push_start);
- EXPECT_FALSE(load_timing_info.push_end.is_null());
-
- EXPECT_THAT(delegate.WaitForClose(), IsOk());
- EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy_util_.GetStatusKey()));
- EXPECT_EQ(msg, delegate.TakeReceivedData());
-
- EXPECT_THAT(push_delegate.WaitForClose(), IsOk());
- EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy_util_.GetStatusKey()));
- EXPECT_EQ(pushed_msg, push_delegate.TakeReceivedData());
-}
-
-TEST_F(SpdyStreamTest, StreamError) {
- SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
- kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
- AddWrite(req);
-
- SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
- AddRead(resp);
-
- SpdySerializedFrame msg(
- spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, false));
- AddWrite(msg);
-
- SpdySerializedFrame echo(
- spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, false));
- AddRead(echo);
-
- AddReadEOF();
-
- BoundTestNetLog log;
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, log.bound());
- ASSERT_TRUE(stream);
-
- StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
- SpdyHeaderBlock headers(
- spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
- EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
- IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
-
- const SpdyStreamId stream_id = delegate.stream_id();
-
- EXPECT_TRUE(delegate.send_headers_completed());
- EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy_util_.GetStatusKey()));
- EXPECT_EQ(SpdyString(kPostBody, kPostBodyLength),
- delegate.TakeReceivedData());
- EXPECT_TRUE(data.AllWriteDataConsumed());
-
- // Check that the NetLog was filled reasonably.
- TestNetLogEntry::List entries;
- log.GetEntries(&entries);
- EXPECT_LT(0u, entries.size());
-
- // Check that we logged SPDY_STREAM_ERROR correctly.
- int pos = ExpectLogContainsSomewhere(
- entries, 0, NetLogEventType::HTTP2_STREAM_ERROR, NetLogEventPhase::NONE);
-
- int stream_id2;
- ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &stream_id2));
- EXPECT_EQ(static_cast<int>(stream_id), stream_id2);
-}
-
-// Make sure that large blocks of data are properly split up into frame-sized
-// chunks for a request/response (i.e., an HTTP-like) stream.
-TEST_F(SpdyStreamTest, SendLargeDataAfterOpenRequestResponse) {
- SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
- kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
- AddWrite(req);
-
- SpdyString chunk_data(kMaxSpdyFrameChunkSize, 'x');
- SpdySerializedFrame chunk(spdy_util_.ConstructSpdyDataFrame(
- 1, chunk_data.data(), chunk_data.length(), false));
- AddWrite(chunk);
- AddWrite(chunk);
-
- SpdySerializedFrame last_chunk(spdy_util_.ConstructSpdyDataFrame(
- 1, chunk_data.data(), chunk_data.length(), true));
- AddWrite(last_chunk);
-
- SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
- AddRead(resp);
-
- AddReadEOF();
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
- ASSERT_TRUE(stream);
-
- SpdyString body_data(3 * kMaxSpdyFrameChunkSize, 'x');
- StreamDelegateWithBody delegate(stream, body_data);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
- SpdyHeaderBlock headers(
- spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
- EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
- IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
-
- EXPECT_TRUE(delegate.send_headers_completed());
- EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy_util_.GetStatusKey()));
- EXPECT_EQ(SpdyString(), delegate.TakeReceivedData());
- EXPECT_TRUE(data.AllWriteDataConsumed());
-}
-
-// Make sure that large blocks of data are properly split up into frame-sized
-// chunks for a bidirectional (i.e., non-HTTP-like) stream.
-TEST_F(SpdyStreamTest, SendLargeDataAfterOpenBidirectional) {
- SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
- kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
- AddWrite(req);
-
- SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
- AddRead(resp);
-
- SpdyString chunk_data(kMaxSpdyFrameChunkSize, 'x');
- SpdySerializedFrame chunk(spdy_util_.ConstructSpdyDataFrame(
- 1, chunk_data.data(), chunk_data.length(), false));
- AddWrite(chunk);
- AddWrite(chunk);
- AddWrite(chunk);
-
- AddReadEOF();
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
- ASSERT_TRUE(stream);
-
- SpdyString body_data(3 * kMaxSpdyFrameChunkSize, 'x');
- StreamDelegateSendImmediate delegate(stream, body_data);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
- SpdyHeaderBlock headers(
- spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
- EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
- IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
-
- EXPECT_TRUE(delegate.send_headers_completed());
- EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy_util_.GetStatusKey()));
- EXPECT_EQ(SpdyString(), delegate.TakeReceivedData());
- EXPECT_TRUE(data.AllWriteDataConsumed());
-}
-
-// Receiving a header with uppercase ASCII should result in a protocol error.
-TEST_F(SpdyStreamTest, UpperCaseHeaders) {
- SpdySerializedFrame req(
- spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
- AddWrite(req);
-
- const char* const kExtraHeaders[] = {"X-UpperCase", "yes"};
- SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(
- kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
- AddRead(reply);
-
- SpdySerializedFrame rst(
- spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_PROTOCOL_ERROR));
- AddWrite(rst);
-
- AddReadEOF();
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
- ASSERT_TRUE(stream);
-
- StreamDelegateDoNothing delegate(stream);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
- SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
- EXPECT_THAT(
- stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
- IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
-
- // Finish async network reads and writes.
- base::RunLoop().RunUntilIdle();
-
- EXPECT_TRUE(data.AllWriteDataConsumed());
- EXPECT_TRUE(data.AllReadDataConsumed());
-}
-
-// Receiving a header with uppercase ASCII should result in a protocol error
-// even for a push stream.
-TEST_F(SpdyStreamTest, UpperCaseHeadersOnPush) {
- SpdySerializedFrame req(
- spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
- AddWrite(req);
-
- SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
- AddRead(reply);
-
- const char* const kExtraHeaders[] = {"X-UpperCase", "yes"};
- SpdySerializedFrame push(spdy_util_.ConstructSpdyPush(
- kExtraHeaders, arraysize(kExtraHeaders) / 2, 2, 1, kPushUrl));
- AddRead(push);
-
- SpdySerializedFrame priority(
- spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
- AddWrite(priority);
-
- SpdySerializedFrame rst(
- spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_PROTOCOL_ERROR));
- AddWrite(rst);
-
- AddReadPause();
-
- AddReadEOF();
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
- ASSERT_TRUE(stream);
-
- StreamDelegateDoNothing delegate(stream);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
- SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
- EXPECT_THAT(
- stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
- IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- data.RunUntilPaused();
-
- SpdyStream* push_stream;
- EXPECT_THAT(session->GetPushStream(GURL(kPushUrl), IDLE, &push_stream,
- NetLogWithSource()),
- IsOk());
- EXPECT_FALSE(push_stream);
-
- data.Resume();
-
- EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
-
- EXPECT_TRUE(data.AllWriteDataConsumed());
- EXPECT_TRUE(data.AllReadDataConsumed());
-}
-
-TEST_F(SpdyStreamTest, HeadersMustHaveStatus) {
- SpdySerializedFrame req(
- spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
- AddWrite(req);
-
- // Response headers without ":status" header field: protocol error.
- SpdyHeaderBlock header_block_without_status;
- header_block_without_status[spdy_util_.GetMethodKey()] = "GET";
- header_block_without_status[spdy_util_.GetHostKey()] = "www.example.org";
- header_block_without_status[spdy_util_.GetSchemeKey()] = "https";
- header_block_without_status[spdy_util_.GetPathKey()] = "/";
- SpdySerializedFrame reply(
- spdy_util_.ConstructSpdyReply(1, std::move(header_block_without_status)));
- AddRead(reply);
-
- SpdySerializedFrame rst(
- spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_PROTOCOL_ERROR));
- AddWrite(rst);
-
- AddReadEOF();
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
- ASSERT_TRUE(stream);
-
- StreamDelegateDoNothing delegate(stream);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
- SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
- EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
- NO_MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
-
- // Finish async network reads and writes.
- base::RunLoop().RunUntilIdle();
-
- EXPECT_TRUE(data.AllWriteDataConsumed());
- EXPECT_TRUE(data.AllReadDataConsumed());
-}
-
-TEST_F(SpdyStreamTest, HeadersMustHaveStatusOnPushedStream) {
- SpdySerializedFrame req(
- spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
- AddWrite(req);
-
- SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
- AddRead(reply);
-
- SpdySerializedFrame push_promise(spdy_util_.ConstructInitialSpdyPushFrame(
- spdy_util_.ConstructGetHeaderBlock(kPushUrl), 2, 1));
- AddRead(push_promise);
-
- SpdySerializedFrame priority(
- spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
- AddWrite(priority);
-
- // Response headers without ":status" header field: protocol error.
- SpdyHeaderBlock header_block_without_status;
- header_block_without_status[spdy_util_.GetMethodKey()] = "GET";
- header_block_without_status[spdy_util_.GetHostKey()] = "www.example.org";
- header_block_without_status[spdy_util_.GetSchemeKey()] = "https";
- header_block_without_status[spdy_util_.GetPathKey()] = "/";
- SpdySerializedFrame pushed_reply(
- spdy_util_.ConstructSpdyReply(2, std::move(header_block_without_status)));
- AddRead(pushed_reply);
-
- SpdySerializedFrame rst(
- spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_PROTOCOL_ERROR));
- AddWrite(rst);
-
- SpdySerializedFrame body(
- spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, true));
- AddRead(body);
-
- AddReadEOF();
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
- ASSERT_TRUE(stream);
-
- StreamDelegateDoNothing delegate(stream);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
- SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
- EXPECT_THAT(
- stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
- IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- EXPECT_THAT(delegate.WaitForClose(), IsOk());
- EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy_util_.GetStatusKey()));
- EXPECT_EQ(SpdyString(kPostBody, kPostBodyLength),
- delegate.TakeReceivedData());
-
- // Finish async network reads and writes.
- base::RunLoop().RunUntilIdle();
-
- EXPECT_TRUE(data.AllWriteDataConsumed());
- EXPECT_TRUE(data.AllReadDataConsumed());
-}
-
-TEST_F(SpdyStreamTest, HeadersMustPreceedData) {
- SpdySerializedFrame req(
- spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
- AddWrite(req);
-
- // Response body not preceeded by headers: protocol error.
- SpdySerializedFrame body(
- spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, true));
- AddRead(body);
-
- SpdySerializedFrame rst(
- spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_PROTOCOL_ERROR));
- AddWrite(rst);
-
- AddReadEOF();
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
- ASSERT_TRUE(stream);
-
- StreamDelegateDoNothing delegate(stream);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
- SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
- EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
- NO_MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
-}
-
-TEST_F(SpdyStreamTest, HeadersMustPreceedDataOnPushedStream) {
- SpdySerializedFrame req(
- spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
- AddWrite(req);
-
- SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
- AddRead(reply);
-
- SpdySerializedFrame push_promise(spdy_util_.ConstructInitialSpdyPushFrame(
- spdy_util_.ConstructGetHeaderBlock(kPushUrl), 2, 1));
- AddRead(push_promise);
-
- SpdySerializedFrame priority(
- spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
- AddWrite(priority);
-
- SpdySerializedFrame pushed_body(
- spdy_util_.ConstructSpdyDataFrame(2, kPostBody, kPostBodyLength, true));
- AddRead(pushed_body);
-
- SpdySerializedFrame rst(
- spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_PROTOCOL_ERROR));
- AddWrite(rst);
-
- SpdySerializedFrame body(
- spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, true));
- AddRead(body);
-
- AddReadEOF();
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
- ASSERT_TRUE(stream);
-
- StreamDelegateDoNothing delegate(stream);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
- SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
- EXPECT_THAT(
- stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
- IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- EXPECT_THAT(delegate.WaitForClose(), IsOk());
- EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy_util_.GetStatusKey()));
- EXPECT_EQ(SpdyString(kPostBody, kPostBodyLength),
- delegate.TakeReceivedData());
-
- // Finish async network reads and writes.
- base::RunLoop().RunUntilIdle();
-
- EXPECT_TRUE(data.AllWriteDataConsumed());
- EXPECT_TRUE(data.AllReadDataConsumed());
-}
-
-TEST_F(SpdyStreamTest, TrailersMustNotFollowTrailers) {
- SpdySerializedFrame req(
- spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
- AddWrite(req);
-
- SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
- AddRead(reply);
-
- SpdySerializedFrame body(
- spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, false));
- AddRead(body);
-
- SpdyHeaderBlock trailers_block;
- trailers_block["foo"] = "bar";
- SpdySerializedFrame first_trailers(spdy_util_.ConstructSpdyResponseHeaders(
- 1, std::move(trailers_block), false));
- AddRead(first_trailers);
-
- // Trailers following trailers: procotol error.
- SpdySerializedFrame second_trailers(spdy_util_.ConstructSpdyResponseHeaders(
- 1, std::move(trailers_block), true));
- AddRead(second_trailers);
-
- SpdySerializedFrame rst(
- spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_PROTOCOL_ERROR));
- AddWrite(rst);
-
- AddReadEOF();
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
- ASSERT_TRUE(stream);
-
- StreamDelegateDoNothing delegate(stream);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
- SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
- EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
- NO_MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
-
- // Finish async network reads and writes.
- base::RunLoop().RunUntilIdle();
-
- EXPECT_TRUE(data.AllWriteDataConsumed());
- EXPECT_TRUE(data.AllReadDataConsumed());
-}
-
-TEST_F(SpdyStreamTest, DataMustNotFollowTrailers) {
- SpdySerializedFrame req(
- spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
- AddWrite(req);
-
- SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
- AddRead(reply);
-
- SpdySerializedFrame body(
- spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, false));
- AddRead(body);
-
- SpdyHeaderBlock trailers_block;
- trailers_block["foo"] = "bar";
- SpdySerializedFrame trailers(spdy_util_.ConstructSpdyResponseHeaders(
- 1, std::move(trailers_block), false));
- AddRead(trailers);
-
- // DATA frame following trailers: protocol error.
- AddRead(body);
-
- SpdySerializedFrame rst(
- spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_PROTOCOL_ERROR));
- AddWrite(rst);
-
- AddReadEOF();
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
- ASSERT_TRUE(stream);
-
- StreamDelegateDoNothing delegate(stream);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
- SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
- EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
- NO_MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
-
- // Finish async network reads and writes.
- base::RunLoop().RunUntilIdle();
-
- EXPECT_TRUE(data.AllWriteDataConsumed());
- EXPECT_TRUE(data.AllReadDataConsumed());
-}
-
-TEST_F(SpdyStreamTest, InformationalHeaders) {
- SpdySerializedFrame req(
- spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
- AddWrite(req);
-
- SpdyHeaderBlock informational_headers;
- informational_headers[":status"] = "100";
- SpdySerializedFrame informational_response(
- spdy_util_.ConstructSpdyResponseHeaders(
- 1, std::move(informational_headers), false));
- AddRead(informational_response);
-
- SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
- AddRead(reply);
-
- SpdySerializedFrame body(
- spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, true));
- AddRead(body);
-
- AddReadEOF();
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
- ASSERT_TRUE(stream);
-
- StreamDelegateDoNothing delegate(stream);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
- SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
- EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
- NO_MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- EXPECT_THAT(delegate.WaitForClose(), IsOk());
- EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy_util_.GetStatusKey()));
- EXPECT_EQ(SpdyString(kPostBody, kPostBodyLength),
- delegate.TakeReceivedData());
-
- // Finish async network reads and writes.
- base::RunLoop().RunUntilIdle();
-
- EXPECT_TRUE(data.AllWriteDataConsumed());
- EXPECT_TRUE(data.AllReadDataConsumed());
-}
-
-TEST_F(SpdyStreamTest, StatusMustBeNumber) {
- SpdySerializedFrame req(
- spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
- AddWrite(req);
-
- SpdyHeaderBlock incorrect_headers;
- incorrect_headers[":status"] = "nan";
- SpdySerializedFrame reply(spdy_util_.ConstructSpdyResponseHeaders(
- 1, std::move(incorrect_headers), false));
- AddRead(reply);
-
- SpdySerializedFrame rst(
- spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_PROTOCOL_ERROR));
- AddWrite(rst);
-
- AddReadEOF();
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
- ASSERT_TRUE(stream);
-
- StreamDelegateDoNothing delegate(stream);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
- SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
- EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
- NO_MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
-
- // Finish async network reads and writes.
- base::RunLoop().RunUntilIdle();
-
- EXPECT_TRUE(data.AllWriteDataConsumed());
- EXPECT_TRUE(data.AllReadDataConsumed());
-}
-
-TEST_F(SpdyStreamTest, StatusCannotHaveExtraText) {
- SpdySerializedFrame req(
- spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
- AddWrite(req);
-
- SpdyHeaderBlock headers_with_status_text;
- headers_with_status_text[":status"] =
- "200 Some random extra text describing status";
- SpdySerializedFrame reply(spdy_util_.ConstructSpdyResponseHeaders(
- 1, std::move(headers_with_status_text), false));
- AddRead(reply);
-
- SpdySerializedFrame body(
- spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, true));
- AddRead(body);
-
- SpdySerializedFrame rst(
- spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_PROTOCOL_ERROR));
- AddWrite(rst);
-
- AddReadEOF();
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
- ASSERT_TRUE(stream);
-
- StreamDelegateDoNothing delegate(stream);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
- SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
- EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
- NO_MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
-
- // Finish async network reads and writes.
- base::RunLoop().RunUntilIdle();
-
- EXPECT_TRUE(data.AllWriteDataConsumed());
- EXPECT_TRUE(data.AllReadDataConsumed());
-}
-
-TEST_F(SpdyStreamTest, StatusMustBePresent) {
- SpdySerializedFrame req(
- spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
- AddWrite(req);
-
- SpdyHeaderBlock headers_without_status;
- SpdySerializedFrame reply(spdy_util_.ConstructSpdyResponseHeaders(
- 1, std::move(headers_without_status), false));
- AddRead(reply);
-
- SpdySerializedFrame body(
- spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, true));
- AddRead(body);
-
- SpdySerializedFrame rst(
- spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_PROTOCOL_ERROR));
- AddWrite(rst);
-
- AddReadEOF();
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
- ASSERT_TRUE(stream);
-
- StreamDelegateDoNothing delegate(stream);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
- SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
- EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
- NO_MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
-
- // Finish async network reads and writes.
- base::RunLoop().RunUntilIdle();
-
- EXPECT_TRUE(data.AllWriteDataConsumed());
- EXPECT_TRUE(data.AllReadDataConsumed());
-}
-
-// Call IncreaseSendWindowSize on a stream with a large enough delta to overflow
-// an int32_t. The SpdyStream should handle that case gracefully.
-TEST_F(SpdyStreamTest, IncreaseSendWindowSizeOverflow) {
- SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
- kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
- AddWrite(req);
-
- AddReadPause();
-
- // Triggered by the overflowing call to IncreaseSendWindowSize
- // below.
- SpdySerializedFrame rst(
- spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_FLOW_CONTROL_ERROR));
- AddWrite(rst);
-
- AddReadEOF();
-
- BoundTestNetLog log;
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, log.bound());
- ASSERT_TRUE(stream);
- StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
- stream->SetDelegate(&delegate);
-
- SpdyHeaderBlock headers(
- spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
- EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
- IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- data.RunUntilPaused();
-
- int32_t old_send_window_size = stream->send_window_size();
- ASSERT_GT(old_send_window_size, 0);
- int32_t delta_window_size =
- std::numeric_limits<int32_t>::max() - old_send_window_size + 1;
- stream->IncreaseSendWindowSize(delta_window_size);
- EXPECT_FALSE(stream);
-
- data.Resume();
- base::RunLoop().RunUntilIdle();
-
- EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
-}
-
-// Functions used with
-// RunResumeAfterUnstall{RequestResponse,Bidirectional}Test().
-
-void StallStream(const base::WeakPtr<SpdyStream>& stream) {
- // Reduce the send window size to 0 to stall.
- while (stream->send_window_size() > 0) {
- stream->DecreaseSendWindowSize(
- std::min(kMaxSpdyFrameChunkSize, stream->send_window_size()));
- }
-}
-
-void IncreaseStreamSendWindowSize(const base::WeakPtr<SpdyStream>& stream,
- int32_t delta_window_size) {
- EXPECT_TRUE(stream->send_stalled_by_flow_control());
- stream->IncreaseSendWindowSize(delta_window_size);
- EXPECT_FALSE(stream->send_stalled_by_flow_control());
-}
-
-void AdjustStreamSendWindowSize(const base::WeakPtr<SpdyStream>& stream,
- int32_t delta_window_size) {
- // Make sure that negative adjustments are handled properly.
- EXPECT_TRUE(stream->send_stalled_by_flow_control());
- stream->AdjustSendWindowSize(-delta_window_size);
- EXPECT_TRUE(stream->send_stalled_by_flow_control());
- stream->AdjustSendWindowSize(+delta_window_size);
- EXPECT_TRUE(stream->send_stalled_by_flow_control());
- stream->AdjustSendWindowSize(+delta_window_size);
- EXPECT_FALSE(stream->send_stalled_by_flow_control());
-}
-
-// Given an unstall function, runs a test to make sure that a
-// request/response (i.e., an HTTP-like) stream resumes after a stall
-// and unstall.
-void SpdyStreamTest::RunResumeAfterUnstallRequestResponseTest(
- const UnstallFunction& unstall_function) {
- SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
- kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
- AddWrite(req);
-
- SpdySerializedFrame body(
- spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, true));
- AddWrite(body);
-
- SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
- AddRead(resp);
-
- AddReadEOF();
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
- ASSERT_TRUE(stream);
-
- StreamDelegateWithBody delegate(stream, kPostBodyStringPiece);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
- EXPECT_FALSE(stream->send_stalled_by_flow_control());
-
- SpdyHeaderBlock headers(
- spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
- EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
- IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- StallStream(stream);
-
- base::RunLoop().RunUntilIdle();
-
- EXPECT_TRUE(stream->send_stalled_by_flow_control());
-
- unstall_function.Run(stream, kPostBodyLength);
-
- EXPECT_FALSE(stream->send_stalled_by_flow_control());
-
- EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
-
- EXPECT_TRUE(delegate.send_headers_completed());
- EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status"));
- EXPECT_EQ(SpdyString(), delegate.TakeReceivedData());
- EXPECT_TRUE(data.AllWriteDataConsumed());
-}
-
-TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeIncreaseRequestResponse) {
- RunResumeAfterUnstallRequestResponseTest(
- base::Bind(&IncreaseStreamSendWindowSize));
-}
-
-TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeAdjustRequestResponse) {
- RunResumeAfterUnstallRequestResponseTest(
- base::Bind(&AdjustStreamSendWindowSize));
-}
-
-// Given an unstall function, runs a test to make sure that a bidirectional
-// (i.e., non-HTTP-like) stream resumes after a stall and unstall.
-void SpdyStreamTest::RunResumeAfterUnstallBidirectionalTest(
- const UnstallFunction& unstall_function) {
- SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
- kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
- AddWrite(req);
-
- AddReadPause();
-
- SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
- AddRead(resp);
-
- SpdySerializedFrame msg(
- spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, false));
- AddWrite(msg);
-
- SpdySerializedFrame echo(
- spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, false));
- AddRead(echo);
-
- AddReadEOF();
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
- ASSERT_TRUE(stream);
-
- StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
- SpdyHeaderBlock headers(
- spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
- EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
- IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- data.RunUntilPaused();
-
- EXPECT_FALSE(stream->send_stalled_by_flow_control());
-
- StallStream(stream);
-
- data.Resume();
- base::RunLoop().RunUntilIdle();
-
- EXPECT_TRUE(stream->send_stalled_by_flow_control());
-
- unstall_function.Run(stream, kPostBodyLength);
-
- EXPECT_FALSE(stream->send_stalled_by_flow_control());
-
- EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
-
- EXPECT_TRUE(delegate.send_headers_completed());
- EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status"));
- EXPECT_EQ(SpdyString(kPostBody, kPostBodyLength),
- delegate.TakeReceivedData());
- EXPECT_TRUE(data.AllWriteDataConsumed());
-}
-
-TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeIncreaseBidirectional) {
- RunResumeAfterUnstallBidirectionalTest(
- base::Bind(&IncreaseStreamSendWindowSize));
-}
-
-TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeAdjustBidirectional) {
- RunResumeAfterUnstallBidirectionalTest(
- base::Bind(&AdjustStreamSendWindowSize));
-}
-
-// Test calculation of amount of bytes received from network.
-TEST_F(SpdyStreamTest, ReceivedBytes) {
- SpdySerializedFrame req(
- spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
- AddWrite(req);
-
- AddReadPause();
-
- SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
- AddRead(reply);
-
- AddReadPause();
-
- SpdySerializedFrame msg(
- spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, false));
- AddRead(msg);
-
- AddReadPause();
-
- AddReadEOF();
-
- SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- AddSSLSocketData();
-
- base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
-
- base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
- SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
- ASSERT_TRUE(stream);
-
- StreamDelegateDoNothing delegate(stream);
- stream->SetDelegate(&delegate);
-
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
- SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
- EXPECT_THAT(
- stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
- IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
-
- int64_t reply_frame_len = reply.size();
- int64_t data_header_len = kDataFrameMinimumSize;
- int64_t data_frame_len = data_header_len + kPostBodyLength;
- int64_t response_len = reply_frame_len + data_frame_len;
-
- EXPECT_EQ(0, stream->raw_received_bytes());
-
- // REQUEST
- data.RunUntilPaused();
- EXPECT_EQ(0, stream->raw_received_bytes());
-
- // REPLY
- data.Resume();
- data.RunUntilPaused();
- EXPECT_EQ(reply_frame_len, stream->raw_received_bytes());
-
- // DATA
- data.Resume();
- data.RunUntilPaused();
- EXPECT_EQ(response_len, stream->raw_received_bytes());
-
- // FIN
- data.Resume();
- EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
-}
-
-} // namespace test
-
-} // namespace net
« no previous file with comments | « net/spdy/spdy_stream_test_util.cc ('k') | net/spdy/spdy_test_util_common.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698