1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/spdy/spdy_headers_block_parser.h"
9 #include "base/sys_byteorder.h"
13 SpdyHeadersBlockParserReader::SpdyHeadersBlockParserReader(
14 base::StringPiece prefix
,
15 base::StringPiece suffix
)
21 size_t SpdyHeadersBlockParserReader::Available() {
23 return suffix_
.length() - offset_
;
25 return prefix_
.length() + suffix_
.length() - offset_
;
29 bool SpdyHeadersBlockParserReader::ReadN(size_t count
, char* out
) {
30 if (Available() < count
)
33 if (!in_suffix_
&& count
> (prefix_
.length() - offset_
)) {
34 count
-= prefix_
.length() - offset_
;
35 out
= std::copy(prefix_
.begin() + offset_
, prefix_
.end(), out
);
38 // Fallthrough to suffix read.
39 } else if (!in_suffix_
) {
40 // Read is satisfied by the prefix.
41 DCHECK_GE(prefix_
.length() - offset_
, count
);
42 std::copy(prefix_
.begin() + offset_
,
43 prefix_
.begin() + offset_
+ count
,
48 // Read is satisfied by the suffix.
50 DCHECK_GE(suffix_
.length() - offset_
, count
);
51 std::copy(suffix_
.begin() + offset_
,
52 suffix_
.begin() + offset_
+ count
,
58 std::vector
<char> SpdyHeadersBlockParserReader::Remainder() {
59 std::vector
<char> remainder(Available(), '\0');
60 if (remainder
.size()) {
61 ReadN(remainder
.size(), &remainder
[0]);
63 DCHECK_EQ(0u, Available());
67 SpdyHeadersBlockParser::SpdyHeadersBlockParser(
68 SpdyHeadersHandlerInterface
* handler
) : state_(READING_HEADER_BLOCK_LEN
),
69 remaining_key_value_pairs_for_frame_(0), next_field_len_(0),
73 SpdyHeadersBlockParser::~SpdyHeadersBlockParser() {}
75 bool SpdyHeadersBlockParser::ParseUInt32(Reader
* reader
,
76 uint32_t* parsed_value
) {
77 // Are there enough bytes available?
78 if (reader
->Available() < sizeof(uint32_t)) {
82 // Read the required bytes, convert from network to host
83 // order and return the parsed out integer.
84 char buf
[sizeof(uint32_t)];
85 reader
->ReadN(sizeof(uint32_t), buf
);
86 *parsed_value
= base::NetToHost32(*reinterpret_cast<const uint32_t *>(buf
));
90 void SpdyHeadersBlockParser::Reset() {
91 // Clear any saved state about the last headers block.
92 headers_block_prefix_
.clear();
93 state_
= READING_HEADER_BLOCK_LEN
;
96 void SpdyHeadersBlockParser::HandleControlFrameHeadersData(
97 const char* headers_data
, size_t len
) {
98 // Only do something if we received anything new.
103 // Reader avoids copying data.
104 base::StringPiece prefix
;
105 if (headers_block_prefix_
.size()) {
106 prefix
.set(&headers_block_prefix_
[0], headers_block_prefix_
.size());
108 Reader
reader(prefix
, base::StringPiece(headers_data
, len
));
110 // If we didn't parse out yet the number of key-value pairs in this
111 // headers block, try to do it now (succeeds if we received enough bytes).
112 if (state_
== READING_HEADER_BLOCK_LEN
) {
113 if (ParseUInt32(&reader
, &remaining_key_value_pairs_for_frame_
)) {
114 handler_
->OnHeaderBlock(remaining_key_value_pairs_for_frame_
);
115 state_
= READING_KEY_LEN
;
117 headers_block_prefix_
= reader
.Remainder();
122 // Parse out and handle the key-value pairs.
123 while (remaining_key_value_pairs_for_frame_
> 0) {
124 // Parse the key-value length, in case we don't already have it.
125 if ((state_
== READING_KEY_LEN
) || (state_
== READING_VALUE_LEN
)) {
126 if (ParseUInt32(&reader
, &next_field_len_
)) {
127 state_
== READING_KEY_LEN
? state_
= READING_KEY
:
128 state_
= READING_VALUE
;
130 // Did not receive enough bytes.
135 // Parse the next field if we received enough bytes.
136 if (reader
.Available() >= next_field_len_
) {
137 // Copy the field from the cord.
138 char* key_value_buf(new char[next_field_len_
]);
139 reader
.ReadN(next_field_len_
, key_value_buf
);
141 // Is this field a key?
142 if (state_
== READING_KEY
) {
143 current_key
.reset(key_value_buf
);
144 key_len_
= next_field_len_
;
145 state_
= READING_VALUE_LEN
;
147 } else if (state_
== READING_VALUE
) {
148 // We already had the key, now we got its value.
149 current_value
.reset(key_value_buf
);
151 // Call the handler for the key-value pair that we received.
152 handler_
->OnKeyValuePair(
153 base::StringPiece(current_key
.get(), key_len_
),
154 base::StringPiece(current_value
.get(), next_field_len_
));
156 // Free allocated key and value strings.
158 current_value
.reset();
160 // Finished handling a key-value pair.
161 remaining_key_value_pairs_for_frame_
--;
163 // Finished handling a header, prepare for the next one.
164 state_
= READING_KEY_LEN
;
167 // Did not receive enough bytes.
172 // Unread suffix becomes the prefix upon next invocation.
173 headers_block_prefix_
= reader
.Remainder();
175 // Did we finish handling the current block?
176 if (remaining_key_value_pairs_for_frame_
== 0) {
177 handler_
->OnHeaderBlockEnd();