Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/spdy/spdy_stream.h" | 5 #include "net/spdy/spdy_stream.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
| 12 #include "base/location.h" | 12 #include "base/location.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/metrics/histogram_macros.h" | 14 #include "base/metrics/histogram_macros.h" |
| 15 #include "base/single_thread_task_runner.h" | 15 #include "base/single_thread_task_runner.h" |
| 16 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
| 17 #include "base/strings/string_piece.h" | |
| 17 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
| 18 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
| 19 #include "base/threading/thread_task_runner_handle.h" | 20 #include "base/threading/thread_task_runner_handle.h" |
| 20 #include "base/values.h" | 21 #include "base/values.h" |
| 21 #include "net/log/net_log.h" | 22 #include "net/log/net_log.h" |
| 22 #include "net/log/net_log_capture_mode.h" | 23 #include "net/log/net_log_capture_mode.h" |
| 23 #include "net/log/net_log_event_type.h" | 24 #include "net/log/net_log_event_type.h" |
| 24 #include "net/spdy/spdy_buffer_producer.h" | 25 #include "net/spdy/spdy_buffer_producer.h" |
| 25 #include "net/spdy/spdy_http_utils.h" | 26 #include "net/spdy/spdy_http_utils.h" |
| 26 #include "net/spdy/spdy_session.h" | 27 #include "net/spdy/spdy_session.h" |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 372 } | 373 } |
| 373 | 374 |
| 374 void SpdyStream::OnHeadersReceived(const SpdyHeaderBlock& response_headers, | 375 void SpdyStream::OnHeadersReceived(const SpdyHeaderBlock& response_headers, |
| 375 base::Time response_time, | 376 base::Time response_time, |
| 376 base::TimeTicks recv_first_byte_time) { | 377 base::TimeTicks recv_first_byte_time) { |
| 377 switch (response_state_) { | 378 switch (response_state_) { |
| 378 case READY_FOR_HEADERS: | 379 case READY_FOR_HEADERS: |
| 379 // No header block has been received yet. | 380 // No header block has been received yet. |
| 380 DCHECK(response_headers_.empty()); | 381 DCHECK(response_headers_.empty()); |
| 381 | 382 |
| 382 if (response_headers.find(":status") == response_headers.end()) { | 383 { |
| 383 const std::string error("Response headers do not include :status."); | 384 SpdyHeaderBlock::const_iterator it = response_headers.find(":status"); |
| 384 LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error); | 385 if (it == response_headers.end()) { |
| 385 session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR, error); | 386 const std::string error("Response headers do not include :status."); |
| 386 return; | 387 LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error); |
| 388 session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR, error); | |
| 389 return; | |
| 390 } | |
| 391 | |
| 392 int status; | |
| 393 if (!StringToInt(it->second, &status)) { | |
| 394 const std::string error("Cannot parse :status."); | |
|
Ryan Hamilton
2016/12/06 20:02:18
I wonder if there are any servers spitting out old
Bence
2016/12/06 20:10:13
No, we do not. That's why our unittests producing
Ryan Hamilton
2016/12/06 23:48:14
So if there are servers out there which return "20
Bence
2016/12/07 00:22:12
That is correct, and this is a functional change i
| |
| 395 LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error); | |
| 396 session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR, error); | |
| 397 return; | |
| 398 } | |
| 399 | |
| 400 // Ignore informational headers. | |
| 401 // TODO(bnc): Add support for 103 Early Hints, https://crbug.com/671310. | |
| 402 if (status / 100 == 1) { | |
| 403 return; | |
| 404 } | |
| 387 } | 405 } |
|
Ryan Hamilton
2016/12/06 20:02:18
This is surprisingly clean. nice.
| |
| 388 | 406 |
| 389 response_state_ = READY_FOR_DATA_OR_TRAILERS; | 407 response_state_ = READY_FOR_DATA_OR_TRAILERS; |
| 390 | 408 |
| 391 switch (type_) { | 409 switch (type_) { |
| 392 case SPDY_BIDIRECTIONAL_STREAM: | 410 case SPDY_BIDIRECTIONAL_STREAM: |
| 393 case SPDY_REQUEST_RESPONSE_STREAM: | 411 case SPDY_REQUEST_RESPONSE_STREAM: |
| 394 // A bidirectional stream or a request/response stream is ready for | 412 // A bidirectional stream or a request/response stream is ready for |
| 395 // the response headers only after request headers are sent. | 413 // the response headers only after request headers are sent. |
| 396 if (io_state_ == STATE_IDLE) { | 414 if (io_state_ == STATE_IDLE) { |
| 397 const std::string error("Response received before request sent."); | 415 const std::string error("Response received before request sent."); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 433 | 451 |
| 434 response_state_ = TRAILERS_RECEIVED; | 452 response_state_ = TRAILERS_RECEIVED; |
| 435 delegate_->OnTrailers(response_headers); | 453 delegate_->OnTrailers(response_headers); |
| 436 break; | 454 break; |
| 437 | 455 |
| 438 case TRAILERS_RECEIVED: | 456 case TRAILERS_RECEIVED: |
| 439 // No further header blocks are allowed after trailers. | 457 // No further header blocks are allowed after trailers. |
| 440 const std::string error("Header block received after trailers."); | 458 const std::string error("Header block received after trailers."); |
| 441 LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error); | 459 LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error); |
| 442 session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR, error); | 460 session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR, error); |
| 443 return; | 461 break; |
| 444 } | 462 } |
| 445 } | 463 } |
| 446 | 464 |
| 447 void SpdyStream::OnPushPromiseHeadersReceived(SpdyHeaderBlock headers) { | 465 void SpdyStream::OnPushPromiseHeadersReceived(SpdyHeaderBlock headers) { |
| 448 CHECK(!request_headers_valid_); | 466 CHECK(!request_headers_valid_); |
| 449 CHECK_EQ(io_state_, STATE_IDLE); | 467 CHECK_EQ(io_state_, STATE_IDLE); |
| 450 CHECK_EQ(type_, SPDY_PUSH_STREAM); | 468 CHECK_EQ(type_, SPDY_PUSH_STREAM); |
| 451 DCHECK(!delegate_); | 469 DCHECK(!delegate_); |
| 452 | 470 |
| 453 io_state_ = STATE_RESERVED_REMOTE; | 471 io_state_ = STATE_RESERVED_REMOTE; |
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 883 description = base::StringPrintf("Unknown state 0x%08X (%u)", state, | 901 description = base::StringPrintf("Unknown state 0x%08X (%u)", state, |
| 884 state); | 902 state); |
| 885 break; | 903 break; |
| 886 } | 904 } |
| 887 return description; | 905 return description; |
| 888 } | 906 } |
| 889 | 907 |
| 890 #undef STATE_CASE | 908 #undef STATE_CASE |
| 891 | 909 |
| 892 } // namespace net | 910 } // namespace net |
| OLD | NEW |