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

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: Add copy constructor to fix win build Created 8 years, 5 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 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 173
174 NextProto g_default_protocol = kProtoUnknown; 174 NextProto g_default_protocol = kProtoUnknown;
175 size_t g_init_max_concurrent_streams = 100; 175 size_t g_init_max_concurrent_streams = 100;
176 size_t g_max_concurrent_stream_limit = 256; 176 size_t g_max_concurrent_stream_limit = 256;
177 size_t g_default_initial_rcv_window_size = 10 * 1024 * 1024; // 10MB 177 size_t g_default_initial_rcv_window_size = 10 * 1024 * 1024; // 10MB
178 bool g_enable_ping_based_connection_checking = true; 178 bool g_enable_ping_based_connection_checking = true;
179 179
180 } // namespace 180 } // namespace
181 181
182 // static 182 // static
183 void SpdySession::SpdyIOBufferProducer::ActivateStream(
184 SpdySession* spdy_session,
185 SpdyStream* spdy_stream) {
186 spdy_session->ActivateStream(spdy_stream);
187 }
188
189 // static
190 SpdyIOBuffer* SpdySession::SpdyIOBufferProducer::CreateIOBuffer(
191 SpdyFrame* frame,
192 RequestPriority priority,
193 SpdyStream* stream) {
194 size_t size = frame->length() + SpdyFrame::kHeaderSize;
195 DCHECK_GT(size, 0u);
196
197 // TODO(mbelshe): We have too much copying of data here.
198 IOBufferWithSize* buffer = new IOBufferWithSize(size);
199 memcpy(buffer->data(), frame->data(), size);
200
201 return new SpdyIOBuffer(buffer, size, priority, stream);
202 }
203
204 // static
183 void SpdySession::set_default_protocol(NextProto default_protocol) { 205 void SpdySession::set_default_protocol(NextProto default_protocol) {
184 g_default_protocol = default_protocol; 206 g_default_protocol = default_protocol;
185 } 207 }
186 208
187 // static 209 // static
188 void SpdySession::set_max_concurrent_streams(size_t value) { 210 void SpdySession::set_max_concurrent_streams(size_t value) {
189 g_max_concurrent_stream_limit = value; 211 g_max_concurrent_stream_limit = value;
190 } 212 }
191 213
192 // static 214 // static
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 370
349 SSLInfo ssl_info; 371 SSLInfo ssl_info;
350 bool was_npn_negotiated; 372 bool was_npn_negotiated;
351 NextProto protocol_negotiated = kProtoUnknown; 373 NextProto protocol_negotiated = kProtoUnknown;
352 if (!GetSSLInfo(&ssl_info, &was_npn_negotiated, &protocol_negotiated)) 374 if (!GetSSLInfo(&ssl_info, &was_npn_negotiated, &protocol_negotiated))
353 return true; // This is not a secure session, so all domains are okay. 375 return true; // This is not a secure session, so all domains are okay.
354 376
355 return !ssl_info.client_cert_sent && ssl_info.cert->VerifyNameMatch(domain); 377 return !ssl_info.client_cert_sent && ssl_info.cert->VerifyNameMatch(domain);
356 } 378 }
357 379
380 void SpdySession::SetStreamHasWriteAvailable(SpdyStream* stream,
381 SpdyIOBufferProducer* producer) {
382 write_queue_.push(producer);
383 stream_producers_[producer] = stream;
384 WriteSocketLater();
385 }
386
358 int SpdySession::GetPushStream( 387 int SpdySession::GetPushStream(
359 const GURL& url, 388 const GURL& url,
360 scoped_refptr<SpdyStream>* stream, 389 scoped_refptr<SpdyStream>* stream,
361 const BoundNetLog& stream_net_log) { 390 const BoundNetLog& stream_net_log) {
362 CHECK_NE(state_, CLOSED); 391 CHECK_NE(state_, CLOSED);
363 392
364 *stream = NULL; 393 *stream = NULL;
365 394
366 // Don't allow access to secure push streams over an unauthenticated, but 395 // Don't allow access to secure push streams over an unauthenticated, but
367 // encrypted SSL socket. 396 // encrypted SSL socket.
(...skipping 18 matching lines...) Expand all
386 return 0; 415 return 0;
387 } 416 }
388 417
389 int SpdySession::CreateStream( 418 int SpdySession::CreateStream(
390 const GURL& url, 419 const GURL& url,
391 RequestPriority priority, 420 RequestPriority priority,
392 scoped_refptr<SpdyStream>* spdy_stream, 421 scoped_refptr<SpdyStream>* spdy_stream,
393 const BoundNetLog& stream_net_log, 422 const BoundNetLog& stream_net_log,
394 const CompletionCallback& callback) { 423 const CompletionCallback& callback) {
395 if (!max_concurrent_streams_ || 424 if (!max_concurrent_streams_ ||
396 active_streams_.size() < max_concurrent_streams_) { 425 (active_streams_.size() + created_streams_.size() <
426 max_concurrent_streams_)) {
397 return CreateStreamImpl(url, priority, spdy_stream, stream_net_log); 427 return CreateStreamImpl(url, priority, spdy_stream, stream_net_log);
398 } 428 }
399 429
400 stalled_streams_++; 430 stalled_streams_++;
401 net_log().AddEvent(NetLog::TYPE_SPDY_SESSION_STALLED_MAX_STREAMS); 431 net_log().AddEvent(NetLog::TYPE_SPDY_SESSION_STALLED_MAX_STREAMS);
402 create_stream_queues_[priority].push( 432 create_stream_queues_[priority].push(
403 PendingCreateStream(url, priority, spdy_stream, 433 PendingCreateStream(url, priority, spdy_stream,
404 stream_net_log, callback)); 434 stream_net_log, callback));
405 return ERR_IO_PENDING; 435 return ERR_IO_PENDING;
406 } 436 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 CloseSessionOnError( 506 CloseSessionOnError(
477 static_cast<net::Error>(certificate_error_code_), 507 static_cast<net::Error>(certificate_error_code_),
478 true, 508 true,
479 "Tried to create SPDY stream for secure content over an " 509 "Tried to create SPDY stream for secure content over an "
480 "unauthenticated session."); 510 "unauthenticated session.");
481 return ERR_SPDY_PROTOCOL_ERROR; 511 return ERR_SPDY_PROTOCOL_ERROR;
482 } 512 }
483 513
484 const std::string& path = url.PathForRequest(); 514 const std::string& path = url.PathForRequest();
485 515
486 const SpdyStreamId stream_id = GetNewStreamId();
487
488 *spdy_stream = new SpdyStream(this, 516 *spdy_stream = new SpdyStream(this,
489 stream_id,
490 false, 517 false,
491 stream_net_log); 518 stream_net_log);
492 const scoped_refptr<SpdyStream>& stream = *spdy_stream; 519 const scoped_refptr<SpdyStream>& stream = *spdy_stream;
493 520
494 stream->set_priority(priority); 521 stream->set_priority(priority);
495 stream->set_path(path); 522 stream->set_path(path);
496 stream->set_send_window_size(initial_send_window_size_); 523 stream->set_send_window_size(initial_send_window_size_);
497 stream->set_recv_window_size(initial_recv_window_size_); 524 stream->set_recv_window_size(initial_recv_window_size_);
498 ActivateStream(stream); 525 created_streams_.insert(stream);
499 526
500 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyPriorityCount", 527 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyPriorityCount",
501 static_cast<int>(priority), 0, 10, 11); 528 static_cast<int>(priority), 0, 10, 11);
502 529
503 // TODO(mbelshe): Optimize memory allocations 530 // TODO(mbelshe): Optimize memory allocations
504 531
505 DCHECK_EQ(active_streams_[stream_id].get(), stream.get());
506 return OK; 532 return OK;
507 } 533 }
508 534
509 bool SpdySession::NeedsCredentials() const { 535 bool SpdySession::NeedsCredentials() const {
510 if (!is_secure_) 536 if (!is_secure_)
511 return false; 537 return false;
512 SSLClientSocket* ssl_socket = GetSSLClientSocket(); 538 SSLClientSocket* ssl_socket = GetSSLClientSocket();
513 if (ssl_socket->GetNegotiatedProtocol() < kProtoSPDY3) 539 if (ssl_socket->GetNegotiatedProtocol() < kProtoSPDY3)
514 return false; 540 return false;
515 return ssl_socket->WasDomainBoundCertSent(); 541 return ssl_socket->WasDomainBoundCertSent();
516 } 542 }
517 543
518 void SpdySession::AddPooledAlias(const HostPortProxyPair& alias) { 544 void SpdySession::AddPooledAlias(const HostPortProxyPair& alias) {
519 pooled_aliases_.insert(alias); 545 pooled_aliases_.insert(alias);
520 } 546 }
521 547
522 int SpdySession::GetProtocolVersion() const { 548 int SpdySession::GetProtocolVersion() const {
523 DCHECK(buffered_spdy_framer_.get()); 549 DCHECK(buffered_spdy_framer_.get());
524 return buffered_spdy_framer_->protocol_version(); 550 return buffered_spdy_framer_->protocol_version();
525 } 551 }
526 552
527 int SpdySession::WriteSynStream( 553 SpdySynStreamControlFrame* SpdySession::CreateSynStream(
528 SpdyStreamId stream_id, 554 SpdyStreamId stream_id,
529 RequestPriority priority, 555 RequestPriority priority,
530 uint8 credential_slot, 556 uint8 credential_slot,
531 SpdyControlFlags flags, 557 SpdyControlFlags flags,
532 const linked_ptr<SpdyHeaderBlock>& headers) { 558 const linked_ptr<SpdyHeaderBlock>& headers) {
533 // Find our stream 559 CHECK(IsStreamActive(stream_id));
534 if (!IsStreamActive(stream_id))
535 return ERR_INVALID_SPDY_STREAM;
536 const scoped_refptr<SpdyStream>& stream = active_streams_[stream_id]; 560 const scoped_refptr<SpdyStream>& stream = active_streams_[stream_id];
537 CHECK_EQ(stream->stream_id(), stream_id); 561 CHECK_EQ(stream->stream_id(), stream_id);
538 562
539 SendPrefacePingIfNoneInFlight(); 563 SendPrefacePingIfNoneInFlight();
540 564
541 DCHECK(buffered_spdy_framer_.get()); 565 DCHECK(buffered_spdy_framer_.get());
542 scoped_ptr<SpdySynStreamControlFrame> syn_frame( 566 scoped_ptr<SpdySynStreamControlFrame> syn_frame(
543 buffered_spdy_framer_->CreateSynStream( 567 buffered_spdy_framer_->CreateSynStream(
544 stream_id, 0, 568 stream_id, 0,
545 ConvertRequestPriorityToSpdyPriority(priority, GetProtocolVersion()), 569 ConvertRequestPriorityToSpdyPriority(priority, GetProtocolVersion()),
546 credential_slot, flags, false, headers.get())); 570 credential_slot, flags, true, headers.get()));
547 // We enqueue all SYN_STREAM frames at the same priority to ensure
548 // that we do not send them out-of-order.
549 // http://crbug.com/111708
550 QueueFrame(syn_frame.get(), HIGHEST, stream);
551 571
552 base::StatsCounter spdy_requests("spdy.requests"); 572 base::StatsCounter spdy_requests("spdy.requests");
553 spdy_requests.Increment(); 573 spdy_requests.Increment();
554 streams_initiated_count_++; 574 streams_initiated_count_++;
555 575
556 if (net_log().IsLoggingAllEvents()) { 576 if (net_log().IsLoggingAllEvents()) {
557 net_log().AddEvent( 577 net_log().AddEvent(
558 NetLog::TYPE_SPDY_SESSION_SYN_STREAM, 578 NetLog::TYPE_SPDY_SESSION_SYN_STREAM,
559 base::Bind(&NetLogSpdySynCallback, headers.get(), flags, stream_id, 0)); 579 base::Bind(&NetLogSpdySynCallback, headers.get(), flags, stream_id, 0));
560 } 580 }
561 581
562 return ERR_IO_PENDING; 582 return syn_frame.release();
563 } 583 }
564 584
565 int SpdySession::WriteCredentialFrame(const std::string& origin, 585 SpdyCredentialControlFrame* SpdySession::CreateCredentialFrame(
566 SSLClientCertType type, 586 const std::string& origin,
567 const std::string& key, 587 SSLClientCertType type,
568 const std::string& cert, 588 const std::string& key,
569 RequestPriority priority) { 589 const std::string& cert,
590 RequestPriority priority) {
570 DCHECK(is_secure_); 591 DCHECK(is_secure_);
571 unsigned char secret[32]; // 32 bytes from the spec 592 unsigned char secret[32]; // 32 bytes from the spec
572 GetSSLClientSocket()->ExportKeyingMaterial("SPDY certificate proof", 593 GetSSLClientSocket()->ExportKeyingMaterial("SPDY certificate proof",
573 true, origin, 594 true, origin,
574 secret, arraysize(secret)); 595 secret, arraysize(secret));
575 596
576 // Convert the key string into a vector<unit8> 597 // Convert the key string into a vector<unit8>
577 std::vector<uint8> key_data; 598 std::vector<uint8> key_data;
578 for (size_t i = 0; i < key.length(); i++) { 599 for (size_t i = 0; i < key.length(); i++) {
579 key_data.push_back(key[i]); 600 key_data.push_back(key[i]);
(...skipping 21 matching lines...) Expand all
601 SpdyCredential credential; 622 SpdyCredential credential;
602 GURL origin_url(origin); 623 GURL origin_url(origin);
603 credential.slot = 624 credential.slot =
604 credential_state_.SetHasCredential(origin_url); 625 credential_state_.SetHasCredential(origin_url);
605 credential.certs.push_back(cert); 626 credential.certs.push_back(cert);
606 credential.proof.assign(proof.begin(), proof.end()); 627 credential.proof.assign(proof.begin(), proof.end());
607 628
608 DCHECK(buffered_spdy_framer_.get()); 629 DCHECK(buffered_spdy_framer_.get());
609 scoped_ptr<SpdyCredentialControlFrame> credential_frame( 630 scoped_ptr<SpdyCredentialControlFrame> credential_frame(
610 buffered_spdy_framer_->CreateCredentialFrame(credential)); 631 buffered_spdy_framer_->CreateCredentialFrame(credential));
611 // We enqueue all SYN_STREAM frames at the same priority to ensure
612 // that we do not send them out-of-order, which means that we need
613 // to enqueue all CREDENTIAL frames at this priority to ensure that
614 // they are sent *before* the SYN_STREAM that references them.
615 // http://crbug.com/111708
616 QueueFrame(credential_frame.get(), HIGHEST, NULL);
617 632
618 if (net_log().IsLoggingAllEvents()) { 633 if (net_log().IsLoggingAllEvents()) {
619 net_log().AddEvent( 634 net_log().AddEvent(
620 NetLog::TYPE_SPDY_SESSION_SEND_CREDENTIAL, 635 NetLog::TYPE_SPDY_SESSION_SEND_CREDENTIAL,
621 base::Bind(&NetLogSpdyCredentialCallback, credential.slot, &origin)); 636 base::Bind(&NetLogSpdyCredentialCallback, credential.slot, &origin));
622 } 637 }
623 return ERR_IO_PENDING; 638 return credential_frame.release();
624 } 639 }
625 640
626 int SpdySession::WriteStreamData(SpdyStreamId stream_id, 641 SpdyDataFrame* SpdySession::CreateDataFrame(SpdyStreamId stream_id,
627 net::IOBuffer* data, int len, 642 net::IOBuffer* data, int len,
628 SpdyDataFlags flags) { 643 SpdyDataFlags flags) {
629 // Find our stream 644 // Find our stream
630 CHECK(IsStreamActive(stream_id)); 645 CHECK(IsStreamActive(stream_id));
631 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; 646 scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
632 CHECK_EQ(stream->stream_id(), stream_id); 647 CHECK_EQ(stream->stream_id(), stream_id);
633 648
634 if (len > kMaxSpdyFrameChunkSize) { 649 if (len > kMaxSpdyFrameChunkSize) {
635 len = kMaxSpdyFrameChunkSize; 650 len = kMaxSpdyFrameChunkSize;
636 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN); 651 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN);
637 } 652 }
638 653
639 // Obey send window size of the stream if flow control is enabled. 654 // Obey send window size of the stream if flow control is enabled.
640 if (flow_control_) { 655 if (flow_control_) {
641 if (stream->send_window_size() <= 0) { 656 if (stream->send_window_size() <= 0) {
642 // Because we queue frames onto the session, it is possible that 657 // Because we queue frames onto the session, it is possible that
643 // a stream was not flow controlled at the time it attempted the 658 // a stream was not flow controlled at the time it attempted the
644 // write, but when we go to fulfill the write, it is now flow 659 // write, but when we go to fulfill the write, it is now flow
645 // controlled. This is why we need the session to mark the stream 660 // controlled. This is why we need the session to mark the stream
646 // as stalled - because only the session knows for sure when the 661 // as stalled - because only the session knows for sure when the
647 // stall occurs. 662 // stall occurs.
648 stream->set_stalled_by_flow_control(true); 663 stream->set_stalled_by_flow_control(true);
649 net_log().AddEvent( 664 net_log().AddEvent(
650 NetLog::TYPE_SPDY_SESSION_STALLED_ON_SEND_WINDOW, 665 NetLog::TYPE_SPDY_SESSION_STALLED_ON_SEND_WINDOW,
651 NetLog::IntegerCallback("stream_id", stream_id)); 666 NetLog::IntegerCallback("stream_id", stream_id));
652 return ERR_IO_PENDING; 667 return NULL;
653 } 668 }
654 int new_len = std::min(len, stream->send_window_size()); 669 int new_len = std::min(len, stream->send_window_size());
655 if (new_len < len) { 670 if (new_len < len) {
656 len = new_len; 671 len = new_len;
657 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN); 672 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN);
658 } 673 }
659 stream->DecreaseSendWindowSize(len); 674 stream->DecreaseSendWindowSize(len);
660 } 675 }
661 676
662 if (net_log().IsLoggingAllEvents()) { 677 if (net_log().IsLoggingAllEvents()) {
663 net_log().AddEvent( 678 net_log().AddEvent(
664 NetLog::TYPE_SPDY_SESSION_SEND_DATA, 679 NetLog::TYPE_SPDY_SESSION_SEND_DATA,
665 base::Bind(&NetLogSpdyDataCallback, stream_id, len, flags)); 680 base::Bind(&NetLogSpdyDataCallback, stream_id, len, flags));
666 } 681 }
667 682
668 // Send PrefacePing for DATA_FRAMEs with nonzero payload size. 683 // Send PrefacePing for DATA_FRAMEs with nonzero payload size.
669 if (len > 0) 684 if (len > 0)
670 SendPrefacePingIfNoneInFlight(); 685 SendPrefacePingIfNoneInFlight();
671 686
672 // TODO(mbelshe): reduce memory copies here. 687 // TODO(mbelshe): reduce memory copies here.
673 DCHECK(buffered_spdy_framer_.get()); 688 DCHECK(buffered_spdy_framer_.get());
674 scoped_ptr<SpdyDataFrame> frame( 689 scoped_ptr<SpdyDataFrame> frame(
675 buffered_spdy_framer_->CreateDataFrame( 690 buffered_spdy_framer_->CreateDataFrame(
676 stream_id, data->data(), len, flags)); 691 stream_id, data->data(), len, flags));
677 QueueFrame(frame.get(), stream->priority(), stream);
678 692
679 return ERR_IO_PENDING; 693 return frame.release();
680 } 694 }
681 695
682 void SpdySession::CloseStream(SpdyStreamId stream_id, int status) { 696 void SpdySession::CloseStream(SpdyStreamId stream_id, int status) {
697 DCHECK_NE(0u, stream_id);
683 // TODO(mbelshe): We should send a RST_STREAM control frame here 698 // TODO(mbelshe): We should send a RST_STREAM control frame here
684 // so that the server can cancel a large send. 699 // so that the server can cancel a large send.
685 700
686 DeleteStream(stream_id, status); 701 DeleteStream(stream_id, status);
687 } 702 }
688 703
704 void SpdySession::CloseCreatedStream(SpdyStream* stream, int status) {
705 DCHECK_EQ(0u, stream->stream_id());
706 created_streams_.erase(scoped_refptr<SpdyStream>(stream));
707 }
708
689 void SpdySession::ResetStream(SpdyStreamId stream_id, 709 void SpdySession::ResetStream(SpdyStreamId stream_id,
690 SpdyStatusCodes status, 710 SpdyStatusCodes status,
691 const std::string& description) { 711 const std::string& description) {
692 net_log().AddEvent( 712 net_log().AddEvent(
693 NetLog::TYPE_SPDY_SESSION_SEND_RST_STREAM, 713 NetLog::TYPE_SPDY_SESSION_SEND_RST_STREAM,
694 base::Bind(&NetLogSpdyRstCallback, stream_id, status, &description)); 714 base::Bind(&NetLogSpdyRstCallback, stream_id, status, &description));
695 715
696 DCHECK(buffered_spdy_framer_.get()); 716 DCHECK(buffered_spdy_framer_.get());
697 scoped_ptr<SpdyRstStreamControlFrame> rst_frame( 717 scoped_ptr<SpdyRstStreamControlFrame> rst_frame(
698 buffered_spdy_framer_->CreateRstStream(stream_id, status)); 718 buffered_spdy_framer_->CreateRstStream(stream_id, status));
699 719
700 // Default to lowest priority unless we know otherwise. 720 // Default to lowest priority unless we know otherwise.
701 RequestPriority priority = net::IDLE; 721 RequestPriority priority = net::IDLE;
702 if(IsStreamActive(stream_id)) { 722 if(IsStreamActive(stream_id)) {
703 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; 723 scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
704 priority = stream->priority(); 724 priority = stream->priority();
705 } 725 }
706 QueueFrame(rst_frame.get(), priority, NULL); 726 QueueFrame(rst_frame.release(), priority);
707 RecordProtocolErrorHistogram( 727 RecordProtocolErrorHistogram(
708 static_cast<SpdyProtocolErrorDetails>(status + STATUS_CODE_INVALID)); 728 static_cast<SpdyProtocolErrorDetails>(status + STATUS_CODE_INVALID));
709 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); 729 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR);
710 } 730 }
711 731
712 bool SpdySession::IsStreamActive(SpdyStreamId stream_id) const { 732 bool SpdySession::IsStreamActive(SpdyStreamId stream_id) const {
713 return ContainsKey(active_streams_, stream_id); 733 return ContainsKey(active_streams_, stream_id);
714 } 734 }
715 735
716 LoadState SpdySession::GetLoadState() const { 736 LoadState SpdySession::GetLoadState() const {
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 // closed, just return. 904 // closed, just return.
885 if (state_ < CONNECTED || state_ == CLOSED) 905 if (state_ < CONNECTED || state_ == CLOSED)
886 return; 906 return;
887 907
888 if (write_pending_) // Another write is in progress still. 908 if (write_pending_) // Another write is in progress still.
889 return; 909 return;
890 910
891 // Loop sending frames until we've sent everything or until the write 911 // Loop sending frames until we've sent everything or until the write
892 // returns error (or ERR_IO_PENDING). 912 // returns error (or ERR_IO_PENDING).
893 DCHECK(buffered_spdy_framer_.get()); 913 DCHECK(buffered_spdy_framer_.get());
894 while (in_flight_write_.buffer() || !queue_.empty()) { 914 while (in_flight_write_.buffer() || !write_queue_.empty()) {
895 if (!in_flight_write_.buffer()) { 915 if (!in_flight_write_.buffer()) {
896 // Grab the next SpdyFrame to send. 916 // Grab the next SpdyBuffer to send.
897 SpdyIOBuffer next_buffer = queue_.top(); 917 scoped_ptr<SpdyIOBufferProducer> producer(write_queue_.top());
898 queue_.pop(); 918 scoped_ptr<SpdyIOBuffer> buffer(producer->ProduceNextBuffer(this));
919 stream_producers_.erase(producer.get());
920 write_queue_.pop();
921 // It is possible that a stream had data to write, but a
922 // WINDOW_UPDATE frame has been received which made that
923 // stream no longer writable.
924 // TODO(rch): consider handling that case by removing the
925 // stream from the writable queue?
926 if (buffer == NULL)
927 continue;
899 928
900 // We've deferred compression until just before we write it to the socket, 929 in_flight_write_ = *buffer;
901 // which is now. At this time, we don't compress our data frames.
902 SpdyFrame uncompressed_frame(next_buffer.buffer()->data(), false);
903 size_t size;
904 if (buffered_spdy_framer_->IsCompressible(uncompressed_frame)) {
905 DCHECK(uncompressed_frame.is_control_frame());
906 const SpdyControlFrame* uncompressed_control_frame =
907 reinterpret_cast<const SpdyControlFrame*>(&uncompressed_frame);
908 scoped_ptr<SpdyFrame> compressed_frame(
909 buffered_spdy_framer_->CompressControlFrame(
910 *uncompressed_control_frame));
911 if (!compressed_frame.get()) {
912 RecordProtocolErrorHistogram(
913 PROTOCOL_ERROR_SPDY_COMPRESSION_FAILURE);
914 CloseSessionOnError(
915 net::ERR_SPDY_PROTOCOL_ERROR, true, "SPDY Compression failure.");
916 return;
917 }
918
919 size = compressed_frame->length() + SpdyFrame::kHeaderSize;
920
921 DCHECK_GT(size, 0u);
922
923 // TODO(mbelshe): We have too much copying of data here.
924 IOBufferWithSize* buffer = new IOBufferWithSize(size);
925 memcpy(buffer->data(), compressed_frame->data(), size);
926
927 // Attempt to send the frame.
928 in_flight_write_ = SpdyIOBuffer(buffer, size, HIGHEST,
929 next_buffer.stream());
930 } else {
931 size = uncompressed_frame.length() + SpdyFrame::kHeaderSize;
932 in_flight_write_ = next_buffer;
933 }
934 } else { 930 } else {
935 DCHECK(in_flight_write_.buffer()->BytesRemaining()); 931 DCHECK(in_flight_write_.buffer()->BytesRemaining());
936 } 932 }
937 933
938 write_pending_ = true; 934 write_pending_ = true;
939 int rv = connection_->socket()->Write( 935 int rv = connection_->socket()->Write(
940 in_flight_write_.buffer(), 936 in_flight_write_.buffer(),
941 in_flight_write_.buffer()->BytesRemaining(), 937 in_flight_write_.buffer()->BytesRemaining(),
942 base::Bind(&SpdySession::OnWriteComplete, base::Unretained(this))); 938 base::Bind(&SpdySession::OnWriteComplete, base::Unretained(this)));
943 if (rv == net::ERR_IO_PENDING) 939 if (rv == net::ERR_IO_PENDING)
(...skipping 26 matching lines...) Expand all
970 while (!create_stream_queues_[i].empty()) { 966 while (!create_stream_queues_[i].empty()) {
971 PendingCreateStream pending_create = create_stream_queues_[i].front(); 967 PendingCreateStream pending_create = create_stream_queues_[i].front();
972 create_stream_queues_[i].pop(); 968 create_stream_queues_[i].pop();
973 pending_create.callback.Run(ERR_ABORTED); 969 pending_create.callback.Run(ERR_ABORTED);
974 } 970 }
975 } 971 }
976 972
977 while (!active_streams_.empty()) { 973 while (!active_streams_.empty()) {
978 ActiveStreamMap::iterator it = active_streams_.begin(); 974 ActiveStreamMap::iterator it = active_streams_.begin();
979 const scoped_refptr<SpdyStream>& stream = it->second; 975 const scoped_refptr<SpdyStream>& stream = it->second;
980 DCHECK(stream); 976 LogAbandonedStream(stream, status);
981 std::string description = base::StringPrintf(
982 "ABANDONED (stream_id=%d): ", stream->stream_id()) + stream->path();
983 stream->LogStreamError(status, description);
984 DeleteStream(stream->stream_id(), status); 977 DeleteStream(stream->stream_id(), status);
985 } 978 }
986 979
980 while (!created_streams_.empty()) {
981 CreatedStreamSet::iterator it = created_streams_.begin();
982 const scoped_refptr<SpdyStream>& stream = *it;
983 LogAbandonedStream(stream, status);
984 stream->OnClose(status);
985 created_streams_.erase(it);
986 }
987
987 // We also need to drain the queue. 988 // We also need to drain the queue.
988 while (queue_.size()) 989 while (!write_queue_.empty()) {
989 queue_.pop(); 990 SpdyIOBufferProducer* producer = write_queue_.top();
991 stream_producers_.erase(producer);
992 delete producer;
993 write_queue_.pop();
994 }
995 }
996
997 void SpdySession::LogAbandonedStream(const scoped_refptr<SpdyStream>& stream,
998 net::Error status) {
999 DCHECK(stream);
1000 std::string description = base::StringPrintf(
1001 "ABANDONED (stream_id=%d): ", stream->stream_id()) + stream->path();
1002 stream->LogStreamError(status, description);
990 } 1003 }
991 1004
992 int SpdySession::GetNewStreamId() { 1005 int SpdySession::GetNewStreamId() {
993 int id = stream_hi_water_mark_; 1006 int id = stream_hi_water_mark_;
994 stream_hi_water_mark_ += 2; 1007 stream_hi_water_mark_ += 2;
995 if (stream_hi_water_mark_ > 0x7fff) 1008 if (stream_hi_water_mark_ > 0x7fff)
996 stream_hi_water_mark_ = 1; 1009 stream_hi_water_mark_ = 1;
997 return id; 1010 return id;
998 } 1011 }
999 1012
1000 void SpdySession::QueueFrame(SpdyFrame* frame,
1001 RequestPriority priority,
1002 SpdyStream* stream) {
1003 int length = SpdyFrame::kHeaderSize + frame->length();
1004 IOBuffer* buffer = new IOBuffer(length);
1005 memcpy(buffer->data(), frame->data(), length);
1006 queue_.push(SpdyIOBuffer(buffer, length, priority, stream));
1007
1008 WriteSocketLater();
1009 }
1010
1011 void SpdySession::CloseSessionOnError(net::Error err, 1013 void SpdySession::CloseSessionOnError(net::Error err,
1012 bool remove_from_pool, 1014 bool remove_from_pool,
1013 const std::string& description) { 1015 const std::string& description) {
1014 // Closing all streams can have a side-effect of dropping the last reference 1016 // Closing all streams can have a side-effect of dropping the last reference
1015 // to |this|. Hold a reference through this function. 1017 // to |this|. Hold a reference through this function.
1016 scoped_refptr<SpdySession> self(this); 1018 scoped_refptr<SpdySession> self(this);
1017 1019
1018 DCHECK_LT(err, OK); 1020 DCHECK_LT(err, OK);
1019 net_log_.AddEvent( 1021 net_log_.AddEvent(
1020 NetLog::TYPE_SPDY_SESSION_CLOSE, 1022 NetLog::TYPE_SPDY_SESSION_CLOSE,
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1090 return connection_->socket()->GetPeerAddress(address); 1092 return connection_->socket()->GetPeerAddress(address);
1091 } 1093 }
1092 1094
1093 int SpdySession::GetLocalAddress(IPEndPoint* address) const { 1095 int SpdySession::GetLocalAddress(IPEndPoint* address) const {
1094 if (!connection_->socket()) 1096 if (!connection_->socket())
1095 return ERR_SOCKET_NOT_CONNECTED; 1097 return ERR_SOCKET_NOT_CONNECTED;
1096 1098
1097 return connection_->socket()->GetLocalAddress(address); 1099 return connection_->socket()->GetLocalAddress(address);
1098 } 1100 }
1099 1101
1102 class SimpleSpdyIOBufferProducer : public SpdySession::SpdyIOBufferProducer {
1103 public:
1104 SimpleSpdyIOBufferProducer(SpdyFrame* frame,
1105 RequestPriority priority)
1106 : frame_(frame),
1107 priority_(priority) {
1108 }
1109
1110 virtual RequestPriority GetPriority() const OVERRIDE {
1111 return priority_;
1112 }
1113
1114 virtual SpdyIOBuffer* ProduceNextBuffer(SpdySession* session) {
1115 return SpdySession::SpdyIOBufferProducer::CreateIOBuffer(
1116 frame_, priority_, NULL);
1117 }
1118
1119 private:
1120 SpdyFrame* frame_;
1121 RequestPriority priority_;
1122 };
1123
1124 void SpdySession::QueueFrame(SpdyFrame* frame,
1125 RequestPriority priority) {
1126 SimpleSpdyIOBufferProducer* producer =
1127 new SimpleSpdyIOBufferProducer(frame, priority);
1128 write_queue_.push(producer);
1129 WriteSocketLater();
1130 }
1131
1100 void SpdySession::ActivateStream(SpdyStream* stream) { 1132 void SpdySession::ActivateStream(SpdyStream* stream) {
1133 if (stream->stream_id() == 0) {
1134 stream->set_stream_id(GetNewStreamId());
1135 created_streams_.erase(scoped_refptr<SpdyStream>(stream));
1136 }
1101 const SpdyStreamId id = stream->stream_id(); 1137 const SpdyStreamId id = stream->stream_id();
1102 DCHECK(!IsStreamActive(id)); 1138 DCHECK(!IsStreamActive(id));
1103 1139
1104 active_streams_[id] = stream; 1140 active_streams_[id] = stream;
1105 } 1141 }
1106 1142
1107 void SpdySession::DeleteStream(SpdyStreamId id, int status) { 1143 void SpdySession::DeleteStream(SpdyStreamId id, int status) {
1108 // For push streams, if they are being deleted normally, we leave 1144 // For push streams, if they are being deleted normally, we leave
1109 // the stream in the unclaimed_pushed_streams_ list. However, if 1145 // the stream in the unclaimed_pushed_streams_ list. However, if
1110 // the stream is errored out, clean it up entirely. 1146 // the stream is errored out, clean it up entirely.
1111 if (status != OK) { 1147 if (status != OK) {
1112 PushedStreamMap::iterator it; 1148 PushedStreamMap::iterator it;
1113 for (it = unclaimed_pushed_streams_.begin(); 1149 for (it = unclaimed_pushed_streams_.begin();
1114 it != unclaimed_pushed_streams_.end(); ++it) { 1150 it != unclaimed_pushed_streams_.end(); ++it) {
1115 scoped_refptr<SpdyStream> curr = it->second; 1151 scoped_refptr<SpdyStream> curr = it->second;
1116 if (id == curr->stream_id()) { 1152 if (id == curr->stream_id()) {
1117 unclaimed_pushed_streams_.erase(it); 1153 unclaimed_pushed_streams_.erase(it);
1118 break; 1154 break;
1119 } 1155 }
1120 } 1156 }
1121 } 1157 }
1122 1158
1123 // The stream might have been deleted. 1159 // The stream might have been deleted.
1124 ActiveStreamMap::iterator it2 = active_streams_.find(id); 1160 ActiveStreamMap::iterator it2 = active_streams_.find(id);
1125 if (it2 == active_streams_.end()) 1161 if (it2 == active_streams_.end())
1126 return; 1162 return;
1127 1163
1164 // Possibly remove from the write queue.
1165 WriteQueue old = write_queue_;
1166 write_queue_ = WriteQueue();
1167 while (!old.empty()) {
1168 SpdyIOBufferProducer* producer = old.top();
1169 StreamProducerMap::iterator it = stream_producers_.find(producer);
1170 if (it == stream_producers_.end() || it->second->stream_id() != id)
1171 write_queue_.push(producer);
1172 else
1173 delete producer;
1174 old.pop();
1175 }
1176
1128 // If this is an active stream, call the callback. 1177 // If this is an active stream, call the callback.
1129 const scoped_refptr<SpdyStream> stream(it2->second); 1178 const scoped_refptr<SpdyStream> stream(it2->second);
1130 active_streams_.erase(it2); 1179 active_streams_.erase(it2);
1131 if (stream) 1180 if (stream)
1132 stream->OnClose(status); 1181 stream->OnClose(status);
1133 ProcessPendingCreateStreams(); 1182 ProcessPendingCreateStreams();
1134 } 1183 }
1135 1184
1136 void SpdySession::RemoveFromPool() { 1185 void SpdySession::RemoveFromPool() {
1137 if (spdy_session_pool_) { 1186 if (spdy_session_pool_) {
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1347 } 1396 }
1348 1397
1349 // There should not be an existing pushed stream with the same path. 1398 // There should not be an existing pushed stream with the same path.
1350 PushedStreamMap::iterator it = unclaimed_pushed_streams_.find(url); 1399 PushedStreamMap::iterator it = unclaimed_pushed_streams_.find(url);
1351 if (it != unclaimed_pushed_streams_.end()) { 1400 if (it != unclaimed_pushed_streams_.end()) {
1352 ResetStream(stream_id, PROTOCOL_ERROR, 1401 ResetStream(stream_id, PROTOCOL_ERROR,
1353 "Received duplicate pushed stream with url: " + url); 1402 "Received duplicate pushed stream with url: " + url);
1354 return; 1403 return;
1355 } 1404 }
1356 1405
1357 scoped_refptr<SpdyStream> stream( 1406 scoped_refptr<SpdyStream> stream(new SpdyStream(this, true, net_log_));
1358 new SpdyStream(this, stream_id, true, net_log_)); 1407 stream->set_stream_id(stream_id);
1359 1408
1360 stream->set_path(gurl.PathForRequest()); 1409 stream->set_path(gurl.PathForRequest());
1361 stream->set_send_window_size(initial_send_window_size_); 1410 stream->set_send_window_size(initial_send_window_size_);
1362 stream->set_recv_window_size(initial_recv_window_size_); 1411 stream->set_recv_window_size(initial_recv_window_size_);
1363 1412
1364 unclaimed_pushed_streams_[url] = stream; 1413 unclaimed_pushed_streams_[url] = stream;
1365 1414
1366 ActivateStream(stream); 1415 ActivateStream(stream);
1367 stream->set_response_received(); 1416 stream->set_response_received();
1368 1417
1369 // Parse the headers. 1418 // Parse the headers.
1370 if (!Respond(*headers, stream)) 1419 if (!Respond(*headers, stream))
1371 return; 1420 return;
1372 1421
1373 base::StatsCounter push_requests("spdy.pushed_streams"); 1422 base::StatsCounter push_requests("spdy.pushed_streams");
1374 push_requests.Increment(); 1423 push_requests.Increment();
1375 } 1424 }
1376 1425
1377 void SpdySession::OnSynReply(const SpdySynReplyControlFrame& frame, 1426 void SpdySession::OnSynReply(const SpdySynReplyControlFrame& frame,
1378 const linked_ptr<SpdyHeaderBlock>& headers) { 1427 const linked_ptr<SpdyHeaderBlock>& headers) {
1379 SpdyStreamId stream_id = frame.stream_id(); 1428 SpdyStreamId stream_id = frame.stream_id();
1380
1381 if (net_log().IsLoggingAllEvents()) { 1429 if (net_log().IsLoggingAllEvents()) {
1382 net_log().AddEvent( 1430 net_log().AddEvent(
1383 NetLog::TYPE_SPDY_SESSION_SYN_REPLY, 1431 NetLog::TYPE_SPDY_SESSION_SYN_REPLY,
1384 base::Bind(&NetLogSpdySynCallback, 1432 base::Bind(&NetLogSpdySynCallback,
1385 headers.get(), static_cast<SpdyControlFlags>(frame.flags()), 1433 headers.get(), static_cast<SpdyControlFlags>(frame.flags()),
1386 stream_id, 0)); 1434 stream_id, 0));
1387 } 1435 }
1388 1436
1389 if (!IsStreamActive(stream_id)) { 1437 if (!IsStreamActive(stream_id)) {
1390 // NOTE: it may just be that the stream was cancelled. 1438 // NOTE: it may just be that the stream was cancelled.
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1554 CHECK_EQ(stream->stream_id(), stream_id); 1602 CHECK_EQ(stream->stream_id(), stream_id);
1555 1603
1556 net_log_.AddEvent( 1604 net_log_.AddEvent(
1557 NetLog::TYPE_SPDY_SESSION_SENT_WINDOW_UPDATE, 1605 NetLog::TYPE_SPDY_SESSION_SENT_WINDOW_UPDATE,
1558 base::Bind(&NetLogSpdyWindowUpdateCallback, 1606 base::Bind(&NetLogSpdyWindowUpdateCallback,
1559 stream_id, delta_window_size)); 1607 stream_id, delta_window_size));
1560 1608
1561 DCHECK(buffered_spdy_framer_.get()); 1609 DCHECK(buffered_spdy_framer_.get());
1562 scoped_ptr<SpdyWindowUpdateControlFrame> window_update_frame( 1610 scoped_ptr<SpdyWindowUpdateControlFrame> window_update_frame(
1563 buffered_spdy_framer_->CreateWindowUpdate(stream_id, delta_window_size)); 1611 buffered_spdy_framer_->CreateWindowUpdate(stream_id, delta_window_size));
1564 QueueFrame(window_update_frame.get(), stream->priority(), NULL); 1612 QueueFrame(window_update_frame.release(), stream->priority());
1565 } 1613 }
1566 1614
1567 // Given a cwnd that we would have sent to the server, modify it based on the 1615 // Given a cwnd that we would have sent to the server, modify it based on the
1568 // field trial policy. 1616 // field trial policy.
1569 uint32 ApplyCwndFieldTrialPolicy(int cwnd) { 1617 uint32 ApplyCwndFieldTrialPolicy(int cwnd) {
1570 base::FieldTrial* trial = base::FieldTrialList::Find("SpdyCwnd"); 1618 base::FieldTrial* trial = base::FieldTrialList::Find("SpdyCwnd");
1571 if (!trial) { 1619 if (!trial) {
1572 LOG(WARNING) << "Could not find \"SpdyCwnd\" in FieldTrialList"; 1620 LOG(WARNING) << "Could not find \"SpdyCwnd\" in FieldTrialList";
1573 return cwnd; 1621 return cwnd;
1574 } 1622 }
(...skipping 18 matching lines...) Expand all
1593 SettingsMap settings_map; 1641 SettingsMap settings_map;
1594 // Create a new settings frame notifying the sever of our 1642 // Create a new settings frame notifying the sever of our
1595 // max_concurrent_streams_ and initial window size. 1643 // max_concurrent_streams_ and initial window size.
1596 settings_map[SETTINGS_MAX_CONCURRENT_STREAMS] = 1644 settings_map[SETTINGS_MAX_CONCURRENT_STREAMS] =
1597 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kInitialMaxConcurrentStreams); 1645 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kInitialMaxConcurrentStreams);
1598 if (GetProtocolVersion() > 2 && 1646 if (GetProtocolVersion() > 2 &&
1599 initial_recv_window_size_ != kSpdyStreamInitialWindowSize) { 1647 initial_recv_window_size_ != kSpdyStreamInitialWindowSize) {
1600 settings_map[SETTINGS_INITIAL_WINDOW_SIZE] = 1648 settings_map[SETTINGS_INITIAL_WINDOW_SIZE] =
1601 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, initial_recv_window_size_); 1649 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, initial_recv_window_size_);
1602 } 1650 }
1603 sent_settings_ = true;
1604 SendSettings(settings_map); 1651 SendSettings(settings_map);
1605 } 1652 }
1606 1653
1607 // Next notify the server about the settings they have previously 1654 // Next notify the server about the settings they have previously
1608 // told us to use when communicating with them. 1655 // told us to use when communicating with them.
1609 const SettingsMap& settings_map = 1656 const SettingsMap& settings_map =
1610 http_server_properties_->GetSpdySettings(host_port_pair()); 1657 http_server_properties_->GetSpdySettings(host_port_pair());
1611 if (settings_map.empty()) 1658 if (settings_map.empty())
1612 return; 1659 return;
1613 1660
(...skipping 12 matching lines...) Expand all
1626 1673
1627 const SettingsMap& settings_map_new = 1674 const SettingsMap& settings_map_new =
1628 http_server_properties_->GetSpdySettings(host_port_pair()); 1675 http_server_properties_->GetSpdySettings(host_port_pair());
1629 for (SettingsMap::const_iterator i = settings_map_new.begin(), 1676 for (SettingsMap::const_iterator i = settings_map_new.begin(),
1630 end = settings_map_new.end(); i != end; ++i) { 1677 end = settings_map_new.end(); i != end; ++i) {
1631 const SpdySettingsIds new_id = i->first; 1678 const SpdySettingsIds new_id = i->first;
1632 const uint32 new_val = i->second.second; 1679 const uint32 new_val = i->second.second;
1633 HandleSetting(new_id, new_val); 1680 HandleSetting(new_id, new_val);
1634 } 1681 }
1635 1682
1636 sent_settings_ = true;
1637 SendSettings(settings_map_new); 1683 SendSettings(settings_map_new);
1638 } 1684 }
1639 1685
1640 1686
1641 void SpdySession::SendSettings(const SettingsMap& settings) { 1687 void SpdySession::SendSettings(const SettingsMap& settings) {
1642 net_log_.AddEvent( 1688 net_log_.AddEvent(
1643 NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS, 1689 NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS,
1644 base::Bind(&NetLogSpdySettingsCallback, &settings)); 1690 base::Bind(&NetLogSpdySettingsCallback, &settings));
1645 1691
1646 // Create the SETTINGS frame and send it. 1692 // Create the SETTINGS frame and send it.
1647 DCHECK(buffered_spdy_framer_.get()); 1693 DCHECK(buffered_spdy_framer_.get());
1648 scoped_ptr<SpdySettingsControlFrame> settings_frame( 1694 scoped_ptr<SpdySettingsControlFrame> settings_frame(
1649 buffered_spdy_framer_->CreateSettings(settings)); 1695 buffered_spdy_framer_->CreateSettings(settings));
1650 QueueFrame(settings_frame.get(), HIGHEST, NULL); 1696 sent_settings_ = true;
1697 QueueFrame(settings_frame.release(), HIGHEST);
1651 } 1698 }
1652 1699
1653 void SpdySession::HandleSetting(uint32 id, uint32 value) { 1700 void SpdySession::HandleSetting(uint32 id, uint32 value) {
1654 switch (id) { 1701 switch (id) {
1655 case SETTINGS_MAX_CONCURRENT_STREAMS: 1702 case SETTINGS_MAX_CONCURRENT_STREAMS:
1656 max_concurrent_streams_ = std::min(static_cast<size_t>(value), 1703 max_concurrent_streams_ = std::min(static_cast<size_t>(value),
1657 g_max_concurrent_stream_limit); 1704 g_max_concurrent_stream_limit);
1658 ProcessPendingCreateStreams(); 1705 ProcessPendingCreateStreams();
1659 break; 1706 break;
1660 case SETTINGS_INITIAL_WINDOW_SIZE: 1707 case SETTINGS_INITIAL_WINDOW_SIZE:
(...skipping 14 matching lines...) Expand all
1675 } 1722 }
1676 } 1723 }
1677 1724
1678 void SpdySession::UpdateStreamsSendWindowSize(int32 delta_window_size) { 1725 void SpdySession::UpdateStreamsSendWindowSize(int32 delta_window_size) {
1679 ActiveStreamMap::iterator it; 1726 ActiveStreamMap::iterator it;
1680 for (it = active_streams_.begin(); it != active_streams_.end(); ++it) { 1727 for (it = active_streams_.begin(); it != active_streams_.end(); ++it) {
1681 const scoped_refptr<SpdyStream>& stream = it->second; 1728 const scoped_refptr<SpdyStream>& stream = it->second;
1682 DCHECK(stream); 1729 DCHECK(stream);
1683 stream->AdjustSendWindowSize(delta_window_size); 1730 stream->AdjustSendWindowSize(delta_window_size);
1684 } 1731 }
1732
1733 CreatedStreamSet::iterator i;
1734 for (i = created_streams_.begin(); i != created_streams_.end(); i++) {
1735 const scoped_refptr<SpdyStream>& stream = *i;
1736 stream->AdjustSendWindowSize(delta_window_size);
1737 }
1685 } 1738 }
1686 1739
1687 void SpdySession::SendPrefacePingIfNoneInFlight() { 1740 void SpdySession::SendPrefacePingIfNoneInFlight() {
1688 if (pings_in_flight_ || !g_enable_ping_based_connection_checking) 1741 if (pings_in_flight_ || !g_enable_ping_based_connection_checking)
1689 return; 1742 return;
1690 1743
1691 base::TimeTicks now = base::TimeTicks::Now(); 1744 base::TimeTicks now = base::TimeTicks::Now();
1692 // If there is no activity in the session, then send a preface-PING. 1745 // If there is no activity in the session, then send a preface-PING.
1693 if ((now - last_activity_time_) > connection_at_risk_of_loss_time_) 1746 if ((now - last_activity_time_) > connection_at_risk_of_loss_time_)
1694 SendPrefacePing(); 1747 SendPrefacePing();
1695 } 1748 }
1696 1749
1697 void SpdySession::SendPrefacePing() { 1750 void SpdySession::SendPrefacePing() {
1698 WritePingFrame(next_ping_id_); 1751 WritePingFrame(next_ping_id_);
1699 } 1752 }
1700 1753
1701 void SpdySession::WritePingFrame(uint32 unique_id) { 1754 void SpdySession::WritePingFrame(uint32 unique_id) {
1702 DCHECK(buffered_spdy_framer_.get()); 1755 DCHECK(buffered_spdy_framer_.get());
1703 scoped_ptr<SpdyPingControlFrame> ping_frame( 1756 scoped_ptr<SpdyPingControlFrame> ping_frame(
1704 buffered_spdy_framer_->CreatePingFrame(next_ping_id_)); 1757 buffered_spdy_framer_->CreatePingFrame(next_ping_id_));
1705 QueueFrame(ping_frame.get(), HIGHEST, NULL); 1758 QueueFrame(ping_frame.release(), HIGHEST);
1706 1759
1707 if (net_log().IsLoggingAllEvents()) { 1760 if (net_log().IsLoggingAllEvents()) {
1708 net_log().AddEvent( 1761 net_log().AddEvent(
1709 NetLog::TYPE_SPDY_SESSION_PING, 1762 NetLog::TYPE_SPDY_SESSION_PING,
1710 base::Bind(&NetLogSpdyPingCallback, next_ping_id_, "sent")); 1763 base::Bind(&NetLogSpdyPingCallback, next_ping_id_, "sent"));
1711 } 1764 }
1712 if (unique_id % 2 != 0) { 1765 if (unique_id % 2 != 0) {
1713 next_ping_id_ += 2; 1766 next_ping_id_ += 2;
1714 ++pings_in_flight_; 1767 ++pings_in_flight_;
1715 PlanToCheckPingStatus(); 1768 PlanToCheckPingStatus();
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1858 SSLClientSocket* SpdySession::GetSSLClientSocket() const { 1911 SSLClientSocket* SpdySession::GetSSLClientSocket() const {
1859 if (!is_secure_) 1912 if (!is_secure_)
1860 return NULL; 1913 return NULL;
1861 SSLClientSocket* ssl_socket = 1914 SSLClientSocket* ssl_socket =
1862 reinterpret_cast<SSLClientSocket*>(connection_->socket()); 1915 reinterpret_cast<SSLClientSocket*>(connection_->socket());
1863 DCHECK(ssl_socket); 1916 DCHECK(ssl_socket);
1864 return ssl_socket; 1917 return ssl_socket;
1865 } 1918 }
1866 1919
1867 } // namespace net 1920 } // 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