Chromium Code Reviews| 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_http_stream.h" | 5 #include "net/spdy/spdy_http_stream.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <list> | 8 #include <list> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 128 IOBuffer* buf, int buf_len, const CompletionCallback& callback) { | 128 IOBuffer* buf, int buf_len, const CompletionCallback& callback) { |
| 129 if (stream_) { | 129 if (stream_) { |
| 130 CHECK(stream_->is_idle()); | 130 CHECK(stream_->is_idle()); |
| 131 CHECK(!stream_->closed()); | 131 CHECK(!stream_->closed()); |
| 132 } | 132 } |
| 133 CHECK(buf); | 133 CHECK(buf); |
| 134 CHECK(buf_len); | 134 CHECK(buf_len); |
| 135 CHECK(!callback.is_null()); | 135 CHECK(!callback.is_null()); |
| 136 | 136 |
| 137 // If we have data buffered, complete the IO immediately. | 137 // If we have data buffered, complete the IO immediately. |
| 138 if (!response_body_.empty()) { | 138 if (!response_body_queue_.IsEmpty()) { |
| 139 int bytes_read = 0; | 139 size_t bytes_consumed = response_body_queue_.Dequeue(buf->data(), buf_len); |
|
Ryan Hamilton
2013/04/16 18:44:25
nice cleanup
| |
| 140 while (!response_body_.empty() && buf_len > 0) { | |
| 141 scoped_refptr<IOBufferWithSize> data = response_body_.front(); | |
| 142 const int bytes_to_copy = std::min(buf_len, data->size()); | |
| 143 memcpy(&(buf->data()[bytes_read]), data->data(), bytes_to_copy); | |
| 144 buf_len -= bytes_to_copy; | |
| 145 if (bytes_to_copy == data->size()) { | |
| 146 response_body_.pop_front(); | |
| 147 } else { | |
| 148 const int bytes_remaining = data->size() - bytes_to_copy; | |
| 149 IOBufferWithSize* new_buffer = new IOBufferWithSize(bytes_remaining); | |
| 150 memcpy(new_buffer->data(), &(data->data()[bytes_to_copy]), | |
| 151 bytes_remaining); | |
| 152 response_body_.pop_front(); | |
| 153 response_body_.push_front(make_scoped_refptr(new_buffer)); | |
| 154 } | |
| 155 bytes_read += bytes_to_copy; | |
| 156 } | |
| 157 if (stream_) | 140 if (stream_) |
| 158 stream_->IncreaseRecvWindowSize(bytes_read); | 141 stream_->IncreaseRecvWindowSize(bytes_consumed); |
| 159 return bytes_read; | 142 return bytes_consumed; |
| 160 } else if (stream_closed_) { | 143 } else if (stream_closed_) { |
| 161 return closed_stream_status_; | 144 return closed_stream_status_; |
| 162 } | 145 } |
| 163 | 146 |
| 164 CHECK(callback_.is_null()); | 147 CHECK(callback_.is_null()); |
| 165 CHECK(!user_buffer_); | 148 CHECK(!user_buffer_); |
| 166 CHECK_EQ(0, user_buffer_len_); | 149 CHECK_EQ(0, user_buffer_len_); |
| 167 | 150 |
| 168 callback_ = callback; | 151 callback_ = callback; |
| 169 user_buffer_ = buf; | 152 user_buffer_ = buf; |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 427 DoCallback(status); | 410 DoCallback(status); |
| 428 | 411 |
| 429 return status; | 412 return status; |
| 430 } | 413 } |
| 431 | 414 |
| 432 void SpdyHttpStream::OnHeadersSent() { | 415 void SpdyHttpStream::OnHeadersSent() { |
| 433 // For HTTP streams, no HEADERS frame is sent from the client. | 416 // For HTTP streams, no HEADERS frame is sent from the client. |
| 434 NOTREACHED(); | 417 NOTREACHED(); |
| 435 } | 418 } |
| 436 | 419 |
| 437 int SpdyHttpStream::OnDataReceived(const char* data, int length) { | 420 int SpdyHttpStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { |
| 438 // SpdyStream won't call us with data if the header block didn't contain a | 421 // SpdyStream won't call us with data if the header block didn't contain a |
| 439 // valid set of headers. So we don't expect to not have headers received | 422 // valid set of headers. So we don't expect to not have headers received |
| 440 // here. | 423 // here. |
| 441 if (!response_headers_received_) | 424 if (!response_headers_received_) |
| 442 return ERR_INCOMPLETE_SPDY_HEADERS; | 425 return ERR_INCOMPLETE_SPDY_HEADERS; |
| 443 | 426 |
| 444 // Note that data may be received for a SpdyStream prior to the user calling | 427 // Note that data may be received for a SpdyStream prior to the user calling |
| 445 // ReadResponseBody(), therefore user_buffer_ may be NULL. This may often | 428 // ReadResponseBody(), therefore user_buffer_ may be NULL. This may often |
| 446 // happen for server initiated streams. | 429 // happen for server initiated streams. |
| 447 DCHECK(stream_.get()); | 430 DCHECK(stream_.get()); |
| 448 DCHECK(!stream_->closed() || stream_->pushed()); | 431 DCHECK(!stream_->closed() || stream_->pushed()); |
| 449 if (length > 0) { | 432 if (buffer) { |
| 450 // Save the received data. | 433 response_body_queue_.Enqueue(buffer.Pass()); |
| 451 IOBufferWithSize* io_buffer = new IOBufferWithSize(length); | |
| 452 memcpy(io_buffer->data(), data, length); | |
| 453 response_body_.push_back(make_scoped_refptr(io_buffer)); | |
| 454 | 434 |
| 455 if (user_buffer_) { | 435 if (user_buffer_) { |
| 456 // Handing small chunks of data to the caller creates measurable overhead. | 436 // Handing small chunks of data to the caller creates measurable overhead. |
| 457 // We buffer data in short time-spans and send a single read notification. | 437 // We buffer data in short time-spans and send a single read notification. |
| 458 ScheduleBufferedReadCallback(); | 438 ScheduleBufferedReadCallback(); |
| 459 } | 439 } |
| 460 } | 440 } |
| 461 return OK; | 441 return OK; |
| 462 } | 442 } |
| 463 | 443 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 502 kBufferTime); | 482 kBufferTime); |
| 503 } | 483 } |
| 504 | 484 |
| 505 // Checks to see if we should wait for more buffered data before notifying | 485 // Checks to see if we should wait for more buffered data before notifying |
| 506 // the caller. Returns true if we should wait, false otherwise. | 486 // the caller. Returns true if we should wait, false otherwise. |
| 507 bool SpdyHttpStream::ShouldWaitForMoreBufferedData() const { | 487 bool SpdyHttpStream::ShouldWaitForMoreBufferedData() const { |
| 508 // If the response is complete, there is no point in waiting. | 488 // If the response is complete, there is no point in waiting. |
| 509 if (stream_closed_) | 489 if (stream_closed_) |
| 510 return false; | 490 return false; |
| 511 | 491 |
| 512 int bytes_buffered = 0; | 492 DCHECK_GT(user_buffer_len_, 0); |
| 513 std::list<scoped_refptr<IOBufferWithSize> >::const_iterator it; | 493 return response_body_queue_.GetTotalSize() < |
| 514 for (it = response_body_.begin(); | 494 static_cast<size_t>(user_buffer_len_); |
| 515 it != response_body_.end() && bytes_buffered < user_buffer_len_; | |
| 516 ++it) | |
| 517 bytes_buffered += (*it)->size(); | |
| 518 | |
| 519 return bytes_buffered < user_buffer_len_; | |
| 520 } | 495 } |
| 521 | 496 |
| 522 bool SpdyHttpStream::DoBufferedReadCallback() { | 497 bool SpdyHttpStream::DoBufferedReadCallback() { |
| 523 buffered_read_callback_pending_ = false; | 498 buffered_read_callback_pending_ = false; |
| 524 | 499 |
| 525 // If the transaction is cancelled or errored out, we don't need to complete | 500 // If the transaction is cancelled or errored out, we don't need to complete |
| 526 // the read. | 501 // the read. |
| 527 if (!stream_ && !stream_closed_) | 502 if (!stream_ && !stream_closed_) |
| 528 return false; | 503 return false; |
| 529 | 504 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 593 bool SpdyHttpStream::IsSpdyHttpStream() const { | 568 bool SpdyHttpStream::IsSpdyHttpStream() const { |
| 594 return true; | 569 return true; |
| 595 } | 570 } |
| 596 | 571 |
| 597 void SpdyHttpStream::Drain(HttpNetworkSession* session) { | 572 void SpdyHttpStream::Drain(HttpNetworkSession* session) { |
| 598 Close(false); | 573 Close(false); |
| 599 delete this; | 574 delete this; |
| 600 } | 575 } |
| 601 | 576 |
| 602 } // namespace net | 577 } // namespace net |
| OLD | NEW |