websocket_job_unittest.cc revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/ref_counted.h"
93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_split.h"
103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_util.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "googleurl/src/gurl.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/cookie_policy.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/cookie_store.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_errors.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/sys_addrinfo.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/socket_stream/socket_stream.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request_context.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/websockets/websocket_job.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/websockets/websocket_throttle.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gmock/include/gmock/gmock.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/platform_test.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace net {
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MockSocketStream : public SocketStream {
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockSocketStream(const GURL& url, SocketStream::Delegate* delegate)
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : SocketStream(url, delegate) {}
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~MockSocketStream() {}
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Connect() {}
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool SendData(const char* data, int len) {
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    sent_data_ += std::string(data, len);
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Close() {}
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void RestartWithAuth(
403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      const string16& username, const string16& password) {}
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void DetachDelegate() {
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delegate_ = NULL;
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::string& sent_data() const {
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return sent_data_;
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string sent_data_;
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MockSocketStreamDelegate : public SocketStream::Delegate {
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockSocketStreamDelegate()
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : amount_sent_(0) {}
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~MockSocketStreamDelegate() {}
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnConnected(SocketStream* socket, int max_pending_send_allowed) {
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnSentData(SocketStream* socket, int amount_sent) {
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    amount_sent_ += amount_sent;
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnReceivedData(SocketStream* socket,
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              const char* data, int len) {
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    received_data_ += std::string(data, len);
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnClose(SocketStream* socket) {
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size_t amount_sent() const { return amount_sent_; }
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::string& received_data() const { return received_data_; }
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int amount_sent_;
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string received_data_;
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MockCookieStore : public CookieStore {
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct Entry {
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GURL url;
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string cookie_line;
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CookieOptions options;
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockCookieStore() {}
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool SetCookieWithOptions(const GURL& url,
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    const std::string& cookie_line,
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    const CookieOptions& options) {
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Entry entry;
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    entry.url = url;
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    entry.cookie_line = cookie_line;
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    entry.options = options;
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    entries_.push_back(entry);
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual std::string GetCookiesWithOptions(const GURL& url,
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            const CookieOptions& options) {
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string result;
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0; i < entries_.size(); i++) {
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Entry &entry = entries_[i];
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (url == entry.url) {
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (!result.empty()) {
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          result += "; ";
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        result += entry.cookie_line;
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return result;
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void DeleteCookie(const GURL& url,
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            const std::string& cookie_name) {}
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual CookieMonster* GetCookieMonster() { return NULL; }
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::vector<Entry>& entries() const { return entries_; }
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  friend class base::RefCountedThreadSafe<MockCookieStore>;
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~MockCookieStore() {}
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<Entry> entries_;
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MockCookiePolicy : public CookiePolicy,
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         public base::RefCountedThreadSafe<MockCookiePolicy> {
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockCookiePolicy() : allow_all_cookies_(true), callback_(NULL) {}
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_allow_all_cookies(bool allow_all_cookies) {
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    allow_all_cookies_ = allow_all_cookies;
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual int CanGetCookies(const GURL& url,
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            const GURL& first_party_for_cookies,
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            CompletionCallback* callback) {
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(!callback_);
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    callback_ = callback;
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->PostTask(
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        FROM_HERE, NewRunnableMethod(this, &MockCookiePolicy::OnCanGetCookies));
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return ERR_IO_PENDING;
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual int CanSetCookie(const GURL& url,
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           const GURL& first_party_for_cookies,
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           const std::string& cookie_line,
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           CompletionCallback* callback) {
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(!callback_);
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    callback_ = callback;
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->PostTask(
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        FROM_HERE, NewRunnableMethod(this, &MockCookiePolicy::OnCanSetCookie));
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return ERR_IO_PENDING;
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  friend class base::RefCountedThreadSafe<MockCookiePolicy>;
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~MockCookiePolicy() {}
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void OnCanGetCookies() {
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CompletionCallback* callback = callback_;
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    callback_ = NULL;
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (allow_all_cookies_)
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      callback->Run(OK);
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    else
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      callback->Run(ERR_ACCESS_DENIED);
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void OnCanSetCookie() {
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CompletionCallback* callback = callback_;
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    callback_ = NULL;
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (allow_all_cookies_)
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      callback->Run(OK);
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    else
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      callback->Run(ERR_ACCESS_DENIED);
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool allow_all_cookies_;
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CompletionCallback* callback_;
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MockURLRequestContext : public URLRequestContext {
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockURLRequestContext(CookieStore* cookie_store,
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        CookiePolicy* cookie_policy) {
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cookie_store_ = cookie_store;
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cookie_policy_ = cookie_policy;
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  friend class base::RefCountedThreadSafe<MockURLRequestContext>;
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~MockURLRequestContext() {}
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass WebSocketJobTest : public PlatformTest {
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void SetUp() {
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cookie_store_ = new MockCookieStore;
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cookie_policy_ = new MockCookiePolicy;
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    context_ = new MockURLRequestContext(
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        cookie_store_.get(), cookie_policy_.get());
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void TearDown() {
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cookie_store_ = NULL;
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cookie_policy_ = NULL;
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    context_ = NULL;
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    websocket_ = NULL;
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    socket_ = NULL;
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void InitWebSocketJob(const GURL& url, MockSocketStreamDelegate* delegate) {
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    websocket_ = new WebSocketJob(delegate);
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    socket_ = new MockSocketStream(url, websocket_.get());
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    websocket_->InitSocketStream(socket_.get());
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    websocket_->set_context(context_.get());
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    websocket_->state_ = WebSocketJob::CONNECTING;
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    struct addrinfo addr;
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    memset(&addr, 0, sizeof(struct addrinfo));
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    addr.ai_family = AF_INET;
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    addr.ai_addrlen = sizeof(struct sockaddr_in);
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    struct sockaddr_in sa_in;
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    memset(&sa_in, 0, sizeof(struct sockaddr_in));
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    memcpy(&sa_in.sin_addr, "\x7f\0\0\1", 4);
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    addr.ai_addr = reinterpret_cast<sockaddr*>(&sa_in);
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    addr.ai_next = NULL;
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    websocket_->addresses_.Copy(&addr, true);
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Singleton<WebSocketThrottle>::get()->PutInQueue(websocket_);
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebSocketJob::State GetWebSocketJobState() {
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return websocket_->state_;
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void CloseWebSocketJob() {
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (websocket_->socket_) {
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      websocket_->socket_->DetachDelegate();
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Singleton<WebSocketThrottle>::get()->RemoveFromQueue(websocket_);
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    websocket_->state_ = WebSocketJob::CLOSED;
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    websocket_->delegate_ = NULL;
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    websocket_->socket_ = NULL;
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<MockCookieStore> cookie_store_;
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<MockCookiePolicy> cookie_policy_;
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<MockURLRequestContext> context_;
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<WebSocketJob> websocket_;
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<MockSocketStream> socket_;
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(WebSocketJobTest, SimpleHandshake) {
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url("ws://example.com/demo");
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockSocketStreamDelegate delegate;
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitWebSocketJob(url, &delegate);
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char* kHandshakeRequestMessage =
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "GET /demo HTTP/1.1\r\n"
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Host: example.com\r\n"
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Connection: Upgrade\r\n"
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Key2: 12998 5 Y3 1  .P00\r\n"
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Protocol: sample\r\n"
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Upgrade: WebSocket\r\n"
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5\r\n"
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Origin: http://example.com\r\n"
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "\r\n"
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "^n:ds[4U";
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool sent = websocket_->SendData(kHandshakeRequestMessage,
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   strlen(kHandshakeRequestMessage));
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(true, sent);
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kHandshakeRequestMessage, socket_->sent_data());
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  websocket_->OnSentData(socket_.get(), strlen(kHandshakeRequestMessage));
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(strlen(kHandshakeRequestMessage), delegate.amount_sent());
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const char kHandshakeResponseMessage[] =
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Upgrade: WebSocket\r\n"
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Connection: Upgrade\r\n"
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Origin: http://example.com\r\n"
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Location: ws://example.com/demo\r\n"
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Protocol: sample\r\n"
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "\r\n"
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "8jKS'y:G*Co,Wxa-";
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  websocket_->OnReceivedData(socket_.get(),
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             kHandshakeResponseMessage,
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             strlen(kHandshakeResponseMessage));
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kHandshakeResponseMessage, delegate.received_data());
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(WebSocketJob::OPEN, GetWebSocketJobState());
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CloseWebSocketJob();
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(WebSocketJobTest, SlowHandshake) {
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url("ws://example.com/demo");
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockSocketStreamDelegate delegate;
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitWebSocketJob(url, &delegate);
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char* kHandshakeRequestMessage =
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "GET /demo HTTP/1.1\r\n"
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Host: example.com\r\n"
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Connection: Upgrade\r\n"
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Key2: 12998 5 Y3 1  .P00\r\n"
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Protocol: sample\r\n"
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Upgrade: WebSocket\r\n"
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5\r\n"
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Origin: http://example.com\r\n"
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "\r\n"
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "^n:ds[4U";
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool sent = websocket_->SendData(kHandshakeRequestMessage,
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   strlen(kHandshakeRequestMessage));
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(true, sent);
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We assume request is sent in one data chunk (from WebKit)
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We don't support streaming request.
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kHandshakeRequestMessage, socket_->sent_data());
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  websocket_->OnSentData(socket_.get(), strlen(kHandshakeRequestMessage));
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(strlen(kHandshakeRequestMessage), delegate.amount_sent());
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const char kHandshakeResponseMessage[] =
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Upgrade: WebSocket\r\n"
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Connection: Upgrade\r\n"
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Origin: http://example.com\r\n"
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Location: ws://example.com/demo\r\n"
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Protocol: sample\r\n"
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "\r\n"
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "8jKS'y:G*Co,Wxa-";
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<std::string> lines;
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SplitString(kHandshakeResponseMessage, '\n', &lines);
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < lines.size() - 2; i++) {
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string line = lines[i] + "\r\n";
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SCOPED_TRACE("Line: " + line);
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    websocket_->OnReceivedData(socket_,
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               line.c_str(),
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               line.size());
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->RunAllPending();
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(delegate.received_data().empty());
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  websocket_->OnReceivedData(socket_.get(), "\r\n", 2);
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(delegate.received_data().empty());
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  websocket_->OnReceivedData(socket_.get(), "8jKS'y:G*Co,Wxa-", 16);
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kHandshakeResponseMessage, delegate.received_data());
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(WebSocketJob::OPEN, GetWebSocketJobState());
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CloseWebSocketJob();
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(WebSocketJobTest, HandshakeWithCookie) {
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url("ws://example.com/demo");
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL cookieUrl("http://example.com/demo");
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CookieOptions cookie_options;
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cookie_store_->SetCookieWithOptions(
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      cookieUrl, "CR-test=1", cookie_options);
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cookie_options.set_include_httponly();
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cookie_store_->SetCookieWithOptions(
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      cookieUrl, "CR-test-httponly=1", cookie_options);
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockSocketStreamDelegate delegate;
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitWebSocketJob(url, &delegate);
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char* kHandshakeRequestMessage =
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "GET /demo HTTP/1.1\r\n"
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Host: example.com\r\n"
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Connection: Upgrade\r\n"
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Key2: 12998 5 Y3 1  .P00\r\n"
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Protocol: sample\r\n"
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Upgrade: WebSocket\r\n"
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5\r\n"
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Origin: http://example.com\r\n"
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Cookie: WK-test=1\r\n"
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "\r\n"
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "^n:ds[4U";
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char* kHandshakeRequestExpected =
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "GET /demo HTTP/1.1\r\n"
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Host: example.com\r\n"
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Connection: Upgrade\r\n"
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Key2: 12998 5 Y3 1  .P00\r\n"
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Protocol: sample\r\n"
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Upgrade: WebSocket\r\n"
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5\r\n"
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Origin: http://example.com\r\n"
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Cookie: CR-test=1; CR-test-httponly=1\r\n"
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "\r\n"
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "^n:ds[4U";
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool sent = websocket_->SendData(kHandshakeRequestMessage,
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   strlen(kHandshakeRequestMessage));
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(true, sent);
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kHandshakeRequestExpected, socket_->sent_data());
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  websocket_->OnSentData(socket_, strlen(kHandshakeRequestExpected));
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(strlen(kHandshakeRequestMessage), delegate.amount_sent());
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const char kHandshakeResponseMessage[] =
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Upgrade: WebSocket\r\n"
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Connection: Upgrade\r\n"
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Origin: http://example.com\r\n"
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Location: ws://example.com/demo\r\n"
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Protocol: sample\r\n"
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Set-Cookie: CR-set-test=1\r\n"
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "\r\n"
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "8jKS'y:G*Co,Wxa-";
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char* kHandshakeResponseExpected =
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Upgrade: WebSocket\r\n"
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Connection: Upgrade\r\n"
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Origin: http://example.com\r\n"
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Location: ws://example.com/demo\r\n"
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Protocol: sample\r\n"
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "\r\n"
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "8jKS'y:G*Co,Wxa-";
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  websocket_->OnReceivedData(socket_.get(),
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             kHandshakeResponseMessage,
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             strlen(kHandshakeResponseMessage));
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kHandshakeResponseExpected, delegate.received_data());
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(WebSocketJob::OPEN, GetWebSocketJobState());
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(3U, cookie_store_->entries().size());
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(cookieUrl, cookie_store_->entries()[0].url);
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("CR-test=1", cookie_store_->entries()[0].cookie_line);
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(cookieUrl, cookie_store_->entries()[1].url);
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("CR-test-httponly=1", cookie_store_->entries()[1].cookie_line);
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(cookieUrl, cookie_store_->entries()[2].url);
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("CR-set-test=1", cookie_store_->entries()[2].cookie_line);
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CloseWebSocketJob();
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(WebSocketJobTest, HandshakeWithCookieButNotAllowed) {
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url("ws://example.com/demo");
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL cookieUrl("http://example.com/demo");
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CookieOptions cookie_options;
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cookie_store_->SetCookieWithOptions(
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      cookieUrl, "CR-test=1", cookie_options);
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cookie_options.set_include_httponly();
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cookie_store_->SetCookieWithOptions(
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      cookieUrl, "CR-test-httponly=1", cookie_options);
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cookie_policy_->set_allow_all_cookies(false);
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockSocketStreamDelegate delegate;
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitWebSocketJob(url, &delegate);
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char* kHandshakeRequestMessage =
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "GET /demo HTTP/1.1\r\n"
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Host: example.com\r\n"
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Connection: Upgrade\r\n"
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Key2: 12998 5 Y3 1  .P00\r\n"
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Protocol: sample\r\n"
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Upgrade: WebSocket\r\n"
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5\r\n"
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Origin: http://example.com\r\n"
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Cookie: WK-test=1\r\n"
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "\r\n"
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "^n:ds[4U";
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char* kHandshakeRequestExpected =
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "GET /demo HTTP/1.1\r\n"
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Host: example.com\r\n"
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Connection: Upgrade\r\n"
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Key2: 12998 5 Y3 1  .P00\r\n"
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Protocol: sample\r\n"
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Upgrade: WebSocket\r\n"
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5\r\n"
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Origin: http://example.com\r\n"
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "\r\n"
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "^n:ds[4U";
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool sent = websocket_->SendData(kHandshakeRequestMessage,
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   strlen(kHandshakeRequestMessage));
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(true, sent);
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kHandshakeRequestExpected, socket_->sent_data());
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  websocket_->OnSentData(socket_, strlen(kHandshakeRequestExpected));
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(strlen(kHandshakeRequestMessage), delegate.amount_sent());
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const char kHandshakeResponseMessage[] =
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Upgrade: WebSocket\r\n"
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Connection: Upgrade\r\n"
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Origin: http://example.com\r\n"
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Location: ws://example.com/demo\r\n"
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Protocol: sample\r\n"
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Set-Cookie: CR-set-test=1\r\n"
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "\r\n"
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "8jKS'y:G*Co,Wxa-";
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const char* kHandshakeResponseExpected =
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Upgrade: WebSocket\r\n"
501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Connection: Upgrade\r\n"
502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Origin: http://example.com\r\n"
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Location: ws://example.com/demo\r\n"
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Sec-WebSocket-Protocol: sample\r\n"
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "\r\n"
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "8jKS'y:G*Co,Wxa-";
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  websocket_->OnReceivedData(socket_.get(),
509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             kHandshakeResponseMessage,
510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             strlen(kHandshakeResponseMessage));
511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kHandshakeResponseExpected, delegate.received_data());
513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(WebSocketJob::OPEN, GetWebSocketJobState());
514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2U, cookie_store_->entries().size());
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(cookieUrl, cookie_store_->entries()[0].url);
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("CR-test=1", cookie_store_->entries()[0].cookie_line);
518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(cookieUrl, cookie_store_->entries()[1].url);
519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("CR-test-httponly=1", cookie_store_->entries()[1].cookie_line);
520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CloseWebSocketJob();
522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace net
525