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

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

Issue 10815074: Instead of enqueueing SPDY frames, enqueue SPDY streams that are ready to produce data. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove logging and cleanup Created 8 years, 4 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
« no previous file with comments | « net/spdy/spdy_session.h ('k') | net/spdy/spdy_session_spdy2_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/bind.h" 10 #include "base/bind.h"
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 size_t g_default_initial_rcv_window_size = 10 * 1024 * 1024; // 10MB 187 size_t g_default_initial_rcv_window_size = 10 * 1024 * 1024; // 10MB
188 bool g_enable_ping_based_connection_checking = true; 188 bool g_enable_ping_based_connection_checking = true;
189 189
190 typedef base::TimeTicks (*ExternalTimeFunc)(void); 190 typedef base::TimeTicks (*ExternalTimeFunc)(void);
191 191
192 static ExternalTimeFunc g_time_func = base::TimeTicks::Now; 192 static ExternalTimeFunc g_time_func = base::TimeTicks::Now;
193 193
194 } // namespace 194 } // namespace
195 195
196 // static 196 // static
197 void SpdySession::SpdyIOBufferProducer::ActivateStream(
198 SpdySession* spdy_session,
199 SpdyStream* spdy_stream) {
200 spdy_session->ActivateStream(spdy_stream);
201 }
202
203 // static
204 SpdyIOBuffer* SpdySession::SpdyIOBufferProducer::CreateIOBuffer(
205 SpdyFrame* frame,
206 RequestPriority priority,
207 SpdyStream* stream) {
208 size_t size = frame->length() + SpdyFrame::kHeaderSize;
209 DCHECK_GT(size, 0u);
210
211 // TODO(mbelshe): We have too much copying of data here.
212 IOBufferWithSize* buffer = new IOBufferWithSize(size);
213 memcpy(buffer->data(), frame->data(), size);
214
215 return new SpdyIOBuffer(buffer, size, priority, stream);
216 }
217
218 // static
197 void SpdySession::set_default_protocol(NextProto default_protocol) { 219 void SpdySession::set_default_protocol(NextProto default_protocol) {
198 g_default_protocol = default_protocol; 220 g_default_protocol = default_protocol;
199 } 221 }
200 222
201 // static 223 // static
202 void SpdySession::set_max_concurrent_streams(size_t value) { 224 void SpdySession::set_max_concurrent_streams(size_t value) {
203 g_max_concurrent_stream_limit = value; 225 g_max_concurrent_stream_limit = value;
204 } 226 }
205 227
206 // static 228 // static
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 SSLInfo ssl_info; 404 SSLInfo ssl_info;
383 bool was_npn_negotiated; 405 bool was_npn_negotiated;
384 NextProto protocol_negotiated = kProtoUnknown; 406 NextProto protocol_negotiated = kProtoUnknown;
385 if (!GetSSLInfo(&ssl_info, &was_npn_negotiated, &protocol_negotiated)) 407 if (!GetSSLInfo(&ssl_info, &was_npn_negotiated, &protocol_negotiated))
386 return true; // This is not a secure session, so all domains are okay. 408 return true; // This is not a secure session, so all domains are okay.
387 409
388 return !ssl_info.channel_id_sent && !ssl_info.client_cert_sent && 410 return !ssl_info.channel_id_sent && !ssl_info.client_cert_sent &&
389 ssl_info.cert->VerifyNameMatch(domain); 411 ssl_info.cert->VerifyNameMatch(domain);
390 } 412 }
391 413
414 void SpdySession::SetStreamHasWriteAvailable(SpdyStream* stream,
415 SpdyIOBufferProducer* producer) {
416 write_queue_.push(producer);
417 stream_producers_[producer] = stream;
418 WriteSocketLater();
419 }
420
392 int SpdySession::GetPushStream( 421 int SpdySession::GetPushStream(
393 const GURL& url, 422 const GURL& url,
394 scoped_refptr<SpdyStream>* stream, 423 scoped_refptr<SpdyStream>* stream,
395 const BoundNetLog& stream_net_log) { 424 const BoundNetLog& stream_net_log) {
396 CHECK_NE(state_, CLOSED); 425 CHECK_NE(state_, CLOSED);
397 426
398 *stream = NULL; 427 *stream = NULL;
399 428
400 // Don't allow access to secure push streams over an unauthenticated, but 429 // Don't allow access to secure push streams over an unauthenticated, but
401 // encrypted SSL socket. 430 // encrypted SSL socket.
(...skipping 18 matching lines...) Expand all
420 return 0; 449 return 0;
421 } 450 }
422 451
423 int SpdySession::CreateStream( 452 int SpdySession::CreateStream(
424 const GURL& url, 453 const GURL& url,
425 RequestPriority priority, 454 RequestPriority priority,
426 scoped_refptr<SpdyStream>* spdy_stream, 455 scoped_refptr<SpdyStream>* spdy_stream,
427 const BoundNetLog& stream_net_log, 456 const BoundNetLog& stream_net_log,
428 const CompletionCallback& callback) { 457 const CompletionCallback& callback) {
429 if (!max_concurrent_streams_ || 458 if (!max_concurrent_streams_ ||
430 active_streams_.size() < max_concurrent_streams_) { 459 (active_streams_.size() + created_streams_.size() <
460 max_concurrent_streams_)) {
431 return CreateStreamImpl(url, priority, spdy_stream, stream_net_log); 461 return CreateStreamImpl(url, priority, spdy_stream, stream_net_log);
432 } 462 }
433 463
434 stalled_streams_++; 464 stalled_streams_++;
435 net_log().AddEvent(NetLog::TYPE_SPDY_SESSION_STALLED_MAX_STREAMS); 465 net_log().AddEvent(NetLog::TYPE_SPDY_SESSION_STALLED_MAX_STREAMS);
436 create_stream_queues_[priority].push( 466 create_stream_queues_[priority].push(
437 PendingCreateStream(url, priority, spdy_stream, 467 PendingCreateStream(url, priority, spdy_stream,
438 stream_net_log, callback)); 468 stream_net_log, callback));
439 return ERR_IO_PENDING; 469 return ERR_IO_PENDING;
440 } 470 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 CloseSessionOnError( 540 CloseSessionOnError(
511 static_cast<net::Error>(certificate_error_code_), 541 static_cast<net::Error>(certificate_error_code_),
512 true, 542 true,
513 "Tried to create SPDY stream for secure content over an " 543 "Tried to create SPDY stream for secure content over an "
514 "unauthenticated session."); 544 "unauthenticated session.");
515 return ERR_SPDY_PROTOCOL_ERROR; 545 return ERR_SPDY_PROTOCOL_ERROR;
516 } 546 }
517 547
518 const std::string& path = url.PathForRequest(); 548 const std::string& path = url.PathForRequest();
519 549
520 const SpdyStreamId stream_id = GetNewStreamId();
521
522 *spdy_stream = new SpdyStream(this, 550 *spdy_stream = new SpdyStream(this,
523 stream_id,
524 false, 551 false,
525 stream_net_log); 552 stream_net_log);
526 const scoped_refptr<SpdyStream>& stream = *spdy_stream; 553 const scoped_refptr<SpdyStream>& stream = *spdy_stream;
527 554
528 stream->set_priority(priority); 555 stream->set_priority(priority);
529 stream->set_path(path); 556 stream->set_path(path);
530 stream->set_send_window_size(initial_send_window_size_); 557 stream->set_send_window_size(initial_send_window_size_);
531 stream->set_recv_window_size(initial_recv_window_size_); 558 stream->set_recv_window_size(initial_recv_window_size_);
532 ActivateStream(stream); 559 created_streams_.insert(stream);
533 560
534 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyPriorityCount", 561 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyPriorityCount",
535 static_cast<int>(priority), 0, 10, 11); 562 static_cast<int>(priority), 0, 10, 11);
536 563
537 // TODO(mbelshe): Optimize memory allocations 564 // TODO(mbelshe): Optimize memory allocations
538 565
539 DCHECK_EQ(active_streams_[stream_id].get(), stream.get());
540 return OK; 566 return OK;
541 } 567 }
542 568
543 bool SpdySession::NeedsCredentials() const { 569 bool SpdySession::NeedsCredentials() const {
544 if (!is_secure_) 570 if (!is_secure_)
545 return false; 571 return false;
546 SSLClientSocket* ssl_socket = GetSSLClientSocket(); 572 SSLClientSocket* ssl_socket = GetSSLClientSocket();
547 if (ssl_socket->GetNegotiatedProtocol() < kProtoSPDY3) 573 if (ssl_socket->GetNegotiatedProtocol() < kProtoSPDY3)
548 return false; 574 return false;
549 return ssl_socket->WasChannelIDSent(); 575 return ssl_socket->WasChannelIDSent();
550 } 576 }
551 577
552 void SpdySession::AddPooledAlias(const HostPortProxyPair& alias) { 578 void SpdySession::AddPooledAlias(const HostPortProxyPair& alias) {
553 pooled_aliases_.insert(alias); 579 pooled_aliases_.insert(alias);
554 } 580 }
555 581
556 int SpdySession::GetProtocolVersion() const { 582 int SpdySession::GetProtocolVersion() const {
557 DCHECK(buffered_spdy_framer_.get()); 583 DCHECK(buffered_spdy_framer_.get());
558 return buffered_spdy_framer_->protocol_version(); 584 return buffered_spdy_framer_->protocol_version();
559 } 585 }
560 586
561 int SpdySession::WriteSynStream( 587 SpdySynStreamControlFrame* SpdySession::CreateSynStream(
562 SpdyStreamId stream_id, 588 SpdyStreamId stream_id,
563 RequestPriority priority, 589 RequestPriority priority,
564 uint8 credential_slot, 590 uint8 credential_slot,
565 SpdyControlFlags flags, 591 SpdyControlFlags flags,
566 const SpdyHeaderBlock& headers) { 592 const SpdyHeaderBlock& headers) {
567 // Find our stream 593 CHECK(IsStreamActive(stream_id));
568 if (!IsStreamActive(stream_id))
569 return ERR_INVALID_SPDY_STREAM;
570 const scoped_refptr<SpdyStream>& stream = active_streams_[stream_id]; 594 const scoped_refptr<SpdyStream>& stream = active_streams_[stream_id];
571 CHECK_EQ(stream->stream_id(), stream_id); 595 CHECK_EQ(stream->stream_id(), stream_id);
572 596
573 SendPrefacePingIfNoneInFlight(); 597 SendPrefacePingIfNoneInFlight();
574 598
575 DCHECK(buffered_spdy_framer_.get()); 599 DCHECK(buffered_spdy_framer_.get());
576 scoped_ptr<SpdySynStreamControlFrame> syn_frame( 600 scoped_ptr<SpdySynStreamControlFrame> syn_frame(
577 buffered_spdy_framer_->CreateSynStream( 601 buffered_spdy_framer_->CreateSynStream(
578 stream_id, 0, 602 stream_id, 0,
579 ConvertRequestPriorityToSpdyPriority(priority, GetProtocolVersion()), 603 ConvertRequestPriorityToSpdyPriority(priority, GetProtocolVersion()),
580 credential_slot, flags, false, &headers)); 604 credential_slot, flags, true, &headers));
581 // We enqueue all SYN_STREAM frames at the same priority to ensure
582 // that we do not send them out-of-order.
583 // http://crbug.com/111708
584 QueueFrame(syn_frame.get(), HIGHEST, stream);
585 605
586 base::StatsCounter spdy_requests("spdy.requests"); 606 base::StatsCounter spdy_requests("spdy.requests");
587 spdy_requests.Increment(); 607 spdy_requests.Increment();
588 streams_initiated_count_++; 608 streams_initiated_count_++;
589 609
590 if (net_log().IsLoggingAllEvents()) { 610 if (net_log().IsLoggingAllEvents()) {
591 net_log().AddEvent( 611 net_log().AddEvent(
592 NetLog::TYPE_SPDY_SESSION_SYN_STREAM, 612 NetLog::TYPE_SPDY_SESSION_SYN_STREAM,
593 base::Bind(&NetLogSpdySynCallback, &headers, 613 base::Bind(&NetLogSpdySynCallback, &headers,
594 (flags & CONTROL_FLAG_FIN) != 0, 614 (flags & CONTROL_FLAG_FIN) != 0,
595 (flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0, 615 (flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0,
596 stream_id, 0)); 616 stream_id, 0));
597 } 617 }
598 618
599 return ERR_IO_PENDING; 619 return syn_frame.release();
600 } 620 }
601 621
602 int SpdySession::WriteCredentialFrame(const std::string& origin, 622 SpdyCredentialControlFrame* SpdySession::CreateCredentialFrame(
603 SSLClientCertType type, 623 const std::string& origin,
604 const std::string& key, 624 SSLClientCertType type,
605 const std::string& cert, 625 const std::string& key,
606 RequestPriority priority) { 626 const std::string& cert,
627 RequestPriority priority) {
607 DCHECK(is_secure_); 628 DCHECK(is_secure_);
608 unsigned char secret[32]; // 32 bytes from the spec 629 unsigned char secret[32]; // 32 bytes from the spec
609 GetSSLClientSocket()->ExportKeyingMaterial("SPDY certificate proof", 630 GetSSLClientSocket()->ExportKeyingMaterial("SPDY certificate proof",
610 true, origin, 631 true, origin,
611 secret, arraysize(secret)); 632 secret, arraysize(secret));
612 633
613 // Convert the key string into a vector<unit8> 634 // Convert the key string into a vector<unit8>
614 std::vector<uint8> key_data; 635 std::vector<uint8> key_data;
615 for (size_t i = 0; i < key.length(); i++) { 636 for (size_t i = 0; i < key.length(); i++) {
616 key_data.push_back(key[i]); 637 key_data.push_back(key[i]);
(...skipping 21 matching lines...) Expand all
638 SpdyCredential credential; 659 SpdyCredential credential;
639 GURL origin_url(origin); 660 GURL origin_url(origin);
640 credential.slot = 661 credential.slot =
641 credential_state_.SetHasCredential(origin_url); 662 credential_state_.SetHasCredential(origin_url);
642 credential.certs.push_back(cert); 663 credential.certs.push_back(cert);
643 credential.proof.assign(proof.begin(), proof.end()); 664 credential.proof.assign(proof.begin(), proof.end());
644 665
645 DCHECK(buffered_spdy_framer_.get()); 666 DCHECK(buffered_spdy_framer_.get());
646 scoped_ptr<SpdyCredentialControlFrame> credential_frame( 667 scoped_ptr<SpdyCredentialControlFrame> credential_frame(
647 buffered_spdy_framer_->CreateCredentialFrame(credential)); 668 buffered_spdy_framer_->CreateCredentialFrame(credential));
648 // We enqueue all SYN_STREAM frames at the same priority to ensure
649 // that we do not send them out-of-order, which means that we need
650 // to enqueue all CREDENTIAL frames at this priority to ensure that
651 // they are sent *before* the SYN_STREAM that references them.
652 // http://crbug.com/111708
653 QueueFrame(credential_frame.get(), HIGHEST, NULL);
654 669
655 if (net_log().IsLoggingAllEvents()) { 670 if (net_log().IsLoggingAllEvents()) {
656 net_log().AddEvent( 671 net_log().AddEvent(
657 NetLog::TYPE_SPDY_SESSION_SEND_CREDENTIAL, 672 NetLog::TYPE_SPDY_SESSION_SEND_CREDENTIAL,
658 base::Bind(&NetLogSpdyCredentialCallback, credential.slot, &origin)); 673 base::Bind(&NetLogSpdyCredentialCallback, credential.slot, &origin));
659 } 674 }
660 return ERR_IO_PENDING; 675 return credential_frame.release();
661 } 676 }
662 677
663 int SpdySession::WriteStreamData(SpdyStreamId stream_id, 678 SpdyDataFrame* SpdySession::CreateDataFrame(SpdyStreamId stream_id,
664 net::IOBuffer* data, int len, 679 net::IOBuffer* data, int len,
665 SpdyDataFlags flags) { 680 SpdyDataFlags flags) {
666 // Find our stream 681 // Find our stream
667 CHECK(IsStreamActive(stream_id)); 682 CHECK(IsStreamActive(stream_id));
668 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; 683 scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
669 CHECK_EQ(stream->stream_id(), stream_id); 684 CHECK_EQ(stream->stream_id(), stream_id);
670 685
671 if (len > kMaxSpdyFrameChunkSize) { 686 if (len > kMaxSpdyFrameChunkSize) {
672 len = kMaxSpdyFrameChunkSize; 687 len = kMaxSpdyFrameChunkSize;
673 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN); 688 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN);
674 } 689 }
675 690
676 // Obey send window size of the stream if flow control is enabled. 691 // Obey send window size of the stream if flow control is enabled.
677 if (flow_control_) { 692 if (flow_control_) {
678 if (stream->send_window_size() <= 0) { 693 if (stream->send_window_size() <= 0) {
679 // Because we queue frames onto the session, it is possible that 694 // Because we queue frames onto the session, it is possible that
680 // a stream was not flow controlled at the time it attempted the 695 // a stream was not flow controlled at the time it attempted the
681 // write, but when we go to fulfill the write, it is now flow 696 // write, but when we go to fulfill the write, it is now flow
682 // controlled. This is why we need the session to mark the stream 697 // controlled. This is why we need the session to mark the stream
683 // as stalled - because only the session knows for sure when the 698 // as stalled - because only the session knows for sure when the
684 // stall occurs. 699 // stall occurs.
685 stream->set_stalled_by_flow_control(true); 700 stream->set_stalled_by_flow_control(true);
686 net_log().AddEvent( 701 net_log().AddEvent(
687 NetLog::TYPE_SPDY_SESSION_STALLED_ON_SEND_WINDOW, 702 NetLog::TYPE_SPDY_SESSION_STALLED_ON_SEND_WINDOW,
688 NetLog::IntegerCallback("stream_id", stream_id)); 703 NetLog::IntegerCallback("stream_id", stream_id));
689 return ERR_IO_PENDING; 704 return NULL;
690 } 705 }
691 int new_len = std::min(len, stream->send_window_size()); 706 int new_len = std::min(len, stream->send_window_size());
692 if (new_len < len) { 707 if (new_len < len) {
693 len = new_len; 708 len = new_len;
694 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN); 709 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN);
695 } 710 }
696 stream->DecreaseSendWindowSize(len); 711 stream->DecreaseSendWindowSize(len);
697 } 712 }
698 713
699 if (net_log().IsLoggingAllEvents()) { 714 if (net_log().IsLoggingAllEvents()) {
700 net_log().AddEvent( 715 net_log().AddEvent(
701 NetLog::TYPE_SPDY_SESSION_SEND_DATA, 716 NetLog::TYPE_SPDY_SESSION_SEND_DATA,
702 base::Bind(&NetLogSpdyDataCallback, stream_id, len, flags)); 717 base::Bind(&NetLogSpdyDataCallback, stream_id, len, flags));
703 } 718 }
704 719
705 // Send PrefacePing for DATA_FRAMEs with nonzero payload size. 720 // Send PrefacePing for DATA_FRAMEs with nonzero payload size.
706 if (len > 0) 721 if (len > 0)
707 SendPrefacePingIfNoneInFlight(); 722 SendPrefacePingIfNoneInFlight();
708 723
709 // TODO(mbelshe): reduce memory copies here. 724 // TODO(mbelshe): reduce memory copies here.
710 DCHECK(buffered_spdy_framer_.get()); 725 DCHECK(buffered_spdy_framer_.get());
711 scoped_ptr<SpdyDataFrame> frame( 726 scoped_ptr<SpdyDataFrame> frame(
712 buffered_spdy_framer_->CreateDataFrame( 727 buffered_spdy_framer_->CreateDataFrame(
713 stream_id, data->data(), len, flags)); 728 stream_id, data->data(), len, flags));
714 QueueFrame(frame.get(), stream->priority(), stream);
715 729
716 return ERR_IO_PENDING; 730 return frame.release();
717 } 731 }
718 732
719 void SpdySession::CloseStream(SpdyStreamId stream_id, int status) { 733 void SpdySession::CloseStream(SpdyStreamId stream_id, int status) {
734 DCHECK_NE(0u, stream_id);
720 // TODO(mbelshe): We should send a RST_STREAM control frame here 735 // TODO(mbelshe): We should send a RST_STREAM control frame here
721 // so that the server can cancel a large send. 736 // so that the server can cancel a large send.
722 737
723 DeleteStream(stream_id, status); 738 DeleteStream(stream_id, status);
724 } 739 }
725 740
741 void SpdySession::CloseCreatedStream(SpdyStream* stream, int status) {
742 DCHECK_EQ(0u, stream->stream_id());
743 created_streams_.erase(scoped_refptr<SpdyStream>(stream));
744 }
745
726 void SpdySession::ResetStream(SpdyStreamId stream_id, 746 void SpdySession::ResetStream(SpdyStreamId stream_id,
727 SpdyStatusCodes status, 747 SpdyStatusCodes status,
728 const std::string& description) { 748 const std::string& description) {
729 net_log().AddEvent( 749 net_log().AddEvent(
730 NetLog::TYPE_SPDY_SESSION_SEND_RST_STREAM, 750 NetLog::TYPE_SPDY_SESSION_SEND_RST_STREAM,
731 base::Bind(&NetLogSpdyRstCallback, stream_id, status, &description)); 751 base::Bind(&NetLogSpdyRstCallback, stream_id, status, &description));
732 752
733 DCHECK(buffered_spdy_framer_.get()); 753 DCHECK(buffered_spdy_framer_.get());
734 scoped_ptr<SpdyRstStreamControlFrame> rst_frame( 754 scoped_ptr<SpdyRstStreamControlFrame> rst_frame(
735 buffered_spdy_framer_->CreateRstStream(stream_id, status)); 755 buffered_spdy_framer_->CreateRstStream(stream_id, status));
736 756
737 // Default to lowest priority unless we know otherwise. 757 // Default to lowest priority unless we know otherwise.
738 RequestPriority priority = net::IDLE; 758 RequestPriority priority = net::IDLE;
739 if(IsStreamActive(stream_id)) { 759 if(IsStreamActive(stream_id)) {
740 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; 760 scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
741 priority = stream->priority(); 761 priority = stream->priority();
742 } 762 }
743 QueueFrame(rst_frame.get(), priority, NULL); 763 QueueFrame(rst_frame.release(), priority);
744 RecordProtocolErrorHistogram( 764 RecordProtocolErrorHistogram(
745 static_cast<SpdyProtocolErrorDetails>(status + STATUS_CODE_INVALID)); 765 static_cast<SpdyProtocolErrorDetails>(status + STATUS_CODE_INVALID));
746 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); 766 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR);
747 } 767 }
748 768
749 bool SpdySession::IsStreamActive(SpdyStreamId stream_id) const { 769 bool SpdySession::IsStreamActive(SpdyStreamId stream_id) const {
750 return ContainsKey(active_streams_, stream_id); 770 return ContainsKey(active_streams_, stream_id);
751 } 771 }
752 772
753 LoadState SpdySession::GetLoadState() const { 773 LoadState SpdySession::GetLoadState() const {
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 // closed, just return. 941 // closed, just return.
922 if (state_ < CONNECTED || state_ == CLOSED) 942 if (state_ < CONNECTED || state_ == CLOSED)
923 return; 943 return;
924 944
925 if (write_pending_) // Another write is in progress still. 945 if (write_pending_) // Another write is in progress still.
926 return; 946 return;
927 947
928 // Loop sending frames until we've sent everything or until the write 948 // Loop sending frames until we've sent everything or until the write
929 // returns error (or ERR_IO_PENDING). 949 // returns error (or ERR_IO_PENDING).
930 DCHECK(buffered_spdy_framer_.get()); 950 DCHECK(buffered_spdy_framer_.get());
931 while (in_flight_write_.buffer() || !queue_.empty()) { 951 while (in_flight_write_.buffer() || !write_queue_.empty()) {
932 if (!in_flight_write_.buffer()) { 952 if (!in_flight_write_.buffer()) {
933 // Grab the next SpdyFrame to send. 953 // Grab the next SpdyBuffer to send.
934 SpdyIOBuffer next_buffer = queue_.top(); 954 scoped_ptr<SpdyIOBufferProducer> producer(write_queue_.top());
935 queue_.pop(); 955 write_queue_.pop();
956 scoped_ptr<SpdyIOBuffer> buffer(producer->ProduceNextBuffer(this));
957 stream_producers_.erase(producer.get());
958 // It is possible that a stream had data to write, but a
959 // WINDOW_UPDATE frame has been received which made that
960 // stream no longer writable.
961 // TODO(rch): consider handling that case by removing the
962 // stream from the writable queue?
963 if (buffer == NULL)
964 continue;
936 965
937 // We've deferred compression until just before we write it to the socket, 966 in_flight_write_ = *buffer;
938 // which is now. At this time, we don't compress our data frames.
939 SpdyFrame uncompressed_frame(next_buffer.buffer()->data(), false);
940 size_t size;
941 if (buffered_spdy_framer_->IsCompressible(uncompressed_frame)) {
942 DCHECK(uncompressed_frame.is_control_frame());
943 const SpdyControlFrame* uncompressed_control_frame =
944 reinterpret_cast<const SpdyControlFrame*>(&uncompressed_frame);
945 scoped_ptr<SpdyFrame> compressed_frame(
946 buffered_spdy_framer_->CompressControlFrame(
947 *uncompressed_control_frame));
948 if (!compressed_frame.get()) {
949 RecordProtocolErrorHistogram(
950 PROTOCOL_ERROR_SPDY_COMPRESSION_FAILURE);
951 CloseSessionOnError(
952 net::ERR_SPDY_PROTOCOL_ERROR, true, "SPDY Compression failure.");
953 return;
954 }
955
956 size = compressed_frame->length() + SpdyFrame::kHeaderSize;
957
958 DCHECK_GT(size, 0u);
959
960 // TODO(mbelshe): We have too much copying of data here.
961 IOBufferWithSize* buffer = new IOBufferWithSize(size);
962 memcpy(buffer->data(), compressed_frame->data(), size);
963
964 // Attempt to send the frame.
965 in_flight_write_ = SpdyIOBuffer(buffer, size, HIGHEST,
966 next_buffer.stream());
967 } else {
968 size = uncompressed_frame.length() + SpdyFrame::kHeaderSize;
969 in_flight_write_ = next_buffer;
970 }
971 } else { 967 } else {
972 DCHECK(in_flight_write_.buffer()->BytesRemaining()); 968 DCHECK(in_flight_write_.buffer()->BytesRemaining());
973 } 969 }
974 970
975 write_pending_ = true; 971 write_pending_ = true;
976 int rv = connection_->socket()->Write( 972 int rv = connection_->socket()->Write(
977 in_flight_write_.buffer(), 973 in_flight_write_.buffer(),
978 in_flight_write_.buffer()->BytesRemaining(), 974 in_flight_write_.buffer()->BytesRemaining(),
979 base::Bind(&SpdySession::OnWriteComplete, base::Unretained(this))); 975 base::Bind(&SpdySession::OnWriteComplete, base::Unretained(this)));
980 if (rv == net::ERR_IO_PENDING) 976 if (rv == net::ERR_IO_PENDING)
(...skipping 26 matching lines...) Expand all
1007 while (!create_stream_queues_[i].empty()) { 1003 while (!create_stream_queues_[i].empty()) {
1008 PendingCreateStream pending_create = create_stream_queues_[i].front(); 1004 PendingCreateStream pending_create = create_stream_queues_[i].front();
1009 create_stream_queues_[i].pop(); 1005 create_stream_queues_[i].pop();
1010 pending_create.callback.Run(ERR_ABORTED); 1006 pending_create.callback.Run(ERR_ABORTED);
1011 } 1007 }
1012 } 1008 }
1013 1009
1014 while (!active_streams_.empty()) { 1010 while (!active_streams_.empty()) {
1015 ActiveStreamMap::iterator it = active_streams_.begin(); 1011 ActiveStreamMap::iterator it = active_streams_.begin();
1016 const scoped_refptr<SpdyStream>& stream = it->second; 1012 const scoped_refptr<SpdyStream>& stream = it->second;
1017 DCHECK(stream); 1013 LogAbandonedStream(stream, status);
1018 std::string description = base::StringPrintf(
1019 "ABANDONED (stream_id=%d): ", stream->stream_id()) + stream->path();
1020 stream->LogStreamError(status, description);
1021 DeleteStream(stream->stream_id(), status); 1014 DeleteStream(stream->stream_id(), status);
1022 } 1015 }
1023 1016
1017 while (!created_streams_.empty()) {
1018 CreatedStreamSet::iterator it = created_streams_.begin();
1019 const scoped_refptr<SpdyStream>& stream = *it;
1020 LogAbandonedStream(stream, status);
1021 stream->OnClose(status);
1022 created_streams_.erase(it);
1023 }
1024
1024 // We also need to drain the queue. 1025 // We also need to drain the queue.
1025 while (queue_.size()) 1026 while (!write_queue_.empty()) {
1026 queue_.pop(); 1027 scoped_ptr<SpdyIOBufferProducer> producer(write_queue_.top());
1028 write_queue_.pop();
1029 stream_producers_.erase(producer.get());
1030 }
1031 }
1032
1033 void SpdySession::LogAbandonedStream(const scoped_refptr<SpdyStream>& stream,
1034 net::Error status) {
1035 DCHECK(stream);
1036 std::string description = base::StringPrintf(
1037 "ABANDONED (stream_id=%d): ", stream->stream_id()) + stream->path();
1038 stream->LogStreamError(status, description);
1027 } 1039 }
1028 1040
1029 int SpdySession::GetNewStreamId() { 1041 int SpdySession::GetNewStreamId() {
1030 int id = stream_hi_water_mark_; 1042 int id = stream_hi_water_mark_;
1031 stream_hi_water_mark_ += 2; 1043 stream_hi_water_mark_ += 2;
1032 if (stream_hi_water_mark_ > 0x7fff) 1044 if (stream_hi_water_mark_ > 0x7fff)
1033 stream_hi_water_mark_ = 1; 1045 stream_hi_water_mark_ = 1;
1034 return id; 1046 return id;
1035 } 1047 }
1036 1048
1037 void SpdySession::QueueFrame(SpdyFrame* frame,
1038 RequestPriority priority,
1039 SpdyStream* stream) {
1040 int length = SpdyFrame::kHeaderSize + frame->length();
1041 IOBuffer* buffer = new IOBuffer(length);
1042 memcpy(buffer->data(), frame->data(), length);
1043 queue_.push(SpdyIOBuffer(buffer, length, priority, stream));
1044
1045 WriteSocketLater();
1046 }
1047
1048 void SpdySession::CloseSessionOnError(net::Error err, 1049 void SpdySession::CloseSessionOnError(net::Error err,
1049 bool remove_from_pool, 1050 bool remove_from_pool,
1050 const std::string& description) { 1051 const std::string& description) {
1051 // Closing all streams can have a side-effect of dropping the last reference 1052 // Closing all streams can have a side-effect of dropping the last reference
1052 // to |this|. Hold a reference through this function. 1053 // to |this|. Hold a reference through this function.
1053 scoped_refptr<SpdySession> self(this); 1054 scoped_refptr<SpdySession> self(this);
1054 1055
1055 DCHECK_LT(err, OK); 1056 DCHECK_LT(err, OK);
1056 net_log_.AddEvent( 1057 net_log_.AddEvent(
1057 NetLog::TYPE_SPDY_SESSION_CLOSE, 1058 NetLog::TYPE_SPDY_SESSION_CLOSE,
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1124 return connection_->socket()->GetPeerAddress(address); 1125 return connection_->socket()->GetPeerAddress(address);
1125 } 1126 }
1126 1127
1127 int SpdySession::GetLocalAddress(IPEndPoint* address) const { 1128 int SpdySession::GetLocalAddress(IPEndPoint* address) const {
1128 if (!connection_->socket()) 1129 if (!connection_->socket())
1129 return ERR_SOCKET_NOT_CONNECTED; 1130 return ERR_SOCKET_NOT_CONNECTED;
1130 1131
1131 return connection_->socket()->GetLocalAddress(address); 1132 return connection_->socket()->GetLocalAddress(address);
1132 } 1133 }
1133 1134
1135 class SimpleSpdyIOBufferProducer : public SpdySession::SpdyIOBufferProducer {
1136 public:
1137 SimpleSpdyIOBufferProducer(SpdyFrame* frame,
1138 RequestPriority priority)
1139 : frame_(frame),
1140 priority_(priority) {
1141 }
1142
1143 virtual RequestPriority GetPriority() const OVERRIDE {
1144 return priority_;
1145 }
1146
1147 virtual SpdyIOBuffer* ProduceNextBuffer(SpdySession* session) {
1148 return SpdySession::SpdyIOBufferProducer::CreateIOBuffer(
1149 frame_.get(), priority_, NULL);
1150 }
1151
1152 private:
1153 scoped_ptr<SpdyFrame> frame_;
1154 RequestPriority priority_;
1155 };
1156
1157 void SpdySession::QueueFrame(SpdyFrame* frame,
1158 RequestPriority priority) {
1159 SimpleSpdyIOBufferProducer* producer =
1160 new SimpleSpdyIOBufferProducer(frame, priority);
1161 write_queue_.push(producer);
1162 WriteSocketLater();
1163 }
1164
1134 void SpdySession::ActivateStream(SpdyStream* stream) { 1165 void SpdySession::ActivateStream(SpdyStream* stream) {
1166 if (stream->stream_id() == 0) {
1167 stream->set_stream_id(GetNewStreamId());
1168 created_streams_.erase(scoped_refptr<SpdyStream>(stream));
1169 }
1135 const SpdyStreamId id = stream->stream_id(); 1170 const SpdyStreamId id = stream->stream_id();
1136 DCHECK(!IsStreamActive(id)); 1171 DCHECK(!IsStreamActive(id));
1137 1172
1138 active_streams_[id] = stream; 1173 active_streams_[id] = stream;
1139 } 1174 }
1140 1175
1141 void SpdySession::DeleteStream(SpdyStreamId id, int status) { 1176 void SpdySession::DeleteStream(SpdyStreamId id, int status) {
1142 // For push streams, if they are being deleted normally, we leave 1177 // For push streams, if they are being deleted normally, we leave
1143 // the stream in the unclaimed_pushed_streams_ list. However, if 1178 // the stream in the unclaimed_pushed_streams_ list. However, if
1144 // the stream is errored out, clean it up entirely. 1179 // the stream is errored out, clean it up entirely.
1145 if (status != OK) { 1180 if (status != OK) {
1146 PushedStreamMap::iterator it; 1181 PushedStreamMap::iterator it;
1147 for (it = unclaimed_pushed_streams_.begin(); 1182 for (it = unclaimed_pushed_streams_.begin();
1148 it != unclaimed_pushed_streams_.end(); ++it) { 1183 it != unclaimed_pushed_streams_.end(); ++it) {
1149 scoped_refptr<SpdyStream> curr = it->second.first; 1184 scoped_refptr<SpdyStream> curr = it->second.first;
1150 if (id == curr->stream_id()) { 1185 if (id == curr->stream_id()) {
1151 unclaimed_pushed_streams_.erase(it); 1186 unclaimed_pushed_streams_.erase(it);
1152 break; 1187 break;
1153 } 1188 }
1154 } 1189 }
1155 } 1190 }
1156 1191
1157 // The stream might have been deleted. 1192 // The stream might have been deleted.
1158 ActiveStreamMap::iterator it2 = active_streams_.find(id); 1193 ActiveStreamMap::iterator it2 = active_streams_.find(id);
1159 if (it2 == active_streams_.end()) 1194 if (it2 == active_streams_.end())
1160 return; 1195 return;
1161 1196
1197 // Possibly remove from the write queue.
1198 WriteQueue old = write_queue_;
1199 write_queue_ = WriteQueue();
1200 while (!old.empty()) {
1201 scoped_ptr<SpdyIOBufferProducer> producer(old.top());
1202 old.pop();
1203 StreamProducerMap::iterator it = stream_producers_.find(producer.get());
1204 if (it == stream_producers_.end() || it->second->stream_id() != id) {
1205 write_queue_.push(producer.release());
1206 } else {
1207 stream_producers_.erase(producer.get());
1208 producer.reset(NULL);
1209 }
1210 }
1211
1162 // If this is an active stream, call the callback. 1212 // If this is an active stream, call the callback.
1163 const scoped_refptr<SpdyStream> stream(it2->second); 1213 const scoped_refptr<SpdyStream> stream(it2->second);
1164 active_streams_.erase(it2); 1214 active_streams_.erase(it2);
1165 if (stream) 1215 if (stream)
1166 stream->OnClose(status); 1216 stream->OnClose(status);
1167 ProcessPendingCreateStreams(); 1217 ProcessPendingCreateStreams();
1168 } 1218 }
1169 1219
1170 void SpdySession::RemoveFromPool() { 1220 void SpdySession::RemoveFromPool() {
1171 if (spdy_session_pool_) { 1221 if (spdy_session_pool_) {
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
1372 } 1422 }
1373 1423
1374 // There should not be an existing pushed stream with the same path. 1424 // There should not be an existing pushed stream with the same path.
1375 PushedStreamMap::iterator it = unclaimed_pushed_streams_.find(url); 1425 PushedStreamMap::iterator it = unclaimed_pushed_streams_.find(url);
1376 if (it != unclaimed_pushed_streams_.end()) { 1426 if (it != unclaimed_pushed_streams_.end()) {
1377 ResetStream(stream_id, PROTOCOL_ERROR, 1427 ResetStream(stream_id, PROTOCOL_ERROR,
1378 "Received duplicate pushed stream with url: " + url); 1428 "Received duplicate pushed stream with url: " + url);
1379 return; 1429 return;
1380 } 1430 }
1381 1431
1382 scoped_refptr<SpdyStream> stream( 1432 scoped_refptr<SpdyStream> stream(new SpdyStream(this, true, net_log_));
1383 new SpdyStream(this, stream_id, true, net_log_)); 1433 stream->set_stream_id(stream_id);
1384 1434
1385 stream->set_path(gurl.PathForRequest()); 1435 stream->set_path(gurl.PathForRequest());
1386 stream->set_send_window_size(initial_send_window_size_); 1436 stream->set_send_window_size(initial_send_window_size_);
1387 stream->set_recv_window_size(initial_recv_window_size_); 1437 stream->set_recv_window_size(initial_recv_window_size_);
1388 1438
1389 DeleteExpiredPushedStreams(); 1439 DeleteExpiredPushedStreams();
1390 unclaimed_pushed_streams_[url] = 1440 unclaimed_pushed_streams_[url] =
1391 std::pair<scoped_refptr<SpdyStream>, base::TimeTicks> ( 1441 std::pair<scoped_refptr<SpdyStream>, base::TimeTicks> (
1392 stream, g_time_func()); 1442 stream, g_time_func());
1393 1443
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
1611 CHECK_EQ(stream->stream_id(), stream_id); 1661 CHECK_EQ(stream->stream_id(), stream_id);
1612 1662
1613 net_log_.AddEvent( 1663 net_log_.AddEvent(
1614 NetLog::TYPE_SPDY_SESSION_SENT_WINDOW_UPDATE, 1664 NetLog::TYPE_SPDY_SESSION_SENT_WINDOW_UPDATE,
1615 base::Bind(&NetLogSpdyWindowUpdateCallback, 1665 base::Bind(&NetLogSpdyWindowUpdateCallback,
1616 stream_id, delta_window_size)); 1666 stream_id, delta_window_size));
1617 1667
1618 DCHECK(buffered_spdy_framer_.get()); 1668 DCHECK(buffered_spdy_framer_.get());
1619 scoped_ptr<SpdyWindowUpdateControlFrame> window_update_frame( 1669 scoped_ptr<SpdyWindowUpdateControlFrame> window_update_frame(
1620 buffered_spdy_framer_->CreateWindowUpdate(stream_id, delta_window_size)); 1670 buffered_spdy_framer_->CreateWindowUpdate(stream_id, delta_window_size));
1621 QueueFrame(window_update_frame.get(), stream->priority(), NULL); 1671 QueueFrame(window_update_frame.release(), stream->priority());
1622 } 1672 }
1623 1673
1624 // Given a cwnd that we would have sent to the server, modify it based on the 1674 // Given a cwnd that we would have sent to the server, modify it based on the
1625 // field trial policy. 1675 // field trial policy.
1626 uint32 ApplyCwndFieldTrialPolicy(int cwnd) { 1676 uint32 ApplyCwndFieldTrialPolicy(int cwnd) {
1627 base::FieldTrial* trial = base::FieldTrialList::Find("SpdyCwnd"); 1677 base::FieldTrial* trial = base::FieldTrialList::Find("SpdyCwnd");
1628 if (!trial) { 1678 if (!trial) {
1629 LOG(WARNING) << "Could not find \"SpdyCwnd\" in FieldTrialList"; 1679 LOG(WARNING) << "Could not find \"SpdyCwnd\" in FieldTrialList";
1630 return cwnd; 1680 return cwnd;
1631 } 1681 }
(...skipping 18 matching lines...) Expand all
1650 SettingsMap settings_map; 1700 SettingsMap settings_map;
1651 // Create a new settings frame notifying the sever of our 1701 // Create a new settings frame notifying the sever of our
1652 // max_concurrent_streams_ and initial window size. 1702 // max_concurrent_streams_ and initial window size.
1653 settings_map[SETTINGS_MAX_CONCURRENT_STREAMS] = 1703 settings_map[SETTINGS_MAX_CONCURRENT_STREAMS] =
1654 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams); 1704 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams);
1655 if (GetProtocolVersion() > 2 && 1705 if (GetProtocolVersion() > 2 &&
1656 initial_recv_window_size_ != kSpdyStreamInitialWindowSize) { 1706 initial_recv_window_size_ != kSpdyStreamInitialWindowSize) {
1657 settings_map[SETTINGS_INITIAL_WINDOW_SIZE] = 1707 settings_map[SETTINGS_INITIAL_WINDOW_SIZE] =
1658 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, initial_recv_window_size_); 1708 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, initial_recv_window_size_);
1659 } 1709 }
1660 sent_settings_ = true;
1661 SendSettings(settings_map); 1710 SendSettings(settings_map);
1662 } 1711 }
1663 1712
1664 // Next notify the server about the settings they have previously 1713 // Next notify the server about the settings they have previously
1665 // told us to use when communicating with them. 1714 // told us to use when communicating with them.
1666 const SettingsMap& settings_map = 1715 const SettingsMap& settings_map =
1667 http_server_properties_->GetSpdySettings(host_port_pair()); 1716 http_server_properties_->GetSpdySettings(host_port_pair());
1668 if (settings_map.empty()) 1717 if (settings_map.empty())
1669 return; 1718 return;
1670 1719
(...skipping 12 matching lines...) Expand all
1683 1732
1684 const SettingsMap& settings_map_new = 1733 const SettingsMap& settings_map_new =
1685 http_server_properties_->GetSpdySettings(host_port_pair()); 1734 http_server_properties_->GetSpdySettings(host_port_pair());
1686 for (SettingsMap::const_iterator i = settings_map_new.begin(), 1735 for (SettingsMap::const_iterator i = settings_map_new.begin(),
1687 end = settings_map_new.end(); i != end; ++i) { 1736 end = settings_map_new.end(); i != end; ++i) {
1688 const SpdySettingsIds new_id = i->first; 1737 const SpdySettingsIds new_id = i->first;
1689 const uint32 new_val = i->second.second; 1738 const uint32 new_val = i->second.second;
1690 HandleSetting(new_id, new_val); 1739 HandleSetting(new_id, new_val);
1691 } 1740 }
1692 1741
1693 sent_settings_ = true;
1694 SendSettings(settings_map_new); 1742 SendSettings(settings_map_new);
1695 } 1743 }
1696 1744
1697 1745
1698 void SpdySession::SendSettings(const SettingsMap& settings) { 1746 void SpdySession::SendSettings(const SettingsMap& settings) {
1699 net_log_.AddEvent( 1747 net_log_.AddEvent(
1700 NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS, 1748 NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS,
1701 base::Bind(&NetLogSpdySettingsCallback, &settings)); 1749 base::Bind(&NetLogSpdySettingsCallback, &settings));
1702 1750
1703 // Create the SETTINGS frame and send it. 1751 // Create the SETTINGS frame and send it.
1704 DCHECK(buffered_spdy_framer_.get()); 1752 DCHECK(buffered_spdy_framer_.get());
1705 scoped_ptr<SpdySettingsControlFrame> settings_frame( 1753 scoped_ptr<SpdySettingsControlFrame> settings_frame(
1706 buffered_spdy_framer_->CreateSettings(settings)); 1754 buffered_spdy_framer_->CreateSettings(settings));
1707 QueueFrame(settings_frame.get(), HIGHEST, NULL); 1755 sent_settings_ = true;
1756 QueueFrame(settings_frame.release(), HIGHEST);
1708 } 1757 }
1709 1758
1710 void SpdySession::HandleSetting(uint32 id, uint32 value) { 1759 void SpdySession::HandleSetting(uint32 id, uint32 value) {
1711 switch (id) { 1760 switch (id) {
1712 case SETTINGS_MAX_CONCURRENT_STREAMS: 1761 case SETTINGS_MAX_CONCURRENT_STREAMS:
1713 max_concurrent_streams_ = std::min(static_cast<size_t>(value), 1762 max_concurrent_streams_ = std::min(static_cast<size_t>(value),
1714 g_max_concurrent_stream_limit); 1763 g_max_concurrent_stream_limit);
1715 ProcessPendingCreateStreams(); 1764 ProcessPendingCreateStreams();
1716 break; 1765 break;
1717 case SETTINGS_INITIAL_WINDOW_SIZE: 1766 case SETTINGS_INITIAL_WINDOW_SIZE:
(...skipping 14 matching lines...) Expand all
1732 } 1781 }
1733 } 1782 }
1734 1783
1735 void SpdySession::UpdateStreamsSendWindowSize(int32 delta_window_size) { 1784 void SpdySession::UpdateStreamsSendWindowSize(int32 delta_window_size) {
1736 ActiveStreamMap::iterator it; 1785 ActiveStreamMap::iterator it;
1737 for (it = active_streams_.begin(); it != active_streams_.end(); ++it) { 1786 for (it = active_streams_.begin(); it != active_streams_.end(); ++it) {
1738 const scoped_refptr<SpdyStream>& stream = it->second; 1787 const scoped_refptr<SpdyStream>& stream = it->second;
1739 DCHECK(stream); 1788 DCHECK(stream);
1740 stream->AdjustSendWindowSize(delta_window_size); 1789 stream->AdjustSendWindowSize(delta_window_size);
1741 } 1790 }
1791
1792 CreatedStreamSet::iterator i;
1793 for (i = created_streams_.begin(); i != created_streams_.end(); i++) {
1794 const scoped_refptr<SpdyStream>& stream = *i;
1795 stream->AdjustSendWindowSize(delta_window_size);
1796 }
1742 } 1797 }
1743 1798
1744 void SpdySession::SendPrefacePingIfNoneInFlight() { 1799 void SpdySession::SendPrefacePingIfNoneInFlight() {
1745 if (pings_in_flight_ || !g_enable_ping_based_connection_checking) 1800 if (pings_in_flight_ || !g_enable_ping_based_connection_checking)
1746 return; 1801 return;
1747 1802
1748 base::TimeTicks now = base::TimeTicks::Now(); 1803 base::TimeTicks now = base::TimeTicks::Now();
1749 // If there is no activity in the session, then send a preface-PING. 1804 // If there is no activity in the session, then send a preface-PING.
1750 if ((now - last_activity_time_) > connection_at_risk_of_loss_time_) 1805 if ((now - last_activity_time_) > connection_at_risk_of_loss_time_)
1751 SendPrefacePing(); 1806 SendPrefacePing();
1752 } 1807 }
1753 1808
1754 void SpdySession::SendPrefacePing() { 1809 void SpdySession::SendPrefacePing() {
1755 WritePingFrame(next_ping_id_); 1810 WritePingFrame(next_ping_id_);
1756 } 1811 }
1757 1812
1758 void SpdySession::WritePingFrame(uint32 unique_id) { 1813 void SpdySession::WritePingFrame(uint32 unique_id) {
1759 DCHECK(buffered_spdy_framer_.get()); 1814 DCHECK(buffered_spdy_framer_.get());
1760 scoped_ptr<SpdyPingControlFrame> ping_frame( 1815 scoped_ptr<SpdyPingControlFrame> ping_frame(
1761 buffered_spdy_framer_->CreatePingFrame(next_ping_id_)); 1816 buffered_spdy_framer_->CreatePingFrame(next_ping_id_));
1762 QueueFrame(ping_frame.get(), HIGHEST, NULL); 1817 QueueFrame(ping_frame.release(), HIGHEST);
1763 1818
1764 if (net_log().IsLoggingAllEvents()) { 1819 if (net_log().IsLoggingAllEvents()) {
1765 net_log().AddEvent( 1820 net_log().AddEvent(
1766 NetLog::TYPE_SPDY_SESSION_PING, 1821 NetLog::TYPE_SPDY_SESSION_PING,
1767 base::Bind(&NetLogSpdyPingCallback, next_ping_id_, "sent")); 1822 base::Bind(&NetLogSpdyPingCallback, next_ping_id_, "sent"));
1768 } 1823 }
1769 if (unique_id % 2 != 0) { 1824 if (unique_id % 2 != 0) {
1770 next_ping_id_ += 2; 1825 next_ping_id_ += 2;
1771 ++pings_in_flight_; 1826 ++pings_in_flight_;
1772 PlanToCheckPingStatus(); 1827 PlanToCheckPingStatus();
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1915 SSLClientSocket* SpdySession::GetSSLClientSocket() const { 1970 SSLClientSocket* SpdySession::GetSSLClientSocket() const {
1916 if (!is_secure_) 1971 if (!is_secure_)
1917 return NULL; 1972 return NULL;
1918 SSLClientSocket* ssl_socket = 1973 SSLClientSocket* ssl_socket =
1919 reinterpret_cast<SSLClientSocket*>(connection_->socket()); 1974 reinterpret_cast<SSLClientSocket*>(connection_->socket());
1920 DCHECK(ssl_socket); 1975 DCHECK(ssl_socket);
1921 return ssl_socket; 1976 return ssl_socket;
1922 } 1977 }
1923 1978
1924 } // namespace net 1979 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_session.h ('k') | net/spdy/spdy_session_spdy2_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698