From d969f962341b416af6606f36b15651e0b8f1353f Mon Sep 17 00:00:00 2001 From: Mehmet Mert Yildiran Date: Wed, 6 May 2020 14:58:38 +0300 Subject: [PATCH] Copy the properties of http.IncomingMessage.prototype to request object by deep cloning --- .gitignore | 1 + .../lib/__tests__/compatLayer.request.test.js | 30 +++++++++++++++++++ .../apigw-lambda-compat/lib/compatLayer.js | 4 ++- .../next-aws-cloudfront.request.test.js | 30 +++++++++++++++++++ .../next-aws-cloudfront.js | 4 ++- .../lambda-at-edge-compat/package-lock.json | 2 +- 6 files changed, 68 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 31598a0966..3015fb6399 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ sls-next-build .DS_Store yarn.lock dist +.vscode diff --git a/packages/apigw-lambda-compat/lib/__tests__/compatLayer.request.test.js b/packages/apigw-lambda-compat/lib/__tests__/compatLayer.request.test.js index 1851487a4f..1f3a91f7d4 100644 --- a/packages/apigw-lambda-compat/lib/__tests__/compatLayer.request.test.js +++ b/packages/apigw-lambda-compat/lib/__tests__/compatLayer.request.test.js @@ -1,4 +1,5 @@ const create = require("../compatLayer"); +const http = require("http"); describe("compatLayer.request", () => { it("request url path", () => { @@ -276,4 +277,33 @@ describe("compatLayer.request", () => { expect(req.connection).toEqual({}); done(); }); + + it("request preserve http.IncomingMessage.prototype property", () => { + const exampleProperty = "I'm an example property"; + http.IncomingMessage.prototype.exampleProperty = exampleProperty; + const { req } = create({ + requestContext: { + path: "" + } + }); + + expect(typeof req.exampleProperty !== "undefined").toEqual(true); + expect(req.exampleProperty).toEqual(exampleProperty); + }); + + it("request preserve http.IncomingMessage.prototype function", () => { + const exampleFunction = function() { + return "I'm an example function."; + }; + http.IncomingMessage.prototype.exampleFunction = exampleFunction; + const { req } = create({ + requestContext: { + path: "" + } + }); + + expect(typeof req.exampleFunction === "function").toEqual(true); + expect(req.exampleFunction()).toEqual(exampleFunction()); + expect(req.exampleFunction.toString()).toEqual(exampleFunction.toString()); + }); }); diff --git a/packages/apigw-lambda-compat/lib/compatLayer.js b/packages/apigw-lambda-compat/lib/compatLayer.js index 2bc3375bdc..fab8828972 100644 --- a/packages/apigw-lambda-compat/lib/compatLayer.js +++ b/packages/apigw-lambda-compat/lib/compatLayer.js @@ -1,5 +1,6 @@ const Stream = require("stream"); const queryString = require("querystring"); +const http = require("http"); const reqResMapper = (event, callback) => { const base64Support = process.env.BINARY_SUPPORT === "yes"; @@ -11,7 +12,8 @@ const reqResMapper = (event, callback) => { }; let responsePromise; - const req = new Stream.Readable(); + const newStream = new Stream.Readable(); + const req = Object.assign(newStream, http.IncomingMessage.prototype); req.url = (event.requestContext.path || event.path || "").replace( new RegExp("^/" + event.requestContext.stage), diff --git a/packages/lambda-at-edge-compat/__tests__/next-aws-cloudfront.request.test.js b/packages/lambda-at-edge-compat/__tests__/next-aws-cloudfront.request.test.js index 8974e82f19..a42145d250 100644 --- a/packages/lambda-at-edge-compat/__tests__/next-aws-cloudfront.request.test.js +++ b/packages/lambda-at-edge-compat/__tests__/next-aws-cloudfront.request.test.js @@ -1,4 +1,5 @@ const create = require("../next-aws-cloudfront"); +const http = require("http"); const { SPECIAL_NODE_HEADERS } = create; @@ -194,4 +195,33 @@ describe("Request Tests", () => { expect(req.connection).toEqual({}); done(); }); + + it("request preserve http.IncomingMessage.prototype property", () => { + const exampleProperty = "I'm an example property"; + http.IncomingMessage.prototype.exampleProperty = exampleProperty; + const { req } = create({ + request: { + uri: "" + } + }); + + expect(typeof req.exampleProperty !== "undefined").toEqual(true); + expect(req.exampleProperty).toEqual(exampleProperty); + }); + + it("request preserve http.IncomingMessage.prototype function", () => { + const exampleFunction = function() { + return "I'm an example function."; + }; + http.IncomingMessage.prototype.exampleFunction = exampleFunction; + const { req } = create({ + request: { + uri: "" + } + }); + + expect(typeof req.exampleFunction === "function").toEqual(true); + expect(req.exampleFunction()).toEqual(exampleFunction()); + expect(req.exampleFunction.toString()).toEqual(exampleFunction.toString()); + }); }); diff --git a/packages/lambda-at-edge-compat/next-aws-cloudfront.js b/packages/lambda-at-edge-compat/next-aws-cloudfront.js index b0f848c01b..b19efd9a8b 100644 --- a/packages/lambda-at-edge-compat/next-aws-cloudfront.js +++ b/packages/lambda-at-edge-compat/next-aws-cloudfront.js @@ -1,5 +1,6 @@ const Stream = require("stream"); const zlib = require("zlib"); +const http = require("http"); const specialNodeHeaders = [ "age", @@ -89,7 +90,8 @@ const handler = event => { headers: {} }; - const req = new Stream.Readable(); + const newStream = new Stream.Readable(); + const req = Object.assign(newStream, http.IncomingMessage.prototype); req.url = cfRequest.uri; req.method = cfRequest.method; req.rawHeaders = []; diff --git a/packages/lambda-at-edge-compat/package-lock.json b/packages/lambda-at-edge-compat/package-lock.json index 620b8c05c6..c7fd5c6e65 100644 --- a/packages/lambda-at-edge-compat/package-lock.json +++ b/packages/lambda-at-edge-compat/package-lock.json @@ -6,7 +6,7 @@ "dependencies": { "@types/aws-lambda": { "version": "8.10.50", - "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.50.tgz", + "resolved": false, "integrity": "sha512-RDzmQ5mO1f0BViKiuOudENZmoCACEa461nTRVtxhsAiEqGCgwdhCYN0aFgk42X5+ELAiqJKbv2mK0LkopYRYQg==", "dev": true }