| 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_stream.h" | 5 #include "net/spdy/spdy_stream.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "base/metrics/histogram_macros.h" | 11 #include "base/metrics/histogram_macros.h" |
| 12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
| 13 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
| 14 #include "base/values.h" | 14 #include "base/values.h" |
| 15 #include "net/spdy/spdy_buffer_producer.h" | 15 #include "net/spdy/spdy_buffer_producer.h" |
| 16 #include "net/spdy/spdy_http_utils.h" | 16 #include "net/spdy/spdy_http_utils.h" |
| 17 #include "net/spdy/spdy_session.h" | 17 #include "net/spdy/spdy_session.h" |
| 18 | 18 |
| 19 namespace net { | 19 namespace net { |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 base::Value* NetLogSpdyStreamErrorCallback( | 23 scoped_ptr<base::Value> NetLogSpdyStreamErrorCallback( |
| 24 SpdyStreamId stream_id, | 24 SpdyStreamId stream_id, |
| 25 int status, | 25 int status, |
| 26 const std::string* description, | 26 const std::string* description, |
| 27 NetLogCaptureMode /* capture_mode */) { | 27 NetLogCaptureMode /* capture_mode */) { |
| 28 base::DictionaryValue* dict = new base::DictionaryValue(); | 28 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
| 29 dict->SetInteger("stream_id", static_cast<int>(stream_id)); | 29 dict->SetInteger("stream_id", static_cast<int>(stream_id)); |
| 30 dict->SetInteger("status", status); | 30 dict->SetInteger("status", status); |
| 31 dict->SetString("description", *description); | 31 dict->SetString("description", *description); |
| 32 return dict; | 32 return dict.Pass(); |
| 33 } | 33 } |
| 34 | 34 |
| 35 base::Value* NetLogSpdyStreamWindowUpdateCallback( | 35 scoped_ptr<base::Value> NetLogSpdyStreamWindowUpdateCallback( |
| 36 SpdyStreamId stream_id, | 36 SpdyStreamId stream_id, |
| 37 int32 delta, | 37 int32 delta, |
| 38 int32 window_size, | 38 int32 window_size, |
| 39 NetLogCaptureMode /* capture_mode */) { | 39 NetLogCaptureMode /* capture_mode */) { |
| 40 base::DictionaryValue* dict = new base::DictionaryValue(); | 40 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
| 41 dict->SetInteger("stream_id", stream_id); | 41 dict->SetInteger("stream_id", stream_id); |
| 42 dict->SetInteger("delta", delta); | 42 dict->SetInteger("delta", delta); |
| 43 dict->SetInteger("window_size", window_size); | 43 dict->SetInteger("window_size", window_size); |
| 44 return dict; | 44 return dict.Pass(); |
| 45 } | 45 } |
| 46 | 46 |
| 47 bool ContainsUppercaseAscii(const std::string& str) { | 47 bool ContainsUppercaseAscii(const std::string& str) { |
| 48 for (std::string::const_iterator i(str.begin()); i != str.end(); ++i) { | 48 for (std::string::const_iterator i(str.begin()); i != str.end(); ++i) { |
| 49 if (*i >= 'A' && *i <= 'Z') { | 49 if (*i >= 'A' && *i <= 'Z') { |
| 50 return true; | 50 return true; |
| 51 } | 51 } |
| 52 } | 52 } |
| 53 return false; | 53 return false; |
| 54 } | 54 } |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 "Received WINDOW_UPDATE [delta: %d] for stream %d overflows " | 267 "Received WINDOW_UPDATE [delta: %d] for stream %d overflows " |
| 268 "send_window_size_ [current: %d]", delta_window_size, stream_id_, | 268 "send_window_size_ [current: %d]", delta_window_size, stream_id_, |
| 269 send_window_size_); | 269 send_window_size_); |
| 270 session_->ResetStream(stream_id_, RST_STREAM_FLOW_CONTROL_ERROR, desc); | 270 session_->ResetStream(stream_id_, RST_STREAM_FLOW_CONTROL_ERROR, desc); |
| 271 return; | 271 return; |
| 272 } | 272 } |
| 273 } | 273 } |
| 274 | 274 |
| 275 send_window_size_ += delta_window_size; | 275 send_window_size_ += delta_window_size; |
| 276 | 276 |
| 277 net_log_.AddEvent( | 277 net_log_.AddEvent(NetLog::TYPE_HTTP2_STREAM_UPDATE_SEND_WINDOW, |
| 278 NetLog::TYPE_HTTP2_STREAM_UPDATE_SEND_WINDOW, | 278 base::Bind(NetLogSpdyStreamWindowUpdateCallback, stream_id_, |
| 279 base::Bind(&NetLogSpdyStreamWindowUpdateCallback, stream_id_, | 279 delta_window_size, send_window_size_)); |
| 280 delta_window_size, send_window_size_)); | |
| 281 | 280 |
| 282 PossiblyResumeIfSendStalled(); | 281 PossiblyResumeIfSendStalled(); |
| 283 } | 282 } |
| 284 | 283 |
| 285 void SpdyStream::DecreaseSendWindowSize(int32 delta_window_size) { | 284 void SpdyStream::DecreaseSendWindowSize(int32 delta_window_size) { |
| 286 DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM); | 285 DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM); |
| 287 | 286 |
| 288 if (IsClosed()) | 287 if (IsClosed()) |
| 289 return; | 288 return; |
| 290 | 289 |
| 291 // We only call this method when sending a frame. Therefore, | 290 // We only call this method when sending a frame. Therefore, |
| 292 // |delta_window_size| should be within the valid frame size range. | 291 // |delta_window_size| should be within the valid frame size range. |
| 293 DCHECK_GE(delta_window_size, 1); | 292 DCHECK_GE(delta_window_size, 1); |
| 294 DCHECK_LE(delta_window_size, kMaxSpdyFrameChunkSize); | 293 DCHECK_LE(delta_window_size, kMaxSpdyFrameChunkSize); |
| 295 | 294 |
| 296 // |send_window_size_| should have been at least |delta_window_size| for | 295 // |send_window_size_| should have been at least |delta_window_size| for |
| 297 // this call to happen. | 296 // this call to happen. |
| 298 DCHECK_GE(send_window_size_, delta_window_size); | 297 DCHECK_GE(send_window_size_, delta_window_size); |
| 299 | 298 |
| 300 send_window_size_ -= delta_window_size; | 299 send_window_size_ -= delta_window_size; |
| 301 | 300 |
| 302 net_log_.AddEvent( | 301 net_log_.AddEvent(NetLog::TYPE_HTTP2_STREAM_UPDATE_SEND_WINDOW, |
| 303 NetLog::TYPE_HTTP2_STREAM_UPDATE_SEND_WINDOW, | 302 base::Bind(NetLogSpdyStreamWindowUpdateCallback, stream_id_, |
| 304 base::Bind(&NetLogSpdyStreamWindowUpdateCallback, stream_id_, | 303 -delta_window_size, send_window_size_)); |
| 305 -delta_window_size, send_window_size_)); | |
| 306 } | 304 } |
| 307 | 305 |
| 308 void SpdyStream::OnReadBufferConsumed( | 306 void SpdyStream::OnReadBufferConsumed( |
| 309 size_t consume_size, | 307 size_t consume_size, |
| 310 SpdyBuffer::ConsumeSource consume_source) { | 308 SpdyBuffer::ConsumeSource consume_source) { |
| 311 DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM); | 309 DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM); |
| 312 DCHECK_GE(consume_size, 1u); | 310 DCHECK_GE(consume_size, 1u); |
| 313 DCHECK_LE(consume_size, static_cast<size_t>(kint32max)); | 311 DCHECK_LE(consume_size, static_cast<size_t>(kint32max)); |
| 314 IncreaseRecvWindowSize(static_cast<int32>(consume_size)); | 312 IncreaseRecvWindowSize(static_cast<int32>(consume_size)); |
| 315 } | 313 } |
| 316 | 314 |
| 317 void SpdyStream::IncreaseRecvWindowSize(int32 delta_window_size) { | 315 void SpdyStream::IncreaseRecvWindowSize(int32 delta_window_size) { |
| 318 DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM); | 316 DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM); |
| 319 | 317 |
| 320 // By the time a read is processed by the delegate, this stream may | 318 // By the time a read is processed by the delegate, this stream may |
| 321 // already be inactive. | 319 // already be inactive. |
| 322 if (!session_->IsStreamActive(stream_id_)) | 320 if (!session_->IsStreamActive(stream_id_)) |
| 323 return; | 321 return; |
| 324 | 322 |
| 325 DCHECK_GE(unacked_recv_window_bytes_, 0); | 323 DCHECK_GE(unacked_recv_window_bytes_, 0); |
| 326 DCHECK_GE(recv_window_size_, unacked_recv_window_bytes_); | 324 DCHECK_GE(recv_window_size_, unacked_recv_window_bytes_); |
| 327 DCHECK_GE(delta_window_size, 1); | 325 DCHECK_GE(delta_window_size, 1); |
| 328 // Check for overflow. | 326 // Check for overflow. |
| 329 DCHECK_LE(delta_window_size, kint32max - recv_window_size_); | 327 DCHECK_LE(delta_window_size, kint32max - recv_window_size_); |
| 330 | 328 |
| 331 recv_window_size_ += delta_window_size; | 329 recv_window_size_ += delta_window_size; |
| 332 net_log_.AddEvent( | 330 net_log_.AddEvent(NetLog::TYPE_HTTP2_STREAM_UPDATE_RECV_WINDOW, |
| 333 NetLog::TYPE_HTTP2_STREAM_UPDATE_RECV_WINDOW, | 331 base::Bind(NetLogSpdyStreamWindowUpdateCallback, stream_id_, |
| 334 base::Bind(&NetLogSpdyStreamWindowUpdateCallback, stream_id_, | 332 delta_window_size, recv_window_size_)); |
| 335 delta_window_size, recv_window_size_)); | |
| 336 | 333 |
| 337 unacked_recv_window_bytes_ += delta_window_size; | 334 unacked_recv_window_bytes_ += delta_window_size; |
| 338 if (unacked_recv_window_bytes_ > max_recv_window_size_ / 2) { | 335 if (unacked_recv_window_bytes_ > max_recv_window_size_ / 2) { |
| 339 session_->SendStreamWindowUpdate( | 336 session_->SendStreamWindowUpdate( |
| 340 stream_id_, static_cast<uint32>(unacked_recv_window_bytes_)); | 337 stream_id_, static_cast<uint32>(unacked_recv_window_bytes_)); |
| 341 unacked_recv_window_bytes_ = 0; | 338 unacked_recv_window_bytes_ = 0; |
| 342 } | 339 } |
| 343 } | 340 } |
| 344 | 341 |
| 345 void SpdyStream::DecreaseRecvWindowSize(int32 delta_window_size) { | 342 void SpdyStream::DecreaseRecvWindowSize(int32 delta_window_size) { |
| 346 DCHECK(session_->IsStreamActive(stream_id_)); | 343 DCHECK(session_->IsStreamActive(stream_id_)); |
| 347 DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM); | 344 DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM); |
| 348 DCHECK_GE(delta_window_size, 1); | 345 DCHECK_GE(delta_window_size, 1); |
| 349 | 346 |
| 350 // The receiving window size as the peer knows it is | 347 // The receiving window size as the peer knows it is |
| 351 // |recv_window_size_ - unacked_recv_window_bytes_|, if more data are sent by | 348 // |recv_window_size_ - unacked_recv_window_bytes_|, if more data are sent by |
| 352 // the peer, that means that the receive window is not being respected. | 349 // the peer, that means that the receive window is not being respected. |
| 353 if (delta_window_size > recv_window_size_ - unacked_recv_window_bytes_) { | 350 if (delta_window_size > recv_window_size_ - unacked_recv_window_bytes_) { |
| 354 session_->ResetStream( | 351 session_->ResetStream( |
| 355 stream_id_, RST_STREAM_FLOW_CONTROL_ERROR, | 352 stream_id_, RST_STREAM_FLOW_CONTROL_ERROR, |
| 356 "delta_window_size is " + base::IntToString(delta_window_size) + | 353 "delta_window_size is " + base::IntToString(delta_window_size) + |
| 357 " in DecreaseRecvWindowSize, which is larger than the receive " + | 354 " in DecreaseRecvWindowSize, which is larger than the receive " + |
| 358 "window size of " + base::IntToString(recv_window_size_)); | 355 "window size of " + base::IntToString(recv_window_size_)); |
| 359 return; | 356 return; |
| 360 } | 357 } |
| 361 | 358 |
| 362 recv_window_size_ -= delta_window_size; | 359 recv_window_size_ -= delta_window_size; |
| 363 net_log_.AddEvent( | 360 net_log_.AddEvent(NetLog::TYPE_HTTP2_STREAM_UPDATE_RECV_WINDOW, |
| 364 NetLog::TYPE_HTTP2_STREAM_UPDATE_RECV_WINDOW, | 361 base::Bind(NetLogSpdyStreamWindowUpdateCallback, stream_id_, |
| 365 base::Bind(&NetLogSpdyStreamWindowUpdateCallback, stream_id_, | 362 -delta_window_size, recv_window_size_)); |
| 366 -delta_window_size, recv_window_size_)); | |
| 367 } | 363 } |
| 368 | 364 |
| 369 int SpdyStream::GetPeerAddress(IPEndPoint* address) const { | 365 int SpdyStream::GetPeerAddress(IPEndPoint* address) const { |
| 370 return session_->GetPeerAddress(address); | 366 return session_->GetPeerAddress(address); |
| 371 } | 367 } |
| 372 | 368 |
| 373 int SpdyStream::GetLocalAddress(IPEndPoint* address) const { | 369 int SpdyStream::GetLocalAddress(IPEndPoint* address) const { |
| 374 return session_->GetLocalAddress(address); | 370 return session_->GetLocalAddress(address); |
| 375 } | 371 } |
| 376 | 372 |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 return OK; | 616 return OK; |
| 621 } | 617 } |
| 622 } | 618 } |
| 623 | 619 |
| 624 SpdyMajorVersion SpdyStream::GetProtocolVersion() const { | 620 SpdyMajorVersion SpdyStream::GetProtocolVersion() const { |
| 625 return session_->GetProtocolVersion(); | 621 return session_->GetProtocolVersion(); |
| 626 } | 622 } |
| 627 | 623 |
| 628 void SpdyStream::LogStreamError(int status, const std::string& description) { | 624 void SpdyStream::LogStreamError(int status, const std::string& description) { |
| 629 net_log_.AddEvent(NetLog::TYPE_HTTP2_STREAM_ERROR, | 625 net_log_.AddEvent(NetLog::TYPE_HTTP2_STREAM_ERROR, |
| 630 base::Bind(&NetLogSpdyStreamErrorCallback, stream_id_, | 626 base::Bind(NetLogSpdyStreamErrorCallback, stream_id_, |
| 631 status, &description)); | 627 status, &description)); |
| 632 } | 628 } |
| 633 | 629 |
| 634 void SpdyStream::OnClose(int status) { | 630 void SpdyStream::OnClose(int status) { |
| 635 // In most cases, the stream should already be CLOSED. The exception is when a | 631 // In most cases, the stream should already be CLOSED. The exception is when a |
| 636 // SpdySession is shutting down while the stream is in an intermediate state. | 632 // SpdySession is shutting down while the stream is in an intermediate state. |
| 637 io_state_ = STATE_CLOSED; | 633 io_state_ = STATE_CLOSED; |
| 638 response_status_ = status; | 634 response_status_ = status; |
| 639 Delegate* delegate = delegate_; | 635 Delegate* delegate = delegate_; |
| 640 delegate_ = NULL; | 636 delegate_ = NULL; |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 924 description = base::StringPrintf("Unknown state 0x%08X (%u)", state, | 920 description = base::StringPrintf("Unknown state 0x%08X (%u)", state, |
| 925 state); | 921 state); |
| 926 break; | 922 break; |
| 927 } | 923 } |
| 928 return description; | 924 return description; |
| 929 } | 925 } |
| 930 | 926 |
| 931 #undef STATE_CASE | 927 #undef STATE_CASE |
| 932 | 928 |
| 933 } // namespace net | 929 } // namespace net |
| OLD | NEW |