blob: e58cd0b8ee5ab7307574a5532ddd3241bf3d112e [file] [log] [blame]
[email protected]3d587372013-06-01 04:31:451// Copyright 2013 The Chromium Authors. All rights reserved.
[email protected]4f386422010-07-20 04:19:492// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Bence Béky94658bf2018-05-11 19:22:585#include "net/spdy/spdy_stream.h"
avid0181f32015-12-10 19:41:476
dchengc7eeda422015-12-26 03:56:487#include <stdint.h>
danakjaee3e1ec2016-04-16 00:23:188
diannahu46ab1812016-12-26 21:27:079#include <algorithm>
[email protected]3d587372013-06-01 04:31:4510#include <cstddef>
avid0181f32015-12-10 19:41:4711#include <limits>
danakjaee3e1ec2016-04-16 00:23:1812#include <memory>
Bence Béky4e83f492018-05-13 23:14:2513#include <string>
dchengc7eeda422015-12-26 03:56:4814#include <utility>
[email protected]3d587372013-06-01 04:31:4515#include <vector>
16
[email protected]3b63f8f42011-03-28 01:54:1517#include "base/memory/ref_counted.h"
mmenkee24011922015-12-17 22:12:5918#include "base/run_loop.h"
Bence Béky4e83f492018-05-13 23:14:2519#include "base/strings/string_piece.h"
[email protected]1bbabc82013-03-25 21:11:0220#include "net/base/request_priority.h"
Bence Béky5b1e4ce72018-01-11 14:55:1521#include "net/http/http_request_info.h"
mikecirone8b85c432016-09-08 19:11:0022#include "net/log/net_log_event_type.h"
mmenke16a7cbdd2015-04-24 23:00:5623#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4624#include "net/log/test_net_log_entry.h"
25#include "net/log/test_net_log_util.h"
Paul Jensena457017a2018-01-19 23:52:0426#include "net/socket/socket_tag.h"
[email protected]6fe2e992013-06-12 03:38:4327#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5828#include "net/spdy/buffered_spdy_framer.h"
29#include "net/spdy/http2_push_promise_index.h"
30#include "net/spdy/spdy_http_utils.h"
31#include "net/spdy/spdy_session.h"
32#include "net/spdy/spdy_session_pool.h"
33#include "net/spdy/spdy_stream_test_util.h"
34#include "net/spdy/spdy_test_util_common.h"
bnc032658ba2016-09-26 18:17:1535#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0136#include "net/test/gtest_util.h"
bnc032658ba2016-09-26 18:17:1537#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0138#include "net/test/test_with_scoped_task_environment.h"
Ryan Hamilton2e003eea2018-05-02 00:24:2939#include "net/third_party/spdy/core/spdy_protocol.h"
robpercival214763f2016-07-01 23:27:0140#include "testing/gmock/include/gmock/gmock.h"
[email protected]4f386422010-07-20 04:19:4941#include "testing/gtest/include/gtest/gtest.h"
42
[email protected]4f386422010-07-20 04:19:4943// TODO(ukai): factor out common part with spdy_http_stream_unittest.cc
[email protected]b9ec6882011-07-01 07:40:2644//
45namespace net {
[email protected]4f386422010-07-20 04:19:4946
[email protected]34a4dea2013-03-13 00:42:3047namespace test {
48
[email protected]4f386422010-07-20 04:19:4949namespace {
50
bnca2fbdc9b2016-11-22 21:14:2651const char kPushUrl[] = "https://www.example.org/push";
[email protected]cbdd73162013-03-18 23:27:3352const char kPostBody[] = "\0hello!\xff";
53const size_t kPostBodyLength = arraysize(kPostBody);
Bence Béky4e83f492018-05-13 23:14:2554const base::StringPiece kPostBodyStringPiece(kPostBody, kPostBodyLength);
[email protected]39d13d942012-07-19 16:48:2055
bnca2fbdc9b2016-11-22 21:14:2656static base::TimeTicks g_time_now;
57
58base::TimeTicks InstantaneousReads() {
59 return g_time_now;
60}
61
rdsmithebb50aa2015-11-12 03:44:3862} // namespace
63
Bence Béky98447b12018-05-08 03:14:0164class SpdyStreamTest : public TestWithScopedTaskEnvironment {
[email protected]4f386422010-07-20 04:19:4965 protected:
[email protected]d2de7da2013-05-22 07:49:5666 // A function that takes a SpdyStream and the number of bytes which
67 // will unstall the next frame completely.
avid0181f32015-12-10 19:41:4768 typedef base::Callback<void(const base::WeakPtr<SpdyStream>&, int32_t)>
[email protected]d2de7da2013-05-22 07:49:5669 UnstallFunction;
70
bnca2fbdc9b2016-11-22 21:14:2671 SpdyStreamTest()
72 : url_(kDefaultUrl),
73 session_(SpdySessionDependencies::SpdyCreateSession(&session_deps_)),
74 offset_(0),
75 ssl_(SYNCHRONOUS, OK) {}
rdsmithebb50aa2015-11-12 03:44:3876
Chris Watkins61914cb2017-12-01 19:59:0077 ~SpdyStreamTest() override = default;
[email protected]4f386422010-07-20 04:19:4978
[email protected]795cbf82013-07-22 09:37:2779 base::WeakPtr<SpdySession> CreateDefaultSpdySession() {
bnca2fbdc9b2016-11-22 21:14:2680 SpdySessionKey key(HostPortPair::FromURL(url_), ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1181 PRIVACY_MODE_DISABLED,
82 SpdySessionKey::IsProxySession::kFalse, SocketTag());
Bence Béky0ef1556e2017-06-30 19:52:5283 return CreateSpdySession(session_.get(), key, NetLogWithSource());
[email protected]34a4dea2013-03-13 00:42:3084 }
85
fdoray92e35a72016-06-10 15:54:5586 void TearDown() override { base::RunLoop().RunUntilIdle(); }
[email protected]4f386422010-07-20 04:19:4987
[email protected]d2de7da2013-05-22 07:49:5688 void RunResumeAfterUnstallRequestResponseTest(
89 const UnstallFunction& unstall_function);
90
91 void RunResumeAfterUnstallBidirectionalTest(
92 const UnstallFunction& unstall_function);
93
[email protected]3d587372013-06-01 04:31:4594 // Add{Read,Write}() populates lists that are eventually passed to a
95 // SocketData class. |frame| must live for the whole test.
96
Ryan Hamilton0239aac2018-05-19 00:03:1397 void AddRead(const spdy::SpdySerializedFrame& frame) {
[email protected]3d587372013-06-01 04:31:4598 reads_.push_back(CreateMockRead(frame, offset_++));
99 }
100
Ryan Hamilton0239aac2018-05-19 00:03:13101 void AddWrite(const spdy::SpdySerializedFrame& frame) {
[email protected]3d587372013-06-01 04:31:45102 writes_.push_back(CreateMockWrite(frame, offset_++));
103 }
104
105 void AddReadEOF() {
106 reads_.push_back(MockRead(ASYNC, 0, offset_++));
107 }
108
mmenkee24011922015-12-17 22:12:59109 void AddWritePause() {
110 writes_.push_back(MockWrite(ASYNC, ERR_IO_PENDING, offset_++));
111 }
112
113 void AddReadPause() {
114 reads_.push_back(MockRead(ASYNC, ERR_IO_PENDING, offset_++));
115 }
116
Ryan Sleevib8d7ea02018-05-07 20:01:01117 base::span<const MockRead> GetReads() { return reads_; }
118 base::span<const MockWrite> GetWrites() { return writes_; }
[email protected]3d587372013-06-01 04:31:45119
caseqe8340bc92016-04-20 00:02:57120 void ActivatePushStream(SpdySession* session, SpdyStream* stream) {
121 std::unique_ptr<SpdyStream> activated =
122 session->ActivateCreatedStream(stream);
123 activated->set_stream_id(2);
124 session->InsertActivatedStream(std::move(activated));
125 }
126
bnc032658ba2016-09-26 18:17:15127 void AddSSLSocketData() {
128 // Load a cert that is valid for
129 // www.example.org, mail.example.org, and mail.example.com.
Ryan Sleevi4f832092017-11-21 23:25:49130 ssl_.ssl_info.cert =
131 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
132 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15133 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
134 }
135
Bence Béky7bf94362018-01-10 13:19:36136 static size_t num_pushed_streams(base::WeakPtr<SpdySession> session) {
137 return session->num_pushed_streams_;
138 }
139
140 static SpdySessionPool* spdy_session_pool(
141 base::WeakPtr<SpdySession> session) {
142 return session->pool_;
143 }
144
bnca2fbdc9b2016-11-22 21:14:26145 const GURL url_;
[email protected]a4a67772013-05-08 22:56:07146 SpdyTestUtil spdy_util_;
[email protected]34a4dea2013-03-13 00:42:30147 SpdySessionDependencies session_deps_;
danakjaee3e1ec2016-04-16 00:23:18148 std::unique_ptr<HttpNetworkSession> session_;
[email protected]3d587372013-06-01 04:31:45149
150 private:
151 // Used by Add{Read,Write}() above.
152 std::vector<MockWrite> writes_;
153 std::vector<MockRead> reads_;
154 int offset_;
bnc032658ba2016-09-26 18:17:15155 SSLSocketDataProvider ssl_;
[email protected]4f386422010-07-20 04:19:49156};
157
bncd16676a2016-07-20 16:23:01158TEST_F(SpdyStreamTest, SendDataAfterOpen) {
Ryan Hamilton0239aac2018-05-19 00:03:13159 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:26160 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41161 AddWrite(req);
[email protected]3d587372013-06-01 04:31:45162
Ryan Hamilton0239aac2018-05-19 00:03:13163 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41164 AddRead(resp);
[email protected]3d587372013-06-01 04:31:45165
Ryan Hamilton0239aac2018-05-19 00:03:13166 spdy::SpdySerializedFrame msg(
Bence Békyd74f4382018-02-20 18:26:19167 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bncdf80d44fd2016-07-15 20:27:41168 AddWrite(msg);
[email protected]4f386422010-07-20 04:19:49169
Ryan Hamilton0239aac2018-05-19 00:03:13170 spdy::SpdySerializedFrame echo(
Bence Békyd74f4382018-02-20 18:26:19171 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bncdf80d44fd2016-07-15 20:27:41172 AddRead(echo);
[email protected]4f386422010-07-20 04:19:49173
[email protected]3d587372013-06-01 04:31:45174 AddReadEOF();
175
Ryan Sleevib8d7ea02018-05-07 20:01:01176 SequencedSocketData data(GetReads(), GetWrites());
[email protected]d973e99a2012-02-17 21:02:36177 MockConnect connect_data(SYNCHRONOUS, OK);
[email protected]dd54bd82012-07-19 23:44:57178 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59179 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4f386422010-07-20 04:19:49180
bnc032658ba2016-09-26 18:17:15181 AddSSLSocketData();
182
[email protected]795cbf82013-07-22 09:37:27183 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]e3861ca2013-03-02 01:00:45184
tfarina428341112016-09-22 13:38:20185 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26186 SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52187 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18188 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]4f386422010-07-20 04:19:49189
[email protected]194cfcf2013-05-23 21:44:44190 StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
[email protected]34a4dea2013-03-13 00:42:30191 stream->SetDelegate(&delegate);
[email protected]4f386422010-07-20 04:19:49192
Ryan Hamilton0239aac2018-05-19 00:03:13193 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:26194 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
195 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
196 IsError(ERR_IO_PENDING));
[email protected]4f386422010-07-20 04:19:49197
robpercival214763f2016-07-01 23:27:01198 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
[email protected]4f386422010-07-20 04:19:49199
[email protected]34a4dea2013-03-13 00:42:30200 EXPECT_TRUE(delegate.send_headers_completed());
Ryan Hamilton0239aac2018-05-19 00:03:13201 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
Bence Béky4e83f492018-05-13 23:14:25202 EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
[email protected]09a8d9172013-04-17 19:23:49203 delegate.TakeReceivedData());
rch37de576c2015-05-17 20:28:17204 EXPECT_TRUE(data.AllWriteDataConsumed());
[email protected]4f386422010-07-20 04:19:49205}
206
xunjieli294da722015-08-11 19:15:02207// Delegate that receives trailers.
208class StreamDelegateWithTrailers : public test::StreamDelegateWithBody {
209 public:
210 StreamDelegateWithTrailers(const base::WeakPtr<SpdyStream>& stream,
Bence Béky4e83f492018-05-13 23:14:25211 base::StringPiece data)
xunjieli294da722015-08-11 19:15:02212 : StreamDelegateWithBody(stream, data) {}
213
Chris Watkins61914cb2017-12-01 19:59:00214 ~StreamDelegateWithTrailers() override = default;
xunjieli294da722015-08-11 19:15:02215
Ryan Hamilton0239aac2018-05-19 00:03:13216 void OnTrailers(const spdy::SpdyHeaderBlock& trailers) override {
bnc94893a72016-06-30 13:45:25217 trailers_ = trailers.Clone();
xunjieli294da722015-08-11 19:15:02218 }
219
Ryan Hamilton0239aac2018-05-19 00:03:13220 const spdy::SpdyHeaderBlock& trailers() const { return trailers_; }
xunjieli294da722015-08-11 19:15:02221
222 private:
Ryan Hamilton0239aac2018-05-19 00:03:13223 spdy::SpdyHeaderBlock trailers_;
xunjieli294da722015-08-11 19:15:02224};
225
bnca2fbdc9b2016-11-22 21:14:26226// Regression test for https://crbug.com/481033.
bncd16676a2016-07-20 16:23:01227TEST_F(SpdyStreamTest, Trailers) {
Ryan Hamilton0239aac2018-05-19 00:03:13228 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:26229 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41230 AddWrite(req);
xunjieli294da722015-08-11 19:15:02231
Ryan Hamilton0239aac2018-05-19 00:03:13232 spdy::SpdySerializedFrame msg(
Bence Békyd74f4382018-02-20 18:26:19233 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bncdf80d44fd2016-07-15 20:27:41234 AddWrite(msg);
xunjieli294da722015-08-11 19:15:02235
Ryan Hamilton0239aac2018-05-19 00:03:13236 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41237 AddRead(resp);
xunjieli294da722015-08-11 19:15:02238
Ryan Hamilton0239aac2018-05-19 00:03:13239 spdy::SpdySerializedFrame echo(
Bence Békyd74f4382018-02-20 18:26:19240 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bncdf80d44fd2016-07-15 20:27:41241 AddRead(echo);
xunjieli294da722015-08-11 19:15:02242
Ryan Hamilton0239aac2018-05-19 00:03:13243 spdy::SpdyHeaderBlock late_headers;
bnc38dcd392016-02-09 23:19:49244 late_headers["foo"] = "bar";
Ryan Hamilton0239aac2018-05-19 00:03:13245 spdy::SpdySerializedFrame trailers(spdy_util_.ConstructSpdyResponseHeaders(
bncdf80d44fd2016-07-15 20:27:41246 1, std::move(late_headers), false));
247 AddRead(trailers);
xunjieli294da722015-08-11 19:15:02248
249 AddReadEOF();
250
Ryan Sleevib8d7ea02018-05-07 20:01:01251 SequencedSocketData data(GetReads(), GetWrites());
xunjieli294da722015-08-11 19:15:02252 MockConnect connect_data(SYNCHRONOUS, OK);
253 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59254 session_deps_.socket_factory->AddSocketDataProvider(&data);
xunjieli294da722015-08-11 19:15:02255
bnc032658ba2016-09-26 18:17:15256 AddSSLSocketData();
257
xunjieli294da722015-08-11 19:15:02258 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
259
260 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26261 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52262 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18263 EXPECT_EQ(kDefaultUrl, stream->url().spec());
xunjieli294da722015-08-11 19:15:02264
265 StreamDelegateWithTrailers delegate(stream, kPostBodyStringPiece);
266 stream->SetDelegate(&delegate);
267
Ryan Hamilton0239aac2018-05-19 00:03:13268 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:26269 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
270 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
271 IsError(ERR_IO_PENDING));
xunjieli294da722015-08-11 19:15:02272
robpercival214763f2016-07-01 23:27:01273 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
xunjieli294da722015-08-11 19:15:02274
275 EXPECT_TRUE(delegate.send_headers_completed());
Ryan Hamilton0239aac2018-05-19 00:03:13276 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
277 const spdy::SpdyHeaderBlock& received_trailers = delegate.trailers();
278 spdy::SpdyHeaderBlock::const_iterator it = received_trailers.find("foo");
xunjieli294da722015-08-11 19:15:02279 EXPECT_EQ("bar", it->second);
Bence Béky4e83f492018-05-13 23:14:25280 EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
xunjieli294da722015-08-11 19:15:02281 delegate.TakeReceivedData());
282 EXPECT_TRUE(data.AllWriteDataConsumed());
283}
284
bncd16676a2016-07-20 16:23:01285TEST_F(SpdyStreamTest, PushedStream) {
Ryan Hamilton0239aac2018-05-19 00:03:13286 spdy::SpdySerializedFrame req(
287 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnca2fbdc9b2016-11-22 21:14:26288 AddWrite(req);
289
Ryan Hamilton0239aac2018-05-19 00:03:13290 spdy::SpdySerializedFrame reply(
291 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bnca2fbdc9b2016-11-22 21:14:26292 AddRead(reply);
293
Ryan Hamilton0239aac2018-05-19 00:03:13294 spdy::SpdySerializedFrame push(
bnca2fbdc9b2016-11-22 21:14:26295 spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushUrl));
296 AddRead(push);
297
Ryan Hamilton0239aac2018-05-19 00:03:13298 spdy::SpdySerializedFrame priority(
tombergan5d22c182017-01-11 02:05:35299 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
300 AddWrite(priority);
301
bnca2fbdc9b2016-11-22 21:14:26302 AddReadPause();
303
Bence Béky4e83f492018-05-13 23:14:25304 base::StringPiece pushed_msg("foo");
Ryan Hamilton0239aac2018-05-19 00:03:13305 spdy::SpdySerializedFrame pushed_body(
Bence Békyd74f4382018-02-20 18:26:19306 spdy_util_.ConstructSpdyDataFrame(2, pushed_msg, true));
bnca2fbdc9b2016-11-22 21:14:26307 AddRead(pushed_body);
308
Bence Béky4e83f492018-05-13 23:14:25309 base::StringPiece msg("bar");
Ryan Hamilton0239aac2018-05-19 00:03:13310 spdy::SpdySerializedFrame body(
311 spdy_util_.ConstructSpdyDataFrame(1, msg, true));
bnca2fbdc9b2016-11-22 21:14:26312 AddRead(body);
313
[email protected]6d116e1a2013-06-24 07:42:15314 AddReadEOF();
315
Ryan Sleevib8d7ea02018-05-07 20:01:01316 SequencedSocketData data(GetReads(), GetWrites());
[email protected]0e861e92012-03-15 18:42:19317 MockConnect connect_data(SYNCHRONOUS, OK);
[email protected]dd54bd82012-07-19 23:44:57318 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59319 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]0e861e92012-03-15 18:42:19320
bnc032658ba2016-09-26 18:17:15321 AddSSLSocketData();
322
bnca2fbdc9b2016-11-22 21:14:26323 g_time_now = base::TimeTicks::Now();
324 session_deps_.time_func = InstantaneousReads;
325 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
[email protected]a7a265ef2010-12-08 18:05:57326
bnca2fbdc9b2016-11-22 21:14:26327 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
328
329 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
330 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
331 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18332 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bnca2fbdc9b2016-11-22 21:14:26333
334 StreamDelegateDoNothing delegate(stream);
335 stream->SetDelegate(&delegate);
caseqe8340bc92016-04-20 00:02:57336
Ryan Hamilton0239aac2018-05-19 00:03:13337 spdy::SpdyHeaderBlock headers(
338 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnca2fbdc9b2016-11-22 21:14:26339 EXPECT_THAT(
340 stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
341 IsError(ERR_IO_PENDING));
[email protected]6cd63ba2014-06-12 16:14:56342
bnca2fbdc9b2016-11-22 21:14:26343 data.RunUntilPaused();
[email protected]a7a265ef2010-12-08 18:05:57344
Bence Béky7bf94362018-01-10 13:19:36345 const SpdySessionKey key(HostPortPair::FromURL(url_), ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:11346 PRIVACY_MODE_DISABLED,
347 SpdySessionKey::IsProxySession::kFalse, SocketTag());
Bence Béky5b1e4ce72018-01-11 14:55:15348 const GURL pushed_url(kPushUrl);
349 HttpRequestInfo push_request;
350 push_request.url = pushed_url;
351 push_request.method = "GET";
Bence Béky7bf94362018-01-10 13:19:36352 base::WeakPtr<SpdySession> session_with_pushed_stream;
Ryan Hamilton0239aac2018-05-19 00:03:13353 spdy::SpdyStreamId pushed_stream_id;
Bence Béky7bf94362018-01-10 13:19:36354 spdy_session_pool(session)->push_promise_index()->ClaimPushedStream(
Bence Béky5b1e4ce72018-01-11 14:55:15355 key, pushed_url, push_request, &session_with_pushed_stream,
356 &pushed_stream_id);
Bence Béky7bf94362018-01-10 13:19:36357 EXPECT_EQ(session.get(), session_with_pushed_stream.get());
358 EXPECT_EQ(2u, pushed_stream_id);
359
bnc4e6e77482017-01-22 12:59:43360 SpdyStream* push_stream;
Bence Béky5b1e4ce72018-01-11 14:55:15361 EXPECT_THAT(session->GetPushedStream(pushed_url, pushed_stream_id, IDLE,
Bence Békyc6834652018-10-03 00:47:39362 &push_stream),
tombergan5d22c182017-01-11 02:05:35363 IsOk());
bnca2fbdc9b2016-11-22 21:14:26364 ASSERT_TRUE(push_stream);
Bence Béky39d74292018-03-02 04:31:18365 EXPECT_EQ(kPushUrl, push_stream->url().spec());
caseqe8340bc92016-04-20 00:02:57366
367 LoadTimingInfo load_timing_info;
bnca2fbdc9b2016-11-22 21:14:26368 EXPECT_TRUE(push_stream->GetLoadTimingInfo(&load_timing_info));
369 EXPECT_EQ(g_time_now, load_timing_info.push_start);
caseqe8340bc92016-04-20 00:02:57370 EXPECT_TRUE(load_timing_info.push_end.is_null());
371
bnc4e6e77482017-01-22 12:59:43372 StreamDelegateDoNothing push_delegate(push_stream->GetWeakPtr());
bnca2fbdc9b2016-11-22 21:14:26373 push_stream->SetDelegate(&push_delegate);
[email protected]6d116e1a2013-06-24 07:42:15374
bnca2fbdc9b2016-11-22 21:14:26375 data.Resume();
[email protected]6d116e1a2013-06-24 07:42:15376
bnca2fbdc9b2016-11-22 21:14:26377 EXPECT_TRUE(push_stream->GetLoadTimingInfo(&load_timing_info));
378 EXPECT_EQ(g_time_now, load_timing_info.push_start);
379 EXPECT_FALSE(load_timing_info.push_end.is_null());
380
381 EXPECT_THAT(delegate.WaitForClose(), IsOk());
Ryan Hamilton0239aac2018-05-19 00:03:13382 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
bnca2fbdc9b2016-11-22 21:14:26383 EXPECT_EQ(msg, delegate.TakeReceivedData());
[email protected]6d116e1a2013-06-24 07:42:15384
bnca2fbdc9b2016-11-22 21:14:26385 EXPECT_THAT(push_delegate.WaitForClose(), IsOk());
Ryan Hamilton0239aac2018-05-19 00:03:13386 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
bnca2fbdc9b2016-11-22 21:14:26387 EXPECT_EQ(pushed_msg, push_delegate.TakeReceivedData());
Bence Békya60ed842018-04-26 23:45:44388
389 // Finish async network reads and writes.
390 base::RunLoop().RunUntilIdle();
391
392 EXPECT_TRUE(data.AllWriteDataConsumed());
393 EXPECT_TRUE(data.AllReadDataConsumed());
[email protected]a7a265ef2010-12-08 18:05:57394}
395
bncd16676a2016-07-20 16:23:01396TEST_F(SpdyStreamTest, StreamError) {
Ryan Hamilton0239aac2018-05-19 00:03:13397 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:26398 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41399 AddWrite(req);
[email protected]3d587372013-06-01 04:31:45400
Ryan Hamilton0239aac2018-05-19 00:03:13401 spdy::SpdySerializedFrame resp(
402 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:41403 AddRead(resp);
[email protected]3d587372013-06-01 04:31:45404
Ryan Hamilton0239aac2018-05-19 00:03:13405 spdy::SpdySerializedFrame msg(
Bence Békyd74f4382018-02-20 18:26:19406 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bncdf80d44fd2016-07-15 20:27:41407 AddWrite(msg);
[email protected]3d587372013-06-01 04:31:45408
Ryan Hamilton0239aac2018-05-19 00:03:13409 spdy::SpdySerializedFrame echo(
Bence Békyd74f4382018-02-20 18:26:19410 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bncdf80d44fd2016-07-15 20:27:41411 AddRead(echo);
[email protected]3d587372013-06-01 04:31:45412
413 AddReadEOF();
[email protected]d245c342012-02-23 20:49:15414
vishal.b62985ca92015-04-17 08:45:51415 BoundTestNetLog log;
[email protected]d245c342012-02-23 20:49:15416
Ryan Sleevib8d7ea02018-05-07 20:01:01417 SequencedSocketData data(GetReads(), GetWrites());
[email protected]d245c342012-02-23 20:49:15418 MockConnect connect_data(SYNCHRONOUS, OK);
[email protected]dd54bd82012-07-19 23:44:57419 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59420 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]d245c342012-02-23 20:49:15421
bnc032658ba2016-09-26 18:17:15422 AddSSLSocketData();
423
[email protected]795cbf82013-07-22 09:37:27424 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]d245c342012-02-23 20:49:15425
bnca2fbdc9b2016-11-22 21:14:26426 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
427 SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, log.bound());
wezca1070932016-05-26 20:30:52428 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18429 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]d245c342012-02-23 20:49:15430
[email protected]194cfcf2013-05-23 21:44:44431 StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
[email protected]34a4dea2013-03-13 00:42:30432 stream->SetDelegate(&delegate);
[email protected]d245c342012-02-23 20:49:15433
Ryan Hamilton0239aac2018-05-19 00:03:13434 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:26435 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
436 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
437 IsError(ERR_IO_PENDING));
[email protected]d245c342012-02-23 20:49:15438
robpercival214763f2016-07-01 23:27:01439 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
[email protected]218f4b62012-07-20 20:12:41440
Ryan Hamilton0239aac2018-05-19 00:03:13441 const spdy::SpdyStreamId stream_id = delegate.stream_id();
[email protected]c92f4b4542012-07-26 23:53:21442
[email protected]34a4dea2013-03-13 00:42:30443 EXPECT_TRUE(delegate.send_headers_completed());
Ryan Hamilton0239aac2018-05-19 00:03:13444 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
Bence Béky4e83f492018-05-13 23:14:25445 EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
[email protected]09a8d9172013-04-17 19:23:49446 delegate.TakeReceivedData());
rch37de576c2015-05-17 20:28:17447 EXPECT_TRUE(data.AllWriteDataConsumed());
[email protected]d245c342012-02-23 20:49:15448
449 // Check that the NetLog was filled reasonably.
mmenke43758e62015-05-04 21:09:46450 TestNetLogEntry::List entries;
[email protected]d245c342012-02-23 20:49:15451 log.GetEntries(&entries);
452 EXPECT_LT(0u, entries.size());
453
454 // Check that we logged SPDY_STREAM_ERROR correctly.
ttuttle859dc7a2015-04-23 19:42:29455 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00456 entries, 0, NetLogEventType::HTTP2_STREAM_ERROR, NetLogEventPhase::NONE);
[email protected]d245c342012-02-23 20:49:15457
[email protected]f3da152d2012-06-02 01:00:57458 int stream_id2;
459 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &stream_id2));
460 EXPECT_EQ(static_cast<int>(stream_id), stream_id2);
[email protected]d245c342012-02-23 20:49:15461}
[email protected]a7a265ef2010-12-08 18:05:57462
bnca2fbdc9b2016-11-22 21:14:26463// Make sure that large blocks of data are properly split up into frame-sized
464// chunks for a request/response (i.e., an HTTP-like) stream.
bncd16676a2016-07-20 16:23:01465TEST_F(SpdyStreamTest, SendLargeDataAfterOpenRequestResponse) {
Ryan Hamilton0239aac2018-05-19 00:03:13466 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:26467 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41468 AddWrite(req);
[email protected]3d587372013-06-01 04:31:45469
Bence Béky4e83f492018-05-13 23:14:25470 std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
Ryan Hamilton0239aac2018-05-19 00:03:13471 spdy::SpdySerializedFrame chunk(
Bence Békyd74f4382018-02-20 18:26:19472 spdy_util_.ConstructSpdyDataFrame(1, chunk_data, false));
bncdf80d44fd2016-07-15 20:27:41473 AddWrite(chunk);
474 AddWrite(chunk);
[email protected]3d587372013-06-01 04:31:45475
Ryan Hamilton0239aac2018-05-19 00:03:13476 spdy::SpdySerializedFrame last_chunk(
Bence Békyd74f4382018-02-20 18:26:19477 spdy_util_.ConstructSpdyDataFrame(1, chunk_data, true));
bncdf80d44fd2016-07-15 20:27:41478 AddWrite(last_chunk);
[email protected]aa19cfc2013-05-23 16:41:38479
Ryan Hamilton0239aac2018-05-19 00:03:13480 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41481 AddRead(resp);
[email protected]aa19cfc2013-05-23 16:41:38482
[email protected]3d587372013-06-01 04:31:45483 AddReadEOF();
484
Ryan Sleevib8d7ea02018-05-07 20:01:01485 SequencedSocketData data(GetReads(), GetWrites());
[email protected]aa19cfc2013-05-23 16:41:38486 MockConnect connect_data(SYNCHRONOUS, OK);
487 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59488 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]aa19cfc2013-05-23 16:41:38489
bnc032658ba2016-09-26 18:17:15490 AddSSLSocketData();
491
[email protected]795cbf82013-07-22 09:37:27492 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]aa19cfc2013-05-23 16:41:38493
tfarina428341112016-09-22 13:38:20494 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26495 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52496 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18497 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]aa19cfc2013-05-23 16:41:38498
Bence Béky4e83f492018-05-13 23:14:25499 std::string body_data(3 * kMaxSpdyFrameChunkSize, 'x');
[email protected]aa19cfc2013-05-23 16:41:38500 StreamDelegateWithBody delegate(stream, body_data);
501 stream->SetDelegate(&delegate);
502
Ryan Hamilton0239aac2018-05-19 00:03:13503 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:26504 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
505 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
506 IsError(ERR_IO_PENDING));
[email protected]aa19cfc2013-05-23 16:41:38507
robpercival214763f2016-07-01 23:27:01508 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
[email protected]aa19cfc2013-05-23 16:41:38509
510 EXPECT_TRUE(delegate.send_headers_completed());
Ryan Hamilton0239aac2018-05-19 00:03:13511 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
Bence Béky4e83f492018-05-13 23:14:25512 EXPECT_EQ(std::string(), delegate.TakeReceivedData());
rch37de576c2015-05-17 20:28:17513 EXPECT_TRUE(data.AllWriteDataConsumed());
[email protected]aa19cfc2013-05-23 16:41:38514}
515
bnca2fbdc9b2016-11-22 21:14:26516// Make sure that large blocks of data are properly split up into frame-sized
517// chunks for a bidirectional (i.e., non-HTTP-like) stream.
bncd16676a2016-07-20 16:23:01518TEST_F(SpdyStreamTest, SendLargeDataAfterOpenBidirectional) {
Ryan Hamilton0239aac2018-05-19 00:03:13519 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:26520 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41521 AddWrite(req);
[email protected]3d587372013-06-01 04:31:45522
Ryan Hamilton0239aac2018-05-19 00:03:13523 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41524 AddRead(resp);
[email protected]3d587372013-06-01 04:31:45525
Bence Béky4e83f492018-05-13 23:14:25526 std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
Ryan Hamilton0239aac2018-05-19 00:03:13527 spdy::SpdySerializedFrame chunk(
Bence Békyd74f4382018-02-20 18:26:19528 spdy_util_.ConstructSpdyDataFrame(1, chunk_data, false));
bncdf80d44fd2016-07-15 20:27:41529 AddWrite(chunk);
530 AddWrite(chunk);
531 AddWrite(chunk);
[email protected]aa19cfc2013-05-23 16:41:38532
[email protected]3d587372013-06-01 04:31:45533 AddReadEOF();
[email protected]aa19cfc2013-05-23 16:41:38534
Ryan Sleevib8d7ea02018-05-07 20:01:01535 SequencedSocketData data(GetReads(), GetWrites());
[email protected]aa19cfc2013-05-23 16:41:38536 MockConnect connect_data(SYNCHRONOUS, OK);
537 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59538 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]aa19cfc2013-05-23 16:41:38539
bnc032658ba2016-09-26 18:17:15540 AddSSLSocketData();
541
[email protected]795cbf82013-07-22 09:37:27542 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]aa19cfc2013-05-23 16:41:38543
tfarina428341112016-09-22 13:38:20544 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26545 SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52546 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18547 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]aa19cfc2013-05-23 16:41:38548
Bence Béky4e83f492018-05-13 23:14:25549 std::string body_data(3 * kMaxSpdyFrameChunkSize, 'x');
[email protected]194cfcf2013-05-23 21:44:44550 StreamDelegateSendImmediate delegate(stream, body_data);
[email protected]aa19cfc2013-05-23 16:41:38551 stream->SetDelegate(&delegate);
552
Ryan Hamilton0239aac2018-05-19 00:03:13553 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:26554 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
555 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
556 IsError(ERR_IO_PENDING));
[email protected]aa19cfc2013-05-23 16:41:38557
robpercival214763f2016-07-01 23:27:01558 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
[email protected]aa19cfc2013-05-23 16:41:38559
560 EXPECT_TRUE(delegate.send_headers_completed());
Ryan Hamilton0239aac2018-05-19 00:03:13561 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
Bence Béky4e83f492018-05-13 23:14:25562 EXPECT_EQ(std::string(), delegate.TakeReceivedData());
rch37de576c2015-05-17 20:28:17563 EXPECT_TRUE(data.AllWriteDataConsumed());
[email protected]aa19cfc2013-05-23 16:41:38564}
565
bnca2fbdc9b2016-11-22 21:14:26566// Receiving a header with uppercase ASCII should result in a protocol error.
bncd16676a2016-07-20 16:23:01567TEST_F(SpdyStreamTest, UpperCaseHeaders) {
Ryan Hamilton0239aac2018-05-19 00:03:13568 spdy::SpdySerializedFrame req(
569 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnca2fbdc9b2016-11-22 21:14:26570 AddWrite(req);
[email protected]6d116e1a2013-06-24 07:42:15571
572 const char* const kExtraHeaders[] = {"X-UpperCase", "yes"};
Ryan Hamilton0239aac2018-05-19 00:03:13573 spdy::SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(
bnc4c214312016-11-28 16:49:15574 kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
bncdf80d44fd2016-07-15 20:27:41575 AddRead(reply);
[email protected]6d116e1a2013-06-24 07:42:15576
Ryan Hamilton0239aac2018-05-19 00:03:13577 spdy::SpdySerializedFrame rst(
578 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bncdf80d44fd2016-07-15 20:27:41579 AddWrite(rst);
[email protected]6d116e1a2013-06-24 07:42:15580
581 AddReadEOF();
582
Ryan Sleevib8d7ea02018-05-07 20:01:01583 SequencedSocketData data(GetReads(), GetWrites());
[email protected]6d116e1a2013-06-24 07:42:15584 MockConnect connect_data(SYNCHRONOUS, OK);
585 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59586 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6d116e1a2013-06-24 07:42:15587
bnc032658ba2016-09-26 18:17:15588 AddSSLSocketData();
589
[email protected]795cbf82013-07-22 09:37:27590 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]6d116e1a2013-06-24 07:42:15591
tfarina428341112016-09-22 13:38:20592 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26593 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52594 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18595 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]6d116e1a2013-06-24 07:42:15596
597 StreamDelegateDoNothing delegate(stream);
598 stream->SetDelegate(&delegate);
599
Ryan Hamilton0239aac2018-05-19 00:03:13600 spdy::SpdyHeaderBlock headers(
601 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnca2fbdc9b2016-11-22 21:14:26602 EXPECT_THAT(
603 stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
604 IsError(ERR_IO_PENDING));
[email protected]6d116e1a2013-06-24 07:42:15605
robpercival214763f2016-07-01 23:27:01606 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
bnc4c214312016-11-28 16:49:15607
bnceb9aa7112017-01-05 01:03:46608 // Finish async network reads and writes.
609 base::RunLoop().RunUntilIdle();
610
bnc4c214312016-11-28 16:49:15611 EXPECT_TRUE(data.AllWriteDataConsumed());
612 EXPECT_TRUE(data.AllReadDataConsumed());
[email protected]6d116e1a2013-06-24 07:42:15613}
614
bnca2fbdc9b2016-11-22 21:14:26615// Receiving a header with uppercase ASCII should result in a protocol error
616// even for a push stream.
bncd16676a2016-07-20 16:23:01617TEST_F(SpdyStreamTest, UpperCaseHeadersOnPush) {
Ryan Hamilton0239aac2018-05-19 00:03:13618 spdy::SpdySerializedFrame req(
619 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnca2fbdc9b2016-11-22 21:14:26620 AddWrite(req);
[email protected]6d116e1a2013-06-24 07:42:15621
Ryan Hamilton0239aac2018-05-19 00:03:13622 spdy::SpdySerializedFrame reply(
623 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:41624 AddRead(reply);
[email protected]6d116e1a2013-06-24 07:42:15625
bnc4c214312016-11-28 16:49:15626 const char* const kExtraHeaders[] = {"X-UpperCase", "yes"};
Ryan Hamilton0239aac2018-05-19 00:03:13627 spdy::SpdySerializedFrame push(spdy_util_.ConstructSpdyPush(
bnc4c214312016-11-28 16:49:15628 kExtraHeaders, arraysize(kExtraHeaders) / 2, 2, 1, kPushUrl));
bncdf80d44fd2016-07-15 20:27:41629 AddRead(push);
[email protected]6d116e1a2013-06-24 07:42:15630
Ryan Hamilton0239aac2018-05-19 00:03:13631 spdy::SpdySerializedFrame priority(
tombergan5d22c182017-01-11 02:05:35632 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
633 AddWrite(priority);
634
Ryan Hamilton0239aac2018-05-19 00:03:13635 spdy::SpdySerializedFrame rst(
636 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_PROTOCOL_ERROR));
bncdf80d44fd2016-07-15 20:27:41637 AddWrite(rst);
[email protected]6d116e1a2013-06-24 07:42:15638
mmenkee24011922015-12-17 22:12:59639 AddReadPause();
640
[email protected]6d116e1a2013-06-24 07:42:15641 AddReadEOF();
642
Ryan Sleevib8d7ea02018-05-07 20:01:01643 SequencedSocketData data(GetReads(), GetWrites());
[email protected]6d116e1a2013-06-24 07:42:15644 MockConnect connect_data(SYNCHRONOUS, OK);
645 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59646 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6d116e1a2013-06-24 07:42:15647
bnc032658ba2016-09-26 18:17:15648 AddSSLSocketData();
649
[email protected]795cbf82013-07-22 09:37:27650 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]6d116e1a2013-06-24 07:42:15651
tfarina428341112016-09-22 13:38:20652 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26653 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52654 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18655 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]6d116e1a2013-06-24 07:42:15656
657 StreamDelegateDoNothing delegate(stream);
658 stream->SetDelegate(&delegate);
659
Ryan Hamilton0239aac2018-05-19 00:03:13660 spdy::SpdyHeaderBlock headers(
661 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnca2fbdc9b2016-11-22 21:14:26662 EXPECT_THAT(
663 stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
664 IsError(ERR_IO_PENDING));
[email protected]6d116e1a2013-06-24 07:42:15665
mmenkee24011922015-12-17 22:12:59666 data.RunUntilPaused();
[email protected]6d116e1a2013-06-24 07:42:15667
Bence Béky7bf94362018-01-10 13:19:36668 EXPECT_EQ(0u, num_pushed_streams(session));
[email protected]6d116e1a2013-06-24 07:42:15669
mmenkee24011922015-12-17 22:12:59670 data.Resume();
[email protected]6d116e1a2013-06-24 07:42:15671
robpercival214763f2016-07-01 23:27:01672 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
bnc4c214312016-11-28 16:49:15673
674 EXPECT_TRUE(data.AllWriteDataConsumed());
675 EXPECT_TRUE(data.AllReadDataConsumed());
[email protected]6d116e1a2013-06-24 07:42:15676}
677
bnc4c214312016-11-28 16:49:15678TEST_F(SpdyStreamTest, HeadersMustHaveStatus) {
Ryan Hamilton0239aac2018-05-19 00:03:13679 spdy::SpdySerializedFrame req(
680 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnc4c214312016-11-28 16:49:15681 AddWrite(req);
682
683 // Response headers without ":status" header field: protocol error.
Ryan Hamilton0239aac2018-05-19 00:03:13684 spdy::SpdyHeaderBlock header_block_without_status;
685 header_block_without_status[spdy::kHttp2MethodHeader] = "GET";
686 header_block_without_status[spdy::kHttp2AuthorityHeader] = "www.example.org";
687 header_block_without_status[spdy::kHttp2SchemeHeader] = "https";
688 header_block_without_status[spdy::kHttp2PathHeader] = "/";
689 spdy::SpdySerializedFrame reply(
bnc4c214312016-11-28 16:49:15690 spdy_util_.ConstructSpdyReply(1, std::move(header_block_without_status)));
691 AddRead(reply);
692
Ryan Hamilton0239aac2018-05-19 00:03:13693 spdy::SpdySerializedFrame rst(
694 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bnc4c214312016-11-28 16:49:15695 AddWrite(rst);
696
697 AddReadEOF();
698
Ryan Sleevib8d7ea02018-05-07 20:01:01699 SequencedSocketData data(GetReads(), GetWrites());
bnc4c214312016-11-28 16:49:15700 MockConnect connect_data(SYNCHRONOUS, OK);
701 data.set_connect_data(connect_data);
702 session_deps_.socket_factory->AddSocketDataProvider(&data);
703
704 AddSSLSocketData();
705
706 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
707
708 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
709 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
710 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18711 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bnc4c214312016-11-28 16:49:15712
713 StreamDelegateDoNothing delegate(stream);
714 stream->SetDelegate(&delegate);
715
Ryan Hamilton0239aac2018-05-19 00:03:13716 spdy::SpdyHeaderBlock headers(
717 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnc4c214312016-11-28 16:49:15718 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
719 NO_MORE_DATA_TO_SEND));
bnc4c214312016-11-28 16:49:15720
721 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
722
bnceb9aa7112017-01-05 01:03:46723 // Finish async network reads and writes.
724 base::RunLoop().RunUntilIdle();
725
bnc4c214312016-11-28 16:49:15726 EXPECT_TRUE(data.AllWriteDataConsumed());
727 EXPECT_TRUE(data.AllReadDataConsumed());
728}
729
730TEST_F(SpdyStreamTest, HeadersMustHaveStatusOnPushedStream) {
Ryan Hamilton0239aac2018-05-19 00:03:13731 spdy::SpdySerializedFrame req(
732 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnca2fbdc9b2016-11-22 21:14:26733 AddWrite(req);
[email protected]6d116e1a2013-06-24 07:42:15734
Ryan Hamilton0239aac2018-05-19 00:03:13735 spdy::SpdySerializedFrame reply(
736 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:41737 AddRead(reply);
[email protected]6d116e1a2013-06-24 07:42:15738
Ryan Hamilton0239aac2018-05-19 00:03:13739 spdy::SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise(
Bence Békyf1d78522018-01-11 01:16:50740 1, 2, spdy_util_.ConstructGetHeaderBlock(kPushUrl)));
bnc4c214312016-11-28 16:49:15741 AddRead(push_promise);
[email protected]6d116e1a2013-06-24 07:42:15742
Ryan Hamilton0239aac2018-05-19 00:03:13743 spdy::SpdySerializedFrame priority(
tombergan5d22c182017-01-11 02:05:35744 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
745 AddWrite(priority);
746
bnc4c214312016-11-28 16:49:15747 // Response headers without ":status" header field: protocol error.
Ryan Hamilton0239aac2018-05-19 00:03:13748 spdy::SpdyHeaderBlock header_block_without_status;
749 header_block_without_status[spdy::kHttp2MethodHeader] = "GET";
750 header_block_without_status[spdy::kHttp2AuthorityHeader] = "www.example.org";
751 header_block_without_status[spdy::kHttp2SchemeHeader] = "https";
752 header_block_without_status[spdy::kHttp2PathHeader] = "/";
753 spdy::SpdySerializedFrame pushed_reply(
bnc4c214312016-11-28 16:49:15754 spdy_util_.ConstructSpdyReply(2, std::move(header_block_without_status)));
755 AddRead(pushed_reply);
mmenkee24011922015-12-17 22:12:59756
Ryan Hamilton0239aac2018-05-19 00:03:13757 spdy::SpdySerializedFrame rst(
758 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_PROTOCOL_ERROR));
bncdf80d44fd2016-07-15 20:27:41759 AddWrite(rst);
[email protected]6d116e1a2013-06-24 07:42:15760
Ryan Hamilton0239aac2018-05-19 00:03:13761 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:19762 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bnc4c214312016-11-28 16:49:15763 AddRead(body);
764
[email protected]6d116e1a2013-06-24 07:42:15765 AddReadEOF();
766
Ryan Sleevib8d7ea02018-05-07 20:01:01767 SequencedSocketData data(GetReads(), GetWrites());
[email protected]6d116e1a2013-06-24 07:42:15768 MockConnect connect_data(SYNCHRONOUS, OK);
769 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59770 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6d116e1a2013-06-24 07:42:15771
bnc032658ba2016-09-26 18:17:15772 AddSSLSocketData();
773
[email protected]795cbf82013-07-22 09:37:27774 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]6d116e1a2013-06-24 07:42:15775
tfarina428341112016-09-22 13:38:20776 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26777 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52778 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18779 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]6d116e1a2013-06-24 07:42:15780
781 StreamDelegateDoNothing delegate(stream);
782 stream->SetDelegate(&delegate);
783
Ryan Hamilton0239aac2018-05-19 00:03:13784 spdy::SpdyHeaderBlock headers(
785 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnca2fbdc9b2016-11-22 21:14:26786 EXPECT_THAT(
787 stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
788 IsError(ERR_IO_PENDING));
[email protected]6d116e1a2013-06-24 07:42:15789
bnc4c214312016-11-28 16:49:15790 EXPECT_THAT(delegate.WaitForClose(), IsOk());
Ryan Hamilton0239aac2018-05-19 00:03:13791 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
Bence Béky4e83f492018-05-13 23:14:25792 EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
bnc4c214312016-11-28 16:49:15793 delegate.TakeReceivedData());
[email protected]6d116e1a2013-06-24 07:42:15794
bnceb9aa7112017-01-05 01:03:46795 // Finish async network reads and writes.
796 base::RunLoop().RunUntilIdle();
797
bnc4c214312016-11-28 16:49:15798 EXPECT_TRUE(data.AllWriteDataConsumed());
799 EXPECT_TRUE(data.AllReadDataConsumed());
[email protected]6d116e1a2013-06-24 07:42:15800}
801
bnc4c214312016-11-28 16:49:15802TEST_F(SpdyStreamTest, HeadersMustPreceedData) {
Ryan Hamilton0239aac2018-05-19 00:03:13803 spdy::SpdySerializedFrame req(
804 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnc4c214312016-11-28 16:49:15805 AddWrite(req);
806
807 // Response body not preceeded by headers: protocol error.
Ryan Hamilton0239aac2018-05-19 00:03:13808 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:19809 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bnc4c214312016-11-28 16:49:15810 AddRead(body);
811
Ryan Hamilton0239aac2018-05-19 00:03:13812 spdy::SpdySerializedFrame rst(
813 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bnc4c214312016-11-28 16:49:15814 AddWrite(rst);
815
816 AddReadEOF();
817
Ryan Sleevib8d7ea02018-05-07 20:01:01818 SequencedSocketData data(GetReads(), GetWrites());
bnc4c214312016-11-28 16:49:15819 MockConnect connect_data(SYNCHRONOUS, OK);
820 data.set_connect_data(connect_data);
821 session_deps_.socket_factory->AddSocketDataProvider(&data);
822
823 AddSSLSocketData();
824
825 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
826
827 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
828 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
829 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18830 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bnc4c214312016-11-28 16:49:15831
832 StreamDelegateDoNothing delegate(stream);
833 stream->SetDelegate(&delegate);
834
Ryan Hamilton0239aac2018-05-19 00:03:13835 spdy::SpdyHeaderBlock headers(
836 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnc4c214312016-11-28 16:49:15837 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
838 NO_MORE_DATA_TO_SEND));
bnc4c214312016-11-28 16:49:15839
840 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
841}
842
843TEST_F(SpdyStreamTest, HeadersMustPreceedDataOnPushedStream) {
Ryan Hamilton0239aac2018-05-19 00:03:13844 spdy::SpdySerializedFrame req(
845 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnca2fbdc9b2016-11-22 21:14:26846 AddWrite(req);
[email protected]6d116e1a2013-06-24 07:42:15847
Ryan Hamilton0239aac2018-05-19 00:03:13848 spdy::SpdySerializedFrame reply(
849 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:41850 AddRead(reply);
[email protected]6d116e1a2013-06-24 07:42:15851
Ryan Hamilton0239aac2018-05-19 00:03:13852 spdy::SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise(
Bence Békyf1d78522018-01-11 01:16:50853 1, 2, spdy_util_.ConstructGetHeaderBlock(kPushUrl)));
bnc4c214312016-11-28 16:49:15854 AddRead(push_promise);
[email protected]6d116e1a2013-06-24 07:42:15855
Ryan Hamilton0239aac2018-05-19 00:03:13856 spdy::SpdySerializedFrame priority(
tombergan5d22c182017-01-11 02:05:35857 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
858 AddWrite(priority);
859
Ryan Hamilton0239aac2018-05-19 00:03:13860 spdy::SpdySerializedFrame pushed_body(
Bence Békyd74f4382018-02-20 18:26:19861 spdy_util_.ConstructSpdyDataFrame(2, kPostBodyStringPiece, true));
bnc4c214312016-11-28 16:49:15862 AddRead(pushed_body);
mmenkee24011922015-12-17 22:12:59863
Ryan Hamilton0239aac2018-05-19 00:03:13864 spdy::SpdySerializedFrame rst(
865 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_PROTOCOL_ERROR));
bncdf80d44fd2016-07-15 20:27:41866 AddWrite(rst);
[email protected]6d116e1a2013-06-24 07:42:15867
Ryan Hamilton0239aac2018-05-19 00:03:13868 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:19869 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bnc4c214312016-11-28 16:49:15870 AddRead(body);
871
[email protected]6d116e1a2013-06-24 07:42:15872 AddReadEOF();
873
Ryan Sleevib8d7ea02018-05-07 20:01:01874 SequencedSocketData data(GetReads(), GetWrites());
[email protected]6d116e1a2013-06-24 07:42:15875 MockConnect connect_data(SYNCHRONOUS, OK);
876 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59877 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6d116e1a2013-06-24 07:42:15878
bnc032658ba2016-09-26 18:17:15879 AddSSLSocketData();
880
[email protected]795cbf82013-07-22 09:37:27881 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]6d116e1a2013-06-24 07:42:15882
tfarina428341112016-09-22 13:38:20883 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26884 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52885 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18886 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]6d116e1a2013-06-24 07:42:15887
888 StreamDelegateDoNothing delegate(stream);
889 stream->SetDelegate(&delegate);
890
Ryan Hamilton0239aac2018-05-19 00:03:13891 spdy::SpdyHeaderBlock headers(
892 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnca2fbdc9b2016-11-22 21:14:26893 EXPECT_THAT(
894 stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
895 IsError(ERR_IO_PENDING));
[email protected]6d116e1a2013-06-24 07:42:15896
bnc4c214312016-11-28 16:49:15897 EXPECT_THAT(delegate.WaitForClose(), IsOk());
Ryan Hamilton0239aac2018-05-19 00:03:13898 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
Bence Béky4e83f492018-05-13 23:14:25899 EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
bnc4c214312016-11-28 16:49:15900 delegate.TakeReceivedData());
[email protected]6d116e1a2013-06-24 07:42:15901
bnceb9aa7112017-01-05 01:03:46902 // Finish async network reads and writes.
903 base::RunLoop().RunUntilIdle();
904
bnc4c214312016-11-28 16:49:15905 EXPECT_TRUE(data.AllWriteDataConsumed());
906 EXPECT_TRUE(data.AllReadDataConsumed());
907}
[email protected]6d116e1a2013-06-24 07:42:15908
bnc4c214312016-11-28 16:49:15909TEST_F(SpdyStreamTest, TrailersMustNotFollowTrailers) {
Ryan Hamilton0239aac2018-05-19 00:03:13910 spdy::SpdySerializedFrame req(
911 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnc4c214312016-11-28 16:49:15912 AddWrite(req);
[email protected]6d116e1a2013-06-24 07:42:15913
Ryan Hamilton0239aac2018-05-19 00:03:13914 spdy::SpdySerializedFrame reply(
915 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bnc4c214312016-11-28 16:49:15916 AddRead(reply);
[email protected]6d116e1a2013-06-24 07:42:15917
Ryan Hamilton0239aac2018-05-19 00:03:13918 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:19919 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bnc4c214312016-11-28 16:49:15920 AddRead(body);
[email protected]6d116e1a2013-06-24 07:42:15921
Ryan Hamilton0239aac2018-05-19 00:03:13922 spdy::SpdyHeaderBlock trailers_block;
bnc4c214312016-11-28 16:49:15923 trailers_block["foo"] = "bar";
Ryan Hamilton0239aac2018-05-19 00:03:13924 spdy::SpdySerializedFrame first_trailers(
925 spdy_util_.ConstructSpdyResponseHeaders(1, std::move(trailers_block),
926 false));
bnc4c214312016-11-28 16:49:15927 AddRead(first_trailers);
928
929 // Trailers following trailers: procotol error.
Ryan Hamilton0239aac2018-05-19 00:03:13930 spdy::SpdySerializedFrame second_trailers(
931 spdy_util_.ConstructSpdyResponseHeaders(1, std::move(trailers_block),
932 true));
bnc4c214312016-11-28 16:49:15933 AddRead(second_trailers);
934
Ryan Hamilton0239aac2018-05-19 00:03:13935 spdy::SpdySerializedFrame rst(
936 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bnc4c214312016-11-28 16:49:15937 AddWrite(rst);
938
939 AddReadEOF();
940
Ryan Sleevib8d7ea02018-05-07 20:01:01941 SequencedSocketData data(GetReads(), GetWrites());
bnc4c214312016-11-28 16:49:15942 MockConnect connect_data(SYNCHRONOUS, OK);
943 data.set_connect_data(connect_data);
944 session_deps_.socket_factory->AddSocketDataProvider(&data);
945
946 AddSSLSocketData();
947
948 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
949
950 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
951 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
952 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18953 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bnc4c214312016-11-28 16:49:15954
955 StreamDelegateDoNothing delegate(stream);
956 stream->SetDelegate(&delegate);
957
Ryan Hamilton0239aac2018-05-19 00:03:13958 spdy::SpdyHeaderBlock headers(
959 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnc4c214312016-11-28 16:49:15960 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
961 NO_MORE_DATA_TO_SEND));
bnc4c214312016-11-28 16:49:15962
963 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
964
bnceb9aa7112017-01-05 01:03:46965 // Finish async network reads and writes.
966 base::RunLoop().RunUntilIdle();
967
bnc4c214312016-11-28 16:49:15968 EXPECT_TRUE(data.AllWriteDataConsumed());
969 EXPECT_TRUE(data.AllReadDataConsumed());
970}
971
972TEST_F(SpdyStreamTest, DataMustNotFollowTrailers) {
Ryan Hamilton0239aac2018-05-19 00:03:13973 spdy::SpdySerializedFrame req(
974 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnc4c214312016-11-28 16:49:15975 AddWrite(req);
976
Ryan Hamilton0239aac2018-05-19 00:03:13977 spdy::SpdySerializedFrame reply(
978 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bnc4c214312016-11-28 16:49:15979 AddRead(reply);
980
Ryan Hamilton0239aac2018-05-19 00:03:13981 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:19982 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bnc4c214312016-11-28 16:49:15983 AddRead(body);
984
Ryan Hamilton0239aac2018-05-19 00:03:13985 spdy::SpdyHeaderBlock trailers_block;
bnc4c214312016-11-28 16:49:15986 trailers_block["foo"] = "bar";
Ryan Hamilton0239aac2018-05-19 00:03:13987 spdy::SpdySerializedFrame trailers(spdy_util_.ConstructSpdyResponseHeaders(
bnc4c214312016-11-28 16:49:15988 1, std::move(trailers_block), false));
989 AddRead(trailers);
990
991 // DATA frame following trailers: protocol error.
992 AddRead(body);
993
Ryan Hamilton0239aac2018-05-19 00:03:13994 spdy::SpdySerializedFrame rst(
995 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bnc4c214312016-11-28 16:49:15996 AddWrite(rst);
997
998 AddReadEOF();
999
Ryan Sleevib8d7ea02018-05-07 20:01:011000 SequencedSocketData data(GetReads(), GetWrites());
bnc4c214312016-11-28 16:49:151001 MockConnect connect_data(SYNCHRONOUS, OK);
1002 data.set_connect_data(connect_data);
1003 session_deps_.socket_factory->AddSocketDataProvider(&data);
1004
1005 AddSSLSocketData();
1006
1007 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1008
1009 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1010 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1011 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181012 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bnc4c214312016-11-28 16:49:151013
1014 StreamDelegateDoNothing delegate(stream);
1015 stream->SetDelegate(&delegate);
1016
Ryan Hamilton0239aac2018-05-19 00:03:131017 spdy::SpdyHeaderBlock headers(
1018 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnc4c214312016-11-28 16:49:151019 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
1020 NO_MORE_DATA_TO_SEND));
bnc4c214312016-11-28 16:49:151021
1022 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
1023
bnceb9aa7112017-01-05 01:03:461024 // Finish async network reads and writes.
1025 base::RunLoop().RunUntilIdle();
1026
bnc4c214312016-11-28 16:49:151027 EXPECT_TRUE(data.AllWriteDataConsumed());
1028 EXPECT_TRUE(data.AllReadDataConsumed());
[email protected]6d116e1a2013-06-24 07:42:151029}
1030
bncc9f762a2016-12-06 20:38:231031TEST_F(SpdyStreamTest, InformationalHeaders) {
Ryan Hamilton0239aac2018-05-19 00:03:131032 spdy::SpdySerializedFrame req(
1033 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncc9f762a2016-12-06 20:38:231034 AddWrite(req);
1035
Ryan Hamilton0239aac2018-05-19 00:03:131036 spdy::SpdyHeaderBlock informational_headers;
bncc9f762a2016-12-06 20:38:231037 informational_headers[":status"] = "100";
Ryan Hamilton0239aac2018-05-19 00:03:131038 spdy::SpdySerializedFrame informational_response(
bncc9f762a2016-12-06 20:38:231039 spdy_util_.ConstructSpdyResponseHeaders(
1040 1, std::move(informational_headers), false));
1041 AddRead(informational_response);
1042
Ryan Hamilton0239aac2018-05-19 00:03:131043 spdy::SpdySerializedFrame reply(
1044 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncc9f762a2016-12-06 20:38:231045 AddRead(reply);
1046
Ryan Hamilton0239aac2018-05-19 00:03:131047 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:191048 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bncc9f762a2016-12-06 20:38:231049 AddRead(body);
1050
1051 AddReadEOF();
1052
Ryan Sleevib8d7ea02018-05-07 20:01:011053 SequencedSocketData data(GetReads(), GetWrites());
bncc9f762a2016-12-06 20:38:231054 MockConnect connect_data(SYNCHRONOUS, OK);
1055 data.set_connect_data(connect_data);
1056 session_deps_.socket_factory->AddSocketDataProvider(&data);
1057
1058 AddSSLSocketData();
1059
1060 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1061
1062 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1063 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1064 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181065 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bncc9f762a2016-12-06 20:38:231066
1067 StreamDelegateDoNothing delegate(stream);
1068 stream->SetDelegate(&delegate);
1069
Ryan Hamilton0239aac2018-05-19 00:03:131070 spdy::SpdyHeaderBlock headers(
1071 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bncc9f762a2016-12-06 20:38:231072 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
1073 NO_MORE_DATA_TO_SEND));
bncc9f762a2016-12-06 20:38:231074
1075 EXPECT_THAT(delegate.WaitForClose(), IsOk());
Ryan Hamilton0239aac2018-05-19 00:03:131076 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
Bence Béky4e83f492018-05-13 23:14:251077 EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
bncc9f762a2016-12-06 20:38:231078 delegate.TakeReceivedData());
1079
bnceb9aa7112017-01-05 01:03:461080 // Finish async network reads and writes.
1081 base::RunLoop().RunUntilIdle();
1082
bncc9f762a2016-12-06 20:38:231083 EXPECT_TRUE(data.AllWriteDataConsumed());
1084 EXPECT_TRUE(data.AllReadDataConsumed());
1085}
1086
bnc4ce149622017-03-30 03:31:011087TEST_F(SpdyStreamTest, StatusMustBeNumber) {
Ryan Hamilton0239aac2018-05-19 00:03:131088 spdy::SpdySerializedFrame req(
1089 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncc9f762a2016-12-06 20:38:231090 AddWrite(req);
1091
Ryan Hamilton0239aac2018-05-19 00:03:131092 spdy::SpdyHeaderBlock incorrect_headers;
bncc9f762a2016-12-06 20:38:231093 incorrect_headers[":status"] = "nan";
Ryan Hamilton0239aac2018-05-19 00:03:131094 spdy::SpdySerializedFrame reply(spdy_util_.ConstructSpdyResponseHeaders(
bncc9f762a2016-12-06 20:38:231095 1, std::move(incorrect_headers), false));
1096 AddRead(reply);
1097
Ryan Hamilton0239aac2018-05-19 00:03:131098 spdy::SpdySerializedFrame rst(
1099 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bncc9f762a2016-12-06 20:38:231100 AddWrite(rst);
1101
1102 AddReadEOF();
1103
Ryan Sleevib8d7ea02018-05-07 20:01:011104 SequencedSocketData data(GetReads(), GetWrites());
bncc9f762a2016-12-06 20:38:231105 MockConnect connect_data(SYNCHRONOUS, OK);
1106 data.set_connect_data(connect_data);
1107 session_deps_.socket_factory->AddSocketDataProvider(&data);
1108
1109 AddSSLSocketData();
1110
1111 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1112
1113 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1114 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1115 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181116 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bncc9f762a2016-12-06 20:38:231117
1118 StreamDelegateDoNothing delegate(stream);
1119 stream->SetDelegate(&delegate);
1120
Ryan Hamilton0239aac2018-05-19 00:03:131121 spdy::SpdyHeaderBlock headers(
1122 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bncc9f762a2016-12-06 20:38:231123 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
1124 NO_MORE_DATA_TO_SEND));
bncc9f762a2016-12-06 20:38:231125
1126 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
1127
bnceb9aa7112017-01-05 01:03:461128 // Finish async network reads and writes.
1129 base::RunLoop().RunUntilIdle();
1130
bncc9f762a2016-12-06 20:38:231131 EXPECT_TRUE(data.AllWriteDataConsumed());
1132 EXPECT_TRUE(data.AllReadDataConsumed());
1133}
1134
bnc4ce149622017-03-30 03:31:011135TEST_F(SpdyStreamTest, StatusCannotHaveExtraText) {
Ryan Hamilton0239aac2018-05-19 00:03:131136 spdy::SpdySerializedFrame req(
1137 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnc50ee38e2016-12-08 01:23:541138 AddWrite(req);
1139
Ryan Hamilton0239aac2018-05-19 00:03:131140 spdy::SpdyHeaderBlock headers_with_status_text;
bnc50ee38e2016-12-08 01:23:541141 headers_with_status_text[":status"] =
1142 "200 Some random extra text describing status";
Ryan Hamilton0239aac2018-05-19 00:03:131143 spdy::SpdySerializedFrame reply(spdy_util_.ConstructSpdyResponseHeaders(
bnc50ee38e2016-12-08 01:23:541144 1, std::move(headers_with_status_text), false));
1145 AddRead(reply);
1146
Ryan Hamilton0239aac2018-05-19 00:03:131147 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:191148 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bnc50ee38e2016-12-08 01:23:541149 AddRead(body);
1150
Ryan Hamilton0239aac2018-05-19 00:03:131151 spdy::SpdySerializedFrame rst(
1152 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bnc4ce149622017-03-30 03:31:011153 AddWrite(rst);
1154
bnc50ee38e2016-12-08 01:23:541155 AddReadEOF();
1156
Ryan Sleevib8d7ea02018-05-07 20:01:011157 SequencedSocketData data(GetReads(), GetWrites());
bnc50ee38e2016-12-08 01:23:541158 MockConnect connect_data(SYNCHRONOUS, OK);
1159 data.set_connect_data(connect_data);
1160 session_deps_.socket_factory->AddSocketDataProvider(&data);
1161
1162 AddSSLSocketData();
1163
1164 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1165
1166 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1167 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1168 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181169 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bnc50ee38e2016-12-08 01:23:541170
1171 StreamDelegateDoNothing delegate(stream);
1172 stream->SetDelegate(&delegate);
1173
Ryan Hamilton0239aac2018-05-19 00:03:131174 spdy::SpdyHeaderBlock headers(
1175 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnc50ee38e2016-12-08 01:23:541176 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
1177 NO_MORE_DATA_TO_SEND));
bnc50ee38e2016-12-08 01:23:541178
bnc4ce149622017-03-30 03:31:011179 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
1180
1181 // Finish async network reads and writes.
1182 base::RunLoop().RunUntilIdle();
1183
1184 EXPECT_TRUE(data.AllWriteDataConsumed());
1185 EXPECT_TRUE(data.AllReadDataConsumed());
1186}
1187
1188TEST_F(SpdyStreamTest, StatusMustBePresent) {
Ryan Hamilton0239aac2018-05-19 00:03:131189 spdy::SpdySerializedFrame req(
1190 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnc4ce149622017-03-30 03:31:011191 AddWrite(req);
1192
Ryan Hamilton0239aac2018-05-19 00:03:131193 spdy::SpdyHeaderBlock headers_without_status;
1194 spdy::SpdySerializedFrame reply(spdy_util_.ConstructSpdyResponseHeaders(
bnc4ce149622017-03-30 03:31:011195 1, std::move(headers_without_status), false));
1196 AddRead(reply);
1197
Ryan Hamilton0239aac2018-05-19 00:03:131198 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:191199 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bnc4ce149622017-03-30 03:31:011200 AddRead(body);
1201
Ryan Hamilton0239aac2018-05-19 00:03:131202 spdy::SpdySerializedFrame rst(
1203 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bnc4ce149622017-03-30 03:31:011204 AddWrite(rst);
1205
1206 AddReadEOF();
1207
Ryan Sleevib8d7ea02018-05-07 20:01:011208 SequencedSocketData data(GetReads(), GetWrites());
bnc4ce149622017-03-30 03:31:011209 MockConnect connect_data(SYNCHRONOUS, OK);
1210 data.set_connect_data(connect_data);
1211 session_deps_.socket_factory->AddSocketDataProvider(&data);
1212
1213 AddSSLSocketData();
1214
1215 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1216
1217 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1218 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1219 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181220 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bnc4ce149622017-03-30 03:31:011221
1222 StreamDelegateDoNothing delegate(stream);
1223 stream->SetDelegate(&delegate);
1224
Ryan Hamilton0239aac2018-05-19 00:03:131225 spdy::SpdyHeaderBlock headers(
1226 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnc4ce149622017-03-30 03:31:011227 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
1228 NO_MORE_DATA_TO_SEND));
bnc4ce149622017-03-30 03:31:011229
1230 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
bnc50ee38e2016-12-08 01:23:541231
bnceb9aa7112017-01-05 01:03:461232 // Finish async network reads and writes.
1233 base::RunLoop().RunUntilIdle();
1234
bnc50ee38e2016-12-08 01:23:541235 EXPECT_TRUE(data.AllWriteDataConsumed());
1236 EXPECT_TRUE(data.AllReadDataConsumed());
1237}
1238
bnca2fbdc9b2016-11-22 21:14:261239// Call IncreaseSendWindowSize on a stream with a large enough delta to overflow
1240// an int32_t. The SpdyStream should handle that case gracefully.
bncd16676a2016-07-20 16:23:011241TEST_F(SpdyStreamTest, IncreaseSendWindowSizeOverflow) {
Ryan Hamilton0239aac2018-05-19 00:03:131242 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:261243 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:411244 AddWrite(req);
[email protected]3d587372013-06-01 04:31:451245
mmenkee24011922015-12-17 22:12:591246 AddReadPause();
1247
[email protected]1e5ebd82013-02-20 20:07:241248 // Triggered by the overflowing call to IncreaseSendWindowSize
1249 // below.
Ryan Hamilton0239aac2018-05-19 00:03:131250 spdy::SpdySerializedFrame rst(spdy_util_.ConstructSpdyRstStream(
1251 1, spdy::ERROR_CODE_FLOW_CONTROL_ERROR));
bncdf80d44fd2016-07-15 20:27:411252 AddWrite(rst);
[email protected]3d587372013-06-01 04:31:451253
1254 AddReadEOF();
[email protected]1e5ebd82013-02-20 20:07:241255
vishal.b62985ca92015-04-17 08:45:511256 BoundTestNetLog log;
[email protected]1e5ebd82013-02-20 20:07:241257
Ryan Sleevib8d7ea02018-05-07 20:01:011258 SequencedSocketData data(GetReads(), GetWrites());
[email protected]1e5ebd82013-02-20 20:07:241259 MockConnect connect_data(SYNCHRONOUS, OK);
1260 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:591261 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1e5ebd82013-02-20 20:07:241262
bnc032658ba2016-09-26 18:17:151263 AddSSLSocketData();
1264
[email protected]795cbf82013-07-22 09:37:271265 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]1e5ebd82013-02-20 20:07:241266
bnca2fbdc9b2016-11-22 21:14:261267 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1268 SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, log.bound());
wezca1070932016-05-26 20:30:521269 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181270 EXPECT_EQ(kDefaultUrl, stream->url().spec());
1271
[email protected]194cfcf2013-05-23 21:44:441272 StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
[email protected]1c6b12a2013-03-21 00:59:111273 stream->SetDelegate(&delegate);
[email protected]1e5ebd82013-02-20 20:07:241274
Ryan Hamilton0239aac2018-05-19 00:03:131275 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:261276 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
1277 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
1278 IsError(ERR_IO_PENDING));
[email protected]1c12c062013-05-14 23:13:481279
mmenkee24011922015-12-17 22:12:591280 data.RunUntilPaused();
[email protected]1e5ebd82013-02-20 20:07:241281
avid0181f32015-12-10 19:41:471282 int32_t old_send_window_size = stream->send_window_size();
[email protected]1e5ebd82013-02-20 20:07:241283 ASSERT_GT(old_send_window_size, 0);
avid0181f32015-12-10 19:41:471284 int32_t delta_window_size =
1285 std::numeric_limits<int32_t>::max() - old_send_window_size + 1;
[email protected]1e5ebd82013-02-20 20:07:241286 stream->IncreaseSendWindowSize(delta_window_size);
bnca2fbdc9b2016-11-22 21:14:261287 EXPECT_FALSE(stream);
[email protected]1e5ebd82013-02-20 20:07:241288
mmenkee24011922015-12-17 22:12:591289 data.Resume();
1290 base::RunLoop().RunUntilIdle();
[email protected]1c12c062013-05-14 23:13:481291
Bence Béky6b9c1352018-05-10 11:51:251292 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_FLOW_CONTROL_ERROR));
[email protected]1e5ebd82013-02-20 20:07:241293}
1294
[email protected]d2de7da2013-05-22 07:49:561295// Functions used with
1296// RunResumeAfterUnstall{RequestResponse,Bidirectional}Test().
1297
1298void StallStream(const base::WeakPtr<SpdyStream>& stream) {
1299 // Reduce the send window size to 0 to stall.
1300 while (stream->send_window_size() > 0) {
1301 stream->DecreaseSendWindowSize(
1302 std::min(kMaxSpdyFrameChunkSize, stream->send_window_size()));
1303 }
1304}
1305
1306void IncreaseStreamSendWindowSize(const base::WeakPtr<SpdyStream>& stream,
avid0181f32015-12-10 19:41:471307 int32_t delta_window_size) {
[email protected]d2de7da2013-05-22 07:49:561308 EXPECT_TRUE(stream->send_stalled_by_flow_control());
1309 stream->IncreaseSendWindowSize(delta_window_size);
1310 EXPECT_FALSE(stream->send_stalled_by_flow_control());
1311}
1312
1313void AdjustStreamSendWindowSize(const base::WeakPtr<SpdyStream>& stream,
avid0181f32015-12-10 19:41:471314 int32_t delta_window_size) {
[email protected]d2de7da2013-05-22 07:49:561315 // Make sure that negative adjustments are handled properly.
1316 EXPECT_TRUE(stream->send_stalled_by_flow_control());
Bence Béky05dcb0382017-09-15 20:07:581317 EXPECT_TRUE(stream->AdjustSendWindowSize(-delta_window_size));
[email protected]d2de7da2013-05-22 07:49:561318 EXPECT_TRUE(stream->send_stalled_by_flow_control());
Bence Béky05dcb0382017-09-15 20:07:581319 EXPECT_TRUE(stream->AdjustSendWindowSize(+delta_window_size));
[email protected]d2de7da2013-05-22 07:49:561320 EXPECT_TRUE(stream->send_stalled_by_flow_control());
Bence Béky05dcb0382017-09-15 20:07:581321 EXPECT_TRUE(stream->AdjustSendWindowSize(+delta_window_size));
[email protected]d2de7da2013-05-22 07:49:561322 EXPECT_FALSE(stream->send_stalled_by_flow_control());
1323}
1324
1325// Given an unstall function, runs a test to make sure that a
1326// request/response (i.e., an HTTP-like) stream resumes after a stall
1327// and unstall.
[email protected]3d587372013-06-01 04:31:451328void SpdyStreamTest::RunResumeAfterUnstallRequestResponseTest(
[email protected]d2de7da2013-05-22 07:49:561329 const UnstallFunction& unstall_function) {
Ryan Hamilton0239aac2018-05-19 00:03:131330 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:261331 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:411332 AddWrite(req);
[email protected]3d587372013-06-01 04:31:451333
Ryan Hamilton0239aac2018-05-19 00:03:131334 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:191335 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bncdf80d44fd2016-07-15 20:27:411336 AddWrite(body);
[email protected]34a4dea2013-03-13 00:42:301337
Ryan Hamilton0239aac2018-05-19 00:03:131338 spdy::SpdySerializedFrame resp(
1339 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:411340 AddRead(resp);
[email protected]34a4dea2013-03-13 00:42:301341
[email protected]3d587372013-06-01 04:31:451342 AddReadEOF();
1343
Ryan Sleevib8d7ea02018-05-07 20:01:011344 SequencedSocketData data(GetReads(), GetWrites());
[email protected]34a4dea2013-03-13 00:42:301345 MockConnect connect_data(SYNCHRONOUS, OK);
1346 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:591347 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]34a4dea2013-03-13 00:42:301348
bnc032658ba2016-09-26 18:17:151349 AddSSLSocketData();
1350
[email protected]795cbf82013-07-22 09:37:271351 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]34a4dea2013-03-13 00:42:301352
tfarina428341112016-09-22 13:38:201353 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:261354 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:521355 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181356 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]34a4dea2013-03-13 00:42:301357
[email protected]d26ff352013-05-13 08:48:281358 StreamDelegateWithBody delegate(stream, kPostBodyStringPiece);
[email protected]34a4dea2013-03-13 00:42:301359 stream->SetDelegate(&delegate);
1360
[email protected]1c6b12a2013-03-21 00:59:111361 EXPECT_FALSE(stream->send_stalled_by_flow_control());
[email protected]34a4dea2013-03-13 00:42:301362
Ryan Hamilton0239aac2018-05-19 00:03:131363 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:261364 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
1365 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
1366 IsError(ERR_IO_PENDING));
[email protected]34a4dea2013-03-13 00:42:301367
[email protected]d2de7da2013-05-22 07:49:561368 StallStream(stream);
1369
mmenkee24011922015-12-17 22:12:591370 base::RunLoop().RunUntilIdle();
[email protected]34a4dea2013-03-13 00:42:301371
[email protected]1c6b12a2013-03-21 00:59:111372 EXPECT_TRUE(stream->send_stalled_by_flow_control());
[email protected]34a4dea2013-03-13 00:42:301373
[email protected]d2de7da2013-05-22 07:49:561374 unstall_function.Run(stream, kPostBodyLength);
[email protected]34a4dea2013-03-13 00:42:301375
[email protected]1c6b12a2013-03-21 00:59:111376 EXPECT_FALSE(stream->send_stalled_by_flow_control());
[email protected]34a4dea2013-03-13 00:42:301377
robpercival214763f2016-07-01 23:27:011378 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
[email protected]34a4dea2013-03-13 00:42:301379
1380 EXPECT_TRUE(delegate.send_headers_completed());
1381 EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status"));
Bence Béky4e83f492018-05-13 23:14:251382 EXPECT_EQ(std::string(), delegate.TakeReceivedData());
rch37de576c2015-05-17 20:28:171383 EXPECT_TRUE(data.AllWriteDataConsumed());
[email protected]cbdd73162013-03-18 23:27:331384}
1385
bncd16676a2016-07-20 16:23:011386TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeIncreaseRequestResponse) {
[email protected]d2de7da2013-05-22 07:49:561387 RunResumeAfterUnstallRequestResponseTest(
1388 base::Bind(&IncreaseStreamSendWindowSize));
1389}
1390
bncd16676a2016-07-20 16:23:011391TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeAdjustRequestResponse) {
[email protected]d2de7da2013-05-22 07:49:561392 RunResumeAfterUnstallRequestResponseTest(
1393 base::Bind(&AdjustStreamSendWindowSize));
1394}
1395
bnca2fbdc9b2016-11-22 21:14:261396// Given an unstall function, runs a test to make sure that a bidirectional
1397// (i.e., non-HTTP-like) stream resumes after a stall and unstall.
[email protected]3d587372013-06-01 04:31:451398void SpdyStreamTest::RunResumeAfterUnstallBidirectionalTest(
[email protected]d2de7da2013-05-22 07:49:561399 const UnstallFunction& unstall_function) {
Ryan Hamilton0239aac2018-05-19 00:03:131400 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:261401 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:411402 AddWrite(req);
[email protected]3d587372013-06-01 04:31:451403
mmenkee24011922015-12-17 22:12:591404 AddReadPause();
1405
Ryan Hamilton0239aac2018-05-19 00:03:131406 spdy::SpdySerializedFrame resp(
1407 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:411408 AddRead(resp);
[email protected]3d587372013-06-01 04:31:451409
Ryan Hamilton0239aac2018-05-19 00:03:131410 spdy::SpdySerializedFrame msg(
Bence Békyd74f4382018-02-20 18:26:191411 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bncdf80d44fd2016-07-15 20:27:411412 AddWrite(msg);
[email protected]cbdd73162013-03-18 23:27:331413
Ryan Hamilton0239aac2018-05-19 00:03:131414 spdy::SpdySerializedFrame echo(
Bence Békyd74f4382018-02-20 18:26:191415 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bncdf80d44fd2016-07-15 20:27:411416 AddRead(echo);
[email protected]cbdd73162013-03-18 23:27:331417
[email protected]3d587372013-06-01 04:31:451418 AddReadEOF();
1419
Ryan Sleevib8d7ea02018-05-07 20:01:011420 SequencedSocketData data(GetReads(), GetWrites());
[email protected]cbdd73162013-03-18 23:27:331421 MockConnect connect_data(SYNCHRONOUS, OK);
1422 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:591423 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]cbdd73162013-03-18 23:27:331424
bnc032658ba2016-09-26 18:17:151425 AddSSLSocketData();
1426
[email protected]795cbf82013-07-22 09:37:271427 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]cbdd73162013-03-18 23:27:331428
tfarina428341112016-09-22 13:38:201429 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:261430 SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:521431 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181432 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]cbdd73162013-03-18 23:27:331433
[email protected]194cfcf2013-05-23 21:44:441434 StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
[email protected]cbdd73162013-03-18 23:27:331435 stream->SetDelegate(&delegate);
1436
Ryan Hamilton0239aac2018-05-19 00:03:131437 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:261438 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
1439 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
1440 IsError(ERR_IO_PENDING));
[email protected]cbdd73162013-03-18 23:27:331441
mmenkee24011922015-12-17 22:12:591442 data.RunUntilPaused();
[email protected]cbdd73162013-03-18 23:27:331443
[email protected]1c6b12a2013-03-21 00:59:111444 EXPECT_FALSE(stream->send_stalled_by_flow_control());
[email protected]cbdd73162013-03-18 23:27:331445
[email protected]d2de7da2013-05-22 07:49:561446 StallStream(stream);
[email protected]cbdd73162013-03-18 23:27:331447
mmenkee24011922015-12-17 22:12:591448 data.Resume();
1449 base::RunLoop().RunUntilIdle();
[email protected]cbdd73162013-03-18 23:27:331450
[email protected]1c6b12a2013-03-21 00:59:111451 EXPECT_TRUE(stream->send_stalled_by_flow_control());
[email protected]cbdd73162013-03-18 23:27:331452
[email protected]d2de7da2013-05-22 07:49:561453 unstall_function.Run(stream, kPostBodyLength);
[email protected]cbdd73162013-03-18 23:27:331454
[email protected]1c6b12a2013-03-21 00:59:111455 EXPECT_FALSE(stream->send_stalled_by_flow_control());
[email protected]cbdd73162013-03-18 23:27:331456
robpercival214763f2016-07-01 23:27:011457 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
[email protected]cbdd73162013-03-18 23:27:331458
1459 EXPECT_TRUE(delegate.send_headers_completed());
1460 EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status"));
Bence Béky4e83f492018-05-13 23:14:251461 EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
[email protected]09a8d9172013-04-17 19:23:491462 delegate.TakeReceivedData());
rch37de576c2015-05-17 20:28:171463 EXPECT_TRUE(data.AllWriteDataConsumed());
[email protected]d2de7da2013-05-22 07:49:561464}
1465
bncd16676a2016-07-20 16:23:011466TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeIncreaseBidirectional) {
[email protected]d2de7da2013-05-22 07:49:561467 RunResumeAfterUnstallBidirectionalTest(
1468 base::Bind(&IncreaseStreamSendWindowSize));
1469}
1470
bncd16676a2016-07-20 16:23:011471TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeAdjustBidirectional) {
[email protected]d2de7da2013-05-22 07:49:561472 RunResumeAfterUnstallBidirectionalTest(
1473 base::Bind(&AdjustStreamSendWindowSize));
[email protected]34a4dea2013-03-13 00:42:301474}
1475
[email protected]533f0de2013-12-09 23:03:361476// Test calculation of amount of bytes received from network.
bncd16676a2016-07-20 16:23:011477TEST_F(SpdyStreamTest, ReceivedBytes) {
Ryan Hamilton0239aac2018-05-19 00:03:131478 spdy::SpdySerializedFrame req(
1479 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnca2fbdc9b2016-11-22 21:14:261480 AddWrite(req);
[email protected]533f0de2013-12-09 23:03:361481
mmenkee24011922015-12-17 22:12:591482 AddReadPause();
1483
Ryan Hamilton0239aac2018-05-19 00:03:131484 spdy::SpdySerializedFrame reply(
1485 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:411486 AddRead(reply);
[email protected]533f0de2013-12-09 23:03:361487
mmenkee24011922015-12-17 22:12:591488 AddReadPause();
1489
Ryan Hamilton0239aac2018-05-19 00:03:131490 spdy::SpdySerializedFrame msg(
Bence Békyd74f4382018-02-20 18:26:191491 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bncdf80d44fd2016-07-15 20:27:411492 AddRead(msg);
[email protected]533f0de2013-12-09 23:03:361493
mmenkee24011922015-12-17 22:12:591494 AddReadPause();
1495
[email protected]533f0de2013-12-09 23:03:361496 AddReadEOF();
1497
Ryan Sleevib8d7ea02018-05-07 20:01:011498 SequencedSocketData data(GetReads(), GetWrites());
[email protected]533f0de2013-12-09 23:03:361499 MockConnect connect_data(SYNCHRONOUS, OK);
1500 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:591501 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]533f0de2013-12-09 23:03:361502
bnc032658ba2016-09-26 18:17:151503 AddSSLSocketData();
1504
[email protected]533f0de2013-12-09 23:03:361505 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1506
tfarina428341112016-09-22 13:38:201507 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:261508 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:521509 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181510 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]533f0de2013-12-09 23:03:361511
1512 StreamDelegateDoNothing delegate(stream);
1513 stream->SetDelegate(&delegate);
1514
Ryan Hamilton0239aac2018-05-19 00:03:131515 spdy::SpdyHeaderBlock headers(
1516 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnca2fbdc9b2016-11-22 21:14:261517 EXPECT_THAT(
1518 stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
1519 IsError(ERR_IO_PENDING));
[email protected]533f0de2013-12-09 23:03:361520
bncdf80d44fd2016-07-15 20:27:411521 int64_t reply_frame_len = reply.size();
Ryan Hamilton0239aac2018-05-19 00:03:131522 int64_t data_header_len = spdy::kDataFrameMinimumSize;
avid0181f32015-12-10 19:41:471523 int64_t data_frame_len = data_header_len + kPostBodyLength;
1524 int64_t response_len = reply_frame_len + data_frame_len;
[email protected]533f0de2013-12-09 23:03:361525
1526 EXPECT_EQ(0, stream->raw_received_bytes());
[email protected]533f0de2013-12-09 23:03:361527
bnca2fbdc9b2016-11-22 21:14:261528 // REQUEST
mmenkee24011922015-12-17 22:12:591529 data.RunUntilPaused();
1530 EXPECT_EQ(0, stream->raw_received_bytes());
1531
1532 // REPLY
1533 data.Resume();
1534 data.RunUntilPaused();
1535 EXPECT_EQ(reply_frame_len, stream->raw_received_bytes());
1536
1537 // DATA
1538 data.Resume();
1539 data.RunUntilPaused();
1540 EXPECT_EQ(response_len, stream->raw_received_bytes());
1541
1542 // FIN
1543 data.Resume();
robpercival214763f2016-07-01 23:27:011544 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
[email protected]533f0de2013-12-09 23:03:361545}
1546
Bence Békycf3fd8a42018-02-09 20:15:471547// Regression test for https://crbug.com/810763.
1548TEST_F(SpdyStreamTest, DataOnHalfClosedRemoveStream) {
Ryan Hamilton0239aac2018-05-19 00:03:131549 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
Bence Békycf3fd8a42018-02-09 20:15:471550 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
1551 AddWrite(req);
1552
Ryan Hamilton0239aac2018-05-19 00:03:131553 spdy::SpdyHeaderBlock response_headers;
1554 response_headers[spdy::kHttp2StatusHeader] = "200";
1555 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
Bence Békycf3fd8a42018-02-09 20:15:471556 1, std::move(response_headers), /* fin = */ true));
1557 AddRead(resp);
1558
Ryan Hamilton0239aac2018-05-19 00:03:131559 spdy::SpdySerializedFrame data_frame(
Bence Békyd74f4382018-02-20 18:26:191560 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
Bence Békycf3fd8a42018-02-09 20:15:471561 AddRead(data_frame);
1562
Ryan Hamilton0239aac2018-05-19 00:03:131563 spdy::SpdySerializedFrame rst(
1564 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_STREAM_CLOSED));
Bence Békycf3fd8a42018-02-09 20:15:471565 AddWrite(rst);
1566
1567 AddReadEOF();
1568
Ryan Sleevib8d7ea02018-05-07 20:01:011569 SequencedSocketData data(GetReads(), GetWrites());
Bence Békycf3fd8a42018-02-09 20:15:471570 MockConnect connect_data(SYNCHRONOUS, OK);
1571 data.set_connect_data(connect_data);
1572 session_deps_.socket_factory->AddSocketDataProvider(&data);
1573
1574 AddSSLSocketData();
1575
1576 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1577
1578 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1579 SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
1580 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181581 EXPECT_EQ(kDefaultUrl, stream->url().spec());
Bence Békycf3fd8a42018-02-09 20:15:471582
1583 StreamDelegateDoNothing delegate(stream);
1584 stream->SetDelegate(&delegate);
1585
Ryan Hamilton0239aac2018-05-19 00:03:131586 spdy::SpdyHeaderBlock headers(
Bence Békycf3fd8a42018-02-09 20:15:471587 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
1588 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
1589 IsError(ERR_IO_PENDING));
Bence Békycf3fd8a42018-02-09 20:15:471590
Bence Béky6b9c1352018-05-10 11:51:251591 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_STREAM_CLOSED));
Bence Békycf3fd8a42018-02-09 20:15:471592
1593 base::RunLoop().RunUntilIdle();
1594
1595 EXPECT_TRUE(data.AllReadDataConsumed());
1596 EXPECT_TRUE(data.AllWriteDataConsumed());
1597}
1598
[email protected]39d13d942012-07-19 16:48:201599} // namespace test
1600
[email protected]4f386422010-07-20 04:19:491601} // namespace net