summaryrefslogtreecommitdiff
path: root/chromium/net/http2/http2_constants.h
blob: 05c85026975833dac4594dc3fabc5c26c0826b0c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_HTTP2_HTTP2_CONSTANTS_H_
#define NET_HTTP2_HTTP2_CONSTANTS_H_

// Constants from the HTTP/2 spec, RFC 7540, and associated helper functions.

#include <stdint.h>

#include <iosfwd>
#include <ostream>

#include "net/http2/platform/api/http2_export.h"
#include "net/http2/platform/api/http2_string.h"

namespace net {

// TODO(jamessynge): create http2_simple_types for types similar to
// SpdyStreamId, but not for structures like Http2FrameHeader. Then will be
// able to move these stream id functions there.
constexpr uint32_t UInt31Mask() {
  return 0x7fffffff;
}
constexpr uint32_t StreamIdMask() {
  return UInt31Mask();
}

// The value used to identify types of frames. Upper case to match the RFC.
// The comments indicate which flags are valid for that frame type.
// ALTSVC is defined in http://httpwg.org/http-extensions/alt-svc.html
// (not yet final standard as of March 2016, but close).
enum class Http2FrameType : uint8_t {
  DATA = 0,           // END_STREAM | PADDED
  HEADERS = 1,        // END_STREAM | END_HEADERS | PADDED | PRIORITY
  PRIORITY = 2,       //
  RST_STREAM = 3,     //
  SETTINGS = 4,       // ACK
  PUSH_PROMISE = 5,   // END_HEADERS | PADDED
  PING = 6,           // ACK
  GOAWAY = 7,         //
  WINDOW_UPDATE = 8,  //
  CONTINUATION = 9,   // END_HEADERS
  ALTSVC = 10,        //
};

// Is the frame type known/supported?
inline bool IsSupportedHttp2FrameType(uint32_t v) {
  return v <= static_cast<uint32_t>(Http2FrameType::ALTSVC);
}
inline bool IsSupportedHttp2FrameType(Http2FrameType v) {
  return IsSupportedHttp2FrameType(static_cast<uint32_t>(v));
}

// The return type is 'Http2String' so that they can generate a unique string
// for each unsupported value. Since these are just used for debugging/error
// messages, that isn't a cost to we need to worry about. The same applies to
// the functions later in this file.
HTTP2_EXPORT_PRIVATE Http2String Http2FrameTypeToString(Http2FrameType v);
HTTP2_EXPORT_PRIVATE Http2String Http2FrameTypeToString(uint8_t v);
HTTP2_EXPORT_PRIVATE inline std::ostream& operator<<(std::ostream& out,
                                                     Http2FrameType v) {
  return out << Http2FrameTypeToString(v);
}

// Flags that appear in supported frame types. These are treated as bit masks.
// The comments indicate for which frame types the flag is valid.
enum Http2FrameFlag {
  END_STREAM = 0x01,   // DATA, HEADERS
  ACK = 0x01,          // SETTINGS, PING
  END_HEADERS = 0x04,  // HEADERS, PUSH_PROMISE, CONTINUATION
  PADDED = 0x08,       // DATA, HEADERS, PUSH_PROMISE
  PRIORITY = 0x20,     // HEADERS
};

// Formats zero or more flags for the specified type of frame. Returns an
// empty string if flags==0.
HTTP2_EXPORT_PRIVATE Http2String Http2FrameFlagsToString(Http2FrameType type,
                                                         uint8_t flags);
HTTP2_EXPORT_PRIVATE Http2String Http2FrameFlagsToString(uint8_t type,
                                                         uint8_t flags);

// Error codes for GOAWAY and RST_STREAM frames.
enum class Http2ErrorCode : uint32_t {
  // The associated condition is not a result of an error. For example, a GOAWAY
  // might include this code to indicate graceful shutdown of a connection.
  HTTP2_NO_ERROR = 0x0,

