OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/logging.h" | 7 #include "base/logging.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/values.h" | 9 #include "base/values.h" |
10 #include "net/spdy/spdy_session.h" | 10 #include "net/spdy/spdy_session.h" |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 } else { | 105 } else { |
106 delegate_->OnDataReceived(NULL, 0); | 106 delegate_->OnDataReceived(NULL, 0); |
107 session_->CloseStream(stream_id_, net::OK); | 107 session_->CloseStream(stream_id_, net::OK); |
108 // Note: |this| may be deleted after calling CloseStream. | 108 // Note: |this| may be deleted after calling CloseStream. |
109 DCHECK_EQ(buffers.size() - 1, i); | 109 DCHECK_EQ(buffers.size() - 1, i); |
110 } | 110 } |
111 } | 111 } |
112 } | 112 } |
113 | 113 |
114 void SpdyStream::DetachDelegate() { | 114 void SpdyStream::DetachDelegate() { |
| 115 if (delegate_) |
| 116 delegate_->set_chunk_callback(NULL); |
115 delegate_ = NULL; | 117 delegate_ = NULL; |
116 if (!closed()) | 118 if (!closed()) |
117 Cancel(); | 119 Cancel(); |
118 } | 120 } |
119 | 121 |
120 const linked_ptr<spdy::SpdyHeaderBlock>& SpdyStream::spdy_headers() const { | 122 const linked_ptr<spdy::SpdyHeaderBlock>& SpdyStream::spdy_headers() const { |
121 return request_; | 123 return request_; |
122 } | 124 } |
123 | 125 |
124 void SpdyStream::set_spdy_headers( | 126 void SpdyStream::set_spdy_headers( |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 | 343 |
342 // This function is only called when an entire frame is written. | 344 // This function is only called when an entire frame is written. |
343 void SpdyStream::OnWriteComplete(int bytes) { | 345 void SpdyStream::OnWriteComplete(int bytes) { |
344 DCHECK_LE(0, bytes); | 346 DCHECK_LE(0, bytes); |
345 send_bytes_ += bytes; | 347 send_bytes_ += bytes; |
346 if (cancelled() || closed()) | 348 if (cancelled() || closed()) |
347 return; | 349 return; |
348 DoLoop(bytes); | 350 DoLoop(bytes); |
349 } | 351 } |
350 | 352 |
| 353 void SpdyStream::OnChunkAvailable() { |
| 354 DCHECK(io_state_ == STATE_SEND_HEADERS || io_state_ == STATE_SEND_BODY || |
| 355 io_state_ == STATE_SEND_BODY_COMPLETE); |
| 356 if (io_state_ == STATE_SEND_BODY) |
| 357 OnWriteComplete(0); |
| 358 } |
| 359 |
351 void SpdyStream::OnClose(int status) { | 360 void SpdyStream::OnClose(int status) { |
352 io_state_ = STATE_DONE; | 361 io_state_ = STATE_DONE; |
353 response_status_ = status; | 362 response_status_ = status; |
354 Delegate* delegate = delegate_; | 363 Delegate* delegate = delegate_; |
355 delegate_ = NULL; | 364 delegate_ = NULL; |
356 if (delegate) | 365 if (delegate) { |
| 366 delegate->set_chunk_callback(NULL); |
357 delegate->OnClose(status); | 367 delegate->OnClose(status); |
| 368 } |
358 } | 369 } |
359 | 370 |
360 void SpdyStream::Cancel() { | 371 void SpdyStream::Cancel() { |
361 if (cancelled()) | 372 if (cancelled()) |
362 return; | 373 return; |
363 | 374 |
364 cancelled_ = true; | 375 cancelled_ = true; |
365 if (session_->IsStreamActive(stream_id_)) | 376 if (session_->IsStreamActive(stream_id_)) |
366 session_->ResetStream(stream_id_, spdy::CANCEL); | 377 session_->ResetStream(stream_id_, spdy::CANCEL); |
367 } | 378 } |
368 | 379 |
369 int SpdyStream::SendRequest(bool has_upload_data) { | 380 int SpdyStream::SendRequest(bool has_upload_data) { |
| 381 if (delegate_) |
| 382 delegate_->set_chunk_callback(this); |
| 383 |
370 // Pushed streams do not send any data, and should always be in STATE_OPEN or | 384 // Pushed streams do not send any data, and should always be in STATE_OPEN or |
371 // STATE_DONE. However, we still want to return IO_PENDING to mimic non-push | 385 // STATE_DONE. However, we still want to return IO_PENDING to mimic non-push |
372 // behavior. | 386 // behavior. |
373 has_upload_data_ = has_upload_data; | 387 has_upload_data_ = has_upload_data; |
374 if (pushed_) { | 388 if (pushed_) { |
375 send_time_ = base::TimeTicks::Now(); | 389 send_time_ = base::TimeTicks::Now(); |
376 DCHECK(!has_upload_data_); | 390 DCHECK(!has_upload_data_); |
377 DCHECK(response_received()); | 391 DCHECK(response_received()); |
378 return ERR_IO_PENDING; | 392 return ERR_IO_PENDING; |
379 } | 393 } |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 io_state_ = STATE_SEND_BODY_COMPLETE; | 552 io_state_ = STATE_SEND_BODY_COMPLETE; |
539 if (!delegate_) | 553 if (!delegate_) |
540 return ERR_UNEXPECTED; | 554 return ERR_UNEXPECTED; |
541 return delegate_->OnSendBody(); | 555 return delegate_->OnSendBody(); |
542 } | 556 } |
543 | 557 |
544 int SpdyStream::DoSendBodyComplete(int result) { | 558 int SpdyStream::DoSendBodyComplete(int result) { |
545 if (result < 0) | 559 if (result < 0) |
546 return result; | 560 return result; |
547 | 561 |
548 CHECK_NE(result, 0); | |
549 | |
550 if (!delegate_) | 562 if (!delegate_) |
551 return ERR_UNEXPECTED; | 563 return ERR_UNEXPECTED; |
552 | 564 |
553 if (!delegate_->OnSendBodyComplete(result)) | 565 bool eof = false; |
| 566 result = delegate_->OnSendBodyComplete(result, &eof); |
| 567 if (!eof) |
554 io_state_ = STATE_SEND_BODY; | 568 io_state_ = STATE_SEND_BODY; |
555 else | 569 else |
556 io_state_ = STATE_WAITING_FOR_RESPONSE; | 570 io_state_ = STATE_WAITING_FOR_RESPONSE; |
557 | 571 |
558 return OK; | 572 return result; |
559 } | 573 } |
560 | 574 |
561 int SpdyStream::DoOpen(int result) { | 575 int SpdyStream::DoOpen(int result) { |
562 if (delegate_) | 576 if (delegate_) |
563 delegate_->OnDataSent(result); | 577 delegate_->OnDataSent(result); |
564 io_state_ = STATE_OPEN; | 578 io_state_ = STATE_OPEN; |
565 return result; | 579 return result; |
566 } | 580 } |
567 | 581 |
568 void SpdyStream::UpdateHistograms() { | 582 void SpdyStream::UpdateHistograms() { |
569 // We need all timers to be filled in, otherwise metrics can be bogus. | 583 // We need all timers to be filled in, otherwise metrics can be bogus. |
570 if (send_time_.is_null() || recv_first_byte_time_.is_null() || | 584 if (send_time_.is_null() || recv_first_byte_time_.is_null() || |
571 recv_last_byte_time_.is_null()) | 585 recv_last_byte_time_.is_null()) |
572 return; | 586 return; |
573 | 587 |
574 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTimeToFirstByte", | 588 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTimeToFirstByte", |
575 recv_first_byte_time_ - send_time_); | 589 recv_first_byte_time_ - send_time_); |
576 UMA_HISTOGRAM_TIMES("Net.SpdyStreamDownloadTime", | 590 UMA_HISTOGRAM_TIMES("Net.SpdyStreamDownloadTime", |
577 recv_last_byte_time_ - recv_first_byte_time_); | 591 recv_last_byte_time_ - recv_first_byte_time_); |
578 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime", | 592 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime", |
579 recv_last_byte_time_ - send_time_); | 593 recv_last_byte_time_ - send_time_); |
580 | 594 |
581 UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_); | 595 UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_); |
582 UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_); | 596 UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_); |
583 } | 597 } |
584 | 598 |
585 } // namespace net | 599 } // namespace net |
OLD | NEW |