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 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 state_ = SPDY_RESET; | 148 state_ = SPDY_RESET; |
149 previous_state_ = SPDY_RESET; | 149 previous_state_ = SPDY_RESET; |
150 error_code_ = SPDY_NO_ERROR; | 150 error_code_ = SPDY_NO_ERROR; |
151 remaining_data_ = 0; | 151 remaining_data_ = 0; |
152 remaining_control_payload_ = 0; | 152 remaining_control_payload_ = 0; |
153 remaining_control_header_ = 0; | 153 remaining_control_header_ = 0; |
154 current_frame_len_ = 0; | 154 current_frame_len_ = 0; |
155 settings_scratch_.Reset(); | 155 settings_scratch_.Reset(); |
156 } | 156 } |
157 | 157 |
| 158 size_t SpdyFramer::GetControlFrameMinimumSize() const { |
| 159 // Size, in bytes, of the control frame header. Future versions of SPDY |
| 160 // will likely vary this, so we allow for the flexibility of a function call |
| 161 // for this value as opposed to a constant. |
| 162 return 8; |
| 163 } |
| 164 |
| 165 size_t SpdyFramer::GetSynStreamMinimumSize() const { |
| 166 // Size, in bytes, of a SYN_STREAM frame not including the variable-length |
| 167 // name-value block. Calculated as: |
| 168 // control frame header + 2 * 4 (stream IDs) + 1 (priority) + 1 (slot) |
| 169 return GetControlFrameMinimumSize() + 10; |
| 170 } |
| 171 |
| 172 size_t SpdyFramer::GetSynReplyMinimumSize() const { |
| 173 // Size, in bytes, of a SYN_REPLY frame not including the variable-length |
| 174 // name-value block. Calculated as: |
| 175 // control frame header + 4 (stream ID) |
| 176 size_t size = GetControlFrameMinimumSize() + 4; |
| 177 |
| 178 // In SPDY 2, there were 2 unused bytes before payload. |
| 179 if (protocol_version() < 3) { |
| 180 size += 2; |
| 181 } |
| 182 |
| 183 return size; |
| 184 } |
| 185 |
| 186 size_t SpdyFramer::GetRstStreamSize() const { |
| 187 // Size, in bytes, of a RST_STREAM frame. Calculated as: |
| 188 // control frame header + 4 (stream id) + 4 (status code) |
| 189 return GetControlFrameMinimumSize() + 8; |
| 190 } |
| 191 |
| 192 size_t SpdyFramer::GetSettingsMinimumSize() const { |
| 193 // Size, in bytes, of a SETTINGS frame not including the IDs and values |
| 194 // from the variable-length value block. Calculated as: |
| 195 // control frame header + 4 (number of ID/value pairs) |
| 196 return GetControlFrameMinimumSize() + 4; |
| 197 } |
| 198 |
| 199 size_t SpdyFramer::GetPingSize() const { |
| 200 // Size, in bytes, of this PING frame. Calculated as: |
| 201 // control frame header + 4 (id) |
| 202 return GetControlFrameMinimumSize() + 4; |
| 203 } |
| 204 |
| 205 size_t SpdyFramer::GetGoAwaySize() const { |
| 206 // Size, in bytes, of this GOAWAY frame. Calculated as: |
| 207 // control frame header + 4 (last good stream id) |
| 208 size_t size = GetControlFrameMinimumSize() + 4; |
| 209 |
| 210 // SPDY 3+ GOAWAY frames also contain a status. |
| 211 if (protocol_version() >= 3) { |
| 212 size += 4; |
| 213 } |
| 214 |
| 215 return size; |
| 216 } |
| 217 |
| 218 size_t SpdyFramer::GetHeadersMinimumSize() const { |
| 219 // Size, in bytes, of a HEADERS frame not including the variable-length |
| 220 // name-value block. Calculated as: |
| 221 // control frame header + 4 (stream ID) |
| 222 size_t size = GetControlFrameMinimumSize() + 4; |
| 223 |
| 224 // In SPDY 2, there were 2 unused bytes before payload. |
| 225 if (protocol_version() < 3) { |
| 226 size += 2; |
| 227 } |
| 228 |
| 229 return size; |
| 230 } |
| 231 |
| 232 size_t SpdyFramer::GetWindowUpdateSize() const { |
| 233 // Size, in bytes, of this WINDOW_UPDATE frame. Calculated as: |
| 234 // control frame header + 4 (stream id) + 4 (delta) |
| 235 return GetControlFrameMinimumSize() + 8; |
| 236 } |
| 237 |
| 238 size_t SpdyFramer::GetCredentialMinimumSize() const { |
| 239 // Size, in bytes, of a CREDENTIAL frame sans variable-length certificate list |
| 240 // and proof. Calculated as: |
| 241 // control frame header + 2 (slot) |
| 242 return GetControlFrameMinimumSize() + 2; |
| 243 } |
| 244 |
158 const char* SpdyFramer::StateToString(int state) { | 245 const char* SpdyFramer::StateToString(int state) { |
159 switch (state) { | 246 switch (state) { |
160 case SPDY_ERROR: | 247 case SPDY_ERROR: |
161 return "ERROR"; | 248 return "ERROR"; |
162 case SPDY_DONE: | 249 case SPDY_DONE: |
163 return "DONE"; | 250 return "DONE"; |
164 case SPDY_AUTO_RESET: | 251 case SPDY_AUTO_RESET: |
165 return "AUTO_RESET"; | 252 return "AUTO_RESET"; |
166 case SPDY_RESET: | 253 case SPDY_RESET: |
167 return "RESET"; | 254 return "RESET"; |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 if (current_control_frame.type() == NOOP) { | 548 if (current_control_frame.type() == NOOP) { |
462 DLOG(INFO) << "NOOP control frame found. Ignoring."; | 549 DLOG(INFO) << "NOOP control frame found. Ignoring."; |
463 CHANGE_STATE(SPDY_AUTO_RESET); | 550 CHANGE_STATE(SPDY_AUTO_RESET); |
464 return; | 551 return; |
465 } | 552 } |
466 | 553 |
467 // Do some sanity checking on the control frame sizes. | 554 // Do some sanity checking on the control frame sizes. |
468 switch (current_control_frame.type()) { | 555 switch (current_control_frame.type()) { |
469 case SYN_STREAM: | 556 case SYN_STREAM: |
470 if (current_control_frame.length() < | 557 if (current_control_frame.length() < |
471 SpdySynStreamControlFrame::size() - SpdyControlFrame::kHeaderSize) { | 558 GetSynStreamMinimumSize() - SpdyControlFrame::kHeaderSize) { |
472 set_error(SPDY_INVALID_CONTROL_FRAME); | 559 set_error(SPDY_INVALID_CONTROL_FRAME); |
473 } else if (current_control_frame.flags() & | 560 } else if (current_control_frame.flags() & |
474 ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) { | 561 ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) { |
475 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 562 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
476 } | 563 } |
477 break; | 564 break; |
478 case SYN_REPLY: | 565 case SYN_REPLY: |
479 if (current_control_frame.length() < | 566 if (current_control_frame.length() < |
480 SpdySynReplyControlFrame::size() - SpdyControlFrame::kHeaderSize) { | 567 GetSynReplyMinimumSize() - SpdyControlFrame::kHeaderSize) { |
481 set_error(SPDY_INVALID_CONTROL_FRAME); | 568 set_error(SPDY_INVALID_CONTROL_FRAME); |
482 } else if (current_control_frame.flags() & ~CONTROL_FLAG_FIN) { | 569 } else if (current_control_frame.flags() & ~CONTROL_FLAG_FIN) { |
483 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 570 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
484 } | 571 } |
485 break; | 572 break; |
486 case RST_STREAM: | 573 case RST_STREAM: |
487 if (current_control_frame.length() != | 574 if (current_control_frame.length() != |
488 SpdyRstStreamControlFrame::size() - SpdyFrame::kHeaderSize) { | 575 GetRstStreamSize() - SpdyFrame::kHeaderSize) { |
489 set_error(SPDY_INVALID_CONTROL_FRAME); | 576 set_error(SPDY_INVALID_CONTROL_FRAME); |
490 } else if (current_control_frame.flags() != 0) { | 577 } else if (current_control_frame.flags() != 0) { |
491 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 578 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
492 } | 579 } |
493 break; | 580 break; |
494 case SETTINGS: | 581 case SETTINGS: |
495 // Make sure that we have an integral number of 8-byte key/value pairs, | 582 // Make sure that we have an integral number of 8-byte key/value pairs, |
496 // plus a 4-byte length field. | 583 // plus a 4-byte length field. |
497 if (current_control_frame.length() < | 584 if (current_control_frame.length() < |
498 SpdySettingsControlFrame::size() - SpdyControlFrame::kHeaderSize || | 585 GetSettingsMinimumSize() - SpdyControlFrame::kHeaderSize || |
499 (current_control_frame.length() % 8 != 4)) { | 586 (current_control_frame.length() % 8 != 4)) { |
500 DLOG(WARNING) << "Invalid length for SETTINGS frame: " | 587 DLOG(WARNING) << "Invalid length for SETTINGS frame: " |
501 << current_control_frame.length(); | 588 << current_control_frame.length(); |
502 set_error(SPDY_INVALID_CONTROL_FRAME); | 589 set_error(SPDY_INVALID_CONTROL_FRAME); |
503 } else if (current_control_frame.flags() & | 590 } else if (current_control_frame.flags() & |
504 ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) { | 591 ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) { |
505 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 592 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
506 } | 593 } |
507 break; | 594 break; |
508 case GOAWAY: | 595 case GOAWAY: |
509 { | 596 { |
510 // SPDY 2 GOAWAY frames are 4 bytes smaller than in SPDY 3. We account | 597 if (current_control_frame.length() != |
511 // for this difference via a separate offset variable, since | 598 GetGoAwaySize() - SpdyFrame::kHeaderSize) { |
512 // SpdyGoAwayControlFrame::size() returns the SPDY 3 size. | |
513 const size_t goaway_offset = (protocol_version() < 3) ? 4 : 0; | |
514 if (current_control_frame.length() + goaway_offset != | |
515 SpdyGoAwayControlFrame::size() - SpdyFrame::kHeaderSize) { | |
516 set_error(SPDY_INVALID_CONTROL_FRAME); | 599 set_error(SPDY_INVALID_CONTROL_FRAME); |
517 } else if (current_control_frame.flags() != 0) { | 600 } else if (current_control_frame.flags() != 0) { |
518 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 601 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
519 } | 602 } |
520 break; | 603 break; |
521 } | 604 } |
522 case HEADERS: | 605 case HEADERS: |
523 if (current_control_frame.length() < | 606 if (current_control_frame.length() < |
524 SpdyHeadersControlFrame::size() - SpdyControlFrame::kHeaderSize) { | 607 GetHeadersMinimumSize() - SpdyControlFrame::kHeaderSize) { |
525 set_error(SPDY_INVALID_CONTROL_FRAME); | 608 set_error(SPDY_INVALID_CONTROL_FRAME); |
526 } else if (current_control_frame.flags() & ~CONTROL_FLAG_FIN) { | 609 } else if (current_control_frame.flags() & ~CONTROL_FLAG_FIN) { |
527 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 610 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
528 } | 611 } |
529 break; | 612 break; |
530 case WINDOW_UPDATE: | 613 case WINDOW_UPDATE: |
531 if (current_control_frame.length() != | 614 if (current_control_frame.length() != |
532 SpdyWindowUpdateControlFrame::size() - | 615 GetWindowUpdateSize() - SpdyControlFrame::kHeaderSize) { |
533 SpdyControlFrame::kHeaderSize) { | |
534 set_error(SPDY_INVALID_CONTROL_FRAME); | 616 set_error(SPDY_INVALID_CONTROL_FRAME); |
535 } else if (current_control_frame.flags() != 0) { | 617 } else if (current_control_frame.flags() != 0) { |
536 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 618 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
537 } | 619 } |
538 break; | 620 break; |
539 case PING: | 621 case PING: |
540 if (current_control_frame.length() != | 622 if (current_control_frame.length() != |
541 SpdyPingControlFrame::size() - SpdyControlFrame::kHeaderSize) { | 623 GetPingSize() - SpdyControlFrame::kHeaderSize) { |
542 set_error(SPDY_INVALID_CONTROL_FRAME); | 624 set_error(SPDY_INVALID_CONTROL_FRAME); |
543 } else if (current_control_frame.flags() != 0) { | 625 } else if (current_control_frame.flags() != 0) { |
544 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 626 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
545 } | 627 } |
546 break; | 628 break; |
547 case CREDENTIAL: | 629 case CREDENTIAL: |
548 if (current_control_frame.length() < | 630 if (current_control_frame.length() < |
549 SpdyCredentialControlFrame::size() - SpdyControlFrame::kHeaderSize) { | 631 GetCredentialMinimumSize() - SpdyControlFrame::kHeaderSize) { |
550 set_error(SPDY_INVALID_CONTROL_FRAME); | 632 set_error(SPDY_INVALID_CONTROL_FRAME); |
551 } else if (current_control_frame.flags() != 0) { | 633 } else if (current_control_frame.flags() != 0) { |
552 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 634 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
553 } | 635 } |
554 break; | 636 break; |
555 default: | 637 default: |
556 LOG(WARNING) << "Valid " << display_protocol_ | 638 LOG(WARNING) << "Valid " << display_protocol_ |
557 << " control frame with unhandled type: " | 639 << " control frame with unhandled type: " |
558 << current_control_frame.type(); | 640 << current_control_frame.type(); |
559 DLOG(FATAL); | 641 DLOG(FATAL); |
(...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1316 SpdySerializedFrame* SpdyFramer::SerializeSynStream( | 1398 SpdySerializedFrame* SpdyFramer::SerializeSynStream( |
1317 const SpdySynStreamIR& syn_stream) { | 1399 const SpdySynStreamIR& syn_stream) { |
1318 uint8 flags = 0; | 1400 uint8 flags = 0; |
1319 if (syn_stream.fin()) { | 1401 if (syn_stream.fin()) { |
1320 flags |= CONTROL_FLAG_FIN; | 1402 flags |= CONTROL_FLAG_FIN; |
1321 } | 1403 } |
1322 if (syn_stream.unidirectional()) { | 1404 if (syn_stream.unidirectional()) { |
1323 flags |= CONTROL_FLAG_UNIDIRECTIONAL; | 1405 flags |= CONTROL_FLAG_UNIDIRECTIONAL; |
1324 } | 1406 } |
1325 | 1407 |
1326 // The size, in bytes, of this frame not including the variable-length | |
1327 // name-value block. Calculated as: | |
1328 // 8 (control frame header) + 2 * 4 (stream IDs) + 1 (priority) + 1 (slot) | |
1329 const size_t kSynStreamSizeBeforeNameValueBlock = 18; | |
1330 | |
1331 // The size of this frame, including variable-length name-value block. | 1408 // The size of this frame, including variable-length name-value block. |
1332 const size_t size = kSynStreamSizeBeforeNameValueBlock | 1409 const size_t size = GetSynStreamMinimumSize() |
1333 + GetSerializedLength(protocol_version(), | 1410 + GetSerializedLength(protocol_version(), |
1334 &(syn_stream.name_value_block())); | 1411 &(syn_stream.name_value_block())); |
1335 | 1412 |
1336 SpdyFrameBuilder builder(SYN_STREAM, flags, protocol_version(), size); | 1413 SpdyFrameBuilder builder(SYN_STREAM, flags, protocol_version(), size); |
1337 builder.WriteUInt32(syn_stream.stream_id()); | 1414 builder.WriteUInt32(syn_stream.stream_id()); |
1338 builder.WriteUInt32(syn_stream.associated_to_stream_id()); | 1415 builder.WriteUInt32(syn_stream.associated_to_stream_id()); |
1339 uint8 priority = syn_stream.priority(); | 1416 uint8 priority = syn_stream.priority(); |
1340 if (priority > GetLowestPriority()) { | 1417 if (priority > GetLowestPriority()) { |
1341 DLOG(DFATAL) << "Priority out-of-bounds."; | 1418 DLOG(DFATAL) << "Priority out-of-bounds."; |
1342 priority = GetLowestPriority(); | 1419 priority = GetLowestPriority(); |
1343 } | 1420 } |
1344 builder.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5)); | 1421 builder.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5)); |
1345 builder.WriteUInt8(syn_stream.slot()); | 1422 builder.WriteUInt8(syn_stream.slot()); |
1346 DCHECK_EQ(kSynStreamSizeBeforeNameValueBlock, builder.length()); | 1423 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length()); |
1347 SerializeNameValueBlock(&builder, syn_stream); | 1424 SerializeNameValueBlock(&builder, syn_stream); |
1348 | 1425 |
1349 return builder.take(); | 1426 return builder.take(); |
1350 } | 1427 } |
1351 | 1428 |
1352 SpdySynReplyControlFrame* SpdyFramer::CreateSynReply( | 1429 SpdySynReplyControlFrame* SpdyFramer::CreateSynReply( |
1353 SpdyStreamId stream_id, | 1430 SpdyStreamId stream_id, |
1354 SpdyControlFlags flags, | 1431 SpdyControlFlags flags, |
1355 bool compressed, | 1432 bool compressed, |
1356 const SpdyHeaderBlock* headers) { | 1433 const SpdyHeaderBlock* headers) { |
(...skipping 14 matching lines...) Expand all Loading... |
1371 return reply_frame.release(); | 1448 return reply_frame.release(); |
1372 } | 1449 } |
1373 | 1450 |
1374 SpdySerializedFrame* SpdyFramer::SerializeSynReply( | 1451 SpdySerializedFrame* SpdyFramer::SerializeSynReply( |
1375 const SpdySynReplyIR& syn_reply) { | 1452 const SpdySynReplyIR& syn_reply) { |
1376 uint8 flags = 0; | 1453 uint8 flags = 0; |
1377 if (syn_reply.fin()) { | 1454 if (syn_reply.fin()) { |
1378 flags |= CONTROL_FLAG_FIN; | 1455 flags |= CONTROL_FLAG_FIN; |
1379 } | 1456 } |
1380 | 1457 |
1381 // The size, in bytes, of this frame not including the variable-length | |
1382 // name-value block. Calculated as: | |
1383 // 8 (control frame header) + 4 (stream ID) | |
1384 size_t syn_reply_size_before_name_value_block = 12; | |
1385 // In SPDY 2, there were 2 unused bytes before payload. | |
1386 if (protocol_version() < 3) { | |
1387 syn_reply_size_before_name_value_block += 2; | |
1388 } | |
1389 | |
1390 // The size of this frame, including variable-length name-value block. | 1458 // The size of this frame, including variable-length name-value block. |
1391 size_t size = syn_reply_size_before_name_value_block | 1459 size_t size = GetSynReplyMinimumSize() |
1392 + GetSerializedLength(protocol_version(), | 1460 + GetSerializedLength(protocol_version(), |
1393 &(syn_reply.name_value_block())); | 1461 &(syn_reply.name_value_block())); |
1394 | 1462 |
1395 SpdyFrameBuilder builder(SYN_REPLY, flags, protocol_version(), size); | 1463 SpdyFrameBuilder builder(SYN_REPLY, flags, protocol_version(), size); |
1396 builder.WriteUInt32(syn_reply.stream_id()); | 1464 builder.WriteUInt32(syn_reply.stream_id()); |
1397 if (protocol_version() < 3) { | 1465 if (protocol_version() < 3) { |
1398 builder.WriteUInt16(0); // Unused. | 1466 builder.WriteUInt16(0); // Unused. |
1399 } | 1467 } |
1400 DCHECK_EQ(syn_reply_size_before_name_value_block, builder.length()); | 1468 DCHECK_EQ(GetSynReplyMinimumSize(), builder.length()); |
1401 SerializeNameValueBlock(&builder, syn_reply); | 1469 SerializeNameValueBlock(&builder, syn_reply); |
1402 | 1470 |
1403 return builder.take(); | 1471 return builder.take(); |
1404 } | 1472 } |
1405 | 1473 |
1406 SpdyRstStreamControlFrame* SpdyFramer::CreateRstStream( | 1474 SpdyRstStreamControlFrame* SpdyFramer::CreateRstStream( |
1407 SpdyStreamId stream_id, | 1475 SpdyStreamId stream_id, |
1408 SpdyRstStreamStatus status) const { | 1476 SpdyRstStreamStatus status) const { |
1409 SpdyRstStreamIR rst_stream(stream_id, status); | 1477 SpdyRstStreamIR rst_stream(stream_id, status); |
1410 return reinterpret_cast<SpdyRstStreamControlFrame*>( | 1478 return reinterpret_cast<SpdyRstStreamControlFrame*>( |
1411 SerializeRstStream(rst_stream)); | 1479 SerializeRstStream(rst_stream)); |
1412 } | 1480 } |
1413 | 1481 |
1414 SpdySerializedFrame* SpdyFramer::SerializeRstStream( | 1482 SpdySerializedFrame* SpdyFramer::SerializeRstStream( |
1415 const SpdyRstStreamIR& rst_stream) const { | 1483 const SpdyRstStreamIR& rst_stream) const { |
1416 // Size of our RST_STREAM frame. Calculated as: | |
1417 // 8 (control frame header) + 4 (stream id) + 4 (status code) | |
1418 const size_t kRstStreamFrameSize = 16; | |
1419 | |
1420 SpdyFrameBuilder builder(RST_STREAM, | 1484 SpdyFrameBuilder builder(RST_STREAM, |
1421 kNoFlags, | 1485 kNoFlags, |
1422 protocol_version(), | 1486 protocol_version(), |
1423 kRstStreamFrameSize); | 1487 GetRstStreamSize()); |
1424 builder.WriteUInt32(rst_stream.stream_id()); | 1488 builder.WriteUInt32(rst_stream.stream_id()); |
1425 builder.WriteUInt32(rst_stream.status()); | 1489 builder.WriteUInt32(rst_stream.status()); |
1426 DCHECK_EQ(kRstStreamFrameSize, builder.length()); | 1490 DCHECK_EQ(GetRstStreamSize(), builder.length()); |
1427 return builder.take(); | 1491 return builder.take(); |
1428 } | 1492 } |
1429 | 1493 |
1430 SpdySettingsControlFrame* SpdyFramer::CreateSettings( | 1494 SpdySettingsControlFrame* SpdyFramer::CreateSettings( |
1431 const SettingsMap& values) const { | 1495 const SettingsMap& values) const { |
1432 SpdySettingsIR settings; | 1496 SpdySettingsIR settings; |
1433 for (SettingsMap::const_iterator it = values.begin(); | 1497 for (SettingsMap::const_iterator it = values.begin(); |
1434 it != values.end(); | 1498 it != values.end(); |
1435 ++it) { | 1499 ++it) { |
1436 settings.AddSetting(it->first, | 1500 settings.AddSetting(it->first, |
1437 (it->second.first & SETTINGS_FLAG_PLEASE_PERSIST) != 0, | 1501 (it->second.first & SETTINGS_FLAG_PLEASE_PERSIST) != 0, |
1438 (it->second.first & SETTINGS_FLAG_PERSISTED) != 0, | 1502 (it->second.first & SETTINGS_FLAG_PERSISTED) != 0, |
1439 it->second.second); | 1503 it->second.second); |
1440 } | 1504 } |
1441 return reinterpret_cast<SpdySettingsControlFrame*>( | 1505 return reinterpret_cast<SpdySettingsControlFrame*>( |
1442 SerializeSettings(settings)); | 1506 SerializeSettings(settings)); |
1443 } | 1507 } |
1444 | 1508 |
1445 SpdySerializedFrame* SpdyFramer::SerializeSettings( | 1509 SpdySerializedFrame* SpdyFramer::SerializeSettings( |
1446 const SpdySettingsIR& settings) const { | 1510 const SpdySettingsIR& settings) const { |
1447 uint8 flags = 0; | 1511 uint8 flags = 0; |
1448 if (settings.clear_settings()) { | 1512 if (settings.clear_settings()) { |
1449 flags |= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS; | 1513 flags |= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS; |
1450 } | 1514 } |
1451 const SpdySettingsIR::ValueMap* values = &(settings.values()); | 1515 const SpdySettingsIR::ValueMap* values = &(settings.values()); |
1452 | 1516 |
1453 // Size, in bytes, of this SETTINGS frame not including the IDs and values | |
1454 // from the variable-length value block. Calculated as: | |
1455 // 8 (control frame header) + 4 (number of ID/value pairs) | |
1456 const size_t kSettingsSizeWithoutValues = 12; | |
1457 // Size, in bytes, of this SETTINGS frame. | 1517 // Size, in bytes, of this SETTINGS frame. |
1458 const size_t size = kSettingsSizeWithoutValues + (values->size() * 8); | 1518 const size_t size = GetSettingsMinimumSize() + (values->size() * 8); |
1459 | 1519 |
1460 SpdyFrameBuilder builder(SETTINGS, flags, protocol_version(), size); | 1520 SpdyFrameBuilder builder(SETTINGS, flags, protocol_version(), size); |
1461 builder.WriteUInt32(values->size()); | 1521 builder.WriteUInt32(values->size()); |
1462 DCHECK_EQ(kSettingsSizeWithoutValues, builder.length()); | 1522 DCHECK_EQ(GetSettingsMinimumSize(), builder.length()); |
1463 for (SpdySettingsIR::ValueMap::const_iterator it = values->begin(); | 1523 for (SpdySettingsIR::ValueMap::const_iterator it = values->begin(); |
1464 it != values->end(); | 1524 it != values->end(); |
1465 ++it) { | 1525 ++it) { |
1466 uint8 setting_flags = 0; | 1526 uint8 setting_flags = 0; |
1467 if (it->second.persist_value) { | 1527 if (it->second.persist_value) { |
1468 setting_flags |= SETTINGS_FLAG_PLEASE_PERSIST; | 1528 setting_flags |= SETTINGS_FLAG_PLEASE_PERSIST; |
1469 } | 1529 } |
1470 if (it->second.persisted) { | 1530 if (it->second.persisted) { |
1471 setting_flags |= SETTINGS_FLAG_PERSISTED; | 1531 setting_flags |= SETTINGS_FLAG_PERSISTED; |
1472 } | 1532 } |
1473 SettingsFlagsAndId flags_and_id(setting_flags, it->first); | 1533 SettingsFlagsAndId flags_and_id(setting_flags, it->first); |
1474 uint32 id_and_flags_wire = flags_and_id.GetWireFormat(protocol_version()); | 1534 uint32 id_and_flags_wire = flags_and_id.GetWireFormat(protocol_version()); |
1475 builder.WriteBytes(&id_and_flags_wire, 4); | 1535 builder.WriteBytes(&id_and_flags_wire, 4); |
1476 builder.WriteUInt32(it->second.value); | 1536 builder.WriteUInt32(it->second.value); |
1477 } | 1537 } |
1478 DCHECK_EQ(size, builder.length()); | 1538 DCHECK_EQ(size, builder.length()); |
1479 return builder.take(); | 1539 return builder.take(); |
1480 } | 1540 } |
1481 | 1541 |
1482 SpdyPingControlFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) const { | 1542 SpdyPingControlFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) const { |
1483 SpdyPingIR ping(unique_id); | 1543 SpdyPingIR ping(unique_id); |
1484 return reinterpret_cast<SpdyPingControlFrame*>(SerializePing(ping)); | 1544 return reinterpret_cast<SpdyPingControlFrame*>(SerializePing(ping)); |
1485 } | 1545 } |
1486 | 1546 |
1487 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const { | 1547 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const { |
1488 // Size, in bytes, of this PING frame. Calculated as: | 1548 SpdyFrameBuilder builder(PING, 0, protocol_version(), GetPingSize()); |
1489 // 8 (control frame header) + 4 (id) | |
1490 const size_t kPingSize = 12; | |
1491 SpdyFrameBuilder builder(PING, 0, protocol_version(), kPingSize); | |
1492 builder.WriteUInt32(ping.id()); | 1549 builder.WriteUInt32(ping.id()); |
1493 DCHECK_EQ(kPingSize, builder.length()); | 1550 DCHECK_EQ(GetPingSize(), builder.length()); |
1494 return builder.take(); | 1551 return builder.take(); |
1495 } | 1552 } |
1496 | 1553 |
1497 SpdyGoAwayControlFrame* SpdyFramer::CreateGoAway( | 1554 SpdyGoAwayControlFrame* SpdyFramer::CreateGoAway( |
1498 SpdyStreamId last_accepted_stream_id, | 1555 SpdyStreamId last_accepted_stream_id, |
1499 SpdyGoAwayStatus status) const { | 1556 SpdyGoAwayStatus status) const { |
1500 SpdyGoAwayIR goaway(last_accepted_stream_id, status); | 1557 SpdyGoAwayIR goaway(last_accepted_stream_id, status); |
1501 return reinterpret_cast<SpdyGoAwayControlFrame*>(SerializeGoAway(goaway)); | 1558 return reinterpret_cast<SpdyGoAwayControlFrame*>(SerializeGoAway(goaway)); |
1502 } | 1559 } |
1503 | 1560 |
1504 SpdySerializedFrame* SpdyFramer::SerializeGoAway( | 1561 SpdySerializedFrame* SpdyFramer::SerializeGoAway( |
1505 const SpdyGoAwayIR& goaway) const { | 1562 const SpdyGoAwayIR& goaway) const { |
1506 // Size, in bytes, of this GOAWAY frame. Calculated as: | 1563 SpdyFrameBuilder builder(GOAWAY, 0, protocol_version(), GetGoAwaySize()); |
1507 // 8 (control frame header) + 4 (last good stream id) | |
1508 size_t size = 12; | |
1509 // SPDY 3+ GOAWAY frames also contain a status. | |
1510 if (protocol_version() >= 3) { | |
1511 size += 4; | |
1512 } | |
1513 SpdyFrameBuilder builder(GOAWAY, 0, protocol_version(), size); | |
1514 builder.WriteUInt32(goaway.last_good_stream_id()); | 1564 builder.WriteUInt32(goaway.last_good_stream_id()); |
1515 if (protocol_version() >= 3) { | 1565 if (protocol_version() >= 3) { |
1516 builder.WriteUInt32(goaway.status()); | 1566 builder.WriteUInt32(goaway.status()); |
1517 } | 1567 } |
1518 DCHECK_EQ(size, builder.length()); | 1568 DCHECK_EQ(GetGoAwaySize(), builder.length()); |
1519 return builder.take(); | 1569 return builder.take(); |
1520 } | 1570 } |
1521 | 1571 |
1522 SpdyHeadersControlFrame* SpdyFramer::CreateHeaders( | 1572 SpdyHeadersControlFrame* SpdyFramer::CreateHeaders( |
1523 SpdyStreamId stream_id, | 1573 SpdyStreamId stream_id, |
1524 SpdyControlFlags flags, | 1574 SpdyControlFlags flags, |
1525 bool compressed, | 1575 bool compressed, |
1526 const SpdyHeaderBlock* header_block) { | 1576 const SpdyHeaderBlock* header_block) { |
1527 // Basically the same as CreateSynReply(). | 1577 // Basically the same as CreateSynReply(). |
1528 DCHECK_EQ(0, flags & (!CONTROL_FLAG_FIN)); | 1578 DCHECK_EQ(0, flags & (!CONTROL_FLAG_FIN)); |
(...skipping 13 matching lines...) Expand all Loading... |
1542 return headers_frame.release(); | 1592 return headers_frame.release(); |
1543 } | 1593 } |
1544 | 1594 |
1545 SpdySerializedFrame* SpdyFramer::SerializeHeaders( | 1595 SpdySerializedFrame* SpdyFramer::SerializeHeaders( |
1546 const SpdyHeadersIR& headers) { | 1596 const SpdyHeadersIR& headers) { |
1547 uint8 flags = 0; | 1597 uint8 flags = 0; |
1548 if (headers.fin()) { | 1598 if (headers.fin()) { |
1549 flags |= CONTROL_FLAG_FIN; | 1599 flags |= CONTROL_FLAG_FIN; |
1550 } | 1600 } |
1551 | 1601 |
1552 // The size, in bytes, of this frame not including the variable-length | |
1553 // name-value block. Calculated as: | |
1554 // 8 (control frame header) + 4 (stream ID) | |
1555 size_t headers_size_before_name_value_block = 12; | |
1556 // In SPDY 2, there were 2 unused bytes before payload. | |
1557 if (protocol_version() < 3) { | |
1558 headers_size_before_name_value_block += 2; | |
1559 } | |
1560 | |
1561 // The size of this frame, including variable-length name-value block. | 1602 // The size of this frame, including variable-length name-value block. |
1562 size_t size = headers_size_before_name_value_block | 1603 size_t size = GetHeadersMinimumSize() |
1563 + GetSerializedLength(protocol_version(), | 1604 + GetSerializedLength(protocol_version(), |
1564 &(headers.name_value_block())); | 1605 &(headers.name_value_block())); |
1565 | 1606 |
1566 SpdyFrameBuilder builder(HEADERS, flags, protocol_version(), size); | 1607 SpdyFrameBuilder builder(HEADERS, flags, protocol_version(), size); |
1567 builder.WriteUInt32(headers.stream_id()); | 1608 builder.WriteUInt32(headers.stream_id()); |
1568 if (protocol_version() < 3) { | 1609 if (protocol_version() < 3) { |
1569 builder.WriteUInt16(0); // Unused. | 1610 builder.WriteUInt16(0); // Unused. |
1570 } | 1611 } |
1571 DCHECK_EQ(headers_size_before_name_value_block, builder.length()); | 1612 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); |
1572 | 1613 |
1573 SerializeNameValueBlock(&builder, headers); | 1614 SerializeNameValueBlock(&builder, headers); |
1574 DCHECK_EQ(size, builder.length()); | 1615 DCHECK_EQ(size, builder.length()); |
1575 | 1616 |
1576 return builder.take(); | 1617 return builder.take(); |
1577 } | 1618 } |
1578 | 1619 |
1579 SpdyWindowUpdateControlFrame* SpdyFramer::CreateWindowUpdate( | 1620 SpdyWindowUpdateControlFrame* SpdyFramer::CreateWindowUpdate( |
1580 SpdyStreamId stream_id, | 1621 SpdyStreamId stream_id, |
1581 uint32 delta_window_size) const { | 1622 uint32 delta_window_size) const { |
1582 SpdyWindowUpdateIR window_update(stream_id, delta_window_size); | 1623 SpdyWindowUpdateIR window_update(stream_id, delta_window_size); |
1583 return reinterpret_cast<SpdyWindowUpdateControlFrame*>( | 1624 return reinterpret_cast<SpdyWindowUpdateControlFrame*>( |
1584 SerializeWindowUpdate(window_update)); | 1625 SerializeWindowUpdate(window_update)); |
1585 } | 1626 } |
1586 | 1627 |
1587 SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate( | 1628 SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate( |
1588 const SpdyWindowUpdateIR& window_update) const { | 1629 const SpdyWindowUpdateIR& window_update) const { |
1589 // Size, in bytes, of this WINDOW_UPDATE frame. Calculated as: | |
1590 // 8 (control frame header) + 4 (stream id) + 4 (delta) | |
1591 const size_t kWindowUpdateSize = 16; | |
1592 | |
1593 SpdyFrameBuilder builder(WINDOW_UPDATE, | 1630 SpdyFrameBuilder builder(WINDOW_UPDATE, |
1594 kNoFlags, | 1631 kNoFlags, |
1595 protocol_version(), | 1632 protocol_version(), |
1596 kWindowUpdateSize); | 1633 GetWindowUpdateSize()); |
1597 builder.WriteUInt32(window_update.stream_id()); | 1634 builder.WriteUInt32(window_update.stream_id()); |
1598 builder.WriteUInt32(window_update.delta()); | 1635 builder.WriteUInt32(window_update.delta()); |
1599 DCHECK_EQ(kWindowUpdateSize, builder.length()); | 1636 DCHECK_EQ(GetWindowUpdateSize(), builder.length()); |
1600 return builder.take(); | 1637 return builder.take(); |
1601 } | 1638 } |
1602 | 1639 |
1603 // TODO(hkhalil): Gut with SpdyCredential removal. | 1640 // TODO(hkhalil): Gut with SpdyCredential removal. |
1604 SpdyCredentialControlFrame* SpdyFramer::CreateCredentialFrame( | 1641 SpdyCredentialControlFrame* SpdyFramer::CreateCredentialFrame( |
1605 const SpdyCredential& credential) const { | 1642 const SpdyCredential& credential) const { |
1606 SpdyCredentialIR credential_ir(credential.slot); | 1643 SpdyCredentialIR credential_ir(credential.slot); |
1607 credential_ir.set_proof(credential.proof); | 1644 credential_ir.set_proof(credential.proof); |
1608 for (std::vector<std::string>::const_iterator cert = credential.certs.begin(); | 1645 for (std::vector<std::string>::const_iterator cert = credential.certs.begin(); |
1609 cert != credential.certs.end(); | 1646 cert != credential.certs.end(); |
1610 ++cert) { | 1647 ++cert) { |
1611 credential_ir.AddCertificate(*cert); | 1648 credential_ir.AddCertificate(*cert); |
1612 } | 1649 } |
1613 return reinterpret_cast<SpdyCredentialControlFrame*>( | 1650 return reinterpret_cast<SpdyCredentialControlFrame*>( |
1614 SerializeCredential(credential_ir)); | 1651 SerializeCredential(credential_ir)); |
1615 } | 1652 } |
1616 | 1653 |
1617 SpdySerializedFrame* SpdyFramer::SerializeCredential( | 1654 SpdySerializedFrame* SpdyFramer::SerializeCredential( |
1618 const SpdyCredentialIR& credential) const { | 1655 const SpdyCredentialIR& credential) const { |
1619 size_t size = 8; // Room for frame header. | 1656 size_t size = GetCredentialMinimumSize(); |
1620 size += 2; // Room for slot. | |
1621 size += 4 + credential.proof().length(); // Room for proof. | 1657 size += 4 + credential.proof().length(); // Room for proof. |
1622 for (SpdyCredentialIR::CertificateList::const_iterator it = | 1658 for (SpdyCredentialIR::CertificateList::const_iterator it = |
1623 credential.certificates()->begin(); | 1659 credential.certificates()->begin(); |
1624 it != credential.certificates()->end(); | 1660 it != credential.certificates()->end(); |
1625 ++it) { | 1661 ++it) { |
1626 size += 4 + it->length(); // Room for certificate. | 1662 size += 4 + it->length(); // Room for certificate. |
1627 } | 1663 } |
1628 | 1664 |
1629 SpdyFrameBuilder builder(CREDENTIAL, 0, protocol_version(), size); | 1665 SpdyFrameBuilder builder(CREDENTIAL, 0, protocol_version(), size); |
1630 builder.WriteUInt16(credential.slot()); | 1666 builder.WriteUInt16(credential.slot()); |
| 1667 DCHECK_EQ(GetCredentialMinimumSize(), builder.length()); |
1631 builder.WriteStringPiece32(credential.proof()); | 1668 builder.WriteStringPiece32(credential.proof()); |
1632 for (SpdyCredentialIR::CertificateList::const_iterator it = | 1669 for (SpdyCredentialIR::CertificateList::const_iterator it = |
1633 credential.certificates()->begin(); | 1670 credential.certificates()->begin(); |
1634 it != credential.certificates()->end(); | 1671 it != credential.certificates()->end(); |
1635 ++it) { | 1672 ++it) { |
1636 builder.WriteStringPiece32(*it); | 1673 builder.WriteStringPiece32(*it); |
1637 } | 1674 } |
1638 DCHECK_EQ(size, builder.length()); | 1675 DCHECK_EQ(size, builder.length()); |
1639 return builder.take(); | 1676 return builder.take(); |
1640 } | 1677 } |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1979 reinterpret_cast<const SpdyControlFrame&>(frame); | 2016 reinterpret_cast<const SpdyControlFrame&>(frame); |
1980 return control_frame.type() == SYN_STREAM || | 2017 return control_frame.type() == SYN_STREAM || |
1981 control_frame.type() == SYN_REPLY || | 2018 control_frame.type() == SYN_REPLY || |
1982 control_frame.type() == HEADERS; | 2019 control_frame.type() == HEADERS; |
1983 } | 2020 } |
1984 | 2021 |
1985 // We don't compress Data frames. | 2022 // We don't compress Data frames. |
1986 return false; | 2023 return false; |
1987 } | 2024 } |
1988 | 2025 |
1989 size_t SpdyFramer::GetMinimumControlFrameSize(int version, | |
1990 SpdyControlType type) { | |
1991 switch (type) { | |
1992 case SYN_STREAM: | |
1993 return SpdySynStreamControlFrame::size(); | |
1994 case SYN_REPLY: | |
1995 return SpdySynReplyControlFrame::size(); | |
1996 case RST_STREAM: | |
1997 return SpdyRstStreamControlFrame::size(); | |
1998 case SETTINGS: | |
1999 return SpdySettingsControlFrame::size(); | |
2000 case NOOP: | |
2001 // Even though NOOP is no longer supported, we still correctly report its | |
2002 // size so that it can be handled correctly as incoming data if | |
2003 // implementations so desire. | |
2004 return SpdyFrame::kHeaderSize; | |
2005 case PING: | |
2006 return SpdyPingControlFrame::size(); | |
2007 case GOAWAY: | |
2008 if (version < 3) { | |
2009 // SPDY 2 GOAWAY is smaller by 32 bits. Since | |
2010 // SpdyGoAwayControlFrame::size() returns the size for SPDY 3, we adjust | |
2011 // before returning here. | |
2012 return SpdyGoAwayControlFrame::size() - 4; | |
2013 } else { | |
2014 return SpdyGoAwayControlFrame::size(); | |
2015 } | |
2016 case HEADERS: | |
2017 return SpdyHeadersControlFrame::size(); | |
2018 case WINDOW_UPDATE: | |
2019 return SpdyWindowUpdateControlFrame::size(); | |
2020 case CREDENTIAL: | |
2021 return SpdyCredentialControlFrame::size(); | |
2022 case NUM_CONTROL_FRAME_TYPES: | |
2023 break; | |
2024 } | |
2025 LOG(ERROR) << "Unknown control frame type " << type; | |
2026 return std::numeric_limits<size_t>::max(); | |
2027 } | |
2028 | |
2029 /* static */ | 2026 /* static */ |
2030 SpdyStreamId SpdyFramer::GetControlFrameStreamId( | 2027 SpdyStreamId SpdyFramer::GetControlFrameStreamId( |
2031 const SpdyControlFrame* control_frame) { | 2028 const SpdyControlFrame* control_frame) { |
2032 SpdyStreamId stream_id = kInvalidStream; | 2029 SpdyStreamId stream_id = kInvalidStream; |
2033 if (control_frame != NULL) { | 2030 if (control_frame != NULL) { |
2034 switch (control_frame->type()) { | 2031 switch (control_frame->type()) { |
2035 case SYN_STREAM: | 2032 case SYN_STREAM: |
2036 stream_id = reinterpret_cast<const SpdySynStreamControlFrame*>( | 2033 stream_id = reinterpret_cast<const SpdySynStreamControlFrame*>( |
2037 control_frame)->stream_id(); | 2034 control_frame)->stream_id(); |
2038 break; | 2035 break; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2088 builder->WriteString(it->first); | 2085 builder->WriteString(it->first); |
2089 builder->WriteString(it->second); | 2086 builder->WriteString(it->second); |
2090 } else { | 2087 } else { |
2091 builder->WriteStringPiece32(it->first); | 2088 builder->WriteStringPiece32(it->first); |
2092 builder->WriteStringPiece32(it->second); | 2089 builder->WriteStringPiece32(it->second); |
2093 } | 2090 } |
2094 } | 2091 } |
2095 } | 2092 } |
2096 | 2093 |
2097 } // namespace net | 2094 } // namespace net |
OLD | NEW |