  // The endpoint detected an unspecific protocol error. This error is for use
  // when a more specific error code is not available.
  PROTOCOL_ERROR = 0x1,

  // The endpoint encountered an unexpected internal error.
  INTERNAL_ERROR = 0x2,

  // The endpoint detected that its peer violated the flow-control protocol.
  FLOW_CONTROL_ERROR = 0x3,

  // The endpoint sent a SETTINGS frame but did not receive a response in a
  // timely manner. See Section 6.5.3 ("Settings Synchronization").
  SETTINGS_TIMEOUT = 0x4,

  // The endpoint received a frame after a stream was half-closed.
  STREAM_CLOSED = 0x5,

  // The endpoint received a frame with an invalid size.
  FRAME_SIZE_ERROR = 0x6,

  // The endpoint refused the stream prior to performing any application
  // processing (see Section 8.1.4 for details).
  REFUSED_STREAM = 0x7,

  // Used by the endpoint to indicate that the stream is no longer needed.
  CANCEL = 0x8,

  // The endpoint is unable to maintain the header compression context
  // for the connection.
  COMPRESSION_ERROR = 0x9,

  // The connection established in response to a CONNECT request (Section 8.3)
  // was reset or abnormally closed.
  CONNECT_ERROR = 0xa,

  // The endpoint detected that its peer is exhibiting a behavior that might
  // be generating excessive load.
  ENHANCE_YOUR_CALM = 0xb,

  // The underlying transport has properties that do not meet minimum
  // security requirements (see Section 9.2).
  INADEQUATE_SECURITY = 0xc,

  // The endpoint requires that HTTP/1.1 be used instead of HTTP/2.
  HTTP_1_1_REQUIRED = 0xd,
};

// Is the error code supported? (So far that means it is in RFC 7540.)
inline bool IsSupportedHttp2ErrorCode(uint32_t v) {
  return v <= static_cast<uint32_t>(Http2ErrorCode::HTTP_1_1_REQUIRED);
}
inline bool IsSupportedHttp2ErrorCode(Http2ErrorCode v) {
  return IsSupportedHttp2ErrorCode(static_cast<uint32_t>(v));
}

// Format the specified error code.
HTTP2_EXPORT_PRIVATE Http2String Http2ErrorCodeToString(uint32_t v);
HTTP2_EXPORT_PRIVATE Http2String Http2ErrorCodeToString(Http2ErrorCode v);
HTTP2_EXPORT_PRIVATE inline std::ostream& operator<<(std::ostream& out,
                                                     Http2ErrorCode v) {
  return out << Http2ErrorCodeToString(v);
}

// Supported parameters in SETTINGS frames; so far just those in RFC 7540.
enum class Http2SettingsParameter : uint16_t {
  // Allows the sender to inform the remote endpoint of the maximum size of the
  // header compression table used to decode header blocks, in octets. The
  // encoder can select any size equal to or less than this value by using
  // signaling specific to the header compression format inside a header block
  // (see [COMPRESSION]). The initial value is 4,096 octets.
  HEADER_TABLE_SIZE = 0x1,

  // This setting can be used to disable server push (Section 8.2). An endpoint
  // MUST NOT send a PUSH_PROMISE frame if it receives this parameter set to a
  // value of 0. An endpoint that has both set this parameter to 0 and had it
  // acknowledged MUST treat the receipt of a PUSH_PROMISE frame as a connection
  // error (Section 5.4.1) of type PROTOCOL_ERROR.
  //
  // The initial value is 1, which indicates that server push is permitted. Any
  // value other than 0 or 1 MUST be treated as a connection error (Section
  // 5.4.1) of type PROTOCOL_ERROR.
  ENABLE_PUSH = 0x2,

