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 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 return 8; | 160 return 8; |
161 } | 161 } |
162 | 162 |
163 // Size, in bytes, of the control frame header. | 163 // Size, in bytes, of the control frame header. |
164 size_t SpdyFramer::GetControlFrameHeaderSize() const { | 164 size_t SpdyFramer::GetControlFrameHeaderSize() const { |
165 switch (protocol_version()) { | 165 switch (protocol_version()) { |
166 case 2: | 166 case 2: |
167 case 3: | 167 case 3: |
168 return 8; | 168 return 8; |
169 case 4: | 169 case 4: |
170 return 4; | 170 return 8; |
171 } | 171 } |
172 LOG(DFATAL) << "Unhandled SPDY version."; | 172 LOG(DFATAL) << "Unhandled SPDY version."; |
173 return 0; | 173 return 0; |
174 } | 174 } |
175 | 175 |
176 size_t SpdyFramer::GetSynStreamMinimumSize() const { | 176 size_t SpdyFramer::GetSynStreamMinimumSize() const { |
177 // Size, in bytes, of a SYN_STREAM frame not including the variable-length | 177 // Size, in bytes, of a SYN_STREAM frame not including the variable-length |
178 // name-value block. Calculated as: | 178 // name-value block. |
179 // control frame header + 2 * 4 (stream IDs) + 1 (priority) + 1 (slot) | 179 if (spdy_version_ < 4) { |
180 return GetControlFrameHeaderSize() + 10; | 180 // Calculated as: |
| 181 // control frame header + 2 * 4 (stream IDs) + 1 (priority) + 1 (slot) |
| 182 return GetControlFrameHeaderSize() + 10; |
| 183 } else { |
| 184 // Calculated as: |
| 185 // frame prefix + 4 (associated stream ID) + 1 (priority) + 1 (slot) |
| 186 return GetControlFrameHeaderSize() + 6; |
| 187 } |
181 } | 188 } |
182 | 189 |
183 size_t SpdyFramer::GetSynReplyMinimumSize() const { | 190 size_t SpdyFramer::GetSynReplyMinimumSize() const { |
184 // Size, in bytes, of a SYN_REPLY frame not including the variable-length | 191 // Size, in bytes, of a SYN_REPLY frame not including the variable-length |
185 // name-value block. Calculated as: | 192 // name-value block. |
186 // control frame header + 4 (stream ID) | 193 size_t size = GetControlFrameHeaderSize(); |
187 size_t size = GetControlFrameHeaderSize() + 4; | 194 if (spdy_version_ < 4) { |
| 195 // Calculated as: |
| 196 // control frame header + 4 (stream IDs) |
| 197 size += 4; |
| 198 } |
188 | 199 |
189 // In SPDY 2, there were 2 unused bytes before payload. | 200 // In SPDY 2, there were 2 unused bytes before payload. |
190 if (protocol_version() < 3) { | 201 if (protocol_version() < 3) { |
191 size += 2; | 202 size += 2; |
192 } | 203 } |
193 | 204 |
194 return size; | 205 return size; |
195 } | 206 } |
196 | 207 |
197 size_t SpdyFramer::GetRstStreamSize() const { | 208 size_t SpdyFramer::GetRstStreamSize() const { |
198 // Size, in bytes, of a RST_STREAM frame. Calculated as: | 209 // Size, in bytes, of a RST_STREAM frame. |
199 // control frame header + 4 (stream id) + 4 (status code) | 210 if (spdy_version_ < 4) { |
200 return GetControlFrameHeaderSize() + 8; | 211 // Calculated as: |
| 212 // control frame header + 4 (stream id) + 4 (status code) |
| 213 return GetControlFrameHeaderSize() + 8; |
| 214 } else { |
| 215 // Calculated as: |
| 216 // frame prefix + 4 (status code) |
| 217 return GetControlFrameHeaderSize() + 4; |
| 218 } |
201 } | 219 } |
202 | 220 |
203 size_t SpdyFramer::GetSettingsMinimumSize() const { | 221 size_t SpdyFramer::GetSettingsMinimumSize() const { |
204 // Size, in bytes, of a SETTINGS frame not including the IDs and values | 222 // Size, in bytes, of a SETTINGS frame not including the IDs and values |
205 // from the variable-length value block. Calculated as: | 223 // from the variable-length value block. Calculated as: |
206 // control frame header + 4 (number of ID/value pairs) | 224 // control frame header + 4 (number of ID/value pairs) |
207 return GetControlFrameHeaderSize() + 4; | 225 return GetControlFrameHeaderSize() + 4; |
208 } | 226 } |
209 | 227 |
210 size_t SpdyFramer::GetPingSize() const { | 228 size_t SpdyFramer::GetPingSize() const { |
211 // Size, in bytes, of this PING frame. Calculated as: | 229 // Size, in bytes, of this PING frame. Calculated as: |
212 // control frame header + 4 (id) | 230 // control frame header + 4 (id) |
213 return GetControlFrameHeaderSize() + 4; | 231 return GetControlFrameHeaderSize() + 4; |
214 } | 232 } |
215 | 233 |
216 size_t SpdyFramer::GetGoAwaySize() const { | 234 size_t SpdyFramer::GetGoAwaySize() const { |
217 // Size, in bytes, of this GOAWAY frame. Calculated as: | 235 // Size, in bytes, of this GOAWAY frame. Calculated as: |
218 // control frame header + 4 (last good stream id) | 236 // control frame header + 4 (last good stream id) |
219 size_t size = GetControlFrameHeaderSize() + 4; | 237 size_t size = GetControlFrameHeaderSize() + 4; |
220 | 238 |
221 // SPDY 3+ GOAWAY frames also contain a status. | 239 // SPDY 3+ GOAWAY frames also contain a status. |
222 if (protocol_version() >= 3) { | 240 if (protocol_version() >= 3) { |
223 size += 4; | 241 size += 4; |
224 } | 242 } |
225 | 243 |
226 return size; | 244 return size; |
227 } | 245 } |
228 | 246 |
229 size_t SpdyFramer::GetHeadersMinimumSize() const { | 247 size_t SpdyFramer::GetHeadersMinimumSize() const { |
230 // Size, in bytes, of a HEADERS frame not including the variable-length | 248 // Size, in bytes, of a SYN_REPLY frame not including the variable-length |
231 // name-value block. Calculated as: | 249 // name-value block. |
232 // control frame header + 4 (stream ID) | 250 size_t size = GetControlFrameHeaderSize(); |
233 size_t size = GetControlFrameHeaderSize() + 4; | 251 if (spdy_version_ < 4) { |
| 252 // Calculated as: |
| 253 // control frame header + 4 (stream IDs) |
| 254 size += 4; |
| 255 } |
234 | 256 |
235 // In SPDY 2, there were 2 unused bytes before payload. | 257 // In SPDY 2, there were 2 unused bytes before payload. |
236 if (protocol_version() < 3) { | 258 if (protocol_version() < 3) { |
237 size += 2; | 259 size += 2; |
238 } | 260 } |
239 | 261 |
240 return size; | 262 return size; |
241 } | 263 } |
242 | 264 |
243 size_t SpdyFramer::GetWindowUpdateSize() const { | 265 size_t SpdyFramer::GetWindowUpdateSize() const { |
244 // Size, in bytes, of this WINDOW_UPDATE frame. Calculated as: | 266 // Size, in bytes, of a WINDOW_UPDATE frame. |
245 // control frame header + 4 (stream id) + 4 (delta) | 267 if (spdy_version_ < 4) { |
246 return GetControlFrameHeaderSize() + 8; | 268 // Calculated as: |
| 269 // control frame header + 4 (stream id) + 4 (delta) |
| 270 return GetControlFrameHeaderSize() + 8; |
| 271 } else { |
| 272 // Calculated as: |
| 273 // frame prefix + 4 (delta) |
| 274 return GetControlFrameHeaderSize() + 4; |
| 275 } |
247 } | 276 } |
248 | 277 |
249 size_t SpdyFramer::GetCredentialMinimumSize() const { | 278 size_t SpdyFramer::GetCredentialMinimumSize() const { |
250 // Size, in bytes, of a CREDENTIAL frame sans variable-length certificate list | 279 // Size, in bytes, of a CREDENTIAL frame sans variable-length certificate list |
251 // and proof. Calculated as: | 280 // and proof. Calculated as: |
252 // control frame header + 2 (slot) | 281 // control frame header + 2 (slot) |
253 return GetControlFrameHeaderSize() + 2; | 282 return GetControlFrameHeaderSize() + 2; |
254 } | 283 } |
255 | 284 |
256 size_t SpdyFramer::GetFrameMinimumSize() const { | 285 size_t SpdyFramer::GetFrameMinimumSize() const { |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 | 564 |
536 successful_read = reader->ReadUInt8(¤t_frame_flags_); | 565 successful_read = reader->ReadUInt8(¤t_frame_flags_); |
537 DCHECK(successful_read); | 566 DCHECK(successful_read); |
538 | 567 |
539 uint32 length_field = 0; | 568 uint32 length_field = 0; |
540 successful_read = reader->ReadUInt24(&length_field); | 569 successful_read = reader->ReadUInt24(&length_field); |
541 DCHECK(successful_read); | 570 DCHECK(successful_read); |
542 remaining_data_length_ = length_field; | 571 remaining_data_length_ = length_field; |
543 current_frame_length_ = remaining_data_length_ + reader->GetBytesConsumed(); | 572 current_frame_length_ = remaining_data_length_ + reader->GetBytesConsumed(); |
544 } else { | 573 } else { |
545 // TODO(hkhalil): Avoid re-reading fields as possible for DATA frames? | |
546 version = protocol_version(); | 574 version = protocol_version(); |
547 uint16 length_field = 0; | 575 uint16 length_field = 0; |
548 bool successful_read = reader->ReadUInt16(&length_field); | 576 bool successful_read = reader->ReadUInt16(&length_field); |
549 DCHECK(successful_read); | 577 DCHECK(successful_read); |
550 current_frame_length_ = length_field; | 578 current_frame_length_ = length_field; |
551 | 579 |
552 uint8 control_frame_type_field_uint8 = DATA; | 580 uint8 control_frame_type_field_uint8 = DATA; |
553 successful_read = reader->ReadUInt8(&control_frame_type_field_uint8); | 581 successful_read = reader->ReadUInt8(&control_frame_type_field_uint8); |
554 DCHECK(successful_read); | 582 DCHECK(successful_read); |
555 // We check control_frame_type_field's validity in | 583 // We check control_frame_type_field's validity in |
556 // ProcessControlFrameHeader(). | 584 // ProcessControlFrameHeader(). |
557 control_frame_type_field = control_frame_type_field_uint8; | 585 control_frame_type_field = control_frame_type_field_uint8; |
558 is_control_frame = (control_frame_type_field != DATA); | 586 is_control_frame = (control_frame_type_field != DATA); |
559 | 587 |
560 successful_read = reader->ReadUInt8(¤t_frame_flags_); | 588 successful_read = reader->ReadUInt8(¤t_frame_flags_); |
561 DCHECK(successful_read); | 589 DCHECK(successful_read); |
562 | 590 |
563 if (!is_control_frame) { | 591 successful_read = reader->ReadUInt31(¤t_frame_stream_id_); |
564 // We may not have the entirety of the DATA frame header. | 592 DCHECK(successful_read); |
565 if (current_frame_buffer_length_ < GetDataFrameMinimumSize()) { | 593 |
566 size_t bytes_desired = | |
567 GetDataFrameMinimumSize() - current_frame_buffer_length_; | |
568 UpdateCurrentFrameBuffer(&data, &len, bytes_desired); | |
569 if (current_frame_buffer_length_ < GetDataFrameMinimumSize()) { | |
570 return original_len - len; | |
571 } | |
572 } | |
573 // Construct a new SpdyFrameReader aware of the new frame length. | |
574 reader.reset(new SpdyFrameReader(current_frame_buffer_.get(), | |
575 current_frame_buffer_length_)); | |
576 reader->Seek(GetControlFrameHeaderSize()); | |
577 successful_read = reader->ReadUInt31(¤t_frame_stream_id_); | |
578 DCHECK(successful_read); | |
579 } | |
580 remaining_data_length_ = current_frame_length_ - reader->GetBytesConsumed(); | 594 remaining_data_length_ = current_frame_length_ - reader->GetBytesConsumed(); |
581 } | 595 } |
582 DCHECK_EQ(is_control_frame ? GetControlFrameHeaderSize() | 596 DCHECK_EQ(is_control_frame ? GetControlFrameHeaderSize() |
583 : GetDataFrameMinimumSize(), | 597 : GetDataFrameMinimumSize(), |
584 reader->GetBytesConsumed()); | 598 reader->GetBytesConsumed()); |
585 DCHECK_EQ(current_frame_length_, | 599 DCHECK_EQ(current_frame_length_, |
586 remaining_data_length_ + reader->GetBytesConsumed()); | 600 remaining_data_length_ + reader->GetBytesConsumed()); |
587 | 601 |
588 // This is just a sanity check for help debugging early frame errors. | 602 // This is just a sanity check for help debugging early frame errors. |
589 if (remaining_data_length_ > 1000000u) { | 603 if (remaining_data_length_ > 1000000u) { |
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1035 } | 1049 } |
1036 | 1050 |
1037 if (remaining_control_header_ == 0) { | 1051 if (remaining_control_header_ == 0) { |
1038 SpdyFrameReader reader(current_frame_buffer_.get(), | 1052 SpdyFrameReader reader(current_frame_buffer_.get(), |
1039 current_frame_buffer_length_); | 1053 current_frame_buffer_length_); |
1040 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header. | 1054 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header. |
1041 | 1055 |
1042 switch (current_frame_type_) { | 1056 switch (current_frame_type_) { |
1043 case SYN_STREAM: | 1057 case SYN_STREAM: |
1044 { | 1058 { |
1045 bool successful_read = reader.ReadUInt31(¤t_frame_stream_id_); | 1059 bool successful_read = true; |
1046 DCHECK(successful_read); | 1060 if (spdy_version_ < 4) { |
| 1061 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); |
| 1062 DCHECK(successful_read); |
| 1063 } |
1047 | 1064 |
1048 SpdyStreamId associated_to_stream_id = kInvalidStream; | 1065 SpdyStreamId associated_to_stream_id = kInvalidStream; |
1049 successful_read = reader.ReadUInt31(&associated_to_stream_id); | 1066 successful_read = reader.ReadUInt31(&associated_to_stream_id); |
1050 DCHECK(successful_read); | 1067 DCHECK(successful_read); |
1051 | 1068 |
1052 SpdyPriority priority = 0; | 1069 SpdyPriority priority = 0; |
1053 successful_read = reader.ReadUInt8(&priority); | 1070 successful_read = reader.ReadUInt8(&priority); |
1054 DCHECK(successful_read); | 1071 DCHECK(successful_read); |
1055 if (protocol_version() < 3) { | 1072 if (protocol_version() < 3) { |
1056 priority = priority >> 6; | 1073 priority = priority >> 6; |
(...skipping 18 matching lines...) Expand all Loading... |
1075 slot, | 1092 slot, |
1076 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, | 1093 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, |
1077 (current_frame_flags_ & CONTROL_FLAG_UNIDIRECTIONAL) != 0); | 1094 (current_frame_flags_ & CONTROL_FLAG_UNIDIRECTIONAL) != 0); |
1078 } | 1095 } |
1079 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); | 1096 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); |
1080 break; | 1097 break; |
1081 case SYN_REPLY: | 1098 case SYN_REPLY: |
1082 case HEADERS: | 1099 case HEADERS: |
1083 // SYN_REPLY and HEADERS are the same, save for the visitor call. | 1100 // SYN_REPLY and HEADERS are the same, save for the visitor call. |
1084 { | 1101 { |
1085 bool successful_read = reader.ReadUInt31(¤t_frame_stream_id_); | 1102 bool successful_read = true; |
1086 DCHECK(successful_read); | 1103 if (spdy_version_ < 4) { |
| 1104 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); |
| 1105 DCHECK(successful_read); |
| 1106 } |
1087 if (protocol_version() < 3) { | 1107 if (protocol_version() < 3) { |
1088 // SPDY 2 had two unused bytes here. Seek past them. | 1108 // SPDY 2 had two unused bytes here. Seek past them. |
1089 reader.Seek(2); | 1109 reader.Seek(2); |
1090 } | 1110 } |
1091 DCHECK(reader.IsDoneReading()); | 1111 DCHECK(reader.IsDoneReading()); |
1092 if (current_frame_type_ == SYN_REPLY) { | 1112 if (current_frame_type_ == SYN_REPLY) { |
1093 visitor_->OnSynReply( | 1113 visitor_->OnSynReply( |
1094 current_frame_stream_id_, | 1114 current_frame_stream_id_, |
1095 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0); | 1115 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0); |
1096 } else { | 1116 } else { |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1281 case PING: { | 1301 case PING: { |
1282 SpdyPingId id = 0; | 1302 SpdyPingId id = 0; |
1283 bool successful_read = reader.ReadUInt32(&id); | 1303 bool successful_read = reader.ReadUInt32(&id); |
1284 DCHECK(successful_read); | 1304 DCHECK(successful_read); |
1285 DCHECK(reader.IsDoneReading()); | 1305 DCHECK(reader.IsDoneReading()); |
1286 visitor_->OnPing(id); | 1306 visitor_->OnPing(id); |
1287 } | 1307 } |
1288 break; | 1308 break; |
1289 case WINDOW_UPDATE: { | 1309 case WINDOW_UPDATE: { |
1290 uint32 delta_window_size = 0; | 1310 uint32 delta_window_size = 0; |
1291 bool successful_read = reader.ReadUInt31(¤t_frame_stream_id_); | 1311 bool successful_read = true; |
1292 DCHECK(successful_read); | 1312 if (spdy_version_ < 4) { |
1293 successful_read = reader.ReadUInt31(&delta_window_size); | 1313 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); |
| 1314 DCHECK(successful_read); |
| 1315 } |
| 1316 successful_read = reader.ReadUInt32(&delta_window_size); |
1294 DCHECK(successful_read); | 1317 DCHECK(successful_read); |
1295 DCHECK(reader.IsDoneReading()); | 1318 DCHECK(reader.IsDoneReading()); |
1296 visitor_->OnWindowUpdate(current_frame_stream_id_, | 1319 visitor_->OnWindowUpdate(current_frame_stream_id_, |
1297 delta_window_size); | 1320 delta_window_size); |
1298 } | 1321 } |
1299 break; | 1322 break; |
1300 case RST_STREAM: { | 1323 case RST_STREAM: { |
1301 bool successful_read = reader.ReadUInt32(¤t_frame_stream_id_); | 1324 bool successful_read = true; |
1302 DCHECK(successful_read); | 1325 if (spdy_version_ < 4) { |
| 1326 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); |
| 1327 DCHECK(successful_read); |
| 1328 } |
1303 SpdyRstStreamStatus status = RST_STREAM_INVALID; | 1329 SpdyRstStreamStatus status = RST_STREAM_INVALID; |
1304 uint32 status_raw = status; | 1330 uint32 status_raw = status; |
1305 successful_read = reader.ReadUInt32(&status_raw); | 1331 successful_read = reader.ReadUInt32(&status_raw); |
1306 DCHECK(successful_read); | 1332 DCHECK(successful_read); |
1307 if (status_raw > RST_STREAM_INVALID && | 1333 if (status_raw > RST_STREAM_INVALID && |
1308 status_raw < RST_STREAM_NUM_STATUS_CODES) { | 1334 status_raw < RST_STREAM_NUM_STATUS_CODES) { |
1309 status = static_cast<SpdyRstStreamStatus>(status_raw); | 1335 status = static_cast<SpdyRstStreamStatus>(status_raw); |
1310 } else { | 1336 } else { |
1311 // TODO(hkhalil): Probably best to OnError here, depending on | 1337 // TODO(hkhalil): Probably best to OnError here, depending on |
1312 // our interpretation of the spec. Keeping with existing liberal | 1338 // our interpretation of the spec. Keeping with existing liberal |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1504 } | 1530 } |
1505 if (syn_stream.unidirectional()) { | 1531 if (syn_stream.unidirectional()) { |
1506 flags |= CONTROL_FLAG_UNIDIRECTIONAL; | 1532 flags |= CONTROL_FLAG_UNIDIRECTIONAL; |
1507 } | 1533 } |
1508 | 1534 |
1509 // The size of this frame, including variable-length name-value block. | 1535 // The size of this frame, including variable-length name-value block. |
1510 const size_t size = GetSynStreamMinimumSize() | 1536 const size_t size = GetSynStreamMinimumSize() |
1511 + GetSerializedLength(syn_stream.name_value_block()); | 1537 + GetSerializedLength(syn_stream.name_value_block()); |
1512 | 1538 |
1513 SpdyFrameBuilder builder(size); | 1539 SpdyFrameBuilder builder(size); |
1514 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags); | 1540 if (spdy_version_ < 4) { |
1515 builder.WriteUInt32(syn_stream.stream_id()); | 1541 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags); |
| 1542 builder.WriteUInt32(syn_stream.stream_id()); |
| 1543 } else { |
| 1544 builder.WriteFramePrefix(*this, |
| 1545 SYN_STREAM, |
| 1546 flags, |
| 1547 syn_stream.stream_id()); |
| 1548 } |
1516 builder.WriteUInt32(syn_stream.associated_to_stream_id()); | 1549 builder.WriteUInt32(syn_stream.associated_to_stream_id()); |
1517 uint8 priority = syn_stream.priority(); | 1550 uint8 priority = syn_stream.priority(); |
1518 if (priority > GetLowestPriority()) { | 1551 if (priority > GetLowestPriority()) { |
1519 DLOG(DFATAL) << "Priority out-of-bounds."; | 1552 DLOG(DFATAL) << "Priority out-of-bounds."; |
1520 priority = GetLowestPriority(); | 1553 priority = GetLowestPriority(); |
1521 } | 1554 } |
1522 builder.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5)); | 1555 builder.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5)); |
1523 builder.WriteUInt8(syn_stream.slot()); | 1556 builder.WriteUInt8(syn_stream.slot()); |
1524 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length()); | 1557 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length()); |
1525 SerializeNameValueBlock(&builder, syn_stream); | 1558 SerializeNameValueBlock(&builder, syn_stream); |
(...skipping 26 matching lines...) Expand all Loading... |
1552 uint8 flags = 0; | 1585 uint8 flags = 0; |
1553 if (syn_reply.fin()) { | 1586 if (syn_reply.fin()) { |
1554 flags |= CONTROL_FLAG_FIN; | 1587 flags |= CONTROL_FLAG_FIN; |
1555 } | 1588 } |
1556 | 1589 |
1557 // The size of this frame, including variable-length name-value block. | 1590 // The size of this frame, including variable-length name-value block. |
1558 size_t size = GetSynReplyMinimumSize() | 1591 size_t size = GetSynReplyMinimumSize() |
1559 + GetSerializedLength(syn_reply.name_value_block()); | 1592 + GetSerializedLength(syn_reply.name_value_block()); |
1560 | 1593 |
1561 SpdyFrameBuilder builder(size); | 1594 SpdyFrameBuilder builder(size); |
1562 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags); | 1595 if (spdy_version_ < 4) { |
1563 builder.WriteUInt32(syn_reply.stream_id()); | 1596 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags); |
| 1597 builder.WriteUInt32(syn_reply.stream_id()); |
| 1598 } else { |
| 1599 builder.WriteFramePrefix(*this, |
| 1600 SYN_REPLY, |
| 1601 flags, |
| 1602 syn_reply.stream_id()); |
| 1603 } |
1564 if (protocol_version() < 3) { | 1604 if (protocol_version() < 3) { |
1565 builder.WriteUInt16(0); // Unused. | 1605 builder.WriteUInt16(0); // Unused. |
1566 } | 1606 } |
1567 DCHECK_EQ(GetSynReplyMinimumSize(), builder.length()); | 1607 DCHECK_EQ(GetSynReplyMinimumSize(), builder.length()); |
1568 SerializeNameValueBlock(&builder, syn_reply); | 1608 SerializeNameValueBlock(&builder, syn_reply); |
1569 | 1609 |
1570 return builder.take(); | 1610 return builder.take(); |
1571 } | 1611 } |
1572 | 1612 |
1573 SpdyFrame* SpdyFramer::CreateRstStream( | 1613 SpdyFrame* SpdyFramer::CreateRstStream( |
1574 SpdyStreamId stream_id, | 1614 SpdyStreamId stream_id, |
1575 SpdyRstStreamStatus status) const { | 1615 SpdyRstStreamStatus status) const { |
1576 SpdyRstStreamIR rst_stream(stream_id, status); | 1616 SpdyRstStreamIR rst_stream(stream_id, status); |
1577 return SerializeRstStream(rst_stream); | 1617 return SerializeRstStream(rst_stream); |
1578 } | 1618 } |
1579 | 1619 |
1580 SpdySerializedFrame* SpdyFramer::SerializeRstStream( | 1620 SpdySerializedFrame* SpdyFramer::SerializeRstStream( |
1581 const SpdyRstStreamIR& rst_stream) const { | 1621 const SpdyRstStreamIR& rst_stream) const { |
1582 SpdyFrameBuilder builder(GetRstStreamSize()); | 1622 SpdyFrameBuilder builder(GetRstStreamSize()); |
1583 builder.WriteControlFrameHeader(*this, RST_STREAM, 0); | 1623 if (spdy_version_ < 4) { |
1584 builder.WriteUInt32(rst_stream.stream_id()); | 1624 builder.WriteControlFrameHeader(*this, RST_STREAM, 0); |
| 1625 builder.WriteUInt32(rst_stream.stream_id()); |
| 1626 } else { |
| 1627 builder.WriteFramePrefix(*this, |
| 1628 RST_STREAM, |
| 1629 0, |
| 1630 rst_stream.stream_id()); |
| 1631 } |
1585 builder.WriteUInt32(rst_stream.status()); | 1632 builder.WriteUInt32(rst_stream.status()); |
1586 DCHECK_EQ(GetRstStreamSize(), builder.length()); | 1633 DCHECK_EQ(GetRstStreamSize(), builder.length()); |
1587 return builder.take(); | 1634 return builder.take(); |
1588 } | 1635 } |
1589 | 1636 |
1590 SpdyFrame* SpdyFramer::CreateSettings( | 1637 SpdyFrame* SpdyFramer::CreateSettings( |
1591 const SettingsMap& values) const { | 1638 const SettingsMap& values) const { |
1592 SpdySettingsIR settings; | 1639 SpdySettingsIR settings; |
1593 for (SettingsMap::const_iterator it = values.begin(); | 1640 for (SettingsMap::const_iterator it = values.begin(); |
1594 it != values.end(); | 1641 it != values.end(); |
(...skipping 11 matching lines...) Expand all Loading... |
1606 uint8 flags = 0; | 1653 uint8 flags = 0; |
1607 if (settings.clear_settings()) { | 1654 if (settings.clear_settings()) { |
1608 flags |= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS; | 1655 flags |= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS; |
1609 } | 1656 } |
1610 const SpdySettingsIR::ValueMap* values = &(settings.values()); | 1657 const SpdySettingsIR::ValueMap* values = &(settings.values()); |
1611 | 1658 |
1612 // Size, in bytes, of this SETTINGS frame. | 1659 // Size, in bytes, of this SETTINGS frame. |
1613 const size_t size = GetSettingsMinimumSize() + (values->size() * 8); | 1660 const size_t size = GetSettingsMinimumSize() + (values->size() * 8); |
1614 | 1661 |
1615 SpdyFrameBuilder builder(size); | 1662 SpdyFrameBuilder builder(size); |
1616 builder.WriteControlFrameHeader(*this, SETTINGS, flags); | 1663 if (spdy_version_ < 4) { |
| 1664 builder.WriteControlFrameHeader(*this, SETTINGS, flags); |
| 1665 } else { |
| 1666 builder.WriteFramePrefix(*this, SETTINGS, flags, 0); |
| 1667 } |
1617 builder.WriteUInt32(values->size()); | 1668 builder.WriteUInt32(values->size()); |
1618 DCHECK_EQ(GetSettingsMinimumSize(), builder.length()); | 1669 DCHECK_EQ(GetSettingsMinimumSize(), builder.length()); |
1619 for (SpdySettingsIR::ValueMap::const_iterator it = values->begin(); | 1670 for (SpdySettingsIR::ValueMap::const_iterator it = values->begin(); |
1620 it != values->end(); | 1671 it != values->end(); |
1621 ++it) { | 1672 ++it) { |
1622 uint8 setting_flags = 0; | 1673 uint8 setting_flags = 0; |
1623 if (it->second.persist_value) { | 1674 if (it->second.persist_value) { |
1624 setting_flags |= SETTINGS_FLAG_PLEASE_PERSIST; | 1675 setting_flags |= SETTINGS_FLAG_PLEASE_PERSIST; |
1625 } | 1676 } |
1626 if (it->second.persisted) { | 1677 if (it->second.persisted) { |
1627 setting_flags |= SETTINGS_FLAG_PERSISTED; | 1678 setting_flags |= SETTINGS_FLAG_PERSISTED; |
1628 } | 1679 } |
1629 SettingsFlagsAndId flags_and_id(setting_flags, it->first); | 1680 SettingsFlagsAndId flags_and_id(setting_flags, it->first); |
1630 uint32 id_and_flags_wire = flags_and_id.GetWireFormat(protocol_version()); | 1681 uint32 id_and_flags_wire = flags_and_id.GetWireFormat(protocol_version()); |
1631 builder.WriteBytes(&id_and_flags_wire, 4); | 1682 builder.WriteBytes(&id_and_flags_wire, 4); |
1632 builder.WriteUInt32(it->second.value); | 1683 builder.WriteUInt32(it->second.value); |
1633 } | 1684 } |
1634 DCHECK_EQ(size, builder.length()); | 1685 DCHECK_EQ(size, builder.length()); |
1635 return builder.take(); | 1686 return builder.take(); |
1636 } | 1687 } |
1637 | 1688 |
1638 SpdyFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) const { | 1689 SpdyFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) const { |
1639 SpdyPingIR ping(unique_id); | 1690 SpdyPingIR ping(unique_id); |
1640 return SerializePing(ping); | 1691 return SerializePing(ping); |
1641 } | 1692 } |
1642 | 1693 |
1643 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const { | 1694 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const { |
1644 SpdyFrameBuilder builder(GetPingSize()); | 1695 SpdyFrameBuilder builder(GetPingSize()); |
1645 builder.WriteControlFrameHeader(*this, PING, 0); | 1696 if (spdy_version_ < 4) { |
| 1697 builder.WriteControlFrameHeader(*this, PING, kNoFlags); |
| 1698 } else { |
| 1699 builder.WriteFramePrefix(*this, PING, 0, 0); |
| 1700 } |
1646 builder.WriteUInt32(ping.id()); | 1701 builder.WriteUInt32(ping.id()); |
1647 DCHECK_EQ(GetPingSize(), builder.length()); | 1702 DCHECK_EQ(GetPingSize(), builder.length()); |
1648 return builder.take(); | 1703 return builder.take(); |
1649 } | 1704 } |
1650 | 1705 |
1651 SpdyFrame* SpdyFramer::CreateGoAway( | 1706 SpdyFrame* SpdyFramer::CreateGoAway( |
1652 SpdyStreamId last_accepted_stream_id, | 1707 SpdyStreamId last_accepted_stream_id, |
1653 SpdyGoAwayStatus status) const { | 1708 SpdyGoAwayStatus status) const { |
1654 SpdyGoAwayIR goaway(last_accepted_stream_id, status); | 1709 SpdyGoAwayIR goaway(last_accepted_stream_id, status); |
1655 return SerializeGoAway(goaway); | 1710 return SerializeGoAway(goaway); |
1656 } | 1711 } |
1657 | 1712 |
1658 SpdySerializedFrame* SpdyFramer::SerializeGoAway( | 1713 SpdySerializedFrame* SpdyFramer::SerializeGoAway( |
1659 const SpdyGoAwayIR& goaway) const { | 1714 const SpdyGoAwayIR& goaway) const { |
1660 SpdyFrameBuilder builder(GetGoAwaySize()); | 1715 SpdyFrameBuilder builder(GetGoAwaySize()); |
1661 builder.WriteControlFrameHeader(*this, GOAWAY, 0); | 1716 if (spdy_version_ < 4) { |
| 1717 builder.WriteControlFrameHeader(*this, GOAWAY, kNoFlags); |
| 1718 } else { |
| 1719 builder.WriteFramePrefix(*this, GOAWAY, 0, 0); |
| 1720 } |
1662 builder.WriteUInt32(goaway.last_good_stream_id()); | 1721 builder.WriteUInt32(goaway.last_good_stream_id()); |
1663 if (protocol_version() >= 3) { | 1722 if (protocol_version() >= 3) { |
1664 builder.WriteUInt32(goaway.status()); | 1723 builder.WriteUInt32(goaway.status()); |
1665 } | 1724 } |
1666 DCHECK_EQ(GetGoAwaySize(), builder.length()); | 1725 DCHECK_EQ(GetGoAwaySize(), builder.length()); |
1667 return builder.take(); | 1726 return builder.take(); |
1668 } | 1727 } |
1669 | 1728 |
1670 SpdyFrame* SpdyFramer::CreateHeaders( | 1729 SpdyFrame* SpdyFramer::CreateHeaders( |
1671 SpdyStreamId stream_id, | 1730 SpdyStreamId stream_id, |
(...skipping 18 matching lines...) Expand all Loading... |
1690 uint8 flags = 0; | 1749 uint8 flags = 0; |
1691 if (headers.fin()) { | 1750 if (headers.fin()) { |
1692 flags |= CONTROL_FLAG_FIN; | 1751 flags |= CONTROL_FLAG_FIN; |
1693 } | 1752 } |
1694 | 1753 |
1695 // The size of this frame, including variable-length name-value block. | 1754 // The size of this frame, including variable-length name-value block. |
1696 size_t size = GetHeadersMinimumSize() | 1755 size_t size = GetHeadersMinimumSize() |
1697 + GetSerializedLength(headers.name_value_block()); | 1756 + GetSerializedLength(headers.name_value_block()); |
1698 | 1757 |
1699 SpdyFrameBuilder builder(size); | 1758 SpdyFrameBuilder builder(size); |
1700 builder.WriteControlFrameHeader(*this, HEADERS, flags); | 1759 if (spdy_version_ < 4) { |
1701 builder.WriteUInt32(headers.stream_id()); | 1760 builder.WriteControlFrameHeader(*this, HEADERS, flags); |
| 1761 builder.WriteUInt32(headers.stream_id()); |
| 1762 } else { |
| 1763 builder.WriteFramePrefix(*this, |
| 1764 HEADERS, |
| 1765 flags, |
| 1766 headers.stream_id()); |
| 1767 } |
1702 if (protocol_version() < 3) { | 1768 if (protocol_version() < 3) { |
1703 builder.WriteUInt16(0); // Unused. | 1769 builder.WriteUInt16(0); // Unused. |
1704 } | 1770 } |
1705 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); | 1771 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); |
1706 | 1772 |
1707 SerializeNameValueBlock(&builder, headers); | 1773 SerializeNameValueBlock(&builder, headers); |
1708 | 1774 |
1709 return builder.take(); | 1775 return builder.take(); |
1710 } | 1776 } |
1711 | 1777 |
1712 SpdyFrame* SpdyFramer::CreateWindowUpdate( | 1778 SpdyFrame* SpdyFramer::CreateWindowUpdate( |
1713 SpdyStreamId stream_id, | 1779 SpdyStreamId stream_id, |
1714 uint32 delta_window_size) const { | 1780 uint32 delta_window_size) const { |
1715 SpdyWindowUpdateIR window_update(stream_id, delta_window_size); | 1781 SpdyWindowUpdateIR window_update(stream_id, delta_window_size); |
1716 return SerializeWindowUpdate(window_update); | 1782 return SerializeWindowUpdate(window_update); |
1717 } | 1783 } |
1718 | 1784 |
1719 SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate( | 1785 SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate( |
1720 const SpdyWindowUpdateIR& window_update) const { | 1786 const SpdyWindowUpdateIR& window_update) const { |
1721 SpdyFrameBuilder builder(GetWindowUpdateSize()); | 1787 SpdyFrameBuilder builder(GetWindowUpdateSize()); |
1722 builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags); | 1788 if (spdy_version_ < 4) { |
1723 builder.WriteUInt32(window_update.stream_id()); | 1789 builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags); |
| 1790 builder.WriteUInt32(window_update.stream_id()); |
| 1791 } else { |
| 1792 builder.WriteFramePrefix(*this, |
| 1793 WINDOW_UPDATE, |
| 1794 kNoFlags, |
| 1795 window_update.stream_id()); |
| 1796 } |
1724 builder.WriteUInt32(window_update.delta()); | 1797 builder.WriteUInt32(window_update.delta()); |
1725 DCHECK_EQ(GetWindowUpdateSize(), builder.length()); | 1798 DCHECK_EQ(GetWindowUpdateSize(), builder.length()); |
1726 return builder.take(); | 1799 return builder.take(); |
1727 } | 1800 } |
1728 | 1801 |
1729 // TODO(hkhalil): Gut with SpdyCredential removal. | 1802 // TODO(hkhalil): Gut with SpdyCredential removal. |
1730 SpdyFrame* SpdyFramer::CreateCredentialFrame( | 1803 SpdyFrame* SpdyFramer::CreateCredentialFrame( |
1731 const SpdyCredential& credential) const { | 1804 const SpdyCredential& credential) const { |
1732 SpdyCredentialIR credential_ir(credential.slot); | 1805 SpdyCredentialIR credential_ir(credential.slot); |
1733 credential_ir.set_proof(credential.proof); | 1806 credential_ir.set_proof(credential.proof); |
(...skipping 10 matching lines...) Expand all Loading... |
1744 size_t size = GetCredentialMinimumSize(); | 1817 size_t size = GetCredentialMinimumSize(); |
1745 size += 4 + credential.proof().length(); // Room for proof. | 1818 size += 4 + credential.proof().length(); // Room for proof. |
1746 for (SpdyCredentialIR::CertificateList::const_iterator it = | 1819 for (SpdyCredentialIR::CertificateList::const_iterator it = |
1747 credential.certificates()->begin(); | 1820 credential.certificates()->begin(); |
1748 it != credential.certificates()->end(); | 1821 it != credential.certificates()->end(); |
1749 ++it) { | 1822 ++it) { |
1750 size += 4 + it->length(); // Room for certificate. | 1823 size += 4 + it->length(); // Room for certificate. |
1751 } | 1824 } |
1752 | 1825 |
1753 SpdyFrameBuilder builder(size); | 1826 SpdyFrameBuilder builder(size); |
1754 builder.WriteControlFrameHeader(*this, CREDENTIAL, 0); | 1827 if (spdy_version_ < 4) { |
| 1828 builder.WriteControlFrameHeader(*this, CREDENTIAL, kNoFlags); |
| 1829 } else { |
| 1830 builder.WriteFramePrefix(*this, CREDENTIAL, kNoFlags, 0); |
| 1831 } |
1755 builder.WriteUInt16(credential.slot()); | 1832 builder.WriteUInt16(credential.slot()); |
1756 DCHECK_EQ(GetCredentialMinimumSize(), builder.length()); | 1833 DCHECK_EQ(GetCredentialMinimumSize(), builder.length()); |
1757 builder.WriteStringPiece32(credential.proof()); | 1834 builder.WriteStringPiece32(credential.proof()); |
1758 for (SpdyCredentialIR::CertificateList::const_iterator it = | 1835 for (SpdyCredentialIR::CertificateList::const_iterator it = |
1759 credential.certificates()->begin(); | 1836 credential.certificates()->begin(); |
1760 it != credential.certificates()->end(); | 1837 it != credential.certificates()->end(); |
1761 ++it) { | 1838 ++it) { |
1762 builder.WriteStringPiece32(*it); | 1839 builder.WriteStringPiece32(*it); |
1763 } | 1840 } |
1764 DCHECK_EQ(size, builder.length()); | 1841 DCHECK_EQ(size, builder.length()); |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2064 post_compress_bytes.Add(compressed_size); | 2141 post_compress_bytes.Add(compressed_size); |
2065 | 2142 |
2066 compressed_frames.Increment(); | 2143 compressed_frames.Increment(); |
2067 | 2144 |
2068 if (debug_visitor_ != NULL) { | 2145 if (debug_visitor_ != NULL) { |
2069 debug_visitor_->OnCompressedHeaderBlock(uncompressed_len, compressed_size); | 2146 debug_visitor_->OnCompressedHeaderBlock(uncompressed_len, compressed_size); |
2070 } | 2147 } |
2071 } | 2148 } |
2072 | 2149 |
2073 } // namespace net | 2150 } // namespace net |
OLD | NEW |