| Index: net/spdy/spdy_session.cc
|
| diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
|
| index 347c6fd4fbd1734976c521a0baf99a7e0b446989..17934a3bfd045303f8e1744310694fe3efa154af 100644
|
| --- a/net/spdy/spdy_session.cc
|
| +++ b/net/spdy/spdy_session.cc
|
| @@ -527,8 +527,7 @@ SpdySession::SpdySession(
|
|
|
| SpdySession::~SpdySession() {
|
| CHECK(!in_io_loop_);
|
| - DCHECK(!pool_);
|
| - DcheckClosed();
|
| + DcheckDraining();
|
|
|
| // TODO(akalin): Check connection->is_initialized() instead. This
|
| // requires re-working CreateFakeSpdySession(), though.
|
| @@ -602,7 +601,7 @@ void SpdySession::InitializeWithSocket(
|
| NetLog::TYPE_SPDY_SESSION_INITIALIZED,
|
| connection_->socket()->NetLog().source().ToEventParametersCallback());
|
|
|
| - DCHECK_NE(availability_state_, STATE_CLOSED);
|
| + DCHECK_EQ(availability_state_, STATE_AVAILABLE);
|
| connection_->AddHigherLayeredPool(this);
|
| if (enable_sending_initial_data_)
|
| SendInitialData();
|
| @@ -619,7 +618,7 @@ bool SpdySession::VerifyDomainAuthentication(const std::string& domain) {
|
| if (!verify_domain_authentication_)
|
| return true;
|
|
|
| - if (availability_state_ == STATE_CLOSED)
|
| + if (availability_state_ == STATE_DRAINING)
|
| return false;
|
|
|
| SSLInfo ssl_info;
|
| @@ -645,8 +644,7 @@ int SpdySession::GetPushStream(
|
|
|
| stream->reset();
|
|
|
| - // TODO(akalin): Add unit test exercising this code path.
|
| - if (availability_state_ == STATE_CLOSED)
|
| + if (availability_state_ == STATE_DRAINING)
|
| return ERR_CONNECTION_CLOSED;
|
|
|
| Error err = TryAccessStream(url);
|
| @@ -666,17 +664,14 @@ int SpdySession::GetPushStream(
|
| // another being closed due to received data.
|
|
|
| Error SpdySession::TryAccessStream(const GURL& url) {
|
| - DCHECK_NE(availability_state_, STATE_CLOSED);
|
| -
|
| if (is_secure_ && certificate_error_code_ != OK &&
|
| (url.SchemeIs("https") || url.SchemeIs("wss"))) {
|
| RecordProtocolErrorHistogram(
|
| PROTOCOL_ERROR_REQUEST_FOR_SECURE_CONTENT_OVER_INSECURE_SESSION);
|
| - CloseSessionResult result = DoCloseSession(
|
| + DoDrainSession(
|
| static_cast<Error>(certificate_error_code_),
|
| "Tried to get SPDY stream for secure content over an unauthenticated "
|
| "session.");
|
| - DCHECK_EQ(result, SESSION_CLOSED_AND_REMOVED);
|
| return ERR_SPDY_PROTOCOL_ERROR;
|
| }
|
| return OK;
|
| @@ -690,8 +685,7 @@ int SpdySession::TryCreateStream(
|
| if (availability_state_ == STATE_GOING_AWAY)
|
| return ERR_FAILED;
|
|
|
| - // TODO(akalin): Add unit test exercising this code path.
|
| - if (availability_state_ == STATE_CLOSED)
|
| + if (availability_state_ == STATE_DRAINING)
|
| return ERR_CONNECTION_CLOSED;
|
|
|
| Error err = TryAccessStream(request->url());
|
| @@ -721,8 +715,7 @@ int SpdySession::CreateStream(const SpdyStreamRequest& request,
|
| if (availability_state_ == STATE_GOING_AWAY)
|
| return ERR_FAILED;
|
|
|
| - // TODO(akalin): Add unit test exercising this code path.
|
| - if (availability_state_ == STATE_CLOSED)
|
| + if (availability_state_ == STATE_DRAINING)
|
| return ERR_CONNECTION_CLOSED;
|
|
|
| Error err = TryAccessStream(request.url());
|
| @@ -738,10 +731,9 @@ int SpdySession::CreateStream(const SpdyStreamRequest& request,
|
| UMA_HISTOGRAM_BOOLEAN("Net.SpdySession.CreateStreamWithSocketConnected",
|
| connection_->socket()->IsConnected());
|
| if (!connection_->socket()->IsConnected()) {
|
| - CloseSessionResult result = DoCloseSession(
|
| + DoDrainSession(
|
| ERR_CONNECTION_CLOSED,
|
| "Tried to create SPDY stream for a closed socket connection.");
|
| - DCHECK_EQ(result, SESSION_CLOSED_AND_REMOVED);
|
| return ERR_CONNECTION_CLOSED;
|
| }
|
| }
|
| @@ -882,17 +874,12 @@ base::WeakPtr<SpdySession> SpdySession::GetWeakPtr() {
|
|
|
| bool SpdySession::CloseOneIdleConnection() {
|
| CHECK(!in_io_loop_);
|
| - DCHECK_NE(availability_state_, STATE_CLOSED);
|
| DCHECK(pool_);
|
| - if (!active_streams_.empty())
|
| - return false;
|
| - CloseSessionResult result =
|
| - DoCloseSession(ERR_CONNECTION_CLOSED, "Closing one idle connection.");
|
| - if (result != SESSION_CLOSED_AND_REMOVED) {
|
| - NOTREACHED();
|
| - return false;
|
| + if (active_streams_.empty()) {
|
| + DoDrainSession(ERR_CONNECTION_CLOSED, "Closing idle connection.");
|
| }
|
| - return true;
|
| + // Return false as the socket wasn't immediately closed.
|
| + return false;
|
| }
|
|
|
| void SpdySession::EnqueueStreamWrite(
|
| @@ -945,8 +932,7 @@ scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id,
|
| IOBuffer* data,
|
| int len,
|
| SpdyDataFlags flags) {
|
| - if (availability_state_ == STATE_CLOSED) {
|
| - NOTREACHED();
|
| + if (availability_state_ == STATE_DRAINING) {
|
| return scoped_ptr<SpdyBuffer>();
|
| }
|
|
|
| @@ -1135,22 +1121,13 @@ void SpdySession::CloseActiveStreamIterator(ActiveStreamMap::iterator it,
|
| if (owned_stream->type() == SPDY_PUSH_STREAM)
|
| unclaimed_pushed_streams_.erase(owned_stream->url());
|
|
|
| - base::WeakPtr<SpdySession> weak_this = GetWeakPtr();
|
| -
|
| DeleteStream(owned_stream.Pass(), status);
|
| -
|
| - if (!weak_this)
|
| - return;
|
| -
|
| - if (availability_state_ == STATE_CLOSED)
|
| - return;
|
| + MaybeFinishGoingAway();
|
|
|
| // If there are no active streams and the socket pool is stalled, close the
|
| // session to free up a socket slot.
|
| if (active_streams_.empty() && connection_->IsPoolStalled()) {
|
| - CloseSessionResult result =
|
| - DoCloseSession(ERR_CONNECTION_CLOSED, "Closing idle connection.");
|
| - CHECK_NE(result, SESSION_ALREADY_CLOSED);
|
| + DoDrainSession(ERR_CONNECTION_CLOSED, "Closing idle connection.");
|
| }
|
| }
|
|
|
| @@ -1195,31 +1172,21 @@ void SpdySession::EnqueueResetStreamFrame(SpdyStreamId stream_id,
|
|
|
| void SpdySession::PumpReadLoop(ReadState expected_read_state, int result) {
|
| CHECK(!in_io_loop_);
|
| - CHECK_NE(availability_state_, STATE_CLOSED);
|
| - CHECK_EQ(read_state_, expected_read_state);
|
| -
|
| - result = DoReadLoop(expected_read_state, result);
|
| -
|
| - if (availability_state_ == STATE_CLOSED) {
|
| - CHECK_EQ(result, error_on_close_);
|
| - CHECK_LT(error_on_close_, ERR_IO_PENDING);
|
| - RemoveFromPool();
|
| + if (availability_state_ == STATE_DRAINING) {
|
| return;
|
| }
|
| -
|
| - CHECK(result == OK || result == ERR_IO_PENDING);
|
| + ignore_result(DoReadLoop(expected_read_state, result));
|
| }
|
|
|
| int SpdySession::DoReadLoop(ReadState expected_read_state, int result) {
|
| CHECK(!in_io_loop_);
|
| - CHECK_NE(availability_state_, STATE_CLOSED);
|
| CHECK_EQ(read_state_, expected_read_state);
|
|
|
| in_io_loop_ = true;
|
|
|
| int bytes_read_without_yielding = 0;
|
|
|
| - // Loop until the session is closed, the read becomes blocked, or
|
| + // Loop until the session is draining, the read becomes blocked, or
|
| // the read limit is exceeded.
|
| while (true) {
|
| switch (read_state_) {
|
| @@ -1237,11 +1204,8 @@ int SpdySession::DoReadLoop(ReadState expected_read_state, int result) {
|
| break;
|
| }
|
|
|
| - if (availability_state_ == STATE_CLOSED) {
|
| - CHECK_EQ(result, error_on_close_);
|
| - CHECK_LT(result, ERR_IO_PENDING);
|
| + if (availability_state_ == STATE_DRAINING)
|
| break;
|
| - }
|
|
|
| if (result == ERR_IO_PENDING)
|
| break;
|
| @@ -1265,7 +1229,6 @@ int SpdySession::DoReadLoop(ReadState expected_read_state, int result) {
|
|
|
| int SpdySession::DoRead() {
|
| CHECK(in_io_loop_);
|
| - CHECK_NE(availability_state_, STATE_CLOSED);
|
|
|
| CHECK(connection_);
|
| CHECK(connection_->socket());
|
| @@ -1279,7 +1242,6 @@ int SpdySession::DoRead() {
|
|
|
| int SpdySession::DoReadComplete(int result) {
|
| CHECK(in_io_loop_);
|
| - DCHECK_NE(availability_state_, STATE_CLOSED);
|
|
|
| // Parse a frame. For now this code requires that the frame fit into our
|
| // buffer (kReadBufferSize).
|
| @@ -1288,20 +1250,13 @@ int SpdySession::DoReadComplete(int result) {
|
| if (result == 0) {
|
| UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySession.BytesRead.EOF",
|
| total_bytes_received_, 1, 100000000, 50);
|
| - CloseSessionResult close_session_result =
|
| - DoCloseSession(ERR_CONNECTION_CLOSED, "Connection closed");
|
| - DCHECK_EQ(close_session_result, SESSION_CLOSED_BUT_NOT_REMOVED);
|
| - DCHECK_EQ(availability_state_, STATE_CLOSED);
|
| - DCHECK_EQ(error_on_close_, ERR_CONNECTION_CLOSED);
|
| + DoDrainSession(ERR_CONNECTION_CLOSED, "Connection closed");
|
| +
|
| return ERR_CONNECTION_CLOSED;
|
| }
|
|
|
| if (result < 0) {
|
| - CloseSessionResult close_session_result =
|
| - DoCloseSession(static_cast<Error>(result), "result is < 0.");
|
| - DCHECK_EQ(close_session_result, SESSION_CLOSED_BUT_NOT_REMOVED);
|
| - DCHECK_EQ(availability_state_, STATE_CLOSED);
|
| - DCHECK_EQ(error_on_close_, result);
|
| + DoDrainSession(static_cast<Error>(result), "result is < 0.");
|
| return result;
|
| }
|
| CHECK_LE(result, kReadBufferSize);
|
| @@ -1316,9 +1271,8 @@ int SpdySession::DoReadComplete(int result) {
|
| result -= bytes_processed;
|
| data += bytes_processed;
|
|
|
| - if (availability_state_ == STATE_CLOSED) {
|
| - DCHECK_LT(error_on_close_, ERR_IO_PENDING);
|
| - return error_on_close_;
|
| + if (availability_state_ == STATE_DRAINING) {
|
| + return ERR_CONNECTION_CLOSED;
|
| }
|
|
|
| DCHECK_EQ(buffered_spdy_framer_->error_code(), SpdyFramer::SPDY_NO_ERROR);
|
| @@ -1330,24 +1284,19 @@ int SpdySession::DoReadComplete(int result) {
|
|
|
| void SpdySession::PumpWriteLoop(WriteState expected_write_state, int result) {
|
| CHECK(!in_io_loop_);
|
| - DCHECK_NE(availability_state_, STATE_CLOSED);
|
| DCHECK_EQ(write_state_, expected_write_state);
|
|
|
| - result = DoWriteLoop(expected_write_state, result);
|
| + DoWriteLoop(expected_write_state, result);
|
|
|
| - if (availability_state_ == STATE_CLOSED) {
|
| - DCHECK_EQ(result, error_on_close_);
|
| - DCHECK_LT(error_on_close_, ERR_IO_PENDING);
|
| - RemoveFromPool();
|
| + if (availability_state_ == STATE_DRAINING && !in_flight_write_ &&
|
| + write_queue_.IsEmpty()) {
|
| + pool_->RemoveUnavailableSession(GetWeakPtr()); // Destroys |this|.
|
| return;
|
| }
|
| -
|
| - DCHECK(result == OK || result == ERR_IO_PENDING);
|
| }
|
|
|
| int SpdySession::DoWriteLoop(WriteState expected_write_state, int result) {
|
| CHECK(!in_io_loop_);
|
| - DCHECK_NE(availability_state_, STATE_CLOSED);
|
| DCHECK_NE(write_state_, WRITE_STATE_IDLE);
|
| DCHECK_EQ(write_state_, expected_write_state);
|
|
|
| @@ -1369,12 +1318,6 @@ int SpdySession::DoWriteLoop(WriteState expected_write_state, int result) {
|
| break;
|
| }
|
|
|
| - if (availability_state_ == STATE_CLOSED) {
|
| - DCHECK_EQ(result, error_on_close_);
|
| - DCHECK_LT(result, ERR_IO_PENDING);
|
| - break;
|
| - }
|
| -
|
| if (write_state_ == WRITE_STATE_IDLE) {
|
| DCHECK_EQ(result, ERR_IO_PENDING);
|
| break;
|
| @@ -1392,7 +1335,6 @@ int SpdySession::DoWriteLoop(WriteState expected_write_state, int result) {
|
|
|
| int SpdySession::DoWrite() {
|
| CHECK(in_io_loop_);
|
| - DCHECK_NE(availability_state_, STATE_CLOSED);
|
|
|
| DCHECK(buffered_spdy_framer_);
|
| if (in_flight_write_) {
|
| @@ -1456,7 +1398,6 @@ int SpdySession::DoWrite() {
|
|
|
| int SpdySession::DoWriteComplete(int result) {
|
| CHECK(in_io_loop_);
|
| - DCHECK_NE(availability_state_, STATE_CLOSED);
|
| DCHECK_NE(result, ERR_IO_PENDING);
|
| DCHECK_GT(in_flight_write_->GetRemainingSize(), 0u);
|
|
|
| @@ -1468,12 +1409,9 @@ int SpdySession::DoWriteComplete(int result) {
|
| in_flight_write_frame_type_ = DATA;
|
| in_flight_write_frame_size_ = 0;
|
| in_flight_write_stream_.reset();
|
| - CloseSessionResult close_session_result =
|
| - DoCloseSession(static_cast<Error>(result), "Write error");
|
| - DCHECK_EQ(close_session_result, SESSION_CLOSED_BUT_NOT_REMOVED);
|
| - DCHECK_EQ(availability_state_, STATE_CLOSED);
|
| - DCHECK_EQ(error_on_close_, result);
|
| - return result;
|
| + write_state_ = WRITE_STATE_DO_WRITE;
|
| + DoDrainSession(static_cast<Error>(result), "Write error");
|
| + return OK;
|
| }
|
|
|
| // It should not be possible to have written more bytes than our
|
| @@ -1517,13 +1455,11 @@ void SpdySession::DcheckGoingAway() const {
|
| #endif
|
| }
|
|
|
| -void SpdySession::DcheckClosed() const {
|
| +void SpdySession::DcheckDraining() const {
|
| DcheckGoingAway();
|
| - DCHECK_EQ(availability_state_, STATE_CLOSED);
|
| - DCHECK_LT(error_on_close_, ERR_IO_PENDING);
|
| + DCHECK_EQ(availability_state_, STATE_DRAINING);
|
| DCHECK(active_streams_.empty());
|
| DCHECK(unclaimed_pushed_streams_.empty());
|
| - DCHECK(write_queue_.IsEmpty());
|
| }
|
|
|
| void SpdySession::StartGoingAway(SpdyStreamId last_good_stream_id,
|
| @@ -1573,21 +1509,21 @@ void SpdySession::StartGoingAway(SpdyStreamId last_good_stream_id,
|
| }
|
|
|
| void SpdySession::MaybeFinishGoingAway() {
|
| - DcheckGoingAway();
|
| - if (active_streams_.empty() && availability_state_ != STATE_CLOSED) {
|
| - CloseSessionResult result =
|
| - DoCloseSession(ERR_CONNECTION_CLOSED, "Finished going away");
|
| - CHECK_NE(result, SESSION_ALREADY_CLOSED);
|
| + if (active_streams_.empty() && availability_state_ == STATE_GOING_AWAY) {
|
| + DoDrainSession(OK, "Finished going away");
|
| }
|
| }
|
|
|
| -SpdySession::CloseSessionResult SpdySession::DoCloseSession(
|
| - Error err,
|
| - const std::string& description) {
|
| - CHECK_LT(err, ERR_IO_PENDING);
|
| +void SpdySession::DoDrainSession(Error err, const std::string& description) {
|
| + if (availability_state_ == STATE_DRAINING) {
|
| + return;
|
| + }
|
| + MakeUnavailable();
|
|
|
| - if (availability_state_ == STATE_CLOSED)
|
| - return SESSION_ALREADY_CLOSED;
|
| + // TODO(jgraettinger): If draining with an |err|, enqueue a GOAWAY frame here.
|
| +
|
| + availability_state_ = STATE_DRAINING;
|
| + error_on_close_ = err;
|
|
|
| net_log_.AddEvent(
|
| NetLog::TYPE_SPDY_SESSION_CLOSE,
|
| @@ -1597,32 +1533,9 @@ SpdySession::CloseSessionResult SpdySession::DoCloseSession(
|
| UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySession.BytesRead.OtherErrors",
|
| total_bytes_received_, 1, 100000000, 50);
|
|
|
| - CHECK(pool_);
|
| - if (availability_state_ != STATE_GOING_AWAY)
|
| - pool_->MakeSessionUnavailable(GetWeakPtr());
|
| -
|
| - availability_state_ = STATE_CLOSED;
|
| - error_on_close_ = err;
|
| -
|
| StartGoingAway(0, err);
|
| - write_queue_.Clear();
|
| -
|
| - DcheckClosed();
|
| -
|
| - if (in_io_loop_)
|
| - return SESSION_CLOSED_BUT_NOT_REMOVED;
|
| -
|
| - RemoveFromPool();
|
| - return SESSION_CLOSED_AND_REMOVED;
|
| -}
|
| -
|
| -void SpdySession::RemoveFromPool() {
|
| - DcheckClosed();
|
| - CHECK(pool_);
|
| -
|
| - SpdySessionPool* pool = pool_;
|
| - pool_ = NULL;
|
| - pool->RemoveUnavailableSession(GetWeakPtr());
|
| + DcheckDraining();
|
| + MaybePostWriteLoop();
|
| }
|
|
|
| void SpdySession::LogAbandonedStream(SpdyStream* stream, Error status) {
|
| @@ -1661,15 +1574,12 @@ SpdyStreamId SpdySession::GetNewStreamId() {
|
|
|
| void SpdySession::CloseSessionOnError(Error err,
|
| const std::string& description) {
|
| - // We may be called from anywhere, so we can't expect a particular
|
| - // return value.
|
| - ignore_result(DoCloseSession(err, description));
|
| + DoDrainSession(err, description);
|
| }
|
|
|
| void SpdySession::MakeUnavailable() {
|
| - if (availability_state_ < STATE_GOING_AWAY) {
|
| + if (availability_state_ == STATE_AVAILABLE) {
|
| availability_state_ = STATE_GOING_AWAY;
|
| - DCHECK(pool_);
|
| pool_->MakeSessionUnavailable(GetWeakPtr());
|
| }
|
| }
|
| @@ -1778,14 +1688,16 @@ void SpdySession::EnqueueWrite(RequestPriority priority,
|
| SpdyFrameType frame_type,
|
| scoped_ptr<SpdyBufferProducer> producer,
|
| const base::WeakPtr<SpdyStream>& stream) {
|
| - if (availability_state_ == STATE_CLOSED)
|
| + if (availability_state_ == STATE_DRAINING)
|
| return;
|
|
|
| - bool was_idle = write_queue_.IsEmpty();
|
| write_queue_.Enqueue(priority, frame_type, producer.Pass(), stream);
|
| + MaybePostWriteLoop();
|
| +}
|
| +
|
| +void SpdySession::MaybePostWriteLoop() {
|
| if (write_state_ == WRITE_STATE_IDLE) {
|
| - DCHECK(was_idle);
|
| - DCHECK(!in_flight_write_);
|
| + CHECK(!in_flight_write_);
|
| write_state_ = WRITE_STATE_DO_WRITE;
|
| base::MessageLoop::current()->PostTask(
|
| FROM_HERE,
|
| @@ -1829,26 +1741,10 @@ void SpdySession::DeleteStream(scoped_ptr<SpdyStream> stream, int status) {
|
| }
|
|
|
| write_queue_.RemovePendingWritesForStream(stream->GetWeakPtr());
|
| -
|
| - // |stream->OnClose()| may end up closing |this|, so detect that.
|
| - base::WeakPtr<SpdySession> weak_this = GetWeakPtr();
|
| -
|
| stream->OnClose(status);
|
|
|
| - if (!weak_this)
|
| - return;
|
| -
|
| - switch (availability_state_) {
|
| - case STATE_AVAILABLE:
|
| - ProcessPendingStreamRequests();
|
| - break;
|
| - case STATE_GOING_AWAY:
|
| - DcheckGoingAway();
|
| - MaybeFinishGoingAway();
|
| - break;
|
| - case STATE_CLOSED:
|
| - // Do nothing.
|
| - break;
|
| + if (availability_state_ == STATE_AVAILABLE) {
|
| + ProcessPendingStreamRequests();
|
| }
|
| }
|
|
|
| @@ -1892,24 +1788,16 @@ bool SpdySession::GetSSLCertRequestInfo(
|
| void SpdySession::OnError(SpdyFramer::SpdyError error_code) {
|
| CHECK(in_io_loop_);
|
|
|
| - if (availability_state_ == STATE_CLOSED)
|
| - return;
|
| -
|
| RecordProtocolErrorHistogram(MapFramerErrorToProtocolError(error_code));
|
| std::string description = base::StringPrintf(
|
| "SPDY_ERROR error_code: %d.", error_code);
|
| - CloseSessionResult result =
|
| - DoCloseSession(ERR_SPDY_PROTOCOL_ERROR, description);
|
| - DCHECK_EQ(result, SESSION_CLOSED_BUT_NOT_REMOVED);
|
| + DoDrainSession(ERR_SPDY_PROTOCOL_ERROR, description);
|
| }
|
|
|
| void SpdySession::OnStreamError(SpdyStreamId stream_id,
|
| const std::string& description) {
|
| CHECK(in_io_loop_);
|
|
|
| - if (availability_state_ == STATE_CLOSED)
|
| - return;
|
| -
|
| ActiveStreamMap::iterator it = active_streams_.find(stream_id);
|
| if (it == active_streams_.end()) {
|
| // We still want to send a frame to reset the stream even if we
|
| @@ -1927,9 +1815,6 @@ void SpdySession::OnDataFrameHeader(SpdyStreamId stream_id,
|
| bool fin) {
|
| CHECK(in_io_loop_);
|
|
|
| - if (availability_state_ == STATE_CLOSED)
|
| - return;
|
| -
|
| ActiveStreamMap::iterator it = active_streams_.find(stream_id);
|
|
|
| // By the time data comes in, the stream may already be inactive.
|
| @@ -1950,9 +1835,6 @@ void SpdySession::OnStreamFrameData(SpdyStreamId stream_id,
|
| bool fin) {
|
| CHECK(in_io_loop_);
|
|
|
| - if (availability_state_ == STATE_CLOSED)
|
| - return;
|
| -
|
| if (data == NULL && len != 0) {
|
| // This is notification of consumed data padding.
|
| // TODO(jgraettinger): Properly flow padding into WINDOW_UPDATE frames.
|
| @@ -2012,9 +1894,6 @@ void SpdySession::OnStreamFrameData(SpdyStreamId stream_id,
|
| void SpdySession::OnSettings(bool clear_persisted) {
|
| CHECK(in_io_loop_);
|
|
|
| - if (availability_state_ == STATE_CLOSED)
|
| - return;
|
| -
|
| if (clear_persisted)
|
| http_server_properties_->ClearSpdySettings(host_port_pair());
|
|
|
| @@ -2042,9 +1921,6 @@ void SpdySession::OnSetting(SpdySettingsIds id,
|
| uint32 value) {
|
| CHECK(in_io_loop_);
|
|
|
| - if (availability_state_ == STATE_CLOSED)
|
| - return;
|
| -
|
| HandleSetting(id, value);
|
| http_server_properties_->SetSpdySetting(
|
| host_port_pair(),
|
| @@ -2112,9 +1988,6 @@ void SpdySession::OnSynStream(SpdyStreamId stream_id,
|
| const SpdyHeaderBlock& headers) {
|
| CHECK(in_io_loop_);
|
|
|
| - if (availability_state_ == STATE_CLOSED)
|
| - return;
|
| -
|
| base::Time response_time = base::Time::Now();
|
| base::TimeTicks recv_first_byte_time = time_func_();
|
|
|
| @@ -2300,9 +2173,6 @@ void SpdySession::OnSynReply(SpdyStreamId stream_id,
|
| const SpdyHeaderBlock& headers) {
|
| CHECK(in_io_loop_);
|
|
|
| - if (availability_state_ == STATE_CLOSED)
|
| - return;
|
| -
|
| base::Time response_time = base::Time::Now();
|
| base::TimeTicks recv_first_byte_time = time_func_();
|
|
|
| @@ -2350,9 +2220,6 @@ void SpdySession::OnHeaders(SpdyStreamId stream_id,
|
| const SpdyHeaderBlock& headers) {
|
| CHECK(in_io_loop_);
|
|
|
| - if (availability_state_ == STATE_CLOSED)
|
| - return;
|
| -
|
| if (net_log().IsLogging()) {
|
| net_log().AddEvent(
|
| NetLog::TYPE_SPDY_SESSION_RECV_HEADERS,
|
| @@ -2400,9 +2267,6 @@ void SpdySession::OnRstStream(SpdyStreamId stream_id,
|
| SpdyRstStreamStatus status) {
|
| CHECK(in_io_loop_);
|
|
|
| - if (availability_state_ == STATE_CLOSED)
|
| - return;
|
| -
|
| std::string description;
|
| net_log().AddEvent(
|
| NetLog::TYPE_SPDY_SESSION_RST_STREAM,
|
| @@ -2438,9 +2302,6 @@ void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id,
|
| SpdyGoAwayStatus status) {
|
| CHECK(in_io_loop_);
|
|
|
| - if (availability_state_ == STATE_CLOSED)
|
| - return;
|
| -
|
| net_log_.AddEvent(NetLog::TYPE_SPDY_SESSION_GOAWAY,
|
| base::Bind(&NetLogSpdyGoAwayCallback,
|
| last_accepted_stream_id,
|
| @@ -2459,9 +2320,6 @@ void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id,
|
| void SpdySession::OnPing(SpdyPingId unique_id, bool is_ack) {
|
| CHECK(in_io_loop_);
|
|
|
| - if (availability_state_ == STATE_CLOSED)
|
| - return;
|
| -
|
| net_log_.AddEvent(
|
| NetLog::TYPE_SPDY_SESSION_PING,
|
| base::Bind(&NetLogSpdyPingCallback, unique_id, is_ack, "received"));
|
| @@ -2476,9 +2334,7 @@ void SpdySession::OnPing(SpdyPingId unique_id, bool is_ack) {
|
| --pings_in_flight_;
|
| if (pings_in_flight_ < 0) {
|
| RecordProtocolErrorHistogram(PROTOCOL_ERROR_UNEXPECTED_PING);
|
| - CloseSessionResult result =
|
| - DoCloseSession(ERR_SPDY_PROTOCOL_ERROR, "pings_in_flight_ is < 0.");
|
| - DCHECK_EQ(result, SESSION_CLOSED_BUT_NOT_REMOVED);
|
| + DoDrainSession(ERR_SPDY_PROTOCOL_ERROR, "pings_in_flight_ is < 0.");
|
| pings_in_flight_ = 0;
|
| return;
|
| }
|
| @@ -2495,9 +2351,6 @@ void SpdySession::OnWindowUpdate(SpdyStreamId stream_id,
|
| uint32 delta_window_size) {
|
| CHECK(in_io_loop_);
|
|
|
| - if (availability_state_ == STATE_CLOSED)
|
| - return;
|
| -
|
| DCHECK_LE(delta_window_size, static_cast<uint32>(kint32max));
|
| net_log_.AddEvent(
|
| NetLog::TYPE_SPDY_SESSION_RECEIVED_WINDOW_UPDATE_FRAME,
|
| @@ -2515,11 +2368,10 @@ void SpdySession::OnWindowUpdate(SpdyStreamId stream_id,
|
|
|
| if (delta_window_size < 1u) {
|
| RecordProtocolErrorHistogram(PROTOCOL_ERROR_INVALID_WINDOW_UPDATE_SIZE);
|
| - CloseSessionResult result = DoCloseSession(
|
| + DoDrainSession(
|
| ERR_SPDY_PROTOCOL_ERROR,
|
| "Received WINDOW_UPDATE with an invalid delta_window_size " +
|
| - base::UintToString(delta_window_size));
|
| - DCHECK_EQ(result, SESSION_CLOSED_BUT_NOT_REMOVED);
|
| + base::UintToString(delta_window_size));
|
| return;
|
| }
|
|
|
| @@ -2576,7 +2428,6 @@ void SpdySession::SendStreamWindowUpdate(SpdyStreamId stream_id,
|
|
|
| void SpdySession::SendInitialData() {
|
| DCHECK(enable_sending_initial_data_);
|
| - DCHECK_NE(availability_state_, STATE_CLOSED);
|
|
|
| if (send_connection_header_prefix_) {
|
| DCHECK_EQ(protocol_, kProtoSPDY4);
|
| @@ -2642,8 +2493,6 @@ void SpdySession::SendInitialData() {
|
|
|
|
|
| void SpdySession::SendSettings(const SettingsMap& settings) {
|
| - DCHECK_NE(availability_state_, STATE_CLOSED);
|
| -
|
| net_log_.AddEvent(
|
| NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS,
|
| base::Bind(&NetLogSpdySendSettingsCallback, &settings));
|
| @@ -2772,7 +2621,6 @@ void SpdySession::PlanToCheckPingStatus() {
|
|
|
| void SpdySession::CheckPingStatus(base::TimeTicks last_check_time) {
|
| CHECK(!in_io_loop_);
|
| - DCHECK_NE(availability_state_, STATE_CLOSED);
|
|
|
| // Check if we got a response back for all PINGs we had sent.
|
| if (pings_in_flight_ == 0) {
|
| @@ -2788,9 +2636,7 @@ void SpdySession::CheckPingStatus(base::TimeTicks last_check_time) {
|
| if (delay.InMilliseconds() < 0 || last_activity_time_ < last_check_time) {
|
| // Track all failed PING messages in a separate bucket.
|
| RecordPingRTTHistogram(base::TimeDelta::Max());
|
| - CloseSessionResult result =
|
| - DoCloseSession(ERR_SPDY_PING_FAILED, "Failed ping.");
|
| - DCHECK_EQ(result, SESSION_CLOSED_AND_REMOVED);
|
| + DoDrainSession(ERR_SPDY_PING_FAILED, "Failed ping.");
|
| return;
|
| }
|
|
|
| @@ -2923,9 +2769,6 @@ void SpdySession::OnWriteBufferConsumed(
|
| // We can be called with |in_io_loop_| set if a write SpdyBuffer is
|
| // deleted (e.g., a stream is closed due to incoming data).
|
|
|
| - if (availability_state_ == STATE_CLOSED)
|
| - return;
|
| -
|
| DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
|
|
|
| if (consume_source == SpdyBuffer::DISCARD) {
|
| @@ -2945,7 +2788,6 @@ void SpdySession::IncreaseSendWindowSize(int32 delta_window_size) {
|
| // We can be called with |in_io_loop_| set if a SpdyBuffer is
|
| // deleted (e.g., a stream is closed due to incoming data).
|
|
|
| - DCHECK_NE(availability_state_, STATE_CLOSED);
|
| DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
|
| DCHECK_GE(delta_window_size, 1);
|
|
|
| @@ -2953,13 +2795,12 @@ void SpdySession::IncreaseSendWindowSize(int32 delta_window_size) {
|
| int32 max_delta_window_size = kint32max - session_send_window_size_;
|
| if (delta_window_size > max_delta_window_size) {
|
| RecordProtocolErrorHistogram(PROTOCOL_ERROR_INVALID_WINDOW_UPDATE_SIZE);
|
| - CloseSessionResult result = DoCloseSession(
|
| + DoDrainSession(
|
| ERR_SPDY_PROTOCOL_ERROR,
|
| "Received WINDOW_UPDATE [delta: " +
|
| - base::IntToString(delta_window_size) +
|
| - "] for session overflows session_send_window_size_ [current: " +
|
| - base::IntToString(session_send_window_size_) + "]");
|
| - DCHECK_NE(result, SESSION_ALREADY_CLOSED);
|
| + base::IntToString(delta_window_size) +
|
| + "] for session overflows session_send_window_size_ [current: " +
|
| + base::IntToString(session_send_window_size_) + "]");
|
| return;
|
| }
|
|
|
| @@ -2975,7 +2816,6 @@ void SpdySession::IncreaseSendWindowSize(int32 delta_window_size) {
|
| }
|
|
|
| void SpdySession::DecreaseSendWindowSize(int32 delta_window_size) {
|
| - DCHECK_NE(availability_state_, STATE_CLOSED);
|
| DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
|
|
|
| // We only call this method when sending a frame. Therefore,
|
| @@ -3001,9 +2841,6 @@ void SpdySession::OnReadBufferConsumed(
|
| // We can be called with |in_io_loop_| set if a read SpdyBuffer is
|
| // deleted (e.g., discarded by a SpdyReadQueue).
|
|
|
| - if (availability_state_ == STATE_CLOSED)
|
| - return;
|
| -
|
| DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
|
| DCHECK_GE(consume_size, 1u);
|
| DCHECK_LE(consume_size, static_cast<size_t>(kint32max));
|
| @@ -3012,7 +2849,6 @@ void SpdySession::OnReadBufferConsumed(
|
| }
|
|
|
| void SpdySession::IncreaseRecvWindowSize(int32 delta_window_size) {
|
| - DCHECK_NE(availability_state_, STATE_CLOSED);
|
| DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
|
| DCHECK_GE(session_unacked_recv_window_bytes_, 0);
|
| DCHECK_GE(session_recv_window_size_, session_unacked_recv_window_bytes_);
|
| @@ -3045,12 +2881,11 @@ void SpdySession::DecreaseRecvWindowSize(int32 delta_window_size) {
|
| // negative. If we do, the receive window isn't being respected.
|
| if (delta_window_size > session_recv_window_size_) {
|
| RecordProtocolErrorHistogram(PROTOCOL_ERROR_RECEIVE_WINDOW_VIOLATION);
|
| - CloseSessionResult result = DoCloseSession(
|
| + DoDrainSession(
|
| ERR_SPDY_PROTOCOL_ERROR,
|
| "delta_window_size is " + base::IntToString(delta_window_size) +
|
| " in DecreaseRecvWindowSize, which is larger than the receive " +
|
| "window size of " + base::IntToString(session_recv_window_size_));
|
| - DCHECK_EQ(result, SESSION_CLOSED_BUT_NOT_REMOVED);
|
| return;
|
| }
|
|
|
| @@ -3077,7 +2912,7 @@ void SpdySession::ResumeSendStalledStreams() {
|
| // have to worry about streams being closed, as well as ourselves
|
| // being closed.
|
|
|
| - while (availability_state_ != STATE_CLOSED && !IsSendStalled()) {
|
| + while (!IsSendStalled()) {
|
| size_t old_size = 0;
|
| #if DCHECK_IS_ON
|
| old_size = GetTotalSize(stream_send_unstall_queue_);
|
|
|