forked from nodejs/node
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhttp2.js
More file actions
129 lines (110 loc) Β· 3.24 KB
/
http2.js
File metadata and controls
129 lines (110 loc) Β· 3.24 KB
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
'use strict';
// An HTTP/2 testing tool used to create mock frames for direct testing
// of HTTP/2 endpoints.
const kFrameData = Symbol('frame-data');
const FLAG_EOS = 0x1;
const FLAG_ACK = 0x1;
const FLAG_EOH = 0x4;
const FLAG_PADDED = 0x8;
const PADDING = Buffer.alloc(255);
const kClientMagic = Buffer.from('505249202a20485454502f322' +
'e300d0a0d0a534d0d0a0d0a', 'hex');
const kFakeRequestHeaders = Buffer.from('828684410f7777772e65' +
'78616d706c652e636f6d', 'hex');
const kFakeResponseHeaders = Buffer.from('4803333032580770726976617465611d' +
'4d6f6e2c203231204f63742032303133' +
'2032303a31333a323120474d546e1768' +
'747470733a2f2f7777772e6578616d70' +
'6c652e636f6d', 'hex');
function isUint32(val) {
return val >>> 0 === val;
}
function isUint24(val) {
return val >>> 0 === val && val <= 0xFFFFFF;
}
function isUint8(val) {
return val >>> 0 === val && val <= 0xFF;
}
function write32BE(array, pos, val) {
if (!isUint32(val))
throw new RangeError('val is not a 32-bit number');
array[pos++] = (val >> 24) & 0xff;
array[pos++] = (val >> 16) & 0xff;
array[pos++] = (val >> 8) & 0xff;
array[pos++] = val & 0xff;
}
function write24BE(array, pos, val) {
if (!isUint24(val))
throw new RangeError('val is not a 24-bit number');
array[pos++] = (val >> 16) & 0xff;
array[pos++] = (val >> 8) & 0xff;
array[pos++] = val & 0xff;
}
function write8(array, pos, val) {
if (!isUint8(val))
throw new RangeError('val is not an 8-bit number');
array[pos] = val;
}
class Frame {
constructor(length, type, flags, id) {
this[kFrameData] = Buffer.alloc(9);
write24BE(this[kFrameData], 0, length);
write8(this[kFrameData], 3, type);
write8(this[kFrameData], 4, flags);
write32BE(this[kFrameData], 5, id);
}
get data() {
return this[kFrameData];
}
}
class SettingsFrame extends Frame {
constructor(ack = false) {
let flags = 0;
if (ack)
flags |= FLAG_ACK;
super(0, 4, flags, 0);
}
}
class HeadersFrame extends Frame {
constructor(id, payload, padlen = 0, final = false) {
let len = payload.length;
let flags = FLAG_EOH;
if (final) flags |= FLAG_EOS;
const buffers = [payload];
if (padlen > 0) {
buffers.unshift(Buffer.from([padlen]));
buffers.push(PADDING.slice(0, padlen));
len += padlen + 1;
flags |= FLAG_PADDED;
}
super(len, 1, flags, id);
buffers.unshift(this[kFrameData]);
this[kFrameData] = Buffer.concat(buffers);
}
}
class PingFrame extends Frame {
constructor(ack = false) {
const buffers = [Buffer.alloc(8)];
super(8, 6, ack ? 1 : 0, 0);
buffers.unshift(this[kFrameData]);
this[kFrameData] = Buffer.concat(buffers);
}
}
class AltSvcFrame extends Frame {
constructor(size) {
const buffers = [Buffer.alloc(size)];
super(size, 10, 0, 0);
buffers.unshift(this[kFrameData]);
this[kFrameData] = Buffer.concat(buffers);
}
}
module.exports = {
Frame,
AltSvcFrame,
HeadersFrame,
SettingsFrame,
PingFrame,
kFakeRequestHeaders,
kFakeResponseHeaders,
kClientMagic,
};