OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/spdy/spdy_session.h" | 5 #include "net/spdy/spdy_session.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "crypto/ec_private_key.h" | 25 #include "crypto/ec_private_key.h" |
26 #include "crypto/ec_signature_creator.h" | 26 #include "crypto/ec_signature_creator.h" |
27 #include "net/base/connection_type_histograms.h" | 27 #include "net/base/connection_type_histograms.h" |
28 #include "net/base/net_log.h" | 28 #include "net/base/net_log.h" |
29 #include "net/base/net_util.h" | 29 #include "net/base/net_util.h" |
30 #include "net/cert/asn1_util.h" | 30 #include "net/cert/asn1_util.h" |
31 #include "net/http/http_network_session.h" | 31 #include "net/http/http_network_session.h" |
32 #include "net/http/http_server_properties.h" | 32 #include "net/http/http_server_properties.h" |
33 #include "net/spdy/spdy_credential_builder.h" | 33 #include "net/spdy/spdy_credential_builder.h" |
34 #include "net/spdy/spdy_frame_builder.h" | 34 #include "net/spdy/spdy_frame_builder.h" |
| 35 #include "net/spdy/spdy_frame_producer.h" |
35 #include "net/spdy/spdy_http_utils.h" | 36 #include "net/spdy/spdy_http_utils.h" |
36 #include "net/spdy/spdy_protocol.h" | 37 #include "net/spdy/spdy_protocol.h" |
37 #include "net/spdy/spdy_session_pool.h" | 38 #include "net/spdy/spdy_session_pool.h" |
38 #include "net/spdy/spdy_stream.h" | 39 #include "net/spdy/spdy_stream.h" |
39 #include "net/ssl/server_bound_cert_service.h" | 40 #include "net/ssl/server_bound_cert_service.h" |
40 | 41 |
41 namespace net { | 42 namespace net { |
42 | 43 |
43 namespace { | 44 namespace { |
44 | 45 |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 | 280 |
280 void SpdyStreamRequest::Reset() { | 281 void SpdyStreamRequest::Reset() { |
281 session_ = NULL; | 282 session_ = NULL; |
282 stream_ = NULL; | 283 stream_ = NULL; |
283 url_ = GURL(); | 284 url_ = GURL(); |
284 priority_ = MINIMUM_PRIORITY; | 285 priority_ = MINIMUM_PRIORITY; |
285 net_log_ = BoundNetLog(); | 286 net_log_ = BoundNetLog(); |
286 callback_.Reset(); | 287 callback_.Reset(); |
287 } | 288 } |
288 | 289 |
289 // static | |
290 void SpdySession::SpdyIOBufferProducer::ActivateStream( | |
291 SpdySession* spdy_session, | |
292 SpdyStream* spdy_stream) { | |
293 spdy_session->ActivateStream(spdy_stream); | |
294 } | |
295 | |
296 // static | |
297 SpdyIOBuffer* SpdySession::SpdyIOBufferProducer::CreateIOBuffer( | |
298 SpdyFrame* frame, | |
299 RequestPriority priority, | |
300 SpdyStream* stream) { | |
301 size_t size = frame->size(); | |
302 DCHECK_GT(size, 0u); | |
303 | |
304 // TODO(mbelshe): We have too much copying of data here. | |
305 IOBufferWithSize* buffer = new IOBufferWithSize(size); | |
306 memcpy(buffer->data(), frame->data(), size); | |
307 | |
308 return new SpdyIOBuffer(buffer, size, priority, stream); | |
309 } | |
310 | |
311 SpdySession::SpdySession(const HostPortProxyPair& host_port_proxy_pair, | 290 SpdySession::SpdySession(const HostPortProxyPair& host_port_proxy_pair, |
312 SpdySessionPool* spdy_session_pool, | 291 SpdySessionPool* spdy_session_pool, |
313 HttpServerProperties* http_server_properties, | 292 HttpServerProperties* http_server_properties, |
314 bool verify_domain_authentication, | 293 bool verify_domain_authentication, |
315 bool enable_sending_initial_settings, | 294 bool enable_sending_initial_settings, |
316 bool enable_credential_frames, | 295 bool enable_credential_frames, |
317 bool enable_compression, | 296 bool enable_compression, |
318 bool enable_ping_based_connection_checking, | 297 bool enable_ping_based_connection_checking, |
319 NextProto default_protocol, | 298 NextProto default_protocol, |
320 size_t stream_initial_recv_window_size, | 299 size_t stream_initial_recv_window_size, |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 | 376 |
398 if (connection_->is_initialized()) { | 377 if (connection_->is_initialized()) { |
399 // With SPDY we can't recycle sockets. | 378 // With SPDY we can't recycle sockets. |
400 connection_->socket()->Disconnect(); | 379 connection_->socket()->Disconnect(); |
401 } | 380 } |
402 | 381 |
403 // Streams should all be gone now. | 382 // Streams should all be gone now. |
404 DCHECK_EQ(0u, num_active_streams()); | 383 DCHECK_EQ(0u, num_active_streams()); |
405 DCHECK_EQ(0u, num_unclaimed_pushed_streams()); | 384 DCHECK_EQ(0u, num_unclaimed_pushed_streams()); |
406 | 385 |
407 for (int i = NUM_PRIORITIES - 1; i >= MINIMUM_PRIORITY; --i) { | 386 for (int i = 0; i < NUM_PRIORITIES; ++i) { |
408 DCHECK(pending_create_stream_queues_[i].empty()); | 387 DCHECK(pending_create_stream_queues_[i].empty()); |
409 } | 388 } |
410 DCHECK(pending_stream_request_completions_.empty()); | 389 DCHECK(pending_stream_request_completions_.empty()); |
411 | 390 |
412 RecordHistograms(); | 391 RecordHistograms(); |
413 | 392 |
414 net_log_.EndEvent(NetLog::TYPE_SPDY_SESSION); | 393 net_log_.EndEvent(NetLog::TYPE_SPDY_SESSION); |
415 } | 394 } |
416 | 395 |
417 net::Error SpdySession::InitializeWithSocket( | 396 net::Error SpdySession::InitializeWithSocket( |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 return true; // This is not a secure session, so all domains are okay. | 471 return true; // This is not a secure session, so all domains are okay. |
493 | 472 |
494 return !ssl_info.client_cert_sent && | 473 return !ssl_info.client_cert_sent && |
495 (enable_credential_frames_ || !ssl_info.channel_id_sent || | 474 (enable_credential_frames_ || !ssl_info.channel_id_sent || |
496 ServerBoundCertService::GetDomainForHost(domain) == | 475 ServerBoundCertService::GetDomainForHost(domain) == |
497 ServerBoundCertService::GetDomainForHost( | 476 ServerBoundCertService::GetDomainForHost( |
498 host_port_proxy_pair_.first.host())) && | 477 host_port_proxy_pair_.first.host())) && |
499 ssl_info.cert->VerifyNameMatch(domain); | 478 ssl_info.cert->VerifyNameMatch(domain); |
500 } | 479 } |
501 | 480 |
502 void SpdySession::SetStreamHasWriteAvailable(SpdyStream* stream, | |
503 SpdyIOBufferProducer* producer) { | |
504 write_queue_.push(producer); | |
505 stream_producers_[producer] = stream; | |
506 WriteSocketLater(); | |
507 } | |
508 | |
509 int SpdySession::GetPushStream( | 481 int SpdySession::GetPushStream( |
510 const GURL& url, | 482 const GURL& url, |
511 scoped_refptr<SpdyStream>* stream, | 483 scoped_refptr<SpdyStream>* stream, |
512 const BoundNetLog& stream_net_log) { | 484 const BoundNetLog& stream_net_log) { |
513 CHECK_NE(state_, CLOSED); | 485 CHECK_NE(state_, CLOSED); |
514 | 486 |
515 *stream = NULL; | 487 *stream = NULL; |
516 | 488 |
517 // Don't allow access to secure push streams over an unauthenticated, but | 489 // Don't allow access to secure push streams over an unauthenticated, but |
518 // encrypted SSL socket. | 490 // encrypted SSL socket. |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
652 | 624 |
653 void SpdySession::AddPooledAlias(const HostPortProxyPair& alias) { | 625 void SpdySession::AddPooledAlias(const HostPortProxyPair& alias) { |
654 pooled_aliases_.insert(alias); | 626 pooled_aliases_.insert(alias); |
655 } | 627 } |
656 | 628 |
657 int SpdySession::GetProtocolVersion() const { | 629 int SpdySession::GetProtocolVersion() const { |
658 DCHECK(buffered_spdy_framer_.get()); | 630 DCHECK(buffered_spdy_framer_.get()); |
659 return buffered_spdy_framer_->protocol_version(); | 631 return buffered_spdy_framer_->protocol_version(); |
660 } | 632 } |
661 | 633 |
662 SpdyFrame* SpdySession::CreateSynStream( | 634 void SpdySession::EnqueueStreamWrite( |
| 635 SpdyStream* stream, |
| 636 scoped_ptr<SpdyFrameProducer> producer) { |
| 637 EnqueueWrite(stream->priority(), producer.Pass(), stream); |
| 638 } |
| 639 |
| 640 scoped_ptr<SpdyFrame> SpdySession::CreateSynStream( |
663 SpdyStreamId stream_id, | 641 SpdyStreamId stream_id, |
664 RequestPriority priority, | 642 RequestPriority priority, |
665 uint8 credential_slot, | 643 uint8 credential_slot, |
666 SpdyControlFlags flags, | 644 SpdyControlFlags flags, |
667 const SpdyHeaderBlock& headers) { | 645 const SpdyHeaderBlock& headers) { |
668 CHECK(IsStreamActive(stream_id)); | 646 CHECK(IsStreamActive(stream_id)); |
669 const scoped_refptr<SpdyStream>& stream = active_streams_[stream_id]; | 647 const scoped_refptr<SpdyStream>& stream = active_streams_[stream_id]; |
670 CHECK_EQ(stream->stream_id(), stream_id); | 648 CHECK_EQ(stream->stream_id(), stream_id); |
671 | 649 |
672 SendPrefacePingIfNoneInFlight(); | 650 SendPrefacePingIfNoneInFlight(); |
(...skipping 11 matching lines...) Expand all Loading... |
684 | 662 |
685 if (net_log().IsLoggingAllEvents()) { | 663 if (net_log().IsLoggingAllEvents()) { |
686 net_log().AddEvent( | 664 net_log().AddEvent( |
687 NetLog::TYPE_SPDY_SESSION_SYN_STREAM, | 665 NetLog::TYPE_SPDY_SESSION_SYN_STREAM, |
688 base::Bind(&NetLogSpdySynCallback, &headers, | 666 base::Bind(&NetLogSpdySynCallback, &headers, |
689 (flags & CONTROL_FLAG_FIN) != 0, | 667 (flags & CONTROL_FLAG_FIN) != 0, |
690 (flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0, | 668 (flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0, |
691 stream_id, 0)); | 669 stream_id, 0)); |
692 } | 670 } |
693 | 671 |
694 return syn_frame.release(); | 672 return syn_frame.Pass(); |
695 } | 673 } |
696 | 674 |
697 SpdyFrame* SpdySession::CreateCredentialFrame( | 675 int SpdySession::CreateCredentialFrame( |
698 const std::string& origin, | 676 const std::string& origin, |
699 SSLClientCertType type, | 677 SSLClientCertType type, |
700 const std::string& key, | 678 const std::string& key, |
701 const std::string& cert, | 679 const std::string& cert, |
702 RequestPriority priority) { | 680 RequestPriority priority, |
| 681 scoped_ptr<SpdyFrame>* credential_frame) { |
703 DCHECK(is_secure_); | 682 DCHECK(is_secure_); |
704 SSLClientSocket* ssl_socket = GetSSLClientSocket(); | 683 SSLClientSocket* ssl_socket = GetSSLClientSocket(); |
705 DCHECK(ssl_socket); | 684 DCHECK(ssl_socket); |
706 DCHECK(ssl_socket->WasChannelIDSent()); | 685 DCHECK(ssl_socket->WasChannelIDSent()); |
707 | 686 |
708 SpdyCredential credential; | 687 SpdyCredential credential; |
709 std::string tls_unique; | 688 std::string tls_unique; |
710 ssl_socket->GetTLSUniqueChannelBinding(&tls_unique); | 689 ssl_socket->GetTLSUniqueChannelBinding(&tls_unique); |
711 size_t slot = credential_state_.SetHasCredential(GURL(origin)); | 690 size_t slot = credential_state_.SetHasCredential(GURL(origin)); |
712 int rv = SpdyCredentialBuilder::Build(tls_unique, type, key, cert, slot, | 691 int rv = SpdyCredentialBuilder::Build(tls_unique, type, key, cert, slot, |
713 &credential); | 692 &credential); |
714 DCHECK_EQ(OK, rv); | 693 DCHECK_NE(rv, ERR_IO_PENDING); |
715 if (rv != OK) | 694 if (rv != OK) |
716 return NULL; | 695 return rv; |
717 | 696 |
718 DCHECK(buffered_spdy_framer_.get()); | 697 DCHECK(buffered_spdy_framer_.get()); |
719 scoped_ptr<SpdyFrame> credential_frame( | 698 credential_frame->reset( |
720 buffered_spdy_framer_->CreateCredentialFrame(credential)); | 699 buffered_spdy_framer_->CreateCredentialFrame(credential)); |
721 | 700 |
722 if (net_log().IsLoggingAllEvents()) { | 701 if (net_log().IsLoggingAllEvents()) { |
723 net_log().AddEvent( | 702 net_log().AddEvent( |
724 NetLog::TYPE_SPDY_SESSION_SEND_CREDENTIAL, | 703 NetLog::TYPE_SPDY_SESSION_SEND_CREDENTIAL, |
725 base::Bind(&NetLogSpdyCredentialCallback, credential.slot, &origin)); | 704 base::Bind(&NetLogSpdyCredentialCallback, credential.slot, &origin)); |
726 } | 705 } |
727 return credential_frame.release(); | 706 return OK; |
728 } | 707 } |
729 | 708 |
730 SpdyFrame* SpdySession::CreateHeadersFrame( | 709 scoped_ptr<SpdyFrame> SpdySession::CreateHeadersFrame( |
731 SpdyStreamId stream_id, | 710 SpdyStreamId stream_id, |
732 const SpdyHeaderBlock& headers, | 711 const SpdyHeaderBlock& headers, |
733 SpdyControlFlags flags) { | 712 SpdyControlFlags flags) { |
734 // Find our stream | 713 // Find our stream |
735 CHECK(IsStreamActive(stream_id)); | 714 CHECK(IsStreamActive(stream_id)); |
736 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; | 715 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
737 CHECK_EQ(stream->stream_id(), stream_id); | 716 CHECK_EQ(stream->stream_id(), stream_id); |
738 | 717 |
739 // Create a HEADER frame. | 718 // Create a HEADER frame. |
740 scoped_ptr<SpdyFrame> frame( | 719 scoped_ptr<SpdyFrame> frame( |
741 buffered_spdy_framer_->CreateHeaders( | 720 buffered_spdy_framer_->CreateHeaders( |
742 stream_id, flags, enable_compression_, &headers)); | 721 stream_id, flags, enable_compression_, &headers)); |
743 | 722 |
744 if (net_log().IsLoggingAllEvents()) { | 723 if (net_log().IsLoggingAllEvents()) { |
745 bool fin = flags & CONTROL_FLAG_FIN; | 724 bool fin = flags & CONTROL_FLAG_FIN; |
746 net_log().AddEvent( | 725 net_log().AddEvent( |
747 NetLog::TYPE_SPDY_SESSION_SEND_HEADERS, | 726 NetLog::TYPE_SPDY_SESSION_SEND_HEADERS, |
748 base::Bind(&NetLogSpdySynCallback, | 727 base::Bind(&NetLogSpdySynCallback, |
749 &headers, fin, /*unidirectional=*/false, | 728 &headers, fin, /*unidirectional=*/false, |
750 stream_id, 0)); | 729 stream_id, 0)); |
751 } | 730 } |
752 return frame.release(); | 731 return frame.Pass(); |
753 } | 732 } |
754 | 733 |
755 SpdyFrame* SpdySession::CreateDataFrame(SpdyStreamId stream_id, | 734 scoped_ptr<SpdyFrame> SpdySession::CreateDataFrame(SpdyStreamId stream_id, |
756 net::IOBuffer* data, int len, | 735 net::IOBuffer* data, |
757 SpdyDataFlags flags) { | 736 int len, |
| 737 SpdyDataFlags flags) { |
758 // Find our stream | 738 // Find our stream |
759 CHECK(IsStreamActive(stream_id)); | 739 CHECK(IsStreamActive(stream_id)); |
760 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; | 740 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
761 CHECK_EQ(stream->stream_id(), stream_id); | 741 CHECK_EQ(stream->stream_id(), stream_id); |
762 | 742 |
763 if (len < 0) { | 743 if (len < 0) { |
764 NOTREACHED(); | 744 NOTREACHED(); |
765 return NULL; | 745 return scoped_ptr<SpdyFrame>(); |
766 } | 746 } |
767 | 747 |
768 if (len > kMaxSpdyFrameChunkSize) { | 748 if (len > kMaxSpdyFrameChunkSize) { |
769 len = kMaxSpdyFrameChunkSize; | 749 len = kMaxSpdyFrameChunkSize; |
770 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN); | 750 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN); |
771 } | 751 } |
772 | 752 |
773 // Obey send window size of the stream (and session, if applicable) | 753 // Obey send window size of the stream (and session, if applicable) |
774 // if flow control is enabled. | 754 // if flow control is enabled. |
775 if (flow_control_state_ >= FLOW_CONTROL_STREAM) { | 755 if (flow_control_state_ >= FLOW_CONTROL_STREAM) { |
776 int32 effective_window_size = stream->send_window_size(); | 756 int32 effective_window_size = stream->send_window_size(); |
777 if (effective_window_size <= 0) { | 757 if (effective_window_size <= 0) { |
778 // Because we queue frames onto the session, it is possible that | 758 // Because we queue frames onto the session, it is possible that |
779 // a stream was not flow controlled at the time it attempted the | 759 // a stream was not flow controlled at the time it attempted the |
780 // write, but when we go to fulfill the write, it is now flow | 760 // write, but when we go to fulfill the write, it is now flow |
781 // controlled. This is why we need the session to mark the stream | 761 // controlled. This is why we need the session to mark the stream |
782 // as stalled - because only the session knows for sure when the | 762 // as stalled - because only the session knows for sure when the |
783 // stall occurs. | 763 // stall occurs. |
784 stream->set_send_stalled_by_flow_control(true); | 764 stream->set_send_stalled_by_flow_control(true); |
785 net_log().AddEvent( | 765 net_log().AddEvent( |
786 NetLog::TYPE_SPDY_SESSION_STREAM_STALLED_ON_STREAM_SEND_WINDOW, | 766 NetLog::TYPE_SPDY_SESSION_STREAM_STALLED_ON_STREAM_SEND_WINDOW, |
787 NetLog::IntegerCallback("stream_id", stream_id)); | 767 NetLog::IntegerCallback("stream_id", stream_id)); |
788 return NULL; | 768 return scoped_ptr<SpdyFrame>(); |
789 } | 769 } |
790 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) { | 770 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) { |
791 effective_window_size = | 771 effective_window_size = |
792 std::min(effective_window_size, session_send_window_size_); | 772 std::min(effective_window_size, session_send_window_size_); |
793 if (effective_window_size <= 0) { | 773 if (effective_window_size <= 0) { |
794 DCHECK(IsSendStalled()); | 774 DCHECK(IsSendStalled()); |
795 stream->set_send_stalled_by_flow_control(true); | 775 stream->set_send_stalled_by_flow_control(true); |
796 QueueSendStalledStream(stream); | 776 QueueSendStalledStream(stream); |
797 net_log().AddEvent( | 777 net_log().AddEvent( |
798 NetLog::TYPE_SPDY_SESSION_STREAM_STALLED_ON_SESSION_SEND_WINDOW, | 778 NetLog::TYPE_SPDY_SESSION_STREAM_STALLED_ON_SESSION_SEND_WINDOW, |
799 NetLog::IntegerCallback("stream_id", stream_id)); | 779 NetLog::IntegerCallback("stream_id", stream_id)); |
800 return NULL; | 780 return scoped_ptr<SpdyFrame>(); |
801 } | 781 } |
802 } | 782 } |
803 | 783 |
804 int new_len = std::min(len, effective_window_size); | 784 int new_len = std::min(len, effective_window_size); |
805 if (new_len < len) { | 785 if (new_len < len) { |
806 len = new_len; | 786 len = new_len; |
807 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN); | 787 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN); |
808 } | 788 } |
809 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) | 789 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) |
810 DecreaseSendWindowSize(static_cast<int32>(len)); | 790 DecreaseSendWindowSize(static_cast<int32>(len)); |
(...skipping 10 matching lines...) Expand all Loading... |
821 // Send PrefacePing for DATA_FRAMEs with nonzero payload size. | 801 // Send PrefacePing for DATA_FRAMEs with nonzero payload size. |
822 if (len > 0) | 802 if (len > 0) |
823 SendPrefacePingIfNoneInFlight(); | 803 SendPrefacePingIfNoneInFlight(); |
824 | 804 |
825 // TODO(mbelshe): reduce memory copies here. | 805 // TODO(mbelshe): reduce memory copies here. |
826 DCHECK(buffered_spdy_framer_.get()); | 806 DCHECK(buffered_spdy_framer_.get()); |
827 scoped_ptr<SpdyFrame> frame( | 807 scoped_ptr<SpdyFrame> frame( |
828 buffered_spdy_framer_->CreateDataFrame( | 808 buffered_spdy_framer_->CreateDataFrame( |
829 stream_id, data->data(), static_cast<uint32>(len), flags)); | 809 stream_id, data->data(), static_cast<uint32>(len), flags)); |
830 | 810 |
831 return frame.release(); | 811 return frame.Pass(); |
832 } | 812 } |
833 | 813 |
834 void SpdySession::CloseStream(SpdyStreamId stream_id, int status) { | 814 void SpdySession::CloseStream(SpdyStreamId stream_id, int status) { |
835 DCHECK_NE(0u, stream_id); | 815 DCHECK_NE(0u, stream_id); |
836 // TODO(mbelshe): We should send a RST_STREAM control frame here | 816 // TODO(mbelshe): We should send a RST_STREAM control frame here |
837 // so that the server can cancel a large send. | 817 // so that the server can cancel a large send. |
838 | 818 |
839 DeleteStream(stream_id, status); | 819 DeleteStream(stream_id, status); |
840 } | 820 } |
841 | 821 |
(...skipping 14 matching lines...) Expand all Loading... |
856 DCHECK(buffered_spdy_framer_.get()); | 836 DCHECK(buffered_spdy_framer_.get()); |
857 scoped_ptr<SpdyFrame> rst_frame( | 837 scoped_ptr<SpdyFrame> rst_frame( |
858 buffered_spdy_framer_->CreateRstStream(stream_id, status)); | 838 buffered_spdy_framer_->CreateRstStream(stream_id, status)); |
859 | 839 |
860 // Default to lowest priority unless we know otherwise. | 840 // Default to lowest priority unless we know otherwise. |
861 RequestPriority priority = net::IDLE; | 841 RequestPriority priority = net::IDLE; |
862 if (IsStreamActive(stream_id)) { | 842 if (IsStreamActive(stream_id)) { |
863 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; | 843 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
864 priority = stream->priority(); | 844 priority = stream->priority(); |
865 } | 845 } |
866 QueueFrame(rst_frame.release(), priority); | 846 EnqueueSessionWrite(priority, rst_frame.Pass()); |
867 RecordProtocolErrorHistogram( | 847 RecordProtocolErrorHistogram( |
868 static_cast<SpdyProtocolErrorDetails>(status + STATUS_CODE_INVALID)); | 848 static_cast<SpdyProtocolErrorDetails>(status + STATUS_CODE_INVALID)); |
869 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); | 849 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); |
870 } | 850 } |
871 | 851 |
872 bool SpdySession::IsStreamActive(SpdyStreamId stream_id) const { | 852 bool SpdySession::IsStreamActive(SpdyStreamId stream_id) const { |
873 return ContainsKey(active_streams_, stream_id); | 853 return ContainsKey(active_streams_, stream_id); |
874 } | 854 } |
875 | 855 |
876 LoadState SpdySession::GetLoadState() const { | 856 LoadState SpdySession::GetLoadState() const { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
923 buffered_spdy_framer_->ProcessInput(data, bytes_read); | 903 buffered_spdy_framer_->ProcessInput(data, bytes_read); |
924 bytes_read -= bytes_processed; | 904 bytes_read -= bytes_processed; |
925 data += bytes_processed; | 905 data += bytes_processed; |
926 } | 906 } |
927 | 907 |
928 if (state_ != CLOSED) | 908 if (state_ != CLOSED) |
929 ReadSocket(); | 909 ReadSocket(); |
930 } | 910 } |
931 | 911 |
932 void SpdySession::OnWriteComplete(int result) { | 912 void SpdySession::OnWriteComplete(int result) { |
| 913 // Releasing the in-flight write can have a side-effect of dropping |
| 914 // the last reference to |this|. Hold a reference through this |
| 915 // function. |
| 916 scoped_refptr<SpdySession> self(this); |
| 917 |
933 DCHECK(write_pending_); | 918 DCHECK(write_pending_); |
934 DCHECK(in_flight_write_.size()); | 919 DCHECK_GT(in_flight_write_.buffer()->BytesRemaining(), 0); |
935 | 920 |
936 last_activity_time_ = base::TimeTicks::Now(); | 921 last_activity_time_ = base::TimeTicks::Now(); |
937 write_pending_ = false; | 922 write_pending_ = false; |
938 | 923 |
939 scoped_refptr<SpdyStream> stream = in_flight_write_.stream(); | 924 if (result < 0) { |
| 925 in_flight_write_.Release(); |
| 926 CloseSessionOnError(static_cast<net::Error>(result), true, "Write error"); |
| 927 return; |
| 928 } |
940 | 929 |
941 if (result >= 0) { | 930 // It should not be possible to have written more bytes than our |
942 // It should not be possible to have written more bytes than our | 931 // in_flight_write_. |
943 // in_flight_write_. | 932 DCHECK_LE(result, in_flight_write_.buffer()->BytesRemaining()); |
944 DCHECK_LE(result, in_flight_write_.buffer()->BytesRemaining()); | |
945 | 933 |
946 in_flight_write_.buffer()->DidConsume(result); | 934 in_flight_write_.buffer()->DidConsume(result); |
947 | 935 |
948 // We only notify the stream when we've fully written the pending frame. | 936 // We only notify the stream when we've fully written the pending frame. |
949 if (!in_flight_write_.buffer()->BytesRemaining()) { | 937 if (in_flight_write_.buffer()->BytesRemaining() == 0) { |
950 if (stream) { | 938 DCHECK_GT(result, 0); |
951 // Report the number of bytes written to the caller, but exclude the | |
952 // frame size overhead. NOTE: if this frame was compressed the | |
953 // reported bytes written is the compressed size, not the original | |
954 // size. | |
955 if (result > 0) { | |
956 result = in_flight_write_.buffer()->size(); | |
957 DCHECK_GE(result, | |
958 static_cast<int>( | |
959 buffered_spdy_framer_->GetControlFrameHeaderSize())); | |
960 result -= buffered_spdy_framer_->GetControlFrameHeaderSize(); | |
961 } | |
962 | 939 |
963 // It is possible that the stream was cancelled while we were writing | 940 scoped_refptr<SpdyStream> stream = in_flight_write_.stream(); |
964 // to the socket. | |
965 if (!stream->cancelled()) | |
966 stream->OnWriteComplete(result); | |
967 } | |
968 | 941 |
969 // Cleanup the write which just completed. | 942 // It is possible that the stream was cancelled while we were writing |
970 in_flight_write_.release(); | 943 // to the socket. |
| 944 if (stream && !stream->cancelled()) { |
| 945 // Report the number of bytes written to the caller, but exclude the |
| 946 // frame size overhead. NOTE: if this frame was compressed the |
| 947 // reported bytes written is the compressed size, not the original |
| 948 // size. |
| 949 result = in_flight_write_.buffer()->size(); |
| 950 DCHECK_GE(result, |
| 951 static_cast<int>( |
| 952 buffered_spdy_framer_->GetControlFrameHeaderSize())); |
| 953 result -= buffered_spdy_framer_->GetControlFrameHeaderSize(); |
| 954 |
| 955 stream->OnWriteComplete(result); |
971 } | 956 } |
972 | 957 |
973 // Write more data. We're already in a continuation, so we can | 958 // Cleanup the write which just completed. |
974 // go ahead and write it immediately (without going back to the | 959 in_flight_write_.Release(); |
975 // message loop). | 960 } |
976 WriteSocketLater(); | |
977 } else { | |
978 in_flight_write_.release(); | |
979 | 961 |
980 // The stream is now errored. Close it down. | 962 // Write more data. We're already in a continuation, so we can go |
981 CloseSessionOnError( | 963 // ahead and write it immediately (without going back to the message |
982 static_cast<net::Error>(result), true, "The stream has errored."); | 964 // loop). |
983 } | 965 WriteSocketLater(); |
984 } | 966 } |
985 | 967 |
986 net::Error SpdySession::ReadSocket() { | 968 net::Error SpdySession::ReadSocket() { |
987 if (read_pending_) | 969 if (read_pending_) |
988 return OK; | 970 return OK; |
989 | 971 |
990 if (state_ == CLOSED) { | 972 if (state_ == CLOSED) { |
991 NOTREACHED(); | 973 NOTREACHED(); |
992 return ERR_UNEXPECTED; | 974 return ERR_UNEXPECTED; |
993 } | 975 } |
994 | 976 |
995 CHECK(connection_.get()); | 977 CHECK(connection_.get()); |
996 CHECK(connection_->socket()); | 978 CHECK(connection_->socket()); |
997 int bytes_read = connection_->socket()->Read( | 979 int bytes_read = connection_->socket()->Read( |
998 read_buffer_.get(), | 980 read_buffer_.get(), |
999 kReadBufferSize, | 981 kReadBufferSize, |
1000 base::Bind(&SpdySession::OnReadComplete, base::Unretained(this))); | 982 base::Bind(&SpdySession::OnReadComplete, weak_factory_.GetWeakPtr())); |
1001 switch (bytes_read) { | 983 switch (bytes_read) { |
1002 case 0: | 984 case 0: |
1003 // Socket is closed! | 985 // Socket is closed! |
1004 CloseSessionOnError(ERR_CONNECTION_CLOSED, true, "bytes_read is 0."); | 986 CloseSessionOnError(ERR_CONNECTION_CLOSED, true, "bytes_read is 0."); |
1005 return ERR_CONNECTION_CLOSED; | 987 return ERR_CONNECTION_CLOSED; |
1006 case net::ERR_IO_PENDING: | 988 case net::ERR_IO_PENDING: |
1007 // Waiting for data. Nothing to do now. | 989 // Waiting for data. Nothing to do now. |
1008 read_pending_ = true; | 990 read_pending_ = true; |
1009 return ERR_IO_PENDING; | 991 return ERR_IO_PENDING; |
1010 default: | 992 default: |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1044 // closed, just return. | 1026 // closed, just return. |
1045 if (state_ < CONNECTED || state_ == CLOSED) | 1027 if (state_ < CONNECTED || state_ == CLOSED) |
1046 return; | 1028 return; |
1047 | 1029 |
1048 if (write_pending_) // Another write is in progress still. | 1030 if (write_pending_) // Another write is in progress still. |
1049 return; | 1031 return; |
1050 | 1032 |
1051 // Loop sending frames until we've sent everything or until the write | 1033 // Loop sending frames until we've sent everything or until the write |
1052 // returns error (or ERR_IO_PENDING). | 1034 // returns error (or ERR_IO_PENDING). |
1053 DCHECK(buffered_spdy_framer_.get()); | 1035 DCHECK(buffered_spdy_framer_.get()); |
1054 while (in_flight_write_.buffer() || !write_queue_.empty()) { | 1036 while (true) { |
1055 if (!in_flight_write_.buffer()) { | 1037 if (in_flight_write_.buffer()) { |
1056 // Grab the next SpdyBuffer to send. | 1038 DCHECK_GT(in_flight_write_.buffer()->BytesRemaining(), 0); |
1057 scoped_ptr<SpdyIOBufferProducer> producer(write_queue_.top()); | 1039 } else { |
1058 write_queue_.pop(); | 1040 // Grab the next frame to send. |
1059 scoped_ptr<SpdyIOBuffer> buffer(producer->ProduceNextBuffer(this)); | 1041 scoped_ptr<SpdyFrameProducer> producer; |
1060 stream_producers_.erase(producer.get()); | 1042 scoped_refptr<SpdyStream> stream; |
| 1043 if (!write_queue_.Dequeue(&producer, &stream)) |
| 1044 break; |
| 1045 |
1061 // It is possible that a stream had data to write, but a | 1046 // It is possible that a stream had data to write, but a |
1062 // WINDOW_UPDATE frame has been received which made that | 1047 // WINDOW_UPDATE frame has been received which made that |
1063 // stream no longer writable. | 1048 // stream no longer writable. |
1064 // TODO(rch): consider handling that case by removing the | 1049 // TODO(rch): consider handling that case by removing the |
1065 // stream from the writable queue? | 1050 // stream from the writable queue? |
1066 if (buffer == NULL) | 1051 if (stream.get() && stream->cancelled()) |
1067 continue; | 1052 continue; |
1068 | 1053 |
1069 in_flight_write_ = *buffer; | 1054 if (stream.get() && stream->stream_id() == 0) |
1070 } else { | 1055 ActivateStream(stream); |
1071 DCHECK(in_flight_write_.buffer()->BytesRemaining()); | 1056 |
| 1057 scoped_ptr<SpdyFrame> frame = producer->ProduceFrame(); |
| 1058 if (!frame) { |
| 1059 NOTREACHED(); |
| 1060 continue; |
| 1061 } |
| 1062 DCHECK_GT(frame->size(), 0u); |
| 1063 |
| 1064 // TODO(mbelshe): We have too much copying of data here. |
| 1065 scoped_refptr<IOBufferWithSize> buffer = |
| 1066 new IOBufferWithSize(frame->size()); |
| 1067 memcpy(buffer->data(), frame->data(), frame->size()); |
| 1068 in_flight_write_ = SpdyIOBuffer(buffer, frame->size(), stream); |
1072 } | 1069 } |
1073 | 1070 |
1074 write_pending_ = true; | 1071 write_pending_ = true; |
1075 int rv = connection_->socket()->Write( | 1072 int rv = connection_->socket()->Write( |
1076 in_flight_write_.buffer(), | 1073 in_flight_write_.buffer(), |
1077 in_flight_write_.buffer()->BytesRemaining(), | 1074 in_flight_write_.buffer()->BytesRemaining(), |
1078 base::Bind(&SpdySession::OnWriteComplete, weak_factory_.GetWeakPtr())); | 1075 base::Bind(&SpdySession::OnWriteComplete, weak_factory_.GetWeakPtr())); |
1079 if (rv == net::ERR_IO_PENDING) | 1076 if (rv == net::ERR_IO_PENDING) |
1080 break; | 1077 break; |
1081 | 1078 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1119 } | 1116 } |
1120 | 1117 |
1121 while (!created_streams_.empty()) { | 1118 while (!created_streams_.empty()) { |
1122 CreatedStreamSet::iterator it = created_streams_.begin(); | 1119 CreatedStreamSet::iterator it = created_streams_.begin(); |
1123 const scoped_refptr<SpdyStream> stream = *it; | 1120 const scoped_refptr<SpdyStream> stream = *it; |
1124 created_streams_.erase(it); | 1121 created_streams_.erase(it); |
1125 LogAbandonedStream(stream, status); | 1122 LogAbandonedStream(stream, status); |
1126 stream->OnClose(status); | 1123 stream->OnClose(status); |
1127 } | 1124 } |
1128 | 1125 |
1129 // We also need to drain the queue. | 1126 write_queue_.Clear(); |
1130 while (!write_queue_.empty()) { | |
1131 scoped_ptr<SpdyIOBufferProducer> producer(write_queue_.top()); | |
1132 write_queue_.pop(); | |
1133 stream_producers_.erase(producer.get()); | |
1134 } | |
1135 } | 1127 } |
1136 | 1128 |
1137 void SpdySession::LogAbandonedStream(const scoped_refptr<SpdyStream>& stream, | 1129 void SpdySession::LogAbandonedStream(const scoped_refptr<SpdyStream>& stream, |
1138 net::Error status) { | 1130 net::Error status) { |
1139 DCHECK(stream); | 1131 DCHECK(stream); |
1140 std::string description = base::StringPrintf( | 1132 std::string description = base::StringPrintf( |
1141 "ABANDONED (stream_id=%d): ", stream->stream_id()) + stream->path(); | 1133 "ABANDONED (stream_id=%d): ", stream->stream_id()) + stream->path(); |
1142 stream->LogStreamError(status, description); | 1134 stream->LogStreamError(status, description); |
1143 } | 1135 } |
1144 | 1136 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1250 if (connection_->socket()) { | 1242 if (connection_->socket()) { |
1251 rv = connection_->socket()->GetLocalAddress(address); | 1243 rv = connection_->socket()->GetLocalAddress(address); |
1252 } | 1244 } |
1253 | 1245 |
1254 UMA_HISTOGRAM_BOOLEAN("Net.SpdySessionSocketNotConnectedGetLocalAddress", | 1246 UMA_HISTOGRAM_BOOLEAN("Net.SpdySessionSocketNotConnectedGetLocalAddress", |
1255 rv == ERR_SOCKET_NOT_CONNECTED); | 1247 rv == ERR_SOCKET_NOT_CONNECTED); |
1256 | 1248 |
1257 return rv; | 1249 return rv; |
1258 } | 1250 } |
1259 | 1251 |
1260 class SimpleSpdyIOBufferProducer : public SpdySession::SpdyIOBufferProducer { | 1252 void SpdySession::EnqueueSessionWrite(RequestPriority priority, |
1261 public: | 1253 scoped_ptr<SpdyFrame> frame) { |
1262 SimpleSpdyIOBufferProducer(SpdyFrame* frame, | 1254 EnqueueWrite( |
1263 RequestPriority priority) | 1255 priority, |
1264 : frame_(frame), | 1256 scoped_ptr<SpdyFrameProducer>(new SimpleFrameProducer(frame.Pass())), |
1265 priority_(priority) { | 1257 NULL); |
1266 } | 1258 } |
1267 | 1259 |
1268 virtual RequestPriority GetPriority() const OVERRIDE { | 1260 void SpdySession::EnqueueWrite(RequestPriority priority, |
1269 return priority_; | 1261 scoped_ptr<SpdyFrameProducer> producer, |
1270 } | 1262 const scoped_refptr<SpdyStream>& stream) { |
1271 | 1263 write_queue_.Enqueue(priority, producer.Pass(), stream); |
1272 virtual SpdyIOBuffer* ProduceNextBuffer(SpdySession* session) OVERRIDE { | |
1273 return SpdySession::SpdyIOBufferProducer::CreateIOBuffer( | |
1274 frame_.get(), priority_, NULL); | |
1275 } | |
1276 | |
1277 private: | |
1278 scoped_ptr<SpdyFrame> frame_; | |
1279 RequestPriority priority_; | |
1280 }; | |
1281 | |
1282 void SpdySession::QueueFrame(SpdyFrame* frame, | |
1283 RequestPriority priority) { | |
1284 SimpleSpdyIOBufferProducer* producer = | |
1285 new SimpleSpdyIOBufferProducer(frame, priority); | |
1286 write_queue_.push(producer); | |
1287 WriteSocketLater(); | 1264 WriteSocketLater(); |
1288 } | 1265 } |
1289 | 1266 |
1290 void SpdySession::ActivateStream(SpdyStream* stream) { | 1267 void SpdySession::ActivateStream(SpdyStream* stream) { |
1291 if (stream->stream_id() == 0) { | 1268 if (stream->stream_id() == 0) { |
1292 stream->set_stream_id(GetNewStreamId()); | 1269 stream->set_stream_id(GetNewStreamId()); |
1293 created_streams_.erase(scoped_refptr<SpdyStream>(stream)); | 1270 created_streams_.erase(scoped_refptr<SpdyStream>(stream)); |
1294 } | 1271 } |
1295 const SpdyStreamId id = stream->stream_id(); | 1272 const SpdyStreamId id = stream->stream_id(); |
1296 DCHECK(!IsStreamActive(id)); | 1273 DCHECK(!IsStreamActive(id)); |
1297 | 1274 |
1298 active_streams_[id] = stream; | 1275 active_streams_[id] = stream; |
1299 } | 1276 } |
1300 | 1277 |
1301 void SpdySession::DeleteStream(SpdyStreamId id, int status) { | 1278 void SpdySession::DeleteStream(SpdyStreamId id, int status) { |
1302 // For push streams, if they are being deleted normally, we leave | 1279 // For push streams, if they are being deleted normally, we leave |
1303 // the stream in the unclaimed_pushed_streams_ list. However, if | 1280 // the stream in the unclaimed_pushed_streams_ list. However, if |
1304 // the stream is errored out, clean it up entirely. | 1281 // the stream is errored out, clean it up entirely. |
1305 if (status != OK) { | 1282 if (status != OK) { |
1306 PushedStreamMap::iterator it; | 1283 for (PushedStreamMap::iterator it = unclaimed_pushed_streams_.begin(); |
1307 for (it = unclaimed_pushed_streams_.begin(); | |
1308 it != unclaimed_pushed_streams_.end(); ++it) { | 1284 it != unclaimed_pushed_streams_.end(); ++it) { |
1309 scoped_refptr<SpdyStream> curr = it->second.first; | 1285 scoped_refptr<SpdyStream> curr = it->second.first; |
1310 if (id == curr->stream_id()) { | 1286 if (id == curr->stream_id()) { |
1311 unclaimed_pushed_streams_.erase(it); | 1287 unclaimed_pushed_streams_.erase(it); |
1312 break; | 1288 break; |
1313 } | 1289 } |
1314 } | 1290 } |
1315 } | 1291 } |
1316 | 1292 |
1317 // The stream might have been deleted. | 1293 // The stream might have been deleted. |
1318 ActiveStreamMap::iterator it2 = active_streams_.find(id); | 1294 ActiveStreamMap::iterator it = active_streams_.find(id); |
1319 if (it2 == active_streams_.end()) | 1295 if (it == active_streams_.end()) |
1320 return; | 1296 return; |
1321 | 1297 |
1322 // Possibly remove from the write queue. | 1298 const scoped_refptr<SpdyStream> stream(it->second); |
1323 WriteQueue old = write_queue_; | 1299 active_streams_.erase(it); |
1324 write_queue_ = WriteQueue(); | 1300 DCHECK(stream); |
1325 while (!old.empty()) { | 1301 |
1326 scoped_ptr<SpdyIOBufferProducer> producer(old.top()); | 1302 write_queue_.RemovePendingWritesForStream(stream); |
1327 old.pop(); | |
1328 StreamProducerMap::iterator it = stream_producers_.find(producer.get()); | |
1329 if (it == stream_producers_.end() || it->second->stream_id() != id) { | |
1330 write_queue_.push(producer.release()); | |
1331 } else { | |
1332 stream_producers_.erase(producer.get()); | |
1333 producer.reset(NULL); | |
1334 } | |
1335 } | |
1336 | 1303 |
1337 // If this is an active stream, call the callback. | 1304 // If this is an active stream, call the callback. |
1338 const scoped_refptr<SpdyStream> stream(it2->second); | |
1339 active_streams_.erase(it2); | |
1340 DCHECK(stream); | |
1341 stream->OnClose(status); | 1305 stream->OnClose(status); |
1342 ProcessPendingStreamRequests(); | 1306 ProcessPendingStreamRequests(); |
1343 } | 1307 } |
1344 | 1308 |
1345 void SpdySession::RemoveFromPool() { | 1309 void SpdySession::RemoveFromPool() { |
1346 if (spdy_session_pool_) { | 1310 if (spdy_session_pool_) { |
1347 SpdySessionPool* pool = spdy_session_pool_; | 1311 SpdySessionPool* pool = spdy_session_pool_; |
1348 spdy_session_pool_ = NULL; | 1312 spdy_session_pool_ = NULL; |
1349 pool->Remove(make_scoped_refptr(this)); | 1313 pool->Remove(make_scoped_refptr(this)); |
1350 } | 1314 } |
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1914 void SpdySession::SendSettings(const SettingsMap& settings) { | 1878 void SpdySession::SendSettings(const SettingsMap& settings) { |
1915 net_log_.AddEvent( | 1879 net_log_.AddEvent( |
1916 NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS, | 1880 NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS, |
1917 base::Bind(&NetLogSpdySettingsCallback, &settings)); | 1881 base::Bind(&NetLogSpdySettingsCallback, &settings)); |
1918 | 1882 |
1919 // Create the SETTINGS frame and send it. | 1883 // Create the SETTINGS frame and send it. |
1920 DCHECK(buffered_spdy_framer_.get()); | 1884 DCHECK(buffered_spdy_framer_.get()); |
1921 scoped_ptr<SpdyFrame> settings_frame( | 1885 scoped_ptr<SpdyFrame> settings_frame( |
1922 buffered_spdy_framer_->CreateSettings(settings)); | 1886 buffered_spdy_framer_->CreateSettings(settings)); |
1923 sent_settings_ = true; | 1887 sent_settings_ = true; |
1924 QueueFrame(settings_frame.release(), HIGHEST); | 1888 EnqueueSessionWrite(HIGHEST, settings_frame.Pass()); |
1925 } | 1889 } |
1926 | 1890 |
1927 void SpdySession::HandleSetting(uint32 id, uint32 value) { | 1891 void SpdySession::HandleSetting(uint32 id, uint32 value) { |
1928 switch (id) { | 1892 switch (id) { |
1929 case SETTINGS_MAX_CONCURRENT_STREAMS: | 1893 case SETTINGS_MAX_CONCURRENT_STREAMS: |
1930 max_concurrent_streams_ = std::min(static_cast<size_t>(value), | 1894 max_concurrent_streams_ = std::min(static_cast<size_t>(value), |
1931 kMaxConcurrentStreamLimit); | 1895 kMaxConcurrentStreamLimit); |
1932 ProcessPendingStreamRequests(); | 1896 ProcessPendingStreamRequests(); |
1933 break; | 1897 break; |
1934 case SETTINGS_INITIAL_WINDOW_SIZE: { | 1898 case SETTINGS_INITIAL_WINDOW_SIZE: { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2002 } | 1966 } |
2003 | 1967 |
2004 net_log_.AddEvent( | 1968 net_log_.AddEvent( |
2005 NetLog::TYPE_SPDY_SESSION_SENT_WINDOW_UPDATE_FRAME, | 1969 NetLog::TYPE_SPDY_SESSION_SENT_WINDOW_UPDATE_FRAME, |
2006 base::Bind(&NetLogSpdyWindowUpdateFrameCallback, | 1970 base::Bind(&NetLogSpdyWindowUpdateFrameCallback, |
2007 stream_id, delta_window_size)); | 1971 stream_id, delta_window_size)); |
2008 | 1972 |
2009 DCHECK(buffered_spdy_framer_.get()); | 1973 DCHECK(buffered_spdy_framer_.get()); |
2010 scoped_ptr<SpdyFrame> window_update_frame( | 1974 scoped_ptr<SpdyFrame> window_update_frame( |
2011 buffered_spdy_framer_->CreateWindowUpdate(stream_id, delta_window_size)); | 1975 buffered_spdy_framer_->CreateWindowUpdate(stream_id, delta_window_size)); |
2012 QueueFrame(window_update_frame.release(), priority); | 1976 EnqueueSessionWrite(priority, window_update_frame.Pass()); |
2013 } | 1977 } |
2014 | 1978 |
2015 void SpdySession::WritePingFrame(uint32 unique_id) { | 1979 void SpdySession::WritePingFrame(uint32 unique_id) { |
2016 DCHECK(buffered_spdy_framer_.get()); | 1980 DCHECK(buffered_spdy_framer_.get()); |
2017 scoped_ptr<SpdyFrame> ping_frame( | 1981 scoped_ptr<SpdyFrame> ping_frame( |
2018 buffered_spdy_framer_->CreatePingFrame(unique_id)); | 1982 buffered_spdy_framer_->CreatePingFrame(unique_id)); |
2019 QueueFrame(ping_frame.release(), HIGHEST); | 1983 EnqueueSessionWrite(HIGHEST, ping_frame.Pass()); |
2020 | 1984 |
2021 if (net_log().IsLoggingAllEvents()) { | 1985 if (net_log().IsLoggingAllEvents()) { |
2022 net_log().AddEvent( | 1986 net_log().AddEvent( |
2023 NetLog::TYPE_SPDY_SESSION_PING, | 1987 NetLog::TYPE_SPDY_SESSION_PING, |
2024 base::Bind(&NetLogSpdyPingCallback, unique_id, "sent")); | 1988 base::Bind(&NetLogSpdyPingCallback, unique_id, "sent")); |
2025 } | 1989 } |
2026 if (unique_id % 2 != 0) { | 1990 if (unique_id % 2 != 0) { |
2027 next_ping_id_ += 2; | 1991 next_ping_id_ += 2; |
2028 ++pings_in_flight_; | 1992 ++pings_in_flight_; |
2029 PlanToCheckPingStatus(); | 1993 PlanToCheckPingStatus(); |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2304 } | 2268 } |
2305 | 2269 |
2306 session_recv_window_size_ -= delta_window_size; | 2270 session_recv_window_size_ -= delta_window_size; |
2307 net_log_.AddEvent( | 2271 net_log_.AddEvent( |
2308 NetLog::TYPE_SPDY_SESSION_UPDATE_RECV_WINDOW, | 2272 NetLog::TYPE_SPDY_SESSION_UPDATE_RECV_WINDOW, |
2309 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 2273 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
2310 -delta_window_size, session_recv_window_size_)); | 2274 -delta_window_size, session_recv_window_size_)); |
2311 } | 2275 } |
2312 | 2276 |
2313 } // namespace net | 2277 } // namespace net |
OLD | NEW |