  // Indicates the maximum number of concurrent streams that the sender will
  // allow. This limit is directional: it applies to the number of streams that
  // the sender permits the receiver to create. Initially, there is no limit to
  // this value. It is recommended that this value be no smaller than 100, so as
  // to not unnecessarily limit parallelism.
  //
  // A value of 0 for MAX_CONCURRENT_STREAMS SHOULD NOT be treated as
  // special by endpoints. A zero value does prevent the creation of new
  // streams; however, this can also happen for any limit that is exhausted with
  // active streams. Servers SHOULD only set a zero value for short durations;
  // if a server does not wish to accept requests, closing the connection is
  // more appropriate.
  MAX_CONCURRENT_STREAMS = 0x3,

  // Indicates the sender's initial window size (in octets) for stream-level
  // flow control. The initial value is 2^16-1 (65,535) octets.
  //
  // This setting affects the window size of all streams (see Section 6.9.2).
  //
  // Values above the maximum flow-control window size of 2^31-1 MUST be treated
  // as a connection error (Section 5.4.1) of type FLOW_CONTROL_ERROR.
  INITIAL_WINDOW_SIZE = 0x4,

  // Indicates the size of the largest frame payload that the sender is willing
  // to receive, in octets.
  //
  // The initial value is 2^14 (16,384) octets. The value advertised by an
  // endpoint MUST be between this initial value and the maximum allowed frame
  // size (2^24-1 or 16,777,215 octets), inclusive. Values outside this range
  // MUST be treated as a connection error (Section 5.4.1) of type
  // PROTOCOL_ERROR.
  MAX_FRAME_SIZE = 0x5,

  // This advisory setting informs a peer of the maximum size of header list
  // that the sender is prepared to accept, in octets. The value is based on the
  // uncompressed size of header fields, including the length of the name and
  // value in octets plus an overhead of 32 octets for each header field.
  //
  // For any given request, a lower limit than what is advertised MAY be
  // enforced. The initial value of this setting is unlimited.
  MAX_HEADER_LIST_SIZE = 0x6,
};

// Is the settings parameter supported (so far that means it is in RFC 7540)?
inline bool IsSupportedHttp2SettingsParameter(uint32_t v) {
  return 0 < v &&
         v <= static_cast<uint32_t>(
                  Http2SettingsParameter::MAX_HEADER_LIST_SIZE);
}
inline bool IsSupportedHttp2SettingsParameter(Http2SettingsParameter v) {
  return IsSupportedHttp2SettingsParameter(static_cast<uint32_t>(v));
}

// Format the specified settings parameter.
HTTP2_EXPORT_PRIVATE Http2String Http2SettingsParameterToString(uint32_t v);
HTTP2_EXPORT_PRIVATE Http2String
Http2SettingsParameterToString(Http2SettingsParameter v);
inline std::ostream& operator<<(std::ostream& out, Http2SettingsParameter v) {
  return out << Http2SettingsParameterToString(v);
}

// Information about the initial, minimum and maximum value of settings (not
// applicable to all settings parameters).
class Http2SettingsInfo {
 public:
  // Default value for HEADER_TABLE_SIZE.
  static constexpr uint32_t DefaultHeaderTableSize() { return 4096; }

  // Default value for ENABLE_PUSH.
  static constexpr bool DefaultEnablePush() { return true; }

  // Default value for INITIAL_WINDOW_SIZE.
  static constexpr uint32_t DefaultInitialWindowSize() { return 65535; }

  // Maximum value for INITIAL_WINDOW_SIZE, and for the connection flow control
  // window, and for each stream flow control window.
  static constexpr uint32_t MaximumWindowSize() { return UInt31Mask(); }

  // Default value for MAX_FRAME_SIZE.
  static constexpr uint32_t DefaultMaxFrameSize() { return 16384; }

  // Minimum value for MAX_FRAME_SIZE.
  static constexpr uint32_t MinimumMaxFrameSize() { return 16384; }

  // Maximum value for MAX_FRAME_SIZE.
  static constexpr uint32_t MaximumMaxFrameSize() { return (1 << 24) - 1; }
};

}  // namespace net

#endif  // NET_HTTP2_HTTP2_CONSTANTS_H_