Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: net/spdy/spdy_session.cc

Issue 10448083: Fix out of order SYN_STEAM frames. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Make SpdyFrameProducer a nested class in SpdySession. Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698