• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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