OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // TODO(rtenhove) clean up frame buffer size calculations so that we aren't | 5 // TODO(rtenhove) clean up frame buffer size calculations so that we aren't |
6 // constantly adding and subtracting header sizes; this is ugly and error- | 6 // constantly adding and subtracting header sizes; this is ugly and error- |
7 // prone. | 7 // prone. |
8 | 8 |
9 #include "net/spdy/spdy_framer.h" | 9 #include "net/spdy/spdy_framer.h" |
10 | 10 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(int version, | 83 SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(int version, |
84 uint32 wire) { | 84 uint32 wire) { |
85 if (version < 3) { | 85 if (version < 3) { |
86 ConvertFlagsAndIdForSpdy2(&wire); | 86 ConvertFlagsAndIdForSpdy2(&wire); |
87 } | 87 } |
88 return SettingsFlagsAndId(ntohl(wire) >> 24, ntohl(wire) & 0x00ffffff); | 88 return SettingsFlagsAndId(ntohl(wire) >> 24, ntohl(wire) & 0x00ffffff); |
89 } | 89 } |
90 | 90 |
91 SettingsFlagsAndId::SettingsFlagsAndId(uint8 flags, uint32 id) | 91 SettingsFlagsAndId::SettingsFlagsAndId(uint8 flags, uint32 id) |
92 : flags_(flags), id_(id & 0x00ffffff) { | 92 : flags_(flags), id_(id & 0x00ffffff) { |
93 LOG_IF(DFATAL, id > (1u << 24)) << "SPDY setting ID too large."; | 93 LOG_IF(DFATAL, id > (1u << 24)) << "SPDY setting ID too large: " << id; |
94 } | 94 } |
95 | 95 |
96 uint32 SettingsFlagsAndId::GetWireFormat(int version) const { | 96 uint32 SettingsFlagsAndId::GetWireFormat(int version) const { |
97 uint32 wire = htonl(id_ & 0x00ffffff) | htonl(flags_ << 24); | 97 uint32 wire = htonl(id_ & 0x00ffffff) | htonl(flags_ << 24); |
98 if (version < 3) { | 98 if (version < 3) { |
99 ConvertFlagsAndIdForSpdy2(&wire); | 99 ConvertFlagsAndIdForSpdy2(&wire); |
100 } | 100 } |
101 return wire; | 101 return wire; |
102 } | 102 } |
103 | 103 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 previous_state_ = SPDY_RESET; | 154 previous_state_ = SPDY_RESET; |
155 error_code_ = SPDY_NO_ERROR; | 155 error_code_ = SPDY_NO_ERROR; |
156 remaining_data_length_ = 0; | 156 remaining_data_length_ = 0; |
157 remaining_control_header_ = 0; | 157 remaining_control_header_ = 0; |
158 current_frame_buffer_length_ = 0; | 158 current_frame_buffer_length_ = 0; |
159 current_frame_type_ = DATA; | 159 current_frame_type_ = DATA; |
160 current_frame_flags_ = 0; | 160 current_frame_flags_ = 0; |
161 current_frame_length_ = 0; | 161 current_frame_length_ = 0; |
162 current_frame_stream_id_ = kInvalidStream; | 162 current_frame_stream_id_ = kInvalidStream; |
163 settings_scratch_.Reset(); | 163 settings_scratch_.Reset(); |
| 164 remaining_padding_payload_length_ = 0; |
| 165 remaining_padding_length_fields_ = 0; |
164 } | 166 } |
165 | 167 |
166 size_t SpdyFramer::GetDataFrameMinimumSize() const { | 168 size_t SpdyFramer::GetDataFrameMinimumSize() const { |
167 // Size, in bytes, of the data frame header. Future versions of SPDY | 169 // Size, in bytes, of the data frame header. Future versions of SPDY |
168 // will likely vary this, so we allow for the flexibility of a function call | 170 // will likely vary this, so we allow for the flexibility of a function call |
169 // for this value as opposed to a constant. | 171 // for this value as opposed to a constant. |
170 return 8; | 172 return 8; |
171 } | 173 } |
172 | 174 |
173 // Size, in bytes, of the control frame header. | 175 // Size, in bytes, of the control frame header. |
174 size_t SpdyFramer::GetControlFrameHeaderSize() const { | 176 size_t SpdyFramer::GetControlFrameHeaderSize() const { |
175 switch (protocol_version()) { | 177 switch (protocol_version()) { |
176 case SPDY2: | 178 case SPDY2: |
177 case SPDY3: | 179 case SPDY3: |
178 case SPDY4: | 180 case SPDY4: |
179 return 8; | 181 return 8; |
180 } | 182 } |
181 LOG(DFATAL) << "Unhandled SPDY version."; | 183 LOG(DFATAL) << "Unhandled SPDY version."; |
182 return 0; | 184 return 0; |
183 } | 185 } |
184 | 186 |
185 size_t SpdyFramer::GetSynStreamMinimumSize() const { | 187 size_t SpdyFramer::GetSynStreamMinimumSize() const { |
186 // Size, in bytes, of a SYN_STREAM frame not including the variable-length | 188 // Size, in bytes, of a SYN_STREAM frame not including the variable-length |
187 // name-value block. | 189 // name-value block. |
188 if (spdy_version_ < 4) { | 190 if (protocol_version() <= SPDY3) { |
189 // Calculated as: | 191 // Calculated as: |
190 // control frame header + 2 * 4 (stream IDs) + 1 (priority) | 192 // control frame header + 2 * 4 (stream IDs) + 1 (priority) |
191 // + 1 (unused, was credential slot) | 193 // + 1 (unused, was credential slot) |
192 return GetControlFrameHeaderSize() + 10; | 194 return GetControlFrameHeaderSize() + 10; |
193 } else { | 195 } else { |
194 // Calculated as: | 196 // Calculated as: |
195 // frame prefix + 4 (priority) | 197 // frame prefix + 4 (priority) |
196 return GetControlFrameHeaderSize() + 4; | 198 return GetControlFrameHeaderSize() + 4; |
197 } | 199 } |
198 } | 200 } |
199 | 201 |
200 size_t SpdyFramer::GetSynReplyMinimumSize() const { | 202 size_t SpdyFramer::GetSynReplyMinimumSize() const { |
201 // Size, in bytes, of a SYN_REPLY frame not including the variable-length | 203 // Size, in bytes, of a SYN_REPLY frame not including the variable-length |
202 // name-value block. | 204 // name-value block. |
203 size_t size = GetControlFrameHeaderSize(); | 205 size_t size = GetControlFrameHeaderSize(); |
204 if (spdy_version_ < 4) { | 206 if (protocol_version() <= SPDY3) { |
205 // Calculated as: | 207 // Calculated as: |
206 // control frame header + 4 (stream IDs) | 208 // control frame header + 4 (stream IDs) |
207 size += 4; | 209 size += 4; |
208 } | 210 } |
209 | 211 |
210 // In SPDY 2, there were 2 unused bytes before payload. | 212 // In SPDY 2, there were 2 unused bytes before payload. |
211 if (protocol_version() < 3) { | 213 if (protocol_version() < SPDY3) { |
212 size += 2; | 214 size += 2; |
213 } | 215 } |
214 | 216 |
215 return size; | 217 return size; |
216 } | 218 } |
217 | 219 |
218 size_t SpdyFramer::GetRstStreamMinimumSize() const { | 220 size_t SpdyFramer::GetRstStreamMinimumSize() const { |
219 // Size, in bytes, of a RST_STREAM frame. | 221 // Size, in bytes, of a RST_STREAM frame. |
220 if (spdy_version_ < 4) { | 222 if (protocol_version() <= SPDY3) { |
221 // Calculated as: | 223 // Calculated as: |
222 // control frame header + 4 (stream id) + 4 (status code) | 224 // control frame header + 4 (stream id) + 4 (status code) |
223 return GetControlFrameHeaderSize() + 8; | 225 return GetControlFrameHeaderSize() + 8; |
224 } else { | 226 } else { |
225 // Calculated as: | 227 // Calculated as: |
226 // frame prefix + 4 (status code) | 228 // frame prefix + 4 (status code) |
227 return GetControlFrameHeaderSize() + 4; | 229 return GetControlFrameHeaderSize() + 4; |
228 } | 230 } |
229 } | 231 } |
230 | 232 |
231 size_t SpdyFramer::GetSettingsMinimumSize() const { | 233 size_t SpdyFramer::GetSettingsMinimumSize() const { |
232 // Size, in bytes, of a SETTINGS frame not including the IDs and values | 234 // Size, in bytes, of a SETTINGS frame not including the IDs and values |
233 // from the variable-length value block. Calculated as: | 235 // from the variable-length value block. Calculated as: |
234 // control frame header + 4 (number of ID/value pairs) | 236 // control frame header + 4 (number of ID/value pairs) |
235 if (spdy_version_ < 4) { | 237 if (protocol_version() <= SPDY3) { |
236 return GetControlFrameHeaderSize() + 4; | 238 return GetControlFrameHeaderSize() + 4; |
237 } else { | 239 } else { |
238 return GetControlFrameHeaderSize(); | 240 return GetControlFrameHeaderSize(); |
239 } | 241 } |
240 } | 242 } |
241 | 243 |
242 size_t SpdyFramer::GetPingSize() const { | 244 size_t SpdyFramer::GetPingSize() const { |
243 // Size, in bytes, of this PING frame. | 245 // Size, in bytes, of this PING frame. |
244 if (spdy_version_ < 4) { | 246 if (protocol_version() <= SPDY3) { |
245 // Calculated as: | 247 // Calculated as: |
246 // control frame header + 4 (id) | 248 // control frame header + 4 (id) |
247 return GetControlFrameHeaderSize() + 4; | 249 return GetControlFrameHeaderSize() + 4; |
248 } else { | 250 } else { |
249 // Calculated as: | 251 // Calculated as: |
250 // control frame header + 8 (id) | 252 // control frame header + 8 (id) |
251 return GetControlFrameHeaderSize() + 8; | 253 return GetControlFrameHeaderSize() + 8; |
252 } | 254 } |
253 } | 255 } |
254 | 256 |
(...skipping 10 matching lines...) Expand all Loading... |
265 size += 4; | 267 size += 4; |
266 } | 268 } |
267 | 269 |
268 return size; | 270 return size; |
269 } | 271 } |
270 | 272 |
271 size_t SpdyFramer::GetHeadersMinimumSize() const { | 273 size_t SpdyFramer::GetHeadersMinimumSize() const { |
272 // Size, in bytes, of a HEADERS frame not including the variable-length | 274 // Size, in bytes, of a HEADERS frame not including the variable-length |
273 // name-value block. | 275 // name-value block. |
274 size_t size = GetControlFrameHeaderSize(); | 276 size_t size = GetControlFrameHeaderSize(); |
275 if (spdy_version_ < 4) { | 277 if (protocol_version() <= SPDY3) { |
276 // Calculated as: | 278 // Calculated as: |
277 // control frame header + 4 (stream IDs) | 279 // control frame header + 4 (stream IDs) |
278 size += 4; | 280 size += 4; |
279 } | 281 } |
280 | 282 |
281 // In SPDY 2, there were 2 unused bytes before payload. | 283 // In SPDY 2, there were 2 unused bytes before payload. |
282 if (protocol_version() < 3) { | 284 if (protocol_version() <= SPDY2) { |
283 size += 2; | 285 size += 2; |
284 } | 286 } |
285 | 287 |
286 return size; | 288 return size; |
287 } | 289 } |
288 | 290 |
289 size_t SpdyFramer::GetWindowUpdateSize() const { | 291 size_t SpdyFramer::GetWindowUpdateSize() const { |
290 // Size, in bytes, of a WINDOW_UPDATE frame. | 292 // Size, in bytes, of a WINDOW_UPDATE frame. |
291 if (spdy_version_ < 4) { | 293 if (protocol_version() <= SPDY3) { |
292 // Calculated as: | 294 // Calculated as: |
293 // control frame header + 4 (stream id) + 4 (delta) | 295 // control frame header + 4 (stream id) + 4 (delta) |
294 return GetControlFrameHeaderSize() + 8; | 296 return GetControlFrameHeaderSize() + 8; |
295 } else { | 297 } else { |
296 // Calculated as: | 298 // Calculated as: |
297 // frame prefix + 4 (delta) | 299 // frame prefix + 4 (delta) |
298 return GetControlFrameHeaderSize() + 4; | 300 return GetControlFrameHeaderSize() + 4; |
299 } | 301 } |
300 } | 302 } |
301 | 303 |
(...skipping 15 matching lines...) Expand all Loading... |
317 // Size, in bytes, of a CONTINUATION frame not including the variable-length | 319 // Size, in bytes, of a CONTINUATION frame not including the variable-length |
318 // headers fragments. | 320 // headers fragments. |
319 return GetControlFrameHeaderSize(); | 321 return GetControlFrameHeaderSize(); |
320 } | 322 } |
321 | 323 |
322 size_t SpdyFramer::GetFrameMinimumSize() const { | 324 size_t SpdyFramer::GetFrameMinimumSize() const { |
323 return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize()); | 325 return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize()); |
324 } | 326 } |
325 | 327 |
326 size_t SpdyFramer::GetFrameMaximumSize() const { | 328 size_t SpdyFramer::GetFrameMaximumSize() const { |
327 if (protocol_version() < 4) { | 329 if (protocol_version() <= SPDY3) { |
328 // 24-bit length field plus eight-byte frame header. | 330 // 24-bit length field plus eight-byte frame header. |
329 return ((1<<24) - 1) + 8; | 331 return ((1<<24) - 1) + 8; |
330 } else { | 332 } else { |
331 // 14-bit length field. | 333 // 14-bit length field. |
332 return (1<<14) - 1; | 334 return (1<<14) - 1; |
333 } | 335 } |
334 } | 336 } |
335 | 337 |
336 size_t SpdyFramer::GetDataFrameMaximumPayload() const { | 338 size_t SpdyFramer::GetDataFrameMaximumPayload() const { |
337 return GetFrameMaximumSize() - GetDataFrameMinimumSize(); | 339 return GetFrameMaximumSize() - GetDataFrameMinimumSize(); |
338 } | 340 } |
339 | 341 |
340 const char* SpdyFramer::StateToString(int state) { | 342 const char* SpdyFramer::StateToString(int state) { |
341 switch (state) { | 343 switch (state) { |
342 case SPDY_ERROR: | 344 case SPDY_ERROR: |
343 return "ERROR"; | 345 return "ERROR"; |
344 case SPDY_AUTO_RESET: | 346 case SPDY_AUTO_RESET: |
345 return "AUTO_RESET"; | 347 return "AUTO_RESET"; |
346 case SPDY_RESET: | 348 case SPDY_RESET: |
347 return "RESET"; | 349 return "RESET"; |
348 case SPDY_READING_COMMON_HEADER: | 350 case SPDY_READING_COMMON_HEADER: |
349 return "READING_COMMON_HEADER"; | 351 return "READING_COMMON_HEADER"; |
350 case SPDY_CONTROL_FRAME_PAYLOAD: | 352 case SPDY_CONTROL_FRAME_PAYLOAD: |
351 return "CONTROL_FRAME_PAYLOAD"; | 353 return "CONTROL_FRAME_PAYLOAD"; |
| 354 case SPDY_READ_PADDING_LENGTH: |
| 355 return "SPDY_READ_PADDING_LENGTH"; |
| 356 case SPDY_CONSUME_PADDING: |
| 357 return "SPDY_CONSUME_PADDING"; |
352 case SPDY_IGNORE_REMAINING_PAYLOAD: | 358 case SPDY_IGNORE_REMAINING_PAYLOAD: |
353 return "IGNORE_REMAINING_PAYLOAD"; | 359 return "IGNORE_REMAINING_PAYLOAD"; |
354 case SPDY_FORWARD_STREAM_FRAME: | 360 case SPDY_FORWARD_STREAM_FRAME: |
355 return "FORWARD_STREAM_FRAME"; | 361 return "FORWARD_STREAM_FRAME"; |
356 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: | 362 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: |
357 return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK"; | 363 return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK"; |
358 case SPDY_CONTROL_FRAME_HEADER_BLOCK: | 364 case SPDY_CONTROL_FRAME_HEADER_BLOCK: |
359 return "SPDY_CONTROL_FRAME_HEADER_BLOCK"; | 365 return "SPDY_CONTROL_FRAME_HEADER_BLOCK"; |
360 case SPDY_GOAWAY_FRAME_PAYLOAD: | 366 case SPDY_GOAWAY_FRAME_PAYLOAD: |
361 return "SPDY_GOAWAY_FRAME_PAYLOAD"; | 367 return "SPDY_GOAWAY_FRAME_PAYLOAD"; |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 | 524 |
519 case SPDY_SETTINGS_FRAME_PAYLOAD: { | 525 case SPDY_SETTINGS_FRAME_PAYLOAD: { |
520 int bytes_read = ProcessSettingsFramePayload(data, len); | 526 int bytes_read = ProcessSettingsFramePayload(data, len); |
521 len -= bytes_read; | 527 len -= bytes_read; |
522 data += bytes_read; | 528 data += bytes_read; |
523 break; | 529 break; |
524 } | 530 } |
525 | 531 |
526 case SPDY_CONTROL_FRAME_HEADER_BLOCK: { | 532 case SPDY_CONTROL_FRAME_HEADER_BLOCK: { |
527 int bytes_read = ProcessControlFrameHeaderBlock( | 533 int bytes_read = ProcessControlFrameHeaderBlock( |
528 data, len, spdy_version_ >= 4 ? true : false); | 534 data, len, protocol_version() > SPDY3); |
529 len -= bytes_read; | 535 len -= bytes_read; |
530 data += bytes_read; | 536 data += bytes_read; |
531 break; | 537 break; |
532 } | 538 } |
533 | 539 |
534 case SPDY_RST_STREAM_FRAME_PAYLOAD: { | 540 case SPDY_RST_STREAM_FRAME_PAYLOAD: { |
535 size_t bytes_read = ProcessRstStreamFramePayload(data, len); | 541 size_t bytes_read = ProcessRstStreamFramePayload(data, len); |
536 len -= bytes_read; | 542 len -= bytes_read; |
537 data += bytes_read; | 543 data += bytes_read; |
538 break; | 544 break; |
539 } | 545 } |
540 | 546 |
541 case SPDY_GOAWAY_FRAME_PAYLOAD: { | 547 case SPDY_GOAWAY_FRAME_PAYLOAD: { |
542 size_t bytes_read = ProcessGoAwayFramePayload(data, len); | 548 size_t bytes_read = ProcessGoAwayFramePayload(data, len); |
543 len -= bytes_read; | 549 len -= bytes_read; |
544 data += bytes_read; | 550 data += bytes_read; |
545 break; | 551 break; |
546 } | 552 } |
547 | 553 |
548 case SPDY_CONTROL_FRAME_PAYLOAD: { | 554 case SPDY_CONTROL_FRAME_PAYLOAD: { |
549 size_t bytes_read = ProcessControlFramePayload(data, len); | 555 size_t bytes_read = ProcessControlFramePayload(data, len); |
550 len -= bytes_read; | 556 len -= bytes_read; |
551 data += bytes_read; | 557 data += bytes_read; |
552 break; | 558 break; |
553 } | 559 } |
554 | 560 |
| 561 case SPDY_READ_PADDING_LENGTH: { |
| 562 size_t bytes_read = ProcessFramePaddingLength(data, len); |
| 563 len -= bytes_read; |
| 564 data += bytes_read; |
| 565 break; |
| 566 } |
| 567 |
| 568 case SPDY_CONSUME_PADDING: { |
| 569 size_t bytes_read = ProcessFramePadding(data, len); |
| 570 len -= bytes_read; |
| 571 data += bytes_read; |
| 572 break; |
| 573 } |
| 574 |
555 case SPDY_IGNORE_REMAINING_PAYLOAD: | 575 case SPDY_IGNORE_REMAINING_PAYLOAD: |
556 // control frame has too-large payload | 576 // control frame has too-large payload |
557 // intentional fallthrough | 577 // intentional fallthrough |
558 case SPDY_FORWARD_STREAM_FRAME: { | 578 case SPDY_FORWARD_STREAM_FRAME: { |
559 size_t bytes_read = ProcessDataFramePayload(data, len); | 579 size_t bytes_read = ProcessDataFramePayload(data, len); |
560 len -= bytes_read; | 580 len -= bytes_read; |
561 data += bytes_read; | 581 data += bytes_read; |
562 break; | 582 break; |
563 } | 583 } |
564 default: | 584 default: |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 new SpdyFrameReader(current_frame_buffer_.get(), | 627 new SpdyFrameReader(current_frame_buffer_.get(), |
608 current_frame_buffer_length_)); | 628 current_frame_buffer_length_)); |
609 | 629 |
610 uint16 version = 0; | 630 uint16 version = 0; |
611 bool is_control_frame = false; | 631 bool is_control_frame = false; |
612 | 632 |
613 uint16 control_frame_type_field = DATA; | 633 uint16 control_frame_type_field = DATA; |
614 // ProcessControlFrameHeader() will set current_frame_type_ to the | 634 // ProcessControlFrameHeader() will set current_frame_type_ to the |
615 // correct value if this is a valid control frame. | 635 // correct value if this is a valid control frame. |
616 current_frame_type_ = DATA; | 636 current_frame_type_ = DATA; |
617 if (protocol_version() < 4) { | 637 if (protocol_version() <= SPDY3) { |
618 bool successful_read = reader->ReadUInt16(&version); | 638 bool successful_read = reader->ReadUInt16(&version); |
619 DCHECK(successful_read); | 639 DCHECK(successful_read); |
620 is_control_frame = (version & kControlFlagMask) != 0; | 640 is_control_frame = (version & kControlFlagMask) != 0; |
621 version &= ~kControlFlagMask; // Only valid for control frames. | 641 version &= ~kControlFlagMask; // Only valid for control frames. |
622 | 642 |
623 if (is_control_frame) { | 643 if (is_control_frame) { |
624 // We check control_frame_type_field's validity in | 644 // We check control_frame_type_field's validity in |
625 // ProcessControlFrameHeader(). | 645 // ProcessControlFrameHeader(). |
626 successful_read = reader->ReadUInt16(&control_frame_type_field); | 646 successful_read = reader->ReadUInt16(&control_frame_type_field); |
627 } else { | 647 } else { |
628 reader->Rewind(); | 648 reader->Rewind(); |
629 successful_read = reader->ReadUInt31(¤t_frame_stream_id_); | 649 successful_read = reader->ReadUInt31(¤t_frame_stream_id_); |
630 } | 650 } |
631 DCHECK(successful_read); | 651 DCHECK(successful_read); |
632 | 652 |
633 successful_read = reader->ReadUInt8(¤t_frame_flags_); | 653 successful_read = reader->ReadUInt8(¤t_frame_flags_); |
634 DCHECK(successful_read); | 654 DCHECK(successful_read); |
635 | 655 |
636 uint32 length_field = 0; | 656 uint32 length_field = 0; |
637 successful_read = reader->ReadUInt24(&length_field); | 657 successful_read = reader->ReadUInt24(&length_field); |
638 DCHECK(successful_read); | 658 DCHECK(successful_read); |
639 remaining_data_length_ = length_field; | 659 remaining_data_length_ = length_field; |
640 current_frame_length_ = remaining_data_length_ + reader->GetBytesConsumed(); | 660 current_frame_length_ = remaining_data_length_ + reader->GetBytesConsumed(); |
641 } else { | 661 } else { |
642 version = protocol_version(); | 662 version = protocol_version(); |
643 uint16 length_field = 0; | 663 uint16 length_field = 0; |
644 bool successful_read = reader->ReadUInt16(&length_field); | 664 bool successful_read = reader->ReadUInt16(&length_field); |
645 DCHECK(successful_read); | 665 DCHECK(successful_read); |
646 current_frame_length_ = length_field; | |
647 | 666 |
648 uint8 control_frame_type_field_uint8 = DATA; | 667 uint8 control_frame_type_field_uint8 = DATA; |
649 successful_read = reader->ReadUInt8(&control_frame_type_field_uint8); | 668 successful_read = reader->ReadUInt8(&control_frame_type_field_uint8); |
650 DCHECK(successful_read); | 669 DCHECK(successful_read); |
651 // We check control_frame_type_field's validity in | 670 // We check control_frame_type_field's validity in |
652 // ProcessControlFrameHeader(). | 671 // ProcessControlFrameHeader(). |
653 control_frame_type_field = control_frame_type_field_uint8; | 672 control_frame_type_field = control_frame_type_field_uint8; |
654 is_control_frame = (control_frame_type_field != DATA); | 673 is_control_frame = (control_frame_type_field != DATA); |
655 | 674 |
| 675 if (is_control_frame) { |
| 676 current_frame_length_ = length_field + GetControlFrameHeaderSize(); |
| 677 } else { |
| 678 current_frame_length_ = length_field + GetDataFrameMinimumSize(); |
| 679 } |
| 680 |
656 successful_read = reader->ReadUInt8(¤t_frame_flags_); | 681 successful_read = reader->ReadUInt8(¤t_frame_flags_); |
657 DCHECK(successful_read); | 682 DCHECK(successful_read); |
658 | 683 |
659 successful_read = reader->ReadUInt31(¤t_frame_stream_id_); | 684 successful_read = reader->ReadUInt31(¤t_frame_stream_id_); |
660 DCHECK(successful_read); | 685 DCHECK(successful_read); |
661 | 686 |
662 remaining_data_length_ = current_frame_length_ - reader->GetBytesConsumed(); | 687 remaining_data_length_ = current_frame_length_ - reader->GetBytesConsumed(); |
663 | 688 |
664 // Before we accept a DATA frame, we need to make sure we're not in the | 689 // Before we accept a DATA frame, we need to make sure we're not in the |
665 // middle of processing a header block. | 690 // middle of processing a header block. |
666 if (expect_continuation_ != 0 && control_frame_type_field != CONTINUATION) { | 691 const bool is_continuation_frame = (control_frame_type_field == |
667 DLOG(ERROR) << "The framer was expecting to receive a CONTINUATION " | 692 SpdyConstants::SerializeFrameType(protocol_version(), CONTINUATION)); |
668 << "frame, but instead received frame type " | 693 if ((expect_continuation_ != 0) != is_continuation_frame) { |
669 << current_frame_type_; | 694 if (expect_continuation_ != 0) { |
670 set_error(SPDY_UNEXPECTED_FRAME); | 695 DLOG(ERROR) << "The framer was expecting to receive a CONTINUATION " |
671 return original_len - len; | 696 << "frame, but instead received frame type " |
672 } else if (control_frame_type_field == CONTINUATION && | 697 << control_frame_type_field; |
673 expect_continuation_ == 0) { | 698 } else { |
674 DLOG(ERROR) << "The framer received an unexpected CONTINUATION frame."; | 699 DLOG(ERROR) << "The framer received an unexpected CONTINUATION frame."; |
| 700 } |
675 set_error(SPDY_UNEXPECTED_FRAME); | 701 set_error(SPDY_UNEXPECTED_FRAME); |
676 return original_len - len; | 702 return original_len - len; |
677 } | 703 } |
678 } | 704 } |
679 DCHECK_EQ(is_control_frame ? GetControlFrameHeaderSize() | 705 DCHECK_EQ(is_control_frame ? GetControlFrameHeaderSize() |
680 : GetDataFrameMinimumSize(), | 706 : GetDataFrameMinimumSize(), |
681 reader->GetBytesConsumed()); | 707 reader->GetBytesConsumed()); |
682 DCHECK_EQ(current_frame_length_, | 708 DCHECK_EQ(current_frame_length_, |
683 remaining_data_length_ + reader->GetBytesConsumed()); | 709 remaining_data_length_ + reader->GetBytesConsumed()); |
684 | 710 |
685 // This is just a sanity check for help debugging early frame errors. | 711 // This is just a sanity check for help debugging early frame errors. |
686 if (remaining_data_length_ > 1000000u) { | 712 if (remaining_data_length_ > 1000000u) { |
687 // The strncmp for 5 is safe because we only hit this point if we | 713 // The strncmp for 5 is safe because we only hit this point if we |
688 // have kMinCommonHeader (8) bytes | 714 // have kMinCommonHeader (8) bytes |
689 if (!syn_frame_processed_ && | 715 if (!syn_frame_processed_ && |
690 strncmp(current_frame_buffer_.get(), "HTTP/", 5) == 0) { | 716 strncmp(current_frame_buffer_.get(), "HTTP/", 5) == 0) { |
691 LOG(WARNING) << "Unexpected HTTP response to " << display_protocol_ | 717 LOG(WARNING) << "Unexpected HTTP response to " << display_protocol_ |
692 << " request"; | 718 << " request"; |
693 probable_http_response_ = true; | 719 probable_http_response_ = true; |
694 } else { | 720 } else { |
695 LOG(WARNING) << "Unexpectedly large frame. " << display_protocol_ | 721 LOG(WARNING) << "Unexpectedly large frame. " << display_protocol_ |
696 << " session is likely corrupt."; | 722 << " session is likely corrupt."; |
697 } | 723 } |
698 } | 724 } |
699 | 725 |
700 // if we're here, then we have the common header all received. | 726 // if we're here, then we have the common header all received. |
701 if (!is_control_frame) { | 727 if (!is_control_frame) { |
702 if (protocol_version() >= 4) { | 728 if (protocol_version() > SPDY3) { |
703 // Catch bogus tests sending oversized DATA frames. | 729 // Catch bogus tests sending oversized DATA frames. |
704 DCHECK_GE(GetFrameMaximumSize(), current_frame_length_) | 730 DCHECK_GE(GetFrameMaximumSize(), current_frame_length_) |
705 << "DATA frame too large for SPDY >= 4."; | 731 << "DATA frame too large for SPDY >= 4."; |
706 } | 732 } |
707 | 733 |
708 if (current_frame_flags_ & ~DATA_FLAG_FIN) { | 734 uint8 valid_data_flags = 0; |
| 735 if (protocol_version() > SPDY3) { |
| 736 valid_data_flags = DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT | |
| 737 DATA_FLAG_PAD_LOW | DATA_FLAG_PAD_HIGH; |
| 738 } else { |
| 739 valid_data_flags = DATA_FLAG_FIN; |
| 740 } |
| 741 |
| 742 if (current_frame_flags_ & ~valid_data_flags) { |
709 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); | 743 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); |
710 } else { | 744 } else { |
711 visitor_->OnDataFrameHeader(current_frame_stream_id_, | 745 visitor_->OnDataFrameHeader(current_frame_stream_id_, |
712 remaining_data_length_, | 746 remaining_data_length_, |
713 current_frame_flags_ & DATA_FLAG_FIN); | 747 current_frame_flags_ & DATA_FLAG_FIN); |
714 if (remaining_data_length_ > 0) { | 748 if (remaining_data_length_ > 0) { |
715 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME); | 749 CHANGE_STATE(SPDY_READ_PADDING_LENGTH); |
716 } else { | 750 } else { |
717 // Empty data frame. | 751 // Empty data frame. |
718 if (current_frame_flags_ & DATA_FLAG_FIN) { | 752 if (current_frame_flags_ & DATA_FLAG_FIN) { |
719 visitor_->OnStreamFrameData( | 753 visitor_->OnStreamFrameData( |
720 current_frame_stream_id_, NULL, 0, true); | 754 current_frame_stream_id_, NULL, 0, true); |
721 } | 755 } |
722 CHANGE_STATE(SPDY_AUTO_RESET); | 756 CHANGE_STATE(SPDY_AUTO_RESET); |
723 } | 757 } |
724 } | 758 } |
725 } else if (version != spdy_version_) { | 759 } else if (version != protocol_version()) { |
726 // We check version before we check validity: version can never be | 760 // We check version before we check validity: version can never be |
727 // 'invalid', it can only be unsupported. | 761 // 'invalid', it can only be unsupported. |
728 DVLOG(1) << "Unsupported SPDY version " << version | 762 DVLOG(1) << "Unsupported SPDY version " << version |
729 << " (expected " << spdy_version_ << ")"; | 763 << " (expected " << protocol_version() << ")"; |
730 set_error(SPDY_UNSUPPORTED_VERSION); | 764 set_error(SPDY_UNSUPPORTED_VERSION); |
731 } else { | 765 } else { |
732 ProcessControlFrameHeader(control_frame_type_field); | 766 ProcessControlFrameHeader(control_frame_type_field); |
733 } | 767 } |
734 | 768 |
735 return original_len - len; | 769 return original_len - len; |
736 } | 770 } |
737 | 771 |
738 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { | 772 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { |
739 DCHECK_EQ(SPDY_NO_ERROR, error_code_); | 773 DCHECK_EQ(SPDY_NO_ERROR, error_code_); |
740 DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_); | 774 DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_); |
741 | 775 |
742 if (control_frame_type_field < FIRST_CONTROL_TYPE || | 776 // Early detection of deprecated frames that we ignore. |
743 control_frame_type_field > LAST_CONTROL_TYPE) { | 777 if (protocol_version() <= SPDY3) { |
| 778 if (control_frame_type_field == NOOP) { |
| 779 current_frame_type_ = NOOP; |
| 780 DVLOG(1) << "NOOP control frame found. Ignoring."; |
| 781 CHANGE_STATE(SPDY_AUTO_RESET); |
| 782 return; |
| 783 } |
| 784 |
| 785 if (control_frame_type_field == CREDENTIAL) { |
| 786 current_frame_type_ = CREDENTIAL; |
| 787 DCHECK_EQ(SPDY3, protocol_version()); |
| 788 DVLOG(1) << "CREDENTIAL control frame found. Ignoring."; |
| 789 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); |
| 790 return; |
| 791 } |
| 792 } |
| 793 |
| 794 if (!SpdyConstants::IsValidFrameType(protocol_version(), |
| 795 control_frame_type_field)) { |
| 796 DLOG(WARNING) << "Invalid control frame type " << control_frame_type_field |
| 797 << " (protocol version: " << protocol_version() << ")"; |
744 set_error(SPDY_INVALID_CONTROL_FRAME); | 798 set_error(SPDY_INVALID_CONTROL_FRAME); |
745 return; | 799 return; |
746 } | 800 } |
747 | 801 |
748 current_frame_type_ = static_cast<SpdyFrameType>(control_frame_type_field); | 802 current_frame_type_ = SpdyConstants::ParseFrameType(protocol_version(), |
749 | 803 control_frame_type_field); |
750 if (current_frame_type_ == NOOP) { | |
751 DVLOG(1) << "NOOP control frame found. Ignoring."; | |
752 CHANGE_STATE(SPDY_AUTO_RESET); | |
753 return; | |
754 } | |
755 | |
756 if (current_frame_type_ == CREDENTIAL) { | |
757 DCHECK_EQ(3, protocol_version()); | |
758 DVLOG(1) << "CREDENTIAL control frame found. Ignoring."; | |
759 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); | |
760 return; | |
761 } | |
762 | 804 |
763 // Do some sanity checking on the control frame sizes and flags. | 805 // Do some sanity checking on the control frame sizes and flags. |
764 switch (current_frame_type_) { | 806 switch (current_frame_type_) { |
765 case SYN_STREAM: | 807 case SYN_STREAM: |
766 DCHECK_GT(4, spdy_version_); | |
767 if (current_frame_length_ < GetSynStreamMinimumSize()) { | 808 if (current_frame_length_ < GetSynStreamMinimumSize()) { |
768 set_error(SPDY_INVALID_CONTROL_FRAME); | 809 set_error(SPDY_INVALID_CONTROL_FRAME); |
769 } else if (current_frame_flags_ & | 810 } else if (current_frame_flags_ & |
770 ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) { | 811 ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) { |
771 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 812 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
772 } | 813 } |
773 break; | 814 break; |
774 case SYN_REPLY: | 815 case SYN_REPLY: |
775 if (current_frame_length_ < GetSynReplyMinimumSize()) { | 816 if (current_frame_length_ < GetSynReplyMinimumSize()) { |
776 set_error(SPDY_INVALID_CONTROL_FRAME); | 817 set_error(SPDY_INVALID_CONTROL_FRAME); |
777 } else if (current_frame_flags_ & ~CONTROL_FLAG_FIN) { | 818 } else if (current_frame_flags_ & ~CONTROL_FLAG_FIN) { |
778 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 819 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
779 } | 820 } |
780 break; | 821 break; |
781 case RST_STREAM: | 822 case RST_STREAM: |
782 // For SPDY versions < 4, the header has a fixed length. | 823 // For SPDY versions < 4, the header has a fixed length. |
783 // For SPDY version 4 and up, the RST_STREAM frame may include optional | 824 // For SPDY version 4 and up, the RST_STREAM frame may include optional |
784 // opaque data, so we only have a lower limit on the frame size. | 825 // opaque data, so we only have a lower limit on the frame size. |
785 if ((current_frame_length_ != GetRstStreamMinimumSize() && | 826 if ((current_frame_length_ != GetRstStreamMinimumSize() && |
786 protocol_version() < 4) || | 827 protocol_version() <= SPDY3) || |
787 (current_frame_length_ < GetRstStreamMinimumSize() && | 828 (current_frame_length_ < GetRstStreamMinimumSize() && |
788 protocol_version() >= 4)) { | 829 protocol_version() > SPDY3)) { |
789 set_error(SPDY_INVALID_CONTROL_FRAME); | 830 set_error(SPDY_INVALID_CONTROL_FRAME); |
790 } else if (current_frame_flags_ != 0) { | 831 } else if (current_frame_flags_ != 0) { |
791 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 832 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
792 } | 833 } |
793 break; | 834 break; |
794 case SETTINGS: | 835 case SETTINGS: |
795 { | 836 { |
796 // Make sure that we have an integral number of 8-byte key/value pairs, | 837 // Make sure that we have an integral number of 8-byte key/value pairs, |
797 // plus a 4-byte length field in SPDY3 and below. | 838 // plus a 4-byte length field in SPDY3 and below. |
798 size_t values_prefix_size = (protocol_version() < 4 ? 4 : 0); | 839 size_t values_prefix_size = (protocol_version() <= SPDY3 ? 4 : 0); |
799 // Size of each key/value pair in bytes. | 840 // Size of each key/value pair in bytes. |
800 size_t setting_size = (protocol_version() < 4 ? 8 : 5); | 841 size_t setting_size = (protocol_version() <= SPDY3 ? 8 : 5); |
801 if (current_frame_length_ < GetSettingsMinimumSize() || | 842 if (current_frame_length_ < GetSettingsMinimumSize() || |
802 (current_frame_length_ - GetControlFrameHeaderSize()) | 843 (current_frame_length_ - GetControlFrameHeaderSize()) |
803 % setting_size != values_prefix_size) { | 844 % setting_size != values_prefix_size) { |
804 DLOG(WARNING) << "Invalid length for SETTINGS frame: " | 845 DLOG(WARNING) << "Invalid length for SETTINGS frame: " |
805 << current_frame_length_; | 846 << current_frame_length_; |
806 set_error(SPDY_INVALID_CONTROL_FRAME); | 847 set_error(SPDY_INVALID_CONTROL_FRAME); |
807 } else if (protocol_version() < 4 && | 848 } else if (protocol_version() <= SPDY3 && |
808 current_frame_flags_ & | 849 current_frame_flags_ & |
809 ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) { | 850 ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) { |
810 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 851 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
811 } else if (protocol_version() >= 4 && | 852 } else if (protocol_version() > SPDY3 && |
812 current_frame_flags_ & ~SETTINGS_FLAG_ACK) { | 853 current_frame_flags_ & ~SETTINGS_FLAG_ACK) { |
813 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 854 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
814 } else if (protocol_version() >= 4 && | 855 } else if (protocol_version() > SPDY3 && |
815 current_frame_flags_ & SETTINGS_FLAG_ACK && | 856 current_frame_flags_ & SETTINGS_FLAG_ACK && |
816 current_frame_length_ > GetSettingsMinimumSize()) { | 857 current_frame_length_ > GetSettingsMinimumSize()) { |
817 set_error(SPDY_INVALID_CONTROL_FRAME); | 858 set_error(SPDY_INVALID_CONTROL_FRAME); |
818 } | 859 } |
819 break; | 860 break; |
820 } | 861 } |
821 case PING: | 862 case PING: |
822 if (current_frame_length_ != GetPingSize()) { | 863 if (current_frame_length_ != GetPingSize()) { |
823 set_error(SPDY_INVALID_CONTROL_FRAME); | 864 set_error(SPDY_INVALID_CONTROL_FRAME); |
824 } else if ((protocol_version() < 4 && current_frame_flags_ != 0) || | 865 } else if ((protocol_version() <= SPDY3 && current_frame_flags_ != 0) || |
825 (current_frame_flags_ & ~PING_FLAG_ACK)) { | 866 (current_frame_flags_ & ~PING_FLAG_ACK)) { |
826 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 867 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
827 } | 868 } |
828 break; | 869 break; |
829 case GOAWAY: | 870 case GOAWAY: |
830 { | 871 { |
831 // For SPDY version < 4, there are only mandatory fields and the header | 872 // For SPDY version < 4, there are only mandatory fields and the header |
832 // has a fixed length. For SPDY version >= 4, optional opaque data may | 873 // has a fixed length. For SPDY version >= 4, optional opaque data may |
833 // be appended to the GOAWAY frame, thus there is only a minimal length | 874 // be appended to the GOAWAY frame, thus there is only a minimal length |
834 // restriction. | 875 // restriction. |
835 if ((current_frame_length_ != GetGoAwayMinimumSize() && | 876 if ((current_frame_length_ != GetGoAwayMinimumSize() && |
836 protocol_version() < 4) || | 877 protocol_version() <= SPDY3) || |
837 (current_frame_length_ < GetGoAwayMinimumSize() && | 878 (current_frame_length_ < GetGoAwayMinimumSize() && |
838 protocol_version() >= 4)) { | 879 protocol_version() > SPDY3)) { |
839 set_error(SPDY_INVALID_CONTROL_FRAME); | 880 set_error(SPDY_INVALID_CONTROL_FRAME); |
840 } else if (current_frame_flags_ != 0) { | 881 } else if (current_frame_flags_ != 0) { |
841 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 882 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
842 } | 883 } |
843 break; | 884 break; |
844 } | 885 } |
845 case HEADERS: | 886 case HEADERS: |
846 { | 887 { |
847 size_t min_size = GetHeadersMinimumSize(); | 888 size_t min_size = GetHeadersMinimumSize(); |
848 if (spdy_version_ > 3 && | 889 if (protocol_version() > SPDY3 && |
849 (current_frame_flags_ & HEADERS_FLAG_PRIORITY)) { | 890 (current_frame_flags_ & HEADERS_FLAG_PRIORITY)) { |
850 min_size += 4; | 891 min_size += 4; |
851 } | 892 } |
852 if (current_frame_length_ < min_size) { | 893 if (current_frame_length_ < min_size) { |
853 set_error(SPDY_INVALID_CONTROL_FRAME); | 894 set_error(SPDY_INVALID_CONTROL_FRAME); |
854 } else if (spdy_version_ < 4 && | 895 } else if (protocol_version() <= SPDY3 && |
855 current_frame_flags_ & ~CONTROL_FLAG_FIN) { | 896 current_frame_flags_ & ~CONTROL_FLAG_FIN) { |
856 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 897 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
857 } else if (spdy_version_ >= 4 && current_frame_flags_ & | 898 } else if (protocol_version() > SPDY3 && current_frame_flags_ & |
858 ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | | 899 ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | |
859 HEADERS_FLAG_END_HEADERS)) { | 900 HEADERS_FLAG_END_HEADERS)) { |
860 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 901 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
861 } | 902 } |
862 } | 903 } |
863 break; | 904 break; |
864 case WINDOW_UPDATE: | 905 case WINDOW_UPDATE: |
865 if (current_frame_length_ != GetWindowUpdateSize()) { | 906 if (current_frame_length_ != GetWindowUpdateSize()) { |
866 set_error(SPDY_INVALID_CONTROL_FRAME); | 907 set_error(SPDY_INVALID_CONTROL_FRAME); |
867 } else if (current_frame_flags_ != 0) { | 908 } else if (current_frame_flags_ != 0) { |
868 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 909 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
869 } | 910 } |
870 break; | 911 break; |
871 case BLOCKED: | 912 case BLOCKED: |
872 if (current_frame_length_ != GetBlockedSize()) { | 913 if (current_frame_length_ != GetBlockedSize()) { |
873 set_error(SPDY_INVALID_CONTROL_FRAME); | 914 set_error(SPDY_INVALID_CONTROL_FRAME); |
874 } else if (current_frame_flags_ != 0) { | 915 } else if (current_frame_flags_ != 0) { |
875 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 916 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
876 } | 917 } |
877 break; | 918 break; |
878 case PUSH_PROMISE: | 919 case PUSH_PROMISE: |
879 if (current_frame_length_ < GetPushPromiseMinimumSize()) { | 920 if (current_frame_length_ < GetPushPromiseMinimumSize()) { |
880 set_error(SPDY_INVALID_CONTROL_FRAME); | 921 set_error(SPDY_INVALID_CONTROL_FRAME); |
881 } else if (spdy_version_ < 4 && current_frame_flags_ != 0) { | 922 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) { |
882 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 923 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
883 } else if (spdy_version_ >= 4 && current_frame_flags_ & | 924 } else if (protocol_version() > SPDY3 && current_frame_flags_ & |
884 ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE) { | 925 ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE) { |
885 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 926 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
886 } | 927 } |
887 break; | 928 break; |
888 case CONTINUATION: | 929 case CONTINUATION: |
889 if (current_frame_length_ < GetContinuationMinimumSize() || | 930 if (current_frame_length_ < GetContinuationMinimumSize()) { |
890 protocol_version() < 4) { | |
891 set_error(SPDY_INVALID_CONTROL_FRAME); | 931 set_error(SPDY_INVALID_CONTROL_FRAME); |
892 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) { | 932 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) { |
893 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 933 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
894 } | 934 } |
895 break; | 935 break; |
896 default: | 936 default: |
897 LOG(WARNING) << "Valid " << display_protocol_ | 937 LOG(WARNING) << "Valid " << display_protocol_ |
898 << " control frame with unhandled type: " | 938 << " control frame with unhandled type: " |
899 << current_frame_type_; | 939 << current_frame_type_; |
900 // This branch should be unreachable because of the frame type bounds | 940 // This branch should be unreachable because of the frame type bounds |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
936 break; | 976 break; |
937 case SYN_REPLY: | 977 case SYN_REPLY: |
938 syn_frame_processed_ = true; | 978 syn_frame_processed_ = true; |
939 frame_size_without_variable_data = GetSynReplyMinimumSize(); | 979 frame_size_without_variable_data = GetSynReplyMinimumSize(); |
940 break; | 980 break; |
941 case SETTINGS: | 981 case SETTINGS: |
942 frame_size_without_variable_data = GetSettingsMinimumSize(); | 982 frame_size_without_variable_data = GetSettingsMinimumSize(); |
943 break; | 983 break; |
944 case HEADERS: | 984 case HEADERS: |
945 frame_size_without_variable_data = GetHeadersMinimumSize(); | 985 frame_size_without_variable_data = GetHeadersMinimumSize(); |
946 if (spdy_version_ > 3 && current_frame_flags_ & HEADERS_FLAG_PRIORITY) { | 986 if (protocol_version() > SPDY3 && |
| 987 current_frame_flags_ & HEADERS_FLAG_PRIORITY) { |
947 frame_size_without_variable_data += 4; // priority | 988 frame_size_without_variable_data += 4; // priority |
948 } | 989 } |
949 break; | 990 break; |
950 case PUSH_PROMISE: | 991 case PUSH_PROMISE: |
951 frame_size_without_variable_data = GetPushPromiseMinimumSize(); | 992 frame_size_without_variable_data = GetPushPromiseMinimumSize(); |
952 break; | 993 break; |
953 case CONTINUATION: | 994 case CONTINUATION: |
954 frame_size_without_variable_data = GetContinuationMinimumSize(); | 995 frame_size_without_variable_data = GetContinuationMinimumSize(); |
955 break; | 996 break; |
956 default: | 997 default: |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1221 } | 1262 } |
1222 | 1263 |
1223 if (remaining_control_header_ == 0) { | 1264 if (remaining_control_header_ == 0) { |
1224 SpdyFrameReader reader(current_frame_buffer_.get(), | 1265 SpdyFrameReader reader(current_frame_buffer_.get(), |
1225 current_frame_buffer_length_); | 1266 current_frame_buffer_length_); |
1226 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header. | 1267 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header. |
1227 | 1268 |
1228 switch (current_frame_type_) { | 1269 switch (current_frame_type_) { |
1229 case SYN_STREAM: | 1270 case SYN_STREAM: |
1230 { | 1271 { |
1231 DCHECK_GT(4, spdy_version_); | 1272 DCHECK_GE(SPDY3, protocol_version()); |
1232 bool successful_read = true; | 1273 bool successful_read = true; |
1233 if (spdy_version_ < 4) { | 1274 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); |
1234 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); | 1275 DCHECK(successful_read); |
1235 DCHECK(successful_read); | |
1236 } | |
1237 if (current_frame_stream_id_ == 0) { | 1276 if (current_frame_stream_id_ == 0) { |
1238 set_error(SPDY_INVALID_CONTROL_FRAME); | 1277 set_error(SPDY_INVALID_CONTROL_FRAME); |
1239 break; | 1278 break; |
1240 } | 1279 } |
1241 | 1280 |
1242 SpdyStreamId associated_to_stream_id = kInvalidStream; | 1281 SpdyStreamId associated_to_stream_id = kInvalidStream; |
1243 successful_read = reader.ReadUInt31(&associated_to_stream_id); | 1282 successful_read = reader.ReadUInt31(&associated_to_stream_id); |
1244 DCHECK(successful_read); | 1283 DCHECK(successful_read); |
1245 | 1284 |
1246 SpdyPriority priority = 0; | 1285 SpdyPriority priority = 0; |
1247 successful_read = reader.ReadUInt8(&priority); | 1286 successful_read = reader.ReadUInt8(&priority); |
1248 DCHECK(successful_read); | 1287 DCHECK(successful_read); |
1249 if (protocol_version() < 3) { | 1288 if (protocol_version() <= SPDY2) { |
1250 priority = priority >> 6; | 1289 priority = priority >> 6; |
1251 } else { | 1290 } else { |
1252 priority = priority >> 5; | 1291 priority = priority >> 5; |
1253 } | 1292 } |
1254 | 1293 |
1255 // Seek past unused byte; used to be credential slot in SPDY 3. | 1294 // Seek past unused byte; used to be credential slot in SPDY 3. |
1256 reader.Seek(1); | 1295 reader.Seek(1); |
1257 | 1296 |
1258 DCHECK(reader.IsDoneReading()); | 1297 DCHECK(reader.IsDoneReading()); |
1259 if (debug_visitor_) { | 1298 if (debug_visitor_) { |
1260 debug_visitor_->OnReceiveCompressedFrame( | 1299 debug_visitor_->OnReceiveCompressedFrame( |
1261 current_frame_stream_id_, | 1300 current_frame_stream_id_, |
1262 current_frame_type_, | 1301 current_frame_type_, |
1263 current_frame_length_); | 1302 current_frame_length_); |
1264 } | 1303 } |
1265 visitor_->OnSynStream( | 1304 visitor_->OnSynStream( |
1266 current_frame_stream_id_, | 1305 current_frame_stream_id_, |
1267 associated_to_stream_id, | 1306 associated_to_stream_id, |
1268 priority, | 1307 priority, |
1269 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, | 1308 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, |
1270 (current_frame_flags_ & CONTROL_FLAG_UNIDIRECTIONAL) != 0); | 1309 (current_frame_flags_ & CONTROL_FLAG_UNIDIRECTIONAL) != 0); |
1271 } | 1310 } |
1272 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); | 1311 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); |
1273 break; | 1312 break; |
1274 case SETTINGS: | 1313 case SETTINGS: |
1275 if (spdy_version_ >= 4 && current_frame_flags_ & SETTINGS_FLAG_ACK) { | 1314 if (protocol_version() > SPDY3 && |
| 1315 current_frame_flags_ & SETTINGS_FLAG_ACK) { |
1276 visitor_->OnSettingsAck(); | 1316 visitor_->OnSettingsAck(); |
1277 CHANGE_STATE(SPDY_AUTO_RESET); | 1317 CHANGE_STATE(SPDY_AUTO_RESET); |
1278 } else { | 1318 } else { |
1279 visitor_->OnSettings(current_frame_flags_ & | 1319 visitor_->OnSettings(current_frame_flags_ & |
1280 SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS); | 1320 SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS); |
1281 CHANGE_STATE(SPDY_SETTINGS_FRAME_PAYLOAD); | 1321 CHANGE_STATE(SPDY_SETTINGS_FRAME_PAYLOAD); |
1282 } | 1322 } |
1283 break; | 1323 break; |
1284 case SYN_REPLY: | 1324 case SYN_REPLY: |
1285 case HEADERS: | 1325 case HEADERS: |
1286 // SYN_REPLY and HEADERS are the same, save for the visitor call. | 1326 // SYN_REPLY and HEADERS are the same, save for the visitor call. |
1287 { | 1327 { |
1288 if (spdy_version_ > 3) { | 1328 if (protocol_version() > SPDY3) { |
1289 DCHECK_EQ(HEADERS, current_frame_type_); | 1329 DCHECK_EQ(HEADERS, current_frame_type_); |
1290 } | 1330 } |
1291 bool successful_read = true; | 1331 bool successful_read = true; |
1292 if (spdy_version_ < 4) { | 1332 if (protocol_version() <= SPDY3) { |
1293 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); | 1333 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); |
1294 DCHECK(successful_read); | 1334 DCHECK(successful_read); |
1295 } | 1335 } |
1296 if (current_frame_stream_id_ == 0) { | 1336 if (current_frame_stream_id_ == 0) { |
1297 set_error(SPDY_INVALID_CONTROL_FRAME); | 1337 set_error(SPDY_INVALID_CONTROL_FRAME); |
1298 break; | 1338 break; |
1299 } | 1339 } |
1300 if (protocol_version() < 3) { | 1340 if (protocol_version() <= SPDY2) { |
1301 // SPDY 2 had two unused bytes here. Seek past them. | 1341 // SPDY 2 had two unused bytes here. Seek past them. |
1302 reader.Seek(2); | 1342 reader.Seek(2); |
1303 } | 1343 } |
1304 if (spdy_version_ > 3 && | 1344 if (protocol_version() > SPDY3 && |
1305 !(current_frame_flags_ & HEADERS_FLAG_END_HEADERS) && | 1345 !(current_frame_flags_ & HEADERS_FLAG_END_HEADERS) && |
1306 current_frame_type_ == HEADERS) { | 1346 current_frame_type_ == HEADERS) { |
1307 expect_continuation_ = current_frame_stream_id_; | 1347 expect_continuation_ = current_frame_stream_id_; |
1308 end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN; | 1348 end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN; |
1309 } | 1349 } |
1310 const bool has_priority = | 1350 const bool has_priority = |
1311 (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0; | 1351 (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0; |
1312 uint32 priority = 0; | 1352 uint32 priority = 0; |
1313 if (protocol_version() > 3 && has_priority) { | 1353 if (protocol_version() > SPDY3 && has_priority) { |
1314 successful_read = reader.ReadUInt31(&priority); | 1354 successful_read = reader.ReadUInt31(&priority); |
1315 DCHECK(successful_read); | 1355 DCHECK(successful_read); |
1316 } | 1356 } |
1317 DCHECK(reader.IsDoneReading()); | 1357 DCHECK(reader.IsDoneReading()); |
1318 if (debug_visitor_) { | 1358 if (debug_visitor_) { |
1319 // SPDY 4 reports HEADERS with PRIORITY as SYN_STREAM. | 1359 // SPDY 4 reports HEADERS with PRIORITY as SYN_STREAM. |
1320 SpdyFrameType reported_type = current_frame_type_; | 1360 SpdyFrameType reported_type = current_frame_type_; |
1321 if (protocol_version() > 3 && has_priority) { | 1361 if (protocol_version() > SPDY3 && has_priority) { |
1322 reported_type = SYN_STREAM; | 1362 reported_type = SYN_STREAM; |
1323 } | 1363 } |
1324 debug_visitor_->OnReceiveCompressedFrame( | 1364 debug_visitor_->OnReceiveCompressedFrame( |
1325 current_frame_stream_id_, | 1365 current_frame_stream_id_, |
1326 reported_type, | 1366 reported_type, |
1327 current_frame_length_); | 1367 current_frame_length_); |
1328 } | 1368 } |
1329 if (current_frame_type_ == SYN_REPLY) { | 1369 if (current_frame_type_ == SYN_REPLY) { |
1330 visitor_->OnSynReply( | 1370 visitor_->OnSynReply( |
1331 current_frame_stream_id_, | 1371 current_frame_stream_id_, |
1332 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0); | 1372 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0); |
1333 } else if (spdy_version_ > 3 && | 1373 } else if (protocol_version() > SPDY3 && |
1334 current_frame_flags_ & HEADERS_FLAG_PRIORITY) { | 1374 current_frame_flags_ & HEADERS_FLAG_PRIORITY) { |
1335 // SPDY 4+ is missing SYN_STREAM. Simulate it so that API changes | 1375 // SPDY 4+ is missing SYN_STREAM. Simulate it so that API changes |
1336 // can be made independent of wire changes. | 1376 // can be made independent of wire changes. |
1337 visitor_->OnSynStream( | 1377 visitor_->OnSynStream( |
1338 current_frame_stream_id_, | 1378 current_frame_stream_id_, |
1339 0, // associated_to_stream_id | 1379 0, // associated_to_stream_id |
1340 priority, | 1380 priority, |
1341 current_frame_flags_ & CONTROL_FLAG_FIN, | 1381 current_frame_flags_ & CONTROL_FLAG_FIN, |
1342 false); // unidirectional | 1382 false); // unidirectional |
1343 } else { | 1383 } else { |
1344 visitor_->OnHeaders( | 1384 visitor_->OnHeaders( |
1345 current_frame_stream_id_, | 1385 current_frame_stream_id_, |
1346 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, | 1386 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, |
1347 expect_continuation_ == 0); | 1387 expect_continuation_ == 0); |
1348 } | 1388 } |
1349 } | 1389 } |
1350 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); | 1390 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); |
1351 break; | 1391 break; |
1352 case PUSH_PROMISE: | 1392 case PUSH_PROMISE: |
1353 { | 1393 { |
1354 DCHECK_LE(4, protocol_version()); | 1394 DCHECK_LT(SPDY3, protocol_version()); |
1355 if (current_frame_stream_id_ == 0) { | 1395 if (current_frame_stream_id_ == 0) { |
1356 set_error(SPDY_INVALID_CONTROL_FRAME); | 1396 set_error(SPDY_INVALID_CONTROL_FRAME); |
1357 break; | 1397 break; |
1358 } | 1398 } |
1359 SpdyStreamId promised_stream_id = kInvalidStream; | 1399 SpdyStreamId promised_stream_id = kInvalidStream; |
1360 bool successful_read = reader.ReadUInt31(&promised_stream_id); | 1400 bool successful_read = reader.ReadUInt31(&promised_stream_id); |
1361 DCHECK(successful_read); | 1401 DCHECK(successful_read); |
1362 DCHECK(reader.IsDoneReading()); | 1402 DCHECK(reader.IsDoneReading()); |
1363 if (promised_stream_id == 0) { | 1403 if (promised_stream_id == 0) { |
1364 set_error(SPDY_INVALID_CONTROL_FRAME); | 1404 set_error(SPDY_INVALID_CONTROL_FRAME); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1433 size_t process_bytes = std::min(data_len, remaining_data_length_); | 1473 size_t process_bytes = std::min(data_len, remaining_data_length_); |
1434 if (is_hpack_header_block) { | 1474 if (is_hpack_header_block) { |
1435 if (!hpack_decoder_.HandleControlFrameHeadersData(current_frame_stream_id_, | 1475 if (!hpack_decoder_.HandleControlFrameHeadersData(current_frame_stream_id_, |
1436 data, | 1476 data, |
1437 process_bytes)) { | 1477 process_bytes)) { |
1438 // TODO(jgraettinger): Finer-grained HPACK error codes. | 1478 // TODO(jgraettinger): Finer-grained HPACK error codes. |
1439 set_error(SPDY_DECOMPRESS_FAILURE); | 1479 set_error(SPDY_DECOMPRESS_FAILURE); |
1440 processed_successfully = false; | 1480 processed_successfully = false; |
1441 } | 1481 } |
1442 } else if (process_bytes > 0) { | 1482 } else if (process_bytes > 0) { |
1443 if (enable_compression_ && spdy_version_ < 4) { | 1483 if (enable_compression_ && protocol_version() <= SPDY3) { |
1444 processed_successfully = IncrementallyDecompressControlFrameHeaderData( | 1484 processed_successfully = IncrementallyDecompressControlFrameHeaderData( |
1445 current_frame_stream_id_, data, process_bytes); | 1485 current_frame_stream_id_, data, process_bytes); |
1446 } else { | 1486 } else { |
1447 processed_successfully = IncrementallyDeliverControlFrameHeaderData( | 1487 processed_successfully = IncrementallyDeliverControlFrameHeaderData( |
1448 current_frame_stream_id_, data, process_bytes); | 1488 current_frame_stream_id_, data, process_bytes); |
1449 } | 1489 } |
1450 } | 1490 } |
1451 remaining_data_length_ -= process_bytes; | 1491 remaining_data_length_ -= process_bytes; |
1452 | 1492 |
1453 // Handle the case that there is no futher data in this frame. | 1493 // Handle the case that there is no futher data in this frame. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1490 return process_bytes; | 1530 return process_bytes; |
1491 } | 1531 } |
1492 | 1532 |
1493 size_t SpdyFramer::ProcessSettingsFramePayload(const char* data, | 1533 size_t SpdyFramer::ProcessSettingsFramePayload(const char* data, |
1494 size_t data_len) { | 1534 size_t data_len) { |
1495 DCHECK_EQ(SPDY_SETTINGS_FRAME_PAYLOAD, state_); | 1535 DCHECK_EQ(SPDY_SETTINGS_FRAME_PAYLOAD, state_); |
1496 DCHECK_EQ(SETTINGS, current_frame_type_); | 1536 DCHECK_EQ(SETTINGS, current_frame_type_); |
1497 size_t unprocessed_bytes = std::min(data_len, remaining_data_length_); | 1537 size_t unprocessed_bytes = std::min(data_len, remaining_data_length_); |
1498 size_t processed_bytes = 0; | 1538 size_t processed_bytes = 0; |
1499 | 1539 |
1500 size_t setting_size = spdy_version_ < 4 ? 8 : 5; | 1540 size_t setting_size = protocol_version() <= SPDY3 ? 8 : 5; |
1501 | 1541 |
1502 // Loop over our incoming data. | 1542 // Loop over our incoming data. |
1503 while (unprocessed_bytes > 0) { | 1543 while (unprocessed_bytes > 0) { |
1504 // Process up to one setting at a time. | 1544 // Process up to one setting at a time. |
1505 size_t processing = std::min( | 1545 size_t processing = std::min( |
1506 unprocessed_bytes, | 1546 unprocessed_bytes, |
1507 static_cast<size_t>(setting_size - settings_scratch_.setting_buf_len)); | 1547 static_cast<size_t>(setting_size - settings_scratch_.setting_buf_len)); |
1508 | 1548 |
1509 // Check if we have a complete setting in our input. | 1549 // Check if we have a complete setting in our input. |
1510 if (processing == setting_size) { | 1550 if (processing == setting_size) { |
(...skipping 29 matching lines...) Expand all Loading... |
1540 remaining_data_length_ -= processed_bytes; | 1580 remaining_data_length_ -= processed_bytes; |
1541 if (remaining_data_length_ == 0) { | 1581 if (remaining_data_length_ == 0) { |
1542 visitor_->OnSettingsEnd(); | 1582 visitor_->OnSettingsEnd(); |
1543 CHANGE_STATE(SPDY_AUTO_RESET); | 1583 CHANGE_STATE(SPDY_AUTO_RESET); |
1544 } | 1584 } |
1545 | 1585 |
1546 return processed_bytes; | 1586 return processed_bytes; |
1547 } | 1587 } |
1548 | 1588 |
1549 void SpdyFramer::DeliverHpackBlockAsSpdy3Block() { | 1589 void SpdyFramer::DeliverHpackBlockAsSpdy3Block() { |
1550 DCHECK_GE(spdy_version_, SPDY4); | 1590 DCHECK_LT(SPDY3, protocol_version()); |
1551 DCHECK_EQ(remaining_data_length_, 0u); | 1591 DCHECK_EQ(0u, remaining_data_length_); |
1552 | 1592 |
1553 const SpdyNameValueBlock& block = hpack_decoder_.decoded_block(); | 1593 const SpdyNameValueBlock& block = hpack_decoder_.decoded_block(); |
1554 if (block.empty()) { | 1594 if (block.empty()) { |
1555 // Special-case this to make tests happy. | 1595 // Special-case this to make tests happy. |
1556 ProcessControlFrameHeaderBlock(NULL, 0, false); | 1596 ProcessControlFrameHeaderBlock(NULL, 0, false); |
1557 return; | 1597 return; |
1558 } | 1598 } |
1559 SpdyFrameBuilder builder( | 1599 SpdyFrameBuilder builder( |
1560 GetSerializedLength(protocol_version(), &block)); | 1600 GetSerializedLength(protocol_version(), &block)); |
1561 | 1601 |
1562 SerializeNameValueBlockWithoutCompression(&builder, block); | 1602 SerializeNameValueBlockWithoutCompression(&builder, block); |
1563 scoped_ptr<SpdyFrame> frame(builder.take()); | 1603 scoped_ptr<SpdyFrame> frame(builder.take()); |
1564 | 1604 |
1565 remaining_data_length_ = frame->size(); | 1605 remaining_data_length_ = frame->size(); |
1566 ProcessControlFrameHeaderBlock(frame->data(), frame->size(), false); | 1606 ProcessControlFrameHeaderBlock(frame->data(), frame->size(), false); |
1567 } | 1607 } |
1568 | 1608 |
1569 bool SpdyFramer::ProcessSetting(const char* data) { | 1609 bool SpdyFramer::ProcessSetting(const char* data) { |
| 1610 int id_field; |
1570 SpdySettingsIds id; | 1611 SpdySettingsIds id; |
1571 uint8 flags = 0; | 1612 uint8 flags = 0; |
1572 uint32 value; | 1613 uint32 value; |
1573 | 1614 |
1574 // Extract fields. | 1615 // Extract fields. |
1575 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id. | 1616 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id. |
1576 if (spdy_version_ < 4) { | 1617 if (protocol_version() <= SPDY3) { |
1577 const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data)); | 1618 const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data)); |
1578 SettingsFlagsAndId id_and_flags = | 1619 SettingsFlagsAndId id_and_flags = |
1579 SettingsFlagsAndId::FromWireFormat(spdy_version_, id_and_flags_wire); | 1620 SettingsFlagsAndId::FromWireFormat(protocol_version(), id_and_flags_wire); |
1580 id = static_cast<SpdySettingsIds>(id_and_flags.id()); | 1621 id_field = id_and_flags.id(); |
1581 flags = id_and_flags.flags(); | 1622 flags = id_and_flags.flags(); |
1582 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4))); | 1623 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4))); |
1583 } else { | 1624 } else { |
1584 id = static_cast<SpdySettingsIds>(*(reinterpret_cast<const uint8*>(data))); | 1625 id_field = *(reinterpret_cast<const uint8*>(data)); |
1585 value = ntohl(*(reinterpret_cast<const uint32*>(data + 1))); | 1626 value = ntohl(*(reinterpret_cast<const uint32*>(data + 1))); |
1586 } | 1627 } |
1587 | 1628 |
1588 // Validate id. | 1629 // Validate id. |
1589 switch (id) { | 1630 if (!SpdyConstants::IsValidSettingId(protocol_version(), id_field)) { |
1590 case SETTINGS_UPLOAD_BANDWIDTH: | 1631 DLOG(WARNING) << "Unknown SETTINGS ID: " << id_field; |
1591 case SETTINGS_DOWNLOAD_BANDWIDTH: | 1632 return false; |
1592 case SETTINGS_ROUND_TRIP_TIME: | |
1593 case SETTINGS_MAX_CONCURRENT_STREAMS: | |
1594 case SETTINGS_CURRENT_CWND: | |
1595 case SETTINGS_DOWNLOAD_RETRANS_RATE: | |
1596 case SETTINGS_INITIAL_WINDOW_SIZE: | |
1597 // Valid values. | |
1598 break; | |
1599 default: | |
1600 DLOG(WARNING) << "Unknown SETTINGS ID: " << id; | |
1601 return false; | |
1602 } | 1633 } |
| 1634 id = SpdyConstants::ParseSettingId(protocol_version(), id_field); |
1603 | 1635 |
1604 if (spdy_version_ < 4) { | 1636 if (protocol_version() <= SPDY3) { |
1605 // Detect duplicates. | 1637 // Detect duplicates. |
1606 if (static_cast<uint32>(id) <= settings_scratch_.last_setting_id) { | 1638 if (id <= settings_scratch_.last_setting_id) { |
1607 DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id | 1639 DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id |
1608 << " in " << display_protocol_ << " SETTINGS frame " | 1640 << " in " << display_protocol_ << " SETTINGS frame " |
1609 << "(last setting id was " | 1641 << "(last setting id was " |
1610 << settings_scratch_.last_setting_id << ")."; | 1642 << settings_scratch_.last_setting_id << ")."; |
1611 return false; | 1643 return false; |
1612 } | 1644 } |
1613 settings_scratch_.last_setting_id = id; | 1645 settings_scratch_.last_setting_id = id; |
1614 | 1646 |
1615 // Validate flags. | 1647 // Validate flags. |
1616 uint8 kFlagsMask = SETTINGS_FLAG_PLEASE_PERSIST | SETTINGS_FLAG_PERSISTED; | 1648 uint8 kFlagsMask = SETTINGS_FLAG_PLEASE_PERSIST | SETTINGS_FLAG_PERSISTED; |
(...skipping 16 matching lines...) Expand all Loading... |
1633 remaining_data_length_ -= bytes_read; | 1665 remaining_data_length_ -= bytes_read; |
1634 if (remaining_data_length_ == 0) { | 1666 if (remaining_data_length_ == 0) { |
1635 SpdyFrameReader reader(current_frame_buffer_.get(), | 1667 SpdyFrameReader reader(current_frame_buffer_.get(), |
1636 current_frame_buffer_length_); | 1668 current_frame_buffer_length_); |
1637 reader.Seek(GetControlFrameHeaderSize()); // Skip frame header. | 1669 reader.Seek(GetControlFrameHeaderSize()); // Skip frame header. |
1638 | 1670 |
1639 // Use frame-specific handlers. | 1671 // Use frame-specific handlers. |
1640 switch (current_frame_type_) { | 1672 switch (current_frame_type_) { |
1641 case PING: { | 1673 case PING: { |
1642 SpdyPingId id = 0; | 1674 SpdyPingId id = 0; |
1643 bool is_ack = | 1675 bool is_ack = protocol_version() > SPDY3 && |
1644 spdy_version_ >= 4 && (current_frame_flags_ & PING_FLAG_ACK); | 1676 (current_frame_flags_ & PING_FLAG_ACK); |
1645 bool successful_read = true; | 1677 bool successful_read = true; |
1646 if (spdy_version_ < 4) { | 1678 if (protocol_version() <= SPDY3) { |
1647 uint32 id32 = 0; | 1679 uint32 id32 = 0; |
1648 successful_read = reader.ReadUInt32(&id32); | 1680 successful_read = reader.ReadUInt32(&id32); |
1649 id = id32; | 1681 id = id32; |
1650 } else { | 1682 } else { |
1651 successful_read = reader.ReadUInt64(&id); | 1683 successful_read = reader.ReadUInt64(&id); |
1652 } | 1684 } |
1653 DCHECK(successful_read); | 1685 DCHECK(successful_read); |
1654 DCHECK(reader.IsDoneReading()); | 1686 DCHECK(reader.IsDoneReading()); |
1655 visitor_->OnPing(id, is_ack); | 1687 visitor_->OnPing(id, is_ack); |
1656 } | 1688 } |
1657 break; | 1689 break; |
1658 case WINDOW_UPDATE: { | 1690 case WINDOW_UPDATE: { |
1659 uint32 delta_window_size = 0; | 1691 uint32 delta_window_size = 0; |
1660 bool successful_read = true; | 1692 bool successful_read = true; |
1661 if (spdy_version_ < 4) { | 1693 if (protocol_version() <= SPDY3) { |
1662 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); | 1694 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); |
1663 DCHECK(successful_read); | 1695 DCHECK(successful_read); |
1664 } | 1696 } |
1665 successful_read = reader.ReadUInt32(&delta_window_size); | 1697 successful_read = reader.ReadUInt32(&delta_window_size); |
1666 DCHECK(successful_read); | 1698 DCHECK(successful_read); |
1667 DCHECK(reader.IsDoneReading()); | 1699 DCHECK(reader.IsDoneReading()); |
1668 visitor_->OnWindowUpdate(current_frame_stream_id_, | 1700 visitor_->OnWindowUpdate(current_frame_stream_id_, |
1669 delta_window_size); | 1701 delta_window_size); |
1670 } | 1702 } |
1671 break; | 1703 break; |
1672 case BLOCKED: { | 1704 case BLOCKED: { |
1673 DCHECK_LE(4, protocol_version()); | 1705 DCHECK_LT(SPDY3, protocol_version()); |
1674 DCHECK(reader.IsDoneReading()); | 1706 DCHECK(reader.IsDoneReading()); |
1675 visitor_->OnBlocked(current_frame_stream_id_); | 1707 visitor_->OnBlocked(current_frame_stream_id_); |
1676 } | 1708 } |
1677 break; | 1709 break; |
1678 default: | 1710 default: |
1679 // Unreachable. | 1711 // Unreachable. |
1680 LOG(FATAL) << "Unhandled control frame " << current_frame_type_; | 1712 LOG(FATAL) << "Unhandled control frame " << current_frame_type_; |
1681 } | 1713 } |
1682 | 1714 |
1683 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); | 1715 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); |
(...skipping 23 matching lines...) Expand all Loading... |
1707 if (current_frame_buffer_length_ == header_size) { | 1739 if (current_frame_buffer_length_ == header_size) { |
1708 // Parse out the last good stream id. | 1740 // Parse out the last good stream id. |
1709 SpdyFrameReader reader(current_frame_buffer_.get(), | 1741 SpdyFrameReader reader(current_frame_buffer_.get(), |
1710 current_frame_buffer_length_); | 1742 current_frame_buffer_length_); |
1711 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header. | 1743 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header. |
1712 bool successful_read = reader.ReadUInt31(¤t_frame_stream_id_); | 1744 bool successful_read = reader.ReadUInt31(¤t_frame_stream_id_); |
1713 DCHECK(successful_read); | 1745 DCHECK(successful_read); |
1714 | 1746 |
1715 // In SPDYv3 and up, frames also specify a status code - parse it out. | 1747 // In SPDYv3 and up, frames also specify a status code - parse it out. |
1716 SpdyGoAwayStatus status = GOAWAY_OK; | 1748 SpdyGoAwayStatus status = GOAWAY_OK; |
1717 if (spdy_version_ >= 3) { | 1749 if (protocol_version() >= SPDY3) { |
1718 uint32 status_raw = GOAWAY_OK; | 1750 uint32 status_raw = GOAWAY_OK; |
1719 successful_read = reader.ReadUInt32(&status_raw); | 1751 successful_read = reader.ReadUInt32(&status_raw); |
1720 DCHECK(successful_read); | 1752 DCHECK(successful_read); |
1721 // We've read an unsigned integer, so it's enough to only check | 1753 // We've read an unsigned integer, so it's enough to only check |
1722 // upper bound to ensure the value is in valid range. | 1754 // upper bound to ensure the value is in valid range. |
1723 if (status_raw < GOAWAY_NUM_STATUS_CODES) { | 1755 if (status_raw < GOAWAY_NUM_STATUS_CODES) { |
1724 status = static_cast<SpdyGoAwayStatus>(status_raw); | 1756 status = static_cast<SpdyGoAwayStatus>(status_raw); |
1725 } else { | 1757 } else { |
1726 // TODO(hkhalil): Probably best to OnError here, depending on | 1758 // TODO(hkhalil): Probably best to OnError here, depending on |
1727 // our interpretation of the spec. Keeping with existing liberal | 1759 // our interpretation of the spec. Keeping with existing liberal |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1768 if (!already_parsed_header) { | 1800 if (!already_parsed_header) { |
1769 // Buffer the new RST_STREAM header bytes we got. | 1801 // Buffer the new RST_STREAM header bytes we got. |
1770 UpdateCurrentFrameBuffer(&data, &len, unread_header_bytes); | 1802 UpdateCurrentFrameBuffer(&data, &len, unread_header_bytes); |
1771 | 1803 |
1772 // Do we have enough to parse the constant size RST_STREAM header? | 1804 // Do we have enough to parse the constant size RST_STREAM header? |
1773 if (current_frame_buffer_length_ == header_size) { | 1805 if (current_frame_buffer_length_ == header_size) { |
1774 // Parse out the last good stream id. | 1806 // Parse out the last good stream id. |
1775 SpdyFrameReader reader(current_frame_buffer_.get(), | 1807 SpdyFrameReader reader(current_frame_buffer_.get(), |
1776 current_frame_buffer_length_); | 1808 current_frame_buffer_length_); |
1777 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header. | 1809 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header. |
1778 if (protocol_version() < 4) { | 1810 if (protocol_version() <= SPDY3) { |
1779 bool successful_read = reader.ReadUInt31(¤t_frame_stream_id_); | 1811 bool successful_read = reader.ReadUInt31(¤t_frame_stream_id_); |
1780 DCHECK(successful_read); | 1812 DCHECK(successful_read); |
1781 } | 1813 } |
1782 | 1814 |
1783 SpdyRstStreamStatus status = RST_STREAM_INVALID; | 1815 SpdyRstStreamStatus status = RST_STREAM_INVALID; |
1784 uint32 status_raw = status; | 1816 uint32 status_raw = status; |
1785 bool successful_read = reader.ReadUInt32(&status_raw); | 1817 bool successful_read = reader.ReadUInt32(&status_raw); |
1786 DCHECK(successful_read); | 1818 DCHECK(successful_read); |
1787 // We've read an unsigned integer, so it's enough to only check | 1819 // We've read an unsigned integer, so it's enough to only check |
1788 // upper bound to ensure the value is in valid range. | 1820 // upper bound to ensure the value is in valid range. |
(...skipping 19 matching lines...) Expand all Loading... |
1808 if (!processed_successfully) { | 1840 if (!processed_successfully) { |
1809 set_error(SPDY_RST_STREAM_FRAME_CORRUPT); | 1841 set_error(SPDY_RST_STREAM_FRAME_CORRUPT); |
1810 } else if (remaining_data_length_ == 0) { | 1842 } else if (remaining_data_length_ == 0) { |
1811 // Signal that there is not more opaque data. | 1843 // Signal that there is not more opaque data. |
1812 visitor_->OnRstStreamFrameData(NULL, 0); | 1844 visitor_->OnRstStreamFrameData(NULL, 0); |
1813 CHANGE_STATE(SPDY_AUTO_RESET); | 1845 CHANGE_STATE(SPDY_AUTO_RESET); |
1814 } | 1846 } |
1815 return original_len; | 1847 return original_len; |
1816 } | 1848 } |
1817 | 1849 |
| 1850 size_t SpdyFramer::ProcessFramePaddingLength(const char* data, size_t len) { |
| 1851 DCHECK_EQ(SPDY_READ_PADDING_LENGTH, state_); |
| 1852 |
| 1853 size_t original_len = len; |
| 1854 if (remaining_padding_length_fields_ == 0) { |
| 1855 DCHECK_EQ(remaining_padding_payload_length_, 0u); |
| 1856 bool pad_low = false; |
| 1857 bool pad_high = false; |
| 1858 if (current_frame_flags_ & net::DATA_FLAG_PAD_LOW) { |
| 1859 pad_low = true; |
| 1860 ++remaining_padding_length_fields_; |
| 1861 } |
| 1862 if (current_frame_flags_ & net::DATA_FLAG_PAD_HIGH) { |
| 1863 pad_high = true; |
| 1864 ++remaining_padding_length_fields_; |
| 1865 } |
| 1866 if ((pad_high && !pad_low) || |
| 1867 remaining_data_length_ < remaining_padding_length_fields_) { |
| 1868 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); |
| 1869 return 0; |
| 1870 } |
| 1871 } |
| 1872 |
| 1873 // Parse the padding length. |
| 1874 while (len != 0 && remaining_padding_length_fields_ != 0) { |
| 1875 remaining_padding_payload_length_ = |
| 1876 (remaining_padding_payload_length_ << 8) + |
| 1877 *reinterpret_cast<const uint8*>(data); |
| 1878 ++data; |
| 1879 --len; |
| 1880 --remaining_padding_length_fields_; |
| 1881 --remaining_data_length_; |
| 1882 } |
| 1883 |
| 1884 if (remaining_padding_length_fields_ == 0) { |
| 1885 if (remaining_padding_payload_length_ > remaining_data_length_) { |
| 1886 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); |
| 1887 return 0; |
| 1888 } |
| 1889 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME); |
| 1890 } |
| 1891 return original_len - len; |
| 1892 } |
| 1893 |
| 1894 size_t SpdyFramer::ProcessFramePadding(const char* data, size_t len) { |
| 1895 DCHECK_EQ(SPDY_CONSUME_PADDING, state_); |
| 1896 |
| 1897 size_t original_len = len; |
| 1898 if (remaining_padding_payload_length_ > 0) { |
| 1899 DCHECK_EQ(remaining_padding_payload_length_, remaining_data_length_); |
| 1900 size_t amount_to_discard = std::min(remaining_padding_payload_length_, len); |
| 1901 // The visitor needs to know about padding so it can send window updates. |
| 1902 // Communicate the padding to the visitor through a NULL data pointer, with |
| 1903 // a nonzero size. |
| 1904 if (amount_to_discard) { |
| 1905 visitor_->OnStreamFrameData( |
| 1906 current_frame_stream_id_, NULL, amount_to_discard, false); |
| 1907 } |
| 1908 data += amount_to_discard; |
| 1909 len -= amount_to_discard; |
| 1910 remaining_padding_payload_length_ -= amount_to_discard; |
| 1911 remaining_data_length_ -= amount_to_discard; |
| 1912 |
| 1913 // If the FIN flag is set, and there is no more data in this data |
| 1914 // frame, inform the visitor of EOF via a 0-length data frame. |
| 1915 if (!remaining_data_length_ && current_frame_flags_ & DATA_FLAG_FIN) { |
| 1916 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true); |
| 1917 } |
| 1918 } |
| 1919 |
| 1920 if (remaining_data_length_ == 0) { |
| 1921 CHANGE_STATE(SPDY_AUTO_RESET); |
| 1922 } |
| 1923 return original_len - len; |
| 1924 } |
| 1925 |
1818 size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) { | 1926 size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) { |
1819 size_t original_len = len; | 1927 size_t original_len = len; |
1820 | 1928 if (remaining_data_length_ - remaining_padding_payload_length_ > 0) { |
1821 if (remaining_data_length_ > 0) { | 1929 size_t amount_to_forward = std::min( |
1822 size_t amount_to_forward = std::min(remaining_data_length_, len); | 1930 remaining_data_length_ - remaining_padding_payload_length_, len); |
1823 if (amount_to_forward && state_ != SPDY_IGNORE_REMAINING_PAYLOAD) { | 1931 if (amount_to_forward && state_ != SPDY_IGNORE_REMAINING_PAYLOAD) { |
1824 // Only inform the visitor if there is data. | 1932 // Only inform the visitor if there is data. |
1825 if (amount_to_forward) { | 1933 if (amount_to_forward) { |
1826 visitor_->OnStreamFrameData( | 1934 visitor_->OnStreamFrameData( |
1827 current_frame_stream_id_, data, amount_to_forward, false); | 1935 current_frame_stream_id_, data, amount_to_forward, false); |
1828 } | 1936 } |
1829 } | 1937 } |
1830 data += amount_to_forward; | 1938 data += amount_to_forward; |
1831 len -= amount_to_forward; | 1939 len -= amount_to_forward; |
1832 remaining_data_length_ -= amount_to_forward; | 1940 remaining_data_length_ -= amount_to_forward; |
1833 | 1941 |
1834 // If the FIN flag is set, and there is no more data in this data | 1942 // If the FIN flag is set, and there is no more data in this data |
1835 // frame, inform the visitor of EOF via a 0-length data frame. | 1943 // frame, inform the visitor of EOF via a 0-length data frame. |
1836 if (!remaining_data_length_ && current_frame_flags_ & DATA_FLAG_FIN) { | 1944 if (!remaining_data_length_ && current_frame_flags_ & DATA_FLAG_FIN) { |
1837 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true); | 1945 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true); |
1838 } | 1946 } |
1839 } | 1947 } |
1840 | 1948 |
1841 if (remaining_data_length_ == 0) { | 1949 if (remaining_data_length_ == remaining_padding_payload_length_) { |
1842 CHANGE_STATE(SPDY_AUTO_RESET); | 1950 CHANGE_STATE(SPDY_CONSUME_PADDING); |
1843 } | 1951 } |
1844 return original_len - len; | 1952 return original_len - len; |
1845 } | 1953 } |
1846 | 1954 |
1847 size_t SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data, | 1955 size_t SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data, |
1848 size_t header_length, | 1956 size_t header_length, |
1849 SpdyHeaderBlock* block) const { | 1957 SpdyHeaderBlock* block) const { |
1850 SpdyFrameReader reader(header_data, header_length); | 1958 SpdyFrameReader reader(header_data, header_length); |
1851 | 1959 |
1852 // Read number of headers. | 1960 // Read number of headers. |
1853 uint32 num_headers; | 1961 uint32 num_headers; |
1854 if (spdy_version_ < 3) { | 1962 if (protocol_version() <= SPDY2) { |
1855 uint16 temp; | 1963 uint16 temp; |
1856 if (!reader.ReadUInt16(&temp)) { | 1964 if (!reader.ReadUInt16(&temp)) { |
1857 DVLOG(1) << "Unable to read number of headers."; | 1965 DVLOG(1) << "Unable to read number of headers."; |
1858 return 0; | 1966 return 0; |
1859 } | 1967 } |
1860 num_headers = temp; | 1968 num_headers = temp; |
1861 } else { | 1969 } else { |
1862 if (!reader.ReadUInt32(&num_headers)) { | 1970 if (!reader.ReadUInt32(&num_headers)) { |
1863 DVLOG(1) << "Unable to read number of headers."; | 1971 DVLOG(1) << "Unable to read number of headers."; |
1864 return 0; | 1972 return 0; |
1865 } | 1973 } |
1866 } | 1974 } |
1867 | 1975 |
1868 // Read each header. | 1976 // Read each header. |
1869 for (uint32 index = 0; index < num_headers; ++index) { | 1977 for (uint32 index = 0; index < num_headers; ++index) { |
1870 base::StringPiece temp; | 1978 base::StringPiece temp; |
1871 | 1979 |
1872 // Read header name. | 1980 // Read header name. |
1873 if ((spdy_version_ < 3) ? !reader.ReadStringPiece16(&temp) | 1981 if ((protocol_version() <= SPDY2) ? !reader.ReadStringPiece16(&temp) |
1874 : !reader.ReadStringPiece32(&temp)) { | 1982 : !reader.ReadStringPiece32(&temp)) { |
1875 DVLOG(1) << "Unable to read header name (" << index + 1 << " of " | 1983 DVLOG(1) << "Unable to read header name (" << index + 1 << " of " |
1876 << num_headers << ")."; | 1984 << num_headers << ")."; |
1877 return 0; | 1985 return 0; |
1878 } | 1986 } |
1879 std::string name = temp.as_string(); | 1987 std::string name = temp.as_string(); |
1880 | 1988 |
1881 // Read header value. | 1989 // Read header value. |
1882 if ((spdy_version_ < 3) ? !reader.ReadStringPiece16(&temp) | 1990 if ((protocol_version() <= SPDY2) ? !reader.ReadStringPiece16(&temp) |
1883 : !reader.ReadStringPiece32(&temp)) { | 1991 : !reader.ReadStringPiece32(&temp)) { |
1884 DVLOG(1) << "Unable to read header value (" << index + 1 << " of " | 1992 DVLOG(1) << "Unable to read header value (" << index + 1 << " of " |
1885 << num_headers << ")."; | 1993 << num_headers << ")."; |
1886 return 0; | 1994 return 0; |
1887 } | 1995 } |
1888 std::string value = temp.as_string(); | 1996 std::string value = temp.as_string(); |
1889 | 1997 |
1890 // Ensure no duplicates. | 1998 // Ensure no duplicates. |
1891 if (block->find(name) != block->end()) { | 1999 if (block->find(name) != block->end()) { |
1892 DVLOG(1) << "Duplicate header '" << name << "' (" << index + 1 << " of " | 2000 DVLOG(1) << "Duplicate header '" << name << "' (" << index + 1 << " of " |
1893 << num_headers << ")."; | 2001 << num_headers << ")."; |
1894 return 0; | 2002 return 0; |
1895 } | 2003 } |
1896 | 2004 |
1897 // Store header. | 2005 // Store header. |
1898 (*block)[name] = value; | 2006 (*block)[name] = value; |
1899 } | 2007 } |
1900 return reader.GetBytesConsumed(); | 2008 return reader.GetBytesConsumed(); |
1901 } | 2009 } |
1902 | 2010 |
1903 SpdySerializedFrame* SpdyFramer::SerializeData(const SpdyDataIR& data) const { | 2011 SpdySerializedFrame* SpdyFramer::SerializeData(const SpdyDataIR& datair) const { |
1904 const size_t kSize = GetDataFrameMinimumSize() + data.data().length(); | 2012 uint8 flags = DATA_FLAG_NONE; |
1905 | 2013 if (datair.fin()) { |
1906 SpdyDataFlags flags = DATA_FLAG_NONE; | |
1907 if (data.fin()) { | |
1908 flags = DATA_FLAG_FIN; | 2014 flags = DATA_FLAG_FIN; |
1909 } | 2015 } |
1910 | 2016 |
1911 SpdyFrameBuilder builder(kSize); | 2017 if (protocol_version() > SPDY3) { |
1912 builder.WriteDataFrameHeader(*this, data.stream_id(), flags); | 2018 int num_padding_fields = 0; |
1913 builder.WriteBytes(data.data().data(), data.data().length()); | 2019 if (datair.pad_low()) { |
1914 DCHECK_EQ(kSize, builder.length()); | 2020 flags |= DATA_FLAG_PAD_LOW; |
1915 return builder.take(); | 2021 ++num_padding_fields; |
| 2022 } |
| 2023 if (datair.pad_high()) { |
| 2024 flags |= DATA_FLAG_PAD_HIGH; |
| 2025 ++num_padding_fields; |
| 2026 } |
| 2027 |
| 2028 const size_t size_with_padding = num_padding_fields + |
| 2029 datair.data().length() + datair.padding_payload_len() + |
| 2030 GetDataFrameMinimumSize(); |
| 2031 SpdyFrameBuilder builder(size_with_padding); |
| 2032 builder.WriteDataFrameHeader(*this, datair.stream_id(), flags); |
| 2033 if (datair.pad_high()) { |
| 2034 builder.WriteUInt8(datair.padding_payload_len() >> 8); |
| 2035 } |
| 2036 if (datair.pad_low()) { |
| 2037 builder.WriteUInt8(datair.padding_payload_len() & 0xff); |
| 2038 } |
| 2039 builder.WriteBytes(datair.data().data(), datair.data().length()); |
| 2040 if (datair.padding_payload_len() > 0) { |
| 2041 string padding = string(datair.padding_payload_len(), '0'); |
| 2042 builder.WriteBytes(padding.data(), padding.length()); |
| 2043 } |
| 2044 DCHECK_EQ(size_with_padding, builder.length()); |
| 2045 return builder.take(); |
| 2046 } else { |
| 2047 const size_t size = GetDataFrameMinimumSize() + datair.data().length(); |
| 2048 SpdyFrameBuilder builder(size); |
| 2049 builder.WriteDataFrameHeader(*this, datair.stream_id(), flags); |
| 2050 builder.WriteBytes(datair.data().data(), datair.data().length()); |
| 2051 DCHECK_EQ(size, builder.length()); |
| 2052 return builder.take(); |
| 2053 } |
1916 } | 2054 } |
1917 | 2055 |
1918 SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeader( | 2056 SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeader( |
1919 const SpdyDataIR& data) const { | 2057 const SpdyDataIR& data) const { |
1920 const size_t kSize = GetDataFrameMinimumSize(); | 2058 const size_t kSize = GetDataFrameMinimumSize(); |
1921 | 2059 |
1922 SpdyDataFlags flags = DATA_FLAG_NONE; | 2060 uint8 flags = DATA_FLAG_NONE; |
1923 if (data.fin()) { | 2061 if (data.fin()) { |
1924 flags = DATA_FLAG_FIN; | 2062 flags = DATA_FLAG_FIN; |
1925 } | 2063 } |
| 2064 if (protocol_version() > SPDY3) { |
| 2065 if (data.pad_low()) { |
| 2066 flags |= DATA_FLAG_PAD_LOW; |
| 2067 } |
| 2068 if (data.pad_high()) { |
| 2069 flags |= DATA_FLAG_PAD_HIGH; |
| 2070 } |
| 2071 } |
1926 | 2072 |
1927 SpdyFrameBuilder builder(kSize); | 2073 SpdyFrameBuilder builder(kSize); |
1928 builder.WriteDataFrameHeader(*this, data.stream_id(), flags); | 2074 builder.WriteDataFrameHeader(*this, data.stream_id(), flags); |
1929 if (protocol_version() < 4) { | 2075 builder.OverwriteLength(*this, data.data().length()); |
1930 builder.OverwriteLength(*this, data.data().length()); | |
1931 } else { | |
1932 builder.OverwriteLength(*this, data.data().length() + kSize); | |
1933 } | |
1934 DCHECK_EQ(kSize, builder.length()); | 2076 DCHECK_EQ(kSize, builder.length()); |
1935 return builder.take(); | 2077 return builder.take(); |
1936 } | 2078 } |
1937 | 2079 |
1938 SpdySerializedFrame* SpdyFramer::SerializeSynStream( | 2080 SpdySerializedFrame* SpdyFramer::SerializeSynStream( |
1939 const SpdySynStreamIR& syn_stream) { | 2081 const SpdySynStreamIR& syn_stream) { |
1940 uint8 flags = 0; | 2082 uint8 flags = 0; |
1941 if (syn_stream.fin()) { | 2083 if (syn_stream.fin()) { |
1942 flags |= CONTROL_FLAG_FIN; | 2084 flags |= CONTROL_FLAG_FIN; |
1943 } | 2085 } |
1944 if (syn_stream.unidirectional()) { | 2086 if (syn_stream.unidirectional()) { |
1945 // TODO(hkhalil): invalid for HTTP2. | 2087 // TODO(hkhalil): invalid for HTTP2. |
1946 flags |= CONTROL_FLAG_UNIDIRECTIONAL; | 2088 flags |= CONTROL_FLAG_UNIDIRECTIONAL; |
1947 } | 2089 } |
1948 // In SPDY >= 4, SYN_STREAM frames are HEADERS frames, but for now | 2090 // In SPDY >= 4, SYN_STREAM frames are HEADERS frames, but for now |
1949 // we never expect to have to overflow into a CONTINUATION frame. | 2091 // we never expect to have to overflow into a CONTINUATION frame. |
1950 if (spdy_version_ >= 4) { | 2092 if (protocol_version() > SPDY3) { |
1951 flags |= HEADERS_FLAG_PRIORITY; | 2093 flags |= HEADERS_FLAG_PRIORITY; |
1952 flags |= HEADERS_FLAG_END_HEADERS; | 2094 flags |= HEADERS_FLAG_END_HEADERS; |
1953 } | 2095 } |
1954 | 2096 |
1955 // Sanitize priority. | 2097 // Sanitize priority. |
1956 uint8 priority = syn_stream.priority(); | 2098 uint8 priority = syn_stream.priority(); |
1957 if (priority > GetLowestPriority()) { | 2099 if (priority > GetLowestPriority()) { |
1958 DLOG(DFATAL) << "Priority out-of-bounds."; | 2100 DLOG(DFATAL) << "Priority out-of-bounds."; |
1959 priority = GetLowestPriority(); | 2101 priority = GetLowestPriority(); |
1960 } | 2102 } |
1961 | 2103 |
1962 // The size of this frame, including variable-length name-value block. | 2104 // The size of this frame, including variable-length name-value block. |
1963 size_t size = GetSynStreamMinimumSize(); | 2105 size_t size = GetSynStreamMinimumSize(); |
1964 | 2106 |
1965 string hpack_encoding; | 2107 string hpack_encoding; |
1966 if (spdy_version_ >= 4) { | 2108 if (protocol_version() > SPDY3) { |
1967 hpack_encoder_.EncodeHeaderSet(syn_stream.name_value_block(), | 2109 hpack_encoder_.EncodeHeaderSet(syn_stream.name_value_block(), |
1968 &hpack_encoding); | 2110 &hpack_encoding); |
1969 size += hpack_encoding.size(); | 2111 size += hpack_encoding.size(); |
1970 } else { | 2112 } else { |
1971 size += GetSerializedLength(syn_stream.name_value_block()); | 2113 size += GetSerializedLength(syn_stream.name_value_block()); |
1972 } | 2114 } |
1973 | 2115 |
1974 SpdyFrameBuilder builder(size); | 2116 SpdyFrameBuilder builder(size); |
1975 if (spdy_version_ < 4) { | 2117 if (protocol_version() <= SPDY3) { |
1976 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags); | 2118 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags); |
1977 builder.WriteUInt32(syn_stream.stream_id()); | 2119 builder.WriteUInt32(syn_stream.stream_id()); |
1978 builder.WriteUInt32(syn_stream.associated_to_stream_id()); | 2120 builder.WriteUInt32(syn_stream.associated_to_stream_id()); |
1979 builder.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5)); | 2121 builder.WriteUInt8(priority << ((protocol_version() <= SPDY2) ? 6 : 5)); |
1980 builder.WriteUInt8(0); // Unused byte where credential slot used to be. | 2122 builder.WriteUInt8(0); // Unused byte where credential slot used to be. |
1981 } else { | 2123 } else { |
1982 builder.WriteFramePrefix(*this, | 2124 builder.WriteFramePrefix(*this, |
1983 HEADERS, | 2125 HEADERS, |
1984 flags, | 2126 flags, |
1985 syn_stream.stream_id()); | 2127 syn_stream.stream_id()); |
1986 builder.WriteUInt32(priority); | 2128 builder.WriteUInt32(priority); |
1987 } | 2129 } |
1988 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length()); | 2130 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length()); |
1989 if (spdy_version_ >= 4) { | 2131 if (protocol_version() > SPDY3) { |
1990 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); | 2132 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); |
1991 } else { | 2133 } else { |
1992 SerializeNameValueBlock(&builder, syn_stream); | 2134 SerializeNameValueBlock(&builder, syn_stream); |
1993 } | 2135 } |
1994 | 2136 |
1995 if (debug_visitor_) { | 2137 if (debug_visitor_) { |
1996 const size_t payload_len = spdy_version_ >= 4 ? hpack_encoding.size() : | 2138 const size_t payload_len = protocol_version() > SPDY3 ? |
| 2139 hpack_encoding.size() : |
1997 GetSerializedLength(protocol_version(), | 2140 GetSerializedLength(protocol_version(), |
1998 &(syn_stream.name_value_block())); | 2141 &(syn_stream.name_value_block())); |
1999 // SPDY 4 reports this compression as a SYN_STREAM compression. | 2142 // SPDY 4 reports this compression as a SYN_STREAM compression. |
2000 debug_visitor_->OnSendCompressedFrame(syn_stream.stream_id(), | 2143 debug_visitor_->OnSendCompressedFrame(syn_stream.stream_id(), |
2001 SYN_STREAM, | 2144 SYN_STREAM, |
2002 payload_len, | 2145 payload_len, |
2003 builder.length()); | 2146 builder.length()); |
2004 } | 2147 } |
2005 | 2148 |
2006 return builder.take(); | 2149 return builder.take(); |
2007 } | 2150 } |
2008 | 2151 |
2009 SpdySerializedFrame* SpdyFramer::SerializeSynReply( | 2152 SpdySerializedFrame* SpdyFramer::SerializeSynReply( |
2010 const SpdySynReplyIR& syn_reply) { | 2153 const SpdySynReplyIR& syn_reply) { |
2011 uint8 flags = 0; | 2154 uint8 flags = 0; |
2012 if (syn_reply.fin()) { | 2155 if (syn_reply.fin()) { |
2013 flags |= CONTROL_FLAG_FIN; | 2156 flags |= CONTROL_FLAG_FIN; |
2014 } | 2157 } |
2015 // In SPDY >= 4, SYN_REPLY frames are HEADERS frames, but for now | 2158 // In SPDY >= 4, SYN_REPLY frames are HEADERS frames, but for now |
2016 // we never expect to have to overflow into a CONTINUATION frame. | 2159 // we never expect to have to overflow into a CONTINUATION frame. |
2017 if (spdy_version_ >= 4) { | 2160 if (protocol_version() > SPDY3) { |
2018 flags |= HEADERS_FLAG_END_HEADERS; | 2161 flags |= HEADERS_FLAG_END_HEADERS; |
2019 } | 2162 } |
2020 | 2163 |
2021 // The size of this frame, including variable-length name-value block. | 2164 // The size of this frame, including variable-length name-value block. |
2022 size_t size = GetSynReplyMinimumSize(); | 2165 size_t size = GetSynReplyMinimumSize(); |
2023 | 2166 |
2024 string hpack_encoding; | 2167 string hpack_encoding; |
2025 if (spdy_version_ >= 4) { | 2168 if (protocol_version() > SPDY3) { |
2026 hpack_encoder_.EncodeHeaderSet(syn_reply.name_value_block(), | 2169 hpack_encoder_.EncodeHeaderSet(syn_reply.name_value_block(), |
2027 &hpack_encoding); | 2170 &hpack_encoding); |
2028 size += hpack_encoding.size(); | 2171 size += hpack_encoding.size(); |
2029 } else { | 2172 } else { |
2030 size += GetSerializedLength(syn_reply.name_value_block()); | 2173 size += GetSerializedLength(syn_reply.name_value_block()); |
2031 } | 2174 } |
2032 | 2175 |
2033 SpdyFrameBuilder builder(size); | 2176 SpdyFrameBuilder builder(size); |
2034 if (spdy_version_ < 4) { | 2177 if (protocol_version() <= SPDY3) { |
2035 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags); | 2178 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags); |
2036 builder.WriteUInt32(syn_reply.stream_id()); | 2179 builder.WriteUInt32(syn_reply.stream_id()); |
2037 } else { | 2180 } else { |
2038 builder.WriteFramePrefix(*this, | 2181 builder.WriteFramePrefix(*this, |
2039 HEADERS, | 2182 HEADERS, |
2040 flags, | 2183 flags, |
2041 syn_reply.stream_id()); | 2184 syn_reply.stream_id()); |
2042 } | 2185 } |
2043 if (protocol_version() < 3) { | 2186 if (protocol_version() < SPDY3) { |
2044 builder.WriteUInt16(0); // Unused. | 2187 builder.WriteUInt16(0); // Unused. |
2045 } | 2188 } |
2046 DCHECK_EQ(GetSynReplyMinimumSize(), builder.length()); | 2189 DCHECK_EQ(GetSynReplyMinimumSize(), builder.length()); |
2047 if (spdy_version_ >= 4) { | 2190 if (protocol_version() > SPDY3) { |
2048 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); | 2191 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); |
2049 } else { | 2192 } else { |
2050 SerializeNameValueBlock(&builder, syn_reply); | 2193 SerializeNameValueBlock(&builder, syn_reply); |
2051 } | 2194 } |
2052 | 2195 |
2053 if (debug_visitor_) { | 2196 if (debug_visitor_) { |
2054 const size_t payload_len = spdy_version_ >= 4 ? hpack_encoding.size() : | 2197 const size_t payload_len = protocol_version() > SPDY3 ? |
| 2198 hpack_encoding.size() : |
2055 GetSerializedLength(protocol_version(), | 2199 GetSerializedLength(protocol_version(), |
2056 &(syn_reply.name_value_block())); | 2200 &(syn_reply.name_value_block())); |
2057 debug_visitor_->OnSendCompressedFrame(syn_reply.stream_id(), | 2201 debug_visitor_->OnSendCompressedFrame(syn_reply.stream_id(), |
2058 SYN_REPLY, | 2202 SYN_REPLY, |
2059 payload_len, | 2203 payload_len, |
2060 builder.length()); | 2204 builder.length()); |
2061 } | 2205 } |
2062 | 2206 |
2063 return builder.take(); | 2207 return builder.take(); |
2064 } | 2208 } |
2065 | 2209 |
2066 SpdySerializedFrame* SpdyFramer::SerializeRstStream( | 2210 SpdySerializedFrame* SpdyFramer::SerializeRstStream( |
2067 const SpdyRstStreamIR& rst_stream) const { | 2211 const SpdyRstStreamIR& rst_stream) const { |
2068 // TODO(jgraettinger): For now, Chromium will support parsing RST_STREAM | 2212 // TODO(jgraettinger): For now, Chromium will support parsing RST_STREAM |
2069 // payloads, but will not emit them. SPDY4 is used for draft HTTP/2, | 2213 // payloads, but will not emit them. SPDY4 is used for draft HTTP/2, |
2070 // which doesn't currently include RST_STREAM payloads. GFE flags have been | 2214 // which doesn't currently include RST_STREAM payloads. GFE flags have been |
2071 // commented but left in place to simplify future patching. | 2215 // commented but left in place to simplify future patching. |
2072 // Compute the output buffer size, taking opaque data into account. | 2216 // Compute the output buffer size, taking opaque data into account. |
2073 uint16 expected_length = GetRstStreamMinimumSize(); | 2217 uint16 expected_length = GetRstStreamMinimumSize(); |
2074 if (protocol_version() >= 4) { | 2218 if (protocol_version() > SPDY3) { |
2075 expected_length += rst_stream.description().size(); | 2219 expected_length += rst_stream.description().size(); |
2076 } | 2220 } |
2077 SpdyFrameBuilder builder(expected_length); | 2221 SpdyFrameBuilder builder(expected_length); |
2078 | 2222 |
2079 // Serialize the RST_STREAM frame. | 2223 // Serialize the RST_STREAM frame. |
2080 if (protocol_version() < 4) { | 2224 if (protocol_version() <= SPDY3) { |
2081 builder.WriteControlFrameHeader(*this, RST_STREAM, 0); | 2225 builder.WriteControlFrameHeader(*this, RST_STREAM, 0); |
2082 builder.WriteUInt32(rst_stream.stream_id()); | 2226 builder.WriteUInt32(rst_stream.stream_id()); |
2083 } else { | 2227 } else { |
2084 builder.WriteFramePrefix(*this, RST_STREAM, 0, rst_stream.stream_id()); | 2228 builder.WriteFramePrefix(*this, RST_STREAM, 0, rst_stream.stream_id()); |
2085 } | 2229 } |
2086 | 2230 |
2087 builder.WriteUInt32(rst_stream.status()); | 2231 builder.WriteUInt32(rst_stream.status()); |
2088 | 2232 |
2089 // In SPDY4 and up, RST_STREAM frames may also specify opaque data. | 2233 // In SPDY4 and up, RST_STREAM frames may also specify opaque data. |
2090 if (protocol_version() >= 4 && rst_stream.description().size() > 0) { | 2234 if (protocol_version() > SPDY3 && rst_stream.description().size() > 0) { |
2091 builder.WriteBytes(rst_stream.description().data(), | 2235 builder.WriteBytes(rst_stream.description().data(), |
2092 rst_stream.description().size()); | 2236 rst_stream.description().size()); |
2093 } | 2237 } |
2094 | 2238 |
2095 DCHECK_EQ(expected_length, builder.length()); | 2239 DCHECK_EQ(expected_length, builder.length()); |
2096 return builder.take(); | 2240 return builder.take(); |
2097 } | 2241 } |
2098 | 2242 |
2099 SpdySerializedFrame* SpdyFramer::SerializeSettings( | 2243 SpdySerializedFrame* SpdyFramer::SerializeSettings( |
2100 const SpdySettingsIR& settings) const { | 2244 const SpdySettingsIR& settings) const { |
2101 uint8 flags = 0; | 2245 uint8 flags = 0; |
2102 | 2246 |
2103 if (spdy_version_ < 4) { | 2247 if (protocol_version() <= SPDY3) { |
2104 if (settings.clear_settings()) { | 2248 if (settings.clear_settings()) { |
2105 flags |= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS; | 2249 flags |= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS; |
2106 } | 2250 } |
2107 } else { | 2251 } else { |
2108 if (settings.is_ack()) { | 2252 if (settings.is_ack()) { |
2109 flags |= SETTINGS_FLAG_ACK; | 2253 flags |= SETTINGS_FLAG_ACK; |
2110 } | 2254 } |
2111 } | 2255 } |
2112 const SpdySettingsIR::ValueMap* values = &(settings.values()); | 2256 const SpdySettingsIR::ValueMap* values = &(settings.values()); |
2113 | 2257 |
2114 size_t setting_size = (protocol_version() < 4 ? 8 : 5); | 2258 size_t setting_size = (protocol_version() <= SPDY3 ? 8 : 5); |
2115 // Size, in bytes, of this SETTINGS frame. | 2259 // Size, in bytes, of this SETTINGS frame. |
2116 const size_t size = GetSettingsMinimumSize() + | 2260 const size_t size = GetSettingsMinimumSize() + |
2117 (values->size() * setting_size); | 2261 (values->size() * setting_size); |
2118 SpdyFrameBuilder builder(size); | 2262 SpdyFrameBuilder builder(size); |
2119 if (spdy_version_ < 4) { | 2263 if (protocol_version() <= SPDY3) { |
2120 builder.WriteControlFrameHeader(*this, SETTINGS, flags); | 2264 builder.WriteControlFrameHeader(*this, SETTINGS, flags); |
2121 } else { | 2265 } else { |
2122 builder.WriteFramePrefix(*this, SETTINGS, flags, 0); | 2266 builder.WriteFramePrefix(*this, SETTINGS, flags, 0); |
2123 } | 2267 } |
2124 | 2268 |
2125 // If this is an ACK, payload should be empty. | 2269 // If this is an ACK, payload should be empty. |
2126 if (spdy_version_ >= 4 && settings.is_ack()) { | 2270 if (protocol_version() > SPDY3 && settings.is_ack()) { |
2127 return builder.take(); | 2271 return builder.take(); |
2128 } | 2272 } |
2129 | 2273 |
2130 if (spdy_version_ < 4) { | 2274 if (protocol_version() <= SPDY3) { |
2131 builder.WriteUInt32(values->size()); | 2275 builder.WriteUInt32(values->size()); |
2132 } | 2276 } |
2133 DCHECK_EQ(GetSettingsMinimumSize(), builder.length()); | 2277 DCHECK_EQ(GetSettingsMinimumSize(), builder.length()); |
2134 for (SpdySettingsIR::ValueMap::const_iterator it = values->begin(); | 2278 for (SpdySettingsIR::ValueMap::const_iterator it = values->begin(); |
2135 it != values->end(); | 2279 it != values->end(); |
2136 ++it) { | 2280 ++it) { |
2137 if (spdy_version_ < 4) { | 2281 if (protocol_version() <= SPDY3) { |
2138 uint8 setting_flags = 0; | 2282 uint8 setting_flags = 0; |
2139 if (it->second.persist_value) { | 2283 if (it->second.persist_value) { |
2140 setting_flags |= SETTINGS_FLAG_PLEASE_PERSIST; | 2284 setting_flags |= SETTINGS_FLAG_PLEASE_PERSIST; |
2141 } | 2285 } |
2142 if (it->second.persisted) { | 2286 if (it->second.persisted) { |
2143 setting_flags |= SETTINGS_FLAG_PERSISTED; | 2287 setting_flags |= SETTINGS_FLAG_PERSISTED; |
2144 } | 2288 } |
2145 SettingsFlagsAndId flags_and_id(setting_flags, it->first); | 2289 SettingsFlagsAndId flags_and_id( |
| 2290 setting_flags, |
| 2291 SpdyConstants::SerializeSettingId(protocol_version(), it->first)); |
2146 uint32 id_and_flags_wire = flags_and_id.GetWireFormat(protocol_version()); | 2292 uint32 id_and_flags_wire = flags_and_id.GetWireFormat(protocol_version()); |
2147 builder.WriteBytes(&id_and_flags_wire, 4); | 2293 builder.WriteBytes(&id_and_flags_wire, 4); |
2148 } else { | 2294 } else { |
2149 builder.WriteUInt8(static_cast<uint8>(it->first)); | 2295 builder.WriteUInt8(SpdyConstants::SerializeSettingId(protocol_version(), |
| 2296 it->first)); |
2150 } | 2297 } |
2151 builder.WriteUInt32(it->second.value); | 2298 builder.WriteUInt32(it->second.value); |
2152 } | 2299 } |
2153 DCHECK_EQ(size, builder.length()); | 2300 DCHECK_EQ(size, builder.length()); |
2154 return builder.take(); | 2301 return builder.take(); |
2155 } | 2302 } |
2156 | 2303 |
2157 SpdyFrame* SpdyFramer::SerializeBlocked(const SpdyBlockedIR& blocked) const { | 2304 SpdyFrame* SpdyFramer::SerializeBlocked(const SpdyBlockedIR& blocked) const { |
2158 DCHECK_LE(4, protocol_version()); | 2305 DCHECK_LT(SPDY3, protocol_version()); |
2159 SpdyFrameBuilder builder(GetBlockedSize()); | 2306 SpdyFrameBuilder builder(GetBlockedSize()); |
2160 builder.WriteFramePrefix(*this, BLOCKED, kNoFlags, blocked.stream_id()); | 2307 builder.WriteFramePrefix(*this, BLOCKED, kNoFlags, blocked.stream_id()); |
2161 return builder.take(); | 2308 return builder.take(); |
2162 } | 2309 } |
2163 | 2310 |
2164 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const { | 2311 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const { |
2165 SpdyFrameBuilder builder(GetPingSize()); | 2312 SpdyFrameBuilder builder(GetPingSize()); |
2166 if (spdy_version_ < 4) { | 2313 if (protocol_version() <= SPDY3) { |
2167 builder.WriteControlFrameHeader(*this, PING, kNoFlags); | 2314 builder.WriteControlFrameHeader(*this, PING, kNoFlags); |
2168 builder.WriteUInt32(static_cast<uint32>(ping.id())); | 2315 builder.WriteUInt32(static_cast<uint32>(ping.id())); |
2169 } else { | 2316 } else { |
2170 uint8 flags = 0; | 2317 uint8 flags = 0; |
2171 if (ping.is_ack()) { | 2318 if (ping.is_ack()) { |
2172 flags |= PING_FLAG_ACK; | 2319 flags |= PING_FLAG_ACK; |
2173 } | 2320 } |
2174 builder.WriteFramePrefix(*this, PING, flags, 0); | 2321 builder.WriteFramePrefix(*this, PING, flags, 0); |
2175 builder.WriteUInt64(ping.id()); | 2322 builder.WriteUInt64(ping.id()); |
2176 } | 2323 } |
2177 DCHECK_EQ(GetPingSize(), builder.length()); | 2324 DCHECK_EQ(GetPingSize(), builder.length()); |
2178 return builder.take(); | 2325 return builder.take(); |
2179 } | 2326 } |
2180 | 2327 |
2181 SpdySerializedFrame* SpdyFramer::SerializeGoAway( | 2328 SpdySerializedFrame* SpdyFramer::SerializeGoAway( |
2182 const SpdyGoAwayIR& goaway) const { | 2329 const SpdyGoAwayIR& goaway) const { |
2183 | 2330 |
2184 // Compute the output buffer size, take opaque data into account. | 2331 // Compute the output buffer size, take opaque data into account. |
2185 uint16 expected_length = GetGoAwayMinimumSize(); | 2332 uint16 expected_length = GetGoAwayMinimumSize(); |
2186 if (protocol_version() >= 4) { | 2333 if (protocol_version() > SPDY3) { |
2187 expected_length += goaway.description().size(); | 2334 expected_length += goaway.description().size(); |
2188 } | 2335 } |
2189 SpdyFrameBuilder builder(expected_length); | 2336 SpdyFrameBuilder builder(expected_length); |
2190 | 2337 |
2191 // Serialize the GOAWAY frame. | 2338 // Serialize the GOAWAY frame. |
2192 if (spdy_version_ < 4) { | 2339 if (protocol_version() <= SPDY3) { |
2193 builder.WriteControlFrameHeader(*this, GOAWAY, kNoFlags); | 2340 builder.WriteControlFrameHeader(*this, GOAWAY, kNoFlags); |
2194 } else { | 2341 } else { |
2195 builder.WriteFramePrefix(*this, GOAWAY, 0, 0); | 2342 builder.WriteFramePrefix(*this, GOAWAY, 0, 0); |
2196 } | 2343 } |
2197 | 2344 |
2198 // GOAWAY frames specify the last good stream id for all SPDY versions. | 2345 // GOAWAY frames specify the last good stream id for all SPDY versions. |
2199 builder.WriteUInt32(goaway.last_good_stream_id()); | 2346 builder.WriteUInt32(goaway.last_good_stream_id()); |
2200 | 2347 |
2201 // In SPDY3 and up, GOAWAY frames also specify the error status code. | 2348 // In SPDY3 and up, GOAWAY frames also specify the error status code. |
2202 if (protocol_version() >= 3) { | 2349 if (protocol_version() >= SPDY3) { |
2203 builder.WriteUInt32(goaway.status()); | 2350 builder.WriteUInt32(goaway.status()); |
2204 } | 2351 } |
2205 | 2352 |
2206 // In SPDY4 and up, GOAWAY frames may also specify opaque data. | 2353 // In SPDY4 and up, GOAWAY frames may also specify opaque data. |
2207 if ((protocol_version() >= 4) && (goaway.description().size() > 0)) { | 2354 if ((protocol_version() > SPDY3) && (goaway.description().size() > 0)) { |
2208 builder.WriteBytes(goaway.description().data(), | 2355 builder.WriteBytes(goaway.description().data(), |
2209 goaway.description().size()); | 2356 goaway.description().size()); |
2210 } | 2357 } |
2211 | 2358 |
2212 DCHECK_EQ(expected_length, builder.length()); | 2359 DCHECK_EQ(expected_length, builder.length()); |
2213 return builder.take(); | 2360 return builder.take(); |
2214 } | 2361 } |
2215 | 2362 |
2216 SpdySerializedFrame* SpdyFramer::SerializeHeaders( | 2363 SpdySerializedFrame* SpdyFramer::SerializeHeaders( |
2217 const SpdyHeadersIR& headers) { | 2364 const SpdyHeadersIR& headers) { |
2218 uint8 flags = 0; | 2365 uint8 flags = 0; |
2219 if (headers.fin()) { | 2366 if (headers.fin()) { |
2220 flags |= CONTROL_FLAG_FIN; | 2367 flags |= CONTROL_FLAG_FIN; |
2221 } | 2368 } |
2222 if (spdy_version_ >= 4) { | 2369 if (protocol_version() > SPDY3) { |
2223 if (headers.end_headers()) { | 2370 if (headers.end_headers()) { |
2224 flags |= HEADERS_FLAG_END_HEADERS; | 2371 flags |= HEADERS_FLAG_END_HEADERS; |
2225 } | 2372 } |
2226 if (headers.has_priority()) { | 2373 if (headers.has_priority()) { |
2227 flags |= HEADERS_FLAG_PRIORITY; | 2374 flags |= HEADERS_FLAG_PRIORITY; |
2228 } | 2375 } |
2229 } | 2376 } |
2230 | 2377 |
2231 // The size of this frame, including variable-length name-value block. | 2378 // The size of this frame, including variable-length name-value block. |
2232 size_t size = GetHeadersMinimumSize(); | 2379 size_t size = GetHeadersMinimumSize(); |
2233 | 2380 |
2234 uint32 priority = headers.priority(); | 2381 uint32 priority = headers.priority(); |
2235 if (headers.has_priority()) { | 2382 if (headers.has_priority()) { |
2236 if (priority > GetLowestPriority()) { | 2383 if (priority > GetLowestPriority()) { |
2237 DLOG(DFATAL) << "Priority out-of-bounds."; | 2384 DLOG(DFATAL) << "Priority out-of-bounds."; |
2238 priority = GetLowestPriority(); | 2385 priority = GetLowestPriority(); |
2239 } | 2386 } |
2240 size += 4; | 2387 size += 4; |
2241 } | 2388 } |
2242 | 2389 |
2243 string hpack_encoding; | 2390 string hpack_encoding; |
2244 if (spdy_version_ >= 4) { | 2391 if (protocol_version() > SPDY3) { |
2245 hpack_encoder_.EncodeHeaderSet(headers.name_value_block(), &hpack_encoding); | 2392 hpack_encoder_.EncodeHeaderSet(headers.name_value_block(), &hpack_encoding); |
2246 size += hpack_encoding.size(); | 2393 size += hpack_encoding.size(); |
2247 } else { | 2394 } else { |
2248 size += GetSerializedLength(headers.name_value_block()); | 2395 size += GetSerializedLength(headers.name_value_block()); |
2249 } | 2396 } |
2250 | 2397 |
2251 SpdyFrameBuilder builder(size); | 2398 SpdyFrameBuilder builder(size); |
2252 if (spdy_version_ < 4) { | 2399 if (protocol_version() <= SPDY3) { |
2253 builder.WriteControlFrameHeader(*this, HEADERS, flags); | 2400 builder.WriteControlFrameHeader(*this, HEADERS, flags); |
2254 builder.WriteUInt32(headers.stream_id()); | 2401 builder.WriteUInt32(headers.stream_id()); |
2255 } else { | 2402 } else { |
2256 builder.WriteFramePrefix(*this, | 2403 builder.WriteFramePrefix(*this, |
2257 HEADERS, | 2404 HEADERS, |
2258 flags, | 2405 flags, |
2259 headers.stream_id()); | 2406 headers.stream_id()); |
2260 if (headers.has_priority()) { | 2407 if (headers.has_priority()) { |
2261 builder.WriteUInt32(priority); | 2408 builder.WriteUInt32(priority); |
2262 } | 2409 } |
2263 } | 2410 } |
2264 if (protocol_version() < 3) { | 2411 if (protocol_version() <= SPDY2) { |
2265 builder.WriteUInt16(0); // Unused. | 2412 builder.WriteUInt16(0); // Unused. |
2266 } | 2413 } |
2267 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); | 2414 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); |
2268 | 2415 |
2269 if (spdy_version_ >= 4) { | 2416 if (protocol_version() > SPDY3) { |
2270 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); | 2417 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); |
2271 } else { | 2418 } else { |
2272 SerializeNameValueBlock(&builder, headers); | 2419 SerializeNameValueBlock(&builder, headers); |
2273 } | 2420 } |
2274 | 2421 |
2275 if (debug_visitor_) { | 2422 if (debug_visitor_) { |
2276 const size_t payload_len = spdy_version_ >= 4 ? hpack_encoding.size() : | 2423 const size_t payload_len = protocol_version() > SPDY3 ? |
| 2424 hpack_encoding.size() : |
2277 GetSerializedLength(protocol_version(), | 2425 GetSerializedLength(protocol_version(), |
2278 &(headers.name_value_block())); | 2426 &(headers.name_value_block())); |
2279 debug_visitor_->OnSendCompressedFrame(headers.stream_id(), | 2427 debug_visitor_->OnSendCompressedFrame(headers.stream_id(), |
2280 HEADERS, | 2428 HEADERS, |
2281 payload_len, | 2429 payload_len, |
2282 builder.length()); | 2430 builder.length()); |
2283 } | 2431 } |
2284 | 2432 |
2285 return builder.take(); | 2433 return builder.take(); |
2286 } | 2434 } |
2287 | 2435 |
2288 SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate( | 2436 SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate( |
2289 const SpdyWindowUpdateIR& window_update) const { | 2437 const SpdyWindowUpdateIR& window_update) const { |
2290 SpdyFrameBuilder builder(GetWindowUpdateSize()); | 2438 SpdyFrameBuilder builder(GetWindowUpdateSize()); |
2291 if (spdy_version_ < 4) { | 2439 if (protocol_version() <= SPDY3) { |
2292 builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags); | 2440 builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags); |
2293 builder.WriteUInt32(window_update.stream_id()); | 2441 builder.WriteUInt32(window_update.stream_id()); |
2294 } else { | 2442 } else { |
2295 builder.WriteFramePrefix(*this, | 2443 builder.WriteFramePrefix(*this, |
2296 WINDOW_UPDATE, | 2444 WINDOW_UPDATE, |
2297 kNoFlags, | 2445 kNoFlags, |
2298 window_update.stream_id()); | 2446 window_update.stream_id()); |
2299 } | 2447 } |
2300 builder.WriteUInt32(window_update.delta()); | 2448 builder.WriteUInt32(window_update.delta()); |
2301 DCHECK_EQ(GetWindowUpdateSize(), builder.length()); | 2449 DCHECK_EQ(GetWindowUpdateSize(), builder.length()); |
2302 return builder.take(); | 2450 return builder.take(); |
2303 } | 2451 } |
2304 | 2452 |
2305 SpdyFrame* SpdyFramer::SerializePushPromise( | 2453 SpdyFrame* SpdyFramer::SerializePushPromise( |
2306 const SpdyPushPromiseIR& push_promise) { | 2454 const SpdyPushPromiseIR& push_promise) { |
2307 DCHECK_LE(4, protocol_version()); | 2455 DCHECK_LT(SPDY3, protocol_version()); |
2308 uint8 flags = 0; | 2456 uint8 flags = 0; |
2309 if (push_promise.end_push_promise()) { | 2457 if (push_promise.end_push_promise()) { |
2310 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE; | 2458 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE; |
2311 } | 2459 } |
2312 // The size of this frame, including variable-length name-value block. | 2460 // The size of this frame, including variable-length name-value block. |
2313 size_t size = GetPushPromiseMinimumSize(); | 2461 size_t size = GetPushPromiseMinimumSize(); |
2314 | 2462 |
2315 string hpack_encoding; | 2463 string hpack_encoding; |
2316 if (spdy_version_ >= 4) { | 2464 if (protocol_version() > SPDY3) { |
2317 hpack_encoder_.EncodeHeaderSet(push_promise.name_value_block(), | 2465 hpack_encoder_.EncodeHeaderSet(push_promise.name_value_block(), |
2318 &hpack_encoding); | 2466 &hpack_encoding); |
2319 size += hpack_encoding.size(); | 2467 size += hpack_encoding.size(); |
2320 } else { | 2468 } else { |
2321 size += GetSerializedLength(push_promise.name_value_block()); | 2469 size += GetSerializedLength(push_promise.name_value_block()); |
2322 } | 2470 } |
2323 | 2471 |
2324 SpdyFrameBuilder builder(size); | 2472 SpdyFrameBuilder builder(size); |
2325 builder.WriteFramePrefix(*this, PUSH_PROMISE, flags, | 2473 builder.WriteFramePrefix(*this, PUSH_PROMISE, flags, |
2326 push_promise.stream_id()); | 2474 push_promise.stream_id()); |
2327 builder.WriteUInt32(push_promise.promised_stream_id()); | 2475 builder.WriteUInt32(push_promise.promised_stream_id()); |
2328 DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length()); | 2476 DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length()); |
2329 | 2477 |
2330 if (spdy_version_ >= 4) { | 2478 if (protocol_version() > SPDY3) { |
2331 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); | 2479 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); |
2332 } else { | 2480 } else { |
2333 SerializeNameValueBlock(&builder, push_promise); | 2481 SerializeNameValueBlock(&builder, push_promise); |
2334 } | 2482 } |
2335 | 2483 |
2336 if (debug_visitor_) { | 2484 if (debug_visitor_) { |
2337 const size_t payload_len = spdy_version_ >= 4 ? hpack_encoding.size() : | 2485 const size_t payload_len = protocol_version() > SPDY3 ? |
| 2486 hpack_encoding.size() : |
2338 GetSerializedLength(protocol_version(), | 2487 GetSerializedLength(protocol_version(), |
2339 &(push_promise.name_value_block())); | 2488 &(push_promise.name_value_block())); |
2340 debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(), | 2489 debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(), |
2341 PUSH_PROMISE, payload_len, builder.length()); | 2490 PUSH_PROMISE, payload_len, builder.length()); |
2342 } | 2491 } |
2343 | 2492 |
2344 return builder.take(); | 2493 return builder.take(); |
2345 } | 2494 } |
2346 | 2495 |
2347 // TODO(jgraettinger): This implementation is incorrect. The continuation | 2496 // TODO(jgraettinger): This implementation is incorrect. The continuation |
2348 // frame continues a previously-begun HPACK encoding; it doesn't begin a | 2497 // frame continues a previously-begun HPACK encoding; it doesn't begin a |
2349 // new one. Figure out whether it makes sense to keep SerializeContinuation(). | 2498 // new one. Figure out whether it makes sense to keep SerializeContinuation(). |
2350 SpdyFrame* SpdyFramer::SerializeContinuation( | 2499 SpdyFrame* SpdyFramer::SerializeContinuation( |
2351 const SpdyContinuationIR& continuation) { | 2500 const SpdyContinuationIR& continuation) { |
2352 CHECK_GE(spdy_version_, 4); | 2501 CHECK_LT(SPDY3, protocol_version()); |
2353 uint8 flags = 0; | 2502 uint8 flags = 0; |
2354 if (continuation.end_headers()) { | 2503 if (continuation.end_headers()) { |
2355 flags |= HEADERS_FLAG_END_HEADERS; | 2504 flags |= HEADERS_FLAG_END_HEADERS; |
2356 } | 2505 } |
2357 | 2506 |
2358 // The size of this frame, including variable-length name-value block. | 2507 // The size of this frame, including variable-length name-value block. |
2359 size_t size = GetContinuationMinimumSize(); | 2508 size_t size = GetContinuationMinimumSize(); |
2360 string hpack_encoding; | 2509 string hpack_encoding; |
2361 hpack_encoder_.EncodeHeaderSet(continuation.name_value_block(), | 2510 hpack_encoder_.EncodeHeaderSet(continuation.name_value_block(), |
2362 &hpack_encoding); | 2511 &hpack_encoding); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2434 | 2583 |
2435 } // namespace | 2584 } // namespace |
2436 | 2585 |
2437 SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) { | 2586 SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) { |
2438 FrameSerializationVisitor visitor(this); | 2587 FrameSerializationVisitor visitor(this); |
2439 frame.Visit(&visitor); | 2588 frame.Visit(&visitor); |
2440 return visitor.ReleaseSerializedFrame(); | 2589 return visitor.ReleaseSerializedFrame(); |
2441 } | 2590 } |
2442 | 2591 |
2443 size_t SpdyFramer::GetSerializedLength(const SpdyHeaderBlock& headers) { | 2592 size_t SpdyFramer::GetSerializedLength(const SpdyHeaderBlock& headers) { |
2444 CHECK_LT(spdy_version_, 4); | 2593 CHECK_GE(SPDY3, protocol_version()); |
2445 const size_t uncompressed_length = | 2594 const size_t uncompressed_length = |
2446 GetSerializedLength(protocol_version(), &headers); | 2595 GetSerializedLength(protocol_version(), &headers); |
2447 if (!enable_compression_) { | 2596 if (!enable_compression_) { |
2448 return uncompressed_length; | 2597 return uncompressed_length; |
2449 } | 2598 } |
2450 z_stream* compressor = GetHeaderCompressor(); | 2599 z_stream* compressor = GetHeaderCompressor(); |
2451 // Since we'll be performing lots of flushes when compressing the data, | 2600 // Since we'll be performing lots of flushes when compressing the data, |
2452 // zlib's lower bounds may be insufficient. | 2601 // zlib's lower bounds may be insufficient. |
2453 return 2 * deflateBound(compressor, uncompressed_length); | 2602 return 2 * deflateBound(compressor, uncompressed_length); |
2454 } | 2603 } |
(...skipping 19 matching lines...) Expand all Loading... |
2474 header_compressor_.reset(new z_stream); | 2623 header_compressor_.reset(new z_stream); |
2475 memset(header_compressor_.get(), 0, sizeof(z_stream)); | 2624 memset(header_compressor_.get(), 0, sizeof(z_stream)); |
2476 | 2625 |
2477 int success = deflateInit2(header_compressor_.get(), | 2626 int success = deflateInit2(header_compressor_.get(), |
2478 kCompressorLevel, | 2627 kCompressorLevel, |
2479 Z_DEFLATED, | 2628 Z_DEFLATED, |
2480 kCompressorWindowSizeInBits, | 2629 kCompressorWindowSizeInBits, |
2481 kCompressorMemLevel, | 2630 kCompressorMemLevel, |
2482 Z_DEFAULT_STRATEGY); | 2631 Z_DEFAULT_STRATEGY); |
2483 if (success == Z_OK) { | 2632 if (success == Z_OK) { |
2484 const char* dictionary = (spdy_version_ < 3) ? kV2Dictionary | 2633 const char* dictionary = (protocol_version() <= SPDY2) ? |
2485 : kV3Dictionary; | 2634 kV2Dictionary : kV3Dictionary; |
2486 const int dictionary_size = (spdy_version_ < 3) ? kV2DictionarySize | 2635 const int dictionary_size = (protocol_version() <= SPDY2) ? |
2487 : kV3DictionarySize; | 2636 kV2DictionarySize : kV3DictionarySize; |
2488 success = deflateSetDictionary(header_compressor_.get(), | 2637 success = deflateSetDictionary(header_compressor_.get(), |
2489 reinterpret_cast<const Bytef*>(dictionary), | 2638 reinterpret_cast<const Bytef*>(dictionary), |
2490 dictionary_size); | 2639 dictionary_size); |
2491 } | 2640 } |
2492 if (success != Z_OK) { | 2641 if (success != Z_OK) { |
2493 LOG(WARNING) << "deflateSetDictionary failure: " << success; | 2642 LOG(WARNING) << "deflateSetDictionary failure: " << success; |
2494 header_compressor_.reset(NULL); | 2643 header_compressor_.reset(NULL); |
2495 return NULL; | 2644 return NULL; |
2496 } | 2645 } |
2497 return header_compressor_.get(); | 2646 return header_compressor_.get(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2537 // If we get a SYN_STREAM/SYN_REPLY/HEADERS frame with stream ID zero, we | 2686 // If we get a SYN_STREAM/SYN_REPLY/HEADERS frame with stream ID zero, we |
2538 // signal an error back in ProcessControlFrameBeforeHeaderBlock. So if we've | 2687 // signal an error back in ProcessControlFrameBeforeHeaderBlock. So if we've |
2539 // reached this method successfully, stream_id should be nonzero. | 2688 // reached this method successfully, stream_id should be nonzero. |
2540 DCHECK_LT(0u, stream_id); | 2689 DCHECK_LT(0u, stream_id); |
2541 while (decomp->avail_in > 0 && processed_successfully) { | 2690 while (decomp->avail_in > 0 && processed_successfully) { |
2542 decomp->next_out = reinterpret_cast<Bytef*>(buffer); | 2691 decomp->next_out = reinterpret_cast<Bytef*>(buffer); |
2543 decomp->avail_out = arraysize(buffer); | 2692 decomp->avail_out = arraysize(buffer); |
2544 | 2693 |
2545 int rv = inflate(decomp, Z_SYNC_FLUSH); | 2694 int rv = inflate(decomp, Z_SYNC_FLUSH); |
2546 if (rv == Z_NEED_DICT) { | 2695 if (rv == Z_NEED_DICT) { |
2547 const char* dictionary = (spdy_version_ < 3) ? kV2Dictionary | 2696 const char* dictionary = (protocol_version() <= SPDY2) ? kV2Dictionary |
2548 : kV3Dictionary; | 2697 : kV3Dictionary; |
2549 const int dictionary_size = (spdy_version_ < 3) ? kV2DictionarySize | 2698 const int dictionary_size = (protocol_version() <= SPDY2) ? |
2550 : kV3DictionarySize; | 2699 kV2DictionarySize : kV3DictionarySize; |
2551 const DictionaryIds& ids = g_dictionary_ids.Get(); | 2700 const DictionaryIds& ids = g_dictionary_ids.Get(); |
2552 const uLong dictionary_id = (spdy_version_ < 3) ? ids.v2_dictionary_id | 2701 const uLong dictionary_id = (protocol_version() <= SPDY2) ? |
2553 : ids.v3_dictionary_id; | 2702 ids.v2_dictionary_id : ids.v3_dictionary_id; |
2554 // Need to try again with the right dictionary. | 2703 // Need to try again with the right dictionary. |
2555 if (decomp->adler == dictionary_id) { | 2704 if (decomp->adler == dictionary_id) { |
2556 rv = inflateSetDictionary(decomp, | 2705 rv = inflateSetDictionary(decomp, |
2557 reinterpret_cast<const Bytef*>(dictionary), | 2706 reinterpret_cast<const Bytef*>(dictionary), |
2558 dictionary_size); | 2707 dictionary_size); |
2559 if (rv == Z_OK) | 2708 if (rv == Z_OK) |
2560 rv = inflate(decomp, Z_SYNC_FLUSH); | 2709 rv = inflate(decomp, Z_SYNC_FLUSH); |
2561 } | 2710 } |
2562 } | 2711 } |
2563 | 2712 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2601 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); | 2750 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); |
2602 } | 2751 } |
2603 } | 2752 } |
2604 return read_successfully; | 2753 return read_successfully; |
2605 } | 2754 } |
2606 | 2755 |
2607 void SpdyFramer::SerializeNameValueBlockWithoutCompression( | 2756 void SpdyFramer::SerializeNameValueBlockWithoutCompression( |
2608 SpdyFrameBuilder* builder, | 2757 SpdyFrameBuilder* builder, |
2609 const SpdyNameValueBlock& name_value_block) const { | 2758 const SpdyNameValueBlock& name_value_block) const { |
2610 // Serialize number of headers. | 2759 // Serialize number of headers. |
2611 if (protocol_version() < 3) { | 2760 if (protocol_version() <= SPDY2) { |
2612 builder->WriteUInt16(name_value_block.size()); | 2761 builder->WriteUInt16(name_value_block.size()); |
2613 } else { | 2762 } else { |
2614 builder->WriteUInt32(name_value_block.size()); | 2763 builder->WriteUInt32(name_value_block.size()); |
2615 } | 2764 } |
2616 | 2765 |
2617 // Serialize each header. | 2766 // Serialize each header. |
2618 for (SpdyHeaderBlock::const_iterator it = name_value_block.begin(); | 2767 for (SpdyHeaderBlock::const_iterator it = name_value_block.begin(); |
2619 it != name_value_block.end(); | 2768 it != name_value_block.end(); |
2620 ++it) { | 2769 ++it) { |
2621 if (protocol_version() < 3) { | 2770 if (protocol_version() <= SPDY2) { |
2622 builder->WriteString(it->first); | 2771 builder->WriteString(it->first); |
2623 builder->WriteString(it->second); | 2772 builder->WriteString(it->second); |
2624 } else { | 2773 } else { |
2625 builder->WriteStringPiece32(it->first); | 2774 builder->WriteStringPiece32(it->first); |
2626 builder->WriteStringPiece32(it->second); | 2775 builder->WriteStringPiece32(it->second); |
2627 } | 2776 } |
2628 } | 2777 } |
2629 } | 2778 } |
2630 | 2779 |
2631 void SpdyFramer::SerializeNameValueBlock( | 2780 void SpdyFramer::SerializeNameValueBlock( |
2632 SpdyFrameBuilder* builder, | 2781 SpdyFrameBuilder* builder, |
2633 const SpdyFrameWithNameValueBlockIR& frame) { | 2782 const SpdyFrameWithNameValueBlockIR& frame) { |
2634 CHECK_LT(spdy_version_, 4); | 2783 CHECK_GE(SPDY3, protocol_version()); |
2635 if (!enable_compression_) { | 2784 if (!enable_compression_) { |
2636 return SerializeNameValueBlockWithoutCompression(builder, | 2785 return SerializeNameValueBlockWithoutCompression(builder, |
2637 frame.name_value_block()); | 2786 frame.name_value_block()); |
2638 } | 2787 } |
2639 | 2788 |
2640 // First build an uncompressed version to be fed into the compressor. | 2789 // First build an uncompressed version to be fed into the compressor. |
2641 const size_t uncompressed_len = GetSerializedLength( | 2790 const size_t uncompressed_len = GetSerializedLength( |
2642 protocol_version(), &(frame.name_value_block())); | 2791 protocol_version(), &(frame.name_value_block())); |
2643 SpdyFrameBuilder uncompressed_builder(uncompressed_len); | 2792 SpdyFrameBuilder uncompressed_builder(uncompressed_len); |
2644 SerializeNameValueBlockWithoutCompression(&uncompressed_builder, | 2793 SerializeNameValueBlockWithoutCompression(&uncompressed_builder, |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2692 builder->Seek(compressed_size); | 2841 builder->Seek(compressed_size); |
2693 builder->RewriteLength(*this); | 2842 builder->RewriteLength(*this); |
2694 | 2843 |
2695 pre_compress_bytes.Add(uncompressed_len); | 2844 pre_compress_bytes.Add(uncompressed_len); |
2696 post_compress_bytes.Add(compressed_size); | 2845 post_compress_bytes.Add(compressed_size); |
2697 | 2846 |
2698 compressed_frames.Increment(); | 2847 compressed_frames.Increment(); |
2699 } | 2848 } |
2700 | 2849 |
2701 } // namespace net | 2850 } // namespace net |
OLD | NEW |