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_spdy2.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"
22 namespace test_spdy2
{
26 // Parses a URL into the scheme, host, and path components required for a
28 void ParseUrl(const char* const url
, std::string
* scheme
, std::string
* host
,
31 path
->assign(gurl
.PathForRequest());
32 scheme
->assign(gurl
.scheme());
33 host
->assign(gurl
.host());
34 if (gurl
.has_port()) {
36 host
->append(gurl
.port());
42 // Chop a frame into an array of MockWrites.
43 // |data| is the frame to chop.
44 // |length| is the length of the frame to chop.
45 // |num_chunks| is the number of chunks to create.
46 MockWrite
* ChopWriteFrame(const char* data
, int length
, int num_chunks
) {
47 MockWrite
* chunks
= new MockWrite
[num_chunks
];
48 int chunk_size
= length
/ num_chunks
;
49 for (int index
= 0; index
< num_chunks
; index
++) {
50 const char* ptr
= data
+ (index
* chunk_size
);
51 if (index
== num_chunks
- 1)
52 chunk_size
+= length
% chunk_size
; // The last chunk takes the remainder.
53 chunks
[index
] = MockWrite(ASYNC
, ptr
, chunk_size
);
58 // Chop a SpdyFrame into an array of MockWrites.
59 // |frame| is the frame to chop.
60 // |num_chunks| is the number of chunks to create.
61 MockWrite
* ChopWriteFrame(const SpdyFrame
& frame
, int num_chunks
) {
62 return ChopWriteFrame(frame
.data(),
63 frame
.length() + SpdyFrame::kHeaderSize
,
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
) {
72 MockRead
* chunks
= new MockRead
[num_chunks
];
73 int chunk_size
= length
/ num_chunks
;
74 for (int index
= 0; index
< num_chunks
; index
++) {
75 const char* ptr
= data
+ (index
* chunk_size
);
76 if (index
== num_chunks
- 1)
77 chunk_size
+= length
% chunk_size
; // The last chunk takes the remainder.
78 chunks
[index
] = MockRead(ASYNC
, ptr
, chunk_size
);
83 // Chop a SpdyFrame into an array of MockReads.
84 // |frame| is the frame to chop.
85 // |num_chunks| is the number of chunks to create.
86 MockRead
* ChopReadFrame(const SpdyFrame
& frame
, int num_chunks
) {
87 return ChopReadFrame(frame
.data(),
88 frame
.length() + SpdyFrame::kHeaderSize
,
92 // Adds headers and values to a map.
93 // |extra_headers| is an array of { name, value } pairs, arranged as strings
94 // where the even entries are the header names, and the odd entries are the
96 // |headers| gets filled in from |extra_headers|.
97 void AppendHeadersToSpdyFrame(const char* const extra_headers
[],
98 int extra_header_count
,
99 SpdyHeaderBlock
* headers
) {
100 std::string this_header
;
101 std::string this_value
;
103 if (!extra_header_count
)
106 // Sanity check: Non-NULL header list.
107 DCHECK(NULL
!= extra_headers
) << "NULL header value pair list";
108 // Sanity check: Non-NULL header map.
109 DCHECK(NULL
!= headers
) << "NULL header map";
110 // Copy in the headers.
111 for (int i
= 0; i
< extra_header_count
; i
++) {
112 // Sanity check: Non-empty header.
113 DCHECK_NE('\0', *extra_headers
[i
* 2]) << "Empty header value pair";
114 this_header
= extra_headers
[i
* 2];
115 std::string::size_type header_len
= this_header
.length();
118 this_value
= extra_headers
[1 + (i
* 2)];
119 std::string new_value
;
120 if (headers
->find(this_header
) != headers
->end()) {
121 // More than one entry in the header.
122 // Don't add the header again, just the append to the value,
123 // separated by a NULL character.
126 new_value
= (*headers
)[this_header
];
127 // Put in a NULL separator.
128 new_value
.append(1, '\0');
129 // Append the new value.
130 new_value
+= this_value
;
132 // Not a duplicate, just write the value.
133 new_value
= this_value
;
135 (*headers
)[this_header
] = new_value
;
139 // Writes |val| to a location of size |len|, in big-endian format.
140 // in the buffer pointed to by |buffer_handle|.
141 // Updates the |*buffer_handle| pointer by |len|
142 // Returns the number of bytes written
143 int AppendToBuffer(int val
,
145 unsigned char** buffer_handle
,
146 int* buffer_len_remaining
) {
149 DCHECK((size_t) len
<= sizeof(len
)) << "Data length too long for data type";
150 DCHECK(NULL
!= buffer_handle
) << "NULL buffer handle";
151 DCHECK(NULL
!= *buffer_handle
) << "NULL pointer";
152 DCHECK(NULL
!= buffer_len_remaining
)
153 << "NULL buffer remainder length pointer";
154 DCHECK_GE(*buffer_len_remaining
, len
) << "Insufficient buffer size";
155 for (int i
= 0; i
< len
; i
++) {
156 int shift
= (8 * (len
- (i
+ 1)));
157 unsigned char val_chunk
= (val
>> shift
) & 0x0FF;
158 *(*buffer_handle
)++ = val_chunk
;
159 *buffer_len_remaining
+= 1;
164 // Construct a SPDY packet.
165 // |head| is the start of the packet, up to but not including
166 // the header value pairs.
167 // |extra_headers| are the extra header-value pairs, which typically
168 // will vary the most between calls.
169 // |tail| is any (relatively constant) header-value pairs to add.
170 // |buffer| is the buffer we're filling in.
171 // Returns a SpdyFrame.
172 SpdyFrame
* ConstructSpdyPacket(const SpdyHeaderInfo
& header_info
,
173 const char* const extra_headers
[],
174 int extra_header_count
,
175 const char* const tail
[],
176 int tail_header_count
) {
177 BufferedSpdyFramer
framer(2, header_info
.compressed
);
178 SpdyHeaderBlock headers
;
179 // Copy in the extra headers to our map.
180 AppendHeadersToSpdyFrame(extra_headers
, extra_header_count
, &headers
);
181 // Copy in the tail headers to our map.
182 if (tail
&& tail_header_count
)
183 AppendHeadersToSpdyFrame(tail
, tail_header_count
, &headers
);
184 SpdyFrame
* frame
= NULL
;
185 switch (header_info
.kind
) {
187 frame
= framer
.CreateSynStream(header_info
.id
, header_info
.assoc_id
,
188 header_info
.priority
, 0,
189 header_info
.control_flags
,
190 header_info
.compressed
, &headers
);
193 frame
= framer
.CreateSynReply(header_info
.id
, header_info
.control_flags
,
194 header_info
.compressed
, &headers
);
197 frame
= framer
.CreateRstStream(header_info
.id
, header_info
.status
);
200 frame
= framer
.CreateHeaders(header_info
.id
, header_info
.control_flags
,
201 header_info
.compressed
, &headers
);
204 frame
= framer
.CreateDataFrame(header_info
.id
, header_info
.data
,
205 header_info
.data_length
,
206 header_info
.data_flags
);
212 // Construct an expected SPDY SETTINGS frame.
213 // |settings| are the settings to set.
214 // Returns the constructed frame. The caller takes ownership of the frame.
215 SpdyFrame
* ConstructSpdySettings(const SettingsMap
& settings
) {
216 BufferedSpdyFramer
framer(2, false);
217 return framer
.CreateSettings(settings
);
220 // Construct an expected SPDY CREDENTIAL frame.
221 // |credential| is the credential to sen.
222 // Returns the constructed frame. The caller takes ownership of the frame.
223 SpdyFrame
* ConstructSpdyCredential(
224 const SpdyCredential
& credential
) {
225 BufferedSpdyFramer
framer(2, false);
226 return framer
.CreateCredentialFrame(credential
);
229 // Construct a SPDY PING frame.
230 // Returns the constructed frame. The caller takes ownership of the frame.
231 SpdyFrame
* ConstructSpdyPing(uint32 ping_id
) {
232 BufferedSpdyFramer
framer(2, false);
233 return framer
.CreatePingFrame(ping_id
);
236 // Construct a SPDY GOAWAY frame.
237 // Returns the constructed frame. The caller takes ownership of the frame.
238 SpdyFrame
* ConstructSpdyGoAway() {
239 BufferedSpdyFramer
framer(2, false);
240 return framer
.CreateGoAway(0, GOAWAY_OK
);
243 // Construct a SPDY WINDOW_UPDATE frame.
244 // Returns the constructed frame. The caller takes ownership of the frame.
245 SpdyFrame
* ConstructSpdyWindowUpdate(
246 const SpdyStreamId stream_id
, uint32 delta_window_size
) {
247 BufferedSpdyFramer
framer(2, false);
248 return framer
.CreateWindowUpdate(stream_id
, delta_window_size
);
251 // Construct a SPDY RST_STREAM frame.
252 // Returns the constructed frame. The caller takes ownership of the frame.
253 SpdyFrame
* ConstructSpdyRstStream(SpdyStreamId stream_id
,
254 SpdyStatusCodes status
) {
255 BufferedSpdyFramer
framer(2, false);
256 return framer
.CreateRstStream(stream_id
, status
);
259 // Construct a single SPDY header entry, for validation.
260 // |extra_headers| are the extra header-value pairs.
261 // |buffer| is the buffer we're filling in.
262 // |index| is the index of the header we want.
263 // Returns the number of bytes written into |buffer|.
264 int ConstructSpdyHeader(const char* const extra_headers
[],
265 int extra_header_count
,
269 const char* this_header
= NULL
;
270 const char* this_value
= NULL
;
271 if (!buffer
|| !buffer_length
)
274 // Sanity check: Non-empty header list.
275 DCHECK(NULL
!= extra_headers
) << "NULL extra headers pointer";
276 // Sanity check: Index out of range.
277 DCHECK((index
>= 0) && (index
< extra_header_count
))
279 << " out of range [0, " << extra_header_count
<< ")";
280 this_header
= extra_headers
[index
* 2];
281 // Sanity check: Non-empty header.
284 std::string::size_type header_len
= strlen(this_header
);
287 this_value
= extra_headers
[1 + (index
* 2)];
288 // Sanity check: Non-empty value.
291 int n
= base::snprintf(buffer
,
299 SpdyFrame
* ConstructSpdyControlFrame(const char* const extra_headers
[],
300 int extra_header_count
,
303 RequestPriority request_priority
,
304 SpdyControlType type
,
305 SpdyControlFlags flags
,
306 const char* const* kHeaders
,
308 return ConstructSpdyControlFrame(extra_headers
,
320 SpdyFrame
* ConstructSpdyControlFrame(const char* const extra_headers
[],
321 int extra_header_count
,
323 SpdyStreamId stream_id
,
324 RequestPriority request_priority
,
325 SpdyControlType type
,
326 SpdyControlFlags flags
,
327 const char* const* kHeaders
,
329 SpdyStreamId associated_stream_id
) {
330 const SpdyHeaderInfo kSynStartHeader
= {
332 stream_id
, // Stream ID
333 associated_stream_id
, // Associated stream ID
334 ConvertRequestPriorityToSpdyPriority(request_priority
, 2),
336 flags
, // Control Flags
337 compressed
, // Compressed
341 DATA_FLAG_NONE
// Data Flags
343 return ConstructSpdyPacket(kSynStartHeader
,
350 // Constructs a standard SPDY GET SYN packet, optionally compressed
351 // for the url |url|.
352 // |extra_headers| are the extra header-value pairs, which typically
353 // will vary the most between calls.
354 // Returns a SpdyFrame.
355 SpdyFrame
* ConstructSpdyGet(const char* const url
,
357 SpdyStreamId stream_id
,
358 RequestPriority request_priority
) {
359 const SpdyHeaderInfo kSynStartHeader
= {
360 SYN_STREAM
, // Kind = Syn
361 stream_id
, // Stream ID
362 0, // Associated stream ID
363 ConvertRequestPriorityToSpdyPriority(request_priority
, 2),
365 CONTROL_FLAG_FIN
, // Control Flags
366 compressed
, // Compressed
370 DATA_FLAG_NONE
// Data Flags
373 std::string scheme
, host
, path
;
374 ParseUrl(url
, &scheme
, &host
, &path
);
375 const char* const headers
[] = {
378 "host", host
.c_str(),
379 "scheme", scheme
.c_str(),
380 "version", "HTTP/1.1"
382 return ConstructSpdyPacket(
387 arraysize(headers
) / 2);
390 // Constructs a standard SPDY GET SYN packet, optionally compressed.
391 // |extra_headers| are the extra header-value pairs, which typically
392 // will vary the most between calls.
393 // Returns a SpdyFrame.
394 SpdyFrame
* ConstructSpdyGet(const char* const extra_headers
[],
395 int extra_header_count
,
398 RequestPriority request_priority
) {
399 return ConstructSpdyGet(extra_headers
, extra_header_count
, compressed
,
400 stream_id
, request_priority
, true);
403 // Constructs a standard SPDY GET SYN packet, optionally compressed.
404 // |extra_headers| are the extra header-value pairs, which typically
405 // will vary the most between calls.
406 // Returns a SpdyFrame.
407 SpdyFrame
* ConstructSpdyGet(const char* const extra_headers
[],
408 int extra_header_count
,
411 RequestPriority request_priority
,
413 const char* const kStandardGetHeaders
[] = {
415 "url", (direct
? "/" : "http://www.google.com/"),
416 "host", "www.google.com",
418 "version", "HTTP/1.1"
420 return ConstructSpdyControlFrame(extra_headers
,
428 arraysize(kStandardGetHeaders
));
431 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
432 SpdyFrame
* ConstructSpdyConnect(const char* const extra_headers
[],
433 int extra_header_count
,
435 const char* const kConnectHeaders
[] = {
437 "url", "www.google.com:443",
438 "host", "www.google.com",
439 "version", "HTTP/1.1",
441 return ConstructSpdyControlFrame(extra_headers
,
443 /*compressed*/ false,
449 arraysize(kConnectHeaders
));
452 // Constructs a standard SPDY push SYN packet.
453 // |extra_headers| are the extra header-value pairs, which typically
454 // will vary the most between calls.
455 // Returns a SpdyFrame.
456 SpdyFrame
* ConstructSpdyPush(const char* const extra_headers
[],
457 int extra_header_count
,
459 int associated_stream_id
) {
460 const char* const kStandardGetHeaders
[] = {
463 "version", "HTTP/1.1"
465 return ConstructSpdyControlFrame(extra_headers
,
473 arraysize(kStandardGetHeaders
),
474 associated_stream_id
);
477 SpdyFrame
* ConstructSpdyPush(const char* const extra_headers
[],
478 int extra_header_count
,
480 int associated_stream_id
,
482 const char* const kStandardGetHeaders
[] = {
486 "version", "HTTP/1.1"
488 return ConstructSpdyControlFrame(extra_headers
,
496 arraysize(kStandardGetHeaders
),
497 associated_stream_id
);
500 SpdyFrame
* ConstructSpdyPush(const char* const extra_headers
[],
501 int extra_header_count
,
503 int associated_stream_id
,
506 const char* location
) {
507 const char* const kStandardGetHeaders
[] = {
510 "location", location
,
512 "version", "HTTP/1.1"
514 return ConstructSpdyControlFrame(extra_headers
,
522 arraysize(kStandardGetHeaders
),
523 associated_stream_id
);
526 SpdyFrame
* ConstructSpdyPush(int stream_id
,
527 int associated_stream_id
,
529 const char* const kStandardGetHeaders
[] = {
532 return ConstructSpdyControlFrame(0,
540 arraysize(kStandardGetHeaders
),
541 associated_stream_id
);
544 SpdyFrame
* ConstructSpdyPushHeaders(int stream_id
,
545 const char* const extra_headers
[],
546 int extra_header_count
) {
547 const char* const kStandardGetHeaders
[] = {
549 "version", "HTTP/1.1"
551 return ConstructSpdyControlFrame(extra_headers
,
559 arraysize(kStandardGetHeaders
));
562 // Constructs a standard SPDY SYN_REPLY packet with the specified status code.
563 // Returns a SpdyFrame.
564 SpdyFrame
* ConstructSpdySynReplyError(const char* const status
,
565 const char* const* const extra_headers
,
566 int extra_header_count
,
568 const char* const kStandardGetHeaders
[] = {
571 "version", "HTTP/1.1"
573 return ConstructSpdyControlFrame(extra_headers
,
581 arraysize(kStandardGetHeaders
));
584 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
585 // |extra_headers| are the extra header-value pairs, which typically
586 // will vary the most between calls.
587 // Returns a SpdyFrame.
588 SpdyFrame
* ConstructSpdyGetSynReplyRedirect(int stream_id
) {
589 static const char* const kExtraHeaders
[] = {
590 "location", "http://www.foo.com/index.php",
592 return ConstructSpdySynReplyError("301 Moved Permanently", kExtraHeaders
,
593 arraysize(kExtraHeaders
)/2, stream_id
);
596 // Constructs a standard SPDY SYN_REPLY packet with an Internal Server
597 // Error status code.
598 // Returns a SpdyFrame.
599 SpdyFrame
* ConstructSpdySynReplyError(int stream_id
) {
600 return ConstructSpdySynReplyError("500 Internal Server Error", NULL
, 0, 1);
603 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
604 // |extra_headers| are the extra header-value pairs, which typically
605 // will vary the most between calls.
606 // Returns a SpdyFrame.
607 SpdyFrame
* ConstructSpdyGetSynReply(const char* const extra_headers
[],
608 int extra_header_count
,
610 static const char* const kStandardGetHeaders
[] = {
613 "version", "HTTP/1.1"
615 return ConstructSpdyControlFrame(extra_headers
,
623 arraysize(kStandardGetHeaders
));
626 // Constructs a standard SPDY POST SYN packet.
627 // |content_length| is the size of post data.
628 // |extra_headers| are the extra header-value pairs, which typically
629 // will vary the most between calls.
630 // Returns a SpdyFrame.
631 SpdyFrame
* ConstructSpdyPost(int64 content_length
,
632 const char* const extra_headers
[],
633 int extra_header_count
) {
634 std::string length_str
= base::Int64ToString(content_length
);
635 const char* post_headers
[] = {
638 "host", "www.google.com",
640 "version", "HTTP/1.1",
641 "content-length", length_str
.c_str()
643 return ConstructSpdyControlFrame(extra_headers
,
651 arraysize(post_headers
));
654 // Constructs a chunked transfer SPDY POST SYN packet.
655 // |extra_headers| are the extra header-value pairs, which typically
656 // will vary the most between calls.
657 // Returns a SpdyFrame.
658 SpdyFrame
* ConstructChunkedSpdyPost(const char* const extra_headers
[],
659 int extra_header_count
) {
660 const char* post_headers
[] = {
663 "host", "www.google.com",
665 "version", "HTTP/1.1"
667 return ConstructSpdyControlFrame(extra_headers
,
675 arraysize(post_headers
));
678 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY POST.
679 // |extra_headers| are the extra header-value pairs, which typically
680 // will vary the most between calls.
681 // Returns a SpdyFrame.
682 SpdyFrame
* ConstructSpdyPostSynReply(const char* const extra_headers
[],
683 int extra_header_count
) {
684 static const char* const kStandardGetHeaders
[] = {
688 "version", "HTTP/1.1"
690 return ConstructSpdyControlFrame(extra_headers
,
698 arraysize(kStandardGetHeaders
));
701 // Constructs a single SPDY data frame with the default contents.
702 SpdyFrame
* ConstructSpdyBodyFrame(int stream_id
, bool fin
) {
703 BufferedSpdyFramer
framer(2, false);
704 return framer
.CreateDataFrame(
705 stream_id
, kUploadData
, kUploadDataSize
,
706 fin
? DATA_FLAG_FIN
: DATA_FLAG_NONE
);
709 // Constructs a single SPDY data frame with the given content.
710 SpdyFrame
* ConstructSpdyBodyFrame(int stream_id
, const char* data
,
711 uint32 len
, bool fin
) {
712 BufferedSpdyFramer
framer(2, false);
713 return framer
.CreateDataFrame(
714 stream_id
, data
, len
, fin
? DATA_FLAG_FIN
: DATA_FLAG_NONE
);
717 // Wraps |frame| in the payload of a data frame in stream |stream_id|.
718 SpdyFrame
* ConstructWrappedSpdyFrame(const scoped_ptr
<SpdyFrame
>& frame
,
720 return ConstructSpdyBodyFrame(stream_id
, frame
->data(),
721 frame
->length() + SpdyFrame::kHeaderSize
,
725 // Construct an expected SPDY reply string.
726 // |extra_headers| are the extra header-value pairs, which typically
727 // will vary the most between calls.
728 // |buffer| is the buffer we're filling in.
729 // Returns the number of bytes written into |buffer|.
730 int ConstructSpdyReplyString(const char* const extra_headers
[],
731 int extra_header_count
,
735 char* buffer_write
= buffer
;
736 int buffer_left
= buffer_length
;
737 SpdyHeaderBlock headers
;
738 if (!buffer
|| !buffer_length
)
740 // Copy in the extra headers.
741 AppendHeadersToSpdyFrame(extra_headers
, extra_header_count
, &headers
);
742 // The iterator gets us the list of header/value pairs in sorted order.
743 SpdyHeaderBlock::iterator next
= headers
.begin();
744 SpdyHeaderBlock::iterator last
= headers
.end();
745 for ( ; next
!= last
; ++next
) {
747 int value_len
, current_len
, offset
;
748 const char* header_string
= next
->first
.c_str();
749 packet_size
+= AppendToBuffer(header_string
,
750 next
->first
.length(),
753 packet_size
+= AppendToBuffer(": ",
757 // Write the value(s).
758 const char* value_string
= next
->second
.c_str();
759 // Check if it's split among two or more values.
760 value_len
= next
->second
.length();
761 current_len
= strlen(value_string
);
763 // Handle the first N-1 values.
764 while (current_len
< value_len
) {
765 // Finish this line -- write the current value.
766 packet_size
+= AppendToBuffer(value_string
+ offset
,
767 current_len
- offset
,
770 packet_size
+= AppendToBuffer("\n",
774 // Advance to next value.
775 offset
= current_len
+ 1;
776 current_len
+= 1 + strlen(value_string
+ offset
);
777 // Start another line -- add the header again.
778 packet_size
+= AppendToBuffer(header_string
,
779 next
->first
.length(),
782 packet_size
+= AppendToBuffer(": ",
787 EXPECT_EQ(value_len
, current_len
);
788 // Copy the last (or only) value.
789 packet_size
+= AppendToBuffer(value_string
+ offset
,
793 packet_size
+= AppendToBuffer("\n",
801 // Create a MockWrite from the given SpdyFrame.
802 MockWrite
CreateMockWrite(const SpdyFrame
& req
) {
804 ASYNC
, req
.data(), req
.length() + SpdyFrame::kHeaderSize
);
807 // Create a MockWrite from the given SpdyFrame and sequence number.
808 MockWrite
CreateMockWrite(const SpdyFrame
& req
, int seq
) {
809 return CreateMockWrite(req
, seq
, ASYNC
);
812 // Create a MockWrite from the given SpdyFrame and sequence number.
813 MockWrite
CreateMockWrite(const SpdyFrame
& req
, int seq
, IoMode mode
) {
815 mode
, req
.data(), req
.length() + SpdyFrame::kHeaderSize
, seq
);
818 // Create a MockRead from the given SpdyFrame.
819 MockRead
CreateMockRead(const SpdyFrame
& resp
) {
821 ASYNC
, resp
.data(), resp
.length() + SpdyFrame::kHeaderSize
);
824 // Create a MockRead from the given SpdyFrame and sequence number.
825 MockRead
CreateMockRead(const SpdyFrame
& resp
, int seq
) {
826 return CreateMockRead(resp
, seq
, ASYNC
);
829 // Create a MockRead from the given SpdyFrame and sequence number.
830 MockRead
CreateMockRead(const SpdyFrame
& resp
, int seq
, IoMode mode
) {
832 mode
, resp
.data(), resp
.length() + SpdyFrame::kHeaderSize
, seq
);
835 // Combines the given SpdyFrames into the given char array and returns
837 int CombineFrames(const SpdyFrame
** frames
, int num_frames
,
838 char* buff
, int buff_len
) {
840 for (int i
= 0; i
< num_frames
; ++i
) {
841 total_len
+= frames
[i
]->length() + SpdyFrame::kHeaderSize
;
843 DCHECK_LE(total_len
, buff_len
);
845 for (int i
= 0; i
< num_frames
; ++i
) {
846 int len
= frames
[i
]->length() + SpdyFrame::kHeaderSize
;
847 memcpy(ptr
, frames
[i
]->data(), len
);
853 SpdySessionDependencies::SpdySessionDependencies()
854 : host_resolver(new MockCachingHostResolver
),
855 cert_verifier(new MockCertVerifier
),
856 proxy_service(ProxyService::CreateDirect()),
857 ssl_config_service(new SSLConfigServiceDefaults
),
858 socket_factory(new MockClientSocketFactory
),
859 deterministic_socket_factory(new DeterministicMockClientSocketFactory
),
860 http_auth_handler_factory(
861 HttpAuthHandlerFactory::CreateDefault(host_resolver
.get())),
862 enable_ip_pooling(true),
863 enable_compression(false),
865 time_func(&base::TimeTicks::Now
),
867 // Note: The CancelledTransaction test does cleanup by running all
868 // tasks in the message loop (RunAllPending). Unfortunately, that
869 // doesn't clean up tasks on the host resolver thread; and
870 // TCPConnectJob is currently not cancellable. Using synchronous
871 // lookups allows the test to shutdown cleanly. Until we have
872 // cancellable TCPConnectJobs, use synchronous lookups.
873 host_resolver
->set_synchronous_mode(true);
876 SpdySessionDependencies::SpdySessionDependencies(ProxyService
* proxy_service
)
877 : host_resolver(new MockHostResolver
),
878 cert_verifier(new MockCertVerifier
),
879 proxy_service(proxy_service
),
880 ssl_config_service(new SSLConfigServiceDefaults
),
881 socket_factory(new MockClientSocketFactory
),
882 deterministic_socket_factory(new DeterministicMockClientSocketFactory
),
883 http_auth_handler_factory(
884 HttpAuthHandlerFactory::CreateDefault(host_resolver
.get())),
885 enable_ip_pooling(true),
886 enable_compression(false),
888 time_func(&base::TimeTicks::Now
),
891 SpdySessionDependencies::~SpdySessionDependencies() {}
894 HttpNetworkSession
* SpdySessionDependencies::SpdyCreateSession(
895 SpdySessionDependencies
* session_deps
) {
896 net::HttpNetworkSession::Params params
= CreateSessionParams(session_deps
);
897 params
.client_socket_factory
= session_deps
->socket_factory
.get();
898 HttpNetworkSession
* http_session
= new HttpNetworkSession(params
);
899 SpdySessionPoolPeer
pool_peer(http_session
->spdy_session_pool());
900 pool_peer
.EnableSendingInitialSettings(false);
905 HttpNetworkSession
* SpdySessionDependencies::SpdyCreateSessionDeterministic(
906 SpdySessionDependencies
* session_deps
) {
907 net::HttpNetworkSession::Params params
= CreateSessionParams(session_deps
);
908 params
.client_socket_factory
=
909 session_deps
->deterministic_socket_factory
.get();
910 HttpNetworkSession
* http_session
= new HttpNetworkSession(params
);
911 SpdySessionPoolPeer
pool_peer(http_session
->spdy_session_pool());
912 pool_peer
.EnableSendingInitialSettings(false);
917 net::HttpNetworkSession::Params
SpdySessionDependencies::CreateSessionParams(
918 SpdySessionDependencies
* session_deps
) {
919 net::HttpNetworkSession::Params params
;
920 params
.host_resolver
= session_deps
->host_resolver
.get();
921 params
.cert_verifier
= session_deps
->cert_verifier
.get();
922 params
.proxy_service
= session_deps
->proxy_service
.get();
923 params
.ssl_config_service
= session_deps
->ssl_config_service
;
924 params
.http_auth_handler_factory
=
925 session_deps
->http_auth_handler_factory
.get();
926 params
.http_server_properties
= &session_deps
->http_server_properties
;
927 params
.enable_spdy_ip_pooling
= session_deps
->enable_ip_pooling
;
928 params
.enable_spdy_compression
= session_deps
->enable_compression
;
929 params
.enable_spdy_ping_based_connection_checking
= session_deps
->enable_ping
;
930 params
.spdy_default_protocol
= kProtoSPDY2
;
931 params
.time_func
= session_deps
->time_func
;
932 params
.trusted_spdy_proxy
= session_deps
->trusted_spdy_proxy
;
933 params
.net_log
= session_deps
->net_log
;
937 SpdyURLRequestContext::SpdyURLRequestContext()
938 : ALLOW_THIS_IN_INITIALIZER_LIST(storage_(this)) {
939 storage_
.set_host_resolver(scoped_ptr
<HostResolver
>(new MockHostResolver
));
940 storage_
.set_cert_verifier(new MockCertVerifier
);
941 storage_
.set_proxy_service(ProxyService::CreateDirect());
942 storage_
.set_ssl_config_service(new SSLConfigServiceDefaults
);
943 storage_
.set_http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault(
945 storage_
.set_http_server_properties(new HttpServerPropertiesImpl
);
946 net::HttpNetworkSession::Params params
;
947 params
.client_socket_factory
= &socket_factory_
;
948 params
.host_resolver
= host_resolver();
949 params
.cert_verifier
= cert_verifier();
950 params
.proxy_service
= proxy_service();
951 params
.ssl_config_service
= ssl_config_service();
952 params
.http_auth_handler_factory
= http_auth_handler_factory();
953 params
.network_delegate
= network_delegate();
954 params
.enable_spdy_compression
= false;
955 params
.enable_spdy_ping_based_connection_checking
= false;
956 params
.spdy_default_protocol
= kProtoSPDY2
;
957 params
.http_server_properties
= http_server_properties();
958 scoped_refptr
<HttpNetworkSession
> network_session(
959 new HttpNetworkSession(params
));
960 SpdySessionPoolPeer
pool_peer(network_session
->spdy_session_pool());
961 pool_peer
.EnableSendingInitialSettings(false);
962 storage_
.set_http_transaction_factory(new HttpCache(
964 HttpCache::DefaultBackend::InMemory(0)));
967 SpdyURLRequestContext::~SpdyURLRequestContext() {
970 const SpdyHeaderInfo
MakeSpdyHeader(SpdyControlType type
) {
971 const SpdyHeaderInfo kHeader
= {
974 0, // Associated stream ID
975 ConvertRequestPriorityToSpdyPriority(LOWEST
, 2), // Priority
976 CONTROL_FLAG_FIN
, // Control Flags
981 DATA_FLAG_NONE
// Data Flags
986 } // namespace test_spdy2