| respondWithFile(path,headers,options){ |
| if(this.destroyed||this.closed) |
| thrownewerrors.Error('ERR_HTTP2_INVALID_STREAM'); |
| if(this.headersSent) |
| thrownewerrors.Error('ERR_HTTP2_HEADERS_SENT'); |
| |
| assertIsObject(options,'options'); |
| options=Object.assign({},options); |
| |
| if(options.offset!==undefined&&typeofoptions.offset!=='number') |
| thrownewerrors.TypeError('ERR_INVALID_OPT_VALUE', |
| 'offset', |
| options.offset); |
| |
| if(options.length!==undefined&&typeofoptions.length!=='number') |
| thrownewerrors.TypeError('ERR_INVALID_OPT_VALUE', |
| 'length', |
| options.length); |
| |
| if(options.statCheck!==undefined&& |
| typeofoptions.statCheck!=='function'){ |
| thrownewerrors.TypeError('ERR_INVALID_OPT_VALUE', |
| 'statCheck', |
| options.statCheck); |
| } |
| |
| letstreamOptions=0; |
| if(options.getTrailers!==undefined){ |
| if(typeofoptions.getTrailers!=='function'){ |
| thrownewerrors.TypeError('ERR_INVALID_OPT_VALUE', |
| 'getTrailers', |
| options.getTrailers); |
| } |
| streamOptions|=STREAM_OPTION_GET_TRAILERS; |
| this[kState].getTrailers=options.getTrailers; |
| } |
| |
| constsession=this[kSession]; |
| debug(`Http2Stream ${this[kID]} [Http2Session `+ |
| `${sessionName(session[kType])}]: initiating response`); |
| this[kUpdateTimer](); |
| |
| |
| headers=processHeaders(headers); |
| conststatusCode=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){ |
| thrownewerrors.Error('ERR_HTTP2_PAYLOAD_FORBIDDEN',statusCode); |
| } |
| |
| fs.open(path,'r', |
| afterOpen.bind(this,session,options,headers,streamOptions)); |
| } |
I came across this issue while writing unit tests for
stream.respond()in PR #18861The method
respondWithFile()does not setstate.flags, thusheadersSentis still set to false:node/lib/internal/http2/core.js
Lines 2267 to 2321 in 472cde6
This looks like a bug as both
respond()andrespondWithFD()setstate.flagsso thatheadersSentis set to true.