// Copyright 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/websockets/websocket_job.h"

#include <string>
#include <vector>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "net/base/completion_callback.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/cookies/cookie_store.h"
#include "net/cookies/cookie_store_test_helpers.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_transaction_factory.h"
#include "net/http/transport_security_state.h"
#include "net/proxy/proxy_service.h"
#include "net/socket/next_proto.h"
#include "net/socket/socket_test_util.h"
#include "net/socket_stream/socket_stream.h"
#include "net/spdy/spdy_session.h"
#include "net/spdy/spdy_websocket_test_util.h"
#include "net/ssl/ssl_config_service.h"
#include "net/url_request/url_request_context.h"
#include "net/websockets/websocket_throttle.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
#include "url/gurl.h"

namespace net {

namespace {

class MockSocketStream : public SocketStream {
 public:
  MockSocketStream(const GURL& url, SocketStream::Delegate* delegate,
                   URLRequestContext* context, CookieStore* cookie_store)
      : SocketStream(url, delegate, context, cookie_store) {}

  void Connect() override {}
  bool SendData(const char* data, int len) override {
    sent_data_ += std::string(data, len);
    return true;
  }

  void Close() override {}
  void RestartWithAuth(const AuthCredentials& credentials) override {}

  void DetachDelegate() override { delegate_ = NULL; }

  const std::string& sent_data() const {
    return sent_data_;
  }

 protected:
  ~MockSocketStream() override {}

 private:
  std::string sent_data_;
};

class MockSocketStreamDelegate : public SocketStream::Delegate {
 public:
  MockSocketStreamDelegate()
      : amount_sent_(0), allow_all_cookies_(true) {}
  void set_allow_all_cookies(bool allow_all_cookies) {
    allow_all_cookies_ = allow_all_cookies;
  }
  ~MockSocketStreamDelegate() override {}

  void SetOnStartOpenConnection(const base::Closure& callback) {
    on_start_open_connection_ = callback;
  }
  void SetOnConnected(const base::Closure& callback) {
    on_connected_ = callback;
  }
  void SetOnSentData(const base::Closure& callback) {
    on_sent_data_ = callback;
  }
  void SetOnReceivedData(const base::Closure& callback) {
    on_received_data_ = callback;
  }
  void SetOnClose(const base::Closure& callback) {
    on_close_ = callback;
  }

  int OnStartOpenConnection(SocketStream* socket,
                            const CompletionCallback& callback) override {
    if (!on_start_open_connection_.is_null())
      on_start_open_connection_.Run();
    return OK;
  }
  void OnConnected(SocketStream* socket,
                   int max_pending_send_allowed) override {
    if (!on_connected_.is_null())
      on_connected_.Run();
  }
  void OnSentData(SocketStream* socket, int amount_sent) override {
    amount_sent_ += amount_sent;
    if (!on_sent_data_.is_null())
      on_sent_data_.Run();
  }
  void OnReceivedData(SocketStream* socket,
                      const char* data,
                      int len) override {
    received_data_ += std::string(data, len);
    if (!on_received_data_.is_null())
      on_received_data_.Run();
  }
  void OnClose(SocketStream* socket) override {
    if (!on_close_.is_null())
      on_close_.Run();
  }
  bool CanGetCookies(SocketStream* socket, const GURL& url) override {
    return allow_all_cookies_;
  }
  bool CanSetCookie(SocketStream* request,
                    const GURL& url,
                    const std::string& cookie_line,
                    CookieOptions* options) override {
    return allow_all_cookies_;
  }

  size_t amount_sent() const { return amount_sent_; }
  const std::string& received_data() const { return received_data_; }

 private:
  int amount_sent_;
  bool allow_all_cookies_;
  std::string received_data_;
  base::Closure on_start_open_connection_;
  base::Closure on_connected_;
  base::Closure on_sent_data_;
  base::Closure on_received_data_;
  base::Closure on_close_;
};

class MockCookieStore : public CookieStore {
 public:
  struct Entry {
    GURL url;
    std::string cookie_line;
    CookieOptions options;
  };

  MockCookieStore() {}

  bool SetCookieWithOptions(const GURL& url,
                            const std::string& cookie_line,
                            const CookieOptions& options) {
    Entry entry;
    entry.url = url;
    entry.cookie_line = cookie_line;
    entry.options = options;
    entries_.push_back(entry);
    return true;
  }

  std::string GetCookiesWithOptions(const GURL& url,
                                    const CookieOptions& options) {
    std::string result;
    for (size_t i = 0; i < entries_.size(); i++) {
      Entry& entry = entries_[i];
      if (url == entry.url) {
        if (!result.empty()) {
          result += "; ";
        }
        result += entry.cookie_line;
      }
    }
    return result;
  }

  // CookieStore:
  void SetCookieWithOptionsAsync(const GURL& url,
                                 const std::string& cookie_line,
                                 const CookieOptions& options,
                                 const SetCookiesCallback& callback) override {
    bool result = SetCookieWithOptions(url, cookie_line, options);
    if (!callback.is_null())
      callback.Run(result);
  }

  void GetCookiesWithOptionsAsync(const GURL& url,
                                  const CookieOptions& options,
                                  const GetCookiesCallback& callback) override {
    if (!callback.is_null())
      callback.Run(GetCookiesWithOptions(url, options));
  }

  void GetAllCookiesForURLAsync(
      const GURL& url,
      const GetCookieListCallback& callback) override {
    ADD_FAILURE();
  }

  void DeleteCookieAsync(const GURL& url,
                         const std::string& cookie_name,
                         const base::Closure& callback) override {
    ADD_FAILURE();
  }

  void DeleteAllCreatedBetweenAsync(const base::Time& delete_begin,
                                    const base::Time& delete_end,
                                    const DeleteCallback& callback) override {
    ADD_FAILURE();
  }

  void DeleteAllCreatedBetweenForHostAsync(
      const base::Time delete_begin,
      const base::Time delete_end,
      const GURL& url,
      const DeleteCallback& callback) override {
    ADD_FAILURE();
  }

