-
-
Notifications
You must be signed in to change notification settings - Fork 33.6k
Closed
Labels
http2Issues or PRs related to the http2 subsystem.Issues or PRs related to the http2 subsystem.invalidIssues and PRs that are invalid.Issues and PRs that are invalid.
Description
- Version: v10.0.0-pre
- Platform: N/A
- Subsystem: http2
I came across this issue while writing unit tests for stream.respond() in PR #18861
The method respondWithFile() does not set state.flags, thus headersSent is still set to false:
node/lib/internal/http2/core.js
Lines 2267 to 2321 in 472cde6
| respondWithFile(path, headers, options) { | |
| if (this.destroyed || this.closed) | |
| throw new errors.Error('ERR_HTTP2_INVALID_STREAM'); | |
| if (this.headersSent) | |
| throw new errors.Error('ERR_HTTP2_HEADERS_SENT'); | |
| assertIsObject(options, 'options'); | |
| options = Object.assign({}, options); | |
| if (options.offset !== undefined && typeof options.offset !== 'number') | |
| throw new errors.TypeError('ERR_INVALID_OPT_VALUE', | |
| 'offset', | |
| options.offset); | |
| if (options.length !== undefined && typeof options.length !== 'number') | |
| throw new errors.TypeError('ERR_INVALID_OPT_VALUE', | |
| 'length', | |
| options.length); | |
| if (options.statCheck !== undefined && | |
| typeof options.statCheck !== 'function') { | |
| throw new errors.TypeError('ERR_INVALID_OPT_VALUE', | |
| 'statCheck', | |
| options.statCheck); | |
| } | |
| let streamOptions = 0; | |
| if (options.getTrailers !== undefined) { | |
| if (typeof options.getTrailers !== 'function') { | |
| throw new errors.TypeError('ERR_INVALID_OPT_VALUE', | |
| 'getTrailers', | |
| options.getTrailers); | |
| } | |
| streamOptions |= STREAM_OPTION_GET_TRAILERS; | |
| this[kState].getTrailers = options.getTrailers; | |
| } | |
| const session = this[kSession]; | |
| debug(`Http2Stream ${this[kID]} [Http2Session ` + | |
| `${sessionName(session[kType])}]: initiating response`); | |
| this[kUpdateTimer](); | |
| headers = processHeaders(headers); | |
| const statusCode = headers[HTTP2_HEADER_STATUS] |= 0; | |
| // Payload/DATA frames are not permitted in these cases | |
| if (statusCode === HTTP_STATUS_NO_CONTENT || | |
| statusCode === HTTP_STATUS_RESET_CONTENT || | |
| statusCode === HTTP_STATUS_NOT_MODIFIED) { | |
| throw new errors.Error('ERR_HTTP2_PAYLOAD_FORBIDDEN', statusCode); | |
| } | |
| fs.open(path, 'r', | |
| afterOpen.bind(this, session, options, headers, streamOptions)); | |
| } |
This looks like a bug as both respond() and respondWithFD() set state.flags so that headersSent is set to true.
Metadata
Metadata
Assignees
Labels
http2Issues or PRs related to the http2 subsystem.Issues or PRs related to the http2 subsystem.invalidIssues and PRs that are invalid.Issues and PRs that are invalid.