mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-24 14:26:09 +03:00
136 lines
4.2 KiB
C++
136 lines
4.2 KiB
C++
|
// 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 <cstring>
|
||
|
#include <string>
|
||
|
#include <utility>
|
||
|
|
||
|
#include "base/bind.h"
|
||
|
#include "base/callback.h"
|
||
|
#include "base/memory/ref_counted.h"
|
||
|
#include "base/stl_util.h"
|
||
|
#include "net/base/io_buffer.h"
|
||
|
#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
|
||
|
#include "testing/gtest/include/gtest/gtest.h"
|
||
|
|
||
|
namespace net {
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
const char kData[] = "hello!\0hi.";
|
||
|
const size_t kDataSize = base::size(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 spdy::SpdySerializedFrame and make sure its
|
||
|
// data points to the frame's underlying data.
|
||
|
TEST_F(SpdyBufferTest, FrameConstructor) {
|
||
|
SpdyBuffer buffer(std::make_unique<spdy::SpdySerializedFrame>(
|
||
|
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));
|
||
|
}
|
||
|
|
||
|
void IncrementBy(size_t* x,
|
||
|
SpdyBuffer::ConsumeSource expected_consume_source,
|
||
|
size_t delta,
|
||
|
SpdyBuffer::ConsumeSource consume_source) {
|
||
|
EXPECT_EQ(expected_consume_source, consume_source);
|
||
|
*x += delta;
|
||
|
}
|
||
|
|
||
|
// Construct a SpdyBuffer and call Consume() on it, which should
|
||
|
// update the remaining data pointer and size appropriately, as well
|
||
|
// as calling the consume callbacks.
|
||
|
TEST_F(SpdyBufferTest, Consume) {
|
||
|
SpdyBuffer buffer(kData, kDataSize);
|
||
|
|
||
|
size_t x1 = 0;
|
||
|
size_t x2 = 0;
|
||
|
buffer.AddConsumeCallback(
|
||
|
base::Bind(&IncrementBy, &x1, SpdyBuffer::CONSUME));
|
||
|
buffer.AddConsumeCallback(
|
||
|
base::Bind(&IncrementBy, &x2, SpdyBuffer::CONSUME));
|
||
|
|
||
|
EXPECT_EQ(std::string(kData, kDataSize), BufferToString(buffer));
|
||
|
|
||
|
buffer.Consume(5);
|
||
|
EXPECT_EQ(std::string(kData + 5, kDataSize - 5), BufferToString(buffer));
|
||
|
EXPECT_EQ(5u, x1);
|
||
|
EXPECT_EQ(5u, x2);
|
||
|
|
||
|
buffer.Consume(kDataSize - 5);
|
||
|
EXPECT_EQ(0u, buffer.GetRemainingSize());
|
||
|
EXPECT_EQ(kDataSize, x1);
|
||
|
EXPECT_EQ(kDataSize, x2);
|
||
|
}
|
||
|
|
||
|
// Construct a SpdyBuffer and attach a ConsumeCallback to it. The
|
||
|
// callback should be called when the SpdyBuffer is destroyed.
|
||
|
TEST_F(SpdyBufferTest, ConsumeOnDestruction) {
|
||
|
size_t x = 0;
|
||
|
|
||
|
{
|
||
|
SpdyBuffer buffer(kData, kDataSize);
|
||
|
buffer.AddConsumeCallback(
|
||
|
base::Bind(&IncrementBy, &x, SpdyBuffer::DISCARD));
|
||
|
}
|
||
|
|
||
|
EXPECT_EQ(kDataSize, x);
|
||
|
}
|
||
|
|
||
|
// 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));
|
||
|
}
|
||
|
|
||
|
// Make sure the IOBuffer returned by GetIOBufferForRemainingData()
|
||
|
// outlives the buffer itself.
|
||
|
TEST_F(SpdyBufferTest, IOBufferForRemainingDataOutlivesBuffer) {
|
||
|
auto buffer = std::make_unique<SpdyBuffer>(kData, kDataSize);
|
||
|
scoped_refptr<IOBuffer> io_buffer = buffer->GetIOBufferForRemainingData();
|
||
|
buffer.reset();
|
||
|
|
||
|
// This will cause a use-after-free error if |io_buffer| doesn't
|
||
|
// outlive |buffer|.
|
||
|
std::memcpy(io_buffer->data(), kData, kDataSize);
|
||
|
}
|
||
|
|
||
|
} // namespace
|
||
|
|
||
|
} // namespace net
|