diff options
author | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-17 10:16:33 +0000 |
---|---|---|
committer | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-17 10:16:33 +0000 |
commit | ba3443695a61a148ed76c8701f0def16919f904c (patch) | |
tree | 1f48590dc5d970963558d1e6f9435d39242e2044 | |
parent | 9dc5e0f60d009bd665aaac4f0ccbc02af6fffa25 (diff) | |
download | chromium_src-ba3443695a61a148ed76c8701f0def16919f904c.zip chromium_src-ba3443695a61a148ed76c8701f0def16919f904c.tar.gz chromium_src-ba3443695a61a148ed76c8701f0def16919f904c.tar.bz2 |
Revert 194560 "[SPDY] Replace SpdyIOBuffer with new SpdyBuffer c..."
> [SPDY] Replace SpdyIOBuffer with new SpdyBuffer class
>
> Use SpdyBuffer for both SPDY reads and writes. A future
> CL will add hooks to SpdyBuffer so that we keep track of
> flow control windows properly.
>
> Replace SpdyFrameProducer with SpdyBufferProducer.
>
> Also introduce new SpdyReadQueue class for delegates
> of SpdyStream to use.
>
> BUG=176592
>
> Review URL: https://codereview.chromium.org/13990005
TBR=akalin@chromium.org
Review URL: https://codereview.chromium.org/13996009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@194562 0039d316-1c4b-4281-b951-d872f2087c98
34 files changed, 422 insertions, 775 deletions
diff --git a/net/net.gyp b/net/net.gyp index 3ba59da..bb7e584 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -859,16 +859,14 @@ 'spdy/buffered_spdy_framer.cc', 'spdy/buffered_spdy_framer.h', 'spdy/spdy_bitmasks.h', - 'spdy/spdy_buffer.cc', - 'spdy/spdy_buffer.h', - 'spdy/spdy_buffer_producer.cc', - 'spdy/spdy_buffer_producer.h', 'spdy/spdy_credential_builder.cc', 'spdy/spdy_credential_builder.h', 'spdy/spdy_credential_state.cc', 'spdy/spdy_credential_state.h', 'spdy/spdy_frame_builder.cc', 'spdy/spdy_frame_builder.h', + 'spdy/spdy_frame_producer.cc', + 'spdy/spdy_frame_producer.h', 'spdy/spdy_frame_reader.cc', 'spdy/spdy_frame_reader.h', 'spdy/spdy_framer.cc', @@ -879,13 +877,13 @@ 'spdy/spdy_http_stream.h', 'spdy/spdy_http_utils.cc', 'spdy/spdy_http_utils.h', + 'spdy/spdy_io_buffer.cc', + 'spdy/spdy_io_buffer.h', 'spdy/spdy_priority_forest.h', 'spdy/spdy_protocol.cc', 'spdy/spdy_protocol.h', 'spdy/spdy_proxy_client_socket.cc', 'spdy/spdy_proxy_client_socket.h', - 'spdy/spdy_read_queue.cc', - 'spdy/spdy_read_queue.h', 'spdy/spdy_session.cc', 'spdy/spdy_session.h', 'spdy/spdy_session_pool.cc', @@ -1681,7 +1679,6 @@ 'spdy/buffered_spdy_framer_spdy3_unittest.cc', 'spdy/buffered_spdy_framer_spdy2_unittest.cc', 'spdy/spdy_credential_builder_unittest.cc', - 'spdy/spdy_buffer_unittest.cc', 'spdy/spdy_credential_state_unittest.cc', 'spdy/spdy_frame_builder_test.cc', 'spdy/spdy_frame_reader_test.cc', @@ -1696,7 +1693,6 @@ 'spdy/spdy_protocol_test.cc', 'spdy/spdy_proxy_client_socket_spdy3_unittest.cc', 'spdy/spdy_proxy_client_socket_spdy2_unittest.cc', - 'spdy/spdy_read_queue_unittest.cc', 'spdy/spdy_session_spdy3_unittest.cc', 'spdy/spdy_session_spdy2_unittest.cc', 'spdy/spdy_session_test_util.cc', diff --git a/net/spdy/spdy_buffer.cc b/net/spdy/spdy_buffer.cc deleted file mode 100644 index 3257bef..0000000 --- a/net/spdy/spdy_buffer.cc +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/spdy/spdy_buffer.h" - -#include <cstring> - -#include "base/logging.h" -#include "net/base/io_buffer.h" -#include "net/spdy/spdy_protocol.h" - -namespace net { - -namespace { - -// Makes a SpdyFrame with |size| bytes of data copied from -// |data|. |data| must be non-NULL and |size| must be positive. -scoped_ptr<SpdyFrame> MakeSpdyFrame(const char* data, size_t size) { - DCHECK(data); - DCHECK_GT(size, 0u); - scoped_array<char> frame_data(new char[size]); - std::memcpy(frame_data.get(), data, size); - scoped_ptr<SpdyFrame> frame( - new SpdyFrame(frame_data.release(), size, true /* owns_buffer */)); - return frame.Pass(); -} - -} // namespace - -SpdyBuffer::SpdyBuffer(scoped_ptr<SpdyFrame> frame) - : frame_(frame.Pass()), - offset_(0) {} - -// The given data may not be strictly a SPDY frame; we (ab)use -// |frame_| just as a container. -SpdyBuffer::SpdyBuffer(const char* data, size_t size) : - frame_(MakeSpdyFrame(data, size)), - offset_(0) {} - -SpdyBuffer::~SpdyBuffer() {} - -const char* SpdyBuffer::GetRemainingData() const { - return frame_->data() + offset_; -} - -size_t SpdyBuffer::GetRemainingSize() const { - return frame_->size() - offset_; -} - -void SpdyBuffer::Consume(size_t consume_size) { - DCHECK_GE(consume_size, 1u); - DCHECK_LE(consume_size, GetRemainingSize()); - offset_ += consume_size; -}; - -IOBuffer* SpdyBuffer::GetIOBufferForRemainingData() { - return new WrappedIOBuffer(GetRemainingData()); -} - -} // namespace net diff --git a/net/spdy/spdy_buffer.h b/net/spdy/spdy_buffer.h deleted file mode 100644 index c4c5b8f..0000000 --- a/net/spdy/spdy_buffer.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_SPDY_SPDY_BUFFER_H_ -#define NET_SPDY_SPDY_BUFFER_H_ - -#include <cstddef> - -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "net/base/net_export.h" - -namespace net { - -class IOBuffer; -class SpdyFrame; - -// SpdyBuffer is a class to hold data read from or to be written to a -// SPDY connection. It is similar to a DrainableIOBuffer but is not -// ref-counted and will include a way to get notified when Consume() -// is called. -// -// NOTE(akalin): This explicitly does not inherit from IOBuffer to -// avoid the needless ref-counting and to avoid working around the -// fact that IOBuffer member functions are not virtual. -class NET_EXPORT_PRIVATE SpdyBuffer { - public: - // Construct with the data in the given frame. Assumes that data is - // owned by |frame| or outlives it. - explicit SpdyBuffer(scoped_ptr<SpdyFrame> frame); - - // Construct with a copy of the given raw data. |data| must be - // non-NULL and |size| must be non-zero. - SpdyBuffer(const char* data, size_t size); - - ~SpdyBuffer(); - - // Returns the remaining (unconsumed) data. - const char* GetRemainingData() const; - - // Returns the number of remaining (unconsumed) bytes. - size_t GetRemainingSize() const; - - // Consume the given number of bytes, which must be positive but not - // greater than GetRemainingSize(). - // - // TODO(akalin): Add a way to get notified when Consume() is called. - void Consume(size_t consume_size); - - // Returns an IOBuffer pointing to the data starting at - // GetRemainingData(). Use with care; the returned IOBuffer must not - // be used past the lifetime of this object, and it is not updated - // when Consume() is called. - IOBuffer* GetIOBufferForRemainingData(); - - private: - const scoped_ptr<SpdyFrame> frame_; - size_t offset_; - - DISALLOW_COPY_AND_ASSIGN(SpdyBuffer); -}; - -} // namespace net - -#endif // NET_SPDY_SPDY_BUFFER_H_ diff --git a/net/spdy/spdy_buffer_producer.cc b/net/spdy/spdy_buffer_producer.cc deleted file mode 100644 index 3a9598c..0000000 --- a/net/spdy/spdy_buffer_producer.cc +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/spdy/spdy_buffer_producer.h" - -#include "base/logging.h" -#include "net/spdy/spdy_buffer.h" -#include "net/spdy/spdy_protocol.h" - -namespace net { - -SpdyBufferProducer::SpdyBufferProducer() {} - -SpdyBufferProducer::~SpdyBufferProducer() {} - -SimpleBufferProducer::SimpleBufferProducer(scoped_ptr<SpdyBuffer> buffer) - : buffer_(buffer.Pass()) {} - -SimpleBufferProducer::~SimpleBufferProducer() {} - -scoped_ptr<SpdyBuffer> SimpleBufferProducer::ProduceBuffer() { - DCHECK(buffer_); - return buffer_.Pass(); -} - -} // namespace net diff --git a/net/spdy/spdy_buffer_producer.h b/net/spdy/spdy_buffer_producer.h deleted file mode 100644 index fe82b1a..0000000 --- a/net/spdy/spdy_buffer_producer.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_SPDY_SPDY_BUFFER_PRODUCER_H_ -#define NET_SPDY_SPDY_BUFFER_PRODUCER_H_ - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "base/memory/scoped_ptr.h" -#include "net/base/net_export.h" - -namespace net { - -class SpdyBuffer; - -// An object which provides a SpdyBuffer for writing. We pass these -// around instead of SpdyBuffers since some buffers have to be -// generated "just in time". -class NET_EXPORT_PRIVATE SpdyBufferProducer { - public: - SpdyBufferProducer(); - - // Produces the buffer to be written. Will be called at most once. - virtual scoped_ptr<SpdyBuffer> ProduceBuffer() = 0; - - virtual ~SpdyBufferProducer(); - - private: - DISALLOW_COPY_AND_ASSIGN(SpdyBufferProducer); -}; - -// A simple wrapper around a single SpdyBuffer. -class NET_EXPORT_PRIVATE SimpleBufferProducer : public SpdyBufferProducer { - public: - explicit SimpleBufferProducer(scoped_ptr<SpdyBuffer> buffer); - - virtual ~SimpleBufferProducer(); - - virtual scoped_ptr<SpdyBuffer> ProduceBuffer() OVERRIDE; - - private: - scoped_ptr<SpdyBuffer> buffer_; - - DISALLOW_COPY_AND_ASSIGN(SimpleBufferProducer); -}; - -} // namespace net - -#endif // NET_SPDY_SPDY_BUFFER_PRODUCER_H_ diff --git a/net/spdy/spdy_buffer_unittest.cc b/net/spdy/spdy_buffer_unittest.cc deleted file mode 100644 index fbd7705..0000000 --- a/net/spdy/spdy_buffer_unittest.cc +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/spdy/spdy_buffer.h" - -#include <cstddef> -#include <string> - -#include "base/basictypes.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "net/base/io_buffer.h" -#include "net/spdy/spdy_protocol.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { - -namespace { - -const char kData[] = "hello!\0hi."; -const size_t kDataSize = arraysize(kData); - -class SpdyBufferTest : public ::testing::Test {}; - -// Make a string from the data remaining in |buffer|. -std::string BufferToString(const SpdyBuffer& buffer) { - return std::string(buffer.GetRemainingData(), buffer.GetRemainingSize()); -} - -// Construct a SpdyBuffer from a SpdyFrame and make sure its data -// points to the frame's underlying data. -TEST_F(SpdyBufferTest, FrameConstructor) { - SpdyBuffer buffer( - scoped_ptr<SpdyFrame>( - new SpdyFrame(const_cast<char*>(kData), kDataSize, - false /* owns_buffer */))); - - EXPECT_EQ(kData, buffer.GetRemainingData()); - EXPECT_EQ(kDataSize, buffer.GetRemainingSize()); -} - -// Construct a SpdyBuffer from a const char*/size_t pair and make sure -// it makes a copy of the data. -TEST_F(SpdyBufferTest, DataConstructor) { - std::string data(kData, kDataSize); - SpdyBuffer buffer(data.data(), data.size()); - // This mutation shouldn't affect |buffer|'s data. - data[0] = 'H'; - - EXPECT_NE(kData, buffer.GetRemainingData()); - EXPECT_EQ(kDataSize, buffer.GetRemainingSize()); - EXPECT_EQ(std::string(kData, kDataSize), BufferToString(buffer)); -} - -// Construct a SpdyBuffer and call Consume() on it, which should -// update the remaining data pointer and size appropriately. -TEST_F(SpdyBufferTest, Consume) { - SpdyBuffer buffer(kData, kDataSize); - - EXPECT_EQ(std::string(kData, kDataSize), BufferToString(buffer)); - - buffer.Consume(5); - EXPECT_EQ(std::string(kData + 5, kDataSize - 5), BufferToString(buffer)); - - buffer.Consume(kDataSize - 5); - EXPECT_EQ(0u, buffer.GetRemainingSize()); -} - -// Make sure the IOBuffer returned by GetIOBufferForRemainingData() -// points to the buffer's remaining data and isn't updated by -// Consume(). -TEST_F(SpdyBufferTest, GetIOBufferForRemainingData) { - SpdyBuffer buffer(kData, kDataSize); - - buffer.Consume(5); - scoped_refptr<IOBuffer> io_buffer = buffer.GetIOBufferForRemainingData(); - size_t io_buffer_size = buffer.GetRemainingSize(); - const std::string expectedData(kData + 5, kDataSize - 5); - EXPECT_EQ(expectedData, std::string(io_buffer->data(), io_buffer_size)); - - buffer.Consume(kDataSize - 5); - EXPECT_EQ(expectedData, std::string(io_buffer->data(), io_buffer_size)); -} - -} // namespace - -} // namespace net diff --git a/net/spdy/spdy_frame_producer.cc b/net/spdy/spdy_frame_producer.cc new file mode 100644 index 0000000..dc16744 --- /dev/null +++ b/net/spdy/spdy_frame_producer.cc @@ -0,0 +1,26 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/spdy/spdy_frame_producer.h" + +#include "base/logging.h" +#include "net/spdy/spdy_protocol.h" + +namespace net { + +SpdyFrameProducer::SpdyFrameProducer() {} + +SpdyFrameProducer::~SpdyFrameProducer() {} + +SimpleFrameProducer::SimpleFrameProducer(scoped_ptr<SpdyFrame> frame) + : frame_(frame.Pass()) {} + +SimpleFrameProducer::~SimpleFrameProducer() {} + +scoped_ptr<SpdyFrame> SimpleFrameProducer::ProduceFrame() { + DCHECK(frame_); + return frame_.Pass(); +} + +} // namespace net diff --git a/net/spdy/spdy_frame_producer.h b/net/spdy/spdy_frame_producer.h new file mode 100644 index 0000000..9db20ce --- /dev/null +++ b/net/spdy/spdy_frame_producer.h @@ -0,0 +1,50 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_SPDY_SPDY_FRAME_PRODUCER_H_ +#define NET_SPDY_SPDY_FRAME_PRODUCER_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" +#include "net/base/net_export.h" + +namespace net { + +class SpdyFrame; + +// An object which provides a SpdyFrame for writing. We pass these +// around instead of SpdyFrames since some frames have to be generated +// "just in time". +class NET_EXPORT_PRIVATE SpdyFrameProducer { + public: + SpdyFrameProducer(); + + // Produces the frame to be written. Will be called at most once. + virtual scoped_ptr<SpdyFrame> ProduceFrame() = 0; + + virtual ~SpdyFrameProducer(); + + private: + DISALLOW_COPY_AND_ASSIGN(SpdyFrameProducer); +}; + +// A simple wrapper around a single SpdyFrame. +class NET_EXPORT_PRIVATE SimpleFrameProducer : public SpdyFrameProducer { + public: + explicit SimpleFrameProducer(scoped_ptr<SpdyFrame> frame); + + virtual ~SimpleFrameProducer(); + + virtual scoped_ptr<SpdyFrame> ProduceFrame() OVERRIDE; + + private: + scoped_ptr<SpdyFrame> frame_; + + DISALLOW_COPY_AND_ASSIGN(SimpleFrameProducer); +}; + +} // namespace net + +#endif // NET_SPDY_SPDY_FRAME_PRODUCER_H_ diff --git a/net/spdy/spdy_http_stream.cc b/net/spdy/spdy_http_stream.cc index 9053bc3..4eb82bf 100644 --- a/net/spdy/spdy_http_stream.cc +++ b/net/spdy/spdy_http_stream.cc @@ -135,11 +135,28 @@ int SpdyHttpStream::ReadResponseBody( CHECK(!callback.is_null()); // If we have data buffered, complete the IO immediately. - if (!response_body_queue_.IsEmpty()) { - size_t bytes_consumed = response_body_queue_.Dequeue(buf->data(), buf_len); + if (!response_body_.empty()) { + int bytes_read = 0; + while (!response_body_.empty() && buf_len > 0) { + scoped_refptr<IOBufferWithSize> data = response_body_.front(); + const int bytes_to_copy = std::min(buf_len, data->size()); + memcpy(&(buf->data()[bytes_read]), data->data(), bytes_to_copy); + buf_len -= bytes_to_copy; + if (bytes_to_copy == data->size()) { + response_body_.pop_front(); + } else { + const int bytes_remaining = data->size() - bytes_to_copy; + IOBufferWithSize* new_buffer = new IOBufferWithSize(bytes_remaining); + memcpy(new_buffer->data(), &(data->data()[bytes_to_copy]), + bytes_remaining); + response_body_.pop_front(); + response_body_.push_front(make_scoped_refptr(new_buffer)); + } + bytes_read += bytes_to_copy; + } if (stream_) - stream_->IncreaseRecvWindowSize(bytes_consumed); - return bytes_consumed; + stream_->IncreaseRecvWindowSize(bytes_read); + return bytes_read; } else if (stream_closed_) { return closed_stream_status_; } @@ -417,7 +434,7 @@ void SpdyHttpStream::OnHeadersSent() { NOTREACHED(); } -int SpdyHttpStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { +int SpdyHttpStream::OnDataReceived(const char* data, int length) { // SpdyStream won't call us with data if the header block didn't contain a // valid set of headers. So we don't expect to not have headers received // here. @@ -429,8 +446,11 @@ int SpdyHttpStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { // happen for server initiated streams. DCHECK(stream_.get()); DCHECK(!stream_->closed() || stream_->pushed()); - if (buffer) { - response_body_queue_.Enqueue(buffer.Pass()); + if (length > 0) { + // Save the received data. + IOBufferWithSize* io_buffer = new IOBufferWithSize(length); + memcpy(io_buffer->data(), data, length); + response_body_.push_back(make_scoped_refptr(io_buffer)); if (user_buffer_) { // Handing small chunks of data to the caller creates measurable overhead. @@ -489,9 +509,14 @@ bool SpdyHttpStream::ShouldWaitForMoreBufferedData() const { if (stream_closed_) return false; - DCHECK_GT(user_buffer_len_, 0); - return response_body_queue_.GetTotalSize() < - static_cast<size_t>(user_buffer_len_); + int bytes_buffered = 0; + std::list<scoped_refptr<IOBufferWithSize> >::const_iterator it; + for (it = response_body_.begin(); + it != response_body_.end() && bytes_buffered < user_buffer_len_; + ++it) + bytes_buffered += (*it)->size(); + + return bytes_buffered < user_buffer_len_; } bool SpdyHttpStream::DoBufferedReadCallback() { diff --git a/net/spdy/spdy_http_stream.h b/net/spdy/spdy_http_stream.h index 2af82f0..226d01c 100644 --- a/net/spdy/spdy_http_stream.h +++ b/net/spdy/spdy_http_stream.h @@ -13,7 +13,6 @@ #include "net/base/completion_callback.h" #include "net/base/net_log.h" #include "net/http/http_stream.h" -#include "net/spdy/spdy_read_queue.h" #include "net/spdy/spdy_stream.h" namespace net { @@ -90,7 +89,7 @@ class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate, base::Time response_time, int status) OVERRIDE; virtual void OnHeadersSent() OVERRIDE; - virtual int OnDataReceived(scoped_ptr<SpdyBuffer> buffer) OVERRIDE; + virtual int OnDataReceived(const char* buffer, int bytes) OVERRIDE; virtual void OnDataSent(size_t bytes_sent) OVERRIDE; virtual void OnClose(int status) OVERRIDE; @@ -140,7 +139,8 @@ class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate, bool response_headers_received_; // Indicates waiting for more HEADERS. // We buffer the response body as it arrives asynchronously from the stream. - SpdyReadQueue response_body_queue_; + // TODO(mbelshe): is this infinite buffering? + std::list<scoped_refptr<IOBufferWithSize> > response_body_; CompletionCallback callback_; diff --git a/net/spdy/spdy_io_buffer.cc b/net/spdy/spdy_io_buffer.cc new file mode 100644 index 0000000..441b033 --- /dev/null +++ b/net/spdy/spdy_io_buffer.cc @@ -0,0 +1,38 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/spdy/spdy_io_buffer.h" +#include "net/spdy/spdy_stream.h" + +namespace net { + +SpdyIOBuffer::SpdyIOBuffer() {} + +SpdyIOBuffer::SpdyIOBuffer(IOBuffer* buffer, int size, SpdyStream* stream) + : buffer_(new DrainableIOBuffer(buffer, size)), stream_(stream) {} + +SpdyIOBuffer::SpdyIOBuffer(const SpdyIOBuffer& rhs) { + buffer_ = rhs.buffer_; + stream_ = rhs.stream_; +} + +SpdyIOBuffer::~SpdyIOBuffer() {} + +SpdyIOBuffer& SpdyIOBuffer::operator=(const SpdyIOBuffer& rhs) { + buffer_ = rhs.buffer_; + stream_ = rhs.stream_; + return *this; +} + +void SpdyIOBuffer::Swap(SpdyIOBuffer* other) { + buffer_.swap(other->buffer_); + stream_.swap(other->stream_); +} + +void SpdyIOBuffer::Release() { + buffer_ = NULL; + stream_ = NULL; +} + +} // namespace net diff --git a/net/spdy/spdy_io_buffer.h b/net/spdy/spdy_io_buffer.h new file mode 100644 index 0000000..ed95e70 --- /dev/null +++ b/net/spdy/spdy_io_buffer.h @@ -0,0 +1,56 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_SPDY_SPDY_IO_BUFFER_H_ +#define NET_SPDY_SPDY_IO_BUFFER_H_ + +#include "base/memory/ref_counted.h" +#include "net/base/io_buffer.h" +#include "net/base/net_export.h" + +namespace net { + +class SpdyStream; + +// A class for managing SPDY write buffers. These write buffers need +// to track the SpdyStream which they are associated with so that the +// session can activate the stream lazily and also notify the stream +// on completion of the write. +class NET_EXPORT_PRIVATE SpdyIOBuffer { + public: + SpdyIOBuffer(); + + // Constructor + // |buffer| is the actual data buffer. + // |size| is the size of the data buffer. + // |stream| is a pointer to the stream which is managing this buffer + // (can be NULL if the write is for the session itself). + SpdyIOBuffer(IOBuffer* buffer, int size, SpdyStream* stream); + + // Declare this instead of using the default so that we avoid needing to + // include spdy_stream.h. + SpdyIOBuffer(const SpdyIOBuffer& rhs); + + ~SpdyIOBuffer(); + + // Declare this instead of using the default so that we avoid needing to + // include spdy_stream.h. + SpdyIOBuffer& operator=(const SpdyIOBuffer& rhs); + + void Swap(SpdyIOBuffer* other); + + void Release(); + + // Accessors. + DrainableIOBuffer* buffer() const { return buffer_; } + const scoped_refptr<SpdyStream>& stream() const { return stream_; } + + private: + scoped_refptr<DrainableIOBuffer> buffer_; + scoped_refptr<SpdyStream> stream_; +}; + +} // namespace net + +#endif // NET_SPDY_SPDY_IO_BUFFER_H_ diff --git a/net/spdy/spdy_proxy_client_socket.cc b/net/spdy/spdy_proxy_client_socket.cc index c09a5bd..7978d60 100644 --- a/net/spdy/spdy_proxy_client_socket.cc +++ b/net/spdy/spdy_proxy_client_socket.cc @@ -39,7 +39,7 @@ SpdyProxyClientSocket::SpdyProxyClientSocket( GURL("https://" + proxy_server.ToString()), auth_cache, auth_handler_factory)), - user_buffer_len_(0), + user_buffer_(NULL), write_buffer_len_(0), write_bytes_outstanding_(0), ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), @@ -127,9 +127,8 @@ int SpdyProxyClientSocket::Connect(const CompletionCallback& callback) { } void SpdyProxyClientSocket::Disconnect() { - read_buffer_queue_.Clear(); + read_buffer_.clear(); user_buffer_ = NULL; - user_buffer_len_ = 0; read_callback_.Reset(); write_buffer_len_ = 0; @@ -151,8 +150,7 @@ bool SpdyProxyClientSocket::IsConnected() const { } bool SpdyProxyClientSocket::IsConnectedAndIdle() const { - return IsConnected() && read_buffer_queue_.IsEmpty() && - spdy_stream_->is_idle(); + return IsConnected() && read_buffer_.empty() && spdy_stream_->is_idle(); } const BoundNetLog& SpdyProxyClientSocket::NetLog() const { @@ -198,16 +196,15 @@ int SpdyProxyClientSocket::Read(IOBuffer* buf, int buf_len, if (next_state_ == STATE_DISCONNECTED) return ERR_SOCKET_NOT_CONNECTED; - if (next_state_ == STATE_CLOSED && read_buffer_queue_.IsEmpty()) { + if (next_state_ == STATE_CLOSED && read_buffer_.empty()) { return 0; } DCHECK(next_state_ == STATE_OPEN || next_state_ == STATE_CLOSED); DCHECK(buf); - size_t result = PopulateUserReadBuffer(buf->data(), buf_len); + user_buffer_ = new DrainableIOBuffer(buf, buf_len); + int result = PopulateUserReadBuffer(); if (result == 0) { - user_buffer_ = buf; - user_buffer_len_ = static_cast<size_t>(buf_len); DCHECK(!callback.is_null()); read_callback_ = callback; return ERR_IO_PENDING; @@ -216,13 +213,30 @@ int SpdyProxyClientSocket::Read(IOBuffer* buf, int buf_len, return result; } -size_t SpdyProxyClientSocket::PopulateUserReadBuffer(char* data, size_t len) { - size_t bytes_consumed = read_buffer_queue_.Dequeue(data, len); +int SpdyProxyClientSocket::PopulateUserReadBuffer() { + if (!user_buffer_) + return ERR_IO_PENDING; - if (bytes_consumed > 0 && spdy_stream_) - spdy_stream_->IncreaseRecvWindowSize(bytes_consumed); + int bytes_read = 0; + while (!read_buffer_.empty() && user_buffer_->BytesRemaining() > 0) { + scoped_refptr<DrainableIOBuffer> data = read_buffer_.front(); + const int bytes_to_copy = std::min(user_buffer_->BytesRemaining(), + data->BytesRemaining()); + memcpy(user_buffer_->data(), data->data(), bytes_to_copy); + user_buffer_->DidConsume(bytes_to_copy); + bytes_read += bytes_to_copy; + if (data->BytesRemaining() == bytes_to_copy) { + // Consumed all data from this buffer + read_buffer_.pop_front(); + } else { + data->DidConsume(bytes_to_copy); + } + } - return bytes_consumed; + if (bytes_read > 0 && spdy_stream_) + spdy_stream_->IncreaseRecvWindowSize(bytes_read); + + return user_buffer_->BytesConsumed(); } int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len, @@ -512,23 +526,23 @@ void SpdyProxyClientSocket::OnHeadersSent() { NOTREACHED(); } -// Called when data is received or on EOF (if |buffer| is NULL). -int SpdyProxyClientSocket::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { - if (buffer) { - net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, - buffer->GetRemainingSize(), - buffer->GetRemainingData()); - read_buffer_queue_.Enqueue(buffer.Pass()); - } else { - net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, 0, NULL); +// Called when data is received. +int SpdyProxyClientSocket::OnDataReceived(const char* data, int length) { + net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, + length, data); + if (length > 0) { + // Save the received data. + scoped_refptr<IOBuffer> io_buffer(new IOBuffer(length)); + memcpy(io_buffer->data(), data, length); + read_buffer_.push_back( + make_scoped_refptr(new DrainableIOBuffer(io_buffer, length))); } if (!read_callback_.is_null()) { - int rv = PopulateUserReadBuffer(user_buffer_->data(), user_buffer_len_); + int rv = PopulateUserReadBuffer(); CompletionCallback c = read_callback_; read_callback_.Reset(); user_buffer_ = NULL; - user_buffer_len_ = 0; c.Run(rv); } return OK; @@ -577,7 +591,7 @@ void SpdyProxyClientSocket::OnClose(int status) { read_callback.Run(status); } else if (!read_callback_.is_null()) { // If we have a read_callback_, the we need to make sure we call it back. - OnDataReceived(scoped_ptr<SpdyBuffer>()); + OnDataReceived(NULL, 0); } // This may have been deleted by read_callback_, so check first. if (weak_ptr && !write_callback.is_null()) diff --git a/net/spdy/spdy_proxy_client_socket.h b/net/spdy/spdy_proxy_client_socket.h index e25e1e3..8d3f047 100644 --- a/net/spdy/spdy_proxy_client_socket.h +++ b/net/spdy/spdy_proxy_client_socket.h @@ -5,8 +5,8 @@ #ifndef NET_SPDY_SPDY_PROXY_CLIENT_SOCKET_H_ #define NET_SPDY_SPDY_PROXY_CLIENT_SOCKET_H_ -#include <list> #include <string> +#include <list> #include "base/basictypes.h" #include "base/memory/ref_counted.h" @@ -21,7 +21,6 @@ #include "net/http/proxy_client_socket.h" #include "net/spdy/spdy_http_stream.h" #include "net/spdy/spdy_protocol.h" -#include "net/spdy/spdy_read_queue.h" #include "net/spdy/spdy_session.h" #include "net/spdy/spdy_stream.h" @@ -98,7 +97,7 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket, base::Time response_time, int status) OVERRIDE; virtual void OnHeadersSent() OVERRIDE; - virtual int OnDataReceived(scoped_ptr<SpdyBuffer> buffer) OVERRIDE; + virtual int OnDataReceived(const char* data, int length) OVERRIDE; virtual void OnDataSent(size_t bytes_sent) OVERRIDE; virtual void OnClose(int status) OVERRIDE; @@ -127,7 +126,7 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket, // Populates |user_buffer_| with as much read data as possible // and returns the number of bytes read. - size_t PopulateUserReadBuffer(char* out, size_t len); + int PopulateUserReadBuffer(); State next_state_; @@ -150,11 +149,10 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket, scoped_refptr<HttpAuthController> auth_; // We buffer the response body as it arrives asynchronously from the stream. - SpdyReadQueue read_buffer_queue_; + std::list<scoped_refptr<DrainableIOBuffer> > read_buffer_; // User provided buffer for the Read() response. - scoped_refptr<IOBuffer> user_buffer_; - size_t user_buffer_len_; + scoped_refptr<DrainableIOBuffer> user_buffer_; // User specified number of bytes to be written. int write_buffer_len_; diff --git a/net/spdy/spdy_read_queue.cc b/net/spdy/spdy_read_queue.cc deleted file mode 100644 index 36f1e06..0000000 --- a/net/spdy/spdy_read_queue.cc +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/spdy/spdy_read_queue.h" - -#include "base/logging.h" -#include "base/stl_util.h" -#include "net/spdy/spdy_buffer.h" - -namespace net { - -SpdyReadQueue::SpdyReadQueue() : total_size_(0) {} - -SpdyReadQueue::~SpdyReadQueue() { - Clear(); -} - -bool SpdyReadQueue::IsEmpty() const { - DCHECK_EQ(queue_.empty(), total_size_ == 0); - return queue_.empty(); -} - -size_t SpdyReadQueue::GetTotalSize() const { - return total_size_; -} - -void SpdyReadQueue::Enqueue(scoped_ptr<SpdyBuffer> buffer) { - DCHECK_GT(buffer->GetRemainingSize(), 0u); - total_size_ += buffer->GetRemainingSize(); - queue_.push_back(buffer.release()); -} - -size_t SpdyReadQueue::Dequeue(char* out, size_t len) { - DCHECK_GT(len, 0u); - size_t bytes_copied = 0; - while (!queue_.empty() && bytes_copied < len) { - SpdyBuffer* buffer = queue_.front(); - size_t bytes_to_copy = - std::min(len - bytes_copied, buffer->GetRemainingSize()); - memcpy(out + bytes_copied, buffer->GetRemainingData(), bytes_to_copy); - bytes_copied += bytes_to_copy; - if (bytes_to_copy == buffer->GetRemainingSize()) { - delete queue_.front(); - queue_.pop_front(); - } else { - buffer->Consume(bytes_to_copy); - } - } - total_size_ -= bytes_copied; - return bytes_copied; -} - -void SpdyReadQueue::Clear() { - STLDeleteElements(&queue_); - queue_.clear(); -} - -} // namespace diff --git a/net/spdy/spdy_read_queue.h b/net/spdy/spdy_read_queue.h deleted file mode 100644 index 65f3daf..0000000 --- a/net/spdy/spdy_read_queue.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_SPDY_SPDY_BUFFER_QUEUE_H_ -#define NET_SPDY_SPDY_BUFFER_QUEUE_H_ - -#include <cstddef> -#include <deque> - -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "net/base/net_export.h" - -namespace net { - -class SpdyBuffer; - -// A FIFO queue of incoming data from a SPDY connection. Useful for -// SpdyStream delegates. -class NET_EXPORT_PRIVATE SpdyReadQueue { - public: - SpdyReadQueue(); - ~SpdyReadQueue(); - - // Returns whether there's anything in the queue. - bool IsEmpty() const; - - // Returns the total number of bytes in the queue. - size_t GetTotalSize() const; - - // Enqueues the bytes in |buffer|. - void Enqueue(scoped_ptr<SpdyBuffer> buffer); - - // Dequeues up to |len| (which must be positive) bytes into - // |out|. Returns the number of bytes dequeued. - size_t Dequeue(char* out, size_t len); - - // Removes all bytes from the queue. - void Clear(); - - private: - std::deque<SpdyBuffer*> queue_; - size_t total_size_; - - DISALLOW_COPY_AND_ASSIGN(SpdyReadQueue); -}; - -} // namespace net - -#endif // NET_SPDY_SPDY_BUFFER_QUEUE_H_ diff --git a/net/spdy/spdy_read_queue_unittest.cc b/net/spdy/spdy_read_queue_unittest.cc deleted file mode 100644 index 7281f68..0000000 --- a/net/spdy/spdy_read_queue_unittest.cc +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/spdy/spdy_read_queue.h" - -#include <algorithm> -#include <cstddef> -#include <string> - -#include "base/memory/scoped_ptr.h" -#include "base/stl_util.h" -#include "net/spdy/spdy_buffer.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { - -namespace { - -const char kData[] = "SPDY read queue test data.\0Some more data."; -const size_t kDataSize = arraysize(kData); - -// Enqueues |data| onto |queue| in chunks of at most |max_buffer_size| -// bytes. -void EnqueueString(const std::string& data, - size_t max_buffer_size, - SpdyReadQueue* queue) { - ASSERT_GT(data.size(), 0u); - ASSERT_GT(max_buffer_size, 0u); - size_t old_total_size = queue->GetTotalSize(); - for (size_t i = 0; i < data.size();) { - size_t buffer_size = std::min(data.size() - i, max_buffer_size); - queue->Enqueue( - scoped_ptr<SpdyBuffer>(new SpdyBuffer(data.data() + i, buffer_size))); - i += buffer_size; - EXPECT_FALSE(queue->IsEmpty()); - EXPECT_EQ(old_total_size + i, queue->GetTotalSize()); - } -} - -// Dequeues all bytes in |queue| in chunks of at most -// |max_buffer_size| bytes and returns the data as a string. -std::string DrainToString(size_t max_buffer_size, SpdyReadQueue* queue) { - std::string data; - - // Pad the buffer so we can detect out-of-bound writes. - size_t padding = std::max(static_cast<size_t>(4096), queue->GetTotalSize()); - size_t buffer_size_with_padding = padding + max_buffer_size + padding; - scoped_ptr<char[]> buffer(new char[buffer_size_with_padding]); - std::memset(buffer.get(), 0, buffer_size_with_padding); - char* buffer_data = buffer.get() + padding; - - while (!queue->IsEmpty()) { - size_t old_total_size = queue->GetTotalSize(); - EXPECT_GT(old_total_size, 0u); - size_t dequeued_bytes = queue->Dequeue(buffer_data, max_buffer_size); - - // Make sure |queue| doesn't write past either end of its given - // boundaries. - for (int i = 1; i <= static_cast<int>(padding); ++i) { - EXPECT_EQ('\0', buffer_data[-i]) << -i; - } - for (size_t i = 0; i < padding; ++i) { - EXPECT_EQ('\0', buffer_data[max_buffer_size + i]) << i; - } - - data.append(buffer_data, dequeued_bytes); - EXPECT_EQ(dequeued_bytes, std::min(max_buffer_size, dequeued_bytes)); - EXPECT_EQ(queue->GetTotalSize(), old_total_size - dequeued_bytes); - } - EXPECT_TRUE(queue->IsEmpty()); - return data; -} - -// Enqueue a test string with the given enqueue/dequeue max buffer -// sizes. -void RunEnqueueDequeueTest(size_t enqueue_max_buffer_size, - size_t dequeue_max_buffer_size) { - std::string data(kData, kDataSize); - SpdyReadQueue read_queue; - EnqueueString(data, enqueue_max_buffer_size, &read_queue); - const std::string& drained_data = - DrainToString(dequeue_max_buffer_size, &read_queue); - EXPECT_EQ(data, drained_data); -} - -class SpdyReadQueueTest : public ::testing::Test {}; - -// Call RunEnqueueDequeueTest() with various buffer size combinatinos. - -TEST_F(SpdyReadQueueTest, LargeEnqueueAndDequeueBuffers) { - RunEnqueueDequeueTest(2 * kDataSize, 2 * kDataSize); -} - -TEST_F(SpdyReadQueueTest, OneByteEnqueueAndDequeueBuffers) { - RunEnqueueDequeueTest(1, 1); -} - -TEST_F(SpdyReadQueueTest, CoprimeBufferSizes) { - RunEnqueueDequeueTest(2, 3); - RunEnqueueDequeueTest(3, 2); -} - -} // namespace - -} // namespace net diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc index f705731..1b59ec7 100644 --- a/net/spdy/spdy_session.cc +++ b/net/spdy/spdy_session.cc @@ -31,9 +31,9 @@ #include "net/cert/asn1_util.h" #include "net/http/http_network_session.h" #include "net/http/http_server_properties.h" -#include "net/spdy/spdy_buffer_producer.h" #include "net/spdy/spdy_credential_builder.h" #include "net/spdy/spdy_frame_builder.h" +#include "net/spdy/spdy_frame_producer.h" #include "net/spdy/spdy_http_utils.h" #include "net/spdy/spdy_protocol.h" #include "net/spdy/spdy_session_pool.h" @@ -312,7 +312,6 @@ SpdySession::SpdySession(const HostPortProxyPair& host_port_proxy_pair, stream_hi_water_mark_(kFirstStreamId), write_pending_(false), in_flight_write_frame_type_(DATA), - in_flight_write_frame_size_(0), delayed_write_pending_(false), is_secure_(false), certificate_error_code_(OK), @@ -637,7 +636,7 @@ int SpdySession::GetProtocolVersion() const { void SpdySession::EnqueueStreamWrite( SpdyStream* stream, SpdyFrameType frame_type, - scoped_ptr<SpdyBufferProducer> producer) { + scoped_ptr<SpdyFrameProducer> producer) { DCHECK(frame_type == HEADERS || frame_type == DATA || frame_type == CREDENTIAL || @@ -739,18 +738,18 @@ scoped_ptr<SpdyFrame> SpdySession::CreateHeadersFrame( return frame.Pass(); } -scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id, - net::IOBuffer* data, - int len, - SpdyDataFlags flags) { - // Find our stream. +scoped_ptr<SpdyFrame> SpdySession::CreateDataFrame(SpdyStreamId stream_id, + net::IOBuffer* data, + int len, + SpdyDataFlags flags) { + // Find our stream CHECK(IsStreamActive(stream_id)); scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; CHECK_EQ(stream->stream_id(), stream_id); if (len < 0) { NOTREACHED(); - return scoped_ptr<SpdyBuffer>(); + return scoped_ptr<SpdyFrame>(); } if (len > kMaxSpdyFrameChunkSize) { @@ -773,7 +772,7 @@ scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id, net_log().AddEvent( NetLog::TYPE_SPDY_SESSION_STREAM_STALLED_ON_STREAM_SEND_WINDOW, NetLog::IntegerCallback("stream_id", stream_id)); - return scoped_ptr<SpdyBuffer>(); + return scoped_ptr<SpdyFrame>(); } if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) { effective_window_size = @@ -785,7 +784,7 @@ scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id, net_log().AddEvent( NetLog::TYPE_SPDY_SESSION_STREAM_STALLED_ON_SESSION_SEND_WINDOW, NetLog::IntegerCallback("stream_id", stream_id)); - return scoped_ptr<SpdyBuffer>(); + return scoped_ptr<SpdyFrame>(); } } @@ -816,7 +815,7 @@ scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id, buffered_spdy_framer_->CreateDataFrame( stream_id, data->data(), static_cast<uint32>(len), flags)); - return scoped_ptr<SpdyBuffer>(new SpdyBuffer(frame.Pass())); + return frame.Pass(); } void SpdySession::CloseStream(SpdyStreamId stream_id, int status) { @@ -983,45 +982,42 @@ void SpdySession::OnWriteComplete(int result) { scoped_refptr<SpdySession> self(this); DCHECK(write_pending_); - DCHECK_GT(in_flight_write_->GetRemainingSize(), 0u); + DCHECK_GT(in_flight_write_.buffer()->BytesRemaining(), 0); last_activity_time_ = base::TimeTicks::Now(); write_pending_ = false; if (result < 0) { - in_flight_write_.reset(); + in_flight_write_.Release(); in_flight_write_frame_type_ = DATA; - in_flight_write_frame_size_ = 0; - in_flight_write_stream_ = NULL; - CloseSessionOnError(static_cast<Error>(result), true, "Write error"); + CloseSessionOnError(static_cast<net::Error>(result), true, "Write error"); return; } // It should not be possible to have written more bytes than our // in_flight_write_. - DCHECK_LE(static_cast<size_t>(result), - in_flight_write_->GetRemainingSize()); - - if (result > 0) { - in_flight_write_->Consume(static_cast<size_t>(result)); - - // We only notify the stream when we've fully written the pending frame. - if (in_flight_write_->GetRemainingSize() == 0) { - // It is possible that the stream was cancelled while we were - // writing to the socket. - if (in_flight_write_stream_ && !in_flight_write_stream_->cancelled()) { - DCHECK_GT(in_flight_write_frame_size_, 0u); - in_flight_write_stream_->OnFrameWriteComplete( - in_flight_write_frame_type_, - in_flight_write_frame_size_); - } + DCHECK_LE(result, in_flight_write_.buffer()->BytesRemaining()); + + in_flight_write_.buffer()->DidConsume(result); - // Cleanup the write which just completed. - in_flight_write_.reset(); - in_flight_write_frame_type_ = DATA; - in_flight_write_frame_size_ = 0; - in_flight_write_stream_ = NULL; + // We only notify the stream when we've fully written the pending frame. + if (in_flight_write_.buffer()->BytesRemaining() == 0) { + DCHECK_GT(result, 0); + + scoped_refptr<SpdyStream> stream = in_flight_write_.stream(); + + // It is possible that the stream was cancelled while we were writing + // to the socket. + if (stream && !stream->cancelled()) { + DCHECK_GT(in_flight_write_.buffer()->size(), 0); + stream->OnFrameWriteComplete( + in_flight_write_frame_type_, + static_cast<size_t>(in_flight_write_.buffer()->size())); } + + // Cleanup the write which just completed. + in_flight_write_.Release(); + in_flight_write_frame_type_ = DATA; } // Write more data. We're already in a continuation, so we can go @@ -1061,12 +1057,12 @@ void SpdySession::WriteSocket() { // returns error (or ERR_IO_PENDING). DCHECK(buffered_spdy_framer_.get()); while (true) { - if (in_flight_write_) { - DCHECK_GT(in_flight_write_->GetRemainingSize(), 0u); + if (in_flight_write_.buffer()) { + DCHECK_GT(in_flight_write_.buffer()->BytesRemaining(), 0); } else { // Grab the next frame to send. SpdyFrameType frame_type = DATA; - scoped_ptr<SpdyBufferProducer> producer; + scoped_ptr<SpdyFrameProducer> producer; scoped_refptr<SpdyStream> stream; if (!write_queue_.Dequeue(&frame_type, &producer, &stream)) break; @@ -1090,25 +1086,25 @@ void SpdySession::WriteSocket() { } } - in_flight_write_ = producer->ProduceBuffer(); - if (!in_flight_write_) { + scoped_ptr<SpdyFrame> frame = producer->ProduceFrame(); + if (!frame) { NOTREACHED(); continue; } + DCHECK_GT(frame->size(), 0u); + + // TODO(mbelshe): We have too much copying of data here. + scoped_refptr<IOBufferWithSize> buffer = + new IOBufferWithSize(frame->size()); + memcpy(buffer->data(), frame->data(), frame->size()); + in_flight_write_ = SpdyIOBuffer(buffer, frame->size(), stream); in_flight_write_frame_type_ = frame_type; - in_flight_write_frame_size_ = in_flight_write_->GetRemainingSize(); - DCHECK_GE(in_flight_write_frame_size_, - buffered_spdy_framer_->GetFrameMinimumSize()); - in_flight_write_stream_ = stream; } write_pending_ = true; - // We keep |in_flight_write_| alive until OnWriteComplete(), so - // it's okay to use GetIOBufferForRemainingData() since the socket - // doesn't use the IOBuffer past OnWriteComplete(). int rv = connection_->socket()->Write( - in_flight_write_->GetIOBufferForRemainingData(), - in_flight_write_->GetRemainingSize(), + in_flight_write_.buffer(), + in_flight_write_.buffer()->BytesRemaining(), base::Bind(&SpdySession::OnWriteComplete, weak_factory_.GetWeakPtr())); if (rv == net::ERR_IO_PENDING) break; @@ -1298,15 +1294,13 @@ void SpdySession::EnqueueSessionWrite(RequestPriority priority, frame_type == PING); EnqueueWrite( priority, frame_type, - scoped_ptr<SpdyBufferProducer>( - new SimpleBufferProducer( - scoped_ptr<SpdyBuffer>(new SpdyBuffer(frame.Pass())))), + scoped_ptr<SpdyFrameProducer>(new SimpleFrameProducer(frame.Pass())), NULL); } void SpdySession::EnqueueWrite(RequestPriority priority, SpdyFrameType frame_type, - scoped_ptr<SpdyBufferProducer> producer, + scoped_ptr<SpdyFrameProducer> producer, const scoped_refptr<SpdyStream>& stream) { write_queue_.Enqueue(priority, frame_type, producer.Pass(), stream); WriteSocketLater(); @@ -1424,24 +1418,16 @@ void SpdySession::OnStreamFrameData(SpdyStreamId stream_id, base::Bind(&NetLogSpdyDataCallback, stream_id, len, fin)); } - ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); - // By the time data comes in, the stream may already be inactive. - if (it == active_streams_.end()) + if (!IsStreamActive(stream_id)) return; // Only decrease the window size for data for active streams. if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION && len > 0) DecreaseRecvWindowSize(static_cast<int32>(len)); - scoped_ptr<SpdyBuffer> buffer; - if (data) { - DCHECK_GT(len, 0u); - buffer.reset(new SpdyBuffer(data, len)); - } else { - DCHECK_EQ(len, 0u); - } - it->second->OnDataReceived(buffer.Pass()); + scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; + stream->OnDataReceived(data, len); } void SpdySession::OnSetting(SpdySettingsIds id, @@ -1710,7 +1696,7 @@ void SpdySession::OnRstStream(SpdyStreamId stream_id, CHECK(!stream->cancelled()); if (status == 0) { - stream->OnDataReceived(scoped_ptr<SpdyBuffer>()); + stream->OnDataReceived(NULL, 0); } else if (status == RST_STREAM_REFUSED_STREAM) { DeleteStream(stream_id, ERR_SPDY_SERVER_REFUSED_STREAM); } else { diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h index 55ac9f9..b4e7335 100644 --- a/net/spdy/spdy_session.h +++ b/net/spdy/spdy_session.h @@ -26,9 +26,9 @@ #include "net/socket/ssl_client_socket.h" #include "net/socket/stream_socket.h" #include "net/spdy/buffered_spdy_framer.h" -#include "net/spdy/spdy_buffer.h" #include "net/spdy/spdy_credential_state.h" #include "net/spdy/spdy_header_block.h" +#include "net/spdy/spdy_io_buffer.h" #include "net/spdy/spdy_protocol.h" #include "net/spdy/spdy_session_pool.h" #include "net/spdy/spdy_write_queue.h" @@ -246,7 +246,7 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>, // producer is used to produce its frame. void EnqueueStreamWrite(SpdyStream* stream, SpdyFrameType frame_type, - scoped_ptr<SpdyBufferProducer> producer); + scoped_ptr<SpdyFrameProducer> producer); // Creates and returns a SYN frame for |stream_id|. scoped_ptr<SpdyFrame> CreateSynStream( @@ -271,12 +271,12 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>, const SpdyHeaderBlock& headers, SpdyControlFlags flags); - // Creates and returns a SpdyBuffer holding a data frame with the - // given data. May return NULL if stalled by flow control. - scoped_ptr<SpdyBuffer> CreateDataBuffer(SpdyStreamId stream_id, - net::IOBuffer* data, - int len, - SpdyDataFlags flags); + // Creates and returns a data frame. May return NULL if stalled by + // flow control. + scoped_ptr<SpdyFrame> CreateDataFrame(SpdyStreamId stream_id, + net::IOBuffer* data, + int len, + SpdyDataFlags flags); // Close a stream. void CloseStream(SpdyStreamId stream_id, int status); @@ -584,7 +584,7 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>, // with the given priority. void EnqueueWrite(RequestPriority priority, SpdyFrameType frame_type, - scoped_ptr<SpdyBufferProducer> producer, + scoped_ptr<SpdyFrameProducer> producer, const scoped_refptr<SpdyStream>& stream); // Track active streams in the active stream list. @@ -771,18 +771,10 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>, // The write queue. SpdyWriteQueue write_queue_; - // Data for the frame we are currently sending. - // Whether we have a socket write pending completion. - bool write_pending_; - // The buffer we're currently writing. - scoped_ptr<SpdyBuffer> in_flight_write_; - // The type of the frame in |in_flight_write_|. + // The packet we are currently sending. + bool write_pending_; // Will be true when a write is in progress. + SpdyIOBuffer in_flight_write_; // This is the write buffer in progress. SpdyFrameType in_flight_write_frame_type_; - // The size of the frame in |in_flight_write_|. - size_t in_flight_write_frame_size_; - // The stream to notify when |in_flight_write_| has been written to - // the socket completely. - scoped_refptr<SpdyStream> in_flight_write_stream_; // Flag if we have a pending message scheduled for WriteSocket. bool delayed_write_pending_; diff --git a/net/spdy/spdy_session_spdy2_unittest.cc b/net/spdy/spdy_session_spdy2_unittest.cc index e483e35..5069a22 100644 --- a/net/spdy/spdy_session_spdy2_unittest.cc +++ b/net/spdy/spdy_session_spdy2_unittest.cc @@ -10,7 +10,9 @@ #include "net/base/net_log_unittest.h" #include "net/base/request_priority.h" #include "net/base/test_data_directory.h" +#include "net/base/test_data_stream.h" #include "net/dns/host_cache.h" +#include "net/spdy/spdy_io_buffer.h" #include "net/spdy/spdy_session_pool.h" #include "net/spdy/spdy_session_test_util.h" #include "net/spdy/spdy_stream.h" diff --git a/net/spdy/spdy_session_spdy3_unittest.cc b/net/spdy/spdy_session_spdy3_unittest.cc index 1c63960..40e805f 100644 --- a/net/spdy/spdy_session_spdy3_unittest.cc +++ b/net/spdy/spdy_session_spdy3_unittest.cc @@ -13,6 +13,7 @@ #include "net/base/test_data_stream.h" #include "net/dns/host_cache.h" #include "net/spdy/spdy_http_utils.h" +#include "net/spdy/spdy_io_buffer.h" #include "net/spdy/spdy_session_pool.h" #include "net/spdy/spdy_session_test_util.h" #include "net/spdy/spdy_stream.h" diff --git a/net/spdy/spdy_stream.cc b/net/spdy/spdy_stream.cc index 3de3716..69d9cfa 100644 --- a/net/spdy/spdy_stream.cc +++ b/net/spdy/spdy_stream.cc @@ -12,7 +12,7 @@ #include "base/message_loop.h" #include "base/stringprintf.h" #include "base/values.h" -#include "net/spdy/spdy_buffer_producer.h" +#include "net/spdy/spdy_frame_producer.h" #include "net/spdy/spdy_http_utils.h" #include "net/spdy/spdy_session.h" @@ -54,23 +54,22 @@ bool ContainsUpperAscii(const std::string& str) { } // namespace // A wrapper around a stream that calls into ProduceSynStreamFrame(). -class SpdyStream::SynStreamBufferProducer : public SpdyBufferProducer { +class SpdyStream::SynStreamFrameProducer : public SpdyFrameProducer { public: - SynStreamBufferProducer(const base::WeakPtr<SpdyStream>& stream) + SynStreamFrameProducer(const base::WeakPtr<SpdyStream>& stream) : stream_(stream) { DCHECK(stream_); } - virtual ~SynStreamBufferProducer() {} + virtual ~SynStreamFrameProducer() {} - virtual scoped_ptr<SpdyBuffer> ProduceBuffer() OVERRIDE { + virtual scoped_ptr<SpdyFrame> ProduceFrame() OVERRIDE { if (!stream_) { NOTREACHED(); - return scoped_ptr<SpdyBuffer>(); + return scoped_ptr<SpdyFrame>(); } DCHECK_GT(stream_->stream_id(), 0u); - return scoped_ptr<SpdyBuffer>( - new SpdyBuffer(stream_->ProduceSynStreamFrame())); + return stream_->ProduceSynStreamFrame(); } private: @@ -79,9 +78,9 @@ class SpdyStream::SynStreamBufferProducer : public SpdyBufferProducer { // A wrapper around a stream that calls into ProduceHeaderFrame() with // a given header block. -class SpdyStream::HeaderBufferProducer : public SpdyBufferProducer { +class SpdyStream::HeaderFrameProducer : public SpdyFrameProducer { public: - HeaderBufferProducer(const base::WeakPtr<SpdyStream>& stream, + HeaderFrameProducer(const base::WeakPtr<SpdyStream>& stream, scoped_ptr<SpdyHeaderBlock> headers) : stream_(stream), headers_(headers.Pass()) { @@ -89,16 +88,15 @@ class SpdyStream::HeaderBufferProducer : public SpdyBufferProducer { DCHECK(headers_); } - virtual ~HeaderBufferProducer() {} + virtual ~HeaderFrameProducer() {} - virtual scoped_ptr<SpdyBuffer> ProduceBuffer() OVERRIDE { + virtual scoped_ptr<SpdyFrame> ProduceFrame() OVERRIDE { if (!stream_) { NOTREACHED(); - return scoped_ptr<SpdyBuffer>(); + return scoped_ptr<SpdyFrame>(); } DCHECK_GT(stream_->stream_id(), 0u); - return scoped_ptr<SpdyBuffer>( - new SpdyBuffer(stream_->ProduceHeaderFrame(headers_.Pass()))); + return stream_->ProduceHeaderFrame(headers_.Pass()); } private: @@ -177,17 +175,17 @@ void SpdyStream::PushedStreamReplayData() { return; } - std::vector<SpdyBuffer*> buffers; - pending_buffers_.release(&buffers); + std::vector<scoped_refptr<IOBufferWithSize> > buffers; + buffers.swap(pending_buffers_); for (size_t i = 0; i < buffers.size(); ++i) { // It is always possible that a callback to the delegate results in // the delegate no longer being available. if (!delegate_) break; if (buffers[i]) { - delegate_->OnDataReceived(scoped_ptr<SpdyBuffer>(buffers[i])); + delegate_->OnDataReceived(buffers[i]->data(), buffers[i]->size()); } else { - delegate_->OnDataReceived(scoped_ptr<SpdyBuffer>()); + delegate_->OnDataReceived(NULL, 0); session_->CloseStream(stream_id_, net::OK); // Note: |this| may be deleted after calling CloseStream. DCHECK_EQ(buffers.size() - 1, i); @@ -452,8 +450,9 @@ int SpdyStream::OnHeaders(const SpdyHeaderBlock& headers) { return rv; } -void SpdyStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { +void SpdyStream::OnDataReceived(const char* data, size_t length) { DCHECK(session_->IsStreamActive(stream_id_)); + DCHECK_LT(length, 1u << 24); // If we don't have a response, then the SYN_REPLY did not come through. // We cannot pass data up to the caller unless the reply headers have been // received. @@ -466,8 +465,10 @@ void SpdyStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { if (!delegate_ || continue_buffering_data_) { // It should be valid for this to happen in the server push case. // We'll return received data when delegate gets attached to the stream. - if (buffer) { - pending_buffers_.push_back(buffer.release()); + if (length > 0) { + IOBufferWithSize* buf = new IOBufferWithSize(length); + memcpy(buf->data(), data, length); + pending_buffers_.push_back(make_scoped_refptr(buf)); } else { pending_buffers_.push_back(NULL); metrics_.StopStream(); @@ -479,15 +480,14 @@ void SpdyStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { CHECK(!closed()); - if (!buffer) { + // A zero-length read means that the stream is being closed. + if (length == 0) { metrics_.StopStream(); session_->CloseStream(stream_id_, net::OK); // Note: |this| may be deleted after calling CloseStream. return; } - size_t length = buffer->GetRemainingSize(); - DCHECK_LE(length, session_->GetDataFrameMaximumPayload()); if (session_->flow_control_state() >= SpdySession::FLOW_CONTROL_STREAM) DecreaseRecvWindowSize(static_cast<int32>(length)); @@ -496,7 +496,7 @@ void SpdyStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { recv_bytes_ += length; recv_last_byte_time_ = base::TimeTicks::Now(); - if (delegate_->OnDataReceived(buffer.Pass()) != net::OK) { + if (delegate_->OnDataReceived(data, length) != net::OK) { // |delegate_| rejected the data. LogStreamError(ERR_SPDY_PROTOCOL_ERROR, "Delegate rejected the data"); session_->CloseStream(stream_id_, ERR_SPDY_PROTOCOL_ERROR); @@ -580,8 +580,8 @@ void SpdyStream::QueueHeaders(scoped_ptr<SpdyHeaderBlock> headers) { session_->EnqueueStreamWrite( this, HEADERS, - scoped_ptr<SpdyBufferProducer>( - new HeaderBufferProducer( + scoped_ptr<SpdyFrameProducer>( + new HeaderFrameProducer( weak_ptr_factory_.GetWeakPtr(), headers.Pass()))); } @@ -594,16 +594,15 @@ void SpdyStream::QueueStreamData(IOBuffer* data, CHECK_GT(stream_id_, 0u); CHECK(!cancelled()); - scoped_ptr<SpdyBuffer> data_buffer(session_->CreateDataBuffer( + scoped_ptr<SpdyFrame> data_frame(session_->CreateDataFrame( stream_id_, data, length, flags)); - // We'll get called again by PossiblyResumeIfSendStalled(). - if (!data_buffer) + if (!data_frame) return; session_->EnqueueStreamWrite( this, DATA, - scoped_ptr<SpdyBufferProducer>( - new SimpleBufferProducer(data_buffer.Pass()))); + scoped_ptr<SpdyFrameProducer>( + new SimpleFrameProducer(data_frame.Pass()))); } bool SpdyStream::GetSSLInfo(SSLInfo* ssl_info, @@ -785,9 +784,7 @@ int SpdyStream::DoSendDomainBoundCert() { // the state machine appropriately. session_->EnqueueStreamWrite( this, CREDENTIAL, - scoped_ptr<SpdyBufferProducer>( - new SimpleBufferProducer( - scoped_ptr<SpdyBuffer>(new SpdyBuffer(frame.Pass()))))); + scoped_ptr<SpdyFrameProducer>(new SimpleFrameProducer(frame.Pass()))); return ERR_IO_PENDING; } @@ -803,8 +800,8 @@ int SpdyStream::DoSendHeaders() { session_->EnqueueStreamWrite( this, SYN_STREAM, - scoped_ptr<SpdyBufferProducer>( - new SynStreamBufferProducer(weak_ptr_factory_.GetWeakPtr()))); + scoped_ptr<SpdyFrameProducer>( + new SynStreamFrameProducer(weak_ptr_factory_.GetWeakPtr()))); return ERR_IO_PENDING; } diff --git a/net/spdy/spdy_stream.h b/net/spdy/spdy_stream.h index fd145ea..881b48e 100644 --- a/net/spdy/spdy_stream.h +++ b/net/spdy/spdy_stream.h @@ -12,7 +12,6 @@ #include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" -#include "base/memory/scoped_vector.h" #include "base/memory/weak_ptr.h" #include "googleurl/src/gurl.h" #include "net/base/bandwidth_metrics.h" @@ -84,10 +83,9 @@ class NET_EXPORT_PRIVATE SpdyStream // Called when a HEADERS frame is sent. virtual void OnHeadersSent() = 0; - // Called when data is received. |buffer| may be NULL, which - // signals EOF. Must return OK if the data was received - // successfully, or a network error code otherwise. - virtual int OnDataReceived(scoped_ptr<SpdyBuffer> buffer) = 0; + // Called when data is received. + // Returns network error code. OK when it successfully receives data. + virtual int OnDataReceived(const char* data, int length) = 0; // Called when data is sent. virtual void OnDataSent(size_t bytes_sent) = 0; @@ -220,7 +218,7 @@ class NET_EXPORT_PRIVATE SpdyStream // // |length| is the number of bytes received (at most 2^24 - 1) or 0 if // the stream is being closed. - void OnDataReceived(scoped_ptr<SpdyBuffer> buffer); + void OnDataReceived(const char* buffer, size_t length); // Called by the SpdySession when a frame has been successfully and // completely written. |frame_size| is the total size of the frame @@ -291,8 +289,8 @@ class NET_EXPORT_PRIVATE SpdyStream int GetProtocolVersion() const; private: - class SynStreamBufferProducer; - class HeaderBufferProducer; + class SynStreamFrameProducer; + class HeaderFrameProducer; enum State { STATE_NONE, @@ -413,7 +411,7 @@ class NET_EXPORT_PRIVATE SpdyStream int recv_bytes_; // Data received before delegate is attached. - ScopedVector<SpdyBuffer> pending_buffers_; + std::vector<scoped_refptr<IOBufferWithSize> > pending_buffers_; SSLClientCertType domain_bound_cert_type_; std::string domain_bound_private_key_; diff --git a/net/spdy/spdy_stream_test_util.cc b/net/spdy/spdy_stream_test_util.cc index 0165c20..ac96cf9 100644 --- a/net/spdy/spdy_stream_test_util.cc +++ b/net/spdy/spdy_stream_test_util.cc @@ -37,7 +37,7 @@ int ClosingDelegate::OnResponseReceived(const SpdyHeaderBlock& response, void ClosingDelegate::OnHeadersSent() {} -int ClosingDelegate::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { +int ClosingDelegate::OnDataReceived(const char* data, int length) { return OK; } @@ -77,11 +77,8 @@ void StreamDelegateBase::OnHeadersSent() { headers_sent_++; } -int StreamDelegateBase::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { - if (buffer) { - received_data_ += std::string(buffer->GetRemainingData(), - buffer->GetRemainingSize()); - } +int StreamDelegateBase::OnDataReceived(const char* buffer, int bytes) { + received_data_ += std::string(buffer, bytes); return OK; } diff --git a/net/spdy/spdy_stream_test_util.h b/net/spdy/spdy_stream_test_util.h index a7ca912..5fc74af 100644 --- a/net/spdy/spdy_stream_test_util.h +++ b/net/spdy/spdy_stream_test_util.h @@ -32,7 +32,7 @@ class ClosingDelegate : public SpdyStream::Delegate { base::Time response_time, int status) OVERRIDE; virtual void OnHeadersSent() OVERRIDE; - virtual int OnDataReceived(scoped_ptr<SpdyBuffer> buffer) OVERRIDE; + virtual int OnDataReceived(const char* data, int length) OVERRIDE; virtual void OnDataSent(size_t bytes_sent) OVERRIDE; virtual void OnClose(int status) OVERRIDE; @@ -54,7 +54,7 @@ class StreamDelegateBase : public SpdyStream::Delegate { base::Time response_time, int status) OVERRIDE; virtual void OnHeadersSent() OVERRIDE; - virtual int OnDataReceived(scoped_ptr<SpdyBuffer> buffer) OVERRIDE; + virtual int OnDataReceived(const char* buffer, int bytes) OVERRIDE; virtual void OnDataSent(size_t bytes_sent) OVERRIDE; virtual void OnClose(int status) OVERRIDE; diff --git a/net/spdy/spdy_websocket_stream.cc b/net/spdy/spdy_websocket_stream.cc index a17ff73..1f80d48 100644 --- a/net/spdy/spdy_websocket_stream.cc +++ b/net/spdy/spdy_websocket_stream.cc @@ -8,8 +8,8 @@ #include "base/bind_helpers.h" #include "base/compiler_specific.h" #include "googleurl/src/gurl.h" -#include "net/base/io_buffer.h" #include "net/base/net_errors.h" +#include "net/base/io_buffer.h" #include "net/spdy/spdy_framer.h" #include "net/spdy/spdy_protocol.h" #include "net/spdy/spdy_session.h" @@ -116,9 +116,9 @@ void SpdyWebSocketStream::OnHeadersSent() { NOTREACHED(); } -int SpdyWebSocketStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { +int SpdyWebSocketStream::OnDataReceived(const char* data, int length) { DCHECK(delegate_); - delegate_->OnReceivedSpdyData(buffer.Pass()); + delegate_->OnReceivedSpdyData(data, length); return OK; } diff --git a/net/spdy/spdy_websocket_stream.h b/net/spdy/spdy_websocket_stream.h index 02f6c7c..2cef1c6 100644 --- a/net/spdy/spdy_websocket_stream.h +++ b/net/spdy/spdy_websocket_stream.h @@ -49,7 +49,7 @@ class NET_EXPORT_PRIVATE SpdyWebSocketStream virtual void OnSentSpdyData(size_t bytes_sent) = 0; // Called when data is received. - virtual void OnReceivedSpdyData(scoped_ptr<SpdyBuffer> buffer) = 0; + virtual void OnReceivedSpdyData(const char* data, int length) = 0; // Called when SpdyStream is closed. virtual void OnCloseSpdyStream() = 0; @@ -81,7 +81,7 @@ class NET_EXPORT_PRIVATE SpdyWebSocketStream base::Time response_time, int status) OVERRIDE; virtual void OnHeadersSent() OVERRIDE; - virtual int OnDataReceived(scoped_ptr<SpdyBuffer> buffer) OVERRIDE; + virtual int OnDataReceived(const char* data, int length) OVERRIDE; virtual void OnDataSent(size_t bytes_sent) OVERRIDE; virtual void OnClose(int status) OVERRIDE; diff --git a/net/spdy/spdy_websocket_stream_spdy2_unittest.cc b/net/spdy/spdy_websocket_stream_spdy2_unittest.cc index 695359f..b9b8ce3 100644 --- a/net/spdy/spdy_websocket_stream_spdy2_unittest.cc +++ b/net/spdy/spdy_websocket_stream_spdy2_unittest.cc @@ -116,19 +116,13 @@ class SpdyWebSocketStreamEventRecorder : public SpdyWebSocketStream::Delegate { if (!on_sent_data_.is_null()) on_sent_data_.Run(&events_.back()); } - virtual void OnReceivedSpdyData(scoped_ptr<SpdyBuffer> buffer) OVERRIDE { - std::string buffer_data; - size_t buffer_len = 0; - if (buffer) { - buffer_len = buffer->GetRemainingSize(); - buffer_data.append(buffer->GetRemainingData(), buffer_len); - } + virtual void OnReceivedSpdyData(const char* data, int length) OVERRIDE { events_.push_back( SpdyWebSocketStreamEvent( SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA, SpdyHeaderBlock(), - buffer_len, - buffer_data)); + length, + std::string(data, length))); if (!on_received_data_.is_null()) on_received_data_.Run(&events_.back()); } diff --git a/net/spdy/spdy_websocket_stream_spdy3_unittest.cc b/net/spdy/spdy_websocket_stream_spdy3_unittest.cc index 5b30a43..d008b1a 100644 --- a/net/spdy/spdy_websocket_stream_spdy3_unittest.cc +++ b/net/spdy/spdy_websocket_stream_spdy3_unittest.cc @@ -116,19 +116,13 @@ class SpdyWebSocketStreamEventRecorder : public SpdyWebSocketStream::Delegate { if (!on_sent_data_.is_null()) on_sent_data_.Run(&events_.back()); } - virtual void OnReceivedSpdyData(scoped_ptr<SpdyBuffer> buffer) OVERRIDE { - std::string buffer_data; - size_t buffer_len = 0; - if (buffer) { - buffer_len = buffer->GetRemainingSize(); - buffer_data.append(buffer->GetRemainingData(), buffer_len); - } + virtual void OnReceivedSpdyData(const char* data, int length) OVERRIDE { events_.push_back( SpdyWebSocketStreamEvent( SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA, SpdyHeaderBlock(), - buffer_len, - buffer_data)); + length, + std::string(data, length))); if (!on_received_data_.is_null()) on_received_data_.Run(&events_.back()); } diff --git a/net/spdy/spdy_write_queue.cc b/net/spdy/spdy_write_queue.cc index 18ddc39..f33cf62 100644 --- a/net/spdy/spdy_write_queue.cc +++ b/net/spdy/spdy_write_queue.cc @@ -7,8 +7,7 @@ #include <cstddef> #include "base/logging.h" -#include "net/spdy/spdy_buffer.h" -#include "net/spdy/spdy_buffer_producer.h" +#include "net/spdy/spdy_frame_producer.h" #include "net/spdy/spdy_stream.h" namespace net { @@ -17,7 +16,7 @@ SpdyWriteQueue::PendingWrite::PendingWrite() : frame_producer(NULL) {} SpdyWriteQueue::PendingWrite::PendingWrite( SpdyFrameType frame_type, - SpdyBufferProducer* frame_producer, + SpdyFrameProducer* frame_producer, const scoped_refptr<SpdyStream>& stream) : frame_type(frame_type), frame_producer(frame_producer), @@ -33,7 +32,7 @@ SpdyWriteQueue::~SpdyWriteQueue() { void SpdyWriteQueue::Enqueue(RequestPriority priority, SpdyFrameType frame_type, - scoped_ptr<SpdyBufferProducer> frame_producer, + scoped_ptr<SpdyFrameProducer> frame_producer, const scoped_refptr<SpdyStream>& stream) { if (stream.get()) { DCHECK_EQ(stream->priority(), priority); @@ -43,7 +42,7 @@ void SpdyWriteQueue::Enqueue(RequestPriority priority, } bool SpdyWriteQueue::Dequeue(SpdyFrameType* frame_type, - scoped_ptr<SpdyBufferProducer>* frame_producer, + scoped_ptr<SpdyFrameProducer>* frame_producer, scoped_refptr<SpdyStream>* stream) { for (int i = NUM_PRIORITIES - 1; i >= 0; --i) { if (!queue_[i].empty()) { diff --git a/net/spdy/spdy_write_queue.h b/net/spdy/spdy_write_queue.h index 1b8f1b8..996fca75 100644 --- a/net/spdy/spdy_write_queue.h +++ b/net/spdy/spdy_write_queue.h @@ -16,11 +16,10 @@ namespace net { -class SpdyBuffer; -class SpdyBufferProducer; +class SpdyFrameProducer; class SpdyStream; -// A queue of SpdyBufferProducers to produce frames to write. Ordered +// A queue of SpdyFrameProducers to produce frames to write. Ordered // by priority, and then FIFO. class NET_EXPORT_PRIVATE SpdyWriteQueue { public: @@ -33,7 +32,7 @@ class NET_EXPORT_PRIVATE SpdyWriteQueue { // is non-NULL, its priority must be equal to |priority|. void Enqueue(RequestPriority priority, SpdyFrameType frame_type, - scoped_ptr<SpdyBufferProducer> frame_producer, + scoped_ptr<SpdyFrameProducer> frame_producer, const scoped_refptr<SpdyStream>& stream); // Dequeues the frame producer with the highest priority that was @@ -41,7 +40,7 @@ class NET_EXPORT_PRIVATE SpdyWriteQueue { // fills in |frame_type|, |frame_producer|, and |stream| if // successful -- otherwise, just returns false. bool Dequeue(SpdyFrameType* frame_type, - scoped_ptr<SpdyBufferProducer>* frame_producer, + scoped_ptr<SpdyFrameProducer>* frame_producer, scoped_refptr<SpdyStream>* stream); // Removes all pending writes for the given stream, which must be @@ -57,12 +56,12 @@ class NET_EXPORT_PRIVATE SpdyWriteQueue { SpdyFrameType frame_type; // This has to be a raw pointer since we store this in an STL // container. - SpdyBufferProducer* frame_producer; + SpdyFrameProducer* frame_producer; scoped_refptr<SpdyStream> stream; PendingWrite(); PendingWrite(SpdyFrameType frame_type, - SpdyBufferProducer* frame_producer, + SpdyFrameProducer* frame_producer, const scoped_refptr<SpdyStream>& stream); ~PendingWrite(); }; diff --git a/net/spdy/spdy_write_queue_unittest.cc b/net/spdy/spdy_write_queue_unittest.cc index c98074f..e284619 100644 --- a/net/spdy/spdy_write_queue_unittest.cc +++ b/net/spdy/spdy_write_queue_unittest.cc @@ -14,7 +14,7 @@ #include "base/strings/string_number_conversions.h" #include "net/base/net_log.h" #include "net/base/request_priority.h" -#include "net/spdy/spdy_buffer_producer.h" +#include "net/spdy/spdy_frame_producer.h" #include "net/spdy/spdy_stream.h" #include "testing/gtest/include/gtest/gtest.h" @@ -26,33 +26,31 @@ class SpdyWriteQueueTest : public ::testing::Test {}; // Makes a SpdyFrameProducer producing a frame with the data in the // given string. -scoped_ptr<SpdyBufferProducer> StringToProducer(const std::string& s) { +scoped_ptr<SpdyFrameProducer> StringToProducer(const std::string& s) { scoped_ptr<char[]> data(new char[s.size()]); std::memcpy(data.get(), s.data(), s.size()); - return scoped_ptr<SpdyBufferProducer>( - new SimpleBufferProducer( - scoped_ptr<SpdyBuffer>( - new SpdyBuffer( - scoped_ptr<SpdyFrame>( - new SpdyFrame(data.release(), s.size(), true)))))); + return scoped_ptr<SpdyFrameProducer>( + new SimpleFrameProducer( + scoped_ptr<SpdyFrame>( + new SpdyFrame(data.release(), s.size(), true)))); } -// Makes a SpdyBufferProducer producing a frame with the data in the +// Makes a SpdyFrameProducer producing a frame with the data in the // given int (converted to a string). -scoped_ptr<SpdyBufferProducer> IntToProducer(int i) { +scoped_ptr<SpdyFrameProducer> IntToProducer(int i) { return StringToProducer(base::IntToString(i)); } // Produces a frame with the given producer and returns a copy of its // data as a string. -std::string ProducerToString(scoped_ptr<SpdyBufferProducer> producer) { - scoped_ptr<SpdyBuffer> buffer = producer->ProduceBuffer(); - return std::string(buffer->GetRemainingData(), buffer->GetRemainingSize()); +std::string ProducerToString(scoped_ptr<SpdyFrameProducer> producer) { + scoped_ptr<SpdyFrame> frame = producer->ProduceFrame(); + return std::string(frame->data(), frame->size()); } // Produces a frame with the given producer and returns a copy of its // data as an int (converted from a string). -int ProducerToInt(scoped_ptr<SpdyBufferProducer> producer) { +int ProducerToInt(scoped_ptr<SpdyFrameProducer> producer) { int i = 0; EXPECT_TRUE(base::StringToInt(ProducerToString(producer.Pass()), &i)); return i; @@ -71,9 +69,9 @@ SpdyStream* MakeTestStream(RequestPriority priority) { TEST_F(SpdyWriteQueueTest, DequeuesByPriority) { SpdyWriteQueue write_queue; - scoped_ptr<SpdyBufferProducer> producer_low = StringToProducer("LOW"); - scoped_ptr<SpdyBufferProducer> producer_medium = StringToProducer("MEDIUM"); - scoped_ptr<SpdyBufferProducer> producer_highest = StringToProducer("HIGHEST"); + scoped_ptr<SpdyFrameProducer> producer_low = StringToProducer("LOW"); + scoped_ptr<SpdyFrameProducer> producer_medium = StringToProducer("MEDIUM"); + scoped_ptr<SpdyFrameProducer> producer_highest = StringToProducer("HIGHEST"); // A NULL stream should still work. scoped_refptr<SpdyStream> stream_low(NULL); @@ -88,7 +86,7 @@ TEST_F(SpdyWriteQueueTest, DequeuesByPriority) { HIGHEST, RST_STREAM, producer_highest.Pass(), stream_highest); SpdyFrameType frame_type = DATA; - scoped_ptr<SpdyBufferProducer> frame_producer; + scoped_ptr<SpdyFrameProducer> frame_producer; scoped_refptr<SpdyStream> stream; ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); EXPECT_EQ(RST_STREAM, frame_type); @@ -113,9 +111,9 @@ TEST_F(SpdyWriteQueueTest, DequeuesByPriority) { TEST_F(SpdyWriteQueueTest, DequeuesFIFO) { SpdyWriteQueue write_queue; - scoped_ptr<SpdyBufferProducer> producer1 = IntToProducer(1); - scoped_ptr<SpdyBufferProducer> producer2 = IntToProducer(2); - scoped_ptr<SpdyBufferProducer> producer3 = IntToProducer(3); + scoped_ptr<SpdyFrameProducer> producer1 = IntToProducer(1); + scoped_ptr<SpdyFrameProducer> producer2 = IntToProducer(2); + scoped_ptr<SpdyFrameProducer> producer3 = IntToProducer(3); scoped_refptr<SpdyStream> stream1(MakeTestStream(DEFAULT_PRIORITY)); scoped_refptr<SpdyStream> stream2(MakeTestStream(DEFAULT_PRIORITY)); @@ -126,7 +124,7 @@ TEST_F(SpdyWriteQueueTest, DequeuesFIFO) { write_queue.Enqueue(DEFAULT_PRIORITY, RST_STREAM, producer3.Pass(), stream3); SpdyFrameType frame_type = DATA; - scoped_ptr<SpdyBufferProducer> frame_producer; + scoped_ptr<SpdyFrameProducer> frame_producer; scoped_refptr<SpdyStream> stream; ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); EXPECT_EQ(SYN_STREAM, frame_type); @@ -164,7 +162,7 @@ TEST_F(SpdyWriteQueueTest, RemovePendingWritesForStream) { for (int i = 0; i < 100; i += 3) { SpdyFrameType frame_type = DATA; - scoped_ptr<SpdyBufferProducer> frame_producer; + scoped_ptr<SpdyFrameProducer> frame_producer; scoped_refptr<SpdyStream> stream; ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); EXPECT_EQ(SYN_STREAM, frame_type); @@ -173,7 +171,7 @@ TEST_F(SpdyWriteQueueTest, RemovePendingWritesForStream) { } SpdyFrameType frame_type = DATA; - scoped_ptr<SpdyBufferProducer> frame_producer; + scoped_ptr<SpdyFrameProducer> frame_producer; scoped_refptr<SpdyStream> stream; EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); } @@ -191,11 +189,11 @@ TEST_F(SpdyWriteQueueTest, Clear) { write_queue.Clear(); SpdyFrameType frame_type = DATA; - scoped_ptr<SpdyBufferProducer> frame_producer; + scoped_ptr<SpdyFrameProducer> frame_producer; scoped_refptr<SpdyStream> stream; EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); } -} // namespace +} } // namespace net diff --git a/net/websockets/websocket_job.cc b/net/websockets/websocket_job.cc index 53e0eda..3aeb8aa 100644 --- a/net/websockets/websocket_job.cc +++ b/net/websockets/websocket_job.cc @@ -9,10 +9,10 @@ #include "base/bind.h" #include "base/lazy_instance.h" #include "googleurl/src/gurl.h" -#include "net/base/io_buffer.h" #include "net/base/net_errors.h" #include "net/base/net_log.h" #include "net/cookies/cookie_store.h" +#include "net/base/io_buffer.h" #include "net/http/http_network_session.h" #include "net/http/http_transaction_factory.h" #include "net/http/http_util.h" @@ -330,19 +330,14 @@ void WebSocketJob::OnSentSpdyData(size_t bytes_sent) { OnSentData(socket_, static_cast<int>(bytes_sent)); } -void WebSocketJob::OnReceivedSpdyData(scoped_ptr<SpdyBuffer> buffer) { +void WebSocketJob::OnReceivedSpdyData(const char* data, int length) { DCHECK_NE(INITIALIZED, state_); DCHECK_NE(CONNECTING, state_); if (state_ == CLOSED) return; if (!spdy_websocket_stream_.get()) return; - if (buffer) { - OnReceivedData(socket_, buffer->GetRemainingData(), - buffer->GetRemainingSize()); - } else { - OnReceivedData(socket_, NULL, 0); - } + OnReceivedData(socket_, data, length); } void WebSocketJob::OnCloseSpdyStream() { diff --git a/net/websockets/websocket_job.h b/net/websockets/websocket_job.h index 02e4dfd..29f327c 100644 --- a/net/websockets/websocket_job.h +++ b/net/websockets/websocket_job.h @@ -83,7 +83,7 @@ class NET_EXPORT WebSocketJob virtual int OnReceivedSpdyResponseHeader( const SpdyHeaderBlock& headers, int status) OVERRIDE; virtual void OnSentSpdyData(size_t bytes_sent) OVERRIDE; - virtual void OnReceivedSpdyData(scoped_ptr<SpdyBuffer> buffer) OVERRIDE; + virtual void OnReceivedSpdyData(const char* data, int length) OVERRIDE; virtual void OnCloseSpdyStream() OVERRIDE; private: |