websocket_test_util.h 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  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. #ifndef NET_WEBSOCKETS_WEBSOCKET_TEST_UTIL_H_
  5. #define NET_WEBSOCKETS_WEBSOCKET_TEST_UTIL_H_
  6. #include <stdint.h>
  7. #include <memory>
  8. #include <string>
  9. #include <utility>
  10. #include <vector>
  11. #include "net/http/http_basic_state.h"
  12. #include "net/http/http_request_headers.h"
  13. #include "net/http/http_stream_parser.h"
  14. #include "net/socket/client_socket_handle.h"
  15. #include "net/third_party/quiche/src/quiche/spdy/core/http2_header_block.h"
  16. #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
  17. #include "net/url_request/url_request_test_util.h"
  18. #include "net/websockets/websocket_handshake_stream_create_helper.h"
  19. #include "net/websockets/websocket_stream.h"
  20. #include "third_party/abseil-cpp/absl/types/optional.h"
  21. namespace url {
  22. class Origin;
  23. } // namespace url
  24. namespace net {
  25. using WebSocketExtraHeaders = std::vector<std::pair<std::string, std::string>>;
  26. class MockClientSocketFactory;
  27. class WebSocketBasicHandshakeStream;
  28. class SequencedSocketData;
  29. class IPEndPoint;
  30. struct SSLSocketDataProvider;
  31. class LinearCongruentialGenerator {
  32. public:
  33. explicit LinearCongruentialGenerator(uint32_t seed);
  34. uint32_t Generate();
  35. private:
  36. uint64_t current_;
  37. };
  38. // Converts a vector of header key-value pairs into a single string.
  39. std::string WebSocketExtraHeadersToString(const WebSocketExtraHeaders& headers);
  40. // Converts a vector of header key-value pairs into an HttpRequestHeaders
  41. HttpRequestHeaders WebSocketExtraHeadersToHttpRequestHeaders(
  42. const WebSocketExtraHeaders& headers);
  43. // Generates a standard WebSocket handshake request. The challenge key used is
  44. // "dGhlIHNhbXBsZSBub25jZQ==".
  45. std::string WebSocketStandardRequest(
  46. const std::string& path,
  47. const std::string& host,
  48. const url::Origin& origin,
  49. const WebSocketExtraHeaders& send_additional_request_headers,
  50. const WebSocketExtraHeaders& extra_headers);
  51. // Generates a standard WebSocket handshake request. The challenge key used is
  52. // "dGhlIHNhbXBsZSBub25jZQ==". |cookies| must be empty or terminated with
  53. // "\r\n".
  54. std::string WebSocketStandardRequestWithCookies(
  55. const std::string& path,
  56. const std::string& host,
  57. const url::Origin& origin,
  58. const WebSocketExtraHeaders& cookies,
  59. const WebSocketExtraHeaders& send_additional_request_headers,
  60. const WebSocketExtraHeaders& extra_headers);
  61. // A response with the appropriate accept header to match the above
  62. // challenge key. Each header in |extra_headers| must be terminated with
  63. // "\r\n".
  64. std::string WebSocketStandardResponse(const std::string& extra_headers);
  65. // WebSocketCommonTestHeaders() generates a common set of request headers
  66. // corresponding to WebSocketStandardRequest("/", "www.example.org",
  67. // url::Origin::Create(GURL("http://origin.example.org")), "", "")
  68. HttpRequestHeaders WebSocketCommonTestHeaders();
  69. // Generates a handshake request header block when using WebSockets over HTTP/2.
  70. spdy::Http2HeaderBlock WebSocketHttp2Request(
  71. const std::string& path,
  72. const std::string& authority,
  73. const std::string& origin,
  74. const WebSocketExtraHeaders& extra_headers);
  75. // Generates a handshake response header block when using WebSockets over
  76. // HTTP/2.
  77. spdy::Http2HeaderBlock WebSocketHttp2Response(
  78. const WebSocketExtraHeaders& extra_headers);
  79. // This class provides a convenient way to construct a MockClientSocketFactory
  80. // for WebSocket tests.
  81. class WebSocketMockClientSocketFactoryMaker {
  82. public:
  83. WebSocketMockClientSocketFactoryMaker();
  84. WebSocketMockClientSocketFactoryMaker(
  85. const WebSocketMockClientSocketFactoryMaker&) = delete;
  86. WebSocketMockClientSocketFactoryMaker& operator=(
  87. const WebSocketMockClientSocketFactoryMaker&) = delete;
  88. ~WebSocketMockClientSocketFactoryMaker();
  89. // Tell the factory to create a socket which expects |expect_written| to be
  90. // written, and responds with |return_to_read|. The test will fail if the
  91. // expected text is not written, or all the bytes are not read. This adds data
  92. // for a new mock-socket using AddRawExpections(), and so can be called
  93. // multiple times to queue up multiple mock sockets, but usually in those
  94. // cases the lower-level AddRawExpections() interface is more appropriate.
  95. void SetExpectations(const std::string& expect_written,
  96. const std::string& return_to_read);
  97. // A low-level interface to permit arbitrary expectations to be added. The
  98. // mock sockets will be created in the same order that they were added.
  99. void AddRawExpectations(std::unique_ptr<SequencedSocketData> socket_data);
  100. // Allow an SSL socket data provider to be added. You must also supply a mock
  101. // transport socket for it to use. If the mock SSL handshake fails then the
  102. // mock transport socket will connect but have nothing read or written. If the
  103. // mock handshake succeeds then the data from the underlying transport socket
  104. // will be passed through unchanged (without encryption).
  105. void AddSSLSocketDataProvider(
  106. std::unique_ptr<SSLSocketDataProvider> ssl_socket_data);
  107. // Call to get a pointer to the factory, which remains owned by this object.
  108. MockClientSocketFactory* factory();
  109. private:
  110. struct Detail;
  111. std::unique_ptr<Detail> detail_;
  112. };
  113. // This class encapsulates the details of creating a
  114. // URLRequestContext that returns mock ClientSocketHandles that do what is
  115. // required by the tests.
  116. struct WebSocketTestURLRequestContextHost {
  117. public:
  118. WebSocketTestURLRequestContextHost();
  119. WebSocketTestURLRequestContextHost(
  120. const WebSocketTestURLRequestContextHost&) = delete;
  121. WebSocketTestURLRequestContextHost& operator=(
  122. const WebSocketTestURLRequestContextHost&) = delete;
  123. ~WebSocketTestURLRequestContextHost();
  124. void SetExpectations(const std::string& expect_written,
  125. const std::string& return_to_read) {
  126. maker_.SetExpectations(expect_written, return_to_read);
  127. }
  128. void AddRawExpectations(std::unique_ptr<SequencedSocketData> socket_data);
  129. // Allow an SSL socket data provider to be added.
  130. void AddSSLSocketDataProvider(
  131. std::unique_ptr<SSLSocketDataProvider> ssl_socket_data);
  132. // Allow a proxy to be set. Usage:
  133. // SetProxyConfig("proxy1:8000");
  134. // Any syntax accepted by net::ProxyConfig::ParseFromString() will work.
  135. // Do not call after GetURLRequestContext() has been called.
  136. void SetProxyConfig(const std::string& proxy_rules);
  137. // Call after calling one of SetExpections() or AddRawExpectations(). The
  138. // returned pointer remains owned by this object.
  139. URLRequestContext* GetURLRequestContext();
  140. const TestNetworkDelegate& network_delegate() const {
  141. // This is safe because we set a TestNetworkDelegate on
  142. // `url_request_context_` creation.
  143. return *static_cast<TestNetworkDelegate*>(
  144. url_request_context_->network_delegate());
  145. }
  146. private:
  147. WebSocketMockClientSocketFactoryMaker maker_;
  148. std::unique_ptr<URLRequestContextBuilder> url_request_context_builder_;
  149. std::unique_ptr<URLRequestContext> url_request_context_;
  150. TestNetworkDelegate network_delegate_;
  151. };
  152. // WebSocketStream::ConnectDelegate implementation that does nothing.
  153. class DummyConnectDelegate : public WebSocketStream::ConnectDelegate {
  154. public:
  155. DummyConnectDelegate() = default;
  156. ~DummyConnectDelegate() override = default;
  157. void OnCreateRequest(URLRequest* url_request) override {}
  158. void OnSuccess(
  159. std::unique_ptr<WebSocketStream> stream,
  160. std::unique_ptr<WebSocketHandshakeResponseInfo> response) override {}
  161. void OnFailure(const std::string& message,
  162. int net_error,
  163. absl::optional<int> response_code) override {}
  164. void OnStartOpeningHandshake(
  165. std::unique_ptr<WebSocketHandshakeRequestInfo> request) override {}
  166. void OnSSLCertificateError(
  167. std::unique_ptr<WebSocketEventInterface::SSLErrorCallbacks>
  168. ssl_error_callbacks,
  169. int net_error,
  170. const SSLInfo& ssl_info,
  171. bool fatal) override {}
  172. int OnAuthRequired(const AuthChallengeInfo& auth_info,
  173. scoped_refptr<HttpResponseHeaders> response_headers,
  174. const IPEndPoint& remote_endpoint,
  175. base::OnceCallback<void(const AuthCredentials*)> callback,
  176. absl::optional<AuthCredentials>* credentials) override;
  177. };
  178. // WebSocketStreamRequestAPI implementation that sets the value of
  179. // Sec-WebSocket-Key to the deterministic key that is used by tests.
  180. class TestWebSocketStreamRequestAPI : public WebSocketStreamRequestAPI {
  181. public:
  182. TestWebSocketStreamRequestAPI() = default;
  183. ~TestWebSocketStreamRequestAPI() override = default;
  184. void OnBasicHandshakeStreamCreated(
  185. WebSocketBasicHandshakeStream* handshake_stream) override;
  186. void OnHttp2HandshakeStreamCreated(
  187. WebSocketHttp2HandshakeStream* handshake_stream) override;
  188. void OnFailure(const std::string& message,
  189. int net_error,
  190. absl::optional<int> response_code) override {}
  191. };
  192. // A sub-class of WebSocketHandshakeStreamCreateHelper which sets a
  193. // deterministic key to use in the WebSocket handshake, and uses a dummy
  194. // ConnectDelegate and WebSocketStreamRequestAPI.
  195. class TestWebSocketHandshakeStreamCreateHelper
  196. : public WebSocketHandshakeStreamCreateHelper {
  197. public:
  198. // Constructor for using dummy ConnectDelegate and WebSocketStreamRequestAPI.
  199. TestWebSocketHandshakeStreamCreateHelper()
  200. : WebSocketHandshakeStreamCreateHelper(&connect_delegate_,
  201. /* requested_subprotocols = */ {},
  202. &request_) {}
  203. TestWebSocketHandshakeStreamCreateHelper(
  204. const TestWebSocketHandshakeStreamCreateHelper&) = delete;
  205. TestWebSocketHandshakeStreamCreateHelper& operator=(
  206. const TestWebSocketHandshakeStreamCreateHelper&) = delete;
  207. ~TestWebSocketHandshakeStreamCreateHelper() override = default;
  208. private:
  209. DummyConnectDelegate connect_delegate_;
  210. TestWebSocketStreamRequestAPI request_;
  211. };
  212. } // namespace net
  213. #endif // NET_WEBSOCKETS_WEBSOCKET_TEST_UTIL_H_