1 // Copyright (c) 2012 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.
5 #ifndef NET_SPDY_SPDY_TEST_UTIL_H_
6 #define NET_SPDY_SPDY_TEST_UTIL_H_
8 #include "base/basictypes.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "crypto/ec_private_key.h"
11 #include "crypto/ec_signature_creator.h"
12 #include "net/base/cert_verifier.h"
13 #include "net/base/host_port_pair.h"
14 #include "net/base/mock_host_resolver.h"
15 #include "net/base/request_priority.h"
16 #include "net/base/ssl_config_service_defaults.h"
17 #include "net/http/http_auth_handler_factory.h"
18 #include "net/http/http_cache.h"
19 #include "net/http/http_network_session.h"
20 #include "net/http/http_network_layer.h"
21 #include "net/http/http_server_properties_impl.h"
22 #include "net/http/http_transaction_factory.h"
23 #include "net/proxy/proxy_service.h"
24 #include "net/socket/socket_test_util.h"
25 #include "net/spdy/spdy_session.h"
26 #include "net/url_request/url_request_context.h"
27 #include "net/url_request/url_request_context_storage.h"
30 class ECSignatureCreatorFactory
;
35 namespace test_spdy3
{
37 // Default upload data used by both, mock objects and framer when creating
39 const char kDefaultURL
[] = "http://www.google.com";
40 const char kUploadData
[] = "hello!";
41 const int kUploadDataSize
= arraysize(kUploadData
)-1;
43 // NOTE: In GCC, on a Mac, this can't be in an anonymous namespace!
44 // This struct holds information used to construct spdy control and data frames.
45 struct SpdyHeaderInfo
{
48 SpdyStreamId assoc_id
;
49 SpdyPriority priority
;
50 size_t credential_slot
;
51 SpdyControlFlags control_flags
;
53 SpdyStatusCodes status
;
56 SpdyDataFlags data_flags
;
59 // An ECSignatureCreator that returns deterministic signatures.
60 class MockECSignatureCreator
: public crypto::ECSignatureCreator
{
62 explicit MockECSignatureCreator(crypto::ECPrivateKey
* key
);
64 // crypto::ECSignatureCreator
65 virtual bool Sign(const uint8
* data
,
67 std::vector
<uint8
>* signature
) OVERRIDE
;
68 virtual bool DecodeSignature(const std::vector
<uint8
>& signature
,
69 std::vector
<uint8
>* out_raw_sig
) OVERRIDE
;
72 crypto::ECPrivateKey
* key_
;
74 DISALLOW_COPY_AND_ASSIGN(MockECSignatureCreator
);
77 // An ECSignatureCreatorFactory creates MockECSignatureCreator.
78 class MockECSignatureCreatorFactory
: public crypto::ECSignatureCreatorFactory
{
80 MockECSignatureCreatorFactory();
81 virtual ~MockECSignatureCreatorFactory();
83 // crypto::ECSignatureCreatorFactory
84 virtual crypto::ECSignatureCreator
* Create(
85 crypto::ECPrivateKey
* key
) OVERRIDE
;
88 DISALLOW_COPY_AND_ASSIGN(MockECSignatureCreatorFactory
);
91 // Chop a frame into an array of MockWrites.
92 // |data| is the frame to chop.
93 // |length| is the length of the frame to chop.
94 // |num_chunks| is the number of chunks to create.
95 MockWrite
* ChopWriteFrame(const char* data
, int length
, int num_chunks
);
97 // Chop a SpdyFrame into an array of MockWrites.
98 // |frame| is the frame to chop.
99 // |num_chunks| is the number of chunks to create.
100 MockWrite
* ChopWriteFrame(const SpdyFrame
& frame
, int num_chunks
);
102 // Chop a frame into an array of MockReads.
103 // |data| is the frame to chop.
104 // |length| is the length of the frame to chop.
105 // |num_chunks| is the number of chunks to create.
106 MockRead
* ChopReadFrame(const char* data
, int length
, int num_chunks
);
108 // Chop a SpdyFrame into an array of MockReads.
109 // |frame| is the frame to chop.
110 // |num_chunks| is the number of chunks to create.
111 MockRead
* ChopReadFrame(const SpdyFrame
& frame
, int num_chunks
);
113 // Adds headers and values to a map.
114 // |extra_headers| is an array of { name, value } pairs, arranged as strings
115 // where the even entries are the header names, and the odd entries are the
117 // |headers| gets filled in from |extra_headers|.
118 void AppendHeadersToSpdyFrame(const char* const extra_headers
[],
119 int extra_header_count
,
120 SpdyHeaderBlock
* headers
);
122 // Writes |str| of the given |len| to the buffer pointed to by |buffer_handle|.
123 // Uses a template so buffer_handle can be a char* or an unsigned char*.
124 // Updates the |*buffer_handle| pointer by |len|
125 // Returns the number of bytes written into *|buffer_handle|
127 int AppendToBuffer(const char* str
,
130 int* buffer_len_remaining
) {
132 DCHECK(NULL
!= buffer_handle
) << "NULL buffer handle";
133 DCHECK(NULL
!= *buffer_handle
) << "NULL pointer";
134 DCHECK(NULL
!= buffer_len_remaining
)
135 << "NULL buffer remainder length pointer";
136 DCHECK_GE(*buffer_len_remaining
, len
) << "Insufficient buffer size";
137 memcpy(*buffer_handle
, str
, len
);
138 *buffer_handle
+= len
;
139 *buffer_len_remaining
-= len
;
143 // Writes |val| to a location of size |len|, in big-endian format.
144 // in the buffer pointed to by |buffer_handle|.
145 // Updates the |*buffer_handle| pointer by |len|
146 // Returns the number of bytes written
147 int AppendToBuffer(int val
,
149 unsigned char** buffer_handle
,
150 int* buffer_len_remaining
);
152 // Construct a SPDY packet.
153 // |head| is the start of the packet, up to but not including
154 // the header value pairs.
155 // |extra_headers| are the extra header-value pairs, which typically
156 // will vary the most between calls.
157 // |tail| is any (relatively constant) header-value pairs to add.
158 // |buffer| is the buffer we're filling in.
159 // Returns a SpdyFrame.
160 SpdyFrame
* ConstructSpdyPacket(const SpdyHeaderInfo
& header_info
,
161 const char* const extra_headers
[],
162 int extra_header_count
,
163 const char* const tail
[],
164 int tail_header_count
);
166 // Construct a generic SpdyControlFrame.
167 SpdyFrame
* ConstructSpdyControlFrame(const char* const extra_headers
[],
168 int extra_header_count
,
171 RequestPriority request_priority
,
172 SpdyControlType type
,
173 SpdyControlFlags flags
,
174 const char* const* kHeaders
,
176 SpdyFrame
* ConstructSpdyControlFrame(const char* const extra_headers
[],
177 int extra_header_count
,
179 SpdyStreamId stream_id
,
180 RequestPriority request_priority
,
181 SpdyControlType type
,
182 SpdyControlFlags flags
,
183 const char* const* kHeaders
,
185 SpdyStreamId associated_stream_id
);
187 // Construct an expected SPDY reply string.
188 // |extra_headers| are the extra header-value pairs, which typically
189 // will vary the most between calls.
190 // |buffer| is the buffer we're filling in.
191 // Returns the number of bytes written into |buffer|.
192 int ConstructSpdyReplyString(const char* const extra_headers
[],
193 int extra_header_count
,
197 // Construct an expected SPDY SETTINGS frame.
198 // |settings| are the settings to set.
199 // Returns the constructed frame. The caller takes ownership of the frame.
200 SpdyFrame
* ConstructSpdySettings(const SettingsMap
& settings
);
202 // Construct an expected SPDY CREDENTIAL frame.
203 // |credential| is the credential to send.
204 // Returns the constructed frame. The caller takes ownership of the frame.
205 SpdyFrame
* ConstructSpdyCredential(const SpdyCredential
& credential
);
207 // Construct a SPDY PING frame.
208 // Returns the constructed frame. The caller takes ownership of the frame.
209 SpdyFrame
* ConstructSpdyPing(uint32 ping_id
);
211 // Construct a SPDY GOAWAY frame.
212 // Returns the constructed frame. The caller takes ownership of the frame.
213 SpdyFrame
* ConstructSpdyGoAway();
215 // Construct a SPDY WINDOW_UPDATE frame.
216 // Returns the constructed frame. The caller takes ownership of the frame.
217 SpdyFrame
* ConstructSpdyWindowUpdate(SpdyStreamId
, uint32 delta_window_size
);
219 // Construct a SPDY RST_STREAM frame.
220 // Returns the constructed frame. The caller takes ownership of the frame.
221 SpdyFrame
* ConstructSpdyRstStream(SpdyStreamId stream_id
,
222 SpdyStatusCodes status
);
224 // Construct a single SPDY header entry, for validation.
225 // |extra_headers| are the extra header-value pairs.
226 // |buffer| is the buffer we're filling in.
227 // |index| is the index of the header we want.
228 // Returns the number of bytes written into |buffer|.
229 int ConstructSpdyHeader(const char* const extra_headers
[],
230 int extra_header_count
,
235 // Constructs a standard SPDY GET SYN packet, optionally compressed
236 // for the url |url|.
237 // |extra_headers| are the extra header-value pairs, which typically
238 // will vary the most between calls.
239 // Returns a SpdyFrame.
240 SpdyFrame
* ConstructSpdyGet(const char* const url
,
242 SpdyStreamId stream_id
,
243 RequestPriority request_priority
);
245 // Constructs a standard SPDY GET SYN packet, optionally compressed.
246 // |extra_headers| are the extra header-value pairs, which typically
247 // will vary the most between calls.
248 // Returns a SpdyFrame.
249 SpdyFrame
* ConstructSpdyGet(const char* const extra_headers
[],
250 int extra_header_count
,
253 RequestPriority request_priority
);
255 // Constructs a standard SPDY GET SYN packet, optionally compressed.
256 // |extra_headers| are the extra header-value pairs, which typically
257 // will vary the most between calls. If |direct| is false, the
258 // the full url will be used instead of simply the path.
259 // Returns a SpdyFrame.
260 SpdyFrame
* ConstructSpdyGet(const char* const extra_headers
[],
261 int extra_header_count
,
264 RequestPriority request_priority
,
267 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
268 SpdyFrame
* ConstructSpdyConnect(const char* const extra_headers
[],
269 int extra_header_count
,
272 // Constructs a standard SPDY push SYN packet.
273 // |extra_headers| are the extra header-value pairs, which typically
274 // will vary the most between calls.
275 // Returns a SpdyFrame.
276 SpdyFrame
* ConstructSpdyPush(const char* const extra_headers
[],
277 int extra_header_count
,
279 int associated_stream_id
);
280 SpdyFrame
* ConstructSpdyPush(const char* const extra_headers
[],
281 int extra_header_count
,
283 int associated_stream_id
,
285 SpdyFrame
* ConstructSpdyPush(const char* const extra_headers
[],
286 int extra_header_count
,
288 int associated_stream_id
,
291 const char* location
);
292 SpdyFrame
* ConstructSpdyPush(int stream_id
,
293 int associated_stream_id
,
296 SpdyFrame
* ConstructSpdyPushHeaders(int stream_id
,
297 const char* const extra_headers
[],
298 int extra_header_count
);
300 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
301 // |extra_headers| are the extra header-value pairs, which typically
302 // will vary the most between calls.
303 // Returns a SpdyFrame.
304 SpdyFrame
* ConstructSpdyGetSynReply(const char* const extra_headers
[],
305 int extra_header_count
,
308 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
309 // |extra_headers| are the extra header-value pairs, which typically
310 // will vary the most between calls.
311 // Returns a SpdyFrame.
312 SpdyFrame
* ConstructSpdyGetSynReplyRedirect(int stream_id
);
314 // Constructs a standard SPDY SYN_REPLY packet with an Internal Server
315 // Error status code.
316 // Returns a SpdyFrame.
317 SpdyFrame
* ConstructSpdySynReplyError(int stream_id
);
319 // Constructs a standard SPDY SYN_REPLY packet with the specified status code.
320 // Returns a SpdyFrame.
321 SpdyFrame
* ConstructSpdySynReplyError(const char* const status
,
322 const char* const* const extra_headers
,
323 int extra_header_count
,
326 // Constructs a standard SPDY POST SYN packet.
327 // |extra_headers| are the extra header-value pairs, which typically
328 // will vary the most between calls.
329 // Returns a SpdyFrame.
330 SpdyFrame
* ConstructSpdyPost(int64 content_length
,
331 const char* const extra_headers
[],
332 int extra_header_count
);
334 // Constructs a chunked transfer SPDY POST SYN packet.
335 // |extra_headers| are the extra header-value pairs, which typically
336 // will vary the most between calls.
337 // Returns a SpdyFrame.
338 SpdyFrame
* ConstructChunkedSpdyPost(const char* const extra_headers
[],
339 int extra_header_count
);
341 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY POST.
342 // |extra_headers| are the extra header-value pairs, which typically
343 // will vary the most between calls.
344 // Returns a SpdyFrame.
345 SpdyFrame
* ConstructSpdyPostSynReply(const char* const extra_headers
[],
346 int extra_header_count
);
348 // Constructs a single SPDY data frame with the contents "hello!"
349 SpdyFrame
* ConstructSpdyBodyFrame(int stream_id
,
352 // Constructs a single SPDY data frame with the given content.
353 SpdyFrame
* ConstructSpdyBodyFrame(int stream_id
, const char* data
,
354 uint32 len
, bool fin
);
356 // Wraps |frame| in the payload of a data frame in stream |stream_id|.
357 SpdyFrame
* ConstructWrappedSpdyFrame(const scoped_ptr
<SpdyFrame
>& frame
,
360 // Create an async MockWrite from the given SpdyFrame.
361 MockWrite
CreateMockWrite(const SpdyFrame
& req
);
363 // Create an async MockWrite from the given SpdyFrame and sequence number.
364 MockWrite
CreateMockWrite(const SpdyFrame
& req
, int seq
);
366 MockWrite
CreateMockWrite(const SpdyFrame
& req
, int seq
, IoMode mode
);
368 // Create a MockRead from the given SpdyFrame.
369 MockRead
CreateMockRead(const SpdyFrame
& resp
);
371 // Create a MockRead from the given SpdyFrame and sequence number.
372 MockRead
CreateMockRead(const SpdyFrame
& resp
, int seq
);
374 MockRead
CreateMockRead(const SpdyFrame
& resp
, int seq
, IoMode mode
);
376 // Combines the given SpdyFrames into the given char array and returns
378 int CombineFrames(const SpdyFrame
** frames
, int num_frames
,
379 char* buff
, int buff_len
);
381 // Helper to manage the lifetimes of the dependencies for a
382 // HttpNetworkTransaction.
383 struct SpdySessionDependencies
{
384 // Default set of dependencies -- "null" proxy service.
385 SpdySessionDependencies();
387 // Custom proxy service dependency.
388 explicit SpdySessionDependencies(ProxyService
* proxy_service
);
390 ~SpdySessionDependencies();
392 static HttpNetworkSession
* SpdyCreateSession(
393 SpdySessionDependencies
* session_deps
);
394 static HttpNetworkSession
* SpdyCreateSessionDeterministic(
395 SpdySessionDependencies
* session_deps
);
396 static HttpNetworkSession::Params
CreateSessionParams(
397 SpdySessionDependencies
* session_deps
);
399 // NOTE: host_resolver must be ordered before http_auth_handler_factory.
400 scoped_ptr
<MockHostResolverBase
> host_resolver
;
401 scoped_ptr
<CertVerifier
> cert_verifier
;
402 scoped_ptr
<ProxyService
> proxy_service
;
403 scoped_refptr
<SSLConfigService
> ssl_config_service
;
404 scoped_ptr
<MockClientSocketFactory
> socket_factory
;
405 scoped_ptr
<DeterministicMockClientSocketFactory
> deterministic_socket_factory
;
406 scoped_ptr
<HttpAuthHandlerFactory
> http_auth_handler_factory
;
407 HttpServerPropertiesImpl http_server_properties
;
408 bool enable_ip_pooling
;
409 bool enable_compression
;
411 size_t initial_recv_window_size
;
412 SpdySession::TimeFunc time_func
;
413 std::string trusted_spdy_proxy
;
417 class SpdyURLRequestContext
: public URLRequestContext
{
419 SpdyURLRequestContext();
420 virtual ~SpdyURLRequestContext();
422 MockClientSocketFactory
& socket_factory() { return socket_factory_
; }
425 MockClientSocketFactory socket_factory_
;
426 net::URLRequestContextStorage storage_
;
429 const SpdyHeaderInfo
MakeSpdyHeader(SpdyControlType type
);
431 class SpdySessionPoolPeer
{
433 explicit SpdySessionPoolPeer(SpdySessionPool
* pool
)
436 void AddAlias(const IPEndPoint
& address
, const HostPortProxyPair
& pair
) {
437 pool_
->AddAlias(address
, pair
);
440 void RemoveAliases(const HostPortProxyPair
& pair
) {
441 pool_
->RemoveAliases(pair
);
444 void RemoveSpdySession(const scoped_refptr
<SpdySession
>& session
) {
445 pool_
->Remove(session
);
448 void DisableDomainAuthenticationVerification() {
449 pool_
->verify_domain_authentication_
= false;
452 void EnableSendingInitialSettings(bool enabled
) {
453 pool_
->enable_sending_initial_settings_
= enabled
;
457 SpdySessionPool
* const pool_
;
459 DISALLOW_COPY_AND_ASSIGN(SpdySessionPoolPeer
);
462 } // namespace test_spdy3
466 #endif // NET_SPDY_SPDY_TEST_UTIL_H_