forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspdy_protocol.cc
382 lines (335 loc) · 9.74 KB
/
spdy_protocol.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/spdy/spdy_protocol.h"
namespace net {
SpdyFrameWithNameValueBlockIR::SpdyFrameWithNameValueBlockIR(
SpdyStreamId stream_id) : SpdyFrameWithFinIR(stream_id) {}
SpdyFrameWithNameValueBlockIR::~SpdyFrameWithNameValueBlockIR() {}
SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id, const base::StringPiece& data)
: SpdyFrameWithFinIR(stream_id),
pad_low_(false),
pad_high_(false),
padding_payload_len_(0) {
SetDataDeep(data);
}
SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id)
: SpdyFrameWithFinIR(stream_id),
pad_low_(false),
pad_high_(false),
padding_payload_len_(0) {}
SpdyDataIR::~SpdyDataIR() {}
bool SpdyConstants::IsValidFrameType(SpdyMajorVersion version,
int frame_type_field) {
switch (version) {
case SPDY2:
case SPDY3:
// SYN_STREAM is the first valid frame.
if (frame_type_field < SerializeFrameType(version, SYN_STREAM)) {
return false;
}
// WINDOW_UPDATE is the last valid frame.
if (frame_type_field > SerializeFrameType(version, WINDOW_UPDATE)) {
return false;
}
// The valid range is non-contiguous.
if (frame_type_field == NOOP) {
return false;
}
return true;
case SPDY4:
// DATA is the first valid frame.
if (frame_type_field < SerializeFrameType(version, DATA)) {
return false;
}
// BLOCKED is the last valid frame.
if (frame_type_field > SerializeFrameType(version, BLOCKED)) {
return false;
}
return true;
}
LOG(DFATAL) << "Unhandled SPDY version " << version;
return false;
}
SpdyFrameType SpdyConstants::ParseFrameType(SpdyMajorVersion version,
int frame_type_field) {
switch (version) {
case SPDY2:
case SPDY3:
switch (frame_type_field) {
case 1:
return SYN_STREAM;
case 2:
return SYN_REPLY;
case 3:
return RST_STREAM;
case 4:
return SETTINGS;
case 6:
return PING;
case 7:
return GOAWAY;
case 8:
return HEADERS;
case 9:
return WINDOW_UPDATE;
}
break;
case SPDY4:
switch (frame_type_field) {
case 0:
return DATA;
case 1:
return HEADERS;
// TODO(hkhalil): Add PRIORITY.
case 3:
return RST_STREAM;
case 4:
return SETTINGS;
case 5:
return PUSH_PROMISE;
case 6:
return PING;
case 7:
return GOAWAY;
case 8:
return WINDOW_UPDATE;
case 9:
return CONTINUATION;
case 10:
return BLOCKED;
}
break;
}
LOG(DFATAL) << "Unhandled frame type " << frame_type_field;
return DATA;
}
int SpdyConstants::SerializeFrameType(SpdyMajorVersion version,
SpdyFrameType frame_type) {
switch (version) {
case SPDY2:
case SPDY3:
switch (frame_type) {
case SYN_STREAM:
return 1;
case SYN_REPLY:
return 2;
case RST_STREAM:
return 3;
case SETTINGS:
return 4;
case PING:
return 6;
case GOAWAY:
return 7;
case HEADERS:
return 8;
case WINDOW_UPDATE:
return 9;
default:
LOG(DFATAL) << "Serializing unhandled frame type " << frame_type;
return -1;
}
case SPDY4:
switch (frame_type) {
case DATA:
return 0;
case HEADERS:
return 1;
// TODO(hkhalil): Add PRIORITY.
case RST_STREAM:
return 3;
case SETTINGS:
return 4;
case PUSH_PROMISE:
return 5;
case PING:
return 6;
case GOAWAY:
return 7;
case WINDOW_UPDATE:
return 8;
case CONTINUATION:
return 9;
case BLOCKED:
return 10;
default:
LOG(DFATAL) << "Serializing unhandled frame type " << frame_type;
return -1;
}
}
LOG(DFATAL) << "Unhandled SPDY version " << version;
return -1;
}
bool SpdyConstants::IsValidSettingId(SpdyMajorVersion version,
int setting_id_field) {
switch (version) {
case SPDY2:
case SPDY3:
// UPLOAD_BANDWIDTH is the first valid setting id.
if (setting_id_field <
SerializeSettingId(version, SETTINGS_UPLOAD_BANDWIDTH)) {
return false;
}
// INITIAL_WINDOW_SIZE is the last valid setting id.
if (setting_id_field >
SerializeSettingId(version, SETTINGS_INITIAL_WINDOW_SIZE)) {
return false;
}
return true;
case SPDY4:
// HEADER_TABLE_SIZE is the first valid setting id.
if (setting_id_field <
SerializeSettingId(version, SETTINGS_HEADER_TABLE_SIZE)) {
return false;
}
// INITIAL_WINDOW_SIZE is the last valid setting id.
if (setting_id_field >
SerializeSettingId(version, SETTINGS_INITIAL_WINDOW_SIZE)) {
return false;
}
return true;
}
LOG(DFATAL) << "Unhandled SPDY version " << version;
return false;
}
SpdySettingsIds SpdyConstants::ParseSettingId(SpdyMajorVersion version,
int setting_id_field) {
switch (version) {
case SPDY2:
case SPDY3:
switch (setting_id_field) {
case 1:
return SETTINGS_UPLOAD_BANDWIDTH;
case 2:
return SETTINGS_DOWNLOAD_BANDWIDTH;
case 3:
return SETTINGS_ROUND_TRIP_TIME;
case 4:
return SETTINGS_MAX_CONCURRENT_STREAMS;
case 5:
return SETTINGS_CURRENT_CWND;
case 6:
return SETTINGS_DOWNLOAD_RETRANS_RATE;
case 7:
return SETTINGS_INITIAL_WINDOW_SIZE;
}
break;
case SPDY4:
switch (setting_id_field) {
case 1:
return SETTINGS_HEADER_TABLE_SIZE;
case 2:
return SETTINGS_ENABLE_PUSH;
case 3:
return SETTINGS_MAX_CONCURRENT_STREAMS;
case 4:
return SETTINGS_INITIAL_WINDOW_SIZE;
}
break;
}
LOG(DFATAL) << "Unhandled setting ID " << setting_id_field;
return SETTINGS_UPLOAD_BANDWIDTH;
}
int SpdyConstants::SerializeSettingId(SpdyMajorVersion version,
SpdySettingsIds id) {
switch (version) {
case SPDY2:
case SPDY3:
switch (id) {
case SETTINGS_UPLOAD_BANDWIDTH:
return 1;
case SETTINGS_DOWNLOAD_BANDWIDTH:
return 2;
case SETTINGS_ROUND_TRIP_TIME:
return 3;
case SETTINGS_MAX_CONCURRENT_STREAMS:
return 4;
case SETTINGS_CURRENT_CWND:
return 5;
case SETTINGS_DOWNLOAD_RETRANS_RATE:
return 6;
case SETTINGS_INITIAL_WINDOW_SIZE:
return 7;
default:
LOG(DFATAL) << "Serializing unhandled setting id " << id;
return -1;
}
case SPDY4:
switch (id) {
case SETTINGS_HEADER_TABLE_SIZE:
return 1;
case SETTINGS_ENABLE_PUSH:
return 2;
case SETTINGS_MAX_CONCURRENT_STREAMS:
return 3;
case SETTINGS_INITIAL_WINDOW_SIZE:
return 4;
default:
LOG(DFATAL) << "Serializing unhandled setting id " << id;
return -1;
}
}
LOG(DFATAL) << "Unhandled SPDY version " << version;
return -1;
}
void SpdyDataIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitData(*this);
}
void SpdySynStreamIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitSynStream(*this);
}
void SpdySynReplyIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitSynReply(*this);
}
SpdyRstStreamIR::SpdyRstStreamIR(SpdyStreamId stream_id,
SpdyRstStreamStatus status,
base::StringPiece description)
: SpdyFrameWithStreamIdIR(stream_id),
description_(description) {
set_status(status);
}
SpdyRstStreamIR::~SpdyRstStreamIR() {}
void SpdyRstStreamIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitRstStream(*this);
}
SpdySettingsIR::SpdySettingsIR()
: clear_settings_(false),
is_ack_(false) {}
SpdySettingsIR::~SpdySettingsIR() {}
void SpdySettingsIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitSettings(*this);
}
void SpdyPingIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitPing(*this);
}
SpdyGoAwayIR::SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
SpdyGoAwayStatus status,
const base::StringPiece& description)
: description_(description) {
set_last_good_stream_id(last_good_stream_id);
set_status(status);
}
SpdyGoAwayIR::~SpdyGoAwayIR() {}
const base::StringPiece& SpdyGoAwayIR::description() const {
return description_;
}
void SpdyGoAwayIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitGoAway(*this);
}
void SpdyHeadersIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitHeaders(*this);
}
void SpdyWindowUpdateIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitWindowUpdate(*this);
}
void SpdyBlockedIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitBlocked(*this);
}
void SpdyPushPromiseIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitPushPromise(*this);
}
void SpdyContinuationIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitContinuation(*this);
}
} // namespace net