OLD | NEW |
| (Empty) |
1 // Copyright 2016 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. | |
4 | |
5 #ifndef NET_HTTP2_HTTP2_STRUCTURES_H_ | |
6 #define NET_HTTP2_HTTP2_STRUCTURES_H_ | |
7 | |
8 // Defines structs for various fixed sized structures in HTTP/2. | |
9 // | |
10 // Those structs with multiple fields have constructors that take arguments in | |
11 // the same order as their encoding (which may be different from their order | |
12 // in the struct). For single field structs, use aggregate initialization if | |
13 // desired, e.g.: | |
14 // | |
15 // Http2RstStreamFields var{Http2ErrorCode::ENHANCE_YOUR_CALM}; | |
16 // or: | |
17 // SomeFunc(Http2RstStreamFields{Http2ErrorCode::ENHANCE_YOUR_CALM}); | |
18 // | |
19 // Each struct includes a static method EncodedSize which returns the number | |
20 // of bytes of the encoding. | |
21 // | |
22 // With the exception of Http2FrameHeader, all the types are named | |
23 // Http2<X>Fields, where X is the title-case form of the frame which always | |
24 // includes the fields; the "always" is to cover the case of the PRIORITY frame; | |
25 // its fields optionally appear in the HEADERS frame, but the struct is called | |
26 // Http2PriorityFields. | |
27 | |
28 #include <stddef.h> | |
29 #include <stdint.h> | |
30 | |
31 #include <ostream> | |
32 #include <string> | |
33 | |
34 #include "base/logging.h" | |
35 #include "net/base/net_export.h" | |
36 #include "net/http2/http2_constants.h" | |
37 | |
38 namespace net { | |
39 | |
40 struct NET_EXPORT_PRIVATE Http2FrameHeader { | |
41 Http2FrameHeader() {} | |
42 Http2FrameHeader(uint32_t payload_length, | |
43 Http2FrameType type, | |
44 uint8_t flags, | |
45 uint32_t stream_id) | |
46 : payload_length(payload_length), | |
47 stream_id(stream_id), | |
48 type(type), | |
49 flags(static_cast<Http2FrameFlag>(flags)) { | |
50 DCHECK_LT(payload_length, static_cast<uint32_t>(1 << 24)) | |
51 << "Payload Length is only a 24 bit field\n" | |
52 << ToString(); | |
53 } | |
54 | |
55 static constexpr size_t EncodedSize() { return 9; } | |
56 | |
57 // Keep the current value of those flags that are in | |
58 // valid_flags, and clear all the others. | |
59 void RetainFlags(uint8_t valid_flags) { | |
60 flags = static_cast<Http2FrameFlag>(flags & valid_flags); | |
61 } | |
62 | |
63 // Returns true if any of the flags in flag_mask are set, | |
64 // otherwise false. | |
65 bool HasAnyFlags(uint8_t flag_mask) const { return 0 != (flags & flag_mask); } | |
66 | |
67 // Is the END_STREAM flag set? | |
68 bool IsEndStream() const { | |
69 DCHECK(type == Http2FrameType::DATA || type == Http2FrameType::HEADERS) | |
70 << ToString(); | |
71 return (flags & Http2FrameFlag::FLAG_END_STREAM) != 0; | |
72 } | |
73 | |
74 // Is the ACK flag set? | |
75 bool IsAck() const { | |
76 DCHECK(type == Http2FrameType::SETTINGS || type == Http2FrameType::PING) | |
77 << ToString(); | |
78 return (flags & Http2FrameFlag::FLAG_ACK) != 0; | |
79 } | |
80 | |
81 // Is the END_HEADERS flag set? | |
82 bool IsEndHeaders() const { | |
83 DCHECK(type == Http2FrameType::HEADERS || | |
84 type == Http2FrameType::PUSH_PROMISE || | |
85 type == Http2FrameType::CONTINUATION) | |
86 << ToString(); | |
87 return (flags & Http2FrameFlag::FLAG_END_HEADERS) != 0; | |
88 } | |
89 | |
90 // Is the PADDED flag set? | |
91 bool IsPadded() const { | |
92 DCHECK(type == Http2FrameType::DATA || type == Http2FrameType::HEADERS || | |
93 type == Http2FrameType::PUSH_PROMISE) | |
94 << ToString(); | |
95 return (flags & Http2FrameFlag::FLAG_PADDED) != 0; | |
96 } | |
97 | |
98 // Is the PRIORITY flag set? | |
99 bool HasPriority() const { | |
100 DCHECK_EQ(type, Http2FrameType::HEADERS) << ToString(); | |
101 return (flags & Http2FrameFlag::FLAG_PRIORITY) != 0; | |
102 } | |
103 | |
104 // Does the encoding of this header start with "HTTP/", indicating that it | |
105 // might be from a non-HTTP/2 server. | |
106 bool IsProbableHttpResponse() const; | |
107 | |
108 // Produce strings useful for debugging/logging messages. | |
109 std::string ToString() const; | |
110 std::string FlagsToString() const; | |
111 | |
112 // 24 bit length of the payload after the header, including any padding. | |
113 // First field in encoding. | |
114 uint32_t payload_length; // 24 bits | |
115 | |
116 // 31 bit stream id, with high bit (32nd bit) reserved (must be zero), | |
117 // and is cleared during decoding. | |
118 // Fourth field in encoding. | |
119 uint32_t stream_id; | |
120 | |
121 // Type of the frame. | |
122 // Second field in encoding. | |
123 Http2FrameType type; | |
124 | |
125 // Flag bits, with interpretations that depend upon the frame type. | |
126 // Flag bits not used by the frame type are cleared. | |
127 // Third field in encoding. | |
128 Http2FrameFlag flags; | |
129 }; | |
130 | |
131 NET_EXPORT_PRIVATE bool operator==(const Http2FrameHeader& a, | |
132 const Http2FrameHeader& b); | |
133 NET_EXPORT_PRIVATE inline bool operator!=(const Http2FrameHeader& a, | |
134 const Http2FrameHeader& b) { | |
135 return !(a == b); | |
136 } | |
137 NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out, | |
138 const Http2FrameHeader& v); | |
139 | |
140 // Http2PriorityFields: | |
141 | |
142 struct NET_EXPORT_PRIVATE Http2PriorityFields { | |
143 Http2PriorityFields() {} | |
144 Http2PriorityFields(uint32_t stream_dependency, | |
145 uint32_t weight, | |
146 bool is_exclusive) | |
147 : stream_dependency(stream_dependency), | |
148 weight(weight), | |
149 is_exclusive(is_exclusive) { | |
150 // Can't have the high-bit set in the stream id because we need to use | |
151 // that for the EXCLUSIVE flag bit. | |
152 DCHECK_EQ(stream_dependency, stream_dependency & StreamIdMask()) | |
153 << "Stream Dependency is only a 31-bit field.\n" | |
154 << ToString(); | |
155 DCHECK_LE(1u, weight) << "Weight is too small."; | |
156 DCHECK_LE(weight, 256u) << "Weight is too large."; | |
157 } | |
158 static constexpr size_t EncodedSize() { return 5; } | |
159 | |
160 // Produce strings useful for debugging/logging messages. | |
161 std::string ToString() const; | |
162 | |
163 // A 31-bit stream identifier for the stream that this stream depends on. | |
164 uint32_t stream_dependency; | |
165 | |
166 // Weight (1 to 256) is encoded as a byte in the range 0 to 255, so we | |
167 // add one when decoding, and store it in a field larger than a byte. | |
168 uint32_t weight; | |
169 | |
170 // A single-bit flag indicating that the stream dependency is exclusive; | |
171 // extracted from high bit of stream dependency field during decoding. | |
172 bool is_exclusive; | |
173 }; | |
174 | |
175 NET_EXPORT_PRIVATE bool operator==(const Http2PriorityFields& a, | |
176 const Http2PriorityFields& b); | |
177 NET_EXPORT_PRIVATE inline bool operator!=(const Http2PriorityFields& a, | |
178 const Http2PriorityFields& b) { | |
179 return !(a == b); | |
180 } | |
181 NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out, | |
182 const Http2PriorityFields& v); | |
183 | |
184 // Http2RstStreamFields: | |
185 | |
186 struct Http2RstStreamFields { | |
187 static constexpr size_t EncodedSize() { return 4; } | |
188 bool IsSupportedErrorCode() const { | |
189 return IsSupportedHttp2ErrorCode(error_code); | |
190 } | |
191 | |
192 Http2ErrorCode error_code; | |
193 }; | |
194 | |
195 NET_EXPORT_PRIVATE bool operator==(const Http2RstStreamFields& a, | |
196 const Http2RstStreamFields& b); | |
197 NET_EXPORT_PRIVATE inline bool operator!=(const Http2RstStreamFields& a, | |
198 const Http2RstStreamFields& b) { | |
199 return !(a == b); | |
200 } | |
201 NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out, | |
202 const Http2RstStreamFields& v); | |
203 | |
204 // Http2SettingFields: | |
205 | |
206 struct Http2SettingFields { | |
207 Http2SettingFields() {} | |
208 Http2SettingFields(Http2SettingsParameter parameter, uint32_t value) | |
209 : parameter(parameter), value(value) {} | |
210 static constexpr size_t EncodedSize() { return 6; } | |
211 bool IsSupportedParameter() const { | |
212 return IsSupportedHttp2SettingsParameter(parameter); | |
213 } | |
214 | |
215 Http2SettingsParameter parameter; | |
216 uint32_t value; | |
217 }; | |
218 | |
219 NET_EXPORT_PRIVATE bool operator==(const Http2SettingFields& a, | |
220 const Http2SettingFields& b); | |
221 NET_EXPORT_PRIVATE inline bool operator!=(const Http2SettingFields& a, | |
222 const Http2SettingFields& b) { | |
223 return !(a == b); | |
224 } | |
225 NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out, | |
226 const Http2SettingFields& v); | |
227 | |
228 // Http2PushPromiseFields: | |
229 | |
230 struct Http2PushPromiseFields { | |
231 static constexpr size_t EncodedSize() { return 4; } | |
232 | |
233 uint32_t promised_stream_id; | |
234 }; | |
235 | |
236 NET_EXPORT_PRIVATE bool operator==(const Http2PushPromiseFields& a, | |
237 const Http2PushPromiseFields& b); | |
238 NET_EXPORT_PRIVATE inline bool operator!=(const Http2PushPromiseFields& a, | |
239 const Http2PushPromiseFields& b) { | |
240 return !(a == b); | |
241 } | |
242 NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out, | |
243 const Http2PushPromiseFields& v); | |
244 | |
245 // Http2PingFields: | |
246 | |
247 struct Http2PingFields { | |
248 static constexpr size_t EncodedSize() { return 8; } | |
249 | |
250 // TODO(jamessynge): Rename opaque_data to opaque_bytes. | |
251 uint8_t opaque_data[8]; | |
252 }; | |
253 | |
254 NET_EXPORT_PRIVATE bool operator==(const Http2PingFields& a, | |
255 const Http2PingFields& b); | |
256 NET_EXPORT_PRIVATE inline bool operator!=(const Http2PingFields& a, | |
257 const Http2PingFields& b) { | |
258 return !(a == b); | |
259 } | |
260 NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out, | |
261 const Http2PingFields& v); | |
262 | |
263 // Http2GoAwayFields: | |
264 | |
265 struct Http2GoAwayFields { | |
266 Http2GoAwayFields() {} | |
267 Http2GoAwayFields(uint32_t last_stream_id, Http2ErrorCode error_code) | |
268 : last_stream_id(last_stream_id), error_code(error_code) {} | |
269 static constexpr size_t EncodedSize() { return 8; } | |
270 bool IsSupportedErrorCode() const { | |
271 return IsSupportedHttp2ErrorCode(error_code); | |
272 } | |
273 | |
274 uint32_t last_stream_id; | |
275 Http2ErrorCode error_code; | |
276 }; | |
277 | |
278 NET_EXPORT_PRIVATE bool operator==(const Http2GoAwayFields& a, | |
279 const Http2GoAwayFields& b); | |
280 NET_EXPORT_PRIVATE inline bool operator!=(const Http2GoAwayFields& a, | |
281 const Http2GoAwayFields& b) { | |
282 return !(a == b); | |
283 } | |
284 NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out, | |
285 const Http2GoAwayFields& v); | |
286 | |
287 // Http2WindowUpdateFields: | |
288 | |
289 struct Http2WindowUpdateFields { | |
290 static constexpr size_t EncodedSize() { return 4; } | |
291 | |
292 // 31-bit, unsigned increase in the window size (only positive values are | |
293 // allowed). The high-bit is reserved for the future. | |
294 uint32_t window_size_increment; | |
295 }; | |
296 | |
297 NET_EXPORT_PRIVATE bool operator==(const Http2WindowUpdateFields& a, | |
298 const Http2WindowUpdateFields& b); | |
299 NET_EXPORT_PRIVATE inline bool operator!=(const Http2WindowUpdateFields& a, | |
300 const Http2WindowUpdateFields& b) { | |
301 return !(a == b); | |
302 } | |
303 NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out, | |
304 const Http2WindowUpdateFields& v); | |
305 | |
306 // Http2AltSvcFields: | |
307 | |
308 struct Http2AltSvcFields { | |
309 static constexpr size_t EncodedSize() { return 2; } | |
310 | |
311 // This is the one fixed size portion of the ALTSVC payload. | |
312 uint16_t origin_length; | |
313 }; | |
314 | |
315 NET_EXPORT_PRIVATE bool operator==(const Http2AltSvcFields& a, | |
316 const Http2AltSvcFields& b); | |
317 NET_EXPORT_PRIVATE inline bool operator!=(const Http2AltSvcFields& a, | |
318 const Http2AltSvcFields& b) { | |
319 return !(a == b); | |
320 } | |
321 NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out, | |
322 const Http2AltSvcFields& v); | |
323 | |
324 } // namespace net | |
325 | |
326 #endif // NET_HTTP2_HTTP2_STRUCTURES_H_ | |
OLD | NEW |