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_protocol.h"
6
7 namespace net {
8
SpdyFrameWithNameValueBlockIR(SpdyStreamId stream_id)9 SpdyFrameWithNameValueBlockIR::SpdyFrameWithNameValueBlockIR(
10 SpdyStreamId stream_id) : SpdyFrameWithFinIR(stream_id) {}
11
~SpdyFrameWithNameValueBlockIR()12 SpdyFrameWithNameValueBlockIR::~SpdyFrameWithNameValueBlockIR() {}
13
SpdyDataIR(SpdyStreamId stream_id,const base::StringPiece & data)14 SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id, const base::StringPiece& data)
15 : SpdyFrameWithFinIR(stream_id),
16 padded_(false),
17 padding_payload_len_(0) {
18 SetDataDeep(data);
19 }
20
SpdyDataIR(SpdyStreamId stream_id)21 SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id)
22 : SpdyFrameWithFinIR(stream_id),
23 padded_(false),
24 padding_payload_len_(0) {}
25
~SpdyDataIR()26 SpdyDataIR::~SpdyDataIR() {}
27
IsValidFrameType(SpdyMajorVersion version,int frame_type_field)28 bool SpdyConstants::IsValidFrameType(SpdyMajorVersion version,
29 int frame_type_field) {
30 switch (version) {
31 case SPDY2:
32 case SPDY3:
33 // SYN_STREAM is the first valid frame.
34 if (frame_type_field < SerializeFrameType(version, SYN_STREAM)) {
35 return false;
36 }
37
38 // WINDOW_UPDATE is the last valid frame.
39 if (frame_type_field > SerializeFrameType(version, WINDOW_UPDATE)) {
40 return false;
41 }
42
43 return true;
44 case SPDY4:
45 case SPDY5:
46 // Check for recognized extensions.
47 if (frame_type_field == SerializeFrameType(version, ALTSVC) ||
48 frame_type_field == SerializeFrameType(version, BLOCKED)) {
49 return true;
50 }
51
52 // DATA is the first valid frame.
53 if (frame_type_field < SerializeFrameType(version, DATA)) {
54 return false;
55 }
56
57 // CONTINUATION is the last valid frame.
58 if (frame_type_field > SerializeFrameType(version, CONTINUATION)) {
59 return false;
60 }
61
62 return true;
63 }
64
65 LOG(DFATAL) << "Unhandled SPDY version " << version;
66 return false;
67 }
68
ParseFrameType(SpdyMajorVersion version,int frame_type_field)69 SpdyFrameType SpdyConstants::ParseFrameType(SpdyMajorVersion version,
70 int frame_type_field) {
71 switch (version) {
72 case SPDY2:
73 case SPDY3:
74 switch (frame_type_field) {
75 case 1:
76 return SYN_STREAM;
77 case 2:
78 return SYN_REPLY;
79 case 3:
80 return RST_STREAM;
81 case 4:
82 return SETTINGS;
83 case 6:
84 return PING;
85 case 7:
86 return GOAWAY;
87 case 8:
88 return HEADERS;
89 case 9:
90 return WINDOW_UPDATE;
91 }
92 break;
93 case SPDY4:
94 case SPDY5:
95 switch (frame_type_field) {
96 case 0:
97 return DATA;
98 case 1:
99 return HEADERS;
100 case 2:
101 return PRIORITY;
102 case 3:
103 return RST_STREAM;
104 case 4:
105 return SETTINGS;
106 case 5:
107 return PUSH_PROMISE;
108 case 6:
109 return PING;
110 case 7:
111 return GOAWAY;
112 case 8:
113 return WINDOW_UPDATE;
114 case 9:
115 return CONTINUATION;
116 case 10:
117 return ALTSVC;
118 case 11:
119 return BLOCKED;
120 }
121 break;
122 }
123
124 LOG(DFATAL) << "Unhandled frame type " << frame_type_field;
125 return DATA;
126 }
127
SerializeFrameType(SpdyMajorVersion version,SpdyFrameType frame_type)128 int SpdyConstants::SerializeFrameType(SpdyMajorVersion version,
129 SpdyFrameType frame_type) {
130 switch (version) {
131 case SPDY2:
132 case SPDY3:
133 switch (frame_type) {
134 case SYN_STREAM:
135 return 1;
136 case SYN_REPLY:
137 return 2;
138 case RST_STREAM:
139 return 3;
140 case SETTINGS:
141 return 4;
142 case PING:
143 return 6;
144 case GOAWAY:
145 return 7;
146 case HEADERS:
147 return 8;
148 case WINDOW_UPDATE:
149 return 9;
150 default:
151 LOG(DFATAL) << "Serializing unhandled frame type " << frame_type;
152 return -1;
153 }
154 case SPDY4:
155 case SPDY5:
156 switch (frame_type) {
157 case DATA:
158 return 0;
159 case HEADERS:
160 return 1;
161 case PRIORITY:
162 return 2;
163 case RST_STREAM:
164 return 3;
165 case SETTINGS:
166 return 4;
167 case PUSH_PROMISE:
168 return 5;
169 case PING:
170 return 6;
171 case GOAWAY:
172 return 7;
173 case WINDOW_UPDATE:
174 return 8;
175 case CONTINUATION:
176 return 9;
177 // ALTSVC and BLOCKED are extensions.
178 case ALTSVC:
179 return 10;
180 case BLOCKED:
181 return 11;
182 default:
183 LOG(DFATAL) << "Serializing unhandled frame type " << frame_type;
184 return -1;
185 }
186 }
187
188 LOG(DFATAL) << "Unhandled SPDY version " << version;
189 return -1;
190 }
191
DataFrameType(SpdyMajorVersion version)192 int SpdyConstants::DataFrameType(SpdyMajorVersion version) {
193 switch (version) {
194 case SPDY2:
195 case SPDY3:
196 return 0;
197 case SPDY4:
198 case SPDY5:
199 return SerializeFrameType(version, DATA);
200 }
201
202 LOG(DFATAL) << "Unhandled SPDY version " << version;
203 return 0;
204 }
205
IsValidSettingId(SpdyMajorVersion version,int setting_id_field)206 bool SpdyConstants::IsValidSettingId(SpdyMajorVersion version,
207 int setting_id_field) {
208 switch (version) {
209 case SPDY2:
210 case SPDY3:
211 // UPLOAD_BANDWIDTH is the first valid setting id.
212 if (setting_id_field <
213 SerializeSettingId(version, SETTINGS_UPLOAD_BANDWIDTH)) {
214 return false;
215 }
216
217 // INITIAL_WINDOW_SIZE is the last valid setting id.
218 if (setting_id_field >
219 SerializeSettingId(version, SETTINGS_INITIAL_WINDOW_SIZE)) {
220 return false;
221 }
222
223 return true;
224 case SPDY4:
225 case SPDY5:
226 // HEADER_TABLE_SIZE is the first valid setting id.
227 if (setting_id_field <
228 SerializeSettingId(version, SETTINGS_HEADER_TABLE_SIZE)) {
229 return false;
230 }
231
232 // MAX_HEADER_LIST_SIZE is the last valid setting id.
233 if (setting_id_field >
234 SerializeSettingId(version, SETTINGS_MAX_HEADER_LIST_SIZE)) {
235 return false;
236 }
237
238 return true;
239 }
240
241 LOG(DFATAL) << "Unhandled SPDY version " << version;
242 return false;
243 }
244
ParseSettingId(SpdyMajorVersion version,int setting_id_field)245 SpdySettingsIds SpdyConstants::ParseSettingId(SpdyMajorVersion version,
246 int setting_id_field) {
247 switch (version) {
248 case SPDY2:
249 case SPDY3:
250 switch (setting_id_field) {
251 case 1:
252 return SETTINGS_UPLOAD_BANDWIDTH;
253 case 2:
254 return SETTINGS_DOWNLOAD_BANDWIDTH;
255 case 3:
256 return SETTINGS_ROUND_TRIP_TIME;
257 case 4:
258 return SETTINGS_MAX_CONCURRENT_STREAMS;
259 case 5:
260 return SETTINGS_CURRENT_CWND;
261 case 6:
262 return SETTINGS_DOWNLOAD_RETRANS_RATE;
263 case 7:
264 return SETTINGS_INITIAL_WINDOW_SIZE;
265 }
266 break;
267 case SPDY4:
268 case SPDY5:
269 switch (setting_id_field) {
270 case 1:
271 return SETTINGS_HEADER_TABLE_SIZE;
272 case 2:
273 return SETTINGS_ENABLE_PUSH;
274 case 3:
275 return SETTINGS_MAX_CONCURRENT_STREAMS;
276 case 4:
277 return SETTINGS_INITIAL_WINDOW_SIZE;
278 case 5:
279 return SETTINGS_MAX_FRAME_SIZE;
280 case 6:
281 return SETTINGS_MAX_HEADER_LIST_SIZE;
282 }
283 break;
284 }
285
286 LOG(DFATAL) << "Unhandled setting ID " << setting_id_field;
287 return SETTINGS_UPLOAD_BANDWIDTH;
288 }
289
SerializeSettingId(SpdyMajorVersion version,SpdySettingsIds id)290 int SpdyConstants::SerializeSettingId(SpdyMajorVersion version,
291 SpdySettingsIds id) {
292 switch (version) {
293 case SPDY2:
294 case SPDY3:
295 switch (id) {
296 case SETTINGS_UPLOAD_BANDWIDTH:
297 return 1;
298 case SETTINGS_DOWNLOAD_BANDWIDTH:
299 return 2;
300 case SETTINGS_ROUND_TRIP_TIME:
301 return 3;
302 case SETTINGS_MAX_CONCURRENT_STREAMS:
303 return 4;
304 case SETTINGS_CURRENT_CWND:
305 return 5;
306 case SETTINGS_DOWNLOAD_RETRANS_RATE:
307 return 6;
308 case SETTINGS_INITIAL_WINDOW_SIZE:
309 return 7;
310 default:
311 LOG(DFATAL) << "Serializing unhandled setting id " << id;
312 return -1;
313 }
314 case SPDY4:
315 case SPDY5:
316 switch (id) {
317 case SETTINGS_HEADER_TABLE_SIZE:
318 return 1;
319 case SETTINGS_ENABLE_PUSH:
320 return 2;
321 case SETTINGS_MAX_CONCURRENT_STREAMS:
322 return 3;
323 case SETTINGS_INITIAL_WINDOW_SIZE:
324 return 4;
325 case SETTINGS_MAX_FRAME_SIZE:
326 return 5;
327 case SETTINGS_MAX_HEADER_LIST_SIZE:
328 return 6;
329 default:
330 LOG(DFATAL) << "Serializing unhandled setting id " << id;
331 return -1;
332 }
333 }
334 LOG(DFATAL) << "Unhandled SPDY version " << version;
335 return -1;
336 }
337
IsValidRstStreamStatus(SpdyMajorVersion version,int rst_stream_status_field)338 bool SpdyConstants::IsValidRstStreamStatus(SpdyMajorVersion version,
339 int rst_stream_status_field) {
340 switch (version) {
341 case SPDY2:
342 case SPDY3:
343 // PROTOCOL_ERROR is the valid first status code.
344 if (rst_stream_status_field <
345 SerializeRstStreamStatus(version, RST_STREAM_PROTOCOL_ERROR)) {
346 return false;
347 }
348
349 // FRAME_TOO_LARGE is the valid last status code.
350 if (rst_stream_status_field >
351 SerializeRstStreamStatus(version, RST_STREAM_FRAME_TOO_LARGE)) {
352 return false;
353 }
354
355 return true;
356 case SPDY4:
357 case SPDY5:
358 // NO_ERROR is the first valid status code.
359 if (rst_stream_status_field <
360 SerializeRstStreamStatus(version, RST_STREAM_PROTOCOL_ERROR)) {
361 return false;
362 }
363
364 // TODO(hkhalil): Omit COMPRESSION_ERROR and SETTINGS_TIMEOUT
365 /*
366 // This works because GOAWAY and RST_STREAM share a namespace.
367 if (rst_stream_status_field ==
368 SerializeGoAwayStatus(version, GOAWAY_COMPRESSION_ERROR) ||
369 rst_stream_status_field ==
370 SerializeGoAwayStatus(version, GOAWAY_SETTINGS_TIMEOUT)) {
371 return false;
372 }
373 */
374
375 // ENHANCE_YOUR_CALM is the last valid status code.
376 if (rst_stream_status_field >
377 SerializeRstStreamStatus(version, RST_STREAM_ENHANCE_YOUR_CALM)) {
378 return false;
379 }
380
381 return true;
382 }
383 LOG(DFATAL) << "Unhandled SPDY version " << version;
384 return false;
385 }
386
ParseRstStreamStatus(SpdyMajorVersion version,int rst_stream_status_field)387 SpdyRstStreamStatus SpdyConstants::ParseRstStreamStatus(
388 SpdyMajorVersion version,
389 int rst_stream_status_field) {
390 switch (version) {
391 case SPDY2:
392 case SPDY3:
393 switch (rst_stream_status_field) {
394 case 1:
395 return RST_STREAM_PROTOCOL_ERROR;
396 case 2:
397 return RST_STREAM_INVALID_STREAM;
398 case 3:
399 return RST_STREAM_REFUSED_STREAM;
400 case 4:
401 return RST_STREAM_UNSUPPORTED_VERSION;
402 case 5:
403 return RST_STREAM_CANCEL;
404 case 6:
405 return RST_STREAM_INTERNAL_ERROR;
406 case 7:
407 return RST_STREAM_FLOW_CONTROL_ERROR;
408 case 8:
409 return RST_STREAM_STREAM_IN_USE;
410 case 9:
411 return RST_STREAM_STREAM_ALREADY_CLOSED;
412 case 10:
413 return RST_STREAM_INVALID_CREDENTIALS;
414 case 11:
415 return RST_STREAM_FRAME_TOO_LARGE;
416 }
417 break;
418 case SPDY4:
419 case SPDY5:
420 switch (rst_stream_status_field) {
421 case 1:
422 return RST_STREAM_PROTOCOL_ERROR;
423 case 2:
424 return RST_STREAM_INTERNAL_ERROR;
425 case 3:
426 return RST_STREAM_FLOW_CONTROL_ERROR;
427 case 5:
428 return RST_STREAM_STREAM_CLOSED;
429 case 6:
430 return RST_STREAM_FRAME_SIZE_ERROR;
431 case 7:
432 return RST_STREAM_REFUSED_STREAM;
433 case 8:
434 return RST_STREAM_CANCEL;
435 case 10:
436 return RST_STREAM_CONNECT_ERROR;
437 case 11:
438 return RST_STREAM_ENHANCE_YOUR_CALM;
439 }
440 break;
441 }
442
443 LOG(DFATAL) << "Invalid RST_STREAM status " << rst_stream_status_field;
444 return RST_STREAM_PROTOCOL_ERROR;
445 }
446
SerializeRstStreamStatus(SpdyMajorVersion version,SpdyRstStreamStatus rst_stream_status)447 int SpdyConstants::SerializeRstStreamStatus(
448 SpdyMajorVersion version,
449 SpdyRstStreamStatus rst_stream_status) {
450 switch (version) {
451 case SPDY2:
452 case SPDY3:
453 switch (rst_stream_status) {
454 case RST_STREAM_PROTOCOL_ERROR:
455 return 1;
456 case RST_STREAM_INVALID_STREAM:
457 return 2;
458 case RST_STREAM_REFUSED_STREAM:
459 return 3;
460 case RST_STREAM_UNSUPPORTED_VERSION:
461 return 4;
462 case RST_STREAM_CANCEL:
463 return 5;
464 case RST_STREAM_INTERNAL_ERROR:
465 return 6;
466 case RST_STREAM_FLOW_CONTROL_ERROR:
467 return 7;
468 case RST_STREAM_STREAM_IN_USE:
469 return 8;
470 case RST_STREAM_STREAM_ALREADY_CLOSED:
471 return 9;
472 case RST_STREAM_INVALID_CREDENTIALS:
473 return 10;
474 case RST_STREAM_FRAME_TOO_LARGE:
475 return 11;
476 default:
477 LOG(DFATAL) << "Unhandled RST_STREAM status "
478 << rst_stream_status;
479 return -1;
480 }
481 case SPDY4:
482 case SPDY5:
483 switch (rst_stream_status) {
484 case RST_STREAM_PROTOCOL_ERROR:
485 return 1;
486 case RST_STREAM_INTERNAL_ERROR:
487 return 2;
488 case RST_STREAM_FLOW_CONTROL_ERROR:
489 return 3;
490 case RST_STREAM_STREAM_CLOSED:
491 return 5;
492 case RST_STREAM_FRAME_SIZE_ERROR:
493 return 6;
494 case RST_STREAM_REFUSED_STREAM:
495 return 7;
496 case RST_STREAM_CANCEL:
497 return 8;
498 case RST_STREAM_CONNECT_ERROR:
499 return 10;
500 case RST_STREAM_ENHANCE_YOUR_CALM:
501 return 11;
502 default:
503 LOG(DFATAL) << "Unhandled RST_STREAM status "
504 << rst_stream_status;
505 return -1;
506 }
507 }
508 LOG(DFATAL) << "Unhandled SPDY version " << version;
509 return -1;
510 }
511
IsValidGoAwayStatus(SpdyMajorVersion version,int goaway_status_field)512 bool SpdyConstants::IsValidGoAwayStatus(SpdyMajorVersion version,
513 int goaway_status_field) {
514 switch (version) {
515 case SPDY2:
516 case SPDY3:
517 // GOAWAY_OK is the first valid status.
518 if (goaway_status_field < SerializeGoAwayStatus(version, GOAWAY_OK)) {
519 return false;
520 }
521
522 // GOAWAY_INTERNAL_ERROR is the last valid status.
523 if (goaway_status_field > SerializeGoAwayStatus(version,
524 GOAWAY_INTERNAL_ERROR)) {
525 return false;
526 }
527
528 return true;
529 case SPDY4:
530 case SPDY5:
531 // GOAWAY_NO_ERROR is the first valid status.
532 if (goaway_status_field < SerializeGoAwayStatus(version,
533 GOAWAY_NO_ERROR)) {
534 return false;
535 }
536
537 // GOAWAY_INADEQUATE_SECURITY is the last valid status.
538 if (goaway_status_field >
539 SerializeGoAwayStatus(version, GOAWAY_INADEQUATE_SECURITY)) {
540 return false;
541 }
542
543 return true;
544 }
545 LOG(DFATAL) << "Unknown SpdyMajorVersion " << version;
546 return false;
547 }
548
ParseGoAwayStatus(SpdyMajorVersion version,int goaway_status_field)549 SpdyGoAwayStatus SpdyConstants::ParseGoAwayStatus(SpdyMajorVersion version,
550 int goaway_status_field) {
551 switch (version) {
552 case SPDY2:
553 case SPDY3:
554 switch (goaway_status_field) {
555 case 0:
556 return GOAWAY_OK;
557 case 1:
558 return GOAWAY_PROTOCOL_ERROR;
559 case 2:
560 return GOAWAY_INTERNAL_ERROR;
561 }
562 break;
563 case SPDY4:
564 case SPDY5:
565 switch (goaway_status_field) {
566 case 0:
567 return GOAWAY_NO_ERROR;
568 case 1:
569 return GOAWAY_PROTOCOL_ERROR;
570 case 2:
571 return GOAWAY_INTERNAL_ERROR;
572 case 3:
573 return GOAWAY_FLOW_CONTROL_ERROR;
574 case 4:
575 return GOAWAY_SETTINGS_TIMEOUT;
576 case 5:
577 return GOAWAY_STREAM_CLOSED;
578 case 6:
579 return GOAWAY_FRAME_SIZE_ERROR;
580 case 7:
581 return GOAWAY_REFUSED_STREAM;
582 case 8:
583 return GOAWAY_CANCEL;
584 case 9:
585 return GOAWAY_COMPRESSION_ERROR;
586 case 10:
587 return GOAWAY_CONNECT_ERROR;
588 case 11:
589 return GOAWAY_ENHANCE_YOUR_CALM;
590 case 12:
591 return GOAWAY_INADEQUATE_SECURITY;
592 }
593 break;
594 }
595
596 LOG(DFATAL) << "Unhandled GOAWAY status " << goaway_status_field;
597 return GOAWAY_PROTOCOL_ERROR;
598 }
599
ParseMajorVersion(int version_number)600 SpdyMajorVersion SpdyConstants::ParseMajorVersion(int version_number) {
601 switch (version_number) {
602 case 2:
603 return SPDY2;
604 case 3:
605 return SPDY3;
606 case 4:
607 return SPDY4;
608 case 5:
609 return SPDY5;
610 default:
611 LOG(DFATAL) << "Unsupported SPDY version number: " << version_number;
612 return SPDY3;
613 }
614 }
615
SerializeMajorVersion(SpdyMajorVersion version)616 int SpdyConstants::SerializeMajorVersion(SpdyMajorVersion version) {
617 switch (version) {
618 case SPDY2:
619 return 2;
620 case SPDY3:
621 return 3;
622 case SPDY4:
623 return 4;
624 case SPDY5:
625 return 5;
626 default:
627 LOG(DFATAL) << "Unsupported SPDY major version: " << version;
628 return -1;
629 }
630 }
631
GetVersionString(SpdyMajorVersion version)632 std::string SpdyConstants::GetVersionString(SpdyMajorVersion version) {
633 switch (version) {
634 case SPDY2:
635 return "spdy/2";
636 case SPDY3:
637 return "spdy/3";
638 case SPDY4:
639 return "spdy/4";
640 case SPDY5:
641 return "spdy/5";
642 default:
643 LOG(DFATAL) << "Unsupported SPDY major version: " << version;
644 return "spdy/3";
645 }
646 }
647
SerializeGoAwayStatus(SpdyMajorVersion version,SpdyGoAwayStatus status)648 int SpdyConstants::SerializeGoAwayStatus(SpdyMajorVersion version,
649 SpdyGoAwayStatus status) {
650 switch (version) {
651 case SPDY2:
652 case SPDY3:
653 // TODO(jgraettinger): Merge this back to server-side.
654 switch (status) {
655 case GOAWAY_NO_ERROR:
656 return 0;
657 case GOAWAY_PROTOCOL_ERROR:
658 case GOAWAY_INTERNAL_ERROR:
659 case GOAWAY_FLOW_CONTROL_ERROR:
660 case GOAWAY_SETTINGS_TIMEOUT:
661 case GOAWAY_STREAM_CLOSED:
662 case GOAWAY_FRAME_SIZE_ERROR:
663 case GOAWAY_REFUSED_STREAM:
664 case GOAWAY_CANCEL:
665 case GOAWAY_COMPRESSION_ERROR:
666 case GOAWAY_CONNECT_ERROR:
667 case GOAWAY_ENHANCE_YOUR_CALM:
668 case GOAWAY_INADEQUATE_SECURITY:
669 return 1; // PROTOCOL_ERROR.
670 default:
671 LOG(DFATAL) << "Serializing unhandled GOAWAY status " << status;
672 return -1;
673 }
674 case SPDY4:
675 case SPDY5:
676 switch (status) {
677 case GOAWAY_NO_ERROR:
678 return 0;
679 case GOAWAY_PROTOCOL_ERROR:
680 return 1;
681 case GOAWAY_INTERNAL_ERROR:
682 return 2;
683 case GOAWAY_FLOW_CONTROL_ERROR:
684 return 3;
685 case GOAWAY_SETTINGS_TIMEOUT:
686 return 4;
687 case GOAWAY_STREAM_CLOSED:
688 return 5;
689 case GOAWAY_FRAME_SIZE_ERROR:
690 return 6;
691 case GOAWAY_REFUSED_STREAM:
692 return 7;
693 case GOAWAY_CANCEL:
694 return 8;
695 case GOAWAY_COMPRESSION_ERROR:
696 return 9;
697 case GOAWAY_CONNECT_ERROR:
698 return 10;
699 case GOAWAY_ENHANCE_YOUR_CALM:
700 return 11;
701 case GOAWAY_INADEQUATE_SECURITY:
702 return 12;
703 default:
704 LOG(DFATAL) << "Serializing unhandled GOAWAY status " << status;
705 return -1;
706 }
707 }
708 LOG(DFATAL) << "Unknown SpdyMajorVersion " << version;
709 return -1;
710 }
711
GetDataFrameMinimumSize(SpdyMajorVersion version)712 size_t SpdyConstants::GetDataFrameMinimumSize(SpdyMajorVersion version) {
713 switch (version) {
714 case SPDY2:
715 case SPDY3:
716 return 8;
717 case SPDY4:
718 case SPDY5:
719 return 9;
720 }
721 LOG(DFATAL) << "Unhandled SPDY version.";
722 return 0;
723 }
724
GetControlFrameHeaderSize(SpdyMajorVersion version)725 size_t SpdyConstants::GetControlFrameHeaderSize(SpdyMajorVersion version) {
726 switch (version) {
727 case SPDY2:
728 case SPDY3:
729 return 8;
730 case SPDY4:
731 case SPDY5:
732 return 9;
733 }
734 LOG(DFATAL) << "Unhandled SPDY version.";
735 return 0;
736 }
737
GetPrefixLength(SpdyFrameType type,SpdyMajorVersion version)738 size_t SpdyConstants::GetPrefixLength(SpdyFrameType type,
739 SpdyMajorVersion version) {
740 if (type != DATA) {
741 return GetControlFrameHeaderSize(version);
742 } else {
743 return GetDataFrameMinimumSize(version);
744 }
745 }
746
GetFrameMaximumSize(SpdyMajorVersion version)747 size_t SpdyConstants::GetFrameMaximumSize(SpdyMajorVersion version) {
748 if (version < SPDY4) {
749 // 24-bit length field plus eight-byte frame header.
750 return ((1<<24) - 1) + 8;
751 } else {
752 // Max payload of 2^14 plus nine-byte frame header.
753 // TODO(mlavan): In HTTP/2 this is actually not a constant;
754 // payload size can be set using the MAX_FRAME_SIZE setting to
755 // anything between 1 << 14 and (1 << 24) - 1
756 return (1 << 14) + 9;
757 }
758 }
759
GetSizeOfSizeField(SpdyMajorVersion version)760 size_t SpdyConstants::GetSizeOfSizeField(SpdyMajorVersion version) {
761 return (version < SPDY3) ? sizeof(uint16) : sizeof(uint32);
762 }
763
GetSettingSize(SpdyMajorVersion version)764 size_t SpdyConstants::GetSettingSize(SpdyMajorVersion version) {
765 return version <= SPDY3 ? 8 : 6;
766 }
767
Visit(SpdyFrameVisitor * visitor) const768 void SpdyDataIR::Visit(SpdyFrameVisitor* visitor) const {
769 return visitor->VisitData(*this);
770 }
771
Visit(SpdyFrameVisitor * visitor) const772 void SpdySynStreamIR::Visit(SpdyFrameVisitor* visitor) const {
773 return visitor->VisitSynStream(*this);
774 }
775
Visit(SpdyFrameVisitor * visitor) const776 void SpdySynReplyIR::Visit(SpdyFrameVisitor* visitor) const {
777 return visitor->VisitSynReply(*this);
778 }
779
SpdyRstStreamIR(SpdyStreamId stream_id,SpdyRstStreamStatus status,base::StringPiece description)780 SpdyRstStreamIR::SpdyRstStreamIR(SpdyStreamId stream_id,
781 SpdyRstStreamStatus status,
782 base::StringPiece description)
783 : SpdyFrameWithStreamIdIR(stream_id),
784 description_(description) {
785 set_status(status);
786 }
787
~SpdyRstStreamIR()788 SpdyRstStreamIR::~SpdyRstStreamIR() {}
789
Visit(SpdyFrameVisitor * visitor) const790 void SpdyRstStreamIR::Visit(SpdyFrameVisitor* visitor) const {
791 return visitor->VisitRstStream(*this);
792 }
793
SpdySettingsIR()794 SpdySettingsIR::SpdySettingsIR()
795 : clear_settings_(false),
796 is_ack_(false) {}
797
~SpdySettingsIR()798 SpdySettingsIR::~SpdySettingsIR() {}
799
Visit(SpdyFrameVisitor * visitor) const800 void SpdySettingsIR::Visit(SpdyFrameVisitor* visitor) const {
801 return visitor->VisitSettings(*this);
802 }
803
Visit(SpdyFrameVisitor * visitor) const804 void SpdyPingIR::Visit(SpdyFrameVisitor* visitor) const {
805 return visitor->VisitPing(*this);
806 }
807
SpdyGoAwayIR(SpdyStreamId last_good_stream_id,SpdyGoAwayStatus status,const base::StringPiece & description)808 SpdyGoAwayIR::SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
809 SpdyGoAwayStatus status,
810 const base::StringPiece& description)
811 : description_(description) {
812 set_last_good_stream_id(last_good_stream_id);
813 set_status(status);
814 }
815
~SpdyGoAwayIR()816 SpdyGoAwayIR::~SpdyGoAwayIR() {}
817
description() const818 const base::StringPiece& SpdyGoAwayIR::description() const {
819 return description_;
820 }
821
Visit(SpdyFrameVisitor * visitor) const822 void SpdyGoAwayIR::Visit(SpdyFrameVisitor* visitor) const {
823 return visitor->VisitGoAway(*this);
824 }
825
Visit(SpdyFrameVisitor * visitor) const826 void SpdyHeadersIR::Visit(SpdyFrameVisitor* visitor) const {
827 return visitor->VisitHeaders(*this);
828 }
829
Visit(SpdyFrameVisitor * visitor) const830 void SpdyWindowUpdateIR::Visit(SpdyFrameVisitor* visitor) const {
831 return visitor->VisitWindowUpdate(*this);
832 }
833
Visit(SpdyFrameVisitor * visitor) const834 void SpdyBlockedIR::Visit(SpdyFrameVisitor* visitor) const {
835 return visitor->VisitBlocked(*this);
836 }
837
Visit(SpdyFrameVisitor * visitor) const838 void SpdyPushPromiseIR::Visit(SpdyFrameVisitor* visitor) const {
839 return visitor->VisitPushPromise(*this);
840 }
841
Visit(SpdyFrameVisitor * visitor) const842 void SpdyContinuationIR::Visit(SpdyFrameVisitor* visitor) const {
843 return visitor->VisitContinuation(*this);
844 }
845
SpdyAltSvcIR(SpdyStreamId stream_id)846 SpdyAltSvcIR::SpdyAltSvcIR(SpdyStreamId stream_id)
847 : SpdyFrameWithStreamIdIR(stream_id),
848 max_age_(0),
849 port_(0) {}
850
Visit(SpdyFrameVisitor * visitor) const851 void SpdyAltSvcIR::Visit(SpdyFrameVisitor* visitor) const {
852 return visitor->VisitAltSvc(*this);
853 }
854
SpdyPriorityIR(SpdyStreamId stream_id)855 SpdyPriorityIR::SpdyPriorityIR(SpdyStreamId stream_id)
856 : SpdyFrameWithStreamIdIR(stream_id) {
857 }
858
SpdyPriorityIR(SpdyStreamId stream_id,SpdyStreamId parent_stream_id,uint8 weight,bool exclusive)859 SpdyPriorityIR::SpdyPriorityIR(SpdyStreamId stream_id,
860 SpdyStreamId parent_stream_id,
861 uint8 weight,
862 bool exclusive)
863 : SpdyFrameWithStreamIdIR(stream_id),
864 parent_stream_id_(parent_stream_id),
865 weight_(weight),
866 exclusive_(exclusive) {
867 }
868
Visit(SpdyFrameVisitor * visitor) const869 void SpdyPriorityIR::Visit(SpdyFrameVisitor* visitor) const {
870 return visitor->VisitPriority(*this);
871 }
872
873 } // namespace net
874