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 |