forked from nodejs/node
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
http2: fix refs to status 205, add tests
Fix references within http2 core to HTTP_STATUS_CONTENT_RESET to point to the correct HTTP_STATUS_RESET_CONTENT. Add tests for status 204, 205 & 304 in respond, respondWithFD & respondWithFile. Add general error tests for respondWithFD & respondWithFile. PR-URL: nodejs#15153 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Claudio Rodriguez <cjrodr@yahoo.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
- Loading branch information
1 parent
c20901a
commit 45357d0
Showing
4 changed files
with
270 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// Flags: --expose-http2 | ||
'use strict'; | ||
|
||
const common = require('../common'); | ||
if (!common.hasCrypto) | ||
common.skip('missing crypto'); | ||
const http2 = require('http2'); | ||
const path = require('path'); | ||
|
||
const optionsWithTypeError = { | ||
offset: 'number', | ||
length: 'number', | ||
statCheck: 'function', | ||
getTrailers: 'function' | ||
}; | ||
|
||
const types = { | ||
boolean: true, | ||
function: () => {}, | ||
number: 1, | ||
object: {}, | ||
array: [], | ||
null: null, | ||
symbol: Symbol('test') | ||
}; | ||
|
||
const fname = path.resolve(common.fixturesDir, 'elipses.txt'); | ||
|
||
const server = http2.createServer(); | ||
|
||
server.on('stream', common.mustCall((stream) => { | ||
// Check for all possible TypeError triggers on options | ||
Object.keys(optionsWithTypeError).forEach((option) => { | ||
Object.keys(types).forEach((type) => { | ||
if (type === optionsWithTypeError[option]) { | ||
return; | ||
} | ||
|
||
common.expectsError( | ||
() => stream.respondWithFile(fname, { | ||
[http2.constants.HTTP2_HEADER_CONTENT_TYPE]: 'text/plain' | ||
}, { | ||
[option]: types[type] | ||
}), | ||
{ | ||
type: TypeError, | ||
code: 'ERR_INVALID_OPT_VALUE', | ||
message: `The value "${String(types[type])}" is invalid ` + | ||
`for option "${option}"` | ||
} | ||
); | ||
}); | ||
}); | ||
|
||
// Should throw if :status 204, 205 or 304 | ||
[204, 205, 304].forEach((status) => common.expectsError( | ||
() => stream.respondWithFile(fname, { | ||
[http2.constants.HTTP2_HEADER_CONTENT_TYPE]: 'text/plain', | ||
':status': status, | ||
}), | ||
{ | ||
code: 'ERR_HTTP2_PAYLOAD_FORBIDDEN', | ||
message: `Responses with ${status} status must not have a payload` | ||
} | ||
)); | ||
|
||
// Should throw if headers already sent | ||
stream.respond({ | ||
':status': 200, | ||
}); | ||
common.expectsError( | ||
() => stream.respondWithFile(fname, { | ||
[http2.constants.HTTP2_HEADER_CONTENT_TYPE]: 'text/plain' | ||
}), | ||
{ | ||
code: 'ERR_HTTP2_HEADERS_SENT', | ||
message: 'Response has already been initiated.' | ||
} | ||
); | ||
|
||
// Should throw if stream already destroyed | ||
stream.destroy(); | ||
common.expectsError( | ||
() => stream.respondWithFile(fname, { | ||
[http2.constants.HTTP2_HEADER_CONTENT_TYPE]: 'text/plain' | ||
}), | ||
{ | ||
code: 'ERR_HTTP2_INVALID_STREAM', | ||
message: 'The stream has been destroyed' | ||
} | ||
); | ||
})); | ||
|
||
server.listen(0, common.mustCall(() => { | ||
const client = http2.connect(`http://localhost:${server.address().port}`); | ||
const req = client.request(); | ||
|
||
req.on('streamClosed', common.mustCall(() => { | ||
client.destroy(); | ||
server.close(); | ||
})); | ||
req.end(); | ||
})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
// Flags: --expose-http2 | ||
'use strict'; | ||
|
||
const common = require('../common'); | ||
if (!common.hasCrypto) | ||
common.skip('missing crypto'); | ||
const http2 = require('http2'); | ||
const path = require('path'); | ||
const fs = require('fs'); | ||
|
||
const optionsWithTypeError = { | ||
offset: 'number', | ||
length: 'number', | ||
statCheck: 'function', | ||
getTrailers: 'function' | ||
}; | ||
|
||
const types = { | ||
boolean: true, | ||
function: () => {}, | ||
number: 1, | ||
object: {}, | ||
array: [], | ||
null: null, | ||
symbol: Symbol('test') | ||
}; | ||
|
||
const fname = path.resolve(common.fixturesDir, 'elipses.txt'); | ||
const fd = fs.openSync(fname, 'r'); | ||
|
||
const server = http2.createServer(); | ||
|
||
server.on('stream', common.mustCall((stream) => { | ||
// should throw if fd isn't a number | ||
Object.keys(types).forEach((type) => { | ||
if (type === 'number') { | ||
return; | ||
} | ||
|
||
common.expectsError( | ||
() => stream.respondWithFD(types[type], { | ||
[http2.constants.HTTP2_HEADER_CONTENT_TYPE]: 'text/plain' | ||
}), | ||
{ | ||
type: TypeError, | ||
code: 'ERR_INVALID_ARG_TYPE', | ||
message: 'The "fd" argument must be of type number' | ||
} | ||
); | ||
}); | ||
|
||
// Check for all possible TypeError triggers on options | ||
Object.keys(optionsWithTypeError).forEach((option) => { | ||
Object.keys(types).forEach((type) => { | ||
if (type === optionsWithTypeError[option]) { | ||
return; | ||
} | ||
|
||
common.expectsError( | ||
() => stream.respondWithFD(fd, { | ||
[http2.constants.HTTP2_HEADER_CONTENT_TYPE]: 'text/plain' | ||
}, { | ||
[option]: types[type] | ||
}), | ||
{ | ||
type: TypeError, | ||
code: 'ERR_INVALID_OPT_VALUE', | ||
message: `The value "${String(types[type])}" is invalid ` + | ||
`for option "${option}"` | ||
} | ||
); | ||
}); | ||
}); | ||
|
||
// Should throw if :status 204, 205 or 304 | ||
[204, 205, 304].forEach((status) => common.expectsError( | ||
() => stream.respondWithFD(fd, { | ||
[http2.constants.HTTP2_HEADER_CONTENT_TYPE]: 'text/plain', | ||
':status': status, | ||
}), | ||
{ | ||
code: 'ERR_HTTP2_PAYLOAD_FORBIDDEN', | ||
message: `Responses with ${status} status must not have a payload` | ||
} | ||
)); | ||
|
||
// Should throw if headers already sent | ||
stream.respond({ | ||
':status': 200, | ||
}); | ||
common.expectsError( | ||
() => stream.respondWithFD(fd, { | ||
[http2.constants.HTTP2_HEADER_CONTENT_TYPE]: 'text/plain' | ||
}), | ||
{ | ||
code: 'ERR_HTTP2_HEADERS_SENT', | ||
message: 'Response has already been initiated.' | ||
} | ||
); | ||
|
||
// Should throw if stream already destroyed | ||
stream.destroy(); | ||
common.expectsError( | ||
() => stream.respondWithFD(fd, { | ||
[http2.constants.HTTP2_HEADER_CONTENT_TYPE]: 'text/plain' | ||
}), | ||
{ | ||
code: 'ERR_HTTP2_INVALID_STREAM', | ||
message: 'The stream has been destroyed' | ||
} | ||
); | ||
})); | ||
|
||
server.listen(0, common.mustCall(() => { | ||
const client = http2.connect(`http://localhost:${server.address().port}`); | ||
const req = client.request(); | ||
|
||
req.on('streamClosed', common.mustCall(() => { | ||
client.destroy(); | ||
server.close(); | ||
})); | ||
req.end(); | ||
})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Flags: --expose-http2 | ||
'use strict'; | ||
|
||
const common = require('../common'); | ||
if (!common.hasCrypto) | ||
common.skip('missing crypto'); | ||
const http2 = require('http2'); | ||
const assert = require('assert'); | ||
|
||
const server = http2.createServer(); | ||
|
||
// Check that stream ends immediately after respond on :status 204, 205 & 304 | ||
|
||
const status = [204, 205, 304]; | ||
|
||
server.on('stream', common.mustCall((stream) => { | ||
stream.on('streamClosed', common.mustCall(() => { | ||
assert.strictEqual(stream.destroyed, true); | ||
})); | ||
stream.respond({ ':status': status.shift() }); | ||
}, 3)); | ||
|
||
server.listen(0, common.mustCall(makeRequest)); | ||
|
||
function makeRequest() { | ||
const client = http2.connect(`http://localhost:${server.address().port}`); | ||
const req = client.request(); | ||
req.resume(); | ||
|
||
req.on('end', common.mustCall(() => { | ||
client.destroy(); | ||
|
||
if (!status.length) { | ||
server.close(); | ||
} else { | ||
makeRequest(); | ||
} | ||
})); | ||
req.end(); | ||
} |