blob: ba5de5fd0ed1356d102fcc21fee33ad9d0aaf6d5 [file] [log] [blame]
[email protected]ce9f7ffd2013-10-11 06:04:111// 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#ifndef NET_WEBSOCKETS_WEBSOCKET_TEST_UTIL_H_
6#define NET_WEBSOCKETS_WEBSOCKET_TEST_UTIL_H_
7
tfarina8a2c66c22015-10-13 19:14:498#include <stdint.h>
Avi Drissman13fc8932015-12-20 04:40:469
danakj9c5cab52016-04-16 00:54:3310#include <memory>
[email protected]a31ecc02013-12-05 08:30:5511#include <string>
Bence Béky46bfbc12018-02-22 19:28:2012#include <utility>
Bence Békye1805c42018-02-08 13:02:3713#include <vector>
[email protected]a31ecc02013-12-05 08:30:5514
tfarinaea94afc232015-10-20 04:23:3615#include "base/macros.h"
Bence Békydca6bd92018-01-30 13:43:0616#include "net/http/http_basic_state.h"
Yutaka Hirano2f65eec2018-05-23 01:58:2217#include "net/http/http_request_headers.h"
Bence Békydca6bd92018-01-30 13:43:0618#include "net/http/http_stream_parser.h"
19#include "net/socket/client_socket_handle.h"
Ryan Hamilton2e003eea2018-05-02 00:24:2920#include "net/third_party/spdy/core/spdy_header_block.h"
Bence Békydca6bd92018-01-30 13:43:0621#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]a31ecc02013-12-05 08:30:5522#include "net/url_request/url_request_test_util.h"
Bence Béky8d1c6052018-02-07 12:48:1523#include "net/websockets/websocket_handshake_stream_create_helper.h"
[email protected]efa9e732013-11-29 02:55:0524#include "net/websockets/websocket_stream.h"
25
[email protected]7824cf82014-03-13 10:22:5726namespace url {
mkwst4997ce82015-07-25 12:00:0527class Origin;
[email protected]7824cf82014-03-13 10:22:5728} // namespace url
29
[email protected]ce9f7ffd2013-10-11 06:04:1130namespace net {
31
Bence Béky46bfbc12018-02-22 19:28:2032using WebSocketExtraHeaders = std::vector<std::pair<std::string, std::string>>;
33
mmenked0d201a2015-06-08 12:00:1234class MockClientSocketFactory;
Bence Béky8d1c6052018-02-07 12:48:1535class WebSocketBasicHandshakeStream;
Lily Houghton8c2f97d2018-01-22 05:06:5936class ProxyResolutionService;
mmenked0d201a2015-06-08 12:00:1237class SequencedSocketData;
[email protected]a62449522014-06-05 11:11:1538struct SSLSocketDataProvider;
[email protected]efa9e732013-11-29 02:55:0539
[email protected]ce9f7ffd2013-10-11 06:04:1140class LinearCongruentialGenerator {
41 public:
tfarina8a2c66c22015-10-13 19:14:4942 explicit LinearCongruentialGenerator(uint32_t seed);
43 uint32_t Generate();
[email protected]ce9f7ffd2013-10-11 06:04:1144
45 private:
tfarina8a2c66c22015-10-13 19:14:4946 uint64_t current_;
[email protected]ce9f7ffd2013-10-11 06:04:1147};
48
Bence Béky3a0c48532018-03-02 13:38:5149// Converts a vector of header key-value pairs into a single string.
50std::string WebSocketExtraHeadersToString(const WebSocketExtraHeaders& headers);
51
Yutaka Hirano2f65eec2018-05-23 01:58:2252// Converts a vector of header key-value pairs into an HttpRequestHeaders
53HttpRequestHeaders WebSocketExtraHeadersToHttpRequestHeaders(
54 const WebSocketExtraHeaders& headers);
55
[email protected]a31ecc02013-12-05 08:30:5556// Generates a standard WebSocket handshake request. The challenge key used is
57// "dGhlIHNhbXBsZSBub25jZQ==". Each header in |extra_headers| must be terminated
58// with "\r\n".
alladacef397d2016-06-29 17:52:2359std::string WebSocketStandardRequest(
60 const std::string& path,
61 const std::string& host,
62 const url::Origin& origin,
63 const std::string& send_additional_request_headers,
64 const std::string& extra_headers);
yhirano01a5d662015-02-12 04:33:0665
66// Generates a standard WebSocket handshake request. The challenge key used is
67// "dGhlIHNhbXBsZSBub25jZQ==". |cookies| must be empty or terminated with
68// "\r\n". Each header in |extra_headers| must be terminated with "\r\n".
69std::string WebSocketStandardRequestWithCookies(
70 const std::string& path,
71 const std::string& host,
mkwst4997ce82015-07-25 12:00:0572 const url::Origin& origin,
yhirano01a5d662015-02-12 04:33:0673 const std::string& cookies,
alladacef397d2016-06-29 17:52:2374 const std::string& send_additional_request_headers,
yhirano01a5d662015-02-12 04:33:0675 const std::string& extra_headers);
[email protected]a31ecc02013-12-05 08:30:5576
77// A response with the appropriate accept header to match the above challenge
78// key. Each header in |extra_headers| must be terminated with "\r\n".
yhirano01a5d662015-02-12 04:33:0679std::string WebSocketStandardResponse(const std::string& extra_headers);
[email protected]a31ecc02013-12-05 08:30:5580
Bence Béky46bfbc12018-02-22 19:28:2081// Generates a handshake request header block when using WebSockets over HTTP/2.
Ryan Hamilton0239aac2018-05-19 00:03:1382spdy::SpdyHeaderBlock WebSocketHttp2Request(
Bence Béky46bfbc12018-02-22 19:28:2083 const std::string& path,
84 const std::string& authority,
85 const std::string& origin,
86 const WebSocketExtraHeaders& extra_headers);
87
88// Generates a handshake response header block when using WebSockets over
89// HTTP/2.
Ryan Hamilton0239aac2018-05-19 00:03:1390spdy::SpdyHeaderBlock WebSocketHttp2Response(
Bence Béky46bfbc12018-02-22 19:28:2091 const WebSocketExtraHeaders& extra_headers);
92
mmenked0d201a2015-06-08 12:00:1293// This class provides a convenient way to construct a MockClientSocketFactory
94// for WebSocket tests.
95class WebSocketMockClientSocketFactoryMaker {
[email protected]a31ecc02013-12-05 08:30:5596 public:
mmenked0d201a2015-06-08 12:00:1297 WebSocketMockClientSocketFactoryMaker();
98 ~WebSocketMockClientSocketFactoryMaker();
[email protected]a31ecc02013-12-05 08:30:5599
[email protected]a62449522014-06-05 11:11:15100 // Tell the factory to create a socket which expects |expect_written| to be
101 // written, and responds with |return_to_read|. The test will fail if the
102 // expected text is not written, or all the bytes are not read. This adds data
103 // for a new mock-socket using AddRawExpections(), and so can be called
104 // multiple times to queue up multiple mock sockets, but usually in those
105 // cases the lower-level AddRawExpections() interface is more appropriate.
[email protected]a31ecc02013-12-05 08:30:55106 void SetExpectations(const std::string& expect_written,
107 const std::string& return_to_read);
108
[email protected]a62449522014-06-05 11:11:15109 // A low-level interface to permit arbitrary expectations to be added. The
110 // mock sockets will be created in the same order that they were added.
danakj9c5cab52016-04-16 00:54:33111 void AddRawExpectations(std::unique_ptr<SequencedSocketData> socket_data);
[email protected]a62449522014-06-05 11:11:15112
113 // Allow an SSL socket data provider to be added. You must also supply a mock
114 // transport socket for it to use. If the mock SSL handshake fails then the
115 // mock transport socket will connect but have nothing read or written. If the
116 // mock handshake succeeds then the data from the underlying transport socket
117 // will be passed through unchanged (without encryption).
118 void AddSSLSocketDataProvider(
danakj9c5cab52016-04-16 00:54:33119 std::unique_ptr<SSLSocketDataProvider> ssl_socket_data);
[email protected]a31ecc02013-12-05 08:30:55120
121 // Call to get a pointer to the factory, which remains owned by this object.
mmenked0d201a2015-06-08 12:00:12122 MockClientSocketFactory* factory();
[email protected]a31ecc02013-12-05 08:30:55123
124 private:
125 struct Detail;
danakj9c5cab52016-04-16 00:54:33126 std::unique_ptr<Detail> detail_;
[email protected]a31ecc02013-12-05 08:30:55127
mmenked0d201a2015-06-08 12:00:12128 DISALLOW_COPY_AND_ASSIGN(WebSocketMockClientSocketFactoryMaker);
[email protected]a31ecc02013-12-05 08:30:55129};
130
131// This class encapsulates the details of creating a
132// TestURLRequestContext that returns mock ClientSocketHandles that do what is
133// required by the tests.
134struct WebSocketTestURLRequestContextHost {
135 public:
136 WebSocketTestURLRequestContextHost();
137 ~WebSocketTestURLRequestContextHost();
138
139 void SetExpectations(const std::string& expect_written,
140 const std::string& return_to_read) {
141 maker_.SetExpectations(expect_written, return_to_read);
142 }
143
danakj9c5cab52016-04-16 00:54:33144 void AddRawExpectations(std::unique_ptr<SequencedSocketData> socket_data);
[email protected]a31ecc02013-12-05 08:30:55145
[email protected]a62449522014-06-05 11:11:15146 // Allow an SSL socket data provider to be added.
147 void AddSSLSocketDataProvider(
danakj9c5cab52016-04-16 00:54:33148 std::unique_ptr<SSLSocketDataProvider> ssl_socket_data);
[email protected]a62449522014-06-05 11:11:15149
ricea38fc268c2015-02-09 02:41:29150 // Allow a proxy to be set. Usage:
151 // SetProxyConfig("proxy1:8000");
152 // Any syntax accepted by net::ProxyConfig::ParseFromString() will work.
153 // Do not call after GetURLRequestContext() has been called.
154 void SetProxyConfig(const std::string& proxy_rules);
155
[email protected]a62449522014-06-05 11:11:15156 // Call after calling one of SetExpections() or AddRawExpectations(). The
[email protected]654866142014-06-24 22:53:31157 // returned pointer remains owned by this object.
[email protected]a31ecc02013-12-05 08:30:55158 TestURLRequestContext* GetURLRequestContext();
159
yhirano96205c42017-01-18 22:45:18160 const TestNetworkDelegate& network_delegate() const {
161 return network_delegate_;
162 }
163
[email protected]a31ecc02013-12-05 08:30:55164 private:
mmenked0d201a2015-06-08 12:00:12165 WebSocketMockClientSocketFactoryMaker maker_;
[email protected]a31ecc02013-12-05 08:30:55166 TestURLRequestContext url_request_context_;
167 TestNetworkDelegate network_delegate_;
Lily Houghton8c2f97d2018-01-22 05:06:59168 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
[email protected]654866142014-06-24 22:53:31169 bool url_request_context_initialized_;
[email protected]a31ecc02013-12-05 08:30:55170
171 DISALLOW_COPY_AND_ASSIGN(WebSocketTestURLRequestContextHost);
172};
173
Bence Béky8d1c6052018-02-07 12:48:15174// WebSocketStream::ConnectDelegate implementation that does nothing.
175class DummyConnectDelegate : public WebSocketStream::ConnectDelegate {
Bence Békydca6bd92018-01-30 13:43:06176 public:
Bence Béky8d1c6052018-02-07 12:48:15177 DummyConnectDelegate() = default;
178 ~DummyConnectDelegate() override = default;
179 void OnCreateRequest(URLRequest* url_request) override {}
180 void OnSuccess(std::unique_ptr<WebSocketStream> stream) override {}
181 void OnFailure(const std::string& message) override {}
182 void OnStartOpeningHandshake(
183 std::unique_ptr<WebSocketHandshakeRequestInfo> request) override {}
184 void OnFinishOpeningHandshake(
185 std::unique_ptr<WebSocketHandshakeResponseInfo> response) override {}
186 void OnSSLCertificateError(
187 std::unique_ptr<WebSocketEventInterface::SSLErrorCallbacks>
188 ssl_error_callbacks,
189 const SSLInfo& ssl_info,
190 bool fatal) override {}
Bence Békydca6bd92018-01-30 13:43:06191};
192
Bence Béky8d1c6052018-02-07 12:48:15193// WebSocketStreamRequest implementation that does nothing.
194class DummyWebSocketStreamRequest : public WebSocketStreamRequest {
Bence Békydca6bd92018-01-30 13:43:06195 public:
Bence Béky8d1c6052018-02-07 12:48:15196 DummyWebSocketStreamRequest() = default;
197 ~DummyWebSocketStreamRequest() override = default;
198 void OnHandshakeStreamCreated(
199 WebSocketHandshakeStreamBase* handshake_stream) override {}
200 void OnFailure(const std::string& message) override {}
Bence Békydca6bd92018-01-30 13:43:06201};
202
Bence Béky8d1c6052018-02-07 12:48:15203// A sub-class of WebSocketHandshakeStreamCreateHelper which sets a
204// deterministic key to use in the WebSocket handshake, and optionally uses a
205// dummy ConnectDelegate and a dummy WebSocketStreamRequest.
206class TestWebSocketHandshakeStreamCreateHelper
207 : public WebSocketHandshakeStreamCreateHelper {
Bence Békydca6bd92018-01-30 13:43:06208 public:
Bence Béky8d1c6052018-02-07 12:48:15209 // Constructor for using dummy ConnectDelegate and WebSocketStreamRequest.
210 TestWebSocketHandshakeStreamCreateHelper()
211 : WebSocketHandshakeStreamCreateHelper(
212 &connect_delegate_,
213 std::vector<std::string>() /* requested_subprotocols */) {
214 WebSocketHandshakeStreamCreateHelper::set_stream_request(&request_);
215 }
216
217 // Constructor for using custom ConnectDelegate and subprotocols.
218 // Caller must call set_stream_request() with a WebSocketStreamRequest before
219 // calling CreateBasicStream().
220 TestWebSocketHandshakeStreamCreateHelper(
221 WebSocketStream::ConnectDelegate* connect_delegate,
222 const std::vector<std::string>& requested_subprotocols)
223 : WebSocketHandshakeStreamCreateHelper(connect_delegate,
224 requested_subprotocols) {}
225
226 ~TestWebSocketHandshakeStreamCreateHelper() override = default;
227
228 void OnBasicStreamCreated(WebSocketBasicHandshakeStream* stream) override;
229
230 private:
231 DummyConnectDelegate connect_delegate_;
232 DummyWebSocketStreamRequest request_;
233
234 DISALLOW_COPY_AND_ASSIGN(TestWebSocketHandshakeStreamCreateHelper);
Bence Békydca6bd92018-01-30 13:43:06235};
236
[email protected]ce9f7ffd2013-10-11 06:04:11237} // namespace net
238
239#endif // NET_WEBSOCKETS_WEBSOCKET_TEST_UTIL_H_