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 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 } | 288 } |
289 | 289 |
290 private: | 290 private: |
291 const base::WeakPtr<SpdyStreamRequest> request_; | 291 const base::WeakPtr<SpdyStreamRequest> request_; |
292 }; | 292 }; |
293 | 293 |
294 // The maximum number of concurrent streams we will ever create. Even if | 294 // The maximum number of concurrent streams we will ever create. Even if |
295 // the server permits more, we will never exceed this limit. | 295 // the server permits more, we will never exceed this limit. |
296 const size_t kMaxConcurrentStreamLimit = 256; | 296 const size_t kMaxConcurrentStreamLimit = 256; |
297 | 297 |
| 298 class SpdyServerPushHelper : public ServerPushDelegate::ServerPushHelper { |
| 299 public: |
| 300 explicit SpdyServerPushHelper(base::WeakPtr<SpdySession> session, |
| 301 const GURL& url) |
| 302 : session_(session), request_url_(url) {} |
| 303 |
| 304 void Cancel() override { |
| 305 if (session_) |
| 306 session_->CancelPush(request_url_); |
| 307 } |
| 308 |
| 309 const GURL& GetURL() override { return request_url_; } |
| 310 |
| 311 private: |
| 312 base::WeakPtr<SpdySession> session_; |
| 313 const GURL request_url_; |
| 314 }; |
| 315 |
298 } // namespace | 316 } // namespace |
299 | 317 |
300 SpdyProtocolErrorDetails MapFramerErrorToProtocolError( | 318 SpdyProtocolErrorDetails MapFramerErrorToProtocolError( |
301 SpdyFramer::SpdyError err) { | 319 SpdyFramer::SpdyError err) { |
302 switch (err) { | 320 switch (err) { |
303 case SpdyFramer::SPDY_NO_ERROR: | 321 case SpdyFramer::SPDY_NO_ERROR: |
304 return SPDY_ERROR_NO_ERROR; | 322 return SPDY_ERROR_NO_ERROR; |
305 case SpdyFramer::SPDY_INVALID_STREAM_ID: | 323 case SpdyFramer::SPDY_INVALID_STREAM_ID: |
306 return SPDY_ERROR_INVALID_STREAM_ID; | 324 return SPDY_ERROR_INVALID_STREAM_ID; |
307 case SpdyFramer::SPDY_INVALID_CONTROL_FRAME: | 325 case SpdyFramer::SPDY_INVALID_CONTROL_FRAME: |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 NetLog* net_log) | 655 NetLog* net_log) |
638 : in_io_loop_(false), | 656 : in_io_loop_(false), |
639 spdy_session_key_(spdy_session_key), | 657 spdy_session_key_(spdy_session_key), |
640 pool_(NULL), | 658 pool_(NULL), |
641 http_server_properties_(http_server_properties), | 659 http_server_properties_(http_server_properties), |
642 transport_security_state_(transport_security_state), | 660 transport_security_state_(transport_security_state), |
643 read_buffer_(new IOBuffer(kReadBufferSize)), | 661 read_buffer_(new IOBuffer(kReadBufferSize)), |
644 stream_hi_water_mark_(kFirstStreamId), | 662 stream_hi_water_mark_(kFirstStreamId), |
645 last_accepted_push_stream_id_(0), | 663 last_accepted_push_stream_id_(0), |
646 unclaimed_pushed_streams_(this), | 664 unclaimed_pushed_streams_(this), |
| 665 push_delegate_(nullptr), |
647 num_pushed_streams_(0u), | 666 num_pushed_streams_(0u), |
648 num_active_pushed_streams_(0u), | 667 num_active_pushed_streams_(0u), |
649 bytes_pushed_count_(0u), | 668 bytes_pushed_count_(0u), |
650 bytes_pushed_and_unclaimed_count_(0u), | 669 bytes_pushed_and_unclaimed_count_(0u), |
651 in_flight_write_frame_type_(DATA), | 670 in_flight_write_frame_type_(DATA), |
652 in_flight_write_frame_size_(0), | 671 in_flight_write_frame_size_(0), |
653 is_secure_(false), | 672 is_secure_(false), |
654 availability_state_(STATE_AVAILABLE), | 673 availability_state_(STATE_AVAILABLE), |
655 read_state_(READ_STATE_DO_READ), | 674 read_state_(READ_STATE_DO_READ), |
656 write_state_(WRITE_STATE_IDLE), | 675 write_state_(WRITE_STATE_IDLE), |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
775 return ERR_CONNECTION_CLOSED; | 794 return ERR_CONNECTION_CLOSED; |
776 | 795 |
777 *stream = GetActivePushStream(url); | 796 *stream = GetActivePushStream(url); |
778 if (*stream) { | 797 if (*stream) { |
779 DCHECK_LT(streams_pushed_and_claimed_count_, streams_pushed_count_); | 798 DCHECK_LT(streams_pushed_and_claimed_count_, streams_pushed_count_); |
780 streams_pushed_and_claimed_count_++; | 799 streams_pushed_and_claimed_count_++; |
781 } | 800 } |
782 return OK; | 801 return OK; |
783 } | 802 } |
784 | 803 |
| 804 void SpdySession::CancelPush(const GURL& url) { |
| 805 UnclaimedPushedStreamContainer::const_iterator unclaimed_it = |
| 806 unclaimed_pushed_streams_.find(url); |
| 807 if (unclaimed_it == unclaimed_pushed_streams_.end()) |
| 808 return; |
| 809 |
| 810 SpdyStreamId stream_id = unclaimed_it->second.stream_id; |
| 811 |
| 812 if (active_streams_.find(stream_id) == active_streams_.end()) { |
| 813 ResetStream(stream_id, RST_STREAM_CANCEL, |
| 814 "Cancelled push stream with url: " + url.spec()); |
| 815 } |
| 816 unclaimed_pushed_streams_.erase(unclaimed_it); |
| 817 } |
| 818 |
785 // {,Try}CreateStream() can be called with |in_io_loop_| set if a stream is | 819 // {,Try}CreateStream() can be called with |in_io_loop_| set if a stream is |
786 // being created in response to another being closed due to received data. | 820 // being created in response to another being closed due to received data. |
787 | 821 |
788 int SpdySession::TryCreateStream( | 822 int SpdySession::TryCreateStream( |
789 const base::WeakPtr<SpdyStreamRequest>& request, | 823 const base::WeakPtr<SpdyStreamRequest>& request, |
790 base::WeakPtr<SpdyStream>* stream) { | 824 base::WeakPtr<SpdyStream>* stream) { |
791 DCHECK(request); | 825 DCHECK(request); |
792 | 826 |
793 if (availability_state_ == STATE_GOING_AWAY) | 827 if (availability_state_ == STATE_GOING_AWAY) |
794 return ERR_FAILED; | 828 return ERR_FAILED; |
(...skipping 1831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2626 DeleteExpiredPushedStreams(); | 2660 DeleteExpiredPushedStreams(); |
2627 | 2661 |
2628 InsertActivatedStream(std::move(stream)); | 2662 InsertActivatedStream(std::move(stream)); |
2629 | 2663 |
2630 ActiveStreamMap::iterator active_it = active_streams_.find(stream_id); | 2664 ActiveStreamMap::iterator active_it = active_streams_.find(stream_id); |
2631 if (active_it == active_streams_.end()) { | 2665 if (active_it == active_streams_.end()) { |
2632 NOTREACHED(); | 2666 NOTREACHED(); |
2633 return false; | 2667 return false; |
2634 } | 2668 } |
2635 | 2669 |
| 2670 // Notify the push_delegate that a push promise has been received. |
| 2671 if (push_delegate_) { |
| 2672 push_delegate_->OnPush(base::MakeUnique<SpdyServerPushHelper>( |
| 2673 weak_factory_.GetWeakPtr(), gurl)); |
| 2674 } |
| 2675 |
2636 active_it->second.stream->OnPushPromiseHeadersReceived(std::move(headers)); | 2676 active_it->second.stream->OnPushPromiseHeadersReceived(std::move(headers)); |
2637 DCHECK(active_it->second.stream->IsReservedRemote()); | 2677 DCHECK(active_it->second.stream->IsReservedRemote()); |
2638 num_pushed_streams_++; | 2678 num_pushed_streams_++; |
2639 return true; | 2679 return true; |
2640 } | 2680 } |
2641 | 2681 |
2642 void SpdySession::CancelPush(const GURL& url) { | |
2643 UnclaimedPushedStreamContainer::const_iterator unclaimed_it = | |
2644 unclaimed_pushed_streams_.find(url); | |
2645 if (unclaimed_it == unclaimed_pushed_streams_.end()) | |
2646 return; | |
2647 | |
2648 SpdyStreamId stream_id = unclaimed_it->second.stream_id; | |
2649 | |
2650 if (active_streams_.find(stream_id) == active_streams_.end()) { | |
2651 ResetStream(stream_id, RST_STREAM_CANCEL, | |
2652 "Cancelled push stream with url: " + url.spec()); | |
2653 } | |
2654 unclaimed_pushed_streams_.erase(unclaimed_it); | |
2655 } | |
2656 | |
2657 void SpdySession::OnPushPromise(SpdyStreamId stream_id, | 2682 void SpdySession::OnPushPromise(SpdyStreamId stream_id, |
2658 SpdyStreamId promised_stream_id, | 2683 SpdyStreamId promised_stream_id, |
2659 SpdyHeaderBlock headers) { | 2684 SpdyHeaderBlock headers) { |
2660 CHECK(in_io_loop_); | 2685 CHECK(in_io_loop_); |
2661 | 2686 |
2662 if (net_log_.IsCapturing()) { | 2687 if (net_log_.IsCapturing()) { |
2663 net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_PUSH_PROMISE, | 2688 net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_PUSH_PROMISE, |
2664 base::Bind(&NetLogSpdyPushPromiseReceivedCallback, | 2689 base::Bind(&NetLogSpdyPushPromiseReceivedCallback, |
2665 &headers, stream_id, promised_stream_id)); | 2690 &headers, stream_id, promised_stream_id)); |
2666 } | 2691 } |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3133 if (!queue->empty()) { | 3158 if (!queue->empty()) { |
3134 SpdyStreamId stream_id = queue->front(); | 3159 SpdyStreamId stream_id = queue->front(); |
3135 queue->pop_front(); | 3160 queue->pop_front(); |
3136 return stream_id; | 3161 return stream_id; |
3137 } | 3162 } |
3138 } | 3163 } |
3139 return 0; | 3164 return 0; |
3140 } | 3165 } |
3141 | 3166 |
3142 } // namespace net | 3167 } // namespace net |
OLD | NEW |