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 <limits> | 8 #include <limits> |
9 #include <map> | 9 #include <map> |
10 #include <utility> | 10 #include <utility> |
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 transport_security_state_(transport_security_state), | 637 transport_security_state_(transport_security_state), |
638 read_buffer_(new IOBuffer(kReadBufferSize)), | 638 read_buffer_(new IOBuffer(kReadBufferSize)), |
639 stream_hi_water_mark_(kFirstStreamId), | 639 stream_hi_water_mark_(kFirstStreamId), |
640 last_accepted_push_stream_id_(0), | 640 last_accepted_push_stream_id_(0), |
641 unclaimed_pushed_streams_(this), | 641 unclaimed_pushed_streams_(this), |
642 num_pushed_streams_(0u), | 642 num_pushed_streams_(0u), |
643 num_active_pushed_streams_(0u), | 643 num_active_pushed_streams_(0u), |
644 in_flight_write_frame_type_(DATA), | 644 in_flight_write_frame_type_(DATA), |
645 in_flight_write_frame_size_(0), | 645 in_flight_write_frame_size_(0), |
646 is_secure_(false), | 646 is_secure_(false), |
647 certificate_error_code_(OK), | |
648 availability_state_(STATE_AVAILABLE), | 647 availability_state_(STATE_AVAILABLE), |
649 read_state_(READ_STATE_DO_READ), | 648 read_state_(READ_STATE_DO_READ), |
650 write_state_(WRITE_STATE_IDLE), | 649 write_state_(WRITE_STATE_IDLE), |
651 error_on_close_(OK), | 650 error_on_close_(OK), |
652 max_concurrent_streams_(kInitialMaxConcurrentStreams), | 651 max_concurrent_streams_(kInitialMaxConcurrentStreams), |
653 max_concurrent_pushed_streams_(kMaxConcurrentPushedStreams), | 652 max_concurrent_pushed_streams_(kMaxConcurrentPushedStreams), |
654 streams_initiated_count_(0), | 653 streams_initiated_count_(0), |
655 streams_pushed_count_(0), | 654 streams_pushed_count_(0), |
656 streams_pushed_and_claimed_count_(0), | 655 streams_pushed_and_claimed_count_(0), |
657 streams_abandoned_count_(0), | 656 streams_abandoned_count_(0), |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
700 connection_->socket()->Disconnect(); | 699 connection_->socket()->Disconnect(); |
701 | 700 |
702 RecordHistograms(); | 701 RecordHistograms(); |
703 | 702 |
704 net_log_.EndEvent(NetLogEventType::HTTP2_SESSION); | 703 net_log_.EndEvent(NetLogEventType::HTTP2_SESSION); |
705 } | 704 } |
706 | 705 |
707 void SpdySession::InitializeWithSocket( | 706 void SpdySession::InitializeWithSocket( |
708 std::unique_ptr<ClientSocketHandle> connection, | 707 std::unique_ptr<ClientSocketHandle> connection, |
709 SpdySessionPool* pool, | 708 SpdySessionPool* pool, |
710 bool is_secure, | 709 bool is_secure) { |
711 int certificate_error_code) { | |
712 CHECK(!in_io_loop_); | 710 CHECK(!in_io_loop_); |
713 DCHECK_EQ(availability_state_, STATE_AVAILABLE); | 711 DCHECK_EQ(availability_state_, STATE_AVAILABLE); |
714 DCHECK_EQ(read_state_, READ_STATE_DO_READ); | 712 DCHECK_EQ(read_state_, READ_STATE_DO_READ); |
715 DCHECK_EQ(write_state_, WRITE_STATE_IDLE); | 713 DCHECK_EQ(write_state_, WRITE_STATE_IDLE); |
716 DCHECK(!connection_); | 714 DCHECK(!connection_); |
717 | 715 |
718 DCHECK(certificate_error_code == OK || | |
719 certificate_error_code < ERR_IO_PENDING); | |
720 // TODO(akalin): Check connection->is_initialized() instead. This | 716 // TODO(akalin): Check connection->is_initialized() instead. This |
721 // requires re-working CreateFakeSpdySession(), though. | 717 // requires re-working CreateFakeSpdySession(), though. |
722 DCHECK(connection->socket()); | 718 DCHECK(connection->socket()); |
723 | 719 |
724 connection_ = std::move(connection); | 720 connection_ = std::move(connection); |
725 is_secure_ = is_secure; | 721 is_secure_ = is_secure; |
726 certificate_error_code_ = certificate_error_code; | |
727 | 722 |
728 session_send_window_size_ = kDefaultInitialWindowSize; | 723 session_send_window_size_ = kDefaultInitialWindowSize; |
729 session_recv_window_size_ = kDefaultInitialWindowSize; | 724 session_recv_window_size_ = kDefaultInitialWindowSize; |
730 | 725 |
731 buffered_spdy_framer_.reset(new BufferedSpdyFramer()); | 726 buffered_spdy_framer_.reset(new BufferedSpdyFramer()); |
732 buffered_spdy_framer_->set_visitor(this); | 727 buffered_spdy_framer_->set_visitor(this); |
733 buffered_spdy_framer_->set_debug_visitor(this); | 728 buffered_spdy_framer_->set_debug_visitor(this); |
734 buffered_spdy_framer_->UpdateHeaderDecoderTableSize(kMaxHeaderTableSize); | 729 buffered_spdy_framer_->UpdateHeaderDecoderTableSize(kMaxHeaderTableSize); |
735 | 730 |
736 net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_INITIALIZED, | 731 net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_INITIALIZED, |
(...skipping 28 matching lines...) Expand all Loading... |
765 int SpdySession::GetPushStream(const GURL& url, | 760 int SpdySession::GetPushStream(const GURL& url, |
766 base::WeakPtr<SpdyStream>* stream, | 761 base::WeakPtr<SpdyStream>* stream, |
767 const NetLogWithSource& stream_net_log) { | 762 const NetLogWithSource& stream_net_log) { |
768 CHECK(!in_io_loop_); | 763 CHECK(!in_io_loop_); |
769 | 764 |
770 stream->reset(); | 765 stream->reset(); |
771 | 766 |
772 if (availability_state_ == STATE_DRAINING) | 767 if (availability_state_ == STATE_DRAINING) |
773 return ERR_CONNECTION_CLOSED; | 768 return ERR_CONNECTION_CLOSED; |
774 | 769 |
775 Error err = TryAccessStream(url); | |
776 if (err != OK) | |
777 return err; | |
778 | |
779 *stream = GetActivePushStream(url); | 770 *stream = GetActivePushStream(url); |
780 if (*stream) { | 771 if (*stream) { |
781 DCHECK_LT(streams_pushed_and_claimed_count_, streams_pushed_count_); | 772 DCHECK_LT(streams_pushed_and_claimed_count_, streams_pushed_count_); |
782 streams_pushed_and_claimed_count_++; | 773 streams_pushed_and_claimed_count_++; |
783 } | 774 } |
784 return OK; | 775 return OK; |
785 } | 776 } |
786 | 777 |
787 // {,Try}CreateStream() and TryAccessStream() can be called with | 778 // {,Try}CreateStream() can be called with |in_io_loop_| set if a stream is |
788 // |in_io_loop_| set if a stream is being created in response to | 779 // being created in response to another being closed due to received data. |
789 // another being closed due to received data. | |
790 | |
791 Error SpdySession::TryAccessStream(const GURL& url) { | |
792 if (is_secure_ && certificate_error_code_ != OK && | |
793 (url.SchemeIs("https") || url.SchemeIs("wss"))) { | |
794 RecordProtocolErrorHistogram( | |
795 PROTOCOL_ERROR_REQUEST_FOR_SECURE_CONTENT_OVER_INSECURE_SESSION); | |
796 DoDrainSession( | |
797 static_cast<Error>(certificate_error_code_), | |
798 "Tried to get SPDY stream for secure content over an unauthenticated " | |
799 "session."); | |
800 return ERR_SPDY_PROTOCOL_ERROR; | |
801 } | |
802 return OK; | |
803 } | |
804 | 780 |
805 int SpdySession::TryCreateStream( | 781 int SpdySession::TryCreateStream( |
806 const base::WeakPtr<SpdyStreamRequest>& request, | 782 const base::WeakPtr<SpdyStreamRequest>& request, |
807 base::WeakPtr<SpdyStream>* stream) { | 783 base::WeakPtr<SpdyStream>* stream) { |
808 DCHECK(request); | 784 DCHECK(request); |
809 | 785 |
810 if (availability_state_ == STATE_GOING_AWAY) | 786 if (availability_state_ == STATE_GOING_AWAY) |
811 return ERR_FAILED; | 787 return ERR_FAILED; |
812 | 788 |
813 if (availability_state_ == STATE_DRAINING) | 789 if (availability_state_ == STATE_DRAINING) |
814 return ERR_CONNECTION_CLOSED; | 790 return ERR_CONNECTION_CLOSED; |
815 | 791 |
816 Error err = TryAccessStream(request->url()); | |
817 if (err != OK) | |
818 return err; | |
819 | |
820 if ((active_streams_.size() + created_streams_.size() - num_pushed_streams_ < | 792 if ((active_streams_.size() + created_streams_.size() - num_pushed_streams_ < |
821 max_concurrent_streams_)) { | 793 max_concurrent_streams_)) { |
822 return CreateStream(*request, stream); | 794 return CreateStream(*request, stream); |
823 } | 795 } |
824 | 796 |
825 stalled_streams_++; | 797 stalled_streams_++; |
826 net_log().AddEvent(NetLogEventType::HTTP2_SESSION_STALLED_MAX_STREAMS); | 798 net_log().AddEvent(NetLogEventType::HTTP2_SESSION_STALLED_MAX_STREAMS); |
827 RequestPriority priority = request->priority(); | 799 RequestPriority priority = request->priority(); |
828 CHECK_GE(priority, MINIMUM_PRIORITY); | 800 CHECK_GE(priority, MINIMUM_PRIORITY); |
829 CHECK_LE(priority, MAXIMUM_PRIORITY); | 801 CHECK_LE(priority, MAXIMUM_PRIORITY); |
830 pending_create_stream_queues_[priority].push_back(request); | 802 pending_create_stream_queues_[priority].push_back(request); |
831 return ERR_IO_PENDING; | 803 return ERR_IO_PENDING; |
832 } | 804 } |
833 | 805 |
834 int SpdySession::CreateStream(const SpdyStreamRequest& request, | 806 int SpdySession::CreateStream(const SpdyStreamRequest& request, |
835 base::WeakPtr<SpdyStream>* stream) { | 807 base::WeakPtr<SpdyStream>* stream) { |
836 DCHECK_GE(request.priority(), MINIMUM_PRIORITY); | 808 DCHECK_GE(request.priority(), MINIMUM_PRIORITY); |
837 DCHECK_LE(request.priority(), MAXIMUM_PRIORITY); | 809 DCHECK_LE(request.priority(), MAXIMUM_PRIORITY); |
838 | 810 |
839 if (availability_state_ == STATE_GOING_AWAY) | 811 if (availability_state_ == STATE_GOING_AWAY) |
840 return ERR_FAILED; | 812 return ERR_FAILED; |
841 | 813 |
842 if (availability_state_ == STATE_DRAINING) | 814 if (availability_state_ == STATE_DRAINING) |
843 return ERR_CONNECTION_CLOSED; | 815 return ERR_CONNECTION_CLOSED; |
844 | 816 |
845 Error err = TryAccessStream(request.url()); | |
846 if (err != OK) { | |
847 // This should have been caught in TryCreateStream(). | |
848 NOTREACHED(); | |
849 return err; | |
850 } | |
851 | |
852 DCHECK(connection_->socket()); | 817 DCHECK(connection_->socket()); |
853 UMA_HISTOGRAM_BOOLEAN("Net.SpdySession.CreateStreamWithSocketConnected", | 818 UMA_HISTOGRAM_BOOLEAN("Net.SpdySession.CreateStreamWithSocketConnected", |
854 connection_->socket()->IsConnected()); | 819 connection_->socket()->IsConnected()); |
855 if (!connection_->socket()->IsConnected()) { | 820 if (!connection_->socket()->IsConnected()) { |
856 DoDrainSession( | 821 DoDrainSession( |
857 ERR_CONNECTION_CLOSED, | 822 ERR_CONNECTION_CLOSED, |
858 "Tried to create SPDY stream for a closed socket connection."); | 823 "Tried to create SPDY stream for a closed socket connection."); |
859 return ERR_CONNECTION_CLOSED; | 824 return ERR_CONNECTION_CLOSED; |
860 } | 825 } |
861 | 826 |
(...skipping 2277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3139 if (!queue->empty()) { | 3104 if (!queue->empty()) { |
3140 SpdyStreamId stream_id = queue->front(); | 3105 SpdyStreamId stream_id = queue->front(); |
3141 queue->pop_front(); | 3106 queue->pop_front(); |
3142 return stream_id; | 3107 return stream_id; |
3143 } | 3108 } |
3144 } | 3109 } |
3145 return 0; | 3110 return 0; |
3146 } | 3111 } |
3147 | 3112 |
3148 } // namespace net | 3113 } // namespace net |
OLD | NEW |