| 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 |