quic_chromium_client_stream_test.cc 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/quic/quic_chromium_client_stream.h"
  5. #include <string>
  6. #include "base/bind.h"
  7. #include "base/callback_helpers.h"
  8. #include "base/memory/ptr_util.h"
  9. #include "base/memory/raw_ptr.h"
  10. #include "base/run_loop.h"
  11. #include "base/strings/string_number_conversions.h"
  12. #include "net/base/io_buffer.h"
  13. #include "net/base/net_errors.h"
  14. #include "net/base/test_completion_callback.h"
  15. #include "net/quic/quic_chromium_client_session.h"
  16. #include "net/test/gtest_util.h"
  17. #include "net/test/test_with_task_environment.h"
  18. #include "net/third_party/quiche/src/quiche/quic/core/crypto/null_encrypter.h"
  19. #include "net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_client_session_base.h"
  20. #include "net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_client_stream.h"
  21. #include "net/third_party/quiche/src/quiche/quic/core/http/spdy_utils.h"
  22. #include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
  23. #include "net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h"
  24. #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_config_peer.h"
  25. #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_connection_peer.h"
  26. #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_session_peer.h"
  27. #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
  28. #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
  29. #include "testing/gmock/include/gmock/gmock.h"
  30. using testing::_;
  31. using testing::Return;
  32. namespace net::test {
  33. namespace {
  34. class MockQuicClientSessionBase : public quic::QuicSpdyClientSessionBase {
  35. public:
  36. explicit MockQuicClientSessionBase(quic::QuicConnection* connection,
  37. quic::QuicClientPushPromiseIndex* index);
  38. MockQuicClientSessionBase(const MockQuicClientSessionBase&) = delete;
  39. MockQuicClientSessionBase& operator=(const MockQuicClientSessionBase&) =
  40. delete;
  41. ~MockQuicClientSessionBase() override;
  42. const quic::QuicCryptoStream* GetCryptoStream() const override {
  43. return crypto_stream_.get();
  44. }
  45. quic::QuicCryptoStream* GetMutableCryptoStream() override {
  46. return crypto_stream_.get();
  47. }
  48. // From quic::QuicSession.
  49. MOCK_METHOD2(OnConnectionClosed,
  50. void(const quic::QuicConnectionCloseFrame& frame,
  51. quic::ConnectionCloseSource source));
  52. MOCK_METHOD1(CreateIncomingStream,
  53. quic::QuicSpdyStream*(quic::QuicStreamId id));
  54. MOCK_METHOD1(CreateIncomingStream,
  55. quic::QuicSpdyStream*(quic::PendingStream* pending));
  56. MOCK_METHOD0(CreateOutgoingBidirectionalStream, QuicChromiumClientStream*());
  57. MOCK_METHOD0(CreateOutgoingUnidirectionalStream, QuicChromiumClientStream*());
  58. MOCK_METHOD6(WritevData,
  59. quic::QuicConsumedData(quic::QuicStreamId id,
  60. size_t write_length,
  61. quic::QuicStreamOffset offset,
  62. quic::StreamSendingState state,
  63. quic::TransmissionType type,
  64. quic::EncryptionLevel level));
  65. MOCK_METHOD2(WriteControlFrame,
  66. bool(const quic::QuicFrame&, quic::TransmissionType));
  67. MOCK_METHOD4(SendRstStream,
  68. void(quic::QuicStreamId stream_id,
  69. quic::QuicRstStreamErrorCode error,
  70. quic::QuicStreamOffset bytes_written,
  71. bool send_rst_only));
  72. MOCK_METHOD2(OnStreamHeaders,
  73. void(quic::QuicStreamId stream_id,
  74. absl::string_view headers_data));
  75. MOCK_METHOD2(OnStreamHeadersPriority,
  76. void(quic::QuicStreamId stream_id,
  77. const spdy::SpdyStreamPrecedence& precedence));
  78. MOCK_METHOD3(OnStreamHeadersComplete,
  79. void(quic::QuicStreamId stream_id, bool fin, size_t frame_len));
  80. MOCK_METHOD2(OnPromiseHeaders,
  81. void(quic::QuicStreamId stream_id,
  82. absl::string_view headers_data));
  83. MOCK_METHOD3(OnPromiseHeadersComplete,
  84. void(quic::QuicStreamId stream_id,
  85. quic::QuicStreamId promised_stream_id,
  86. size_t frame_len));
  87. MOCK_CONST_METHOD0(OneRttKeysAvailable, bool());
  88. // Methods taking non-copyable types like spdy::Http2HeaderBlock by value
  89. // cannot be mocked directly.
  90. size_t WriteHeadersOnHeadersStream(
  91. quic::QuicStreamId id,
  92. spdy::Http2HeaderBlock headers,
  93. bool fin,
  94. const spdy::SpdyStreamPrecedence& precedence,
  95. quiche::QuicheReferenceCountedPointer<quic::QuicAckListenerInterface>
  96. ack_listener) override {
  97. return WriteHeadersOnHeadersStreamMock(id, headers, fin, precedence,
  98. std::move(ack_listener));
  99. }
  100. MOCK_METHOD5(WriteHeadersOnHeadersStreamMock,
  101. size_t(quic::QuicStreamId id,
  102. const spdy::Http2HeaderBlock& headers,
  103. bool fin,
  104. const spdy::SpdyStreamPrecedence& precedence,
  105. const quiche::QuicheReferenceCountedPointer<
  106. quic::QuicAckListenerInterface>& ack_listener));
  107. MOCK_METHOD1(OnHeadersHeadOfLineBlocking, void(quic::QuicTime::Delta delta));
  108. using quic::QuicSession::ActivateStream;
  109. // Returns a quic::QuicConsumedData that indicates all of |write_length| (and
  110. // |fin| if set) has been consumed.
  111. static quic::QuicConsumedData ConsumeAllData(
  112. quic::QuicStreamId id,
  113. size_t write_length,
  114. quic::QuicStreamOffset offset,
  115. bool fin,
  116. quic::QuicAckListenerInterface* ack_listener);
  117. void OnProofValid(
  118. const quic::QuicCryptoClientConfig::CachedState& cached) override {}
  119. void OnProofVerifyDetailsAvailable(
  120. const quic::ProofVerifyDetails& verify_details) override {}
  121. bool IsAuthorized(const std::string& hostname) override { return true; }
  122. protected:
  123. MOCK_METHOD1(ShouldCreateIncomingStream, bool(quic::QuicStreamId id));
  124. MOCK_METHOD0(ShouldCreateOutgoingBidirectionalStream, bool());
  125. MOCK_METHOD0(ShouldCreateOutgoingUnidirectionalStream, bool());
  126. private:
  127. std::unique_ptr<quic::QuicCryptoStream> crypto_stream_;
  128. };
  129. MockQuicClientSessionBase::MockQuicClientSessionBase(
  130. quic::QuicConnection* connection,
  131. quic::QuicClientPushPromiseIndex* push_promise_index)
  132. : quic::QuicSpdyClientSessionBase(connection,
  133. push_promise_index,
  134. quic::test::DefaultQuicConfig(),
  135. connection->supported_versions()) {
  136. crypto_stream_ = std::make_unique<quic::test::MockQuicCryptoStream>(this);
  137. Initialize();
  138. ON_CALL(*this, WritevData(_, _, _, _, _, _))
  139. .WillByDefault(testing::Return(quic::QuicConsumedData(0, false)));
  140. }
  141. MockQuicClientSessionBase::~MockQuicClientSessionBase() = default;
  142. class QuicChromiumClientStreamTest
  143. : public ::testing::TestWithParam<quic::ParsedQuicVersion>,
  144. public WithTaskEnvironment {
  145. public:
  146. QuicChromiumClientStreamTest()
  147. : version_(GetParam()),
  148. crypto_config_(
  149. quic::test::crypto_test_utils::ProofVerifierForTesting()),
  150. session_(new quic::test::MockQuicConnection(
  151. &helper_,
  152. &alarm_factory_,
  153. quic::Perspective::IS_CLIENT,
  154. quic::test::SupportedVersions(version_)),
  155. &push_promise_index_) {
  156. quic::test::QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
  157. session_.config(), quic::kMinimumFlowControlSendWindow);
  158. quic::test::QuicConfigPeer::
  159. SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
  160. session_.config(), quic::kMinimumFlowControlSendWindow);
  161. quic::test::QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(
  162. session_.config(), 10);
  163. session_.OnConfigNegotiated();
  164. stream_ = new QuicChromiumClientStream(
  165. quic::test::GetNthClientInitiatedBidirectionalStreamId(
  166. version_.transport_version, 0),
  167. &session_, quic::BIDIRECTIONAL, NetLogWithSource(),
  168. TRAFFIC_ANNOTATION_FOR_TESTS);
  169. session_.ActivateStream(base::WrapUnique(stream_.get()));
  170. handle_ = stream_->CreateHandle();
  171. helper_.AdvanceTime(quic::QuicTime::Delta::FromSeconds(1));
  172. session_.connection()->SetEncrypter(
  173. quic::ENCRYPTION_FORWARD_SECURE,
  174. std::make_unique<quic::NullEncrypter>(quic::Perspective::IS_CLIENT));
  175. }
  176. void InitializeHeaders() {
  177. headers_[":host"] = "www.google.com";
  178. headers_[":path"] = "/index.hml";
  179. headers_[":scheme"] = "https";
  180. headers_[":status"] = "200";
  181. headers_["cookie"] =
  182. "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; "
  183. "__utmc=160408618; "
  184. "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX"
  185. "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX"
  186. "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT"
  187. "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0"
  188. "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh"
  189. "1zFMi5vzcns38-8_Sns; "
  190. "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-"
  191. "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339"
  192. "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c"
  193. "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%"
  194. "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4"
  195. "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1"
  196. "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP"
  197. "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6"
  198. "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b"
  199. "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6"
  200. "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG"
  201. "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk"
  202. "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
  203. "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
  204. "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
  205. }
  206. spdy::Http2HeaderBlock CreateResponseHeaders(const std::string& status_code) {
  207. spdy::Http2HeaderBlock headers;
  208. headers[":status"] = status_code;
  209. return headers;
  210. }
  211. void ReadData(absl::string_view expected_data) {
  212. scoped_refptr<IOBuffer> buffer =
  213. base::MakeRefCounted<IOBuffer>(expected_data.length() + 1);
  214. EXPECT_EQ(static_cast<int>(expected_data.length()),
  215. stream_->Read(buffer.get(), expected_data.length() + 1));
  216. EXPECT_EQ(expected_data,
  217. absl::string_view(buffer->data(), expected_data.length()));
  218. }
  219. quic::QuicHeaderList ProcessHeaders(const spdy::Http2HeaderBlock& headers) {
  220. quic::QuicHeaderList h = quic::test::AsHeaderList(headers);
  221. stream_->OnStreamHeaderList(false, h.uncompressed_header_bytes(), h);
  222. return h;
  223. }
  224. quic::QuicHeaderList ProcessTrailers(const spdy::Http2HeaderBlock& headers) {
  225. quic::QuicHeaderList h = quic::test::AsHeaderList(headers);
  226. stream_->OnStreamHeaderList(true, h.uncompressed_header_bytes(), h);
  227. return h;
  228. }
  229. quic::QuicHeaderList ProcessHeadersFull(
  230. const spdy::Http2HeaderBlock& headers) {
  231. quic::QuicHeaderList h = ProcessHeaders(headers);
  232. TestCompletionCallback callback;
  233. EXPECT_EQ(static_cast<int>(h.uncompressed_header_bytes()),
  234. handle_->ReadInitialHeaders(&headers_, callback.callback()));
  235. EXPECT_EQ(headers, headers_);
  236. EXPECT_TRUE(stream_->header_list().empty());
  237. return h;
  238. }
  239. quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
  240. return quic::test::GetNthClientInitiatedBidirectionalStreamId(
  241. session_.connection()->transport_version(), n);
  242. }
  243. quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
  244. return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
  245. session_.connection()->transport_version(), n);
  246. }
  247. void ResetStreamCallback(QuicChromiumClientStream* stream, int /*rv*/) {
  248. stream->Reset(quic::QUIC_STREAM_CANCELLED);
  249. }
  250. std::string ConstructDataHeader(size_t body_len) {
  251. if (!version_.HasIetfQuicFrames()) {
  252. return "";
  253. }
  254. quiche::QuicheBuffer buffer = quic::HttpEncoder::SerializeDataFrameHeader(
  255. body_len, quiche::SimpleBufferAllocator::Get());
  256. return std::string(buffer.data(), buffer.size());
  257. }
  258. const quic::ParsedQuicVersion version_;
  259. quic::QuicCryptoClientConfig crypto_config_;
  260. std::unique_ptr<QuicChromiumClientStream::Handle> handle_;
  261. std::unique_ptr<QuicChromiumClientStream::Handle> handle2_;
  262. quic::test::MockQuicConnectionHelper helper_;
  263. quic::test::MockAlarmFactory alarm_factory_;
  264. MockQuicClientSessionBase session_;
  265. raw_ptr<QuicChromiumClientStream> stream_;
  266. spdy::Http2HeaderBlock headers_;
  267. spdy::Http2HeaderBlock trailers_;
  268. quic::QuicClientPushPromiseIndex push_promise_index_;
  269. };
  270. INSTANTIATE_TEST_SUITE_P(Version,
  271. QuicChromiumClientStreamTest,
  272. ::testing::ValuesIn(quic::AllSupportedVersions()),
  273. ::testing::PrintToStringParamName());
  274. TEST_P(QuicChromiumClientStreamTest, Handle) {
  275. testing::InSequence seq;
  276. EXPECT_TRUE(handle_->IsOpen());
  277. EXPECT_EQ(quic::test::GetNthClientInitiatedBidirectionalStreamId(
  278. version_.transport_version, 0),
  279. handle_->id());
  280. EXPECT_EQ(quic::QUIC_NO_ERROR, handle_->connection_error());
  281. EXPECT_EQ(quic::QUIC_STREAM_NO_ERROR, handle_->stream_error());
  282. EXPECT_TRUE(handle_->IsFirstStream());
  283. EXPECT_FALSE(handle_->IsDoneReading());
  284. EXPECT_FALSE(handle_->fin_sent());
  285. EXPECT_FALSE(handle_->fin_received());
  286. EXPECT_EQ(0u, handle_->stream_bytes_read());
  287. EXPECT_EQ(0u, handle_->stream_bytes_written());
  288. EXPECT_EQ(0u, handle_->NumBytesConsumed());
  289. InitializeHeaders();
  290. quic::QuicStreamOffset offset = 0;
  291. ProcessHeadersFull(headers_);
  292. quic::QuicStreamFrame frame2(
  293. quic::test::GetNthClientInitiatedBidirectionalStreamId(
  294. version_.transport_version, 0),
  295. true, offset, absl::string_view());
  296. stream_->OnStreamFrame(frame2);
  297. EXPECT_TRUE(handle_->fin_received());
  298. handle_->OnFinRead();
  299. const char kData1[] = "hello world";
  300. const size_t kDataLen = std::size(kData1);
  301. // All data written.
  302. std::string header = ConstructDataHeader(kDataLen);
  303. if (version_.HasIetfQuicFrames()) {
  304. EXPECT_CALL(session_,
  305. WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
  306. .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
  307. }
  308. EXPECT_CALL(session_,
  309. WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
  310. .WillOnce(Return(quic::QuicConsumedData(kDataLen, true)));
  311. TestCompletionCallback callback;
  312. EXPECT_EQ(OK, handle_->WriteStreamData(base::StringPiece(kData1, kDataLen),
  313. true, callback.callback()));
  314. EXPECT_FALSE(handle_->IsOpen());
  315. EXPECT_EQ(quic::test::GetNthClientInitiatedBidirectionalStreamId(
  316. version_.transport_version, 0),
  317. handle_->id());
  318. EXPECT_EQ(quic::QUIC_NO_ERROR, handle_->connection_error());
  319. EXPECT_EQ(quic::QUIC_STREAM_NO_ERROR, handle_->stream_error());
  320. EXPECT_TRUE(handle_->IsFirstStream());
  321. EXPECT_TRUE(handle_->IsDoneReading());
  322. EXPECT_TRUE(handle_->fin_sent());
  323. EXPECT_TRUE(handle_->fin_received());
  324. EXPECT_EQ(0u, handle_->stream_bytes_read());
  325. EXPECT_EQ(header.length() + kDataLen, handle_->stream_bytes_written());
  326. EXPECT_EQ(0u, handle_->NumBytesConsumed());
  327. EXPECT_EQ(ERR_CONNECTION_CLOSED,
  328. handle_->WriteStreamData(base::StringPiece(kData1, kDataLen), true,
  329. callback.callback()));
  330. std::vector<scoped_refptr<IOBuffer>> buffers = {
  331. base::MakeRefCounted<IOBuffer>(10)};
  332. std::vector<int> lengths = {10};
  333. EXPECT_EQ(
  334. ERR_CONNECTION_CLOSED,
  335. handle_->WritevStreamData(buffers, lengths, true, callback.callback()));
  336. spdy::Http2HeaderBlock headers;
  337. EXPECT_EQ(0, handle_->WriteHeaders(std::move(headers), true, nullptr));
  338. }
  339. TEST_P(QuicChromiumClientStreamTest, HandleAfterConnectionClose) {
  340. quic::test::QuicConnectionPeer::TearDownLocalConnectionState(
  341. session_.connection());
  342. stream_->OnConnectionClosed(quic::QUIC_INVALID_FRAME_DATA,
  343. quic::ConnectionCloseSource::FROM_PEER);
  344. EXPECT_FALSE(handle_->IsOpen());
  345. EXPECT_EQ(quic::QUIC_INVALID_FRAME_DATA, handle_->connection_error());
  346. }
  347. TEST_P(QuicChromiumClientStreamTest, HandleAfterStreamReset) {
  348. if (version_.HasIetfQuicFrames()) {
  349. // Make a STOP_SENDING frame and pass it to QUIC. For V99/IETF QUIC,
  350. // we need both a REST_STREAM and a STOP_SENDING to effect a closed
  351. // stream.
  352. quic::QuicStopSendingFrame stop_sending_frame(
  353. quic::kInvalidControlFrameId,
  354. quic::test::GetNthClientInitiatedBidirectionalStreamId(
  355. version_.transport_version, 0),
  356. quic::QUIC_STREAM_CANCELLED);
  357. session_.OnStopSendingFrame(stop_sending_frame);
  358. }
  359. // Verify that the Handle still behaves correctly after the stream is reset.
  360. quic::QuicRstStreamFrame rst(
  361. quic::kInvalidControlFrameId,
  362. quic::test::GetNthClientInitiatedBidirectionalStreamId(
  363. version_.transport_version, 0),
  364. quic::QUIC_STREAM_CANCELLED, 0);
  365. stream_->OnStreamReset(rst);
  366. EXPECT_FALSE(handle_->IsOpen());
  367. EXPECT_EQ(quic::QUIC_STREAM_CANCELLED, handle_->stream_error());
  368. }
  369. TEST_P(QuicChromiumClientStreamTest, OnFinRead) {
  370. InitializeHeaders();
  371. quic::QuicStreamOffset offset = 0;
  372. ProcessHeadersFull(headers_);
  373. quic::QuicStreamFrame frame2(
  374. quic::test::GetNthClientInitiatedBidirectionalStreamId(
  375. version_.transport_version, 0),
  376. true, offset, absl::string_view());
  377. stream_->OnStreamFrame(frame2);
  378. }
  379. TEST_P(QuicChromiumClientStreamTest, OnDataAvailable) {
  380. InitializeHeaders();
  381. ProcessHeadersFull(headers_);
  382. const char data[] = "hello world!";
  383. int data_len = strlen(data);
  384. size_t offset = 0;
  385. if (version_.HasIetfQuicFrames()) {
  386. std::string header = ConstructDataHeader(data_len);
  387. stream_->OnStreamFrame(quic::QuicStreamFrame(
  388. quic::test::GetNthClientInitiatedBidirectionalStreamId(
  389. version_.transport_version, 0),
  390. /*fin=*/false,
  391. /*offset=*/offset, header));
  392. offset += header.length();
  393. }
  394. stream_->OnStreamFrame(quic::QuicStreamFrame(
  395. quic::test::GetNthClientInitiatedBidirectionalStreamId(
  396. version_.transport_version, 0),
  397. /*fin=*/false,
  398. /*offset=*/offset, data));
  399. // Read the body and verify that it arrives correctly.
  400. TestCompletionCallback callback;
  401. scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(2 * data_len);
  402. EXPECT_EQ(data_len,
  403. handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback()));
  404. EXPECT_EQ(absl::string_view(data),
  405. absl::string_view(buffer->data(), data_len));
  406. }
  407. TEST_P(QuicChromiumClientStreamTest, OnDataAvailableAfterReadBody) {
  408. InitializeHeaders();
  409. ProcessHeadersFull(headers_);
  410. const char data[] = "hello world!";
  411. int data_len = strlen(data);
  412. // Start to read the body.
  413. TestCompletionCallback callback;
  414. scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(2 * data_len);
  415. EXPECT_EQ(ERR_IO_PENDING,
  416. handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback()));
  417. size_t offset = 0;
  418. if (version_.HasIetfQuicFrames()) {
  419. std::string header = ConstructDataHeader(data_len);
  420. stream_->OnStreamFrame(quic::QuicStreamFrame(
  421. quic::test::GetNthClientInitiatedBidirectionalStreamId(
  422. version_.transport_version, 0),
  423. /*fin=*/false,
  424. /*offset=*/offset, header));
  425. offset += header.length();
  426. }
  427. stream_->OnStreamFrame(quic::QuicStreamFrame(
  428. quic::test::GetNthClientInitiatedBidirectionalStreamId(
  429. version_.transport_version, 0),
  430. /*fin=*/false,
  431. /*offset=*/offset, data));
  432. EXPECT_EQ(data_len, callback.WaitForResult());
  433. EXPECT_EQ(absl::string_view(data),
  434. absl::string_view(buffer->data(), data_len));
  435. base::RunLoop().RunUntilIdle();
  436. }
  437. TEST_P(QuicChromiumClientStreamTest, ProcessHeadersWithError) {
  438. spdy::Http2HeaderBlock bad_headers;
  439. bad_headers["NAME"] = "...";
  440. EXPECT_CALL(
  441. *static_cast<quic::test::MockQuicConnection*>(session_.connection()),
  442. OnStreamReset(quic::test::GetNthClientInitiatedBidirectionalStreamId(
  443. version_.transport_version, 0),
  444. quic::QUIC_BAD_APPLICATION_PAYLOAD));
  445. auto headers = quic::test::AsHeaderList(bad_headers);
  446. stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
  447. headers);
  448. base::RunLoop().RunUntilIdle();
  449. }
  450. TEST_P(QuicChromiumClientStreamTest, OnDataAvailableWithError) {
  451. InitializeHeaders();
  452. auto headers = quic::test::AsHeaderList(headers_);
  453. ProcessHeadersFull(headers_);
  454. const char data[] = "hello world!";
  455. int data_len = strlen(data);
  456. // Start to read the body.
  457. TestCompletionCallback callback;
  458. scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(2 * data_len);
  459. EXPECT_EQ(
  460. ERR_IO_PENDING,
  461. handle_->ReadBody(
  462. buffer.get(), 2 * data_len,
  463. base::BindOnce(&QuicChromiumClientStreamTest::ResetStreamCallback,
  464. base::Unretained(this), stream_)));
  465. EXPECT_CALL(
  466. *static_cast<quic::test::MockQuicConnection*>(session_.connection()),
  467. OnStreamReset(quic::test::GetNthClientInitiatedBidirectionalStreamId(
  468. version_.transport_version, 0),
  469. quic::QUIC_STREAM_CANCELLED));
  470. // Receive the data and close the stream during the callback.
  471. size_t offset = 0;
  472. if (version_.HasIetfQuicFrames()) {
  473. std::string header = ConstructDataHeader(data_len);
  474. stream_->OnStreamFrame(quic::QuicStreamFrame(
  475. quic::test::GetNthClientInitiatedBidirectionalStreamId(
  476. version_.transport_version, 0),
  477. /*fin=*/false,
  478. /*offset=*/offset, header));
  479. offset += header.length();
  480. }
  481. stream_->OnStreamFrame(quic::QuicStreamFrame(
  482. quic::test::GetNthClientInitiatedBidirectionalStreamId(
  483. version_.transport_version, 0),
  484. /*fin=*/false,
  485. /*offset=*/0, data));
  486. base::RunLoop().RunUntilIdle();
  487. }
  488. TEST_P(QuicChromiumClientStreamTest, OnError) {
  489. // EXPECT_CALL(delegate_, OnError(ERR_INTERNET_DISCONNECTED)).Times(1);
  490. stream_->OnError(ERR_INTERNET_DISCONNECTED);
  491. stream_->OnError(ERR_INTERNET_DISCONNECTED);
  492. }
  493. TEST_P(QuicChromiumClientStreamTest, OnTrailers) {
  494. InitializeHeaders();
  495. ProcessHeadersFull(headers_);
  496. const char data[] = "hello world!";
  497. int data_len = strlen(data);
  498. size_t offset = 0;
  499. if (version_.HasIetfQuicFrames()) {
  500. std::string header = ConstructDataHeader(data_len);
  501. stream_->OnStreamFrame(quic::QuicStreamFrame(
  502. quic::test::GetNthClientInitiatedBidirectionalStreamId(
  503. version_.transport_version, 0),
  504. /*fin=*/false,
  505. /*offset=*/offset, header));
  506. offset += header.length();
  507. }
  508. stream_->OnStreamFrame(quic::QuicStreamFrame(
  509. quic::test::GetNthClientInitiatedBidirectionalStreamId(
  510. version_.transport_version, 0),
  511. /*fin=*/false,
  512. /*offset=*/offset, data));
  513. // Read the body and verify that it arrives correctly.
  514. TestCompletionCallback callback;
  515. scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(2 * data_len);
  516. EXPECT_EQ(data_len,
  517. handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback()));
  518. EXPECT_EQ(absl::string_view(data),
  519. absl::string_view(buffer->data(), data_len));
  520. spdy::Http2HeaderBlock trailers;
  521. trailers["bar"] = "foo";
  522. if (!version_.HasIetfQuicFrames()) {
  523. trailers[quic::kFinalOffsetHeaderKey] = base::NumberToString(strlen(data));
  524. }
  525. auto t = ProcessTrailers(trailers);
  526. TestCompletionCallback trailers_callback;
  527. EXPECT_EQ(
  528. static_cast<int>(t.uncompressed_header_bytes()),
  529. handle_->ReadTrailingHeaders(&trailers_, trailers_callback.callback()));
  530. // Read the body and verify that it arrives correctly.
  531. EXPECT_EQ(0,
  532. handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback()));
  533. // Make sure quic::kFinalOffsetHeaderKey is gone from the delivered actual
  534. // trailers.
  535. trailers.erase(quic::kFinalOffsetHeaderKey);
  536. EXPECT_EQ(trailers, trailers_);
  537. base::RunLoop().RunUntilIdle();
  538. }
  539. // Tests that trailers are marked as consumed only before delegate is to be
  540. // immediately notified about trailers.
  541. TEST_P(QuicChromiumClientStreamTest, MarkTrailersConsumedWhenNotifyDelegate) {
  542. InitializeHeaders();
  543. ProcessHeadersFull(headers_);
  544. const char data[] = "hello world!";
  545. int data_len = strlen(data);
  546. size_t offset = 0;
  547. if (version_.HasIetfQuicFrames()) {
  548. std::string header = ConstructDataHeader(data_len);
  549. stream_->OnStreamFrame(quic::QuicStreamFrame(
  550. quic::test::GetNthClientInitiatedBidirectionalStreamId(
  551. version_.transport_version, 0),
  552. /*fin=*/false,
  553. /*offset=*/offset, header));
  554. offset += header.length();
  555. }
  556. stream_->OnStreamFrame(quic::QuicStreamFrame(
  557. quic::test::GetNthClientInitiatedBidirectionalStreamId(
  558. version_.transport_version, 0),
  559. /*fin=*/false,
  560. /*offset=*/offset, data));
  561. // Read the body and verify that it arrives correctly.
  562. TestCompletionCallback callback;
  563. scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(2 * data_len);
  564. EXPECT_EQ(data_len,
  565. handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback()));
  566. EXPECT_EQ(absl::string_view(data),
  567. absl::string_view(buffer->data(), data_len));
  568. // Read again, and it will be pending.
  569. EXPECT_THAT(
  570. handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback()),
  571. IsError(ERR_IO_PENDING));
  572. spdy::Http2HeaderBlock trailers;
  573. trailers["bar"] = "foo";
  574. if (!version_.HasIetfQuicFrames()) {
  575. trailers[quic::kFinalOffsetHeaderKey] = base::NumberToString(strlen(data));
  576. }
  577. quic::QuicHeaderList t = ProcessTrailers(trailers);
  578. EXPECT_FALSE(stream_->IsDoneReading());
  579. EXPECT_EQ(static_cast<int>(t.uncompressed_header_bytes()),
  580. handle_->ReadTrailingHeaders(&trailers_, callback.callback()));
  581. // Read the body and verify that it arrives correctly.
  582. EXPECT_EQ(0, callback.WaitForResult());
  583. // Make sure the stream is properly closed since trailers and data are all
  584. // consumed.
  585. EXPECT_TRUE(stream_->IsDoneReading());
  586. // Make sure quic::kFinalOffsetHeaderKey is gone from the delivered actual
  587. // trailers.
  588. trailers.erase(quic::kFinalOffsetHeaderKey);
  589. EXPECT_EQ(trailers, trailers_);
  590. base::RunLoop().RunUntilIdle();
  591. }
  592. // Test that if Read() is called after response body is read and after trailers
  593. // are received but not yet delivered, Read() will return ERR_IO_PENDING instead
  594. // of 0 (EOF).
  595. TEST_P(QuicChromiumClientStreamTest, ReadAfterTrailersReceivedButNotDelivered) {
  596. InitializeHeaders();
  597. ProcessHeadersFull(headers_);
  598. const char data[] = "hello world!";
  599. int data_len = strlen(data);
  600. size_t offset = 0;
  601. if (version_.HasIetfQuicFrames()) {
  602. std::string header = ConstructDataHeader(data_len);
  603. stream_->OnStreamFrame(quic::QuicStreamFrame(
  604. quic::test::GetNthClientInitiatedBidirectionalStreamId(
  605. version_.transport_version, 0),
  606. /*fin=*/false,
  607. /*offset=*/offset, header));
  608. offset += header.length();
  609. }
  610. stream_->OnStreamFrame(quic::QuicStreamFrame(
  611. quic::test::GetNthClientInitiatedBidirectionalStreamId(
  612. version_.transport_version, 0),
  613. /*fin=*/false,
  614. /*offset=*/offset, data));
  615. // Read the body and verify that it arrives correctly.
  616. TestCompletionCallback callback;
  617. scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(2 * data_len);
  618. EXPECT_EQ(data_len,
  619. handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback()));
  620. EXPECT_EQ(absl::string_view(data),
  621. absl::string_view(buffer->data(), data_len));
  622. // Deliver trailers. Delegate notification is posted asynchronously.
  623. spdy::Http2HeaderBlock trailers;
  624. trailers["bar"] = "foo";
  625. if (!version_.HasIetfQuicFrames()) {
  626. trailers[quic::kFinalOffsetHeaderKey] = base::NumberToString(strlen(data));
  627. }
  628. quic::QuicHeaderList t = ProcessTrailers(trailers);
  629. EXPECT_FALSE(stream_->IsDoneReading());
  630. // Read again, it return ERR_IO_PENDING.
  631. EXPECT_THAT(
  632. handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback()),
  633. IsError(ERR_IO_PENDING));
  634. // Trailers are not delivered
  635. EXPECT_FALSE(stream_->IsDoneReading());
  636. TestCompletionCallback callback2;
  637. EXPECT_EQ(static_cast<int>(t.uncompressed_header_bytes()),
  638. handle_->ReadTrailingHeaders(&trailers_, callback2.callback()));
  639. // Read the body and verify that it arrives correctly.
  640. // OnDataAvailable() should follow right after and Read() will return 0.
  641. EXPECT_EQ(0, callback.WaitForResult());
  642. // Make sure the stream is properly closed since trailers and data are all
  643. // consumed.
  644. EXPECT_TRUE(stream_->IsDoneReading());
  645. // Make sure quic::kFinalOffsetHeaderKey is gone from the delivered actual
  646. // trailers.
  647. trailers.erase(quic::kFinalOffsetHeaderKey);
  648. EXPECT_EQ(trailers, trailers_);
  649. base::RunLoop().RunUntilIdle();
  650. }
  651. TEST_P(QuicChromiumClientStreamTest, WriteStreamData) {
  652. testing::InSequence seq;
  653. const char kData1[] = "hello world";
  654. const size_t kDataLen = std::size(kData1);
  655. // All data written.
  656. if (version_.HasIetfQuicFrames()) {
  657. std::string header = ConstructDataHeader(kDataLen);
  658. EXPECT_CALL(session_,
  659. WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
  660. .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
  661. }
  662. EXPECT_CALL(session_,
  663. WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
  664. .WillOnce(Return(quic::QuicConsumedData(kDataLen, true)));
  665. TestCompletionCallback callback;
  666. EXPECT_EQ(OK, handle_->WriteStreamData(base::StringPiece(kData1, kDataLen),
  667. true, callback.callback()));
  668. }
  669. TEST_P(QuicChromiumClientStreamTest, WriteStreamDataAsync) {
  670. testing::InSequence seq;
  671. const char kData1[] = "hello world";
  672. const size_t kDataLen = std::size(kData1);
  673. // No data written.
  674. EXPECT_CALL(session_,
  675. WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
  676. .WillOnce(Return(quic::QuicConsumedData(0, false)));
  677. TestCompletionCallback callback;
  678. EXPECT_EQ(ERR_IO_PENDING,
  679. handle_->WriteStreamData(base::StringPiece(kData1, kDataLen), true,
  680. callback.callback()));
  681. ASSERT_FALSE(callback.have_result());
  682. // All data written.
  683. if (version_.HasIetfQuicFrames()) {
  684. std::string header = ConstructDataHeader(kDataLen);
  685. EXPECT_CALL(session_,
  686. WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
  687. .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
  688. }
  689. EXPECT_CALL(session_,
  690. WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
  691. .WillOnce(Return(quic::QuicConsumedData(kDataLen, true)));
  692. stream_->OnCanWrite();
  693. // Do 2 writes in version 99.
  694. if (version_.HasIetfQuicFrames()) {
  695. stream_->OnCanWrite();
  696. }
  697. ASSERT_TRUE(callback.have_result());
  698. EXPECT_THAT(callback.WaitForResult(), IsOk());
  699. }
  700. TEST_P(QuicChromiumClientStreamTest, WritevStreamData) {
  701. testing::InSequence seq;
  702. scoped_refptr<StringIOBuffer> buf1 =
  703. base::MakeRefCounted<StringIOBuffer>("hello world!");
  704. scoped_refptr<StringIOBuffer> buf2 =
  705. base::MakeRefCounted<StringIOBuffer>("Just a small payload");
  706. // All data written.
  707. if (version_.HasIetfQuicFrames()) {
  708. std::string header = ConstructDataHeader(buf1->size());
  709. EXPECT_CALL(session_,
  710. WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
  711. .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
  712. }
  713. EXPECT_CALL(session_,
  714. WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
  715. .WillOnce(Return(quic::QuicConsumedData(buf1->size(), false)));
  716. if (version_.HasIetfQuicFrames()) {
  717. std::string header = ConstructDataHeader(buf2->size());
  718. EXPECT_CALL(session_,
  719. WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
  720. .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
  721. }
  722. EXPECT_CALL(session_,
  723. WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
  724. .WillOnce(Return(quic::QuicConsumedData(buf2->size(), true)));
  725. TestCompletionCallback callback;
  726. EXPECT_EQ(
  727. OK, handle_->WritevStreamData({buf1, buf2}, {buf1->size(), buf2->size()},
  728. true, callback.callback()));
  729. }
  730. TEST_P(QuicChromiumClientStreamTest, WritevStreamDataAsync) {
  731. testing::InSequence seq;
  732. scoped_refptr<StringIOBuffer> buf1 =
  733. base::MakeRefCounted<StringIOBuffer>("hello world!");
  734. scoped_refptr<StringIOBuffer> buf2 =
  735. base::MakeRefCounted<StringIOBuffer>("Just a small payload");
  736. // Only a part of the data is written.
  737. if (version_.HasIetfQuicFrames()) {
  738. std::string header = ConstructDataHeader(buf1->size());
  739. EXPECT_CALL(session_,
  740. WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
  741. .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
  742. }
  743. EXPECT_CALL(session_,
  744. WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
  745. // First piece of data is written.
  746. .WillOnce(Return(quic::QuicConsumedData(buf1->size(), false)));
  747. // Second piece of data is queued.
  748. EXPECT_CALL(session_,
  749. WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
  750. .WillOnce(Return(quic::QuicConsumedData(0, false)));
  751. TestCompletionCallback callback;
  752. EXPECT_EQ(ERR_IO_PENDING,
  753. handle_->WritevStreamData({buf1.get(), buf2.get()},
  754. {buf1->size(), buf2->size()}, true,
  755. callback.callback()));
  756. ASSERT_FALSE(callback.have_result());
  757. // The second piece of data is written.
  758. if (version_.HasIetfQuicFrames()) {
  759. std::string header = ConstructDataHeader(buf2->size());
  760. EXPECT_CALL(session_,
  761. WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
  762. .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
  763. }
  764. EXPECT_CALL(session_,
  765. WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
  766. .WillOnce(Return(quic::QuicConsumedData(buf2->size(), true)));
  767. stream_->OnCanWrite();
  768. if (version_.HasIetfQuicFrames()) {
  769. stream_->OnCanWrite();
  770. }
  771. ASSERT_TRUE(callback.have_result());
  772. EXPECT_THAT(callback.WaitForResult(), IsOk());
  773. }
  774. TEST_P(QuicChromiumClientStreamTest, HeadersBeforeHandle) {
  775. // We don't use stream_ because we want an incoming server push
  776. // stream.
  777. quic::QuicStreamId stream_id = GetNthServerInitiatedUnidirectionalStreamId(0);
  778. QuicChromiumClientStream* stream2 = new QuicChromiumClientStream(
  779. stream_id, &session_, quic::READ_UNIDIRECTIONAL, NetLogWithSource(),
  780. TRAFFIC_ANNOTATION_FOR_TESTS);
  781. session_.ActivateStream(base::WrapUnique(stream2));
  782. InitializeHeaders();
  783. // Receive the headers before the delegate is set.
  784. quic::QuicHeaderList header_list = quic::test::AsHeaderList(headers_);
  785. stream2->OnStreamHeaderList(true, header_list.uncompressed_header_bytes(),
  786. header_list);
  787. // Now set the delegate and verify that the headers are delivered.
  788. handle2_ = stream2->CreateHandle();
  789. TestCompletionCallback callback;
  790. EXPECT_EQ(static_cast<int>(header_list.uncompressed_header_bytes()),
  791. handle2_->ReadInitialHeaders(&headers_, callback.callback()));
  792. EXPECT_EQ(headers_, headers_);
  793. }
  794. TEST_P(QuicChromiumClientStreamTest, HeadersAndDataBeforeHandle) {
  795. // We don't use stream_ because we want an incoming server push
  796. // stream.
  797. quic::QuicStreamId stream_id = GetNthServerInitiatedUnidirectionalStreamId(0);
  798. QuicChromiumClientStream* stream2 = new QuicChromiumClientStream(
  799. stream_id, &session_, quic::READ_UNIDIRECTIONAL, NetLogWithSource(),
  800. TRAFFIC_ANNOTATION_FOR_TESTS);
  801. session_.ActivateStream(base::WrapUnique(stream2));
  802. InitializeHeaders();
  803. // Receive the headers and data before the delegate is set.
  804. quic::QuicHeaderList header_list = quic::test::AsHeaderList(headers_);
  805. stream2->OnStreamHeaderList(false, header_list.uncompressed_header_bytes(),
  806. header_list);
  807. const char data[] = "hello world!";
  808. size_t offset = 0;
  809. if (version_.HasIetfQuicFrames()) {
  810. std::string header = ConstructDataHeader(strlen(data));
  811. stream2->OnStreamFrame(quic::QuicStreamFrame(stream_id,
  812. /*fin=*/false,
  813. /*offset=*/offset, header));
  814. offset += header.length();
  815. }
  816. stream2->OnStreamFrame(quic::QuicStreamFrame(stream_id, /*fin=*/false,
  817. /*offset=*/offset, data));
  818. // Now set the delegate and verify that the headers are delivered, but
  819. // not the data, which needs to be read explicitly.
  820. handle2_ = stream2->CreateHandle();
  821. TestCompletionCallback callback;
  822. EXPECT_EQ(static_cast<int>(header_list.uncompressed_header_bytes()),
  823. handle2_->ReadInitialHeaders(&headers_, callback.callback()));
  824. EXPECT_EQ(headers_, headers_);
  825. base::RunLoop().RunUntilIdle();
  826. // Now explicitly read the data.
  827. int data_len = std::size(data) - 1;
  828. scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(data_len + 1);
  829. ASSERT_EQ(data_len, stream2->Read(buffer.get(), data_len + 1));
  830. EXPECT_EQ(absl::string_view(data),
  831. absl::string_view(buffer->data(), data_len));
  832. }
  833. // Regression test for https://crbug.com/1043531.
  834. TEST_P(QuicChromiumClientStreamTest, ResetOnEmptyResponseHeaders) {
  835. if (!VersionUsesHttp3(version_.transport_version)) {
  836. // QuicSpdyStream resets itself on empty headers,
  837. // because it is used to signal that headers were too large.
  838. EXPECT_CALL(
  839. *static_cast<quic::test::MockQuicConnection*>(session_.connection()),
  840. OnStreamReset(stream_->id(), quic::QUIC_HEADERS_TOO_LARGE));
  841. }
  842. const spdy::Http2HeaderBlock empty_response_headers;
  843. ProcessHeaders(empty_response_headers);
  844. if (VersionUsesHttp3(version_.transport_version)) {
  845. // Empty headers are allowed by QuicSpdyStream,
  846. // but an error is generated by QuicChromiumClientStream.
  847. int rv = handle_->ReadInitialHeaders(&headers_, CompletionOnceCallback());
  848. EXPECT_THAT(rv, IsError(net::ERR_QUIC_PROTOCOL_ERROR));
  849. }
  850. }
  851. // Tests that the stream resets when it receives an invalid ":status"
  852. // pseudo-header value.
  853. TEST_P(QuicChromiumClientStreamTest, InvalidStatus) {
  854. spdy::Http2HeaderBlock headers = CreateResponseHeaders("xxx");
  855. EXPECT_CALL(
  856. *static_cast<quic::test::MockQuicConnection*>(session_.connection()),
  857. OnStreamReset(quic::test::GetNthClientInitiatedBidirectionalStreamId(
  858. version_.transport_version, 0),
  859. quic::QUIC_BAD_APPLICATION_PAYLOAD));
  860. ProcessHeaders(headers);
  861. EXPECT_FALSE(handle_->IsOpen());
  862. EXPECT_EQ(quic::QUIC_BAD_APPLICATION_PAYLOAD, handle_->stream_error());
  863. }
  864. // Tests that the stream resets when it receives 101 Switching Protocols.
  865. TEST_P(QuicChromiumClientStreamTest, SwitchingProtocolsResponse) {
  866. spdy::Http2HeaderBlock informational_headers = CreateResponseHeaders("101");
  867. EXPECT_CALL(
  868. *static_cast<quic::test::MockQuicConnection*>(session_.connection()),
  869. OnStreamReset(quic::test::GetNthClientInitiatedBidirectionalStreamId(
  870. version_.transport_version, 0),
  871. quic::QUIC_BAD_APPLICATION_PAYLOAD));
  872. ProcessHeaders(informational_headers);
  873. EXPECT_FALSE(handle_->IsOpen());
  874. EXPECT_EQ(quic::QUIC_BAD_APPLICATION_PAYLOAD, handle_->stream_error());
  875. }
  876. // Tests that the stream ignores 100 Continue response.
  877. TEST_P(QuicChromiumClientStreamTest, ContinueResponse) {
  878. spdy::Http2HeaderBlock informational_headers = CreateResponseHeaders("100");
  879. // This informational headers should be ignored.
  880. ProcessHeaders(informational_headers);
  881. // Pass the initial headers.
  882. InitializeHeaders();
  883. quic::QuicHeaderList header_list = ProcessHeaders(headers_);
  884. // Read the initial headers.
  885. spdy::Http2HeaderBlock response_headers;
  886. // Pass DoNothing because the initial headers is already available and the
  887. // callback won't be called.
  888. EXPECT_EQ(static_cast<int>(header_list.uncompressed_header_bytes()),
  889. handle_->ReadInitialHeaders(&response_headers, base::DoNothing()));
  890. base::RunLoop().RunUntilIdle();
  891. EXPECT_EQ(response_headers, headers_);
  892. }
  893. // Tests that the stream handles 103 Early Hints responses.
  894. TEST_P(QuicChromiumClientStreamTest, EarlyHintsResponses) {
  895. // Pass Two Early Hints responses to the stream.
  896. spdy::Http2HeaderBlock hints1_headers = CreateResponseHeaders("103");
  897. hints1_headers["x-header1"] = "foo";
  898. quic::QuicHeaderList header_list = ProcessHeaders(hints1_headers);
  899. const size_t hints1_bytes = header_list.uncompressed_header_bytes();
  900. spdy::Http2HeaderBlock hints2_headers = CreateResponseHeaders("103");
  901. hints2_headers["x-header2"] = "foobarbaz";
  902. header_list = ProcessHeaders(hints2_headers);
  903. const size_t hints2_bytes = header_list.uncompressed_header_bytes();
  904. // Pass the initial headers to the stream.
  905. InitializeHeaders();
  906. header_list = ProcessHeaders(headers_);
  907. const size_t initial_headers_bytes = header_list.uncompressed_header_bytes();
  908. spdy::Http2HeaderBlock headers;
  909. // Read headers. The first two reads should return Early Hints.
  910. EXPECT_EQ(static_cast<int>(hints1_bytes),
  911. handle_->ReadInitialHeaders(&headers, base::DoNothing()));
  912. base::RunLoop().RunUntilIdle();
  913. EXPECT_EQ(headers, hints1_headers);
  914. base::TimeTicks first_early_hints_time = handle_->first_early_hints_time();
  915. EXPECT_FALSE(first_early_hints_time.is_null());
  916. EXPECT_EQ(static_cast<int>(hints2_bytes),
  917. handle_->ReadInitialHeaders(&headers, base::DoNothing()));
  918. base::RunLoop().RunUntilIdle();
  919. EXPECT_EQ(headers, hints2_headers);
  920. EXPECT_EQ(first_early_hints_time, handle_->first_early_hints_time());
  921. // The third read should return the initial headers.
  922. EXPECT_EQ(static_cast<int>(initial_headers_bytes),
  923. handle_->ReadInitialHeaders(&headers, base::DoNothing()));
  924. base::RunLoop().RunUntilIdle();
  925. EXPECT_EQ(headers, headers_);
  926. }
  927. // Tests that pending reads for Early Hints work.
  928. TEST_P(QuicChromiumClientStreamTest, EarlyHintsAsync) {
  929. spdy::Http2HeaderBlock headers;
  930. TestCompletionCallback hints_callback;
  931. // Try to read headers. The read should be blocked.
  932. EXPECT_EQ(ERR_IO_PENDING,
  933. handle_->ReadInitialHeaders(&headers, hints_callback.callback()));
  934. // Pass an Early Hints and the initial headers.
  935. spdy::Http2HeaderBlock hints_headers = CreateResponseHeaders("103");
  936. hints_headers["x-header1"] = "foo";
  937. quic::QuicHeaderList header_list = ProcessHeaders(hints_headers);
  938. const size_t hints_bytes = header_list.uncompressed_header_bytes();
  939. InitializeHeaders();
  940. header_list = ProcessHeaders(headers_);
  941. const size_t initial_headers_bytes = header_list.uncompressed_header_bytes();
  942. // Wait for the pending headers read. The result should be the Early Hints.
  943. const int hints_result = hints_callback.WaitForResult();
  944. EXPECT_EQ(hints_result, static_cast<int>(hints_bytes));
  945. EXPECT_EQ(headers, hints_headers);
  946. // Second read should return the initial headers.
  947. EXPECT_EQ(static_cast<int>(initial_headers_bytes),
  948. handle_->ReadInitialHeaders(&headers, base::DoNothing()));
  949. EXPECT_EQ(headers, headers_);
  950. }
  951. // Tests that Early Hints after the initial headers is treated as an error.
  952. TEST_P(QuicChromiumClientStreamTest, EarlyHintsAfterInitialHeaders) {
  953. InitializeHeaders();
  954. ProcessHeadersFull(headers_);
  955. // Early Hints after the initial headers are treated as trailers, and it
  956. // should result in an error because trailers must not contain pseudo-headers
  957. // like ":status".
  958. EXPECT_CALL(
  959. *static_cast<quic::test::MockQuicConnection*>(session_.connection()),
  960. CloseConnection(
  961. quic::QUIC_INVALID_HEADERS_STREAM_DATA, _,
  962. quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
  963. spdy::Http2HeaderBlock hints_headers;
  964. hints_headers[":status"] = "103";
  965. ProcessHeaders(hints_headers);
  966. base::RunLoop().RunUntilIdle();
  967. }
  968. // Similar to the above test but don't read the initial headers.
  969. TEST_P(QuicChromiumClientStreamTest, EarlyHintsAfterInitialHeadersWithoutRead) {
  970. InitializeHeaders();
  971. ProcessHeaders(headers_);
  972. // Early Hints after the initial headers are treated as trailers, and it
  973. // should result in an error because trailers must not contain pseudo-headers
  974. // like ":status".
  975. EXPECT_CALL(
  976. *static_cast<quic::test::MockQuicConnection*>(session_.connection()),
  977. CloseConnection(
  978. quic::QUIC_INVALID_HEADERS_STREAM_DATA, _,
  979. quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
  980. spdy::Http2HeaderBlock hints_headers;
  981. hints_headers[":status"] = "103";
  982. ProcessHeaders(hints_headers);
  983. base::RunLoop().RunUntilIdle();
  984. }
  985. // Regression test for https://crbug.com/1248970. Write an Early Hints headers,
  986. // an initial response headers and trailers in succession without reading in
  987. // the middle of writings.
  988. TEST_P(QuicChromiumClientStreamTest, TrailersAfterEarlyHintsWithoutRead) {
  989. // Process an Early Hints response headers on the stream.
  990. spdy::Http2HeaderBlock hints_headers = CreateResponseHeaders("103");
  991. quic::QuicHeaderList hints_header_list = ProcessHeaders(hints_headers);
  992. // Process an initial response headers on the stream.
  993. InitializeHeaders();
  994. quic::QuicHeaderList header_list = ProcessHeaders(headers_);
  995. // Process a trailer headers on the stream. This should not hit any DCHECK.
  996. spdy::Http2HeaderBlock trailers;
  997. trailers["bar"] = "foo";
  998. quic::QuicHeaderList trailer_header_list = ProcessTrailers(trailers);
  999. base::RunLoop().RunUntilIdle();
  1000. // Read the Early Hints response from the handle.
  1001. {
  1002. spdy::Http2HeaderBlock headers;
  1003. TestCompletionCallback callback;
  1004. EXPECT_EQ(static_cast<int>(hints_header_list.uncompressed_header_bytes()),
  1005. handle_->ReadInitialHeaders(&headers, callback.callback()));
  1006. EXPECT_EQ(headers, hints_headers);
  1007. }
  1008. // Read the initial headers from the handle.
  1009. {
  1010. spdy::Http2HeaderBlock headers;
  1011. TestCompletionCallback callback;
  1012. EXPECT_EQ(static_cast<int>(header_list.uncompressed_header_bytes()),
  1013. handle_->ReadInitialHeaders(&headers, callback.callback()));
  1014. EXPECT_EQ(headers, headers_);
  1015. }
  1016. // Read trailers from the handle.
  1017. {
  1018. spdy::Http2HeaderBlock headers;
  1019. TestCompletionCallback callback;
  1020. EXPECT_EQ(static_cast<int>(trailer_header_list.uncompressed_header_bytes()),
  1021. handle_->ReadTrailingHeaders(&headers, callback.callback()));
  1022. EXPECT_EQ(headers, trailers);
  1023. }
  1024. }
  1025. } // namespace
  1026. } // namespace net::test