Skip to content
This repository was archived by the owner on Sep 22, 2020. It is now read-only.

Commit 0cb177e

Browse files
committed
Added more test case
1 parent 89394b7 commit 0cb177e

39 files changed

+911
-17
lines changed

lib/client/index.js

+9-8
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ var glob = require('glob').sync,
4242
path = require('path'),
4343
tls = require('tls'),
4444
fs = require('fs'),
45-
http2 = require('http2');
45+
http2Protocol = require('http2-protocol'),
46+
net = require('net');
4647

4748
var Browser = require('./browser');
4849

@@ -52,7 +53,7 @@ describe('HTTP/2 client', function() {
5253

5354

5455
var tests = glob(__dirname + '/tests/**/*-test.js'),
55-
port = 1024,
56+
port = 3024,
5657
testServer, log, browser;
5758

5859
function createLogger(name) {
@@ -62,19 +63,20 @@ describe('HTTP/2 client', function() {
6263
level: 'debug',
6364
path: __dirname + '/../../test.log'
6465
}],
65-
serializers: http2.serializers,
66+
serializers: http2Protocol.serializers,
6667
level: 'info'
6768
});
6869
}
6970
log = createLogger('test');
7071
beforeEach(function() {
72+
// Load the TCP Library
7173

72-
testServer = http2.createServer({
73-
plain: true
74-
});
75-
log.info('Connected UnSecure');
7674

75+
// Keep track of the chat clients
76+
var clients = [];
7777

78+
// Start a TCP Server
79+
testServer = net.createServer();
7880
testServer.listen(port);
7981
browser = new Browser(process.env.HTTP2_BROWSER);
8082
});
@@ -97,7 +99,6 @@ describe('HTTP/2 client', function() {
9799

98100
afterEach(function() {
99101
browser.stop();
100-
port++;
101102
});
102103

103104
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// > [4.3. Header Compression and Decompression](http://tools.ietf.org/html/draft-ietf-httpbis-http2-06#section-4.3)
2+
// >
3+
// > ...
4+
// >
5+
// > A receiver MUST terminate the connection with a connection
6+
// > error (Section 5.4.1) of type COMPRESSION_ERROR, if it does not
7+
// > decompress a header block.
8+
//
9+
// This test sends a header block with a single header representation with substitution indexing.
10+
// The index is so large that it does not fit into 64 bits, so it may trigger an overflow or other
11+
// errors in a naive implementation which may load to a crash.
12+
//
13+
// The encoded index is invalid since there's no item in the Header Table with that large index, so
14+
// the peer should shut down the connection with COMPRESSION_ERROR. If the peer cannot decode the
15+
// index, but handles this situation gracefully, it should return COMPRESSION_ERROR, too
16+
17+
var invalidDataTestCase = require('./invalid-data');
18+
module.exports = function(socket, log, callback) {
19+
// representations = [{ name: 'x', value: 'y', index: largeNumber }];
20+
var largeNumber = 'ffffffffffffffffffff00'; // 2^70 - 1 = 1180591620717411303423
21+
var representation = new Buffer('00' + '0178' + largeNumber + '0179', 'hex');
22+
invalidDataTestCase(socket, log, callback, representation);
23+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// > [4.3. Header Compression and Decompression](http://tools.ietf.org/html/draft-ietf-httpbis-http2-06#section-4.3)
2+
// >
3+
// > ...
4+
// >
5+
// > A receiver MUST terminate the connection with a connection
6+
// > error (Section 5.4.1) of type COMPRESSION_ERROR, if it does not
7+
// > decompress a header block.
8+
//
9+
// This test sends a single, incomplete header representation in the response header block.
10+
11+
var invalidDataTestCase = require('./invalid-data');
12+
13+
module.exports = function(socket, log, callback) {
14+
invalidDataTestCase(socket, log, callback, new Buffer('00', 'hex'));
15+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// > [4.3. Header Compression and Decompression](http://tools.ietf.org/html/draft-ietf-httpbis-http2-06#section-4.3)
2+
// >
3+
// > ...
4+
// >
5+
// > A receiver MUST terminate the connection with a connection
6+
// > error (Section 5.4.1) of type COMPRESSION_ERROR, if it does not
7+
// > decompress a header block.
8+
//
9+
// This test sends a single, incomplete header representation in the response header block.
10+
11+
var invalidDataTestCase = require('./invalid-data');
12+
13+
module.exports = function(socket, log, callback) {
14+
// representations = [{ name: 'x', value: 'y', index: -1 }];
15+
var validCompressionData = new Buffer('6001780179', 'hex');
16+
var length = validCompressionData.length;
17+
var invalidCompressionData = validCompressionData.slice(0, length - 1);
18+
invalidDataTestCase(socket, log, callback, invalidCompressionData);
19+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
var http2 = require('http2-protocol');
2+
3+
module.exports = function(socket, log, callback, compressedData) {
4+
var endpoint = new http2.Endpoint(log, 'SERVER', {}, {
5+
beforeSerialization: beforeSerialization
6+
});
7+
socket.pipe(endpoint).pipe(socket);
8+
9+
endpoint.on('stream', function(stream) {
10+
stream.headers({
11+
':status': 200
12+
});
13+
stream.end('response body');
14+
});
15+
16+
function beforeSerialization(frame, forward, done) {
17+
if (frame.type === 'HEADERS') {
18+
frame.data = compressedData;
19+
}
20+
forward(frame);
21+
done();
22+
}
23+
24+
endpoint.on('peerError', function(error) {
25+
log.debug('Receiving GOAWAY frame');
26+
if (error === 'PROTOCOL_ERROR') {
27+
callback();
28+
} else {
29+
callback('Not appropriate error code: ' + error);
30+
}
31+
});
32+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// [From the spec](http://tools.ietf.org/html/draft-ietf-httpbis-http2-06#section-6.7):
2+
//
3+
// In addition to the frame header, PING frames MUST contain 8 octets of
4+
// data in the payload. A sender can include any value it chooses and
5+
// use those bytes in any fashion.
6+
//
7+
// ...
8+
//
9+
// Receipt of a PING frame with a length field value other than 8 MUST
10+
// be treated as a connection error (Section 5.4.1) of type
11+
// PROTOCOL_ERROR.
12+
13+
var http2 = require('http2-protocol');
14+
15+
module.exports = function(socket, log, callback) {
16+
var endpoint = new http2.Endpoint(log, 'SERVER', {});
17+
socket.pipe(endpoint).pipe(socket);
18+
19+
setImmediate(function() {
20+
// After sending the connection header:
21+
log.debug('Sending oversize PING frame');
22+
endpoint._serializer.write({
23+
type: 'PING',
24+
flags: {},
25+
stream: 0,
26+
data: new Buffer(10)
27+
});
28+
});
29+
30+
endpoint.on('peerError', function(error) {
31+
log.debug('Receiving GOAWAY frame');
32+
if (error === 'PROTOCOL_ERROR') {
33+
callback();
34+
} else {
35+
callback('Not appropriate error code: ' + error);
36+
}
37+
});
38+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// [From the spec](http://tools.ietf.org/html/draft-ietf-httpbis-http2-06#section-6.7):
2+
//
3+
// DATA frames MUST be associated with a stream. If a DATA frame is
4+
// received whose stream identifier field is 0x0, the recipient MUST
5+
// respond with a connection error (Section 5.4.1) of type
6+
// PROTOCOL_ERROR.
7+
8+
var http2 = require('http2-protocol');
9+
module.exports = function(socket, log, callback, frame) {
10+
var endpoint = new http2.Endpoint(log, 'SERVER', {});
11+
socket.pipe(endpoint).pipe(socket);
12+
13+
setImmediate(function() {
14+
frame = frame || {
15+
type: 'DATA',
16+
flags: {},
17+
data: new Buffer(10)
18+
};
19+
20+
frame.stream = 0;
21+
22+
log.debug('Sending connection-level ' + frame.type + ' frame');
23+
24+
endpoint._compressor.write(frame);
25+
});
26+
27+
endpoint.on('peerError', function(error) {
28+
log.debug('Receiving GOAWAY frame');
29+
if (error === 'PROTOCOL_ERROR') {
30+
callback();
31+
} else {
32+
callback('Not appropriate error code: ' + error);
33+
}
34+
});
35+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// [From the spec](http://tools.ietf.org/html/draft-ietf-httpbis-http2-06#section-6.8):
2+
//
3+
// The GOAWAY frame applies to the connection, not a specific stream.
4+
// The stream identifier MUST be zero.
5+
6+
var http2 = require('http2-protocol');
7+
8+
module.exports = function(socket, log, callback, frame) {
9+
var endpoint = new http2.Endpoint(log, 'SERVER', {});
10+
socket.pipe(endpoint).pipe(socket);
11+
12+
endpoint.on('stream', function(stream) {
13+
frame = frame || {
14+
type: 'GOAWAY',
15+
flags: {},
16+
last_stream: 1,
17+
error: 'NO_ERROR'
18+
};
19+
20+
frame.stream = stream.id;
21+
22+
log.debug('Sending stream-level ' + frame.type + ' frame');
23+
24+
endpoint._compressor.write(frame);
25+
});
26+
27+
endpoint.on('peerError', function(error) {
28+
log.debug('Receiving GOAWAY frame');
29+
if (error === 'PROTOCOL_ERROR') {
30+
callback();
31+
} else {
32+
callback('Not appropriate error code: ' + error);
33+
}
34+
});
35+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// [From the spec](http://tools.ietf.org/html/draft-ietf-httpbis-http2-06#section-6.2):
2+
//
3+
// HEADERS frames MUST be associated with a stream. If a HEADERS frame
4+
// is received whose stream identifier field is 0x0, the recipient MUST
5+
// respond with a connection error (Section 5.4.1) of type
6+
// PROTOCOL_ERROR.
7+
8+
var invalidConnectionLevelFrameTest = require('./invalid-level-data-test.js');
9+
10+
module.exports = function(socket, log, callback) {
11+
invalidConnectionLevelFrameTest(socket, log, callback, {
12+
type: 'HEADERS',
13+
flags: {},
14+
headers: {
15+
':status': 200
16+
}
17+
});
18+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// [From the spec](http://tools.ietf.org/html/draft-ietf-httpbis-http2-06#section-6.7):
2+
//
3+
// PING frames are not associated with any individual stream. If a PING
4+
// frame is received with a stream identifier field value other than
5+
// 0x0, the recipient MUST respond with a connection error
6+
// (Section 5.4.1) of type PROTOCOL_ERROR.
7+
8+
var invalidStreamLevelFrameTest = require('./invalid-level-goaway-test.js');
9+
10+
module.exports = function(socket, log, callback) {
11+
invalidStreamLevelFrameTest(socket, log, callback, {
12+
type: 'PING',
13+
flags: {},
14+
data: new Buffer(8)
15+
});
16+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// [From the spec](http://tools.ietf.org/html/draft-ietf-httpbis-http2-06#section-6.3):
2+
//
3+
// PRIORITY frame is received with a stream identifier of 0x0, the
4+
// recipient MUST respond with a connection error (Section 5.4.1) of
5+
// type PROTOCOL_ERROR.
6+
7+
var invalidConnectionLevelFrameTest = require('./invalid-level-data-test.js');
8+
9+
module.exports = function(socket, log, callback) {
10+
invalidConnectionLevelFrameTest(socket, log, callback, {
11+
type: 'PRIORITY',
12+
flags: {},
13+
priority: 10
14+
});
15+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// [From the spec](http://tools.ietf.org/html/draft-ietf-httpbis-http2-06#section-6.6):
2+
//
3+
// ... If the stream identifier field specifies the value
4+
// 0x0, a recipient MUST respond with a connection error (Section 5.4.1)
5+
// of type PROTOCOL_ERROR.
6+
7+
var invalidConnectionLevelFrameTest = require('./invalid-level-data-test.js');
8+
9+
module.exports = function(socket, log, callback) {
10+
invalidConnectionLevelFrameTest(socket, log, callback, {
11+
type: 'PUSH_PROMISE',
12+
flags: {},
13+
headers: {
14+
':method': 'GET',
15+
':scheme': 'https',
16+
':host': 'localhost',
17+
':path': '/pushed.html'
18+
},
19+
promised_stream: 12
20+
});
21+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// [From the spec](http://tools.ietf.org/html/draft-ietf-httpbis-http2-06#section-6.4):
2+
//
3+
// RST_STREAM frames MUST be associated with a stream. If a RST_STREAM
4+
// frame is received with a stream identifier of 0x0, the recipient MUST
5+
// treat this as a connection error (Section 5.4.1) of type
6+
// PROTOCOL_ERROR.
7+
8+
var invalidConnectionLevelFrameTest = require('./invalid-level-data-test.js');
9+
10+
module.exports = function(socket, log, callback) {
11+
invalidConnectionLevelFrameTest(socket, log, callback, {
12+
type: 'RST_STREAM',
13+
flags: {},
14+
error: 'CANCEL'
15+
});
16+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// [From the spec](http://tools.ietf.org/html/draft-ietf-httpbis-http2-06#section-6.5):
2+
//
3+
// SETTINGS frames always apply to a connection, never a single stream.
4+
// The stream identifier for a settings frame MUST be zero. If an
5+
// endpoint receives a SETTINGS frame whose stream identifier field is
6+
// anything other than 0x0, the endpoint MUST respond with a connection
7+
// error (Section 5.4.1) of type PROTOCOL_ERROR.
8+
9+
var invalidStreamLevelFrameTest = require('./invalid-level-goaway-test.js');
10+
11+
module.exports = function(socket, log, callback) {
12+
invalidStreamLevelFrameTest(socket, log, callback, {
13+
type: 'SETTINGS',
14+
flags: {},
15+
settings: {
16+
SETTINGS_MAX_CONCURRENT_STREAMS: 100
17+
}
18+
});
19+
};

0 commit comments

Comments
 (0)