Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(719)

Side by Side Diff: net/spdy/spdy_framer.cc

Issue 12224137: Centralize logic for calculating (minimum) size of SPDY frames, by type, in SpdyFramer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | net/spdy/spdy_framer_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | net/spdy/spdy_framer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698