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_session.h" | 5 #include "net/spdy/spdy_session.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 DISALLOW_COPY_AND_ASSIGN(NetLogSpdyGoAwayParameter); | 297 DISALLOW_COPY_AND_ASSIGN(NetLogSpdyGoAwayParameter); |
298 }; | 298 }; |
299 | 299 |
300 NextProto g_default_protocol = kProtoUnknown; | 300 NextProto g_default_protocol = kProtoUnknown; |
301 size_t g_init_max_concurrent_streams = 10; | 301 size_t g_init_max_concurrent_streams = 10; |
302 size_t g_max_concurrent_stream_limit = 256; | 302 size_t g_max_concurrent_stream_limit = 256; |
303 bool g_enable_ping_based_connection_checking = true; | 303 bool g_enable_ping_based_connection_checking = true; |
304 | 304 |
305 } // namespace | 305 } // namespace |
306 | 306 |
| 307 void SpdySession::SpdyFrameProducer::ActivateStream(SpdySession* spdy_session, |
| 308 SpdyStream* spdy_stream) { |
| 309 spdy_session->ActivateStream(spdy_stream); |
| 310 } |
| 311 |
307 // static | 312 // static |
308 void SpdySession::set_default_protocol(NextProto default_protocol) { | 313 void SpdySession::set_default_protocol(NextProto default_protocol) { |
309 g_default_protocol = default_protocol; | 314 g_default_protocol = default_protocol; |
310 } | 315 } |
311 | 316 |
312 // static | 317 // static |
313 void SpdySession::set_max_concurrent_streams(size_t value) { | 318 void SpdySession::set_max_concurrent_streams(size_t value) { |
314 g_max_concurrent_stream_limit = value; | 319 g_max_concurrent_stream_limit = value; |
315 } | 320 } |
316 | 321 |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 | 471 |
467 SSLInfo ssl_info; | 472 SSLInfo ssl_info; |
468 bool was_npn_negotiated; | 473 bool was_npn_negotiated; |
469 NextProto protocol_negotiated = kProtoUnknown; | 474 NextProto protocol_negotiated = kProtoUnknown; |
470 if (!GetSSLInfo(&ssl_info, &was_npn_negotiated, &protocol_negotiated)) | 475 if (!GetSSLInfo(&ssl_info, &was_npn_negotiated, &protocol_negotiated)) |
471 return true; // This is not a secure session, so all domains are okay. | 476 return true; // This is not a secure session, so all domains are okay. |
472 | 477 |
473 return !ssl_info.client_cert_sent && ssl_info.cert->VerifyNameMatch(domain); | 478 return !ssl_info.client_cert_sent && ssl_info.cert->VerifyNameMatch(domain); |
474 } | 479 } |
475 | 480 |
| 481 void SpdySession::SetStreamHasWriteAvailable(SpdyStream* stream) { |
| 482 write_queue_.push(stream->CreateProducer()); |
| 483 WriteSocketLater(); |
| 484 } |
| 485 |
476 int SpdySession::GetPushStream( | 486 int SpdySession::GetPushStream( |
477 const GURL& url, | 487 const GURL& url, |
478 scoped_refptr<SpdyStream>* stream, | 488 scoped_refptr<SpdyStream>* stream, |
479 const BoundNetLog& stream_net_log) { | 489 const BoundNetLog& stream_net_log) { |
480 CHECK_NE(state_, CLOSED); | 490 CHECK_NE(state_, CLOSED); |
481 | 491 |
482 *stream = NULL; | 492 *stream = NULL; |
483 | 493 |
484 // Don't allow access to secure push streams over an unauthenticated, but | 494 // Don't allow access to secure push streams over an unauthenticated, but |
485 // encrypted SSL socket. | 495 // encrypted SSL socket. |
(...skipping 18 matching lines...) Expand all Loading... |
504 return 0; | 514 return 0; |
505 } | 515 } |
506 | 516 |
507 int SpdySession::CreateStream( | 517 int SpdySession::CreateStream( |
508 const GURL& url, | 518 const GURL& url, |
509 RequestPriority priority, | 519 RequestPriority priority, |
510 scoped_refptr<SpdyStream>* spdy_stream, | 520 scoped_refptr<SpdyStream>* spdy_stream, |
511 const BoundNetLog& stream_net_log, | 521 const BoundNetLog& stream_net_log, |
512 const CompletionCallback& callback) { | 522 const CompletionCallback& callback) { |
513 if (!max_concurrent_streams_ || | 523 if (!max_concurrent_streams_ || |
514 active_streams_.size() < max_concurrent_streams_) { | 524 (active_streams_.size() + created_streams_.size() |
| 525 < max_concurrent_streams_)) { |
515 return CreateStreamImpl(url, priority, spdy_stream, stream_net_log); | 526 return CreateStreamImpl(url, priority, spdy_stream, stream_net_log); |
516 } | 527 } |
517 | 528 |
518 stalled_streams_++; | 529 stalled_streams_++; |
519 net_log().AddEvent(NetLog::TYPE_SPDY_SESSION_STALLED_MAX_STREAMS, NULL); | 530 net_log().AddEvent(NetLog::TYPE_SPDY_SESSION_STALLED_MAX_STREAMS, NULL); |
520 create_stream_queues_[priority].push( | 531 create_stream_queues_[priority].push( |
521 PendingCreateStream(url, priority, spdy_stream, | 532 PendingCreateStream(url, priority, spdy_stream, |
522 stream_net_log, callback)); | 533 stream_net_log, callback)); |
523 return ERR_IO_PENDING; | 534 return ERR_IO_PENDING; |
524 } | 535 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 CloseSessionOnError( | 605 CloseSessionOnError( |
595 static_cast<net::Error>(certificate_error_code_), | 606 static_cast<net::Error>(certificate_error_code_), |
596 true, | 607 true, |
597 "Tried to create SPDY stream for secure content over an " | 608 "Tried to create SPDY stream for secure content over an " |
598 "unauthenticated session."); | 609 "unauthenticated session."); |
599 return ERR_SPDY_PROTOCOL_ERROR; | 610 return ERR_SPDY_PROTOCOL_ERROR; |
600 } | 611 } |
601 | 612 |
602 const std::string& path = url.PathForRequest(); | 613 const std::string& path = url.PathForRequest(); |
603 | 614 |
604 const SpdyStreamId stream_id = GetNewStreamId(); | |
605 | |
606 *spdy_stream = new SpdyStream(this, | 615 *spdy_stream = new SpdyStream(this, |
607 stream_id, | |
608 false, | 616 false, |
609 stream_net_log); | 617 stream_net_log); |
610 const scoped_refptr<SpdyStream>& stream = *spdy_stream; | 618 const scoped_refptr<SpdyStream>& stream = *spdy_stream; |
611 | 619 |
612 stream->set_priority(priority); | 620 stream->set_priority(priority); |
613 stream->set_path(path); | 621 stream->set_path(path); |
614 stream->set_send_window_size(initial_send_window_size_); | 622 stream->set_send_window_size(initial_send_window_size_); |
615 stream->set_recv_window_size(initial_recv_window_size_); | 623 stream->set_recv_window_size(initial_recv_window_size_); |
616 ActivateStream(stream); | 624 created_streams_.insert(stream); |
617 | 625 |
618 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyPriorityCount", | 626 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyPriorityCount", |
619 static_cast<int>(priority), 0, 10, 11); | 627 static_cast<int>(priority), 0, 10, 11); |
620 | 628 |
621 // TODO(mbelshe): Optimize memory allocations | 629 // TODO(mbelshe): Optimize memory allocations |
622 | 630 |
623 DCHECK_EQ(active_streams_[stream_id].get(), stream.get()); | |
624 return OK; | 631 return OK; |
625 } | 632 } |
626 | 633 |
627 bool SpdySession::NeedsCredentials() const { | 634 bool SpdySession::NeedsCredentials() const { |
628 if (!is_secure_) | 635 if (!is_secure_) |
629 return false; | 636 return false; |
630 SSLClientSocket* ssl_socket = GetSSLClientSocket(); | 637 SSLClientSocket* ssl_socket = GetSSLClientSocket(); |
631 if (ssl_socket->GetNegotiatedProtocol() < kProtoSPDY3) | 638 if (ssl_socket->GetNegotiatedProtocol() < kProtoSPDY3) |
632 return false; | 639 return false; |
633 return ssl_socket->WasDomainBoundCertSent(); | 640 return ssl_socket->WasDomainBoundCertSent(); |
634 } | 641 } |
635 | 642 |
636 void SpdySession::AddPooledAlias(const HostPortProxyPair& alias) { | 643 void SpdySession::AddPooledAlias(const HostPortProxyPair& alias) { |
637 pooled_aliases_.insert(alias); | 644 pooled_aliases_.insert(alias); |
638 } | 645 } |
639 | 646 |
640 int SpdySession::GetProtocolVersion() const { | 647 int SpdySession::GetProtocolVersion() const { |
641 DCHECK(buffered_spdy_framer_.get()); | 648 DCHECK(buffered_spdy_framer_.get()); |
642 return buffered_spdy_framer_->protocol_version(); | 649 return buffered_spdy_framer_->protocol_version(); |
643 } | 650 } |
644 | 651 |
645 int SpdySession::WriteSynStream( | 652 SpdySynStreamControlFrame* SpdySession::CreateSynStream( |
646 SpdyStreamId stream_id, | 653 SpdyStreamId stream_id, |
647 RequestPriority priority, | 654 RequestPriority priority, |
648 uint8 credential_slot, | 655 uint8 credential_slot, |
649 SpdyControlFlags flags, | 656 SpdyControlFlags flags, |
650 const linked_ptr<SpdyHeaderBlock>& headers) { | 657 const linked_ptr<SpdyHeaderBlock>& headers) { |
651 // Find our stream | 658 CHECK(IsStreamActive(stream_id)); |
652 if (!IsStreamActive(stream_id)) | |
653 return ERR_INVALID_SPDY_STREAM; | |
654 const scoped_refptr<SpdyStream>& stream = active_streams_[stream_id]; | 659 const scoped_refptr<SpdyStream>& stream = active_streams_[stream_id]; |
655 CHECK_EQ(stream->stream_id(), stream_id); | 660 CHECK_EQ(stream->stream_id(), stream_id); |
656 | 661 |
657 SendPrefacePingIfNoneInFlight(); | 662 SendPrefacePingIfNoneInFlight(); |
658 | 663 |
659 DCHECK(buffered_spdy_framer_.get()); | 664 DCHECK(buffered_spdy_framer_.get()); |
660 scoped_ptr<SpdySynStreamControlFrame> syn_frame( | 665 scoped_ptr<SpdySynStreamControlFrame> syn_frame( |
661 buffered_spdy_framer_->CreateSynStream( | 666 buffered_spdy_framer_->CreateSynStream( |
662 stream_id, 0, | 667 stream_id, 0, |
663 ConvertRequestPriorityToSpdyPriority(priority, GetProtocolVersion()), | 668 ConvertRequestPriorityToSpdyPriority(priority, GetProtocolVersion()), |
664 credential_slot, flags, false, headers.get())); | 669 credential_slot, flags, true, headers.get())); |
665 // We enqueue all SYN_STREAM frames at the same priority to ensure | |
666 // that we do not send them out-of-order. | |
667 // http://crbug.com/111708 | |
668 QueueFrame(syn_frame.get(), HIGHEST, stream); | |
669 | 670 |
670 base::StatsCounter spdy_requests("spdy.requests"); | 671 base::StatsCounter spdy_requests("spdy.requests"); |
671 spdy_requests.Increment(); | 672 spdy_requests.Increment(); |
672 streams_initiated_count_++; | 673 streams_initiated_count_++; |
673 | 674 |
674 if (net_log().IsLoggingAllEvents()) { | 675 if (net_log().IsLoggingAllEvents()) { |
675 net_log().AddEvent( | 676 net_log().AddEvent( |
676 NetLog::TYPE_SPDY_SESSION_SYN_STREAM, | 677 NetLog::TYPE_SPDY_SESSION_SYN_STREAM, |
677 make_scoped_refptr( | 678 make_scoped_refptr( |
678 new NetLogSpdySynParameter(headers, flags, stream_id, 0))); | 679 new NetLogSpdySynParameter(headers, flags, stream_id, 0))); |
679 } | 680 } |
680 | 681 |
681 return ERR_IO_PENDING; | 682 return syn_frame.release(); |
682 } | 683 } |
683 | 684 |
684 int SpdySession::WriteCredentialFrame(const std::string& origin, | 685 SpdyCredentialControlFrame* SpdySession::CreateCredentialFrame( |
685 SSLClientCertType type, | 686 const std::string& origin, |
686 const std::string& key, | 687 SSLClientCertType type, |
687 const std::string& cert, | 688 const std::string& key, |
688 RequestPriority priority) { | 689 const std::string& cert, |
| 690 RequestPriority priority) { |
689 DCHECK(is_secure_); | 691 DCHECK(is_secure_); |
690 unsigned char secret[32]; // 32 bytes from the spec | 692 unsigned char secret[32]; // 32 bytes from the spec |
691 GetSSLClientSocket()->ExportKeyingMaterial("SPDY certificate proof", | 693 GetSSLClientSocket()->ExportKeyingMaterial("SPDY certificate proof", |
692 true, origin, | 694 true, origin, |
693 secret, arraysize(secret)); | 695 secret, arraysize(secret)); |
694 | 696 |
695 // Convert the key string into a vector<unit8> | 697 // Convert the key string into a vector<unit8> |
696 std::vector<uint8> key_data; | 698 std::vector<uint8> key_data; |
697 for (size_t i = 0; i < key.length(); i++) { | 699 for (size_t i = 0; i < key.length(); i++) { |
698 key_data.push_back(key[i]); | 700 key_data.push_back(key[i]); |
(...skipping 21 matching lines...) Expand all Loading... |
720 SpdyCredential credential; | 722 SpdyCredential credential; |
721 GURL origin_url(origin); | 723 GURL origin_url(origin); |
722 credential.slot = | 724 credential.slot = |
723 credential_state_.SetHasCredential(origin_url); | 725 credential_state_.SetHasCredential(origin_url); |
724 credential.certs.push_back(cert); | 726 credential.certs.push_back(cert); |
725 credential.proof.assign(proof.begin(), proof.end()); | 727 credential.proof.assign(proof.begin(), proof.end()); |
726 | 728 |
727 DCHECK(buffered_spdy_framer_.get()); | 729 DCHECK(buffered_spdy_framer_.get()); |
728 scoped_ptr<SpdyCredentialControlFrame> credential_frame( | 730 scoped_ptr<SpdyCredentialControlFrame> credential_frame( |
729 buffered_spdy_framer_->CreateCredentialFrame(credential)); | 731 buffered_spdy_framer_->CreateCredentialFrame(credential)); |
730 // We enqueue all SYN_STREAM frames at the same priority to ensure | |
731 // that we do not send them out-of-order, which means that we need | |
732 // to enqueue all CREDENTIAL frames at this priority to ensure that | |
733 // they are sent *before* the SYN_STREAM that references them. | |
734 // http://crbug.com/111708 | |
735 QueueFrame(credential_frame.get(), HIGHEST, NULL); | |
736 | 732 |
737 if (net_log().IsLoggingAllEvents()) { | 733 if (net_log().IsLoggingAllEvents()) { |
738 net_log().AddEvent( | 734 net_log().AddEvent( |
739 NetLog::TYPE_SPDY_SESSION_SEND_CREDENTIAL, | 735 NetLog::TYPE_SPDY_SESSION_SEND_CREDENTIAL, |
740 make_scoped_refptr( | 736 make_scoped_refptr( |
741 new NetLogSpdyCredentialParameter(credential.slot, | 737 new NetLogSpdyCredentialParameter(credential.slot, |
742 origin))); | 738 origin))); |
743 } | 739 } |
744 return ERR_IO_PENDING; | 740 return credential_frame.release(); |
745 } | 741 } |
746 | 742 |
747 int SpdySession::WriteStreamData(SpdyStreamId stream_id, | 743 SpdyDataFrame* SpdySession::CreateDataFrame(SpdyStreamId stream_id, |
748 net::IOBuffer* data, int len, | 744 net::IOBuffer* data, int len, |
749 SpdyDataFlags flags) { | 745 SpdyDataFlags flags) { |
750 // Find our stream | 746 // Find our stream |
751 CHECK(IsStreamActive(stream_id)); | 747 CHECK(IsStreamActive(stream_id)); |
752 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; | 748 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
753 CHECK_EQ(stream->stream_id(), stream_id); | 749 CHECK_EQ(stream->stream_id(), stream_id); |
754 | 750 |
755 if (len > kMaxSpdyFrameChunkSize) { | 751 if (len > kMaxSpdyFrameChunkSize) { |
756 len = kMaxSpdyFrameChunkSize; | 752 len = kMaxSpdyFrameChunkSize; |
757 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN); | 753 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN); |
758 } | 754 } |
759 | 755 |
760 // Obey send window size of the stream if flow control is enabled. | 756 // Obey send window size of the stream if flow control is enabled. |
761 if (flow_control_) { | 757 if (flow_control_) { |
762 if (stream->send_window_size() <= 0) { | 758 if (stream->send_window_size() <= 0) { |
763 // Because we queue frames onto the session, it is possible that | 759 // Because we queue frames onto the session, it is possible that |
764 // a stream was not flow controlled at the time it attempted the | 760 // a stream was not flow controlled at the time it attempted the |
765 // write, but when we go to fulfill the write, it is now flow | 761 // write, but when we go to fulfill the write, it is now flow |
766 // controlled. This is why we need the session to mark the stream | 762 // controlled. This is why we need the session to mark the stream |
767 // as stalled - because only the session knows for sure when the | 763 // as stalled - because only the session knows for sure when the |
768 // stall occurs. | 764 // stall occurs. |
769 stream->set_stalled_by_flow_control(true); | 765 stream->set_stalled_by_flow_control(true); |
770 net_log().AddEvent( | 766 net_log().AddEvent( |
771 NetLog::TYPE_SPDY_SESSION_STALLED_ON_SEND_WINDOW, | 767 NetLog::TYPE_SPDY_SESSION_STALLED_ON_SEND_WINDOW, |
772 make_scoped_refptr( | 768 make_scoped_refptr( |
773 new NetLogIntegerParameter("stream_id", stream_id))); | 769 new NetLogIntegerParameter("stream_id", stream_id))); |
774 return ERR_IO_PENDING; | 770 return NULL; |
775 } | 771 } |
776 int new_len = std::min(len, stream->send_window_size()); | 772 int new_len = std::min(len, stream->send_window_size()); |
777 if (new_len < len) { | 773 if (new_len < len) { |
778 len = new_len; | 774 len = new_len; |
779 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN); | 775 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN); |
780 } | 776 } |
781 stream->DecreaseSendWindowSize(len); | 777 stream->DecreaseSendWindowSize(len); |
782 } | 778 } |
783 | 779 |
784 if (net_log().IsLoggingAllEvents()) { | 780 if (net_log().IsLoggingAllEvents()) { |
785 net_log().AddEvent( | 781 net_log().AddEvent( |
786 NetLog::TYPE_SPDY_SESSION_SEND_DATA, | 782 NetLog::TYPE_SPDY_SESSION_SEND_DATA, |
787 make_scoped_refptr(new NetLogSpdyDataParameter(stream_id, len, flags))); | 783 make_scoped_refptr(new NetLogSpdyDataParameter(stream_id, len, flags))); |
788 } | 784 } |
789 | 785 |
790 // Send PrefacePing for DATA_FRAMEs with nonzero payload size. | 786 // Send PrefacePing for DATA_FRAMEs with nonzero payload size. |
791 if (len > 0) | 787 if (len > 0) |
792 SendPrefacePingIfNoneInFlight(); | 788 SendPrefacePingIfNoneInFlight(); |
793 | 789 |
794 // TODO(mbelshe): reduce memory copies here. | 790 // TODO(mbelshe): reduce memory copies here. |
795 DCHECK(buffered_spdy_framer_.get()); | 791 DCHECK(buffered_spdy_framer_.get()); |
796 scoped_ptr<SpdyDataFrame> frame( | 792 scoped_ptr<SpdyDataFrame> frame( |
797 buffered_spdy_framer_->CreateDataFrame( | 793 buffered_spdy_framer_->CreateDataFrame( |
798 stream_id, data->data(), len, flags)); | 794 stream_id, data->data(), len, flags)); |
799 QueueFrame(frame.get(), stream->priority(), stream); | |
800 | 795 |
801 return ERR_IO_PENDING; | 796 return frame.release(); |
802 } | 797 } |
803 | 798 |
804 void SpdySession::CloseStream(SpdyStreamId stream_id, int status) { | 799 void SpdySession::CloseStream(SpdyStreamId stream_id, int status) { |
| 800 DCHECK_NE(0u, stream_id); |
805 // TODO(mbelshe): We should send a RST_STREAM control frame here | 801 // TODO(mbelshe): We should send a RST_STREAM control frame here |
806 // so that the server can cancel a large send. | 802 // so that the server can cancel a large send. |
807 | 803 |
808 DeleteStream(stream_id, status); | 804 DeleteStream(stream_id, status); |
809 } | 805 } |
810 | 806 |
| 807 void SpdySession::CloseCreatedStream(SpdyStream* stream, int status) { |
| 808 DCHECK_EQ(0u, stream->stream_id()); |
| 809 created_streams_.erase(scoped_refptr<SpdyStream>(stream)); |
| 810 } |
| 811 |
811 void SpdySession::ResetStream(SpdyStreamId stream_id, | 812 void SpdySession::ResetStream(SpdyStreamId stream_id, |
812 SpdyStatusCodes status, | 813 SpdyStatusCodes status, |
813 const std::string& description) { | 814 const std::string& description) { |
814 net_log().AddEvent( | 815 net_log().AddEvent( |
815 NetLog::TYPE_SPDY_SESSION_SEND_RST_STREAM, | 816 NetLog::TYPE_SPDY_SESSION_SEND_RST_STREAM, |
816 make_scoped_refptr(new NetLogSpdyRstParameter(stream_id, status, | 817 make_scoped_refptr(new NetLogSpdyRstParameter(stream_id, status, |
817 description))); | 818 description))); |
818 | 819 |
819 DCHECK(buffered_spdy_framer_.get()); | 820 DCHECK(buffered_spdy_framer_.get()); |
820 scoped_ptr<SpdyRstStreamControlFrame> rst_frame( | 821 scoped_ptr<SpdyRstStreamControlFrame> rst_frame( |
821 buffered_spdy_framer_->CreateRstStream(stream_id, status)); | 822 buffered_spdy_framer_->CreateRstStream(stream_id, status)); |
822 | 823 |
823 // Default to lowest priority unless we know otherwise. | 824 // Default to lowest priority unless we know otherwise. |
824 RequestPriority priority = net::IDLE; | 825 RequestPriority priority = net::IDLE; |
825 if(IsStreamActive(stream_id)) { | 826 if(IsStreamActive(stream_id)) { |
826 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; | 827 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
827 priority = stream->priority(); | 828 priority = stream->priority(); |
828 } | 829 } |
829 QueueFrame(rst_frame.get(), priority, NULL); | 830 QueueFrame(rst_frame.release(), priority); |
830 RecordProtocolErrorHistogram( | 831 RecordProtocolErrorHistogram( |
831 static_cast<SpdyProtocolErrorDetails>(status + STATUS_CODE_INVALID)); | 832 static_cast<SpdyProtocolErrorDetails>(status + STATUS_CODE_INVALID)); |
832 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); | 833 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); |
833 } | 834 } |
834 | 835 |
835 bool SpdySession::IsStreamActive(SpdyStreamId stream_id) const { | 836 bool SpdySession::IsStreamActive(SpdyStreamId stream_id) const { |
836 return ContainsKey(active_streams_, stream_id); | 837 return ContainsKey(active_streams_, stream_id); |
837 } | 838 } |
838 | 839 |
839 LoadState SpdySession::GetLoadState() const { | 840 LoadState SpdySession::GetLoadState() const { |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1007 // closed, just return. | 1008 // closed, just return. |
1008 if (state_ < CONNECTED || state_ == CLOSED) | 1009 if (state_ < CONNECTED || state_ == CLOSED) |
1009 return; | 1010 return; |
1010 | 1011 |
1011 if (write_pending_) // Another write is in progress still. | 1012 if (write_pending_) // Another write is in progress still. |
1012 return; | 1013 return; |
1013 | 1014 |
1014 // Loop sending frames until we've sent everything or until the write | 1015 // Loop sending frames until we've sent everything or until the write |
1015 // returns error (or ERR_IO_PENDING). | 1016 // returns error (or ERR_IO_PENDING). |
1016 DCHECK(buffered_spdy_framer_.get()); | 1017 DCHECK(buffered_spdy_framer_.get()); |
1017 while (in_flight_write_.buffer() || !queue_.empty()) { | 1018 while (in_flight_write_.buffer() || !write_queue_.empty()) { |
1018 if (!in_flight_write_.buffer()) { | 1019 if (!in_flight_write_.buffer()) { |
1019 // Grab the next SpdyFrame to send. | 1020 // Grab the next SpdyFrame to send. |
1020 SpdyIOBuffer next_buffer = queue_.top(); | 1021 SpdyFrameProducer* producer = write_queue_.top(); |
1021 queue_.pop(); | 1022 write_queue_.pop(); |
| 1023 SpdyStream* stream = producer->GetSpdyStream(); |
| 1024 SpdyFrame* frame = producer->ProduceNextFrame(this); |
| 1025 RequestPriority priority = producer->GetPriority(); |
| 1026 delete producer; |
| 1027 // It is possible that a stream had data to write, but a |
| 1028 // WINDOW_UPDATE frame has been received which made that |
| 1029 // stream no longer writable. |
| 1030 // TODO(rch): consider handling that case by removing the |
| 1031 // stream from the writable queue? |
| 1032 if (frame == NULL) |
| 1033 continue; |
1022 | 1034 |
1023 // We've deferred compression until just before we write it to the socket, | 1035 size_t size = frame->length() + SpdyFrame::kHeaderSize; |
1024 // which is now. At this time, we don't compress our data frames. | 1036 DCHECK_GT(size, 0u); |
1025 SpdyFrame uncompressed_frame(next_buffer.buffer()->data(), false); | |
1026 size_t size; | |
1027 if (buffered_spdy_framer_->IsCompressible(uncompressed_frame)) { | |
1028 DCHECK(uncompressed_frame.is_control_frame()); | |
1029 scoped_ptr<SpdyFrame> compressed_frame( | |
1030 buffered_spdy_framer_->CompressControlFrame( | |
1031 reinterpret_cast<const SpdyControlFrame&>(uncompressed_frame))); | |
1032 if (!compressed_frame.get()) { | |
1033 RecordProtocolErrorHistogram( | |
1034 PROTOCOL_ERROR_SPDY_COMPRESSION_FAILURE); | |
1035 CloseSessionOnError( | |
1036 net::ERR_SPDY_PROTOCOL_ERROR, true, "SPDY Compression failure."); | |
1037 return; | |
1038 } | |
1039 | 1037 |
1040 size = compressed_frame->length() + SpdyFrame::kHeaderSize; | 1038 // TODO(mbelshe): We have too much copying of data here. |
| 1039 IOBufferWithSize* buffer = new IOBufferWithSize(size); |
| 1040 memcpy(buffer->data(), frame->data(), size); |
1041 | 1041 |
1042 DCHECK_GT(size, 0u); | 1042 in_flight_write_ = SpdyIOBuffer(buffer, size, priority, stream); |
1043 | |
1044 // TODO(mbelshe): We have too much copying of data here. | |
1045 IOBufferWithSize* buffer = new IOBufferWithSize(size); | |
1046 memcpy(buffer->data(), compressed_frame->data(), size); | |
1047 | |
1048 // Attempt to send the frame. | |
1049 in_flight_write_ = SpdyIOBuffer(buffer, size, HIGHEST, | |
1050 next_buffer.stream()); | |
1051 } else { | |
1052 size = uncompressed_frame.length() + SpdyFrame::kHeaderSize; | |
1053 in_flight_write_ = next_buffer; | |
1054 } | |
1055 } else { | 1043 } else { |
1056 DCHECK(in_flight_write_.buffer()->BytesRemaining()); | 1044 DCHECK(in_flight_write_.buffer()->BytesRemaining()); |
1057 } | 1045 } |
1058 | 1046 |
1059 write_pending_ = true; | 1047 write_pending_ = true; |
1060 int rv = connection_->socket()->Write( | 1048 int rv = connection_->socket()->Write( |
1061 in_flight_write_.buffer(), | 1049 in_flight_write_.buffer(), |
1062 in_flight_write_.buffer()->BytesRemaining(), | 1050 in_flight_write_.buffer()->BytesRemaining(), |
1063 base::Bind(&SpdySession::OnWriteComplete, base::Unretained(this))); | 1051 base::Bind(&SpdySession::OnWriteComplete, base::Unretained(this))); |
1064 if (rv == net::ERR_IO_PENDING) | 1052 if (rv == net::ERR_IO_PENDING) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1098 while (!active_streams_.empty()) { | 1086 while (!active_streams_.empty()) { |
1099 ActiveStreamMap::iterator it = active_streams_.begin(); | 1087 ActiveStreamMap::iterator it = active_streams_.begin(); |
1100 const scoped_refptr<SpdyStream>& stream = it->second; | 1088 const scoped_refptr<SpdyStream>& stream = it->second; |
1101 DCHECK(stream); | 1089 DCHECK(stream); |
1102 std::string description = base::StringPrintf( | 1090 std::string description = base::StringPrintf( |
1103 "ABANDONED (stream_id=%d): ", stream->stream_id()) + stream->path(); | 1091 "ABANDONED (stream_id=%d): ", stream->stream_id()) + stream->path(); |
1104 stream->LogStreamError(status, description); | 1092 stream->LogStreamError(status, description); |
1105 DeleteStream(stream->stream_id(), status); | 1093 DeleteStream(stream->stream_id(), status); |
1106 } | 1094 } |
1107 | 1095 |
| 1096 while (!created_streams_.empty()) { |
| 1097 CreatedStreamSet::iterator it = created_streams_.begin(); |
| 1098 const scoped_refptr<SpdyStream>& stream = *it; |
| 1099 std::string description = base::StringPrintf( |
| 1100 "ABANDONED (stream_id=%d): ", stream->stream_id()) + stream->path(); |
| 1101 stream->LogStreamError(status, description); |
| 1102 stream->OnClose(status); |
| 1103 created_streams_.erase(it); |
| 1104 } |
| 1105 |
1108 // We also need to drain the queue. | 1106 // We also need to drain the queue. |
1109 while (queue_.size()) | 1107 while (!write_queue_.empty()) { |
1110 queue_.pop(); | 1108 delete write_queue_.top(); |
| 1109 write_queue_.pop(); |
| 1110 } |
1111 } | 1111 } |
1112 | 1112 |
1113 int SpdySession::GetNewStreamId() { | 1113 int SpdySession::GetNewStreamId() { |
1114 int id = stream_hi_water_mark_; | 1114 int id = stream_hi_water_mark_; |
1115 stream_hi_water_mark_ += 2; | 1115 stream_hi_water_mark_ += 2; |
1116 if (stream_hi_water_mark_ > 0x7fff) | 1116 if (stream_hi_water_mark_ > 0x7fff) |
1117 stream_hi_water_mark_ = 1; | 1117 stream_hi_water_mark_ = 1; |
1118 return id; | 1118 return id; |
1119 } | 1119 } |
1120 | 1120 |
1121 void SpdySession::QueueFrame(SpdyFrame* frame, | |
1122 RequestPriority priority, | |
1123 SpdyStream* stream) { | |
1124 int length = SpdyFrame::kHeaderSize + frame->length(); | |
1125 IOBuffer* buffer = new IOBuffer(length); | |
1126 memcpy(buffer->data(), frame->data(), length); | |
1127 queue_.push(SpdyIOBuffer(buffer, length, priority, stream)); | |
1128 | |
1129 WriteSocketLater(); | |
1130 } | |
1131 | |
1132 void SpdySession::CloseSessionOnError(net::Error err, | 1121 void SpdySession::CloseSessionOnError(net::Error err, |
1133 bool remove_from_pool, | 1122 bool remove_from_pool, |
1134 const std::string& description) { | 1123 const std::string& description) { |
1135 // Closing all streams can have a side-effect of dropping the last reference | 1124 // Closing all streams can have a side-effect of dropping the last reference |
1136 // to |this|. Hold a reference through this function. | 1125 // to |this|. Hold a reference through this function. |
1137 scoped_refptr<SpdySession> self(this); | 1126 scoped_refptr<SpdySession> self(this); |
1138 | 1127 |
1139 DCHECK_LT(err, OK); | 1128 DCHECK_LT(err, OK); |
1140 net_log_.AddEvent( | 1129 net_log_.AddEvent( |
1141 NetLog::TYPE_SPDY_SESSION_CLOSE, | 1130 NetLog::TYPE_SPDY_SESSION_CLOSE, |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1212 return connection_->socket()->GetPeerAddress(address); | 1201 return connection_->socket()->GetPeerAddress(address); |
1213 } | 1202 } |
1214 | 1203 |
1215 int SpdySession::GetLocalAddress(IPEndPoint* address) const { | 1204 int SpdySession::GetLocalAddress(IPEndPoint* address) const { |
1216 if (!connection_->socket()) | 1205 if (!connection_->socket()) |
1217 return ERR_SOCKET_NOT_CONNECTED; | 1206 return ERR_SOCKET_NOT_CONNECTED; |
1218 | 1207 |
1219 return connection_->socket()->GetLocalAddress(address); | 1208 return connection_->socket()->GetLocalAddress(address); |
1220 } | 1209 } |
1221 | 1210 |
| 1211 class SimpleSpdyFrameProducer : public SpdySession::SpdyFrameProducer { |
| 1212 public: |
| 1213 SimpleSpdyFrameProducer(SpdyFrame* frame, |
| 1214 RequestPriority priority) |
| 1215 : frame_(frame), |
| 1216 priority_(priority) { |
| 1217 } |
| 1218 virtual RequestPriority GetPriority() const OVERRIDE { |
| 1219 return priority_; |
| 1220 } |
| 1221 virtual SpdyFrame* ProduceNextFrame(SpdySession* spdy_session) OVERRIDE { |
| 1222 return frame_; |
| 1223 } |
| 1224 virtual SpdyStream* GetSpdyStream() OVERRIDE { |
| 1225 return NULL; |
| 1226 } |
| 1227 private: |
| 1228 SpdyFrame* frame_; |
| 1229 RequestPriority priority_; |
| 1230 }; |
| 1231 |
| 1232 void SpdySession::QueueFrame(SpdyFrame* frame, |
| 1233 RequestPriority priority) { |
| 1234 SimpleSpdyFrameProducer* producer |
| 1235 = new SimpleSpdyFrameProducer(frame, priority); |
| 1236 write_queue_.push(producer); |
| 1237 WriteSocketLater(); |
| 1238 } |
| 1239 |
1222 void SpdySession::ActivateStream(SpdyStream* stream) { | 1240 void SpdySession::ActivateStream(SpdyStream* stream) { |
| 1241 if (stream->stream_id() == 0) { |
| 1242 stream->set_stream_id(GetNewStreamId()); |
| 1243 created_streams_.erase(scoped_refptr<SpdyStream>(stream)); |
| 1244 } |
1223 const SpdyStreamId id = stream->stream_id(); | 1245 const SpdyStreamId id = stream->stream_id(); |
1224 DCHECK(!IsStreamActive(id)); | 1246 DCHECK(!IsStreamActive(id)); |
1225 | 1247 |
1226 active_streams_[id] = stream; | 1248 active_streams_[id] = stream; |
1227 } | 1249 } |
1228 | 1250 |
1229 void SpdySession::DeleteStream(SpdyStreamId id, int status) { | 1251 void SpdySession::DeleteStream(SpdyStreamId id, int status) { |
1230 // For push streams, if they are being deleted normally, we leave | 1252 // For push streams, if they are being deleted normally, we leave |
1231 // the stream in the unclaimed_pushed_streams_ list. However, if | 1253 // the stream in the unclaimed_pushed_streams_ list. However, if |
1232 // the stream is errored out, clean it up entirely. | 1254 // the stream is errored out, clean it up entirely. |
1233 if (status != OK) { | 1255 if (status != OK) { |
1234 PushedStreamMap::iterator it; | 1256 PushedStreamMap::iterator it; |
1235 for (it = unclaimed_pushed_streams_.begin(); | 1257 for (it = unclaimed_pushed_streams_.begin(); |
1236 it != unclaimed_pushed_streams_.end(); ++it) { | 1258 it != unclaimed_pushed_streams_.end(); ++it) { |
1237 scoped_refptr<SpdyStream> curr = it->second; | 1259 scoped_refptr<SpdyStream> curr = it->second; |
1238 if (id == curr->stream_id()) { | 1260 if (id == curr->stream_id()) { |
1239 unclaimed_pushed_streams_.erase(it); | 1261 unclaimed_pushed_streams_.erase(it); |
1240 break; | 1262 break; |
1241 } | 1263 } |
1242 } | 1264 } |
1243 } | 1265 } |
1244 | 1266 |
1245 // The stream might have been deleted. | 1267 // The stream might have been deleted. |
1246 ActiveStreamMap::iterator it2 = active_streams_.find(id); | 1268 ActiveStreamMap::iterator it2 = active_streams_.find(id); |
1247 if (it2 == active_streams_.end()) | 1269 if (it2 == active_streams_.end()) |
1248 return; | 1270 return; |
1249 | 1271 |
| 1272 // Possibly remove from the write queue. |
| 1273 WriteQueue old = write_queue_; |
| 1274 write_queue_ = WriteQueue(); |
| 1275 while (!old.empty()) { |
| 1276 SpdyFrameProducer* producer = old.top(); |
| 1277 if (producer->GetSpdyStream() == NULL || |
| 1278 producer->GetSpdyStream()->stream_id() != id) |
| 1279 write_queue_.push(producer); |
| 1280 else |
| 1281 delete producer; |
| 1282 old.pop(); |
| 1283 } |
| 1284 |
1250 // If this is an active stream, call the callback. | 1285 // If this is an active stream, call the callback. |
1251 const scoped_refptr<SpdyStream> stream(it2->second); | 1286 const scoped_refptr<SpdyStream> stream(it2->second); |
1252 active_streams_.erase(it2); | 1287 active_streams_.erase(it2); |
1253 if (stream) | 1288 if (stream) |
1254 stream->OnClose(status); | 1289 stream->OnClose(status); |
1255 ProcessPendingCreateStreams(); | 1290 ProcessPendingCreateStreams(); |
1256 } | 1291 } |
1257 | 1292 |
1258 void SpdySession::RemoveFromPool() { | 1293 void SpdySession::RemoveFromPool() { |
1259 if (spdy_session_pool_) { | 1294 if (spdy_session_pool_) { |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1456 } | 1491 } |
1457 | 1492 |
1458 // There should not be an existing pushed stream with the same path. | 1493 // There should not be an existing pushed stream with the same path. |
1459 PushedStreamMap::iterator it = unclaimed_pushed_streams_.find(url); | 1494 PushedStreamMap::iterator it = unclaimed_pushed_streams_.find(url); |
1460 if (it != unclaimed_pushed_streams_.end()) { | 1495 if (it != unclaimed_pushed_streams_.end()) { |
1461 ResetStream(stream_id, PROTOCOL_ERROR, | 1496 ResetStream(stream_id, PROTOCOL_ERROR, |
1462 "Received duplicate pushed stream with url: " + url); | 1497 "Received duplicate pushed stream with url: " + url); |
1463 return; | 1498 return; |
1464 } | 1499 } |
1465 | 1500 |
1466 scoped_refptr<SpdyStream> stream( | 1501 scoped_refptr<SpdyStream> stream(new SpdyStream(this, true, net_log_)); |
1467 new SpdyStream(this, stream_id, true, net_log_)); | 1502 stream->set_stream_id(stream_id); |
1468 | 1503 |
1469 stream->set_path(gurl.PathForRequest()); | 1504 stream->set_path(gurl.PathForRequest()); |
1470 stream->set_send_window_size(initial_send_window_size_); | 1505 stream->set_send_window_size(initial_send_window_size_); |
1471 stream->set_recv_window_size(initial_recv_window_size_); | 1506 stream->set_recv_window_size(initial_recv_window_size_); |
1472 | 1507 |
1473 unclaimed_pushed_streams_[url] = stream; | 1508 unclaimed_pushed_streams_[url] = stream; |
1474 | 1509 |
1475 ActivateStream(stream); | 1510 ActivateStream(stream); |
1476 stream->set_response_received(); | 1511 stream->set_response_received(); |
1477 | 1512 |
1478 // Parse the headers. | 1513 // Parse the headers. |
1479 if (!Respond(*headers, stream)) | 1514 if (!Respond(*headers, stream)) |
1480 return; | 1515 return; |
1481 | 1516 |
1482 base::StatsCounter push_requests("spdy.pushed_streams"); | 1517 base::StatsCounter push_requests("spdy.pushed_streams"); |
1483 push_requests.Increment(); | 1518 push_requests.Increment(); |
1484 } | 1519 } |
1485 | 1520 |
1486 void SpdySession::OnSynReply(const SpdySynReplyControlFrame& frame, | 1521 void SpdySession::OnSynReply(const SpdySynReplyControlFrame& frame, |
1487 const linked_ptr<SpdyHeaderBlock>& headers) { | 1522 const linked_ptr<SpdyHeaderBlock>& headers) { |
1488 SpdyStreamId stream_id = frame.stream_id(); | 1523 SpdyStreamId stream_id = frame.stream_id(); |
1489 | |
1490 if (net_log().IsLoggingAllEvents()) { | 1524 if (net_log().IsLoggingAllEvents()) { |
1491 net_log().AddEvent( | 1525 net_log().AddEvent( |
1492 NetLog::TYPE_SPDY_SESSION_SYN_REPLY, | 1526 NetLog::TYPE_SPDY_SESSION_SYN_REPLY, |
1493 make_scoped_refptr(new NetLogSpdySynParameter( | 1527 make_scoped_refptr(new NetLogSpdySynParameter( |
1494 headers, static_cast<SpdyControlFlags>(frame.flags()), | 1528 headers, static_cast<SpdyControlFlags>(frame.flags()), |
1495 stream_id, 0))); | 1529 stream_id, 0))); |
1496 } | 1530 } |
1497 | 1531 |
1498 if (!IsStreamActive(stream_id)) { | 1532 if (!IsStreamActive(stream_id)) { |
1499 // NOTE: it may just be that the stream was cancelled. | 1533 // NOTE: it may just be that the stream was cancelled. |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1664 CHECK_EQ(stream->stream_id(), stream_id); | 1698 CHECK_EQ(stream->stream_id(), stream_id); |
1665 | 1699 |
1666 net_log_.AddEvent( | 1700 net_log_.AddEvent( |
1667 NetLog::TYPE_SPDY_SESSION_SENT_WINDOW_UPDATE, | 1701 NetLog::TYPE_SPDY_SESSION_SENT_WINDOW_UPDATE, |
1668 make_scoped_refptr(new NetLogSpdyWindowUpdateParameter( | 1702 make_scoped_refptr(new NetLogSpdyWindowUpdateParameter( |
1669 stream_id, delta_window_size))); | 1703 stream_id, delta_window_size))); |
1670 | 1704 |
1671 DCHECK(buffered_spdy_framer_.get()); | 1705 DCHECK(buffered_spdy_framer_.get()); |
1672 scoped_ptr<SpdyWindowUpdateControlFrame> window_update_frame( | 1706 scoped_ptr<SpdyWindowUpdateControlFrame> window_update_frame( |
1673 buffered_spdy_framer_->CreateWindowUpdate(stream_id, delta_window_size)); | 1707 buffered_spdy_framer_->CreateWindowUpdate(stream_id, delta_window_size)); |
1674 QueueFrame(window_update_frame.get(), stream->priority(), NULL); | 1708 QueueFrame(window_update_frame.release(), stream->priority()); |
1675 } | 1709 } |
1676 | 1710 |
1677 // Given a cwnd that we would have sent to the server, modify it based on the | 1711 // Given a cwnd that we would have sent to the server, modify it based on the |
1678 // field trial policy. | 1712 // field trial policy. |
1679 uint32 ApplyCwndFieldTrialPolicy(int cwnd) { | 1713 uint32 ApplyCwndFieldTrialPolicy(int cwnd) { |
1680 base::FieldTrial* trial = base::FieldTrialList::Find("SpdyCwnd"); | 1714 base::FieldTrial* trial = base::FieldTrialList::Find("SpdyCwnd"); |
1681 if (!trial) { | 1715 if (!trial) { |
1682 LOG(WARNING) << "Could not find \"SpdyCwnd\" in FieldTrialList"; | 1716 LOG(WARNING) << "Could not find \"SpdyCwnd\" in FieldTrialList"; |
1683 return cwnd; | 1717 return cwnd; |
1684 } | 1718 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1726 | 1760 |
1727 net_log_.AddEvent( | 1761 net_log_.AddEvent( |
1728 NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS, | 1762 NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS, |
1729 make_scoped_refptr(new NetLogSpdySettingsParameter(settings_map_new))); | 1763 make_scoped_refptr(new NetLogSpdySettingsParameter(settings_map_new))); |
1730 | 1764 |
1731 // Create the SETTINGS frame and send it. | 1765 // Create the SETTINGS frame and send it. |
1732 DCHECK(buffered_spdy_framer_.get()); | 1766 DCHECK(buffered_spdy_framer_.get()); |
1733 scoped_ptr<SpdySettingsControlFrame> settings_frame( | 1767 scoped_ptr<SpdySettingsControlFrame> settings_frame( |
1734 buffered_spdy_framer_->CreateSettings(settings_map_new)); | 1768 buffered_spdy_framer_->CreateSettings(settings_map_new)); |
1735 sent_settings_ = true; | 1769 sent_settings_ = true; |
1736 QueueFrame(settings_frame.get(), HIGHEST, NULL); | 1770 QueueFrame(settings_frame.release(), HIGHEST); |
1737 } | 1771 } |
1738 | 1772 |
1739 void SpdySession::HandleSetting(uint32 id, uint32 value) { | 1773 void SpdySession::HandleSetting(uint32 id, uint32 value) { |
1740 switch (id) { | 1774 switch (id) { |
1741 case SETTINGS_MAX_CONCURRENT_STREAMS: | 1775 case SETTINGS_MAX_CONCURRENT_STREAMS: |
1742 max_concurrent_streams_ = std::min(static_cast<size_t>(value), | 1776 max_concurrent_streams_ = std::min(static_cast<size_t>(value), |
1743 g_max_concurrent_stream_limit); | 1777 g_max_concurrent_stream_limit); |
1744 ProcessPendingCreateStreams(); | 1778 ProcessPendingCreateStreams(); |
1745 break; | 1779 break; |
1746 case SETTINGS_INITIAL_WINDOW_SIZE: | 1780 case SETTINGS_INITIAL_WINDOW_SIZE: |
(...skipping 16 matching lines...) Expand all Loading... |
1763 } | 1797 } |
1764 } | 1798 } |
1765 | 1799 |
1766 void SpdySession::UpdateStreamsSendWindowSize(int32 delta_window_size) { | 1800 void SpdySession::UpdateStreamsSendWindowSize(int32 delta_window_size) { |
1767 ActiveStreamMap::iterator it; | 1801 ActiveStreamMap::iterator it; |
1768 for (it = active_streams_.begin(); it != active_streams_.end(); ++it) { | 1802 for (it = active_streams_.begin(); it != active_streams_.end(); ++it) { |
1769 const scoped_refptr<SpdyStream>& stream = it->second; | 1803 const scoped_refptr<SpdyStream>& stream = it->second; |
1770 DCHECK(stream); | 1804 DCHECK(stream); |
1771 stream->AdjustSendWindowSize(delta_window_size); | 1805 stream->AdjustSendWindowSize(delta_window_size); |
1772 } | 1806 } |
| 1807 |
| 1808 CreatedStreamSet::iterator i; |
| 1809 for (i = created_streams_.begin(); i != created_streams_.end(); i++) { |
| 1810 const scoped_refptr<SpdyStream>& stream = *i; |
| 1811 stream->AdjustSendWindowSize(delta_window_size); |
| 1812 } |
1773 } | 1813 } |
1774 | 1814 |
1775 void SpdySession::SendPrefacePingIfNoneInFlight() { | 1815 void SpdySession::SendPrefacePingIfNoneInFlight() { |
1776 if (pings_in_flight_ || !g_enable_ping_based_connection_checking) | 1816 if (pings_in_flight_ || !g_enable_ping_based_connection_checking) |
1777 return; | 1817 return; |
1778 | 1818 |
1779 base::TimeTicks now = base::TimeTicks::Now(); | 1819 base::TimeTicks now = base::TimeTicks::Now(); |
1780 // If there is no activity in the session, then send a preface-PING. | 1820 // If there is no activity in the session, then send a preface-PING. |
1781 if ((now - last_activity_time_) > connection_at_risk_of_loss_time_) | 1821 if ((now - last_activity_time_) > connection_at_risk_of_loss_time_) |
1782 SendPrefacePing(); | 1822 SendPrefacePing(); |
1783 } | 1823 } |
1784 | 1824 |
1785 void SpdySession::SendPrefacePing() { | 1825 void SpdySession::SendPrefacePing() { |
1786 WritePingFrame(next_ping_id_); | 1826 WritePingFrame(next_ping_id_); |
1787 } | 1827 } |
1788 | 1828 |
1789 void SpdySession::WritePingFrame(uint32 unique_id) { | 1829 void SpdySession::WritePingFrame(uint32 unique_id) { |
1790 DCHECK(buffered_spdy_framer_.get()); | 1830 DCHECK(buffered_spdy_framer_.get()); |
1791 scoped_ptr<SpdyPingControlFrame> ping_frame( | 1831 scoped_ptr<SpdyPingControlFrame> ping_frame( |
1792 buffered_spdy_framer_->CreatePingFrame(next_ping_id_)); | 1832 buffered_spdy_framer_->CreatePingFrame(next_ping_id_)); |
1793 QueueFrame(ping_frame.get(), HIGHEST, NULL); | 1833 QueueFrame(ping_frame.release(), HIGHEST); |
1794 | 1834 |
1795 if (net_log().IsLoggingAllEvents()) { | 1835 if (net_log().IsLoggingAllEvents()) { |
1796 net_log().AddEvent( | 1836 net_log().AddEvent( |
1797 NetLog::TYPE_SPDY_SESSION_PING, | 1837 NetLog::TYPE_SPDY_SESSION_PING, |
1798 make_scoped_refptr(new NetLogSpdyPingParameter(next_ping_id_, "sent"))); | 1838 make_scoped_refptr(new NetLogSpdyPingParameter(next_ping_id_, "sent"))); |
1799 } | 1839 } |
1800 if (unique_id % 2 != 0) { | 1840 if (unique_id % 2 != 0) { |
1801 next_ping_id_ += 2; | 1841 next_ping_id_ += 2; |
1802 ++pings_in_flight_; | 1842 ++pings_in_flight_; |
1803 PlanToCheckPingStatus(); | 1843 PlanToCheckPingStatus(); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1946 SSLClientSocket* SpdySession::GetSSLClientSocket() const { | 1986 SSLClientSocket* SpdySession::GetSSLClientSocket() const { |
1947 if (!is_secure_) | 1987 if (!is_secure_) |
1948 return NULL; | 1988 return NULL; |
1949 SSLClientSocket* ssl_socket = | 1989 SSLClientSocket* ssl_socket = |
1950 reinterpret_cast<SSLClientSocket*>(connection_->socket()); | 1990 reinterpret_cast<SSLClientSocket*>(connection_->socket()); |
1951 DCHECK(ssl_socket); | 1991 DCHECK(ssl_socket); |
1952 return ssl_socket; | 1992 return ssl_socket; |
1953 } | 1993 } |
1954 | 1994 |
1955 } // namespace net | 1995 } // namespace net |
OLD | NEW |