HttpResponseStream doesn't work when `end`ing the stream without a `write`

Ouverte
#97 1 commentaire 2 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Évaluation

Difficulté
3/5
Temps estimé
1-2 jours
Accessibilité débutants
38/100
Type d'issue
Bug
Clarté
Plutôt claire
Activité
À l'abandon
Stack technique
aws, node.js, typescript
Domaine
api, backend

Piste de recherche

Commencez par lire src/HttpResponseStream.js, en particulier la gestion de onBeforeFirstWrite, puis suivez le chemin de fin de Node ClientRequest décrit dans l’issue. Reproduisez à la fois le cas responseStream.end("Not Found") et le cas responseStream.end(), et vérifiez que le code d’état personnalisé et les en-têtes sont appliqués dans chaque cas.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

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:

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's write:

// https://github.com/aws/aws-lambda-base-images/tree/nodejs18.x -> /var/runtime/index.mjs
req.write = function(chunk, encoding, callback) {
  vvverbose("ResponseStream::write", chunk.length, "callback:", typeof callback);
  if (typeof chunk !== "string" && !Buffer.isBuffer(chunk) && chunk?.constructor !== Uint8Array) {
    chunk = JSON.stringify(chunk);
  }
  if (status === STATUS_READY && typeof this._onBeforeFirstWrite === "function") {
    this._onBeforeFirstWrite((ch) => origWrite(ch));
  }
  const ret = origWrite(chunk, encoding, callback);
  // [snip]

But turns out Node's ClientRequest doesn't call write when ending the stream with a final chunk of data, it calls an internal write_ 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:

If data is specified, it is equivalent to calling request.write(data, encoding) followed by request.end(callback).

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().

Langage dominant
TypeScript
Étoiles
224
Forks
60
Merge moyen
26 min
PR mergées (30 j)
2

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de aws/aws-lambda-nodejs-runtime-interface-client

Toutes les issues de aws/aws-lambda-nodejs-runtime-interface-client

Issues similaires

Plus d'issues TypeScript

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.