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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 SpdyStreamRequest::SpdyStreamRequest() { | 233 SpdyStreamRequest::SpdyStreamRequest() { |
234 Reset(); | 234 Reset(); |
235 } | 235 } |
236 | 236 |
237 SpdyStreamRequest::~SpdyStreamRequest() { | 237 SpdyStreamRequest::~SpdyStreamRequest() { |
238 CancelRequest(); | 238 CancelRequest(); |
239 } | 239 } |
240 | 240 |
241 int SpdyStreamRequest::StartRequest( | 241 int SpdyStreamRequest::StartRequest( |
242 SpdyStreamType type, | 242 SpdyStreamType type, |
243 const scoped_refptr<SpdySession>& session, | 243 const base::WeakPtr<SpdySession>& session, |
244 const GURL& url, | 244 const GURL& url, |
245 RequestPriority priority, | 245 RequestPriority priority, |
246 const BoundNetLog& net_log, | 246 const BoundNetLog& net_log, |
247 const CompletionCallback& callback) { | 247 const CompletionCallback& callback) { |
248 DCHECK(session.get()); | 248 DCHECK(session.get()); |
249 DCHECK(!session_.get()); | 249 DCHECK(!session_.get()); |
250 DCHECK(!stream_.get()); | 250 DCHECK(!stream_.get()); |
251 DCHECK(callback_.is_null()); | 251 DCHECK(callback_.is_null()); |
252 | 252 |
253 type_ = type; | 253 type_ = type; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 DCHECK(!stream_.get()); | 297 DCHECK(!stream_.get()); |
298 DCHECK(!callback_.is_null()); | 298 DCHECK(!callback_.is_null()); |
299 CompletionCallback callback = callback_; | 299 CompletionCallback callback = callback_; |
300 Reset(); | 300 Reset(); |
301 DCHECK_NE(rv, OK); | 301 DCHECK_NE(rv, OK); |
302 callback.Run(rv); | 302 callback.Run(rv); |
303 } | 303 } |
304 | 304 |
305 void SpdyStreamRequest::Reset() { | 305 void SpdyStreamRequest::Reset() { |
306 type_ = SPDY_BIDIRECTIONAL_STREAM; | 306 type_ = SPDY_BIDIRECTIONAL_STREAM; |
307 session_ = NULL; | 307 session_.reset(); |
308 stream_.reset(); | 308 stream_.reset(); |
309 url_ = GURL(); | 309 url_ = GURL(); |
310 priority_ = MINIMUM_PRIORITY; | 310 priority_ = MINIMUM_PRIORITY; |
311 net_log_ = BoundNetLog(); | 311 net_log_ = BoundNetLog(); |
312 callback_.Reset(); | 312 callback_.Reset(); |
313 } | 313 } |
314 | 314 |
315 SpdySession::ActiveStreamInfo::ActiveStreamInfo() | 315 SpdySession::ActiveStreamInfo::ActiveStreamInfo() |
316 : stream(NULL), | 316 : stream(NULL), |
317 waiting_for_syn_reply(false) {} | 317 waiting_for_syn_reply(false) {} |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
625 if (!connection_->socket()->IsConnected()) { | 625 if (!connection_->socket()->IsConnected()) { |
626 CloseSessionResult result = DoCloseSession( | 626 CloseSessionResult result = DoCloseSession( |
627 ERR_CONNECTION_CLOSED, | 627 ERR_CONNECTION_CLOSED, |
628 "Tried to create SPDY stream for a closed socket connection."); | 628 "Tried to create SPDY stream for a closed socket connection."); |
629 DCHECK_EQ(result, SESSION_CLOSED_AND_REMOVED); | 629 DCHECK_EQ(result, SESSION_CLOSED_AND_REMOVED); |
630 return ERR_CONNECTION_CLOSED; | 630 return ERR_CONNECTION_CLOSED; |
631 } | 631 } |
632 } | 632 } |
633 | 633 |
634 scoped_ptr<SpdyStream> new_stream( | 634 scoped_ptr<SpdyStream> new_stream( |
635 new SpdyStream(request.type(), this, request.url(), request.priority(), | 635 new SpdyStream(request.type(), GetWeakPtr(), request.url(), |
| 636 request.priority(), |
636 stream_initial_send_window_size_, | 637 stream_initial_send_window_size_, |
637 stream_initial_recv_window_size_, | 638 stream_initial_recv_window_size_, |
638 request.net_log())); | 639 request.net_log())); |
639 *stream = new_stream->GetWeakPtr(); | 640 *stream = new_stream->GetWeakPtr(); |
640 InsertCreatedStream(new_stream.Pass()); | 641 InsertCreatedStream(new_stream.Pass()); |
641 | 642 |
642 UMA_HISTOGRAM_CUSTOM_COUNTS( | 643 UMA_HISTOGRAM_CUSTOM_COUNTS( |
643 "Net.SpdyPriorityCount", | 644 "Net.SpdyPriorityCount", |
644 static_cast<int>(request.priority()), 0, 10, 11); | 645 static_cast<int>(request.priority()), 0, 10, 11); |
645 | 646 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
716 | 717 |
717 void SpdySession::AddPooledAlias(const SpdySessionKey& alias_key) { | 718 void SpdySession::AddPooledAlias(const SpdySessionKey& alias_key) { |
718 pooled_aliases_.insert(alias_key); | 719 pooled_aliases_.insert(alias_key); |
719 } | 720 } |
720 | 721 |
721 int SpdySession::GetProtocolVersion() const { | 722 int SpdySession::GetProtocolVersion() const { |
722 DCHECK(buffered_spdy_framer_.get()); | 723 DCHECK(buffered_spdy_framer_.get()); |
723 return buffered_spdy_framer_->protocol_version(); | 724 return buffered_spdy_framer_->protocol_version(); |
724 } | 725 } |
725 | 726 |
| 727 base::WeakPtr<SpdySession> SpdySession::GetWeakPtr() { |
| 728 return weak_factory_.GetWeakPtr(); |
| 729 } |
| 730 |
726 bool SpdySession::CloseOneIdleConnection() { | 731 bool SpdySession::CloseOneIdleConnection() { |
727 CHECK(!in_io_loop_); | 732 CHECK(!in_io_loop_); |
728 DCHECK(pool_); | 733 DCHECK(pool_); |
729 DCHECK_NE(availability_state_, STATE_CLOSED); | 734 DCHECK_NE(availability_state_, STATE_CLOSED); |
730 if (!active_streams_.empty()) | 735 if (!active_streams_.empty()) |
731 return false; | 736 return false; |
732 base::WeakPtr<SpdySession> weak_ptr = weak_factory_.GetWeakPtr(); | 737 base::WeakPtr<SpdySession> weak_ptr = weak_factory_.GetWeakPtr(); |
733 CloseSessionResult result = | 738 CloseSessionResult result = |
734 DoCloseSession(ERR_CONNECTION_CLOSED, "Closing one idle connection."); | 739 DoCloseSession(ERR_CONNECTION_CLOSED, "Closing one idle connection."); |
735 DCHECK_EQ(result, SESSION_CLOSED_AND_REMOVED); | 740 DCHECK_EQ(result, SESSION_CLOSED_AND_REMOVED); |
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1318 return connection_->socket()->Write( | 1323 return connection_->socket()->Write( |
1319 write_io_buffer.get(), | 1324 write_io_buffer.get(), |
1320 in_flight_write_->GetRemainingSize(), | 1325 in_flight_write_->GetRemainingSize(), |
1321 base::Bind(&SpdySession::PumpWriteLoop, | 1326 base::Bind(&SpdySession::PumpWriteLoop, |
1322 weak_factory_.GetWeakPtr(), WRITE_STATE_DO_WRITE_COMPLETE)); | 1327 weak_factory_.GetWeakPtr(), WRITE_STATE_DO_WRITE_COMPLETE)); |
1323 } | 1328 } |
1324 | 1329 |
1325 int SpdySession::DoWriteComplete(int result) { | 1330 int SpdySession::DoWriteComplete(int result) { |
1326 CHECK(in_io_loop_); | 1331 CHECK(in_io_loop_); |
1327 DCHECK_NE(availability_state_, STATE_CLOSED); | 1332 DCHECK_NE(availability_state_, STATE_CLOSED); |
1328 | 1333 DCHECK_NE(result, ERR_IO_PENDING); |
1329 DCHECK_GT(in_flight_write_->GetRemainingSize(), 0u); | 1334 DCHECK_GT(in_flight_write_->GetRemainingSize(), 0u); |
1330 | 1335 |
1331 last_activity_time_ = time_func_(); | 1336 last_activity_time_ = time_func_(); |
1332 | 1337 |
1333 if (result < 0) { | 1338 if (result < 0) { |
1334 DCHECK_NE(result, ERR_IO_PENDING); | 1339 DCHECK_NE(result, ERR_IO_PENDING); |
1335 in_flight_write_.reset(); | 1340 in_flight_write_.reset(); |
1336 in_flight_write_frame_type_ = DATA; | 1341 in_flight_write_frame_type_ = DATA; |
1337 in_flight_write_frame_size_ = 0; | 1342 in_flight_write_frame_size_ = 0; |
1338 in_flight_write_stream_.reset(); | 1343 in_flight_write_stream_.reset(); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1459 NetLog::TYPE_SPDY_SESSION_CLOSE, | 1464 NetLog::TYPE_SPDY_SESSION_CLOSE, |
1460 base::Bind(&NetLogSpdySessionCloseCallback, err, &description)); | 1465 base::Bind(&NetLogSpdySessionCloseCallback, err, &description)); |
1461 | 1466 |
1462 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SpdySession.ClosedOnError", -err); | 1467 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SpdySession.ClosedOnError", -err); |
1463 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySession.BytesRead.OtherErrors", | 1468 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySession.BytesRead.OtherErrors", |
1464 total_bytes_received_, 1, 100000000, 50); | 1469 total_bytes_received_, 1, 100000000, 50); |
1465 | 1470 |
1466 // |pool_| will be NULL when |InitializeWithSocket()| is in the | 1471 // |pool_| will be NULL when |InitializeWithSocket()| is in the |
1467 // call stack. | 1472 // call stack. |
1468 if (pool_ && availability_state_ != STATE_GOING_AWAY) | 1473 if (pool_ && availability_state_ != STATE_GOING_AWAY) |
1469 pool_->MakeSessionUnavailable(make_scoped_refptr(this)); | 1474 pool_->MakeSessionUnavailable(GetWeakPtr()); |
1470 | 1475 |
1471 availability_state_ = STATE_CLOSED; | 1476 availability_state_ = STATE_CLOSED; |
1472 error_on_close_ = err; | 1477 error_on_close_ = err; |
1473 | 1478 |
1474 StartGoingAway(0, err); | 1479 StartGoingAway(0, err); |
1475 write_queue_.Clear(); | 1480 write_queue_.Clear(); |
1476 | 1481 |
1477 DcheckClosed(); | 1482 DcheckClosed(); |
1478 | 1483 |
1479 if (in_io_loop_) | 1484 if (in_io_loop_) |
1480 return SESSION_CLOSED_BUT_NOT_REMOVED; | 1485 return SESSION_CLOSED_BUT_NOT_REMOVED; |
1481 | 1486 |
1482 RemoveFromPool(); | 1487 RemoveFromPool(); |
1483 return SESSION_CLOSED_AND_REMOVED; | 1488 return SESSION_CLOSED_AND_REMOVED; |
1484 } | 1489 } |
1485 | 1490 |
1486 void SpdySession::RemoveFromPool() { | 1491 void SpdySession::RemoveFromPool() { |
1487 DcheckClosed(); | 1492 DcheckClosed(); |
1488 CHECK(pool_); | 1493 CHECK(pool_); |
1489 | 1494 |
1490 SpdySessionPool* pool = pool_; | 1495 SpdySessionPool* pool = pool_; |
1491 pool_ = NULL; | 1496 pool_ = NULL; |
1492 pool->RemoveUnavailableSession(make_scoped_refptr(this)); | 1497 pool->RemoveUnavailableSession(GetWeakPtr()); |
1493 } | 1498 } |
1494 | 1499 |
1495 void SpdySession::LogAbandonedStream(SpdyStream* stream, Error status) { | 1500 void SpdySession::LogAbandonedStream(SpdyStream* stream, Error status) { |
1496 DCHECK(stream); | 1501 DCHECK(stream); |
1497 std::string description = base::StringPrintf( | 1502 std::string description = base::StringPrintf( |
1498 "ABANDONED (stream_id=%d): ", stream->stream_id()) + | 1503 "ABANDONED (stream_id=%d): ", stream->stream_id()) + |
1499 stream->url().spec(); | 1504 stream->url().spec(); |
1500 stream->LogStreamError(status, description); | 1505 stream->LogStreamError(status, description); |
1501 // We don't increment the streams abandoned counter here. If the | 1506 // We don't increment the streams abandoned counter here. If the |
1502 // stream isn't active (i.e., it hasn't written anything to the wire | 1507 // stream isn't active (i.e., it hasn't written anything to the wire |
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2021 unclaimed_pushed_streams_.lower_bound(gurl); | 2026 unclaimed_pushed_streams_.lower_bound(gurl); |
2022 if (pushed_it != unclaimed_pushed_streams_.end() && | 2027 if (pushed_it != unclaimed_pushed_streams_.end() && |
2023 pushed_it->first == gurl) { | 2028 pushed_it->first == gurl) { |
2024 SendResetStreamFrame(stream_id, request_priority, RST_STREAM_PROTOCOL_ERROR, | 2029 SendResetStreamFrame(stream_id, request_priority, RST_STREAM_PROTOCOL_ERROR, |
2025 "Received duplicate pushed stream with url: " + | 2030 "Received duplicate pushed stream with url: " + |
2026 gurl.spec()); | 2031 gurl.spec()); |
2027 return; | 2032 return; |
2028 } | 2033 } |
2029 | 2034 |
2030 scoped_ptr<SpdyStream> stream( | 2035 scoped_ptr<SpdyStream> stream( |
2031 new SpdyStream(SPDY_PUSH_STREAM, this, gurl, | 2036 new SpdyStream(SPDY_PUSH_STREAM, GetWeakPtr(), gurl, |
2032 request_priority, | 2037 request_priority, |
2033 stream_initial_send_window_size_, | 2038 stream_initial_send_window_size_, |
2034 stream_initial_recv_window_size_, | 2039 stream_initial_recv_window_size_, |
2035 net_log_)); | 2040 net_log_)); |
2036 stream->set_stream_id(stream_id); | 2041 stream->set_stream_id(stream_id); |
2037 | 2042 |
2038 DeleteExpiredPushedStreams(); | 2043 DeleteExpiredPushedStreams(); |
2039 PushedStreamMap::iterator inserted_pushed_it = | 2044 PushedStreamMap::iterator inserted_pushed_it = |
2040 unclaimed_pushed_streams_.insert( | 2045 unclaimed_pushed_streams_.insert( |
2041 pushed_it, | 2046 pushed_it, |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2218 base::Bind(&NetLogSpdyGoAwayCallback, | 2223 base::Bind(&NetLogSpdyGoAwayCallback, |
2219 last_accepted_stream_id, | 2224 last_accepted_stream_id, |
2220 active_streams_.size(), | 2225 active_streams_.size(), |
2221 unclaimed_pushed_streams_.size(), | 2226 unclaimed_pushed_streams_.size(), |
2222 status)); | 2227 status)); |
2223 if (availability_state_ < STATE_GOING_AWAY) { | 2228 if (availability_state_ < STATE_GOING_AWAY) { |
2224 availability_state_ = STATE_GOING_AWAY; | 2229 availability_state_ = STATE_GOING_AWAY; |
2225 // |pool_| will be NULL when |InitializeWithSocket()| is in the | 2230 // |pool_| will be NULL when |InitializeWithSocket()| is in the |
2226 // call stack. | 2231 // call stack. |
2227 if (pool_) | 2232 if (pool_) |
2228 pool_->MakeSessionUnavailable(make_scoped_refptr(this)); | 2233 pool_->MakeSessionUnavailable(GetWeakPtr()); |
2229 } | 2234 } |
2230 StartGoingAway(last_accepted_stream_id, ERR_ABORTED); | 2235 StartGoingAway(last_accepted_stream_id, ERR_ABORTED); |
2231 // This is to handle the case when we already don't have any active | 2236 // This is to handle the case when we already don't have any active |
2232 // streams (i.e., StartGoingAway() did nothing). Otherwise, we have | 2237 // streams (i.e., StartGoingAway() did nothing). Otherwise, we have |
2233 // active streams and so the last one being closed will finish the | 2238 // active streams and so the last one being closed will finish the |
2234 // going away process (see DeleteStream()). | 2239 // going away process (see DeleteStream()). |
2235 MaybeFinishGoingAway(); | 2240 MaybeFinishGoingAway(); |
2236 } | 2241 } |
2237 | 2242 |
2238 void SpdySession::OnPing(uint32 unique_id) { | 2243 void SpdySession::OnPing(uint32 unique_id) { |
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2893 if (!queue->empty()) { | 2898 if (!queue->empty()) { |
2894 SpdyStreamId stream_id = queue->front(); | 2899 SpdyStreamId stream_id = queue->front(); |
2895 queue->pop_front(); | 2900 queue->pop_front(); |
2896 return stream_id; | 2901 return stream_id; |
2897 } | 2902 } |
2898 } | 2903 } |
2899 return 0; | 2904 return 0; |
2900 } | 2905 } |
2901 | 2906 |
2902 } // namespace net | 2907 } // namespace net |
OLD | NEW |