Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(330)

Side by Side Diff: net/spdy/spdy_framer.cc

Issue 288373004: Add handling + parsing for HTTP/2 ALTSVC frame. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Non-static initializer fixes. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | net/spdy/spdy_framer_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | net/spdy/spdy_framer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698