| Index: net/socket/web_socket_server_socket_unittest.cc
|
| diff --git a/net/socket/web_socket_server_socket_unittest.cc b/net/socket/web_socket_server_socket_unittest.cc
|
| deleted file mode 100644
|
| index 03bbca635a71f2b44e5fc3722d040b1688f05768..0000000000000000000000000000000000000000
|
| --- a/net/socket/web_socket_server_socket_unittest.cc
|
| +++ /dev/null
|
| @@ -1,591 +0,0 @@
|
| -// 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/socket/web_socket_server_socket.h"
|
| -
|
| -#include <stdlib.h>
|
| -#include <algorithm>
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/bind_helpers.h"
|
| -#include "base/memory/ref_counted.h"
|
| -#include "base/memory/weak_ptr.h"
|
| -#include "base/message_loop.h"
|
| -#include "base/string_util.h"
|
| -#include "base/time.h"
|
| -#include "net/base/io_buffer.h"
|
| -#include "net/base/net_errors.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -
|
| -namespace {
|
| -
|
| -const char* kSampleHandshakeRequest[] = {
|
| - "GET /demo HTTP/1.1",
|
| - "Upgrade: WebSocket",
|
| - "Connection: Upgrade",
|
| - "Host: example.com",
|
| - "Origin: http://example.com",
|
| - "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5",
|
| - "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00",
|
| - "",
|
| - "^n:ds[4U"
|
| -};
|
| -
|
| -const char kSampleHandshakeAnswer[] =
|
| - "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
|
| - "Upgrade: WebSocket\r\n"
|
| - "Connection: Upgrade\r\n"
|
| - "Sec-WebSocket-Location: ws://example.com/demo\r\n"
|
| - "Sec-WebSocket-Origin: http://example.com\r\n"
|
| - "\r\n"
|
| - "8jKS'y:G*Co,Wxa-";
|
| -
|
| -const int kHandshakeBufBytes = 1 << 12;
|
| -
|
| -const char kCRLF[] = "\r\n";
|
| -const char kCRLFCRLF[] = "\r\n\r\n";
|
| -const char kSpaceOctet = '\x20';
|
| -
|
| -const int kReadSalt = 7;
|
| -const int kWriteSalt = 5;
|
| -
|
| -int GetRand(int min, int max) {
|
| - CHECK(max >= min);
|
| - CHECK(max - min < RAND_MAX);
|
| - return rand() % (max - min + 1) + min;
|
| -}
|
| -
|
| -class RandIntClass {
|
| - public:
|
| - int operator() (int range) {
|
| - return GetRand(0, range - 1);
|
| - }
|
| -} g_rand;
|
| -
|
| -net::DrainableIOBuffer* ResizeIOBuffer(net::DrainableIOBuffer* buf, int len) {
|
| - net::DrainableIOBuffer* rv = new net::DrainableIOBuffer(
|
| - new net::IOBuffer(len), len);
|
| - std::copy(buf->data(), buf->data() + std::min(len, buf->BytesRemaining()),
|
| - rv->data());
|
| - return rv;
|
| -}
|
| -
|
| -// TODO(dilmah): consider switching to socket_test_util.h
|
| -// Simulates reading from |sample| stream; data supplied in Write() calls are
|
| -// stored in |answer| buffer.
|
| -class TestingTransportSocket : public net::Socket {
|
| - public:
|
| - TestingTransportSocket(
|
| - net::DrainableIOBuffer* sample, net::DrainableIOBuffer* answer)
|
| - : sample_(sample),
|
| - answer_(answer),
|
| - ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
|
| - }
|
| -
|
| - ~TestingTransportSocket() {
|
| - if (!final_read_callback_.is_null()) {
|
| - MessageLoop::current()->PostTask(FROM_HERE,
|
| - base::Bind(&TestingTransportSocket::DoReadCallback,
|
| - weak_factory_.GetWeakPtr(),
|
| - final_read_callback_, 0));
|
| - }
|
| - }
|
| -
|
| - // Socket implementation.
|
| - virtual int Read(net::IOBuffer* buf, int buf_len,
|
| - const net::CompletionCallback& callback) {
|
| - CHECK_GT(buf_len, 0);
|
| - int remaining = sample_->BytesRemaining();
|
| - if (remaining < 1) {
|
| - if (!final_read_callback_.is_null())
|
| - return 0;
|
| - final_read_callback_ = callback;
|
| - return net::ERR_IO_PENDING;
|
| - }
|
| - int lot = GetRand(1, std::min(remaining, buf_len));
|
| - std::copy(sample_->data(), sample_->data() + lot, buf->data());
|
| - sample_->DidConsume(lot);
|
| - if (GetRand(0, 1)) {
|
| - return lot;
|
| - }
|
| - MessageLoop::current()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&TestingTransportSocket::DoReadCallback,
|
| - weak_factory_.GetWeakPtr(), callback, lot));
|
| - return net::ERR_IO_PENDING;
|
| - }
|
| -
|
| - virtual int Write(net::IOBuffer* buf, int buf_len,
|
| - const net::CompletionCallback& callback) {
|
| - CHECK_GT(buf_len, 0);
|
| - int remaining = answer_->BytesRemaining();
|
| - CHECK_GE(remaining, buf_len);
|
| - int lot = std::min(remaining, buf_len);
|
| - if (GetRand(0, 1))
|
| - lot = GetRand(1, lot);
|
| - std::copy(buf->data(), buf->data() + lot, answer_->data());
|
| - answer_->DidConsume(lot);
|
| - if (GetRand(0, 1)) {
|
| - return lot;
|
| - }
|
| - MessageLoop::current()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&TestingTransportSocket::DoWriteCallback,
|
| - weak_factory_.GetWeakPtr(), callback, lot));
|
| - return net::ERR_IO_PENDING;
|
| - }
|
| -
|
| - virtual bool SetReceiveBufferSize(int32 size) {
|
| - return true;
|
| - }
|
| -
|
| - virtual bool SetSendBufferSize(int32 size) {
|
| - return true;
|
| - }
|
| -
|
| - net::DrainableIOBuffer* answer() { return answer_.get(); }
|
| -
|
| - void DoReadCallback(const net::CompletionCallback& callback, int result) {
|
| - if (result == 0 && !is_closed_) {
|
| - MessageLoop::current()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(
|
| - &TestingTransportSocket::DoReadCallback,
|
| - weak_factory_.GetWeakPtr(), callback, 0));
|
| - } else {
|
| - if (!callback.is_null())
|
| - callback.Run(result);
|
| - }
|
| - }
|
| -
|
| - void DoWriteCallback(const net::CompletionCallback& callback, int result) {
|
| - if (!callback.is_null())
|
| - callback.Run(result);
|
| - }
|
| -
|
| - bool is_closed_;
|
| -
|
| - // Data to return for Read requests.
|
| - scoped_refptr<net::DrainableIOBuffer> sample_;
|
| -
|
| - // Data pushed to us by server socket (using Write calls).
|
| - scoped_refptr<net::DrainableIOBuffer> answer_;
|
| -
|
| - // Final read callback to report zero (zero stands for EOF).
|
| - net::CompletionCallback final_read_callback_;
|
| -
|
| - base::WeakPtrFactory<TestingTransportSocket> weak_factory_;
|
| -};
|
| -
|
| -class Validator : public net::WebSocketServerSocket::Delegate {
|
| - public:
|
| - Validator(const std::string& resource,
|
| - const std::string& origin,
|
| - const std::string& host)
|
| - : resource_(resource), origin_(origin), host_(host) {
|
| - }
|
| -
|
| - // WebSocketServerSocket::Delegate implementation.
|
| - virtual bool ValidateWebSocket(
|
| - const std::string& resource,
|
| - const std::string& origin,
|
| - const std::string& host,
|
| - const std::vector<std::string>& subprotocol_list,
|
| - std::string* location_out,
|
| - std::string* subprotocol_out) {
|
| - if (resource != resource_ || origin != origin_ || host != host_)
|
| - return false;
|
| - if (!subprotocol_list.empty())
|
| - *subprotocol_out = subprotocol_list.front();
|
| -
|
| - char tmp[2048];
|
| - base::snprintf(
|
| - tmp, sizeof(tmp), "ws://%s%s", host.c_str(), resource.c_str());
|
| - location_out->assign(tmp);
|
| - return true;
|
| - }
|
| -
|
| - private:
|
| - std::string resource_;
|
| - std::string origin_;
|
| - std::string host_;
|
| -};
|
| -
|
| -char ReferenceSeq(unsigned n, unsigned salt) {
|
| - return (salt * 2 + n * 3) % ('z' - 'a') + 'a';
|
| -}
|
| -
|
| -class ReadWriteTracker {
|
| - public:
|
| - ReadWriteTracker(
|
| - net::WebSocketServerSocket* ws, int bytes_to_read, int bytes_to_write)
|
| - : ws_(ws),
|
| - buf_size_(1 << 14),
|
| - read_buf_(new net::IOBuffer(buf_size_)),
|
| - write_buf_(new net::IOBuffer(buf_size_)),
|
| - bytes_remaining_to_read_(bytes_to_read),
|
| - bytes_remaining_to_write_(bytes_to_write),
|
| - got_final_zero_(false) {
|
| - int rv = ws_->Accept(
|
| - base::Bind(&ReadWriteTracker::OnAccept, base::Unretained(this)));
|
| - if (rv != net::ERR_IO_PENDING)
|
| - OnAccept(rv);
|
| - }
|
| -
|
| - ~ReadWriteTracker() {
|
| - CHECK_EQ(bytes_remaining_to_write_, 0);
|
| - CHECK_EQ(bytes_remaining_to_read_, 0);
|
| - }
|
| -
|
| - void OnAccept(int result) {
|
| - ASSERT_EQ(result, 0);
|
| - if (GetRand(0, 1)) {
|
| - DoRead();
|
| - DoWrite();
|
| - } else {
|
| - DoWrite();
|
| - DoRead();
|
| - }
|
| - }
|
| -
|
| - void DoWrite() {
|
| - if (bytes_remaining_to_write_ < 1)
|
| - return;
|
| - int lot = GetRand(1, bytes_remaining_to_write_);
|
| - lot = std::min(lot, buf_size_);
|
| - for (int i = 0; i < lot; ++i)
|
| - write_buf_->data()[i] = ReferenceSeq(
|
| - bytes_remaining_to_write_ - i - 1, kWriteSalt);
|
| - int rv = ws_->Write(write_buf_, lot, base::Bind(&ReadWriteTracker::OnWrite,
|
| - base::Unretained(this)));
|
| - if (rv != net::ERR_IO_PENDING)
|
| - OnWrite(rv);
|
| - }
|
| -
|
| - void DoRead() {
|
| - int lot = GetRand(1, buf_size_);
|
| - if (bytes_remaining_to_read_ < 1) {
|
| - if (got_final_zero_)
|
| - return;
|
| - } else {
|
| - lot = GetRand(1, bytes_remaining_to_read_);
|
| - lot = std::min(lot, buf_size_);
|
| - }
|
| - int rv = ws_->Read(read_buf_, lot, base::Bind(&ReadWriteTracker::OnRead,
|
| - base::Unretained(this)));
|
| - if (rv != net::ERR_IO_PENDING)
|
| - OnRead(rv);
|
| - }
|
| -
|
| - void OnWrite(int result) {
|
| - ASSERT_GT(result, 0);
|
| - ASSERT_LE(result, bytes_remaining_to_write_);
|
| - bytes_remaining_to_write_ -= result;
|
| - DoWrite();
|
| - }
|
| -
|
| - void OnRead(int result) {
|
| - ASSERT_LE(result, bytes_remaining_to_read_);
|
| - if (bytes_remaining_to_read_ < 1) {
|
| - ASSERT_FALSE(got_final_zero_);
|
| - ASSERT_EQ(result, 0);
|
| - got_final_zero_ = true;
|
| - return;
|
| - }
|
| - for (int i = 0; i < result; ++i) {
|
| - ASSERT_EQ(read_buf_->data()[i], ReferenceSeq(
|
| - bytes_remaining_to_read_ - i - 1, kReadSalt));
|
| - }
|
| - bytes_remaining_to_read_ -= result;
|
| - DoRead();
|
| - }
|
| -
|
| - private:
|
| - net::WebSocketServerSocket* const ws_;
|
| - int const buf_size_;
|
| - scoped_refptr<net::IOBuffer> read_buf_;
|
| - scoped_refptr<net::IOBuffer> write_buf_;
|
| - int bytes_remaining_to_read_;
|
| - int bytes_remaining_to_write_;
|
| - bool got_final_zero_;
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| -namespace net {
|
| -
|
| -class WebSocketServerSocketTest : public testing::Test {
|
| - public:
|
| - virtual ~WebSocketServerSocketTest() {
|
| - }
|
| -
|
| - virtual void SetUp() {
|
| - count_ = 0;
|
| - }
|
| -
|
| - virtual void TearDown() {
|
| - }
|
| -
|
| - void OnAccept0(int result) {
|
| - ASSERT_EQ(result, 0);
|
| - ASSERT_LT(count_, 99999);
|
| - count_ += 1;
|
| - }
|
| -
|
| - void OnAccept1(int result) {
|
| - ASSERT_TRUE(result == ERR_CONNECTION_REFUSED ||
|
| - result == ERR_ACCESS_DENIED);
|
| - ASSERT_LT(count_, 99999);
|
| - count_ += 1;
|
| - }
|
| -
|
| - int count_;
|
| -};
|
| -
|
| -TEST_F(WebSocketServerSocketTest, Handshake) {
|
| - srand(2523456);
|
| - std::vector<Socket*> kill_list;
|
| - std::vector< scoped_refptr<DrainableIOBuffer> > answer_list;
|
| - Validator validator("/demo", "http://example.com/", "example.com");
|
| - count_ = 0;
|
| - const int kNumTests = 300;
|
| - for (int run = kNumTests; run--;) {
|
| - scoped_refptr<DrainableIOBuffer> sample = new DrainableIOBuffer(
|
| - new IOBuffer(kHandshakeBufBytes), kHandshakeBufBytes);
|
| - for (size_t i = 0; i < arraysize(kSampleHandshakeRequest); ++i) {
|
| - std::copy(kSampleHandshakeRequest[i],
|
| - kSampleHandshakeRequest[i] + strlen(kSampleHandshakeRequest[i]),
|
| - sample->data());
|
| - sample->DidConsume(strlen(kSampleHandshakeRequest[i]));
|
| - if (i != arraysize(kSampleHandshakeRequest) - 1) {
|
| - std::copy(kCRLF, kCRLF + strlen(kCRLF), sample->data());
|
| - sample->DidConsume(strlen(kCRLF));
|
| - }
|
| - }
|
| - int sample_len = sample->BytesConsumed();
|
| - sample->SetOffset(0);
|
| - DrainableIOBuffer* answer = new DrainableIOBuffer(
|
| - new IOBuffer(kHandshakeBufBytes), kHandshakeBufBytes);
|
| - answer_list.push_back(answer);
|
| - TestingTransportSocket* transport = new TestingTransportSocket(
|
| - ResizeIOBuffer(sample.get(), sample_len), answer);
|
| - WebSocketServerSocket* ws = CreateWebSocketServerSocket(
|
| - transport, &validator);
|
| - ASSERT_TRUE(ws != NULL);
|
| - kill_list.push_back(ws);
|
| -
|
| - int rv = ws->Accept(base::Bind(&WebSocketServerSocketTest::OnAccept0,
|
| - base::Unretained(this)));
|
| - if (rv != ERR_IO_PENDING)
|
| - OnAccept0(rv);
|
| - }
|
| - MessageLoop::current()->RunAllPending();
|
| - ASSERT_EQ(count_, kNumTests);
|
| - for (size_t i = answer_list.size(); i--;) {
|
| - ASSERT_EQ(answer_list[i]->BytesConsumed() + 0u,
|
| - strlen(kSampleHandshakeAnswer));
|
| - ASSERT_TRUE(std::equal(
|
| - answer_list[i]->data() - answer_list[i]->BytesConsumed(),
|
| - answer_list[i]->data(), kSampleHandshakeAnswer));
|
| - }
|
| - for (size_t i = kill_list.size(); i--;)
|
| - delete kill_list[i];
|
| - MessageLoop::current()->RunAllPending();
|
| -}
|
| -
|
| -TEST_F(WebSocketServerSocketTest, BadCred) {
|
| - srand(9034958);
|
| - std::vector<Socket*> kill_list;
|
| - std::vector< scoped_refptr<DrainableIOBuffer> > answer_list;
|
| - Validator *validator[] = {
|
| - new Validator("/demo", "http://gooogle.com/", "example.com"),
|
| - new Validator("/tcpproxy", "http://example.com/", "example.com"),
|
| - new Validator("/tcpproxy", "http://gooogle.com/", "example.com"),
|
| - new Validator("/demo", "http://example.com/", "exmple.com"),
|
| - new Validator("/demo", "http://gooogle.com/", "gooogle.com")
|
| - };
|
| - count_ = 0;
|
| - for (int run = arraysize(validator); run--;) {
|
| - scoped_refptr<DrainableIOBuffer> sample = new DrainableIOBuffer(
|
| - new IOBuffer(kHandshakeBufBytes), kHandshakeBufBytes);
|
| - for (size_t i = 0; i < arraysize(kSampleHandshakeRequest); ++i) {
|
| - std::copy(kSampleHandshakeRequest[i],
|
| - kSampleHandshakeRequest[i] + strlen(kSampleHandshakeRequest[i]),
|
| - sample->data());
|
| - sample->DidConsume(strlen(kSampleHandshakeRequest[i]));
|
| - if (i != arraysize(kSampleHandshakeRequest) - 1) {
|
| - std::copy(kCRLF, kCRLF + strlen(kCRLF), sample->data());
|
| - sample->DidConsume(strlen(kCRLF));
|
| - }
|
| - }
|
| - int sample_len = sample->BytesConsumed();
|
| - sample->SetOffset(0);
|
| - DrainableIOBuffer* answer = new DrainableIOBuffer(
|
| - new IOBuffer(kHandshakeBufBytes), kHandshakeBufBytes);
|
| - answer_list.push_back(answer);
|
| - TestingTransportSocket* transport = new TestingTransportSocket(
|
| - ResizeIOBuffer(sample.get(), sample_len), answer);
|
| - WebSocketServerSocket* ws = CreateWebSocketServerSocket(
|
| - transport, validator[run]);
|
| - ASSERT_TRUE(ws != NULL);
|
| - kill_list.push_back(ws);
|
| -
|
| - int rv = ws->Accept(base::Bind(&WebSocketServerSocketTest::OnAccept1,
|
| - base::Unretained(this)));
|
| - if (rv != ERR_IO_PENDING)
|
| - OnAccept1(rv);
|
| - }
|
| - MessageLoop::current()->RunAllPending();
|
| - ASSERT_EQ(count_ + 0u, arraysize(validator));
|
| - for (size_t i = answer_list.size(); i--;)
|
| - ASSERT_EQ(answer_list[i]->BytesConsumed(), 0);
|
| - for (size_t i = kill_list.size(); i--;)
|
| - delete kill_list[i];
|
| - for (size_t i = arraysize(validator); i--;)
|
| - delete validator[i];
|
| - MessageLoop::current()->RunAllPending();
|
| -}
|
| -
|
| -TEST_F(WebSocketServerSocketTest, ReorderedHandshake) {
|
| - srand(205643459);
|
| - std::vector<Socket*> kill_list;
|
| - std::vector< scoped_refptr<DrainableIOBuffer> > answer_list;
|
| - Validator validator("/demo", "http://example.com/", "example.com");
|
| - count_ = 0;
|
| - const int kNumTests = 200;
|
| - for (int run = kNumTests; run--;) {
|
| - scoped_refptr<DrainableIOBuffer> sample = new DrainableIOBuffer(
|
| - new IOBuffer(kHandshakeBufBytes), kHandshakeBufBytes);
|
| -
|
| - std::vector<size_t> fields_order;
|
| - for (size_t i = 0; i < arraysize(kSampleHandshakeRequest); ++i)
|
| - fields_order.push_back(i);
|
| - // One leading and two trailing lines of request are special, leave them.
|
| - std::random_shuffle(fields_order.begin() + 1,
|
| - fields_order.begin() + fields_order.size() - 3,
|
| - g_rand);
|
| -
|
| - for (size_t i = 0; i < arraysize(kSampleHandshakeRequest); ++i) {
|
| - size_t j = fields_order[i];
|
| - std::copy(kSampleHandshakeRequest[j],
|
| - kSampleHandshakeRequest[j] + strlen(kSampleHandshakeRequest[j]),
|
| - sample->data());
|
| - sample->DidConsume(strlen(kSampleHandshakeRequest[j]));
|
| - if (i != arraysize(kSampleHandshakeRequest) - 1) {
|
| - std::copy(kCRLF, kCRLF + strlen(kCRLF), sample->data());
|
| - sample->DidConsume(strlen(kCRLF));
|
| - }
|
| - }
|
| - int sample_len = sample->BytesConsumed();
|
| - sample->SetOffset(0);
|
| - DrainableIOBuffer* answer = new DrainableIOBuffer(
|
| - new IOBuffer(kHandshakeBufBytes), kHandshakeBufBytes);
|
| - answer_list.push_back(answer);
|
| - TestingTransportSocket* transport = new TestingTransportSocket(
|
| - ResizeIOBuffer(sample.get(), sample_len), answer);
|
| - WebSocketServerSocket* ws = CreateWebSocketServerSocket(
|
| - transport, &validator);
|
| - ASSERT_TRUE(ws != NULL);
|
| - kill_list.push_back(ws);
|
| -
|
| - int rv = ws->Accept(base::Bind(&WebSocketServerSocketTest::OnAccept0,
|
| - base::Unretained(this)));
|
| - if (rv != ERR_IO_PENDING)
|
| - OnAccept0(rv);
|
| - }
|
| - MessageLoop::current()->RunAllPending();
|
| - ASSERT_EQ(count_, kNumTests);
|
| - for (size_t i = answer_list.size(); i--;) {
|
| - ASSERT_EQ(answer_list[i]->BytesConsumed() + 0u,
|
| - strlen(kSampleHandshakeAnswer));
|
| - ASSERT_TRUE(std::equal(
|
| - answer_list[i]->data() - answer_list[i]->BytesConsumed(),
|
| - answer_list[i]->data(), kSampleHandshakeAnswer));
|
| - }
|
| - for (size_t i = kill_list.size(); i--;)
|
| - delete kill_list[i];
|
| - MessageLoop::current()->RunAllPending();
|
| -}
|
| -
|
| -TEST_F(WebSocketServerSocketTest, ConveyData) {
|
| - srand(8234523);
|
| - std::vector<Socket*> kill_list;
|
| - std::vector<ReadWriteTracker*> tracker_list;
|
| - Validator validator("/demo", "http://example.com/", "example.com");
|
| - count_ = 0;
|
| - const int kNumTests = 150;
|
| - for (int run = kNumTests; run--;) {
|
| - int bytes_to_read = GetRand(1, 1 << 14);
|
| - int bytes_to_write = GetRand(1, 1 << 14);
|
| - int frames_limit = GetRand(1, 1 << 10);
|
| - int sample_limit = kHandshakeBufBytes + bytes_to_write + frames_limit * 2;
|
| - scoped_refptr<DrainableIOBuffer> sample = new DrainableIOBuffer(
|
| - new IOBuffer(sample_limit), sample_limit);
|
| -
|
| - std::vector<size_t> fields_order;
|
| - for (size_t i = 0; i < arraysize(kSampleHandshakeRequest); ++i)
|
| - fields_order.push_back(i);
|
| - // One leading and two trailing lines of request are special, leave them.
|
| - std::random_shuffle(fields_order.begin() + 1,
|
| - fields_order.begin() + fields_order.size() - 3,
|
| - g_rand);
|
| -
|
| - for (size_t i = 0; i < arraysize(kSampleHandshakeRequest); ++i) {
|
| - size_t j = fields_order[i];
|
| - std::copy(kSampleHandshakeRequest[j],
|
| - kSampleHandshakeRequest[j] + strlen(kSampleHandshakeRequest[j]),
|
| - sample->data());
|
| - sample->DidConsume(strlen(kSampleHandshakeRequest[j]));
|
| - if (i != arraysize(kSampleHandshakeRequest) - 1) {
|
| - std::copy(kCRLF, kCRLF + strlen(kCRLF), sample->data());
|
| - sample->DidConsume(strlen(kCRLF));
|
| - }
|
| - }
|
| - {
|
| - bool outside_frame = true;
|
| - int pos = 0;
|
| - for (int i = 0; i < bytes_to_write; ++i) {
|
| - if (outside_frame) {
|
| - sample->data()[pos++] = '\x00';
|
| - outside_frame = false;
|
| - CHECK_GE(frames_limit, 1);
|
| - frames_limit -= 1;
|
| - }
|
| - sample->data()[pos++] = ReferenceSeq(bytes_to_write - i - 1, kReadSalt);
|
| - if ((frames_limit > 1 &&
|
| - GetRand(0, 1 + (bytes_to_write - i) / frames_limit) == 0) ||
|
| - i == bytes_to_write - 1) {
|
| - sample->data()[pos++] = '\xff';
|
| - outside_frame = true;
|
| - }
|
| - }
|
| - sample->DidConsume(pos);
|
| - }
|
| -
|
| - int sample_len = sample->BytesConsumed();
|
| - sample->SetOffset(0);
|
| - int answer_limit = kHandshakeBufBytes + bytes_to_read * 3;
|
| - DrainableIOBuffer* answer = new DrainableIOBuffer(
|
| - new IOBuffer(answer_limit), answer_limit);
|
| - TestingTransportSocket* transport = new TestingTransportSocket(
|
| - ResizeIOBuffer(sample.get(), sample_len), answer);
|
| - WebSocketServerSocket* ws = CreateWebSocketServerSocket(
|
| - transport, &validator);
|
| - ASSERT_TRUE(ws != NULL);
|
| - kill_list.push_back(ws);
|
| -
|
| - ReadWriteTracker* tracker = new ReadWriteTracker(
|
| - ws, bytes_to_write, bytes_to_read);
|
| - tracker_list.push_back(tracker);
|
| - }
|
| - MessageLoop::current()->RunAllPending();
|
| -
|
| - for (size_t i = kill_list.size(); i--;)
|
| - delete kill_list[i];
|
| - for (size_t i = tracker_list.size(); i--;)
|
| - delete tracker_list[i];
|
| - MessageLoop::current()->RunAllPending();
|
| -}
|
| -
|
| -} // namespace net
|
|
|