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 |