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