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 #include "net/spdy/spdy_framer.h" | 5 #include "net/spdy/spdy_framer.h" |
6 | 6 |
7 #include "base/lazy_instance.h" | 7 #include "base/lazy_instance.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/metrics/stats_counters.h" | 9 #include "base/metrics/stats_counters.h" |
10 #include "base/third_party/valgrind/memcheck.h" | 10 #include "base/third_party/valgrind/memcheck.h" |
11 #include "net/spdy/spdy_frame_builder.h" | 11 #include "net/spdy/spdy_frame_builder.h" |
12 #include "net/spdy/spdy_frame_reader.h" | 12 #include "net/spdy/spdy_frame_reader.h" |
13 #include "net/spdy/spdy_bitmasks.h" | 13 #include "net/spdy/spdy_bitmasks.h" |
14 #include "third_party/zlib/zlib.h" | 14 #include "third_party/zlib/zlib.h" |
15 | 15 |
| 16 using base::StringPiece; |
16 using std::string; | 17 using std::string; |
17 using std::vector; | 18 using std::vector; |
18 | 19 |
19 namespace net { | 20 namespace net { |
20 | 21 |
21 namespace { | 22 namespace { |
22 | 23 |
23 // Compute the id of our dictionary so that we know we're using the | 24 // Compute the id of our dictionary so that we know we're using the |
24 // right one when asked for it. | 25 // right one when asked for it. |
25 uLong CalculateDictionaryId(const char* dictionary, | 26 uLong CalculateDictionaryId(const char* dictionary, |
(...skipping 17 matching lines...) Expand all Loading... |
43 // initialized lazily to avoid static initializers. | 44 // initialized lazily to avoid static initializers. |
44 base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids; | 45 base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids; |
45 | 46 |
46 // Used to indicate no flags in a SPDY flags field. | 47 // Used to indicate no flags in a SPDY flags field. |
47 const uint8 kNoFlags = 0; | 48 const uint8 kNoFlags = 0; |
48 | 49 |
49 } // namespace | 50 } // namespace |
50 | 51 |
51 const SpdyStreamId SpdyFramer::kInvalidStream = -1; | 52 const SpdyStreamId SpdyFramer::kInvalidStream = -1; |
52 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024; | 53 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024; |
53 // The size of the control frame buffer. Must be >= the minimum size of the | |
54 // largest control frame, which is SYN_STREAM. See GetSynStreamMinimumSize() for | 54 // largest control frame, which is SYN_STREAM. See GetSynStreamMinimumSize() for |
55 // calculation details. | 55 // calculation details. |
56 const size_t SpdyFramer::kControlFrameBufferSize = 18; | 56 const size_t SpdyFramer::kControlFrameBufferSize = 18; |
57 | 57 |
58 #ifdef DEBUG_SPDY_STATE_CHANGES | 58 #ifdef DEBUG_SPDY_STATE_CHANGES |
59 #define CHANGE_STATE(newstate) \ | 59 #define CHANGE_STATE(newstate) \ |
60 do { \ | 60 do { \ |
61 DVLOG(1) << "Changing state from: " \ | 61 DVLOG(1) << "Changing state from: " \ |
62 << StateToString(state_) \ | 62 << StateToString(state_) \ |
63 << " to " << StateToString(newstate) << "\n"; \ | 63 << " to " << StateToString(newstate) << "\n"; \ |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 // This method is used to preserve buggy behavior and works on both | 102 // This method is used to preserve buggy behavior and works on both |
103 // little-endian and big-endian hosts. | 103 // little-endian and big-endian hosts. |
104 // This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3 | 104 // This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3 |
105 // as well as vice versa). | 105 // as well as vice versa). |
106 void SettingsFlagsAndId::ConvertFlagsAndIdForSpdy2(uint32* val) { | 106 void SettingsFlagsAndId::ConvertFlagsAndIdForSpdy2(uint32* val) { |
107 uint8* wire_array = reinterpret_cast<uint8*>(val); | 107 uint8* wire_array = reinterpret_cast<uint8*>(val); |
108 std::swap(wire_array[0], wire_array[3]); | 108 std::swap(wire_array[0], wire_array[3]); |
109 std::swap(wire_array[1], wire_array[2]); | 109 std::swap(wire_array[1], wire_array[2]); |
110 } | 110 } |
111 | 111 |
| 112 SpdyAltSvcScratch::SpdyAltSvcScratch() { Reset(); } |
| 113 SpdyAltSvcScratch::~SpdyAltSvcScratch() {} |
| 114 |
112 bool SpdyFramerVisitorInterface::OnGoAwayFrameData(const char* goaway_data, | 115 bool SpdyFramerVisitorInterface::OnGoAwayFrameData(const char* goaway_data, |
113 size_t len) { | 116 size_t len) { |
114 return true; | 117 return true; |
115 } | 118 } |
116 | 119 |
117 bool SpdyFramerVisitorInterface::OnRstStreamFrameData( | 120 bool SpdyFramerVisitorInterface::OnRstStreamFrameData( |
118 const char* rst_stream_data, | 121 const char* rst_stream_data, |
119 size_t len) { | 122 size_t len) { |
120 return true; | 123 return true; |
121 } | 124 } |
(...skipping 28 matching lines...) Expand all Loading... |
150 previous_state_ = SPDY_RESET; | 153 previous_state_ = SPDY_RESET; |
151 error_code_ = SPDY_NO_ERROR; | 154 error_code_ = SPDY_NO_ERROR; |
152 remaining_data_length_ = 0; | 155 remaining_data_length_ = 0; |
153 remaining_control_header_ = 0; | 156 remaining_control_header_ = 0; |
154 current_frame_buffer_length_ = 0; | 157 current_frame_buffer_length_ = 0; |
155 current_frame_type_ = DATA; | 158 current_frame_type_ = DATA; |
156 current_frame_flags_ = 0; | 159 current_frame_flags_ = 0; |
157 current_frame_length_ = 0; | 160 current_frame_length_ = 0; |
158 current_frame_stream_id_ = kInvalidStream; | 161 current_frame_stream_id_ = kInvalidStream; |
159 settings_scratch_.Reset(); | 162 settings_scratch_.Reset(); |
| 163 altsvc_scratch_.Reset(); |
160 remaining_padding_payload_length_ = 0; | 164 remaining_padding_payload_length_ = 0; |
161 remaining_padding_length_fields_ = 0; | 165 remaining_padding_length_fields_ = 0; |
162 } | 166 } |
163 | 167 |
164 size_t SpdyFramer::GetDataFrameMinimumSize() const { | 168 size_t SpdyFramer::GetDataFrameMinimumSize() const { |
165 return SpdyConstants::GetDataFrameMinimumSize(); | 169 return SpdyConstants::GetDataFrameMinimumSize(); |
166 } | 170 } |
167 | 171 |
168 // Size, in bytes, of the control frame header. | 172 // Size, in bytes, of the control frame header. |
169 size_t SpdyFramer::GetControlFrameHeaderSize() const { | 173 size_t SpdyFramer::GetControlFrameHeaderSize() const { |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 // Calculated as frame prefix + 4 (promised stream id). | 304 // Calculated as frame prefix + 4 (promised stream id). |
301 return GetControlFrameHeaderSize() + 4; | 305 return GetControlFrameHeaderSize() + 4; |
302 } | 306 } |
303 | 307 |
304 size_t SpdyFramer::GetContinuationMinimumSize() const { | 308 size_t SpdyFramer::GetContinuationMinimumSize() const { |
305 // Size, in bytes, of a CONTINUATION frame not including the variable-length | 309 // Size, in bytes, of a CONTINUATION frame not including the variable-length |
306 // headers fragments. | 310 // headers fragments. |
307 return GetControlFrameHeaderSize(); | 311 return GetControlFrameHeaderSize(); |
308 } | 312 } |
309 | 313 |
| 314 size_t SpdyFramer::GetAltSvcMinimumSize() const { |
| 315 // Size, in bytes, of an ALTSVC frame not including the Protocol-ID, Host, and |
| 316 // (optional) Origin fields, all of which can vary in length. |
| 317 // Note that this gives a lower bound on the frame size rather than a true |
| 318 // minimum; the actual frame should always be larger than this. |
| 319 // Calculated as frame prefix + 4 (max-age) + 2 (port) + 1 (reserved byte) |
| 320 // + 1 (pid_len) + 1 (host_len). |
| 321 return GetControlFrameHeaderSize() + 9; |
| 322 } |
| 323 |
310 size_t SpdyFramer::GetFrameMinimumSize() const { | 324 size_t SpdyFramer::GetFrameMinimumSize() const { |
311 return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize()); | 325 return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize()); |
312 } | 326 } |
313 | 327 |
314 size_t SpdyFramer::GetFrameMaximumSize() const { | 328 size_t SpdyFramer::GetFrameMaximumSize() const { |
315 return SpdyConstants::GetFrameMaximumSize(protocol_version()); | 329 return SpdyConstants::GetFrameMaximumSize(protocol_version()); |
316 } | 330 } |
317 | 331 |
318 size_t SpdyFramer::GetDataFrameMaximumPayload() const { | 332 size_t SpdyFramer::GetDataFrameMaximumPayload() const { |
319 return GetFrameMaximumSize() - GetDataFrameMinimumSize(); | 333 return GetFrameMaximumSize() - GetDataFrameMinimumSize(); |
(...skipping 26 matching lines...) Expand all Loading... |
346 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: | 360 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: |
347 return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK"; | 361 return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK"; |
348 case SPDY_CONTROL_FRAME_HEADER_BLOCK: | 362 case SPDY_CONTROL_FRAME_HEADER_BLOCK: |
349 return "SPDY_CONTROL_FRAME_HEADER_BLOCK"; | 363 return "SPDY_CONTROL_FRAME_HEADER_BLOCK"; |
350 case SPDY_GOAWAY_FRAME_PAYLOAD: | 364 case SPDY_GOAWAY_FRAME_PAYLOAD: |
351 return "SPDY_GOAWAY_FRAME_PAYLOAD"; | 365 return "SPDY_GOAWAY_FRAME_PAYLOAD"; |
352 case SPDY_RST_STREAM_FRAME_PAYLOAD: | 366 case SPDY_RST_STREAM_FRAME_PAYLOAD: |
353 return "SPDY_RST_STREAM_FRAME_PAYLOAD"; | 367 return "SPDY_RST_STREAM_FRAME_PAYLOAD"; |
354 case SPDY_SETTINGS_FRAME_PAYLOAD: | 368 case SPDY_SETTINGS_FRAME_PAYLOAD: |
355 return "SPDY_SETTINGS_FRAME_PAYLOAD"; | 369 return "SPDY_SETTINGS_FRAME_PAYLOAD"; |
| 370 case SPDY_ALTSVC_FRAME_PAYLOAD: |
| 371 return "SPDY_ALTSVC_FRAME_PAYLOAD"; |
356 } | 372 } |
357 return "UNKNOWN_STATE"; | 373 return "UNKNOWN_STATE"; |
358 } | 374 } |
359 | 375 |
360 void SpdyFramer::set_error(SpdyError error) { | 376 void SpdyFramer::set_error(SpdyError error) { |
361 DCHECK(visitor_); | 377 DCHECK(visitor_); |
362 error_code_ = error; | 378 error_code_ = error; |
363 // These values will usually get reset once we come to the end | 379 // These values will usually get reset once we come to the end |
364 // of a header block, but if we run into an error that | 380 // of a header block, but if we run into an error that |
365 // might not happen, so reset them here. | 381 // might not happen, so reset them here. |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 case WINDOW_UPDATE: | 469 case WINDOW_UPDATE: |
454 return "WINDOW_UPDATE"; | 470 return "WINDOW_UPDATE"; |
455 case CREDENTIAL: | 471 case CREDENTIAL: |
456 return "CREDENTIAL"; | 472 return "CREDENTIAL"; |
457 case BLOCKED: | 473 case BLOCKED: |
458 return "BLOCKED"; | 474 return "BLOCKED"; |
459 case PUSH_PROMISE: | 475 case PUSH_PROMISE: |
460 return "PUSH_PROMISE"; | 476 return "PUSH_PROMISE"; |
461 case CONTINUATION: | 477 case CONTINUATION: |
462 return "CONTINUATION"; | 478 return "CONTINUATION"; |
| 479 case ALTSVC: |
| 480 return "ALTSVC"; |
463 } | 481 } |
464 return "UNKNOWN_CONTROL_TYPE"; | 482 return "UNKNOWN_CONTROL_TYPE"; |
465 } | 483 } |
466 | 484 |
467 size_t SpdyFramer::ProcessInput(const char* data, size_t len) { | 485 size_t SpdyFramer::ProcessInput(const char* data, size_t len) { |
468 DCHECK(visitor_); | 486 DCHECK(visitor_); |
469 DCHECK(data); | 487 DCHECK(data); |
470 | 488 |
471 size_t original_len = len; | 489 size_t original_len = len; |
472 do { | 490 do { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 break; | 550 break; |
533 } | 551 } |
534 | 552 |
535 case SPDY_GOAWAY_FRAME_PAYLOAD: { | 553 case SPDY_GOAWAY_FRAME_PAYLOAD: { |
536 size_t bytes_read = ProcessGoAwayFramePayload(data, len); | 554 size_t bytes_read = ProcessGoAwayFramePayload(data, len); |
537 len -= bytes_read; | 555 len -= bytes_read; |
538 data += bytes_read; | 556 data += bytes_read; |
539 break; | 557 break; |
540 } | 558 } |
541 | 559 |
| 560 case SPDY_ALTSVC_FRAME_PAYLOAD: { |
| 561 size_t bytes_read = ProcessAltSvcFramePayload(data, len); |
| 562 len -= bytes_read; |
| 563 data += bytes_read; |
| 564 break; |
| 565 } |
| 566 |
542 case SPDY_CONTROL_FRAME_PAYLOAD: { | 567 case SPDY_CONTROL_FRAME_PAYLOAD: { |
543 size_t bytes_read = ProcessControlFramePayload(data, len); | 568 size_t bytes_read = ProcessControlFramePayload(data, len); |
544 len -= bytes_read; | 569 len -= bytes_read; |
545 data += bytes_read; | 570 data += bytes_read; |
546 break; | 571 break; |
547 } | 572 } |
548 | 573 |
549 case SPDY_READ_PADDING_LENGTH: { | 574 case SPDY_READ_PADDING_LENGTH: { |
550 size_t bytes_read = ProcessFramePaddingLength(data, len); | 575 size_t bytes_read = ProcessFramePaddingLength(data, len); |
551 len -= bytes_read; | 576 len -= bytes_read; |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
904 } | 929 } |
905 break; | 930 break; |
906 case WINDOW_UPDATE: | 931 case WINDOW_UPDATE: |
907 if (current_frame_length_ != GetWindowUpdateSize()) { | 932 if (current_frame_length_ != GetWindowUpdateSize()) { |
908 set_error(SPDY_INVALID_CONTROL_FRAME); | 933 set_error(SPDY_INVALID_CONTROL_FRAME); |
909 } else if (current_frame_flags_ != 0) { | 934 } else if (current_frame_flags_ != 0) { |
910 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 935 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
911 } | 936 } |
912 break; | 937 break; |
913 case BLOCKED: | 938 case BLOCKED: |
914 if (current_frame_length_ != GetBlockedSize()) { | 939 if (current_frame_length_ != GetBlockedSize() || |
| 940 protocol_version() <= SPDY3) { |
| 941 // TODO(mlavan): BLOCKED frames are no longer part of SPDY4. |
915 set_error(SPDY_INVALID_CONTROL_FRAME); | 942 set_error(SPDY_INVALID_CONTROL_FRAME); |
916 } else if (current_frame_flags_ != 0) { | 943 } else if (current_frame_flags_ != 0) { |
917 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 944 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
918 } | 945 } |
919 break; | 946 break; |
920 case PUSH_PROMISE: | 947 case PUSH_PROMISE: |
921 if (current_frame_length_ < GetPushPromiseMinimumSize()) { | 948 if (current_frame_length_ < GetPushPromiseMinimumSize()) { |
922 set_error(SPDY_INVALID_CONTROL_FRAME); | 949 set_error(SPDY_INVALID_CONTROL_FRAME); |
923 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) { | 950 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) { |
924 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 951 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
925 } else if (protocol_version() > SPDY3 && current_frame_flags_ & | 952 } else if (protocol_version() > SPDY3 && current_frame_flags_ & |
926 ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE) { | 953 ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE) { |
927 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 954 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
928 } | 955 } |
929 break; | 956 break; |
930 case CONTINUATION: | 957 case CONTINUATION: |
931 if (current_frame_length_ < GetContinuationMinimumSize() || | 958 if (current_frame_length_ < GetContinuationMinimumSize() || |
932 protocol_version() <= SPDY3) { | 959 protocol_version() <= SPDY3) { |
933 set_error(SPDY_INVALID_CONTROL_FRAME); | 960 set_error(SPDY_INVALID_CONTROL_FRAME); |
934 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) { | 961 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) { |
935 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 962 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
936 } | 963 } |
937 break; | 964 break; |
| 965 case ALTSVC: |
| 966 if (current_frame_length_ <= GetAltSvcMinimumSize()) { |
| 967 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 968 } else if (current_frame_flags_ != 0) { |
| 969 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 970 } |
| 971 break; |
938 default: | 972 default: |
939 LOG(WARNING) << "Valid " << display_protocol_ | 973 LOG(WARNING) << "Valid " << display_protocol_ |
940 << " control frame with unhandled type: " | 974 << " control frame with unhandled type: " |
941 << current_frame_type_; | 975 << current_frame_type_; |
942 // This branch should be unreachable because of the frame type bounds | 976 // This branch should be unreachable because of the frame type bounds |
943 // check above. However, we DLOG(FATAL) here in an effort to painfully | 977 // check above. However, we DLOG(FATAL) here in an effort to painfully |
944 // club the head of the developer who failed to keep this file in sync | 978 // club the head of the developer who failed to keep this file in sync |
945 // with spdy_protocol.h. | 979 // with spdy_protocol.h. |
946 DLOG(FATAL); | 980 DLOG(FATAL); |
947 set_error(SPDY_INVALID_CONTROL_FRAME); | 981 set_error(SPDY_INVALID_CONTROL_FRAME); |
(...skipping 14 matching lines...) Expand all Loading... |
962 if (current_frame_type_ == GOAWAY) { | 996 if (current_frame_type_ == GOAWAY) { |
963 CHANGE_STATE(SPDY_GOAWAY_FRAME_PAYLOAD); | 997 CHANGE_STATE(SPDY_GOAWAY_FRAME_PAYLOAD); |
964 return; | 998 return; |
965 } | 999 } |
966 | 1000 |
967 if (current_frame_type_ == RST_STREAM) { | 1001 if (current_frame_type_ == RST_STREAM) { |
968 CHANGE_STATE(SPDY_RST_STREAM_FRAME_PAYLOAD); | 1002 CHANGE_STATE(SPDY_RST_STREAM_FRAME_PAYLOAD); |
969 return; | 1003 return; |
970 } | 1004 } |
971 | 1005 |
| 1006 if (current_frame_type_ == ALTSVC) { |
| 1007 CHANGE_STATE(SPDY_ALTSVC_FRAME_PAYLOAD); |
| 1008 return; |
| 1009 } |
972 // Determine the frame size without variable-length data. | 1010 // Determine the frame size without variable-length data. |
973 int32 frame_size_without_variable_data; | 1011 int32 frame_size_without_variable_data; |
974 switch (current_frame_type_) { | 1012 switch (current_frame_type_) { |
975 case SYN_STREAM: | 1013 case SYN_STREAM: |
976 syn_frame_processed_ = true; | 1014 syn_frame_processed_ = true; |
977 frame_size_without_variable_data = GetSynStreamMinimumSize(); | 1015 frame_size_without_variable_data = GetSynStreamMinimumSize(); |
978 break; | 1016 break; |
979 case SYN_REPLY: | 1017 case SYN_REPLY: |
980 syn_frame_processed_ = true; | 1018 syn_frame_processed_ = true; |
981 frame_size_without_variable_data = GetSynReplyMinimumSize(); | 1019 frame_size_without_variable_data = GetSynReplyMinimumSize(); |
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1849 if (!processed_successfully) { | 1887 if (!processed_successfully) { |
1850 set_error(SPDY_RST_STREAM_FRAME_CORRUPT); | 1888 set_error(SPDY_RST_STREAM_FRAME_CORRUPT); |
1851 } else if (remaining_data_length_ == 0) { | 1889 } else if (remaining_data_length_ == 0) { |
1852 // Signal that there is not more opaque data. | 1890 // Signal that there is not more opaque data. |
1853 visitor_->OnRstStreamFrameData(NULL, 0); | 1891 visitor_->OnRstStreamFrameData(NULL, 0); |
1854 CHANGE_STATE(SPDY_AUTO_RESET); | 1892 CHANGE_STATE(SPDY_AUTO_RESET); |
1855 } | 1893 } |
1856 return original_len; | 1894 return original_len; |
1857 } | 1895 } |
1858 | 1896 |
| 1897 size_t SpdyFramer::ProcessAltSvcFramePayload(const char* data, size_t len) { |
| 1898 if (len == 0) { |
| 1899 return 0; |
| 1900 } |
| 1901 |
| 1902 // Clamp to the actual remaining payload. |
| 1903 len = std::min(len, remaining_data_length_); |
| 1904 |
| 1905 size_t processed_bytes = 0; |
| 1906 size_t processing = 0; |
| 1907 size_t bytes_remaining; |
| 1908 char* buffer; |
| 1909 size_t* buffer_len; |
| 1910 |
| 1911 while (len > 0) { |
| 1912 if (altsvc_scratch_.pid_len == 0) { |
| 1913 // The size of the frame up to the PID_LEN field. |
| 1914 size_t fixed_len_portion = GetAltSvcMinimumSize() - 1; |
| 1915 bytes_remaining = fixed_len_portion - current_frame_buffer_length_; |
| 1916 processing = std::min(len, bytes_remaining); |
| 1917 // Buffer the new ALTSVC bytes we got. |
| 1918 UpdateCurrentFrameBuffer(&data, &len, processing); |
| 1919 |
| 1920 // Do we have enough to parse the length of the protocol id? |
| 1921 if (current_frame_buffer_length_ == fixed_len_portion) { |
| 1922 // Parse out the max age, port, and pid_len. |
| 1923 SpdyFrameReader reader(current_frame_buffer_.get(), |
| 1924 current_frame_buffer_length_); |
| 1925 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header. |
| 1926 bool successful_read = reader.ReadUInt32(&altsvc_scratch_.max_age); |
| 1927 reader.ReadUInt16(&altsvc_scratch_.port); |
| 1928 reader.Seek(1); // Reserved byte. |
| 1929 successful_read = successful_read && |
| 1930 reader.ReadUInt8(&altsvc_scratch_.pid_len); |
| 1931 DCHECK(successful_read); |
| 1932 // Sanity check length value. |
| 1933 if (GetAltSvcMinimumSize() + altsvc_scratch_.pid_len >= |
| 1934 current_frame_length_) { |
| 1935 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 1936 return 0; |
| 1937 } |
| 1938 altsvc_scratch_.protocol_id.reset( |
| 1939 new char[size_t(altsvc_scratch_.pid_len)]); |
| 1940 } |
| 1941 processed_bytes += processing; |
| 1942 continue; |
| 1943 } else if (altsvc_scratch_.pid_buf_len < altsvc_scratch_.pid_len) { |
| 1944 // Buffer protocol id field as in comes in. |
| 1945 buffer = altsvc_scratch_.protocol_id.get(); |
| 1946 buffer_len = &altsvc_scratch_.pid_buf_len; |
| 1947 bytes_remaining = altsvc_scratch_.pid_len - altsvc_scratch_.pid_buf_len; |
| 1948 } else if (altsvc_scratch_.host_len == 0) { |
| 1949 // Parse out the host length. |
| 1950 processing = 1; |
| 1951 altsvc_scratch_.host_len = *reinterpret_cast<const uint8*>(data); |
| 1952 // Sanity check length value. |
| 1953 if (GetAltSvcMinimumSize() + altsvc_scratch_.pid_len + |
| 1954 altsvc_scratch_.host_len > current_frame_length_) { |
| 1955 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 1956 return 0; |
| 1957 } |
| 1958 altsvc_scratch_.host.reset(new char[altsvc_scratch_.host_len]); |
| 1959 // Once we have host length, we can also determine the origin length |
| 1960 // by process of elimination. |
| 1961 altsvc_scratch_.origin_len = current_frame_length_ - |
| 1962 GetAltSvcMinimumSize() - |
| 1963 altsvc_scratch_.pid_len - |
| 1964 altsvc_scratch_.host_len; |
| 1965 if (altsvc_scratch_.origin_len > 0) { |
| 1966 altsvc_scratch_.origin.reset(new char[altsvc_scratch_.origin_len]); |
| 1967 } |
| 1968 data += processing; |
| 1969 processed_bytes += processing; |
| 1970 len -= processing; |
| 1971 continue; |
| 1972 } else if (altsvc_scratch_.host_buf_len < altsvc_scratch_.host_len) { |
| 1973 // Buffer host field as it comes in. |
| 1974 // TODO(mlavan): check formatting for host and origin |
| 1975 buffer = altsvc_scratch_.host.get(); |
| 1976 buffer_len = &altsvc_scratch_.host_buf_len; |
| 1977 bytes_remaining = altsvc_scratch_.host_len - altsvc_scratch_.host_buf_len; |
| 1978 } else { |
| 1979 // Buffer (optional) origin field as it comes in. |
| 1980 if (altsvc_scratch_.origin_len <= 0) { |
| 1981 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 1982 return 0; |
| 1983 } |
| 1984 buffer = altsvc_scratch_.origin.get(); |
| 1985 buffer_len = &altsvc_scratch_.origin_buf_len; |
| 1986 bytes_remaining = remaining_data_length_ - |
| 1987 processed_bytes - |
| 1988 altsvc_scratch_.origin_buf_len; |
| 1989 if (len > bytes_remaining) { |
| 1990 // This is our last field; there shouldn't be any more bytes. |
| 1991 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 1992 return 0; |
| 1993 } |
| 1994 } |
| 1995 |
| 1996 // Copy data bytes into the appropriate field. |
| 1997 processing = std::min(len, bytes_remaining); |
| 1998 memcpy(buffer + *buffer_len, |
| 1999 data, |
| 2000 processing); |
| 2001 *buffer_len += processing; |
| 2002 data += processing; |
| 2003 processed_bytes += processing; |
| 2004 len -= processing; |
| 2005 } |
| 2006 |
| 2007 remaining_data_length_ -= processed_bytes; |
| 2008 if (remaining_data_length_ == 0) { |
| 2009 visitor_->OnAltSvc(current_frame_stream_id_, |
| 2010 altsvc_scratch_.max_age, |
| 2011 altsvc_scratch_.port, |
| 2012 StringPiece(altsvc_scratch_.protocol_id.get(), |
| 2013 altsvc_scratch_.pid_len), |
| 2014 StringPiece(altsvc_scratch_.host.get(), |
| 2015 altsvc_scratch_.host_len), |
| 2016 StringPiece(altsvc_scratch_.origin.get(), |
| 2017 altsvc_scratch_.origin_len)); |
| 2018 CHANGE_STATE(SPDY_AUTO_RESET); |
| 2019 } |
| 2020 |
| 2021 return processed_bytes; |
| 2022 } |
| 2023 |
1859 size_t SpdyFramer::ProcessFramePaddingLength(const char* data, size_t len) { | 2024 size_t SpdyFramer::ProcessFramePaddingLength(const char* data, size_t len) { |
1860 DCHECK_EQ(SPDY_READ_PADDING_LENGTH, state_); | 2025 DCHECK_EQ(SPDY_READ_PADDING_LENGTH, state_); |
1861 | 2026 |
1862 size_t original_len = len; | 2027 size_t original_len = len; |
1863 if (remaining_padding_length_fields_ == 0) { | 2028 if (remaining_padding_length_fields_ == 0) { |
1864 DCHECK_EQ(remaining_padding_payload_length_, 0u); | 2029 DCHECK_EQ(remaining_padding_payload_length_, 0u); |
1865 bool pad_low = false; | 2030 bool pad_low = false; |
1866 bool pad_high = false; | 2031 bool pad_high = false; |
1867 if (current_frame_flags_ & DATA_FLAG_PAD_LOW) { | 2032 if (current_frame_flags_ & DATA_FLAG_PAD_LOW) { |
1868 pad_low = true; | 2033 pad_low = true; |
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2596 | 2761 |
2597 if (debug_visitor_) { | 2762 if (debug_visitor_) { |
2598 const size_t payload_len = hpack_encoding.size(); | 2763 const size_t payload_len = hpack_encoding.size(); |
2599 debug_visitor_->OnSendCompressedFrame(continuation.stream_id(), | 2764 debug_visitor_->OnSendCompressedFrame(continuation.stream_id(), |
2600 CONTINUATION, payload_len, builder.length()); | 2765 CONTINUATION, payload_len, builder.length()); |
2601 } | 2766 } |
2602 | 2767 |
2603 return builder.take(); | 2768 return builder.take(); |
2604 } | 2769 } |
2605 | 2770 |
| 2771 SpdyFrame* SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc) { |
| 2772 DCHECK_LT(SPDY3, protocol_version()); |
| 2773 size_t size = GetAltSvcMinimumSize(); |
| 2774 size += altsvc.protocol_id().length(); |
| 2775 size += altsvc.host().length(); |
| 2776 size += altsvc.origin().length(); |
| 2777 |
| 2778 SpdyFrameBuilder builder(size, protocol_version()); |
| 2779 builder.BeginNewFrame(*this, ALTSVC, kNoFlags, altsvc.stream_id()); |
| 2780 |
| 2781 builder.WriteUInt32(altsvc.max_age()); |
| 2782 builder.WriteUInt16(altsvc.port()); |
| 2783 builder.WriteUInt8(0); // Reserved. |
| 2784 builder.WriteUInt8(altsvc.protocol_id().length()); |
| 2785 builder.WriteBytes(altsvc.protocol_id().data(), |
| 2786 altsvc.protocol_id().length()); |
| 2787 builder.WriteUInt8(altsvc.host().length()); |
| 2788 builder.WriteBytes(altsvc.host().data(), altsvc.host().length()); |
| 2789 builder.WriteBytes(altsvc.origin().data(), altsvc.origin().length()); |
| 2790 DCHECK_LT(GetAltSvcMinimumSize(), builder.length()); |
| 2791 return builder.take(); |
| 2792 } |
| 2793 |
2606 namespace { | 2794 namespace { |
2607 | 2795 |
2608 class FrameSerializationVisitor : public SpdyFrameVisitor { | 2796 class FrameSerializationVisitor : public SpdyFrameVisitor { |
2609 public: | 2797 public: |
2610 explicit FrameSerializationVisitor(SpdyFramer* framer) : framer_(framer) {} | 2798 explicit FrameSerializationVisitor(SpdyFramer* framer) : framer_(framer) {} |
2611 virtual ~FrameSerializationVisitor() {} | 2799 virtual ~FrameSerializationVisitor() {} |
2612 | 2800 |
2613 SpdySerializedFrame* ReleaseSerializedFrame() { return frame_.release(); } | 2801 SpdySerializedFrame* ReleaseSerializedFrame() { return frame_.release(); } |
2614 | 2802 |
2615 virtual void VisitData(const SpdyDataIR& data) OVERRIDE { | 2803 virtual void VisitData(const SpdyDataIR& data) OVERRIDE { |
(...skipping 28 matching lines...) Expand all Loading... |
2644 frame_.reset(framer_->SerializeBlocked(blocked)); | 2832 frame_.reset(framer_->SerializeBlocked(blocked)); |
2645 } | 2833 } |
2646 virtual void VisitPushPromise( | 2834 virtual void VisitPushPromise( |
2647 const SpdyPushPromiseIR& push_promise) OVERRIDE { | 2835 const SpdyPushPromiseIR& push_promise) OVERRIDE { |
2648 frame_.reset(framer_->SerializePushPromise(push_promise)); | 2836 frame_.reset(framer_->SerializePushPromise(push_promise)); |
2649 } | 2837 } |
2650 virtual void VisitContinuation( | 2838 virtual void VisitContinuation( |
2651 const SpdyContinuationIR& continuation) OVERRIDE { | 2839 const SpdyContinuationIR& continuation) OVERRIDE { |
2652 frame_.reset(framer_->SerializeContinuation(continuation)); | 2840 frame_.reset(framer_->SerializeContinuation(continuation)); |
2653 } | 2841 } |
| 2842 virtual void VisitAltSvc(const SpdyAltSvcIR& altsvc) OVERRIDE { |
| 2843 frame_.reset(framer_->SerializeAltSvc(altsvc)); |
| 2844 } |
2654 | 2845 |
2655 private: | 2846 private: |
2656 SpdyFramer* framer_; | 2847 SpdyFramer* framer_; |
2657 scoped_ptr<SpdySerializedFrame> frame_; | 2848 scoped_ptr<SpdySerializedFrame> frame_; |
2658 }; | 2849 }; |
2659 | 2850 |
2660 } // namespace | 2851 } // namespace |
2661 | 2852 |
2662 SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) { | 2853 SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) { |
2663 FrameSerializationVisitor visitor(this); | 2854 FrameSerializationVisitor visitor(this); |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2996 builder->Seek(compressed_size); | 3187 builder->Seek(compressed_size); |
2997 builder->RewriteLength(*this); | 3188 builder->RewriteLength(*this); |
2998 | 3189 |
2999 pre_compress_bytes.Add(uncompressed_len); | 3190 pre_compress_bytes.Add(uncompressed_len); |
3000 post_compress_bytes.Add(compressed_size); | 3191 post_compress_bytes.Add(compressed_size); |
3001 | 3192 |
3002 compressed_frames.Increment(); | 3193 compressed_frames.Increment(); |
3003 } | 3194 } |
3004 | 3195 |
3005 } // namespace net | 3196 } // namespace net |
OLD | NEW |