  void DeleteSessionCookiesAsync(const DeleteCallback&) override {
    ADD_FAILURE();
  }

  CookieMonster* GetCookieMonster() override { return NULL; }

  const std::vector<Entry>& entries() const { return entries_; }

 private:
  friend class base::RefCountedThreadSafe<MockCookieStore>;
  ~MockCookieStore() override {}

  std::vector<Entry> entries_;
};

class MockSSLConfigService : public SSLConfigService {
 public:
  void GetSSLConfig(SSLConfig* config) override {}

 protected:
  ~MockSSLConfigService() override {}
};

class MockURLRequestContext : public URLRequestContext {
 public:
  explicit MockURLRequestContext(CookieStore* cookie_store)
      : transport_security_state_() {
    set_cookie_store(cookie_store);
    set_transport_security_state(&transport_security_state_);
    base::Time expiry = base::Time::Now() + base::TimeDelta::FromDays(1000);
    bool include_subdomains = false;
    transport_security_state_.AddHSTS("upgrademe.com", expiry,
                                      include_subdomains);
  }

  ~MockURLRequestContext() override { AssertNoURLRequests(); }

 private:
  TransportSecurityState transport_security_state_;
};

class MockHttpTransactionFactory : public HttpTransactionFactory {
 public:
  MockHttpTransactionFactory(NextProto next_proto,
                             OrderedSocketData* data,
                             bool enable_websocket_over_spdy) {
    data_ = data;
    MockConnect connect_data(SYNCHRONOUS, OK);
    data_->set_connect_data(connect_data);
    session_deps_.reset(new SpdySessionDependencies(next_proto));
    session_deps_->enable_websocket_over_spdy = enable_websocket_over_spdy;
    session_deps_->socket_factory->AddSocketDataProvider(data_);
    http_session_ =
        SpdySessionDependencies::SpdyCreateSession(session_deps_.get());
    host_port_pair_.set_host("example.com");
    host_port_pair_.set_port(80);
    spdy_session_key_ = SpdySessionKey(host_port_pair_,
                                            ProxyServer::Direct(),
                                            PRIVACY_MODE_DISABLED);
    session_ = CreateInsecureSpdySession(
        http_session_, spdy_session_key_, BoundNetLog());
  }

  int CreateTransaction(RequestPriority priority,
                        scoped_ptr<HttpTransaction>* trans) override {
    NOTREACHED();
    return ERR_UNEXPECTED;
  }

  HttpCache* GetCache() override {
    NOTREACHED();
    return NULL;
  }

  HttpNetworkSession* GetSession() override { return http_session_.get(); }

 private:
  OrderedSocketData* data_;
  scoped_ptr<SpdySessionDependencies> session_deps_;
  scoped_refptr<HttpNetworkSession> http_session_;
  base::WeakPtr<SpdySession> session_;
  HostPortPair host_port_pair_;
  SpdySessionKey spdy_session_key_;
};

class DeletingSocketStreamDelegate : public SocketStream::Delegate {
 public:
  DeletingSocketStreamDelegate()
      : delete_next_(false) {}

  // Since this class needs to be able to delete |job_|, it must be the only
  // reference holder (except for temporary references). Provide access to the
  // pointer for tests to use.
  WebSocketJob* job() { return job_.get(); }

  void set_job(WebSocketJob* job) { job_ = job; }

  // After calling this, the next call to a method on this delegate will delete
  // the WebSocketJob object.
  void set_delete_next(bool delete_next) { delete_next_ = delete_next; }

  void DeleteJobMaybe() {
    if (delete_next_) {
      job_->DetachContext();
      job_->DetachDelegate();
      job_ = NULL;
    }
  }

  // SocketStream::Delegate implementation

  // OnStartOpenConnection() is not implemented by SocketStreamDispatcherHost

  void OnConnected(SocketStream* socket,
                   int max_pending_send_allowed) override {
    DeleteJobMaybe();
  }

  void OnSentData(SocketStream* socket, int amount_sent) override {
    DeleteJobMaybe();
  }

  void OnReceivedData(SocketStream* socket,
                      const char* data,
                      int len) override {
    DeleteJobMaybe();
  }

  void OnClose(SocketStream* socket) override { DeleteJobMaybe(); }

  void OnAuthRequired(SocketStream* socket,
                      AuthChallengeInfo* auth_info) override {
    DeleteJobMaybe();
  }

  void OnSSLCertificateError(SocketStream* socket,
                             const SSLInfo& ssl_info,
                             bool fatal) override {
    DeleteJobMaybe();
  }

  void OnError(const SocketStream* socket, int error) override {
    DeleteJobMaybe();
  }

  // CanGetCookies() and CanSetCookies() do not appear to be able to delete the
  // WebSocketJob object.

