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 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
664 | 664 |
665 // Determine the frame size without variable-length data. | 665 // Determine the frame size without variable-length data. |
666 int32 frame_size_without_variable_data; | 666 int32 frame_size_without_variable_data; |
667 switch (current_control_frame.type()) { | 667 switch (current_control_frame.type()) { |
668 case SYN_STREAM: | 668 case SYN_STREAM: |
669 syn_frame_processed_ = true; | 669 syn_frame_processed_ = true; |
670 frame_size_without_variable_data = SpdySynStreamControlFrame::size(); | 670 frame_size_without_variable_data = SpdySynStreamControlFrame::size(); |
671 break; | 671 break; |
672 case SYN_REPLY: | 672 case SYN_REPLY: |
673 syn_frame_processed_ = true; | 673 syn_frame_processed_ = true; |
674 frame_size_without_variable_data = SpdySynReplyControlFrame::size(); | 674 frame_size_without_variable_data = GetSynReplyMinimumSize(); |
675 // SPDY 2 had two bytes of unused space preceeding payload. | |
676 if (spdy_version_ < 3) { | |
677 frame_size_without_variable_data += 2; | |
678 } | |
679 break; | 675 break; |
680 case HEADERS: | 676 case HEADERS: |
681 frame_size_without_variable_data = SpdyHeadersControlFrame::size(); | 677 frame_size_without_variable_data = SpdyHeadersControlFrame::size(); |
682 // SPDY 2 had two bytes of unused space preceeding payload. | 678 // SPDY 2 had two bytes of unused space preceeding payload. |
683 if (spdy_version_ < 3) { | 679 if (spdy_version_ < 3) { |
684 frame_size_without_variable_data += 2; | 680 frame_size_without_variable_data += 2; |
685 } | 681 } |
686 break; | 682 break; |
687 case SETTINGS: | 683 case SETTINGS: |
688 frame_size_without_variable_data = SpdySettingsControlFrame::size(); | 684 frame_size_without_variable_data = SpdySettingsControlFrame::size(); |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
963 syn_stream_frame->associated_stream_id(), | 959 syn_stream_frame->associated_stream_id(), |
964 syn_stream_frame->priority(), | 960 syn_stream_frame->priority(), |
965 syn_stream_frame->credential_slot(), | 961 syn_stream_frame->credential_slot(), |
966 (syn_stream_frame->flags() & CONTROL_FLAG_FIN) != 0, | 962 (syn_stream_frame->flags() & CONTROL_FLAG_FIN) != 0, |
967 (syn_stream_frame->flags() & CONTROL_FLAG_UNIDIRECTIONAL) != 0); | 963 (syn_stream_frame->flags() & CONTROL_FLAG_UNIDIRECTIONAL) != 0); |
968 } | 964 } |
969 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); | 965 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); |
970 break; | 966 break; |
971 case SYN_REPLY: | 967 case SYN_REPLY: |
972 { | 968 { |
973 SpdySynReplyControlFrame* syn_reply_frame = | 969 SpdyFrameReader reader(current_frame_buffer_.get(), |
974 reinterpret_cast<SpdySynReplyControlFrame*>(&control_frame); | 970 current_frame_len_); |
975 visitor_->OnSynReply( | 971 reader.Seek(4); // Seek past control bit, type and version. |
976 syn_reply_frame->stream_id(), | 972 uint8 flags; |
977 (syn_reply_frame->flags() & CONTROL_FLAG_FIN) != 0); | 973 bool successful_read = reader.ReadUInt8(&flags); |
| 974 DCHECK(successful_read); |
| 975 reader.Seek(3); // Seek past length. |
| 976 SpdyStreamId stream_id = kInvalidStream; |
| 977 successful_read = reader.ReadUInt31(&stream_id); |
| 978 DCHECK(successful_read); |
| 979 if (protocol_version() < 3) { |
| 980 // SPDY 2 had two unused bytes here. Seek past them. |
| 981 reader.Seek(2); |
| 982 } |
| 983 DCHECK(reader.IsDoneReading()); |
| 984 visitor_->OnSynReply(stream_id, (flags & CONTROL_FLAG_FIN) != 0); |
978 } | 985 } |
979 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); | 986 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); |
980 break; | 987 break; |
981 case HEADERS: | 988 case HEADERS: |
982 { | 989 { |
983 SpdyHeadersControlFrame* headers_frame = | 990 SpdyHeadersControlFrame* headers_frame = |
984 reinterpret_cast<SpdyHeadersControlFrame*>(&control_frame); | 991 reinterpret_cast<SpdyHeadersControlFrame*>(&control_frame); |
985 visitor_->OnHeaders( | 992 visitor_->OnHeaders( |
986 headers_frame->stream_id(), | 993 headers_frame->stream_id(), |
987 (headers_frame->flags() & CONTROL_FLAG_FIN) != 0); | 994 (headers_frame->flags() & CONTROL_FLAG_FIN) != 0); |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1187 } | 1194 } |
1188 break; | 1195 break; |
1189 case RST_STREAM: { | 1196 case RST_STREAM: { |
1190 SpdyRstStreamControlFrame* rst_stream_frame = | 1197 SpdyRstStreamControlFrame* rst_stream_frame = |
1191 reinterpret_cast<SpdyRstStreamControlFrame*>(&control_frame); | 1198 reinterpret_cast<SpdyRstStreamControlFrame*>(&control_frame); |
1192 visitor_->OnRstStream(rst_stream_frame->stream_id(), | 1199 visitor_->OnRstStream(rst_stream_frame->stream_id(), |
1193 rst_stream_frame->status()); | 1200 rst_stream_frame->status()); |
1194 } | 1201 } |
1195 break; | 1202 break; |
1196 case GOAWAY: { | 1203 case GOAWAY: { |
1197 SpdyGoAwayControlFrame* go_away_frame = | 1204 SpdyFrameReader reader(current_frame_buffer_.get(), |
1198 reinterpret_cast<SpdyGoAwayControlFrame*>(&control_frame); | 1205 current_frame_len_); |
1199 if (spdy_version_ < 3) { | 1206 reader.Seek(GetControlFrameMinimumSize()); // Skip frame header. |
1200 visitor_->OnGoAway(go_away_frame->last_accepted_stream_id(), | 1207 SpdyStreamId last_accepted_stream_id = kInvalidStream; |
1201 GOAWAY_OK); | 1208 bool successful_read = reader.ReadUInt32(&last_accepted_stream_id); |
1202 } else { | 1209 DCHECK(successful_read); |
1203 visitor_->OnGoAway(go_away_frame->last_accepted_stream_id(), | 1210 SpdyGoAwayStatus status = GOAWAY_OK; |
1204 go_away_frame->status()); | 1211 if (spdy_version_ >= 3) { |
| 1212 uint32 status_raw = GOAWAY_OK; |
| 1213 successful_read = reader.ReadUInt32(&status_raw); |
| 1214 DCHECK(successful_read); |
| 1215 if (status_raw > static_cast<uint32>(GOAWAY_INVALID) && |
| 1216 status_raw < static_cast<uint32>(GOAWAY_NUM_STATUS_CODES)) { |
| 1217 status = static_cast<SpdyGoAwayStatus>(status_raw); |
| 1218 } else { |
| 1219 // TODO(hkhalil): Probably best to OnError here, depending on |
| 1220 // our interpretation of the spec. Keeping with existing liberal |
| 1221 // behavior for now. |
| 1222 } |
1205 } | 1223 } |
| 1224 DCHECK(reader.IsDoneReading()); |
| 1225 visitor_->OnGoAway(last_accepted_stream_id, status); |
1206 } | 1226 } |
1207 break; | 1227 break; |
1208 default: | 1228 default: |
1209 // Unreachable. | 1229 // Unreachable. |
1210 LOG(FATAL) << "Unhandled control frame " << control_frame.type(); | 1230 LOG(FATAL) << "Unhandled control frame " << control_frame.type(); |
1211 } | 1231 } |
1212 | 1232 |
1213 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); | 1233 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); |
1214 } | 1234 } |
1215 } | 1235 } |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1427 priority = GetLowestPriority(); | 1447 priority = GetLowestPriority(); |
1428 } | 1448 } |
1429 builder.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5)); | 1449 builder.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5)); |
1430 builder.WriteUInt8(syn_stream.slot()); | 1450 builder.WriteUInt8(syn_stream.slot()); |
1431 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length()); | 1451 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length()); |
1432 SerializeNameValueBlock(&builder, syn_stream); | 1452 SerializeNameValueBlock(&builder, syn_stream); |
1433 | 1453 |
1434 return builder.take(); | 1454 return builder.take(); |
1435 } | 1455 } |
1436 | 1456 |
1437 SpdySynReplyControlFrame* SpdyFramer::CreateSynReply( | 1457 SpdyFrame* SpdyFramer::CreateSynReply( |
1438 SpdyStreamId stream_id, | 1458 SpdyStreamId stream_id, |
1439 SpdyControlFlags flags, | 1459 SpdyControlFlags flags, |
1440 bool compressed, | 1460 bool compressed, |
1441 const SpdyHeaderBlock* headers) { | 1461 const SpdyHeaderBlock* headers) { |
1442 DCHECK_EQ(0, flags & ~CONTROL_FLAG_FIN); | 1462 DCHECK_EQ(0, flags & ~CONTROL_FLAG_FIN); |
1443 | 1463 |
1444 SpdySynReplyIR syn_reply(stream_id); | 1464 SpdySynReplyIR syn_reply(stream_id); |
1445 syn_reply.set_fin(flags & CONTROL_FLAG_FIN); | 1465 syn_reply.set_fin(flags & CONTROL_FLAG_FIN); |
1446 // TODO(hkhalil): Avoid copy here. | 1466 // TODO(hkhalil): Avoid copy here. |
1447 *(syn_reply.GetMutableNameValueBlock()) = *headers; | 1467 *(syn_reply.GetMutableNameValueBlock()) = *headers; |
1448 | 1468 |
1449 scoped_ptr<SpdySynReplyControlFrame> reply_frame( | 1469 scoped_ptr<SpdyControlFrame> reply_frame( |
1450 reinterpret_cast<SpdySynReplyControlFrame*>(SerializeSynReply( | 1470 reinterpret_cast<SpdyControlFrame*>(SerializeSynReply(syn_reply))); |
1451 syn_reply))); | |
1452 if (compressed) { | 1471 if (compressed) { |
1453 return reinterpret_cast<SpdySynReplyControlFrame*>( | 1472 return CompressControlFrame(*reply_frame.get(), headers); |
1454 CompressControlFrame(*reply_frame.get(), headers)); | |
1455 } | 1473 } |
1456 return reply_frame.release(); | 1474 return reply_frame.release(); |
1457 } | 1475 } |
1458 | 1476 |
1459 SpdySerializedFrame* SpdyFramer::SerializeSynReply( | 1477 SpdySerializedFrame* SpdyFramer::SerializeSynReply( |
1460 const SpdySynReplyIR& syn_reply) { | 1478 const SpdySynReplyIR& syn_reply) { |
1461 uint8 flags = 0; | 1479 uint8 flags = 0; |
1462 if (syn_reply.fin()) { | 1480 if (syn_reply.fin()) { |
1463 flags |= CONTROL_FLAG_FIN; | 1481 flags |= CONTROL_FLAG_FIN; |
1464 } | 1482 } |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1552 return reinterpret_cast<SpdyPingControlFrame*>(SerializePing(ping)); | 1570 return reinterpret_cast<SpdyPingControlFrame*>(SerializePing(ping)); |
1553 } | 1571 } |
1554 | 1572 |
1555 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const { | 1573 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const { |
1556 SpdyFrameBuilder builder(PING, 0, protocol_version(), GetPingSize()); | 1574 SpdyFrameBuilder builder(PING, 0, protocol_version(), GetPingSize()); |
1557 builder.WriteUInt32(ping.id()); | 1575 builder.WriteUInt32(ping.id()); |
1558 DCHECK_EQ(GetPingSize(), builder.length()); | 1576 DCHECK_EQ(GetPingSize(), builder.length()); |
1559 return builder.take(); | 1577 return builder.take(); |
1560 } | 1578 } |
1561 | 1579 |
1562 SpdyGoAwayControlFrame* SpdyFramer::CreateGoAway( | 1580 SpdyFrame* SpdyFramer::CreateGoAway( |
1563 SpdyStreamId last_accepted_stream_id, | 1581 SpdyStreamId last_accepted_stream_id, |
1564 SpdyGoAwayStatus status) const { | 1582 SpdyGoAwayStatus status) const { |
1565 SpdyGoAwayIR goaway(last_accepted_stream_id, status); | 1583 SpdyGoAwayIR goaway(last_accepted_stream_id, status); |
1566 return reinterpret_cast<SpdyGoAwayControlFrame*>(SerializeGoAway(goaway)); | 1584 return SerializeGoAway(goaway); |
1567 } | 1585 } |
1568 | 1586 |
1569 SpdySerializedFrame* SpdyFramer::SerializeGoAway( | 1587 SpdySerializedFrame* SpdyFramer::SerializeGoAway( |
1570 const SpdyGoAwayIR& goaway) const { | 1588 const SpdyGoAwayIR& goaway) const { |
1571 SpdyFrameBuilder builder(GOAWAY, 0, protocol_version(), GetGoAwaySize()); | 1589 SpdyFrameBuilder builder(GOAWAY, 0, protocol_version(), GetGoAwaySize()); |
1572 builder.WriteUInt32(goaway.last_good_stream_id()); | 1590 builder.WriteUInt32(goaway.last_good_stream_id()); |
1573 if (protocol_version() >= 3) { | 1591 if (protocol_version() >= 3) { |
1574 builder.WriteUInt32(goaway.status()); | 1592 builder.WriteUInt32(goaway.status()); |
1575 } | 1593 } |
1576 DCHECK_EQ(GetGoAwaySize(), builder.length()); | 1594 DCHECK_EQ(GetGoAwaySize(), builder.length()); |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1784 const SpdySynStreamControlFrame& syn_frame = | 1802 const SpdySynStreamControlFrame& syn_frame = |
1785 reinterpret_cast<const SpdySynStreamControlFrame&>(frame); | 1803 reinterpret_cast<const SpdySynStreamControlFrame&>(frame); |
1786 frame_size = SpdySynStreamControlFrame::size(); | 1804 frame_size = SpdySynStreamControlFrame::size(); |
1787 *payload_length = syn_frame.header_block_len(); | 1805 *payload_length = syn_frame.header_block_len(); |
1788 *header_length = frame_size; | 1806 *header_length = frame_size; |
1789 *payload = frame.data() + *header_length; | 1807 *payload = frame.data() + *header_length; |
1790 } | 1808 } |
1791 break; | 1809 break; |
1792 case SYN_REPLY: | 1810 case SYN_REPLY: |
1793 { | 1811 { |
1794 const SpdySynReplyControlFrame& syn_frame = | 1812 *header_length = GetSynReplyMinimumSize(); |
1795 reinterpret_cast<const SpdySynReplyControlFrame&>(frame); | 1813 *payload_length = frame.length() - |
1796 frame_size = SpdySynReplyControlFrame::size(); | 1814 (*header_length - GetControlFrameMinimumSize()); |
1797 *payload_length = syn_frame.header_block_len(); | |
1798 *header_length = frame_size; | |
1799 *payload = frame.data() + *header_length; | 1815 *payload = frame.data() + *header_length; |
1800 // SPDY 2 had two bytes of unused space preceeding payload. | |
1801 if (spdy_version_ < 3) { | |
1802 *header_length += 2; | |
1803 *payload += 2; | |
1804 } | |
1805 } | 1816 } |
1806 break; | 1817 break; |
1807 case HEADERS: | 1818 case HEADERS: |
1808 { | 1819 { |
1809 const SpdyHeadersControlFrame& headers_frame = | 1820 const SpdyHeadersControlFrame& headers_frame = |
1810 reinterpret_cast<const SpdyHeadersControlFrame&>(frame); | 1821 reinterpret_cast<const SpdyHeadersControlFrame&>(frame); |
1811 frame_size = SpdyHeadersControlFrame::size(); | 1822 frame_size = SpdyHeadersControlFrame::size(); |
1812 *payload_length = headers_frame.header_block_len(); | 1823 *payload_length = headers_frame.header_block_len(); |
1813 *header_length = frame_size; | 1824 *header_length = frame_size; |
1814 *payload = frame.data() + *header_length; | 1825 *payload = frame.data() + *header_length; |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2049 builder->WriteString(it->first); | 2060 builder->WriteString(it->first); |
2050 builder->WriteString(it->second); | 2061 builder->WriteString(it->second); |
2051 } else { | 2062 } else { |
2052 builder->WriteStringPiece32(it->first); | 2063 builder->WriteStringPiece32(it->first); |
2053 builder->WriteStringPiece32(it->second); | 2064 builder->WriteStringPiece32(it->second); |
2054 } | 2065 } |
2055 } | 2066 } |
2056 } | 2067 } |
2057 | 2068 |
2058 } // namespace net | 2069 } // namespace net |
OLD | NEW |