OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/tools/quic/quic_spdy_client_stream.h" | 5 #include "net/tools/quic/quic_spdy_client_stream.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
11 #include "net/quic/core/quic_utils.h" | 11 #include "net/quic/core/quic_utils.h" |
12 #include "net/quic/core/spdy_utils.h" | 12 #include "net/quic/core/spdy_utils.h" |
13 #include "net/quic/test_tools/crypto_test_utils.h" | 13 #include "net/quic/test_tools/crypto_test_utils.h" |
14 #include "net/quic/test_tools/quic_test_utils.h" | 14 #include "net/quic/test_tools/quic_test_utils.h" |
15 #include "net/tools/quic/quic_client_session.h" | 15 #include "net/tools/quic/quic_client_session.h" |
16 #include "testing/gmock/include/gmock/gmock.h" | 16 #include "testing/gmock/include/gmock/gmock.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
18 | 18 |
| 19 using base::IntToString; |
19 using net::test::CryptoTestUtils; | 20 using net::test::CryptoTestUtils; |
20 using net::test::DefaultQuicConfig; | 21 using net::test::DefaultQuicConfig; |
21 using net::test::MockQuicConnection; | 22 using net::test::MockQuicConnection; |
22 using net::test::MockQuicConnectionHelper; | 23 using net::test::MockQuicConnectionHelper; |
23 using net::test::SupportedVersions; | 24 using net::test::SupportedVersions; |
24 using net::test::kClientDataStreamId1; | 25 using net::test::kClientDataStreamId1; |
25 using net::test::kServerDataStreamId1; | 26 using net::test::kServerDataStreamId1; |
26 using net::test::kInitialSessionFlowControlWindowForTest; | 27 using net::test::kInitialSessionFlowControlWindowForTest; |
27 using net::test::kInitialStreamFlowControlWindowForTest; | 28 using net::test::kInitialStreamFlowControlWindowForTest; |
28 | 29 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 QuicSpdyClientStreamTest() | 64 QuicSpdyClientStreamTest() |
64 : connection_(new StrictMock<MockQuicConnection>(&helper_, | 65 : connection_(new StrictMock<MockQuicConnection>(&helper_, |
65 &alarm_factory_, | 66 &alarm_factory_, |
66 Perspective::IS_CLIENT)), | 67 Perspective::IS_CLIENT)), |
67 session_(connection_, &push_promise_index_), | 68 session_(connection_, &push_promise_index_), |
68 body_("hello world") { | 69 body_("hello world") { |
69 session_.Initialize(); | 70 session_.Initialize(); |
70 | 71 |
71 headers_[":status"] = "200"; | 72 headers_[":status"] = "200"; |
72 headers_["content-length"] = "11"; | 73 headers_["content-length"] = "11"; |
73 headers_string_ = SpdyUtils::SerializeUncompressedHeaders(headers_); | |
74 | 74 |
75 stream_.reset(new QuicSpdyClientStream(kClientDataStreamId1, &session_)); | 75 stream_.reset(new QuicSpdyClientStream(kClientDataStreamId1, &session_)); |
76 stream_visitor_.reset(new StreamVisitor()); | 76 stream_visitor_.reset(new StreamVisitor()); |
77 stream_->set_visitor(stream_visitor_.get()); | 77 stream_->set_visitor(stream_visitor_.get()); |
78 } | 78 } |
79 | 79 |
80 class StreamVisitor : public QuicSpdyClientStream::Visitor { | 80 class StreamVisitor : public QuicSpdyClientStream::Visitor { |
81 void OnClose(QuicSpdyStream* stream) override { | 81 void OnClose(QuicSpdyStream* stream) override { |
82 DVLOG(1) << "stream " << stream->id(); | 82 DVLOG(1) << "stream " << stream->id(); |
83 } | 83 } |
84 }; | 84 }; |
85 | 85 |
86 MockQuicConnectionHelper helper_; | 86 MockQuicConnectionHelper helper_; |
87 MockAlarmFactory alarm_factory_; | 87 MockAlarmFactory alarm_factory_; |
88 StrictMock<MockQuicConnection>* connection_; | 88 StrictMock<MockQuicConnection>* connection_; |
89 QuicClientPushPromiseIndex push_promise_index_; | 89 QuicClientPushPromiseIndex push_promise_index_; |
90 | 90 |
91 MockQuicClientSession session_; | 91 MockQuicClientSession session_; |
92 std::unique_ptr<QuicSpdyClientStream> stream_; | 92 std::unique_ptr<QuicSpdyClientStream> stream_; |
93 std::unique_ptr<StreamVisitor> stream_visitor_; | 93 std::unique_ptr<StreamVisitor> stream_visitor_; |
94 SpdyHeaderBlock headers_; | 94 SpdyHeaderBlock headers_; |
95 string headers_string_; | |
96 string body_; | 95 string body_; |
97 }; | 96 }; |
98 | 97 |
99 TEST_F(QuicSpdyClientStreamTest, TestReceivingIllegalResponseStatusCode) { | 98 TEST_F(QuicSpdyClientStreamTest, TestReceivingIllegalResponseStatusCode) { |
100 headers_[":status"] = "200 ok"; | 99 headers_[":status"] = "200 ok"; |
101 headers_string_ = SpdyUtils::SerializeUncompressedHeaders(headers_); | |
102 | 100 |
103 stream_->OnStreamHeaders(headers_string_); | |
104 EXPECT_CALL(*connection_, | 101 EXPECT_CALL(*connection_, |
105 SendRstStream(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD, 0)); | 102 SendRstStream(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD, 0)); |
106 stream_->OnStreamHeadersComplete(false, headers_string_.size()); | 103 auto headers = AsHeaderList(headers_); |
| 104 stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(), |
| 105 headers); |
107 EXPECT_EQ(QUIC_BAD_APPLICATION_PAYLOAD, stream_->stream_error()); | 106 EXPECT_EQ(QUIC_BAD_APPLICATION_PAYLOAD, stream_->stream_error()); |
108 } | 107 } |
109 | 108 |
110 TEST_F(QuicSpdyClientStreamTest, TestFraming) { | 109 TEST_F(QuicSpdyClientStreamTest, TestFraming) { |
111 stream_->OnStreamHeaders(headers_string_); | 110 auto headers = AsHeaderList(headers_); |
112 stream_->OnStreamHeadersComplete(false, headers_string_.size()); | 111 stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(), |
| 112 headers); |
113 stream_->OnStreamFrame( | 113 stream_->OnStreamFrame( |
114 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_)); | 114 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_)); |
115 EXPECT_EQ("200", stream_->response_headers().find(":status")->second); | 115 EXPECT_EQ("200", stream_->response_headers().find(":status")->second); |
116 EXPECT_EQ(200, stream_->response_code()); | 116 EXPECT_EQ(200, stream_->response_code()); |
117 EXPECT_EQ(body_, stream_->data()); | 117 EXPECT_EQ(body_, stream_->data()); |
118 } | 118 } |
119 | 119 |
120 TEST_F(QuicSpdyClientStreamTest, TestFramingOnePacket) { | 120 TEST_F(QuicSpdyClientStreamTest, TestFramingOnePacket) { |
121 stream_->OnStreamHeaders(headers_string_); | 121 auto headers = AsHeaderList(headers_); |
122 stream_->OnStreamHeadersComplete(false, headers_string_.size()); | 122 stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(), |
| 123 headers); |
123 stream_->OnStreamFrame( | 124 stream_->OnStreamFrame( |
124 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_)); | 125 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_)); |
125 EXPECT_EQ("200", stream_->response_headers().find(":status")->second); | 126 EXPECT_EQ("200", stream_->response_headers().find(":status")->second); |
126 EXPECT_EQ(200, stream_->response_code()); | 127 EXPECT_EQ(200, stream_->response_code()); |
127 EXPECT_EQ(body_, stream_->data()); | 128 EXPECT_EQ(body_, stream_->data()); |
128 } | 129 } |
129 | 130 |
130 TEST_F(QuicSpdyClientStreamTest, DISABLED_TestFramingExtraData) { | 131 TEST_F(QuicSpdyClientStreamTest, DISABLED_TestFramingExtraData) { |
131 string large_body = "hello world!!!!!!"; | 132 string large_body = "hello world!!!!!!"; |
132 | 133 |
133 stream_->OnStreamHeaders(headers_string_); | 134 auto headers = AsHeaderList(headers_); |
134 stream_->OnStreamHeadersComplete(false, headers_string_.size()); | 135 stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(), |
| 136 headers); |
135 // The headers should parse successfully. | 137 // The headers should parse successfully. |
136 EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error()); | 138 EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error()); |
137 EXPECT_EQ("200", stream_->response_headers().find(":status")->second); | 139 EXPECT_EQ("200", stream_->response_headers().find(":status")->second); |
138 EXPECT_EQ(200, stream_->response_code()); | 140 EXPECT_EQ(200, stream_->response_code()); |
139 | 141 |
140 EXPECT_CALL(*connection_, | 142 EXPECT_CALL(*connection_, |
141 SendRstStream(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD, 0)); | 143 SendRstStream(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD, 0)); |
142 stream_->OnStreamFrame( | 144 stream_->OnStreamFrame( |
143 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, large_body)); | 145 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, large_body)); |
144 | 146 |
145 EXPECT_NE(QUIC_STREAM_NO_ERROR, stream_->stream_error()); | 147 EXPECT_NE(QUIC_STREAM_NO_ERROR, stream_->stream_error()); |
146 } | 148 } |
147 | 149 |
148 TEST_F(QuicSpdyClientStreamTest, TestNoBidirectionalStreaming) { | 150 TEST_F(QuicSpdyClientStreamTest, TestNoBidirectionalStreaming) { |
149 QuicStreamFrame frame(kClientDataStreamId1, false, 3, StringPiece("asd")); | 151 QuicStreamFrame frame(kClientDataStreamId1, false, 3, StringPiece("asd")); |
150 | 152 |
151 EXPECT_FALSE(stream_->write_side_closed()); | 153 EXPECT_FALSE(stream_->write_side_closed()); |
152 stream_->OnStreamFrame(frame); | 154 stream_->OnStreamFrame(frame); |
153 EXPECT_TRUE(stream_->write_side_closed()); | 155 EXPECT_TRUE(stream_->write_side_closed()); |
154 } | 156 } |
155 | 157 |
156 TEST_F(QuicSpdyClientStreamTest, ReceivingTrailers) { | 158 TEST_F(QuicSpdyClientStreamTest, ReceivingTrailers) { |
157 // Test that receiving trailing headers, containing a final offset, results in | 159 // Test that receiving trailing headers, containing a final offset, results in |
158 // the stream being closed at that byte offset. | 160 // the stream being closed at that byte offset. |
159 // Send headers as usual. | 161 // Send headers as usual. |
160 stream_->OnStreamHeaders(headers_string_); | 162 auto headers = AsHeaderList(headers_); |
161 stream_->OnStreamHeadersComplete(false, headers_string_.size()); | 163 stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(), |
| 164 headers); |
162 | 165 |
163 // Send trailers before sending the body. Even though a FIN has been received | 166 // Send trailers before sending the body. Even though a FIN has been received |
164 // the stream should not be closed, as it does not yet have all the data bytes | 167 // the stream should not be closed, as it does not yet have all the data bytes |
165 // promised by the final offset field. | 168 // promised by the final offset field. |
166 SpdyHeaderBlock trailers; | 169 SpdyHeaderBlock trailer_block; |
167 trailers["trailer key"] = "trailer value"; | 170 trailer_block["trailer key"] = "trailer value"; |
168 trailers[kFinalOffsetHeaderKey] = base::IntToString(body_.size()); | 171 trailer_block[kFinalOffsetHeaderKey] = IntToString(body_.size()); |
169 string trailers_string = SpdyUtils::SerializeUncompressedHeaders(trailers); | 172 auto trailers = AsHeaderList(trailer_block); |
170 stream_->OnStreamHeaders(trailers_string); | 173 stream_->OnStreamHeaderList(true, trailers.uncompressed_header_bytes(), |
171 stream_->OnStreamHeadersComplete(true, trailers_string.size()); | 174 trailers); |
172 | 175 |
173 // Now send the body, which should close the stream as the FIN has been | 176 // Now send the body, which should close the stream as the FIN has been |
174 // received, as well as all data. | 177 // received, as well as all data. |
175 EXPECT_CALL(session_, CloseStream(stream_->id())); | 178 EXPECT_CALL(session_, CloseStream(stream_->id())); |
176 stream_->OnStreamFrame( | 179 stream_->OnStreamFrame( |
177 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_)); | 180 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_)); |
178 } | 181 } |
179 | 182 |
180 } // namespace | 183 } // namespace |
181 } // namespace test | 184 } // namespace test |
182 } // namespace net | 185 } // namespace net |
OLD | NEW |