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 "net/base/cert_verifier.h"
10 #include "net/base/host_port_pair.h"
11 #include "net/base/mock_host_resolver.h"
12 #include "net/base/request_priority.h"
13 #include "net/base/ssl_config_service_defaults.h"
14 #include "net/http/http_auth_handler_factory.h"
15 #include "net/http/http_cache.h"
16 #include "net/http/http_network_session.h"
17 #include "net/http/http_network_layer.h"
18 #include "net/http/http_server_properties_impl.h"
19 #include "net/http/http_transaction_factory.h"
20 #include "net/proxy/proxy_service.h"
21 #include "net/socket/socket_test_util.h"
22 #include "net/spdy/spdy_session.h"
23 #include "net/url_request/url_request_context.h"
24 #include "net/url_request/url_request_context_storage.h"
28 namespace test_spdy2
{
30 // Default upload data used by both, mock objects and framer when creating
32 const char kDefaultURL
[] = "http://www.google.com";
33 const char kUploadData
[] = "hello!";
34 const int kUploadDataSize
= arraysize(kUploadData
)-1;
36 // NOTE: In GCC, on a Mac, this can't be in an anonymous namespace!
37 // This struct holds information used to construct spdy control and data frames.
38 struct SpdyHeaderInfo
{
41 SpdyStreamId assoc_id
;
42 SpdyPriority priority
;
43 SpdyControlFlags control_flags
;
45 SpdyStatusCodes status
;
48 SpdyDataFlags data_flags
;
51 // Chop a frame into an array of MockWrites.
52 // |data| is the frame to chop.
53 // |length| is the length of the frame to chop.
54 // |num_chunks| is the number of chunks to create.
55 MockWrite
* ChopWriteFrame(const char* data
, int length
, int num_chunks
);
57 // Chop a SpdyFrame into an array of MockWrites.
58 // |frame| is the frame to chop.
59 // |num_chunks| is the number of chunks to create.
60 MockWrite
* ChopWriteFrame(const SpdyFrame
& frame
, int num_chunks
);
62 // Chop a frame into an array of MockReads.
63 // |data| is the frame to chop.
64 // |length| is the length of the frame to chop.
65 // |num_chunks| is the number of chunks to create.
66 MockRead
* ChopReadFrame(const char* data
, int length
, int num_chunks
);
68 // Chop a SpdyFrame into an array of MockReads.
69 // |frame| is the frame to chop.
70 // |num_chunks| is the number of chunks to create.
71 MockRead
* ChopReadFrame(const SpdyFrame
& frame
, int num_chunks
);
73 // Adds headers and values to a map.
74 // |extra_headers| is an array of { name, value } pairs, arranged as strings
75 // where the even entries are the header names, and the odd entries are the
77 // |headers| gets filled in from |extra_headers|.
78 void AppendHeadersToSpdyFrame(const char* const extra_headers
[],
79 int extra_header_count
,
80 SpdyHeaderBlock
* headers
);
82 // Writes |str| of the given |len| to the buffer pointed to by |buffer_handle|.
83 // Uses a template so buffer_handle can be a char* or an unsigned char*.
84 // Updates the |*buffer_handle| pointer by |len|
85 // Returns the number of bytes written into *|buffer_handle|
87 int AppendToBuffer(const char* str
,
90 int* buffer_len_remaining
) {
92 DCHECK(NULL
!= buffer_handle
) << "NULL buffer handle";
93 DCHECK(NULL
!= *buffer_handle
) << "NULL pointer";
94 DCHECK(NULL
!= buffer_len_remaining
)
95 << "NULL buffer remainder length pointer";
96 DCHECK_GE(*buffer_len_remaining
, len
) << "Insufficient buffer size";
97 memcpy(*buffer_handle
, str
, len
);
98 *buffer_handle
+= len
;
99 *buffer_len_remaining
-= len
;
103 // Writes |val| to a location of size |len|, in big-endian format.
104 // in the buffer pointed to by |buffer_handle|.
105 // Updates the |*buffer_handle| pointer by |len|
106 // Returns the number of bytes written
107 int AppendToBuffer(int val
,
109 unsigned char** buffer_handle
,
110 int* buffer_len_remaining
);
112 // Construct a SPDY packet.
113 // |head| is the start of the packet, up to but not including
114 // the header value pairs.
115 // |extra_headers| are the extra header-value pairs, which typically
116 // will vary the most between calls.
117 // |tail| is any (relatively constant) header-value pairs to add.
118 // |buffer| is the buffer we're filling in.
119 // Returns a SpdyFrame.
120 SpdyFrame
* ConstructSpdyPacket(const SpdyHeaderInfo
& header_info
,
121 const char* const extra_headers
[],
122 int extra_header_count
,
123 const char* const tail
[],
124 int tail_header_count
);
126 // Construct a generic SpdyControlFrame.
127 SpdyFrame
* ConstructSpdyControlFrame(const char* const extra_headers
[],
128 int extra_header_count
,
131 RequestPriority request_priority
,
132 SpdyControlType type
,
133 SpdyControlFlags flags
,
134 const char* const* kHeaders
,
136 SpdyFrame
* ConstructSpdyControlFrame(const char* const extra_headers
[],
137 int extra_header_count
,
139 SpdyStreamId stream_id
,
140 RequestPriority request_priority
,
141 SpdyControlType type
,
142 SpdyControlFlags flags
,
143 const char* const* kHeaders
,
145 SpdyStreamId associated_stream_id
);
147 // Construct an expected SPDY reply string.
148 // |extra_headers| are the extra header-value pairs, which typically
149 // will vary the most between calls.
150 // |buffer| is the buffer we're filling in.
151 // Returns the number of bytes written into |buffer|.
152 int ConstructSpdyReplyString(const char* const extra_headers
[],
153 int extra_header_count
,
157 // Construct an expected SPDY SETTINGS frame.
158 // |settings| are the settings to set.
159 // Returns the constructed frame. The caller takes ownership of the frame.
160 SpdyFrame
* ConstructSpdySettings(const SettingsMap
& settings
);
162 // Construct an expected SPDY CREDENTIAL frame.
163 // |credential| is the credential to send.
164 // Returns the constructed frame. The caller takes ownership of the frame.
165 SpdyFrame
* ConstructSpdyCredential(const SpdyCredential
& credential
);
167 // Construct a SPDY PING frame.
168 // Returns the constructed frame. The caller takes ownership of the frame.
169 SpdyFrame
* ConstructSpdyPing(uint32 ping_id
);
171 // Construct a SPDY GOAWAY frame.
172 // Returns the constructed frame. The caller takes ownership of the frame.
173 SpdyFrame
* ConstructSpdyGoAway();
175 // Construct a SPDY WINDOW_UPDATE frame.
176 // Returns the constructed frame. The caller takes ownership of the frame.
177 SpdyFrame
* ConstructSpdyWindowUpdate(SpdyStreamId
, uint32 delta_window_size
);
179 // Construct a SPDY RST_STREAM frame.
180 // Returns the constructed frame. The caller takes ownership of the frame.
181 SpdyFrame
* ConstructSpdyRstStream(SpdyStreamId stream_id
,
182 SpdyStatusCodes status
);
184 // Construct a single SPDY header entry, for validation.
185 // |extra_headers| are the extra header-value pairs.
186 // |buffer| is the buffer we're filling in.
187 // |index| is the index of the header we want.
188 // Returns the number of bytes written into |buffer|.
189 int ConstructSpdyHeader(const char* const extra_headers
[],
190 int extra_header_count
,
195 // Constructs a standard SPDY GET SYN packet, optionally compressed
196 // for the url |url|.
197 // |extra_headers| are the extra header-value pairs, which typically
198 // will vary the most between calls.
199 // Returns a SpdyFrame.
200 SpdyFrame
* ConstructSpdyGet(const char* const url
,
202 SpdyStreamId stream_id
,
203 RequestPriority request_priority
);
205 // Constructs a standard SPDY GET SYN packet, optionally compressed.
206 // |extra_headers| are the extra header-value pairs, which typically
207 // will vary the most between calls.
208 // Returns a SpdyFrame.
209 SpdyFrame
* ConstructSpdyGet(const char* const extra_headers
[],
210 int extra_header_count
,
213 RequestPriority request_priority
);
215 // Constructs a standard SPDY GET SYN packet, optionally compressed.
216 // |extra_headers| are the extra header-value pairs, which typically
217 // will vary the most between calls. If |direct| is false, the
218 // the full url will be used instead of simply the path.
219 // Returns a SpdyFrame.
220 SpdyFrame
* ConstructSpdyGet(const char* const extra_headers
[],
221 int extra_header_count
,
224 RequestPriority request_priority
,
227 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
228 SpdyFrame
* ConstructSpdyConnect(const char* const extra_headers
[],
229 int extra_header_count
,
232 // Constructs a standard SPDY push SYN packet.
233 // |extra_headers| are the extra header-value pairs, which typically
234 // will vary the most between calls.
235 // Returns a SpdyFrame.
236 SpdyFrame
* ConstructSpdyPush(const char* const extra_headers
[],
237 int extra_header_count
,
239 int associated_stream_id
);
240 SpdyFrame
* ConstructSpdyPush(const char* const extra_headers
[],
241 int extra_header_count
,
243 int associated_stream_id
,
245 SpdyFrame
* ConstructSpdyPush(const char* const extra_headers
[],
246 int extra_header_count
,
248 int associated_stream_id
,
251 const char* location
);
252 SpdyFrame
* ConstructSpdyPush(int stream_id
,
253 int associated_stream_id
,
256 SpdyFrame
* ConstructSpdyPushHeaders(int stream_id
,
257 const char* const extra_headers
[],
258 int extra_header_count
);
260 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
261 // |extra_headers| are the extra header-value pairs, which typically
262 // will vary the most between calls.
263 // Returns a SpdyFrame.
264 SpdyFrame
* ConstructSpdyGetSynReply(const char* const extra_headers
[],
265 int extra_header_count
,
268 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
269 // |extra_headers| are the extra header-value pairs, which typically
270 // will vary the most between calls.
271 // Returns a SpdyFrame.
272 SpdyFrame
* ConstructSpdyGetSynReplyRedirect(int stream_id
);
274 // Constructs a standard SPDY SYN_REPLY packet with an Internal Server
275 // Error status code.
276 // Returns a SpdyFrame.
277 SpdyFrame
* ConstructSpdySynReplyError(int stream_id
);
279 // Constructs a standard SPDY SYN_REPLY packet with the specified status code.
280 // Returns a SpdyFrame.
281 SpdyFrame
* ConstructSpdySynReplyError(const char* const status
,
282 const char* const* const extra_headers
,
283 int extra_header_count
,
286 // Constructs a standard SPDY POST SYN packet.
287 // |extra_headers| are the extra header-value pairs, which typically
288 // will vary the most between calls.
289 // Returns a SpdyFrame.
290 SpdyFrame
* ConstructSpdyPost(int64 content_length
,
291 const char* const extra_headers
[],
292 int extra_header_count
);
294 // Constructs a chunked transfer SPDY POST SYN packet.
295 // |extra_headers| are the extra header-value pairs, which typically
296 // will vary the most between calls.
297 // Returns a SpdyFrame.
298 SpdyFrame
* ConstructChunkedSpdyPost(const char* const extra_headers
[],
299 int extra_header_count
);
301 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY POST.
302 // |extra_headers| are the extra header-value pairs, which typically
303 // will vary the most between calls.
304 // Returns a SpdyFrame.
305 SpdyFrame
* ConstructSpdyPostSynReply(const char* const extra_headers
[],
306 int extra_header_count
);
308 // Constructs a single SPDY data frame with the contents "hello!"
309 SpdyFrame
* ConstructSpdyBodyFrame(int stream_id
,
312 // Constructs a single SPDY data frame with the given content.
313 SpdyFrame
* ConstructSpdyBodyFrame(int stream_id
, const char* data
,
314 uint32 len
, bool fin
);
316 // Wraps |frame| in the payload of a data frame in stream |stream_id|.
317 SpdyFrame
* ConstructWrappedSpdyFrame(const scoped_ptr
<SpdyFrame
>& frame
,
320 // Create an async MockWrite from the given SpdyFrame.
321 MockWrite
CreateMockWrite(const SpdyFrame
& req
);
323 // Create an async MockWrite from the given SpdyFrame and sequence number.
324 MockWrite
CreateMockWrite(const SpdyFrame
& req
, int seq
);
326 MockWrite
CreateMockWrite(const SpdyFrame
& req
, int seq
, IoMode mode
);
328 // Create a MockRead from the given SpdyFrame.
329 MockRead
CreateMockRead(const SpdyFrame
& resp
);
331 // Create a MockRead from the given SpdyFrame and sequence number.
332 MockRead
CreateMockRead(const SpdyFrame
& resp
, int seq
);
334 MockRead
CreateMockRead(const SpdyFrame
& resp
, int seq
, IoMode mode
);
336 // Combines the given SpdyFrames into the given char array and returns
338 int CombineFrames(const SpdyFrame
** frames
, int num_frames
,
339 char* buff
, int buff_len
);
341 // Helper to manage the lifetimes of the dependencies for a
342 // HttpNetworkTransaction.
343 struct SpdySessionDependencies
{
344 // Default set of dependencies -- "null" proxy service.
345 SpdySessionDependencies();
347 // Custom proxy service dependency.
348 explicit SpdySessionDependencies(ProxyService
* proxy_service
);
350 ~SpdySessionDependencies();
352 static HttpNetworkSession
* SpdyCreateSession(
353 SpdySessionDependencies
* session_deps
);
354 static HttpNetworkSession
* SpdyCreateSessionDeterministic(
355 SpdySessionDependencies
* session_deps
);
356 static HttpNetworkSession::Params
CreateSessionParams(
357 SpdySessionDependencies
* session_deps
);
359 // NOTE: host_resolver must be ordered before http_auth_handler_factory.
360 scoped_ptr
<MockHostResolverBase
> host_resolver
;
361 scoped_ptr
<CertVerifier
> cert_verifier
;
362 scoped_ptr
<ProxyService
> proxy_service
;
363 scoped_refptr
<SSLConfigService
> ssl_config_service
;
364 scoped_ptr
<MockClientSocketFactory
> socket_factory
;
365 scoped_ptr
<DeterministicMockClientSocketFactory
> deterministic_socket_factory
;
366 scoped_ptr
<HttpAuthHandlerFactory
> http_auth_handler_factory
;
367 HttpServerPropertiesImpl http_server_properties
;
368 bool enable_ip_pooling
;
369 bool enable_compression
;
371 SpdySession::TimeFunc time_func
;
372 std::string trusted_spdy_proxy
;
376 class SpdyURLRequestContext
: public URLRequestContext
{
378 SpdyURLRequestContext();
379 virtual ~SpdyURLRequestContext();
381 MockClientSocketFactory
& socket_factory() { return socket_factory_
; }
384 MockClientSocketFactory socket_factory_
;
385 net::URLRequestContextStorage storage_
;
388 const SpdyHeaderInfo
MakeSpdyHeader(SpdyControlType type
);
390 class SpdySessionPoolPeer
{
392 explicit SpdySessionPoolPeer(SpdySessionPool
* pool
)
395 void AddAlias(const IPEndPoint
& address
, const HostPortProxyPair
& pair
) {
396 pool_
->AddAlias(address
, pair
);
399 void RemoveAliases(const HostPortProxyPair
& pair
) {
400 pool_
->RemoveAliases(pair
);
403 void RemoveSpdySession(const scoped_refptr
<SpdySession
>& session
) {
404 pool_
->Remove(session
);
407 void DisableDomainAuthenticationVerification() {
408 pool_
->verify_domain_authentication_
= false;
411 void EnableSendingInitialSettings(bool enabled
) {
412 pool_
->enable_sending_initial_settings_
= enabled
;
416 SpdySessionPool
* const pool_
;
418 DISALLOW_COPY_AND_ASSIGN(SpdySessionPoolPeer
);
421 } // namespace test_spdy2
425 #endif // NET_SPDY_SPDY_TEST_UTIL_H_