Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1881)

Side by Side Diff: net/spdy/spdy_test_util.cc

Issue 9582034: Fork SPDY/2 and SPDY/3 versions of our SPDY tests, in preparation for landing (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Fix merge bug Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/spdy/spdy_test_util.h ('k') | net/spdy/spdy_test_util_spdy2.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
5 #include "net/spdy/spdy_test_util.h"
6
7 #include <string>
8
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/http/http_network_session.h"
14 #include "net/http/http_network_transaction.h"
15 #include "net/http/http_server_properties_impl.h"
16 #include "net/spdy/spdy_framer.h"
17 #include "net/spdy/spdy_http_utils.h"
18
19 namespace net {
20
21 // Chop a frame into an array of MockWrites.
22 // |data| is the frame to chop.
23 // |length| is the length of the frame to chop.
24 // |num_chunks| is the number of chunks to create.
25 MockWrite* ChopWriteFrame(const char* data, int length, int num_chunks) {
26 MockWrite* chunks = new MockWrite[num_chunks];
27 int chunk_size = length / num_chunks;
28 for (int index = 0; index < num_chunks; index++) {
29 const char* ptr = data + (index * chunk_size);
30 if (index == num_chunks - 1)
31 chunk_size += length % chunk_size; // The last chunk takes the remainder.
32 chunks[index] = MockWrite(ASYNC, ptr, chunk_size);
33 }
34 return chunks;
35 }
36
37 // Chop a SpdyFrame into an array of MockWrites.
38 // |frame| is the frame to chop.
39 // |num_chunks| is the number of chunks to create.
40 MockWrite* ChopWriteFrame(const spdy::SpdyFrame& frame, int num_chunks) {
41 return ChopWriteFrame(frame.data(),
42 frame.length() + spdy::SpdyFrame::kHeaderSize,
43 num_chunks);
44 }
45
46 // Chop a frame into an array of MockReads.
47 // |data| is the frame to chop.
48 // |length| is the length of the frame to chop.
49 // |num_chunks| is the number of chunks to create.
50 MockRead* ChopReadFrame(const char* data, int length, int num_chunks) {
51 MockRead* chunks = new MockRead[num_chunks];
52 int chunk_size = length / num_chunks;
53 for (int index = 0; index < num_chunks; index++) {
54 const char* ptr = data + (index * chunk_size);
55 if (index == num_chunks - 1)
56 chunk_size += length % chunk_size; // The last chunk takes the remainder.
57 chunks[index] = MockRead(ASYNC, ptr, chunk_size);
58 }
59 return chunks;
60 }
61
62 // Chop a SpdyFrame into an array of MockReads.
63 // |frame| is the frame to chop.
64 // |num_chunks| is the number of chunks to create.
65 MockRead* ChopReadFrame(const spdy::SpdyFrame& frame, int num_chunks) {
66 return ChopReadFrame(frame.data(),
67 frame.length() + spdy::SpdyFrame::kHeaderSize,
68 num_chunks);
69 }
70
71 // Adds headers and values to a map.
72 // |extra_headers| is an array of { name, value } pairs, arranged as strings
73 // where the even entries are the header names, and the odd entries are the
74 // header values.
75 // |headers| gets filled in from |extra_headers|.
76 void AppendHeadersToSpdyFrame(const char* const extra_headers[],
77 int extra_header_count,
78 spdy::SpdyHeaderBlock* headers) {
79 std::string this_header;
80 std::string this_value;
81
82 if (!extra_header_count)
83 return;
84
85 // Sanity check: Non-NULL header list.
86 DCHECK(NULL != extra_headers) << "NULL header value pair list";
87 // Sanity check: Non-NULL header map.
88 DCHECK(NULL != headers) << "NULL header map";
89 // Copy in the headers.
90 for (int i = 0; i < extra_header_count; i++) {
91 // Sanity check: Non-empty header.
92 DCHECK_NE('\0', *extra_headers[i * 2]) << "Empty header value pair";
93 this_header = extra_headers[i * 2];
94 std::string::size_type header_len = this_header.length();
95 if (!header_len)
96 continue;
97 this_value = extra_headers[1 + (i * 2)];
98 std::string new_value;
99 if (headers->find(this_header) != headers->end()) {
100 // More than one entry in the header.
101 // Don't add the header again, just the append to the value,
102 // separated by a NULL character.
103
104 // Adjust the value.
105 new_value = (*headers)[this_header];
106 // Put in a NULL separator.
107 new_value.append(1, '\0');
108 // Append the new value.
109 new_value += this_value;
110 } else {
111 // Not a duplicate, just write the value.
112 new_value = this_value;
113 }
114 (*headers)[this_header] = new_value;
115 }
116 }
117
118 // Writes |val| to a location of size |len|, in big-endian format.
119 // in the buffer pointed to by |buffer_handle|.
120 // Updates the |*buffer_handle| pointer by |len|
121 // Returns the number of bytes written
122 int AppendToBuffer(int val,
123 int len,
124 unsigned char** buffer_handle,
125 int* buffer_len_remaining) {
126 if (len <= 0)
127 return 0;
128 DCHECK((size_t) len <= sizeof(len)) << "Data length too long for data type";
129 DCHECK(NULL != buffer_handle) << "NULL buffer handle";
130 DCHECK(NULL != *buffer_handle) << "NULL pointer";
131 DCHECK(NULL != buffer_len_remaining)
132 << "NULL buffer remainder length pointer";
133 DCHECK_GE(*buffer_len_remaining, len) << "Insufficient buffer size";
134 for (int i = 0; i < len; i++) {
135 int shift = (8 * (len - (i + 1)));
136 unsigned char val_chunk = (val >> shift) & 0x0FF;
137 *(*buffer_handle)++ = val_chunk;
138 *buffer_len_remaining += 1;
139 }
140 return len;
141 }
142
143 // Construct a SPDY packet.
144 // |head| is the start of the packet, up to but not including
145 // the header value pairs.
146 // |extra_headers| are the extra header-value pairs, which typically
147 // will vary the most between calls.
148 // |tail| is any (relatively constant) header-value pairs to add.
149 // |buffer| is the buffer we're filling in.
150 // Returns a SpdyFrame.
151 spdy::SpdyFrame* ConstructSpdyPacket(const SpdyHeaderInfo& header_info,
152 const char* const extra_headers[],
153 int extra_header_count,
154 const char* const tail[],
155 int tail_header_count) {
156 spdy::SpdyFramer framer;
157 spdy::SpdyHeaderBlock headers;
158 // Copy in the extra headers to our map.
159 AppendHeadersToSpdyFrame(extra_headers, extra_header_count, &headers);
160 // Copy in the tail headers to our map.
161 if (tail && tail_header_count)
162 AppendHeadersToSpdyFrame(tail, tail_header_count, &headers);
163 spdy::SpdyFrame* frame = NULL;
164 switch (header_info.kind) {
165 case spdy::SYN_STREAM:
166 frame = framer.CreateSynStream(header_info.id, header_info.assoc_id,
167 header_info.priority,
168 header_info.control_flags,
169 header_info.compressed, &headers);
170 break;
171 case spdy::SYN_REPLY:
172 frame = framer.CreateSynReply(header_info.id, header_info.control_flags,
173 header_info.compressed, &headers);
174 break;
175 case spdy::RST_STREAM:
176 frame = framer.CreateRstStream(header_info.id, header_info.status);
177 break;
178 case spdy::HEADERS:
179 frame = framer.CreateHeaders(header_info.id, header_info.control_flags,
180 header_info.compressed, &headers);
181 break;
182 default:
183 frame = framer.CreateDataFrame(header_info.id, header_info.data,
184 header_info.data_length,
185 header_info.data_flags);
186 break;
187 }
188 return frame;
189 }
190
191 // Construct an expected SPDY SETTINGS frame.
192 // |settings| are the settings to set.
193 // Returns the constructed frame. The caller takes ownership of the frame.
194 spdy::SpdyFrame* ConstructSpdySettings(
195 const spdy::SpdySettings& settings) {
196 spdy::SpdyFramer framer;
197 return framer.CreateSettings(settings);
198 }
199
200 // Construct an expected SPDY CREDENTIAL frame.
201 // |credential| is the credential to sen.
202 // Returns the constructed frame. The caller takes ownership of the frame.
203 spdy::SpdyFrame* ConstructSpdyCredential(
204 const spdy::SpdyCredential& credential) {
205 spdy::SpdyFramer framer;
206 return framer.CreateCredentialFrame(credential);
207 }
208
209 // Construct a SPDY PING frame.
210 // Returns the constructed frame. The caller takes ownership of the frame.
211 spdy::SpdyFrame* ConstructSpdyPing() {
212 spdy::SpdyFramer framer;
213 return framer.CreatePingFrame(1);
214 }
215
216 // Construct a SPDY GOAWAY frame.
217 // Returns the constructed frame. The caller takes ownership of the frame.
218 spdy::SpdyFrame* ConstructSpdyGoAway() {
219 spdy::SpdyFramer framer;
220 return framer.CreateGoAway(0);
221 }
222
223 // Construct a SPDY WINDOW_UPDATE frame.
224 // Returns the constructed frame. The caller takes ownership of the frame.
225 spdy::SpdyFrame* ConstructSpdyWindowUpdate(
226 const spdy::SpdyStreamId stream_id, uint32 delta_window_size) {
227 spdy::SpdyFramer framer;
228 return framer.CreateWindowUpdate(stream_id, delta_window_size);
229 }
230
231 // Construct a SPDY RST_STREAM frame.
232 // Returns the constructed frame. The caller takes ownership of the frame.
233 spdy::SpdyFrame* ConstructSpdyRstStream(spdy::SpdyStreamId stream_id,
234 spdy::SpdyStatusCodes status) {
235 spdy::SpdyFramer framer;
236 return framer.CreateRstStream(stream_id, status);
237 }
238
239 // Construct a single SPDY header entry, for validation.
240 // |extra_headers| are the extra header-value pairs.
241 // |buffer| is the buffer we're filling in.
242 // |index| is the index of the header we want.
243 // Returns the number of bytes written into |buffer|.
244 int ConstructSpdyHeader(const char* const extra_headers[],
245 int extra_header_count,
246 char* buffer,
247 int buffer_length,
248 int index) {
249 const char* this_header = NULL;
250 const char* this_value = NULL;
251 if (!buffer || !buffer_length)
252 return 0;
253 *buffer = '\0';
254 // Sanity check: Non-empty header list.
255 DCHECK(NULL != extra_headers) << "NULL extra headers pointer";
256 // Sanity check: Index out of range.
257 DCHECK((index >= 0) && (index < extra_header_count))
258 << "Index " << index
259 << " out of range [0, " << extra_header_count << ")";
260 this_header = extra_headers[index * 2];
261 // Sanity check: Non-empty header.
262 if (!*this_header)
263 return 0;
264 std::string::size_type header_len = strlen(this_header);
265 if (!header_len)
266 return 0;
267 this_value = extra_headers[1 + (index * 2)];
268 // Sanity check: Non-empty value.
269 if (!*this_value)
270 this_value = "";
271 int n = base::snprintf(buffer,
272 buffer_length,
273 "%s: %s\r\n",
274 this_header,
275 this_value);
276 return n;
277 }
278
279 spdy::SpdyFrame* ConstructSpdyControlFrame(const char* const extra_headers[],
280 int extra_header_count,
281 bool compressed,
282 int stream_id,
283 RequestPriority request_priority,
284 spdy::SpdyControlType type,
285 spdy::SpdyControlFlags flags,
286 const char* const* kHeaders,
287 int kHeadersSize) {
288 return ConstructSpdyControlFrame(extra_headers,
289 extra_header_count,
290 compressed,
291 stream_id,
292 request_priority,
293 type,
294 flags,
295 kHeaders,
296 kHeadersSize,
297 0);
298 }
299
300 spdy::SpdyFrame* ConstructSpdyControlFrame(const char* const extra_headers[],
301 int extra_header_count,
302 bool compressed,
303 int stream_id,
304 RequestPriority request_priority,
305 spdy::SpdyControlType type,
306 spdy::SpdyControlFlags flags,
307 const char* const* kHeaders,
308 int kHeadersSize,
309 int associated_stream_id) {
310 const SpdyHeaderInfo kSynStartHeader = {
311 type, // Kind = Syn
312 stream_id, // Stream ID
313 associated_stream_id, // Associated stream ID
314 ConvertRequestPriorityToSpdyPriority(request_priority),
315 // Priority
316 flags, // Control Flags
317 compressed, // Compressed
318 spdy::INVALID, // Status
319 NULL, // Data
320 0, // Length
321 spdy::DATA_FLAG_NONE // Data Flags
322 };
323 return ConstructSpdyPacket(kSynStartHeader,
324 extra_headers,
325 extra_header_count,
326 kHeaders,
327 kHeadersSize / 2);
328 }
329
330 // Constructs a standard SPDY GET SYN packet, optionally compressed
331 // for the url |url|.
332 // |extra_headers| are the extra header-value pairs, which typically
333 // will vary the most between calls.
334 // Returns a SpdyFrame.
335 spdy::SpdyFrame* ConstructSpdyGet(const char* const url,
336 bool compressed,
337 int stream_id,
338 RequestPriority request_priority) {
339 const SpdyHeaderInfo kSynStartHeader = {
340 spdy::SYN_STREAM, // Kind = Syn
341 stream_id, // Stream ID
342 0, // Associated stream ID
343 net::ConvertRequestPriorityToSpdyPriority(request_priority),
344 // Priority
345 spdy::CONTROL_FLAG_FIN, // Control Flags
346 compressed, // Compressed
347 spdy::INVALID, // Status
348 NULL, // Data
349 0, // Length
350 spdy::DATA_FLAG_NONE // Data Flags
351 };
352
353 GURL gurl(url);
354
355 // This is so ugly. Why are we using char* in here again?
356 std::string str_path = gurl.PathForRequest();
357 std::string str_scheme = gurl.scheme();
358 std::string str_host = gurl.host();
359 if (gurl.has_port()) {
360 str_host += ":";
361 str_host += gurl.port();
362 }
363 scoped_array<char> req(new char[str_path.size() + 1]);
364 scoped_array<char> scheme(new char[str_scheme.size() + 1]);
365 scoped_array<char> host(new char[str_host.size() + 1]);
366 memcpy(req.get(), str_path.c_str(), str_path.size());
367 memcpy(scheme.get(), str_scheme.c_str(), str_scheme.size());
368 memcpy(host.get(), str_host.c_str(), str_host.size());
369 req.get()[str_path.size()] = '\0';
370 scheme.get()[str_scheme.size()] = '\0';
371 host.get()[str_host.size()] = '\0';
372
373 const char* const headers[] = {
374 "method",
375 "GET",
376 "url",
377 req.get(),
378 "host",
379 host.get(),
380 "scheme",
381 scheme.get(),
382 "version",
383 "HTTP/1.1"
384 };
385 return ConstructSpdyPacket(
386 kSynStartHeader,
387 NULL,
388 0,
389 headers,
390 arraysize(headers) / 2);
391 }
392
393 // Constructs a standard SPDY GET SYN packet, optionally compressed.
394 // |extra_headers| are the extra header-value pairs, which typically
395 // will vary the most between calls.
396 // Returns a SpdyFrame.
397 spdy::SpdyFrame* ConstructSpdyGet(const char* const extra_headers[],
398 int extra_header_count,
399 bool compressed,
400 int stream_id,
401 RequestPriority request_priority) {
402 return ConstructSpdyGet(extra_headers, extra_header_count, compressed,
403 stream_id, request_priority, true);
404 }
405
406 // Constructs a standard SPDY GET SYN packet, optionally compressed.
407 // |extra_headers| are the extra header-value pairs, which typically
408 // will vary the most between calls.
409 // Returns a SpdyFrame.
410 spdy::SpdyFrame* ConstructSpdyGet(const char* const extra_headers[],
411 int extra_header_count,
412 bool compressed,
413 int stream_id,
414 RequestPriority request_priority,
415 bool direct) {
416 const char* const kStandardGetHeaders[] = {
417 "method",
418 "GET",
419 "url",
420 (direct ? "/" : "http://www.google.com/"),
421 "host",
422 "www.google.com",
423 "scheme",
424 "http",
425 "version",
426 "HTTP/1.1"
427 };
428 return ConstructSpdyControlFrame(extra_headers,
429 extra_header_count,
430 compressed,
431 stream_id,
432 request_priority,
433 spdy::SYN_STREAM,
434 spdy::CONTROL_FLAG_FIN,
435 kStandardGetHeaders,
436 arraysize(kStandardGetHeaders));
437 }
438
439 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
440 spdy::SpdyFrame* ConstructSpdyConnect(const char* const extra_headers[],
441 int extra_header_count,
442 int stream_id) {
443 const char* const kConnectHeaders[] = {
444 "method", "CONNECT",
445 "url", "www.google.com:443",
446 "host", "www.google.com",
447 "version", "HTTP/1.1",
448 };
449 return ConstructSpdyControlFrame(extra_headers,
450 extra_header_count,
451 /*compressed*/ false,
452 stream_id,
453 LOWEST,
454 spdy::SYN_STREAM,
455 spdy::CONTROL_FLAG_NONE,
456 kConnectHeaders,
457 arraysize(kConnectHeaders));
458 }
459
460 // Constructs a standard SPDY push SYN packet.
461 // |extra_headers| are the extra header-value pairs, which typically
462 // will vary the most between calls.
463 // Returns a SpdyFrame.
464 spdy::SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
465 int extra_header_count,
466 int stream_id,
467 int associated_stream_id) {
468 const char* const kStandardGetHeaders[] = {
469 "hello",
470 "bye",
471 "status",
472 "200",
473 "version",
474 "HTTP/1.1"
475 };
476 return ConstructSpdyControlFrame(extra_headers,
477 extra_header_count,
478 false,
479 stream_id,
480 LOWEST,
481 spdy::SYN_STREAM,
482 spdy::CONTROL_FLAG_NONE,
483 kStandardGetHeaders,
484 arraysize(kStandardGetHeaders),
485 associated_stream_id);
486 }
487
488 spdy::SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
489 int extra_header_count,
490 int stream_id,
491 int associated_stream_id,
492 const char* url) {
493 const char* const kStandardGetHeaders[] = {
494 "hello",
495 "bye",
496 "status",
497 "200 OK",
498 "url",
499 url,
500 "version",
501 "HTTP/1.1"
502 };
503 return ConstructSpdyControlFrame(extra_headers,
504 extra_header_count,
505 false,
506 stream_id,
507 LOWEST,
508 spdy::SYN_STREAM,
509 spdy::CONTROL_FLAG_NONE,
510 kStandardGetHeaders,
511 arraysize(kStandardGetHeaders),
512 associated_stream_id);
513
514 }
515 spdy::SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
516 int extra_header_count,
517 int stream_id,
518 int associated_stream_id,
519 const char* url,
520 const char* status,
521 const char* location) {
522 const char* const kStandardGetHeaders[] = {
523 "hello",
524 "bye",
525 "status",
526 status,
527 "location",
528 location,
529 "url",
530 url,
531 "version",
532 "HTTP/1.1"
533 };
534 return ConstructSpdyControlFrame(extra_headers,
535 extra_header_count,
536 false,
537 stream_id,
538 LOWEST,
539 spdy::SYN_STREAM,
540 spdy::CONTROL_FLAG_NONE,
541 kStandardGetHeaders,
542 arraysize(kStandardGetHeaders),
543 associated_stream_id);
544 }
545
546 spdy::SpdyFrame* ConstructSpdyPush(int stream_id,
547 int associated_stream_id,
548 const char* url) {
549 const char* const kStandardGetHeaders[] = {
550 "url",
551 url
552 };
553 return ConstructSpdyControlFrame(0,
554 0,
555 false,
556 stream_id,
557 LOWEST,
558 spdy::SYN_STREAM,
559 spdy::CONTROL_FLAG_NONE,
560 kStandardGetHeaders,
561 arraysize(kStandardGetHeaders),
562 associated_stream_id);
563 }
564
565 spdy::SpdyFrame* ConstructSpdyPushHeaders(int stream_id,
566 const char* const extra_headers[],
567 int extra_header_count) {
568 const char* const kStandardGetHeaders[] = {
569 "status",
570 "200 OK",
571 "version",
572 "HTTP/1.1"
573 };
574 return ConstructSpdyControlFrame(extra_headers,
575 extra_header_count,
576 false,
577 stream_id,
578 LOWEST,
579 spdy::HEADERS,
580 spdy::CONTROL_FLAG_NONE,
581 kStandardGetHeaders,
582 arraysize(kStandardGetHeaders));
583 }
584
585 // Constructs a standard SPDY SYN_REPLY packet with the specified status code.
586 // Returns a SpdyFrame.
587 spdy::SpdyFrame* ConstructSpdySynReplyError(
588 const char* const status,
589 const char* const* const extra_headers,
590 int extra_header_count,
591 int stream_id) {
592 const char* const kStandardGetHeaders[] = {
593 "hello",
594 "bye",
595 "status",
596 status,
597 "version",
598 "HTTP/1.1"
599 };
600 return ConstructSpdyControlFrame(extra_headers,
601 extra_header_count,
602 false,
603 stream_id,
604 LOWEST,
605 spdy::SYN_REPLY,
606 spdy::CONTROL_FLAG_NONE,
607 kStandardGetHeaders,
608 arraysize(kStandardGetHeaders));
609 }
610
611 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
612 // |extra_headers| are the extra header-value pairs, which typically
613 // will vary the most between calls.
614 // Returns a SpdyFrame.
615 spdy::SpdyFrame* ConstructSpdyGetSynReplyRedirect(int stream_id) {
616 static const char* const kExtraHeaders[] = {
617 "location",
618 "http://www.foo.com/index.php",
619 };
620 return ConstructSpdySynReplyError("301 Moved Permanently", kExtraHeaders,
621 arraysize(kExtraHeaders)/2, stream_id);
622 }
623
624 // Constructs a standard SPDY SYN_REPLY packet with an Internal Server
625 // Error status code.
626 // Returns a SpdyFrame.
627 spdy::SpdyFrame* ConstructSpdySynReplyError(int stream_id) {
628 return ConstructSpdySynReplyError("500 Internal Server Error", NULL, 0, 1);
629 }
630
631
632
633
634 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
635 // |extra_headers| are the extra header-value pairs, which typically
636 // will vary the most between calls.
637 // Returns a SpdyFrame.
638 spdy::SpdyFrame* ConstructSpdyGetSynReply(const char* const extra_headers[],
639 int extra_header_count,
640 int stream_id) {
641 static const char* const kStandardGetHeaders[] = {
642 "hello",
643 "bye",
644 "status",
645 "200",
646 "version",
647 "HTTP/1.1"
648 };
649 return ConstructSpdyControlFrame(extra_headers,
650 extra_header_count,
651 false,
652 stream_id,
653 LOWEST,
654 spdy::SYN_REPLY,
655 spdy::CONTROL_FLAG_NONE,
656 kStandardGetHeaders,
657 arraysize(kStandardGetHeaders));
658 }
659
660 // Constructs a standard SPDY POST SYN packet.
661 // |content_length| is the size of post data.
662 // |extra_headers| are the extra header-value pairs, which typically
663 // will vary the most between calls.
664 // Returns a SpdyFrame.
665 spdy::SpdyFrame* ConstructSpdyPost(int64 content_length,
666 const char* const extra_headers[],
667 int extra_header_count) {
668 std::string length_str = base::Int64ToString(content_length);
669 const char* post_headers[] = {
670 "method",
671 "POST",
672 "url",
673 "/",
674 "host",
675 "www.google.com",
676 "scheme",
677 "http",
678 "version",
679 "HTTP/1.1",
680 "content-length",
681 length_str.c_str()
682 };
683 return ConstructSpdyControlFrame(extra_headers,
684 extra_header_count,
685 false,
686 1,
687 LOWEST,
688 spdy::SYN_STREAM,
689 spdy::CONTROL_FLAG_NONE,
690 post_headers,
691 arraysize(post_headers));
692 }
693
694 // Constructs a chunked transfer SPDY POST SYN packet.
695 // |extra_headers| are the extra header-value pairs, which typically
696 // will vary the most between calls.
697 // Returns a SpdyFrame.
698 spdy::SpdyFrame* ConstructChunkedSpdyPost(const char* const extra_headers[],
699 int extra_header_count) {
700 const char* post_headers[] = {
701 "method",
702 "POST",
703 "url",
704 "/",
705 "host",
706 "www.google.com",
707 "scheme",
708 "http",
709 "version",
710 "HTTP/1.1"
711 };
712 return ConstructSpdyControlFrame(extra_headers,
713 extra_header_count,
714 false,
715 1,
716 LOWEST,
717 spdy::SYN_STREAM,
718 spdy::CONTROL_FLAG_NONE,
719 post_headers,
720 arraysize(post_headers));
721 }
722
723 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY POST.
724 // |extra_headers| are the extra header-value pairs, which typically
725 // will vary the most between calls.
726 // Returns a SpdyFrame.
727 spdy::SpdyFrame* ConstructSpdyPostSynReply(const char* const extra_headers[],
728 int extra_header_count) {
729 static const char* const kStandardGetHeaders[] = {
730 "hello",
731 "bye",
732 "status",
733 "200",
734 "url",
735 "/index.php",
736 "version",
737 "HTTP/1.1"
738 };
739 return ConstructSpdyControlFrame(extra_headers,
740 extra_header_count,
741 false,
742 1,
743 LOWEST,
744 spdy::SYN_REPLY,
745 spdy::CONTROL_FLAG_NONE,
746 kStandardGetHeaders,
747 arraysize(kStandardGetHeaders));
748 }
749
750 // Constructs a single SPDY data frame with the default contents.
751 spdy::SpdyFrame* ConstructSpdyBodyFrame(int stream_id, bool fin) {
752 spdy::SpdyFramer framer;
753 return framer.CreateDataFrame(
754 stream_id, kUploadData, kUploadDataSize,
755 fin ? spdy::DATA_FLAG_FIN : spdy::DATA_FLAG_NONE);
756 }
757
758 // Constructs a single SPDY data frame with the given content.
759 spdy::SpdyFrame* ConstructSpdyBodyFrame(int stream_id, const char* data,
760 uint32 len, bool fin) {
761 spdy::SpdyFramer framer;
762 return framer.CreateDataFrame(
763 stream_id, data, len, fin ? spdy::DATA_FLAG_FIN : spdy::DATA_FLAG_NONE);
764 }
765
766 // Wraps |frame| in the payload of a data frame in stream |stream_id|.
767 spdy::SpdyFrame* ConstructWrappedSpdyFrame(
768 const scoped_ptr<spdy::SpdyFrame>& frame,
769 int stream_id) {
770 return ConstructSpdyBodyFrame(stream_id, frame->data(),
771 frame->length() + spdy::SpdyFrame::kHeaderSize,
772 false);
773 }
774
775 // Construct an expected SPDY reply string.
776 // |extra_headers| are the extra header-value pairs, which typically
777 // will vary the most between calls.
778 // |buffer| is the buffer we're filling in.
779 // Returns the number of bytes written into |buffer|.
780 int ConstructSpdyReplyString(const char* const extra_headers[],
781 int extra_header_count,
782 char* buffer,
783 int buffer_length) {
784 int packet_size = 0;
785 char* buffer_write = buffer;
786 int buffer_left = buffer_length;
787 spdy::SpdyHeaderBlock headers;
788 if (!buffer || !buffer_length)
789 return 0;
790 // Copy in the extra headers.
791 AppendHeadersToSpdyFrame(extra_headers, extra_header_count, &headers);
792 // The iterator gets us the list of header/value pairs in sorted order.
793 spdy::SpdyHeaderBlock::iterator next = headers.begin();
794 spdy::SpdyHeaderBlock::iterator last = headers.end();
795 for ( ; next != last; ++next) {
796 // Write the header.
797 int value_len, current_len, offset;
798 const char* header_string = next->first.c_str();
799 packet_size += AppendToBuffer(header_string,
800 next->first.length(),
801 &buffer_write,
802 &buffer_left);
803 packet_size += AppendToBuffer(": ",
804 strlen(": "),
805 &buffer_write,
806 &buffer_left);
807 // Write the value(s).
808 const char* value_string = next->second.c_str();
809 // Check if it's split among two or more values.
810 value_len = next->second.length();
811 current_len = strlen(value_string);
812 offset = 0;
813 // Handle the first N-1 values.
814 while (current_len < value_len) {
815 // Finish this line -- write the current value.
816 packet_size += AppendToBuffer(value_string + offset,
817 current_len - offset,
818 &buffer_write,
819 &buffer_left);
820 packet_size += AppendToBuffer("\n",
821 strlen("\n"),
822 &buffer_write,
823 &buffer_left);
824 // Advance to next value.
825 offset = current_len + 1;
826 current_len += 1 + strlen(value_string + offset);
827 // Start another line -- add the header again.
828 packet_size += AppendToBuffer(header_string,
829 next->first.length(),
830 &buffer_write,
831 &buffer_left);
832 packet_size += AppendToBuffer(": ",
833 strlen(": "),
834 &buffer_write,
835 &buffer_left);
836 }
837 EXPECT_EQ(value_len, current_len);
838 // Copy the last (or only) value.
839 packet_size += AppendToBuffer(value_string + offset,
840 value_len - offset,
841 &buffer_write,
842 &buffer_left);
843 packet_size += AppendToBuffer("\n",
844 strlen("\n"),
845 &buffer_write,
846 &buffer_left);
847 }
848 return packet_size;
849 }
850
851 // Create a MockWrite from the given SpdyFrame.
852 MockWrite CreateMockWrite(const spdy::SpdyFrame& req) {
853 return MockWrite(
854 ASYNC, req.data(), req.length() + spdy::SpdyFrame::kHeaderSize);
855 }
856
857 // Create a MockWrite from the given SpdyFrame and sequence number.
858 MockWrite CreateMockWrite(const spdy::SpdyFrame& req, int seq) {
859 return CreateMockWrite(req, seq, ASYNC);
860 }
861
862 // Create a MockWrite from the given SpdyFrame and sequence number.
863 MockWrite CreateMockWrite(const spdy::SpdyFrame& req, int seq, IoMode mode) {
864 return MockWrite(
865 mode, req.data(), req.length() + spdy::SpdyFrame::kHeaderSize, seq);
866 }
867
868 // Create a MockRead from the given SpdyFrame.
869 MockRead CreateMockRead(const spdy::SpdyFrame& resp) {
870 return MockRead(
871 ASYNC, resp.data(), resp.length() + spdy::SpdyFrame::kHeaderSize);
872 }
873
874 // Create a MockRead from the given SpdyFrame and sequence number.
875 MockRead CreateMockRead(const spdy::SpdyFrame& resp, int seq) {
876 return CreateMockRead(resp, seq, ASYNC);
877 }
878
879 // Create a MockRead from the given SpdyFrame and sequence number.
880 MockRead CreateMockRead(const spdy::SpdyFrame& resp, int seq, IoMode mode) {
881 return MockRead(
882 mode, resp.data(), resp.length() + spdy::SpdyFrame::kHeaderSize, seq);
883 }
884
885 // Combines the given SpdyFrames into the given char array and returns
886 // the total length.
887 int CombineFrames(const spdy::SpdyFrame** frames, int num_frames,
888 char* buff, int buff_len) {
889 int total_len = 0;
890 for (int i = 0; i < num_frames; ++i) {
891 total_len += frames[i]->length() + spdy::SpdyFrame::kHeaderSize;
892 }
893 DCHECK_LE(total_len, buff_len);
894 char* ptr = buff;
895 for (int i = 0; i < num_frames; ++i) {
896 int len = frames[i]->length() + spdy::SpdyFrame::kHeaderSize;
897 memcpy(ptr, frames[i]->data(), len);
898 ptr += len;
899 }
900 return total_len;
901 }
902
903 SpdySessionDependencies::SpdySessionDependencies()
904 : host_resolver(new MockCachingHostResolver),
905 cert_verifier(new CertVerifier),
906 proxy_service(ProxyService::CreateDirect()),
907 ssl_config_service(new SSLConfigServiceDefaults),
908 socket_factory(new MockClientSocketFactory),
909 deterministic_socket_factory(new DeterministicMockClientSocketFactory),
910 http_auth_handler_factory(
911 HttpAuthHandlerFactory::CreateDefault(host_resolver.get())) {
912 // Note: The CancelledTransaction test does cleanup by running all
913 // tasks in the message loop (RunAllPending). Unfortunately, that
914 // doesn't clean up tasks on the host resolver thread; and
915 // TCPConnectJob is currently not cancellable. Using synchronous
916 // lookups allows the test to shutdown cleanly. Until we have
917 // cancellable TCPConnectJobs, use synchronous lookups.
918 host_resolver->set_synchronous_mode(true);
919 }
920
921 SpdySessionDependencies::SpdySessionDependencies(ProxyService* proxy_service)
922 : host_resolver(new MockHostResolver),
923 cert_verifier(new CertVerifier),
924 proxy_service(proxy_service),
925 ssl_config_service(new SSLConfigServiceDefaults),
926 socket_factory(new MockClientSocketFactory),
927 deterministic_socket_factory(new DeterministicMockClientSocketFactory),
928 http_auth_handler_factory(
929 HttpAuthHandlerFactory::CreateDefault(host_resolver.get())) {}
930
931 SpdySessionDependencies::~SpdySessionDependencies() {}
932
933 // static
934 HttpNetworkSession* SpdySessionDependencies::SpdyCreateSession(
935 SpdySessionDependencies* session_deps) {
936 net::HttpNetworkSession::Params params;
937 params.client_socket_factory = session_deps->socket_factory.get();
938 params.host_resolver = session_deps->host_resolver.get();
939 params.cert_verifier = session_deps->cert_verifier.get();
940 params.proxy_service = session_deps->proxy_service.get();
941 params.ssl_config_service = session_deps->ssl_config_service;
942 params.http_auth_handler_factory =
943 session_deps->http_auth_handler_factory.get();
944 params.http_server_properties = &session_deps->http_server_properties;
945 return new HttpNetworkSession(params);
946 }
947
948 // static
949 HttpNetworkSession* SpdySessionDependencies::SpdyCreateSessionDeterministic(
950 SpdySessionDependencies* session_deps) {
951 net::HttpNetworkSession::Params params;
952 params.client_socket_factory =
953 session_deps->deterministic_socket_factory.get();
954 params.host_resolver = session_deps->host_resolver.get();
955 params.cert_verifier = session_deps->cert_verifier.get();
956 params.proxy_service = session_deps->proxy_service.get();
957 params.ssl_config_service = session_deps->ssl_config_service;
958 params.http_auth_handler_factory =
959 session_deps->http_auth_handler_factory.get();
960 params.http_server_properties = &session_deps->http_server_properties;
961 return new HttpNetworkSession(params);
962 }
963
964 SpdyURLRequestContext::SpdyURLRequestContext()
965 : ALLOW_THIS_IN_INITIALIZER_LIST(storage_(this)) {
966 storage_.set_host_resolver(new MockHostResolver());
967 storage_.set_cert_verifier(new CertVerifier);
968 storage_.set_proxy_service(ProxyService::CreateDirect());
969 storage_.set_ssl_config_service(new SSLConfigServiceDefaults);
970 storage_.set_http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault(
971 host_resolver()));
972 storage_.set_http_server_properties(new HttpServerPropertiesImpl);
973 net::HttpNetworkSession::Params params;
974 params.client_socket_factory = &socket_factory_;
975 params.host_resolver = host_resolver();
976 params.cert_verifier = cert_verifier();
977 params.proxy_service = proxy_service();
978 params.ssl_config_service = ssl_config_service();
979 params.http_auth_handler_factory = http_auth_handler_factory();
980 params.network_delegate = network_delegate();
981 params.http_server_properties = http_server_properties();
982 scoped_refptr<HttpNetworkSession> network_session(
983 new HttpNetworkSession(params));
984 storage_.set_http_transaction_factory(new HttpCache(
985 network_session,
986 HttpCache::DefaultBackend::InMemory(0)));
987 }
988
989 SpdyURLRequestContext::~SpdyURLRequestContext() {
990 }
991
992 const SpdyHeaderInfo MakeSpdyHeader(spdy::SpdyControlType type) {
993 const SpdyHeaderInfo kHeader = {
994 type, // Kind = Syn
995 1, // Stream ID
996 0, // Associated stream ID
997 2, // Priority
998 spdy::CONTROL_FLAG_FIN, // Control Flags
999 false, // Compressed
1000 spdy::INVALID, // Status
1001 NULL, // Data
1002 0, // Length
1003 spdy::DATA_FLAG_NONE // Data Flags
1004 };
1005 return kHeader;
1006 }
1007 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_test_util.h ('k') | net/spdy/spdy_test_util_spdy2.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698