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 "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 SpdyStream::~SpdyStream() { | 115 SpdyStream::~SpdyStream() { |
116 CHECK(!write_handler_guard_); | 116 CHECK(!write_handler_guard_); |
117 UpdateHistograms(); | 117 UpdateHistograms(); |
118 } | 118 } |
119 | 119 |
120 void SpdyStream::SetDelegate(Delegate* delegate) { | 120 void SpdyStream::SetDelegate(Delegate* delegate) { |
121 CHECK(!delegate_); | 121 CHECK(!delegate_); |
122 CHECK(delegate); | 122 CHECK(delegate); |
123 delegate_ = delegate; | 123 delegate_ = delegate; |
124 | 124 |
125 // TODO(baranovich): allow STATE_RESERVED_REMOTE when push promises will be | |
126 // implemented. | |
127 CHECK(io_state_ == STATE_IDLE || | 125 CHECK(io_state_ == STATE_IDLE || |
128 io_state_ == STATE_HALF_CLOSED_LOCAL_UNCLAIMED); | 126 io_state_ == STATE_HALF_CLOSED_LOCAL_UNCLAIMED || |
| 127 io_state_ == STATE_RESERVED_REMOTE); |
129 | 128 |
130 if (io_state_ == STATE_HALF_CLOSED_LOCAL_UNCLAIMED) { | 129 if (io_state_ == STATE_HALF_CLOSED_LOCAL_UNCLAIMED) { |
131 DCHECK_EQ(type_, SPDY_PUSH_STREAM); | 130 DCHECK_EQ(type_, SPDY_PUSH_STREAM); |
132 base::MessageLoop::current()->PostTask( | 131 base::MessageLoop::current()->PostTask( |
133 FROM_HERE, | 132 FROM_HERE, |
134 base::Bind(&SpdyStream::PushedStreamReplay, GetWeakPtr())); | 133 base::Bind(&SpdyStream::PushedStreamReplay, GetWeakPtr())); |
135 } | 134 } |
136 } | 135 } |
137 | 136 |
138 void SpdyStream::PushedStreamReplay() { | 137 void SpdyStream::PushedStreamReplay() { |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR, | 411 session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR, |
413 "Response received before request sent"); | 412 "Response received before request sent"); |
414 return ERR_SPDY_PROTOCOL_ERROR; | 413 return ERR_SPDY_PROTOCOL_ERROR; |
415 } | 414 } |
416 break; | 415 break; |
417 | 416 |
418 case SPDY_PUSH_STREAM: | 417 case SPDY_PUSH_STREAM: |
419 // Push streams transition to a locally half-closed state upon headers. | 418 // Push streams transition to a locally half-closed state upon headers. |
420 // We must continue to buffer data while waiting for a call to | 419 // We must continue to buffer data while waiting for a call to |
421 // SetDelegate() (which may not ever happen). | 420 // SetDelegate() (which may not ever happen). |
422 // TODO(baranovich): For HTTP 2 push streams, delegate may be set before | |
423 // receiving response headers when PUSH_PROMISE will be implemented. | |
424 // TODO(baranovich): In HTTP 2 additional HEADERS frames are not allowed. | |
425 // Set |response_headers_status_| to RESPONSE_HEADERS_ARE_COMPLETE. | |
426 CHECK_EQ(io_state_, STATE_RESERVED_REMOTE); | 421 CHECK_EQ(io_state_, STATE_RESERVED_REMOTE); |
427 DCHECK(!delegate_); | 422 if (!delegate_) { |
428 io_state_ = STATE_HALF_CLOSED_LOCAL_UNCLAIMED; | 423 io_state_ = STATE_HALF_CLOSED_LOCAL_UNCLAIMED; |
| 424 } else { |
| 425 io_state_ = STATE_HALF_CLOSED_LOCAL; |
| 426 } |
429 break; | 427 break; |
430 } | 428 } |
431 | 429 |
432 metrics_.StartStream(); | 430 metrics_.StartStream(); |
433 | 431 |
434 DCHECK_NE(io_state_, STATE_IDLE); | 432 DCHECK_NE(io_state_, STATE_IDLE); |
435 | 433 |
436 response_time_ = response_time; | 434 response_time_ = response_time; |
437 recv_first_byte_time_ = recv_first_byte_time; | 435 recv_first_byte_time_ = recv_first_byte_time; |
438 return MergeWithResponseHeaders(initial_response_headers); | 436 return MergeWithResponseHeaders(initial_response_headers); |
439 } | 437 } |
440 | 438 |
441 int SpdyStream::OnAdditionalResponseHeadersReceived( | 439 int SpdyStream::OnAdditionalResponseHeadersReceived( |
442 const SpdyHeaderBlock& additional_response_headers) { | 440 const SpdyHeaderBlock& additional_response_headers) { |
443 if (type_ == SPDY_REQUEST_RESPONSE_STREAM) { | 441 if (type_ == SPDY_REQUEST_RESPONSE_STREAM) { |
444 session_->ResetStream( | 442 session_->ResetStream( |
445 stream_id_, RST_STREAM_PROTOCOL_ERROR, | 443 stream_id_, RST_STREAM_PROTOCOL_ERROR, |
446 "Additional headers received for request/response stream"); | 444 "Additional headers received for request/response stream"); |
447 return ERR_SPDY_PROTOCOL_ERROR; | 445 return ERR_SPDY_PROTOCOL_ERROR; |
448 } else if (type_ == SPDY_PUSH_STREAM && | 446 } else if (type_ == SPDY_PUSH_STREAM && |
449 response_headers_status_ == RESPONSE_HEADERS_ARE_COMPLETE) { | 447 response_headers_status_ == RESPONSE_HEADERS_ARE_COMPLETE) { |
450 session_->ResetStream( | 448 session_->ResetStream( |
451 stream_id_, RST_STREAM_PROTOCOL_ERROR, | 449 stream_id_, RST_STREAM_PROTOCOL_ERROR, |
452 "Additional headers received for push stream"); | 450 "Additional headers received for push stream"); |
453 return ERR_SPDY_PROTOCOL_ERROR; | 451 return ERR_SPDY_PROTOCOL_ERROR; |
454 } | 452 } |
455 return MergeWithResponseHeaders(additional_response_headers); | 453 return MergeWithResponseHeaders(additional_response_headers); |
456 } | 454 } |
457 | 455 |
458 int SpdyStream::OnPushPromiseHeadersReceived(const SpdyHeaderBlock& headers) { | 456 void SpdyStream::OnPushPromiseHeadersReceived(const SpdyHeaderBlock& headers) { |
459 CHECK(!request_headers_.get()); | 457 CHECK(!request_headers_.get()); |
460 CHECK_EQ(io_state_, STATE_IDLE); | 458 CHECK_EQ(io_state_, STATE_IDLE); |
461 CHECK_EQ(type_, SPDY_PUSH_STREAM); | 459 CHECK_EQ(type_, SPDY_PUSH_STREAM); |
462 DCHECK(!delegate_); | 460 DCHECK(!delegate_); |
463 | 461 |
464 io_state_ = STATE_RESERVED_REMOTE; | 462 io_state_ = STATE_RESERVED_REMOTE; |
465 request_headers_.reset(new SpdyHeaderBlock(headers)); | 463 request_headers_.reset(new SpdyHeaderBlock(headers)); |
466 return OK; | |
467 } | 464 } |
468 | 465 |
469 void SpdyStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { | 466 void SpdyStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { |
470 DCHECK(session_->IsStreamActive(stream_id_)); | 467 DCHECK(session_->IsStreamActive(stream_id_)); |
471 | 468 |
472 // If we're still buffering data for a push stream, we will do the | 469 // If we're still buffering data for a push stream, we will do the |
473 // check for data received with incomplete headers in | 470 // check for data received with incomplete headers in |
474 // PushedStreamReplayData(). | 471 // PushedStreamReplayData(). |
475 if (io_state_ == STATE_HALF_CLOSED_LOCAL_UNCLAIMED) { | 472 if (io_state_ == STATE_HALF_CLOSED_LOCAL_UNCLAIMED) { |
476 DCHECK_EQ(type_, SPDY_PUSH_STREAM); | 473 DCHECK_EQ(type_, SPDY_PUSH_STREAM); |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 } | 723 } |
727 | 724 |
728 bool SpdyStream::IsIdle() const { | 725 bool SpdyStream::IsIdle() const { |
729 return io_state_ == STATE_IDLE; | 726 return io_state_ == STATE_IDLE; |
730 } | 727 } |
731 | 728 |
732 bool SpdyStream::IsOpen() const { | 729 bool SpdyStream::IsOpen() const { |
733 return io_state_ == STATE_OPEN; | 730 return io_state_ == STATE_OPEN; |
734 } | 731 } |
735 | 732 |
| 733 bool SpdyStream::IsReservedRemote() const { |
| 734 return io_state_ == STATE_RESERVED_REMOTE; |
| 735 } |
| 736 |
736 NextProto SpdyStream::GetProtocol() const { | 737 NextProto SpdyStream::GetProtocol() const { |
737 return session_->protocol(); | 738 return session_->protocol(); |
738 } | 739 } |
739 | 740 |
740 bool SpdyStream::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const { | 741 bool SpdyStream::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const { |
741 if (stream_id_ == 0) | 742 if (stream_id_ == 0) |
742 return false; | 743 return false; |
743 | 744 |
744 return session_->GetLoadTimingInfo(stream_id_, load_timing_info); | 745 return session_->GetLoadTimingInfo(stream_id_, load_timing_info); |
745 } | 746 } |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
902 description = base::StringPrintf("Unknown state 0x%08X (%u)", state, | 903 description = base::StringPrintf("Unknown state 0x%08X (%u)", state, |
903 state); | 904 state); |
904 break; | 905 break; |
905 } | 906 } |
906 return description; | 907 return description; |
907 } | 908 } |
908 | 909 |
909 #undef STATE_CASE | 910 #undef STATE_CASE |
910 | 911 |
911 } // namespace net | 912 } // namespace net |
OLD | NEW |