| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // TODO(rtenhove) clean up frame buffer size calculations so that we aren't | 5 // TODO(rtenhove) clean up frame buffer size calculations so that we aren't |
| 6 // constantly adding and subtracting header sizes; this is ugly and error- | 6 // constantly adding and subtracting header sizes; this is ugly and error- |
| 7 // prone. | 7 // prone. |
| 8 | 8 |
| 9 #include "net/spdy/spdy_framer.h" | 9 #include "net/spdy/spdy_framer.h" |
| 10 | 10 |
| (...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 998 return original_len - len; | 998 return original_len - len; |
| 999 } | 999 } |
| 1000 | 1000 |
| 1001 // Does not buffer the control payload. Instead, either passes directly to the | 1001 // Does not buffer the control payload. Instead, either passes directly to the |
| 1002 // visitor or decompresses and then passes directly to the visitor, via | 1002 // visitor or decompresses and then passes directly to the visitor, via |
| 1003 // IncrementallyDeliverControlFrameHeaderData() or | 1003 // IncrementallyDeliverControlFrameHeaderData() or |
| 1004 // IncrementallyDecompressControlFrameHeaderData() respectively. | 1004 // IncrementallyDecompressControlFrameHeaderData() respectively. |
| 1005 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data, | 1005 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data, |
| 1006 size_t data_len) { | 1006 size_t data_len) { |
| 1007 DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_); | 1007 DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_); |
| 1008 SpdyControlFrame control_frame(current_frame_buffer_.get(), false); | 1008 const SpdyControlFrame control_frame(current_frame_buffer_.get(), false); |
| 1009 | 1009 |
| 1010 bool processed_successfully = true; | 1010 bool processed_successfully = true; |
| 1011 DCHECK(control_frame.type() == SYN_STREAM || | 1011 SpdyStreamId stream_id = kInvalidStream; |
| 1012 control_frame.type() == SYN_REPLY || | 1012 if (control_frame.type() == SYN_STREAM) { |
| 1013 control_frame.type() == HEADERS); | 1013 stream_id = reinterpret_cast<const SpdySynStreamControlFrame*>( |
| 1014 &control_frame)->stream_id(); |
| 1015 } else if (control_frame.type() == SYN_REPLY) { |
| 1016 stream_id = reinterpret_cast<const SpdySynReplyControlFrame*>( |
| 1017 &control_frame)->stream_id(); |
| 1018 } else if (control_frame.type() == HEADERS) { |
| 1019 stream_id = reinterpret_cast<const SpdyHeadersControlFrame*>( |
| 1020 &control_frame)->stream_id(); |
| 1021 } else { |
| 1022 LOG(DFATAL) << "Unhandled frame type in ProcessControlFrameHeaderBlock."; |
| 1023 } |
| 1014 size_t process_bytes = std::min(data_len, remaining_control_payload_); | 1024 size_t process_bytes = std::min(data_len, remaining_control_payload_); |
| 1015 if (process_bytes > 0) { | 1025 if (process_bytes > 0) { |
| 1016 if (enable_compression_) { | 1026 if (enable_compression_) { |
| 1017 processed_successfully = IncrementallyDecompressControlFrameHeaderData( | 1027 processed_successfully = IncrementallyDecompressControlFrameHeaderData( |
| 1018 &control_frame, data, process_bytes); | 1028 stream_id, data, process_bytes); |
| 1019 } else { | 1029 } else { |
| 1020 processed_successfully = IncrementallyDeliverControlFrameHeaderData( | 1030 processed_successfully = IncrementallyDeliverControlFrameHeaderData( |
| 1021 &control_frame, data, process_bytes); | 1031 stream_id, data, process_bytes); |
| 1022 } | 1032 } |
| 1023 | 1033 |
| 1024 remaining_control_payload_ -= process_bytes; | 1034 remaining_control_payload_ -= process_bytes; |
| 1025 remaining_data_ -= process_bytes; | 1035 remaining_data_ -= process_bytes; |
| 1026 } | 1036 } |
| 1027 | 1037 |
| 1028 // Handle the case that there is no futher data in this frame. | 1038 // Handle the case that there is no futher data in this frame. |
| 1029 if (remaining_control_payload_ == 0 && processed_successfully) { | 1039 if (remaining_control_payload_ == 0 && processed_successfully) { |
| 1030 // The complete header block has been delivered. We send a zero-length | 1040 // The complete header block has been delivered. We send a zero-length |
| 1031 // OnControlFrameHeaderData() to indicate this. | 1041 // OnControlFrameHeaderData() to indicate this. |
| 1032 visitor_->OnControlFrameHeaderData( | 1042 visitor_->OnControlFrameHeaderData(stream_id, NULL, 0); |
| 1033 GetControlFrameStreamId(&control_frame), NULL, 0); | |
| 1034 | 1043 |
| 1035 // If this is a FIN, tell the caller. | 1044 // If this is a FIN, tell the caller. |
| 1036 if (control_frame.flags() & CONTROL_FLAG_FIN) { | 1045 if (control_frame.flags() & CONTROL_FLAG_FIN) { |
| 1037 visitor_->OnStreamFrameData(GetControlFrameStreamId(&control_frame), | 1046 visitor_->OnStreamFrameData(stream_id, NULL, 0, DATA_FLAG_FIN); |
| 1038 NULL, 0, DATA_FLAG_FIN); | |
| 1039 } | 1047 } |
| 1040 | 1048 |
| 1041 CHANGE_STATE(SPDY_AUTO_RESET); | 1049 CHANGE_STATE(SPDY_AUTO_RESET); |
| 1042 } | 1050 } |
| 1043 | 1051 |
| 1044 // Handle error. | 1052 // Handle error. |
| 1045 if (!processed_successfully) { | 1053 if (!processed_successfully) { |
| 1046 return data_len; | 1054 return data_len; |
| 1047 } | 1055 } |
| 1048 | 1056 |
| (...skipping 856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1905 } | 1913 } |
| 1906 | 1914 |
| 1907 return new_frame.release(); | 1915 return new_frame.release(); |
| 1908 } | 1916 } |
| 1909 | 1917 |
| 1910 // Incrementally decompress the control frame's header block, feeding the | 1918 // Incrementally decompress the control frame's header block, feeding the |
| 1911 // result to the visitor in chunks. Continue this until the visitor | 1919 // result to the visitor in chunks. Continue this until the visitor |
| 1912 // indicates that it cannot process any more data, or (more commonly) we | 1920 // indicates that it cannot process any more data, or (more commonly) we |
| 1913 // run out of data to deliver. | 1921 // run out of data to deliver. |
| 1914 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData( | 1922 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData( |
| 1915 const SpdyControlFrame* control_frame, | 1923 SpdyStreamId stream_id, |
| 1916 const char* data, | 1924 const char* data, |
| 1917 size_t len) { | 1925 size_t len) { |
| 1918 // Get a decompressor or set error. | 1926 // Get a decompressor or set error. |
| 1919 z_stream* decomp = GetHeaderDecompressor(); | 1927 z_stream* decomp = GetHeaderDecompressor(); |
| 1920 if (decomp == NULL) { | 1928 if (decomp == NULL) { |
| 1921 LOG(DFATAL) << "Couldn't get decompressor for handling compressed headers."; | 1929 LOG(DFATAL) << "Couldn't get decompressor for handling compressed headers."; |
| 1922 set_error(SPDY_DECOMPRESS_FAILURE); | 1930 set_error(SPDY_DECOMPRESS_FAILURE); |
| 1923 return false; | 1931 return false; |
| 1924 } | 1932 } |
| 1925 | 1933 |
| 1926 bool processed_successfully = true; | 1934 bool processed_successfully = true; |
| 1927 char buffer[kHeaderDataChunkMaxSize]; | 1935 char buffer[kHeaderDataChunkMaxSize]; |
| 1928 | 1936 |
| 1929 decomp->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data)); | 1937 decomp->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data)); |
| 1930 decomp->avail_in = len; | 1938 decomp->avail_in = len; |
| 1931 const SpdyStreamId stream_id = GetControlFrameStreamId(control_frame); | |
| 1932 DCHECK_LT(0u, stream_id); | 1939 DCHECK_LT(0u, stream_id); |
| 1933 while (decomp->avail_in > 0 && processed_successfully) { | 1940 while (decomp->avail_in > 0 && processed_successfully) { |
| 1934 decomp->next_out = reinterpret_cast<Bytef*>(buffer); | 1941 decomp->next_out = reinterpret_cast<Bytef*>(buffer); |
| 1935 decomp->avail_out = arraysize(buffer); | 1942 decomp->avail_out = arraysize(buffer); |
| 1936 | 1943 |
| 1937 int rv = inflate(decomp, Z_SYNC_FLUSH); | 1944 int rv = inflate(decomp, Z_SYNC_FLUSH); |
| 1938 if (rv == Z_NEED_DICT) { | 1945 if (rv == Z_NEED_DICT) { |
| 1939 const char* dictionary = (spdy_version_ < 3) ? kV2Dictionary | 1946 const char* dictionary = (spdy_version_ < 3) ? kV2Dictionary |
| 1940 : kV3Dictionary; | 1947 : kV3Dictionary; |
| 1941 const int dictionary_size = (spdy_version_ < 3) ? kV2DictionarySize | 1948 const int dictionary_size = (spdy_version_ < 3) ? kV2DictionarySize |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1975 } else { | 1982 } else { |
| 1976 DLOG(WARNING) << "inflate failure: " << rv << " " << len; | 1983 DLOG(WARNING) << "inflate failure: " << rv << " " << len; |
| 1977 set_error(SPDY_DECOMPRESS_FAILURE); | 1984 set_error(SPDY_DECOMPRESS_FAILURE); |
| 1978 processed_successfully = false; | 1985 processed_successfully = false; |
| 1979 } | 1986 } |
| 1980 } | 1987 } |
| 1981 return processed_successfully; | 1988 return processed_successfully; |
| 1982 } | 1989 } |
| 1983 | 1990 |
| 1984 bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData( | 1991 bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData( |
| 1985 const SpdyControlFrame* control_frame, const char* data, size_t len) { | 1992 SpdyStreamId stream_id, const char* data, size_t len) { |
| 1986 bool read_successfully = true; | 1993 bool read_successfully = true; |
| 1987 const SpdyStreamId stream_id = GetControlFrameStreamId(control_frame); | |
| 1988 while (read_successfully && len > 0) { | 1994 while (read_successfully && len > 0) { |
| 1989 size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize); | 1995 size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize); |
| 1990 read_successfully = visitor_->OnControlFrameHeaderData(stream_id, data, | 1996 read_successfully = visitor_->OnControlFrameHeaderData(stream_id, data, |
| 1991 bytes_to_deliver); | 1997 bytes_to_deliver); |
| 1992 data += bytes_to_deliver; | 1998 data += bytes_to_deliver; |
| 1993 len -= bytes_to_deliver; | 1999 len -= bytes_to_deliver; |
| 1994 if (!read_successfully) { | 2000 if (!read_successfully) { |
| 1995 // Assume that the problem was the header block was too large for the | 2001 // Assume that the problem was the header block was too large for the |
| 1996 // visitor. | 2002 // visitor. |
| 1997 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); | 2003 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2016 reinterpret_cast<const SpdyControlFrame&>(frame); | 2022 reinterpret_cast<const SpdyControlFrame&>(frame); |
| 2017 return control_frame.type() == SYN_STREAM || | 2023 return control_frame.type() == SYN_STREAM || |
| 2018 control_frame.type() == SYN_REPLY || | 2024 control_frame.type() == SYN_REPLY || |
| 2019 control_frame.type() == HEADERS; | 2025 control_frame.type() == HEADERS; |
| 2020 } | 2026 } |
| 2021 | 2027 |
| 2022 // We don't compress Data frames. | 2028 // We don't compress Data frames. |
| 2023 return false; | 2029 return false; |
| 2024 } | 2030 } |
| 2025 | 2031 |
| 2026 /* static */ | |
| 2027 SpdyStreamId SpdyFramer::GetControlFrameStreamId( | |
| 2028 const SpdyControlFrame* control_frame) { | |
| 2029 SpdyStreamId stream_id = kInvalidStream; | |
| 2030 if (control_frame != NULL) { | |
| 2031 switch (control_frame->type()) { | |
| 2032 case SYN_STREAM: | |
| 2033 stream_id = reinterpret_cast<const SpdySynStreamControlFrame*>( | |
| 2034 control_frame)->stream_id(); | |
| 2035 break; | |
| 2036 case SYN_REPLY: | |
| 2037 stream_id = reinterpret_cast<const SpdySynReplyControlFrame*>( | |
| 2038 control_frame)->stream_id(); | |
| 2039 break; | |
| 2040 case HEADERS: | |
| 2041 stream_id = reinterpret_cast<const SpdyHeadersControlFrame*>( | |
| 2042 control_frame)->stream_id(); | |
| 2043 break; | |
| 2044 case RST_STREAM: | |
| 2045 stream_id = reinterpret_cast<const SpdyRstStreamControlFrame*>( | |
| 2046 control_frame)->stream_id(); | |
| 2047 break; | |
| 2048 case WINDOW_UPDATE: | |
| 2049 stream_id = reinterpret_cast<const SpdyWindowUpdateControlFrame*>( | |
| 2050 control_frame)->stream_id(); | |
| 2051 break; | |
| 2052 // All of the following types are not part of a particular stream. | |
| 2053 // They all fall through to the invalid control frame type case. | |
| 2054 // (The default case isn't used so that the compile will break if a new | |
| 2055 // control frame type is added but not included here.) | |
| 2056 case SETTINGS: | |
| 2057 case NOOP: | |
| 2058 case PING: | |
| 2059 case GOAWAY: | |
| 2060 case CREDENTIAL: | |
| 2061 case NUM_CONTROL_FRAME_TYPES: // makes compiler happy | |
| 2062 break; | |
| 2063 } | |
| 2064 } | |
| 2065 return stream_id; | |
| 2066 } | |
| 2067 | |
| 2068 void SpdyFramer::SerializeNameValueBlock( | 2032 void SpdyFramer::SerializeNameValueBlock( |
| 2069 SpdyFrameBuilder* builder, | 2033 SpdyFrameBuilder* builder, |
| 2070 const SpdyFrameWithNameValueBlockIR& frame) const { | 2034 const SpdyFrameWithNameValueBlockIR& frame) const { |
| 2071 const SpdyNameValueBlock* name_value_block = &(frame.name_value_block()); | 2035 const SpdyNameValueBlock* name_value_block = &(frame.name_value_block()); |
| 2072 | 2036 |
| 2073 // Serialize number of headers. | 2037 // Serialize number of headers. |
| 2074 if (protocol_version() < 3) { | 2038 if (protocol_version() < 3) { |
| 2075 builder->WriteUInt16(name_value_block->size()); | 2039 builder->WriteUInt16(name_value_block->size()); |
| 2076 } else { | 2040 } else { |
| 2077 builder->WriteUInt32(name_value_block->size()); | 2041 builder->WriteUInt32(name_value_block->size()); |
| 2078 } | 2042 } |
| 2079 | 2043 |
| 2080 // Serialize each header. | 2044 // Serialize each header. |
| 2081 for (SpdyHeaderBlock::const_iterator it = name_value_block->begin(); | 2045 for (SpdyHeaderBlock::const_iterator it = name_value_block->begin(); |
| 2082 it != name_value_block->end(); | 2046 it != name_value_block->end(); |
| 2083 ++it) { | 2047 ++it) { |
| 2084 if (protocol_version() < 3) { | 2048 if (protocol_version() < 3) { |
| 2085 builder->WriteString(it->first); | 2049 builder->WriteString(it->first); |
| 2086 builder->WriteString(it->second); | 2050 builder->WriteString(it->second); |
| 2087 } else { | 2051 } else { |
| 2088 builder->WriteStringPiece32(it->first); | 2052 builder->WriteStringPiece32(it->first); |
| 2089 builder->WriteStringPiece32(it->second); | 2053 builder->WriteStringPiece32(it->second); |
| 2090 } | 2054 } |
| 2091 } | 2055 } |
| 2092 } | 2056 } |
| 2093 | 2057 |
| 2094 } // namespace net | 2058 } // namespace net |
| OLD | NEW |