 private:
  scoped_refptr<WebSocketJob> job_;
  bool delete_next_;
};

}  // namespace

class WebSocketJobTest : public PlatformTest,
                         public ::testing::WithParamInterface<NextProto> {
 public:
  WebSocketJobTest()
      : spdy_util_(GetParam()),
        enable_websocket_over_spdy_(false) {}

  virtual void SetUp() override {
    stream_type_ = STREAM_INVALID;
    cookie_store_ = new MockCookieStore;
    context_.reset(new MockURLRequestContext(cookie_store_.get()));
  }
  virtual void TearDown() override {
    cookie_store_ = NULL;
    context_.reset();
    websocket_ = NULL;
    socket_ = NULL;
  }
  void DoSendRequest() {
    EXPECT_TRUE(websocket_->SendData(kHandshakeRequestWithoutCookie,
                                     kHandshakeRequestWithoutCookieLength));
  }
  void DoSendData() {
    if (received_data().size() == kHandshakeResponseWithoutCookieLength)
      websocket_->SendData(kDataHello, kDataHelloLength);
  }
  void DoSync() {
    sync_test_callback_.callback().Run(OK);
  }
  int WaitForResult() {
    return sync_test_callback_.WaitForResult();
  }

 protected:
  enum StreamType {
    STREAM_INVALID,
    STREAM_MOCK_SOCKET,
    STREAM_SOCKET,
    STREAM_SPDY_WEBSOCKET,
  };
  enum ThrottlingOption {
    THROTTLING_OFF,
    THROTTLING_ON,
  };
  enum SpdyOption {
    SPDY_OFF,
    SPDY_ON,
  };
  void InitWebSocketJob(const GURL& url,
                        MockSocketStreamDelegate* delegate,
                        StreamType stream_type) {
    DCHECK_NE(STREAM_INVALID, stream_type);
    stream_type_ = stream_type;
    websocket_ = new WebSocketJob(delegate);

    if (stream_type == STREAM_MOCK_SOCKET)
      socket_ = new MockSocketStream(url, websocket_.get(), context_.get(),
                                     NULL);

    if (stream_type == STREAM_SOCKET || stream_type == STREAM_SPDY_WEBSOCKET) {
      if (stream_type == STREAM_SPDY_WEBSOCKET) {
        http_factory_.reset(new MockHttpTransactionFactory(
            GetParam(), data_.get(), enable_websocket_over_spdy_));
        context_->set_http_transaction_factory(http_factory_.get());
      }

      ssl_config_service_ = new MockSSLConfigService();
      context_->set_ssl_config_service(ssl_config_service_.get());
      proxy_service_.reset(ProxyService::CreateDirect());
      context_->set_proxy_service(proxy_service_.get());
      host_resolver_.reset(new MockHostResolver);
      context_->set_host_resolver(host_resolver_.get());

      socket_ = new SocketStream(url, websocket_.get(), context_.get(), NULL);
      socket_factory_.reset(new MockClientSocketFactory);
      DCHECK(data_.get());
      socket_factory_->AddSocketDataProvider(data_.get());
      socket_->SetClientSocketFactory(socket_factory_.get());
    }

    websocket_->InitSocketStream(socket_.get());
    // MockHostResolver resolves all hosts to 127.0.0.1; however, when we create
    // a WebSocketJob purely to block another one in a throttling test, we don't
    // perform a real connect. In that case, the following address is used
    // instead.
    IPAddressNumber ip;
    ParseIPLiteralToNumber("127.0.0.1", &ip);
    websocket_->addresses_ = AddressList::CreateFromIPAddress(ip, 80);
  }
  void SkipToConnecting() {
    websocket_->state_ = WebSocketJob::CONNECTING;
    ASSERT_TRUE(WebSocketThrottle::GetInstance()->PutInQueue(websocket_.get()));
  }
  WebSocketJob::State GetWebSocketJobState() {
    return websocket_->state_;
  }
  void CloseWebSocketJob() {
    if (websocket_->socket_.get()) {
      websocket_->socket_->DetachDelegate();
      WebSocketThrottle::GetInstance()->RemoveFromQueue(websocket_.get());
    }
    websocket_->state_ = WebSocketJob::CLOSED;
    websocket_->delegate_ = NULL;
    websocket_->socket_ = NULL;
  }
  SocketStream* GetSocket(SocketStreamJob* job) {
    return job->socket_.get();
  }
  const std::string& sent_data() const {
    DCHECK_EQ(STREAM_MOCK_SOCKET, stream_type_);
    MockSocketStream* socket =
        static_cast<MockSocketStream*>(socket_.get());
    DCHECK(socket);
    return socket->sent_data();
  }
  const std::string& received_data() const {
    DCHECK_NE(STREAM_INVALID, stream_type_);
    MockSocketStreamDelegate* delegate =
        static_cast<MockSocketStreamDelegate*>(websocket_->delegate_);
    DCHECK(delegate);
    return delegate->received_data();
  }

  void TestSimpleHandshake();
  void TestSlowHandshake();
  void TestHandshakeWithCookie();
  void TestHandshakeWithCookieButNotAllowed();
  void TestHSTSUpgrade();
  void TestInvalidSendData();
  void TestConnectByWebSocket(ThrottlingOption throttling);
  void TestConnectBySpdy(SpdyOption spdy, ThrottlingOption throttling);
  void TestThrottlingLimit();

  SpdyWebSocketTestUtil spdy_util_;
  StreamType stream_type_;
  scoped_refptr<MockCookieStore> cookie_store_;
  scoped_ptr<MockURLRequestContext> context_;
  scoped_refptr<WebSocketJob> websocket_;
  scoped_refptr<SocketStream> socket_;
  scoped_ptr<MockClientSocketFactory> socket_factory_;
  scoped_ptr<OrderedSocketData> data_;
  TestCompletionCallback sync_test_callback_;
  scoped_refptr<MockSSLConfigService> ssl_config_service_;
  scoped_ptr<ProxyService> proxy_service_;
  scoped_ptr<MockHostResolver> host_resolver_;
  scoped_ptr<MockHttpTransactionFactory> http_factory_;

  // Must be set before call to enable_websocket_over_spdy, defaults to false.
  bool enable_websocket_over_spdy_;

  static const char kHandshakeRequestWithoutCookie[];
  static const char kHandshakeRequestWithCookie[];
  static const char kHandshakeRequestWithFilteredCookie[];
  static const char kHandshakeResponseWithoutCookie[];
  static const char kHandshakeResponseWithCookie[];
  static const char kDataHello[];
  static const char kDataWorld[];
  static const char* const kHandshakeRequestForSpdy[];
  static const char* const kHandshakeResponseForSpdy[];
  static const size_t kHandshakeRequestWithoutCookieLength;
  static const size_t kHandshakeRequestWithCookieLength;
  static const size_t kHandshakeRequestWithFilteredCookieLength;
  static const size_t kHandshakeResponseWithoutCookieLength;
  static const size_t kHandshakeResponseWithCookieLength;
  static const size_t kDataHelloLength;
  static const size_t kDataWorldLength;
};

// Tests using this fixture verify that the WebSocketJob can handle being
// deleted while calling back to the delegate correctly. These tests need to be
// run under AddressSanitizer or other systems for detecting use-after-free
// errors in order to find problems.
class WebSocketJobDeleteTest : public ::testing::Test {
 protected:
  WebSocketJobDeleteTest()
      : delegate_(new DeletingSocketStreamDelegate),
        cookie_store_(new MockCookieStore),
        context_(new MockURLRequestContext(cookie_store_.get())) {
    WebSocketJob* websocket = new WebSocketJob(delegate_.get());
    delegate_->set_job(websocket);

    socket_ = new MockSocketStream(
        GURL("ws://127.0.0.1/"), websocket, context_.get(), NULL);

    websocket->InitSocketStream(socket_.get());
  }

