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

Side by Side Diff: net/spdy/spdy_protocol.h

Issue 2832973003: Split net/spdy into core and chromium subdirectories. (Closed)
Patch Set: Fix some more build rules. Created 3 years, 8 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
« no previous file with comments | « net/spdy/spdy_prefixed_buffer_reader_test.cc ('k') | net/spdy/spdy_protocol.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 // This file contains some protocol structures for use with SPDY 3 and HTTP 2
6 // The SPDY 3 spec can be found at:
7 // http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3
8
9 #ifndef NET_SPDY_SPDY_PROTOCOL_H_
10 #define NET_SPDY_SPDY_PROTOCOL_H_
11
12 #include <stddef.h>
13 #include <stdint.h>
14
15 #include <iosfwd>
16 #include <limits>
17 #include <map>
18 #include <memory>
19 #include <utility>
20
21 #include "base/compiler_specific.h"
22 #include "base/logging.h"
23 #include "base/macros.h"
24 #include "base/sys_byteorder.h"
25 #include "net/base/net_export.h"
26 #include "net/spdy/platform/api/spdy_string.h"
27 #include "net/spdy/platform/api/spdy_string_piece.h"
28 #include "net/spdy/spdy_alt_svc_wire_format.h"
29 #include "net/spdy/spdy_bitmasks.h"
30 #include "net/spdy/spdy_bug_tracker.h"
31 #include "net/spdy/spdy_header_block.h"
32
33 namespace net {
34
35 // A stream id is a 31 bit entity.
36 typedef uint32_t SpdyStreamId;
37
38 // Specifies the stream ID used to denote the current session (for
39 // flow control).
40 const SpdyStreamId kSessionFlowControlStreamId = 0;
41
42 // Max stream id.
43 const SpdyStreamId kMaxStreamId = 0x7fffffff;
44
45 // The maximum possible frame payload size allowed by the spec.
46 const uint32_t kSpdyMaxFrameSizeLimit = (1 << 24) - 1;
47
48 // The initial value for the maximum frame payload size as per the spec. This is
49 // the maximum control frame size we accept.
50 const uint32_t kSpdyInitialFrameSizeLimit = 1 << 14;
51
52 // The initial value for the maximum size of the header list, "unlimited" (max
53 // unsigned 32-bit int) as per the spec.
54 const uint32_t kSpdyInitialHeaderListSizeLimit = 0xFFFFFFFF;
55
56 // Maximum window size for a Spdy stream or session.
57 const int32_t kSpdyMaximumWindowSize = 0x7FFFFFFF; // Max signed 32bit int
58
59 // Maximum padding size in octets for one DATA or HEADERS or PUSH_PROMISE frame.
60 const int32_t kPaddingSizePerFrame = 256;
61
62 // The HTTP/2 connection preface, which must be the first bytes sent by the
63 // client upon starting an HTTP/2 connection, and which must be followed by a
64 // SETTINGS frame. Note that even though |kHttp2ConnectionHeaderPrefix| is
65 // defined as a string literal with a null terminator, the actual connection
66 // preface is only the first |kHttp2ConnectionHeaderPrefixSize| bytes, which
67 // excludes the null terminator.
68 NET_EXPORT_PRIVATE extern const char* const kHttp2ConnectionHeaderPrefix;
69 const int kHttp2ConnectionHeaderPrefixSize = 24;
70
71 // Wire values for HTTP2 frame types.
72 enum class SpdyFrameType : uint8_t {
73 DATA = 0x00,
74 HEADERS = 0x01,
75 PRIORITY = 0x02,
76 RST_STREAM = 0x03,
77 SETTINGS = 0x04,
78 PUSH_PROMISE = 0x05,
79 PING = 0x06,
80 GOAWAY = 0x07,
81 WINDOW_UPDATE = 0x08,
82 CONTINUATION = 0x09,
83 // ALTSVC is a public extension.
84 ALTSVC = 0x0a,
85 MAX_FRAME_TYPE = ALTSVC,
86 // The specific value of EXTENSION is meaningless; it is a placeholder used
87 // within SpdyFramer's state machine when handling unknown frames via an
88 // extension API.
89 EXTENSION = 0xff
90 };
91
92 // Flags on data packets.
93 enum SpdyDataFlags {
94 DATA_FLAG_NONE = 0x00,
95 DATA_FLAG_FIN = 0x01,
96 DATA_FLAG_PADDED = 0x08,
97 };
98
99 // Flags on control packets
100 enum SpdyControlFlags {
101 CONTROL_FLAG_NONE = 0x00,
102 CONTROL_FLAG_FIN = 0x01,
103 CONTROL_FLAG_UNIDIRECTIONAL = 0x02,
104 };
105
106 enum SpdyPingFlags {
107 PING_FLAG_ACK = 0x01,
108 };
109
110 // Used by HEADERS, PUSH_PROMISE, and CONTINUATION.
111 enum SpdyHeadersFlags {
112 HEADERS_FLAG_END_HEADERS = 0x04,
113 HEADERS_FLAG_PADDED = 0x08,
114 HEADERS_FLAG_PRIORITY = 0x20,
115 };
116
117 enum SpdyPushPromiseFlags {
118 PUSH_PROMISE_FLAG_END_PUSH_PROMISE = 0x04,
119 PUSH_PROMISE_FLAG_PADDED = 0x08,
120 };
121
122 // Flags on the SETTINGS control frame.
123 enum SpdySettingsControlFlags {
124 SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS = 0x01,
125 };
126
127 enum Http2SettingsControlFlags {
128 SETTINGS_FLAG_ACK = 0x01,
129 };
130
131 // Wire values of HTTP/2 setting identifiers.
132 enum SpdySettingsIds : uint16_t {
133 // HPACK header table maximum size.
134 SETTINGS_HEADER_TABLE_SIZE = 0x1,
135 SETTINGS_MIN = SETTINGS_HEADER_TABLE_SIZE,
136 // Whether or not server push (PUSH_PROMISE) is enabled.
137 SETTINGS_ENABLE_PUSH = 0x2,
138 // The maximum number of simultaneous live streams in each direction.
139 SETTINGS_MAX_CONCURRENT_STREAMS = 0x3,
140 // Initial window size in bytes
141 SETTINGS_INITIAL_WINDOW_SIZE = 0x4,
142 // The size of the largest frame payload that a receiver is willing to accept.
143 SETTINGS_MAX_FRAME_SIZE = 0x5,
144 // The maximum size of header list that the sender is prepared to accept.
145 SETTINGS_MAX_HEADER_LIST_SIZE = 0x6,
146 SETTINGS_MAX = SETTINGS_MAX_HEADER_LIST_SIZE
147 };
148
149 // This explicit operator is needed, otherwise compiler finds
150 // overloaded operator to be ambiguous.
151 NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
152 SpdySettingsIds id);
153
154 // This operator is needed, because SpdyFrameType is an enum class,
155 // therefore implicit conversion to underlying integer type is not allowed.
156 NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
157 SpdyFrameType frame_type);
158
159 using SettingsMap = std::map<SpdySettingsIds, uint32_t>;
160
161 // HTTP/2 error codes, RFC 7540 Section 7.
162 enum SpdyErrorCode : uint32_t {
163 ERROR_CODE_NO_ERROR = 0x0,
164 ERROR_CODE_PROTOCOL_ERROR = 0x1,
165 ERROR_CODE_INTERNAL_ERROR = 0x2,
166 ERROR_CODE_FLOW_CONTROL_ERROR = 0x3,
167 ERROR_CODE_SETTINGS_TIMEOUT = 0x4,
168 ERROR_CODE_STREAM_CLOSED = 0x5,
169 ERROR_CODE_FRAME_SIZE_ERROR = 0x6,
170 ERROR_CODE_REFUSED_STREAM = 0x7,
171 ERROR_CODE_CANCEL = 0x8,
172 ERROR_CODE_COMPRESSION_ERROR = 0x9,
173 ERROR_CODE_CONNECT_ERROR = 0xa,
174 ERROR_CODE_ENHANCE_YOUR_CALM = 0xb,
175 ERROR_CODE_INADEQUATE_SECURITY = 0xc,
176 ERROR_CODE_HTTP_1_1_REQUIRED = 0xd,
177 ERROR_CODE_MAX = ERROR_CODE_HTTP_1_1_REQUIRED
178 };
179
180 // A SPDY priority is a number between 0 and 7 (inclusive).
181 typedef uint8_t SpdyPriority;
182
183 // Lowest and Highest here refer to SPDY priorities as described in
184
185 // https://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1#TOC-2.3.3- Stream-priority
186 const SpdyPriority kV3HighestPriority = 0;
187 const SpdyPriority kV3LowestPriority = 7;
188
189 // Returns SPDY 3.x priority value clamped to the valid range of [0, 7].
190 NET_EXPORT_PRIVATE SpdyPriority ClampSpdy3Priority(SpdyPriority priority);
191
192 // HTTP/2 stream weights are integers in range [1, 256], as specified in RFC
193 // 7540 section 5.3.2. Default stream weight is defined in section 5.3.5.
194 const int kHttp2MinStreamWeight = 1;
195 const int kHttp2MaxStreamWeight = 256;
196 const int kHttp2DefaultStreamWeight = 16;
197
198 // Returns HTTP/2 weight clamped to the valid range of [1, 256].
199 NET_EXPORT_PRIVATE int ClampHttp2Weight(int weight);
200
201 // Maps SPDY 3.x priority value in range [0, 7] to HTTP/2 weight value in range
202 // [1, 256], where priority 0 (i.e. highest precedence) corresponds to maximum
203 // weight 256 and priority 7 (lowest precedence) corresponds to minimum weight
204 // 1.
205 NET_EXPORT_PRIVATE int Spdy3PriorityToHttp2Weight(SpdyPriority priority);
206
207 // Maps HTTP/2 weight value in range [1, 256] to SPDY 3.x priority value in
208 // range [0, 7], where minimum weight 1 corresponds to priority 7 (lowest
209 // precedence) and maximum weight 256 corresponds to priority 0 (highest
210 // precedence).
211 NET_EXPORT_PRIVATE SpdyPriority Http2WeightToSpdy3Priority(int weight);
212
213 // Reserved ID for root stream of HTTP/2 stream dependency tree, as specified
214 // in RFC 7540 section 5.3.1.
215 const unsigned int kHttp2RootStreamId = 0;
216
217 typedef uint64_t SpdyPingId;
218
219 // Returns true if a given on-the-wire enumeration of a frame type is defined
220 // in a standardized HTTP/2 specification, false otherwise.
221 NET_EXPORT_PRIVATE bool IsDefinedFrameType(uint8_t frame_type_field);
222
223 // Parses a frame type from an on-the-wire enumeration.
224 // Behavior is undefined for invalid frame type fields; consumers should first
225 // use IsValidFrameType() to verify validity of frame type fields.
226 NET_EXPORT_PRIVATE SpdyFrameType ParseFrameType(uint8_t frame_type_field);
227
228 // Serializes a frame type to the on-the-wire value.
229 NET_EXPORT_PRIVATE uint8_t SerializeFrameType(SpdyFrameType frame_type);
230
231 // (HTTP/2) All standard frame types except WINDOW_UPDATE are
232 // (stream-specific xor connection-level). Returns false iff we know
233 // the given frame type does not align with the given streamID.
234 NET_EXPORT_PRIVATE bool IsValidHTTP2FrameStreamId(
235 SpdyStreamId current_frame_stream_id,
236 SpdyFrameType frame_type_field);
237
238 // Serialize |frame_type| to string for logging/debugging.
239 const char* FrameTypeToString(SpdyFrameType frame_type);
240
241 // If |wire_setting_id| is the on-the-wire representation of a defined SETTINGS
242 // parameter, parse it to |*setting_id| and return true.
243 NET_EXPORT_PRIVATE bool ParseSettingsId(uint16_t wire_setting_id,
244 SpdySettingsIds* setting_id);
245
246 // Return if |id| corresponds to a defined setting;
247 // stringify |id| to |*settings_id_string| regardless.
248 NET_EXPORT_PRIVATE bool SettingsIdToString(SpdySettingsIds id,
249 const char** settings_id_string);
250
251 // Parse |wire_error_code| to a SpdyErrorCode.
252 // Treat unrecognized error codes as INTERNAL_ERROR
253 // as recommended by the HTTP/2 specification.
254 NET_EXPORT_PRIVATE SpdyErrorCode ParseErrorCode(uint32_t wire_error_code);
255
256 // Serialize RST_STREAM or GOAWAY frame error code to string
257 // for logging/debugging.
258 const char* ErrorCodeToString(SpdyErrorCode error_code);
259
260 // Number of octets in the frame header.
261 const size_t kFrameHeaderSize = 9;
262 // Size, in bytes, of the data frame header.
263 const size_t kDataFrameMinimumSize = kFrameHeaderSize;
264 // Maximum possible configurable size of a frame in octets.
265 const size_t kMaxFrameSizeLimit = kSpdyMaxFrameSizeLimit + kFrameHeaderSize;
266 // Size of a header block size field. Valid only for SPDY 3.
267 const size_t kSizeOfSizeField = sizeof(uint32_t);
268 // Per-header overhead for block size accounting in bytes.
269 const size_t kPerHeaderOverhead = 32;
270 // Initial window size for a stream in bytes.
271 const int32_t kInitialStreamWindowSize = 64 * 1024 - 1;
272 // Initial window size for a session in bytes.
273 const int32_t kInitialSessionWindowSize = 64 * 1024 - 1;
274 // The NPN string for HTTP2, "h2".
275 extern const char* const kHttp2Npn;
276
277 // Variant type (i.e. tagged union) that is either a SPDY 3.x priority value,
278 // or else an HTTP/2 stream dependency tuple {parent stream ID, weight,
279 // exclusive bit}. Templated to allow for use by QUIC code; SPDY and HTTP/2
280 // code should use the concrete type instantiation SpdyStreamPrecedence.
281 template <typename StreamIdType>
282 class StreamPrecedence {
283 public:
284 // Constructs instance that is a SPDY 3.x priority. Clamps priority value to
285 // the valid range [0, 7].
286 explicit StreamPrecedence(SpdyPriority priority)
287 : is_spdy3_priority_(true),
288 spdy3_priority_(ClampSpdy3Priority(priority)) {}
289
290 // Constructs instance that is an HTTP/2 stream weight, parent stream ID, and
291 // exclusive bit. Clamps stream weight to the valid range [1, 256].
292 StreamPrecedence(StreamIdType parent_id, int weight, bool is_exclusive)
293 : is_spdy3_priority_(false),
294 http2_stream_dependency_{parent_id, ClampHttp2Weight(weight),
295 is_exclusive} {}
296
297 // Intentionally copyable, to support pass by value.
298 StreamPrecedence(const StreamPrecedence& other) = default;
299 StreamPrecedence& operator=(const StreamPrecedence& other) = default;
300
301 // Returns true if this instance is a SPDY 3.x priority, or false if this
302 // instance is an HTTP/2 stream dependency.
303 bool is_spdy3_priority() const { return is_spdy3_priority_; }
304
305 // Returns SPDY 3.x priority value. If |is_spdy3_priority()| is true, this is
306 // the value provided at construction, clamped to the legal priority
307 // range. Otherwise, it is the HTTP/2 stream weight mapped to a SPDY 3.x
308 // priority value, where minimum weight 1 corresponds to priority 7 (lowest
309 // precedence) and maximum weight 256 corresponds to priority 0 (highest
310 // precedence).
311 SpdyPriority spdy3_priority() const {
312 return is_spdy3_priority_
313 ? spdy3_priority_
314 : Http2WeightToSpdy3Priority(http2_stream_dependency_.weight);
315 }
316
317 // Returns HTTP/2 parent stream ID. If |is_spdy3_priority()| is false, this is
318 // the value provided at construction, otherwise it is |kHttp2RootStreamId|.
319 StreamIdType parent_id() const {
320 return is_spdy3_priority_ ? kHttp2RootStreamId
321 : http2_stream_dependency_.parent_id;
322 }
323
324 // Returns HTTP/2 stream weight. If |is_spdy3_priority()| is false, this is
325 // the value provided at construction, clamped to the legal weight
326 // range. Otherwise, it is the SPDY 3.x priority value mapped to an HTTP/2
327 // stream weight, where priority 0 (i.e. highest precedence) corresponds to
328 // maximum weight 256 and priority 7 (lowest precedence) corresponds to
329 // minimum weight 1.
330 int weight() const {
331 return is_spdy3_priority_ ? Spdy3PriorityToHttp2Weight(spdy3_priority_)
332 : http2_stream_dependency_.weight;
333 }
334
335 // Returns HTTP/2 parent stream exclusivity. If |is_spdy3_priority()| is
336 // false, this is the value provided at construction, otherwise it is false.
337 bool is_exclusive() const {
338 return !is_spdy3_priority_ && http2_stream_dependency_.is_exclusive;
339 }
340
341 // Facilitates test assertions.
342 bool operator==(const StreamPrecedence& other) const {
343 if (is_spdy3_priority()) {
344 return other.is_spdy3_priority() &&
345 (spdy3_priority() == other.spdy3_priority());
346 } else {
347 return !other.is_spdy3_priority() && (parent_id() == other.parent_id()) &&
348 (weight() == other.weight()) &&
349 (is_exclusive() == other.is_exclusive());
350 }
351 }
352
353 bool operator!=(const StreamPrecedence& other) const {
354 return !(*this == other);
355 }
356
357 private:
358 struct Http2StreamDependency {
359 StreamIdType parent_id;
360 int weight;
361 bool is_exclusive;
362 };
363
364 bool is_spdy3_priority_;
365 union {
366 SpdyPriority spdy3_priority_;
367 Http2StreamDependency http2_stream_dependency_;
368 };
369 };
370
371 typedef StreamPrecedence<SpdyStreamId> SpdyStreamPrecedence;
372
373 class SpdyFrameVisitor;
374
375 // Intermediate representation for HTTP2 frames.
376 class NET_EXPORT_PRIVATE SpdyFrameIR {
377 public:
378 virtual ~SpdyFrameIR() {}
379
380 virtual void Visit(SpdyFrameVisitor* visitor) const = 0;
381 virtual SpdyFrameType frame_type() const = 0;
382
383 protected:
384 SpdyFrameIR() {}
385
386 private:
387 DISALLOW_COPY_AND_ASSIGN(SpdyFrameIR);
388 };
389
390 // Abstract class intended to be inherited by IRs that have a stream associated
391 // to them.
392 class NET_EXPORT_PRIVATE SpdyFrameWithStreamIdIR : public SpdyFrameIR {
393 public:
394 ~SpdyFrameWithStreamIdIR() override {}
395 SpdyStreamId stream_id() const { return stream_id_; }
396 void set_stream_id(SpdyStreamId stream_id) {
397 DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
398 stream_id_ = stream_id;
399 }
400
401 protected:
402 explicit SpdyFrameWithStreamIdIR(SpdyStreamId stream_id) {
403 set_stream_id(stream_id);
404 }
405
406 private:
407 SpdyStreamId stream_id_;
408
409 DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithStreamIdIR);
410 };
411
412 // Abstract class intended to be inherited by IRs that have the option of a FIN
413 // flag. Implies SpdyFrameWithStreamIdIR.
414 class NET_EXPORT_PRIVATE SpdyFrameWithFinIR : public SpdyFrameWithStreamIdIR {
415 public:
416 ~SpdyFrameWithFinIR() override {}
417 bool fin() const { return fin_; }
418 void set_fin(bool fin) { fin_ = fin; }
419
420 protected:
421 explicit SpdyFrameWithFinIR(SpdyStreamId stream_id)
422 : SpdyFrameWithStreamIdIR(stream_id),
423 fin_(false) {}
424
425 private:
426 bool fin_;
427
428 DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithFinIR);
429 };
430
431 // Abstract class intended to be inherited by IRs that contain a header
432 // block. Implies SpdyFrameWithFinIR.
433 class NET_EXPORT_PRIVATE SpdyFrameWithHeaderBlockIR
434 : public NON_EXPORTED_BASE(SpdyFrameWithFinIR) {
435 public:
436 ~SpdyFrameWithHeaderBlockIR() override;
437
438 const SpdyHeaderBlock& header_block() const { return header_block_; }
439 void set_header_block(SpdyHeaderBlock header_block) {
440 // Deep copy.
441 header_block_ = std::move(header_block);
442 }
443 void SetHeader(SpdyStringPiece name, SpdyStringPiece value) {
444 header_block_[name] = value;
445 }
446 bool end_headers() const { return end_headers_; }
447 void set_end_headers(bool end_headers) { end_headers_ = end_headers; }
448
449 protected:
450 SpdyFrameWithHeaderBlockIR(SpdyStreamId stream_id,
451 SpdyHeaderBlock header_block);
452
453 private:
454 SpdyHeaderBlock header_block_;
455 bool end_headers_ = false;
456
457 DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithHeaderBlockIR);
458 };
459
460 class NET_EXPORT_PRIVATE SpdyDataIR
461 : public NON_EXPORTED_BASE(SpdyFrameWithFinIR) {
462 public:
463 // Performs a deep copy on data.
464 SpdyDataIR(SpdyStreamId stream_id, SpdyStringPiece data);
465
466 // Performs a deep copy on data.
467 SpdyDataIR(SpdyStreamId stream_id, const char* data);
468
469 // Moves data into data_store_. Makes a copy if passed a non-movable string.
470 SpdyDataIR(SpdyStreamId stream_id, SpdyString data);
471
472 // Use in conjunction with SetDataShallow() for shallow-copy on data.
473 explicit SpdyDataIR(SpdyStreamId stream_id);
474
475 ~SpdyDataIR() override;
476
477 const char* data() const { return data_; }
478 size_t data_len() const { return data_len_; }
479
480 bool padded() const { return padded_; }
481
482 int padding_payload_len() const { return padding_payload_len_; }
483
484 void set_padding_len(int padding_len) {
485 DCHECK_GT(padding_len, 0);
486 DCHECK_LE(padding_len, kPaddingSizePerFrame);
487 padded_ = true;
488 // The pad field takes one octet on the wire.
489 padding_payload_len_ = padding_len - 1;
490 }
491
492 // Deep-copy of data (keep private copy).
493 void SetDataDeep(SpdyStringPiece data) {
494 data_store_.reset(new SpdyString(data.data(), data.size()));
495 data_ = data_store_->data();
496 data_len_ = data.size();
497 }
498
499 // Shallow-copy of data (do not keep private copy).
500 void SetDataShallow(SpdyStringPiece data) {
501 data_store_.reset();
502 data_ = data.data();
503 data_len_ = data.size();
504 }
505
506 // Use this method if we don't have a contiguous buffer and only
507 // need a length.
508 void SetDataShallow(size_t len) {
509 data_store_.reset();
510 data_ = nullptr;
511 data_len_ = len;
512 }
513
514 void Visit(SpdyFrameVisitor* visitor) const override;
515
516 SpdyFrameType frame_type() const override;
517
518 private:
519 // Used to store data that this SpdyDataIR should own.
520 std::unique_ptr<SpdyString> data_store_;
521 const char* data_;
522 size_t data_len_;
523
524 bool padded_;
525 // padding_payload_len_ = desired padding length - len(padding length field).
526 int padding_payload_len_;
527
528 DISALLOW_COPY_AND_ASSIGN(SpdyDataIR);
529 };
530
531 class NET_EXPORT_PRIVATE SpdyRstStreamIR : public SpdyFrameWithStreamIdIR {
532 public:
533 SpdyRstStreamIR(SpdyStreamId stream_id, SpdyErrorCode error_code);
534
535 ~SpdyRstStreamIR() override;
536
537 SpdyErrorCode error_code() const { return error_code_; }
538 void set_error_code(SpdyErrorCode error_code) { error_code_ = error_code; }
539
540 void Visit(SpdyFrameVisitor* visitor) const override;
541
542 SpdyFrameType frame_type() const override;
543
544 private:
545 SpdyErrorCode error_code_;
546
547 DISALLOW_COPY_AND_ASSIGN(SpdyRstStreamIR);
548 };
549
550 class NET_EXPORT_PRIVATE SpdySettingsIR : public SpdyFrameIR {
551 public:
552 SpdySettingsIR();
553 ~SpdySettingsIR() override;
554
555 // Overwrites as appropriate.
556 const SettingsMap& values() const { return values_; }
557 void AddSetting(SpdySettingsIds id, int32_t value) { values_[id] = value; }
558
559 bool is_ack() const { return is_ack_; }
560 void set_is_ack(bool is_ack) {
561 is_ack_ = is_ack;
562 }
563
564 void Visit(SpdyFrameVisitor* visitor) const override;
565
566 SpdyFrameType frame_type() const override;
567
568 private:
569 SettingsMap values_;
570 bool is_ack_;
571
572 DISALLOW_COPY_AND_ASSIGN(SpdySettingsIR);
573 };
574
575 class NET_EXPORT_PRIVATE SpdyPingIR : public SpdyFrameIR {
576 public:
577 explicit SpdyPingIR(SpdyPingId id) : id_(id), is_ack_(false) {}
578 SpdyPingId id() const { return id_; }
579
580 bool is_ack() const { return is_ack_; }
581 void set_is_ack(bool is_ack) { is_ack_ = is_ack; }
582
583 void Visit(SpdyFrameVisitor* visitor) const override;
584
585 SpdyFrameType frame_type() const override;
586
587 private:
588 SpdyPingId id_;
589 bool is_ack_;
590
591 DISALLOW_COPY_AND_ASSIGN(SpdyPingIR);
592 };
593
594 class NET_EXPORT_PRIVATE SpdyGoAwayIR : public SpdyFrameIR {
595 public:
596 // References description, doesn't copy it, so description must outlast
597 // this SpdyGoAwayIR.
598 SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
599 SpdyErrorCode error_code,
600 SpdyStringPiece description);
601
602 // References description, doesn't copy it, so description must outlast
603 // this SpdyGoAwayIR.
604 SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
605 SpdyErrorCode error_code,
606 const char* description);
607
608 // Moves description into description_store_, so caller doesn't need to
609 // keep description live after constructing this SpdyGoAwayIR.
610 SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
611 SpdyErrorCode error_code,
612 SpdyString description);
613
614 ~SpdyGoAwayIR() override;
615 SpdyStreamId last_good_stream_id() const { return last_good_stream_id_; }
616 void set_last_good_stream_id(SpdyStreamId last_good_stream_id) {
617 DCHECK_EQ(0u, last_good_stream_id & ~kStreamIdMask);
618 last_good_stream_id_ = last_good_stream_id;
619 }
620 SpdyErrorCode error_code() const { return error_code_; }
621 void set_error_code(SpdyErrorCode error_code) {
622 // TODO(hkhalil): Check valid ranges of error_code?
623 error_code_ = error_code;
624 }
625
626 const SpdyStringPiece& description() const { return description_; }
627
628 void Visit(SpdyFrameVisitor* visitor) const override;
629
630 SpdyFrameType frame_type() const override;
631
632 private:
633 SpdyStreamId last_good_stream_id_;
634 SpdyErrorCode error_code_;
635 const SpdyString description_store_;
636 const SpdyStringPiece description_;
637
638 DISALLOW_COPY_AND_ASSIGN(SpdyGoAwayIR);
639 };
640
641 class NET_EXPORT_PRIVATE SpdyHeadersIR : public SpdyFrameWithHeaderBlockIR {
642 public:
643 explicit SpdyHeadersIR(SpdyStreamId stream_id)
644 : SpdyHeadersIR(stream_id, SpdyHeaderBlock()) {}
645 SpdyHeadersIR(SpdyStreamId stream_id, SpdyHeaderBlock header_block)
646 : SpdyFrameWithHeaderBlockIR(stream_id, std::move(header_block)) {}
647
648 void Visit(SpdyFrameVisitor* visitor) const override;
649
650 SpdyFrameType frame_type() const override;
651
652 bool has_priority() const { return has_priority_; }
653 void set_has_priority(bool has_priority) { has_priority_ = has_priority; }
654 int weight() const { return weight_; }
655 void set_weight(int weight) { weight_ = weight; }
656 SpdyStreamId parent_stream_id() const { return parent_stream_id_; }
657 void set_parent_stream_id(SpdyStreamId id) { parent_stream_id_ = id; }
658 bool exclusive() const { return exclusive_; }
659 void set_exclusive(bool exclusive) { exclusive_ = exclusive; }
660 bool padded() const { return padded_; }
661 int padding_payload_len() const { return padding_payload_len_; }
662 void set_padding_len(int padding_len) {
663 DCHECK_GT(padding_len, 0);
664 DCHECK_LE(padding_len, kPaddingSizePerFrame);
665 padded_ = true;
666 // The pad field takes one octet on the wire.
667 padding_payload_len_ = padding_len - 1;
668 }
669
670 private:
671 bool has_priority_ = false;
672 int weight_ = kHttp2DefaultStreamWeight;
673 SpdyStreamId parent_stream_id_ = 0;
674 bool exclusive_ = false;
675 bool padded_ = false;
676 int padding_payload_len_ = 0;
677
678 DISALLOW_COPY_AND_ASSIGN(SpdyHeadersIR);
679 };
680
681 class NET_EXPORT_PRIVATE SpdyWindowUpdateIR : public SpdyFrameWithStreamIdIR {
682 public:
683 SpdyWindowUpdateIR(SpdyStreamId stream_id, int32_t delta)
684 : SpdyFrameWithStreamIdIR(stream_id) {
685 set_delta(delta);
686 }
687 int32_t delta() const { return delta_; }
688 void set_delta(int32_t delta) {
689 DCHECK_LE(0, delta);
690 DCHECK_LE(delta, kSpdyMaximumWindowSize);
691 delta_ = delta;
692 }
693
694 void Visit(SpdyFrameVisitor* visitor) const override;
695
696 SpdyFrameType frame_type() const override;
697
698 private:
699 int32_t delta_;
700
701 DISALLOW_COPY_AND_ASSIGN(SpdyWindowUpdateIR);
702 };
703
704 class NET_EXPORT_PRIVATE SpdyPushPromiseIR : public SpdyFrameWithHeaderBlockIR {
705 public:
706 SpdyPushPromiseIR(SpdyStreamId stream_id, SpdyStreamId promised_stream_id)
707 : SpdyPushPromiseIR(stream_id, promised_stream_id, SpdyHeaderBlock()) {}
708 SpdyPushPromiseIR(SpdyStreamId stream_id,
709 SpdyStreamId promised_stream_id,
710 SpdyHeaderBlock header_block)
711 : SpdyFrameWithHeaderBlockIR(stream_id, std::move(header_block)),
712 promised_stream_id_(promised_stream_id),
713 padded_(false),
714 padding_payload_len_(0) {}
715 SpdyStreamId promised_stream_id() const { return promised_stream_id_; }
716
717 void Visit(SpdyFrameVisitor* visitor) const override;
718
719 SpdyFrameType frame_type() const override;
720
721 bool padded() const { return padded_; }
722 int padding_payload_len() const { return padding_payload_len_; }
723 void set_padding_len(int padding_len) {
724 DCHECK_GT(padding_len, 0);
725 DCHECK_LE(padding_len, kPaddingSizePerFrame);
726 padded_ = true;
727 // The pad field takes one octet on the wire.
728 padding_payload_len_ = padding_len - 1;
729 }
730
731 private:
732 SpdyStreamId promised_stream_id_;
733
734 bool padded_;
735 int padding_payload_len_;
736
737 DISALLOW_COPY_AND_ASSIGN(SpdyPushPromiseIR);
738 };
739
740 class NET_EXPORT_PRIVATE SpdyContinuationIR : public SpdyFrameWithStreamIdIR {
741 public:
742 explicit SpdyContinuationIR(SpdyStreamId stream_id);
743 ~SpdyContinuationIR() override;
744
745 void Visit(SpdyFrameVisitor* visitor) const override;
746
747 SpdyFrameType frame_type() const override;
748
749 bool end_headers() const { return end_headers_; }
750 void set_end_headers(bool end_headers) {end_headers_ = end_headers;}
751 const SpdyString& encoding() const { return *encoding_; }
752 void take_encoding(std::unique_ptr<SpdyString> encoding) {
753 encoding_ = std::move(encoding);
754 }
755
756 private:
757 std::unique_ptr<SpdyString> encoding_;
758 bool end_headers_;
759 DISALLOW_COPY_AND_ASSIGN(SpdyContinuationIR);
760 };
761
762 class NET_EXPORT_PRIVATE SpdyAltSvcIR : public SpdyFrameWithStreamIdIR {
763 public:
764 explicit SpdyAltSvcIR(SpdyStreamId stream_id);
765 ~SpdyAltSvcIR() override;
766
767 SpdyString origin() const { return origin_; }
768 const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector() const {
769 return altsvc_vector_;
770 }
771
772 void set_origin(SpdyString origin) { origin_ = std::move(origin); }
773 void add_altsvc(const SpdyAltSvcWireFormat::AlternativeService& altsvc) {
774 altsvc_vector_.push_back(altsvc);
775 }
776
777 void Visit(SpdyFrameVisitor* visitor) const override;
778
779 SpdyFrameType frame_type() const override;
780
781 private:
782 SpdyString origin_;
783 SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector_;
784 DISALLOW_COPY_AND_ASSIGN(SpdyAltSvcIR);
785 };
786
787 class NET_EXPORT_PRIVATE SpdyPriorityIR : public SpdyFrameWithStreamIdIR {
788 public:
789 explicit SpdyPriorityIR(SpdyStreamId stream_id)
790 : SpdyFrameWithStreamIdIR(stream_id),
791 parent_stream_id_(0),
792 weight_(1),
793 exclusive_(false) {}
794 SpdyPriorityIR(SpdyStreamId stream_id,
795 SpdyStreamId parent_stream_id,
796 int weight,
797 bool exclusive)
798 : SpdyFrameWithStreamIdIR(stream_id),
799 parent_stream_id_(parent_stream_id),
800 weight_(weight),
801 exclusive_(exclusive) {}
802 SpdyStreamId parent_stream_id() const { return parent_stream_id_; }
803 void set_parent_stream_id(SpdyStreamId id) { parent_stream_id_ = id; }
804 int weight() const { return weight_; }
805 void set_weight(uint8_t weight) { weight_ = weight; }
806 bool exclusive() const { return exclusive_; }
807 void set_exclusive(bool exclusive) { exclusive_ = exclusive; }
808
809 void Visit(SpdyFrameVisitor* visitor) const override;
810
811 SpdyFrameType frame_type() const override;
812
813 private:
814 SpdyStreamId parent_stream_id_;
815 int weight_;
816 bool exclusive_;
817 DISALLOW_COPY_AND_ASSIGN(SpdyPriorityIR);
818 };
819
820 class SpdySerializedFrame {
821 public:
822 SpdySerializedFrame()
823 : frame_(const_cast<char*>("")), size_(0), owns_buffer_(false) {}
824
825 // Create a valid SpdySerializedFrame using a pre-created buffer.
826 // If |owns_buffer| is true, this class takes ownership of the buffer and will
827 // delete it on cleanup. The buffer must have been created using new char[].
828 // If |owns_buffer| is false, the caller retains ownership of the buffer and
829 // is responsible for making sure the buffer outlives this frame. In other
830 // words, this class does NOT create a copy of the buffer.
831 SpdySerializedFrame(char* data, size_t size, bool owns_buffer)
832 : frame_(data), size_(size), owns_buffer_(owns_buffer) {}
833
834 SpdySerializedFrame(SpdySerializedFrame&& other)
835 : frame_(other.frame_),
836 size_(other.size_),
837 owns_buffer_(other.owns_buffer_) {
838 // |other| is no longer responsible for the buffer.
839 other.owns_buffer_ = false;
840 }
841
842 SpdySerializedFrame& operator=(SpdySerializedFrame&& other) {
843 // Free buffer if necessary.
844 if (owns_buffer_) {
845 delete[] frame_;
846 }
847 // Take over |other|.
848 frame_ = other.frame_;
849 size_ = other.size_;
850 owns_buffer_ = other.owns_buffer_;
851 // |other| is no longer responsible for the buffer.
852 other.owns_buffer_ = false;
853 return *this;
854 }
855
856 ~SpdySerializedFrame() {
857 if (owns_buffer_) {
858 delete[] frame_;
859 }
860 }
861
862 // Provides access to the frame bytes, which is a buffer containing the frame
863 // packed as expected for sending over the wire.
864 char* data() const { return frame_; }
865
866 // Returns the actual size of the underlying buffer.
867 size_t size() const { return size_; }
868
869 // Returns a buffer containing the contents of the frame, of which the caller
870 // takes ownership, and clears this SpdySerializedFrame.
871 char* ReleaseBuffer() {
872 char* buffer;
873 if (owns_buffer_) {
874 // If the buffer is owned, relinquish ownership to the caller.
875 buffer = frame_;
876 owns_buffer_ = false;
877 } else {
878 // Otherwise, we need to make a copy to give to the caller.
879 buffer = new char[size_];
880 memcpy(buffer, frame_, size_);
881 }
882 *this = SpdySerializedFrame();
883 return buffer;
884 }
885
886 // Returns the estimate of dynamically allocated memory in bytes.
887 size_t EstimateMemoryUsage() const { return owns_buffer_ ? size_ : 0; }
888
889 protected:
890 char* frame_;
891
892 private:
893 size_t size_;
894 bool owns_buffer_;
895 DISALLOW_COPY_AND_ASSIGN(SpdySerializedFrame);
896 };
897
898 // This interface is for classes that want to process SpdyFrameIRs without
899 // having to know what type they are. An instance of this interface can be
900 // passed to a SpdyFrameIR's Visit method, and the appropriate type-specific
901 // method of this class will be called.
902 class SpdyFrameVisitor {
903 public:
904 virtual void VisitRstStream(const SpdyRstStreamIR& rst_stream) = 0;
905 virtual void VisitSettings(const SpdySettingsIR& settings) = 0;
906 virtual void VisitPing(const SpdyPingIR& ping) = 0;
907 virtual void VisitGoAway(const SpdyGoAwayIR& goaway) = 0;
908 virtual void VisitHeaders(const SpdyHeadersIR& headers) = 0;
909 virtual void VisitWindowUpdate(const SpdyWindowUpdateIR& window_update) = 0;
910 virtual void VisitPushPromise(const SpdyPushPromiseIR& push_promise) = 0;
911 virtual void VisitContinuation(const SpdyContinuationIR& continuation) = 0;
912 virtual void VisitAltSvc(const SpdyAltSvcIR& altsvc) = 0;
913 virtual void VisitPriority(const SpdyPriorityIR& priority) = 0;
914 virtual void VisitData(const SpdyDataIR& data) = 0;
915
916 protected:
917 SpdyFrameVisitor() {}
918 virtual ~SpdyFrameVisitor() {}
919
920 private:
921 DISALLOW_COPY_AND_ASSIGN(SpdyFrameVisitor);
922 };
923
924 } // namespace net
925
926 #endif // NET_SPDY_SPDY_PROTOCOL_H_
OLDNEW
« no previous file with comments | « net/spdy/spdy_prefixed_buffer_reader_test.cc ('k') | net/spdy/spdy_protocol.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698