mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
http2: make writeHead behave like HTTP/1.
PR-URL: https://github.com/nodejs/node/pull/14239 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
committed by
James M Snell
parent
a4017736d2
commit
78cd5fedd5
@@ -2402,7 +2402,7 @@ buffer. Returns `false` if all or part of the data was queued in user memory.
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
Does nothing. Added for parity with [HTTP/1]().
|
||||
Throws an error as the `'continue'` flow is not current implemented. Added for parity with [HTTP/1]().
|
||||
|
||||
### response.writeHead(statusCode[, statusMessage][, headers])
|
||||
<!-- YAML
|
||||
|
||||
@@ -386,11 +386,6 @@ class Http2ServerResponse extends Stream {
|
||||
headers[name] = String(value);
|
||||
}
|
||||
|
||||
flushHeaders() {
|
||||
if (this[kStream].headersSent === false)
|
||||
this[kBeginSend]();
|
||||
}
|
||||
|
||||
get statusMessage() {
|
||||
if (statusMessageWarned === false) {
|
||||
process.emitWarning(
|
||||
@@ -403,6 +398,11 @@ class Http2ServerResponse extends Stream {
|
||||
return '';
|
||||
}
|
||||
|
||||
flushHeaders() {
|
||||
if (this[kStream].headersSent === false)
|
||||
this[kBeginSend]();
|
||||
}
|
||||
|
||||
writeHead(statusCode, statusMessage, headers) {
|
||||
if (typeof statusMessage === 'string' && statusMessageWarned === false) {
|
||||
process.emitWarning(
|
||||
@@ -414,6 +414,12 @@ class Http2ServerResponse extends Stream {
|
||||
if (headers === undefined && typeof statusMessage === 'object') {
|
||||
headers = statusMessage;
|
||||
}
|
||||
|
||||
const stream = this[kStream];
|
||||
if (stream.headersSent === true) {
|
||||
throw new errors.Error('ERR_HTTP2_INFO_HEADERS_AFTER_RESPOND');
|
||||
}
|
||||
|
||||
if (headers) {
|
||||
const keys = Object.keys(headers);
|
||||
let key = '';
|
||||
@@ -422,8 +428,9 @@ class Http2ServerResponse extends Stream {
|
||||
this.setHeader(key, headers[key]);
|
||||
}
|
||||
}
|
||||
|
||||
this.statusCode = statusCode;
|
||||
// TODO mcollina this should probably call sendInfo
|
||||
this[kBeginSend]();
|
||||
}
|
||||
|
||||
write(chunk, encoding, cb) {
|
||||
@@ -487,26 +494,6 @@ class Http2ServerResponse extends Stream {
|
||||
stream.setTimeout(msecs, callback);
|
||||
}
|
||||
|
||||
sendContinue(headers) {
|
||||
this.sendInfo(100, headers);
|
||||
}
|
||||
|
||||
sendInfo(code, headers) {
|
||||
const stream = this[kStream];
|
||||
if (stream.headersSent === true) {
|
||||
throw new errors.Error('ERR_HTTP2_INFO_HEADERS_AFTER_RESPOND');
|
||||
}
|
||||
if (headers && typeof headers !== 'object')
|
||||
throw new errors.TypeError('ERR_HTTP2_HEADERS_OBJECT');
|
||||
if (stream === undefined) return;
|
||||
code |= 0;
|
||||
if (code < 100 || code >= 200)
|
||||
throw new errors.RangeError('ERR_HTTP2_INVALID_INFO_STATUS', code);
|
||||
|
||||
headers[constants.HTTP2_HEADER_STATUS] = code;
|
||||
stream.respond(headers);
|
||||
}
|
||||
|
||||
createPushResponse(headers, callback) {
|
||||
const stream = this[kStream];
|
||||
if (stream === undefined) {
|
||||
@@ -544,9 +531,9 @@ class Http2ServerResponse extends Stream {
|
||||
this.emit('finish');
|
||||
}
|
||||
|
||||
// added for parity with HTTP/1
|
||||
writeContinue() {
|
||||
// TODO mcollina this should probably be sendContinue
|
||||
// TODO mcollina check what is the continue flow
|
||||
throw new Error('not implemented yet');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,6 @@ const {
|
||||
const server = createServer(mustCall((request, response) => {
|
||||
strictEqual(response.finished, true);
|
||||
response.writeHead(HTTP_STATUS_OK, { foo: 'bar' });
|
||||
response.flushHeaders();
|
||||
response.end(mustNotCall());
|
||||
}));
|
||||
server.listen(0, mustCall(() => {
|
||||
|
||||
@@ -7,18 +7,24 @@ const h2 = require('http2');
|
||||
|
||||
// Http2ServerResponse.flushHeaders
|
||||
|
||||
let serverResponse;
|
||||
|
||||
const server = h2.createServer();
|
||||
server.listen(0, common.mustCall(function() {
|
||||
const port = server.address().port;
|
||||
server.once('request', common.mustCall(function(request, response) {
|
||||
response.flushHeaders();
|
||||
response.flushHeaders(); // Idempotent
|
||||
response.writeHead(400, { 'foo-bar': 'abc123' }); // Ignored
|
||||
common.expectsError(() => {
|
||||
response.writeHead(400, { 'foo-bar': 'abc123' });
|
||||
}, {
|
||||
code: 'ERR_HTTP2_INFO_HEADERS_AFTER_RESPOND'
|
||||
});
|
||||
|
||||
response.on('finish', common.mustCall(function() {
|
||||
server.close();
|
||||
}));
|
||||
response.end();
|
||||
serverResponse = response;
|
||||
}));
|
||||
|
||||
const url = `http://localhost:${port}`;
|
||||
@@ -33,6 +39,7 @@ server.listen(0, common.mustCall(function() {
|
||||
request.on('response', common.mustCall(function(headers, flags) {
|
||||
assert.strictEqual(headers['foo-bar'], undefined);
|
||||
assert.strictEqual(headers[':status'], 200);
|
||||
serverResponse.end();
|
||||
}, 1));
|
||||
request.on('end', common.mustCall(function() {
|
||||
client.destroy();
|
||||
|
||||
@@ -12,11 +12,13 @@ server.listen(0, common.mustCall(function() {
|
||||
const port = server.address().port;
|
||||
server.once('request', common.mustCall(function(request, response) {
|
||||
response.setHeader('foo-bar', 'def456');
|
||||
response.writeHead(500);
|
||||
response.writeHead(418, { 'foo-bar': 'abc123' }); // Override
|
||||
|
||||
common.expectsError(() => { response.writeHead(300); }, {
|
||||
code: 'ERR_HTTP2_INFO_HEADERS_AFTER_RESPOND'
|
||||
});
|
||||
|
||||
response.on('finish', common.mustCall(function() {
|
||||
assert.doesNotThrow(() => { response.writeHead(300); });
|
||||
server.close();
|
||||
}));
|
||||
response.end();
|
||||
|
||||
Reference in New Issue
Block a user