| 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" |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 request_time_(base::Time::Now()), | 99 request_time_(base::Time::Now()), |
| 100 response_headers_status_(RESPONSE_HEADERS_ARE_INCOMPLETE), | 100 response_headers_status_(RESPONSE_HEADERS_ARE_INCOMPLETE), |
| 101 io_state_(STATE_IDLE), | 101 io_state_(STATE_IDLE), |
| 102 response_status_(OK), | 102 response_status_(OK), |
| 103 net_log_(net_log), | 103 net_log_(net_log), |
| 104 raw_received_bytes_(0), | 104 raw_received_bytes_(0), |
| 105 send_bytes_(0), | 105 send_bytes_(0), |
| 106 recv_bytes_(0), | 106 recv_bytes_(0), |
| 107 write_handler_guard_(false) { | 107 write_handler_guard_(false) { |
| 108 CHECK(type_ == SPDY_BIDIRECTIONAL_STREAM || | 108 CHECK(type_ == SPDY_BIDIRECTIONAL_STREAM || |
| 109 type_ == SPDY_REQUEST_RESPONSE_STREAM || | 109 type_ == SPDY_REQUEST_RESPONSE_STREAM || type_ == SPDY_PUSH_STREAM); |
| 110 type_ == SPDY_PUSH_STREAM); | |
| 111 CHECK_GE(priority_, MINIMUM_PRIORITY); | 110 CHECK_GE(priority_, MINIMUM_PRIORITY); |
| 112 CHECK_LE(priority_, MAXIMUM_PRIORITY); | 111 CHECK_LE(priority_, MAXIMUM_PRIORITY); |
| 113 } | 112 } |
| 114 | 113 |
| 115 SpdyStream::~SpdyStream() { | 114 SpdyStream::~SpdyStream() { |
| 116 CHECK(!write_handler_guard_); | 115 CHECK(!write_handler_guard_); |
| 117 UpdateHistograms(); | 116 UpdateHistograms(); |
| 118 } | 117 } |
| 119 | 118 |
| 120 void SpdyStream::SetDelegate(Delegate* delegate) { | 119 void SpdyStream::SetDelegate(Delegate* delegate) { |
| 121 CHECK(!delegate_); | 120 CHECK(!delegate_); |
| 122 CHECK(delegate); | 121 CHECK(delegate); |
| 123 delegate_ = delegate; | 122 delegate_ = delegate; |
| 124 | 123 |
| 125 CHECK(io_state_ == STATE_IDLE || | 124 CHECK(io_state_ == STATE_IDLE || |
| 126 io_state_ == STATE_HALF_CLOSED_LOCAL_UNCLAIMED); | 125 io_state_ == STATE_HALF_CLOSED_LOCAL_UNCLAIMED); |
| 127 | 126 |
| 128 if (io_state_ == STATE_HALF_CLOSED_LOCAL_UNCLAIMED) { | 127 if (io_state_ == STATE_HALF_CLOSED_LOCAL_UNCLAIMED) { |
| 129 DCHECK_EQ(type_, SPDY_PUSH_STREAM); | 128 DCHECK_EQ(type_, SPDY_PUSH_STREAM); |
| 130 base::MessageLoop::current()->PostTask( | 129 base::MessageLoop::current()->PostTask( |
| 131 FROM_HERE, | 130 FROM_HERE, base::Bind(&SpdyStream::PushedStreamReplay, GetWeakPtr())); |
| 132 base::Bind(&SpdyStream::PushedStreamReplay, GetWeakPtr())); | |
| 133 } | 131 } |
| 134 } | 132 } |
| 135 | 133 |
| 136 void SpdyStream::PushedStreamReplay() { | 134 void SpdyStream::PushedStreamReplay() { |
| 137 DCHECK_EQ(type_, SPDY_PUSH_STREAM); | 135 DCHECK_EQ(type_, SPDY_PUSH_STREAM); |
| 138 DCHECK_NE(stream_id_, 0u); | 136 DCHECK_NE(stream_id_, 0u); |
| 139 CHECK_EQ(stream_id_ % 2, 0u); | 137 CHECK_EQ(stream_id_ % 2, 0u); |
| 140 | 138 |
| 141 CHECK_EQ(io_state_, STATE_HALF_CLOSED_LOCAL_UNCLAIMED); | 139 CHECK_EQ(io_state_, STATE_HALF_CLOSED_LOCAL_UNCLAIMED); |
| 142 io_state_ = STATE_HALF_CLOSED_LOCAL; | 140 io_state_ = STATE_HALF_CLOSED_LOCAL; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 break; | 188 break; |
| 191 } | 189 } |
| 192 } | 190 } |
| 193 } | 191 } |
| 194 | 192 |
| 195 scoped_ptr<SpdyFrame> SpdyStream::ProduceSynStreamFrame() { | 193 scoped_ptr<SpdyFrame> SpdyStream::ProduceSynStreamFrame() { |
| 196 CHECK_EQ(io_state_, STATE_IDLE); | 194 CHECK_EQ(io_state_, STATE_IDLE); |
| 197 CHECK(request_headers_); | 195 CHECK(request_headers_); |
| 198 CHECK_GT(stream_id_, 0u); | 196 CHECK_GT(stream_id_, 0u); |
| 199 | 197 |
| 200 SpdyControlFlags flags = | 198 SpdyControlFlags flags = (pending_send_status_ == NO_MORE_DATA_TO_SEND) |
| 201 (pending_send_status_ == NO_MORE_DATA_TO_SEND) ? | 199 ? CONTROL_FLAG_FIN |
| 202 CONTROL_FLAG_FIN : CONTROL_FLAG_NONE; | 200 : CONTROL_FLAG_NONE; |
| 203 scoped_ptr<SpdyFrame> frame(session_->CreateSynStream( | 201 scoped_ptr<SpdyFrame> frame(session_->CreateSynStream( |
| 204 stream_id_, priority_, flags, *request_headers_)); | 202 stream_id_, priority_, flags, *request_headers_)); |
| 205 send_time_ = base::TimeTicks::Now(); | 203 send_time_ = base::TimeTicks::Now(); |
| 206 return frame.Pass(); | 204 return frame.Pass(); |
| 207 } | 205 } |
| 208 | 206 |
| 209 void SpdyStream::DetachDelegate() { | 207 void SpdyStream::DetachDelegate() { |
| 210 DCHECK(!IsClosed()); | 208 DCHECK(!IsClosed()); |
| 211 delegate_ = NULL; | 209 delegate_ = NULL; |
| 212 Cancel(); | 210 Cancel(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 // Ignore late WINDOW_UPDATEs. | 252 // Ignore late WINDOW_UPDATEs. |
| 255 if (IsClosed()) | 253 if (IsClosed()) |
| 256 return; | 254 return; |
| 257 | 255 |
| 258 if (send_window_size_ > 0) { | 256 if (send_window_size_ > 0) { |
| 259 // Check for overflow. | 257 // Check for overflow. |
| 260 int32 max_delta_window_size = kint32max - send_window_size_; | 258 int32 max_delta_window_size = kint32max - send_window_size_; |
| 261 if (delta_window_size > max_delta_window_size) { | 259 if (delta_window_size > max_delta_window_size) { |
| 262 std::string desc = base::StringPrintf( | 260 std::string desc = base::StringPrintf( |
| 263 "Received WINDOW_UPDATE [delta: %d] for stream %d overflows " | 261 "Received WINDOW_UPDATE [delta: %d] for stream %d overflows " |
| 264 "send_window_size_ [current: %d]", delta_window_size, stream_id_, | 262 "send_window_size_ [current: %d]", |
| 263 delta_window_size, |
| 264 stream_id_, |
| 265 send_window_size_); | 265 send_window_size_); |
| 266 session_->ResetStream(stream_id_, RST_STREAM_FLOW_CONTROL_ERROR, desc); | 266 session_->ResetStream(stream_id_, RST_STREAM_FLOW_CONTROL_ERROR, desc); |
| 267 return; | 267 return; |
| 268 } | 268 } |
| 269 } | 269 } |
| 270 | 270 |
| 271 send_window_size_ += delta_window_size; | 271 send_window_size_ += delta_window_size; |
| 272 | 272 |
| 273 net_log_.AddEvent( | 273 net_log_.AddEvent(NetLog::TYPE_SPDY_STREAM_UPDATE_SEND_WINDOW, |
| 274 NetLog::TYPE_SPDY_STREAM_UPDATE_SEND_WINDOW, | 274 base::Bind(&NetLogSpdyStreamWindowUpdateCallback, |
| 275 base::Bind(&NetLogSpdyStreamWindowUpdateCallback, | 275 stream_id_, |
| 276 stream_id_, delta_window_size, send_window_size_)); | 276 delta_window_size, |
| 277 send_window_size_)); |
| 277 | 278 |
| 278 PossiblyResumeIfSendStalled(); | 279 PossiblyResumeIfSendStalled(); |
| 279 } | 280 } |
| 280 | 281 |
| 281 void SpdyStream::DecreaseSendWindowSize(int32 delta_window_size) { | 282 void SpdyStream::DecreaseSendWindowSize(int32 delta_window_size) { |
| 282 DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM); | 283 DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM); |
| 283 | 284 |
| 284 if (IsClosed()) | 285 if (IsClosed()) |
| 285 return; | 286 return; |
| 286 | 287 |
| 287 // We only call this method when sending a frame. Therefore, | 288 // We only call this method when sending a frame. Therefore, |
| 288 // |delta_window_size| should be within the valid frame size range. | 289 // |delta_window_size| should be within the valid frame size range. |
| 289 DCHECK_GE(delta_window_size, 1); | 290 DCHECK_GE(delta_window_size, 1); |
| 290 DCHECK_LE(delta_window_size, kMaxSpdyFrameChunkSize); | 291 DCHECK_LE(delta_window_size, kMaxSpdyFrameChunkSize); |
| 291 | 292 |
| 292 // |send_window_size_| should have been at least |delta_window_size| for | 293 // |send_window_size_| should have been at least |delta_window_size| for |
| 293 // this call to happen. | 294 // this call to happen. |
| 294 DCHECK_GE(send_window_size_, delta_window_size); | 295 DCHECK_GE(send_window_size_, delta_window_size); |
| 295 | 296 |
| 296 send_window_size_ -= delta_window_size; | 297 send_window_size_ -= delta_window_size; |
| 297 | 298 |
| 298 net_log_.AddEvent( | 299 net_log_.AddEvent(NetLog::TYPE_SPDY_STREAM_UPDATE_SEND_WINDOW, |
| 299 NetLog::TYPE_SPDY_STREAM_UPDATE_SEND_WINDOW, | 300 base::Bind(&NetLogSpdyStreamWindowUpdateCallback, |
| 300 base::Bind(&NetLogSpdyStreamWindowUpdateCallback, | 301 stream_id_, |
| 301 stream_id_, -delta_window_size, send_window_size_)); | 302 -delta_window_size, |
| 303 send_window_size_)); |
| 302 } | 304 } |
| 303 | 305 |
| 304 void SpdyStream::OnReadBufferConsumed( | 306 void SpdyStream::OnReadBufferConsumed( |
| 305 size_t consume_size, | 307 size_t consume_size, |
| 306 SpdyBuffer::ConsumeSource consume_source) { | 308 SpdyBuffer::ConsumeSource consume_source) { |
| 307 DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM); | 309 DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM); |
| 308 DCHECK_GE(consume_size, 1u); | 310 DCHECK_GE(consume_size, 1u); |
| 309 DCHECK_LE(consume_size, static_cast<size_t>(kint32max)); | 311 DCHECK_LE(consume_size, static_cast<size_t>(kint32max)); |
| 310 IncreaseRecvWindowSize(static_cast<int32>(consume_size)); | 312 IncreaseRecvWindowSize(static_cast<int32>(consume_size)); |
| 311 } | 313 } |
| 312 | 314 |
| 313 void SpdyStream::IncreaseRecvWindowSize(int32 delta_window_size) { | 315 void SpdyStream::IncreaseRecvWindowSize(int32 delta_window_size) { |
| 314 DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM); | 316 DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM); |
| 315 | 317 |
| 316 // 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 |
| 317 // already be inactive. | 319 // already be inactive. |
| 318 if (!session_->IsStreamActive(stream_id_)) | 320 if (!session_->IsStreamActive(stream_id_)) |
| 319 return; | 321 return; |
| 320 | 322 |
| 321 DCHECK_GE(unacked_recv_window_bytes_, 0); | 323 DCHECK_GE(unacked_recv_window_bytes_, 0); |
| 322 DCHECK_GE(recv_window_size_, unacked_recv_window_bytes_); | 324 DCHECK_GE(recv_window_size_, unacked_recv_window_bytes_); |
| 323 DCHECK_GE(delta_window_size, 1); | 325 DCHECK_GE(delta_window_size, 1); |
| 324 // Check for overflow. | 326 // Check for overflow. |
| 325 DCHECK_LE(delta_window_size, kint32max - recv_window_size_); | 327 DCHECK_LE(delta_window_size, kint32max - recv_window_size_); |
| 326 | 328 |
| 327 recv_window_size_ += delta_window_size; | 329 recv_window_size_ += delta_window_size; |
| 328 net_log_.AddEvent( | 330 net_log_.AddEvent(NetLog::TYPE_SPDY_STREAM_UPDATE_RECV_WINDOW, |
| 329 NetLog::TYPE_SPDY_STREAM_UPDATE_RECV_WINDOW, | 331 base::Bind(&NetLogSpdyStreamWindowUpdateCallback, |
| 330 base::Bind(&NetLogSpdyStreamWindowUpdateCallback, | 332 stream_id_, |
| 331 stream_id_, delta_window_size, recv_window_size_)); | 333 delta_window_size, |
| 334 recv_window_size_)); |
| 332 | 335 |
| 333 unacked_recv_window_bytes_ += delta_window_size; | 336 unacked_recv_window_bytes_ += delta_window_size; |
| 334 if (unacked_recv_window_bytes_ > | 337 if (unacked_recv_window_bytes_ > |
| 335 session_->stream_initial_recv_window_size() / 2) { | 338 session_->stream_initial_recv_window_size() / 2) { |
| 336 session_->SendStreamWindowUpdate( | 339 session_->SendStreamWindowUpdate( |
| 337 stream_id_, static_cast<uint32>(unacked_recv_window_bytes_)); | 340 stream_id_, static_cast<uint32>(unacked_recv_window_bytes_)); |
| 338 unacked_recv_window_bytes_ = 0; | 341 unacked_recv_window_bytes_ = 0; |
| 339 } | 342 } |
| 340 } | 343 } |
| 341 | 344 |
| 342 void SpdyStream::DecreaseRecvWindowSize(int32 delta_window_size) { | 345 void SpdyStream::DecreaseRecvWindowSize(int32 delta_window_size) { |
| 343 DCHECK(session_->IsStreamActive(stream_id_)); | 346 DCHECK(session_->IsStreamActive(stream_id_)); |
| 344 DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM); | 347 DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM); |
| 345 DCHECK_GE(delta_window_size, 1); | 348 DCHECK_GE(delta_window_size, 1); |
| 346 | 349 |
| 347 // Since we never decrease the initial receive window size, | 350 // Since we never decrease the initial receive window size, |
| 348 // |delta_window_size| should never cause |recv_window_size_| to go | 351 // |delta_window_size| should never cause |recv_window_size_| to go |
| 349 // negative. If we do, the receive window isn't being respected. | 352 // negative. If we do, the receive window isn't being respected. |
| 350 if (delta_window_size > recv_window_size_) { | 353 if (delta_window_size > recv_window_size_) { |
| 351 session_->ResetStream( | 354 session_->ResetStream( |
| 352 stream_id_, RST_STREAM_PROTOCOL_ERROR, | 355 stream_id_, |
| 356 RST_STREAM_PROTOCOL_ERROR, |
| 353 "delta_window_size is " + base::IntToString(delta_window_size) + | 357 "delta_window_size is " + base::IntToString(delta_window_size) + |
| 354 " in DecreaseRecvWindowSize, which is larger than the receive " + | 358 " in DecreaseRecvWindowSize, which is larger than the receive " + |
| 355 "window size of " + base::IntToString(recv_window_size_)); | 359 "window size of " + base::IntToString(recv_window_size_)); |
| 356 return; | 360 return; |
| 357 } | 361 } |
| 358 | 362 |
| 359 recv_window_size_ -= delta_window_size; | 363 recv_window_size_ -= delta_window_size; |
| 360 net_log_.AddEvent( | 364 net_log_.AddEvent(NetLog::TYPE_SPDY_STREAM_UPDATE_RECV_WINDOW, |
| 361 NetLog::TYPE_SPDY_STREAM_UPDATE_RECV_WINDOW, | 365 base::Bind(&NetLogSpdyStreamWindowUpdateCallback, |
| 362 base::Bind(&NetLogSpdyStreamWindowUpdateCallback, | 366 stream_id_, |
| 363 stream_id_, -delta_window_size, recv_window_size_)); | 367 -delta_window_size, |
| 368 recv_window_size_)); |
| 364 } | 369 } |
| 365 | 370 |
| 366 int SpdyStream::GetPeerAddress(IPEndPoint* address) const { | 371 int SpdyStream::GetPeerAddress(IPEndPoint* address) const { |
| 367 return session_->GetPeerAddress(address); | 372 return session_->GetPeerAddress(address); |
| 368 } | 373 } |
| 369 | 374 |
| 370 int SpdyStream::GetLocalAddress(IPEndPoint* address) const { | 375 int SpdyStream::GetLocalAddress(IPEndPoint* address) const { |
| 371 return session_->GetLocalAddress(address); | 376 return session_->GetLocalAddress(address); |
| 372 } | 377 } |
| 373 | 378 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 390 // SpdySession guarantees that this is called at most once. | 395 // SpdySession guarantees that this is called at most once. |
| 391 CHECK(response_headers_.empty()); | 396 CHECK(response_headers_.empty()); |
| 392 | 397 |
| 393 // Check to make sure that we don't receive the response headers | 398 // Check to make sure that we don't receive the response headers |
| 394 // before we're ready for it. | 399 // before we're ready for it. |
| 395 switch (type_) { | 400 switch (type_) { |
| 396 case SPDY_BIDIRECTIONAL_STREAM: | 401 case SPDY_BIDIRECTIONAL_STREAM: |
| 397 // For a bidirectional stream, we're ready for the response | 402 // For a bidirectional stream, we're ready for the response |
| 398 // headers once we've finished sending the request headers. | 403 // headers once we've finished sending the request headers. |
| 399 if (io_state_ == STATE_IDLE) { | 404 if (io_state_ == STATE_IDLE) { |
| 400 session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR, | 405 session_->ResetStream(stream_id_, |
| 406 RST_STREAM_PROTOCOL_ERROR, |
| 401 "Response received before request sent"); | 407 "Response received before request sent"); |
| 402 return ERR_SPDY_PROTOCOL_ERROR; | 408 return ERR_SPDY_PROTOCOL_ERROR; |
| 403 } | 409 } |
| 404 break; | 410 break; |
| 405 | 411 |
| 406 case SPDY_REQUEST_RESPONSE_STREAM: | 412 case SPDY_REQUEST_RESPONSE_STREAM: |
| 407 // For a request/response stream, we're ready for the response | 413 // For a request/response stream, we're ready for the response |
| 408 // headers once we've finished sending the request headers. | 414 // headers once we've finished sending the request headers. |
| 409 if (io_state_ == STATE_IDLE) { | 415 if (io_state_ == STATE_IDLE) { |
| 410 session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR, | 416 session_->ResetStream(stream_id_, |
| 417 RST_STREAM_PROTOCOL_ERROR, |
| 411 "Response received before request sent"); | 418 "Response received before request sent"); |
| 412 return ERR_SPDY_PROTOCOL_ERROR; | 419 return ERR_SPDY_PROTOCOL_ERROR; |
| 413 } | 420 } |
| 414 break; | 421 break; |
| 415 | 422 |
| 416 case SPDY_PUSH_STREAM: | 423 case SPDY_PUSH_STREAM: |
| 417 // Push streams transition to a locally half-closed state upon headers. | 424 // Push streams transition to a locally half-closed state upon headers. |
| 418 // We must continue to buffer data while waiting for a call to | 425 // We must continue to buffer data while waiting for a call to |
| 419 // SetDelegate() (which may not ever happen). | 426 // SetDelegate() (which may not ever happen). |
| 420 // TODO(jgraettinger): When PUSH_PROMISE is added, Handle RESERVED_REMOTE | 427 // TODO(jgraettinger): When PUSH_PROMISE is added, Handle RESERVED_REMOTE |
| (...skipping 10 matching lines...) Expand all Loading... |
| 431 | 438 |
| 432 response_time_ = response_time; | 439 response_time_ = response_time; |
| 433 recv_first_byte_time_ = recv_first_byte_time; | 440 recv_first_byte_time_ = recv_first_byte_time; |
| 434 return MergeWithResponseHeaders(initial_response_headers); | 441 return MergeWithResponseHeaders(initial_response_headers); |
| 435 } | 442 } |
| 436 | 443 |
| 437 int SpdyStream::OnAdditionalResponseHeadersReceived( | 444 int SpdyStream::OnAdditionalResponseHeadersReceived( |
| 438 const SpdyHeaderBlock& additional_response_headers) { | 445 const SpdyHeaderBlock& additional_response_headers) { |
| 439 if (type_ == SPDY_REQUEST_RESPONSE_STREAM) { | 446 if (type_ == SPDY_REQUEST_RESPONSE_STREAM) { |
| 440 session_->ResetStream( | 447 session_->ResetStream( |
| 441 stream_id_, RST_STREAM_PROTOCOL_ERROR, | 448 stream_id_, |
| 449 RST_STREAM_PROTOCOL_ERROR, |
| 442 "Additional headers received for request/response stream"); | 450 "Additional headers received for request/response stream"); |
| 443 return ERR_SPDY_PROTOCOL_ERROR; | 451 return ERR_SPDY_PROTOCOL_ERROR; |
| 444 } else if (type_ == SPDY_PUSH_STREAM && | 452 } else if (type_ == SPDY_PUSH_STREAM && |
| 445 response_headers_status_ == RESPONSE_HEADERS_ARE_COMPLETE) { | 453 response_headers_status_ == RESPONSE_HEADERS_ARE_COMPLETE) { |
| 446 session_->ResetStream( | 454 session_->ResetStream(stream_id_, |
| 447 stream_id_, RST_STREAM_PROTOCOL_ERROR, | 455 RST_STREAM_PROTOCOL_ERROR, |
| 448 "Additional headers received for push stream"); | 456 "Additional headers received for push stream"); |
| 449 return ERR_SPDY_PROTOCOL_ERROR; | 457 return ERR_SPDY_PROTOCOL_ERROR; |
| 450 } | 458 } |
| 451 return MergeWithResponseHeaders(additional_response_headers); | 459 return MergeWithResponseHeaders(additional_response_headers); |
| 452 } | 460 } |
| 453 | 461 |
| 454 void SpdyStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { | 462 void SpdyStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { |
| 455 DCHECK(session_->IsStreamActive(stream_id_)); | 463 DCHECK(session_->IsStreamActive(stream_id_)); |
| 456 | 464 |
| 457 // If we're still buffering data for a push stream, we will do the | 465 // If we're still buffering data for a push stream, we will do the |
| 458 // check for data received with incomplete headers in | 466 // check for data received with incomplete headers in |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 | 524 |
| 517 void SpdyStream::OnFrameWriteComplete(SpdyFrameType frame_type, | 525 void SpdyStream::OnFrameWriteComplete(SpdyFrameType frame_type, |
| 518 size_t frame_size) { | 526 size_t frame_size) { |
| 519 DCHECK_NE(type_, SPDY_PUSH_STREAM); | 527 DCHECK_NE(type_, SPDY_PUSH_STREAM); |
| 520 | 528 |
| 521 if (frame_size < session_->GetFrameMinimumSize() || | 529 if (frame_size < session_->GetFrameMinimumSize() || |
| 522 frame_size > session_->GetFrameMaximumSize()) { | 530 frame_size > session_->GetFrameMaximumSize()) { |
| 523 NOTREACHED(); | 531 NOTREACHED(); |
| 524 return; | 532 return; |
| 525 } | 533 } |
| 526 CHECK(frame_type == SYN_STREAM || | 534 CHECK(frame_type == SYN_STREAM || frame_type == DATA) << frame_type; |
| 527 frame_type == DATA) << frame_type; | |
| 528 | 535 |
| 529 int result = (frame_type == SYN_STREAM) ? | 536 int result = (frame_type == SYN_STREAM) ? OnRequestHeadersSent() |
| 530 OnRequestHeadersSent() : OnDataSent(frame_size); | 537 : OnDataSent(frame_size); |
| 531 if (result == ERR_IO_PENDING) { | 538 if (result == ERR_IO_PENDING) { |
| 532 // The write operation hasn't completed yet. | 539 // The write operation hasn't completed yet. |
| 533 return; | 540 return; |
| 534 } | 541 } |
| 535 | 542 |
| 536 if (pending_send_status_ == NO_MORE_DATA_TO_SEND) { | 543 if (pending_send_status_ == NO_MORE_DATA_TO_SEND) { |
| 537 if(io_state_ == STATE_OPEN) { | 544 if (io_state_ == STATE_OPEN) { |
| 538 io_state_ = STATE_HALF_CLOSED_LOCAL; | 545 io_state_ = STATE_HALF_CLOSED_LOCAL; |
| 539 } else if(io_state_ == STATE_HALF_CLOSED_REMOTE) { | 546 } else if (io_state_ == STATE_HALF_CLOSED_REMOTE) { |
| 540 io_state_ = STATE_CLOSED; | 547 io_state_ = STATE_CLOSED; |
| 541 } else { | 548 } else { |
| 542 NOTREACHED() << io_state_; | 549 NOTREACHED() << io_state_; |
| 543 } | 550 } |
| 544 } | 551 } |
| 545 // Notify delegate of write completion. Must not destroy |this|. | 552 // Notify delegate of write completion. Must not destroy |this|. |
| 546 CHECK(delegate_); | 553 CHECK(delegate_); |
| 547 { | 554 { |
| 548 base::WeakPtr<SpdyStream> weak_this = GetWeakPtr(); | 555 base::WeakPtr<SpdyStream> weak_this = GetWeakPtr(); |
| 549 write_handler_guard_ = true; | 556 write_handler_guard_ = true; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 564 | 571 |
| 565 int SpdyStream::OnRequestHeadersSent() { | 572 int SpdyStream::OnRequestHeadersSent() { |
| 566 CHECK_EQ(io_state_, STATE_IDLE); | 573 CHECK_EQ(io_state_, STATE_IDLE); |
| 567 CHECK_NE(stream_id_, 0u); | 574 CHECK_NE(stream_id_, 0u); |
| 568 | 575 |
| 569 io_state_ = STATE_OPEN; | 576 io_state_ = STATE_OPEN; |
| 570 return OK; | 577 return OK; |
| 571 } | 578 } |
| 572 | 579 |
| 573 int SpdyStream::OnDataSent(size_t frame_size) { | 580 int SpdyStream::OnDataSent(size_t frame_size) { |
| 574 CHECK(io_state_ == STATE_OPEN || | 581 CHECK(io_state_ == STATE_OPEN || io_state_ == STATE_HALF_CLOSED_REMOTE) |
| 575 io_state_ == STATE_HALF_CLOSED_REMOTE) << io_state_; | 582 << io_state_; |
| 576 | 583 |
| 577 size_t frame_payload_size = frame_size - session_->GetDataFrameMinimumSize(); | 584 size_t frame_payload_size = frame_size - session_->GetDataFrameMinimumSize(); |
| 578 | 585 |
| 579 CHECK_GE(frame_size, session_->GetDataFrameMinimumSize()); | 586 CHECK_GE(frame_size, session_->GetDataFrameMinimumSize()); |
| 580 CHECK_LE(frame_payload_size, session_->GetDataFrameMaximumPayload()); | 587 CHECK_LE(frame_payload_size, session_->GetDataFrameMaximumPayload()); |
| 581 | 588 |
| 582 send_bytes_ += frame_payload_size; | 589 send_bytes_ += frame_payload_size; |
| 583 | 590 |
| 584 // If more data is available to send, dispatch it and | 591 // If more data is available to send, dispatch it and |
| 585 // return that the write operation is still ongoing. | 592 // return that the write operation is still ongoing. |
| 586 pending_send_data_->DidConsume(frame_payload_size); | 593 pending_send_data_->DidConsume(frame_payload_size); |
| 587 if (pending_send_data_->BytesRemaining() > 0) { | 594 if (pending_send_data_->BytesRemaining() > 0) { |
| 588 QueueNextDataFrame(); | 595 QueueNextDataFrame(); |
| 589 return ERR_IO_PENDING; | 596 return ERR_IO_PENDING; |
| 590 } else { | 597 } else { |
| 591 pending_send_data_ = NULL; | 598 pending_send_data_ = NULL; |
| 592 return OK; | 599 return OK; |
| 593 } | 600 } |
| 594 } | 601 } |
| 595 | 602 |
| 596 SpdyMajorVersion SpdyStream::GetProtocolVersion() const { | 603 SpdyMajorVersion SpdyStream::GetProtocolVersion() const { |
| 597 return session_->GetProtocolVersion(); | 604 return session_->GetProtocolVersion(); |
| 598 } | 605 } |
| 599 | 606 |
| 600 void SpdyStream::LogStreamError(int status, const std::string& description) { | 607 void SpdyStream::LogStreamError(int status, const std::string& description) { |
| 601 net_log_.AddEvent(NetLog::TYPE_SPDY_STREAM_ERROR, | 608 net_log_.AddEvent( |
| 602 base::Bind(&NetLogSpdyStreamErrorCallback, | 609 NetLog::TYPE_SPDY_STREAM_ERROR, |
| 603 stream_id_, status, &description)); | 610 base::Bind( |
| 611 &NetLogSpdyStreamErrorCallback, stream_id_, status, &description)); |
| 604 } | 612 } |
| 605 | 613 |
| 606 void SpdyStream::OnClose(int status) { | 614 void SpdyStream::OnClose(int status) { |
| 607 // In most cases, the stream should already be CLOSED. The exception is when a | 615 // In most cases, the stream should already be CLOSED. The exception is when a |
| 608 // SpdySession is shutting down while the stream is in an intermediate state. | 616 // SpdySession is shutting down while the stream is in an intermediate state. |
| 609 io_state_ = STATE_CLOSED; | 617 io_state_ = STATE_CLOSED; |
| 610 response_status_ = status; | 618 response_status_ = status; |
| 611 Delegate* delegate = delegate_; | 619 Delegate* delegate = delegate_; |
| 612 delegate_ = NULL; | 620 delegate_ = NULL; |
| 613 if (delegate) | 621 if (delegate) |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 | 656 |
| 649 int SpdyStream::SendRequestHeaders(scoped_ptr<SpdyHeaderBlock> request_headers, | 657 int SpdyStream::SendRequestHeaders(scoped_ptr<SpdyHeaderBlock> request_headers, |
| 650 SpdySendStatus send_status) { | 658 SpdySendStatus send_status) { |
| 651 CHECK_NE(type_, SPDY_PUSH_STREAM); | 659 CHECK_NE(type_, SPDY_PUSH_STREAM); |
| 652 CHECK_EQ(pending_send_status_, MORE_DATA_TO_SEND); | 660 CHECK_EQ(pending_send_status_, MORE_DATA_TO_SEND); |
| 653 CHECK(!request_headers_); | 661 CHECK(!request_headers_); |
| 654 CHECK(!pending_send_data_.get()); | 662 CHECK(!pending_send_data_.get()); |
| 655 CHECK_EQ(io_state_, STATE_IDLE); | 663 CHECK_EQ(io_state_, STATE_IDLE); |
| 656 request_headers_ = request_headers.Pass(); | 664 request_headers_ = request_headers.Pass(); |
| 657 pending_send_status_ = send_status; | 665 pending_send_status_ = send_status; |
| 658 session_->EnqueueStreamWrite( | 666 session_->EnqueueStreamWrite(GetWeakPtr(), |
| 659 GetWeakPtr(), SYN_STREAM, | 667 SYN_STREAM, |
| 660 scoped_ptr<SpdyBufferProducer>( | 668 scoped_ptr<SpdyBufferProducer>( |
| 661 new SynStreamBufferProducer(GetWeakPtr()))); | 669 new SynStreamBufferProducer(GetWeakPtr()))); |
| 662 return ERR_IO_PENDING; | 670 return ERR_IO_PENDING; |
| 663 } | 671 } |
| 664 | 672 |
| 665 void SpdyStream::SendData(IOBuffer* data, | 673 void SpdyStream::SendData(IOBuffer* data, |
| 666 int length, | 674 int length, |
| 667 SpdySendStatus send_status) { | 675 SpdySendStatus send_status) { |
| 668 CHECK_NE(type_, SPDY_PUSH_STREAM); | 676 CHECK_NE(type_, SPDY_PUSH_STREAM); |
| 669 CHECK_EQ(pending_send_status_, MORE_DATA_TO_SEND); | 677 CHECK_EQ(pending_send_status_, MORE_DATA_TO_SEND); |
| 670 CHECK(io_state_ == STATE_OPEN || | 678 CHECK(io_state_ == STATE_OPEN || io_state_ == STATE_HALF_CLOSED_REMOTE) |
| 671 io_state_ == STATE_HALF_CLOSED_REMOTE) << io_state_; | 679 << io_state_; |
| 672 CHECK(!pending_send_data_.get()); | 680 CHECK(!pending_send_data_.get()); |
| 673 pending_send_data_ = new DrainableIOBuffer(data, length); | 681 pending_send_data_ = new DrainableIOBuffer(data, length); |
| 674 pending_send_status_ = send_status; | 682 pending_send_status_ = send_status; |
| 675 QueueNextDataFrame(); | 683 QueueNextDataFrame(); |
| 676 } | 684 } |
| 677 | 685 |
| 678 bool SpdyStream::GetSSLInfo(SSLInfo* ssl_info, | 686 bool SpdyStream::GetSSLInfo(SSLInfo* ssl_info, |
| 679 bool* was_npn_negotiated, | 687 bool* was_npn_negotiated, |
| 680 NextProto* protocol_negotiated) { | 688 NextProto* protocol_negotiated) { |
| 681 return session_->GetSSLInfo( | 689 return session_->GetSSLInfo( |
| 682 ssl_info, was_npn_negotiated, protocol_negotiated); | 690 ssl_info, was_npn_negotiated, protocol_negotiated); |
| 683 } | 691 } |
| 684 | 692 |
| 685 bool SpdyStream::GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) { | 693 bool SpdyStream::GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) { |
| 686 return session_->GetSSLCertRequestInfo(cert_request_info); | 694 return session_->GetSSLCertRequestInfo(cert_request_info); |
| 687 } | 695 } |
| 688 | 696 |
| 689 void SpdyStream::PossiblyResumeIfSendStalled() { | 697 void SpdyStream::PossiblyResumeIfSendStalled() { |
| 690 if (IsLocallyClosed()) { | 698 if (IsLocallyClosed()) { |
| 691 return; | 699 return; |
| 692 } | 700 } |
| 693 if (send_stalled_by_flow_control_ && !session_->IsSendStalled() && | 701 if (send_stalled_by_flow_control_ && !session_->IsSendStalled() && |
| 694 send_window_size_ > 0) { | 702 send_window_size_ > 0) { |
| 695 net_log_.AddEvent( | 703 net_log_.AddEvent(NetLog::TYPE_SPDY_STREAM_FLOW_CONTROL_UNSTALLED, |
| 696 NetLog::TYPE_SPDY_STREAM_FLOW_CONTROL_UNSTALLED, | 704 NetLog::IntegerCallback("stream_id", stream_id_)); |
| 697 NetLog::IntegerCallback("stream_id", stream_id_)); | |
| 698 send_stalled_by_flow_control_ = false; | 705 send_stalled_by_flow_control_ = false; |
| 699 QueueNextDataFrame(); | 706 QueueNextDataFrame(); |
| 700 } | 707 } |
| 701 } | 708 } |
| 702 | 709 |
| 703 bool SpdyStream::IsClosed() const { | 710 bool SpdyStream::IsClosed() const { |
| 704 return io_state_ == STATE_CLOSED; | 711 return io_state_ == STATE_CLOSED; |
| 705 } | 712 } |
| 706 | 713 |
| 707 bool SpdyStream::IsLocallyClosed() const { | 714 bool SpdyStream::IsLocallyClosed() const { |
| 708 return io_state_ == STATE_HALF_CLOSED_LOCAL_UNCLAIMED || | 715 return io_state_ == STATE_HALF_CLOSED_LOCAL_UNCLAIMED || |
| 709 io_state_ == STATE_HALF_CLOSED_LOCAL || | 716 io_state_ == STATE_HALF_CLOSED_LOCAL || io_state_ == STATE_CLOSED; |
| 710 io_state_ == STATE_CLOSED; | |
| 711 } | 717 } |
| 712 | 718 |
| 713 bool SpdyStream::IsIdle() const { | 719 bool SpdyStream::IsIdle() const { |
| 714 return io_state_ == STATE_IDLE; | 720 return io_state_ == STATE_IDLE; |
| 715 } | 721 } |
| 716 | 722 |
| 717 bool SpdyStream::IsOpen() const { | 723 bool SpdyStream::IsOpen() const { |
| 718 return io_state_ == STATE_OPEN; | 724 return io_state_ == STATE_OPEN; |
| 719 } | 725 } |
| 720 | 726 |
| 721 NextProto SpdyStream::GetProtocol() const { | 727 NextProto SpdyStream::GetProtocol() const { |
| 722 return session_->protocol(); | 728 return session_->protocol(); |
| 723 } | 729 } |
| 724 | 730 |
| 725 bool SpdyStream::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const { | 731 bool SpdyStream::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const { |
| 726 if (stream_id_ == 0) | 732 if (stream_id_ == 0) |
| 727 return false; | 733 return false; |
| 728 | 734 |
| 729 return session_->GetLoadTimingInfo(stream_id_, load_timing_info); | 735 return session_->GetLoadTimingInfo(stream_id_, load_timing_info); |
| 730 } | 736 } |
| 731 | 737 |
| 732 GURL SpdyStream::GetUrlFromHeaders() const { | 738 GURL SpdyStream::GetUrlFromHeaders() const { |
| 733 if (type_ != SPDY_PUSH_STREAM && !request_headers_) | 739 if (type_ != SPDY_PUSH_STREAM && !request_headers_) |
| 734 return GURL(); | 740 return GURL(); |
| 735 | 741 |
| 736 const SpdyHeaderBlock& headers = | 742 const SpdyHeaderBlock& headers = |
| 737 (type_ == SPDY_PUSH_STREAM) ? response_headers_ : *request_headers_; | 743 (type_ == SPDY_PUSH_STREAM) ? response_headers_ : *request_headers_; |
| 738 return GetUrlFromHeaderBlock(headers, GetProtocolVersion(), | 744 return GetUrlFromHeaderBlock( |
| 739 type_ == SPDY_PUSH_STREAM); | 745 headers, GetProtocolVersion(), type_ == SPDY_PUSH_STREAM); |
| 740 } | 746 } |
| 741 | 747 |
| 742 bool SpdyStream::HasUrlFromHeaders() const { | 748 bool SpdyStream::HasUrlFromHeaders() const { |
| 743 return !GetUrlFromHeaders().is_empty(); | 749 return !GetUrlFromHeaders().is_empty(); |
| 744 } | 750 } |
| 745 | 751 |
| 746 void SpdyStream::UpdateHistograms() { | 752 void SpdyStream::UpdateHistograms() { |
| 747 // We need at least the receive timers to be filled in, as otherwise | 753 // We need at least the receive timers to be filled in, as otherwise |
| 748 // metrics can be bogus. | 754 // metrics can be bogus. |
| 749 if (recv_first_byte_time_.is_null() || recv_last_byte_time_.is_null()) | 755 if (recv_first_byte_time_.is_null() || recv_last_byte_time_.is_null()) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 769 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime", | 775 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime", |
| 770 recv_last_byte_time_ - effective_send_time); | 776 recv_last_byte_time_ - effective_send_time); |
| 771 | 777 |
| 772 UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_); | 778 UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_); |
| 773 UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_); | 779 UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_); |
| 774 } | 780 } |
| 775 | 781 |
| 776 void SpdyStream::QueueNextDataFrame() { | 782 void SpdyStream::QueueNextDataFrame() { |
| 777 // Until the request has been completely sent, we cannot be sure | 783 // Until the request has been completely sent, we cannot be sure |
| 778 // that our stream_id is correct. | 784 // that our stream_id is correct. |
| 779 CHECK(io_state_ == STATE_OPEN || | 785 CHECK(io_state_ == STATE_OPEN || io_state_ == STATE_HALF_CLOSED_REMOTE) |
| 780 io_state_ == STATE_HALF_CLOSED_REMOTE) << io_state_; | 786 << io_state_; |
| 781 CHECK_GT(stream_id_, 0u); | 787 CHECK_GT(stream_id_, 0u); |
| 782 CHECK(pending_send_data_.get()); | 788 CHECK(pending_send_data_.get()); |
| 783 CHECK_GT(pending_send_data_->BytesRemaining(), 0); | 789 CHECK_GT(pending_send_data_->BytesRemaining(), 0); |
| 784 | 790 |
| 785 SpdyDataFlags flags = | 791 SpdyDataFlags flags = (pending_send_status_ == NO_MORE_DATA_TO_SEND) |
| 786 (pending_send_status_ == NO_MORE_DATA_TO_SEND) ? | 792 ? DATA_FLAG_FIN |
| 787 DATA_FLAG_FIN : DATA_FLAG_NONE; | 793 : DATA_FLAG_NONE; |
| 788 scoped_ptr<SpdyBuffer> data_buffer( | 794 scoped_ptr<SpdyBuffer> data_buffer( |
| 789 session_->CreateDataBuffer(stream_id_, | 795 session_->CreateDataBuffer(stream_id_, |
| 790 pending_send_data_.get(), | 796 pending_send_data_.get(), |
| 791 pending_send_data_->BytesRemaining(), | 797 pending_send_data_->BytesRemaining(), |
| 792 flags)); | 798 flags)); |
| 793 // We'll get called again by PossiblyResumeIfSendStalled(). | 799 // We'll get called again by PossiblyResumeIfSendStalled(). |
| 794 if (!data_buffer) | 800 if (!data_buffer) |
| 795 return; | 801 return; |
| 796 | 802 |
| 797 if (session_->flow_control_state() >= SpdySession::FLOW_CONTROL_STREAM) { | 803 if (session_->flow_control_state() >= SpdySession::FLOW_CONTROL_STREAM) { |
| 798 DCHECK_GE(data_buffer->GetRemainingSize(), | 804 DCHECK_GE(data_buffer->GetRemainingSize(), |
| 799 session_->GetDataFrameMinimumSize()); | 805 session_->GetDataFrameMinimumSize()); |
| 800 size_t payload_size = | 806 size_t payload_size = |
| 801 data_buffer->GetRemainingSize() - session_->GetDataFrameMinimumSize(); | 807 data_buffer->GetRemainingSize() - session_->GetDataFrameMinimumSize(); |
| 802 DCHECK_LE(payload_size, session_->GetDataFrameMaximumPayload()); | 808 DCHECK_LE(payload_size, session_->GetDataFrameMaximumPayload()); |
| 803 DecreaseSendWindowSize(static_cast<int32>(payload_size)); | 809 DecreaseSendWindowSize(static_cast<int32>(payload_size)); |
| 804 // This currently isn't strictly needed, since write frames are | 810 // This currently isn't strictly needed, since write frames are |
| 805 // discarded only if the stream is about to be closed. But have it | 811 // discarded only if the stream is about to be closed. But have it |
| 806 // here anyway just in case this changes. | 812 // here anyway just in case this changes. |
| 807 data_buffer->AddConsumeCallback( | 813 data_buffer->AddConsumeCallback(base::Bind( |
| 808 base::Bind(&SpdyStream::OnWriteBufferConsumed, | 814 &SpdyStream::OnWriteBufferConsumed, GetWeakPtr(), payload_size)); |
| 809 GetWeakPtr(), payload_size)); | |
| 810 } | 815 } |
| 811 | 816 |
| 812 session_->EnqueueStreamWrite( | 817 session_->EnqueueStreamWrite( |
| 813 GetWeakPtr(), DATA, | 818 GetWeakPtr(), |
| 819 DATA, |
| 814 scoped_ptr<SpdyBufferProducer>( | 820 scoped_ptr<SpdyBufferProducer>( |
| 815 new SimpleBufferProducer(data_buffer.Pass()))); | 821 new SimpleBufferProducer(data_buffer.Pass()))); |
| 816 } | 822 } |
| 817 | 823 |
| 818 int SpdyStream::MergeWithResponseHeaders( | 824 int SpdyStream::MergeWithResponseHeaders( |
| 819 const SpdyHeaderBlock& new_response_headers) { | 825 const SpdyHeaderBlock& new_response_headers) { |
| 820 if (new_response_headers.find("transfer-encoding") != | 826 if (new_response_headers.find("transfer-encoding") != |
| 821 new_response_headers.end()) { | 827 new_response_headers.end()) { |
| 822 session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR, | 828 session_->ResetStream(stream_id_, |
| 823 "Received transfer-encoding header"); | 829 RST_STREAM_PROTOCOL_ERROR, |
| 830 "Received transfer-encoding header"); |
| 824 return ERR_SPDY_PROTOCOL_ERROR; | 831 return ERR_SPDY_PROTOCOL_ERROR; |
| 825 } | 832 } |
| 826 | 833 |
| 827 for (SpdyHeaderBlock::const_iterator it = new_response_headers.begin(); | 834 for (SpdyHeaderBlock::const_iterator it = new_response_headers.begin(); |
| 828 it != new_response_headers.end(); ++it) { | 835 it != new_response_headers.end(); |
| 836 ++it) { |
| 829 // Disallow uppercase headers. | 837 // Disallow uppercase headers. |
| 830 if (ContainsUppercaseAscii(it->first)) { | 838 if (ContainsUppercaseAscii(it->first)) { |
| 831 session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR, | 839 session_->ResetStream(stream_id_, |
| 840 RST_STREAM_PROTOCOL_ERROR, |
| 832 "Upper case characters in header: " + it->first); | 841 "Upper case characters in header: " + it->first); |
| 833 return ERR_SPDY_PROTOCOL_ERROR; | 842 return ERR_SPDY_PROTOCOL_ERROR; |
| 834 } | 843 } |
| 835 | 844 |
| 836 SpdyHeaderBlock::iterator it2 = response_headers_.lower_bound(it->first); | 845 SpdyHeaderBlock::iterator it2 = response_headers_.lower_bound(it->first); |
| 837 // Disallow duplicate headers. This is just to be conservative. | 846 // Disallow duplicate headers. This is just to be conservative. |
| 838 if (it2 != response_headers_.end() && it2->first == it->first) { | 847 if (it2 != response_headers_.end() && it2->first == it->first) { |
| 839 session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR, | 848 session_->ResetStream(stream_id_, |
| 849 RST_STREAM_PROTOCOL_ERROR, |
| 840 "Duplicate header: " + it->first); | 850 "Duplicate header: " + it->first); |
| 841 return ERR_SPDY_PROTOCOL_ERROR; | 851 return ERR_SPDY_PROTOCOL_ERROR; |
| 842 } | 852 } |
| 843 | 853 |
| 844 response_headers_.insert(it2, *it); | 854 response_headers_.insert(it2, *it); |
| 845 } | 855 } |
| 846 | 856 |
| 847 // If delegate_ is not yet attached, we'll call | 857 // If delegate_ is not yet attached, we'll call |
| 848 // OnResponseHeadersUpdated() after the delegate gets attached to | 858 // OnResponseHeadersUpdated() after the delegate gets attached to |
| 849 // the stream. | 859 // the stream. |
| 850 if (delegate_) { | 860 if (delegate_) { |
| 851 // The call to OnResponseHeadersUpdated() below may delete |this|, | 861 // The call to OnResponseHeadersUpdated() below may delete |this|, |
| 852 // so use |weak_this| to detect that. | 862 // so use |weak_this| to detect that. |
| 853 base::WeakPtr<SpdyStream> weak_this = GetWeakPtr(); | 863 base::WeakPtr<SpdyStream> weak_this = GetWeakPtr(); |
| 854 | 864 |
| 855 SpdyResponseHeadersStatus status = | 865 SpdyResponseHeadersStatus status = |
| 856 delegate_->OnResponseHeadersUpdated(response_headers_); | 866 delegate_->OnResponseHeadersUpdated(response_headers_); |
| 857 if (status == RESPONSE_HEADERS_ARE_INCOMPLETE) { | 867 if (status == RESPONSE_HEADERS_ARE_INCOMPLETE) { |
| 858 // Since RESPONSE_HEADERS_ARE_INCOMPLETE was returned, we must not | 868 // Since RESPONSE_HEADERS_ARE_INCOMPLETE was returned, we must not |
| 859 // have been closed. | 869 // have been closed. |
| 860 CHECK(weak_this); | 870 CHECK(weak_this); |
| 861 // Incomplete headers are OK only for push streams. | 871 // Incomplete headers are OK only for push streams. |
| 862 if (type_ != SPDY_PUSH_STREAM) { | 872 if (type_ != SPDY_PUSH_STREAM) { |
| 863 session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR, | 873 session_->ResetStream( |
| 864 "Incomplete headers"); | 874 stream_id_, RST_STREAM_PROTOCOL_ERROR, "Incomplete headers"); |
| 865 return ERR_INCOMPLETE_SPDY_HEADERS; | 875 return ERR_INCOMPLETE_SPDY_HEADERS; |
| 866 } | 876 } |
| 867 } else if (weak_this) { | 877 } else if (weak_this) { |
| 868 response_headers_status_ = RESPONSE_HEADERS_ARE_COMPLETE; | 878 response_headers_status_ = RESPONSE_HEADERS_ARE_COMPLETE; |
| 869 } | 879 } |
| 870 } | 880 } |
| 871 | 881 |
| 872 return OK; | 882 return OK; |
| 873 } | 883 } |
| 874 | 884 |
| 875 #define STATE_CASE(s) \ | 885 #define STATE_CASE(s) \ |
| 876 case s: \ | 886 case s: \ |
| 877 description = base::StringPrintf("%s (0x%08X)", #s, s); \ | 887 description = base::StringPrintf("%s (0x%08X)", #s, s); \ |
| 878 break | 888 break |
| 879 | 889 |
| 880 std::string SpdyStream::DescribeState(State state) { | 890 std::string SpdyStream::DescribeState(State state) { |
| 881 std::string description; | 891 std::string description; |
| 882 switch (state) { | 892 switch (state) { |
| 883 STATE_CASE(STATE_IDLE); | 893 STATE_CASE(STATE_IDLE); |
| 884 STATE_CASE(STATE_OPEN); | 894 STATE_CASE(STATE_OPEN); |
| 885 STATE_CASE(STATE_HALF_CLOSED_LOCAL_UNCLAIMED); | 895 STATE_CASE(STATE_HALF_CLOSED_LOCAL_UNCLAIMED); |
| 886 STATE_CASE(STATE_HALF_CLOSED_LOCAL); | 896 STATE_CASE(STATE_HALF_CLOSED_LOCAL); |
| 887 STATE_CASE(STATE_CLOSED); | 897 STATE_CASE(STATE_CLOSED); |
| 888 default: | 898 default: |
| 889 description = base::StringPrintf("Unknown state 0x%08X (%u)", state, | 899 description = |
| 890 state); | 900 base::StringPrintf("Unknown state 0x%08X (%u)", state, state); |
| 891 break; | 901 break; |
| 892 } | 902 } |
| 893 return description; | 903 return description; |
| 894 } | 904 } |
| 895 | 905 |
| 896 #undef STATE_CASE | 906 #undef STATE_CASE |
| 897 | 907 |
| 898 } // namespace net | 908 } // namespace net |
| OLD | NEW |