blob: d29a5b96600dabcd3506379ad84e6cd885e08eb8 [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"
Avi Drissman4365a4782018-12-28 19:26:2419#include "base/stl_util.h"
Bence Béky4e83f492018-05-13 23:14:2520#include "base/strings/string_piece.h"
[email protected]1bbabc82013-03-25 21:11:0221#include "net/base/request_priority.h"
Bence Béky5b1e4ce72018-01-11 14:55:1522#include "net/http/http_request_info.h"
mikecirone8b85c432016-09-08 19:11:0023#include "net/log/net_log_event_type.h"
mmenke16a7cbdd2015-04-24 23:00:5624#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4625#include "net/log/test_net_log_entry.h"
26#include "net/log/test_net_log_util.h"
Paul Jensena457017a2018-01-19 23:52:0427#include "net/socket/socket_tag.h"
[email protected]6fe2e992013-06-12 03:38:4328#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5829#include "net/spdy/buffered_spdy_framer.h"
30#include "net/spdy/http2_push_promise_index.h"
31#include "net/spdy/spdy_http_utils.h"
32#include "net/spdy/spdy_session.h"
33#include "net/spdy/spdy_session_pool.h"
34#include "net/spdy/spdy_stream_test_util.h"
35#include "net/spdy/spdy_test_util_common.h"
bnc032658ba2016-09-26 18:17:1536#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0137#include "net/test/gtest_util.h"
bnc032658ba2016-09-26 18:17:1538#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0139#include "net/test/test_with_scoped_task_environment.h"
Ryan Hamilton2e003eea2018-05-02 00:24:2940#include "net/third_party/spdy/core/spdy_protocol.h"
robpercival214763f2016-07-01 23:27:0141#include "testing/gmock/include/gmock/gmock.h"
[email protected]4f386422010-07-20 04:19:4942#include "testing/gtest/include/gtest/gtest.h"
43
[email protected]4f386422010-07-20 04:19:4944// TODO(ukai): factor out common part with spdy_http_stream_unittest.cc
[email protected]b9ec6882011-07-01 07:40:2645//
46namespace net {
[email protected]4f386422010-07-20 04:19:4947
[email protected]34a4dea2013-03-13 00:42:3048namespace test {
49
[email protected]4f386422010-07-20 04:19:4950namespace {
51
bnca2fbdc9b2016-11-22 21:14:2652const char kPushUrl[] = "https://www.example.org/push";
[email protected]cbdd73162013-03-18 23:27:3353const char kPostBody[] = "\0hello!\xff";
Avi Drissman4365a4782018-12-28 19:26:2454const size_t kPostBodyLength = base::size(kPostBody);
Bence Béky4e83f492018-05-13 23:14:2555const base::StringPiece kPostBodyStringPiece(kPostBody, kPostBodyLength);
[email protected]39d13d942012-07-19 16:48:2056
bnca2fbdc9b2016-11-22 21:14:2657static base::TimeTicks g_time_now;
58
59base::TimeTicks InstantaneousReads() {
60 return g_time_now;
61}
62
rdsmithebb50aa2015-11-12 03:44:3863} // namespace
64
Bence Béky98447b12018-05-08 03:14:0165class SpdyStreamTest : public TestWithScopedTaskEnvironment {
[email protected]4f386422010-07-20 04:19:4966 protected:
[email protected]d2de7da2013-05-22 07:49:5667 // A function that takes a SpdyStream and the number of bytes which
68 // will unstall the next frame completely.
avid0181f32015-12-10 19:41:4769 typedef base::Callback<void(const base::WeakPtr<SpdyStream>&, int32_t)>
[email protected]d2de7da2013-05-22 07:49:5670 UnstallFunction;
71
bnca2fbdc9b2016-11-22 21:14:2672 SpdyStreamTest()
73 : url_(kDefaultUrl),
74 session_(SpdySessionDependencies::SpdyCreateSession(&session_deps_)),
75 offset_(0),
76 ssl_(SYNCHRONOUS, OK) {}
rdsmithebb50aa2015-11-12 03:44:3877
Chris Watkins61914cb2017-12-01 19:59:0078 ~SpdyStreamTest() override = default;
[email protected]4f386422010-07-20 04:19:4979
[email protected]795cbf82013-07-22 09:37:2780 base::WeakPtr<SpdySession> CreateDefaultSpdySession() {
bnca2fbdc9b2016-11-22 21:14:2681 SpdySessionKey key(HostPortPair::FromURL(url_), ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1182 PRIVACY_MODE_DISABLED,
83 SpdySessionKey::IsProxySession::kFalse, SocketTag());
Bence Béky0ef1556e2017-06-30 19:52:5284 return CreateSpdySession(session_.get(), key, NetLogWithSource());
[email protected]34a4dea2013-03-13 00:42:3085 }
86
fdoray92e35a72016-06-10 15:54:5587 void TearDown() override { base::RunLoop().RunUntilIdle(); }
[email protected]4f386422010-07-20 04:19:4988
[email protected]d2de7da2013-05-22 07:49:5689 void RunResumeAfterUnstallRequestResponseTest(
90 const UnstallFunction& unstall_function);
91
92 void RunResumeAfterUnstallBidirectionalTest(
93 const UnstallFunction& unstall_function);
94
[email protected]3d587372013-06-01 04:31:4595 // Add{Read,Write}() populates lists that are eventually passed to a
96 // SocketData class. |frame| must live for the whole test.
97
Ryan Hamilton0239aac2018-05-19 00:03:1398 void AddRead(const spdy::SpdySerializedFrame& frame) {
[email protected]3d587372013-06-01 04:31:4599 reads_.push_back(CreateMockRead(frame, offset_++));
100 }
101
Ryan Hamilton0239aac2018-05-19 00:03:13102 void AddWrite(const spdy::SpdySerializedFrame& frame) {
[email protected]3d587372013-06-01 04:31:45103 writes_.push_back(CreateMockWrite(frame, offset_++));
104 }
105
106 void AddReadEOF() {
107 reads_.push_back(MockRead(ASYNC, 0, offset_++));
108 }
109
mmenkee24011922015-12-17 22:12:59110 void AddWritePause() {
111 writes_.push_back(MockWrite(ASYNC, ERR_IO_PENDING, offset_++));
112 }
113
114 void AddReadPause() {
115 reads_.push_back(MockRead(ASYNC, ERR_IO_PENDING, offset_++));
116 }
117
Ryan Sleevib8d7ea02018-05-07 20:01:01118 base::span<const MockRead> GetReads() { return reads_; }
119 base::span<const MockWrite> GetWrites() { return writes_; }
[email protected]3d587372013-06-01 04:31:45120
caseqe8340bc92016-04-20 00:02:57121 void ActivatePushStream(SpdySession* session, SpdyStream* stream) {
122 std::unique_ptr<SpdyStream> activated =
123 session->ActivateCreatedStream(stream);
124 activated->set_stream_id(2);
125 session->InsertActivatedStream(std::move(activated));
126 }
127
bnc032658ba2016-09-26 18:17:15128 void AddSSLSocketData() {
129 // Load a cert that is valid for
130 // www.example.org, mail.example.org, and mail.example.com.
Ryan Sleevi4f832092017-11-21 23:25:49131 ssl_.ssl_info.cert =
132 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
133 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15134 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
135 }
136
Bence Béky7bf94362018-01-10 13:19:36137 static size_t num_pushed_streams(base::WeakPtr<SpdySession> session) {
138 return session->num_pushed_streams_;
139 }
140
141 static SpdySessionPool* spdy_session_pool(
142 base::WeakPtr<SpdySession> session) {
143 return session->pool_;
144 }
145
bnca2fbdc9b2016-11-22 21:14:26146 const GURL url_;
[email protected]a4a67772013-05-08 22:56:07147 SpdyTestUtil spdy_util_;
[email protected]34a4dea2013-03-13 00:42:30148 SpdySessionDependencies session_deps_;
danakjaee3e1ec2016-04-16 00:23:18149 std::unique_ptr<HttpNetworkSession> session_;
[email protected]3d587372013-06-01 04:31:45150
151 private:
152 // Used by Add{Read,Write}() above.
153 std::vector<MockWrite> writes_;
154 std::vector<MockRead> reads_;
155 int offset_;
bnc032658ba2016-09-26 18:17:15156 SSLSocketDataProvider ssl_;
[email protected]4f386422010-07-20 04:19:49157};
158
bncd16676a2016-07-20 16:23:01159TEST_F(SpdyStreamTest, SendDataAfterOpen) {
Ryan Hamilton0239aac2018-05-19 00:03:13160 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:26161 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41162 AddWrite(req);
[email protected]3d587372013-06-01 04:31:45163
Ryan Hamilton0239aac2018-05-19 00:03:13164 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41165 AddRead(resp);
[email protected]3d587372013-06-01 04:31:45166
Ryan Hamilton0239aac2018-05-19 00:03:13167 spdy::SpdySerializedFrame msg(
Bence Békyd74f4382018-02-20 18:26:19168 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bncdf80d44fd2016-07-15 20:27:41169 AddWrite(msg);
[email protected]4f386422010-07-20 04:19:49170
Ryan Hamilton0239aac2018-05-19 00:03:13171 spdy::SpdySerializedFrame echo(
Bence Békyd74f4382018-02-20 18:26:19172 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bncdf80d44fd2016-07-15 20:27:41173 AddRead(echo);
[email protected]4f386422010-07-20 04:19:49174
[email protected]3d587372013-06-01 04:31:45175 AddReadEOF();
176
Ryan Sleevib8d7ea02018-05-07 20:01:01177 SequencedSocketData data(GetReads(), GetWrites());
[email protected]d973e99a2012-02-17 21:02:36178 MockConnect connect_data(SYNCHRONOUS, OK);
[email protected]dd54bd82012-07-19 23:44:57179 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59180 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4f386422010-07-20 04:19:49181
bnc032658ba2016-09-26 18:17:15182 AddSSLSocketData();
183
[email protected]795cbf82013-07-22 09:37:27184 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]e3861ca2013-03-02 01:00:45185
tfarina42834112016-09-22 13:38:20186 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26187 SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52188 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18189 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]4f386422010-07-20 04:19:49190
[email protected]194cfcf2013-05-23 21:44:44191 StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
[email protected]34a4dea2013-03-13 00:42:30192 stream->SetDelegate(&delegate);
[email protected]4f386422010-07-20 04:19:49193
Ryan Hamilton0239aac2018-05-19 00:03:13194 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:26195 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
196 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
197 IsError(ERR_IO_PENDING));
[email protected]4f386422010-07-20 04:19:49198
robpercival214763f2016-07-01 23:27:01199 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
[email protected]4f386422010-07-20 04:19:49200
[email protected]34a4dea2013-03-13 00:42:30201 EXPECT_TRUE(delegate.send_headers_completed());
Ryan Hamilton0239aac2018-05-19 00:03:13202 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
Bence Béky4e83f492018-05-13 23:14:25203 EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
[email protected]09a8d9172013-04-17 19:23:49204 delegate.TakeReceivedData());
rch37de576c2015-05-17 20:28:17205 EXPECT_TRUE(data.AllWriteDataConsumed());
[email protected]4f386422010-07-20 04:19:49206}
207
xunjieli294da722015-08-11 19:15:02208// Delegate that receives trailers.
209class StreamDelegateWithTrailers : public test::StreamDelegateWithBody {
210 public:
211 StreamDelegateWithTrailers(const base::WeakPtr<SpdyStream>& stream,
Bence Béky4e83f492018-05-13 23:14:25212 base::StringPiece data)
xunjieli294da722015-08-11 19:15:02213 : StreamDelegateWithBody(stream, data) {}
214
Chris Watkins61914cb2017-12-01 19:59:00215 ~StreamDelegateWithTrailers() override = default;
xunjieli294da722015-08-11 19:15:02216
Ryan Hamilton0239aac2018-05-19 00:03:13217 void OnTrailers(const spdy::SpdyHeaderBlock& trailers) override {
bnc94893a72016-06-30 13:45:25218 trailers_ = trailers.Clone();
xunjieli294da722015-08-11 19:15:02219 }
220
Ryan Hamilton0239aac2018-05-19 00:03:13221 const spdy::SpdyHeaderBlock& trailers() const { return trailers_; }
xunjieli294da722015-08-11 19:15:02222
223 private:
Ryan Hamilton0239aac2018-05-19 00:03:13224 spdy::SpdyHeaderBlock trailers_;
xunjieli294da722015-08-11 19:15:02225};
226
bnca2fbdc9b2016-11-22 21:14:26227// Regression test for https://crbug.com/481033.
bncd16676a2016-07-20 16:23:01228TEST_F(SpdyStreamTest, Trailers) {
Ryan Hamilton0239aac2018-05-19 00:03:13229 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:26230 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41231 AddWrite(req);
xunjieli294da722015-08-11 19:15:02232
Ryan Hamilton0239aac2018-05-19 00:03:13233 spdy::SpdySerializedFrame msg(
Bence Békyd74f4382018-02-20 18:26:19234 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bncdf80d44fd2016-07-15 20:27:41235 AddWrite(msg);
xunjieli294da722015-08-11 19:15:02236
Ryan Hamilton0239aac2018-05-19 00:03:13237 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41238 AddRead(resp);
xunjieli294da722015-08-11 19:15:02239
Ryan Hamilton0239aac2018-05-19 00:03:13240 spdy::SpdySerializedFrame echo(
Bence Békyd74f4382018-02-20 18:26:19241 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bncdf80d44fd2016-07-15 20:27:41242 AddRead(echo);
xunjieli294da722015-08-11 19:15:02243
Ryan Hamilton0239aac2018-05-19 00:03:13244 spdy::SpdyHeaderBlock late_headers;
bnc38dcd392016-02-09 23:19:49245 late_headers["foo"] = "bar";
Ryan Hamilton0239aac2018-05-19 00:03:13246 spdy::SpdySerializedFrame trailers(spdy_util_.ConstructSpdyResponseHeaders(
bncdf80d44fd2016-07-15 20:27:41247 1, std::move(late_headers), false));
248 AddRead(trailers);
xunjieli294da722015-08-11 19:15:02249
250 AddReadEOF();
251
Ryan Sleevib8d7ea02018-05-07 20:01:01252 SequencedSocketData data(GetReads(), GetWrites());
xunjieli294da722015-08-11 19:15:02253 MockConnect connect_data(SYNCHRONOUS, OK);
254 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59255 session_deps_.socket_factory->AddSocketDataProvider(&data);
xunjieli294da722015-08-11 19:15:02256
bnc032658ba2016-09-26 18:17:15257 AddSSLSocketData();
258
xunjieli294da722015-08-11 19:15:02259 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
260
261 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26262 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52263 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18264 EXPECT_EQ(kDefaultUrl, stream->url().spec());
xunjieli294da722015-08-11 19:15:02265
266 StreamDelegateWithTrailers delegate(stream, kPostBodyStringPiece);
267 stream->SetDelegate(&delegate);
268
Ryan Hamilton0239aac2018-05-19 00:03:13269 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:26270 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
271 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
272 IsError(ERR_IO_PENDING));
xunjieli294da722015-08-11 19:15:02273
robpercival214763f2016-07-01 23:27:01274 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
xunjieli294da722015-08-11 19:15:02275
276 EXPECT_TRUE(delegate.send_headers_completed());
Ryan Hamilton0239aac2018-05-19 00:03:13277 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
278 const spdy::SpdyHeaderBlock& received_trailers = delegate.trailers();
279 spdy::SpdyHeaderBlock::const_iterator it = received_trailers.find("foo");
xunjieli294da722015-08-11 19:15:02280 EXPECT_EQ("bar", it->second);
Bence Béky4e83f492018-05-13 23:14:25281 EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
xunjieli294da722015-08-11 19:15:02282 delegate.TakeReceivedData());
283 EXPECT_TRUE(data.AllWriteDataConsumed());
284}
285
bncd16676a2016-07-20 16:23:01286TEST_F(SpdyStreamTest, PushedStream) {
Ryan Hamilton0239aac2018-05-19 00:03:13287 spdy::SpdySerializedFrame req(
288 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnca2fbdc9b2016-11-22 21:14:26289 AddWrite(req);
290
Ryan Hamilton0239aac2018-05-19 00:03:13291 spdy::SpdySerializedFrame reply(
292 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bnca2fbdc9b2016-11-22 21:14:26293 AddRead(reply);
294
Ryan Hamilton0239aac2018-05-19 00:03:13295 spdy::SpdySerializedFrame push(
bnca2fbdc9b2016-11-22 21:14:26296 spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushUrl));
297 AddRead(push);
298
Ryan Hamilton0239aac2018-05-19 00:03:13299 spdy::SpdySerializedFrame priority(
tombergan5d22c182017-01-11 02:05:35300 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
301 AddWrite(priority);
302
bnca2fbdc9b2016-11-22 21:14:26303 AddReadPause();
304
Bence Béky4e83f492018-05-13 23:14:25305 base::StringPiece pushed_msg("foo");
Ryan Hamilton0239aac2018-05-19 00:03:13306 spdy::SpdySerializedFrame pushed_body(
Bence Békyd74f4382018-02-20 18:26:19307 spdy_util_.ConstructSpdyDataFrame(2, pushed_msg, true));
bnca2fbdc9b2016-11-22 21:14:26308 AddRead(pushed_body);
309
Bence Béky4e83f492018-05-13 23:14:25310 base::StringPiece msg("bar");
Ryan Hamilton0239aac2018-05-19 00:03:13311 spdy::SpdySerializedFrame body(
312 spdy_util_.ConstructSpdyDataFrame(1, msg, true));
bnca2fbdc9b2016-11-22 21:14:26313 AddRead(body);
314
[email protected]6d116e1a2013-06-24 07:42:15315 AddReadEOF();
316
Ryan Sleevib8d7ea02018-05-07 20:01:01317 SequencedSocketData data(GetReads(), GetWrites());
[email protected]0e861e92012-03-15 18:42:19318 MockConnect connect_data(SYNCHRONOUS, OK);
[email protected]dd54bd82012-07-19 23:44:57319 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59320 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]0e861e92012-03-15 18:42:19321
bnc032658ba2016-09-26 18:17:15322 AddSSLSocketData();
323
bnca2fbdc9b2016-11-22 21:14:26324 g_time_now = base::TimeTicks::Now();
325 session_deps_.time_func = InstantaneousReads;
326 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
[email protected]a7a265ef2010-12-08 18:05:57327
bnca2fbdc9b2016-11-22 21:14:26328 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
329
330 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
331 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
332 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18333 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bnca2fbdc9b2016-11-22 21:14:26334
335 StreamDelegateDoNothing delegate(stream);
336 stream->SetDelegate(&delegate);
caseqe8340bc92016-04-20 00:02:57337
Ryan Hamilton0239aac2018-05-19 00:03:13338 spdy::SpdyHeaderBlock headers(
339 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnca2fbdc9b2016-11-22 21:14:26340 EXPECT_THAT(
341 stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
342 IsError(ERR_IO_PENDING));
[email protected]6cd63ba2014-06-12 16:14:56343
bnca2fbdc9b2016-11-22 21:14:26344 data.RunUntilPaused();
[email protected]a7a265ef2010-12-08 18:05:57345
Bence Béky7bf94362018-01-10 13:19:36346 const SpdySessionKey key(HostPortPair::FromURL(url_), ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:11347 PRIVACY_MODE_DISABLED,
348 SpdySessionKey::IsProxySession::kFalse, SocketTag());
Bence Béky5b1e4ce72018-01-11 14:55:15349 const GURL pushed_url(kPushUrl);
350 HttpRequestInfo push_request;
351 push_request.url = pushed_url;
352 push_request.method = "GET";
Bence Béky7bf94362018-01-10 13:19:36353 base::WeakPtr<SpdySession> session_with_pushed_stream;
Ryan Hamilton0239aac2018-05-19 00:03:13354 spdy::SpdyStreamId pushed_stream_id;
Bence Béky7bf94362018-01-10 13:19:36355 spdy_session_pool(session)->push_promise_index()->ClaimPushedStream(
Bence Béky5b1e4ce72018-01-11 14:55:15356 key, pushed_url, push_request, &session_with_pushed_stream,
357 &pushed_stream_id);
Bence Béky7bf94362018-01-10 13:19:36358 EXPECT_EQ(session.get(), session_with_pushed_stream.get());
359 EXPECT_EQ(2u, pushed_stream_id);
360
bnc4e6e77482017-01-22 12:59:43361 SpdyStream* push_stream;
Bence Béky5b1e4ce72018-01-11 14:55:15362 EXPECT_THAT(session->GetPushedStream(pushed_url, pushed_stream_id, IDLE,
Bence Békyc6834652018-10-03 00:47:39363 &push_stream),
tombergan5d22c182017-01-11 02:05:35364 IsOk());
bnca2fbdc9b2016-11-22 21:14:26365 ASSERT_TRUE(push_stream);
Bence Béky39d74292018-03-02 04:31:18366 EXPECT_EQ(kPushUrl, push_stream->url().spec());
caseqe8340bc92016-04-20 00:02:57367
368 LoadTimingInfo load_timing_info;
bnca2fbdc9b2016-11-22 21:14:26369 EXPECT_TRUE(push_stream->GetLoadTimingInfo(&load_timing_info));
370 EXPECT_EQ(g_time_now, load_timing_info.push_start);
caseqe8340bc92016-04-20 00:02:57371 EXPECT_TRUE(load_timing_info.push_end.is_null());
372
bnc4e6e77482017-01-22 12:59:43373 StreamDelegateDoNothing push_delegate(push_stream->GetWeakPtr());
bnca2fbdc9b2016-11-22 21:14:26374 push_stream->SetDelegate(&push_delegate);
[email protected]6d116e1a2013-06-24 07:42:15375
bnca2fbdc9b2016-11-22 21:14:26376 data.Resume();
[email protected]6d116e1a2013-06-24 07:42:15377
bnca2fbdc9b2016-11-22 21:14:26378 EXPECT_TRUE(push_stream->GetLoadTimingInfo(&load_timing_info));
379 EXPECT_EQ(g_time_now, load_timing_info.push_start);
380 EXPECT_FALSE(load_timing_info.push_end.is_null());
381
382 EXPECT_THAT(delegate.WaitForClose(), IsOk());
Ryan Hamilton0239aac2018-05-19 00:03:13383 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
bnca2fbdc9b2016-11-22 21:14:26384 EXPECT_EQ(msg, delegate.TakeReceivedData());
[email protected]6d116e1a2013-06-24 07:42:15385
bnca2fbdc9b2016-11-22 21:14:26386 EXPECT_THAT(push_delegate.WaitForClose(), IsOk());
Ryan Hamilton0239aac2018-05-19 00:03:13387 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
bnca2fbdc9b2016-11-22 21:14:26388 EXPECT_EQ(pushed_msg, push_delegate.TakeReceivedData());
Bence Békya60ed842018-04-26 23:45:44389
390 // Finish async network reads and writes.
391 base::RunLoop().RunUntilIdle();
392
393 EXPECT_TRUE(data.AllWriteDataConsumed());
394 EXPECT_TRUE(data.AllReadDataConsumed());
[email protected]a7a265ef2010-12-08 18:05:57395}
396
bncd16676a2016-07-20 16:23:01397TEST_F(SpdyStreamTest, StreamError) {
Ryan Hamilton0239aac2018-05-19 00:03:13398 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:26399 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41400 AddWrite(req);
[email protected]3d587372013-06-01 04:31:45401
Ryan Hamilton0239aac2018-05-19 00:03:13402 spdy::SpdySerializedFrame resp(
403 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:41404 AddRead(resp);
[email protected]3d587372013-06-01 04:31:45405
Ryan Hamilton0239aac2018-05-19 00:03:13406 spdy::SpdySerializedFrame msg(
Bence Békyd74f4382018-02-20 18:26:19407 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bncdf80d44fd2016-07-15 20:27:41408 AddWrite(msg);
[email protected]3d587372013-06-01 04:31:45409
Ryan Hamilton0239aac2018-05-19 00:03:13410 spdy::SpdySerializedFrame echo(
Bence Békyd74f4382018-02-20 18:26:19411 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bncdf80d44fd2016-07-15 20:27:41412 AddRead(echo);
[email protected]3d587372013-06-01 04:31:45413
414 AddReadEOF();
[email protected]d245c342012-02-23 20:49:15415
vishal.b62985ca92015-04-17 08:45:51416 BoundTestNetLog log;
[email protected]d245c342012-02-23 20:49:15417
Ryan Sleevib8d7ea02018-05-07 20:01:01418 SequencedSocketData data(GetReads(), GetWrites());
[email protected]d245c342012-02-23 20:49:15419 MockConnect connect_data(SYNCHRONOUS, OK);
[email protected]dd54bd82012-07-19 23:44:57420 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59421 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]d245c342012-02-23 20:49:15422
bnc032658ba2016-09-26 18:17:15423 AddSSLSocketData();
424
[email protected]795cbf82013-07-22 09:37:27425 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]d245c342012-02-23 20:49:15426
bnca2fbdc9b2016-11-22 21:14:26427 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
428 SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, log.bound());
wezca1070932016-05-26 20:30:52429 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18430 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]d245c342012-02-23 20:49:15431
[email protected]194cfcf2013-05-23 21:44:44432 StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
[email protected]34a4dea2013-03-13 00:42:30433 stream->SetDelegate(&delegate);
[email protected]d245c342012-02-23 20:49:15434
Ryan Hamilton0239aac2018-05-19 00:03:13435 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:26436 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
437 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
438 IsError(ERR_IO_PENDING));
[email protected]d245c342012-02-23 20:49:15439
robpercival214763f2016-07-01 23:27:01440 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
[email protected]218f4b62012-07-20 20:12:41441
Ryan Hamilton0239aac2018-05-19 00:03:13442 const spdy::SpdyStreamId stream_id = delegate.stream_id();
[email protected]c92f4b4542012-07-26 23:53:21443
[email protected]34a4dea2013-03-13 00:42:30444 EXPECT_TRUE(delegate.send_headers_completed());
Ryan Hamilton0239aac2018-05-19 00:03:13445 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
Bence Béky4e83f492018-05-13 23:14:25446 EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
[email protected]09a8d9172013-04-17 19:23:49447 delegate.TakeReceivedData());
rch37de576c2015-05-17 20:28:17448 EXPECT_TRUE(data.AllWriteDataConsumed());
[email protected]d245c342012-02-23 20:49:15449
450 // Check that the NetLog was filled reasonably.
mmenke43758e62015-05-04 21:09:46451 TestNetLogEntry::List entries;
[email protected]d245c342012-02-23 20:49:15452 log.GetEntries(&entries);
453 EXPECT_LT(0u, entries.size());
454
455 // Check that we logged SPDY_STREAM_ERROR correctly.
ttuttle859dc7a2015-04-23 19:42:29456 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00457 entries, 0, NetLogEventType::HTTP2_STREAM_ERROR, NetLogEventPhase::NONE);
[email protected]d245c342012-02-23 20:49:15458
[email protected]f3da152d2012-06-02 01:00:57459 int stream_id2;
460 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &stream_id2));
461 EXPECT_EQ(static_cast<int>(stream_id), stream_id2);
[email protected]d245c342012-02-23 20:49:15462}
[email protected]a7a265ef2010-12-08 18:05:57463
bnca2fbdc9b2016-11-22 21:14:26464// Make sure that large blocks of data are properly split up into frame-sized
465// chunks for a request/response (i.e., an HTTP-like) stream.
bncd16676a2016-07-20 16:23:01466TEST_F(SpdyStreamTest, SendLargeDataAfterOpenRequestResponse) {
Ryan Hamilton0239aac2018-05-19 00:03:13467 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:26468 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41469 AddWrite(req);
[email protected]3d587372013-06-01 04:31:45470
Bence Béky4e83f492018-05-13 23:14:25471 std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
Ryan Hamilton0239aac2018-05-19 00:03:13472 spdy::SpdySerializedFrame chunk(
Bence Békyd74f4382018-02-20 18:26:19473 spdy_util_.ConstructSpdyDataFrame(1, chunk_data, false));
bncdf80d44fd2016-07-15 20:27:41474 AddWrite(chunk);
475 AddWrite(chunk);
[email protected]3d587372013-06-01 04:31:45476
Ryan Hamilton0239aac2018-05-19 00:03:13477 spdy::SpdySerializedFrame last_chunk(
Bence Békyd74f4382018-02-20 18:26:19478 spdy_util_.ConstructSpdyDataFrame(1, chunk_data, true));
bncdf80d44fd2016-07-15 20:27:41479 AddWrite(last_chunk);
[email protected]aa19cfc2013-05-23 16:41:38480
Ryan Hamilton0239aac2018-05-19 00:03:13481 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41482 AddRead(resp);
[email protected]aa19cfc2013-05-23 16:41:38483
[email protected]3d587372013-06-01 04:31:45484 AddReadEOF();
485
Ryan Sleevib8d7ea02018-05-07 20:01:01486 SequencedSocketData data(GetReads(), GetWrites());
[email protected]aa19cfc2013-05-23 16:41:38487 MockConnect connect_data(SYNCHRONOUS, OK);
488 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59489 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]aa19cfc2013-05-23 16:41:38490
bnc032658ba2016-09-26 18:17:15491 AddSSLSocketData();
492
[email protected]795cbf82013-07-22 09:37:27493 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]aa19cfc2013-05-23 16:41:38494
tfarina42834112016-09-22 13:38:20495 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26496 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52497 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18498 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]aa19cfc2013-05-23 16:41:38499
Bence Béky4e83f492018-05-13 23:14:25500 std::string body_data(3 * kMaxSpdyFrameChunkSize, 'x');
[email protected]aa19cfc2013-05-23 16:41:38501 StreamDelegateWithBody delegate(stream, body_data);
502 stream->SetDelegate(&delegate);
503
Ryan Hamilton0239aac2018-05-19 00:03:13504 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:26505 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
506 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
507 IsError(ERR_IO_PENDING));
[email protected]aa19cfc2013-05-23 16:41:38508
robpercival214763f2016-07-01 23:27:01509 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
[email protected]aa19cfc2013-05-23 16:41:38510
511 EXPECT_TRUE(delegate.send_headers_completed());
Ryan Hamilton0239aac2018-05-19 00:03:13512 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
Bence Béky4e83f492018-05-13 23:14:25513 EXPECT_EQ(std::string(), delegate.TakeReceivedData());
rch37de576c2015-05-17 20:28:17514 EXPECT_TRUE(data.AllWriteDataConsumed());
[email protected]aa19cfc2013-05-23 16:41:38515}
516
bnca2fbdc9b2016-11-22 21:14:26517// Make sure that large blocks of data are properly split up into frame-sized
518// chunks for a bidirectional (i.e., non-HTTP-like) stream.
bncd16676a2016-07-20 16:23:01519TEST_F(SpdyStreamTest, SendLargeDataAfterOpenBidirectional) {
Ryan Hamilton0239aac2018-05-19 00:03:13520 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:26521 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41522 AddWrite(req);
[email protected]3d587372013-06-01 04:31:45523
Ryan Hamilton0239aac2018-05-19 00:03:13524 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41525 AddRead(resp);
[email protected]3d587372013-06-01 04:31:45526
Bence Béky4e83f492018-05-13 23:14:25527 std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
Ryan Hamilton0239aac2018-05-19 00:03:13528 spdy::SpdySerializedFrame chunk(
Bence Békyd74f4382018-02-20 18:26:19529 spdy_util_.ConstructSpdyDataFrame(1, chunk_data, false));
bncdf80d44fd2016-07-15 20:27:41530 AddWrite(chunk);
531 AddWrite(chunk);
532 AddWrite(chunk);
[email protected]aa19cfc2013-05-23 16:41:38533
[email protected]3d587372013-06-01 04:31:45534 AddReadEOF();
[email protected]aa19cfc2013-05-23 16:41:38535
Ryan Sleevib8d7ea02018-05-07 20:01:01536 SequencedSocketData data(GetReads(), GetWrites());
[email protected]aa19cfc2013-05-23 16:41:38537 MockConnect connect_data(SYNCHRONOUS, OK);
538 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59539 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]aa19cfc2013-05-23 16:41:38540
bnc032658ba2016-09-26 18:17:15541 AddSSLSocketData();
542
[email protected]795cbf82013-07-22 09:37:27543 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]aa19cfc2013-05-23 16:41:38544
tfarina42834112016-09-22 13:38:20545 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26546 SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52547 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18548 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]aa19cfc2013-05-23 16:41:38549
Bence Béky4e83f492018-05-13 23:14:25550 std::string body_data(3 * kMaxSpdyFrameChunkSize, 'x');
[email protected]194cfcf2013-05-23 21:44:44551 StreamDelegateSendImmediate delegate(stream, body_data);
[email protected]aa19cfc2013-05-23 16:41:38552 stream->SetDelegate(&delegate);
553
Ryan Hamilton0239aac2018-05-19 00:03:13554 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:26555 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
556 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
557 IsError(ERR_IO_PENDING));
[email protected]aa19cfc2013-05-23 16:41:38558
robpercival214763f2016-07-01 23:27:01559 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
[email protected]aa19cfc2013-05-23 16:41:38560
561 EXPECT_TRUE(delegate.send_headers_completed());
Ryan Hamilton0239aac2018-05-19 00:03:13562 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
Bence Béky4e83f492018-05-13 23:14:25563 EXPECT_EQ(std::string(), delegate.TakeReceivedData());
rch37de576c2015-05-17 20:28:17564 EXPECT_TRUE(data.AllWriteDataConsumed());
[email protected]aa19cfc2013-05-23 16:41:38565}
566
bnca2fbdc9b2016-11-22 21:14:26567// Receiving a header with uppercase ASCII should result in a protocol error.
bncd16676a2016-07-20 16:23:01568TEST_F(SpdyStreamTest, UpperCaseHeaders) {
Ryan Hamilton0239aac2018-05-19 00:03:13569 spdy::SpdySerializedFrame req(
570 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnca2fbdc9b2016-11-22 21:14:26571 AddWrite(req);
[email protected]6d116e1a2013-06-24 07:42:15572
573 const char* const kExtraHeaders[] = {"X-UpperCase", "yes"};
Ryan Hamilton0239aac2018-05-19 00:03:13574 spdy::SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(
Avi Drissman4365a4782018-12-28 19:26:24575 kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
bncdf80d44fd2016-07-15 20:27:41576 AddRead(reply);
[email protected]6d116e1a2013-06-24 07:42:15577
Ryan Hamilton0239aac2018-05-19 00:03:13578 spdy::SpdySerializedFrame rst(
579 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bncdf80d44fd2016-07-15 20:27:41580 AddWrite(rst);
[email protected]6d116e1a2013-06-24 07:42:15581
582 AddReadEOF();
583
Ryan Sleevib8d7ea02018-05-07 20:01:01584 SequencedSocketData data(GetReads(), GetWrites());
[email protected]6d116e1a2013-06-24 07:42:15585 MockConnect connect_data(SYNCHRONOUS, OK);
586 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59587 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6d116e1a2013-06-24 07:42:15588
bnc032658ba2016-09-26 18:17:15589 AddSSLSocketData();
590
[email protected]795cbf82013-07-22 09:37:27591 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]6d116e1a2013-06-24 07:42:15592
tfarina42834112016-09-22 13:38:20593 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26594 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52595 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18596 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]6d116e1a2013-06-24 07:42:15597
598 StreamDelegateDoNothing delegate(stream);
599 stream->SetDelegate(&delegate);
600
Ryan Hamilton0239aac2018-05-19 00:03:13601 spdy::SpdyHeaderBlock headers(
602 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnca2fbdc9b2016-11-22 21:14:26603 EXPECT_THAT(
604 stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
605 IsError(ERR_IO_PENDING));
[email protected]6d116e1a2013-06-24 07:42:15606
robpercival214763f2016-07-01 23:27:01607 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
bnc4c214312016-11-28 16:49:15608
bnceb9aa7112017-01-05 01:03:46609 // Finish async network reads and writes.
610 base::RunLoop().RunUntilIdle();
611
bnc4c214312016-11-28 16:49:15612 EXPECT_TRUE(data.AllWriteDataConsumed());
613 EXPECT_TRUE(data.AllReadDataConsumed());
[email protected]6d116e1a2013-06-24 07:42:15614}
615
bnca2fbdc9b2016-11-22 21:14:26616// Receiving a header with uppercase ASCII should result in a protocol error
617// even for a push stream.
bncd16676a2016-07-20 16:23:01618TEST_F(SpdyStreamTest, UpperCaseHeadersOnPush) {
Ryan Hamilton0239aac2018-05-19 00:03:13619 spdy::SpdySerializedFrame req(
620 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnca2fbdc9b2016-11-22 21:14:26621 AddWrite(req);
[email protected]6d116e1a2013-06-24 07:42:15622
Ryan Hamilton0239aac2018-05-19 00:03:13623 spdy::SpdySerializedFrame reply(
624 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:41625 AddRead(reply);
[email protected]6d116e1a2013-06-24 07:42:15626
bnc4c214312016-11-28 16:49:15627 const char* const kExtraHeaders[] = {"X-UpperCase", "yes"};
Ryan Hamilton0239aac2018-05-19 00:03:13628 spdy::SpdySerializedFrame push(spdy_util_.ConstructSpdyPush(
Avi Drissman4365a4782018-12-28 19:26:24629 kExtraHeaders, base::size(kExtraHeaders) / 2, 2, 1, kPushUrl));
bncdf80d44fd2016-07-15 20:27:41630 AddRead(push);
[email protected]6d116e1a2013-06-24 07:42:15631
Ryan Hamilton0239aac2018-05-19 00:03:13632 spdy::SpdySerializedFrame priority(
tombergan5d22c182017-01-11 02:05:35633 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
634 AddWrite(priority);
635
Ryan Hamilton0239aac2018-05-19 00:03:13636 spdy::SpdySerializedFrame rst(
637 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_PROTOCOL_ERROR));
bncdf80d44fd2016-07-15 20:27:41638 AddWrite(rst);
[email protected]6d116e1a2013-06-24 07:42:15639
mmenkee24011922015-12-17 22:12:59640 AddReadPause();
641
[email protected]6d116e1a2013-06-24 07:42:15642 AddReadEOF();
643
Ryan Sleevib8d7ea02018-05-07 20:01:01644 SequencedSocketData data(GetReads(), GetWrites());
[email protected]6d116e1a2013-06-24 07:42:15645 MockConnect connect_data(SYNCHRONOUS, OK);
646 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59647 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6d116e1a2013-06-24 07:42:15648
bnc032658ba2016-09-26 18:17:15649 AddSSLSocketData();
650
[email protected]795cbf82013-07-22 09:37:27651 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]6d116e1a2013-06-24 07:42:15652
tfarina42834112016-09-22 13:38:20653 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26654 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52655 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18656 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]6d116e1a2013-06-24 07:42:15657
658 StreamDelegateDoNothing delegate(stream);
659 stream->SetDelegate(&delegate);
660
Ryan Hamilton0239aac2018-05-19 00:03:13661 spdy::SpdyHeaderBlock headers(
662 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnca2fbdc9b2016-11-22 21:14:26663 EXPECT_THAT(
664 stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
665 IsError(ERR_IO_PENDING));
[email protected]6d116e1a2013-06-24 07:42:15666
mmenkee24011922015-12-17 22:12:59667 data.RunUntilPaused();
[email protected]6d116e1a2013-06-24 07:42:15668
Bence Béky7bf94362018-01-10 13:19:36669 EXPECT_EQ(0u, num_pushed_streams(session));
[email protected]6d116e1a2013-06-24 07:42:15670
mmenkee24011922015-12-17 22:12:59671 data.Resume();
[email protected]6d116e1a2013-06-24 07:42:15672
robpercival214763f2016-07-01 23:27:01673 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
bnc4c214312016-11-28 16:49:15674
675 EXPECT_TRUE(data.AllWriteDataConsumed());
676 EXPECT_TRUE(data.AllReadDataConsumed());
[email protected]6d116e1a2013-06-24 07:42:15677}
678
bnc4c214312016-11-28 16:49:15679TEST_F(SpdyStreamTest, HeadersMustHaveStatus) {
Ryan Hamilton0239aac2018-05-19 00:03:13680 spdy::SpdySerializedFrame req(
681 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnc4c214312016-11-28 16:49:15682 AddWrite(req);
683
684 // Response headers without ":status" header field: protocol error.
Ryan Hamilton0239aac2018-05-19 00:03:13685 spdy::SpdyHeaderBlock header_block_without_status;
686 header_block_without_status[spdy::kHttp2MethodHeader] = "GET";
687 header_block_without_status[spdy::kHttp2AuthorityHeader] = "www.example.org";
688 header_block_without_status[spdy::kHttp2SchemeHeader] = "https";
689 header_block_without_status[spdy::kHttp2PathHeader] = "/";
690 spdy::SpdySerializedFrame reply(
bnc4c214312016-11-28 16:49:15691 spdy_util_.ConstructSpdyReply(1, std::move(header_block_without_status)));
692 AddRead(reply);
693
Ryan Hamilton0239aac2018-05-19 00:03:13694 spdy::SpdySerializedFrame rst(
695 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bnc4c214312016-11-28 16:49:15696 AddWrite(rst);
697
698 AddReadEOF();
699
Ryan Sleevib8d7ea02018-05-07 20:01:01700 SequencedSocketData data(GetReads(), GetWrites());
bnc4c214312016-11-28 16:49:15701 MockConnect connect_data(SYNCHRONOUS, OK);
702 data.set_connect_data(connect_data);
703 session_deps_.socket_factory->AddSocketDataProvider(&data);
704
705 AddSSLSocketData();
706
707 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
708
709 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
710 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
711 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18712 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bnc4c214312016-11-28 16:49:15713
714 StreamDelegateDoNothing delegate(stream);
715 stream->SetDelegate(&delegate);
716
Ryan Hamilton0239aac2018-05-19 00:03:13717 spdy::SpdyHeaderBlock headers(
718 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnc4c214312016-11-28 16:49:15719 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
720 NO_MORE_DATA_TO_SEND));
bnc4c214312016-11-28 16:49:15721
722 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
723
bnceb9aa7112017-01-05 01:03:46724 // Finish async network reads and writes.
725 base::RunLoop().RunUntilIdle();
726
bnc4c214312016-11-28 16:49:15727 EXPECT_TRUE(data.AllWriteDataConsumed());
728 EXPECT_TRUE(data.AllReadDataConsumed());
729}
730
731TEST_F(SpdyStreamTest, HeadersMustHaveStatusOnPushedStream) {
Ryan Hamilton0239aac2018-05-19 00:03:13732 spdy::SpdySerializedFrame req(
733 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnca2fbdc9b2016-11-22 21:14:26734 AddWrite(req);
[email protected]6d116e1a2013-06-24 07:42:15735
Ryan Hamilton0239aac2018-05-19 00:03:13736 spdy::SpdySerializedFrame reply(
737 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:41738 AddRead(reply);
[email protected]6d116e1a2013-06-24 07:42:15739
Ryan Hamilton0239aac2018-05-19 00:03:13740 spdy::SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise(
Bence Békyf1d78522018-01-11 01:16:50741 1, 2, spdy_util_.ConstructGetHeaderBlock(kPushUrl)));
bnc4c214312016-11-28 16:49:15742 AddRead(push_promise);
[email protected]6d116e1a2013-06-24 07:42:15743
Ryan Hamilton0239aac2018-05-19 00:03:13744 spdy::SpdySerializedFrame priority(
tombergan5d22c182017-01-11 02:05:35745 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
746 AddWrite(priority);
747
bnc4c214312016-11-28 16:49:15748 // Response headers without ":status" header field: protocol error.
Ryan Hamilton0239aac2018-05-19 00:03:13749 spdy::SpdyHeaderBlock header_block_without_status;
750 header_block_without_status[spdy::kHttp2MethodHeader] = "GET";
751 header_block_without_status[spdy::kHttp2AuthorityHeader] = "www.example.org";
752 header_block_without_status[spdy::kHttp2SchemeHeader] = "https";
753 header_block_without_status[spdy::kHttp2PathHeader] = "/";
754 spdy::SpdySerializedFrame pushed_reply(
bnc4c214312016-11-28 16:49:15755 spdy_util_.ConstructSpdyReply(2, std::move(header_block_without_status)));
756 AddRead(pushed_reply);
mmenkee24011922015-12-17 22:12:59757
Ryan Hamilton0239aac2018-05-19 00:03:13758 spdy::SpdySerializedFrame rst(
759 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_PROTOCOL_ERROR));
bncdf80d44fd2016-07-15 20:27:41760 AddWrite(rst);
[email protected]6d116e1a2013-06-24 07:42:15761
Ryan Hamilton0239aac2018-05-19 00:03:13762 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:19763 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bnc4c214312016-11-28 16:49:15764 AddRead(body);
765
[email protected]6d116e1a2013-06-24 07:42:15766 AddReadEOF();
767
Ryan Sleevib8d7ea02018-05-07 20:01:01768 SequencedSocketData data(GetReads(), GetWrites());
[email protected]6d116e1a2013-06-24 07:42:15769 MockConnect connect_data(SYNCHRONOUS, OK);
770 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59771 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6d116e1a2013-06-24 07:42:15772
bnc032658ba2016-09-26 18:17:15773 AddSSLSocketData();
774
[email protected]795cbf82013-07-22 09:37:27775 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]6d116e1a2013-06-24 07:42:15776
tfarina42834112016-09-22 13:38:20777 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26778 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52779 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18780 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]6d116e1a2013-06-24 07:42:15781
782 StreamDelegateDoNothing delegate(stream);
783 stream->SetDelegate(&delegate);
784
Ryan Hamilton0239aac2018-05-19 00:03:13785 spdy::SpdyHeaderBlock headers(
786 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnca2fbdc9b2016-11-22 21:14:26787 EXPECT_THAT(
788 stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
789 IsError(ERR_IO_PENDING));
[email protected]6d116e1a2013-06-24 07:42:15790
bnc4c214312016-11-28 16:49:15791 EXPECT_THAT(delegate.WaitForClose(), IsOk());
Ryan Hamilton0239aac2018-05-19 00:03:13792 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
Bence Béky4e83f492018-05-13 23:14:25793 EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
bnc4c214312016-11-28 16:49:15794 delegate.TakeReceivedData());
[email protected]6d116e1a2013-06-24 07:42:15795
bnceb9aa7112017-01-05 01:03:46796 // Finish async network reads and writes.
797 base::RunLoop().RunUntilIdle();
798
bnc4c214312016-11-28 16:49:15799 EXPECT_TRUE(data.AllWriteDataConsumed());
800 EXPECT_TRUE(data.AllReadDataConsumed());
[email protected]6d116e1a2013-06-24 07:42:15801}
802
bnc4c214312016-11-28 16:49:15803TEST_F(SpdyStreamTest, HeadersMustPreceedData) {
Ryan Hamilton0239aac2018-05-19 00:03:13804 spdy::SpdySerializedFrame req(
805 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnc4c214312016-11-28 16:49:15806 AddWrite(req);
807
808 // Response body not preceeded by headers: protocol error.
Ryan Hamilton0239aac2018-05-19 00:03:13809 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:19810 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bnc4c214312016-11-28 16:49:15811 AddRead(body);
812
Ryan Hamilton0239aac2018-05-19 00:03:13813 spdy::SpdySerializedFrame rst(
814 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bnc4c214312016-11-28 16:49:15815 AddWrite(rst);
816
817 AddReadEOF();
818
Ryan Sleevib8d7ea02018-05-07 20:01:01819 SequencedSocketData data(GetReads(), GetWrites());
bnc4c214312016-11-28 16:49:15820 MockConnect connect_data(SYNCHRONOUS, OK);
821 data.set_connect_data(connect_data);
822 session_deps_.socket_factory->AddSocketDataProvider(&data);
823
824 AddSSLSocketData();
825
826 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
827
828 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
829 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
830 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18831 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bnc4c214312016-11-28 16:49:15832
833 StreamDelegateDoNothing delegate(stream);
834 stream->SetDelegate(&delegate);
835
Ryan Hamilton0239aac2018-05-19 00:03:13836 spdy::SpdyHeaderBlock headers(
837 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnc4c214312016-11-28 16:49:15838 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
839 NO_MORE_DATA_TO_SEND));
bnc4c214312016-11-28 16:49:15840
841 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
842}
843
844TEST_F(SpdyStreamTest, HeadersMustPreceedDataOnPushedStream) {
Ryan Hamilton0239aac2018-05-19 00:03:13845 spdy::SpdySerializedFrame req(
846 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnca2fbdc9b2016-11-22 21:14:26847 AddWrite(req);
[email protected]6d116e1a2013-06-24 07:42:15848
Ryan Hamilton0239aac2018-05-19 00:03:13849 spdy::SpdySerializedFrame reply(
850 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:41851 AddRead(reply);
[email protected]6d116e1a2013-06-24 07:42:15852
Ryan Hamilton0239aac2018-05-19 00:03:13853 spdy::SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise(
Bence Békyf1d78522018-01-11 01:16:50854 1, 2, spdy_util_.ConstructGetHeaderBlock(kPushUrl)));
bnc4c214312016-11-28 16:49:15855 AddRead(push_promise);
[email protected]6d116e1a2013-06-24 07:42:15856
Ryan Hamilton0239aac2018-05-19 00:03:13857 spdy::SpdySerializedFrame priority(
tombergan5d22c182017-01-11 02:05:35858 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
859 AddWrite(priority);
860
Ryan Hamilton0239aac2018-05-19 00:03:13861 spdy::SpdySerializedFrame pushed_body(
Bence Békyd74f4382018-02-20 18:26:19862 spdy_util_.ConstructSpdyDataFrame(2, kPostBodyStringPiece, true));
bnc4c214312016-11-28 16:49:15863 AddRead(pushed_body);
mmenkee24011922015-12-17 22:12:59864
Ryan Hamilton0239aac2018-05-19 00:03:13865 spdy::SpdySerializedFrame rst(
866 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_PROTOCOL_ERROR));
bncdf80d44fd2016-07-15 20:27:41867 AddWrite(rst);
[email protected]6d116e1a2013-06-24 07:42:15868
Ryan Hamilton0239aac2018-05-19 00:03:13869 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:19870 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bnc4c214312016-11-28 16:49:15871 AddRead(body);
872
[email protected]6d116e1a2013-06-24 07:42:15873 AddReadEOF();
874
Ryan Sleevib8d7ea02018-05-07 20:01:01875 SequencedSocketData data(GetReads(), GetWrites());
[email protected]6d116e1a2013-06-24 07:42:15876 MockConnect connect_data(SYNCHRONOUS, OK);
877 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59878 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6d116e1a2013-06-24 07:42:15879
bnc032658ba2016-09-26 18:17:15880 AddSSLSocketData();
881
[email protected]795cbf82013-07-22 09:37:27882 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]6d116e1a2013-06-24 07:42:15883
tfarina42834112016-09-22 13:38:20884 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26885 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52886 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18887 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]6d116e1a2013-06-24 07:42:15888
889 StreamDelegateDoNothing delegate(stream);
890 stream->SetDelegate(&delegate);
891
Ryan Hamilton0239aac2018-05-19 00:03:13892 spdy::SpdyHeaderBlock headers(
893 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnca2fbdc9b2016-11-22 21:14:26894 EXPECT_THAT(
895 stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
896 IsError(ERR_IO_PENDING));
[email protected]6d116e1a2013-06-24 07:42:15897
bnc4c214312016-11-28 16:49:15898 EXPECT_THAT(delegate.WaitForClose(), IsOk());
Ryan Hamilton0239aac2018-05-19 00:03:13899 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
Bence Béky4e83f492018-05-13 23:14:25900 EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
bnc4c214312016-11-28 16:49:15901 delegate.TakeReceivedData());
[email protected]6d116e1a2013-06-24 07:42:15902
bnceb9aa7112017-01-05 01:03:46903 // Finish async network reads and writes.
904 base::RunLoop().RunUntilIdle();
905
bnc4c214312016-11-28 16:49:15906 EXPECT_TRUE(data.AllWriteDataConsumed());
907 EXPECT_TRUE(data.AllReadDataConsumed());
908}
[email protected]6d116e1a2013-06-24 07:42:15909
bnc4c214312016-11-28 16:49:15910TEST_F(SpdyStreamTest, TrailersMustNotFollowTrailers) {
Ryan Hamilton0239aac2018-05-19 00:03:13911 spdy::SpdySerializedFrame req(
912 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnc4c214312016-11-28 16:49:15913 AddWrite(req);
[email protected]6d116e1a2013-06-24 07:42:15914
Ryan Hamilton0239aac2018-05-19 00:03:13915 spdy::SpdySerializedFrame reply(
916 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bnc4c214312016-11-28 16:49:15917 AddRead(reply);
[email protected]6d116e1a2013-06-24 07:42:15918
Ryan Hamilton0239aac2018-05-19 00:03:13919 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:19920 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bnc4c214312016-11-28 16:49:15921 AddRead(body);
[email protected]6d116e1a2013-06-24 07:42:15922
Ryan Hamilton0239aac2018-05-19 00:03:13923 spdy::SpdyHeaderBlock trailers_block;
bnc4c214312016-11-28 16:49:15924 trailers_block["foo"] = "bar";
Ryan Hamilton0239aac2018-05-19 00:03:13925 spdy::SpdySerializedFrame first_trailers(
926 spdy_util_.ConstructSpdyResponseHeaders(1, std::move(trailers_block),
927 false));
bnc4c214312016-11-28 16:49:15928 AddRead(first_trailers);
929
930 // Trailers following trailers: procotol error.
Ryan Hamilton0239aac2018-05-19 00:03:13931 spdy::SpdySerializedFrame second_trailers(
932 spdy_util_.ConstructSpdyResponseHeaders(1, std::move(trailers_block),
933 true));
bnc4c214312016-11-28 16:49:15934 AddRead(second_trailers);
935
Ryan Hamilton0239aac2018-05-19 00:03:13936 spdy::SpdySerializedFrame rst(
937 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bnc4c214312016-11-28 16:49:15938 AddWrite(rst);
939
940 AddReadEOF();
941
Ryan Sleevib8d7ea02018-05-07 20:01:01942 SequencedSocketData data(GetReads(), GetWrites());
bnc4c214312016-11-28 16:49:15943 MockConnect connect_data(SYNCHRONOUS, OK);
944 data.set_connect_data(connect_data);
945 session_deps_.socket_factory->AddSocketDataProvider(&data);
946
947 AddSSLSocketData();
948
949 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
950
951 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
952 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
953 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18954 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bnc4c214312016-11-28 16:49:15955
956 StreamDelegateDoNothing delegate(stream);
957 stream->SetDelegate(&delegate);
958
Ryan Hamilton0239aac2018-05-19 00:03:13959 spdy::SpdyHeaderBlock headers(
960 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnc4c214312016-11-28 16:49:15961 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
962 NO_MORE_DATA_TO_SEND));
bnc4c214312016-11-28 16:49:15963
964 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
965
bnceb9aa7112017-01-05 01:03:46966 // Finish async network reads and writes.
967 base::RunLoop().RunUntilIdle();
968
bnc4c214312016-11-28 16:49:15969 EXPECT_TRUE(data.AllWriteDataConsumed());
970 EXPECT_TRUE(data.AllReadDataConsumed());
971}
972
973TEST_F(SpdyStreamTest, DataMustNotFollowTrailers) {
Ryan Hamilton0239aac2018-05-19 00:03:13974 spdy::SpdySerializedFrame req(
975 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnc4c214312016-11-28 16:49:15976 AddWrite(req);
977
Ryan Hamilton0239aac2018-05-19 00:03:13978 spdy::SpdySerializedFrame reply(
979 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bnc4c214312016-11-28 16:49:15980 AddRead(reply);
981
Ryan Hamilton0239aac2018-05-19 00:03:13982 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:19983 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bnc4c214312016-11-28 16:49:15984 AddRead(body);
985
Ryan Hamilton0239aac2018-05-19 00:03:13986 spdy::SpdyHeaderBlock trailers_block;
bnc4c214312016-11-28 16:49:15987 trailers_block["foo"] = "bar";
Ryan Hamilton0239aac2018-05-19 00:03:13988 spdy::SpdySerializedFrame trailers(spdy_util_.ConstructSpdyResponseHeaders(
bnc4c214312016-11-28 16:49:15989 1, std::move(trailers_block), false));
990 AddRead(trailers);
991
992 // DATA frame following trailers: protocol error.
993 AddRead(body);
994
Ryan Hamilton0239aac2018-05-19 00:03:13995 spdy::SpdySerializedFrame rst(
996 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bnc4c214312016-11-28 16:49:15997 AddWrite(rst);
998
999 AddReadEOF();
1000
Ryan Sleevib8d7ea02018-05-07 20:01:011001 SequencedSocketData data(GetReads(), GetWrites());
bnc4c214312016-11-28 16:49:151002 MockConnect connect_data(SYNCHRONOUS, OK);
1003 data.set_connect_data(connect_data);
1004 session_deps_.socket_factory->AddSocketDataProvider(&data);
1005
1006 AddSSLSocketData();
1007
1008 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1009
1010 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1011 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1012 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181013 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bnc4c214312016-11-28 16:49:151014
1015 StreamDelegateDoNothing delegate(stream);
1016 stream->SetDelegate(&delegate);
1017
Ryan Hamilton0239aac2018-05-19 00:03:131018 spdy::SpdyHeaderBlock headers(
1019 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnc4c214312016-11-28 16:49:151020 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
1021 NO_MORE_DATA_TO_SEND));
bnc4c214312016-11-28 16:49:151022
1023 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
1024
bnceb9aa7112017-01-05 01:03:461025 // Finish async network reads and writes.
1026 base::RunLoop().RunUntilIdle();
1027
bnc4c214312016-11-28 16:49:151028 EXPECT_TRUE(data.AllWriteDataConsumed());
1029 EXPECT_TRUE(data.AllReadDataConsumed());
[email protected]6d116e1a2013-06-24 07:42:151030}
1031
bncc9f762a2016-12-06 20:38:231032TEST_F(SpdyStreamTest, InformationalHeaders) {
Ryan Hamilton0239aac2018-05-19 00:03:131033 spdy::SpdySerializedFrame req(
1034 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncc9f762a2016-12-06 20:38:231035 AddWrite(req);
1036
Ryan Hamilton0239aac2018-05-19 00:03:131037 spdy::SpdyHeaderBlock informational_headers;
bncc9f762a2016-12-06 20:38:231038 informational_headers[":status"] = "100";
Ryan Hamilton0239aac2018-05-19 00:03:131039 spdy::SpdySerializedFrame informational_response(
bncc9f762a2016-12-06 20:38:231040 spdy_util_.ConstructSpdyResponseHeaders(
1041 1, std::move(informational_headers), false));
1042 AddRead(informational_response);
1043
Ryan Hamilton0239aac2018-05-19 00:03:131044 spdy::SpdySerializedFrame reply(
1045 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncc9f762a2016-12-06 20:38:231046 AddRead(reply);
1047
Ryan Hamilton0239aac2018-05-19 00:03:131048 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:191049 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bncc9f762a2016-12-06 20:38:231050 AddRead(body);
1051
1052 AddReadEOF();
1053
Ryan Sleevib8d7ea02018-05-07 20:01:011054 SequencedSocketData data(GetReads(), GetWrites());
bncc9f762a2016-12-06 20:38:231055 MockConnect connect_data(SYNCHRONOUS, OK);
1056 data.set_connect_data(connect_data);
1057 session_deps_.socket_factory->AddSocketDataProvider(&data);
1058
1059 AddSSLSocketData();
1060
1061 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1062
1063 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1064 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1065 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181066 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bncc9f762a2016-12-06 20:38:231067
1068 StreamDelegateDoNothing delegate(stream);
1069 stream->SetDelegate(&delegate);
1070
Ryan Hamilton0239aac2018-05-19 00:03:131071 spdy::SpdyHeaderBlock headers(
1072 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bncc9f762a2016-12-06 20:38:231073 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
1074 NO_MORE_DATA_TO_SEND));
bncc9f762a2016-12-06 20:38:231075
1076 EXPECT_THAT(delegate.WaitForClose(), IsOk());
Ryan Hamilton0239aac2018-05-19 00:03:131077 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
Bence Béky4e83f492018-05-13 23:14:251078 EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
bncc9f762a2016-12-06 20:38:231079 delegate.TakeReceivedData());
1080
bnceb9aa7112017-01-05 01:03:461081 // Finish async network reads and writes.
1082 base::RunLoop().RunUntilIdle();
1083
bncc9f762a2016-12-06 20:38:231084 EXPECT_TRUE(data.AllWriteDataConsumed());
1085 EXPECT_TRUE(data.AllReadDataConsumed());
1086}
1087
bnc4ce149622017-03-30 03:31:011088TEST_F(SpdyStreamTest, StatusMustBeNumber) {
Ryan Hamilton0239aac2018-05-19 00:03:131089 spdy::SpdySerializedFrame req(
1090 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncc9f762a2016-12-06 20:38:231091 AddWrite(req);
1092
Ryan Hamilton0239aac2018-05-19 00:03:131093 spdy::SpdyHeaderBlock incorrect_headers;
bncc9f762a2016-12-06 20:38:231094 incorrect_headers[":status"] = "nan";
Ryan Hamilton0239aac2018-05-19 00:03:131095 spdy::SpdySerializedFrame reply(spdy_util_.ConstructSpdyResponseHeaders(
bncc9f762a2016-12-06 20:38:231096 1, std::move(incorrect_headers), false));
1097 AddRead(reply);
1098
Ryan Hamilton0239aac2018-05-19 00:03:131099 spdy::SpdySerializedFrame rst(
1100 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bncc9f762a2016-12-06 20:38:231101 AddWrite(rst);
1102
1103 AddReadEOF();
1104
Ryan Sleevib8d7ea02018-05-07 20:01:011105 SequencedSocketData data(GetReads(), GetWrites());
bncc9f762a2016-12-06 20:38:231106 MockConnect connect_data(SYNCHRONOUS, OK);
1107 data.set_connect_data(connect_data);
1108 session_deps_.socket_factory->AddSocketDataProvider(&data);
1109
1110 AddSSLSocketData();
1111
1112 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1113
1114 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1115 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1116 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181117 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bncc9f762a2016-12-06 20:38:231118
1119 StreamDelegateDoNothing delegate(stream);
1120 stream->SetDelegate(&delegate);
1121
Ryan Hamilton0239aac2018-05-19 00:03:131122 spdy::SpdyHeaderBlock headers(
1123 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bncc9f762a2016-12-06 20:38:231124 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
1125 NO_MORE_DATA_TO_SEND));
bncc9f762a2016-12-06 20:38:231126
1127 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
1128
bnceb9aa7112017-01-05 01:03:461129 // Finish async network reads and writes.
1130 base::RunLoop().RunUntilIdle();
1131
bncc9f762a2016-12-06 20:38:231132 EXPECT_TRUE(data.AllWriteDataConsumed());
1133 EXPECT_TRUE(data.AllReadDataConsumed());
1134}
1135
bnc4ce149622017-03-30 03:31:011136TEST_F(SpdyStreamTest, StatusCannotHaveExtraText) {
Ryan Hamilton0239aac2018-05-19 00:03:131137 spdy::SpdySerializedFrame req(
1138 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnc50ee38e2016-12-08 01:23:541139 AddWrite(req);
1140
Ryan Hamilton0239aac2018-05-19 00:03:131141 spdy::SpdyHeaderBlock headers_with_status_text;
bnc50ee38e2016-12-08 01:23:541142 headers_with_status_text[":status"] =
1143 "200 Some random extra text describing status";
Ryan Hamilton0239aac2018-05-19 00:03:131144 spdy::SpdySerializedFrame reply(spdy_util_.ConstructSpdyResponseHeaders(
bnc50ee38e2016-12-08 01:23:541145 1, std::move(headers_with_status_text), false));
1146 AddRead(reply);
1147
Ryan Hamilton0239aac2018-05-19 00:03:131148 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:191149 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bnc50ee38e2016-12-08 01:23:541150 AddRead(body);
1151
Ryan Hamilton0239aac2018-05-19 00:03:131152 spdy::SpdySerializedFrame rst(
1153 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bnc4ce149622017-03-30 03:31:011154 AddWrite(rst);
1155
bnc50ee38e2016-12-08 01:23:541156 AddReadEOF();
1157
Ryan Sleevib8d7ea02018-05-07 20:01:011158 SequencedSocketData data(GetReads(), GetWrites());
bnc50ee38e2016-12-08 01:23:541159 MockConnect connect_data(SYNCHRONOUS, OK);
1160 data.set_connect_data(connect_data);
1161 session_deps_.socket_factory->AddSocketDataProvider(&data);
1162
1163 AddSSLSocketData();
1164
1165 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1166
1167 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1168 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1169 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181170 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bnc50ee38e2016-12-08 01:23:541171
1172 StreamDelegateDoNothing delegate(stream);
1173 stream->SetDelegate(&delegate);
1174
Ryan Hamilton0239aac2018-05-19 00:03:131175 spdy::SpdyHeaderBlock headers(
1176 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnc50ee38e2016-12-08 01:23:541177 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
1178 NO_MORE_DATA_TO_SEND));
bnc50ee38e2016-12-08 01:23:541179
bnc4ce149622017-03-30 03:31:011180 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
1181
1182 // Finish async network reads and writes.
1183 base::RunLoop().RunUntilIdle();
1184
1185 EXPECT_TRUE(data.AllWriteDataConsumed());
1186 EXPECT_TRUE(data.AllReadDataConsumed());
1187}
1188
1189TEST_F(SpdyStreamTest, StatusMustBePresent) {
Ryan Hamilton0239aac2018-05-19 00:03:131190 spdy::SpdySerializedFrame req(
1191 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnc4ce149622017-03-30 03:31:011192 AddWrite(req);
1193
Ryan Hamilton0239aac2018-05-19 00:03:131194 spdy::SpdyHeaderBlock headers_without_status;
1195 spdy::SpdySerializedFrame reply(spdy_util_.ConstructSpdyResponseHeaders(
bnc4ce149622017-03-30 03:31:011196 1, std::move(headers_without_status), false));
1197 AddRead(reply);
1198
Ryan Hamilton0239aac2018-05-19 00:03:131199 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:191200 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bnc4ce149622017-03-30 03:31:011201 AddRead(body);
1202
Ryan Hamilton0239aac2018-05-19 00:03:131203 spdy::SpdySerializedFrame rst(
1204 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bnc4ce149622017-03-30 03:31:011205 AddWrite(rst);
1206
1207 AddReadEOF();
1208
Ryan Sleevib8d7ea02018-05-07 20:01:011209 SequencedSocketData data(GetReads(), GetWrites());
bnc4ce149622017-03-30 03:31:011210 MockConnect connect_data(SYNCHRONOUS, OK);
1211 data.set_connect_data(connect_data);
1212 session_deps_.socket_factory->AddSocketDataProvider(&data);
1213
1214 AddSSLSocketData();
1215
1216 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1217
1218 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1219 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1220 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181221 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bnc4ce149622017-03-30 03:31:011222
1223 StreamDelegateDoNothing delegate(stream);
1224 stream->SetDelegate(&delegate);
1225
Ryan Hamilton0239aac2018-05-19 00:03:131226 spdy::SpdyHeaderBlock headers(
1227 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnc4ce149622017-03-30 03:31:011228 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
1229 NO_MORE_DATA_TO_SEND));
bnc4ce149622017-03-30 03:31:011230
1231 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
bnc50ee38e2016-12-08 01:23:541232
bnceb9aa7112017-01-05 01:03:461233 // Finish async network reads and writes.
1234 base::RunLoop().RunUntilIdle();
1235
bnc50ee38e2016-12-08 01:23:541236 EXPECT_TRUE(data.AllWriteDataConsumed());
1237 EXPECT_TRUE(data.AllReadDataConsumed());
1238}
1239
bnca2fbdc9b2016-11-22 21:14:261240// Call IncreaseSendWindowSize on a stream with a large enough delta to overflow
1241// an int32_t. The SpdyStream should handle that case gracefully.
bncd16676a2016-07-20 16:23:011242TEST_F(SpdyStreamTest, IncreaseSendWindowSizeOverflow) {
Ryan Hamilton0239aac2018-05-19 00:03:131243 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:261244 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:411245 AddWrite(req);
[email protected]3d587372013-06-01 04:31:451246
mmenkee24011922015-12-17 22:12:591247 AddReadPause();
1248
[email protected]1e5ebd82013-02-20 20:07:241249 // Triggered by the overflowing call to IncreaseSendWindowSize
1250 // below.
Ryan Hamilton0239aac2018-05-19 00:03:131251 spdy::SpdySerializedFrame rst(spdy_util_.ConstructSpdyRstStream(
1252 1, spdy::ERROR_CODE_FLOW_CONTROL_ERROR));
bncdf80d44fd2016-07-15 20:27:411253 AddWrite(rst);
[email protected]3d587372013-06-01 04:31:451254
1255 AddReadEOF();
[email protected]1e5ebd82013-02-20 20:07:241256
vishal.b62985ca92015-04-17 08:45:511257 BoundTestNetLog log;
[email protected]1e5ebd82013-02-20 20:07:241258
Ryan Sleevib8d7ea02018-05-07 20:01:011259 SequencedSocketData data(GetReads(), GetWrites());
[email protected]1e5ebd82013-02-20 20:07:241260 MockConnect connect_data(SYNCHRONOUS, OK);
1261 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:591262 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1e5ebd82013-02-20 20:07:241263
bnc032658ba2016-09-26 18:17:151264 AddSSLSocketData();
1265
[email protected]795cbf82013-07-22 09:37:271266 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]1e5ebd82013-02-20 20:07:241267
bnca2fbdc9b2016-11-22 21:14:261268 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1269 SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, log.bound());
wezca1070932016-05-26 20:30:521270 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181271 EXPECT_EQ(kDefaultUrl, stream->url().spec());
1272
[email protected]194cfcf2013-05-23 21:44:441273 StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
[email protected]1c6b12a2013-03-21 00:59:111274 stream->SetDelegate(&delegate);
[email protected]1e5ebd82013-02-20 20:07:241275
Ryan Hamilton0239aac2018-05-19 00:03:131276 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:261277 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
1278 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
1279 IsError(ERR_IO_PENDING));
[email protected]1c12c062013-05-14 23:13:481280
mmenkee24011922015-12-17 22:12:591281 data.RunUntilPaused();
[email protected]1e5ebd82013-02-20 20:07:241282
avid0181f32015-12-10 19:41:471283 int32_t old_send_window_size = stream->send_window_size();
[email protected]1e5ebd82013-02-20 20:07:241284 ASSERT_GT(old_send_window_size, 0);
avid0181f32015-12-10 19:41:471285 int32_t delta_window_size =
1286 std::numeric_limits<int32_t>::max() - old_send_window_size + 1;
[email protected]1e5ebd82013-02-20 20:07:241287 stream->IncreaseSendWindowSize(delta_window_size);
bnca2fbdc9b2016-11-22 21:14:261288 EXPECT_FALSE(stream);
[email protected]1e5ebd82013-02-20 20:07:241289
mmenkee24011922015-12-17 22:12:591290 data.Resume();
1291 base::RunLoop().RunUntilIdle();
[email protected]1c12c062013-05-14 23:13:481292
Bence Béky6b9c1352018-05-10 11:51:251293 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_FLOW_CONTROL_ERROR));
[email protected]1e5ebd82013-02-20 20:07:241294}
1295
[email protected]d2de7da2013-05-22 07:49:561296// Functions used with
1297// RunResumeAfterUnstall{RequestResponse,Bidirectional}Test().
1298
1299void StallStream(const base::WeakPtr<SpdyStream>& stream) {
1300 // Reduce the send window size to 0 to stall.
1301 while (stream->send_window_size() > 0) {
1302 stream->DecreaseSendWindowSize(
1303 std::min(kMaxSpdyFrameChunkSize, stream->send_window_size()));
1304 }
1305}
1306
1307void IncreaseStreamSendWindowSize(const base::WeakPtr<SpdyStream>& stream,
avid0181f32015-12-10 19:41:471308 int32_t delta_window_size) {
[email protected]d2de7da2013-05-22 07:49:561309 EXPECT_TRUE(stream->send_stalled_by_flow_control());
1310 stream->IncreaseSendWindowSize(delta_window_size);
1311 EXPECT_FALSE(stream->send_stalled_by_flow_control());
1312}
1313
1314void AdjustStreamSendWindowSize(const base::WeakPtr<SpdyStream>& stream,
avid0181f32015-12-10 19:41:471315 int32_t delta_window_size) {
[email protected]d2de7da2013-05-22 07:49:561316 // Make sure that negative adjustments are handled properly.
1317 EXPECT_TRUE(stream->send_stalled_by_flow_control());
Bence Béky05dcb0382017-09-15 20:07:581318 EXPECT_TRUE(stream->AdjustSendWindowSize(-delta_window_size));
[email protected]d2de7da2013-05-22 07:49:561319 EXPECT_TRUE(stream->send_stalled_by_flow_control());
Bence Béky05dcb0382017-09-15 20:07:581320 EXPECT_TRUE(stream->AdjustSendWindowSize(+delta_window_size));
[email protected]d2de7da2013-05-22 07:49:561321 EXPECT_TRUE(stream->send_stalled_by_flow_control());
Bence Béky05dcb0382017-09-15 20:07:581322 EXPECT_TRUE(stream->AdjustSendWindowSize(+delta_window_size));
[email protected]d2de7da2013-05-22 07:49:561323 EXPECT_FALSE(stream->send_stalled_by_flow_control());
1324}
1325
1326// Given an unstall function, runs a test to make sure that a
1327// request/response (i.e., an HTTP-like) stream resumes after a stall
1328// and unstall.
[email protected]3d587372013-06-01 04:31:451329void SpdyStreamTest::RunResumeAfterUnstallRequestResponseTest(
[email protected]d2de7da2013-05-22 07:49:561330 const UnstallFunction& unstall_function) {
Ryan Hamilton0239aac2018-05-19 00:03:131331 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:261332 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:411333 AddWrite(req);
[email protected]3d587372013-06-01 04:31:451334
Ryan Hamilton0239aac2018-05-19 00:03:131335 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:191336 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bncdf80d44fd2016-07-15 20:27:411337 AddWrite(body);
[email protected]34a4dea2013-03-13 00:42:301338
Ryan Hamilton0239aac2018-05-19 00:03:131339 spdy::SpdySerializedFrame resp(
1340 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:411341 AddRead(resp);
[email protected]34a4dea2013-03-13 00:42:301342
[email protected]3d587372013-06-01 04:31:451343 AddReadEOF();
1344
Ryan Sleevib8d7ea02018-05-07 20:01:011345 SequencedSocketData data(GetReads(), GetWrites());
[email protected]34a4dea2013-03-13 00:42:301346 MockConnect connect_data(SYNCHRONOUS, OK);
1347 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:591348 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]34a4dea2013-03-13 00:42:301349
bnc032658ba2016-09-26 18:17:151350 AddSSLSocketData();
1351
[email protected]795cbf82013-07-22 09:37:271352 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]34a4dea2013-03-13 00:42:301353
tfarina42834112016-09-22 13:38:201354 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:261355 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:521356 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181357 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]34a4dea2013-03-13 00:42:301358
[email protected]d26ff352013-05-13 08:48:281359 StreamDelegateWithBody delegate(stream, kPostBodyStringPiece);
[email protected]34a4dea2013-03-13 00:42:301360 stream->SetDelegate(&delegate);
1361
[email protected]1c6b12a2013-03-21 00:59:111362 EXPECT_FALSE(stream->send_stalled_by_flow_control());
[email protected]34a4dea2013-03-13 00:42:301363
Ryan Hamilton0239aac2018-05-19 00:03:131364 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:261365 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
1366 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
1367 IsError(ERR_IO_PENDING));
[email protected]34a4dea2013-03-13 00:42:301368
[email protected]d2de7da2013-05-22 07:49:561369 StallStream(stream);
1370
mmenkee24011922015-12-17 22:12:591371 base::RunLoop().RunUntilIdle();
[email protected]34a4dea2013-03-13 00:42:301372
[email protected]1c6b12a2013-03-21 00:59:111373 EXPECT_TRUE(stream->send_stalled_by_flow_control());
[email protected]34a4dea2013-03-13 00:42:301374
[email protected]d2de7da2013-05-22 07:49:561375 unstall_function.Run(stream, kPostBodyLength);
[email protected]34a4dea2013-03-13 00:42:301376
[email protected]1c6b12a2013-03-21 00:59:111377 EXPECT_FALSE(stream->send_stalled_by_flow_control());
[email protected]34a4dea2013-03-13 00:42:301378
robpercival214763f2016-07-01 23:27:011379 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
[email protected]34a4dea2013-03-13 00:42:301380
1381 EXPECT_TRUE(delegate.send_headers_completed());
1382 EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status"));
Bence Béky4e83f492018-05-13 23:14:251383 EXPECT_EQ(std::string(), delegate.TakeReceivedData());
rch37de576c2015-05-17 20:28:171384 EXPECT_TRUE(data.AllWriteDataConsumed());
[email protected]cbdd73162013-03-18 23:27:331385}
1386
bncd16676a2016-07-20 16:23:011387TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeIncreaseRequestResponse) {
[email protected]d2de7da2013-05-22 07:49:561388 RunResumeAfterUnstallRequestResponseTest(
1389 base::Bind(&IncreaseStreamSendWindowSize));
1390}
1391
bncd16676a2016-07-20 16:23:011392TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeAdjustRequestResponse) {
[email protected]d2de7da2013-05-22 07:49:561393 RunResumeAfterUnstallRequestResponseTest(
1394 base::Bind(&AdjustStreamSendWindowSize));
1395}
1396
bnca2fbdc9b2016-11-22 21:14:261397// Given an unstall function, runs a test to make sure that a bidirectional
1398// (i.e., non-HTTP-like) stream resumes after a stall and unstall.
[email protected]3d587372013-06-01 04:31:451399void SpdyStreamTest::RunResumeAfterUnstallBidirectionalTest(
[email protected]d2de7da2013-05-22 07:49:561400 const UnstallFunction& unstall_function) {
Ryan Hamilton0239aac2018-05-19 00:03:131401 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:261402 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:411403 AddWrite(req);
[email protected]3d587372013-06-01 04:31:451404
mmenkee24011922015-12-17 22:12:591405 AddReadPause();
1406
Ryan Hamilton0239aac2018-05-19 00:03:131407 spdy::SpdySerializedFrame resp(
1408 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:411409 AddRead(resp);
[email protected]3d587372013-06-01 04:31:451410
Ryan Hamilton0239aac2018-05-19 00:03:131411 spdy::SpdySerializedFrame msg(
Bence Békyd74f4382018-02-20 18:26:191412 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bncdf80d44fd2016-07-15 20:27:411413 AddWrite(msg);
[email protected]cbdd73162013-03-18 23:27:331414
Ryan Hamilton0239aac2018-05-19 00:03:131415 spdy::SpdySerializedFrame echo(
Bence Békyd74f4382018-02-20 18:26:191416 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bncdf80d44fd2016-07-15 20:27:411417 AddRead(echo);
[email protected]cbdd73162013-03-18 23:27:331418
[email protected]3d587372013-06-01 04:31:451419 AddReadEOF();
1420
Ryan Sleevib8d7ea02018-05-07 20:01:011421 SequencedSocketData data(GetReads(), GetWrites());
[email protected]cbdd73162013-03-18 23:27:331422 MockConnect connect_data(SYNCHRONOUS, OK);
1423 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:591424 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]cbdd73162013-03-18 23:27:331425
bnc032658ba2016-09-26 18:17:151426 AddSSLSocketData();
1427
[email protected]795cbf82013-07-22 09:37:271428 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]cbdd73162013-03-18 23:27:331429
tfarina42834112016-09-22 13:38:201430 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:261431 SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:521432 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181433 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]cbdd73162013-03-18 23:27:331434
[email protected]194cfcf2013-05-23 21:44:441435 StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
[email protected]cbdd73162013-03-18 23:27:331436 stream->SetDelegate(&delegate);
1437
Ryan Hamilton0239aac2018-05-19 00:03:131438 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:261439 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
1440 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
1441 IsError(ERR_IO_PENDING));
[email protected]cbdd73162013-03-18 23:27:331442
mmenkee24011922015-12-17 22:12:591443 data.RunUntilPaused();
[email protected]cbdd73162013-03-18 23:27:331444
[email protected]1c6b12a2013-03-21 00:59:111445 EXPECT_FALSE(stream->send_stalled_by_flow_control());
[email protected]cbdd73162013-03-18 23:27:331446
[email protected]d2de7da2013-05-22 07:49:561447 StallStream(stream);
[email protected]cbdd73162013-03-18 23:27:331448
mmenkee24011922015-12-17 22:12:591449 data.Resume();
1450 base::RunLoop().RunUntilIdle();
[email protected]cbdd73162013-03-18 23:27:331451
[email protected]1c6b12a2013-03-21 00:59:111452 EXPECT_TRUE(stream->send_stalled_by_flow_control());
[email protected]cbdd73162013-03-18 23:27:331453
[email protected]d2de7da2013-05-22 07:49:561454 unstall_function.Run(stream, kPostBodyLength);
[email protected]cbdd73162013-03-18 23:27:331455
[email protected]1c6b12a2013-03-21 00:59:111456 EXPECT_FALSE(stream->send_stalled_by_flow_control());
[email protected]cbdd73162013-03-18 23:27:331457
robpercival214763f2016-07-01 23:27:011458 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
[email protected]cbdd73162013-03-18 23:27:331459
1460 EXPECT_TRUE(delegate.send_headers_completed());
1461 EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status"));
Bence Béky4e83f492018-05-13 23:14:251462 EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
[email protected]09a8d9172013-04-17 19:23:491463 delegate.TakeReceivedData());
rch37de576c2015-05-17 20:28:171464 EXPECT_TRUE(data.AllWriteDataConsumed());
[email protected]d2de7da2013-05-22 07:49:561465}
1466
bncd16676a2016-07-20 16:23:011467TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeIncreaseBidirectional) {
[email protected]d2de7da2013-05-22 07:49:561468 RunResumeAfterUnstallBidirectionalTest(
1469 base::Bind(&IncreaseStreamSendWindowSize));
1470}
1471
bncd16676a2016-07-20 16:23:011472TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeAdjustBidirectional) {
[email protected]d2de7da2013-05-22 07:49:561473 RunResumeAfterUnstallBidirectionalTest(
1474 base::Bind(&AdjustStreamSendWindowSize));
[email protected]34a4dea2013-03-13 00:42:301475}
1476
[email protected]533f0de2013-12-09 23:03:361477// Test calculation of amount of bytes received from network.
bncd16676a2016-07-20 16:23:011478TEST_F(SpdyStreamTest, ReceivedBytes) {
Ryan Hamilton0239aac2018-05-19 00:03:131479 spdy::SpdySerializedFrame req(
1480 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnca2fbdc9b2016-11-22 21:14:261481 AddWrite(req);
[email protected]533f0de2013-12-09 23:03:361482
mmenkee24011922015-12-17 22:12:591483 AddReadPause();
1484
Ryan Hamilton0239aac2018-05-19 00:03:131485 spdy::SpdySerializedFrame reply(
1486 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:411487 AddRead(reply);
[email protected]533f0de2013-12-09 23:03:361488
mmenkee24011922015-12-17 22:12:591489 AddReadPause();
1490
Ryan Hamilton0239aac2018-05-19 00:03:131491 spdy::SpdySerializedFrame msg(
Bence Békyd74f4382018-02-20 18:26:191492 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bncdf80d44fd2016-07-15 20:27:411493 AddRead(msg);
[email protected]533f0de2013-12-09 23:03:361494
mmenkee24011922015-12-17 22:12:591495 AddReadPause();
1496
[email protected]533f0de2013-12-09 23:03:361497 AddReadEOF();
1498
Ryan Sleevib8d7ea02018-05-07 20:01:011499 SequencedSocketData data(GetReads(), GetWrites());
[email protected]533f0de2013-12-09 23:03:361500 MockConnect connect_data(SYNCHRONOUS, OK);
1501 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:591502 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]533f0de2013-12-09 23:03:361503
bnc032658ba2016-09-26 18:17:151504 AddSSLSocketData();
1505
[email protected]533f0de2013-12-09 23:03:361506 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1507
tfarina42834112016-09-22 13:38:201508 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:261509 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:521510 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181511 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]533f0de2013-12-09 23:03:361512
1513 StreamDelegateDoNothing delegate(stream);
1514 stream->SetDelegate(&delegate);
1515
Ryan Hamilton0239aac2018-05-19 00:03:131516 spdy::SpdyHeaderBlock headers(
1517 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnca2fbdc9b2016-11-22 21:14:261518 EXPECT_THAT(
1519 stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
1520 IsError(ERR_IO_PENDING));
[email protected]533f0de2013-12-09 23:03:361521
bncdf80d44fd2016-07-15 20:27:411522 int64_t reply_frame_len = reply.size();
Ryan Hamilton0239aac2018-05-19 00:03:131523 int64_t data_header_len = spdy::kDataFrameMinimumSize;
avid0181f32015-12-10 19:41:471524 int64_t data_frame_len = data_header_len + kPostBodyLength;
1525 int64_t response_len = reply_frame_len + data_frame_len;
[email protected]533f0de2013-12-09 23:03:361526
1527 EXPECT_EQ(0, stream->raw_received_bytes());
[email protected]533f0de2013-12-09 23:03:361528
bnca2fbdc9b2016-11-22 21:14:261529 // REQUEST
mmenkee24011922015-12-17 22:12:591530 data.RunUntilPaused();
1531 EXPECT_EQ(0, stream->raw_received_bytes());
1532
1533 // REPLY
1534 data.Resume();
1535 data.RunUntilPaused();
1536 EXPECT_EQ(reply_frame_len, stream->raw_received_bytes());
1537
1538 // DATA
1539 data.Resume();
1540 data.RunUntilPaused();
1541 EXPECT_EQ(response_len, stream->raw_received_bytes());
1542
1543 // FIN
1544 data.Resume();
robpercival214763f2016-07-01 23:27:011545 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
[email protected]533f0de2013-12-09 23:03:361546}
1547
Bence Békycf3fd8a42018-02-09 20:15:471548// Regression test for https://crbug.com/810763.
1549TEST_F(SpdyStreamTest, DataOnHalfClosedRemoveStream) {
Ryan Hamilton0239aac2018-05-19 00:03:131550 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
Bence Békycf3fd8a42018-02-09 20:15:471551 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
1552 AddWrite(req);
1553
Ryan Hamilton0239aac2018-05-19 00:03:131554 spdy::SpdyHeaderBlock response_headers;
1555 response_headers[spdy::kHttp2StatusHeader] = "200";
1556 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
Bence Békycf3fd8a42018-02-09 20:15:471557 1, std::move(response_headers), /* fin = */ true));
1558 AddRead(resp);
1559
Ryan Hamilton0239aac2018-05-19 00:03:131560 spdy::SpdySerializedFrame data_frame(
Bence Békyd74f4382018-02-20 18:26:191561 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
Bence Békycf3fd8a42018-02-09 20:15:471562 AddRead(data_frame);
1563
Ryan Hamilton0239aac2018-05-19 00:03:131564 spdy::SpdySerializedFrame rst(
1565 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_STREAM_CLOSED));
Bence Békycf3fd8a42018-02-09 20:15:471566 AddWrite(rst);
1567
1568 AddReadEOF();
1569
Ryan Sleevib8d7ea02018-05-07 20:01:011570 SequencedSocketData data(GetReads(), GetWrites());
Bence Békycf3fd8a42018-02-09 20:15:471571 MockConnect connect_data(SYNCHRONOUS, OK);
1572 data.set_connect_data(connect_data);
1573 session_deps_.socket_factory->AddSocketDataProvider(&data);
1574
1575 AddSSLSocketData();
1576
1577 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1578
1579 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1580 SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
1581 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181582 EXPECT_EQ(kDefaultUrl, stream->url().spec());
Bence Békycf3fd8a42018-02-09 20:15:471583
1584 StreamDelegateDoNothing delegate(stream);
1585 stream->SetDelegate(&delegate);
1586
Ryan Hamilton0239aac2018-05-19 00:03:131587 spdy::SpdyHeaderBlock headers(
Bence Békycf3fd8a42018-02-09 20:15:471588 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
1589 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
1590 IsError(ERR_IO_PENDING));
Bence Békycf3fd8a42018-02-09 20:15:471591
Bence Béky6b9c1352018-05-10 11:51:251592 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_STREAM_CLOSED));
Bence Békycf3fd8a42018-02-09 20:15:471593
1594 base::RunLoop().RunUntilIdle();
1595
1596 EXPECT_TRUE(data.AllReadDataConsumed());
1597 EXPECT_TRUE(data.AllWriteDataConsumed());
1598}
1599
[email protected]39d13d942012-07-19 16:48:201600} // namespace test
1601
[email protected]4f386422010-07-20 04:19:491602} // namespace net