| 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 v3_dictionary_id(CalculateDictionaryId(kV3Dictionary, kV3DictionarySize)) | 44 v3_dictionary_id(CalculateDictionaryId(kV3Dictionary, kV3DictionarySize)) |
| 45 {} | 45 {} |
| 46 const uLong v2_dictionary_id; | 46 const uLong v2_dictionary_id; |
| 47 const uLong v3_dictionary_id; | 47 const uLong v3_dictionary_id; |
| 48 }; | 48 }; |
| 49 | 49 |
| 50 // Adler ID for the SPDY header compressor dictionaries. Note that they are | 50 // Adler ID for the SPDY header compressor dictionaries. Note that they are |
| 51 // initialized lazily to avoid static initializers. | 51 // initialized lazily to avoid static initializers. |
| 52 base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids; | 52 base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids; |
| 53 | 53 |
| 54 // Creates a FlagsAndLength. | |
| 55 FlagsAndLength CreateFlagsAndLength(SpdyControlFlags flags, size_t length) { | |
| 56 DCHECK_EQ(0u, length & ~static_cast<size_t>(kLengthMask)); | |
| 57 FlagsAndLength flags_length; | |
| 58 flags_length.length_ = htonl(static_cast<uint32>(length)); | |
| 59 DCHECK_EQ(0, flags & ~kControlFlagsMask); | |
| 60 flags_length.flags_[0] = flags; | |
| 61 return flags_length; | |
| 62 } | |
| 63 | |
| 64 // By default is compression on or off. | 54 // By default is compression on or off. |
| 65 bool g_enable_compression_default = true; | 55 bool g_enable_compression_default = true; |
| 66 | 56 |
| 67 } // namespace | 57 } // namespace |
| 68 | 58 |
| 69 // The initial size of the control frame buffer; this is used internally | 59 // The initial size of the control frame buffer; this is used internally |
| 70 // as we parse through control frames. (It is exposed here for unit test | 60 // as we parse through control frames. (It is exposed here for unit test |
| 71 // purposes.) | 61 // purposes.) |
| 72 size_t SpdyFramer::kControlFrameBufferInitialSize = 32 * 1024; | 62 size_t SpdyFramer::kControlFrameBufferInitialSize = 32 * 1024; |
| 73 | 63 |
| (...skipping 991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1065 SpdyStreamId associated_stream_id, | 1055 SpdyStreamId associated_stream_id, |
| 1066 SpdyPriority priority, | 1056 SpdyPriority priority, |
| 1067 uint8 credential_slot, | 1057 uint8 credential_slot, |
| 1068 SpdyControlFlags flags, | 1058 SpdyControlFlags flags, |
| 1069 bool compressed, | 1059 bool compressed, |
| 1070 const SpdyHeaderBlock* headers) { | 1060 const SpdyHeaderBlock* headers) { |
| 1071 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); | 1061 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); |
| 1072 DCHECK_EQ(0u, associated_stream_id & ~kStreamIdMask); | 1062 DCHECK_EQ(0u, associated_stream_id & ~kStreamIdMask); |
| 1073 | 1063 |
| 1074 // Find our length. | 1064 // Find our length. |
| 1075 size_t expected_frame_size = SpdySynStreamControlFrame::size() + | 1065 size_t frame_size = SpdySynStreamControlFrame::size() + |
| 1076 GetSerializedLength(headers); | 1066 GetSerializedLength(headers); |
| 1077 | 1067 |
| 1078 // Create our FlagsAndLength. | 1068 SpdyFrameBuilder frame(SYN_STREAM, flags, spdy_version_, frame_size); |
| 1079 FlagsAndLength flags_length = CreateFlagsAndLength( | |
| 1080 flags, | |
| 1081 expected_frame_size - SpdyFrame::kHeaderSize); | |
| 1082 | |
| 1083 SpdyFrameBuilder frame(expected_frame_size); | |
| 1084 frame.WriteUInt16(kControlFlagMask | spdy_version_); | |
| 1085 frame.WriteUInt16(SYN_STREAM); | |
| 1086 frame.WriteBytes(&flags_length, sizeof(flags_length)); | |
| 1087 frame.WriteUInt32(stream_id); | 1069 frame.WriteUInt32(stream_id); |
| 1088 frame.WriteUInt32(associated_stream_id); | 1070 frame.WriteUInt32(associated_stream_id); |
| 1089 // Cap as appropriate. | 1071 // Cap as appropriate. |
| 1090 if (priority > GetLowestPriority()) { | 1072 if (priority > GetLowestPriority()) { |
| 1091 DLOG(ERROR) << "Priority out-of-bounds."; | 1073 DLOG(ERROR) << "Priority out-of-bounds."; |
| 1092 priority = GetLowestPriority(); | 1074 priority = GetLowestPriority(); |
| 1093 } | 1075 } |
| 1094 // Priority is 2 bits for <spdy3, 3 bits otherwise. | 1076 // Priority is 2 bits for <spdy3, 3 bits otherwise. |
| 1095 frame.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5)); | 1077 frame.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5)); |
| 1096 frame.WriteUInt8((spdy_version_ < 3) ? 0 : credential_slot); | 1078 frame.WriteUInt8((spdy_version_ < 3) ? 0 : credential_slot); |
| 1097 WriteHeaderBlock(&frame, headers); | 1079 WriteHeaderBlock(&frame, headers); |
| 1080 DCHECK_EQ(static_cast<size_t>(frame.length()), frame_size); |
| 1098 | 1081 |
| 1099 scoped_ptr<SpdySynStreamControlFrame> syn_frame( | 1082 scoped_ptr<SpdySynStreamControlFrame> syn_frame( |
| 1100 reinterpret_cast<SpdySynStreamControlFrame*>(frame.take())); | 1083 reinterpret_cast<SpdySynStreamControlFrame*>(frame.take())); |
| 1101 if (compressed) { | 1084 if (compressed) { |
| 1102 return reinterpret_cast<SpdySynStreamControlFrame*>( | 1085 return reinterpret_cast<SpdySynStreamControlFrame*>( |
| 1103 CompressControlFrame(*syn_frame.get())); | 1086 CompressControlFrame(*syn_frame.get())); |
| 1104 } | 1087 } |
| 1105 return syn_frame.release(); | 1088 return syn_frame.release(); |
| 1106 } | 1089 } |
| 1107 | 1090 |
| 1108 SpdySynReplyControlFrame* SpdyFramer::CreateSynReply( | 1091 SpdySynReplyControlFrame* SpdyFramer::CreateSynReply( |
| 1109 SpdyStreamId stream_id, | 1092 SpdyStreamId stream_id, |
| 1110 SpdyControlFlags flags, | 1093 SpdyControlFlags flags, |
| 1111 bool compressed, | 1094 bool compressed, |
| 1112 const SpdyHeaderBlock* headers) { | 1095 const SpdyHeaderBlock* headers) { |
| 1113 DCHECK_GT(stream_id, 0u); | 1096 DCHECK_GT(stream_id, 0u); |
| 1114 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); | 1097 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); |
| 1115 | 1098 |
| 1116 // Find our length. | 1099 // Find our length. |
| 1117 size_t expected_frame_size = SpdySynReplyControlFrame::size() + | 1100 size_t frame_size = SpdySynReplyControlFrame::size() + |
| 1118 GetSerializedLength(headers); | 1101 GetSerializedLength(headers); |
| 1119 // In SPDY 2, there were 2 unused bytes before payload. | 1102 // In SPDY 2, there were 2 unused bytes before payload. |
| 1120 if (spdy_version_ < 3) { | 1103 if (spdy_version_ < 3) { |
| 1121 expected_frame_size += 2; | 1104 frame_size += 2; |
| 1122 } | 1105 } |
| 1123 | 1106 |
| 1124 // Create our FlagsAndLength. | 1107 SpdyFrameBuilder frame(SYN_REPLY, flags, spdy_version_, frame_size); |
| 1125 FlagsAndLength flags_length = CreateFlagsAndLength( | |
| 1126 flags, | |
| 1127 expected_frame_size - SpdyFrame::kHeaderSize); | |
| 1128 | |
| 1129 SpdyFrameBuilder frame(expected_frame_size); | |
| 1130 frame.WriteUInt16(kControlFlagMask | spdy_version_); | |
| 1131 frame.WriteUInt16(SYN_REPLY); | |
| 1132 frame.WriteBytes(&flags_length, sizeof(flags_length)); | |
| 1133 frame.WriteUInt32(stream_id); | 1108 frame.WriteUInt32(stream_id); |
| 1134 if (spdy_version_ < 3) { | 1109 if (spdy_version_ < 3) { |
| 1135 frame.WriteUInt16(0); // Unused | 1110 frame.WriteUInt16(0); // Unused |
| 1136 } | 1111 } |
| 1137 WriteHeaderBlock(&frame, headers); | 1112 WriteHeaderBlock(&frame, headers); |
| 1113 DCHECK_EQ(static_cast<size_t>(frame.length()), frame_size); |
| 1138 | 1114 |
| 1139 scoped_ptr<SpdySynReplyControlFrame> reply_frame( | 1115 scoped_ptr<SpdySynReplyControlFrame> reply_frame( |
| 1140 reinterpret_cast<SpdySynReplyControlFrame*>(frame.take())); | 1116 reinterpret_cast<SpdySynReplyControlFrame*>(frame.take())); |
| 1141 if (compressed) { | 1117 if (compressed) { |
| 1142 return reinterpret_cast<SpdySynReplyControlFrame*>( | 1118 return reinterpret_cast<SpdySynReplyControlFrame*>( |
| 1143 CompressControlFrame(*reply_frame.get())); | 1119 CompressControlFrame(*reply_frame.get())); |
| 1144 } | 1120 } |
| 1145 return reply_frame.release(); | 1121 return reply_frame.release(); |
| 1146 } | 1122 } |
| 1147 | 1123 |
| 1148 SpdyRstStreamControlFrame* SpdyFramer::CreateRstStream( | 1124 SpdyRstStreamControlFrame* SpdyFramer::CreateRstStream( |
| 1149 SpdyStreamId stream_id, | 1125 SpdyStreamId stream_id, |
| 1150 SpdyStatusCodes status) const { | 1126 SpdyStatusCodes status) const { |
| 1151 DCHECK_GT(stream_id, 0u); | 1127 DCHECK_GT(stream_id, 0u); |
| 1152 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); | 1128 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); |
| 1153 DCHECK_NE(status, INVALID); | 1129 DCHECK_NE(status, INVALID); |
| 1154 DCHECK_LT(status, NUM_STATUS_CODES); | 1130 DCHECK_LT(status, NUM_STATUS_CODES); |
| 1155 | 1131 |
| 1156 SpdyFrameBuilder frame(SpdyRstStreamControlFrame::size()); | 1132 size_t frame_size = SpdyRstStreamControlFrame::size(); |
| 1157 frame.WriteUInt16(kControlFlagMask | spdy_version_); | 1133 SpdyFrameBuilder frame(RST_STREAM, CONTROL_FLAG_NONE, spdy_version_, |
| 1158 frame.WriteUInt16(RST_STREAM); | 1134 frame_size); |
| 1159 frame.WriteUInt32(8); | |
| 1160 frame.WriteUInt32(stream_id); | 1135 frame.WriteUInt32(stream_id); |
| 1161 frame.WriteUInt32(status); | 1136 frame.WriteUInt32(status); |
| 1137 DCHECK_EQ(static_cast<size_t>(frame.length()), frame_size); |
| 1162 return reinterpret_cast<SpdyRstStreamControlFrame*>(frame.take()); | 1138 return reinterpret_cast<SpdyRstStreamControlFrame*>(frame.take()); |
| 1163 } | 1139 } |
| 1164 | 1140 |
| 1165 SpdySettingsControlFrame* SpdyFramer::CreateSettings( | 1141 SpdySettingsControlFrame* SpdyFramer::CreateSettings( |
| 1166 const SpdySettings& values) const { | 1142 const SpdySettings& values) const { |
| 1167 SpdyFrameBuilder frame(SpdySettingsControlFrame::size() + 8 * values.size()); | 1143 size_t frame_size = SpdySettingsControlFrame::size() + 8 * values.size(); |
| 1168 frame.WriteUInt16(kControlFlagMask | spdy_version_); | 1144 SpdyFrameBuilder frame(SETTINGS, CONTROL_FLAG_NONE, spdy_version_, |
| 1169 frame.WriteUInt16(SETTINGS); | 1145 frame_size); |
| 1170 size_t settings_size = | |
| 1171 SpdySettingsControlFrame::size() - SpdyFrame::kHeaderSize + | |
| 1172 8 * values.size(); | |
| 1173 frame.WriteUInt32(settings_size); | |
| 1174 frame.WriteUInt32(values.size()); | 1146 frame.WriteUInt32(values.size()); |
| 1175 SpdySettings::const_iterator it = values.begin(); | 1147 SpdySettings::const_iterator it = values.begin(); |
| 1176 while (it != values.end()) { | 1148 while (it != values.end()) { |
| 1177 uint32 id_and_flags_wire = it->first.GetWireFormat(spdy_version_); | 1149 uint32 id_and_flags_wire = it->first.GetWireFormat(spdy_version_); |
| 1178 frame.WriteBytes(&id_and_flags_wire, 4); | 1150 frame.WriteBytes(&id_and_flags_wire, 4); |
| 1179 frame.WriteUInt32(it->second); | 1151 frame.WriteUInt32(it->second); |
| 1180 ++it; | 1152 ++it; |
| 1181 } | 1153 } |
| 1154 DCHECK_EQ(static_cast<size_t>(frame.length()), frame_size); |
| 1182 return reinterpret_cast<SpdySettingsControlFrame*>(frame.take()); | 1155 return reinterpret_cast<SpdySettingsControlFrame*>(frame.take()); |
| 1183 } | 1156 } |
| 1184 | 1157 |
| 1185 SpdyPingControlFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) const { | 1158 SpdyPingControlFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) const { |
| 1186 SpdyFrameBuilder frame(SpdyPingControlFrame::size()); | 1159 size_t frame_size = SpdyPingControlFrame::size(); |
| 1187 frame.WriteUInt16(kControlFlagMask | spdy_version_); | 1160 SpdyFrameBuilder frame(PING, CONTROL_FLAG_NONE, spdy_version_, frame_size); |
| 1188 frame.WriteUInt16(PING); | |
| 1189 size_t ping_size = SpdyPingControlFrame::size() - SpdyFrame::kHeaderSize; | |
| 1190 frame.WriteUInt32(ping_size); | |
| 1191 frame.WriteUInt32(unique_id); | 1161 frame.WriteUInt32(unique_id); |
| 1162 DCHECK_EQ(static_cast<size_t>(frame.length()), frame_size); |
| 1192 return reinterpret_cast<SpdyPingControlFrame*>(frame.take()); | 1163 return reinterpret_cast<SpdyPingControlFrame*>(frame.take()); |
| 1193 } | 1164 } |
| 1194 | 1165 |
| 1195 SpdyGoAwayControlFrame* SpdyFramer::CreateGoAway( | 1166 SpdyGoAwayControlFrame* SpdyFramer::CreateGoAway( |
| 1196 SpdyStreamId last_accepted_stream_id, | 1167 SpdyStreamId last_accepted_stream_id, |
| 1197 SpdyGoAwayStatus status) const { | 1168 SpdyGoAwayStatus status) const { |
| 1198 DCHECK_EQ(0u, last_accepted_stream_id & ~kStreamIdMask); | 1169 DCHECK_EQ(0u, last_accepted_stream_id & ~kStreamIdMask); |
| 1199 | 1170 |
| 1200 // SPDY 2 GOAWAY frames are 4 bytes smaller than in SPDY 3. We account for | 1171 // SPDY 2 GOAWAY frames are 4 bytes smaller than in SPDY 3. We account for |
| 1201 // this difference via a separate offset variable, since | 1172 // this difference via a separate offset variable, since |
| 1202 // SpdyGoAwayControlFrame::size() returns the SPDY 3 size. | 1173 // SpdyGoAwayControlFrame::size() returns the SPDY 3 size. |
| 1203 const size_t goaway_offset = (protocol_version() < 3) ? 4 : 0; | 1174 const size_t goaway_offset = (protocol_version() < 3) ? 4 : 0; |
| 1204 SpdyFrameBuilder frame(SpdyGoAwayControlFrame::size() - goaway_offset); | 1175 size_t frame_size = SpdyGoAwayControlFrame::size() - goaway_offset; |
| 1205 frame.WriteUInt16(kControlFlagMask | spdy_version_); | 1176 SpdyFrameBuilder frame(GOAWAY, CONTROL_FLAG_NONE, spdy_version_, frame_size); |
| 1206 frame.WriteUInt16(GOAWAY); | |
| 1207 size_t go_away_size = | |
| 1208 SpdyGoAwayControlFrame::size() - SpdyFrame::kHeaderSize - goaway_offset; | |
| 1209 frame.WriteUInt32(go_away_size); | |
| 1210 frame.WriteUInt32(last_accepted_stream_id); | 1177 frame.WriteUInt32(last_accepted_stream_id); |
| 1211 if (protocol_version() >= 3) { | 1178 if (protocol_version() >= 3) { |
| 1212 frame.WriteUInt32(status); | 1179 frame.WriteUInt32(status); |
| 1213 } | 1180 } |
| 1181 DCHECK_EQ(static_cast<size_t>(frame.length()), frame_size); |
| 1214 return reinterpret_cast<SpdyGoAwayControlFrame*>(frame.take()); | 1182 return reinterpret_cast<SpdyGoAwayControlFrame*>(frame.take()); |
| 1215 } | 1183 } |
| 1216 | 1184 |
| 1217 SpdyHeadersControlFrame* SpdyFramer::CreateHeaders( | 1185 SpdyHeadersControlFrame* SpdyFramer::CreateHeaders( |
| 1218 SpdyStreamId stream_id, | 1186 SpdyStreamId stream_id, |
| 1219 SpdyControlFlags flags, | 1187 SpdyControlFlags flags, |
| 1220 bool compressed, | 1188 bool compressed, |
| 1221 const SpdyHeaderBlock* headers) { | 1189 const SpdyHeaderBlock* headers) { |
| 1222 // Basically the same as CreateSynReply(). | 1190 // Basically the same as CreateSynReply(). |
| 1223 DCHECK_GT(stream_id, 0u); | 1191 DCHECK_GT(stream_id, 0u); |
| 1224 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); | 1192 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); |
| 1225 | 1193 |
| 1226 // Find our length. | 1194 // Find our length. |
| 1227 size_t expected_frame_size = SpdyHeadersControlFrame::size() + | 1195 size_t frame_size = SpdyHeadersControlFrame::size() + |
| 1228 GetSerializedLength(headers); | 1196 GetSerializedLength(headers); |
| 1229 // In SPDY 2, there were 2 unused bytes before payload. | 1197 // In SPDY 2, there were 2 unused bytes before payload. |
| 1230 if (spdy_version_ < 3) { | 1198 if (spdy_version_ < 3) { |
| 1231 expected_frame_size += 2; | 1199 frame_size += 2; |
| 1232 } | 1200 } |
| 1233 | 1201 |
| 1234 // Create our FlagsAndLength. | 1202 SpdyFrameBuilder frame(HEADERS, flags, spdy_version_, frame_size); |
| 1235 FlagsAndLength flags_length = CreateFlagsAndLength( | |
| 1236 flags, | |
| 1237 expected_frame_size - SpdyFrame::kHeaderSize); | |
| 1238 | |
| 1239 SpdyFrameBuilder frame(expected_frame_size); | |
| 1240 frame.WriteUInt16(kControlFlagMask | spdy_version_); | |
| 1241 frame.WriteUInt16(HEADERS); | |
| 1242 frame.WriteBytes(&flags_length, sizeof(flags_length)); | |
| 1243 frame.WriteUInt32(stream_id); | 1203 frame.WriteUInt32(stream_id); |
| 1244 if (spdy_version_ < 3) { | 1204 if (spdy_version_ < 3) { |
| 1245 frame.WriteUInt16(0); // Unused | 1205 frame.WriteUInt16(0); // Unused |
| 1246 } | 1206 } |
| 1247 WriteHeaderBlock(&frame, headers); | 1207 WriteHeaderBlock(&frame, headers); |
| 1248 DCHECK_EQ(static_cast<size_t>(frame.length()), expected_frame_size); | 1208 DCHECK_EQ(static_cast<size_t>(frame.length()), frame_size); |
| 1249 | 1209 |
| 1250 scoped_ptr<SpdyHeadersControlFrame> headers_frame( | 1210 scoped_ptr<SpdyHeadersControlFrame> headers_frame( |
| 1251 reinterpret_cast<SpdyHeadersControlFrame*>(frame.take())); | 1211 reinterpret_cast<SpdyHeadersControlFrame*>(frame.take())); |
| 1252 if (compressed) { | 1212 if (compressed) { |
| 1253 return reinterpret_cast<SpdyHeadersControlFrame*>( | 1213 return reinterpret_cast<SpdyHeadersControlFrame*>( |
| 1254 CompressControlFrame(*headers_frame.get())); | 1214 CompressControlFrame(*headers_frame.get())); |
| 1255 } | 1215 } |
| 1256 return headers_frame.release(); | 1216 return headers_frame.release(); |
| 1257 } | 1217 } |
| 1258 | 1218 |
| 1259 SpdyWindowUpdateControlFrame* SpdyFramer::CreateWindowUpdate( | 1219 SpdyWindowUpdateControlFrame* SpdyFramer::CreateWindowUpdate( |
| 1260 SpdyStreamId stream_id, | 1220 SpdyStreamId stream_id, |
| 1261 uint32 delta_window_size) const { | 1221 uint32 delta_window_size) const { |
| 1262 DCHECK_GT(stream_id, 0u); | 1222 DCHECK_GT(stream_id, 0u); |
| 1263 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); | 1223 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); |
| 1264 DCHECK_GT(delta_window_size, 0u); | 1224 DCHECK_GT(delta_window_size, 0u); |
| 1265 DCHECK_LE(delta_window_size, | 1225 DCHECK_LE(delta_window_size, |
| 1266 static_cast<uint32>(kSpdyStreamMaximumWindowSize)); | 1226 static_cast<uint32>(kSpdyStreamMaximumWindowSize)); |
| 1267 | 1227 |
| 1268 SpdyFrameBuilder frame(SpdyWindowUpdateControlFrame::size()); | 1228 size_t frame_size = SpdyWindowUpdateControlFrame::size(); |
| 1269 frame.WriteUInt16(kControlFlagMask | spdy_version_); | 1229 SpdyFrameBuilder frame(WINDOW_UPDATE, CONTROL_FLAG_NONE, spdy_version_, |
| 1270 frame.WriteUInt16(WINDOW_UPDATE); | 1230 frame_size); |
| 1271 size_t window_update_size = SpdyWindowUpdateControlFrame::size() - | |
| 1272 SpdyFrame::kHeaderSize; | |
| 1273 frame.WriteUInt32(window_update_size); | |
| 1274 frame.WriteUInt32(stream_id); | 1231 frame.WriteUInt32(stream_id); |
| 1275 frame.WriteUInt32(delta_window_size); | 1232 frame.WriteUInt32(delta_window_size); |
| 1233 DCHECK_EQ(static_cast<size_t>(frame.length()), frame_size); |
| 1276 return reinterpret_cast<SpdyWindowUpdateControlFrame*>(frame.take()); | 1234 return reinterpret_cast<SpdyWindowUpdateControlFrame*>(frame.take()); |
| 1277 } | 1235 } |
| 1278 | 1236 |
| 1279 SpdyCredentialControlFrame* SpdyFramer::CreateCredentialFrame( | 1237 SpdyCredentialControlFrame* SpdyFramer::CreateCredentialFrame( |
| 1280 const SpdyCredential& credential) const { | 1238 const SpdyCredential& credential) const { |
| 1281 // Calculate the size of the frame by adding the size of the | 1239 // Calculate the size of the frame by adding the size of the |
| 1282 // variable length data to the size of the fixed length data. | 1240 // variable length data to the size of the fixed length data. |
| 1283 size_t frame_size = SpdyCredentialControlFrame::size() + | 1241 size_t frame_size = SpdyCredentialControlFrame::size() + |
| 1284 credential.proof.length(); | 1242 credential.proof.length(); |
| 1285 DCHECK_EQ(SpdyCredentialControlFrame::size(), 14u); | 1243 DCHECK_EQ(SpdyCredentialControlFrame::size(), 14u); |
| 1286 for (std::vector<std::string>::const_iterator cert = credential.certs.begin(); | 1244 for (std::vector<std::string>::const_iterator cert = credential.certs.begin(); |
| 1287 cert != credential.certs.end(); | 1245 cert != credential.certs.end(); |
| 1288 ++cert) { | 1246 ++cert) { |
| 1289 frame_size += sizeof(uint32); // size of the cert_length field | 1247 frame_size += sizeof(uint32); // size of the cert_length field |
| 1290 frame_size += cert->length(); // size of the cert_data field | 1248 frame_size += cert->length(); // size of the cert_data field |
| 1291 } | 1249 } |
| 1292 size_t payload_size = frame_size - SpdyFrame::kHeaderSize; | |
| 1293 | 1250 |
| 1294 SpdyFrameBuilder frame(frame_size); | 1251 SpdyFrameBuilder frame(CREDENTIAL, CONTROL_FLAG_NONE, spdy_version_, |
| 1295 // Create our FlagsAndLength. | 1252 frame_size); |
| 1296 SpdyControlFlags flags = CONTROL_FLAG_NONE; | |
| 1297 FlagsAndLength flags_length = CreateFlagsAndLength(flags, payload_size); | |
| 1298 | |
| 1299 frame.WriteUInt16(kControlFlagMask | spdy_version_); | |
| 1300 frame.WriteUInt16(CREDENTIAL); | |
| 1301 frame.WriteBytes(&flags_length, sizeof(flags_length)); | |
| 1302 frame.WriteUInt16(credential.slot); | 1253 frame.WriteUInt16(credential.slot); |
| 1303 frame.WriteUInt32(credential.proof.size()); | 1254 frame.WriteUInt32(credential.proof.size()); |
| 1304 frame.WriteBytes(credential.proof.c_str(), credential.proof.size()); | 1255 frame.WriteBytes(credential.proof.c_str(), credential.proof.size()); |
| 1305 for (std::vector<std::string>::const_iterator cert = credential.certs.begin(); | 1256 for (std::vector<std::string>::const_iterator cert = credential.certs.begin(); |
| 1306 cert != credential.certs.end(); | 1257 cert != credential.certs.end(); |
| 1307 ++cert) { | 1258 ++cert) { |
| 1308 frame.WriteUInt32(cert->length()); | 1259 frame.WriteUInt32(cert->length()); |
| 1309 frame.WriteBytes(cert->c_str(), cert->length()); | 1260 frame.WriteBytes(cert->c_str(), cert->length()); |
| 1310 } | 1261 } |
| 1262 DCHECK_EQ(static_cast<size_t>(frame.length()), frame_size); |
| 1311 return reinterpret_cast<SpdyCredentialControlFrame*>(frame.take()); | 1263 return reinterpret_cast<SpdyCredentialControlFrame*>(frame.take()); |
| 1312 } | 1264 } |
| 1313 | 1265 |
| 1314 SpdyDataFrame* SpdyFramer::CreateDataFrame(SpdyStreamId stream_id, | 1266 SpdyDataFrame* SpdyFramer::CreateDataFrame(SpdyStreamId stream_id, |
| 1315 const char* data, | 1267 const char* data, |
| 1316 uint32 len, SpdyDataFlags flags) { | 1268 uint32 len, SpdyDataFlags flags) { |
| 1317 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); | 1269 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); |
| 1318 | 1270 |
| 1319 SpdyFrameBuilder frame(SpdyDataFrame::size() + len); | 1271 size_t frame_size = SpdyDataFrame::size() + len; |
| 1320 frame.WriteUInt32(stream_id); | 1272 SpdyFrameBuilder frame(stream_id, flags, frame_size); |
| 1321 | |
| 1322 DCHECK_EQ(0u, len & ~static_cast<size_t>(kLengthMask)); | |
| 1323 FlagsAndLength flags_length; | |
| 1324 flags_length.length_ = htonl(len); | |
| 1325 DCHECK_EQ(0, flags & ~kDataFlagsMask); | |
| 1326 flags_length.flags_[0] = flags; | |
| 1327 frame.WriteBytes(&flags_length, sizeof(flags_length)); | |
| 1328 | |
| 1329 frame.WriteBytes(data, len); | 1273 frame.WriteBytes(data, len); |
| 1274 DCHECK_EQ(static_cast<size_t>(frame.length()), frame_size); |
| 1330 scoped_ptr<SpdyFrame> data_frame(frame.take()); | 1275 scoped_ptr<SpdyFrame> data_frame(frame.take()); |
| 1331 SpdyDataFrame* rv; | 1276 SpdyDataFrame* rv; |
| 1332 if (flags & DATA_FLAG_COMPRESSED) { | 1277 if (flags & DATA_FLAG_COMPRESSED) { |
| 1333 LOG(DFATAL) << "DATA_FLAG_COMPRESSED invalid for " << display_protocol_ | 1278 LOG(DFATAL) << "DATA_FLAG_COMPRESSED invalid for " << display_protocol_ |
| 1334 << "."; | 1279 << "."; |
| 1335 } | 1280 } |
| 1336 rv = reinterpret_cast<SpdyDataFrame*>(data_frame.release()); | 1281 rv = reinterpret_cast<SpdyDataFrame*>(data_frame.release()); |
| 1337 | 1282 |
| 1338 if (flags & DATA_FLAG_FIN) { | 1283 if (flags & DATA_FLAG_FIN) { |
| 1339 CleanupCompressorForStream(stream_id); | 1284 CleanupCompressorForStream(stream_id); |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1802 | 1747 |
| 1803 void SpdyFramer::set_validate_control_frame_sizes(bool value) { | 1748 void SpdyFramer::set_validate_control_frame_sizes(bool value) { |
| 1804 validate_control_frame_sizes_ = value; | 1749 validate_control_frame_sizes_ = value; |
| 1805 } | 1750 } |
| 1806 | 1751 |
| 1807 void SpdyFramer::set_enable_compression_default(bool value) { | 1752 void SpdyFramer::set_enable_compression_default(bool value) { |
| 1808 g_enable_compression_default = value; | 1753 g_enable_compression_default = value; |
| 1809 } | 1754 } |
| 1810 | 1755 |
| 1811 } // namespace net | 1756 } // namespace net |
| OLD | NEW |