| 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 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 size_t max_concurrent_streams_limit, | 542 size_t max_concurrent_streams_limit, |
| 543 TimeFunc time_func, | 543 TimeFunc time_func, |
| 544 const HostPortPair& trusted_spdy_proxy, | 544 const HostPortPair& trusted_spdy_proxy, |
| 545 NetLog* net_log) | 545 NetLog* net_log) |
| 546 : in_io_loop_(false), | 546 : in_io_loop_(false), |
| 547 spdy_session_key_(spdy_session_key), | 547 spdy_session_key_(spdy_session_key), |
| 548 pool_(NULL), | 548 pool_(NULL), |
| 549 http_server_properties_(http_server_properties), | 549 http_server_properties_(http_server_properties), |
| 550 read_buffer_(new IOBuffer(kReadBufferSize)), | 550 read_buffer_(new IOBuffer(kReadBufferSize)), |
| 551 stream_hi_water_mark_(kFirstStreamId), | 551 stream_hi_water_mark_(kFirstStreamId), |
| 552 num_pushed_streams_(0u), | |
| 553 num_active_pushed_streams_(0u), | |
| 554 in_flight_write_frame_type_(DATA), | 552 in_flight_write_frame_type_(DATA), |
| 555 in_flight_write_frame_size_(0), | 553 in_flight_write_frame_size_(0), |
| 556 is_secure_(false), | 554 is_secure_(false), |
| 557 certificate_error_code_(OK), | 555 certificate_error_code_(OK), |
| 558 availability_state_(STATE_AVAILABLE), | 556 availability_state_(STATE_AVAILABLE), |
| 559 read_state_(READ_STATE_DO_READ), | 557 read_state_(READ_STATE_DO_READ), |
| 560 write_state_(WRITE_STATE_IDLE), | 558 write_state_(WRITE_STATE_IDLE), |
| 561 error_on_close_(OK), | 559 error_on_close_(OK), |
| 562 max_concurrent_streams_(initial_max_concurrent_streams == 0 | 560 max_concurrent_streams_(initial_max_concurrent_streams == 0 |
| 563 ? kInitialMaxConcurrentStreams | 561 ? kInitialMaxConcurrentStreams |
| 564 : initial_max_concurrent_streams), | 562 : initial_max_concurrent_streams), |
| 565 max_concurrent_streams_limit_(max_concurrent_streams_limit == 0 | 563 max_concurrent_streams_limit_(max_concurrent_streams_limit == 0 |
| 566 ? kMaxConcurrentStreamLimit | 564 ? kMaxConcurrentStreamLimit |
| 567 : max_concurrent_streams_limit), | 565 : max_concurrent_streams_limit), |
| 568 max_concurrent_pushed_streams_(kMaxConcurrentPushedStreams), | |
| 569 streams_initiated_count_(0), | 566 streams_initiated_count_(0), |
| 570 streams_pushed_count_(0), | 567 streams_pushed_count_(0), |
| 571 streams_pushed_and_claimed_count_(0), | 568 streams_pushed_and_claimed_count_(0), |
| 572 streams_abandoned_count_(0), | 569 streams_abandoned_count_(0), |
| 573 total_bytes_received_(0), | 570 total_bytes_received_(0), |
| 574 sent_settings_(false), | 571 sent_settings_(false), |
| 575 received_settings_(false), | 572 received_settings_(false), |
| 576 stalled_streams_(0), | 573 stalled_streams_(0), |
| 577 pings_in_flight_(0), | 574 pings_in_flight_(0), |
| 578 next_ping_id_(1), | 575 next_ping_id_(1), |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 773 return ERR_FAILED; | 770 return ERR_FAILED; |
| 774 | 771 |
| 775 if (availability_state_ == STATE_DRAINING) | 772 if (availability_state_ == STATE_DRAINING) |
| 776 return ERR_CONNECTION_CLOSED; | 773 return ERR_CONNECTION_CLOSED; |
| 777 | 774 |
| 778 Error err = TryAccessStream(request->url()); | 775 Error err = TryAccessStream(request->url()); |
| 779 if (err != OK) | 776 if (err != OK) |
| 780 return err; | 777 return err; |
| 781 | 778 |
| 782 if (!max_concurrent_streams_ || | 779 if (!max_concurrent_streams_ || |
| 783 (active_streams_.size() + created_streams_.size() - num_pushed_streams_ < | 780 (active_streams_.size() + created_streams_.size() < |
| 784 max_concurrent_streams_)) { | 781 max_concurrent_streams_)) { |
| 785 return CreateStream(*request, stream); | 782 return CreateStream(*request, stream); |
| 786 } | 783 } |
| 787 | 784 |
| 788 stalled_streams_++; | 785 stalled_streams_++; |
| 789 net_log().AddEvent(NetLog::TYPE_SPDY_SESSION_STALLED_MAX_STREAMS); | 786 net_log().AddEvent(NetLog::TYPE_SPDY_SESSION_STALLED_MAX_STREAMS); |
| 790 RequestPriority priority = request->priority(); | 787 RequestPriority priority = request->priority(); |
| 791 CHECK_GE(priority, MINIMUM_PRIORITY); | 788 CHECK_GE(priority, MINIMUM_PRIORITY); |
| 792 CHECK_LE(priority, MAXIMUM_PRIORITY); | 789 CHECK_LE(priority, MAXIMUM_PRIORITY); |
| 793 pending_create_stream_queues_[priority].push_back(request); | 790 pending_create_stream_queues_[priority].push_back(request); |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1214 scoped_ptr<SpdyStream> owned_stream(it->second.stream); | 1211 scoped_ptr<SpdyStream> owned_stream(it->second.stream); |
| 1215 active_streams_.erase(it); | 1212 active_streams_.erase(it); |
| 1216 | 1213 |
| 1217 // TODO(akalin): When SpdyStream was ref-counted (and | 1214 // TODO(akalin): When SpdyStream was ref-counted (and |
| 1218 // |unclaimed_pushed_streams_| held scoped_refptr<SpdyStream>), this | 1215 // |unclaimed_pushed_streams_| held scoped_refptr<SpdyStream>), this |
| 1219 // was only done when status was not OK. This meant that pushed | 1216 // was only done when status was not OK. This meant that pushed |
| 1220 // streams can still be claimed after they're closed. This is | 1217 // streams can still be claimed after they're closed. This is |
| 1221 // probably something that we still want to support, although server | 1218 // probably something that we still want to support, although server |
| 1222 // push is hardly used. Write tests for this and fix this. (See | 1219 // push is hardly used. Write tests for this and fix this. (See |
| 1223 // http://crbug.com/261712 .) | 1220 // http://crbug.com/261712 .) |
| 1224 if (owned_stream->type() == SPDY_PUSH_STREAM) { | 1221 if (owned_stream->type() == SPDY_PUSH_STREAM) |
| 1225 unclaimed_pushed_streams_.erase(owned_stream->url()); | 1222 unclaimed_pushed_streams_.erase(owned_stream->url()); |
| 1226 num_pushed_streams_--; | |
| 1227 if (!owned_stream->IsReservedRemote()) | |
| 1228 num_active_pushed_streams_--; | |
| 1229 } | |
| 1230 | 1223 |
| 1231 DeleteStream(owned_stream.Pass(), status); | 1224 DeleteStream(owned_stream.Pass(), status); |
| 1232 MaybeFinishGoingAway(); | 1225 MaybeFinishGoingAway(); |
| 1233 | 1226 |
| 1234 // If there are no active streams and the socket pool is stalled, close the | 1227 // If there are no active streams and the socket pool is stalled, close the |
| 1235 // session to free up a socket slot. | 1228 // session to free up a socket slot. |
| 1236 if (active_streams_.empty() && connection_->IsPoolStalled()) { | 1229 if (active_streams_.empty() && connection_->IsPoolStalled()) { |
| 1237 DoDrainSession(ERR_CONNECTION_CLOSED, "Closing idle connection."); | 1230 DoDrainSession(ERR_CONNECTION_CLOSED, "Closing idle connection."); |
| 1238 } | 1231 } |
| 1239 } | 1232 } |
| (...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2095 last_compressed_frame_len_ = frame_len; | 2088 last_compressed_frame_len_ = frame_len; |
| 2096 } | 2089 } |
| 2097 | 2090 |
| 2098 int SpdySession::OnInitialResponseHeadersReceived( | 2091 int SpdySession::OnInitialResponseHeadersReceived( |
| 2099 const SpdyHeaderBlock& response_headers, | 2092 const SpdyHeaderBlock& response_headers, |
| 2100 base::Time response_time, | 2093 base::Time response_time, |
| 2101 base::TimeTicks recv_first_byte_time, | 2094 base::TimeTicks recv_first_byte_time, |
| 2102 SpdyStream* stream) { | 2095 SpdyStream* stream) { |
| 2103 CHECK(in_io_loop_); | 2096 CHECK(in_io_loop_); |
| 2104 SpdyStreamId stream_id = stream->stream_id(); | 2097 SpdyStreamId stream_id = stream->stream_id(); |
| 2105 | |
| 2106 if (stream->type() == SPDY_PUSH_STREAM) { | |
| 2107 DCHECK(stream->IsReservedRemote()); | |
| 2108 if (max_concurrent_pushed_streams_ && | |
| 2109 num_active_pushed_streams_ >= max_concurrent_pushed_streams_) { | |
| 2110 ResetStream(stream_id, | |
| 2111 RST_STREAM_REFUSED_STREAM, | |
| 2112 "Stream concurrency limit reached."); | |
| 2113 return STATUS_CODE_REFUSED_STREAM; | |
| 2114 } | |
| 2115 } | |
| 2116 | |
| 2117 // May invalidate |stream|. | 2098 // May invalidate |stream|. |
| 2118 int rv = stream->OnInitialResponseHeadersReceived( | 2099 int rv = stream->OnInitialResponseHeadersReceived( |
| 2119 response_headers, response_time, recv_first_byte_time); | 2100 response_headers, response_time, recv_first_byte_time); |
| 2120 if (rv < 0) { | 2101 if (rv < 0) { |
| 2121 DCHECK_NE(rv, ERR_IO_PENDING); | 2102 DCHECK_NE(rv, ERR_IO_PENDING); |
| 2122 DCHECK(active_streams_.find(stream_id) == active_streams_.end()); | 2103 DCHECK(active_streams_.find(stream_id) == active_streams_.end()); |
| 2123 } | 2104 } |
| 2124 | |
| 2125 if (stream->type() == SPDY_PUSH_STREAM) { | |
| 2126 DCHECK(stream->IsLocallyClosed()); | |
| 2127 num_active_pushed_streams_++; | |
| 2128 } | |
| 2129 | |
| 2130 return rv; | 2105 return rv; |
| 2131 } | 2106 } |
| 2132 | 2107 |
| 2133 void SpdySession::OnSynStream(SpdyStreamId stream_id, | 2108 void SpdySession::OnSynStream(SpdyStreamId stream_id, |
| 2134 SpdyStreamId associated_stream_id, | 2109 SpdyStreamId associated_stream_id, |
| 2135 SpdyPriority priority, | 2110 SpdyPriority priority, |
| 2136 bool fin, | 2111 bool fin, |
| 2137 bool unidirectional, | 2112 bool unidirectional, |
| 2138 const SpdyHeaderBlock& headers) { | 2113 const SpdyHeaderBlock& headers) { |
| 2139 CHECK(in_io_loop_); | 2114 CHECK(in_io_loop_); |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2602 InsertActivatedStream(stream.Pass()); | 2577 InsertActivatedStream(stream.Pass()); |
| 2603 | 2578 |
| 2604 ActiveStreamMap::iterator active_it = active_streams_.find(stream_id); | 2579 ActiveStreamMap::iterator active_it = active_streams_.find(stream_id); |
| 2605 if (active_it == active_streams_.end()) { | 2580 if (active_it == active_streams_.end()) { |
| 2606 NOTREACHED(); | 2581 NOTREACHED(); |
| 2607 return false; | 2582 return false; |
| 2608 } | 2583 } |
| 2609 | 2584 |
| 2610 active_it->second.stream->OnPushPromiseHeadersReceived(headers); | 2585 active_it->second.stream->OnPushPromiseHeadersReceived(headers); |
| 2611 DCHECK(active_it->second.stream->IsReservedRemote()); | 2586 DCHECK(active_it->second.stream->IsReservedRemote()); |
| 2612 num_pushed_streams_++; | |
| 2613 return true; | 2587 return true; |
| 2614 } | 2588 } |
| 2615 | 2589 |
| 2616 void SpdySession::OnPushPromise(SpdyStreamId stream_id, | 2590 void SpdySession::OnPushPromise(SpdyStreamId stream_id, |
| 2617 SpdyStreamId promised_stream_id, | 2591 SpdyStreamId promised_stream_id, |
| 2618 const SpdyHeaderBlock& headers) { | 2592 const SpdyHeaderBlock& headers) { |
| 2619 CHECK(in_io_loop_); | 2593 CHECK(in_io_loop_); |
| 2620 | 2594 |
| 2621 if (net_log_.IsLogging()) { | 2595 if (net_log_.IsLogging()) { |
| 2622 net_log_.AddEvent(NetLog::TYPE_SPDY_SESSION_RECV_PUSH_PROMISE, | 2596 net_log_.AddEvent(NetLog::TYPE_SPDY_SESSION_RECV_PUSH_PROMISE, |
| (...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3159 if (!queue->empty()) { | 3133 if (!queue->empty()) { |
| 3160 SpdyStreamId stream_id = queue->front(); | 3134 SpdyStreamId stream_id = queue->front(); |
| 3161 queue->pop_front(); | 3135 queue->pop_front(); |
| 3162 return stream_id; | 3136 return stream_id; |
| 3163 } | 3137 } |
| 3164 } | 3138 } |
| 3165 return 0; | 3139 return 0; |
| 3166 } | 3140 } |
| 3167 | 3141 |
| 3168 } // namespace net | 3142 } // namespace net |
| OLD | NEW |