blob: 3bb1008758dbc366c106dd1fa64356d58a6baddf [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
Sebastien Marchand6d0558fd2019-01-25 16:49:3717#include "base/bind.h"
[email protected]3b63f8f42011-03-28 01:54:1518#include "base/memory/ref_counted.h"
mmenkee24011922015-12-17 22:12:5919#include "base/run_loop.h"
Avi Drissman4365a4782018-12-28 19:26:2420#include "base/stl_util.h"
Bence Béky4e83f492018-05-13 23:14:2521#include "base/strings/string_piece.h"
[email protected]1bbabc82013-03-25 21:11:0222#include "net/base/request_priority.h"
Bence Béky5b1e4ce72018-01-11 14:55:1523#include "net/http/http_request_info.h"
mikecirone8b85c432016-09-08 19:11:0024#include "net/log/net_log_event_type.h"
mmenke16a7cbdd2015-04-24 23:00:5625#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4626#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"
Victor Vasiliev27cc7712019-01-24 11:50:1440#include "net/third_party/quiche/src/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
Gabriel Charette694c3c332019-08-19 14:53:0565class SpdyStreamTest : public TestWithTaskEnvironment {
[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.
Eric Roman79cc7552019-07-19 02:17:54451 auto entries = log.GetEntries();
[email protected]d245c342012-02-23 20:49:15452 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
Eric Roman79cc7552019-07-19 02:17:54458 EXPECT_EQ(static_cast<int>(stream_id),
459 GetIntegerValueFromParams(entries[pos], "stream_id"));
[email protected]d245c342012-02-23 20:49:15460}
[email protected]a7a265ef2010-12-08 18:05:57461
bnca2fbdc9b2016-11-22 21:14:26462// Make sure that large blocks of data are properly split up into frame-sized
463// chunks for a request/response (i.e., an HTTP-like) stream.
bncd16676a2016-07-20 16:23:01464TEST_F(SpdyStreamTest, SendLargeDataAfterOpenRequestResponse) {
Ryan Hamilton0239aac2018-05-19 00:03:13465 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:26466 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41467 AddWrite(req);
[email protected]3d587372013-06-01 04:31:45468
Bence Béky4e83f492018-05-13 23:14:25469 std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
Ryan Hamilton0239aac2018-05-19 00:03:13470 spdy::SpdySerializedFrame chunk(
Bence Békyd74f4382018-02-20 18:26:19471 spdy_util_.ConstructSpdyDataFrame(1, chunk_data, false));
bncdf80d44fd2016-07-15 20:27:41472 AddWrite(chunk);
473 AddWrite(chunk);
[email protected]3d587372013-06-01 04:31:45474
Ryan Hamilton0239aac2018-05-19 00:03:13475 spdy::SpdySerializedFrame last_chunk(
Bence Békyd74f4382018-02-20 18:26:19476 spdy_util_.ConstructSpdyDataFrame(1, chunk_data, true));
bncdf80d44fd2016-07-15 20:27:41477 AddWrite(last_chunk);
[email protected]aa19cfc2013-05-23 16:41:38478
Ryan Hamilton0239aac2018-05-19 00:03:13479 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41480 AddRead(resp);
[email protected]aa19cfc2013-05-23 16:41:38481
[email protected]3d587372013-06-01 04:31:45482 AddReadEOF();
483
Ryan Sleevib8d7ea02018-05-07 20:01:01484 SequencedSocketData data(GetReads(), GetWrites());
[email protected]aa19cfc2013-05-23 16:41:38485 MockConnect connect_data(SYNCHRONOUS, OK);
486 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59487 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]aa19cfc2013-05-23 16:41:38488
bnc032658ba2016-09-26 18:17:15489 AddSSLSocketData();
490
[email protected]795cbf82013-07-22 09:37:27491 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]aa19cfc2013-05-23 16:41:38492
tfarina42834112016-09-22 13:38:20493 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26494 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52495 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18496 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]aa19cfc2013-05-23 16:41:38497
Bence Béky4e83f492018-05-13 23:14:25498 std::string body_data(3 * kMaxSpdyFrameChunkSize, 'x');
[email protected]aa19cfc2013-05-23 16:41:38499 StreamDelegateWithBody delegate(stream, body_data);
500 stream->SetDelegate(&delegate);
501
Ryan Hamilton0239aac2018-05-19 00:03:13502 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:26503 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
504 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
505 IsError(ERR_IO_PENDING));
[email protected]aa19cfc2013-05-23 16:41:38506
robpercival214763f2016-07-01 23:27:01507 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
[email protected]aa19cfc2013-05-23 16:41:38508
509 EXPECT_TRUE(delegate.send_headers_completed());
Ryan Hamilton0239aac2018-05-19 00:03:13510 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
Bence Béky4e83f492018-05-13 23:14:25511 EXPECT_EQ(std::string(), delegate.TakeReceivedData());
rch37de576c2015-05-17 20:28:17512 EXPECT_TRUE(data.AllWriteDataConsumed());
[email protected]aa19cfc2013-05-23 16:41:38513}
514
bnca2fbdc9b2016-11-22 21:14:26515// Make sure that large blocks of data are properly split up into frame-sized
516// chunks for a bidirectional (i.e., non-HTTP-like) stream.
bncd16676a2016-07-20 16:23:01517TEST_F(SpdyStreamTest, SendLargeDataAfterOpenBidirectional) {
Ryan Hamilton0239aac2018-05-19 00:03:13518 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:26519 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41520 AddWrite(req);
[email protected]3d587372013-06-01 04:31:45521
Ryan Hamilton0239aac2018-05-19 00:03:13522 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
bncdf80d44fd2016-07-15 20:27:41523 AddRead(resp);
[email protected]3d587372013-06-01 04:31:45524
Bence Béky4e83f492018-05-13 23:14:25525 std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
Ryan Hamilton0239aac2018-05-19 00:03:13526 spdy::SpdySerializedFrame chunk(
Bence Békyd74f4382018-02-20 18:26:19527 spdy_util_.ConstructSpdyDataFrame(1, chunk_data, false));
bncdf80d44fd2016-07-15 20:27:41528 AddWrite(chunk);
529 AddWrite(chunk);
530 AddWrite(chunk);
[email protected]aa19cfc2013-05-23 16:41:38531
[email protected]3d587372013-06-01 04:31:45532 AddReadEOF();
[email protected]aa19cfc2013-05-23 16:41:38533
Ryan Sleevib8d7ea02018-05-07 20:01:01534 SequencedSocketData data(GetReads(), GetWrites());
[email protected]aa19cfc2013-05-23 16:41:38535 MockConnect connect_data(SYNCHRONOUS, OK);
536 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59537 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]aa19cfc2013-05-23 16:41:38538
bnc032658ba2016-09-26 18:17:15539 AddSSLSocketData();
540
[email protected]795cbf82013-07-22 09:37:27541 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]aa19cfc2013-05-23 16:41:38542
tfarina42834112016-09-22 13:38:20543 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26544 SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52545 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18546 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]aa19cfc2013-05-23 16:41:38547
Bence Béky4e83f492018-05-13 23:14:25548 std::string body_data(3 * kMaxSpdyFrameChunkSize, 'x');
[email protected]194cfcf2013-05-23 21:44:44549 StreamDelegateSendImmediate delegate(stream, body_data);
[email protected]aa19cfc2013-05-23 16:41:38550 stream->SetDelegate(&delegate);
551
Ryan Hamilton0239aac2018-05-19 00:03:13552 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:26553 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
554 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
555 IsError(ERR_IO_PENDING));
[email protected]aa19cfc2013-05-23 16:41:38556
robpercival214763f2016-07-01 23:27:01557 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
[email protected]aa19cfc2013-05-23 16:41:38558
559 EXPECT_TRUE(delegate.send_headers_completed());
Ryan Hamilton0239aac2018-05-19 00:03:13560 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
Bence Béky4e83f492018-05-13 23:14:25561 EXPECT_EQ(std::string(), delegate.TakeReceivedData());
rch37de576c2015-05-17 20:28:17562 EXPECT_TRUE(data.AllWriteDataConsumed());
[email protected]aa19cfc2013-05-23 16:41:38563}
564
bnca2fbdc9b2016-11-22 21:14:26565// Receiving a header with uppercase ASCII should result in a protocol error.
bncd16676a2016-07-20 16:23:01566TEST_F(SpdyStreamTest, UpperCaseHeaders) {
Ryan Hamilton0239aac2018-05-19 00:03:13567 spdy::SpdySerializedFrame req(
568 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnca2fbdc9b2016-11-22 21:14:26569 AddWrite(req);
[email protected]6d116e1a2013-06-24 07:42:15570
571 const char* const kExtraHeaders[] = {"X-UpperCase", "yes"};
Ryan Hamilton0239aac2018-05-19 00:03:13572 spdy::SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(
Avi Drissman4365a4782018-12-28 19:26:24573 kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
bncdf80d44fd2016-07-15 20:27:41574 AddRead(reply);
[email protected]6d116e1a2013-06-24 07:42:15575
Ryan Hamilton0239aac2018-05-19 00:03:13576 spdy::SpdySerializedFrame rst(
577 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bncdf80d44fd2016-07-15 20:27:41578 AddWrite(rst);
[email protected]6d116e1a2013-06-24 07:42:15579
580 AddReadEOF();
581
Ryan Sleevib8d7ea02018-05-07 20:01:01582 SequencedSocketData data(GetReads(), GetWrites());
[email protected]6d116e1a2013-06-24 07:42:15583 MockConnect connect_data(SYNCHRONOUS, OK);
584 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59585 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6d116e1a2013-06-24 07:42:15586
bnc032658ba2016-09-26 18:17:15587 AddSSLSocketData();
588
[email protected]795cbf82013-07-22 09:37:27589 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]6d116e1a2013-06-24 07:42:15590
tfarina42834112016-09-22 13:38:20591 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26592 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52593 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18594 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]6d116e1a2013-06-24 07:42:15595
596 StreamDelegateDoNothing delegate(stream);
597 stream->SetDelegate(&delegate);
598
Ryan Hamilton0239aac2018-05-19 00:03:13599 spdy::SpdyHeaderBlock headers(
600 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnca2fbdc9b2016-11-22 21:14:26601 EXPECT_THAT(
602 stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
603 IsError(ERR_IO_PENDING));
[email protected]6d116e1a2013-06-24 07:42:15604
Bence Békyd0d69502019-06-25 19:47:18605 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
bnc4c214312016-11-28 16:49:15606
bnceb9aa7112017-01-05 01:03:46607 // Finish async network reads and writes.
608 base::RunLoop().RunUntilIdle();
609
bnc4c214312016-11-28 16:49:15610 EXPECT_TRUE(data.AllWriteDataConsumed());
611 EXPECT_TRUE(data.AllReadDataConsumed());
[email protected]6d116e1a2013-06-24 07:42:15612}
613
bnca2fbdc9b2016-11-22 21:14:26614// Receiving a header with uppercase ASCII should result in a protocol error
615// even for a push stream.
bncd16676a2016-07-20 16:23:01616TEST_F(SpdyStreamTest, UpperCaseHeadersOnPush) {
Ryan Hamilton0239aac2018-05-19 00:03:13617 spdy::SpdySerializedFrame req(
618 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnca2fbdc9b2016-11-22 21:14:26619 AddWrite(req);
[email protected]6d116e1a2013-06-24 07:42:15620
Ryan Hamilton0239aac2018-05-19 00:03:13621 spdy::SpdySerializedFrame reply(
622 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:41623 AddRead(reply);
[email protected]6d116e1a2013-06-24 07:42:15624
bnc4c214312016-11-28 16:49:15625 const char* const kExtraHeaders[] = {"X-UpperCase", "yes"};
Ryan Hamilton0239aac2018-05-19 00:03:13626 spdy::SpdySerializedFrame push(spdy_util_.ConstructSpdyPush(
Avi Drissman4365a4782018-12-28 19:26:24627 kExtraHeaders, base::size(kExtraHeaders) / 2, 2, 1, kPushUrl));
bncdf80d44fd2016-07-15 20:27:41628 AddRead(push);
[email protected]6d116e1a2013-06-24 07:42:15629
Ryan Hamilton0239aac2018-05-19 00:03:13630 spdy::SpdySerializedFrame priority(
tombergan5d22c182017-01-11 02:05:35631 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
632 AddWrite(priority);
633
Ryan Hamilton0239aac2018-05-19 00:03:13634 spdy::SpdySerializedFrame rst(
635 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_PROTOCOL_ERROR));
bncdf80d44fd2016-07-15 20:27:41636 AddWrite(rst);
[email protected]6d116e1a2013-06-24 07:42:15637
mmenkee24011922015-12-17 22:12:59638 AddReadPause();
639
[email protected]6d116e1a2013-06-24 07:42:15640 AddReadEOF();
641
Ryan Sleevib8d7ea02018-05-07 20:01:01642 SequencedSocketData data(GetReads(), GetWrites());
[email protected]6d116e1a2013-06-24 07:42:15643 MockConnect connect_data(SYNCHRONOUS, OK);
644 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59645 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6d116e1a2013-06-24 07:42:15646
bnc032658ba2016-09-26 18:17:15647 AddSSLSocketData();
648
[email protected]795cbf82013-07-22 09:37:27649 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]6d116e1a2013-06-24 07:42:15650
tfarina42834112016-09-22 13:38:20651 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26652 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52653 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18654 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]6d116e1a2013-06-24 07:42:15655
656 StreamDelegateDoNothing delegate(stream);
657 stream->SetDelegate(&delegate);
658
Ryan Hamilton0239aac2018-05-19 00:03:13659 spdy::SpdyHeaderBlock headers(
660 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnca2fbdc9b2016-11-22 21:14:26661 EXPECT_THAT(
662 stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
663 IsError(ERR_IO_PENDING));
[email protected]6d116e1a2013-06-24 07:42:15664
mmenkee24011922015-12-17 22:12:59665 data.RunUntilPaused();
[email protected]6d116e1a2013-06-24 07:42:15666
Bence Béky7bf94362018-01-10 13:19:36667 EXPECT_EQ(0u, num_pushed_streams(session));
[email protected]6d116e1a2013-06-24 07:42:15668
mmenkee24011922015-12-17 22:12:59669 data.Resume();
[email protected]6d116e1a2013-06-24 07:42:15670
robpercival214763f2016-07-01 23:27:01671 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
bnc4c214312016-11-28 16:49:15672
673 EXPECT_TRUE(data.AllWriteDataConsumed());
674 EXPECT_TRUE(data.AllReadDataConsumed());
[email protected]6d116e1a2013-06-24 07:42:15675}
676
bnc4c214312016-11-28 16:49:15677TEST_F(SpdyStreamTest, HeadersMustHaveStatus) {
Ryan Hamilton0239aac2018-05-19 00:03:13678 spdy::SpdySerializedFrame req(
679 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnc4c214312016-11-28 16:49:15680 AddWrite(req);
681
682 // Response headers without ":status" header field: protocol error.
Ryan Hamilton0239aac2018-05-19 00:03:13683 spdy::SpdyHeaderBlock header_block_without_status;
684 header_block_without_status[spdy::kHttp2MethodHeader] = "GET";
685 header_block_without_status[spdy::kHttp2AuthorityHeader] = "www.example.org";
686 header_block_without_status[spdy::kHttp2SchemeHeader] = "https";
687 header_block_without_status[spdy::kHttp2PathHeader] = "/";
688 spdy::SpdySerializedFrame reply(
bnc4c214312016-11-28 16:49:15689 spdy_util_.ConstructSpdyReply(1, std::move(header_block_without_status)));
690 AddRead(reply);
691
Ryan Hamilton0239aac2018-05-19 00:03:13692 spdy::SpdySerializedFrame rst(
693 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bnc4c214312016-11-28 16:49:15694 AddWrite(rst);
695
696 AddReadEOF();
697
Ryan Sleevib8d7ea02018-05-07 20:01:01698 SequencedSocketData data(GetReads(), GetWrites());
bnc4c214312016-11-28 16:49:15699 MockConnect connect_data(SYNCHRONOUS, OK);
700 data.set_connect_data(connect_data);
701 session_deps_.socket_factory->AddSocketDataProvider(&data);
702
703 AddSSLSocketData();
704
705 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
706
707 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
708 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
709 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18710 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bnc4c214312016-11-28 16:49:15711
712 StreamDelegateDoNothing delegate(stream);
713 stream->SetDelegate(&delegate);
714
Ryan Hamilton0239aac2018-05-19 00:03:13715 spdy::SpdyHeaderBlock headers(
716 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnc4c214312016-11-28 16:49:15717 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
718 NO_MORE_DATA_TO_SEND));
bnc4c214312016-11-28 16:49:15719
Bence Békyd0d69502019-06-25 19:47:18720 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
bnc4c214312016-11-28 16:49:15721
bnceb9aa7112017-01-05 01:03:46722 // Finish async network reads and writes.
723 base::RunLoop().RunUntilIdle();
724
bnc4c214312016-11-28 16:49:15725 EXPECT_TRUE(data.AllWriteDataConsumed());
726 EXPECT_TRUE(data.AllReadDataConsumed());
727}
728
729TEST_F(SpdyStreamTest, HeadersMustHaveStatusOnPushedStream) {
Ryan Hamilton0239aac2018-05-19 00:03:13730 spdy::SpdySerializedFrame req(
731 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnca2fbdc9b2016-11-22 21:14:26732 AddWrite(req);
[email protected]6d116e1a2013-06-24 07:42:15733
Ryan Hamilton0239aac2018-05-19 00:03:13734 spdy::SpdySerializedFrame reply(
735 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:41736 AddRead(reply);
[email protected]6d116e1a2013-06-24 07:42:15737
Ryan Hamilton0239aac2018-05-19 00:03:13738 spdy::SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise(
Bence Békyf1d78522018-01-11 01:16:50739 1, 2, spdy_util_.ConstructGetHeaderBlock(kPushUrl)));
bnc4c214312016-11-28 16:49:15740 AddRead(push_promise);
[email protected]6d116e1a2013-06-24 07:42:15741
Ryan Hamilton0239aac2018-05-19 00:03:13742 spdy::SpdySerializedFrame priority(
tombergan5d22c182017-01-11 02:05:35743 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
744 AddWrite(priority);
745
bnc4c214312016-11-28 16:49:15746 // Response headers without ":status" header field: protocol error.
Ryan Hamilton0239aac2018-05-19 00:03:13747 spdy::SpdyHeaderBlock header_block_without_status;
748 header_block_without_status[spdy::kHttp2MethodHeader] = "GET";
749 header_block_without_status[spdy::kHttp2AuthorityHeader] = "www.example.org";
750 header_block_without_status[spdy::kHttp2SchemeHeader] = "https";
751 header_block_without_status[spdy::kHttp2PathHeader] = "/";
752 spdy::SpdySerializedFrame pushed_reply(
bnc4c214312016-11-28 16:49:15753 spdy_util_.ConstructSpdyReply(2, std::move(header_block_without_status)));
754 AddRead(pushed_reply);
mmenkee24011922015-12-17 22:12:59755
Ryan Hamilton0239aac2018-05-19 00:03:13756 spdy::SpdySerializedFrame rst(
757 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_PROTOCOL_ERROR));
bncdf80d44fd2016-07-15 20:27:41758 AddWrite(rst);
[email protected]6d116e1a2013-06-24 07:42:15759
Ryan Hamilton0239aac2018-05-19 00:03:13760 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:19761 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bnc4c214312016-11-28 16:49:15762 AddRead(body);
763
[email protected]6d116e1a2013-06-24 07:42:15764 AddReadEOF();
765
Ryan Sleevib8d7ea02018-05-07 20:01:01766 SequencedSocketData data(GetReads(), GetWrites());
[email protected]6d116e1a2013-06-24 07:42:15767 MockConnect connect_data(SYNCHRONOUS, OK);
768 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59769 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6d116e1a2013-06-24 07:42:15770
bnc032658ba2016-09-26 18:17:15771 AddSSLSocketData();
772
[email protected]795cbf82013-07-22 09:37:27773 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]6d116e1a2013-06-24 07:42:15774
tfarina42834112016-09-22 13:38:20775 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26776 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52777 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18778 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]6d116e1a2013-06-24 07:42:15779
780 StreamDelegateDoNothing delegate(stream);
781 stream->SetDelegate(&delegate);
782
Ryan Hamilton0239aac2018-05-19 00:03:13783 spdy::SpdyHeaderBlock headers(
784 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnca2fbdc9b2016-11-22 21:14:26785 EXPECT_THAT(
786 stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
787 IsError(ERR_IO_PENDING));
[email protected]6d116e1a2013-06-24 07:42:15788
bnc4c214312016-11-28 16:49:15789 EXPECT_THAT(delegate.WaitForClose(), IsOk());
Ryan Hamilton0239aac2018-05-19 00:03:13790 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
Bence Béky4e83f492018-05-13 23:14:25791 EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
bnc4c214312016-11-28 16:49:15792 delegate.TakeReceivedData());
[email protected]6d116e1a2013-06-24 07:42:15793
bnceb9aa7112017-01-05 01:03:46794 // Finish async network reads and writes.
795 base::RunLoop().RunUntilIdle();
796
bnc4c214312016-11-28 16:49:15797 EXPECT_TRUE(data.AllWriteDataConsumed());
798 EXPECT_TRUE(data.AllReadDataConsumed());
[email protected]6d116e1a2013-06-24 07:42:15799}
800
bnc4c214312016-11-28 16:49:15801TEST_F(SpdyStreamTest, HeadersMustPreceedData) {
Ryan Hamilton0239aac2018-05-19 00:03:13802 spdy::SpdySerializedFrame req(
803 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnc4c214312016-11-28 16:49:15804 AddWrite(req);
805
806 // Response body not preceeded by headers: protocol error.
Ryan Hamilton0239aac2018-05-19 00:03:13807 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:19808 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bnc4c214312016-11-28 16:49:15809 AddRead(body);
810
Ryan Hamilton0239aac2018-05-19 00:03:13811 spdy::SpdySerializedFrame rst(
812 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bnc4c214312016-11-28 16:49:15813 AddWrite(rst);
814
815 AddReadEOF();
816
Ryan Sleevib8d7ea02018-05-07 20:01:01817 SequencedSocketData data(GetReads(), GetWrites());
bnc4c214312016-11-28 16:49:15818 MockConnect connect_data(SYNCHRONOUS, OK);
819 data.set_connect_data(connect_data);
820 session_deps_.socket_factory->AddSocketDataProvider(&data);
821
822 AddSSLSocketData();
823
824 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
825
826 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
827 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
828 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18829 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bnc4c214312016-11-28 16:49:15830
831 StreamDelegateDoNothing delegate(stream);
832 stream->SetDelegate(&delegate);
833
Ryan Hamilton0239aac2018-05-19 00:03:13834 spdy::SpdyHeaderBlock headers(
835 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnc4c214312016-11-28 16:49:15836 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
837 NO_MORE_DATA_TO_SEND));
bnc4c214312016-11-28 16:49:15838
Bence Békyd0d69502019-06-25 19:47:18839 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
bnc4c214312016-11-28 16:49:15840}
841
842TEST_F(SpdyStreamTest, HeadersMustPreceedDataOnPushedStream) {
Ryan Hamilton0239aac2018-05-19 00:03:13843 spdy::SpdySerializedFrame req(
844 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnca2fbdc9b2016-11-22 21:14:26845 AddWrite(req);
[email protected]6d116e1a2013-06-24 07:42:15846
Ryan Hamilton0239aac2018-05-19 00:03:13847 spdy::SpdySerializedFrame reply(
848 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:41849 AddRead(reply);
[email protected]6d116e1a2013-06-24 07:42:15850
Ryan Hamilton0239aac2018-05-19 00:03:13851 spdy::SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise(
Bence Békyf1d78522018-01-11 01:16:50852 1, 2, spdy_util_.ConstructGetHeaderBlock(kPushUrl)));
bnc4c214312016-11-28 16:49:15853 AddRead(push_promise);
[email protected]6d116e1a2013-06-24 07:42:15854
Ryan Hamilton0239aac2018-05-19 00:03:13855 spdy::SpdySerializedFrame priority(
tombergan5d22c182017-01-11 02:05:35856 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
857 AddWrite(priority);
858
Ryan Hamilton0239aac2018-05-19 00:03:13859 spdy::SpdySerializedFrame pushed_body(
Bence Békyd74f4382018-02-20 18:26:19860 spdy_util_.ConstructSpdyDataFrame(2, kPostBodyStringPiece, true));
bnc4c214312016-11-28 16:49:15861 AddRead(pushed_body);
mmenkee24011922015-12-17 22:12:59862
Ryan Hamilton0239aac2018-05-19 00:03:13863 spdy::SpdySerializedFrame rst(
864 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_PROTOCOL_ERROR));
bncdf80d44fd2016-07-15 20:27:41865 AddWrite(rst);
[email protected]6d116e1a2013-06-24 07:42:15866
Ryan Hamilton0239aac2018-05-19 00:03:13867 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:19868 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bnc4c214312016-11-28 16:49:15869 AddRead(body);
870
[email protected]6d116e1a2013-06-24 07:42:15871 AddReadEOF();
872
Ryan Sleevib8d7ea02018-05-07 20:01:01873 SequencedSocketData data(GetReads(), GetWrites());
[email protected]6d116e1a2013-06-24 07:42:15874 MockConnect connect_data(SYNCHRONOUS, OK);
875 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:59876 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6d116e1a2013-06-24 07:42:15877
bnc032658ba2016-09-26 18:17:15878 AddSSLSocketData();
879
[email protected]795cbf82013-07-22 09:37:27880 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]6d116e1a2013-06-24 07:42:15881
tfarina42834112016-09-22 13:38:20882 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:26883 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:52884 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18885 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]6d116e1a2013-06-24 07:42:15886
887 StreamDelegateDoNothing delegate(stream);
888 stream->SetDelegate(&delegate);
889
Ryan Hamilton0239aac2018-05-19 00:03:13890 spdy::SpdyHeaderBlock headers(
891 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnca2fbdc9b2016-11-22 21:14:26892 EXPECT_THAT(
893 stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
894 IsError(ERR_IO_PENDING));
[email protected]6d116e1a2013-06-24 07:42:15895
bnc4c214312016-11-28 16:49:15896 EXPECT_THAT(delegate.WaitForClose(), IsOk());
Ryan Hamilton0239aac2018-05-19 00:03:13897 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
Bence Béky4e83f492018-05-13 23:14:25898 EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
bnc4c214312016-11-28 16:49:15899 delegate.TakeReceivedData());
[email protected]6d116e1a2013-06-24 07:42:15900
bnceb9aa7112017-01-05 01:03:46901 // Finish async network reads and writes.
902 base::RunLoop().RunUntilIdle();
903
bnc4c214312016-11-28 16:49:15904 EXPECT_TRUE(data.AllWriteDataConsumed());
905 EXPECT_TRUE(data.AllReadDataConsumed());
906}
[email protected]6d116e1a2013-06-24 07:42:15907
bnc4c214312016-11-28 16:49:15908TEST_F(SpdyStreamTest, TrailersMustNotFollowTrailers) {
Ryan Hamilton0239aac2018-05-19 00:03:13909 spdy::SpdySerializedFrame req(
910 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnc4c214312016-11-28 16:49:15911 AddWrite(req);
[email protected]6d116e1a2013-06-24 07:42:15912
Ryan Hamilton0239aac2018-05-19 00:03:13913 spdy::SpdySerializedFrame reply(
914 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bnc4c214312016-11-28 16:49:15915 AddRead(reply);
[email protected]6d116e1a2013-06-24 07:42:15916
Ryan Hamilton0239aac2018-05-19 00:03:13917 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:19918 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bnc4c214312016-11-28 16:49:15919 AddRead(body);
[email protected]6d116e1a2013-06-24 07:42:15920
Ryan Hamilton0239aac2018-05-19 00:03:13921 spdy::SpdyHeaderBlock trailers_block;
bnc4c214312016-11-28 16:49:15922 trailers_block["foo"] = "bar";
Ryan Hamilton0239aac2018-05-19 00:03:13923 spdy::SpdySerializedFrame first_trailers(
924 spdy_util_.ConstructSpdyResponseHeaders(1, std::move(trailers_block),
925 false));
bnc4c214312016-11-28 16:49:15926 AddRead(first_trailers);
927
928 // Trailers following trailers: procotol error.
Ryan Hamilton0239aac2018-05-19 00:03:13929 spdy::SpdySerializedFrame second_trailers(
930 spdy_util_.ConstructSpdyResponseHeaders(1, std::move(trailers_block),
931 true));
bnc4c214312016-11-28 16:49:15932 AddRead(second_trailers);
933
Ryan Hamilton0239aac2018-05-19 00:03:13934 spdy::SpdySerializedFrame rst(
935 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bnc4c214312016-11-28 16:49:15936 AddWrite(rst);
937
938 AddReadEOF();
939
Ryan Sleevib8d7ea02018-05-07 20:01:01940 SequencedSocketData data(GetReads(), GetWrites());
bnc4c214312016-11-28 16:49:15941 MockConnect connect_data(SYNCHRONOUS, OK);
942 data.set_connect_data(connect_data);
943 session_deps_.socket_factory->AddSocketDataProvider(&data);
944
945 AddSSLSocketData();
946
947 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
948
949 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
950 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
951 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:18952 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bnc4c214312016-11-28 16:49:15953
954 StreamDelegateDoNothing delegate(stream);
955 stream->SetDelegate(&delegate);
956
Ryan Hamilton0239aac2018-05-19 00:03:13957 spdy::SpdyHeaderBlock headers(
958 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnc4c214312016-11-28 16:49:15959 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
960 NO_MORE_DATA_TO_SEND));
bnc4c214312016-11-28 16:49:15961
Bence Békyd0d69502019-06-25 19:47:18962 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
bnc4c214312016-11-28 16:49:15963
bnceb9aa7112017-01-05 01:03:46964 // Finish async network reads and writes.
965 base::RunLoop().RunUntilIdle();
966
bnc4c214312016-11-28 16:49:15967 EXPECT_TRUE(data.AllWriteDataConsumed());
968 EXPECT_TRUE(data.AllReadDataConsumed());
969}
970
971TEST_F(SpdyStreamTest, DataMustNotFollowTrailers) {
Ryan Hamilton0239aac2018-05-19 00:03:13972 spdy::SpdySerializedFrame req(
973 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnc4c214312016-11-28 16:49:15974 AddWrite(req);
975
Ryan Hamilton0239aac2018-05-19 00:03:13976 spdy::SpdySerializedFrame reply(
977 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bnc4c214312016-11-28 16:49:15978 AddRead(reply);
979
Ryan Hamilton0239aac2018-05-19 00:03:13980 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:19981 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bnc4c214312016-11-28 16:49:15982 AddRead(body);
983
Ryan Hamilton0239aac2018-05-19 00:03:13984 spdy::SpdyHeaderBlock trailers_block;
bnc4c214312016-11-28 16:49:15985 trailers_block["foo"] = "bar";
Ryan Hamilton0239aac2018-05-19 00:03:13986 spdy::SpdySerializedFrame trailers(spdy_util_.ConstructSpdyResponseHeaders(
bnc4c214312016-11-28 16:49:15987 1, std::move(trailers_block), false));
988 AddRead(trailers);
989
990 // DATA frame following trailers: protocol error.
991 AddRead(body);
992
Ryan Hamilton0239aac2018-05-19 00:03:13993 spdy::SpdySerializedFrame rst(
994 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bnc4c214312016-11-28 16:49:15995 AddWrite(rst);
996
997 AddReadEOF();
998
Ryan Sleevib8d7ea02018-05-07 20:01:01999 SequencedSocketData data(GetReads(), GetWrites());
bnc4c214312016-11-28 16:49:151000 MockConnect connect_data(SYNCHRONOUS, OK);
1001 data.set_connect_data(connect_data);
1002 session_deps_.socket_factory->AddSocketDataProvider(&data);
1003
1004 AddSSLSocketData();
1005
1006 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1007
1008 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1009 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1010 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181011 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bnc4c214312016-11-28 16:49:151012
1013 StreamDelegateDoNothing delegate(stream);
1014 stream->SetDelegate(&delegate);
1015
Ryan Hamilton0239aac2018-05-19 00:03:131016 spdy::SpdyHeaderBlock headers(
1017 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnc4c214312016-11-28 16:49:151018 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
1019 NO_MORE_DATA_TO_SEND));
bnc4c214312016-11-28 16:49:151020
Bence Békyd0d69502019-06-25 19:47:181021 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
bnc4c214312016-11-28 16:49:151022
bnceb9aa7112017-01-05 01:03:461023 // Finish async network reads and writes.
1024 base::RunLoop().RunUntilIdle();
1025
bnc4c214312016-11-28 16:49:151026 EXPECT_TRUE(data.AllWriteDataConsumed());
1027 EXPECT_TRUE(data.AllReadDataConsumed());
[email protected]6d116e1a2013-06-24 07:42:151028}
1029
bncc9f762a2016-12-06 20:38:231030TEST_F(SpdyStreamTest, InformationalHeaders) {
Ryan Hamilton0239aac2018-05-19 00:03:131031 spdy::SpdySerializedFrame req(
1032 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncc9f762a2016-12-06 20:38:231033 AddWrite(req);
1034
Ryan Hamilton0239aac2018-05-19 00:03:131035 spdy::SpdyHeaderBlock informational_headers;
bncc9f762a2016-12-06 20:38:231036 informational_headers[":status"] = "100";
Ryan Hamilton0239aac2018-05-19 00:03:131037 spdy::SpdySerializedFrame informational_response(
bncc9f762a2016-12-06 20:38:231038 spdy_util_.ConstructSpdyResponseHeaders(
1039 1, std::move(informational_headers), false));
1040 AddRead(informational_response);
1041
Ryan Hamilton0239aac2018-05-19 00:03:131042 spdy::SpdySerializedFrame reply(
1043 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncc9f762a2016-12-06 20:38:231044 AddRead(reply);
1045
Ryan Hamilton0239aac2018-05-19 00:03:131046 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:191047 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bncc9f762a2016-12-06 20:38:231048 AddRead(body);
1049
1050 AddReadEOF();
1051
Ryan Sleevib8d7ea02018-05-07 20:01:011052 SequencedSocketData data(GetReads(), GetWrites());
bncc9f762a2016-12-06 20:38:231053 MockConnect connect_data(SYNCHRONOUS, OK);
1054 data.set_connect_data(connect_data);
1055 session_deps_.socket_factory->AddSocketDataProvider(&data);
1056
1057 AddSSLSocketData();
1058
1059 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1060
1061 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1062 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1063 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181064 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bncc9f762a2016-12-06 20:38:231065
1066 StreamDelegateDoNothing delegate(stream);
1067 stream->SetDelegate(&delegate);
1068
Ryan Hamilton0239aac2018-05-19 00:03:131069 spdy::SpdyHeaderBlock headers(
1070 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bncc9f762a2016-12-06 20:38:231071 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
1072 NO_MORE_DATA_TO_SEND));
bncc9f762a2016-12-06 20:38:231073
1074 EXPECT_THAT(delegate.WaitForClose(), IsOk());
Ryan Hamilton0239aac2018-05-19 00:03:131075 EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
Bence Béky4e83f492018-05-13 23:14:251076 EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
bncc9f762a2016-12-06 20:38:231077 delegate.TakeReceivedData());
1078
bnceb9aa7112017-01-05 01:03:461079 // Finish async network reads and writes.
1080 base::RunLoop().RunUntilIdle();
1081
bncc9f762a2016-12-06 20:38:231082 EXPECT_TRUE(data.AllWriteDataConsumed());
1083 EXPECT_TRUE(data.AllReadDataConsumed());
1084}
1085
bnc4ce149622017-03-30 03:31:011086TEST_F(SpdyStreamTest, StatusMustBeNumber) {
Ryan Hamilton0239aac2018-05-19 00:03:131087 spdy::SpdySerializedFrame req(
1088 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncc9f762a2016-12-06 20:38:231089 AddWrite(req);
1090
Ryan Hamilton0239aac2018-05-19 00:03:131091 spdy::SpdyHeaderBlock incorrect_headers;
bncc9f762a2016-12-06 20:38:231092 incorrect_headers[":status"] = "nan";
Ryan Hamilton0239aac2018-05-19 00:03:131093 spdy::SpdySerializedFrame reply(spdy_util_.ConstructSpdyResponseHeaders(
bncc9f762a2016-12-06 20:38:231094 1, std::move(incorrect_headers), false));
1095 AddRead(reply);
1096
Ryan Hamilton0239aac2018-05-19 00:03:131097 spdy::SpdySerializedFrame rst(
1098 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bncc9f762a2016-12-06 20:38:231099 AddWrite(rst);
1100
1101 AddReadEOF();
1102
Ryan Sleevib8d7ea02018-05-07 20:01:011103 SequencedSocketData data(GetReads(), GetWrites());
bncc9f762a2016-12-06 20:38:231104 MockConnect connect_data(SYNCHRONOUS, OK);
1105 data.set_connect_data(connect_data);
1106 session_deps_.socket_factory->AddSocketDataProvider(&data);
1107
1108 AddSSLSocketData();
1109
1110 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1111
1112 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1113 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1114 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181115 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bncc9f762a2016-12-06 20:38:231116
1117 StreamDelegateDoNothing delegate(stream);
1118 stream->SetDelegate(&delegate);
1119
Ryan Hamilton0239aac2018-05-19 00:03:131120 spdy::SpdyHeaderBlock headers(
1121 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bncc9f762a2016-12-06 20:38:231122 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
1123 NO_MORE_DATA_TO_SEND));
bncc9f762a2016-12-06 20:38:231124
Bence Békyd0d69502019-06-25 19:47:181125 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
bncc9f762a2016-12-06 20:38:231126
bnceb9aa7112017-01-05 01:03:461127 // Finish async network reads and writes.
1128 base::RunLoop().RunUntilIdle();
1129
bncc9f762a2016-12-06 20:38:231130 EXPECT_TRUE(data.AllWriteDataConsumed());
1131 EXPECT_TRUE(data.AllReadDataConsumed());
1132}
1133
bnc4ce149622017-03-30 03:31:011134TEST_F(SpdyStreamTest, StatusCannotHaveExtraText) {
Ryan Hamilton0239aac2018-05-19 00:03:131135 spdy::SpdySerializedFrame req(
1136 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnc50ee38e2016-12-08 01:23:541137 AddWrite(req);
1138
Ryan Hamilton0239aac2018-05-19 00:03:131139 spdy::SpdyHeaderBlock headers_with_status_text;
bnc50ee38e2016-12-08 01:23:541140 headers_with_status_text[":status"] =
1141 "200 Some random extra text describing status";
Ryan Hamilton0239aac2018-05-19 00:03:131142 spdy::SpdySerializedFrame reply(spdy_util_.ConstructSpdyResponseHeaders(
bnc50ee38e2016-12-08 01:23:541143 1, std::move(headers_with_status_text), false));
1144 AddRead(reply);
1145
Ryan Hamilton0239aac2018-05-19 00:03:131146 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:191147 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bnc50ee38e2016-12-08 01:23:541148 AddRead(body);
1149
Ryan Hamilton0239aac2018-05-19 00:03:131150 spdy::SpdySerializedFrame rst(
1151 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bnc4ce149622017-03-30 03:31:011152 AddWrite(rst);
1153
bnc50ee38e2016-12-08 01:23:541154 AddReadEOF();
1155
Ryan Sleevib8d7ea02018-05-07 20:01:011156 SequencedSocketData data(GetReads(), GetWrites());
bnc50ee38e2016-12-08 01:23:541157 MockConnect connect_data(SYNCHRONOUS, OK);
1158 data.set_connect_data(connect_data);
1159 session_deps_.socket_factory->AddSocketDataProvider(&data);
1160
1161 AddSSLSocketData();
1162
1163 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1164
1165 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1166 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1167 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181168 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bnc50ee38e2016-12-08 01:23:541169
1170 StreamDelegateDoNothing delegate(stream);
1171 stream->SetDelegate(&delegate);
1172
Ryan Hamilton0239aac2018-05-19 00:03:131173 spdy::SpdyHeaderBlock headers(
1174 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnc50ee38e2016-12-08 01:23:541175 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
1176 NO_MORE_DATA_TO_SEND));
bnc50ee38e2016-12-08 01:23:541177
Bence Békyd0d69502019-06-25 19:47:181178 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
bnc4ce149622017-03-30 03:31:011179
1180 // Finish async network reads and writes.
1181 base::RunLoop().RunUntilIdle();
1182
1183 EXPECT_TRUE(data.AllWriteDataConsumed());
1184 EXPECT_TRUE(data.AllReadDataConsumed());
1185}
1186
1187TEST_F(SpdyStreamTest, StatusMustBePresent) {
Ryan Hamilton0239aac2018-05-19 00:03:131188 spdy::SpdySerializedFrame req(
1189 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnc4ce149622017-03-30 03:31:011190 AddWrite(req);
1191
Ryan Hamilton0239aac2018-05-19 00:03:131192 spdy::SpdyHeaderBlock headers_without_status;
1193 spdy::SpdySerializedFrame reply(spdy_util_.ConstructSpdyResponseHeaders(
bnc4ce149622017-03-30 03:31:011194 1, std::move(headers_without_status), false));
1195 AddRead(reply);
1196
Ryan Hamilton0239aac2018-05-19 00:03:131197 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:191198 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bnc4ce149622017-03-30 03:31:011199 AddRead(body);
1200
Ryan Hamilton0239aac2018-05-19 00:03:131201 spdy::SpdySerializedFrame rst(
1202 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
bnc4ce149622017-03-30 03:31:011203 AddWrite(rst);
1204
1205 AddReadEOF();
1206
Ryan Sleevib8d7ea02018-05-07 20:01:011207 SequencedSocketData data(GetReads(), GetWrites());
bnc4ce149622017-03-30 03:31:011208 MockConnect connect_data(SYNCHRONOUS, OK);
1209 data.set_connect_data(connect_data);
1210 session_deps_.socket_factory->AddSocketDataProvider(&data);
1211
1212 AddSSLSocketData();
1213
1214 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1215
1216 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1217 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
1218 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181219 EXPECT_EQ(kDefaultUrl, stream->url().spec());
bnc4ce149622017-03-30 03:31:011220
1221 StreamDelegateDoNothing delegate(stream);
1222 stream->SetDelegate(&delegate);
1223
Ryan Hamilton0239aac2018-05-19 00:03:131224 spdy::SpdyHeaderBlock headers(
1225 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnc4ce149622017-03-30 03:31:011226 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
1227 NO_MORE_DATA_TO_SEND));
bnc4ce149622017-03-30 03:31:011228
Bence Békyd0d69502019-06-25 19:47:181229 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
bnc50ee38e2016-12-08 01:23:541230
bnceb9aa7112017-01-05 01:03:461231 // Finish async network reads and writes.
1232 base::RunLoop().RunUntilIdle();
1233
bnc50ee38e2016-12-08 01:23:541234 EXPECT_TRUE(data.AllWriteDataConsumed());
1235 EXPECT_TRUE(data.AllReadDataConsumed());
1236}
1237
bnca2fbdc9b2016-11-22 21:14:261238// Call IncreaseSendWindowSize on a stream with a large enough delta to overflow
1239// an int32_t. The SpdyStream should handle that case gracefully.
bncd16676a2016-07-20 16:23:011240TEST_F(SpdyStreamTest, IncreaseSendWindowSizeOverflow) {
Ryan Hamilton0239aac2018-05-19 00:03:131241 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:261242 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:411243 AddWrite(req);
[email protected]3d587372013-06-01 04:31:451244
mmenkee24011922015-12-17 22:12:591245 AddReadPause();
1246
[email protected]1e5ebd82013-02-20 20:07:241247 // Triggered by the overflowing call to IncreaseSendWindowSize
1248 // below.
Ryan Hamilton0239aac2018-05-19 00:03:131249 spdy::SpdySerializedFrame rst(spdy_util_.ConstructSpdyRstStream(
1250 1, spdy::ERROR_CODE_FLOW_CONTROL_ERROR));
bncdf80d44fd2016-07-15 20:27:411251 AddWrite(rst);
[email protected]3d587372013-06-01 04:31:451252
1253 AddReadEOF();
[email protected]1e5ebd82013-02-20 20:07:241254
vishal.b62985ca92015-04-17 08:45:511255 BoundTestNetLog log;
[email protected]1e5ebd82013-02-20 20:07:241256
Ryan Sleevib8d7ea02018-05-07 20:01:011257 SequencedSocketData data(GetReads(), GetWrites());
[email protected]1e5ebd82013-02-20 20:07:241258 MockConnect connect_data(SYNCHRONOUS, OK);
1259 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:591260 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1e5ebd82013-02-20 20:07:241261
bnc032658ba2016-09-26 18:17:151262 AddSSLSocketData();
1263
[email protected]795cbf82013-07-22 09:37:271264 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]1e5ebd82013-02-20 20:07:241265
bnca2fbdc9b2016-11-22 21:14:261266 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1267 SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, log.bound());
wezca1070932016-05-26 20:30:521268 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181269 EXPECT_EQ(kDefaultUrl, stream->url().spec());
1270
[email protected]194cfcf2013-05-23 21:44:441271 StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
[email protected]1c6b12a2013-03-21 00:59:111272 stream->SetDelegate(&delegate);
[email protected]1e5ebd82013-02-20 20:07:241273
Ryan Hamilton0239aac2018-05-19 00:03:131274 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:261275 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
1276 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
1277 IsError(ERR_IO_PENDING));
[email protected]1c12c062013-05-14 23:13:481278
mmenkee24011922015-12-17 22:12:591279 data.RunUntilPaused();
[email protected]1e5ebd82013-02-20 20:07:241280
avid0181f32015-12-10 19:41:471281 int32_t old_send_window_size = stream->send_window_size();
[email protected]1e5ebd82013-02-20 20:07:241282 ASSERT_GT(old_send_window_size, 0);
avid0181f32015-12-10 19:41:471283 int32_t delta_window_size =
1284 std::numeric_limits<int32_t>::max() - old_send_window_size + 1;
[email protected]1e5ebd82013-02-20 20:07:241285 stream->IncreaseSendWindowSize(delta_window_size);
bnca2fbdc9b2016-11-22 21:14:261286 EXPECT_FALSE(stream);
[email protected]1e5ebd82013-02-20 20:07:241287
mmenkee24011922015-12-17 22:12:591288 data.Resume();
1289 base::RunLoop().RunUntilIdle();
[email protected]1c12c062013-05-14 23:13:481290
Bence Békyd0d69502019-06-25 19:47:181291 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_HTTP2_FLOW_CONTROL_ERROR));
[email protected]1e5ebd82013-02-20 20:07:241292}
1293
[email protected]d2de7da2013-05-22 07:49:561294// Functions used with
1295// RunResumeAfterUnstall{RequestResponse,Bidirectional}Test().
1296
1297void StallStream(const base::WeakPtr<SpdyStream>& stream) {
1298 // Reduce the send window size to 0 to stall.
1299 while (stream->send_window_size() > 0) {
1300 stream->DecreaseSendWindowSize(
1301 std::min(kMaxSpdyFrameChunkSize, stream->send_window_size()));
1302 }
1303}
1304
1305void IncreaseStreamSendWindowSize(const base::WeakPtr<SpdyStream>& stream,
avid0181f32015-12-10 19:41:471306 int32_t delta_window_size) {
[email protected]d2de7da2013-05-22 07:49:561307 EXPECT_TRUE(stream->send_stalled_by_flow_control());
1308 stream->IncreaseSendWindowSize(delta_window_size);
1309 EXPECT_FALSE(stream->send_stalled_by_flow_control());
1310}
1311
1312void AdjustStreamSendWindowSize(const base::WeakPtr<SpdyStream>& stream,
avid0181f32015-12-10 19:41:471313 int32_t delta_window_size) {
[email protected]d2de7da2013-05-22 07:49:561314 // Make sure that negative adjustments are handled properly.
1315 EXPECT_TRUE(stream->send_stalled_by_flow_control());
Bence Béky05dcb0382017-09-15 20:07:581316 EXPECT_TRUE(stream->AdjustSendWindowSize(-delta_window_size));
[email protected]d2de7da2013-05-22 07:49:561317 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_FALSE(stream->send_stalled_by_flow_control());
1322}
1323
1324// Given an unstall function, runs a test to make sure that a
1325// request/response (i.e., an HTTP-like) stream resumes after a stall
1326// and unstall.
[email protected]3d587372013-06-01 04:31:451327void SpdyStreamTest::RunResumeAfterUnstallRequestResponseTest(
[email protected]d2de7da2013-05-22 07:49:561328 const UnstallFunction& unstall_function) {
Ryan Hamilton0239aac2018-05-19 00:03:131329 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:261330 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:411331 AddWrite(req);
[email protected]3d587372013-06-01 04:31:451332
Ryan Hamilton0239aac2018-05-19 00:03:131333 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:191334 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
bncdf80d44fd2016-07-15 20:27:411335 AddWrite(body);
[email protected]34a4dea2013-03-13 00:42:301336
Ryan Hamilton0239aac2018-05-19 00:03:131337 spdy::SpdySerializedFrame resp(
1338 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:411339 AddRead(resp);
[email protected]34a4dea2013-03-13 00:42:301340
[email protected]3d587372013-06-01 04:31:451341 AddReadEOF();
1342
Ryan Sleevib8d7ea02018-05-07 20:01:011343 SequencedSocketData data(GetReads(), GetWrites());
[email protected]34a4dea2013-03-13 00:42:301344 MockConnect connect_data(SYNCHRONOUS, OK);
1345 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:591346 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]34a4dea2013-03-13 00:42:301347
bnc032658ba2016-09-26 18:17:151348 AddSSLSocketData();
1349
[email protected]795cbf82013-07-22 09:37:271350 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]34a4dea2013-03-13 00:42:301351
tfarina42834112016-09-22 13:38:201352 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:261353 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:521354 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181355 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]34a4dea2013-03-13 00:42:301356
[email protected]d26ff352013-05-13 08:48:281357 StreamDelegateWithBody delegate(stream, kPostBodyStringPiece);
[email protected]34a4dea2013-03-13 00:42:301358 stream->SetDelegate(&delegate);
1359
[email protected]1c6b12a2013-03-21 00:59:111360 EXPECT_FALSE(stream->send_stalled_by_flow_control());
[email protected]34a4dea2013-03-13 00:42:301361
Ryan Hamilton0239aac2018-05-19 00:03:131362 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:261363 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
1364 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
1365 IsError(ERR_IO_PENDING));
[email protected]34a4dea2013-03-13 00:42:301366
[email protected]d2de7da2013-05-22 07:49:561367 StallStream(stream);
1368
mmenkee24011922015-12-17 22:12:591369 base::RunLoop().RunUntilIdle();
[email protected]34a4dea2013-03-13 00:42:301370
[email protected]1c6b12a2013-03-21 00:59:111371 EXPECT_TRUE(stream->send_stalled_by_flow_control());
[email protected]34a4dea2013-03-13 00:42:301372
[email protected]d2de7da2013-05-22 07:49:561373 unstall_function.Run(stream, kPostBodyLength);
[email protected]34a4dea2013-03-13 00:42:301374
[email protected]1c6b12a2013-03-21 00:59:111375 EXPECT_FALSE(stream->send_stalled_by_flow_control());
[email protected]34a4dea2013-03-13 00:42:301376
robpercival214763f2016-07-01 23:27:011377 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
[email protected]34a4dea2013-03-13 00:42:301378
1379 EXPECT_TRUE(delegate.send_headers_completed());
1380 EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status"));
Bence Béky4e83f492018-05-13 23:14:251381 EXPECT_EQ(std::string(), delegate.TakeReceivedData());
rch37de576c2015-05-17 20:28:171382 EXPECT_TRUE(data.AllWriteDataConsumed());
[email protected]cbdd73162013-03-18 23:27:331383}
1384
bncd16676a2016-07-20 16:23:011385TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeIncreaseRequestResponse) {
[email protected]d2de7da2013-05-22 07:49:561386 RunResumeAfterUnstallRequestResponseTest(
1387 base::Bind(&IncreaseStreamSendWindowSize));
1388}
1389
bncd16676a2016-07-20 16:23:011390TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeAdjustRequestResponse) {
[email protected]d2de7da2013-05-22 07:49:561391 RunResumeAfterUnstallRequestResponseTest(
1392 base::Bind(&AdjustStreamSendWindowSize));
1393}
1394
bnca2fbdc9b2016-11-22 21:14:261395// Given an unstall function, runs a test to make sure that a bidirectional
1396// (i.e., non-HTTP-like) stream resumes after a stall and unstall.
[email protected]3d587372013-06-01 04:31:451397void SpdyStreamTest::RunResumeAfterUnstallBidirectionalTest(
[email protected]d2de7da2013-05-22 07:49:561398 const UnstallFunction& unstall_function) {
Ryan Hamilton0239aac2018-05-19 00:03:131399 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnca2fbdc9b2016-11-22 21:14:261400 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
bncdf80d44fd2016-07-15 20:27:411401 AddWrite(req);
[email protected]3d587372013-06-01 04:31:451402
mmenkee24011922015-12-17 22:12:591403 AddReadPause();
1404
Ryan Hamilton0239aac2018-05-19 00:03:131405 spdy::SpdySerializedFrame resp(
1406 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:411407 AddRead(resp);
[email protected]3d587372013-06-01 04:31:451408
Ryan Hamilton0239aac2018-05-19 00:03:131409 spdy::SpdySerializedFrame msg(
Bence Békyd74f4382018-02-20 18:26:191410 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bncdf80d44fd2016-07-15 20:27:411411 AddWrite(msg);
[email protected]cbdd73162013-03-18 23:27:331412
Ryan Hamilton0239aac2018-05-19 00:03:131413 spdy::SpdySerializedFrame echo(
Bence Békyd74f4382018-02-20 18:26:191414 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bncdf80d44fd2016-07-15 20:27:411415 AddRead(echo);
[email protected]cbdd73162013-03-18 23:27:331416
[email protected]3d587372013-06-01 04:31:451417 AddReadEOF();
1418
Ryan Sleevib8d7ea02018-05-07 20:01:011419 SequencedSocketData data(GetReads(), GetWrites());
[email protected]cbdd73162013-03-18 23:27:331420 MockConnect connect_data(SYNCHRONOUS, OK);
1421 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:591422 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]cbdd73162013-03-18 23:27:331423
bnc032658ba2016-09-26 18:17:151424 AddSSLSocketData();
1425
[email protected]795cbf82013-07-22 09:37:271426 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
[email protected]cbdd73162013-03-18 23:27:331427
tfarina42834112016-09-22 13:38:201428 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:261429 SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:521430 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181431 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]cbdd73162013-03-18 23:27:331432
[email protected]194cfcf2013-05-23 21:44:441433 StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
[email protected]cbdd73162013-03-18 23:27:331434 stream->SetDelegate(&delegate);
1435
Ryan Hamilton0239aac2018-05-19 00:03:131436 spdy::SpdyHeaderBlock headers(
bnca2fbdc9b2016-11-22 21:14:261437 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
1438 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
1439 IsError(ERR_IO_PENDING));
[email protected]cbdd73162013-03-18 23:27:331440
mmenkee24011922015-12-17 22:12:591441 data.RunUntilPaused();
[email protected]cbdd73162013-03-18 23:27:331442
[email protected]1c6b12a2013-03-21 00:59:111443 EXPECT_FALSE(stream->send_stalled_by_flow_control());
[email protected]cbdd73162013-03-18 23:27:331444
[email protected]d2de7da2013-05-22 07:49:561445 StallStream(stream);
[email protected]cbdd73162013-03-18 23:27:331446
mmenkee24011922015-12-17 22:12:591447 data.Resume();
1448 base::RunLoop().RunUntilIdle();
[email protected]cbdd73162013-03-18 23:27:331449
[email protected]1c6b12a2013-03-21 00:59:111450 EXPECT_TRUE(stream->send_stalled_by_flow_control());
[email protected]cbdd73162013-03-18 23:27:331451
[email protected]d2de7da2013-05-22 07:49:561452 unstall_function.Run(stream, kPostBodyLength);
[email protected]cbdd73162013-03-18 23:27:331453
[email protected]1c6b12a2013-03-21 00:59:111454 EXPECT_FALSE(stream->send_stalled_by_flow_control());
[email protected]cbdd73162013-03-18 23:27:331455
robpercival214763f2016-07-01 23:27:011456 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
[email protected]cbdd73162013-03-18 23:27:331457
1458 EXPECT_TRUE(delegate.send_headers_completed());
1459 EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status"));
Bence Béky4e83f492018-05-13 23:14:251460 EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
[email protected]09a8d9172013-04-17 19:23:491461 delegate.TakeReceivedData());
rch37de576c2015-05-17 20:28:171462 EXPECT_TRUE(data.AllWriteDataConsumed());
[email protected]d2de7da2013-05-22 07:49:561463}
1464
bncd16676a2016-07-20 16:23:011465TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeIncreaseBidirectional) {
[email protected]d2de7da2013-05-22 07:49:561466 RunResumeAfterUnstallBidirectionalTest(
1467 base::Bind(&IncreaseStreamSendWindowSize));
1468}
1469
bncd16676a2016-07-20 16:23:011470TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeAdjustBidirectional) {
[email protected]d2de7da2013-05-22 07:49:561471 RunResumeAfterUnstallBidirectionalTest(
1472 base::Bind(&AdjustStreamSendWindowSize));
[email protected]34a4dea2013-03-13 00:42:301473}
1474
[email protected]533f0de2013-12-09 23:03:361475// Test calculation of amount of bytes received from network.
bncd16676a2016-07-20 16:23:011476TEST_F(SpdyStreamTest, ReceivedBytes) {
Ryan Hamilton0239aac2018-05-19 00:03:131477 spdy::SpdySerializedFrame req(
1478 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bnca2fbdc9b2016-11-22 21:14:261479 AddWrite(req);
[email protected]533f0de2013-12-09 23:03:361480
mmenkee24011922015-12-17 22:12:591481 AddReadPause();
1482
Ryan Hamilton0239aac2018-05-19 00:03:131483 spdy::SpdySerializedFrame reply(
1484 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:411485 AddRead(reply);
[email protected]533f0de2013-12-09 23:03:361486
mmenkee24011922015-12-17 22:12:591487 AddReadPause();
1488
Ryan Hamilton0239aac2018-05-19 00:03:131489 spdy::SpdySerializedFrame msg(
Bence Békyd74f4382018-02-20 18:26:191490 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false));
bncdf80d44fd2016-07-15 20:27:411491 AddRead(msg);
[email protected]533f0de2013-12-09 23:03:361492
mmenkee24011922015-12-17 22:12:591493 AddReadPause();
1494
[email protected]533f0de2013-12-09 23:03:361495 AddReadEOF();
1496
Ryan Sleevib8d7ea02018-05-07 20:01:011497 SequencedSocketData data(GetReads(), GetWrites());
[email protected]533f0de2013-12-09 23:03:361498 MockConnect connect_data(SYNCHRONOUS, OK);
1499 data.set_connect_data(connect_data);
mmenkee24011922015-12-17 22:12:591500 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]533f0de2013-12-09 23:03:361501
bnc032658ba2016-09-26 18:17:151502 AddSSLSocketData();
1503
[email protected]533f0de2013-12-09 23:03:361504 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1505
tfarina42834112016-09-22 13:38:201506 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
bnca2fbdc9b2016-11-22 21:14:261507 SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
wezca1070932016-05-26 20:30:521508 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181509 EXPECT_EQ(kDefaultUrl, stream->url().spec());
[email protected]533f0de2013-12-09 23:03:361510
1511 StreamDelegateDoNothing delegate(stream);
1512 stream->SetDelegate(&delegate);
1513
Ryan Hamilton0239aac2018-05-19 00:03:131514 spdy::SpdyHeaderBlock headers(
1515 spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
bnca2fbdc9b2016-11-22 21:14:261516 EXPECT_THAT(
1517 stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
1518 IsError(ERR_IO_PENDING));
[email protected]533f0de2013-12-09 23:03:361519
bncdf80d44fd2016-07-15 20:27:411520 int64_t reply_frame_len = reply.size();
Ryan Hamilton0239aac2018-05-19 00:03:131521 int64_t data_header_len = spdy::kDataFrameMinimumSize;
avid0181f32015-12-10 19:41:471522 int64_t data_frame_len = data_header_len + kPostBodyLength;
1523 int64_t response_len = reply_frame_len + data_frame_len;
[email protected]533f0de2013-12-09 23:03:361524
1525 EXPECT_EQ(0, stream->raw_received_bytes());
[email protected]533f0de2013-12-09 23:03:361526
bnca2fbdc9b2016-11-22 21:14:261527 // REQUEST
mmenkee24011922015-12-17 22:12:591528 data.RunUntilPaused();
1529 EXPECT_EQ(0, stream->raw_received_bytes());
1530
1531 // REPLY
1532 data.Resume();
1533 data.RunUntilPaused();
1534 EXPECT_EQ(reply_frame_len, stream->raw_received_bytes());
1535
1536 // DATA
1537 data.Resume();
1538 data.RunUntilPaused();
1539 EXPECT_EQ(response_len, stream->raw_received_bytes());
1540
1541 // FIN
1542 data.Resume();
robpercival214763f2016-07-01 23:27:011543 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
[email protected]533f0de2013-12-09 23:03:361544}
1545
Bence Békycf3fd8a42018-02-09 20:15:471546// Regression test for https://crbug.com/810763.
1547TEST_F(SpdyStreamTest, DataOnHalfClosedRemoveStream) {
Ryan Hamilton0239aac2018-05-19 00:03:131548 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
Bence Békycf3fd8a42018-02-09 20:15:471549 kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0));
1550 AddWrite(req);
1551
Ryan Hamilton0239aac2018-05-19 00:03:131552 spdy::SpdyHeaderBlock response_headers;
1553 response_headers[spdy::kHttp2StatusHeader] = "200";
1554 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
Bence Békycf3fd8a42018-02-09 20:15:471555 1, std::move(response_headers), /* fin = */ true));
1556 AddRead(resp);
1557
Ryan Hamilton0239aac2018-05-19 00:03:131558 spdy::SpdySerializedFrame data_frame(
Bence Békyd74f4382018-02-20 18:26:191559 spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
Bence Békycf3fd8a42018-02-09 20:15:471560 AddRead(data_frame);
1561
Ryan Hamilton0239aac2018-05-19 00:03:131562 spdy::SpdySerializedFrame rst(
1563 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_STREAM_CLOSED));
Bence Békycf3fd8a42018-02-09 20:15:471564 AddWrite(rst);
1565
1566 AddReadEOF();
1567
Ryan Sleevib8d7ea02018-05-07 20:01:011568 SequencedSocketData data(GetReads(), GetWrites());
Bence Békycf3fd8a42018-02-09 20:15:471569 MockConnect connect_data(SYNCHRONOUS, OK);
1570 data.set_connect_data(connect_data);
1571 session_deps_.socket_factory->AddSocketDataProvider(&data);
1572
1573 AddSSLSocketData();
1574
1575 base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
1576
1577 base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
1578 SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
1579 ASSERT_TRUE(stream);
Bence Béky39d74292018-03-02 04:31:181580 EXPECT_EQ(kDefaultUrl, stream->url().spec());
Bence Békycf3fd8a42018-02-09 20:15:471581
1582 StreamDelegateDoNothing delegate(stream);
1583 stream->SetDelegate(&delegate);
1584
Ryan Hamilton0239aac2018-05-19 00:03:131585 spdy::SpdyHeaderBlock headers(
Bence Békycf3fd8a42018-02-09 20:15:471586 spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
1587 EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
1588 IsError(ERR_IO_PENDING));
Bence Békycf3fd8a42018-02-09 20:15:471589
Bence Békyd0d69502019-06-25 19:47:181590 EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_HTTP2_STREAM_CLOSED));
Bence Békycf3fd8a42018-02-09 20:15:471591
1592 base::RunLoop().RunUntilIdle();
1593
1594 EXPECT_TRUE(data.AllReadDataConsumed());
1595 EXPECT_TRUE(data.AllWriteDataConsumed());
1596}
1597
[email protected]39d13d942012-07-19 16:48:201598} // namespace test
1599
[email protected]4f386422010-07-20 04:19:491600} // namespace net