OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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_server_stream.h" | 5 #include "net/tools/quic/quic_spdy_server_stream.h" |
6 | 6 |
7 #include "base/strings/string_number_conversions.h" | 7 #include "base/strings/string_number_conversions.h" |
8 #include "base/strings/string_piece.h" | 8 #include "base/strings/string_piece.h" |
9 #include "net/quic/quic_connection.h" | 9 #include "net/quic/quic_connection.h" |
10 #include "net/quic/quic_protocol.h" | 10 #include "net/quic/quic_protocol.h" |
(...skipping 21 matching lines...) Expand all Loading... |
32 using testing::StrictMock; | 32 using testing::StrictMock; |
33 using testing::WithArgs; | 33 using testing::WithArgs; |
34 | 34 |
35 namespace net { | 35 namespace net { |
36 namespace tools { | 36 namespace tools { |
37 namespace test { | 37 namespace test { |
38 | 38 |
39 class QuicSpdyServerStreamPeer : public QuicSpdyServerStream { | 39 class QuicSpdyServerStreamPeer : public QuicSpdyServerStream { |
40 public: | 40 public: |
41 QuicSpdyServerStreamPeer(QuicStreamId stream_id, QuicSession* session) | 41 QuicSpdyServerStreamPeer(QuicStreamId stream_id, QuicSession* session) |
42 : QuicSpdyServerStream(stream_id, session) { | 42 : QuicSpdyServerStream(stream_id, session) {} |
43 } | |
44 | 43 |
45 using QuicSpdyServerStream::SendResponse; | 44 using QuicSpdyServerStream::SendResponse; |
46 using QuicSpdyServerStream::SendErrorResponse; | 45 using QuicSpdyServerStream::SendErrorResponse; |
47 | 46 |
48 BalsaHeaders* mutable_headers() { | 47 BalsaHeaders* mutable_headers() { return &headers_; } |
49 return &headers_; | |
50 } | |
51 | 48 |
52 static void SendResponse(QuicSpdyServerStream* stream) { | 49 static void SendResponse(QuicSpdyServerStream* stream) { |
53 stream->SendResponse(); | 50 stream->SendResponse(); |
54 } | 51 } |
55 | 52 |
56 static void SendErrorResponse(QuicSpdyServerStream* stream) { | 53 static void SendErrorResponse(QuicSpdyServerStream* stream) { |
57 stream->SendResponse(); | 54 stream->SendResponse(); |
58 } | 55 } |
59 | 56 |
60 static const string& body(QuicSpdyServerStream* stream) { | 57 static const string& body(QuicSpdyServerStream* stream) { |
61 return stream->body_; | 58 return stream->body_; |
62 } | 59 } |
63 | 60 |
64 static const BalsaHeaders& headers(QuicSpdyServerStream* stream) { | 61 static const BalsaHeaders& headers(QuicSpdyServerStream* stream) { |
65 return stream->headers_; | 62 return stream->headers_; |
66 } | 63 } |
67 }; | 64 }; |
68 | 65 |
69 namespace { | 66 namespace { |
70 | 67 |
71 class QuicSpdyServerStreamTest : public ::testing::TestWithParam<QuicVersion> { | 68 class QuicSpdyServerStreamTest : public ::testing::TestWithParam<QuicVersion> { |
72 public: | 69 public: |
73 QuicSpdyServerStreamTest() | 70 QuicSpdyServerStreamTest() |
74 : connection_(new StrictMock<MockConnection>( | 71 : connection_( |
75 true, SupportedVersions(GetParam()))), | 72 new StrictMock<MockConnection>(true, |
| 73 SupportedVersions(GetParam()))), |
76 session_(connection_), | 74 session_(connection_), |
77 body_("hello world") { | 75 body_("hello world") { |
78 BalsaHeaders request_headers; | 76 BalsaHeaders request_headers; |
79 request_headers.SetRequestFirstlineFromStringPieces( | 77 request_headers.SetRequestFirstlineFromStringPieces( |
80 "POST", "https://www.google.com/", "HTTP/1.1"); | 78 "POST", "https://www.google.com/", "HTTP/1.1"); |
81 request_headers.ReplaceOrAppendHeader("content-length", "11"); | 79 request_headers.ReplaceOrAppendHeader("content-length", "11"); |
82 | 80 |
83 headers_string_ = SpdyUtils::SerializeRequestHeaders(request_headers); | 81 headers_string_ = SpdyUtils::SerializeRequestHeaders(request_headers); |
84 | 82 |
85 // New streams rely on having the peer's flow control receive window | 83 // New streams rely on having the peer's flow control receive window |
86 // negotiated in the config. | 84 // negotiated in the config. |
87 const uint32 kInitialWindow = 10 * kMaxPacketSize; | 85 const uint32 kInitialWindow = 10 * kMaxPacketSize; |
88 session_.config()->SetInitialFlowControlWindowToSend( | 86 session_.config()->SetInitialFlowControlWindowToSend(kInitialWindow); |
89 kInitialWindow); | |
90 stream_.reset(new QuicSpdyServerStreamPeer(3, &session_)); | 87 stream_.reset(new QuicSpdyServerStreamPeer(3, &session_)); |
91 } | 88 } |
92 | 89 |
93 static void SetUpTestCase() { | 90 static void SetUpTestCase() { QuicInMemoryCachePeer::ResetForTests(); } |
94 QuicInMemoryCachePeer::ResetForTests(); | |
95 } | |
96 | 91 |
97 virtual void SetUp() { | 92 virtual void SetUp() { |
98 QuicInMemoryCache* cache = QuicInMemoryCache::GetInstance(); | 93 QuicInMemoryCache* cache = QuicInMemoryCache::GetInstance(); |
99 | 94 |
100 BalsaHeaders request_headers, response_headers; | 95 BalsaHeaders request_headers, response_headers; |
101 StringPiece body("Yum"); | 96 StringPiece body("Yum"); |
102 request_headers.SetRequestFirstlineFromStringPieces( | 97 request_headers.SetRequestFirstlineFromStringPieces( |
103 "GET", | 98 "GET", "https://www.google.com/foo", "HTTP/1.1"); |
104 "https://www.google.com/foo", | 99 response_headers.SetRequestFirstlineFromStringPieces( |
105 "HTTP/1.1"); | 100 "HTTP/1.1", "200", "OK"); |
106 response_headers.SetRequestFirstlineFromStringPieces("HTTP/1.1", | |
107 "200", | |
108 "OK"); | |
109 response_headers.AppendHeader("content-length", | 101 response_headers.AppendHeader("content-length", |
110 base::IntToString(body.length())); | 102 base::IntToString(body.length())); |
111 | 103 |
112 // Check if response already exists and matches. | 104 // Check if response already exists and matches. |
113 const QuicInMemoryCache::Response* cached_response = | 105 const QuicInMemoryCache::Response* cached_response = |
114 cache->GetResponse(request_headers); | 106 cache->GetResponse(request_headers); |
115 if (cached_response != NULL) { | 107 if (cached_response != NULL) { |
116 string cached_response_headers_str, response_headers_str; | 108 string cached_response_headers_str, response_headers_str; |
117 cached_response->headers().DumpToString(&cached_response_headers_str); | 109 cached_response->headers().DumpToString(&cached_response_headers_str); |
118 response_headers.DumpToString(&response_headers_str); | 110 response_headers.DumpToString(&response_headers_str); |
(...skipping 24 matching lines...) Expand all Loading... |
143 | 135 |
144 QuicConsumedData ConsumeAllData( | 136 QuicConsumedData ConsumeAllData( |
145 QuicStreamId id, | 137 QuicStreamId id, |
146 const IOVector& data, | 138 const IOVector& data, |
147 QuicStreamOffset offset, | 139 QuicStreamOffset offset, |
148 bool fin, | 140 bool fin, |
149 QuicAckNotifier::DelegateInterface* /*ack_notifier_delegate*/) { | 141 QuicAckNotifier::DelegateInterface* /*ack_notifier_delegate*/) { |
150 return QuicConsumedData(data.TotalBufferSize(), fin); | 142 return QuicConsumedData(data.TotalBufferSize(), fin); |
151 } | 143 } |
152 | 144 |
153 INSTANTIATE_TEST_CASE_P(Tests, QuicSpdyServerStreamTest, | 145 INSTANTIATE_TEST_CASE_P(Tests, |
| 146 QuicSpdyServerStreamTest, |
154 ::testing::ValuesIn(QuicSupportedVersions())); | 147 ::testing::ValuesIn(QuicSupportedVersions())); |
155 | 148 |
156 TEST_P(QuicSpdyServerStreamTest, TestFraming) { | 149 TEST_P(QuicSpdyServerStreamTest, TestFraming) { |
157 EXPECT_CALL(session_, WritevData(_, _, _, _, _)).Times(AnyNumber()). | 150 EXPECT_CALL(session_, WritevData(_, _, _, _, _)) |
158 WillRepeatedly(Invoke(ConsumeAllData)); | 151 .Times(AnyNumber()) |
| 152 .WillRepeatedly(Invoke(ConsumeAllData)); |
159 | 153 |
160 EXPECT_EQ(headers_string_.size(), stream_->ProcessData( | 154 EXPECT_EQ( |
161 headers_string_.c_str(), headers_string_.size())); | 155 headers_string_.size(), |
| 156 stream_->ProcessData(headers_string_.c_str(), headers_string_.size())); |
162 EXPECT_EQ(body_.size(), stream_->ProcessData(body_.c_str(), body_.size())); | 157 EXPECT_EQ(body_.size(), stream_->ProcessData(body_.c_str(), body_.size())); |
163 EXPECT_EQ(11u, StreamHeaders().content_length()); | 158 EXPECT_EQ(11u, StreamHeaders().content_length()); |
164 EXPECT_EQ("https://www.google.com/", StreamHeaders().request_uri()); | 159 EXPECT_EQ("https://www.google.com/", StreamHeaders().request_uri()); |
165 EXPECT_EQ("POST", StreamHeaders().request_method()); | 160 EXPECT_EQ("POST", StreamHeaders().request_method()); |
166 EXPECT_EQ(body_, StreamBody()); | 161 EXPECT_EQ(body_, StreamBody()); |
167 } | 162 } |
168 | 163 |
169 TEST_P(QuicSpdyServerStreamTest, TestFramingOnePacket) { | 164 TEST_P(QuicSpdyServerStreamTest, TestFramingOnePacket) { |
170 EXPECT_CALL(session_, WritevData(_, _, _, _, _)).Times(AnyNumber()). | 165 EXPECT_CALL(session_, WritevData(_, _, _, _, _)) |
171 WillRepeatedly(Invoke(ConsumeAllData)); | 166 .Times(AnyNumber()) |
| 167 .WillRepeatedly(Invoke(ConsumeAllData)); |
172 | 168 |
173 string message = headers_string_ + body_; | 169 string message = headers_string_ + body_; |
174 | 170 |
175 EXPECT_EQ(message.size(), stream_->ProcessData( | 171 EXPECT_EQ(message.size(), |
176 message.c_str(), message.size())); | 172 stream_->ProcessData(message.c_str(), message.size())); |
177 EXPECT_EQ(11u, StreamHeaders().content_length()); | 173 EXPECT_EQ(11u, StreamHeaders().content_length()); |
178 EXPECT_EQ("https://www.google.com/", StreamHeaders().request_uri()); | 174 EXPECT_EQ("https://www.google.com/", StreamHeaders().request_uri()); |
179 EXPECT_EQ("POST", StreamHeaders().request_method()); | 175 EXPECT_EQ("POST", StreamHeaders().request_method()); |
180 EXPECT_EQ(body_, StreamBody()); | 176 EXPECT_EQ(body_, StreamBody()); |
181 } | 177 } |
182 | 178 |
183 TEST_P(QuicSpdyServerStreamTest, TestFramingExtraData) { | 179 TEST_P(QuicSpdyServerStreamTest, TestFramingExtraData) { |
184 string large_body = "hello world!!!!!!"; | 180 string large_body = "hello world!!!!!!"; |
185 | 181 |
186 // We'll automatically write out an error (headers + body) | 182 // We'll automatically write out an error (headers + body) |
187 EXPECT_CALL(session_, WritevData(_, _, _, _, _)).Times(AnyNumber()). | 183 EXPECT_CALL(session_, WritevData(_, _, _, _, _)) |
188 WillRepeatedly(Invoke(ConsumeAllData)); | 184 .Times(AnyNumber()) |
| 185 .WillRepeatedly(Invoke(ConsumeAllData)); |
189 | 186 |
190 EXPECT_EQ(headers_string_.size(), stream_->ProcessData( | 187 EXPECT_EQ( |
191 headers_string_.c_str(), headers_string_.size())); | 188 headers_string_.size(), |
| 189 stream_->ProcessData(headers_string_.c_str(), headers_string_.size())); |
192 // Content length is still 11. This will register as an error and we won't | 190 // Content length is still 11. This will register as an error and we won't |
193 // accept the bytes. | 191 // accept the bytes. |
194 stream_->ProcessData(large_body.c_str(), large_body.size()); | 192 stream_->ProcessData(large_body.c_str(), large_body.size()); |
195 EXPECT_EQ(11u, StreamHeaders().content_length()); | 193 EXPECT_EQ(11u, StreamHeaders().content_length()); |
196 EXPECT_EQ("https://www.google.com/", StreamHeaders().request_uri()); | 194 EXPECT_EQ("https://www.google.com/", StreamHeaders().request_uri()); |
197 EXPECT_EQ("POST", StreamHeaders().request_method()); | 195 EXPECT_EQ("POST", StreamHeaders().request_method()); |
198 } | 196 } |
199 | 197 |
200 TEST_P(QuicSpdyServerStreamTest, TestSendResponse) { | 198 TEST_P(QuicSpdyServerStreamTest, TestSendResponse) { |
201 BalsaHeaders* request_headers = stream_->mutable_headers(); | 199 BalsaHeaders* request_headers = stream_->mutable_headers(); |
202 request_headers->SetRequestFirstlineFromStringPieces( | 200 request_headers->SetRequestFirstlineFromStringPieces( |
203 "GET", | 201 "GET", "https://www.google.com/foo", "HTTP/1.1"); |
204 "https://www.google.com/foo", | |
205 "HTTP/1.1"); | |
206 | 202 |
207 response_headers_.SetResponseFirstlineFromStringPieces( | 203 response_headers_.SetResponseFirstlineFromStringPieces( |
208 "HTTP/1.1", "200", "OK"); | 204 "HTTP/1.1", "200", "OK"); |
209 response_headers_.ReplaceOrAppendHeader("content-length", "3"); | 205 response_headers_.ReplaceOrAppendHeader("content-length", "3"); |
210 | 206 |
211 InSequence s; | 207 InSequence s; |
212 EXPECT_CALL(session_, | 208 EXPECT_CALL(session_, WritevData(kHeadersStreamId, _, 0, false, NULL)); |
213 WritevData(kHeadersStreamId, _, 0, false, NULL)); | |
214 | 209 |
215 | 210 EXPECT_CALL(session_, WritevData(_, _, _, _, _)).Times(1).WillOnce( |
216 EXPECT_CALL(session_, WritevData(_, _, _, _, _)).Times(1). | 211 Return(QuicConsumedData(3, true))); |
217 WillOnce(Return(QuicConsumedData(3, true))); | |
218 | 212 |
219 QuicSpdyServerStreamPeer::SendResponse(stream_.get()); | 213 QuicSpdyServerStreamPeer::SendResponse(stream_.get()); |
220 EXPECT_TRUE(stream_->read_side_closed()); | 214 EXPECT_TRUE(stream_->read_side_closed()); |
221 EXPECT_TRUE(stream_->write_side_closed()); | 215 EXPECT_TRUE(stream_->write_side_closed()); |
222 } | 216 } |
223 | 217 |
224 TEST_P(QuicSpdyServerStreamTest, TestSendErrorResponse) { | 218 TEST_P(QuicSpdyServerStreamTest, TestSendErrorResponse) { |
225 response_headers_.SetResponseFirstlineFromStringPieces( | 219 response_headers_.SetResponseFirstlineFromStringPieces( |
226 "HTTP/1.1", "500", "Server Error"); | 220 "HTTP/1.1", "500", "Server Error"); |
227 response_headers_.ReplaceOrAppendHeader("content-length", "3"); | 221 response_headers_.ReplaceOrAppendHeader("content-length", "3"); |
228 | 222 |
229 InSequence s; | 223 InSequence s; |
230 EXPECT_CALL(session_, | 224 EXPECT_CALL(session_, WritevData(kHeadersStreamId, _, 0, false, NULL)); |
231 WritevData(kHeadersStreamId, _, 0, false, NULL)); | |
232 | 225 |
233 EXPECT_CALL(session_, WritevData(_, _, _, _, _)).Times(1). | 226 EXPECT_CALL(session_, WritevData(_, _, _, _, _)).Times(1).WillOnce( |
234 WillOnce(Return(QuicConsumedData(3, true))); | 227 Return(QuicConsumedData(3, true))); |
235 | 228 |
236 QuicSpdyServerStreamPeer::SendErrorResponse(stream_.get()); | 229 QuicSpdyServerStreamPeer::SendErrorResponse(stream_.get()); |
237 EXPECT_TRUE(stream_->read_side_closed()); | 230 EXPECT_TRUE(stream_->read_side_closed()); |
238 EXPECT_TRUE(stream_->write_side_closed()); | 231 EXPECT_TRUE(stream_->write_side_closed()); |
239 } | 232 } |
240 | 233 |
241 TEST_P(QuicSpdyServerStreamTest, InvalidHeadersWithFin) { | 234 TEST_P(QuicSpdyServerStreamTest, InvalidHeadersWithFin) { |
242 char arr[] = { | 235 char arr[] = { |
243 0x3a, 0x68, 0x6f, 0x73, // :hos | 236 0x3a, 0x68, 0x6f, 0x73, // :hos |
244 0x74, 0x00, 0x00, 0x00, // t... | 237 0x74, 0x00, 0x00, 0x00, // t... |
245 0x00, 0x00, 0x00, 0x00, // .... | 238 0x00, 0x00, 0x00, 0x00, // .... |
246 0x07, 0x3a, 0x6d, 0x65, // .:me | 239 0x07, 0x3a, 0x6d, 0x65, // .:me |
247 0x74, 0x68, 0x6f, 0x64, // thod | 240 0x74, 0x68, 0x6f, 0x64, // thod |
248 0x00, 0x00, 0x00, 0x03, // .... | 241 0x00, 0x00, 0x00, 0x03, // .... |
249 0x47, 0x45, 0x54, 0x00, // GET. | 242 0x47, 0x45, 0x54, 0x00, // GET. |
250 0x00, 0x00, 0x05, 0x3a, // ...: | 243 0x00, 0x00, 0x05, 0x3a, // ...: |
251 0x70, 0x61, 0x74, 0x68, // path | 244 0x70, 0x61, 0x74, 0x68, // path |
252 0x00, 0x00, 0x00, 0x04, // .... | 245 0x00, 0x00, 0x00, 0x04, // .... |
253 0x2f, 0x66, 0x6f, 0x6f, // /foo | 246 0x2f, 0x66, 0x6f, 0x6f, // /foo |
254 0x00, 0x00, 0x00, 0x07, // .... | 247 0x00, 0x00, 0x00, 0x07, // .... |
255 0x3a, 0x73, 0x63, 0x68, // :sch | 248 0x3a, 0x73, 0x63, 0x68, // :sch |
256 0x65, 0x6d, 0x65, 0x00, // eme. | 249 0x65, 0x6d, 0x65, 0x00, // eme. |
257 0x00, 0x00, 0x00, 0x00, // .... | 250 0x00, 0x00, 0x00, 0x00, // .... |
258 0x00, 0x00, 0x08, 0x3a, // ...: | 251 0x00, 0x00, 0x08, 0x3a, // ...: |
259 0x76, 0x65, 0x72, 0x73, // vers | 252 0x76, 0x65, 0x72, 0x73, // vers |
260 '\x96', 0x6f, 0x6e, 0x00, // <i(69)>on. | 253 '\x96', 0x6f, 0x6e, 0x00, // <i(69)>on. |
261 0x00, 0x00, 0x08, 0x48, // ...H | 254 0x00, 0x00, 0x08, 0x48, // ...H |
262 0x54, 0x54, 0x50, 0x2f, // TTP/ | 255 0x54, 0x54, 0x50, 0x2f, // TTP/ |
263 0x31, 0x2e, 0x31, // 1.1 | 256 0x31, 0x2e, 0x31, // 1.1 |
264 }; | 257 }; |
265 StringPiece data(arr, arraysize(arr)); | 258 StringPiece data(arr, arraysize(arr)); |
266 QuicStreamFrame frame(stream_->id(), true, 0, MakeIOVector(data)); | 259 QuicStreamFrame frame(stream_->id(), true, 0, MakeIOVector(data)); |
267 // Verify that we don't crash when we get a invalid headers in stream frame. | 260 // Verify that we don't crash when we get a invalid headers in stream frame. |
268 stream_->OnStreamFrame(frame); | 261 stream_->OnStreamFrame(frame); |
269 } | 262 } |
270 | 263 |
271 } // namespace | 264 } // namespace |
272 } // namespace test | 265 } // namespace test |
273 } // namespace tools | 266 } // namespace tools |
274 } // namespace net | 267 } // namespace net |
OLD | NEW |