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 |