| 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 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 void SpdyStream::PushedStreamReplayData() { | 137 void SpdyStream::PushedStreamReplayData() { |
| 138 DCHECK_NE(stream_id_, 0u); | 138 DCHECK_NE(stream_id_, 0u); |
| 139 | 139 |
| 140 if (!delegate_) | 140 if (!delegate_) |
| 141 return; | 141 return; |
| 142 | 142 |
| 143 continue_buffering_data_ = false; | 143 continue_buffering_data_ = false; |
| 144 | 144 |
| 145 // TODO(akalin): This call may delete this object. Figure out what | 145 // TODO(akalin): This call may delete this object. Figure out what |
| 146 // to do in that case. | 146 // to do in that case. |
| 147 int rv = delegate_->OnResponseReceived(*response_, response_time_, OK); | 147 int rv = delegate_->OnResponseHeadersReceived(*response_, response_time_, OK); |
| 148 if (rv == ERR_INCOMPLETE_SPDY_HEADERS) { | 148 if (rv == ERR_INCOMPLETE_SPDY_HEADERS) { |
| 149 // We don't have complete headers. Assume we're waiting for another | 149 // We don't have complete headers. Assume we're waiting for another |
| 150 // HEADERS frame. Since we don't have headers, we had better not have | 150 // HEADERS frame. Since we don't have headers, we had better not have |
| 151 // any pending data frames. | 151 // any pending data frames. |
| 152 if (pending_buffers_.size() != 0U) { | 152 if (pending_buffers_.size() != 0U) { |
| 153 LogStreamError(ERR_SPDY_PROTOCOL_ERROR, | 153 LogStreamError(ERR_SPDY_PROTOCOL_ERROR, |
| 154 "HEADERS incomplete headers, but pending data frames."); | 154 "HEADERS incomplete headers, but pending data frames."); |
| 155 session_->CloseActiveStream(stream_id_, ERR_SPDY_PROTOCOL_ERROR); | 155 session_->CloseActiveStream(stream_id_, ERR_SPDY_PROTOCOL_ERROR); |
| 156 } | 156 } |
| 157 return; | 157 return; |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 } | 361 } |
| 362 | 362 |
| 363 base::Time SpdyStream::GetRequestTime() const { | 363 base::Time SpdyStream::GetRequestTime() const { |
| 364 return request_time_; | 364 return request_time_; |
| 365 } | 365 } |
| 366 | 366 |
| 367 void SpdyStream::SetRequestTime(base::Time t) { | 367 void SpdyStream::SetRequestTime(base::Time t) { |
| 368 request_time_ = t; | 368 request_time_ = t; |
| 369 } | 369 } |
| 370 | 370 |
| 371 int SpdyStream::OnResponseReceived(const SpdyHeaderBlock& response) { | 371 int SpdyStream::OnResponseHeadersReceived(const SpdyHeaderBlock& response) { |
| 372 int rv = OK; | 372 int rv = OK; |
| 373 | 373 |
| 374 metrics_.StartStream(); | 374 metrics_.StartStream(); |
| 375 | 375 |
| 376 DCHECK(response_->empty()); | 376 DCHECK(response_->empty()); |
| 377 *response_ = response; // TODO(ukai): avoid copy. | 377 *response_ = response; // TODO(ukai): avoid copy. |
| 378 | 378 |
| 379 recv_first_byte_time_ = base::TimeTicks::Now(); | 379 recv_first_byte_time_ = base::TimeTicks::Now(); |
| 380 response_time_ = base::Time::Now(); | 380 response_time_ = base::Time::Now(); |
| 381 | 381 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 399 } | 399 } |
| 400 | 400 |
| 401 if ((*response_).find("transfer-encoding") != (*response_).end()) { | 401 if ((*response_).find("transfer-encoding") != (*response_).end()) { |
| 402 session_->ResetStream(stream_id_, priority_, RST_STREAM_PROTOCOL_ERROR, | 402 session_->ResetStream(stream_id_, priority_, RST_STREAM_PROTOCOL_ERROR, |
| 403 "Received transfer-encoding header"); | 403 "Received transfer-encoding header"); |
| 404 return ERR_SPDY_PROTOCOL_ERROR; | 404 return ERR_SPDY_PROTOCOL_ERROR; |
| 405 } | 405 } |
| 406 | 406 |
| 407 if (delegate_) { | 407 if (delegate_) { |
| 408 // May delete this object. | 408 // May delete this object. |
| 409 rv = delegate_->OnResponseReceived(*response_, response_time_, rv); | 409 rv = delegate_->OnResponseHeadersReceived(*response_, response_time_, rv); |
| 410 } | 410 } |
| 411 // If delegate_ is not yet attached, we'll call OnResponseReceived after the | 411 // If delegate_ is not yet attached, we'll call |
| 412 // delegate gets attached to the stream. | 412 // OnResponseHeadersReceived after the delegate gets attached to the |
| 413 // stream. |
| 413 | 414 |
| 414 return rv; | 415 return rv; |
| 415 } | 416 } |
| 416 | 417 |
| 417 int SpdyStream::OnHeaders(const SpdyHeaderBlock& headers) { | 418 int SpdyStream::OnHeaders(const SpdyHeaderBlock& headers) { |
| 418 DCHECK(!response_->empty()); | 419 DCHECK(!response_->empty()); |
| 419 | 420 |
| 420 // Append all the headers into the response header block. | 421 // Append all the headers into the response header block. |
| 421 for (SpdyHeaderBlock::const_iterator it = headers.begin(); | 422 for (SpdyHeaderBlock::const_iterator it = headers.begin(); |
| 422 it != headers.end(); ++it) { | 423 it != headers.end(); ++it) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 439 | 440 |
| 440 if ((*response_).find("transfer-encoding") != (*response_).end()) { | 441 if ((*response_).find("transfer-encoding") != (*response_).end()) { |
| 441 session_->ResetStream(stream_id_, priority_, RST_STREAM_PROTOCOL_ERROR, | 442 session_->ResetStream(stream_id_, priority_, RST_STREAM_PROTOCOL_ERROR, |
| 442 "Received transfer-encoding header"); | 443 "Received transfer-encoding header"); |
| 443 return ERR_SPDY_PROTOCOL_ERROR; | 444 return ERR_SPDY_PROTOCOL_ERROR; |
| 444 } | 445 } |
| 445 | 446 |
| 446 int rv = OK; | 447 int rv = OK; |
| 447 if (delegate_) { | 448 if (delegate_) { |
| 448 // May delete this object. | 449 // May delete this object. |
| 449 rv = delegate_->OnResponseReceived(*response_, response_time_, rv); | 450 rv = delegate_->OnResponseHeadersReceived(*response_, response_time_, rv); |
| 450 // ERR_INCOMPLETE_SPDY_HEADERS means that we are waiting for more | 451 // ERR_INCOMPLETE_SPDY_HEADERS means that we are waiting for more |
| 451 // headers before the response header block is complete. | 452 // headers before the response header block is complete. |
| 452 if (rv == ERR_INCOMPLETE_SPDY_HEADERS) | 453 if (rv == ERR_INCOMPLETE_SPDY_HEADERS) |
| 453 rv = OK; | 454 rv = OK; |
| 454 } | 455 } |
| 455 return rv; | 456 return rv; |
| 456 } | 457 } |
| 457 | 458 |
| 458 void SpdyStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { | 459 void SpdyStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { |
| 459 DCHECK(session_->IsStreamActive(stream_id_)); | 460 DCHECK(session_->IsStreamActive(stream_id_)); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 CHECK_EQ(send_status_, MORE_DATA_TO_SEND); | 570 CHECK_EQ(send_status_, MORE_DATA_TO_SEND); |
| 570 CHECK(!request_); | 571 CHECK(!request_); |
| 571 CHECK(!pending_send_data_); | 572 CHECK(!pending_send_data_); |
| 572 CHECK_EQ(io_state_, STATE_NONE); | 573 CHECK_EQ(io_state_, STATE_NONE); |
| 573 request_ = headers.Pass(); | 574 request_ = headers.Pass(); |
| 574 send_status_ = send_status; | 575 send_status_ = send_status; |
| 575 io_state_ = STATE_GET_DOMAIN_BOUND_CERT; | 576 io_state_ = STATE_GET_DOMAIN_BOUND_CERT; |
| 576 return DoLoop(OK); | 577 return DoLoop(OK); |
| 577 } | 578 } |
| 578 | 579 |
| 579 void SpdyStream::SendStreamData(IOBuffer* data, | 580 void SpdyStream::SendData(IOBuffer* data, |
| 580 int length, | 581 int length, |
| 581 SpdySendStatus send_status) { | 582 SpdySendStatus send_status) { |
| 582 CHECK_NE(type_, SPDY_PUSH_STREAM); | 583 CHECK_NE(type_, SPDY_PUSH_STREAM); |
| 583 CHECK_EQ(send_status_, MORE_DATA_TO_SEND); | 584 CHECK_EQ(send_status_, MORE_DATA_TO_SEND); |
| 584 CHECK_GE(io_state_, STATE_SEND_BODY); | 585 CHECK_GE(io_state_, STATE_SEND_BODY); |
| 585 CHECK(!pending_send_data_); | 586 CHECK(!pending_send_data_); |
| 586 pending_send_data_ = new DrainableIOBuffer(data, length); | 587 pending_send_data_ = new DrainableIOBuffer(data, length); |
| 587 send_status_ = send_status; | 588 send_status_ = send_status; |
| 588 QueueNextDataFrame(); | 589 QueueNextDataFrame(); |
| 589 } | 590 } |
| 590 | 591 |
| 591 bool SpdyStream::GetSSLInfo(SSLInfo* ssl_info, | 592 bool SpdyStream::GetSSLInfo(SSLInfo* ssl_info, |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 result = DoSendDomainBoundCertComplete(result); | 661 result = DoSendDomainBoundCertComplete(result); |
| 661 break; | 662 break; |
| 662 case STATE_SEND_REQUEST_HEADERS: | 663 case STATE_SEND_REQUEST_HEADERS: |
| 663 CHECK_EQ(result, OK); | 664 CHECK_EQ(result, OK); |
| 664 result = DoSendRequestHeaders(); | 665 result = DoSendRequestHeaders(); |
| 665 break; | 666 break; |
| 666 case STATE_SEND_REQUEST_HEADERS_COMPLETE: | 667 case STATE_SEND_REQUEST_HEADERS_COMPLETE: |
| 667 CHECK_EQ(result, OK); | 668 CHECK_EQ(result, OK); |
| 668 result = DoSendRequestHeadersComplete(); | 669 result = DoSendRequestHeadersComplete(); |
| 669 break; | 670 break; |
| 671 // TODO(akalin): Remove the states STATE_SEND_BODY through |
| 672 // STATE_WAITING_FOR_RESPONSE; we can infer correct behavior |
| 673 // from |type_| and |send_status_|. |
| 670 case STATE_SEND_BODY: | 674 case STATE_SEND_BODY: |
| 671 CHECK_EQ(result, OK); | 675 CHECK_EQ(result, OK); |
| 672 result = DoSendBody(); | 676 result = DoSendBody(); |
| 673 break; | 677 break; |
| 674 case STATE_SEND_BODY_COMPLETE: | 678 case STATE_SEND_BODY_COMPLETE: |
| 675 result = DoSendBodyComplete(result); | 679 result = DoSendBodyComplete(result); |
| 676 break; | 680 break; |
| 677 // This is an intermediary waiting state. This state is reached when all | 681 // This is an intermediary waiting state. This state is reached when all |
| 678 // data has been sent, but no data has been received. | 682 // data has been sent, but no data has been received. |
| 679 case STATE_WAITING_FOR_RESPONSE: | 683 case STATE_WAITING_FOR_RESPONSE: |
| 680 io_state_ = STATE_WAITING_FOR_RESPONSE; | 684 io_state_ = STATE_WAITING_FOR_RESPONSE; |
| 681 result = ERR_IO_PENDING; | 685 result = ERR_IO_PENDING; |
| 682 break; | 686 break; |
| 683 // State machine 2: connection is established. | 687 // State machine 2: connection is established. |
| 684 // In STATE_OPEN, OnResponseReceived has already been called. | 688 // In STATE_OPEN, OnResponseHeadersReceived has already been called. |
| 685 // OnDataReceived, OnClose and OnFrameWriteComplete can be called. | 689 // OnDataReceived, OnClose and OnFrameWriteComplete can be called. |
| 686 // Only OnFrameWriteComplete calls DoLoop(). | 690 // Only OnFrameWriteComplete calls DoLoop(). |
| 687 // | 691 // |
| 688 // For HTTP streams, no data is sent from the client while in the OPEN | 692 // For HTTP streams, no data is sent from the client while in the OPEN |
| 689 // state, so OnFrameWriteComplete is never called here. The HTTP body is | 693 // state, so OnFrameWriteComplete is never called here. The HTTP body is |
| 690 // handled in the OnDataReceived callback, which does not call into | 694 // handled in the OnDataReceived callback, which does not call into |
| 691 // DoLoop. | 695 // DoLoop. |
| 692 // | 696 // |
| 693 // For WebSocket streams, which are bi-directional, we'll send and | 697 // For WebSocket streams, which are bi-directional, we'll send and |
| 694 // receive data once the connection is established. Received data is | 698 // receive data once the connection is established. Received data is |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 809 return ERR_IO_PENDING; | 813 return ERR_IO_PENDING; |
| 810 } | 814 } |
| 811 | 815 |
| 812 int SpdyStream::DoSendRequestHeadersComplete() { | 816 int SpdyStream::DoSendRequestHeadersComplete() { |
| 813 DCHECK_NE(type_, SPDY_PUSH_STREAM); | 817 DCHECK_NE(type_, SPDY_PUSH_STREAM); |
| 814 DCHECK_EQ(just_completed_frame_type_, SYN_STREAM); | 818 DCHECK_EQ(just_completed_frame_type_, SYN_STREAM); |
| 815 DCHECK_NE(stream_id_, 0u); | 819 DCHECK_NE(stream_id_, 0u); |
| 816 if (!delegate_) | 820 if (!delegate_) |
| 817 return ERR_UNEXPECTED; | 821 return ERR_UNEXPECTED; |
| 818 | 822 |
| 819 delegate_->OnSendRequestHeadersComplete(); | |
| 820 | |
| 821 switch (type_) { | 823 switch (type_) { |
| 822 case SPDY_BIDIRECTIONAL_STREAM: | 824 case SPDY_BIDIRECTIONAL_STREAM: |
| 823 DCHECK_EQ(send_status_, MORE_DATA_TO_SEND); | 825 DCHECK_EQ(send_status_, MORE_DATA_TO_SEND); |
| 824 io_state_ = STATE_WAITING_FOR_RESPONSE; | 826 io_state_ = STATE_WAITING_FOR_RESPONSE; |
| 825 break; | 827 break; |
| 826 | 828 |
| 827 case SPDY_REQUEST_RESPONSE_STREAM: | 829 case SPDY_REQUEST_RESPONSE_STREAM: |
| 828 io_state_ = | 830 io_state_ = |
| 829 (send_status_ == MORE_DATA_TO_SEND) ? | 831 (send_status_ == MORE_DATA_TO_SEND) ? |
| 830 STATE_SEND_BODY : STATE_WAITING_FOR_RESPONSE; | 832 STATE_SEND_BODY : STATE_WAITING_FOR_RESPONSE; |
| 831 break; | 833 break; |
| 832 | 834 |
| 833 case SPDY_PUSH_STREAM: | 835 case SPDY_PUSH_STREAM: |
| 834 // Fall through. | 836 // Fall through. |
| 835 default: | 837 default: |
| 836 NOTREACHED(); | 838 NOTREACHED(); |
| 837 return ERR_UNEXPECTED; | 839 return ERR_UNEXPECTED; |
| 838 } | 840 } |
| 839 | 841 |
| 842 delegate_->OnRequestHeadersSent(); |
| 843 |
| 840 return OK; | 844 return OK; |
| 841 } | 845 } |
| 842 | 846 |
| 843 // DoSendBody is called to send the optional body for the request. This call | 847 // DoSendBody is called to send the optional body for the request. This call |
| 844 // will also be called as each write of a chunk of the body completes. | 848 // will also be called as each write of a chunk of the body completes. |
| 845 int SpdyStream::DoSendBody() { | 849 int SpdyStream::DoSendBody() { |
| 846 DCHECK_NE(type_, SPDY_PUSH_STREAM); | 850 DCHECK_NE(type_, SPDY_PUSH_STREAM); |
| 847 io_state_ = STATE_SEND_BODY_COMPLETE; | 851 io_state_ = STATE_SEND_BODY_COMPLETE; |
| 848 CHECK(delegate_); | |
| 849 delegate_->OnSendBody(); | |
| 850 return ERR_IO_PENDING; | 852 return ERR_IO_PENDING; |
| 851 } | 853 } |
| 852 | 854 |
| 853 int SpdyStream::DoSendBodyComplete(int result) { | 855 int SpdyStream::DoSendBodyComplete(int result) { |
| 854 DCHECK_NE(type_, SPDY_PUSH_STREAM); | 856 DCHECK_NE(type_, SPDY_PUSH_STREAM); |
| 855 result = ProcessJustCompletedFrame(result, STATE_SEND_BODY_COMPLETE); | 857 result = ProcessJustCompletedFrame(result, STATE_SEND_BODY_COMPLETE); |
| 856 | 858 |
| 857 if (result != OK) | 859 if (result != OK) |
| 858 return result; | 860 return result; |
| 859 | 861 |
| 860 delegate_->OnSendBodyComplete(); | |
| 861 | |
| 862 io_state_ = | 862 io_state_ = |
| 863 (send_status_ == MORE_DATA_TO_SEND) ? | 863 (send_status_ == MORE_DATA_TO_SEND) ? |
| 864 STATE_SEND_BODY : STATE_WAITING_FOR_RESPONSE; | 864 STATE_SEND_BODY : STATE_WAITING_FOR_RESPONSE; |
| 865 | 865 |
| 866 delegate_->OnDataSent(); |
| 867 |
| 866 return OK; | 868 return OK; |
| 867 } | 869 } |
| 868 | 870 |
| 869 int SpdyStream::DoOpen() { | 871 int SpdyStream::DoOpen() { |
| 870 int result = ProcessJustCompletedFrame(OK, STATE_OPEN); | 872 int result = ProcessJustCompletedFrame(OK, STATE_OPEN); |
| 871 | 873 |
| 872 if (result != OK) | 874 if (result != OK) |
| 873 return result; | 875 return result; |
| 874 | 876 |
| 875 // Set |io_state_| first as |delegate_| may check it. | 877 // Set |io_state_| first as |delegate_| may check it. |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 984 GetWeakPtr(), payload_size)); | 986 GetWeakPtr(), payload_size)); |
| 985 } | 987 } |
| 986 | 988 |
| 987 session_->EnqueueStreamWrite( | 989 session_->EnqueueStreamWrite( |
| 988 GetWeakPtr(), DATA, | 990 GetWeakPtr(), DATA, |
| 989 scoped_ptr<SpdyBufferProducer>( | 991 scoped_ptr<SpdyBufferProducer>( |
| 990 new SimpleBufferProducer(data_buffer.Pass()))); | 992 new SimpleBufferProducer(data_buffer.Pass()))); |
| 991 } | 993 } |
| 992 | 994 |
| 993 } // namespace net | 995 } // namespace net |
| OLD | NEW |