spdy_test_util_common.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. // Copyright (c) 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_SPDY_SPDY_TEST_UTIL_COMMON_H_
  5. #define NET_SPDY_SPDY_TEST_UTIL_COMMON_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <map>
  9. #include <memory>
  10. #include <string>
  11. #include <vector>
  12. #include "base/containers/span.h"
  13. #include "base/memory/raw_ptr.h"
  14. #include "base/memory/ref_counted.h"
  15. #include "base/strings/string_piece.h"
  16. #include "crypto/ec_private_key.h"
  17. #include "net/base/completion_once_callback.h"
  18. #include "net/base/proxy_server.h"
  19. #include "net/base/request_priority.h"
  20. #include "net/base/test_completion_callback.h"
  21. #include "net/cert/cert_verifier.h"
  22. #include "net/dns/mock_host_resolver.h"
  23. #include "net/http/http_auth_handler_factory.h"
  24. #include "net/http/http_network_session.h"
  25. #include "net/http/http_response_info.h"
  26. #include "net/http/http_server_properties.h"
  27. #include "net/http/transport_security_state.h"
  28. #include "net/proxy_resolution/proxy_resolution_service.h"
  29. #include "net/socket/socket_test_util.h"
  30. #include "net/spdy/spdy_session.h"
  31. #include "net/spdy/spdy_session_pool.h"
  32. #include "net/ssl/ssl_config_service_defaults.h"
  33. #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"
  34. #include "testing/gtest/include/gtest/gtest.h"
  35. #if BUILDFLAG(ENABLE_REPORTING)
  36. #include "net/network_error_logging/network_error_logging_service.h"
  37. #include "net/reporting/reporting_service.h"
  38. #endif
  39. class GURL;
  40. namespace net {
  41. class CTPolicyEnforcer;
  42. class ClientSocketFactory;
  43. class HashValue;
  44. class HostPortPair;
  45. class HostResolver;
  46. class QuicContext;
  47. class HttpUserAgentSettings;
  48. class NetLogWithSource;
  49. class SpdySessionKey;
  50. class SpdyStream;
  51. class SpdyStreamRequest;
  52. class TransportSecurityState;
  53. class URLRequestContextBuilder;
  54. // Default upload data used by both, mock objects and framer when creating
  55. // data frames.
  56. const char kDefaultUrl[] = "https://www.example.org/";
  57. const char kUploadData[] = "hello!";
  58. const int kUploadDataSize = std::size(kUploadData) - 1;
  59. // While HTTP/2 protocol defines default SETTINGS_MAX_HEADER_LIST_SIZE_FOR_TEST
  60. // to be unlimited, BufferedSpdyFramer constructor requires a value.
  61. const uint32_t kMaxHeaderListSizeForTest = 1024;
  62. // Chop a spdy::SpdySerializedFrame into an array of MockWrites.
  63. // |frame| is the frame to chop.
  64. // |num_chunks| is the number of chunks to create.
  65. std::unique_ptr<MockWrite[]> ChopWriteFrame(
  66. const spdy::SpdySerializedFrame& frame,
  67. int num_chunks);
  68. // Adds headers and values to a map.
  69. // |extra_headers| is an array of { name, value } pairs, arranged as strings
  70. // where the even entries are the header names, and the odd entries are the
  71. // header values.
  72. // |headers| gets filled in from |extra_headers|.
  73. void AppendToHeaderBlock(const char* const extra_headers[],
  74. int extra_header_count,
  75. spdy::Http2HeaderBlock* headers);
  76. // Create an async MockWrite from the given spdy::SpdySerializedFrame.
  77. MockWrite CreateMockWrite(const spdy::SpdySerializedFrame& req);
  78. // Create an async MockWrite from the given spdy::SpdySerializedFrame and
  79. // sequence number.
  80. MockWrite CreateMockWrite(const spdy::SpdySerializedFrame& req, int seq);
  81. MockWrite CreateMockWrite(const spdy::SpdySerializedFrame& req,
  82. int seq,
  83. IoMode mode);
  84. // Create a MockRead from the given spdy::SpdySerializedFrame.
  85. MockRead CreateMockRead(const spdy::SpdySerializedFrame& resp);
  86. // Create a MockRead from the given spdy::SpdySerializedFrame and sequence
  87. // number.
  88. MockRead CreateMockRead(const spdy::SpdySerializedFrame& resp, int seq);
  89. MockRead CreateMockRead(const spdy::SpdySerializedFrame& resp,
  90. int seq,
  91. IoMode mode);
  92. // Combines the given vector of spdy::SpdySerializedFrame into a single frame.
  93. spdy::SpdySerializedFrame CombineFrames(
  94. std::vector<const spdy::SpdySerializedFrame*> frames);
  95. // Returns the spdy::SpdyPriority embedded in the given frame. Returns true
  96. // and fills in |priority| on success.
  97. bool GetSpdyPriority(const spdy::SpdySerializedFrame& frame,
  98. spdy::SpdyPriority* priority);
  99. // Tries to create a stream in |session| synchronously. Returns NULL
  100. // on failure.
  101. base::WeakPtr<SpdyStream> CreateStreamSynchronously(
  102. SpdyStreamType type,
  103. const base::WeakPtr<SpdySession>& session,
  104. const GURL& url,
  105. RequestPriority priority,
  106. const NetLogWithSource& net_log,
  107. bool detect_broken_connection = false,
  108. base::TimeDelta heartbeat_interval = base::Seconds(0));
  109. // Helper class used by some tests to release a stream as soon as it's
  110. // created.
  111. class StreamReleaserCallback : public TestCompletionCallbackBase {
  112. public:
  113. StreamReleaserCallback();
  114. ~StreamReleaserCallback() override;
  115. // Returns a callback that releases |request|'s stream.
  116. CompletionOnceCallback MakeCallback(SpdyStreamRequest* request);
  117. private:
  118. void OnComplete(SpdyStreamRequest* request, int result);
  119. };
  120. // Helper to manage the lifetimes of the dependencies for a
  121. // HttpNetworkTransaction.
  122. struct SpdySessionDependencies {
  123. // Default set of dependencies -- "null" proxy service.
  124. SpdySessionDependencies();
  125. // Custom proxy service dependency.
  126. explicit SpdySessionDependencies(
  127. std::unique_ptr<ProxyResolutionService> proxy_resolution_service);
  128. SpdySessionDependencies(SpdySessionDependencies&&);
  129. ~SpdySessionDependencies();
  130. SpdySessionDependencies& operator=(SpdySessionDependencies&&);
  131. HostResolver* GetHostResolver() {
  132. return alternate_host_resolver ? alternate_host_resolver.get()
  133. : host_resolver.get();
  134. }
  135. static std::unique_ptr<HttpNetworkSession> SpdyCreateSession(
  136. SpdySessionDependencies* session_deps);
  137. // Variant that ignores session_deps->socket_factory, and uses the passed in
  138. // |factory| instead.
  139. static std::unique_ptr<HttpNetworkSession> SpdyCreateSessionWithSocketFactory(
  140. SpdySessionDependencies* session_deps,
  141. ClientSocketFactory* factory);
  142. static HttpNetworkSessionParams CreateSessionParams(
  143. SpdySessionDependencies* session_deps);
  144. static HttpNetworkSessionContext CreateSessionContext(
  145. SpdySessionDependencies* session_deps);
  146. // NOTE: host_resolver must be ordered before http_auth_handler_factory.
  147. std::unique_ptr<MockHostResolverBase> host_resolver;
  148. // For using a HostResolver not derived from MockHostResolverBase.
  149. std::unique_ptr<HostResolver> alternate_host_resolver;
  150. std::unique_ptr<CertVerifier> cert_verifier;
  151. std::unique_ptr<TransportSecurityState> transport_security_state;
  152. std::unique_ptr<CTPolicyEnforcer> ct_policy_enforcer;
  153. std::unique_ptr<ProxyResolutionService> proxy_resolution_service;
  154. std::unique_ptr<HttpUserAgentSettings> http_user_agent_settings;
  155. std::unique_ptr<SSLConfigService> ssl_config_service;
  156. std::unique_ptr<MockClientSocketFactory> socket_factory;
  157. std::unique_ptr<HttpAuthHandlerFactory> http_auth_handler_factory;
  158. std::unique_ptr<HttpServerProperties> http_server_properties;
  159. std::unique_ptr<QuicContext> quic_context;
  160. #if BUILDFLAG(ENABLE_REPORTING)
  161. std::unique_ptr<ReportingService> reporting_service;
  162. std::unique_ptr<NetworkErrorLoggingService> network_error_logging_service;
  163. #endif
  164. bool enable_ip_pooling = true;
  165. bool enable_ping = false;
  166. bool enable_user_alternate_protocol_ports = false;
  167. bool enable_quic = false;
  168. bool enable_server_push_cancellation = false;
  169. size_t session_max_recv_window_size = kDefaultInitialWindowSize;
  170. int session_max_queued_capped_frames = kSpdySessionMaxQueuedCappedFrames;
  171. spdy::SettingsMap http2_settings;
  172. SpdySession::TimeFunc time_func;
  173. bool enable_http2_alternative_service = false;
  174. bool enable_http2_settings_grease = false;
  175. absl::optional<SpdySessionPool::GreasedHttp2Frame> greased_http2_frame;
  176. bool http2_end_stream_with_data_frame = false;
  177. raw_ptr<NetLog> net_log = nullptr;
  178. bool disable_idle_sockets_close_on_memory_pressure = false;
  179. bool enable_early_data = false;
  180. bool key_auth_cache_server_entries_by_network_isolation_key = false;
  181. bool enable_priority_update = false;
  182. #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_IOS)
  183. bool go_away_on_ip_change = true;
  184. #else
  185. bool go_away_on_ip_change = false;
  186. #endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_IOS)
  187. bool ignore_ip_address_changes = false;
  188. };
  189. std::unique_ptr<URLRequestContextBuilder>
  190. CreateSpdyTestURLRequestContextBuilder(
  191. ClientSocketFactory* client_socket_factory);
  192. // Equivalent to pool->GetIfExists(spdy_session_key, NetLogWithSource()) !=
  193. // NULL.
  194. bool HasSpdySession(SpdySessionPool* pool, const SpdySessionKey& key);
  195. // Creates a SPDY session for the given key and puts it in the SPDY
  196. // session pool in |http_session|. A SPDY session for |key| must not
  197. // already exist.
  198. base::WeakPtr<SpdySession> CreateSpdySession(HttpNetworkSession* http_session,
  199. const SpdySessionKey& key,
  200. const NetLogWithSource& net_log);
  201. // Like CreateSpdySession(), but does not fail if there is already an IP
  202. // pooled session for |key|.
  203. base::WeakPtr<SpdySession> CreateSpdySessionWithIpBasedPoolingDisabled(
  204. HttpNetworkSession* http_session,
  205. const SpdySessionKey& key,
  206. const NetLogWithSource& net_log);
  207. // Creates a SPDY session for the given key and puts it in |pool|.
  208. // The returned session will neither receive nor send any data.
  209. // A SPDY session for |key| must not already exist.
  210. base::WeakPtr<SpdySession> CreateFakeSpdySession(SpdySessionPool* pool,
  211. const SpdySessionKey& key);
  212. class SpdySessionPoolPeer {
  213. public:
  214. explicit SpdySessionPoolPeer(SpdySessionPool* pool);
  215. SpdySessionPoolPeer(const SpdySessionPoolPeer&) = delete;
  216. SpdySessionPoolPeer& operator=(const SpdySessionPoolPeer&) = delete;
  217. void RemoveAliases(const SpdySessionKey& key);
  218. void SetEnableSendingInitialData(bool enabled);
  219. private:
  220. const raw_ptr<SpdySessionPool> pool_;
  221. };
  222. class SpdyTestUtil {
  223. public:
  224. SpdyTestUtil();
  225. ~SpdyTestUtil();
  226. // Add the appropriate headers to put |url| into |block|.
  227. void AddUrlToHeaderBlock(base::StringPiece url,
  228. spdy::Http2HeaderBlock* headers) const;
  229. static spdy::Http2HeaderBlock ConstructGetHeaderBlock(base::StringPiece url);
  230. static spdy::Http2HeaderBlock ConstructGetHeaderBlockForProxy(
  231. base::StringPiece url);
  232. static spdy::Http2HeaderBlock ConstructHeadHeaderBlock(
  233. base::StringPiece url,
  234. int64_t content_length);
  235. static spdy::Http2HeaderBlock ConstructPostHeaderBlock(
  236. base::StringPiece url,
  237. int64_t content_length);
  238. static spdy::Http2HeaderBlock ConstructPutHeaderBlock(base::StringPiece url,
  239. int64_t content_length);
  240. // Construct an expected SPDY reply string from the given headers.
  241. std::string ConstructSpdyReplyString(
  242. const spdy::Http2HeaderBlock& headers) const;
  243. // Construct an expected SPDY SETTINGS frame.
  244. // |settings| are the settings to set.
  245. // Returns the constructed frame.
  246. spdy::SpdySerializedFrame ConstructSpdySettings(
  247. const spdy::SettingsMap& settings);
  248. // Constructs an expected SPDY SETTINGS acknowledgement frame.
  249. spdy::SpdySerializedFrame ConstructSpdySettingsAck();
  250. // Construct a SPDY PING frame. Returns the constructed frame.
  251. spdy::SpdySerializedFrame ConstructSpdyPing(uint32_t ping_id, bool is_ack);
  252. // Construct a SPDY GOAWAY frame with the specified last_good_stream_id.
  253. // Returns the constructed frame.
  254. spdy::SpdySerializedFrame ConstructSpdyGoAway(
  255. spdy::SpdyStreamId last_good_stream_id);
  256. // Construct a SPDY GOAWAY frame with the specified last_good_stream_id,
  257. // status, and description. Returns the constructed frame.
  258. spdy::SpdySerializedFrame ConstructSpdyGoAway(
  259. spdy::SpdyStreamId last_good_stream_id,
  260. spdy::SpdyErrorCode error_code,
  261. const std::string& desc);
  262. // Construct a SPDY WINDOW_UPDATE frame. Returns the constructed frame.
  263. spdy::SpdySerializedFrame ConstructSpdyWindowUpdate(
  264. spdy::SpdyStreamId stream_id,
  265. uint32_t delta_window_size);
  266. // Construct a SPDY RST_STREAM frame. Returns the constructed frame.
  267. spdy::SpdySerializedFrame ConstructSpdyRstStream(
  268. spdy::SpdyStreamId stream_id,
  269. spdy::SpdyErrorCode error_code);
  270. // Construct a PRIORITY frame. The weight is derived from |request_priority|.
  271. // Returns the constructed frame.
  272. spdy::SpdySerializedFrame ConstructSpdyPriority(
  273. spdy::SpdyStreamId stream_id,
  274. spdy::SpdyStreamId parent_stream_id,
  275. RequestPriority request_priority,
  276. bool exclusive);
  277. // Constructs a standard SPDY GET HEADERS frame for |url| with header
  278. // compression.
  279. // |extra_headers| are the extra header-value pairs, which typically
  280. // will vary the most between calls.
  281. spdy::SpdySerializedFrame ConstructSpdyGet(const char* const url,
  282. spdy::SpdyStreamId stream_id,
  283. RequestPriority request_priority);
  284. // Constructs a standard SPDY GET HEADERS frame with header compression.
  285. // |extra_headers| are the extra header-value pairs, which typically
  286. // will vary the most between calls. If |direct| is false, the
  287. // the full url will be used instead of simply the path.
  288. spdy::SpdySerializedFrame ConstructSpdyGet(const char* const extra_headers[],
  289. int extra_header_count,
  290. int stream_id,
  291. RequestPriority request_priority);
  292. // Constructs a SPDY HEADERS frame for a CONNECT request.
  293. spdy::SpdySerializedFrame ConstructSpdyConnect(
  294. const char* const extra_headers[],
  295. int extra_header_count,
  296. int stream_id,
  297. RequestPriority priority,
  298. const HostPortPair& host_port_pair);
  299. // Constructs a PUSH_PROMISE frame and a HEADERS frame on the pushed stream.
  300. // |extra_headers| are the extra header-value pairs, which typically
  301. // will vary the most between calls.
  302. // Returns a spdy::SpdySerializedFrame object with the two frames
  303. // concatenated.
  304. spdy::SpdySerializedFrame ConstructSpdyPush(const char* const extra_headers[],
  305. int extra_header_count,
  306. int stream_id,
  307. int associated_stream_id,
  308. const char* url);
  309. spdy::SpdySerializedFrame ConstructSpdyPush(const char* const extra_headers[],
  310. int extra_header_count,
  311. int stream_id,
  312. int associated_stream_id,
  313. const char* url,
  314. const char* status,
  315. const char* location);
  316. // Constructs a PUSH_PROMISE frame.
  317. spdy::SpdySerializedFrame ConstructSpdyPushPromise(
  318. spdy::SpdyStreamId associated_stream_id,
  319. spdy::SpdyStreamId stream_id,
  320. spdy::Http2HeaderBlock headers);
  321. spdy::SpdySerializedFrame ConstructSpdyPushHeaders(
  322. int stream_id,
  323. const char* const extra_headers[],
  324. int extra_header_count);
  325. // Constructs a HEADERS frame with the request header compression context with
  326. // END_STREAM flag set to |fin|.
  327. spdy::SpdySerializedFrame ConstructSpdyResponseHeaders(
  328. int stream_id,
  329. spdy::Http2HeaderBlock headers,
  330. bool fin);
  331. // Construct a HEADERS frame carrying exactly the given headers and priority.
  332. spdy::SpdySerializedFrame ConstructSpdyHeaders(int stream_id,
  333. spdy::Http2HeaderBlock headers,
  334. RequestPriority priority,
  335. bool fin);
  336. // Construct a reply HEADERS frame carrying exactly the given headers and the
  337. // default priority.
  338. spdy::SpdySerializedFrame ConstructSpdyReply(int stream_id,
  339. spdy::Http2HeaderBlock headers);
  340. // Constructs a standard SPDY HEADERS frame to match the SPDY GET.
  341. // |extra_headers| are the extra header-value pairs, which typically
  342. // will vary the most between calls.
  343. spdy::SpdySerializedFrame ConstructSpdyGetReply(
  344. const char* const extra_headers[],
  345. int extra_header_count,
  346. int stream_id);
  347. // Constructs a standard SPDY HEADERS frame with an Internal Server
  348. // Error status code.
  349. spdy::SpdySerializedFrame ConstructSpdyReplyError(int stream_id);
  350. // Constructs a standard SPDY HEADERS frame with the specified status code.
  351. spdy::SpdySerializedFrame ConstructSpdyReplyError(
  352. const char* const status,
  353. const char* const* const extra_headers,
  354. int extra_header_count,
  355. int stream_id);
  356. // Constructs a standard SPDY POST HEADERS frame.
  357. // |extra_headers| are the extra header-value pairs, which typically
  358. // will vary the most between calls.
  359. spdy::SpdySerializedFrame ConstructSpdyPost(const char* url,
  360. spdy::SpdyStreamId stream_id,
  361. int64_t content_length,
  362. RequestPriority priority,
  363. const char* const extra_headers[],
  364. int extra_header_count);
  365. // Constructs a chunked transfer SPDY POST HEADERS frame.
  366. // |extra_headers| are the extra header-value pairs, which typically
  367. // will vary the most between calls.
  368. spdy::SpdySerializedFrame ConstructChunkedSpdyPost(
  369. const char* const extra_headers[],
  370. int extra_header_count);
  371. // Constructs a standard SPDY HEADERS frame to match the SPDY POST.
  372. // |extra_headers| are the extra header-value pairs, which typically
  373. // will vary the most between calls.
  374. spdy::SpdySerializedFrame ConstructSpdyPostReply(
  375. const char* const extra_headers[],
  376. int extra_header_count);
  377. // Constructs a single SPDY data frame with the contents "hello!"
  378. spdy::SpdySerializedFrame ConstructSpdyDataFrame(int stream_id, bool fin);
  379. // Constructs a single SPDY data frame with the given content.
  380. spdy::SpdySerializedFrame ConstructSpdyDataFrame(int stream_id,
  381. base::StringPiece data,
  382. bool fin);
  383. // Constructs a single SPDY data frame with the given content and padding.
  384. spdy::SpdySerializedFrame ConstructSpdyDataFrame(int stream_id,
  385. base::StringPiece data,
  386. bool fin,
  387. int padding_length);
  388. // Wraps |frame| in the payload of a data frame in stream |stream_id|.
  389. spdy::SpdySerializedFrame ConstructWrappedSpdyFrame(
  390. const spdy::SpdySerializedFrame& frame,
  391. int stream_id);
  392. // Serialize a spdy::SpdyFrameIR with |headerless_spdy_framer_|.
  393. spdy::SpdySerializedFrame SerializeFrame(const spdy::SpdyFrameIR& frame_ir);
  394. // Called when necessary (when it will affect stream dependency specification
  395. // when setting dependencies based on priorioties) to notify the utility
  396. // class of stream destruction.
  397. void UpdateWithStreamDestruction(int stream_id);
  398. void set_default_url(const GURL& url) { default_url_ = url; }
  399. private:
  400. // |content_length| may be NULL, in which case the content-length
  401. // header will be omitted.
  402. static spdy::Http2HeaderBlock ConstructHeaderBlock(base::StringPiece method,
  403. base::StringPiece url,
  404. int64_t* content_length);
  405. // Multiple SpdyFramers are required to keep track of header compression
  406. // state.
  407. // Use to serialize frames (request or response) without headers.
  408. spdy::SpdyFramer headerless_spdy_framer_;
  409. // Use to serialize request frames with headers.
  410. spdy::SpdyFramer request_spdy_framer_;
  411. // Use to serialize response frames with headers.
  412. spdy::SpdyFramer response_spdy_framer_;
  413. GURL default_url_;
  414. // Track a FIFO list of the stream_id of all created requests by priority.
  415. std::map<int, std::vector<int>> priority_to_stream_id_list_;
  416. };
  417. namespace test {
  418. // Returns a SHA1 HashValue in which each byte has the value |label|.
  419. HashValue GetTestHashValue(uint8_t label);
  420. // A test implementation of ServerPushDelegate that caches all the pushed
  421. // request and provides a interface to cancel the push given url.
  422. class TestServerPushDelegate : public ServerPushDelegate {
  423. public:
  424. TestServerPushDelegate();
  425. ~TestServerPushDelegate() override;
  426. void OnPush(std::unique_ptr<ServerPushHelper> push_helper,
  427. const NetLogWithSource& session_net_log) override;
  428. bool CancelPush(GURL url);
  429. private:
  430. std::map<GURL, std::unique_ptr<ServerPushHelper>> push_helpers;
  431. };
  432. } // namespace test
  433. } // namespace net
  434. #endif // NET_SPDY_SPDY_TEST_UTIL_COMMON_H_