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 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 71 } | 71 } |
| 72 DCHECK_GT(stream_->stream_id(), 0u); | 72 DCHECK_GT(stream_->stream_id(), 0u); |
| 73 return scoped_ptr<SpdyBuffer>( | 73 return scoped_ptr<SpdyBuffer>( |
| 74 new SpdyBuffer(stream_->ProduceSynStreamFrame())); | 74 new SpdyBuffer(stream_->ProduceSynStreamFrame())); |
| 75 } | 75 } |
| 76 | 76 |
| 77 private: | 77 private: |
| 78 const base::WeakPtr<SpdyStream> stream_; | 78 const base::WeakPtr<SpdyStream> stream_; |
| 79 }; | 79 }; |
| 80 | 80 |
| 81 SpdyStream::SpdyStream(SpdySession* session, | 81 SpdyStream::SpdyStream(SpdyStreamType type, |
| 82 SpdySession* session, | |
| 82 const std::string& path, | 83 const std::string& path, |
| 83 RequestPriority priority, | 84 RequestPriority priority, |
| 84 int32 initial_send_window_size, | 85 int32 initial_send_window_size, |
| 85 int32 initial_recv_window_size, | 86 int32 initial_recv_window_size, |
| 86 bool pushed, | |
| 87 const BoundNetLog& net_log) | 87 const BoundNetLog& net_log) |
| 88 : weak_ptr_factory_(this), | 88 : type_(type), |
| 89 weak_ptr_factory_(this), | |
| 89 in_do_loop_(false), | 90 in_do_loop_(false), |
| 90 continue_buffering_data_(true), | 91 continue_buffering_data_(true), |
| 91 stream_id_(0), | 92 stream_id_(0), |
| 92 path_(path), | 93 path_(path), |
| 93 priority_(priority), | 94 priority_(priority), |
| 94 slot_(0), | 95 slot_(0), |
| 95 send_stalled_by_flow_control_(false), | 96 send_stalled_by_flow_control_(false), |
| 96 send_window_size_(initial_send_window_size), | 97 send_window_size_(initial_send_window_size), |
| 97 recv_window_size_(initial_recv_window_size), | 98 recv_window_size_(initial_recv_window_size), |
| 98 unacked_recv_window_bytes_(0), | 99 unacked_recv_window_bytes_(0), |
| 99 pushed_(pushed), | |
| 100 response_received_(false), | 100 response_received_(false), |
| 101 session_(session), | 101 session_(session), |
| 102 delegate_(NULL), | 102 delegate_(NULL), |
| 103 send_status_(MORE_DATA_TO_SEND), | 103 send_status_( |
| 104 (type_ == SPDY_PUSH_STREAM) ? | |
| 105 NO_MORE_DATA_TO_SEND : MORE_DATA_TO_SEND), | |
| 104 request_time_(base::Time::Now()), | 106 request_time_(base::Time::Now()), |
| 105 response_(new SpdyHeaderBlock), | 107 response_(new SpdyHeaderBlock), |
| 106 io_state_(STATE_NONE), | 108 io_state_(STATE_NONE), |
| 107 response_status_(OK), | 109 response_status_(OK), |
| 108 net_log_(net_log), | 110 net_log_(net_log), |
| 109 send_bytes_(0), | 111 send_bytes_(0), |
| 110 recv_bytes_(0), | 112 recv_bytes_(0), |
| 111 domain_bound_cert_type_(CLIENT_CERT_INVALID_TYPE), | 113 domain_bound_cert_type_(CLIENT_CERT_INVALID_TYPE), |
| 112 just_completed_frame_type_(DATA), | 114 just_completed_frame_type_(DATA), |
| 113 just_completed_frame_size_(0) { | 115 just_completed_frame_size_(0) { |
| 114 } | 116 } |
| 115 | 117 |
| 116 SpdyStream::~SpdyStream() { | 118 SpdyStream::~SpdyStream() { |
| 117 CHECK(!in_do_loop_); | 119 CHECK(!in_do_loop_); |
| 118 UpdateHistograms(); | 120 UpdateHistograms(); |
| 119 } | 121 } |
| 120 | 122 |
| 121 void SpdyStream::SetDelegate(Delegate* delegate) { | 123 void SpdyStream::SetDelegate(Delegate* delegate) { |
| 122 CHECK(delegate); | 124 CHECK(delegate); |
| 123 delegate_ = delegate; | 125 delegate_ = delegate; |
| 124 | 126 |
| 125 if (pushed_) { | 127 if (type_ == SPDY_PUSH_STREAM) { |
| 126 CHECK(response_received()); | 128 CHECK(response_received()); |
| 127 base::MessageLoop::current()->PostTask( | 129 base::MessageLoop::current()->PostTask( |
| 128 FROM_HERE, | 130 FROM_HERE, |
| 129 base::Bind(&SpdyStream::PushedStreamReplayData, GetWeakPtr())); | 131 base::Bind(&SpdyStream::PushedStreamReplayData, GetWeakPtr())); |
| 130 } else { | 132 } else { |
| 131 continue_buffering_data_ = false; | 133 continue_buffering_data_ = false; |
| 132 } | 134 } |
| 133 } | 135 } |
| 134 | 136 |
| 135 void SpdyStream::PushedStreamReplayData() { | 137 void SpdyStream::PushedStreamReplayData() { |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 372 metrics_.StartStream(); | 374 metrics_.StartStream(); |
| 373 | 375 |
| 374 DCHECK(response_->empty()); | 376 DCHECK(response_->empty()); |
| 375 *response_ = response; // TODO(ukai): avoid copy. | 377 *response_ = response; // TODO(ukai): avoid copy. |
| 376 | 378 |
| 377 recv_first_byte_time_ = base::TimeTicks::Now(); | 379 recv_first_byte_time_ = base::TimeTicks::Now(); |
| 378 response_time_ = base::Time::Now(); | 380 response_time_ = base::Time::Now(); |
| 379 | 381 |
| 380 // If we receive a response before we are in STATE_WAITING_FOR_RESPONSE, then | 382 // If we receive a response before we are in STATE_WAITING_FOR_RESPONSE, then |
| 381 // the server has sent the SYN_REPLY too early. | 383 // the server has sent the SYN_REPLY too early. |
| 382 if (!pushed_ && io_state_ != STATE_WAITING_FOR_RESPONSE) | 384 if (type_ != SPDY_PUSH_STREAM && io_state_ != STATE_WAITING_FOR_RESPONSE) |
| 383 return ERR_SPDY_PROTOCOL_ERROR; | 385 return ERR_SPDY_PROTOCOL_ERROR; |
| 384 if (pushed_) | 386 if (type_ == SPDY_PUSH_STREAM) |
| 385 CHECK_EQ(io_state_, STATE_NONE); | 387 CHECK_EQ(io_state_, STATE_NONE); |
| 386 io_state_ = STATE_OPEN; | 388 io_state_ = STATE_OPEN; |
| 387 | 389 |
| 388 // Append all the headers into the response header block. | 390 // Append all the headers into the response header block. |
| 389 for (SpdyHeaderBlock::const_iterator it = response.begin(); | 391 for (SpdyHeaderBlock::const_iterator it = response.begin(); |
| 390 it != response.end(); ++it) { | 392 it != response.end(); ++it) { |
| 391 // Disallow uppercase headers. | 393 // Disallow uppercase headers. |
| 392 if (ContainsUpperAscii(it->first)) { | 394 if (ContainsUpperAscii(it->first)) { |
| 393 session_->ResetStream(stream_id_, priority_, RST_STREAM_PROTOCOL_ERROR, | 395 session_->ResetStream(stream_id_, priority_, RST_STREAM_PROTOCOL_ERROR, |
| 394 "Upper case characters in header: " + it->first); | 396 "Upper case characters in header: " + it->first); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 556 CHECK(!in_do_loop_); | 558 CHECK(!in_do_loop_); |
| 557 if (stream_id_ != 0) { | 559 if (stream_id_ != 0) { |
| 558 session_->CloseActiveStream(stream_id_, OK); | 560 session_->CloseActiveStream(stream_id_, OK); |
| 559 } else { | 561 } else { |
| 560 session_->CloseCreatedStream(GetWeakPtr(), OK); | 562 session_->CloseCreatedStream(GetWeakPtr(), OK); |
| 561 } | 563 } |
| 562 } | 564 } |
| 563 | 565 |
| 564 int SpdyStream::SendRequestHeaders(scoped_ptr<SpdyHeaderBlock> headers, | 566 int SpdyStream::SendRequestHeaders(scoped_ptr<SpdyHeaderBlock> headers, |
| 565 SpdySendStatus send_status) { | 567 SpdySendStatus send_status) { |
| 568 CHECK_NE(type_, SPDY_PUSH_STREAM); | |
| 566 CHECK_EQ(send_status_, MORE_DATA_TO_SEND); | 569 CHECK_EQ(send_status_, MORE_DATA_TO_SEND); |
| 567 CHECK(!request_); | 570 CHECK(!request_); |
| 571 CHECK(!pending_send_data_); | |
| 572 CHECK_EQ(io_state_, STATE_NONE); | |
| 568 request_ = headers.Pass(); | 573 request_ = headers.Pass(); |
| 569 // Pushed streams do not send any data, and should always be | |
| 570 // idle. However, we still want to return IO_PENDING to mimic | |
| 571 // non-push behavior. | |
| 572 send_status_ = send_status; | 574 send_status_ = send_status; |
| 573 if (pushed_) { | |
| 574 DCHECK(is_idle()); | |
| 575 DCHECK_EQ(send_status_, NO_MORE_DATA_TO_SEND); | |
| 576 DCHECK(response_received()); | |
| 577 send_time_ = base::TimeTicks::Now(); | |
| 578 return ERR_IO_PENDING; | |
| 579 } | |
| 580 CHECK_EQ(STATE_NONE, io_state_); | |
| 581 io_state_ = STATE_GET_DOMAIN_BOUND_CERT; | 575 io_state_ = STATE_GET_DOMAIN_BOUND_CERT; |
| 582 return DoLoop(OK); | 576 return DoLoop(OK); |
| 583 } | 577 } |
| 584 | 578 |
| 585 void SpdyStream::SendStreamData(IOBuffer* data, | 579 void SpdyStream::SendStreamData(IOBuffer* data, |
| 586 int length, | 580 int length, |
| 587 SpdySendStatus send_status) { | 581 SpdySendStatus send_status) { |
| 582 CHECK_NE(type_, SPDY_PUSH_STREAM); | |
| 588 CHECK_EQ(send_status_, MORE_DATA_TO_SEND); | 583 CHECK_EQ(send_status_, MORE_DATA_TO_SEND); |
| 584 CHECK_GE(io_state_, STATE_SEND_BODY); | |
| 589 CHECK(!pending_send_data_); | 585 CHECK(!pending_send_data_); |
| 590 pending_send_data_ = new DrainableIOBuffer(data, length); | 586 pending_send_data_ = new DrainableIOBuffer(data, length); |
| 591 send_status_ = send_status; | 587 send_status_ = send_status; |
| 592 QueueNextDataFrame(); | 588 QueueNextDataFrame(); |
| 593 } | 589 } |
| 594 | 590 |
| 595 bool SpdyStream::GetSSLInfo(SSLInfo* ssl_info, | 591 bool SpdyStream::GetSSLInfo(SSLInfo* ssl_info, |
| 596 bool* was_npn_negotiated, | 592 bool* was_npn_negotiated, |
| 597 NextProto* protocol_negotiated) { | 593 NextProto* protocol_negotiated) { |
| 598 return session_->GetSSLInfo( | 594 return session_->GetSSLInfo( |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 614 send_stalled_by_flow_control_ = false; | 610 send_stalled_by_flow_control_ = false; |
| 615 QueueNextDataFrame(); | 611 QueueNextDataFrame(); |
| 616 } | 612 } |
| 617 } | 613 } |
| 618 | 614 |
| 619 base::WeakPtr<SpdyStream> SpdyStream::GetWeakPtr() { | 615 base::WeakPtr<SpdyStream> SpdyStream::GetWeakPtr() { |
| 620 return weak_ptr_factory_.GetWeakPtr(); | 616 return weak_ptr_factory_.GetWeakPtr(); |
| 621 } | 617 } |
| 622 | 618 |
| 623 bool SpdyStream::HasUrl() const { | 619 bool SpdyStream::HasUrl() const { |
| 624 if (pushed_) | 620 if (type_ == SPDY_PUSH_STREAM) |
| 625 return response_received(); | 621 return response_received(); |
| 626 return request_.get() != NULL; | 622 return request_.get() != NULL; |
| 627 } | 623 } |
| 628 | 624 |
| 629 GURL SpdyStream::GetUrl() const { | 625 GURL SpdyStream::GetUrl() const { |
| 630 DCHECK(HasUrl()); | 626 DCHECK(HasUrl()); |
| 631 | 627 |
| 632 const SpdyHeaderBlock& headers = (pushed_) ? *response_ : *request_; | 628 const SpdyHeaderBlock& headers = |
| 633 return GetUrlFromHeaderBlock(headers, GetProtocolVersion(), pushed_); | 629 (type_ == SPDY_PUSH_STREAM) ? *response_ : *request_; |
| 630 return GetUrlFromHeaderBlock(headers, GetProtocolVersion(), | |
| 631 type_ == SPDY_PUSH_STREAM); | |
| 634 } | 632 } |
| 635 | 633 |
| 636 void SpdyStream::OnGetDomainBoundCertComplete(int result) { | 634 void SpdyStream::OnGetDomainBoundCertComplete(int result) { |
| 637 DCHECK_EQ(STATE_GET_DOMAIN_BOUND_CERT_COMPLETE, io_state_); | 635 DCHECK_EQ(io_state_, STATE_GET_DOMAIN_BOUND_CERT_COMPLETE); |
| 638 DoLoop(result); | 636 DoLoop(result); |
| 639 } | 637 } |
| 640 | 638 |
| 641 int SpdyStream::DoLoop(int result) { | 639 int SpdyStream::DoLoop(int result) { |
| 642 CHECK(!in_do_loop_); | 640 CHECK(!in_do_loop_); |
| 643 in_do_loop_ = true; | 641 in_do_loop_ = true; |
| 644 | 642 |
| 645 do { | 643 do { |
| 646 State state = io_state_; | 644 State state = io_state_; |
| 647 io_state_ = STATE_NONE; | 645 io_state_ = STATE_NONE; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 712 io_state_ != STATE_OPEN); | 710 io_state_ != STATE_OPEN); |
| 713 | 711 |
| 714 CHECK(in_do_loop_); | 712 CHECK(in_do_loop_); |
| 715 in_do_loop_ = false; | 713 in_do_loop_ = false; |
| 716 | 714 |
| 717 return result; | 715 return result; |
| 718 } | 716 } |
| 719 | 717 |
| 720 int SpdyStream::DoGetDomainBoundCert() { | 718 int SpdyStream::DoGetDomainBoundCert() { |
| 721 CHECK(request_.get()); | 719 CHECK(request_.get()); |
| 720 DCHECK_NE(type_, SPDY_PUSH_STREAM); | |
| 722 GURL url = GetUrl(); | 721 GURL url = GetUrl(); |
| 723 if (!session_->NeedsCredentials() || pushed_ || !url.SchemeIs("https")) { | 722 if (!session_->NeedsCredentials() || !url.SchemeIs("https")) { |
|
akalin
2013/05/25 07:40:44
Note that I removed the pushed_ check here
| |
| 724 // Proceed directly to sending the request headers | 723 // Proceed directly to sending the request headers |
| 725 io_state_ = STATE_SEND_REQUEST_HEADERS; | 724 io_state_ = STATE_SEND_REQUEST_HEADERS; |
| 726 return OK; | 725 return OK; |
| 727 } | 726 } |
| 728 | 727 |
| 729 slot_ = session_->credential_state()->FindCredentialSlot(GetUrl()); | 728 slot_ = session_->credential_state()->FindCredentialSlot(GetUrl()); |
| 730 if (slot_ != SpdyCredentialState::kNoEntry) { | 729 if (slot_ != SpdyCredentialState::kNoEntry) { |
| 731 // Proceed directly to sending the request headers | 730 // Proceed directly to sending the request headers |
| 732 io_state_ = STATE_SEND_REQUEST_HEADERS; | 731 io_state_ = STATE_SEND_REQUEST_HEADERS; |
| 733 return OK; | 732 return OK; |
| 734 } | 733 } |
| 735 | 734 |
| 736 io_state_ = STATE_GET_DOMAIN_BOUND_CERT_COMPLETE; | 735 io_state_ = STATE_GET_DOMAIN_BOUND_CERT_COMPLETE; |
| 737 ServerBoundCertService* sbc_service = session_->GetServerBoundCertService(); | 736 ServerBoundCertService* sbc_service = session_->GetServerBoundCertService(); |
| 738 DCHECK(sbc_service != NULL); | 737 DCHECK(sbc_service != NULL); |
| 739 std::vector<uint8> requested_cert_types; | 738 std::vector<uint8> requested_cert_types; |
| 740 requested_cert_types.push_back(CLIENT_CERT_ECDSA_SIGN); | 739 requested_cert_types.push_back(CLIENT_CERT_ECDSA_SIGN); |
| 741 int rv = sbc_service->GetDomainBoundCert( | 740 int rv = sbc_service->GetDomainBoundCert( |
| 742 url.GetOrigin().host(), requested_cert_types, | 741 url.GetOrigin().host(), requested_cert_types, |
| 743 &domain_bound_cert_type_, &domain_bound_private_key_, &domain_bound_cert_, | 742 &domain_bound_cert_type_, &domain_bound_private_key_, &domain_bound_cert_, |
| 744 base::Bind(&SpdyStream::OnGetDomainBoundCertComplete, GetWeakPtr()), | 743 base::Bind(&SpdyStream::OnGetDomainBoundCertComplete, GetWeakPtr()), |
| 745 &domain_bound_cert_request_handle_); | 744 &domain_bound_cert_request_handle_); |
| 746 return rv; | 745 return rv; |
| 747 } | 746 } |
| 748 | 747 |
| 749 int SpdyStream::DoGetDomainBoundCertComplete(int result) { | 748 int SpdyStream::DoGetDomainBoundCertComplete(int result) { |
| 749 DCHECK_NE(type_, SPDY_PUSH_STREAM); | |
| 750 if (result != OK) | 750 if (result != OK) |
| 751 return result; | 751 return result; |
| 752 | 752 |
| 753 io_state_ = STATE_SEND_DOMAIN_BOUND_CERT; | 753 io_state_ = STATE_SEND_DOMAIN_BOUND_CERT; |
| 754 slot_ = session_->credential_state()->SetHasCredential(GetUrl()); | 754 slot_ = session_->credential_state()->SetHasCredential(GetUrl()); |
| 755 return OK; | 755 return OK; |
| 756 } | 756 } |
| 757 | 757 |
| 758 int SpdyStream::DoSendDomainBoundCert() { | 758 int SpdyStream::DoSendDomainBoundCert() { |
| 759 CHECK(request_.get()); | |
| 760 DCHECK_NE(type_, SPDY_PUSH_STREAM); | |
| 759 io_state_ = STATE_SEND_DOMAIN_BOUND_CERT_COMPLETE; | 761 io_state_ = STATE_SEND_DOMAIN_BOUND_CERT_COMPLETE; |
| 760 CHECK(request_.get()); | |
| 761 | 762 |
| 762 std::string origin = GetUrl().GetOrigin().spec(); | 763 std::string origin = GetUrl().GetOrigin().spec(); |
| 763 DCHECK(origin[origin.length() - 1] == '/'); | 764 DCHECK(origin[origin.length() - 1] == '/'); |
| 764 origin.erase(origin.length() - 1); // Trim trailing slash. | 765 origin.erase(origin.length() - 1); // Trim trailing slash. |
| 765 scoped_ptr<SpdyFrame> frame; | 766 scoped_ptr<SpdyFrame> frame; |
| 766 int rv = session_->CreateCredentialFrame( | 767 int rv = session_->CreateCredentialFrame( |
| 767 origin, domain_bound_cert_type_, domain_bound_private_key_, | 768 origin, domain_bound_cert_type_, domain_bound_private_key_, |
| 768 domain_bound_cert_, priority_, &frame); | 769 domain_bound_cert_, priority_, &frame); |
| 769 if (rv != OK) { | 770 if (rv != OK) { |
| 770 DCHECK_NE(rv, ERR_IO_PENDING); | 771 DCHECK_NE(rv, ERR_IO_PENDING); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 781 // the state machine appropriately. | 782 // the state machine appropriately. |
| 782 session_->EnqueueStreamWrite( | 783 session_->EnqueueStreamWrite( |
| 783 GetWeakPtr(), CREDENTIAL, | 784 GetWeakPtr(), CREDENTIAL, |
| 784 scoped_ptr<SpdyBufferProducer>( | 785 scoped_ptr<SpdyBufferProducer>( |
| 785 new SimpleBufferProducer( | 786 new SimpleBufferProducer( |
| 786 scoped_ptr<SpdyBuffer>(new SpdyBuffer(frame.Pass()))))); | 787 scoped_ptr<SpdyBuffer>(new SpdyBuffer(frame.Pass()))))); |
| 787 return ERR_IO_PENDING; | 788 return ERR_IO_PENDING; |
| 788 } | 789 } |
| 789 | 790 |
| 790 int SpdyStream::DoSendDomainBoundCertComplete(int result) { | 791 int SpdyStream::DoSendDomainBoundCertComplete(int result) { |
| 792 CHECK_NE(type_, SPDY_PUSH_STREAM); | |
| 791 if (result != OK) | 793 if (result != OK) |
| 792 return result; | 794 return result; |
| 793 | 795 |
| 794 DCHECK_EQ(just_completed_frame_type_, CREDENTIAL); | 796 DCHECK_EQ(just_completed_frame_type_, CREDENTIAL); |
| 795 io_state_ = STATE_SEND_REQUEST_HEADERS; | 797 io_state_ = STATE_SEND_REQUEST_HEADERS; |
| 796 return OK; | 798 return OK; |
| 797 } | 799 } |
| 798 | 800 |
| 799 int SpdyStream::DoSendRequestHeaders() { | 801 int SpdyStream::DoSendRequestHeaders() { |
| 802 DCHECK_NE(type_, SPDY_PUSH_STREAM); | |
| 800 io_state_ = STATE_SEND_REQUEST_HEADERS_COMPLETE; | 803 io_state_ = STATE_SEND_REQUEST_HEADERS_COMPLETE; |
| 801 | 804 |
| 802 session_->EnqueueStreamWrite( | 805 session_->EnqueueStreamWrite( |
| 803 GetWeakPtr(), SYN_STREAM, | 806 GetWeakPtr(), SYN_STREAM, |
| 804 scoped_ptr<SpdyBufferProducer>( | 807 scoped_ptr<SpdyBufferProducer>( |
| 805 new SynStreamBufferProducer(GetWeakPtr()))); | 808 new SynStreamBufferProducer(GetWeakPtr()))); |
| 806 return ERR_IO_PENDING; | 809 return ERR_IO_PENDING; |
| 807 } | 810 } |
| 808 | 811 |
| 809 int SpdyStream::DoSendRequestHeadersComplete() { | 812 int SpdyStream::DoSendRequestHeadersComplete() { |
| 813 DCHECK_NE(type_, SPDY_PUSH_STREAM); | |
| 810 DCHECK_EQ(just_completed_frame_type_, SYN_STREAM); | 814 DCHECK_EQ(just_completed_frame_type_, SYN_STREAM); |
| 811 DCHECK_NE(stream_id_, 0u); | 815 DCHECK_NE(stream_id_, 0u); |
| 812 if (!delegate_) | 816 if (!delegate_) |
| 813 return ERR_UNEXPECTED; | 817 return ERR_UNEXPECTED; |
| 814 | 818 |
| 815 // We don't store the return value in |send_status_|; see comments | 819 delegate_->OnSendRequestHeadersComplete(); |
| 816 // in spdy_stream.h for OnSendRequestHeadersComplete(). | |
| 817 SpdySendStatus send_status = delegate_->OnSendRequestHeadersComplete(); | |
| 818 | 820 |
| 819 io_state_ = | 821 switch (type_) { |
| 820 (send_status == MORE_DATA_TO_SEND) ? | 822 case SPDY_BIDIRECTIONAL_STREAM: |
| 821 STATE_SEND_BODY : STATE_WAITING_FOR_RESPONSE; | 823 DCHECK_EQ(send_status_, MORE_DATA_TO_SEND); |
| 824 io_state_ = STATE_WAITING_FOR_RESPONSE; | |
| 825 break; | |
| 826 | |
| 827 case SPDY_REQUEST_RESPONSE_STREAM: | |
| 828 io_state_ = | |
| 829 (send_status_ == MORE_DATA_TO_SEND) ? | |
| 830 STATE_SEND_BODY : STATE_WAITING_FOR_RESPONSE; | |
| 831 break; | |
| 832 | |
| 833 case SPDY_PUSH_STREAM: | |
| 834 // Fall through. | |
| 835 default: | |
| 836 NOTREACHED(); | |
| 837 return ERR_UNEXPECTED; | |
| 838 } | |
| 822 | 839 |
| 823 return OK; | 840 return OK; |
| 824 } | 841 } |
| 825 | 842 |
| 826 // DoSendBody is called to send the optional body for the request. This call | 843 // DoSendBody is called to send the optional body for the request. This call |
| 827 // will also be called as each write of a chunk of the body completes. | 844 // will also be called as each write of a chunk of the body completes. |
| 828 int SpdyStream::DoSendBody() { | 845 int SpdyStream::DoSendBody() { |
| 846 DCHECK_NE(type_, SPDY_PUSH_STREAM); | |
| 829 io_state_ = STATE_SEND_BODY_COMPLETE; | 847 io_state_ = STATE_SEND_BODY_COMPLETE; |
| 830 CHECK(delegate_); | 848 CHECK(delegate_); |
| 831 delegate_->OnSendBody(); | 849 delegate_->OnSendBody(); |
| 832 return ERR_IO_PENDING; | 850 return ERR_IO_PENDING; |
| 833 } | 851 } |
| 834 | 852 |
| 835 int SpdyStream::DoSendBodyComplete(int result) { | 853 int SpdyStream::DoSendBodyComplete(int result) { |
| 854 DCHECK_NE(type_, SPDY_PUSH_STREAM); | |
| 836 result = ProcessJustCompletedFrame(result, STATE_SEND_BODY_COMPLETE); | 855 result = ProcessJustCompletedFrame(result, STATE_SEND_BODY_COMPLETE); |
| 837 | 856 |
| 838 if (result != OK) | 857 if (result != OK) |
| 839 return result; | 858 return result; |
| 840 | 859 |
| 841 delegate_->OnSendBodyComplete(); | 860 delegate_->OnSendBodyComplete(); |
| 842 | 861 |
| 843 io_state_ = | 862 io_state_ = |
| 844 (send_status_ == MORE_DATA_TO_SEND) ? | 863 (send_status_ == MORE_DATA_TO_SEND) ? |
| 845 STATE_SEND_BODY : STATE_WAITING_FOR_RESPONSE; | 864 STATE_SEND_BODY : STATE_WAITING_FOR_RESPONSE; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 895 | 914 |
| 896 if (!delegate_) { | 915 if (!delegate_) { |
| 897 NOTREACHED(); | 916 NOTREACHED(); |
| 898 return ERR_UNEXPECTED; | 917 return ERR_UNEXPECTED; |
| 899 } | 918 } |
| 900 | 919 |
| 901 return OK; | 920 return OK; |
| 902 } | 921 } |
| 903 | 922 |
| 904 void SpdyStream::UpdateHistograms() { | 923 void SpdyStream::UpdateHistograms() { |
| 905 // We need all timers to be filled in, otherwise metrics can be bogus. | 924 // We need at least the receive timers to be filled in, as otherwise |
| 906 if (send_time_.is_null() || recv_first_byte_time_.is_null() || | 925 // metrics can be bogus. |
| 907 recv_last_byte_time_.is_null()) | 926 if (recv_first_byte_time_.is_null() || recv_last_byte_time_.is_null()) |
| 908 return; | 927 return; |
| 909 | 928 |
| 929 base::TimeTicks effective_send_time; | |
| 930 if (type_ == SPDY_PUSH_STREAM) { | |
| 931 // Push streams shouldn't have |send_time_| filled in. | |
| 932 DCHECK(send_time_.is_null()); | |
| 933 effective_send_time = recv_first_byte_time_; | |
| 934 } else { | |
| 935 // For non-push streams, we also need |send_time_| to be filled | |
| 936 // in. | |
| 937 if (send_time_.is_null()) | |
| 938 return; | |
| 939 effective_send_time = send_time_; | |
| 940 } | |
| 941 | |
| 910 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTimeToFirstByte", | 942 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTimeToFirstByte", |
| 911 recv_first_byte_time_ - send_time_); | 943 recv_first_byte_time_ - effective_send_time); |
| 912 UMA_HISTOGRAM_TIMES("Net.SpdyStreamDownloadTime", | 944 UMA_HISTOGRAM_TIMES("Net.SpdyStreamDownloadTime", |
| 913 recv_last_byte_time_ - recv_first_byte_time_); | 945 recv_last_byte_time_ - recv_first_byte_time_); |
| 914 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime", | 946 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime", |
| 915 recv_last_byte_time_ - send_time_); | 947 recv_last_byte_time_ - effective_send_time); |
| 916 | 948 |
| 917 UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_); | 949 UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_); |
| 918 UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_); | 950 UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_); |
| 919 } | 951 } |
| 920 | 952 |
| 921 void SpdyStream::QueueNextDataFrame() { | 953 void SpdyStream::QueueNextDataFrame() { |
| 922 // Until the request has been completely sent, we cannot be sure | 954 // Until the request has been completely sent, we cannot be sure |
| 923 // that our stream_id is correct. | 955 // that our stream_id is correct. |
| 924 DCHECK_GT(io_state_, STATE_SEND_REQUEST_HEADERS_COMPLETE); | 956 DCHECK_GT(io_state_, STATE_SEND_REQUEST_HEADERS_COMPLETE); |
| 925 CHECK_GT(stream_id_, 0u); | 957 CHECK_GT(stream_id_, 0u); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 952 GetWeakPtr(), payload_size)); | 984 GetWeakPtr(), payload_size)); |
| 953 } | 985 } |
| 954 | 986 |
| 955 session_->EnqueueStreamWrite( | 987 session_->EnqueueStreamWrite( |
| 956 GetWeakPtr(), DATA, | 988 GetWeakPtr(), DATA, |
| 957 scoped_ptr<SpdyBufferProducer>( | 989 scoped_ptr<SpdyBufferProducer>( |
| 958 new SimpleBufferProducer(data_buffer.Pass()))); | 990 new SimpleBufferProducer(data_buffer.Pass()))); |
| 959 } | 991 } |
| 960 | 992 |
| 961 } // namespace net | 993 } // namespace net |
| OLD | NEW |