| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 | 351 |
| 352 size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) { | 352 size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) { |
| 353 // This should only be called when we're in the SPDY_READING_COMMON_HEADER | 353 // This should only be called when we're in the SPDY_READING_COMMON_HEADER |
| 354 // state. | 354 // state. |
| 355 DCHECK_EQ(state_, SPDY_READING_COMMON_HEADER); | 355 DCHECK_EQ(state_, SPDY_READING_COMMON_HEADER); |
| 356 | 356 |
| 357 size_t original_len = len; | 357 size_t original_len = len; |
| 358 SpdyFrame current_frame(current_frame_buffer_, false); | 358 SpdyFrame current_frame(current_frame_buffer_, false); |
| 359 | 359 |
| 360 do { | 360 do { |
| 361 if (current_frame_len_ < SpdyFrame::size()) { | 361 if (current_frame_len_ < SpdyFrame::kHeaderSize) { |
| 362 size_t bytes_desired = SpdyFrame::size() - current_frame_len_; | 362 size_t bytes_desired = SpdyFrame::kHeaderSize - current_frame_len_; |
| 363 UpdateCurrentFrameBuffer(&data, &len, bytes_desired); | 363 UpdateCurrentFrameBuffer(&data, &len, bytes_desired); |
| 364 // Check for an empty data frame. | 364 // Check for an empty data frame. |
| 365 if (current_frame_len_ == SpdyFrame::size() && | 365 if (current_frame_len_ == SpdyFrame::kHeaderSize && |
| 366 !current_frame.is_control_frame() && | 366 !current_frame.is_control_frame() && |
| 367 current_frame.length() == 0) { | 367 current_frame.length() == 0) { |
| 368 if (current_frame.flags() & CONTROL_FLAG_FIN) { | 368 if (current_frame.flags() & CONTROL_FLAG_FIN) { |
| 369 SpdyDataFrame data_frame(current_frame_buffer_, false); | 369 SpdyDataFrame data_frame(current_frame_buffer_, false); |
| 370 visitor_->OnStreamFrameData(data_frame.stream_id(), NULL, 0); | 370 visitor_->OnStreamFrameData(data_frame.stream_id(), NULL, 0); |
| 371 } | 371 } |
| 372 CHANGE_STATE(SPDY_AUTO_RESET); | 372 CHANGE_STATE(SPDY_AUTO_RESET); |
| 373 } | 373 } |
| 374 break; | 374 break; |
| 375 } | 375 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 386 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME); | 386 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME); |
| 387 else | 387 else |
| 388 CHANGE_STATE(SPDY_INTERPRET_CONTROL_FRAME_COMMON_HEADER); | 388 CHANGE_STATE(SPDY_INTERPRET_CONTROL_FRAME_COMMON_HEADER); |
| 389 } while (false); | 389 } while (false); |
| 390 | 390 |
| 391 return original_len - len; | 391 return original_len - len; |
| 392 } | 392 } |
| 393 | 393 |
| 394 void SpdyFramer::ProcessControlFrameHeader() { | 394 void SpdyFramer::ProcessControlFrameHeader() { |
| 395 DCHECK_EQ(SPDY_NO_ERROR, error_code_); | 395 DCHECK_EQ(SPDY_NO_ERROR, error_code_); |
| 396 DCHECK_LE(SpdyFrame::size(), current_frame_len_); | 396 DCHECK_LE(static_cast<size_t>(SpdyFrame::kHeaderSize), current_frame_len_); |
| 397 SpdyControlFrame current_control_frame(current_frame_buffer_, false); | 397 SpdyControlFrame current_control_frame(current_frame_buffer_, false); |
| 398 | 398 |
| 399 // We check version before we check validity: version can never be 'invalid', | 399 // We check version before we check validity: version can never be 'invalid', |
| 400 // it can only be unsupported. | 400 // it can only be unsupported. |
| 401 if (current_control_frame.version() != spdy_version_) { | 401 if (current_control_frame.version() != spdy_version_) { |
| 402 set_error(SPDY_UNSUPPORTED_VERSION); | 402 set_error(SPDY_UNSUPPORTED_VERSION); |
| 403 return; | 403 return; |
| 404 } | 404 } |
| 405 | 405 |
| 406 // Next up, check to see if we have valid data. This should be after version | 406 // Next up, check to see if we have valid data. This should be after version |
| (...skipping 19 matching lines...) Expand all Loading... |
| 426 SpdySynStreamControlFrame::size() - SpdyControlFrame::size()) | 426 SpdySynStreamControlFrame::size() - SpdyControlFrame::size()) |
| 427 set_error(SPDY_INVALID_CONTROL_FRAME); | 427 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 428 break; | 428 break; |
| 429 case SYN_REPLY: | 429 case SYN_REPLY: |
| 430 if (current_control_frame.length() < | 430 if (current_control_frame.length() < |
| 431 SpdySynReplyControlFrame::size() - SpdyControlFrame::size()) | 431 SpdySynReplyControlFrame::size() - SpdyControlFrame::size()) |
| 432 set_error(SPDY_INVALID_CONTROL_FRAME); | 432 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 433 break; | 433 break; |
| 434 case RST_STREAM: | 434 case RST_STREAM: |
| 435 if (current_control_frame.length() != | 435 if (current_control_frame.length() != |
| 436 SpdyRstStreamControlFrame::size() - SpdyFrame::size()) | 436 SpdyRstStreamControlFrame::size() - SpdyFrame::kHeaderSize) |
| 437 set_error(SPDY_INVALID_CONTROL_FRAME); | 437 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 438 break; | 438 break; |
| 439 case SETTINGS: | 439 case SETTINGS: |
| 440 if (current_control_frame.length() < | 440 if (current_control_frame.length() < |
| 441 SpdySettingsControlFrame::size() - SpdyControlFrame::size()) | 441 SpdySettingsControlFrame::size() - SpdyControlFrame::size()) |
| 442 set_error(SPDY_INVALID_CONTROL_FRAME); | 442 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 443 break; | 443 break; |
| 444 case GOAWAY: | 444 case GOAWAY: |
| 445 if (current_control_frame.length() != | 445 if (current_control_frame.length() != |
| 446 SpdyGoAwayControlFrame::size() - SpdyFrame::size()) | 446 SpdyGoAwayControlFrame::size() - SpdyFrame::kHeaderSize) |
| 447 set_error(SPDY_INVALID_CONTROL_FRAME); | 447 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 448 break; | 448 break; |
| 449 case HEADERS: | 449 case HEADERS: |
| 450 if (current_control_frame.length() < | 450 if (current_control_frame.length() < |
| 451 SpdyHeadersControlFrame::size() - SpdyControlFrame::size()) | 451 SpdyHeadersControlFrame::size() - SpdyControlFrame::size()) |
| 452 set_error(SPDY_INVALID_CONTROL_FRAME); | 452 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 453 break; | 453 break; |
| 454 case WINDOW_UPDATE: | 454 case WINDOW_UPDATE: |
| 455 if (current_control_frame.length() != | 455 if (current_control_frame.length() != |
| 456 SpdyWindowUpdateControlFrame::size() - SpdyControlFrame::size()) | 456 SpdyWindowUpdateControlFrame::size() - SpdyControlFrame::size()) |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 visitor_->OnStreamFrameData(current_data_frame.stream_id(), NULL, 0); | 704 visitor_->OnStreamFrameData(current_data_frame.stream_id(), NULL, 0); |
| 705 CleanupDecompressorForStream(current_data_frame.stream_id()); | 705 CleanupDecompressorForStream(current_data_frame.stream_id()); |
| 706 } | 706 } |
| 707 } else { | 707 } else { |
| 708 CHANGE_STATE(SPDY_AUTO_RESET); | 708 CHANGE_STATE(SPDY_AUTO_RESET); |
| 709 } | 709 } |
| 710 return original_len - len; | 710 return original_len - len; |
| 711 } | 711 } |
| 712 | 712 |
| 713 void SpdyFramer::ExpandControlFrameBuffer(size_t size) { | 713 void SpdyFramer::ExpandControlFrameBuffer(size_t size) { |
| 714 size_t alloc_size = size + SpdyFrame::size(); | 714 size_t alloc_size = size + SpdyFrame::kHeaderSize; |
| 715 DCHECK_LE(alloc_size, kControlFrameBufferMaxSize); | 715 DCHECK_LE(alloc_size, kControlFrameBufferMaxSize); |
| 716 if (alloc_size <= current_frame_capacity_) | 716 if (alloc_size <= current_frame_capacity_) |
| 717 return; | 717 return; |
| 718 char* new_buffer = new char[alloc_size]; | 718 char* new_buffer = new char[alloc_size]; |
| 719 memcpy(new_buffer, current_frame_buffer_, current_frame_len_); | 719 memcpy(new_buffer, current_frame_buffer_, current_frame_len_); |
| 720 delete [] current_frame_buffer_; | 720 delete [] current_frame_buffer_; |
| 721 current_frame_capacity_ = alloc_size; | 721 current_frame_capacity_ = alloc_size; |
| 722 current_frame_buffer_ = new_buffer; | 722 current_frame_buffer_ = new_buffer; |
| 723 } | 723 } |
| 724 | 724 |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 840 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); | 840 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); |
| 841 DCHECK_EQ(0u, associated_stream_id & ~kStreamIdMask); | 841 DCHECK_EQ(0u, associated_stream_id & ~kStreamIdMask); |
| 842 | 842 |
| 843 // Find our length. | 843 // Find our length. |
| 844 size_t expected_frame_size = SpdySynStreamControlFrame::size() + | 844 size_t expected_frame_size = SpdySynStreamControlFrame::size() + |
| 845 GetSerializedLength(headers); | 845 GetSerializedLength(headers); |
| 846 | 846 |
| 847 // Create our FlagsAndLength. | 847 // Create our FlagsAndLength. |
| 848 FlagsAndLength flags_length = CreateFlagsAndLength( | 848 FlagsAndLength flags_length = CreateFlagsAndLength( |
| 849 flags, | 849 flags, |
| 850 expected_frame_size - SpdyFrame::size()); | 850 expected_frame_size - SpdyFrame::kHeaderSize); |
| 851 | 851 |
| 852 SpdyFrameBuilder frame(expected_frame_size); | 852 SpdyFrameBuilder frame(expected_frame_size); |
| 853 frame.WriteUInt16(kControlFlagMask | spdy_version_); | 853 frame.WriteUInt16(kControlFlagMask | spdy_version_); |
| 854 frame.WriteUInt16(SYN_STREAM); | 854 frame.WriteUInt16(SYN_STREAM); |
| 855 frame.WriteBytes(&flags_length, sizeof(flags_length)); | 855 frame.WriteBytes(&flags_length, sizeof(flags_length)); |
| 856 frame.WriteUInt32(stream_id); | 856 frame.WriteUInt32(stream_id); |
| 857 frame.WriteUInt32(associated_stream_id); | 857 frame.WriteUInt32(associated_stream_id); |
| 858 frame.WriteUInt16(ntohs(priority) << 6); // Priority. | 858 frame.WriteUInt16(ntohs(priority) << 6); // Priority. |
| 859 WriteHeaderBlock(&frame, headers); | 859 WriteHeaderBlock(&frame, headers); |
| 860 | 860 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 872 DCHECK_GT(stream_id, 0u); | 872 DCHECK_GT(stream_id, 0u); |
| 873 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); | 873 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); |
| 874 | 874 |
| 875 // Find our length. | 875 // Find our length. |
| 876 size_t expected_frame_size = SpdySynReplyControlFrame::size() + | 876 size_t expected_frame_size = SpdySynReplyControlFrame::size() + |
| 877 GetSerializedLength(headers); | 877 GetSerializedLength(headers); |
| 878 | 878 |
| 879 // Create our FlagsAndLength. | 879 // Create our FlagsAndLength. |
| 880 FlagsAndLength flags_length = CreateFlagsAndLength( | 880 FlagsAndLength flags_length = CreateFlagsAndLength( |
| 881 flags, | 881 flags, |
| 882 expected_frame_size - SpdyFrame::size()); | 882 expected_frame_size - SpdyFrame::kHeaderSize); |
| 883 | 883 |
| 884 SpdyFrameBuilder frame(expected_frame_size); | 884 SpdyFrameBuilder frame(expected_frame_size); |
| 885 frame.WriteUInt16(kControlFlagMask | spdy_version_); | 885 frame.WriteUInt16(kControlFlagMask | spdy_version_); |
| 886 frame.WriteUInt16(SYN_REPLY); | 886 frame.WriteUInt16(SYN_REPLY); |
| 887 frame.WriteBytes(&flags_length, sizeof(flags_length)); | 887 frame.WriteBytes(&flags_length, sizeof(flags_length)); |
| 888 frame.WriteUInt32(stream_id); | 888 frame.WriteUInt32(stream_id); |
| 889 frame.WriteUInt16(0); // Unused | 889 frame.WriteUInt16(0); // Unused |
| 890 WriteHeaderBlock(&frame, headers); | 890 WriteHeaderBlock(&frame, headers); |
| 891 | 891 |
| 892 scoped_ptr<SpdySynReplyControlFrame> reply_frame( | 892 scoped_ptr<SpdySynReplyControlFrame> reply_frame( |
| (...skipping 21 matching lines...) Expand all Loading... |
| 914 frame.WriteUInt32(status); | 914 frame.WriteUInt32(status); |
| 915 return reinterpret_cast<SpdyRstStreamControlFrame*>(frame.take()); | 915 return reinterpret_cast<SpdyRstStreamControlFrame*>(frame.take()); |
| 916 } | 916 } |
| 917 | 917 |
| 918 /* static */ | 918 /* static */ |
| 919 SpdySettingsControlFrame* SpdyFramer::CreateSettings( | 919 SpdySettingsControlFrame* SpdyFramer::CreateSettings( |
| 920 const SpdySettings& values) { | 920 const SpdySettings& values) { |
| 921 SpdyFrameBuilder frame(SpdySettingsControlFrame::size() + 8 * values.size()); | 921 SpdyFrameBuilder frame(SpdySettingsControlFrame::size() + 8 * values.size()); |
| 922 frame.WriteUInt16(kControlFlagMask | spdy_version_); | 922 frame.WriteUInt16(kControlFlagMask | spdy_version_); |
| 923 frame.WriteUInt16(SETTINGS); | 923 frame.WriteUInt16(SETTINGS); |
| 924 size_t settings_size = SpdySettingsControlFrame::size() - SpdyFrame::size() + | 924 size_t settings_size = |
| 925 SpdySettingsControlFrame::size() - SpdyFrame::kHeaderSize + |
| 925 8 * values.size(); | 926 8 * values.size(); |
| 926 frame.WriteUInt32(settings_size); | 927 frame.WriteUInt32(settings_size); |
| 927 frame.WriteUInt32(values.size()); | 928 frame.WriteUInt32(values.size()); |
| 928 SpdySettings::const_iterator it = values.begin(); | 929 SpdySettings::const_iterator it = values.begin(); |
| 929 while (it != values.end()) { | 930 while (it != values.end()) { |
| 930 frame.WriteUInt32(it->first.id_); | 931 frame.WriteUInt32(it->first.id_); |
| 931 frame.WriteUInt32(it->second); | 932 frame.WriteUInt32(it->second); |
| 932 ++it; | 933 ++it; |
| 933 } | 934 } |
| 934 return reinterpret_cast<SpdySettingsControlFrame*>(frame.take()); | 935 return reinterpret_cast<SpdySettingsControlFrame*>(frame.take()); |
| 935 } | 936 } |
| 936 | 937 |
| 937 /* static */ | 938 /* static */ |
| 938 SpdyNoOpControlFrame* SpdyFramer::CreateNopFrame() { | 939 SpdyNoOpControlFrame* SpdyFramer::CreateNopFrame() { |
| 939 SpdyFrameBuilder frame(SpdyNoOpControlFrame::size()); | 940 SpdyFrameBuilder frame(SpdyNoOpControlFrame::size()); |
| 940 frame.WriteUInt16(kControlFlagMask | spdy_version_); | 941 frame.WriteUInt16(kControlFlagMask | spdy_version_); |
| 941 frame.WriteUInt16(NOOP); | 942 frame.WriteUInt16(NOOP); |
| 942 frame.WriteUInt32(0); | 943 frame.WriteUInt32(0); |
| 943 return reinterpret_cast<SpdyNoOpControlFrame*>(frame.take()); | 944 return reinterpret_cast<SpdyNoOpControlFrame*>(frame.take()); |
| 944 } | 945 } |
| 945 | 946 |
| 946 /* static */ | 947 /* static */ |
| 947 SpdyPingControlFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) { | 948 SpdyPingControlFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) { |
| 948 SpdyFrameBuilder frame(SpdyPingControlFrame::size()); | 949 SpdyFrameBuilder frame(SpdyPingControlFrame::size()); |
| 949 frame.WriteUInt16(kControlFlagMask | spdy_version_); | 950 frame.WriteUInt16(kControlFlagMask | spdy_version_); |
| 950 frame.WriteUInt16(PING); | 951 frame.WriteUInt16(PING); |
| 951 size_t ping_size = SpdyPingControlFrame::size() - SpdyFrame::size(); | 952 size_t ping_size = SpdyPingControlFrame::size() - SpdyFrame::kHeaderSize; |
| 952 frame.WriteUInt32(ping_size); | 953 frame.WriteUInt32(ping_size); |
| 953 frame.WriteUInt32(unique_id); | 954 frame.WriteUInt32(unique_id); |
| 954 return reinterpret_cast<SpdyPingControlFrame*>(frame.take()); | 955 return reinterpret_cast<SpdyPingControlFrame*>(frame.take()); |
| 955 } | 956 } |
| 956 | 957 |
| 957 /* static */ | 958 /* static */ |
| 958 SpdyGoAwayControlFrame* SpdyFramer::CreateGoAway( | 959 SpdyGoAwayControlFrame* SpdyFramer::CreateGoAway( |
| 959 SpdyStreamId last_accepted_stream_id) { | 960 SpdyStreamId last_accepted_stream_id) { |
| 960 DCHECK_EQ(0u, last_accepted_stream_id & ~kStreamIdMask); | 961 DCHECK_EQ(0u, last_accepted_stream_id & ~kStreamIdMask); |
| 961 | 962 |
| 962 SpdyFrameBuilder frame(SpdyGoAwayControlFrame::size()); | 963 SpdyFrameBuilder frame(SpdyGoAwayControlFrame::size()); |
| 963 frame.WriteUInt16(kControlFlagMask | spdy_version_); | 964 frame.WriteUInt16(kControlFlagMask | spdy_version_); |
| 964 frame.WriteUInt16(GOAWAY); | 965 frame.WriteUInt16(GOAWAY); |
| 965 size_t go_away_size = SpdyGoAwayControlFrame::size() - SpdyFrame::size(); | 966 size_t go_away_size = SpdyGoAwayControlFrame::size() - SpdyFrame::kHeaderSize; |
| 966 frame.WriteUInt32(go_away_size); | 967 frame.WriteUInt32(go_away_size); |
| 967 frame.WriteUInt32(last_accepted_stream_id); | 968 frame.WriteUInt32(last_accepted_stream_id); |
| 968 return reinterpret_cast<SpdyGoAwayControlFrame*>(frame.take()); | 969 return reinterpret_cast<SpdyGoAwayControlFrame*>(frame.take()); |
| 969 } | 970 } |
| 970 | 971 |
| 971 SpdyHeadersControlFrame* SpdyFramer::CreateHeaders(SpdyStreamId stream_id, | 972 SpdyHeadersControlFrame* SpdyFramer::CreateHeaders(SpdyStreamId stream_id, |
| 972 SpdyControlFlags flags, bool compressed, const SpdyHeaderBlock* headers) { | 973 SpdyControlFlags flags, bool compressed, const SpdyHeaderBlock* headers) { |
| 973 // Basically the same as CreateSynReply(). | 974 // Basically the same as CreateSynReply(). |
| 974 DCHECK_GT(stream_id, 0u); | 975 DCHECK_GT(stream_id, 0u); |
| 975 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); | 976 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); |
| 976 | 977 |
| 977 // Find our length. | 978 // Find our length. |
| 978 size_t expected_frame_size = SpdyHeadersControlFrame::size() + | 979 size_t expected_frame_size = SpdyHeadersControlFrame::size() + |
| 979 GetSerializedLength(headers); | 980 GetSerializedLength(headers); |
| 980 | 981 |
| 981 // Create our FlagsAndLength. | 982 // Create our FlagsAndLength. |
| 982 FlagsAndLength flags_length = CreateFlagsAndLength( | 983 FlagsAndLength flags_length = CreateFlagsAndLength( |
| 983 flags, | 984 flags, |
| 984 expected_frame_size - SpdyFrame::size()); | 985 expected_frame_size - SpdyFrame::kHeaderSize); |
| 985 | 986 |
| 986 SpdyFrameBuilder frame(expected_frame_size); | 987 SpdyFrameBuilder frame(expected_frame_size); |
| 987 frame.WriteUInt16(kControlFlagMask | spdy_version_); | 988 frame.WriteUInt16(kControlFlagMask | spdy_version_); |
| 988 frame.WriteUInt16(HEADERS); | 989 frame.WriteUInt16(HEADERS); |
| 989 frame.WriteBytes(&flags_length, sizeof(flags_length)); | 990 frame.WriteBytes(&flags_length, sizeof(flags_length)); |
| 990 frame.WriteUInt32(stream_id); | 991 frame.WriteUInt32(stream_id); |
| 991 frame.WriteUInt16(0); // Unused | 992 frame.WriteUInt16(0); // Unused |
| 992 WriteHeaderBlock(&frame, headers); | 993 WriteHeaderBlock(&frame, headers); |
| 993 DCHECK_EQ(static_cast<size_t>(frame.length()), expected_frame_size); | 994 DCHECK_EQ(static_cast<size_t>(frame.length()), expected_frame_size); |
| 994 | 995 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1007 uint32 delta_window_size) { | 1008 uint32 delta_window_size) { |
| 1008 DCHECK_GT(stream_id, 0u); | 1009 DCHECK_GT(stream_id, 0u); |
| 1009 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); | 1010 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); |
| 1010 DCHECK_GT(delta_window_size, 0u); | 1011 DCHECK_GT(delta_window_size, 0u); |
| 1011 DCHECK_LE(delta_window_size, spdy::kSpdyStreamMaximumWindowSize); | 1012 DCHECK_LE(delta_window_size, spdy::kSpdyStreamMaximumWindowSize); |
| 1012 | 1013 |
| 1013 SpdyFrameBuilder frame(SpdyWindowUpdateControlFrame::size()); | 1014 SpdyFrameBuilder frame(SpdyWindowUpdateControlFrame::size()); |
| 1014 frame.WriteUInt16(kControlFlagMask | spdy_version_); | 1015 frame.WriteUInt16(kControlFlagMask | spdy_version_); |
| 1015 frame.WriteUInt16(WINDOW_UPDATE); | 1016 frame.WriteUInt16(WINDOW_UPDATE); |
| 1016 size_t window_update_size = SpdyWindowUpdateControlFrame::size() - | 1017 size_t window_update_size = SpdyWindowUpdateControlFrame::size() - |
| 1017 SpdyFrame::size(); | 1018 SpdyFrame::kHeaderSize; |
| 1018 frame.WriteUInt32(window_update_size); | 1019 frame.WriteUInt32(window_update_size); |
| 1019 frame.WriteUInt32(stream_id); | 1020 frame.WriteUInt32(stream_id); |
| 1020 frame.WriteUInt32(delta_window_size); | 1021 frame.WriteUInt32(delta_window_size); |
| 1021 return reinterpret_cast<SpdyWindowUpdateControlFrame*>(frame.take()); | 1022 return reinterpret_cast<SpdyWindowUpdateControlFrame*>(frame.take()); |
| 1022 } | 1023 } |
| 1023 | 1024 |
| 1024 SpdyDataFrame* SpdyFramer::CreateDataFrame(SpdyStreamId stream_id, | 1025 SpdyDataFrame* SpdyFramer::CreateDataFrame(SpdyStreamId stream_id, |
| 1025 const char* data, | 1026 const char* data, |
| 1026 uint32 len, SpdyDataFlags flags) { | 1027 uint32 len, SpdyDataFlags flags) { |
| 1027 DCHECK_GT(stream_id, 0u); | 1028 DCHECK_GT(stream_id, 0u); |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1227 *payload_length = headers_frame.header_block_len(); | 1228 *payload_length = headers_frame.header_block_len(); |
| 1228 *header_length = frame_size; | 1229 *header_length = frame_size; |
| 1229 *payload = frame.data() + *header_length; | 1230 *payload = frame.data() + *header_length; |
| 1230 } | 1231 } |
| 1231 break; | 1232 break; |
| 1232 default: | 1233 default: |
| 1233 // TODO(mbelshe): set an error? | 1234 // TODO(mbelshe): set an error? |
| 1234 return false; // We can't compress this frame! | 1235 return false; // We can't compress this frame! |
| 1235 } | 1236 } |
| 1236 } else { | 1237 } else { |
| 1237 frame_size = SpdyFrame::size(); | 1238 frame_size = SpdyFrame::kHeaderSize; |
| 1238 *header_length = frame_size; | 1239 *header_length = frame_size; |
| 1239 *payload_length = frame.length(); | 1240 *payload_length = frame.length(); |
| 1240 *payload = frame.data() + SpdyFrame::size(); | 1241 *payload = frame.data() + SpdyFrame::kHeaderSize; |
| 1241 } | 1242 } |
| 1242 return true; | 1243 return true; |
| 1243 } | 1244 } |
| 1244 | 1245 |
| 1245 SpdyControlFrame* SpdyFramer::CompressControlFrame( | 1246 SpdyControlFrame* SpdyFramer::CompressControlFrame( |
| 1246 const SpdyControlFrame& frame) { | 1247 const SpdyControlFrame& frame) { |
| 1247 z_stream* compressor = GetHeaderCompressor(); | 1248 z_stream* compressor = GetHeaderCompressor(); |
| 1248 if (!compressor) | 1249 if (!compressor) |
| 1249 return NULL; | 1250 return NULL; |
| 1250 return reinterpret_cast<SpdyControlFrame*>( | 1251 return reinterpret_cast<SpdyControlFrame*>( |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1289 if (!enable_compression_) | 1290 if (!enable_compression_) |
| 1290 return DuplicateFrame(frame); | 1291 return DuplicateFrame(frame); |
| 1291 | 1292 |
| 1292 if (!GetFrameBoundaries(frame, &payload_length, &header_length, &payload)) | 1293 if (!GetFrameBoundaries(frame, &payload_length, &header_length, &payload)) |
| 1293 return NULL; | 1294 return NULL; |
| 1294 | 1295 |
| 1295 // Create an output frame. | 1296 // Create an output frame. |
| 1296 int compressed_max_size = deflateBound(compressor, payload_length); | 1297 int compressed_max_size = deflateBound(compressor, payload_length); |
| 1297 int new_frame_size = header_length + compressed_max_size; | 1298 int new_frame_size = header_length + compressed_max_size; |
| 1298 scoped_ptr<SpdyFrame> new_frame(new SpdyFrame(new_frame_size)); | 1299 scoped_ptr<SpdyFrame> new_frame(new SpdyFrame(new_frame_size)); |
| 1299 memcpy(new_frame->data(), frame.data(), frame.length() + SpdyFrame::size()); | 1300 memcpy(new_frame->data(), frame.data(), |
| 1301 frame.length() + SpdyFrame::kHeaderSize); |
| 1300 | 1302 |
| 1301 compressor->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(payload)); | 1303 compressor->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(payload)); |
| 1302 compressor->avail_in = payload_length; | 1304 compressor->avail_in = payload_length; |
| 1303 compressor->next_out = reinterpret_cast<Bytef*>(new_frame->data()) + | 1305 compressor->next_out = reinterpret_cast<Bytef*>(new_frame->data()) + |
| 1304 header_length; | 1306 header_length; |
| 1305 compressor->avail_out = compressed_max_size; | 1307 compressor->avail_out = compressed_max_size; |
| 1306 | 1308 |
| 1307 // Data packets have a 'compressed' flag. | 1309 // Data packets have a 'compressed' flag. |
| 1308 if (!new_frame->is_control_frame()) { | 1310 if (!new_frame->is_control_frame()) { |
| 1309 SpdyDataFrame* data_frame = | 1311 SpdyDataFrame* data_frame = |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1323 return NULL; | 1325 return NULL; |
| 1324 } | 1326 } |
| 1325 | 1327 |
| 1326 int compressed_size = compressed_max_size - compressor->avail_out; | 1328 int compressed_size = compressed_max_size - compressor->avail_out; |
| 1327 | 1329 |
| 1328 // We trust zlib. Also, we can't do anything about it. | 1330 // We trust zlib. Also, we can't do anything about it. |
| 1329 // See http://www.zlib.net/zlib_faq.html#faq36 | 1331 // See http://www.zlib.net/zlib_faq.html#faq36 |
| 1330 (void)VALGRIND_MAKE_MEM_DEFINED(new_frame->data() + header_length, | 1332 (void)VALGRIND_MAKE_MEM_DEFINED(new_frame->data() + header_length, |
| 1331 compressed_size); | 1333 compressed_size); |
| 1332 | 1334 |
| 1333 new_frame->set_length(header_length + compressed_size - SpdyFrame::size()); | 1335 new_frame->set_length( |
| 1336 header_length + compressed_size - SpdyFrame::kHeaderSize); |
| 1334 | 1337 |
| 1335 pre_compress_bytes.Add(payload_length); | 1338 pre_compress_bytes.Add(payload_length); |
| 1336 post_compress_bytes.Add(new_frame->length()); | 1339 post_compress_bytes.Add(new_frame->length()); |
| 1337 | 1340 |
| 1338 compressed_frames.Increment(); | 1341 compressed_frames.Increment(); |
| 1339 | 1342 |
| 1340 return new_frame.release(); | 1343 return new_frame.release(); |
| 1341 } | 1344 } |
| 1342 | 1345 |
| 1343 SpdyFrame* SpdyFramer::DecompressFrameWithZStream(const SpdyFrame& frame, | 1346 SpdyFrame* SpdyFramer::DecompressFrameWithZStream(const SpdyFrame& frame, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1363 return DuplicateFrame(frame); | 1366 return DuplicateFrame(frame); |
| 1364 } | 1367 } |
| 1365 | 1368 |
| 1366 // Create an output frame. Assume it does not need to be longer than | 1369 // Create an output frame. Assume it does not need to be longer than |
| 1367 // the input data. | 1370 // the input data. |
| 1368 size_t decompressed_max_size = kControlFrameBufferInitialSize; | 1371 size_t decompressed_max_size = kControlFrameBufferInitialSize; |
| 1369 int new_frame_size = header_length + decompressed_max_size; | 1372 int new_frame_size = header_length + decompressed_max_size; |
| 1370 if (frame.length() > decompressed_max_size) | 1373 if (frame.length() > decompressed_max_size) |
| 1371 return NULL; | 1374 return NULL; |
| 1372 scoped_ptr<SpdyFrame> new_frame(new SpdyFrame(new_frame_size)); | 1375 scoped_ptr<SpdyFrame> new_frame(new SpdyFrame(new_frame_size)); |
| 1373 memcpy(new_frame->data(), frame.data(), frame.length() + SpdyFrame::size()); | 1376 memcpy(new_frame->data(), frame.data(), |
| 1377 frame.length() + SpdyFrame::kHeaderSize); |
| 1374 | 1378 |
| 1375 decompressor->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(payload)); | 1379 decompressor->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(payload)); |
| 1376 decompressor->avail_in = payload_length; | 1380 decompressor->avail_in = payload_length; |
| 1377 decompressor->next_out = reinterpret_cast<Bytef*>(new_frame->data()) + | 1381 decompressor->next_out = reinterpret_cast<Bytef*>(new_frame->data()) + |
| 1378 header_length; | 1382 header_length; |
| 1379 decompressor->avail_out = decompressed_max_size; | 1383 decompressor->avail_out = decompressed_max_size; |
| 1380 | 1384 |
| 1381 int rv = inflate(decompressor, Z_SYNC_FLUSH); | 1385 int rv = inflate(decompressor, Z_SYNC_FLUSH); |
| 1382 if (rv == Z_NEED_DICT) { | 1386 if (rv == Z_NEED_DICT) { |
| 1383 // Need to try again with the right dictionary. | 1387 // Need to try again with the right dictionary. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1395 } | 1399 } |
| 1396 | 1400 |
| 1397 // Unset the compressed flag for data frames. | 1401 // Unset the compressed flag for data frames. |
| 1398 if (!new_frame->is_control_frame()) { | 1402 if (!new_frame->is_control_frame()) { |
| 1399 SpdyDataFrame* data_frame = | 1403 SpdyDataFrame* data_frame = |
| 1400 reinterpret_cast<SpdyDataFrame*>(new_frame.get()); | 1404 reinterpret_cast<SpdyDataFrame*>(new_frame.get()); |
| 1401 data_frame->set_flags(data_frame->flags() & ~DATA_FLAG_COMPRESSED); | 1405 data_frame->set_flags(data_frame->flags() & ~DATA_FLAG_COMPRESSED); |
| 1402 } | 1406 } |
| 1403 | 1407 |
| 1404 int decompressed_size = decompressed_max_size - decompressor->avail_out; | 1408 int decompressed_size = decompressed_max_size - decompressor->avail_out; |
| 1405 new_frame->set_length(header_length + decompressed_size - SpdyFrame::size()); | 1409 new_frame->set_length( |
| 1410 header_length + decompressed_size - SpdyFrame::kHeaderSize); |
| 1406 | 1411 |
| 1407 // If there is data left, then the frame didn't fully decompress. This | 1412 // If there is data left, then the frame didn't fully decompress. This |
| 1408 // means that there is stranded data at the end of this frame buffer which | 1413 // means that there is stranded data at the end of this frame buffer which |
| 1409 // will be ignored. | 1414 // will be ignored. |
| 1410 DCHECK_EQ(decompressor->avail_in, 0u); | 1415 DCHECK_EQ(decompressor->avail_in, 0u); |
| 1411 | 1416 |
| 1412 pre_decompress_bytes.Add(frame.length()); | 1417 pre_decompress_bytes.Add(frame.length()); |
| 1413 post_decompress_bytes.Add(new_frame->length()); | 1418 post_decompress_bytes.Add(new_frame->length()); |
| 1414 | 1419 |
| 1415 decompressed_frames.Increment(); | 1420 decompressed_frames.Increment(); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1569 while (it != stream_decompressors_.end()) { | 1574 while (it != stream_decompressors_.end()) { |
| 1570 z_stream* decompressor = it->second; | 1575 z_stream* decompressor = it->second; |
| 1571 inflateEnd(decompressor); | 1576 inflateEnd(decompressor); |
| 1572 delete decompressor; | 1577 delete decompressor; |
| 1573 ++it; | 1578 ++it; |
| 1574 } | 1579 } |
| 1575 stream_decompressors_.clear(); | 1580 stream_decompressors_.clear(); |
| 1576 } | 1581 } |
| 1577 | 1582 |
| 1578 SpdyFrame* SpdyFramer::DuplicateFrame(const SpdyFrame& frame) { | 1583 SpdyFrame* SpdyFramer::DuplicateFrame(const SpdyFrame& frame) { |
| 1579 int size = SpdyFrame::size() + frame.length(); | 1584 int size = SpdyFrame::kHeaderSize + frame.length(); |
| 1580 SpdyFrame* new_frame = new SpdyFrame(size); | 1585 SpdyFrame* new_frame = new SpdyFrame(size); |
| 1581 memcpy(new_frame->data(), frame.data(), size); | 1586 memcpy(new_frame->data(), frame.data(), size); |
| 1582 return new_frame; | 1587 return new_frame; |
| 1583 } | 1588 } |
| 1584 | 1589 |
| 1585 size_t SpdyFramer::GetMinimumControlFrameSize(SpdyControlType type) { | 1590 size_t SpdyFramer::GetMinimumControlFrameSize(SpdyControlType type) { |
| 1586 switch (type) { | 1591 switch (type) { |
| 1587 case SYN_STREAM: | 1592 case SYN_STREAM: |
| 1588 return SpdySynStreamControlFrame::size(); | 1593 return SpdySynStreamControlFrame::size(); |
| 1589 case SYN_REPLY: | 1594 case SYN_REPLY: |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1651 } | 1656 } |
| 1652 | 1657 |
| 1653 size_t SpdyFramer::BytesSafeToRead() const { | 1658 size_t SpdyFramer::BytesSafeToRead() const { |
| 1654 switch (state_) { | 1659 switch (state_) { |
| 1655 case SPDY_ERROR: | 1660 case SPDY_ERROR: |
| 1656 case SPDY_DONE: | 1661 case SPDY_DONE: |
| 1657 case SPDY_AUTO_RESET: | 1662 case SPDY_AUTO_RESET: |
| 1658 case SPDY_RESET: | 1663 case SPDY_RESET: |
| 1659 return 0; | 1664 return 0; |
| 1660 case SPDY_READING_COMMON_HEADER: | 1665 case SPDY_READING_COMMON_HEADER: |
| 1661 DCHECK_LT(current_frame_len_, SpdyFrame::size()); | 1666 DCHECK_LT(current_frame_len_, |
| 1662 return SpdyFrame::size() - current_frame_len_; | 1667 static_cast<size_t>(SpdyFrame::kHeaderSize)); |
| 1668 return SpdyFrame::kHeaderSize - current_frame_len_; |
| 1663 case SPDY_INTERPRET_CONTROL_FRAME_COMMON_HEADER: | 1669 case SPDY_INTERPRET_CONTROL_FRAME_COMMON_HEADER: |
| 1664 return 0; | 1670 return 0; |
| 1665 // TODO(rtenneti): Add support for SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK | 1671 // TODO(rtenneti): Add support for SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK |
| 1666 // and SPDY_CONTROL_FRAME_HEADER_BLOCK. | 1672 // and SPDY_CONTROL_FRAME_HEADER_BLOCK. |
| 1667 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: | 1673 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: |
| 1668 case SPDY_CONTROL_FRAME_HEADER_BLOCK: | 1674 case SPDY_CONTROL_FRAME_HEADER_BLOCK: |
| 1669 return 0; | 1675 return 0; |
| 1670 case SPDY_CONTROL_FRAME_PAYLOAD: | 1676 case SPDY_CONTROL_FRAME_PAYLOAD: |
| 1671 case SPDY_IGNORE_REMAINING_PAYLOAD: | 1677 case SPDY_IGNORE_REMAINING_PAYLOAD: |
| 1672 case SPDY_FORWARD_STREAM_FRAME: | 1678 case SPDY_FORWARD_STREAM_FRAME: |
| 1673 return remaining_data_; | 1679 return remaining_data_; |
| 1674 } | 1680 } |
| 1675 // We should never get to here. | 1681 // We should never get to here. |
| 1676 return 0; | 1682 return 0; |
| 1677 } | 1683 } |
| 1678 | 1684 |
| 1679 void SpdyFramer::set_enable_compression(bool value) { | 1685 void SpdyFramer::set_enable_compression(bool value) { |
| 1680 enable_compression_ = value; | 1686 enable_compression_ = value; |
| 1681 } | 1687 } |
| 1682 | 1688 |
| 1683 void SpdyFramer::set_enable_compression_default(bool value) { | 1689 void SpdyFramer::set_enable_compression_default(bool value) { |
| 1684 compression_default_ = value; | 1690 compression_default_ = value; |
| 1685 } | 1691 } |
| 1686 | 1692 |
| 1687 void SpdyFramer::set_validate_control_frame_sizes(bool value) { | 1693 void SpdyFramer::set_validate_control_frame_sizes(bool value) { |
| 1688 validate_control_frame_sizes_ = value; | 1694 validate_control_frame_sizes_ = value; |
| 1689 } | 1695 } |
| 1690 | 1696 |
| 1691 } // namespace spdy | 1697 } // namespace spdy |
| OLD | NEW |