14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file.
44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifndef NET_WEBSOCKETS_WEBSOCKET_TEST_UTIL_H_
64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#define NET_WEBSOCKETS_WEBSOCKET_TEST_UTIL_H_
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <string>
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/basictypes.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/url_request/url_request_test_util.h"
13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/websockets/websocket_stream.h"
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class GURL;
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace base {
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass Timer;
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace base
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace url {
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class Origin;
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace url
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace net {
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class BoundNetLog;
2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class DeterministicMockClientSocketFactory;
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class DeterministicSocketData;
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class URLRequestContext;
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class WebSocketHandshakeStreamCreateHelper;
3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)struct SSLSocketDataProvider;
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class LinearCongruentialGenerator {
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  explicit LinearCongruentialGenerator(uint32 seed);
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  uint32 Generate();
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  uint64 current_;
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Alternate version of WebSocketStream::CreateAndConnectStream() for testing
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// use only. The differences are the use of a |create_helper| argument in place
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// of |requested_subprotocols| and taking |timer| as the handshake timeout
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// timer. Implemented in websocket_stream.cc.
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)NET_EXPORT_PRIVATE extern scoped_ptr<WebSocketStreamRequest>
48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    CreateAndConnectStreamForTesting(
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        const GURL& socket_url,
50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        scoped_ptr<WebSocketHandshakeStreamCreateHelper> create_helper,
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        const url::Origin& origin,
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        URLRequestContext* url_request_context,
53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        const BoundNetLog& net_log,
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate,
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        scoped_ptr<base::Timer> timer);
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Generates a standard WebSocket handshake request. The challenge key used is
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// "dGhlIHNhbXBsZSBub25jZQ==". Each header in |extra_headers| must be terminated
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// with "\r\n".
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)extern std::string WebSocketStandardRequest(const std::string& path,
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                            const std::string& origin,
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                            const std::string& extra_headers);
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// A response with the appropriate accept header to match the above challenge
65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// key. Each header in |extra_headers| must be terminated with "\r\n".
66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)extern std::string WebSocketStandardResponse(const std::string& extra_headers);
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// This class provides a convenient way to construct a
69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// DeterministicMockClientSocketFactory for WebSocket tests.
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class WebSocketDeterministicMockClientSocketFactoryMaker {
71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public:
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  WebSocketDeterministicMockClientSocketFactoryMaker();
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ~WebSocketDeterministicMockClientSocketFactoryMaker();
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Tell the factory to create a socket which expects |expect_written| to be
7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // written, and responds with |return_to_read|. The test will fail if the
7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // expected text is not written, or all the bytes are not read. This adds data
7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // for a new mock-socket using AddRawExpections(), and so can be called
7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // multiple times to queue up multiple mock sockets, but usually in those
8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // cases the lower-level AddRawExpections() interface is more appropriate.
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void SetExpectations(const std::string& expect_written,
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       const std::string& return_to_read);
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // A low-level interface to permit arbitrary expectations to be added. The
8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // mock sockets will be created in the same order that they were added.
8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void AddRawExpectations(scoped_ptr<DeterministicSocketData> socket_data);
8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Allow an SSL socket data provider to be added. You must also supply a mock
8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // transport socket for it to use. If the mock SSL handshake fails then the
9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // mock transport socket will connect but have nothing read or written. If the
9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // mock handshake succeeds then the data from the underlying transport socket
9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // will be passed through unchanged (without encryption).
9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void AddSSLSocketDataProvider(
9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      scoped_ptr<SSLSocketDataProvider> ssl_socket_data);
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Call to get a pointer to the factory, which remains owned by this object.
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DeterministicMockClientSocketFactory* factory();
98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private:
100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  struct Detail;
101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<Detail> detail_;
102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WebSocketDeterministicMockClientSocketFactoryMaker);
104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// This class encapsulates the details of creating a
107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// TestURLRequestContext that returns mock ClientSocketHandles that do what is
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// required by the tests.
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)struct WebSocketTestURLRequestContextHost {
110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public:
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  WebSocketTestURLRequestContextHost();
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ~WebSocketTestURLRequestContextHost();
113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void SetExpectations(const std::string& expect_written,
115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       const std::string& return_to_read) {
116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    maker_.SetExpectations(expect_written, return_to_read);
117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void AddRawExpectations(scoped_ptr<DeterministicSocketData> socket_data);
12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Allow an SSL socket data provider to be added.
12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void AddSSLSocketDataProvider(
12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      scoped_ptr<SSLSocketDataProvider> ssl_socket_data);
124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Call after calling one of SetExpections() or AddRawExpectations(). The
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // returned pointer remains owned by this object.
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  TestURLRequestContext* GetURLRequestContext();
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private:
130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  WebSocketDeterministicMockClientSocketFactoryMaker maker_;
131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  TestURLRequestContext url_request_context_;
132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  TestNetworkDelegate network_delegate_;
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool url_request_context_initialized_;
134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WebSocketTestURLRequestContextHost);
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace net
1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif  // NET_WEBSOCKETS_WEBSOCKET_TEST_UTIL_H_
141