  void SetDeleteNext() { return delegate_->set_delete_next(true); }
  WebSocketJob* job() { return delegate_->job(); }

  scoped_ptr<DeletingSocketStreamDelegate> delegate_;
  scoped_refptr<MockCookieStore> cookie_store_;
  scoped_ptr<MockURLRequestContext> context_;
  scoped_refptr<SocketStream> socket_;
};

const char WebSocketJobTest::kHandshakeRequestWithoutCookie[] =
    "GET /demo HTTP/1.1\r\n"
    "Host: example.com\r\n"
    "Upgrade: WebSocket\r\n"
    "Connection: Upgrade\r\n"
    "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
    "Origin: http://example.com\r\n"
    "Sec-WebSocket-Protocol: sample\r\n"
    "Sec-WebSocket-Version: 13\r\n"
    "\r\n";

const char WebSocketJobTest::kHandshakeRequestWithCookie[] =
    "GET /demo HTTP/1.1\r\n"
    "Host: example.com\r\n"
    "Upgrade: WebSocket\r\n"
    "Connection: Upgrade\r\n"
    "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
    "Origin: http://example.com\r\n"
    "Sec-WebSocket-Protocol: sample\r\n"
    "Sec-WebSocket-Version: 13\r\n"
    "Cookie: WK-test=1\r\n"
    "\r\n";

const char WebSocketJobTest::kHandshakeRequestWithFilteredCookie[] =
    "GET /demo HTTP/1.1\r\n"
    "Host: example.com\r\n"
    "Upgrade: WebSocket\r\n"
    "Connection: Upgrade\r\n"
    "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
    "Origin: http://example.com\r\n"
    "Sec-WebSocket-Protocol: sample\r\n"
    "Sec-WebSocket-Version: 13\r\n"
    "Cookie: CR-test=1; CR-test-httponly=1\r\n"
    "\r\n";

const char WebSocketJobTest::kHandshakeResponseWithoutCookie[] =
    "HTTP/1.1 101 Switching Protocols\r\n"
    "Upgrade: websocket\r\n"
    "Connection: Upgrade\r\n"
    "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
    "Sec-WebSocket-Protocol: sample\r\n"
    "\r\n";

const char WebSocketJobTest::kHandshakeResponseWithCookie[] =
    "HTTP/1.1 101 Switching Protocols\r\n"
    "Upgrade: websocket\r\n"
    "Connection: Upgrade\r\n"
    "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
    "Sec-WebSocket-Protocol: sample\r\n"
    "Set-Cookie: CR-set-test=1\r\n"
    "\r\n";

const char WebSocketJobTest::kDataHello[] = "Hello, ";

const char WebSocketJobTest::kDataWorld[] = "World!\n";

const size_t WebSocketJobTest::kHandshakeRequestWithoutCookieLength =
    arraysize(kHandshakeRequestWithoutCookie) - 1;
const size_t WebSocketJobTest::kHandshakeRequestWithCookieLength =
    arraysize(kHandshakeRequestWithCookie) - 1;
const size_t WebSocketJobTest::kHandshakeRequestWithFilteredCookieLength =
    arraysize(kHandshakeRequestWithFilteredCookie) - 1;
const size_t WebSocketJobTest::kHandshakeResponseWithoutCookieLength =
    arraysize(kHandshakeResponseWithoutCookie) - 1;
const size_t WebSocketJobTest::kHandshakeResponseWithCookieLength =
    arraysize(kHandshakeResponseWithCookie) - 1;
const size_t WebSocketJobTest::kDataHelloLength =
    arraysize(kDataHello) - 1;
const size_t WebSocketJobTest::kDataWorldLength =
    arraysize(kDataWorld) - 1;

void WebSocketJobTest::TestSimpleHandshake() {
  GURL url("ws://example.com/demo");
  MockSocketStreamDelegate delegate;
  InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET);
  SkipToConnecting();

  DoSendRequest();
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(kHandshakeRequestWithoutCookie, sent_data());
  EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
  websocket_->OnSentData(socket_.get(),
                         kHandshakeRequestWithoutCookieLength);
  EXPECT_EQ(kHandshakeRequestWithoutCookieLength, delegate.amount_sent());

  websocket_->OnReceivedData(socket_.get(),
                             kHandshakeResponseWithoutCookie,
                             kHandshakeResponseWithoutCookieLength);
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(kHandshakeResponseWithoutCookie, delegate.received_data());
  EXPECT_EQ(WebSocketJob::OPEN, GetWebSocketJobState());
  CloseWebSocketJob();
}

void WebSocketJobTest::TestSlowHandshake() {
  GURL url("ws://example.com/demo");
  MockSocketStreamDelegate delegate;
  InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET);
  SkipToConnecting();

  DoSendRequest();
  // We assume request is sent in one data chunk (from WebKit)
  // We don't support streaming request.
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(kHandshakeRequestWithoutCookie, sent_data());
  EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
  websocket_->OnSentData(socket_.get(),
                         kHandshakeRequestWithoutCookieLength);
  EXPECT_EQ(kHandshakeRequestWithoutCookieLength, delegate.amount_sent());

  std::vector<std::string> lines;
  base::SplitString(kHandshakeResponseWithoutCookie, '\n', &lines);
  for (size_t i = 0; i < lines.size() - 2; i++) {
    std::string line = lines[i] + "\r\n";
    SCOPED_TRACE("Line: " + line);
    websocket_->OnReceivedData(socket_.get(), line.c_str(), line.size());
    base::MessageLoop::current()->RunUntilIdle();
    EXPECT_TRUE(delegate.received_data().empty());
    EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
  }
  websocket_->OnReceivedData(socket_.get(), "\r\n", 2);
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_FALSE(delegate.received_data().empty());
  EXPECT_EQ(kHandshakeResponseWithoutCookie, delegate.received_data());
  EXPECT_EQ(WebSocketJob::OPEN, GetWebSocketJobState());
  CloseWebSocketJob();
}

