From 76a9d8d6dc2b971f63df19d805c7ab656540525b Mon Sep 17 00:00:00 2001 From: Steven Chim <655241+chimurai@users.noreply.github.com> Date: Mon, 7 Apr 2025 22:02:18 +0200 Subject: [PATCH 1/5] fix(fixRequestBody): prevent multiple .write() calls (#1090) * fix(fixRequestBody): prevent multiple .write() calls * ci(github-actions): bump actions and node versions --- .github/workflows/ci.yml | 30 +++++++++++++++--------------- src/handlers/fix-request-body.ts | 11 +++++++---- test/unit/fix-request-body.spec.ts | 15 +++++++++++++++ 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 42160f48..7e196d88 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,13 +8,13 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Use Node.js 16.x - uses: actions/setup-node@v2 + - uses: actions/checkout@v4 + - name: Use Node.js 22.x + uses: actions/setup-node@v4 with: - node-version: 16.x + node-version: 22.x - - uses: actions/cache@v2 + - uses: actions/cache@v4 id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) with: path: '**/node_modules' @@ -38,16 +38,16 @@ jobs: strategy: matrix: - node-version: [12.x, 14.x, 16.x] + node-version: [18.x, 20.x, 22.x] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - - uses: actions/cache@v2 + - uses: actions/cache@v4 id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) with: path: '**/node_modules' @@ -70,13 +70,13 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Use Node.js 16.x - uses: actions/setup-node@v2 + - uses: actions/checkout@v4 + - name: Use Node.js 22.x + uses: actions/setup-node@v4 with: - node-version: 16.x + node-version: 22.x - - uses: actions/cache@v2 + - uses: actions/cache@v4 id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) with: path: '**/node_modules' @@ -100,7 +100,7 @@ jobs: name: Spellcheck runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: streetsidesoftware/cspell-action@main with: # Github token used to fetch the list of changed files in the commit. diff --git a/src/handlers/fix-request-body.ts b/src/handlers/fix-request-body.ts index 0f45a2f7..bfd4cce1 100644 --- a/src/handlers/fix-request-body.ts +++ b/src/handlers/fix-request-body.ts @@ -13,17 +13,20 @@ export function fixRequestBody(proxyReq: http.ClientRequest, req: http.IncomingM } const contentType = proxyReq.getHeader('Content-Type') as string; + + if (!contentType) { + return; + } + const writeBody = (bodyData: string) => { // deepcode ignore ContentLengthInCode: bodyParser fix proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData)); proxyReq.write(bodyData); }; - if (contentType && contentType.includes('application/json')) { + if (contentType.includes('application/json')) { writeBody(JSON.stringify(requestBody)); - } - - if (contentType && contentType.includes('application/x-www-form-urlencoded')) { + } else if (contentType.includes('application/x-www-form-urlencoded')) { writeBody(querystring.stringify(requestBody)); } } diff --git a/test/unit/fix-request-body.spec.ts b/test/unit/fix-request-body.spec.ts index 5bc42f8c..4415b7e1 100644 --- a/test/unit/fix-request-body.spec.ts +++ b/test/unit/fix-request-body.spec.ts @@ -78,4 +78,19 @@ describe('fixRequestBody', () => { expect(proxyRequest.setHeader).toHaveBeenCalledWith('Content-Length', expectedBody.length); expect(proxyRequest.write).toHaveBeenCalledWith(expectedBody); }); + + it('should parse json and call write() once with incorrect content-type application/x-www-form-urlencoded+application/json', () => { + const proxyRequest = fakeProxyRequest(); + proxyRequest.setHeader('content-type', 'application/x-www-form-urlencoded+application/json'); + + jest.spyOn(proxyRequest, 'setHeader'); + jest.spyOn(proxyRequest, 'write'); + + fixRequestBody(proxyRequest, { body: { someField: 'some value' } } as Request); + + const expectedBody = JSON.stringify({ someField: 'some value' }); + expect(proxyRequest.setHeader).toHaveBeenCalledWith('Content-Length', expectedBody.length); + expect(proxyRequest.write).toHaveBeenCalledTimes(1); + expect(proxyRequest.write).toHaveBeenCalledWith(expectedBody); + }); }); From c50dd06d9102fbb81dd4cbad7a295dddee5f6e1e Mon Sep 17 00:00:00 2001 From: Steven Chim <655241+chimurai@users.noreply.github.com> Date: Wed, 9 Apr 2025 20:26:28 +0200 Subject: [PATCH 2/5] fix(fixRequestBody): handle invalid request (#1091) --- src/handlers/fix-request-body.ts | 35 ++++++++++++- test/unit/fix-request-body.spec.ts | 83 +++++++++++++++++++++++++++--- 2 files changed, 110 insertions(+), 8 deletions(-) diff --git a/src/handlers/fix-request-body.ts b/src/handlers/fix-request-body.ts index bfd4cce1..78fcd345 100644 --- a/src/handlers/fix-request-body.ts +++ b/src/handlers/fix-request-body.ts @@ -2,10 +2,20 @@ import type * as http from 'http'; import type { Request } from '../types'; import * as querystring from 'querystring'; +type HandleBadRequestArgs = { + proxyReq: http.ClientRequest; + req: http.IncomingMessage; + res: http.ServerResponse; +}; + /** * Fix proxied body if bodyParser is involved. */ -export function fixRequestBody(proxyReq: http.ClientRequest, req: http.IncomingMessage): void { +export function fixRequestBody( + proxyReq: http.ClientRequest, + req: http.IncomingMessage, + res: http.ServerResponse +): void { const requestBody = (req as Request).body; if (!requestBody) { @@ -18,6 +28,18 @@ export function fixRequestBody(proxyReq: http.ClientRequest, req: http.IncomingM return; } + // Handle bad request when unexpected "Connect: Upgrade" header is provided + if (/upgrade/gi.test(proxyReq.getHeader('Connection') as string)) { + handleBadRequest({ proxyReq, req, res }); + return; + } + + // Handle bad request when invalid request body is provided + if (hasInvalidKeys(requestBody)) { + handleBadRequest({ proxyReq, req, res }); + return; + } + const writeBody = (bodyData: string) => { // deepcode ignore ContentLengthInCode: bodyParser fix proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData)); @@ -30,3 +52,14 @@ export function fixRequestBody(proxyReq: http.ClientRequest, req: http.IncomingM writeBody(querystring.stringify(requestBody)); } } + +function hasInvalidKeys(obj) { + return Object.keys(obj).some((key) => /[\n\r]/.test(key)); +} + +function handleBadRequest({ proxyReq, req, res }: HandleBadRequestArgs) { + res.writeHead(400); + res.end('Bad Request'); + proxyReq.destroy(); + req.destroy(); +} diff --git a/test/unit/fix-request-body.spec.ts b/test/unit/fix-request-body.spec.ts index 4415b7e1..e95e2045 100644 --- a/test/unit/fix-request-body.spec.ts +++ b/test/unit/fix-request-body.spec.ts @@ -1,4 +1,5 @@ -import { ClientRequest } from 'http'; +import { Socket } from 'net'; +import { ClientRequest, ServerResponse, IncomingMessage } from 'http'; import * as querystring from 'querystring'; import { fixRequestBody } from '../../src/handlers/fix-request-body'; @@ -11,6 +12,11 @@ const fakeProxyRequest = () => { return proxyRequest; }; +const fakeProxyResponse = (): ServerResponse => { + const res = new ServerResponse(new IncomingMessage(new Socket())); + return res; +}; + describe('fixRequestBody', () => { it('should not write when body is undefined', () => { const proxyRequest = fakeProxyRequest(); @@ -18,7 +24,7 @@ describe('fixRequestBody', () => { jest.spyOn(proxyRequest, 'setHeader'); jest.spyOn(proxyRequest, 'write'); - fixRequestBody(proxyRequest, { body: undefined } as Request); + fixRequestBody(proxyRequest, { body: undefined } as Request, fakeProxyResponse()); expect(proxyRequest.setHeader).not.toHaveBeenCalled(); expect(proxyRequest.write).not.toHaveBeenCalled(); @@ -31,7 +37,7 @@ describe('fixRequestBody', () => { jest.spyOn(proxyRequest, 'setHeader'); jest.spyOn(proxyRequest, 'write'); - fixRequestBody(proxyRequest, { body: {} } as Request); + fixRequestBody(proxyRequest, { body: {} } as Request, fakeProxyResponse()); expect(proxyRequest.setHeader).toHaveBeenCalled(); expect(proxyRequest.write).toHaveBeenCalled(); @@ -44,7 +50,11 @@ describe('fixRequestBody', () => { jest.spyOn(proxyRequest, 'setHeader'); jest.spyOn(proxyRequest, 'write'); - fixRequestBody(proxyRequest, { body: { someField: 'some value' } } as Request); + fixRequestBody( + proxyRequest, + { body: { someField: 'some value' } } as Request, + fakeProxyResponse() + ); const expectedBody = JSON.stringify({ someField: 'some value' }); expect(proxyRequest.setHeader).toHaveBeenCalledWith('Content-Length', expectedBody.length); @@ -58,7 +68,11 @@ describe('fixRequestBody', () => { jest.spyOn(proxyRequest, 'setHeader'); jest.spyOn(proxyRequest, 'write'); - fixRequestBody(proxyRequest, { body: { someField: 'some value' } } as Request); + fixRequestBody( + proxyRequest, + { body: { someField: 'some value' } } as Request, + fakeProxyResponse() + ); const expectedBody = querystring.stringify({ someField: 'some value' }); expect(proxyRequest.setHeader).toHaveBeenCalledWith('Content-Length', expectedBody.length); @@ -72,7 +86,11 @@ describe('fixRequestBody', () => { jest.spyOn(proxyRequest, 'setHeader'); jest.spyOn(proxyRequest, 'write'); - fixRequestBody(proxyRequest, { body: { someField: 'some value' } } as Request); + fixRequestBody( + proxyRequest, + { body: { someField: 'some value' } } as Request, + fakeProxyResponse() + ); const expectedBody = querystring.stringify({ someField: 'some value' }); expect(proxyRequest.setHeader).toHaveBeenCalledWith('Content-Length', expectedBody.length); @@ -86,11 +104,62 @@ describe('fixRequestBody', () => { jest.spyOn(proxyRequest, 'setHeader'); jest.spyOn(proxyRequest, 'write'); - fixRequestBody(proxyRequest, { body: { someField: 'some value' } } as Request); + fixRequestBody( + proxyRequest, + { body: { someField: 'some value' } } as Request, + fakeProxyResponse() + ); const expectedBody = JSON.stringify({ someField: 'some value' }); expect(proxyRequest.setHeader).toHaveBeenCalledWith('Content-Length', expectedBody.length); expect(proxyRequest.write).toHaveBeenCalledTimes(1); expect(proxyRequest.write).toHaveBeenCalledWith(expectedBody); }); + + it('should return 400 and abort request on "Connection: Upgrade" header', () => { + const proxyRequest = fakeProxyRequest(); + const request = { body: { someField: 'some value' } } as Request; + + proxyRequest.destroy = jest.fn(); + request.destroy = jest.fn(); + + const proxyResponse = fakeProxyResponse(); + proxyRequest.setHeader('connection', 'upgrade'); + proxyRequest.setHeader('content-type', 'application/x-www-form-urlencoded'); + + jest.spyOn(proxyRequest, 'destroy'); + jest.spyOn(request, 'destroy'); + jest.spyOn(proxyResponse, 'writeHead'); + jest.spyOn(proxyResponse, 'end'); + + fixRequestBody(proxyRequest, request, proxyResponse); + + expect(proxyResponse.writeHead).toHaveBeenCalledWith(400); + expect(proxyResponse.end).toHaveBeenCalledTimes(1); + expect(proxyRequest.destroy).toHaveBeenCalledTimes(1); + expect(request.destroy).toHaveBeenCalledTimes(1); + }); + + it('should return 400 and abort request on invalid request data', () => { + const proxyRequest = fakeProxyRequest(); + const request = { body: { 'INVALID \n\r DATA': '' } } as Request; + + proxyRequest.destroy = jest.fn(); + request.destroy = jest.fn(); + + const proxyResponse = fakeProxyResponse(); + proxyRequest.setHeader('content-type', 'application/x-www-form-urlencoded'); + + jest.spyOn(proxyRequest, 'destroy'); + jest.spyOn(request, 'destroy'); + jest.spyOn(proxyResponse, 'writeHead'); + jest.spyOn(proxyResponse, 'end'); + + fixRequestBody(proxyRequest, request, proxyResponse); + + expect(proxyResponse.writeHead).toHaveBeenCalledWith(400); + expect(proxyResponse.end).toHaveBeenCalledTimes(1); + expect(proxyRequest.destroy).toHaveBeenCalledTimes(1); + expect(request.destroy).toHaveBeenCalledTimes(1); + }); }); From d03d51b54ac8d40db8438a8b216cf1ea92bb7849 Mon Sep 17 00:00:00 2001 From: Steven Chim <655241+chimurai@users.noreply.github.com> Date: Wed, 9 Apr 2025 21:30:36 +0200 Subject: [PATCH 3/5] chore(package): v2.0.8 (#1094) --- CHANGELOG.md | 5 +++++ README.md | 2 +- package.json | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de9c1b0f..22557406 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## [v2.0.8](https://github.com/chimurai/http-proxy-middleware/releases/tag/v2.0.8) + +- fix(fixRequestBody): prevent multiple .write() calls +- fix(fixRequestBody): handle invalid request + ## [v2.0.7](https://github.com/chimurai/http-proxy-middleware/releases/tag/v2.0.7) - ci(github actions): add publish.yml diff --git a/README.md b/README.md index 4eb8e111..31b2a081 100644 --- a/README.md +++ b/README.md @@ -595,4 +595,4 @@ $ yarn spellcheck The MIT License (MIT) -Copyright (c) 2015-2022 Steven Chim +Copyright (c) 2015-2025 Steven Chim diff --git a/package.json b/package.json index 329e6db2..56150637 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "http-proxy-middleware", - "version": "2.0.7", + "version": "2.0.8", "description": "The one-liner node.js proxy middleware for connect, express and browser-sync", "main": "dist/index.js", "types": "dist/index.d.ts", From d22d58764832fea429d60109a19e1a23136d4425 Mon Sep 17 00:00:00 2001 From: Steven Chim <655241+chimurai@users.noreply.github.com> Date: Thu, 10 Apr 2025 14:01:49 +0200 Subject: [PATCH 4/5] fix(fixRequestBody): check readableLength (#1097) --- src/handlers/fix-request-body.ts | 40 +++------------ test/unit/fix-request-body.spec.ts | 81 +++++++++--------------------- 2 files changed, 30 insertions(+), 91 deletions(-) diff --git a/src/handlers/fix-request-body.ts b/src/handlers/fix-request-body.ts index 78fcd345..2a19c880 100644 --- a/src/handlers/fix-request-body.ts +++ b/src/handlers/fix-request-body.ts @@ -2,20 +2,15 @@ import type * as http from 'http'; import type { Request } from '../types'; import * as querystring from 'querystring'; -type HandleBadRequestArgs = { - proxyReq: http.ClientRequest; - req: http.IncomingMessage; - res: http.ServerResponse; -}; - /** * Fix proxied body if bodyParser is involved. */ -export function fixRequestBody( - proxyReq: http.ClientRequest, - req: http.IncomingMessage, - res: http.ServerResponse -): void { +export function fixRequestBody(proxyReq: http.ClientRequest, req: http.IncomingMessage): void { + // skip fixRequestBody() when req.readableLength not 0 (bodyParser failure) + if (req.readableLength !== 0) { + return; + } + const requestBody = (req as Request).body; if (!requestBody) { @@ -28,18 +23,6 @@ export function fixRequestBody( return; } - // Handle bad request when unexpected "Connect: Upgrade" header is provided - if (/upgrade/gi.test(proxyReq.getHeader('Connection') as string)) { - handleBadRequest({ proxyReq, req, res }); - return; - } - - // Handle bad request when invalid request body is provided - if (hasInvalidKeys(requestBody)) { - handleBadRequest({ proxyReq, req, res }); - return; - } - const writeBody = (bodyData: string) => { // deepcode ignore ContentLengthInCode: bodyParser fix proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData)); @@ -52,14 +35,3 @@ export function fixRequestBody( writeBody(querystring.stringify(requestBody)); } } - -function hasInvalidKeys(obj) { - return Object.keys(obj).some((key) => /[\n\r]/.test(key)); -} - -function handleBadRequest({ proxyReq, req, res }: HandleBadRequestArgs) { - res.writeHead(400); - res.end('Bad Request'); - proxyReq.destroy(); - req.destroy(); -} diff --git a/test/unit/fix-request-body.spec.ts b/test/unit/fix-request-body.spec.ts index e95e2045..0348a2df 100644 --- a/test/unit/fix-request-body.spec.ts +++ b/test/unit/fix-request-body.spec.ts @@ -17,6 +17,13 @@ const fakeProxyResponse = (): ServerResponse => { return res; }; +const createRequestWithBody = (body: unknown): Request => { + const req = new IncomingMessage(new Socket()) as Request; + req.url = '/test_path'; + req.body = body; + return req; +}; + describe('fixRequestBody', () => { it('should not write when body is undefined', () => { const proxyRequest = fakeProxyRequest(); @@ -24,7 +31,7 @@ describe('fixRequestBody', () => { jest.spyOn(proxyRequest, 'setHeader'); jest.spyOn(proxyRequest, 'write'); - fixRequestBody(proxyRequest, { body: undefined } as Request, fakeProxyResponse()); + fixRequestBody(proxyRequest, createRequestWithBody(undefined)); expect(proxyRequest.setHeader).not.toHaveBeenCalled(); expect(proxyRequest.write).not.toHaveBeenCalled(); @@ -37,7 +44,7 @@ describe('fixRequestBody', () => { jest.spyOn(proxyRequest, 'setHeader'); jest.spyOn(proxyRequest, 'write'); - fixRequestBody(proxyRequest, { body: {} } as Request, fakeProxyResponse()); + fixRequestBody(proxyRequest, createRequestWithBody({})); expect(proxyRequest.setHeader).toHaveBeenCalled(); expect(proxyRequest.write).toHaveBeenCalled(); @@ -50,11 +57,7 @@ describe('fixRequestBody', () => { jest.spyOn(proxyRequest, 'setHeader'); jest.spyOn(proxyRequest, 'write'); - fixRequestBody( - proxyRequest, - { body: { someField: 'some value' } } as Request, - fakeProxyResponse() - ); + fixRequestBody(proxyRequest, createRequestWithBody({ someField: 'some value' })); const expectedBody = JSON.stringify({ someField: 'some value' }); expect(proxyRequest.setHeader).toHaveBeenCalledWith('Content-Length', expectedBody.length); @@ -68,11 +71,7 @@ describe('fixRequestBody', () => { jest.spyOn(proxyRequest, 'setHeader'); jest.spyOn(proxyRequest, 'write'); - fixRequestBody( - proxyRequest, - { body: { someField: 'some value' } } as Request, - fakeProxyResponse() - ); + fixRequestBody(proxyRequest, createRequestWithBody({ someField: 'some value' })); const expectedBody = querystring.stringify({ someField: 'some value' }); expect(proxyRequest.setHeader).toHaveBeenCalledWith('Content-Length', expectedBody.length); @@ -86,11 +85,7 @@ describe('fixRequestBody', () => { jest.spyOn(proxyRequest, 'setHeader'); jest.spyOn(proxyRequest, 'write'); - fixRequestBody( - proxyRequest, - { body: { someField: 'some value' } } as Request, - fakeProxyResponse() - ); + fixRequestBody(proxyRequest, createRequestWithBody({ someField: 'some value' })); const expectedBody = querystring.stringify({ someField: 'some value' }); expect(proxyRequest.setHeader).toHaveBeenCalledWith('Content-Length', expectedBody.length); @@ -104,11 +99,7 @@ describe('fixRequestBody', () => { jest.spyOn(proxyRequest, 'setHeader'); jest.spyOn(proxyRequest, 'write'); - fixRequestBody( - proxyRequest, - { body: { someField: 'some value' } } as Request, - fakeProxyResponse() - ); + fixRequestBody(proxyRequest, createRequestWithBody({ someField: 'some value' })); const expectedBody = JSON.stringify({ someField: 'some value' }); expect(proxyRequest.setHeader).toHaveBeenCalledWith('Content-Length', expectedBody.length); @@ -116,50 +107,26 @@ describe('fixRequestBody', () => { expect(proxyRequest.write).toHaveBeenCalledWith(expectedBody); }); - it('should return 400 and abort request on "Connection: Upgrade" header', () => { + it('should not fixRequestBody() when there bodyParser fails', () => { const proxyRequest = fakeProxyRequest(); - const request = { body: { someField: 'some value' } } as Request; - - proxyRequest.destroy = jest.fn(); - request.destroy = jest.fn(); - - const proxyResponse = fakeProxyResponse(); - proxyRequest.setHeader('connection', 'upgrade'); - proxyRequest.setHeader('content-type', 'application/x-www-form-urlencoded'); - - jest.spyOn(proxyRequest, 'destroy'); - jest.spyOn(request, 'destroy'); - jest.spyOn(proxyResponse, 'writeHead'); - jest.spyOn(proxyResponse, 'end'); - - fixRequestBody(proxyRequest, request, proxyResponse); - - expect(proxyResponse.writeHead).toHaveBeenCalledWith(400); - expect(proxyResponse.end).toHaveBeenCalledTimes(1); - expect(proxyRequest.destroy).toHaveBeenCalledTimes(1); - expect(request.destroy).toHaveBeenCalledTimes(1); - }); - - it('should return 400 and abort request on invalid request data', () => { - const proxyRequest = fakeProxyRequest(); - const request = { body: { 'INVALID \n\r DATA': '' } } as Request; - - proxyRequest.destroy = jest.fn(); - request.destroy = jest.fn(); + const request = { + get readableLength() { + return 4444; // simulate bodyParser failure + }, + } as Request; const proxyResponse = fakeProxyResponse(); proxyRequest.setHeader('content-type', 'application/x-www-form-urlencoded'); + jest.spyOn(proxyRequest, 'write'); jest.spyOn(proxyRequest, 'destroy'); - jest.spyOn(request, 'destroy'); jest.spyOn(proxyResponse, 'writeHead'); jest.spyOn(proxyResponse, 'end'); - fixRequestBody(proxyRequest, request, proxyResponse); + fixRequestBody(proxyRequest, request); - expect(proxyResponse.writeHead).toHaveBeenCalledWith(400); - expect(proxyResponse.end).toHaveBeenCalledTimes(1); - expect(proxyRequest.destroy).toHaveBeenCalledTimes(1); - expect(request.destroy).toHaveBeenCalledTimes(1); + expect(proxyResponse.end).toHaveBeenCalledTimes(0); + expect(proxyRequest.write).toHaveBeenCalledTimes(0); + expect(proxyRequest.destroy).toHaveBeenCalledTimes(0); }); }); From 617a7c9da9cc90ecc00b0c8b1c2f6a385c879cb1 Mon Sep 17 00:00:00 2001 From: Steven Chim <655241+chimurai@users.noreply.github.com> Date: Thu, 10 Apr 2025 14:10:53 +0200 Subject: [PATCH 5/5] chore(package): v2.0.9 (#1099) --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22557406..4412d3e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## [v2.0.9](https://github.com/chimurai/http-proxy-middleware/releases/tag/v2.0.9) + +- fix(fixRequestBody): check readableLength + ## [v2.0.8](https://github.com/chimurai/http-proxy-middleware/releases/tag/v2.0.8) - fix(fixRequestBody): prevent multiple .write() calls diff --git a/package.json b/package.json index 56150637..041ed2ff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "http-proxy-middleware", - "version": "2.0.8", + "version": "2.0.9", "description": "The one-liner node.js proxy middleware for connect, express and browser-sync", "main": "dist/index.js", "types": "dist/index.d.ts",