When using HttpResponseStream to set the status code and headers on a streaming response, I noticed that if I never call write on the stream, the custom status code and headers don't work.
Example repro:
export const handler = awslambda.streamifyResponse(
async (event, responseStream, context) => {
const metadata = {
statusCode: 404,
headers: { "Content-Type": "text/plain", "X-Foo": "Bar" }
};
responseStream = awslambda.HttpResponseStream.from(responseStream, metadata);
// This will cause a 502 with no custom response headers:
responseStream.end("Not Found");
// This will cause a 200 with no custom response headers:
responseStream.end();
}
);
I believe this is because HttpResponseStream relies on the onBeforeFirstWrite callback:
When using
HttpResponseStream
to set the status code and headers on a streaming response, I noticed that if I never callwrite
on the stream, the custom status code and headers don't work.Example repro:
I believe this is because
HttpResponseStream
relies on theonBeforeFirstWrite
callback:https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/blob/7374a4e338fc3b070811d55ee337740f3f6cb382/src/HttpResponseStream.js#L22-L27
onBeforeFirstWrite
is implemented by overriding http.ClientRequest stream'swrite
:But turns out Node's
ClientRequest
doesn't callwrite
whenend
ing the stream with a finalchunk
of data, it calls an internalwrite_
instead:https://github.com/nodejs/node/blob/544cfc5ef151bca8d625fbccc581200a77b00bc0/lib/_http_outgoing.js#L1106
I guess this could also be considered a Node bug, because their documentation for
ClientRequest.end
says:But even if it did implement that contract correctly, there's still the case of ending the stream with no data, i.e.,
responseStream.end()
.