INSTANTIATE_TEST_CASE_P(
    NextProto,
    WebSocketJobTest,
    testing::Values(kProtoDeprecatedSPDY2,
                    kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));

TEST_P(WebSocketJobTest, DelayedCookies) {
  enable_websocket_over_spdy_ = true;
  GURL url("ws://example.com/demo");
  GURL cookieUrl("http://example.com/demo");
  CookieOptions cookie_options;
  scoped_refptr<DelayedCookieMonster> cookie_store = new DelayedCookieMonster();
  context_->set_cookie_store(cookie_store.get());
  cookie_store->SetCookieWithOptionsAsync(cookieUrl,
                                          "CR-test=1",
                                          cookie_options,
                                          CookieMonster::SetCookiesCallback());
  cookie_options.set_include_httponly();
  cookie_store->SetCookieWithOptionsAsync(
      cookieUrl, "CR-test-httponly=1", cookie_options,
      CookieMonster::SetCookiesCallback());

  MockSocketStreamDelegate delegate;
  InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET);
  SkipToConnecting();

  bool sent = websocket_->SendData(kHandshakeRequestWithCookie,
                                   kHandshakeRequestWithCookieLength);
  EXPECT_TRUE(sent);
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(kHandshakeRequestWithFilteredCookie, sent_data());
  EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
  websocket_->OnSentData(socket_.get(),
                         kHandshakeRequestWithFilteredCookieLength);
  EXPECT_EQ(kHandshakeRequestWithCookieLength,
            delegate.amount_sent());

  websocket_->OnReceivedData(socket_.get(),
                             kHandshakeResponseWithCookie,
                             kHandshakeResponseWithCookieLength);
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(kHandshakeResponseWithoutCookie, delegate.received_data());
  EXPECT_EQ(WebSocketJob::OPEN, GetWebSocketJobState());

  CloseWebSocketJob();
}

void WebSocketJobTest::TestHandshakeWithCookie() {
  GURL url("ws://example.com/demo");
  GURL cookieUrl("http://example.com/demo");
  CookieOptions cookie_options;
  cookie_store_->SetCookieWithOptions(
      cookieUrl, "CR-test=1", cookie_options);
  cookie_options.set_include_httponly();
  cookie_store_->SetCookieWithOptions(
      cookieUrl, "CR-test-httponly=1", cookie_options);

  MockSocketStreamDelegate delegate;
  InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET);
  SkipToConnecting();

  bool sent = websocket_->SendData(kHandshakeRequestWithCookie,
                                   kHandshakeRequestWithCookieLength);
  EXPECT_TRUE(sent);
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(kHandshakeRequestWithFilteredCookie, sent_data());
  EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
  websocket_->OnSentData(socket_.get(),
                         kHandshakeRequestWithFilteredCookieLength);
  EXPECT_EQ(kHandshakeRequestWithCookieLength,
            delegate.amount_sent());

  websocket_->OnReceivedData(socket_.get(),
                             kHandshakeResponseWithCookie,
                             kHandshakeResponseWithCookieLength);
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(kHandshakeResponseWithoutCookie, delegate.received_data());
  EXPECT_EQ(WebSocketJob::OPEN, GetWebSocketJobState());

  EXPECT_EQ(3U, cookie_store_->entries().size());
  EXPECT_EQ(cookieUrl, cookie_store_->entries()[0].url);
  EXPECT_EQ("CR-test=1", cookie_store_->entries()[0].cookie_line);
  EXPECT_EQ(cookieUrl, cookie_store_->entries()[1].url);
  EXPECT_EQ("CR-test-httponly=1", cookie_store_->entries()[1].cookie_line);
  EXPECT_EQ(cookieUrl, cookie_store_->entries()[2].url);
  EXPECT_EQ("CR-set-test=1", cookie_store_->entries()[2].cookie_line);

  CloseWebSocketJob();
}

void WebSocketJobTest::TestHandshakeWithCookieButNotAllowed() {
  GURL url("ws://example.com/demo");
  GURL cookieUrl("http://example.com/demo");
  CookieOptions cookie_options;
  cookie_store_->SetCookieWithOptions(
      cookieUrl, "CR-test=1", cookie_options);
  cookie_options.set_include_httponly();
  cookie_store_->SetCookieWithOptions(
      cookieUrl, "CR-test-httponly=1", cookie_options);

  MockSocketStreamDelegate delegate;
  delegate.set_allow_all_cookies(false);
  InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET);
  SkipToConnecting();

  bool sent = websocket_->SendData(kHandshakeRequestWithCookie,
                                   kHandshakeRequestWithCookieLength);
  EXPECT_TRUE(sent);
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(kHandshakeRequestWithoutCookie, sent_data());
  EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
  websocket_->OnSentData(socket_.get(), kHandshakeRequestWithoutCookieLength);
  EXPECT_EQ(kHandshakeRequestWithCookieLength, delegate.amount_sent());

  websocket_->OnReceivedData(socket_.get(),
                             kHandshakeResponseWithCookie,
                             kHandshakeResponseWithCookieLength);
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(kHandshakeResponseWithoutCookie, delegate.received_data());
  EXPECT_EQ(WebSocketJob::OPEN, GetWebSocketJobState());

  EXPECT_EQ(2U, cookie_store_->entries().size());
  EXPECT_EQ(cookieUrl, cookie_store_->entries()[0].url);
  EXPECT_EQ("CR-test=1", cookie_store_->entries()[0].cookie_line);
  EXPECT_EQ(cookieUrl, cookie_store_->entries()[1].url);
  EXPECT_EQ("CR-test-httponly=1", cookie_store_->entries()[1].cookie_line);

  CloseWebSocketJob();
}

void WebSocketJobTest::TestHSTSUpgrade() {
  GURL url("ws://upgrademe.com/");
  MockSocketStreamDelegate delegate;
  scoped_refptr<SocketStreamJob> job =
      SocketStreamJob::CreateSocketStreamJob(
          url, &delegate, context_->transport_security_state(),
          context_->ssl_config_service(), NULL, NULL);
  EXPECT_TRUE(GetSocket(job.get())->is_secure());
  job->DetachDelegate();

  url = GURL("ws://donotupgrademe.com/");
  job = SocketStreamJob::CreateSocketStreamJob(
      url, &delegate, context_->transport_security_state(),
      context_->ssl_config_service(), NULL, NULL);
  EXPECT_FALSE(GetSocket(job.get())->is_secure());
  job->DetachDelegate();
}

void WebSocketJobTest::TestInvalidSendData() {
  GURL url("ws://example.com/demo");
  MockSocketStreamDelegate delegate;
  InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET);
  SkipToConnecting();

  DoSendRequest();
  // We assume request is sent in one data chunk (from WebKit)
  // We don't support streaming request.
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(kHandshakeRequestWithoutCookie, sent_data());
  EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
  websocket_->OnSentData(socket_.get(),
                         kHandshakeRequestWithoutCookieLength);
  EXPECT_EQ(kHandshakeRequestWithoutCookieLength, delegate.amount_sent());

  // We could not send any data until connection is established.
  bool sent = websocket_->SendData(kHandshakeRequestWithoutCookie,
                                   kHandshakeRequestWithoutCookieLength);
  EXPECT_FALSE(sent);
  EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
  CloseWebSocketJob();
}

// Following tests verify cooperation between WebSocketJob and SocketStream.
// Other former tests use MockSocketStream as SocketStream, so we could not
// check SocketStream behavior.
// OrderedSocketData provide socket level verifiation by checking out-going
// packets in comparison with the MockWrite array and emulating in-coming
// packets with MockRead array.

void WebSocketJobTest::TestConnectByWebSocket(
    ThrottlingOption throttling) {
  // This is a test for verifying cooperation between WebSocketJob and
  // SocketStream. If |throttling| was |THROTTLING_OFF|, it test basic
  // situation. If |throttling| was |THROTTLING_ON|, throttling limits the
  // latter connection.
  MockWrite writes[] = {
    MockWrite(ASYNC,
              kHandshakeRequestWithoutCookie,
              kHandshakeRequestWithoutCookieLength,
              1),
    MockWrite(ASYNC,
              kDataHello,
              kDataHelloLength,
              3)
  };
  MockRead reads[] = {
    MockRead(ASYNC,
             kHandshakeResponseWithoutCookie,
             kHandshakeResponseWithoutCookieLength,
             2),
    MockRead(ASYNC,
             kDataWorld,
             kDataWorldLength,
             4),
    MockRead(SYNCHRONOUS, 0, 5)  // EOF
  };
  data_.reset(new OrderedSocketData(
      reads, arraysize(reads), writes, arraysize(writes)));

  GURL url("ws://example.com/demo");
  MockSocketStreamDelegate delegate;
  WebSocketJobTest* test = this;
  if (throttling == THROTTLING_ON)
    delegate.SetOnStartOpenConnection(
        base::Bind(&WebSocketJobTest::DoSync, base::Unretained(test)));
  delegate.SetOnConnected(
      base::Bind(&WebSocketJobTest::DoSendRequest,
                 base::Unretained(test)));
  delegate.SetOnReceivedData(
      base::Bind(&WebSocketJobTest::DoSendData, base::Unretained(test)));
  delegate.SetOnClose(
      base::Bind(&WebSocketJobTest::DoSync, base::Unretained(test)));
  InitWebSocketJob(url, &delegate, STREAM_SOCKET);

  scoped_refptr<WebSocketJob> block_websocket;
  if (throttling == THROTTLING_ON) {
    // Create former WebSocket object which obstructs the latter one.
    block_websocket = new WebSocketJob(NULL);
    block_websocket->addresses_ = AddressList(websocket_->address_list());
    ASSERT_TRUE(
        WebSocketThrottle::GetInstance()->PutInQueue(block_websocket.get()));
  }

  websocket_->Connect();

  if (throttling == THROTTLING_ON) {
    EXPECT_EQ(OK, WaitForResult());
    EXPECT_TRUE(websocket_->IsWaiting());

    // Remove the former WebSocket object from throttling queue to unblock the
    // latter.
    block_websocket->state_ = WebSocketJob::CLOSED;
    WebSocketThrottle::GetInstance()->RemoveFromQueue(block_websocket.get());
    block_websocket = NULL;
  }

  EXPECT_EQ(OK, WaitForResult());
  EXPECT_TRUE(data_->at_read_eof());
  EXPECT_TRUE(data_->at_write_eof());
  EXPECT_EQ(WebSocketJob::CLOSED, GetWebSocketJobState());
}

void WebSocketJobTest::TestConnectBySpdy(
    SpdyOption spdy, ThrottlingOption throttling) {
  // This is a test for verifying cooperation between WebSocketJob and
  // SocketStream in the situation we have SPDY session to the server. If
  // |throttling| was |THROTTLING_ON|, throttling limits the latter connection.
  // If you enabled spdy, you should specify |spdy| as |SPDY_ON|. Expected
  // results depend on its configuration.
  MockWrite writes_websocket[] = {
    MockWrite(ASYNC,
              kHandshakeRequestWithoutCookie,
              kHandshakeRequestWithoutCookieLength,
              1),
    MockWrite(ASYNC,
              kDataHello,
              kDataHelloLength,
              3)
  };
  MockRead reads_websocket[] = {
    MockRead(ASYNC,
             kHandshakeResponseWithoutCookie,
             kHandshakeResponseWithoutCookieLength,
             2),
    MockRead(ASYNC,
             kDataWorld,
             kDataWorldLength,
             4),
    MockRead(SYNCHRONOUS, 0, 5)  // EOF
  };

  scoped_ptr<SpdyHeaderBlock> request_headers(new SpdyHeaderBlock());
  spdy_util_.SetHeader("path", "/demo", request_headers.get());
  spdy_util_.SetHeader("version", "WebSocket/13", request_headers.get());
  spdy_util_.SetHeader("scheme", "ws", request_headers.get());
  spdy_util_.SetHeader("host", "example.com", request_headers.get());
  spdy_util_.SetHeader("origin", "http://example.com", request_headers.get());
  spdy_util_.SetHeader("sec-websocket-protocol", "sample",
                       request_headers.get());

  scoped_ptr<SpdyHeaderBlock> response_headers(new SpdyHeaderBlock());
  spdy_util_.SetHeader("status", "101 Switching Protocols",
                       response_headers.get());
  spdy_util_.SetHeader("sec-websocket-protocol", "sample",
                       response_headers.get());

  const SpdyStreamId kStreamId = 1;
  scoped_ptr<SpdyFrame> request_frame(
      spdy_util_.ConstructSpdyWebSocketHandshakeRequestFrame(
          request_headers.Pass(),
          kStreamId,
          MEDIUM));
  scoped_ptr<SpdyFrame> response_frame(
      spdy_util_.ConstructSpdyWebSocketHandshakeResponseFrame(
          response_headers.Pass(),
          kStreamId,
          MEDIUM));
  scoped_ptr<SpdyFrame> data_hello_frame(
      spdy_util_.ConstructSpdyWebSocketDataFrame(
          kDataHello,
          kDataHelloLength,
          kStreamId,
          false));
  scoped_ptr<SpdyFrame> data_world_frame(
      spdy_util_.ConstructSpdyWebSocketDataFrame(
          kDataWorld,
          kDataWorldLength,
          kStreamId,
          false));
  MockWrite writes_spdy[] = {
    CreateMockWrite(*request_frame.get(), 1),
    CreateMockWrite(*data_hello_frame.get(), 3),
  };
  MockRead reads_spdy[] = {
    CreateMockRead(*response_frame.get(), 2),
    CreateMockRead(*data_world_frame.get(), 4),
    MockRead(SYNCHRONOUS, 0, 5)  // EOF
  };

  if (spdy == SPDY_ON)
    data_.reset(new OrderedSocketData(
        reads_spdy, arraysize(reads_spdy),
        writes_spdy, arraysize(writes_spdy)));
  else
    data_.reset(new OrderedSocketData(
        reads_websocket, arraysize(reads_websocket),
        writes_websocket, arraysize(writes_websocket)));

  GURL url("ws://example.com/demo");
  MockSocketStreamDelegate delegate;
  WebSocketJobTest* test = this;
  if (throttling == THROTTLING_ON)
    delegate.SetOnStartOpenConnection(
        base::Bind(&WebSocketJobTest::DoSync, base::Unretained(test)));
  delegate.SetOnConnected(
      base::Bind(&WebSocketJobTest::DoSendRequest,
                 base::Unretained(test)));
  delegate.SetOnReceivedData(
      base::Bind(&WebSocketJobTest::DoSendData, base::Unretained(test)));
  delegate.SetOnClose(
      base::Bind(&WebSocketJobTest::DoSync, base::Unretained(test)));
  InitWebSocketJob(url, &delegate, STREAM_SPDY_WEBSOCKET);

  scoped_refptr<WebSocketJob> block_websocket;
  if (throttling == THROTTLING_ON) {
    // Create former WebSocket object which obstructs the latter one.
    block_websocket = new WebSocketJob(NULL);
    block_websocket->addresses_ = AddressList(websocket_->address_list());
    ASSERT_TRUE(
        WebSocketThrottle::GetInstance()->PutInQueue(block_websocket.get()));
  }

  websocket_->Connect();

  if (throttling == THROTTLING_ON) {
    EXPECT_EQ(OK, WaitForResult());
    EXPECT_TRUE(websocket_->IsWaiting());

    // Remove the former WebSocket object from throttling queue to unblock the
    // latter.
    block_websocket->state_ = WebSocketJob::CLOSED;
    WebSocketThrottle::GetInstance()->RemoveFromQueue(block_websocket.get());
    block_websocket = NULL;
  }

  EXPECT_EQ(OK, WaitForResult());
  EXPECT_TRUE(data_->at_read_eof());
  EXPECT_TRUE(data_->at_write_eof());
  EXPECT_EQ(WebSocketJob::CLOSED, GetWebSocketJobState());
}

void WebSocketJobTest::TestThrottlingLimit() {
  std::vector<scoped_refptr<WebSocketJob> > jobs;
  const int kMaxWebSocketJobsThrottled = 1024;
  IPAddressNumber ip;
  ParseIPLiteralToNumber("127.0.0.1", &ip);
  for (int i = 0; i < kMaxWebSocketJobsThrottled + 1; ++i) {
    scoped_refptr<WebSocketJob> job = new WebSocketJob(NULL);
    job->addresses_ = AddressList(AddressList::CreateFromIPAddress(ip, 80));
    if (i >= kMaxWebSocketJobsThrottled)
      EXPECT_FALSE(WebSocketThrottle::GetInstance()->PutInQueue(job.get()));
    else
      EXPECT_TRUE(WebSocketThrottle::GetInstance()->PutInQueue(job.get()));
    jobs.push_back(job);
  }

  // Close the jobs in reverse order. Otherwise, We need to make them prepared
  // for Wakeup call.
  for (std::vector<scoped_refptr<WebSocketJob> >::reverse_iterator iter =
           jobs.rbegin();
       iter != jobs.rend();
       ++iter) {
    WebSocketJob* job = (*iter).get();
    job->state_ = WebSocketJob::CLOSED;
    WebSocketThrottle::GetInstance()->RemoveFromQueue(job);
  }
}

// Execute tests in both spdy-disabled mode and spdy-enabled mode.
TEST_P(WebSocketJobTest, SimpleHandshake) {
  TestSimpleHandshake();
}

TEST_P(WebSocketJobTest, SlowHandshake) {
  TestSlowHandshake();
}

