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 "net/base/cert_verifier.h"
11 #include "net/base/host_port_pair.h"
12 #include "net/base/mock_host_resolver.h"
13 #include "net/base/request_priority.h"
14 #include "net/base/ssl_config_service_defaults.h"
15 #include "net/http/http_auth_handler_factory.h"
16 #include "net/http/http_cache.h"
17 #include "net/http/http_network_session.h"
18 #include "net/http/http_network_layer.h"
19 #include "net/http/http_server_properties_impl.h"
20 #include "net/http/http_transaction_factory.h"
21 #include "net/proxy/proxy_service.h"
22 #include "net/socket/socket_test_util.h"
23 #include "net/url_request/url_request_context.h"
24 #include "net/url_request/url_request_context_storage.h"
27 class ECSignatureCreatorFactory
;
32 namespace test_spdy3
{
34 // Default upload data used by both, mock objects and framer when creating
36 const char kDefaultURL
[] = "http://www.google.com";
37 const char kUploadData
[] = "hello!";
38 const int kUploadDataSize
= arraysize(kUploadData
)-1;
40 // NOTE: In GCC, on a Mac, this can't be in an anonymous namespace!
41 // This struct holds information used to construct spdy control and data frames.
42 struct SpdyHeaderInfo
{
45 SpdyStreamId assoc_id
;
46 SpdyPriority priority
;
47 size_t credential_slot
;
48 SpdyControlFlags control_flags
;
50 SpdyStatusCodes status
;
53 SpdyDataFlags data_flags
;
56 // Chop a frame into an array of MockWrites.
57 // |data| is the frame to chop.
58 // |length| is the length of the frame to chop.
59 // |num_chunks| is the number of chunks to create.
60 MockWrite
* ChopWriteFrame(const char* data
, int length
, int num_chunks
);
62 // Chop a SpdyFrame into an array of MockWrites.
63 // |frame| is the frame to chop.
64 // |num_chunks| is the number of chunks to create.
65 MockWrite
* ChopWriteFrame(const SpdyFrame
& frame
, int num_chunks
);
67 // Chop a frame into an array of MockReads.
68 // |data| is the frame to chop.
69 // |length| is the length of the frame to chop.
70 // |num_chunks| is the number of chunks to create.
71 MockRead
* ChopReadFrame(const char* data
, int length
, int num_chunks
);
73 // Chop a SpdyFrame into an array of MockReads.
74 // |frame| is the frame to chop.
75 // |num_chunks| is the number of chunks to create.
76 MockRead
* ChopReadFrame(const SpdyFrame
& frame
, int num_chunks
);
78 // Adds headers and values to a map.
79 // |extra_headers| is an array of { name, value } pairs, arranged as strings
80 // where the even entries are the header names, and the odd entries are the
82 // |headers| gets filled in from |extra_headers|.
83 void AppendHeadersToSpdyFrame(const char* const extra_headers
[],
84 int extra_header_count
,
85 SpdyHeaderBlock
* headers
);
87 // Writes |str| of the given |len| to the buffer pointed to by |buffer_handle|.
88 // Uses a template so buffer_handle can be a char* or an unsigned char*.
89 // Updates the |*buffer_handle| pointer by |len|
90 // Returns the number of bytes written into *|buffer_handle|
92 int AppendToBuffer(const char* str
,
95 int* buffer_len_remaining
) {
97 DCHECK(NULL
!= buffer_handle
) << "NULL buffer handle";
98 DCHECK(NULL
!= *buffer_handle
) << "NULL pointer";
99 DCHECK(NULL
!= buffer_len_remaining
)
100 << "NULL buffer remainder length pointer";
101 DCHECK_GE(*buffer_len_remaining
, len
) << "Insufficient buffer size";
102 memcpy(*buffer_handle
, str
, len
);
103 *buffer_handle
+= len
;
104 *buffer_len_remaining
-= len
;
108 // Writes |val| to a location of size |len|, in big-endian format.
109 // in the buffer pointed to by |buffer_handle|.
110 // Updates the |*buffer_handle| pointer by |len|
111 // Returns the number of bytes written
112 int AppendToBuffer(int val
,
114 unsigned char** buffer_handle
,
115 int* buffer_len_remaining
);
117 // Construct a SPDY packet.
118 // |head| is the start of the packet, up to but not including
119 // the header value pairs.
120 // |extra_headers| are the extra header-value pairs, which typically
121 // will vary the most between calls.
122 // |tail| is any (relatively constant) header-value pairs to add.
123 // |buffer| is the buffer we're filling in.
124 // Returns a SpdyFrame.
125 SpdyFrame
* ConstructSpdyPacket(const SpdyHeaderInfo
& header_info
,
126 const char* const extra_headers
[],
127 int extra_header_count
,
128 const char* const tail
[],
129 int tail_header_count
);
131 // Construct a generic SpdyControlFrame.
132 SpdyFrame
* ConstructSpdyControlFrame(const char* const extra_headers
[],
133 int extra_header_count
,
136 RequestPriority request_priority
,
137 SpdyControlType type
,
138 SpdyControlFlags flags
,
139 const char* const* kHeaders
,
141 SpdyFrame
* ConstructSpdyControlFrame(const char* const extra_headers
[],
142 int extra_header_count
,
145 RequestPriority request_priority
,
146 SpdyControlType type
,
147 SpdyControlFlags flags
,
148 const char* const* kHeaders
,
150 int associated_stream_id
);
152 // Construct an expected SPDY reply string.
153 // |extra_headers| are the extra header-value pairs, which typically
154 // will vary the most between calls.
155 // |buffer| is the buffer we're filling in.
156 // Returns the number of bytes written into |buffer|.
157 int ConstructSpdyReplyString(const char* const extra_headers
[],
158 int extra_header_count
,
162 // Construct an expected SPDY SETTINGS frame.
163 // |settings| are the settings to set.
164 // Returns the constructed frame. The caller takes ownership of the frame.
165 SpdyFrame
* ConstructSpdySettings(const SettingsMap
& settings
);
167 // Construct an expected SPDY CREDENTIAL frame.
168 // |credential| is the credential to send.
169 // Returns the constructed frame. The caller takes ownership of the frame.
170 SpdyFrame
* ConstructSpdyCredential(const SpdyCredential
& credential
);
172 // Construct a SPDY PING frame.
173 // Returns the constructed frame. The caller takes ownership of the frame.
174 SpdyFrame
* ConstructSpdyPing();
176 // Construct a SPDY GOAWAY frame.
177 // Returns the constructed frame. The caller takes ownership of the frame.
178 SpdyFrame
* ConstructSpdyGoAway();
180 // Construct a SPDY WINDOW_UPDATE frame.
181 // Returns the constructed frame. The caller takes ownership of the frame.
182 SpdyFrame
* ConstructSpdyWindowUpdate(SpdyStreamId
, uint32 delta_window_size
);
184 // Construct a SPDY RST_STREAM frame.
185 // Returns the constructed frame. The caller takes ownership of the frame.
186 SpdyFrame
* ConstructSpdyRstStream(SpdyStreamId stream_id
,
187 SpdyStatusCodes status
);
189 // Construct a single SPDY header entry, for validation.
190 // |extra_headers| are the extra header-value pairs.
191 // |buffer| is the buffer we're filling in.
192 // |index| is the index of the header we want.
193 // Returns the number of bytes written into |buffer|.
194 int ConstructSpdyHeader(const char* const extra_headers
[],
195 int extra_header_count
,
200 // Constructs a standard SPDY GET SYN packet, optionally compressed
201 // for the url |url|.
202 // |extra_headers| are the extra header-value pairs, which typically
203 // will vary the most between calls.
204 // Returns a SpdyFrame.
205 SpdyFrame
* ConstructSpdyGet(const char* const url
,
208 RequestPriority request_priority
);
210 // Constructs a standard SPDY GET SYN packet, optionally compressed.
211 // |extra_headers| are the extra header-value pairs, which typically
212 // will vary the most between calls.
213 // Returns a SpdyFrame.
214 SpdyFrame
* ConstructSpdyGet(const char* const extra_headers
[],
215 int extra_header_count
,
218 RequestPriority request_priority
);
220 // Constructs a standard SPDY GET SYN packet, optionally compressed.
221 // |extra_headers| are the extra header-value pairs, which typically
222 // will vary the most between calls. If |direct| is false, the
223 // the full url will be used instead of simply the path.
224 // Returns a SpdyFrame.
225 SpdyFrame
* ConstructSpdyGet(const char* const extra_headers
[],
226 int extra_header_count
,
229 RequestPriority request_priority
,
232 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
233 SpdyFrame
* ConstructSpdyConnect(const char* const extra_headers
[],
234 int extra_header_count
,
237 // Constructs a standard SPDY push SYN packet.
238 // |extra_headers| are the extra header-value pairs, which typically
239 // will vary the most between calls.
240 // Returns a SpdyFrame.
241 SpdyFrame
* ConstructSpdyPush(const char* const extra_headers
[],
242 int extra_header_count
,
244 int associated_stream_id
);
245 SpdyFrame
* ConstructSpdyPush(const char* const extra_headers
[],
246 int extra_header_count
,
248 int associated_stream_id
,
250 SpdyFrame
* ConstructSpdyPush(const char* const extra_headers
[],
251 int extra_header_count
,
253 int associated_stream_id
,
256 const char* location
);
257 SpdyFrame
* ConstructSpdyPush(int stream_id
,
258 int associated_stream_id
,
261 SpdyFrame
* ConstructSpdyPushHeaders(int stream_id
,
262 const char* const extra_headers
[],
263 int extra_header_count
);
265 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
266 // |extra_headers| are the extra header-value pairs, which typically
267 // will vary the most between calls.
268 // Returns a SpdyFrame.
269 SpdyFrame
* ConstructSpdyGetSynReply(const char* const extra_headers
[],
270 int extra_header_count
,
273 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
274 // |extra_headers| are the extra header-value pairs, which typically
275 // will vary the most between calls.
276 // Returns a SpdyFrame.
277 SpdyFrame
* ConstructSpdyGetSynReplyRedirect(int stream_id
);
279 // Constructs a standard SPDY SYN_REPLY packet with an Internal Server
280 // Error status code.
281 // Returns a SpdyFrame.
282 SpdyFrame
* ConstructSpdySynReplyError(int stream_id
);
284 // Constructs a standard SPDY SYN_REPLY packet with the specified status code.
285 // Returns a SpdyFrame.
286 SpdyFrame
* ConstructSpdySynReplyError(const char* const status
,
287 const char* const* const extra_headers
,
288 int extra_header_count
,
291 // Constructs a standard SPDY POST SYN packet.
292 // |extra_headers| are the extra header-value pairs, which typically
293 // will vary the most between calls.
294 // Returns a SpdyFrame.
295 SpdyFrame
* ConstructSpdyPost(int64 content_length
,
296 const char* const extra_headers
[],
297 int extra_header_count
);
299 // Constructs a chunked transfer SPDY POST SYN packet.
300 // |extra_headers| are the extra header-value pairs, which typically
301 // will vary the most between calls.
302 // Returns a SpdyFrame.
303 SpdyFrame
* ConstructChunkedSpdyPost(const char* const extra_headers
[],
304 int extra_header_count
);
306 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY POST.
307 // |extra_headers| are the extra header-value pairs, which typically
308 // will vary the most between calls.
309 // Returns a SpdyFrame.
310 SpdyFrame
* ConstructSpdyPostSynReply(const char* const extra_headers
[],
311 int extra_header_count
);
313 // Constructs a single SPDY data frame with the contents "hello!"
314 SpdyFrame
* ConstructSpdyBodyFrame(int stream_id
,
317 // Constructs a single SPDY data frame with the given content.
318 SpdyFrame
* ConstructSpdyBodyFrame(int stream_id
, const char* data
,
319 uint32 len
, bool fin
);
321 // Wraps |frame| in the payload of a data frame in stream |stream_id|.
322 SpdyFrame
* ConstructWrappedSpdyFrame(const scoped_ptr
<SpdyFrame
>& frame
,
325 // Create an async MockWrite from the given SpdyFrame.
326 MockWrite
CreateMockWrite(const SpdyFrame
& req
);
328 // Create an async MockWrite from the given SpdyFrame and sequence number.
329 MockWrite
CreateMockWrite(const SpdyFrame
& req
, int seq
);
331 MockWrite
CreateMockWrite(const SpdyFrame
& req
, int seq
, IoMode mode
);
333 // Create a MockRead from the given SpdyFrame.
334 MockRead
CreateMockRead(const SpdyFrame
& resp
);
336 // Create a MockRead from the given SpdyFrame and sequence number.
337 MockRead
CreateMockRead(const SpdyFrame
& resp
, int seq
);
339 MockRead
CreateMockRead(const SpdyFrame
& resp
, int seq
, IoMode mode
);
341 // Combines the given SpdyFrames into the given char array and returns
343 int CombineFrames(const SpdyFrame
** frames
, int num_frames
,
344 char* buff
, int buff_len
);
346 // Helper to manage the lifetimes of the dependencies for a
347 // HttpNetworkTransaction.
348 class SpdySessionDependencies
{
350 // Default set of dependencies -- "null" proxy service.
351 SpdySessionDependencies();
353 // Custom proxy service dependency.
354 explicit SpdySessionDependencies(ProxyService
* proxy_service
);
356 ~SpdySessionDependencies();
358 static HttpNetworkSession
* SpdyCreateSession(
359 SpdySessionDependencies
* session_deps
);
360 static HttpNetworkSession
* SpdyCreateSessionDeterministic(
361 SpdySessionDependencies
* session_deps
);
363 // NOTE: host_resolver must be ordered before http_auth_handler_factory.
364 scoped_ptr
<MockHostResolverBase
> host_resolver
;
365 scoped_ptr
<CertVerifier
> cert_verifier
;
366 scoped_ptr
<ProxyService
> proxy_service
;
367 scoped_refptr
<SSLConfigService
> ssl_config_service
;
368 scoped_ptr
<MockClientSocketFactory
> socket_factory
;
369 scoped_ptr
<DeterministicMockClientSocketFactory
> deterministic_socket_factory
;
370 scoped_ptr
<HttpAuthHandlerFactory
> http_auth_handler_factory
;
371 HttpServerPropertiesImpl http_server_properties
;
372 std::string trusted_spdy_proxy
;
375 class SpdyURLRequestContext
: public URLRequestContext
{
377 SpdyURLRequestContext();
378 virtual ~SpdyURLRequestContext();
380 MockClientSocketFactory
& socket_factory() { return socket_factory_
; }
383 MockClientSocketFactory socket_factory_
;
384 net::URLRequestContextStorage storage_
;
387 const SpdyHeaderInfo
MakeSpdyHeader(SpdyControlType type
);
389 class SpdySessionPoolPeer
{
391 explicit SpdySessionPoolPeer(SpdySessionPool
* pool
)
394 void AddAlias(const IPEndPoint
& address
, const HostPortProxyPair
& pair
) {
395 pool_
->AddAlias(address
, pair
);
398 void RemoveAliases(const HostPortProxyPair
& pair
) {
399 pool_
->RemoveAliases(pair
);
402 void RemoveSpdySession(const scoped_refptr
<SpdySession
>& session
) {
403 pool_
->Remove(session
);
406 void DisableDomainAuthenticationVerification() {
407 pool_
->verify_domain_authentication_
= false;
410 void EnableSendingInitialSettings(bool enabled
) {
411 pool_
->enable_sending_initial_settings_
= enabled
;
415 SpdySessionPool
* const pool_
;
417 DISALLOW_COPY_AND_ASSIGN(SpdySessionPoolPeer
);
420 // Helper to manage the state of a number of SPDY global variables.
421 class SpdyTestStateHelper
{
423 SpdyTestStateHelper();
424 ~SpdyTestStateHelper();
427 // In order to make CREDENTIAL frame creation deterministic, we need to
428 // use a mock EC signature creator, which needs to live throughout
429 // the life of the test.
430 scoped_ptr
<crypto::ECSignatureCreatorFactory
> ec_signature_creator_factory_
;
432 DISALLOW_COPY_AND_ASSIGN(SpdyTestStateHelper
);
435 } // namespace test_spdy3
439 #endif // NET_SPDY_SPDY_TEST_UTIL_H_