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

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

Issue 145353017: Update HPACK implementation to draft 05 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 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/hpack_encoding_context.h ('k') | net/spdy/hpack_encoding_context_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 2014 The Chromium Authors. All rights reserved. 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 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/hpack_encoding_context.h" 5 #include "net/spdy/hpack_encoding_context.h"
6 6
7 #include <cstddef> 7 #include <cstddef>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "net/spdy/hpack_entry.h" 11 #include "net/spdy/hpack_entry.h"
12 12
13 namespace net { 13 namespace net {
14 14
15 using base::StringPiece;
16
15 namespace { 17 namespace {
16 18
17 // An entry in the static table. Must be a POD in order to avoid 19 // An entry in the static table. Must be a POD in order to avoid
18 // static initializers, i.e. no user-defined constructors or 20 // static initializers, i.e. no user-defined constructors or
19 // destructors. 21 // destructors.
20 struct StaticEntry { 22 struct StaticEntry {
21 const char* const name; 23 const char* const name;
22 const size_t name_len; 24 const size_t name_len;
23 const char* const value; 25 const char* const value;
24 const size_t value_len; 26 const size_t value_len;
25 }; 27 };
26 28
27 // The "constructor" for a StaticEntry that computes the lengths at 29 // The "constructor" for a StaticEntry that computes the lengths at
28 // compile time. 30 // compile time.
29 #define STATIC_ENTRY(name, value) \ 31 #define STATIC_ENTRY(name, value) \
30 { name, arraysize(name) - 1, value, arraysize(value) - 1 } 32 { name, arraysize(name) - 1, value, arraysize(value) - 1 }
31 33
32 const StaticEntry kStaticTable[] = { 34 const StaticEntry kStaticTable[] = {
33 STATIC_ENTRY(":authority" , ""), // 0 35 STATIC_ENTRY(":authority" , ""), // 1
34 STATIC_ENTRY(":method" , "GET"), // 1 36 STATIC_ENTRY(":method" , "GET"), // 2
35 STATIC_ENTRY(":method" , "POST"), // 2 37 STATIC_ENTRY(":method" , "POST"), // 3
36 STATIC_ENTRY(":path" , "/"), // 3 38 STATIC_ENTRY(":path" , "/"), // 4
37 STATIC_ENTRY(":path" , "/index.html"), // 4 39 STATIC_ENTRY(":path" , "/index.html"), // 5
38 STATIC_ENTRY(":scheme" , "http"), // 5 40 STATIC_ENTRY(":scheme" , "http"), // 6
39 STATIC_ENTRY(":scheme" , "https"), // 6 41 STATIC_ENTRY(":scheme" , "https"), // 7
40 STATIC_ENTRY(":status" , "200"), // 7 42 STATIC_ENTRY(":status" , "200"), // 8
41 STATIC_ENTRY(":status" , "500"), // 8 43 STATIC_ENTRY(":status" , "500"), // 9
42 STATIC_ENTRY(":status" , "404"), // 9 44 STATIC_ENTRY(":status" , "404"), // 10
43 STATIC_ENTRY(":status" , "403"), // 10 45 STATIC_ENTRY(":status" , "403"), // 11
44 STATIC_ENTRY(":status" , "400"), // 11 46 STATIC_ENTRY(":status" , "400"), // 12
45 STATIC_ENTRY(":status" , "401"), // 12 47 STATIC_ENTRY(":status" , "401"), // 13
46 STATIC_ENTRY("accept-charset" , ""), // 13 48 STATIC_ENTRY("accept-charset" , ""), // 14
47 STATIC_ENTRY("accept-encoding" , ""), // 14 49 STATIC_ENTRY("accept-encoding" , ""), // 15
48 STATIC_ENTRY("accept-language" , ""), // 15 50 STATIC_ENTRY("accept-language" , ""), // 16
49 STATIC_ENTRY("accept-ranges" , ""), // 16 51 STATIC_ENTRY("accept-ranges" , ""), // 17
50 STATIC_ENTRY("accept" , ""), // 17 52 STATIC_ENTRY("accept" , ""), // 18
51 STATIC_ENTRY("access-control-allow-origin" , ""), // 18 53 STATIC_ENTRY("access-control-allow-origin" , ""), // 19
52 STATIC_ENTRY("age" , ""), // 19 54 STATIC_ENTRY("age" , ""), // 20
53 STATIC_ENTRY("allow" , ""), // 20 55 STATIC_ENTRY("allow" , ""), // 21
54 STATIC_ENTRY("authorization" , ""), // 21 56 STATIC_ENTRY("authorization" , ""), // 22
55 STATIC_ENTRY("cache-control" , ""), // 22 57 STATIC_ENTRY("cache-control" , ""), // 23
56 STATIC_ENTRY("content-disposition" , ""), // 23 58 STATIC_ENTRY("content-disposition" , ""), // 24
57 STATIC_ENTRY("content-encoding" , ""), // 24 59 STATIC_ENTRY("content-encoding" , ""), // 25
58 STATIC_ENTRY("content-language" , ""), // 25 60 STATIC_ENTRY("content-language" , ""), // 26
59 STATIC_ENTRY("content-length" , ""), // 26 61 STATIC_ENTRY("content-length" , ""), // 27
60 STATIC_ENTRY("content-location" , ""), // 27 62 STATIC_ENTRY("content-location" , ""), // 28
61 STATIC_ENTRY("content-range" , ""), // 28 63 STATIC_ENTRY("content-range" , ""), // 29
62 STATIC_ENTRY("content-type" , ""), // 29 64 STATIC_ENTRY("content-type" , ""), // 30
63 STATIC_ENTRY("cookie" , ""), // 30 65 STATIC_ENTRY("cookie" , ""), // 31
64 STATIC_ENTRY("date" , ""), // 31 66 STATIC_ENTRY("date" , ""), // 32
65 STATIC_ENTRY("etag" , ""), // 32 67 STATIC_ENTRY("etag" , ""), // 33
66 STATIC_ENTRY("expect" , ""), // 33 68 STATIC_ENTRY("expect" , ""), // 34
67 STATIC_ENTRY("expires" , ""), // 34 69 STATIC_ENTRY("expires" , ""), // 35
68 STATIC_ENTRY("from" , ""), // 35 70 STATIC_ENTRY("from" , ""), // 36
69 STATIC_ENTRY("if-match" , ""), // 36 71 STATIC_ENTRY("host" , ""), // 37
70 STATIC_ENTRY("if-modified-since" , ""), // 37 72 STATIC_ENTRY("if-match" , ""), // 38
71 STATIC_ENTRY("if-none-match" , ""), // 38 73 STATIC_ENTRY("if-modified-since" , ""), // 39
72 STATIC_ENTRY("if-range" , ""), // 39 74 STATIC_ENTRY("if-none-match" , ""), // 40
73 STATIC_ENTRY("if-unmodified-since" , ""), // 40 75 STATIC_ENTRY("if-range" , ""), // 41
74 STATIC_ENTRY("last-modified" , ""), // 41 76 STATIC_ENTRY("if-unmodified-since" , ""), // 42
75 STATIC_ENTRY("link" , ""), // 42 77 STATIC_ENTRY("last-modified" , ""), // 43
76 STATIC_ENTRY("location" , ""), // 43 78 STATIC_ENTRY("link" , ""), // 44
77 STATIC_ENTRY("max-forwards" , ""), // 44 79 STATIC_ENTRY("location" , ""), // 45
78 STATIC_ENTRY("proxy-authenticate" , ""), // 45 80 STATIC_ENTRY("max-forwards" , ""), // 46
79 STATIC_ENTRY("proxy-authorization" , ""), // 46 81 STATIC_ENTRY("proxy-authenticate" , ""), // 47
80 STATIC_ENTRY("range" , ""), // 47 82 STATIC_ENTRY("proxy-authorization" , ""), // 48
81 STATIC_ENTRY("referer" , ""), // 48 83 STATIC_ENTRY("range" , ""), // 49
82 STATIC_ENTRY("refresh" , ""), // 49 84 STATIC_ENTRY("referer" , ""), // 50
83 STATIC_ENTRY("retry-after" , ""), // 50 85 STATIC_ENTRY("refresh" , ""), // 51
84 STATIC_ENTRY("server" , ""), // 51 86 STATIC_ENTRY("retry-after" , ""), // 52
85 STATIC_ENTRY("set-cookie" , ""), // 52 87 STATIC_ENTRY("server" , ""), // 53
86 STATIC_ENTRY("strict-transport-security" , ""), // 53 88 STATIC_ENTRY("set-cookie" , ""), // 54
87 STATIC_ENTRY("transfer-encoding" , ""), // 54 89 STATIC_ENTRY("strict-transport-security" , ""), // 55
88 STATIC_ENTRY("user-agent" , ""), // 55 90 STATIC_ENTRY("transfer-encoding" , ""), // 56
89 STATIC_ENTRY("vary" , ""), // 56 91 STATIC_ENTRY("user-agent" , ""), // 57
90 STATIC_ENTRY("via" , ""), // 57 92 STATIC_ENTRY("vary" , ""), // 58
91 STATIC_ENTRY("www-authenticate" , ""), // 58 93 STATIC_ENTRY("via" , ""), // 59
94 STATIC_ENTRY("www-authenticate" , ""), // 60
92 }; 95 };
93 96
94 #undef STATIC_ENTRY 97 #undef STATIC_ENTRY
95 98
96 const size_t kStaticEntryCount = arraysize(kStaticTable); 99 const size_t kStaticEntryCount = arraysize(kStaticTable);
97 100
98 } // namespace 101 } // namespace
99 102
100 const uint32 HpackEncodingContext::kUntouched = HpackEntry::kUntouched; 103 const uint32 HpackEncodingContext::kUntouched = HpackEntry::kUntouched;
101 104
102 HpackEncodingContext::HpackEncodingContext() {} 105 HpackEncodingContext::HpackEncodingContext() {}
103 106
104 HpackEncodingContext::~HpackEncodingContext() {} 107 HpackEncodingContext::~HpackEncodingContext() {}
105 108
106 uint32 HpackEncodingContext::GetEntryCount() const { 109 uint32 HpackEncodingContext::GetMutableEntryCount() const {
107 return header_table_.GetEntryCount() + kStaticEntryCount; 110 return header_table_.GetEntryCount();
108 } 111 }
109 112
110 base::StringPiece HpackEncodingContext::GetNameAt(uint32 index) const { 113 uint32 HpackEncodingContext::GetEntryCount() const {
111 CHECK_LT(index, GetEntryCount()); 114 return GetMutableEntryCount() + kStaticEntryCount;
112 if (index >= header_table_.GetEntryCount()) { 115 }
116
117 StringPiece HpackEncodingContext::GetNameAt(uint32 index) const {
118 CHECK_GE(index, 1u);
119 CHECK_LE(index, GetEntryCount());
120 if (index > header_table_.GetEntryCount()) {
113 const StaticEntry& entry = 121 const StaticEntry& entry =
114 kStaticTable[index - header_table_.GetEntryCount()]; 122 kStaticTable[index - header_table_.GetEntryCount() - 1];
115 return base::StringPiece(entry.name, entry.name_len); 123 return StringPiece(entry.name, entry.name_len);
116 } 124 }
117 return header_table_.GetEntry(index).name(); 125 return header_table_.GetEntry(index).name();
118 } 126 }
119 127
120 base::StringPiece HpackEncodingContext::GetValueAt(uint32 index) const { 128 StringPiece HpackEncodingContext::GetValueAt(uint32 index) const {
121 CHECK_LT(index, GetEntryCount()); 129 CHECK_GE(index, 1u);
122 if (index >= header_table_.GetEntryCount()) { 130 CHECK_LE(index, GetEntryCount());
131 if (index > header_table_.GetEntryCount()) {
123 const StaticEntry& entry = 132 const StaticEntry& entry =
124 kStaticTable[index - header_table_.GetEntryCount()]; 133 kStaticTable[index - header_table_.GetEntryCount() - 1];
125 return base::StringPiece(entry.value, entry.value_len); 134 return StringPiece(entry.value, entry.value_len);
126 } 135 }
127 return header_table_.GetEntry(index).value(); 136 return header_table_.GetEntry(index).value();
128 } 137 }
129 138
130 bool HpackEncodingContext::IsReferencedAt(uint32 index) const { 139 bool HpackEncodingContext::IsReferencedAt(uint32 index) const {
131 CHECK_LT(index, GetEntryCount()); 140 CHECK_GE(index, 1u);
132 if (index >= header_table_.GetEntryCount()) 141 CHECK_LE(index, GetEntryCount());
142 if (index > header_table_.GetEntryCount())
133 return false; 143 return false;
134 return header_table_.GetEntry(index).IsReferenced(); 144 return header_table_.GetEntry(index).IsReferenced();
135 } 145 }
136 146
137 uint32 HpackEncodingContext::GetTouchCountAt(uint32 index) const { 147 uint32 HpackEncodingContext::GetTouchCountAt(uint32 index) const {
138 CHECK_LT(index, GetEntryCount()); 148 CHECK_GE(index, 1u);
139 if (index >= header_table_.GetEntryCount()) 149 CHECK_LE(index, GetEntryCount());
150 if (index > header_table_.GetEntryCount())
140 return 0; 151 return 0;
141 return header_table_.GetEntry(index).TouchCount(); 152 return header_table_.GetEntry(index).TouchCount();
142 } 153 }
143 154
144 void HpackEncodingContext::SetReferencedAt(uint32 index, bool referenced) { 155 void HpackEncodingContext::SetReferencedAt(uint32 index, bool referenced) {
145 header_table_.GetMutableEntry(index)->SetReferenced(referenced); 156 header_table_.GetMutableEntry(index)->SetReferenced(referenced);
146 } 157 }
147 158
148 void HpackEncodingContext::AddTouchesAt(uint32 index, uint32 touch_count) { 159 void HpackEncodingContext::AddTouchesAt(uint32 index, uint32 touch_count) {
149 header_table_.GetMutableEntry(index)->AddTouches(touch_count); 160 header_table_.GetMutableEntry(index)->AddTouches(touch_count);
150 } 161 }
151 162
152 void HpackEncodingContext::ClearTouchesAt(uint32 index) { 163 void HpackEncodingContext::ClearTouchesAt(uint32 index) {
153 header_table_.GetMutableEntry(index)->ClearTouches(); 164 header_table_.GetMutableEntry(index)->ClearTouches();
154 } 165 }
155 166
156 void HpackEncodingContext::SetMaxSize(uint32 max_size) { 167 void HpackEncodingContext::SetMaxSize(uint32 max_size) {
157 header_table_.SetMaxSize(max_size); 168 header_table_.SetMaxSize(max_size);
158 } 169 }
159 170
160 bool HpackEncodingContext::ProcessIndexedHeader( 171 bool HpackEncodingContext::ProcessIndexedHeader(
161 uint32 index, 172 uint32 index,
162 int32* new_index, 173 uint32* new_index,
163 std::vector<uint32>* removed_referenced_indices) { 174 std::vector<uint32>* removed_referenced_indices) {
164 if (index >= GetEntryCount()) 175 if (index < 1 || index > GetEntryCount())
165 return false; 176 return false;
166 177
167 if (index < header_table_.GetEntryCount()) { 178 if (index <= header_table_.GetEntryCount()) {
168 *new_index = index; 179 *new_index = index;
169 removed_referenced_indices->clear(); 180 removed_referenced_indices->clear();
170 HpackEntry* entry = header_table_.GetMutableEntry(index); 181 HpackEntry* entry = header_table_.GetMutableEntry(index);
171 entry->SetReferenced(!entry->IsReferenced()); 182 entry->SetReferenced(!entry->IsReferenced());
172 } else { 183 } else {
173 // TODO(akalin): Make HpackEntry know about owned strings and 184 // TODO(akalin): Make HpackEntry know about owned strings and
174 // non-owned strings so that it can potentially avoid copies here. 185 // non-owned strings so that it can potentially avoid copies here.
175 HpackEntry entry(GetNameAt(index), GetValueAt(index)); 186 HpackEntry entry(GetNameAt(index), GetValueAt(index));
176 187
177 header_table_.TryAddEntry(entry, new_index, removed_referenced_indices); 188 header_table_.TryAddEntry(entry, new_index, removed_referenced_indices);
178 if (*new_index >= 0) { 189 if (*new_index >= 1) {
179 header_table_.GetMutableEntry(*new_index)->SetReferenced(true); 190 header_table_.GetMutableEntry(*new_index)->SetReferenced(true);
180 } 191 }
181 } 192 }
182 return true; 193 return true;
183 } 194 }
184 195
185 bool HpackEncodingContext::ProcessLiteralHeaderWithIncrementalIndexing( 196 bool HpackEncodingContext::ProcessLiteralHeaderWithIncrementalIndexing(
186 base::StringPiece name, 197 StringPiece name,
187 base::StringPiece value, 198 StringPiece value,
188 int32* index, 199 uint32* index,
189 std::vector<uint32>* removed_referenced_indices) { 200 std::vector<uint32>* removed_referenced_indices) {
190 HpackEntry entry(name, value); 201 HpackEntry entry(name, value);
191 header_table_.TryAddEntry(entry, index, removed_referenced_indices); 202 header_table_.TryAddEntry(entry, index, removed_referenced_indices);
192 if (*index >= 0) { 203 if (*index >= 1) {
193 header_table_.GetMutableEntry(*index)->SetReferenced(true); 204 header_table_.GetMutableEntry(*index)->SetReferenced(true);
194 } 205 }
195 return true; 206 return true;
196 } 207 }
197 208
198 } // namespace net 209 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/hpack_encoding_context.h ('k') | net/spdy/hpack_encoding_context_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698