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/quic/quic_spdy_stream.h" | 5 #include "net/quic/quic_spdy_stream.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "net/quic/quic_bug_tracker.h" | 9 #include "net/quic/quic_bug_tracker.h" |
10 #include "net/quic/quic_spdy_session.h" | 10 #include "net/quic/quic_spdy_session.h" |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 } | 176 } |
177 | 177 |
178 void QuicSpdyStream::OnStreamHeadersComplete(bool fin, size_t frame_len) { | 178 void QuicSpdyStream::OnStreamHeadersComplete(bool fin, size_t frame_len) { |
179 if (!headers_decompressed_) { | 179 if (!headers_decompressed_) { |
180 OnInitialHeadersComplete(fin, frame_len); | 180 OnInitialHeadersComplete(fin, frame_len); |
181 } else { | 181 } else { |
182 OnTrailingHeadersComplete(fin, frame_len); | 182 OnTrailingHeadersComplete(fin, frame_len); |
183 } | 183 } |
184 } | 184 } |
185 | 185 |
| 186 void QuicSpdyStream::OnStreamHeaderList(bool fin, |
| 187 size_t frame_len, |
| 188 const QuicHeaderList& header_list) { |
| 189 if (!headers_decompressed_) { |
| 190 OnInitialHeadersComplete(fin, frame_len, header_list); |
| 191 } else { |
| 192 OnTrailingHeadersComplete(fin, frame_len, header_list); |
| 193 } |
| 194 } |
| 195 |
186 void QuicSpdyStream::OnInitialHeadersComplete(bool fin, size_t /*frame_len*/) { | 196 void QuicSpdyStream::OnInitialHeadersComplete(bool fin, size_t /*frame_len*/) { |
187 headers_decompressed_ = true; | 197 headers_decompressed_ = true; |
188 if (fin) { | 198 if (fin) { |
189 OnStreamFrame(QuicStreamFrame(id(), fin, 0, StringPiece())); | 199 OnStreamFrame(QuicStreamFrame(id(), fin, 0, StringPiece())); |
190 } | 200 } |
191 if (FinishedReadingHeaders()) { | 201 if (FinishedReadingHeaders()) { |
192 sequencer()->SetUnblocked(); | 202 sequencer()->SetUnblocked(); |
193 } | 203 } |
194 } | 204 } |
195 | 205 |
| 206 void QuicSpdyStream::OnInitialHeadersComplete( |
| 207 bool fin, |
| 208 size_t /*frame_len*/, |
| 209 const QuicHeaderList& header_list) { |
| 210 headers_decompressed_ = true; |
| 211 header_list_ = header_list; |
| 212 if (fin) { |
| 213 OnStreamFrame(QuicStreamFrame(id(), fin, 0, StringPiece())); |
| 214 } |
| 215 if (FinishedReadingHeaders()) { |
| 216 sequencer()->SetUnblocked(); |
| 217 } |
| 218 } |
| 219 |
196 void QuicSpdyStream::OnPromiseHeaders(StringPiece headers_data) { | 220 void QuicSpdyStream::OnPromiseHeaders(StringPiece headers_data) { |
197 headers_data.AppendToString(&decompressed_headers_); | 221 headers_data.AppendToString(&decompressed_headers_); |
198 } | 222 } |
199 | 223 |
200 void QuicSpdyStream::OnPromiseHeadersComplete( | 224 void QuicSpdyStream::OnPromiseHeadersComplete( |
201 QuicStreamId /* promised_stream_id */, | 225 QuicStreamId /* promised_stream_id */, |
202 size_t /* frame_len */) { | 226 size_t /* frame_len */) { |
203 // To be overridden in QuicSpdyClientStream. Not supported on | 227 // To be overridden in QuicSpdyClientStream. Not supported on |
204 // server side. | 228 // server side. |
205 session()->connection()->CloseConnection( | 229 session()->connection()->CloseConnection( |
206 QUIC_INVALID_HEADERS_STREAM_DATA, "Promise headers received by server", | 230 QUIC_INVALID_HEADERS_STREAM_DATA, "Promise headers received by server", |
207 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); | 231 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); |
208 return; | 232 return; |
209 } | 233 } |
210 | 234 |
| 235 void QuicSpdyStream::OnPromiseHeaderList( |
| 236 QuicStreamId /* promised_id */, |
| 237 size_t /* frame_len */, |
| 238 const QuicHeaderList& /*header_list */) { |
| 239 // To be overridden in QuicSpdyClientStream. Not supported on |
| 240 // server side. |
| 241 session()->connection()->CloseConnection( |
| 242 QUIC_INVALID_HEADERS_STREAM_DATA, "Promise headers received by server", |
| 243 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); |
| 244 return; |
| 245 } |
| 246 |
211 void QuicSpdyStream::OnTrailingHeadersComplete(bool fin, size_t /*frame_len*/) { | 247 void QuicSpdyStream::OnTrailingHeadersComplete(bool fin, size_t /*frame_len*/) { |
212 DCHECK(!trailers_decompressed_); | 248 DCHECK(!trailers_decompressed_); |
213 if (fin_received()) { | 249 if (fin_received()) { |
214 DLOG(ERROR) << "Received Trailers after FIN, on stream: " << id(); | 250 DLOG(ERROR) << "Received Trailers after FIN, on stream: " << id(); |
215 session()->connection()->CloseConnection( | 251 session()->connection()->CloseConnection( |
216 QUIC_INVALID_HEADERS_STREAM_DATA, "Trailers after fin", | 252 QUIC_INVALID_HEADERS_STREAM_DATA, "Trailers after fin", |
217 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); | 253 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); |
218 return; | 254 return; |
219 } | 255 } |
220 if (!fin) { | 256 if (!fin) { |
(...skipping 17 matching lines...) Expand all Loading... |
238 } | 274 } |
239 | 275 |
240 // The data on this stream ends at |final_byte_offset|. | 276 // The data on this stream ends at |final_byte_offset|. |
241 DVLOG(1) << "Stream ends at byte offset: " << final_byte_offset | 277 DVLOG(1) << "Stream ends at byte offset: " << final_byte_offset |
242 << " currently read: " << stream_bytes_read(); | 278 << " currently read: " << stream_bytes_read(); |
243 | 279 |
244 OnStreamFrame(QuicStreamFrame(id(), fin, final_byte_offset, StringPiece())); | 280 OnStreamFrame(QuicStreamFrame(id(), fin, final_byte_offset, StringPiece())); |
245 trailers_decompressed_ = true; | 281 trailers_decompressed_ = true; |
246 } | 282 } |
247 | 283 |
| 284 void QuicSpdyStream::OnTrailingHeadersComplete( |
| 285 bool fin, |
| 286 size_t /*frame_len*/, |
| 287 const QuicHeaderList& header_list) { |
| 288 DCHECK(!trailers_decompressed_); |
| 289 if (fin_received()) { |
| 290 DLOG(ERROR) << "Received Trailers after FIN, on stream: " << id(); |
| 291 session()->connection()->CloseConnection( |
| 292 QUIC_INVALID_HEADERS_STREAM_DATA, "Trailers after fin", |
| 293 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); |
| 294 return; |
| 295 } |
| 296 if (!fin) { |
| 297 DLOG(ERROR) << "Trailers must have FIN set, on stream: " << id(); |
| 298 session()->connection()->CloseConnection( |
| 299 QUIC_INVALID_HEADERS_STREAM_DATA, "Fin missing from trailers", |
| 300 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); |
| 301 return; |
| 302 } |
| 303 |
| 304 size_t final_byte_offset = 0; |
| 305 if (!SpdyUtils::CopyAndValidateTrailers(header_list, &final_byte_offset, |
| 306 &received_trailers_)) { |
| 307 DLOG(ERROR) << "Trailers are malformed: " << id(); |
| 308 session()->connection()->CloseConnection( |
| 309 QUIC_INVALID_HEADERS_STREAM_DATA, "Trailers are malformed", |
| 310 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); |
| 311 return; |
| 312 } |
| 313 OnStreamFrame(QuicStreamFrame(id(), fin, final_byte_offset, StringPiece())); |
| 314 trailers_decompressed_ = true; |
| 315 } |
| 316 |
248 void QuicSpdyStream::OnStreamReset(const QuicRstStreamFrame& frame) { | 317 void QuicSpdyStream::OnStreamReset(const QuicRstStreamFrame& frame) { |
249 if (frame.error_code != QUIC_STREAM_NO_ERROR || | 318 if (frame.error_code != QUIC_STREAM_NO_ERROR || |
250 version() <= QUIC_VERSION_28) { | 319 version() <= QUIC_VERSION_28) { |
251 ReliableQuicStream::OnStreamReset(frame); | 320 ReliableQuicStream::OnStreamReset(frame); |
252 return; | 321 return; |
253 } | 322 } |
254 DVLOG(1) << "Received QUIC_STREAM_NO_ERROR, not discarding response"; | 323 DVLOG(1) << "Received QUIC_STREAM_NO_ERROR, not discarding response"; |
255 set_rst_received(true); | 324 set_rst_received(true); |
256 MaybeIncreaseHighestReceivedOffset(frame.byte_offset); | 325 MaybeIncreaseHighestReceivedOffset(frame.byte_offset); |
257 set_stream_error(frame.error_code); | 326 set_stream_error(frame.error_code); |
258 CloseWriteSide(); | 327 CloseWriteSide(); |
259 } | 328 } |
260 | 329 |
261 void QuicSpdyStream::OnClose() { | 330 void QuicSpdyStream::OnClose() { |
262 ReliableQuicStream::OnClose(); | 331 ReliableQuicStream::OnClose(); |
263 | 332 |
264 if (visitor_) { | 333 if (visitor_) { |
265 Visitor* visitor = visitor_; | 334 Visitor* visitor = visitor_; |
266 // Calling Visitor::OnClose() may result the destruction of the visitor, | 335 // Calling Visitor::OnClose() may result the destruction of the visitor, |
267 // so we need to ensure we don't call it again. | 336 // so we need to ensure we don't call it again. |
268 visitor_ = nullptr; | 337 visitor_ = nullptr; |
269 visitor->OnClose(this); | 338 visitor->OnClose(this); |
270 } | 339 } |
271 } | 340 } |
272 | 341 |
273 bool QuicSpdyStream::FinishedReadingHeaders() const { | 342 bool QuicSpdyStream::FinishedReadingHeaders() const { |
274 return headers_decompressed_ && decompressed_headers_.empty(); | 343 return headers_decompressed_ && decompressed_headers_.empty() && |
| 344 header_list_.empty(); |
275 } | 345 } |
276 | 346 |
277 bool QuicSpdyStream::ParseHeaderStatusCode(SpdyHeaderBlock* header, | 347 bool QuicSpdyStream::ParseHeaderStatusCode(SpdyHeaderBlock* header, |
278 int* status_code) const { | 348 int* status_code) const { |
279 StringPiece status = (*header)[":status"]; | 349 StringPiece status = (*header)[":status"]; |
280 if (status.size() != 3) { | 350 if (status.size() != 3) { |
281 return false; | 351 return false; |
282 } | 352 } |
283 // First character must be an integer in range [1,5]. | 353 // First character must be an integer in range [1,5]. |
284 if (status[0] < '1' || status[0] > '5') { | 354 if (status[0] < '1' || status[0] > '5') { |
(...skipping 10 matching lines...) Expand all Loading... |
295 // If no further trailing headers are expected, and the decompressed trailers | 365 // If no further trailing headers are expected, and the decompressed trailers |
296 // (if any) have been consumed, then reading of trailers is finished. | 366 // (if any) have been consumed, then reading of trailers is finished. |
297 bool no_more_trailers = fin_received() || trailers_decompressed_; | 367 bool no_more_trailers = fin_received() || trailers_decompressed_; |
298 return no_more_trailers && decompressed_trailers_.empty(); | 368 return no_more_trailers && decompressed_trailers_.empty(); |
299 } | 369 } |
300 | 370 |
301 SpdyPriority QuicSpdyStream::priority() const { | 371 SpdyPriority QuicSpdyStream::priority() const { |
302 return priority_; | 372 return priority_; |
303 } | 373 } |
304 } // namespace net | 374 } // namespace net |
OLD | NEW |