| 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 |