| 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_simple_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_flags.h" | 10 #include "net/quic/quic_flags.h" |
| 11 #include "net/quic/quic_protocol.h" | 11 #include "net/quic/quic_protocol.h" |
| 12 #include "net/quic/quic_utils.h" | 12 #include "net/quic/quic_utils.h" |
| 13 #include "net/quic/spdy_utils.h" | 13 #include "net/quic/spdy_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/quic/test_tools/reliable_quic_stream_peer.h" | 15 #include "net/quic/test_tools/reliable_quic_stream_peer.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 35 using testing::InvokeArgument; | 35 using testing::InvokeArgument; |
| 36 using testing::InSequence; | 36 using testing::InSequence; |
| 37 using testing::Return; | 37 using testing::Return; |
| 38 using testing::StrictMock; | 38 using testing::StrictMock; |
| 39 using testing::WithArgs; | 39 using testing::WithArgs; |
| 40 | 40 |
| 41 namespace net { | 41 namespace net { |
| 42 namespace tools { | 42 namespace tools { |
| 43 namespace test { | 43 namespace test { |
| 44 | 44 |
| 45 class QuicSpdyServerStreamPeer : public QuicSpdyServerStream { | 45 class QuicSimpleServerStreamPeer : public QuicSimpleServerStream { |
| 46 public: | 46 public: |
| 47 QuicSpdyServerStreamPeer(QuicStreamId stream_id, QuicSpdySession* session) | 47 QuicSimpleServerStreamPeer(QuicStreamId stream_id, QuicSpdySession* session) |
| 48 : QuicSpdyServerStream(stream_id, session) {} | 48 : QuicSimpleServerStream(stream_id, session) {} |
| 49 | 49 |
| 50 using QuicSpdyServerStream::SendResponse; | 50 using QuicSimpleServerStream::SendResponse; |
| 51 using QuicSpdyServerStream::SendErrorResponse; | 51 using QuicSimpleServerStream::SendErrorResponse; |
| 52 | 52 |
| 53 SpdyHeaderBlock* mutable_headers() { | 53 SpdyHeaderBlock* mutable_headers() { return &request_headers_; } |
| 54 return &request_headers_; | |
| 55 } | |
| 56 | 54 |
| 57 static void SendResponse(QuicSpdyServerStream* stream) { | 55 static void SendResponse(QuicSimpleServerStream* stream) { |
| 58 stream->SendResponse(); | 56 stream->SendResponse(); |
| 59 } | 57 } |
| 60 | 58 |
| 61 static void SendErrorResponse(QuicSpdyServerStream* stream) { | 59 static void SendErrorResponse(QuicSimpleServerStream* stream) { |
| 62 stream->SendErrorResponse(); | 60 stream->SendErrorResponse(); |
| 63 } | 61 } |
| 64 | 62 |
| 65 static const string& body(QuicSpdyServerStream* stream) { | 63 static const string& body(QuicSimpleServerStream* stream) { |
| 66 return stream->body_; | 64 return stream->body_; |
| 67 } | 65 } |
| 68 | 66 |
| 69 static const int content_length(QuicSpdyServerStream* stream) { | 67 static const int content_length(QuicSimpleServerStream* stream) { |
| 70 return stream->content_length_; | 68 return stream->content_length_; |
| 71 } | 69 } |
| 72 | 70 |
| 73 static const SpdyHeaderBlock& headers(QuicSpdyServerStream* stream) { | 71 static const SpdyHeaderBlock& headers(QuicSimpleServerStream* stream) { |
| 74 return stream->request_headers_; | 72 return stream->request_headers_; |
| 75 } | 73 } |
| 76 }; | 74 }; |
| 77 | 75 |
| 78 namespace { | 76 namespace { |
| 79 | 77 |
| 80 class QuicSpdyServerStreamTest : public ::testing::TestWithParam<QuicVersion> { | 78 class QuicSimpleServerStreamTest |
| 79 : public ::testing::TestWithParam<QuicVersion> { |
| 81 public: | 80 public: |
| 82 QuicSpdyServerStreamTest() | 81 QuicSimpleServerStreamTest() |
| 83 : connection_( | 82 : connection_( |
| 84 new StrictMock<MockConnection>(&helper_, | 83 new StrictMock<MockConnection>(&helper_, |
| 85 Perspective::IS_SERVER, | 84 Perspective::IS_SERVER, |
| 86 SupportedVersions(GetParam()))), | 85 SupportedVersions(GetParam()))), |
| 87 session_(connection_), | 86 session_(connection_), |
| 88 body_("hello world") { | 87 body_("hello world") { |
| 89 SpdyHeaderBlock request_headers; | 88 SpdyHeaderBlock request_headers; |
| 90 request_headers[":host"] = ""; | 89 request_headers[":host"] = ""; |
| 91 request_headers[":authority"] = ""; | 90 request_headers[":authority"] = ""; |
| 92 request_headers[":path"] = "/"; | 91 request_headers[":path"] = "/"; |
| 93 request_headers[":method"] = "POST"; | 92 request_headers[":method"] = "POST"; |
| 94 request_headers[":version"] = "HTTP/1.1"; | 93 request_headers[":version"] = "HTTP/1.1"; |
| 95 request_headers["content-length"] = "11"; | 94 request_headers["content-length"] = "11"; |
| 96 | 95 |
| 97 headers_string_ = | 96 headers_string_ = |
| 98 net::SpdyUtils::SerializeUncompressedHeaders(request_headers); | 97 net::SpdyUtils::SerializeUncompressedHeaders(request_headers); |
| 99 | 98 |
| 100 // New streams rely on having the peer's flow control receive window | 99 // New streams rely on having the peer's flow control receive window |
| 101 // negotiated in the config. | 100 // negotiated in the config. |
| 102 session_.config()->SetInitialStreamFlowControlWindowToSend( | 101 session_.config()->SetInitialStreamFlowControlWindowToSend( |
| 103 kInitialStreamFlowControlWindowForTest); | 102 kInitialStreamFlowControlWindowForTest); |
| 104 session_.config()->SetInitialSessionFlowControlWindowToSend( | 103 session_.config()->SetInitialSessionFlowControlWindowToSend( |
| 105 kInitialSessionFlowControlWindowForTest); | 104 kInitialSessionFlowControlWindowForTest); |
| 106 stream_ = new QuicSpdyServerStreamPeer(::net::test::kClientDataStreamId1, | 105 stream_ = new QuicSimpleServerStreamPeer(::net::test::kClientDataStreamId1, |
| 107 &session_); | 106 &session_); |
| 108 // Register stream_ in dynamic_stream_map_ and pass ownership to session_. | 107 // Register stream_ in dynamic_stream_map_ and pass ownership to session_. |
| 109 session_.ActivateStream(stream_); | 108 session_.ActivateStream(stream_); |
| 110 | 109 |
| 111 QuicInMemoryCachePeer::ResetForTests(); | 110 QuicInMemoryCachePeer::ResetForTests(); |
| 112 } | 111 } |
| 113 | 112 |
| 114 ~QuicSpdyServerStreamTest() override { | 113 ~QuicSimpleServerStreamTest() override { |
| 115 QuicInMemoryCachePeer::ResetForTests(); | 114 QuicInMemoryCachePeer::ResetForTests(); |
| 116 } | 115 } |
| 117 | 116 |
| 118 const string& StreamBody() { return QuicSpdyServerStreamPeer::body(stream_); } | 117 const string& StreamBody() { |
| 118 return QuicSimpleServerStreamPeer::body(stream_); |
| 119 } |
| 119 | 120 |
| 120 StringPiece StreamHeadersValue(const string& key) { | 121 StringPiece StreamHeadersValue(const string& key) { |
| 121 return (*stream_->mutable_headers())[key]; | 122 return (*stream_->mutable_headers())[key]; |
| 122 } | 123 } |
| 123 | 124 |
| 124 SpdyHeaderBlock response_headers_; | 125 SpdyHeaderBlock response_headers_; |
| 125 MockConnectionHelper helper_; | 126 MockConnectionHelper helper_; |
| 126 StrictMock<MockConnection>* connection_; | 127 StrictMock<MockConnection>* connection_; |
| 127 StrictMock<MockQuicSpdySession> session_; | 128 StrictMock<MockQuicSpdySession> session_; |
| 128 QuicSpdyServerStreamPeer* stream_; // Owned by session_. | 129 QuicSimpleServerStreamPeer* stream_; // Owned by session_. |
| 129 string headers_string_; | 130 string headers_string_; |
| 130 string body_; | 131 string body_; |
| 131 }; | 132 }; |
| 132 | 133 |
| 133 INSTANTIATE_TEST_CASE_P(Tests, | 134 INSTANTIATE_TEST_CASE_P(Tests, |
| 134 QuicSpdyServerStreamTest, | 135 QuicSimpleServerStreamTest, |
| 135 ::testing::ValuesIn(QuicSupportedVersions())); | 136 ::testing::ValuesIn(QuicSupportedVersions())); |
| 136 | 137 |
| 137 TEST_P(QuicSpdyServerStreamTest, TestFraming) { | 138 TEST_P(QuicSimpleServerStreamTest, TestFraming) { |
| 138 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) | 139 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
| 139 .Times(AnyNumber()) | 140 .Times(AnyNumber()) |
| 140 .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData)); | 141 .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData)); |
| 141 stream_->OnStreamHeaders(headers_string_); | 142 stream_->OnStreamHeaders(headers_string_); |
| 142 stream_->OnStreamHeadersComplete(false, headers_string_.size()); | 143 stream_->OnStreamHeadersComplete(false, headers_string_.size()); |
| 143 stream_->OnStreamFrame( | 144 stream_->OnStreamFrame( |
| 144 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_)); | 145 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_)); |
| 145 EXPECT_EQ("11", StreamHeadersValue("content-length")); | 146 EXPECT_EQ("11", StreamHeadersValue("content-length")); |
| 146 EXPECT_EQ("/", StreamHeadersValue(":path")); | 147 EXPECT_EQ("/", StreamHeadersValue(":path")); |
| 147 EXPECT_EQ("POST", StreamHeadersValue(":method")); | 148 EXPECT_EQ("POST", StreamHeadersValue(":method")); |
| 148 EXPECT_EQ(body_, StreamBody()); | 149 EXPECT_EQ(body_, StreamBody()); |
| 149 } | 150 } |
| 150 | 151 |
| 151 TEST_P(QuicSpdyServerStreamTest, TestFramingOnePacket) { | 152 TEST_P(QuicSimpleServerStreamTest, TestFramingOnePacket) { |
| 152 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) | 153 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
| 153 .Times(AnyNumber()) | 154 .Times(AnyNumber()) |
| 154 .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData)); | 155 .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData)); |
| 155 | 156 |
| 156 stream_->OnStreamHeaders(headers_string_); | 157 stream_->OnStreamHeaders(headers_string_); |
| 157 stream_->OnStreamHeadersComplete(false, headers_string_.size()); | 158 stream_->OnStreamHeadersComplete(false, headers_string_.size()); |
| 158 stream_->OnStreamFrame( | 159 stream_->OnStreamFrame( |
| 159 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_)); | 160 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_)); |
| 160 EXPECT_EQ("11", StreamHeadersValue("content-length")); | 161 EXPECT_EQ("11", StreamHeadersValue("content-length")); |
| 161 EXPECT_EQ("/", StreamHeadersValue(":path")); | 162 EXPECT_EQ("/", StreamHeadersValue(":path")); |
| 162 EXPECT_EQ("POST", StreamHeadersValue(":method")); | 163 EXPECT_EQ("POST", StreamHeadersValue(":method")); |
| 163 EXPECT_EQ(body_, StreamBody()); | 164 EXPECT_EQ(body_, StreamBody()); |
| 164 } | 165 } |
| 165 | 166 |
| 166 TEST_P(QuicSpdyServerStreamTest, SendQuicRstStreamNoErrorInStopReading) { | 167 TEST_P(QuicSimpleServerStreamTest, SendQuicRstStreamNoErrorInStopReading) { |
| 167 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) | 168 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
| 168 .Times(AnyNumber()) | 169 .Times(AnyNumber()) |
| 169 .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData)); | 170 .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData)); |
| 170 | 171 |
| 171 EXPECT_FALSE(stream_->fin_received()); | 172 EXPECT_FALSE(stream_->fin_received()); |
| 172 EXPECT_FALSE(stream_->rst_received()); | 173 EXPECT_FALSE(stream_->rst_received()); |
| 173 | 174 |
| 174 stream_->set_fin_sent(true); | 175 stream_->set_fin_sent(true); |
| 175 stream_->CloseWriteSide(); | 176 stream_->CloseWriteSide(); |
| 176 | 177 |
| 177 if (GetParam() > QUIC_VERSION_28) { | 178 if (GetParam() > QUIC_VERSION_28) { |
| 178 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(1); | 179 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(1); |
| 179 } else { | 180 } else { |
| 180 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); | 181 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); |
| 181 } | 182 } |
| 182 stream_->StopReading(); | 183 stream_->StopReading(); |
| 183 } | 184 } |
| 184 | 185 |
| 185 TEST_P(QuicSpdyServerStreamTest, TestFramingExtraData) { | 186 TEST_P(QuicSimpleServerStreamTest, TestFramingExtraData) { |
| 186 string large_body = "hello world!!!!!!"; | 187 string large_body = "hello world!!!!!!"; |
| 187 | 188 |
| 188 // We'll automatically write out an error (headers + body) | 189 // We'll automatically write out an error (headers + body) |
| 189 EXPECT_CALL(session_, WriteHeaders(_, _, _, _, _)); | 190 EXPECT_CALL(session_, WriteHeaders(_, _, _, _, _)); |
| 190 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) | 191 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
| 191 .WillOnce(Invoke(MockQuicSpdySession::ConsumeAllData)); | 192 .WillOnce(Invoke(MockQuicSpdySession::ConsumeAllData)); |
| 192 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); | 193 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); |
| 193 | 194 |
| 194 stream_->OnStreamHeaders(headers_string_); | 195 stream_->OnStreamHeaders(headers_string_); |
| 195 stream_->OnStreamHeadersComplete(false, headers_string_.size()); | 196 stream_->OnStreamHeadersComplete(false, headers_string_.size()); |
| 196 stream_->OnStreamFrame( | 197 stream_->OnStreamFrame( |
| 197 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_)); | 198 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_)); |
| 198 // Content length is still 11. This will register as an error and we won't | 199 // Content length is still 11. This will register as an error and we won't |
| 199 // accept the bytes. | 200 // accept the bytes. |
| 200 stream_->OnStreamFrame( | 201 stream_->OnStreamFrame( |
| 201 QuicStreamFrame(stream_->id(), /*fin=*/true, body_.size(), large_body)); | 202 QuicStreamFrame(stream_->id(), /*fin=*/true, body_.size(), large_body)); |
| 202 EXPECT_EQ("11", StreamHeadersValue("content-length")); | 203 EXPECT_EQ("11", StreamHeadersValue("content-length")); |
| 203 EXPECT_EQ("/", StreamHeadersValue(":path")); | 204 EXPECT_EQ("/", StreamHeadersValue(":path")); |
| 204 EXPECT_EQ("POST", StreamHeadersValue(":method")); | 205 EXPECT_EQ("POST", StreamHeadersValue(":method")); |
| 205 } | 206 } |
| 206 | 207 |
| 207 TEST_P(QuicSpdyServerStreamTest, SendResponseWithIllegalResponseStatus) { | 208 TEST_P(QuicSimpleServerStreamTest, SendResponseWithIllegalResponseStatus) { |
| 208 // Send a illegal response with response status not supported by HTTP/2. | 209 // Send a illegal response with response status not supported by HTTP/2. |
| 209 SpdyHeaderBlock* request_headers = stream_->mutable_headers(); | 210 SpdyHeaderBlock* request_headers = stream_->mutable_headers(); |
| 210 (*request_headers)[":path"] = "/bar"; | 211 (*request_headers)[":path"] = "/bar"; |
| 211 (*request_headers)[":authority"] = ""; | 212 (*request_headers)[":authority"] = ""; |
| 212 (*request_headers)[":version"] = "HTTP/1.1"; | 213 (*request_headers)[":version"] = "HTTP/1.1"; |
| 213 (*request_headers)[":method"] = "GET"; | 214 (*request_headers)[":method"] = "GET"; |
| 214 | 215 |
| 215 response_headers_[":version"] = "HTTP/1.1"; | 216 response_headers_[":version"] = "HTTP/1.1"; |
| 216 // HTTP/2 only supports integer responsecode, so "200 OK" is illegal. | 217 // HTTP/2 only supports integer responsecode, so "200 OK" is illegal. |
| 217 response_headers_[":status"] = "200 OK"; | 218 response_headers_[":status"] = "200 OK"; |
| 218 response_headers_["content-length"] = "5"; | 219 response_headers_["content-length"] = "5"; |
| 219 string body = "Yummm"; | 220 string body = "Yummm"; |
| 220 QuicInMemoryCache::GetInstance()->AddResponse("", "/bar", response_headers_, | 221 QuicInMemoryCache::GetInstance()->AddResponse("", "/bar", response_headers_, |
| 221 body); | 222 body); |
| 222 | 223 |
| 223 stream_->set_fin_received(true); | 224 stream_->set_fin_received(true); |
| 224 | 225 |
| 225 InSequence s; | 226 InSequence s; |
| 226 EXPECT_CALL(session_, WriteHeaders(stream_->id(), _, false, _, nullptr)); | 227 EXPECT_CALL(session_, WriteHeaders(stream_->id(), _, false, _, nullptr)); |
| 227 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) | 228 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
| 228 .Times(1) | 229 .Times(1) |
| 229 .WillOnce(Return(QuicConsumedData( | 230 .WillOnce(Return(QuicConsumedData( |
| 230 strlen(QuicSpdyServerStream::kErrorResponseBody), true))); | 231 strlen(QuicSimpleServerStream::kErrorResponseBody), true))); |
| 231 | 232 |
| 232 QuicSpdyServerStreamPeer::SendResponse(stream_); | 233 QuicSimpleServerStreamPeer::SendResponse(stream_); |
| 233 EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_)); | 234 EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_)); |
| 234 EXPECT_TRUE(stream_->reading_stopped()); | 235 EXPECT_TRUE(stream_->reading_stopped()); |
| 235 EXPECT_TRUE(stream_->write_side_closed()); | 236 EXPECT_TRUE(stream_->write_side_closed()); |
| 236 } | 237 } |
| 237 | 238 |
| 238 TEST_P(QuicSpdyServerStreamTest, SendPushResponseWith404Response) { | 239 TEST_P(QuicSimpleServerStreamTest, SendPushResponseWith404Response) { |
| 239 // Create a new promised stream with even id(). | 240 // Create a new promised stream with even id(). |
| 240 QuicSpdyServerStreamPeer* promised_stream = | 241 QuicSimpleServerStreamPeer* promised_stream = |
| 241 new QuicSpdyServerStreamPeer(2, &session_); | 242 new QuicSimpleServerStreamPeer(2, &session_); |
| 242 session_.ActivateStream(promised_stream); | 243 session_.ActivateStream(promised_stream); |
| 243 | 244 |
| 244 // Send a push response with response status 404, which will be regarded as | 245 // Send a push response with response status 404, which will be regarded as |
| 245 // invalid server push response. | 246 // invalid server push response. |
| 246 SpdyHeaderBlock* request_headers = promised_stream->mutable_headers(); | 247 SpdyHeaderBlock* request_headers = promised_stream->mutable_headers(); |
| 247 (*request_headers)[":path"] = "/bar"; | 248 (*request_headers)[":path"] = "/bar"; |
| 248 (*request_headers)[":authority"] = ""; | 249 (*request_headers)[":authority"] = ""; |
| 249 (*request_headers)[":version"] = "HTTP/1.1"; | 250 (*request_headers)[":version"] = "HTTP/1.1"; |
| 250 (*request_headers)[":method"] = "GET"; | 251 (*request_headers)[":method"] = "GET"; |
| 251 | 252 |
| 252 response_headers_[":version"] = "HTTP/1.1"; | 253 response_headers_[":version"] = "HTTP/1.1"; |
| 253 response_headers_[":status"] = "404"; | 254 response_headers_[":status"] = "404"; |
| 254 response_headers_["content-length"] = "8"; | 255 response_headers_["content-length"] = "8"; |
| 255 string body = "NotFound"; | 256 string body = "NotFound"; |
| 256 QuicInMemoryCache::GetInstance()->AddResponse("", "/bar", response_headers_, | 257 QuicInMemoryCache::GetInstance()->AddResponse("", "/bar", response_headers_, |
| 257 body); | 258 body); |
| 258 | 259 |
| 259 InSequence s; | 260 InSequence s; |
| 260 EXPECT_CALL(session_, | 261 EXPECT_CALL(session_, |
| 261 SendRstStream(promised_stream->id(), QUIC_STREAM_CANCELLED, 0)); | 262 SendRstStream(promised_stream->id(), QUIC_STREAM_CANCELLED, 0)); |
| 262 | 263 |
| 263 QuicSpdyServerStreamPeer::SendResponse(promised_stream); | 264 QuicSimpleServerStreamPeer::SendResponse(promised_stream); |
| 264 } | 265 } |
| 265 | 266 |
| 266 TEST_P(QuicSpdyServerStreamTest, SendResponseWithValidHeaders) { | 267 TEST_P(QuicSimpleServerStreamTest, SendResponseWithValidHeaders) { |
| 267 // Add a request and response with valid headers. | 268 // Add a request and response with valid headers. |
| 268 SpdyHeaderBlock* request_headers = stream_->mutable_headers(); | 269 SpdyHeaderBlock* request_headers = stream_->mutable_headers(); |
| 269 (*request_headers)[":path"] = "/bar"; | 270 (*request_headers)[":path"] = "/bar"; |
| 270 (*request_headers)[":authority"] = ""; | 271 (*request_headers)[":authority"] = ""; |
| 271 (*request_headers)[":version"] = "HTTP/1.1"; | 272 (*request_headers)[":version"] = "HTTP/1.1"; |
| 272 (*request_headers)[":method"] = "GET"; | 273 (*request_headers)[":method"] = "GET"; |
| 273 | 274 |
| 274 response_headers_[":version"] = "HTTP/1.1"; | 275 response_headers_[":version"] = "HTTP/1.1"; |
| 275 response_headers_[":status"] = "200"; | 276 response_headers_[":status"] = "200"; |
| 276 response_headers_["content-length"] = "5"; | 277 response_headers_["content-length"] = "5"; |
| 277 string body = "Yummm"; | 278 string body = "Yummm"; |
| 278 QuicInMemoryCache::GetInstance()->AddResponse("", "/bar", response_headers_, | 279 QuicInMemoryCache::GetInstance()->AddResponse("", "/bar", response_headers_, |
| 279 body); | 280 body); |
| 280 stream_->set_fin_received(true); | 281 stream_->set_fin_received(true); |
| 281 | 282 |
| 282 InSequence s; | 283 InSequence s; |
| 283 EXPECT_CALL(session_, WriteHeaders(stream_->id(), _, false, _, nullptr)); | 284 EXPECT_CALL(session_, WriteHeaders(stream_->id(), _, false, _, nullptr)); |
| 284 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) | 285 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
| 285 .Times(1) | 286 .Times(1) |
| 286 .WillOnce(Return(QuicConsumedData(body.length(), true))); | 287 .WillOnce(Return(QuicConsumedData(body.length(), true))); |
| 287 | 288 |
| 288 QuicSpdyServerStreamPeer::SendResponse(stream_); | 289 QuicSimpleServerStreamPeer::SendResponse(stream_); |
| 289 EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_)); | 290 EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_)); |
| 290 EXPECT_TRUE(stream_->reading_stopped()); | 291 EXPECT_TRUE(stream_->reading_stopped()); |
| 291 EXPECT_TRUE(stream_->write_side_closed()); | 292 EXPECT_TRUE(stream_->write_side_closed()); |
| 292 } | 293 } |
| 293 | 294 |
| 294 TEST_P(QuicSpdyServerStreamTest, TestSendErrorResponse) { | 295 TEST_P(QuicSimpleServerStreamTest, TestSendErrorResponse) { |
| 295 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); | 296 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); |
| 296 | 297 |
| 297 response_headers_[":version"] = "HTTP/1.1"; | 298 response_headers_[":version"] = "HTTP/1.1"; |
| 298 response_headers_[":status"] = "500 Server Error"; | 299 response_headers_[":status"] = "500 Server Error"; |
| 299 response_headers_["content-length"] = "3"; | 300 response_headers_["content-length"] = "3"; |
| 300 stream_->set_fin_received(true); | 301 stream_->set_fin_received(true); |
| 301 | 302 |
| 302 InSequence s; | 303 InSequence s; |
| 303 EXPECT_CALL(session_, WriteHeaders(_, _, _, _, _)); | 304 EXPECT_CALL(session_, WriteHeaders(_, _, _, _, _)); |
| 304 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(1). | 305 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
| 305 WillOnce(Return(QuicConsumedData(3, true))); | 306 .Times(1) |
| 307 .WillOnce(Return(QuicConsumedData(3, true))); |
| 306 | 308 |
| 307 QuicSpdyServerStreamPeer::SendErrorResponse(stream_); | 309 QuicSimpleServerStreamPeer::SendErrorResponse(stream_); |
| 308 EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_)); | 310 EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_)); |
| 309 EXPECT_TRUE(stream_->reading_stopped()); | 311 EXPECT_TRUE(stream_->reading_stopped()); |
| 310 EXPECT_TRUE(stream_->write_side_closed()); | 312 EXPECT_TRUE(stream_->write_side_closed()); |
| 311 } | 313 } |
| 312 | 314 |
| 313 TEST_P(QuicSpdyServerStreamTest, InvalidMultipleContentLength) { | 315 TEST_P(QuicSimpleServerStreamTest, InvalidMultipleContentLength) { |
| 314 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); | 316 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); |
| 315 | 317 |
| 316 SpdyHeaderBlock request_headers; | 318 SpdyHeaderBlock request_headers; |
| 317 // \000 is a way to write the null byte when followed by a literal digit. | 319 // \000 is a way to write the null byte when followed by a literal digit. |
| 318 request_headers["content-length"] = StringPiece("11\00012", 5); | 320 request_headers["content-length"] = StringPiece("11\00012", 5); |
| 319 | 321 |
| 320 headers_string_ = SpdyUtils::SerializeUncompressedHeaders(request_headers); | 322 headers_string_ = SpdyUtils::SerializeUncompressedHeaders(request_headers); |
| 321 | 323 |
| 322 EXPECT_CALL(session_, WriteHeaders(_, _, _, _, _)); | 324 EXPECT_CALL(session_, WriteHeaders(_, _, _, _, _)); |
| 323 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) | 325 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
| 324 .Times(AnyNumber()) | 326 .Times(AnyNumber()) |
| 325 .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData)); | 327 .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData)); |
| 326 stream_->OnStreamHeaders(headers_string_); | 328 stream_->OnStreamHeaders(headers_string_); |
| 327 stream_->OnStreamHeadersComplete(true, headers_string_.size()); | 329 stream_->OnStreamHeadersComplete(true, headers_string_.size()); |
| 328 | 330 |
| 329 EXPECT_TRUE(ReliableQuicStreamPeer::read_side_closed(stream_)); | 331 EXPECT_TRUE(ReliableQuicStreamPeer::read_side_closed(stream_)); |
| 330 EXPECT_TRUE(stream_->reading_stopped()); | 332 EXPECT_TRUE(stream_->reading_stopped()); |
| 331 EXPECT_TRUE(stream_->write_side_closed()); | 333 EXPECT_TRUE(stream_->write_side_closed()); |
| 332 } | 334 } |
| 333 | 335 |
| 334 TEST_P(QuicSpdyServerStreamTest, InvalidLeadingNullContentLength) { | 336 TEST_P(QuicSimpleServerStreamTest, InvalidLeadingNullContentLength) { |
| 335 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); | 337 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); |
| 336 | 338 |
| 337 SpdyHeaderBlock request_headers; | 339 SpdyHeaderBlock request_headers; |
| 338 // \000 is a way to write the null byte when followed by a literal digit. | 340 // \000 is a way to write the null byte when followed by a literal digit. |
| 339 request_headers["content-length"] = StringPiece("\00012", 3); | 341 request_headers["content-length"] = StringPiece("\00012", 3); |
| 340 | 342 |
| 341 headers_string_ = SpdyUtils::SerializeUncompressedHeaders(request_headers); | 343 headers_string_ = SpdyUtils::SerializeUncompressedHeaders(request_headers); |
| 342 | 344 |
| 343 EXPECT_CALL(session_, WriteHeaders(_, _, _, _, _)); | 345 EXPECT_CALL(session_, WriteHeaders(_, _, _, _, _)); |
| 344 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) | 346 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
| 345 .Times(AnyNumber()) | 347 .Times(AnyNumber()) |
| 346 .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData)); | 348 .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData)); |
| 347 stream_->OnStreamHeaders(headers_string_); | 349 stream_->OnStreamHeaders(headers_string_); |
| 348 stream_->OnStreamHeadersComplete(true, headers_string_.size()); | 350 stream_->OnStreamHeadersComplete(true, headers_string_.size()); |
| 349 | 351 |
| 350 EXPECT_TRUE(ReliableQuicStreamPeer::read_side_closed(stream_)); | 352 EXPECT_TRUE(ReliableQuicStreamPeer::read_side_closed(stream_)); |
| 351 EXPECT_TRUE(stream_->reading_stopped()); | 353 EXPECT_TRUE(stream_->reading_stopped()); |
| 352 EXPECT_TRUE(stream_->write_side_closed()); | 354 EXPECT_TRUE(stream_->write_side_closed()); |
| 353 } | 355 } |
| 354 | 356 |
| 355 TEST_P(QuicSpdyServerStreamTest, ValidMultipleContentLength) { | 357 TEST_P(QuicSimpleServerStreamTest, ValidMultipleContentLength) { |
| 356 SpdyHeaderBlock request_headers; | 358 SpdyHeaderBlock request_headers; |
| 357 // \000 is a way to write the null byte when followed by a literal digit. | 359 // \000 is a way to write the null byte when followed by a literal digit. |
| 358 request_headers["content-length"] = StringPiece("11\00011", 5); | 360 request_headers["content-length"] = StringPiece("11\00011", 5); |
| 359 | 361 |
| 360 headers_string_ = SpdyUtils::SerializeUncompressedHeaders(request_headers); | 362 headers_string_ = SpdyUtils::SerializeUncompressedHeaders(request_headers); |
| 361 | 363 |
| 362 stream_->OnStreamHeaders(headers_string_); | 364 stream_->OnStreamHeaders(headers_string_); |
| 363 stream_->OnStreamHeadersComplete(false, headers_string_.size()); | 365 stream_->OnStreamHeadersComplete(false, headers_string_.size()); |
| 364 | 366 |
| 365 EXPECT_EQ(11, QuicSpdyServerStreamPeer::content_length(stream_)); | 367 EXPECT_EQ(11, QuicSimpleServerStreamPeer::content_length(stream_)); |
| 366 EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_)); | 368 EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_)); |
| 367 EXPECT_FALSE(stream_->reading_stopped()); | 369 EXPECT_FALSE(stream_->reading_stopped()); |
| 368 EXPECT_FALSE(stream_->write_side_closed()); | 370 EXPECT_FALSE(stream_->write_side_closed()); |
| 369 } | 371 } |
| 370 | 372 |
| 371 TEST_P(QuicSpdyServerStreamTest, SendQuicRstStreamNoErrorWithEarlyResponse) { | 373 TEST_P(QuicSimpleServerStreamTest, SendQuicRstStreamNoErrorWithEarlyResponse) { |
| 372 response_headers_[":version"] = "HTTP/1.1"; | 374 response_headers_[":version"] = "HTTP/1.1"; |
| 373 response_headers_[":status"] = "500 Server Error"; | 375 response_headers_[":status"] = "500 Server Error"; |
| 374 response_headers_["content-length"] = "3"; | 376 response_headers_["content-length"] = "3"; |
| 375 | 377 |
| 376 InSequence s; | 378 InSequence s; |
| 377 EXPECT_CALL(session_, WriteHeaders(stream_->id(), _, _, _, _)); | 379 EXPECT_CALL(session_, WriteHeaders(stream_->id(), _, _, _, _)); |
| 378 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) | 380 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
| 379 .Times(1) | 381 .Times(1) |
| 380 .WillOnce(Return(QuicConsumedData(3, true))); | 382 .WillOnce(Return(QuicConsumedData(3, true))); |
| 381 if (GetParam() > QUIC_VERSION_28) { | 383 if (GetParam() > QUIC_VERSION_28) { |
| 382 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(1); | 384 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(1); |
| 383 } else { | 385 } else { |
| 384 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); | 386 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); |
| 385 } | 387 } |
| 386 EXPECT_FALSE(stream_->fin_received()); | 388 EXPECT_FALSE(stream_->fin_received()); |
| 387 QuicSpdyServerStreamPeer::SendErrorResponse(stream_); | 389 QuicSimpleServerStreamPeer::SendErrorResponse(stream_); |
| 388 EXPECT_TRUE(stream_->reading_stopped()); | 390 EXPECT_TRUE(stream_->reading_stopped()); |
| 389 EXPECT_TRUE(stream_->write_side_closed()); | 391 EXPECT_TRUE(stream_->write_side_closed()); |
| 390 } | 392 } |
| 391 | 393 |
| 392 TEST_P(QuicSpdyServerStreamTest, DoNotSendQuicRstStreamNoErrorWithRstReceived) { | 394 TEST_P(QuicSimpleServerStreamTest, |
| 395 DoNotSendQuicRstStreamNoErrorWithRstReceived) { |
| 393 response_headers_[":version"] = "HTTP/1.1"; | 396 response_headers_[":version"] = "HTTP/1.1"; |
| 394 response_headers_[":status"] = "500 Server Error"; | 397 response_headers_[":status"] = "500 Server Error"; |
| 395 response_headers_["content-length"] = "3"; | 398 response_headers_["content-length"] = "3"; |
| 396 | 399 |
| 397 InSequence s; | 400 InSequence s; |
| 398 EXPECT_FALSE(stream_->reading_stopped()); | 401 EXPECT_FALSE(stream_->reading_stopped()); |
| 399 | 402 |
| 400 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); | 403 EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0); |
| 401 EXPECT_CALL(session_, SendRstStream(_, QUIC_RST_ACKNOWLEDGEMENT, _)).Times(1); | 404 EXPECT_CALL(session_, SendRstStream(_, QUIC_RST_ACKNOWLEDGEMENT, _)).Times(1); |
| 402 QuicRstStreamFrame rst_frame(stream_->id(), QUIC_STREAM_CANCELLED, 1234); | 405 QuicRstStreamFrame rst_frame(stream_->id(), QUIC_STREAM_CANCELLED, 1234); |
| 403 stream_->OnStreamReset(rst_frame); | 406 stream_->OnStreamReset(rst_frame); |
| 404 | 407 |
| 405 EXPECT_TRUE(stream_->reading_stopped()); | 408 EXPECT_TRUE(stream_->reading_stopped()); |
| 406 EXPECT_TRUE(stream_->write_side_closed()); | 409 EXPECT_TRUE(stream_->write_side_closed()); |
| 407 } | 410 } |
| 408 | 411 |
| 409 TEST_P(QuicSpdyServerStreamTest, InvalidHeadersWithFin) { | 412 TEST_P(QuicSimpleServerStreamTest, InvalidHeadersWithFin) { |
| 410 char arr[] = { | 413 char arr[] = { |
| 411 0x3a, 0x68, 0x6f, 0x73, // :hos | 414 0x3a, 0x68, 0x6f, 0x73, // :hos |
| 412 0x74, 0x00, 0x00, 0x00, // t... | 415 0x74, 0x00, 0x00, 0x00, // t... |
| 413 0x00, 0x00, 0x00, 0x00, // .... | 416 0x00, 0x00, 0x00, 0x00, // .... |
| 414 0x07, 0x3a, 0x6d, 0x65, // .:me | 417 0x07, 0x3a, 0x6d, 0x65, // .:me |
| 415 0x74, 0x68, 0x6f, 0x64, // thod | 418 0x74, 0x68, 0x6f, 0x64, // thod |
| 416 0x00, 0x00, 0x00, 0x03, // .... | 419 0x00, 0x00, 0x00, 0x03, // .... |
| 417 0x47, 0x45, 0x54, 0x00, // GET. | 420 0x47, 0x45, 0x54, 0x00, // GET. |
| 418 0x00, 0x00, 0x05, 0x3a, // ...: | 421 0x00, 0x00, 0x05, 0x3a, // ...: |
| 419 0x70, 0x61, 0x74, 0x68, // path | 422 0x70, 0x61, 0x74, 0x68, // path |
| 420 0x00, 0x00, 0x00, 0x04, // .... | 423 0x00, 0x00, 0x00, 0x04, // .... |
| 421 0x2f, 0x66, 0x6f, 0x6f, // /foo | 424 0x2f, 0x66, 0x6f, 0x6f, // /foo |
| 422 0x00, 0x00, 0x00, 0x07, // .... | 425 0x00, 0x00, 0x00, 0x07, // .... |
| 423 0x3a, 0x73, 0x63, 0x68, // :sch | 426 0x3a, 0x73, 0x63, 0x68, // :sch |
| 424 0x65, 0x6d, 0x65, 0x00, // eme. | 427 0x65, 0x6d, 0x65, 0x00, // eme. |
| 425 0x00, 0x00, 0x00, 0x00, // .... | 428 0x00, 0x00, 0x00, 0x00, // .... |
| 426 0x00, 0x00, 0x08, 0x3a, // ...: | 429 0x00, 0x00, 0x08, 0x3a, // ...: |
| 427 0x76, 0x65, 0x72, 0x73, // vers | 430 0x76, 0x65, 0x72, 0x73, // vers |
| 428 '\x96', 0x6f, 0x6e, 0x00, // <i(69)>on. | 431 '\x96', 0x6f, 0x6e, 0x00, // <i(69)>on. |
| 429 0x00, 0x00, 0x08, 0x48, // ...H | 432 0x00, 0x00, 0x08, 0x48, // ...H |
| 430 0x54, 0x54, 0x50, 0x2f, // TTP/ | 433 0x54, 0x54, 0x50, 0x2f, // TTP/ |
| 431 0x31, 0x2e, 0x31, // 1.1 | 434 0x31, 0x2e, 0x31, // 1.1 |
| 432 }; | 435 }; |
| 433 StringPiece data(arr, arraysize(arr)); | 436 StringPiece data(arr, arraysize(arr)); |
| 434 QuicStreamFrame frame(stream_->id(), true, 0, data); | 437 QuicStreamFrame frame(stream_->id(), true, 0, data); |
| 435 // Verify that we don't crash when we get a invalid headers in stream frame. | 438 // Verify that we don't crash when we get a invalid headers in stream frame. |
| 436 stream_->OnStreamFrame(frame); | 439 stream_->OnStreamFrame(frame); |
| 437 } | 440 } |
| 438 | 441 |
| 439 } // namespace | 442 } // namespace |
| 440 } // namespace test | 443 } // namespace test |
| 441 } // namespace tools | 444 } // namespace tools |
| 442 } // namespace net | 445 } // namespace net |
| OLD | NEW |