Skip to content

UnhandledPromiseRejection: Improper headers on http2 response #3830

Closed
@FallingSnow

Description

@FallingSnow

Are you sure this is an issue with the hapi core module or are you just looking for some help?

Issue with hapi core.

Is this a security related issue?

No.

What are you trying to achieve or the steps to reproduce?

Make a http2 request that triggers the following:

!(isInjection || request._core.started) ||
(request._isPayloadPending && !request.raw.req._readableState.ended)

What was the result you received?

No response to request.

(node:8018) UnhandledPromiseRejectionWarning: TypeError [ERR_HTTP2_INVALID_CONNECTION_HEADERS]: HTTP/1 Connection specific headers are forbidden: "connection"
    at mapToHeaders (internal/http2/util.js:453:16)
    at ServerHttp2Stream.respond (internal/http2/core.js:2273:25)
    at Http2ServerResponse.[begin-send] (internal/http2/compat.js:691:19)
    at Http2ServerResponse.writeHead (internal/http2/compat.js:589:21)
    at Object.internals.writeHead ([redacted]/server/node_modules/hapi/lib/transmit.js:340:13)
    at Object.internals.transmit ([redacted]/server/node_modules/hapi/lib/transmit.js:105:15)
    at Object.internals.fail ([redacted]/server/node_modules/hapi/lib/transmit.js:79:22)
    at process._tickCallback (internal/process/next_tick.js:68:7)

What did you expect?

A response of some kind, if this error was handled, an error response.

Context

Fix

From MDN:

Also, Connection and Keep-Alive are ignored in HTTP/2; connection management is handled by other mechanisms there.

Replace:

hapi/lib/transmit.js

Lines 96 to 101 in 7ffd301

const isInjection = Shot.isInjection(request.raw.req);
if (!(isInjection || request._core.started) ||
(request._isPayloadPending && !request.raw.req._readableState.ended)) {
response._header('connection', 'close');
}

With:

const isH2 = request.httpVersion === '2.0';
const isInjection = Shot.isInjection(request.raw.req);
if (!isH2 && (!(isInjection || request._core.started) ||
   (request._isPayloadPending && !request.raw.req._readableState.ended))) {

   response._header('connection', 'close');
}

Afterthoughts

Should this even be allowed to happen? This would suggest that somewhere along the response chain a possible error is not accounted for. What should have really happened is an internal error response to the client and an error message to the console stating: TypeError [ERR_HTTP2_INVALID_CONNECTION_HEADERS]: HTTP/1 Connection specific headers are forbidden: "connection".

Metadata

Metadata

Assignees

Labels

bugBug or defect

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions