• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/websockets/websocket_job.h"
6 
7 #include <string>
8 #include <vector>
9 
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/callback.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/strings/string_split.h"
15 #include "base/strings/string_util.h"
16 #include "net/base/completion_callback.h"
17 #include "net/base/net_errors.h"
18 #include "net/base/test_completion_callback.h"
19 #include "net/cookies/cookie_store.h"
20 #include "net/cookies/cookie_store_test_helpers.h"
21 #include "net/dns/mock_host_resolver.h"
22 #include "net/http/http_transaction_factory.h"
23 #include "net/http/transport_security_state.h"
24 #include "net/proxy/proxy_service.h"
25 #include "net/socket/next_proto.h"
26 #include "net/socket/socket_test_util.h"
27 #include "net/socket_stream/socket_stream.h"
28 #include "net/spdy/spdy_session.h"
29 #include "net/spdy/spdy_websocket_test_util.h"
30 #include "net/ssl/ssl_config_service.h"
31 #include "net/url_request/url_request_context.h"
32 #include "net/websockets/websocket_throttle.h"
33 #include "testing/gmock/include/gmock/gmock.h"
34 #include "testing/gtest/include/gtest/gtest.h"
35 #include "testing/platform_test.h"
36 #include "url/gurl.h"
37 
38 namespace net {
39 
40 namespace {
41 
42 class MockSocketStream : public SocketStream {
43  public:
MockSocketStream(const GURL & url,SocketStream::Delegate * delegate)44   MockSocketStream(const GURL& url, SocketStream::Delegate* delegate)
45       : SocketStream(url, delegate) {}
46 
Connect()47   virtual void Connect() OVERRIDE {}
SendData(const char * data,int len)48   virtual bool SendData(const char* data, int len) OVERRIDE {
49     sent_data_ += std::string(data, len);
50     return true;
51   }
52 
Close()53   virtual void Close() OVERRIDE {}
RestartWithAuth(const AuthCredentials & credentials)54   virtual void RestartWithAuth(
55       const AuthCredentials& credentials) OVERRIDE {
56   }
57 
DetachDelegate()58   virtual void DetachDelegate() OVERRIDE {
59     delegate_ = NULL;
60   }
61 
sent_data() const62   const std::string& sent_data() const {
63     return sent_data_;
64   }
65 
66  protected:
~MockSocketStream()67   virtual ~MockSocketStream() {}
68 
69  private:
70   std::string sent_data_;
71 };
72 
73 class MockSocketStreamDelegate : public SocketStream::Delegate {
74  public:
MockSocketStreamDelegate()75   MockSocketStreamDelegate()
76       : amount_sent_(0), allow_all_cookies_(true) {}
set_allow_all_cookies(bool allow_all_cookies)77   void set_allow_all_cookies(bool allow_all_cookies) {
78     allow_all_cookies_ = allow_all_cookies;
79   }
~MockSocketStreamDelegate()80   virtual ~MockSocketStreamDelegate() {}
81 
SetOnStartOpenConnection(const base::Closure & callback)82   void SetOnStartOpenConnection(const base::Closure& callback) {
83     on_start_open_connection_ = callback;
84   }
SetOnConnected(const base::Closure & callback)85   void SetOnConnected(const base::Closure& callback) {
86     on_connected_ = callback;
87   }
SetOnSentData(const base::Closure & callback)88   void SetOnSentData(const base::Closure& callback) {
89     on_sent_data_ = callback;
90   }
SetOnReceivedData(const base::Closure & callback)91   void SetOnReceivedData(const base::Closure& callback) {
92     on_received_data_ = callback;
93   }
SetOnClose(const base::Closure & callback)94   void SetOnClose(const base::Closure& callback) {
95     on_close_ = callback;
96   }
97 
OnStartOpenConnection(SocketStream * socket,const CompletionCallback & callback)98   virtual int OnStartOpenConnection(
99       SocketStream* socket,
100       const CompletionCallback& callback) OVERRIDE {
101     if (!on_start_open_connection_.is_null())
102       on_start_open_connection_.Run();
103     return OK;
104   }
OnConnected(SocketStream * socket,int max_pending_send_allowed)105   virtual void OnConnected(SocketStream* socket,
106                            int max_pending_send_allowed) OVERRIDE {
107     if (!on_connected_.is_null())
108       on_connected_.Run();
109   }
OnSentData(SocketStream * socket,int amount_sent)110   virtual void OnSentData(SocketStream* socket,
111                           int amount_sent) OVERRIDE {
112     amount_sent_ += amount_sent;
113     if (!on_sent_data_.is_null())
114       on_sent_data_.Run();
115   }
OnReceivedData(SocketStream * socket,const char * data,int len)116   virtual void OnReceivedData(SocketStream* socket,
117                               const char* data, int len) OVERRIDE {
118     received_data_ += std::string(data, len);
119     if (!on_received_data_.is_null())
120       on_received_data_.Run();
121   }
OnClose(SocketStream * socket)122   virtual void OnClose(SocketStream* socket) OVERRIDE {
123     if (!on_close_.is_null())
124       on_close_.Run();
125   }
CanGetCookies(SocketStream * socket,const GURL & url)126   virtual bool CanGetCookies(SocketStream* socket,
127                              const GURL& url) OVERRIDE {
128     return allow_all_cookies_;
129   }
CanSetCookie(SocketStream * request,const GURL & url,const std::string & cookie_line,CookieOptions * options)130   virtual bool CanSetCookie(SocketStream* request,
131                             const GURL& url,
132                             const std::string& cookie_line,
133                             CookieOptions* options) OVERRIDE {
134     return allow_all_cookies_;
135   }
136 
amount_sent() const137   size_t amount_sent() const { return amount_sent_; }
received_data() const138   const std::string& received_data() const { return received_data_; }
139 
140  private:
141   int amount_sent_;
142   bool allow_all_cookies_;
143   std::string received_data_;
144   base::Closure on_start_open_connection_;
145   base::Closure on_connected_;
146   base::Closure on_sent_data_;
147   base::Closure on_received_data_;
148   base::Closure on_close_;
149 };
150 
151 class MockCookieStore : public CookieStore {
152  public:
153   struct Entry {
154     GURL url;
155     std::string cookie_line;
156     CookieOptions options;
157   };
158 
MockCookieStore()159   MockCookieStore() {}
160 
SetCookieWithOptions(const GURL & url,const std::string & cookie_line,const CookieOptions & options)161   bool SetCookieWithOptions(const GURL& url,
162                             const std::string& cookie_line,
163                             const CookieOptions& options) {
164     Entry entry;
165     entry.url = url;
166     entry.cookie_line = cookie_line;
167     entry.options = options;
168     entries_.push_back(entry);
169     return true;
170   }
171 
GetCookiesWithOptions(const GURL & url,const CookieOptions & options)172   std::string GetCookiesWithOptions(const GURL& url,
173                                     const CookieOptions& options) {
174     std::string result;
175     for (size_t i = 0; i < entries_.size(); i++) {
176       Entry& entry = entries_[i];
177       if (url == entry.url) {
178         if (!result.empty()) {
179           result += "; ";
180         }
181         result += entry.cookie_line;
182       }
183     }
184     return result;
185   }
186 
187   // CookieStore:
SetCookieWithOptionsAsync(const GURL & url,const std::string & cookie_line,const CookieOptions & options,const SetCookiesCallback & callback)188   virtual void SetCookieWithOptionsAsync(
189       const GURL& url,
190       const std::string& cookie_line,
191       const CookieOptions& options,
192       const SetCookiesCallback& callback) OVERRIDE {
193     bool result = SetCookieWithOptions(url, cookie_line, options);
194     if (!callback.is_null())
195       callback.Run(result);
196   }
197 
GetCookiesWithOptionsAsync(const GURL & url,const CookieOptions & options,const GetCookiesCallback & callback)198   virtual void GetCookiesWithOptionsAsync(
199       const GURL& url,
200       const CookieOptions& options,
201       const GetCookiesCallback& callback) OVERRIDE {
202     if (!callback.is_null())
203       callback.Run(GetCookiesWithOptions(url, options));
204   }
205 
DeleteCookieAsync(const GURL & url,const std::string & cookie_name,const base::Closure & callback)206   virtual void DeleteCookieAsync(const GURL& url,
207                                  const std::string& cookie_name,
208                                  const base::Closure& callback) OVERRIDE {
209     ADD_FAILURE();
210   }
211 
DeleteAllCreatedBetweenAsync(const base::Time & delete_begin,const base::Time & delete_end,const DeleteCallback & callback)212   virtual void DeleteAllCreatedBetweenAsync(
213       const base::Time& delete_begin,
214       const base::Time& delete_end,
215       const DeleteCallback& callback) OVERRIDE {
216     ADD_FAILURE();
217   }
218 
DeleteSessionCookiesAsync(const DeleteCallback &)219   virtual void DeleteSessionCookiesAsync(const DeleteCallback&) OVERRIDE {
220     ADD_FAILURE();
221   }
222 
GetCookieMonster()223   virtual CookieMonster* GetCookieMonster() OVERRIDE { return NULL; }
224 
entries() const225   const std::vector<Entry>& entries() const { return entries_; }
226 
227  private:
228   friend class base::RefCountedThreadSafe<MockCookieStore>;
~MockCookieStore()229   virtual ~MockCookieStore() {}
230 
231   std::vector<Entry> entries_;
232 };
233 
234 class MockSSLConfigService : public SSLConfigService {
235  public:
GetSSLConfig(SSLConfig * config)236   virtual void GetSSLConfig(SSLConfig* config) OVERRIDE {}
237 
238  protected:
~MockSSLConfigService()239   virtual ~MockSSLConfigService() {}
240 };
241 
242 class MockURLRequestContext : public URLRequestContext {
243  public:
MockURLRequestContext(CookieStore * cookie_store)244   explicit MockURLRequestContext(CookieStore* cookie_store)
245       : transport_security_state_() {
246     set_cookie_store(cookie_store);
247     set_transport_security_state(&transport_security_state_);
248     base::Time expiry = base::Time::Now() + base::TimeDelta::FromDays(1000);
249     bool include_subdomains = false;
250     transport_security_state_.AddHSTS("upgrademe.com", expiry,
251                                       include_subdomains);
252   }
253 
~MockURLRequestContext()254   virtual ~MockURLRequestContext() {}
255 
256  private:
257   TransportSecurityState transport_security_state_;
258 };
259 
260 class MockHttpTransactionFactory : public HttpTransactionFactory {
261  public:
MockHttpTransactionFactory(NextProto next_proto,OrderedSocketData * data)262   MockHttpTransactionFactory(NextProto next_proto, OrderedSocketData* data) {
263     data_ = data;
264     MockConnect connect_data(SYNCHRONOUS, OK);
265     data_->set_connect_data(connect_data);
266     session_deps_.reset(new SpdySessionDependencies(next_proto));
267     session_deps_->socket_factory->AddSocketDataProvider(data_);
268     http_session_ =
269         SpdySessionDependencies::SpdyCreateSession(session_deps_.get());
270     host_port_pair_.set_host("example.com");
271     host_port_pair_.set_port(80);
272     spdy_session_key_ = SpdySessionKey(host_port_pair_,
273                                             ProxyServer::Direct(),
274                                             kPrivacyModeDisabled);
275     session_ = CreateInsecureSpdySession(
276         http_session_, spdy_session_key_, BoundNetLog());
277   }
278 
CreateTransaction(RequestPriority priority,scoped_ptr<HttpTransaction> * trans,HttpTransactionDelegate * delegate)279   virtual int CreateTransaction(
280       RequestPriority priority,
281       scoped_ptr<HttpTransaction>* trans,
282       HttpTransactionDelegate* delegate) OVERRIDE {
283     NOTREACHED();
284     return ERR_UNEXPECTED;
285   }
286 
GetCache()287   virtual HttpCache* GetCache() OVERRIDE {
288     NOTREACHED();
289     return NULL;
290   }
291 
GetSession()292   virtual HttpNetworkSession* GetSession() OVERRIDE {
293     return http_session_.get();
294   }
295 
296  private:
297   OrderedSocketData* data_;
298   scoped_ptr<SpdySessionDependencies> session_deps_;
299   scoped_refptr<HttpNetworkSession> http_session_;
300   base::WeakPtr<SpdySession> session_;
301   HostPortPair host_port_pair_;
302   SpdySessionKey spdy_session_key_;
303 };
304 
305 }  // namespace
306 
307 class WebSocketJobTest : public PlatformTest,
308                          public ::testing::WithParamInterface<NextProto> {
309  public:
WebSocketJobTest()310   WebSocketJobTest() : spdy_util_(GetParam()) {}
311 
SetUp()312   virtual void SetUp() OVERRIDE {
313     stream_type_ = STREAM_INVALID;
314     cookie_store_ = new MockCookieStore;
315     context_.reset(new MockURLRequestContext(cookie_store_.get()));
316   }
TearDown()317   virtual void TearDown() OVERRIDE {
318     cookie_store_ = NULL;
319     context_.reset();
320     websocket_ = NULL;
321     socket_ = NULL;
322   }
DoSendRequest()323   void DoSendRequest() {
324     EXPECT_TRUE(websocket_->SendData(kHandshakeRequestWithoutCookie,
325                                      kHandshakeRequestWithoutCookieLength));
326   }
DoSendData()327   void DoSendData() {
328     if (received_data().size() == kHandshakeResponseWithoutCookieLength)
329       websocket_->SendData(kDataHello, kDataHelloLength);
330   }
DoSync()331   void DoSync() {
332     sync_test_callback_.callback().Run(OK);
333   }
WaitForResult()334   int WaitForResult() {
335     return sync_test_callback_.WaitForResult();
336   }
337  protected:
338   enum StreamType {
339     STREAM_INVALID,
340     STREAM_MOCK_SOCKET,
341     STREAM_SOCKET,
342     STREAM_SPDY_WEBSOCKET,
343   };
344   enum ThrottlingOption {
345     THROTTLING_OFF,
346     THROTTLING_ON,
347   };
348   enum SpdyOption {
349     SPDY_OFF,
350     SPDY_ON,
351   };
InitWebSocketJob(const GURL & url,MockSocketStreamDelegate * delegate,StreamType stream_type)352   void InitWebSocketJob(const GURL& url,
353                         MockSocketStreamDelegate* delegate,
354                         StreamType stream_type) {
355     DCHECK_NE(STREAM_INVALID, stream_type);
356     stream_type_ = stream_type;
357     websocket_ = new WebSocketJob(delegate);
358 
359     if (stream_type == STREAM_MOCK_SOCKET)
360       socket_ = new MockSocketStream(url, websocket_.get());
361 
362     if (stream_type == STREAM_SOCKET || stream_type == STREAM_SPDY_WEBSOCKET) {
363       if (stream_type == STREAM_SPDY_WEBSOCKET) {
364         http_factory_.reset(
365             new MockHttpTransactionFactory(GetParam(), data_.get()));
366         context_->set_http_transaction_factory(http_factory_.get());
367       }
368 
369       ssl_config_service_ = new MockSSLConfigService();
370       context_->set_ssl_config_service(ssl_config_service_.get());
371       proxy_service_.reset(ProxyService::CreateDirect());
372       context_->set_proxy_service(proxy_service_.get());
373       host_resolver_.reset(new MockHostResolver);
374       context_->set_host_resolver(host_resolver_.get());
375 
376       socket_ = new SocketStream(url, websocket_.get());
377       socket_factory_.reset(new MockClientSocketFactory);
378       DCHECK(data_.get());
379       socket_factory_->AddSocketDataProvider(data_.get());
380       socket_->SetClientSocketFactory(socket_factory_.get());
381     }
382 
383     websocket_->InitSocketStream(socket_.get());
384     websocket_->set_context(context_.get());
385     // MockHostResolver resolves all hosts to 127.0.0.1; however, when we create
386     // a WebSocketJob purely to block another one in a throttling test, we don't
387     // perform a real connect. In that case, the following address is used
388     // instead.
389     IPAddressNumber ip;
390     ParseIPLiteralToNumber("127.0.0.1", &ip);
391     websocket_->addresses_ = AddressList::CreateFromIPAddress(ip, 80);
392   }
SkipToConnecting()393   void SkipToConnecting() {
394     websocket_->state_ = WebSocketJob::CONNECTING;
395     ASSERT_TRUE(WebSocketThrottle::GetInstance()->PutInQueue(websocket_.get()));
396   }
GetWebSocketJobState()397   WebSocketJob::State GetWebSocketJobState() {
398     return websocket_->state_;
399   }
CloseWebSocketJob()400   void CloseWebSocketJob() {
401     if (websocket_->socket_.get()) {
402       websocket_->socket_->DetachDelegate();
403       WebSocketThrottle::GetInstance()->RemoveFromQueue(websocket_.get());
404     }
405     websocket_->state_ = WebSocketJob::CLOSED;
406     websocket_->delegate_ = NULL;
407     websocket_->socket_ = NULL;
408   }
GetSocket(SocketStreamJob * job)409   SocketStream* GetSocket(SocketStreamJob* job) {
410     return job->socket_.get();
411   }
sent_data() const412   const std::string& sent_data() const {
413     DCHECK_EQ(STREAM_MOCK_SOCKET, stream_type_);
414     MockSocketStream* socket =
415         static_cast<MockSocketStream*>(socket_.get());
416     DCHECK(socket);
417     return socket->sent_data();
418   }
received_data() const419   const std::string& received_data() const {
420     DCHECK_NE(STREAM_INVALID, stream_type_);
421     MockSocketStreamDelegate* delegate =
422         static_cast<MockSocketStreamDelegate*>(websocket_->delegate_);
423     DCHECK(delegate);
424     return delegate->received_data();
425   }
426 
427   void TestSimpleHandshake();
428   void TestSlowHandshake();
429   void TestHandshakeWithCookie();
430   void TestHandshakeWithCookieButNotAllowed();
431   void TestHSTSUpgrade();
432   void TestInvalidSendData();
433   void TestConnectByWebSocket(ThrottlingOption throttling);
434   void TestConnectBySpdy(SpdyOption spdy, ThrottlingOption throttling);
435   void TestThrottlingLimit();
436 
437   SpdyWebSocketTestUtil spdy_util_;
438   StreamType stream_type_;
439   scoped_refptr<MockCookieStore> cookie_store_;
440   scoped_ptr<MockURLRequestContext> context_;
441   scoped_refptr<WebSocketJob> websocket_;
442   scoped_refptr<SocketStream> socket_;
443   scoped_ptr<MockClientSocketFactory> socket_factory_;
444   scoped_ptr<OrderedSocketData> data_;
445   TestCompletionCallback sync_test_callback_;
446   scoped_refptr<MockSSLConfigService> ssl_config_service_;
447   scoped_ptr<ProxyService> proxy_service_;
448   scoped_ptr<MockHostResolver> host_resolver_;
449   scoped_ptr<MockHttpTransactionFactory> http_factory_;
450 
451   static const char kHandshakeRequestWithoutCookie[];
452   static const char kHandshakeRequestWithCookie[];
453   static const char kHandshakeRequestWithFilteredCookie[];
454   static const char kHandshakeResponseWithoutCookie[];
455   static const char kHandshakeResponseWithCookie[];
456   static const char kDataHello[];
457   static const char kDataWorld[];
458   static const char* const kHandshakeRequestForSpdy[];
459   static const char* const kHandshakeResponseForSpdy[];
460   static const size_t kHandshakeRequestWithoutCookieLength;
461   static const size_t kHandshakeRequestWithCookieLength;
462   static const size_t kHandshakeRequestWithFilteredCookieLength;
463   static const size_t kHandshakeResponseWithoutCookieLength;
464   static const size_t kHandshakeResponseWithCookieLength;
465   static const size_t kDataHelloLength;
466   static const size_t kDataWorldLength;
467 };
468 
469 const char WebSocketJobTest::kHandshakeRequestWithoutCookie[] =
470     "GET /demo HTTP/1.1\r\n"
471     "Host: example.com\r\n"
472     "Upgrade: WebSocket\r\n"
473     "Connection: Upgrade\r\n"
474     "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
475     "Origin: http://example.com\r\n"
476     "Sec-WebSocket-Protocol: sample\r\n"
477     "Sec-WebSocket-Version: 13\r\n"
478     "\r\n";
479 
480 const char WebSocketJobTest::kHandshakeRequestWithCookie[] =
481     "GET /demo HTTP/1.1\r\n"
482     "Host: example.com\r\n"
483     "Upgrade: WebSocket\r\n"
484     "Connection: Upgrade\r\n"
485     "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
486     "Origin: http://example.com\r\n"
487     "Sec-WebSocket-Protocol: sample\r\n"
488     "Sec-WebSocket-Version: 13\r\n"
489     "Cookie: WK-test=1\r\n"
490     "\r\n";
491 
492 const char WebSocketJobTest::kHandshakeRequestWithFilteredCookie[] =
493     "GET /demo HTTP/1.1\r\n"
494     "Host: example.com\r\n"
495     "Upgrade: WebSocket\r\n"
496     "Connection: Upgrade\r\n"
497     "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
498     "Origin: http://example.com\r\n"
499     "Sec-WebSocket-Protocol: sample\r\n"
500     "Sec-WebSocket-Version: 13\r\n"
501     "Cookie: CR-test=1; CR-test-httponly=1\r\n"
502     "\r\n";
503 
504 const char WebSocketJobTest::kHandshakeResponseWithoutCookie[] =
505     "HTTP/1.1 101 Switching Protocols\r\n"
506     "Upgrade: websocket\r\n"
507     "Connection: Upgrade\r\n"
508     "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
509     "Sec-WebSocket-Protocol: sample\r\n"
510     "\r\n";
511 
512 const char WebSocketJobTest::kHandshakeResponseWithCookie[] =
513     "HTTP/1.1 101 Switching Protocols\r\n"
514     "Upgrade: websocket\r\n"
515     "Connection: Upgrade\r\n"
516     "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
517     "Sec-WebSocket-Protocol: sample\r\n"
518     "Set-Cookie: CR-set-test=1\r\n"
519     "\r\n";
520 
521 const char WebSocketJobTest::kDataHello[] = "Hello, ";
522 
523 const char WebSocketJobTest::kDataWorld[] = "World!\n";
524 
525 const size_t WebSocketJobTest::kHandshakeRequestWithoutCookieLength =
526     arraysize(kHandshakeRequestWithoutCookie) - 1;
527 const size_t WebSocketJobTest::kHandshakeRequestWithCookieLength =
528     arraysize(kHandshakeRequestWithCookie) - 1;
529 const size_t WebSocketJobTest::kHandshakeRequestWithFilteredCookieLength =
530     arraysize(kHandshakeRequestWithFilteredCookie) - 1;
531 const size_t WebSocketJobTest::kHandshakeResponseWithoutCookieLength =
532     arraysize(kHandshakeResponseWithoutCookie) - 1;
533 const size_t WebSocketJobTest::kHandshakeResponseWithCookieLength =
534     arraysize(kHandshakeResponseWithCookie) - 1;
535 const size_t WebSocketJobTest::kDataHelloLength =
536     arraysize(kDataHello) - 1;
537 const size_t WebSocketJobTest::kDataWorldLength =
538     arraysize(kDataWorld) - 1;
539 
TestSimpleHandshake()540 void WebSocketJobTest::TestSimpleHandshake() {
541   GURL url("ws://example.com/demo");
542   MockSocketStreamDelegate delegate;
543   InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET);
544   SkipToConnecting();
545 
546   DoSendRequest();
547   base::MessageLoop::current()->RunUntilIdle();
548   EXPECT_EQ(kHandshakeRequestWithoutCookie, sent_data());
549   EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
550   websocket_->OnSentData(socket_.get(),
551                          kHandshakeRequestWithoutCookieLength);
552   EXPECT_EQ(kHandshakeRequestWithoutCookieLength, delegate.amount_sent());
553 
554   websocket_->OnReceivedData(socket_.get(),
555                              kHandshakeResponseWithoutCookie,
556                              kHandshakeResponseWithoutCookieLength);
557   base::MessageLoop::current()->RunUntilIdle();
558   EXPECT_EQ(kHandshakeResponseWithoutCookie, delegate.received_data());
559   EXPECT_EQ(WebSocketJob::OPEN, GetWebSocketJobState());
560   CloseWebSocketJob();
561 }
562 
TestSlowHandshake()563 void WebSocketJobTest::TestSlowHandshake() {
564   GURL url("ws://example.com/demo");
565   MockSocketStreamDelegate delegate;
566   InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET);
567   SkipToConnecting();
568 
569   DoSendRequest();
570   // We assume request is sent in one data chunk (from WebKit)
571   // We don't support streaming request.
572   base::MessageLoop::current()->RunUntilIdle();
573   EXPECT_EQ(kHandshakeRequestWithoutCookie, sent_data());
574   EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
575   websocket_->OnSentData(socket_.get(),
576                          kHandshakeRequestWithoutCookieLength);
577   EXPECT_EQ(kHandshakeRequestWithoutCookieLength, delegate.amount_sent());
578 
579   std::vector<std::string> lines;
580   base::SplitString(kHandshakeResponseWithoutCookie, '\n', &lines);
581   for (size_t i = 0; i < lines.size() - 2; i++) {
582     std::string line = lines[i] + "\r\n";
583     SCOPED_TRACE("Line: " + line);
584     websocket_->OnReceivedData(socket_.get(), line.c_str(), line.size());
585     base::MessageLoop::current()->RunUntilIdle();
586     EXPECT_TRUE(delegate.received_data().empty());
587     EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
588   }
589   websocket_->OnReceivedData(socket_.get(), "\r\n", 2);
590   base::MessageLoop::current()->RunUntilIdle();
591   EXPECT_FALSE(delegate.received_data().empty());
592   EXPECT_EQ(kHandshakeResponseWithoutCookie, delegate.received_data());
593   EXPECT_EQ(WebSocketJob::OPEN, GetWebSocketJobState());
594   CloseWebSocketJob();
595 }
596 
597 INSTANTIATE_TEST_CASE_P(
598     NextProto,
599     WebSocketJobTest,
600     testing::Values(kProtoDeprecatedSPDY2,
601                     kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
602                     kProtoHTTP2Draft04));
603 
TEST_P(WebSocketJobTest,DelayedCookies)604 TEST_P(WebSocketJobTest, DelayedCookies) {
605   WebSocketJob::set_websocket_over_spdy_enabled(true);
606   GURL url("ws://example.com/demo");
607   GURL cookieUrl("http://example.com/demo");
608   CookieOptions cookie_options;
609   scoped_refptr<DelayedCookieMonster> cookie_store = new DelayedCookieMonster();
610   context_->set_cookie_store(cookie_store.get());
611   cookie_store->SetCookieWithOptionsAsync(cookieUrl,
612                                           "CR-test=1",
613                                           cookie_options,
614                                           CookieMonster::SetCookiesCallback());
615   cookie_options.set_include_httponly();
616   cookie_store->SetCookieWithOptionsAsync(
617       cookieUrl, "CR-test-httponly=1", cookie_options,
618       CookieMonster::SetCookiesCallback());
619 
620   MockSocketStreamDelegate delegate;
621   InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET);
622   SkipToConnecting();
623 
624   bool sent = websocket_->SendData(kHandshakeRequestWithCookie,
625                                    kHandshakeRequestWithCookieLength);
626   EXPECT_TRUE(sent);
627   base::MessageLoop::current()->RunUntilIdle();
628   EXPECT_EQ(kHandshakeRequestWithFilteredCookie, sent_data());
629   EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
630   websocket_->OnSentData(socket_.get(),
631                          kHandshakeRequestWithFilteredCookieLength);
632   EXPECT_EQ(kHandshakeRequestWithCookieLength,
633             delegate.amount_sent());
634 
635   websocket_->OnReceivedData(socket_.get(),
636                              kHandshakeResponseWithCookie,
637                              kHandshakeResponseWithCookieLength);
638   base::MessageLoop::current()->RunUntilIdle();
639   EXPECT_EQ(kHandshakeResponseWithoutCookie, delegate.received_data());
640   EXPECT_EQ(WebSocketJob::OPEN, GetWebSocketJobState());
641 
642   CloseWebSocketJob();
643 }
644 
TestHandshakeWithCookie()645 void WebSocketJobTest::TestHandshakeWithCookie() {
646   GURL url("ws://example.com/demo");
647   GURL cookieUrl("http://example.com/demo");
648   CookieOptions cookie_options;
649   cookie_store_->SetCookieWithOptions(
650       cookieUrl, "CR-test=1", cookie_options);
651   cookie_options.set_include_httponly();
652   cookie_store_->SetCookieWithOptions(
653       cookieUrl, "CR-test-httponly=1", cookie_options);
654 
655   MockSocketStreamDelegate delegate;
656   InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET);
657   SkipToConnecting();
658 
659   bool sent = websocket_->SendData(kHandshakeRequestWithCookie,
660                                    kHandshakeRequestWithCookieLength);
661   EXPECT_TRUE(sent);
662   base::MessageLoop::current()->RunUntilIdle();
663   EXPECT_EQ(kHandshakeRequestWithFilteredCookie, sent_data());
664   EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
665   websocket_->OnSentData(socket_.get(),
666                          kHandshakeRequestWithFilteredCookieLength);
667   EXPECT_EQ(kHandshakeRequestWithCookieLength,
668             delegate.amount_sent());
669 
670   websocket_->OnReceivedData(socket_.get(),
671                              kHandshakeResponseWithCookie,
672                              kHandshakeResponseWithCookieLength);
673   base::MessageLoop::current()->RunUntilIdle();
674   EXPECT_EQ(kHandshakeResponseWithoutCookie, delegate.received_data());
675   EXPECT_EQ(WebSocketJob::OPEN, GetWebSocketJobState());
676 
677   EXPECT_EQ(3U, cookie_store_->entries().size());
678   EXPECT_EQ(cookieUrl, cookie_store_->entries()[0].url);
679   EXPECT_EQ("CR-test=1", cookie_store_->entries()[0].cookie_line);
680   EXPECT_EQ(cookieUrl, cookie_store_->entries()[1].url);
681   EXPECT_EQ("CR-test-httponly=1", cookie_store_->entries()[1].cookie_line);
682   EXPECT_EQ(cookieUrl, cookie_store_->entries()[2].url);
683   EXPECT_EQ("CR-set-test=1", cookie_store_->entries()[2].cookie_line);
684 
685   CloseWebSocketJob();
686 }
687 
TestHandshakeWithCookieButNotAllowed()688 void WebSocketJobTest::TestHandshakeWithCookieButNotAllowed() {
689   GURL url("ws://example.com/demo");
690   GURL cookieUrl("http://example.com/demo");
691   CookieOptions cookie_options;
692   cookie_store_->SetCookieWithOptions(
693       cookieUrl, "CR-test=1", cookie_options);
694   cookie_options.set_include_httponly();
695   cookie_store_->SetCookieWithOptions(
696       cookieUrl, "CR-test-httponly=1", cookie_options);
697 
698   MockSocketStreamDelegate delegate;
699   delegate.set_allow_all_cookies(false);
700   InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET);
701   SkipToConnecting();
702 
703   bool sent = websocket_->SendData(kHandshakeRequestWithCookie,
704                                    kHandshakeRequestWithCookieLength);
705   EXPECT_TRUE(sent);
706   base::MessageLoop::current()->RunUntilIdle();
707   EXPECT_EQ(kHandshakeRequestWithoutCookie, sent_data());
708   EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
709   websocket_->OnSentData(socket_.get(), kHandshakeRequestWithoutCookieLength);
710   EXPECT_EQ(kHandshakeRequestWithCookieLength, delegate.amount_sent());
711 
712   websocket_->OnReceivedData(socket_.get(),
713                              kHandshakeResponseWithCookie,
714                              kHandshakeResponseWithCookieLength);
715   base::MessageLoop::current()->RunUntilIdle();
716   EXPECT_EQ(kHandshakeResponseWithoutCookie, delegate.received_data());
717   EXPECT_EQ(WebSocketJob::OPEN, GetWebSocketJobState());
718 
719   EXPECT_EQ(2U, cookie_store_->entries().size());
720   EXPECT_EQ(cookieUrl, cookie_store_->entries()[0].url);
721   EXPECT_EQ("CR-test=1", cookie_store_->entries()[0].cookie_line);
722   EXPECT_EQ(cookieUrl, cookie_store_->entries()[1].url);
723   EXPECT_EQ("CR-test-httponly=1", cookie_store_->entries()[1].cookie_line);
724 
725   CloseWebSocketJob();
726 }
727 
TestHSTSUpgrade()728 void WebSocketJobTest::TestHSTSUpgrade() {
729   GURL url("ws://upgrademe.com/");
730   MockSocketStreamDelegate delegate;
731   scoped_refptr<SocketStreamJob> job =
732       SocketStreamJob::CreateSocketStreamJob(
733           url, &delegate, context_->transport_security_state(),
734           context_->ssl_config_service());
735   EXPECT_TRUE(GetSocket(job.get())->is_secure());
736   job->DetachDelegate();
737 
738   url = GURL("ws://donotupgrademe.com/");
739   job = SocketStreamJob::CreateSocketStreamJob(
740       url, &delegate, context_->transport_security_state(),
741       context_->ssl_config_service());
742   EXPECT_FALSE(GetSocket(job.get())->is_secure());
743   job->DetachDelegate();
744 }
745 
TestInvalidSendData()746 void WebSocketJobTest::TestInvalidSendData() {
747   GURL url("ws://example.com/demo");
748   MockSocketStreamDelegate delegate;
749   InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET);
750   SkipToConnecting();
751 
752   DoSendRequest();
753   // We assume request is sent in one data chunk (from WebKit)
754   // We don't support streaming request.
755   base::MessageLoop::current()->RunUntilIdle();
756   EXPECT_EQ(kHandshakeRequestWithoutCookie, sent_data());
757   EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
758   websocket_->OnSentData(socket_.get(),
759                          kHandshakeRequestWithoutCookieLength);
760   EXPECT_EQ(kHandshakeRequestWithoutCookieLength, delegate.amount_sent());
761 
762   // We could not send any data until connection is established.
763   bool sent = websocket_->SendData(kHandshakeRequestWithoutCookie,
764                                    kHandshakeRequestWithoutCookieLength);
765   EXPECT_FALSE(sent);
766   EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
767   CloseWebSocketJob();
768 }
769 
770 // Following tests verify cooperation between WebSocketJob and SocketStream.
771 // Other former tests use MockSocketStream as SocketStream, so we could not
772 // check SocketStream behavior.
773 // OrderedSocketData provide socket level verifiation by checking out-going
774 // packets in comparison with the MockWrite array and emulating in-coming
775 // packets with MockRead array.
776 
TestConnectByWebSocket(ThrottlingOption throttling)777 void WebSocketJobTest::TestConnectByWebSocket(
778     ThrottlingOption throttling) {
779   // This is a test for verifying cooperation between WebSocketJob and
780   // SocketStream. If |throttling| was |THROTTLING_OFF|, it test basic
781   // situation. If |throttling| was |THROTTLING_ON|, throttling limits the
782   // latter connection.
783   MockWrite writes[] = {
784     MockWrite(ASYNC,
785               kHandshakeRequestWithoutCookie,
786               kHandshakeRequestWithoutCookieLength,
787               1),
788     MockWrite(ASYNC,
789               kDataHello,
790               kDataHelloLength,
791               3)
792   };
793   MockRead reads[] = {
794     MockRead(ASYNC,
795              kHandshakeResponseWithoutCookie,
796              kHandshakeResponseWithoutCookieLength,
797              2),
798     MockRead(ASYNC,
799              kDataWorld,
800              kDataWorldLength,
801              4),
802     MockRead(SYNCHRONOUS, 0, 5)  // EOF
803   };
804   data_.reset(new OrderedSocketData(
805       reads, arraysize(reads), writes, arraysize(writes)));
806 
807   GURL url("ws://example.com/demo");
808   MockSocketStreamDelegate delegate;
809   WebSocketJobTest* test = this;
810   if (throttling == THROTTLING_ON)
811     delegate.SetOnStartOpenConnection(
812         base::Bind(&WebSocketJobTest::DoSync, base::Unretained(test)));
813   delegate.SetOnConnected(
814       base::Bind(&WebSocketJobTest::DoSendRequest,
815                  base::Unretained(test)));
816   delegate.SetOnReceivedData(
817       base::Bind(&WebSocketJobTest::DoSendData, base::Unretained(test)));
818   delegate.SetOnClose(
819       base::Bind(&WebSocketJobTest::DoSync, base::Unretained(test)));
820   InitWebSocketJob(url, &delegate, STREAM_SOCKET);
821 
822   scoped_refptr<WebSocketJob> block_websocket;
823   if (throttling == THROTTLING_ON) {
824     // Create former WebSocket object which obstructs the latter one.
825     block_websocket = new WebSocketJob(NULL);
826     block_websocket->addresses_ = AddressList(websocket_->address_list());
827     ASSERT_TRUE(
828         WebSocketThrottle::GetInstance()->PutInQueue(block_websocket.get()));
829   }
830 
831   websocket_->Connect();
832 
833   if (throttling == THROTTLING_ON) {
834     EXPECT_EQ(OK, WaitForResult());
835     EXPECT_TRUE(websocket_->IsWaiting());
836 
837     // Remove the former WebSocket object from throttling queue to unblock the
838     // latter.
839     block_websocket->state_ = WebSocketJob::CLOSED;
840     WebSocketThrottle::GetInstance()->RemoveFromQueue(block_websocket.get());
841     block_websocket = NULL;
842   }
843 
844   EXPECT_EQ(OK, WaitForResult());
845   EXPECT_TRUE(data_->at_read_eof());
846   EXPECT_TRUE(data_->at_write_eof());
847   EXPECT_EQ(WebSocketJob::CLOSED, GetWebSocketJobState());
848 }
849 
TestConnectBySpdy(SpdyOption spdy,ThrottlingOption throttling)850 void WebSocketJobTest::TestConnectBySpdy(
851     SpdyOption spdy, ThrottlingOption throttling) {
852   // This is a test for verifying cooperation between WebSocketJob and
853   // SocketStream in the situation we have SPDY session to the server. If
854   // |throttling| was |THROTTLING_ON|, throttling limits the latter connection.
855   // If you enabled spdy, you should specify |spdy| as |SPDY_ON|. Expected
856   // results depend on its configuration.
857   MockWrite writes_websocket[] = {
858     MockWrite(ASYNC,
859               kHandshakeRequestWithoutCookie,
860               kHandshakeRequestWithoutCookieLength,
861               1),
862     MockWrite(ASYNC,
863               kDataHello,
864               kDataHelloLength,
865               3)
866   };
867   MockRead reads_websocket[] = {
868     MockRead(ASYNC,
869              kHandshakeResponseWithoutCookie,
870              kHandshakeResponseWithoutCookieLength,
871              2),
872     MockRead(ASYNC,
873              kDataWorld,
874              kDataWorldLength,
875              4),
876     MockRead(SYNCHRONOUS, 0, 5)  // EOF
877   };
878 
879   scoped_ptr<SpdyHeaderBlock> request_headers(new SpdyHeaderBlock());
880   spdy_util_.SetHeader("path", "/demo", request_headers.get());
881   spdy_util_.SetHeader("version", "WebSocket/13", request_headers.get());
882   spdy_util_.SetHeader("scheme", "ws", request_headers.get());
883   spdy_util_.SetHeader("host", "example.com", request_headers.get());
884   spdy_util_.SetHeader("origin", "http://example.com", request_headers.get());
885   spdy_util_.SetHeader("sec-websocket-protocol", "sample",
886                        request_headers.get());
887 
888   scoped_ptr<SpdyHeaderBlock> response_headers(new SpdyHeaderBlock());
889   spdy_util_.SetHeader("status", "101 Switching Protocols",
890                        response_headers.get());
891   spdy_util_.SetHeader("sec-websocket-protocol", "sample",
892                        response_headers.get());
893 
894   const SpdyStreamId kStreamId = 1;
895   scoped_ptr<SpdyFrame> request_frame(
896       spdy_util_.ConstructSpdyWebSocketHandshakeRequestFrame(
897           request_headers.Pass(),
898           kStreamId,
899           MEDIUM));
900   scoped_ptr<SpdyFrame> response_frame(
901       spdy_util_.ConstructSpdyWebSocketHandshakeResponseFrame(
902           response_headers.Pass(),
903           kStreamId,
904           MEDIUM));
905   scoped_ptr<SpdyFrame> data_hello_frame(
906       spdy_util_.ConstructSpdyWebSocketDataFrame(
907           kDataHello,
908           kDataHelloLength,
909           kStreamId,
910           false));
911   scoped_ptr<SpdyFrame> data_world_frame(
912       spdy_util_.ConstructSpdyWebSocketDataFrame(
913           kDataWorld,
914           kDataWorldLength,
915           kStreamId,
916           false));
917   MockWrite writes_spdy[] = {
918     CreateMockWrite(*request_frame.get(), 1),
919     CreateMockWrite(*data_hello_frame.get(), 3),
920   };
921   MockRead reads_spdy[] = {
922     CreateMockRead(*response_frame.get(), 2),
923     CreateMockRead(*data_world_frame.get(), 4),
924     MockRead(SYNCHRONOUS, 0, 5)  // EOF
925   };
926 
927   if (spdy == SPDY_ON)
928     data_.reset(new OrderedSocketData(
929         reads_spdy, arraysize(reads_spdy),
930         writes_spdy, arraysize(writes_spdy)));
931   else
932     data_.reset(new OrderedSocketData(
933         reads_websocket, arraysize(reads_websocket),
934         writes_websocket, arraysize(writes_websocket)));
935 
936   GURL url("ws://example.com/demo");
937   MockSocketStreamDelegate delegate;
938   WebSocketJobTest* test = this;
939   if (throttling == THROTTLING_ON)
940     delegate.SetOnStartOpenConnection(
941         base::Bind(&WebSocketJobTest::DoSync, base::Unretained(test)));
942   delegate.SetOnConnected(
943       base::Bind(&WebSocketJobTest::DoSendRequest,
944                  base::Unretained(test)));
945   delegate.SetOnReceivedData(
946       base::Bind(&WebSocketJobTest::DoSendData, base::Unretained(test)));
947   delegate.SetOnClose(
948       base::Bind(&WebSocketJobTest::DoSync, base::Unretained(test)));
949   InitWebSocketJob(url, &delegate, STREAM_SPDY_WEBSOCKET);
950 
951   scoped_refptr<WebSocketJob> block_websocket;
952   if (throttling == THROTTLING_ON) {
953     // Create former WebSocket object which obstructs the latter one.
954     block_websocket = new WebSocketJob(NULL);
955     block_websocket->addresses_ = AddressList(websocket_->address_list());
956     ASSERT_TRUE(
957         WebSocketThrottle::GetInstance()->PutInQueue(block_websocket.get()));
958   }
959 
960   websocket_->Connect();
961 
962   if (throttling == THROTTLING_ON) {
963     EXPECT_EQ(OK, WaitForResult());
964     EXPECT_TRUE(websocket_->IsWaiting());
965 
966     // Remove the former WebSocket object from throttling queue to unblock the
967     // latter.
968     block_websocket->state_ = WebSocketJob::CLOSED;
969     WebSocketThrottle::GetInstance()->RemoveFromQueue(block_websocket.get());
970     block_websocket = NULL;
971   }
972 
973   EXPECT_EQ(OK, WaitForResult());
974   EXPECT_TRUE(data_->at_read_eof());
975   EXPECT_TRUE(data_->at_write_eof());
976   EXPECT_EQ(WebSocketJob::CLOSED, GetWebSocketJobState());
977 }
978 
TestThrottlingLimit()979 void WebSocketJobTest::TestThrottlingLimit() {
980   std::vector<scoped_refptr<WebSocketJob> > jobs;
981   const int kMaxWebSocketJobsThrottled = 1024;
982   IPAddressNumber ip;
983   ParseIPLiteralToNumber("127.0.0.1", &ip);
984   for (int i = 0; i < kMaxWebSocketJobsThrottled + 1; ++i) {
985     scoped_refptr<WebSocketJob> job = new WebSocketJob(NULL);
986     job->addresses_ = AddressList(AddressList::CreateFromIPAddress(ip, 80));
987     if (i >= kMaxWebSocketJobsThrottled)
988       EXPECT_FALSE(WebSocketThrottle::GetInstance()->PutInQueue(job));
989     else
990       EXPECT_TRUE(WebSocketThrottle::GetInstance()->PutInQueue(job));
991     jobs.push_back(job);
992   }
993 
994   // Close the jobs in reverse order. Otherwise, We need to make them prepared
995   // for Wakeup call.
996   for (std::vector<scoped_refptr<WebSocketJob> >::reverse_iterator iter =
997            jobs.rbegin();
998        iter != jobs.rend();
999        ++iter) {
1000     WebSocketJob* job = (*iter).get();
1001     job->state_ = WebSocketJob::CLOSED;
1002     WebSocketThrottle::GetInstance()->RemoveFromQueue(job);
1003   }
1004 }
1005 
1006 // Execute tests in both spdy-disabled mode and spdy-enabled mode.
TEST_P(WebSocketJobTest,SimpleHandshake)1007 TEST_P(WebSocketJobTest, SimpleHandshake) {
1008   WebSocketJob::set_websocket_over_spdy_enabled(false);
1009   TestSimpleHandshake();
1010 }
1011 
TEST_P(WebSocketJobTest,SlowHandshake)1012 TEST_P(WebSocketJobTest, SlowHandshake) {
1013   WebSocketJob::set_websocket_over_spdy_enabled(false);
1014   TestSlowHandshake();
1015 }
1016 
TEST_P(WebSocketJobTest,HandshakeWithCookie)1017 TEST_P(WebSocketJobTest, HandshakeWithCookie) {
1018   WebSocketJob::set_websocket_over_spdy_enabled(false);
1019   TestHandshakeWithCookie();
1020 }
1021 
TEST_P(WebSocketJobTest,HandshakeWithCookieButNotAllowed)1022 TEST_P(WebSocketJobTest, HandshakeWithCookieButNotAllowed) {
1023   WebSocketJob::set_websocket_over_spdy_enabled(false);
1024   TestHandshakeWithCookieButNotAllowed();
1025 }
1026 
TEST_P(WebSocketJobTest,HSTSUpgrade)1027 TEST_P(WebSocketJobTest, HSTSUpgrade) {
1028   WebSocketJob::set_websocket_over_spdy_enabled(false);
1029   TestHSTSUpgrade();
1030 }
1031 
TEST_P(WebSocketJobTest,InvalidSendData)1032 TEST_P(WebSocketJobTest, InvalidSendData) {
1033   WebSocketJob::set_websocket_over_spdy_enabled(false);
1034   TestInvalidSendData();
1035 }
1036 
TEST_P(WebSocketJobTest,SimpleHandshakeSpdyEnabled)1037 TEST_P(WebSocketJobTest, SimpleHandshakeSpdyEnabled) {
1038   WebSocketJob::set_websocket_over_spdy_enabled(true);
1039   TestSimpleHandshake();
1040 }
1041 
TEST_P(WebSocketJobTest,SlowHandshakeSpdyEnabled)1042 TEST_P(WebSocketJobTest, SlowHandshakeSpdyEnabled) {
1043   WebSocketJob::set_websocket_over_spdy_enabled(true);
1044   TestSlowHandshake();
1045 }
1046 
TEST_P(WebSocketJobTest,HandshakeWithCookieSpdyEnabled)1047 TEST_P(WebSocketJobTest, HandshakeWithCookieSpdyEnabled) {
1048   WebSocketJob::set_websocket_over_spdy_enabled(true);
1049   TestHandshakeWithCookie();
1050 }
1051 
TEST_P(WebSocketJobTest,HandshakeWithCookieButNotAllowedSpdyEnabled)1052 TEST_P(WebSocketJobTest, HandshakeWithCookieButNotAllowedSpdyEnabled) {
1053   WebSocketJob::set_websocket_over_spdy_enabled(true);
1054   TestHandshakeWithCookieButNotAllowed();
1055 }
1056 
TEST_P(WebSocketJobTest,HSTSUpgradeSpdyEnabled)1057 TEST_P(WebSocketJobTest, HSTSUpgradeSpdyEnabled) {
1058   WebSocketJob::set_websocket_over_spdy_enabled(true);
1059   TestHSTSUpgrade();
1060 }
1061 
TEST_P(WebSocketJobTest,InvalidSendDataSpdyEnabled)1062 TEST_P(WebSocketJobTest, InvalidSendDataSpdyEnabled) {
1063   WebSocketJob::set_websocket_over_spdy_enabled(true);
1064   TestInvalidSendData();
1065 }
1066 
TEST_P(WebSocketJobTest,ConnectByWebSocket)1067 TEST_P(WebSocketJobTest, ConnectByWebSocket) {
1068   WebSocketJob::set_websocket_over_spdy_enabled(false);
1069   TestConnectByWebSocket(THROTTLING_OFF);
1070 }
1071 
TEST_P(WebSocketJobTest,ConnectByWebSocketSpdyEnabled)1072 TEST_P(WebSocketJobTest, ConnectByWebSocketSpdyEnabled) {
1073   WebSocketJob::set_websocket_over_spdy_enabled(true);
1074   TestConnectByWebSocket(THROTTLING_OFF);
1075 }
1076 
TEST_P(WebSocketJobTest,ConnectBySpdy)1077 TEST_P(WebSocketJobTest, ConnectBySpdy) {
1078   WebSocketJob::set_websocket_over_spdy_enabled(false);
1079   TestConnectBySpdy(SPDY_OFF, THROTTLING_OFF);
1080 }
1081 
TEST_P(WebSocketJobTest,ConnectBySpdySpdyEnabled)1082 TEST_P(WebSocketJobTest, ConnectBySpdySpdyEnabled) {
1083   WebSocketJob::set_websocket_over_spdy_enabled(true);
1084   TestConnectBySpdy(SPDY_ON, THROTTLING_OFF);
1085 }
1086 
TEST_P(WebSocketJobTest,ThrottlingWebSocket)1087 TEST_P(WebSocketJobTest, ThrottlingWebSocket) {
1088   WebSocketJob::set_websocket_over_spdy_enabled(false);
1089   TestConnectByWebSocket(THROTTLING_ON);
1090 }
1091 
TEST_P(WebSocketJobTest,ThrottlingMaxNumberOfThrottledJobLimit)1092 TEST_P(WebSocketJobTest, ThrottlingMaxNumberOfThrottledJobLimit) {
1093   TestThrottlingLimit();
1094 }
1095 
TEST_P(WebSocketJobTest,ThrottlingWebSocketSpdyEnabled)1096 TEST_P(WebSocketJobTest, ThrottlingWebSocketSpdyEnabled) {
1097   WebSocketJob::set_websocket_over_spdy_enabled(true);
1098   TestConnectByWebSocket(THROTTLING_ON);
1099 }
1100 
TEST_P(WebSocketJobTest,ThrottlingSpdy)1101 TEST_P(WebSocketJobTest, ThrottlingSpdy) {
1102   WebSocketJob::set_websocket_over_spdy_enabled(false);
1103   TestConnectBySpdy(SPDY_OFF, THROTTLING_ON);
1104 }
1105 
TEST_P(WebSocketJobTest,ThrottlingSpdySpdyEnabled)1106 TEST_P(WebSocketJobTest, ThrottlingSpdySpdyEnabled) {
1107   WebSocketJob::set_websocket_over_spdy_enabled(true);
1108   TestConnectBySpdy(SPDY_ON, THROTTLING_ON);
1109 }
1110 
1111 // TODO(toyoshim): Add tests to verify throttling, SPDY stream limitation.
1112 // TODO(toyoshim,yutak): Add tests to verify closing handshake.
1113 }  // namespace net
1114