TEST_P(WebSocketJobTest, HandshakeWithCookie) {
  TestHandshakeWithCookie();
}

TEST_P(WebSocketJobTest, HandshakeWithCookieButNotAllowed) {
  TestHandshakeWithCookieButNotAllowed();
}

TEST_P(WebSocketJobTest, HSTSUpgrade) {
  TestHSTSUpgrade();
}

TEST_P(WebSocketJobTest, InvalidSendData) {
  TestInvalidSendData();
}

TEST_P(WebSocketJobTest, SimpleHandshakeSpdyEnabled) {
  enable_websocket_over_spdy_ = true;
  TestSimpleHandshake();
}

TEST_P(WebSocketJobTest, SlowHandshakeSpdyEnabled) {
  enable_websocket_over_spdy_ = true;
  TestSlowHandshake();
}

TEST_P(WebSocketJobTest, HandshakeWithCookieSpdyEnabled) {
  enable_websocket_over_spdy_ = true;
  TestHandshakeWithCookie();
}

TEST_P(WebSocketJobTest, HandshakeWithCookieButNotAllowedSpdyEnabled) {
  enable_websocket_over_spdy_ = true;
  TestHandshakeWithCookieButNotAllowed();
}

TEST_P(WebSocketJobTest, HSTSUpgradeSpdyEnabled) {
  enable_websocket_over_spdy_ = true;
  TestHSTSUpgrade();
}

TEST_P(WebSocketJobTest, InvalidSendDataSpdyEnabled) {
  enable_websocket_over_spdy_ = true;
  TestInvalidSendData();
}

TEST_P(WebSocketJobTest, ConnectByWebSocket) {
  enable_websocket_over_spdy_ = true;
  TestConnectByWebSocket(THROTTLING_OFF);
}

TEST_P(WebSocketJobTest, ConnectByWebSocketSpdyEnabled) {
  enable_websocket_over_spdy_ = true;
  TestConnectByWebSocket(THROTTLING_OFF);
}

TEST_P(WebSocketJobTest, ConnectBySpdy) {
  TestConnectBySpdy(SPDY_OFF, THROTTLING_OFF);
}

TEST_P(WebSocketJobTest, ConnectBySpdySpdyEnabled) {
  enable_websocket_over_spdy_ = true;
  TestConnectBySpdy(SPDY_ON, THROTTLING_OFF);
}

TEST_P(WebSocketJobTest, ThrottlingWebSocket) {
  TestConnectByWebSocket(THROTTLING_ON);
}

TEST_P(WebSocketJobTest, ThrottlingMaxNumberOfThrottledJobLimit) {
  TestThrottlingLimit();
}

TEST_P(WebSocketJobTest, ThrottlingWebSocketSpdyEnabled) {
  enable_websocket_over_spdy_ = true;
  TestConnectByWebSocket(THROTTLING_ON);
}

TEST_P(WebSocketJobTest, ThrottlingSpdy) {
  TestConnectBySpdy(SPDY_OFF, THROTTLING_ON);
}

TEST_P(WebSocketJobTest, ThrottlingSpdySpdyEnabled) {
  enable_websocket_over_spdy_ = true;
  TestConnectBySpdy(SPDY_ON, THROTTLING_ON);
}

TEST_F(WebSocketJobDeleteTest, OnClose) {
  SetDeleteNext();
  job()->OnClose(socket_.get());
  // OnClose() sets WebSocketJob::_socket to NULL before we can detach it, so
  // socket_->delegate is still set at this point. Clear it to avoid hitting
  // DCHECK(!delegate_) in the SocketStream destructor. SocketStream::Finish()
  // is the only caller of this method in real code, and it also sets delegate_
  // to NULL.
  socket_->DetachDelegate();
  EXPECT_FALSE(job());
}

TEST_F(WebSocketJobDeleteTest, OnAuthRequired) {
  SetDeleteNext();
  job()->OnAuthRequired(socket_.get(), NULL);
  EXPECT_FALSE(job());
}

TEST_F(WebSocketJobDeleteTest, OnSSLCertificateError) {
  SSLInfo ssl_info;
  SetDeleteNext();
  job()->OnSSLCertificateError(socket_.get(), ssl_info, true);
  EXPECT_FALSE(job());
}

TEST_F(WebSocketJobDeleteTest, OnError) {
  SetDeleteNext();
  job()->OnError(socket_.get(), ERR_CONNECTION_RESET);
  EXPECT_FALSE(job());
}

TEST_F(WebSocketJobDeleteTest, OnSentSpdyHeaders) {
  job()->Connect();
  SetDeleteNext();
  job()->OnSentSpdyHeaders();
  EXPECT_FALSE(job());
}

TEST_F(WebSocketJobDeleteTest, OnSentHandshakeRequest) {
  static const char kMinimalRequest[] =
      "GET /demo HTTP/1.1\r\n"
      "Host: example.com\r\n"
      "Upgrade: WebSocket\r\n"
      "Connection: Upgrade\r\n"
      "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
      "Origin: http://example.com\r\n"
      "Sec-WebSocket-Version: 13\r\n"
      "\r\n";
  const size_t kMinimalRequestSize = arraysize(kMinimalRequest) - 1;
  job()->Connect();
  job()->SendData(kMinimalRequest, kMinimalRequestSize);
  SetDeleteNext();
  job()->OnSentData(socket_.get(), kMinimalRequestSize);
  EXPECT_FALSE(job());
}

TEST_F(WebSocketJobDeleteTest, NotifyHeadersComplete) {
  static const char kMinimalResponse[] =
      "HTTP/1.1 101 Switching Protocols\r\n"
      "Upgrade: websocket\r\n"
      "Connection: Upgrade\r\n"
      "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
      "\r\n";
  job()->Connect();
  SetDeleteNext();
  job()->OnReceivedData(
      socket_.get(), kMinimalResponse, arraysize(kMinimalResponse) - 1);
  EXPECT_FALSE(job());
}

// TODO(toyoshim): Add tests to verify throttling, SPDY stream limitation.
// TODO(toyoshim,yutak): Add tests to verify closing handshake.
}  // namespace net
