@jaypie/express 1.2.11 → 1.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -55,18 +55,21 @@ class LambdaRequest extends node_stream.Readable {
55
55
  remoteAddress: options.remoteAddress,
56
56
  };
57
57
  this.connection = this.socket;
58
- // Schedule body push for next tick to ensure stream is ready
59
- // This is needed for body parsers that consume the stream
60
- if (this.bodyBuffer && this.bodyBuffer.length > 0) {
61
- process.nextTick(() => {
62
- if (!this.bodyPushed) {
58
+ // Schedule body push for next tick to ensure stream is ready.
59
+ // This is needed for body parsers that consume the stream.
60
+ // CRITICAL: Always schedule the push, even for empty bodies, to ensure
61
+ // the stream emits 'end'. Otherwise, middleware that waits for the request
62
+ // stream to end (like body parsers) will hang forever on GET requests.
63
+ process.nextTick(() => {
64
+ if (!this.bodyPushed) {
65
+ if (this.bodyBuffer && this.bodyBuffer.length > 0) {
63
66
  this.push(this.bodyBuffer);
64
- this.push(null);
65
- this.bodyPushed = true;
66
- this.complete = true;
67
67
  }
68
- });
69
- }
68
+ this.push(null); // Signal end of stream
69
+ this.bodyPushed = true;
70
+ this.complete = true;
71
+ }
72
+ });
70
73
  }
71
74
  //
72
75
  // Readable stream implementation
@@ -1613,15 +1616,22 @@ function safeSendJson(res, statusCode, data) {
1613
1616
  }
1614
1617
  // Fall back to standard Express methods for real responses
1615
1618
  res.status(statusCode);
1616
- // CRITICAL: For Lambda streaming responses, flush headers before send to
1617
- // initialize the stream wrapper. This ensures the status code is captured
1618
- // before any writes occur (which would auto-flush with default 200).
1619
+ // CRITICAL: For Lambda streaming responses, set content-type BEFORE flushing
1620
+ // headers, then flush to initialize the stream wrapper with all headers.
1619
1621
  // Uses Symbol marker for reliable detection that survives prototype manipulation.
1620
- if (isLambdaStreamingResponse(res) &&
1621
- typeof res.flushHeaders === "function") {
1622
- res.flushHeaders();
1622
+ if (isLambdaStreamingResponse(res)) {
1623
+ // Set content-type before flushing so it's included in the metadata
1624
+ res.setHeader("content-type", "application/json");
1625
+ if (typeof res.flushHeaders === "function") {
1626
+ res.flushHeaders();
1627
+ }
1628
+ // Write JSON directly and end the stream (don't call res.json which would
1629
+ // try to set content-type again after headers are already sent)
1630
+ res.end(JSON.stringify(data));
1631
+ }
1632
+ else {
1633
+ res.json(data);
1623
1634
  }
1624
- res.json(data);
1625
1635
  }
1626
1636
  /**
1627
1637
  * Safely send a response body, avoiding dd-trace interception.
@@ -1653,15 +1663,25 @@ function safeSend(res, statusCode, body) {
1653
1663
  // initialize the stream wrapper. This ensures the status code is captured
1654
1664
  // before any writes occur (which would auto-flush with default 200).
1655
1665
  // Uses Symbol marker for reliable detection that survives prototype manipulation.
1656
- if (isLambdaStreamingResponse(res) &&
1657
- typeof res.flushHeaders === "function") {
1658
- res.flushHeaders();
1659
- }
1660
- if (body !== undefined) {
1661
- res.send(body);
1666
+ if (isLambdaStreamingResponse(res)) {
1667
+ if (typeof res.flushHeaders === "function") {
1668
+ res.flushHeaders();
1669
+ }
1670
+ // Write directly to stream and end (bypass Express send middleware)
1671
+ if (body !== undefined) {
1672
+ res.end(body);
1673
+ }
1674
+ else {
1675
+ res.end();
1676
+ }
1662
1677
  }
1663
1678
  else {
1664
- res.send();
1679
+ if (body !== undefined) {
1680
+ res.send(body);
1681
+ }
1682
+ else {
1683
+ res.send();
1684
+ }
1665
1685
  }
1666
1686
  }
1667
1687
  function expressHandler(handlerOrOptions, optionsOrHandler) {