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 #include "net/spdy/spdy_test_util_spdy3.h"
9 #include "base/basictypes.h"
10 #include "base/compiler_specific.h"
11 #include "base/string_number_conversions.h"
12 #include "base/string_util.h"
13 #include "net/base/mock_cert_verifier.h"
14 #include "net/http/http_network_session.h"
15 #include "net/http/http_network_transaction.h"
16 #include "net/http/http_server_properties_impl.h"
17 #include "net/spdy/buffered_spdy_framer.h"
18 #include "net/spdy/spdy_http_utils.h"
19 #include "net/spdy/spdy_session.h"
23 namespace test_spdy3
{
27 // Parses a URL into the scheme, host, and path components required for a
29 void ParseUrl(const char* const url
, std::string
* scheme
, std::string
* host
,
32 path
->assign(gurl
.PathForRequest());
33 scheme
->assign(gurl
.scheme());
34 host
->assign(gurl
.host());
35 if (gurl
.has_port()) {
37 host
->append(gurl
.port());
43 // Chop a frame into an array of MockWrites.
44 // |data| is the frame to chop.
45 // |length| is the length of the frame to chop.
46 // |num_chunks| is the number of chunks to create.
47 MockWrite
* ChopWriteFrame(const char* data
, int length
, int num_chunks
) {
48 MockWrite
* chunks
= new MockWrite
[num_chunks
];
49 int chunk_size
= length
/ num_chunks
;
50 for (int index
= 0; index
< num_chunks
; index
++) {
51 const char* ptr
= data
+ (index
* chunk_size
);
52 if (index
== num_chunks
- 1)
53 chunk_size
+= length
% chunk_size
; // The last chunk takes the remainder.
54 chunks
[index
] = MockWrite(ASYNC
, ptr
, chunk_size
);
59 // Chop a SpdyFrame into an array of MockWrites.
60 // |frame| is the frame to chop.
61 // |num_chunks| is the number of chunks to create.
62 MockWrite
* ChopWriteFrame(const SpdyFrame
& frame
, int num_chunks
) {
63 return ChopWriteFrame(frame
.data(),
64 frame
.length() + SpdyFrame::kHeaderSize
,
68 // Chop a frame into an array of MockReads.
69 // |data| is the frame to chop.
70 // |length| is the length of the frame to chop.
71 // |num_chunks| is the number of chunks to create.
72 MockRead
* ChopReadFrame(const char* data
, int length
, int num_chunks
) {
73 MockRead
* chunks
= new MockRead
[num_chunks
];
74 int chunk_size
= length
/ num_chunks
;
75 for (int index
= 0; index
< num_chunks
; index
++) {
76 const char* ptr
= data
+ (index
* chunk_size
);
77 if (index
== num_chunks
- 1)
78 chunk_size
+= length
% chunk_size
; // The last chunk takes the remainder.
79 chunks
[index
] = MockRead(ASYNC
, ptr
, chunk_size
);
84 // Chop a SpdyFrame into an array of MockReads.
85 // |frame| is the frame to chop.
86 // |num_chunks| is the number of chunks to create.
87 MockRead
* ChopReadFrame(const SpdyFrame
& frame
, int num_chunks
) {
88 return ChopReadFrame(frame
.data(),
89 frame
.length() + SpdyFrame::kHeaderSize
,
93 // Adds headers and values to a map.
94 // |extra_headers| is an array of { name, value } pairs, arranged as strings
95 // where the even entries are the header names, and the odd entries are the
97 // |headers| gets filled in from |extra_headers|.
98 void AppendHeadersToSpdyFrame(const char* const extra_headers
[],
99 int extra_header_count
,
100 SpdyHeaderBlock
* headers
) {
101 std::string this_header
;
102 std::string this_value
;
104 if (!extra_header_count
)
107 // Sanity check: Non-NULL header list.
108 DCHECK(NULL
!= extra_headers
) << "NULL header value pair list";
109 // Sanity check: Non-NULL header map.
110 DCHECK(NULL
!= headers
) << "NULL header map";
111 // Copy in the headers.
112 for (int i
= 0; i
< extra_header_count
; i
++) {
113 // Sanity check: Non-empty header.
114 DCHECK_NE('\0', *extra_headers
[i
* 2]) << "Empty header value pair";
115 this_header
= extra_headers
[i
* 2];
116 std::string::size_type header_len
= this_header
.length();
119 this_value
= extra_headers
[1 + (i
* 2)];
120 std::string new_value
;
121 if (headers
->find(this_header
) != headers
->end()) {
122 // More than one entry in the header.
123 // Don't add the header again, just the append to the value,
124 // separated by a NULL character.
127 new_value
= (*headers
)[this_header
];
128 // Put in a NULL separator.
129 new_value
.append(1, '\0');
130 // Append the new value.
131 new_value
+= this_value
;
133 // Not a duplicate, just write the value.
134 new_value
= this_value
;
136 (*headers
)[this_header
] = new_value
;
140 // Writes |val| to a location of size |len|, in big-endian format.
141 // in the buffer pointed to by |buffer_handle|.
142 // Updates the |*buffer_handle| pointer by |len|
143 // Returns the number of bytes written
144 int AppendToBuffer(int val
,
146 unsigned char** buffer_handle
,
147 int* buffer_len_remaining
) {
150 DCHECK((size_t) len
<= sizeof(len
)) << "Data length too long for data type";
151 DCHECK(NULL
!= buffer_handle
) << "NULL buffer handle";
152 DCHECK(NULL
!= *buffer_handle
) << "NULL pointer";
153 DCHECK(NULL
!= buffer_len_remaining
)
154 << "NULL buffer remainder length pointer";
155 DCHECK_GE(*buffer_len_remaining
, len
) << "Insufficient buffer size";
156 for (int i
= 0; i
< len
; i
++) {
157 int shift
= (8 * (len
- (i
+ 1)));
158 unsigned char val_chunk
= (val
>> shift
) & 0x0FF;
159 *(*buffer_handle
)++ = val_chunk
;
160 *buffer_len_remaining
+= 1;
165 // Construct a SPDY packet.
166 // |head| is the start of the packet, up to but not including
167 // the header value pairs.
168 // |extra_headers| are the extra header-value pairs, which typically
169 // will vary the most between calls.
170 // |tail| is any (relatively constant) header-value pairs to add.
171 // |buffer| is the buffer we're filling in.
172 // Returns a SpdyFrame.
173 SpdyFrame
* ConstructSpdyPacket(const SpdyHeaderInfo
& header_info
,
174 const char* const extra_headers
[],
175 int extra_header_count
,
176 const char* const tail
[],
177 int tail_header_count
) {
178 BufferedSpdyFramer
framer(3);
179 SpdyHeaderBlock headers
;
180 // Copy in the extra headers to our map.
181 AppendHeadersToSpdyFrame(extra_headers
, extra_header_count
, &headers
);
182 // Copy in the tail headers to our map.
183 if (tail
&& tail_header_count
)
184 AppendHeadersToSpdyFrame(tail
, tail_header_count
, &headers
);
185 SpdyFrame
* frame
= NULL
;
186 switch (header_info
.kind
) {
188 frame
= framer
.CreateSynStream(header_info
.id
, header_info
.assoc_id
,
189 header_info
.priority
,
190 header_info
.credential_slot
,
191 header_info
.control_flags
,
192 header_info
.compressed
, &headers
);
195 frame
= framer
.CreateSynReply(header_info
.id
, header_info
.control_flags
,
196 header_info
.compressed
, &headers
);
199 frame
= framer
.CreateRstStream(header_info
.id
, header_info
.status
);
202 frame
= framer
.CreateHeaders(header_info
.id
, header_info
.control_flags
,
203 header_info
.compressed
, &headers
);
206 frame
= framer
.CreateDataFrame(header_info
.id
, header_info
.data
,
207 header_info
.data_length
,
208 header_info
.data_flags
);
214 // Construct an expected SPDY SETTINGS frame.
215 // |settings| are the settings to set.
216 // Returns the constructed frame. The caller takes ownership of the frame.
217 SpdyFrame
* ConstructSpdySettings(const SettingsMap
& settings
) {
218 BufferedSpdyFramer
framer(3);
219 return framer
.CreateSettings(settings
);
222 // Construct an expected SPDY CREDENTIAL frame.
223 // |credential| is the credential to sen.
224 // Returns the constructed frame. The caller takes ownership of the frame.
225 SpdyFrame
* ConstructSpdyCredential(
226 const SpdyCredential
& credential
) {
227 BufferedSpdyFramer
framer(3);
228 return framer
.CreateCredentialFrame(credential
);
231 // Construct a SPDY PING frame.
232 // Returns the constructed frame. The caller takes ownership of the frame.
233 SpdyFrame
* ConstructSpdyPing() {
234 BufferedSpdyFramer
framer(3);
235 return framer
.CreatePingFrame(1);
238 // Construct a SPDY GOAWAY frame.
239 // Returns the constructed frame. The caller takes ownership of the frame.
240 SpdyFrame
* ConstructSpdyGoAway() {
241 BufferedSpdyFramer
framer(3);
242 return framer
.CreateGoAway(0, GOAWAY_OK
);
245 // Construct a SPDY WINDOW_UPDATE frame.
246 // Returns the constructed frame. The caller takes ownership of the frame.
247 SpdyFrame
* ConstructSpdyWindowUpdate(
248 const SpdyStreamId stream_id
, uint32 delta_window_size
) {
249 BufferedSpdyFramer
framer(3);
250 return framer
.CreateWindowUpdate(stream_id
, delta_window_size
);
253 // Construct a SPDY RST_STREAM frame.
254 // Returns the constructed frame. The caller takes ownership of the frame.
255 SpdyFrame
* ConstructSpdyRstStream(SpdyStreamId stream_id
,
256 SpdyStatusCodes status
) {
257 BufferedSpdyFramer
framer(3);
258 return framer
.CreateRstStream(stream_id
, status
);
261 // Construct a single SPDY header entry, for validation.
262 // |extra_headers| are the extra header-value pairs.
263 // |buffer| is the buffer we're filling in.
264 // |index| is the index of the header we want.
265 // Returns the number of bytes written into |buffer|.
266 int ConstructSpdyHeader(const char* const extra_headers
[],
267 int extra_header_count
,
271 const char* this_header
= NULL
;
272 const char* this_value
= NULL
;
273 if (!buffer
|| !buffer_length
)
276 // Sanity check: Non-empty header list.
277 DCHECK(NULL
!= extra_headers
) << "NULL extra headers pointer";
278 // Sanity check: Index out of range.
279 DCHECK((index
>= 0) && (index
< extra_header_count
))
281 << " out of range [0, " << extra_header_count
<< ")";
282 this_header
= extra_headers
[index
* 2];
283 // Sanity check: Non-empty header.
286 std::string::size_type header_len
= strlen(this_header
);
289 this_value
= extra_headers
[1 + (index
* 2)];
290 // Sanity check: Non-empty value.
293 int n
= base::snprintf(buffer
,
301 SpdyFrame
* ConstructSpdyControlFrame(const char* const extra_headers
[],
302 int extra_header_count
,
305 RequestPriority request_priority
,
306 SpdyControlType type
,
307 SpdyControlFlags flags
,
308 const char* const* kHeaders
,
310 return ConstructSpdyControlFrame(extra_headers
,
322 SpdyFrame
* ConstructSpdyControlFrame(const char* const extra_headers
[],
323 int extra_header_count
,
326 RequestPriority request_priority
,
327 SpdyControlType type
,
328 SpdyControlFlags flags
,
329 const char* const* kHeaders
,
331 int associated_stream_id
) {
332 const SpdyHeaderInfo kSynStartHeader
= {
334 stream_id
, // Stream ID
335 associated_stream_id
, // Associated stream ID
336 ConvertRequestPriorityToSpdyPriority(request_priority
, 3),
338 0, // Credential Slot
339 flags
, // Control Flags
340 compressed
, // Compressed
344 DATA_FLAG_NONE
// Data Flags
346 return ConstructSpdyPacket(kSynStartHeader
,
353 // Constructs a standard SPDY GET SYN packet, optionally compressed
354 // for the url |url|.
355 // |extra_headers| are the extra header-value pairs, which typically
356 // will vary the most between calls.
357 // Returns a SpdyFrame.
358 SpdyFrame
* ConstructSpdyGet(const char* const url
,
361 RequestPriority request_priority
) {
362 const SpdyHeaderInfo kSynStartHeader
= {
363 SYN_STREAM
, // Kind = Syn
364 stream_id
, // Stream ID
365 0, // Associated stream ID
366 ConvertRequestPriorityToSpdyPriority(request_priority
, 3),
368 0, // Credential Slot
369 CONTROL_FLAG_FIN
, // Control Flags
370 compressed
, // Compressed
374 DATA_FLAG_NONE
// Data Flags
377 std::string scheme
, host
, path
;
378 ParseUrl(url
, &scheme
, &host
, &path
);
379 const char* const headers
[] = {
381 ":path", path
.c_str(),
382 ":host", host
.c_str(),
383 ":scheme", scheme
.c_str(),
384 ":version", "HTTP/1.1"
386 return ConstructSpdyPacket(
391 arraysize(headers
) / 2);
394 // Constructs a standard SPDY GET SYN packet, optionally compressed.
395 // |extra_headers| are the extra header-value pairs, which typically
396 // will vary the most between calls.
397 // Returns a SpdyFrame.
398 SpdyFrame
* ConstructSpdyGet(const char* const extra_headers
[],
399 int extra_header_count
,
402 RequestPriority request_priority
) {
403 return ConstructSpdyGet(extra_headers
, extra_header_count
, compressed
,
404 stream_id
, request_priority
, true);
407 // Constructs a standard SPDY GET SYN packet, optionally compressed.
408 // |extra_headers| are the extra header-value pairs, which typically
409 // will vary the most between calls.
410 // Returns a SpdyFrame.
411 SpdyFrame
* ConstructSpdyGet(const char* const extra_headers
[],
412 int extra_header_count
,
415 RequestPriority request_priority
,
417 const char* const kStandardGetHeaders
[] = {
429 return ConstructSpdyControlFrame(extra_headers
,
437 arraysize(kStandardGetHeaders
));
440 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
441 SpdyFrame
* ConstructSpdyConnect(const char* const extra_headers
[],
442 int extra_header_count
,
444 const char* const kConnectHeaders
[] = {
445 ":method", "CONNECT",
446 ":path", "www.google.com:443",
447 ":host", "www.google.com",
448 ":version", "HTTP/1.1",
450 return ConstructSpdyControlFrame(extra_headers
,
452 /*compressed*/ false,
458 arraysize(kConnectHeaders
));
461 // Constructs a standard SPDY push SYN packet.
462 // |extra_headers| are the extra header-value pairs, which typically
463 // will vary the most between calls.
464 // Returns a SpdyFrame.
465 SpdyFrame
* ConstructSpdyPush(const char* const extra_headers
[],
466 int extra_header_count
,
468 int associated_stream_id
) {
469 const char* const kStandardPushHeaders
[] = {
472 ":version", "HTTP/1.1"
474 return ConstructSpdyControlFrame(extra_headers
,
481 kStandardPushHeaders
,
482 arraysize(kStandardPushHeaders
),
483 associated_stream_id
);
486 SpdyFrame
* ConstructSpdyPush(const char* const extra_headers
[],
487 int extra_header_count
,
489 int associated_stream_id
,
491 std::string scheme
, host
, path
;
492 ParseUrl(url
, &scheme
, &host
, &path
);
493 const char* const headers
[] = {
496 ":version", "HTTP/1.1",
497 ":path", path
.c_str(),
498 ":host", host
.c_str(),
499 ":scheme", scheme
.c_str(),
501 return ConstructSpdyControlFrame(extra_headers
,
510 associated_stream_id
);
513 SpdyFrame
* ConstructSpdyPush(const char* const extra_headers
[],
514 int extra_header_count
,
516 int associated_stream_id
,
519 const char* location
) {
520 std::string scheme
, host
, path
;
521 ParseUrl(url
, &scheme
, &host
, &path
);
522 const char* const headers
[] = {
525 "location", location
,
526 ":path", path
.c_str(),
527 ":host", host
.c_str(),
528 ":scheme", scheme
.c_str(),
529 ":version", "HTTP/1.1"
531 return ConstructSpdyControlFrame(extra_headers
,
540 associated_stream_id
);
543 SpdyFrame
* ConstructSpdyPushHeaders(int stream_id
,
544 const char* const extra_headers
[],
545 int extra_header_count
) {
546 const char* const kStandardGetHeaders
[] = {
552 return ConstructSpdyControlFrame(extra_headers
,
560 arraysize(kStandardGetHeaders
));
563 // Constructs a standard SPDY SYN_REPLY packet with the specified status code.
564 // Returns a SpdyFrame.
565 SpdyFrame
* ConstructSpdySynReplyError(
566 const char* const status
,
567 const char* const* const extra_headers
,
568 int extra_header_count
,
570 const char* const kStandardGetHeaders
[] = {
578 return ConstructSpdyControlFrame(extra_headers
,
586 arraysize(kStandardGetHeaders
));
589 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
590 // |extra_headers| are the extra header-value pairs, which typically
591 // will vary the most between calls.
592 // Returns a SpdyFrame.
593 SpdyFrame
* ConstructSpdyGetSynReplyRedirect(int stream_id
) {
594 static const char* const kExtraHeaders
[] = {
596 "http://www.foo.com/index.php",
598 return ConstructSpdySynReplyError("301 Moved Permanently", kExtraHeaders
,
599 arraysize(kExtraHeaders
)/2, stream_id
);
602 // Constructs a standard SPDY SYN_REPLY packet with an Internal Server
603 // Error status code.
604 // Returns a SpdyFrame.
605 SpdyFrame
* ConstructSpdySynReplyError(int stream_id
) {
606 return ConstructSpdySynReplyError("500 Internal Server Error", NULL
, 0, 1);
612 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
613 // |extra_headers| are the extra header-value pairs, which typically
614 // will vary the most between calls.
615 // Returns a SpdyFrame.
616 SpdyFrame
* ConstructSpdyGetSynReply(const char* const extra_headers
[],
617 int extra_header_count
,
619 static const char* const kStandardGetHeaders
[] = {
627 return ConstructSpdyControlFrame(extra_headers
,
635 arraysize(kStandardGetHeaders
));
638 // Constructs a standard SPDY POST SYN packet.
639 // |content_length| is the size of post data.
640 // |extra_headers| are the extra header-value pairs, which typically
641 // will vary the most between calls.
642 // Returns a SpdyFrame.
643 SpdyFrame
* ConstructSpdyPost(int64 content_length
,
644 const char* const extra_headers
[],
645 int extra_header_count
) {
646 std::string length_str
= base::Int64ToString(content_length
);
647 const char* post_headers
[] = {
661 return ConstructSpdyControlFrame(extra_headers
,
669 arraysize(post_headers
));
672 // Constructs a chunked transfer SPDY POST SYN packet.
673 // |extra_headers| are the extra header-value pairs, which typically
674 // will vary the most between calls.
675 // Returns a SpdyFrame.
676 SpdyFrame
* ConstructChunkedSpdyPost(const char* const extra_headers
[],
677 int extra_header_count
) {
678 const char* post_headers
[] = {
690 return ConstructSpdyControlFrame(extra_headers
,
698 arraysize(post_headers
));
701 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY POST.
702 // |extra_headers| are the extra header-value pairs, which typically
703 // will vary the most between calls.
704 // Returns a SpdyFrame.
705 SpdyFrame
* ConstructSpdyPostSynReply(const char* const extra_headers
[],
706 int extra_header_count
) {
707 static const char* const kStandardGetHeaders
[] = {
717 return ConstructSpdyControlFrame(extra_headers
,
725 arraysize(kStandardGetHeaders
));
728 // Constructs a single SPDY data frame with the default contents.
729 SpdyFrame
* ConstructSpdyBodyFrame(int stream_id
, bool fin
) {
730 BufferedSpdyFramer
framer(3);
731 return framer
.CreateDataFrame(
732 stream_id
, kUploadData
, kUploadDataSize
,
733 fin
? DATA_FLAG_FIN
: DATA_FLAG_NONE
);
736 // Constructs a single SPDY data frame with the given content.
737 SpdyFrame
* ConstructSpdyBodyFrame(int stream_id
, const char* data
,
738 uint32 len
, bool fin
) {
739 BufferedSpdyFramer
framer(3);
740 return framer
.CreateDataFrame(
741 stream_id
, data
, len
, fin
? DATA_FLAG_FIN
: DATA_FLAG_NONE
);
744 // Wraps |frame| in the payload of a data frame in stream |stream_id|.
745 SpdyFrame
* ConstructWrappedSpdyFrame(
746 const scoped_ptr
<SpdyFrame
>& frame
,
748 return ConstructSpdyBodyFrame(stream_id
, frame
->data(),
749 frame
->length() + SpdyFrame::kHeaderSize
,
753 // Construct an expected SPDY reply string.
754 // |extra_headers| are the extra header-value pairs, which typically
755 // will vary the most between calls.
756 // |buffer| is the buffer we're filling in.
757 // Returns the number of bytes written into |buffer|.
758 int ConstructSpdyReplyString(const char* const extra_headers
[],
759 int extra_header_count
,
763 char* buffer_write
= buffer
;
764 int buffer_left
= buffer_length
;
765 SpdyHeaderBlock headers
;
766 if (!buffer
|| !buffer_length
)
768 // Copy in the extra headers.
769 AppendHeadersToSpdyFrame(extra_headers
, extra_header_count
, &headers
);
770 // The iterator gets us the list of header/value pairs in sorted order.
771 SpdyHeaderBlock::iterator next
= headers
.begin();
772 SpdyHeaderBlock::iterator last
= headers
.end();
773 for ( ; next
!= last
; ++next
) {
775 int value_len
, current_len
, offset
;
776 const char* header_string
= next
->first
.c_str();
777 if (header_string
&& header_string
[0] == ':')
779 packet_size
+= AppendToBuffer(header_string
,
780 strlen(header_string
),
783 packet_size
+= AppendToBuffer(": ",
787 // Write the value(s).
788 const char* value_string
= next
->second
.c_str();
789 // Check if it's split among two or more values.
790 value_len
= next
->second
.length();
791 current_len
= strlen(value_string
);
793 // Handle the first N-1 values.
794 while (current_len
< value_len
) {
795 // Finish this line -- write the current value.
796 packet_size
+= AppendToBuffer(value_string
+ offset
,
797 current_len
- offset
,
800 packet_size
+= AppendToBuffer("\n",
804 // Advance to next value.
805 offset
= current_len
+ 1;
806 current_len
+= 1 + strlen(value_string
+ offset
);
807 // Start another line -- add the header again.
808 packet_size
+= AppendToBuffer(header_string
,
809 next
->first
.length(),
812 packet_size
+= AppendToBuffer(": ",
817 EXPECT_EQ(value_len
, current_len
);
818 // Copy the last (or only) value.
819 packet_size
+= AppendToBuffer(value_string
+ offset
,
823 packet_size
+= AppendToBuffer("\n",
831 // Create a MockWrite from the given SpdyFrame.
832 MockWrite
CreateMockWrite(const SpdyFrame
& req
) {
834 ASYNC
, req
.data(), req
.length() + SpdyFrame::kHeaderSize
);
837 // Create a MockWrite from the given SpdyFrame and sequence number.
838 MockWrite
CreateMockWrite(const SpdyFrame
& req
, int seq
) {
839 return CreateMockWrite(req
, seq
, ASYNC
);
842 // Create a MockWrite from the given SpdyFrame and sequence number.
843 MockWrite
CreateMockWrite(const SpdyFrame
& req
, int seq
, IoMode mode
) {
845 mode
, req
.data(), req
.length() + SpdyFrame::kHeaderSize
, seq
);
848 // Create a MockRead from the given SpdyFrame.
849 MockRead
CreateMockRead(const SpdyFrame
& resp
) {
851 ASYNC
, resp
.data(), resp
.length() + SpdyFrame::kHeaderSize
);
854 // Create a MockRead from the given SpdyFrame and sequence number.
855 MockRead
CreateMockRead(const SpdyFrame
& resp
, int seq
) {
856 return CreateMockRead(resp
, seq
, ASYNC
);
859 // Create a MockRead from the given SpdyFrame and sequence number.
860 MockRead
CreateMockRead(const SpdyFrame
& resp
, int seq
, IoMode mode
) {
862 mode
, resp
.data(), resp
.length() + SpdyFrame::kHeaderSize
, seq
);
865 // Combines the given SpdyFrames into the given char array and returns
867 int CombineFrames(const SpdyFrame
** frames
, int num_frames
,
868 char* buff
, int buff_len
) {
870 for (int i
= 0; i
< num_frames
; ++i
) {
871 total_len
+= frames
[i
]->length() + SpdyFrame::kHeaderSize
;
873 DCHECK_LE(total_len
, buff_len
);
875 for (int i
= 0; i
< num_frames
; ++i
) {
876 int len
= frames
[i
]->length() + SpdyFrame::kHeaderSize
;
877 memcpy(ptr
, frames
[i
]->data(), len
);
883 SpdySessionDependencies::SpdySessionDependencies()
884 : host_resolver(new MockCachingHostResolver
),
885 cert_verifier(new MockCertVerifier
),
886 proxy_service(ProxyService::CreateDirect()),
887 ssl_config_service(new SSLConfigServiceDefaults
),
888 socket_factory(new MockClientSocketFactory
),
889 deterministic_socket_factory(new DeterministicMockClientSocketFactory
),
890 http_auth_handler_factory(
891 HttpAuthHandlerFactory::CreateDefault(host_resolver
.get())) {
892 // Note: The CancelledTransaction test does cleanup by running all
893 // tasks in the message loop (RunAllPending). Unfortunately, that
894 // doesn't clean up tasks on the host resolver thread; and
895 // TCPConnectJob is currently not cancellable. Using synchronous
896 // lookups allows the test to shutdown cleanly. Until we have
897 // cancellable TCPConnectJobs, use synchronous lookups.
898 host_resolver
->set_synchronous_mode(true);
901 SpdySessionDependencies::SpdySessionDependencies(ProxyService
* proxy_service
)
902 : host_resolver(new MockHostResolver
),
903 cert_verifier(new MockCertVerifier
),
904 proxy_service(proxy_service
),
905 ssl_config_service(new SSLConfigServiceDefaults
),
906 socket_factory(new MockClientSocketFactory
),
907 deterministic_socket_factory(new DeterministicMockClientSocketFactory
),
908 http_auth_handler_factory(
909 HttpAuthHandlerFactory::CreateDefault(host_resolver
.get())) {}
911 SpdySessionDependencies::~SpdySessionDependencies() {}
914 HttpNetworkSession
* SpdySessionDependencies::SpdyCreateSession(
915 SpdySessionDependencies
* session_deps
) {
916 net::HttpNetworkSession::Params params
;
917 params
.client_socket_factory
= session_deps
->socket_factory
.get();
918 params
.host_resolver
= session_deps
->host_resolver
.get();
919 params
.cert_verifier
= session_deps
->cert_verifier
.get();
920 params
.proxy_service
= session_deps
->proxy_service
.get();
921 params
.ssl_config_service
= session_deps
->ssl_config_service
;
922 params
.http_auth_handler_factory
=
923 session_deps
->http_auth_handler_factory
.get();
924 params
.http_server_properties
= &session_deps
->http_server_properties
;
925 return new HttpNetworkSession(params
);
929 HttpNetworkSession
* SpdySessionDependencies::SpdyCreateSessionDeterministic(
930 SpdySessionDependencies
* session_deps
) {
931 net::HttpNetworkSession::Params params
;
932 params
.client_socket_factory
=
933 session_deps
->deterministic_socket_factory
.get();
934 params
.host_resolver
= session_deps
->host_resolver
.get();
935 params
.cert_verifier
= session_deps
->cert_verifier
.get();
936 params
.proxy_service
= session_deps
->proxy_service
.get();
937 params
.ssl_config_service
= session_deps
->ssl_config_service
;
938 params
.http_auth_handler_factory
=
939 session_deps
->http_auth_handler_factory
.get();
940 params
.http_server_properties
= &session_deps
->http_server_properties
;
941 return new HttpNetworkSession(params
);
944 SpdyURLRequestContext::SpdyURLRequestContext()
945 : ALLOW_THIS_IN_INITIALIZER_LIST(storage_(this)) {
946 storage_
.set_host_resolver(new MockHostResolver());
947 storage_
.set_cert_verifier(new MockCertVerifier
);
948 storage_
.set_proxy_service(ProxyService::CreateDirect());
949 storage_
.set_ssl_config_service(new SSLConfigServiceDefaults
);
950 storage_
.set_http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault(
952 storage_
.set_http_server_properties(new HttpServerPropertiesImpl
);
953 net::HttpNetworkSession::Params params
;
954 params
.client_socket_factory
= &socket_factory_
;
955 params
.host_resolver
= host_resolver();
956 params
.cert_verifier
= cert_verifier();
957 params
.proxy_service
= proxy_service();
958 params
.ssl_config_service
= ssl_config_service();
959 params
.http_auth_handler_factory
= http_auth_handler_factory();
960 params
.network_delegate
= network_delegate();
961 params
.http_server_properties
= http_server_properties();
962 scoped_refptr
<HttpNetworkSession
> network_session(
963 new HttpNetworkSession(params
));
964 storage_
.set_http_transaction_factory(new HttpCache(
966 HttpCache::DefaultBackend::InMemory(0)));
969 SpdyURLRequestContext::~SpdyURLRequestContext() {
972 const SpdyHeaderInfo
MakeSpdyHeader(SpdyControlType type
) {
973 const SpdyHeaderInfo kHeader
= {
976 0, // Associated stream ID
977 ConvertRequestPriorityToSpdyPriority(LOWEST
, 3), // Priority
978 0, // Credential Slot
979 CONTROL_FLAG_FIN
, // Control Flags
984 DATA_FLAG_NONE
// Data Flags
989 SpdyTestStateHelper::SpdyTestStateHelper() {
990 // Pings can be non-deterministic, because they are sent via timer.
991 SpdySession::set_enable_ping_based_connection_checking(false);
992 // Compression is per-session which makes it impossible to create
993 // SPDY frames with static methods.
994 BufferedSpdyFramer::set_enable_compression_default(false);
997 SpdyTestStateHelper::~SpdyTestStateHelper() {
998 SpdySession::ResetStaticSettingsToInit();
999 // TODO(rch): save/restore this value
1000 BufferedSpdyFramer::set_enable_compression_default(true);
1003 } // namespace test_spdy3