From d65ec54f23a17b98452e691b9263a59dfca5ec98 Mon Sep 17 00:00:00 2001 From: Nina Berg Date: Mon, 7 Apr 2025 11:30:24 -0400 Subject: [PATCH 1/3] proxy-backend support sse connections closing Signed-off-by: Nina Berg --- plugins/proxy-backend/src/service/router.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/plugins/proxy-backend/src/service/router.ts b/plugins/proxy-backend/src/service/router.ts index a6a52db63a..e58bccd7af 100644 --- a/plugins/proxy-backend/src/service/router.ts +++ b/plugins/proxy-backend/src/service/router.ts @@ -214,8 +214,12 @@ export function buildMiddleware( ].map(h => h.toLocaleLowerCase()), ); - // only forward the allowed headers in backend->client - fullConfig.onProxyRes = (proxyRes: http.IncomingMessage) => { + fullConfig.onProxyRes = ( + proxyRes: http.IncomingMessage, + _, + res: express.Response, + ) => { + // only forward the allowed headers in backend->client const headerNames = Object.keys(proxyRes.headers); headerNames.forEach(h => { @@ -223,6 +227,14 @@ export function buildMiddleware( delete proxyRes.headers[h]; } }); + + // handle SSE connections closed by the backend + // https://github.com/chimurai/http-proxy-middleware/discussions/765 + proxyRes.on('close', () => { + if (!res.writableEnded) { + res.end(); + } + }); }; if (reviveConsumedRequestBodies) { From 9b5b744e240e1b2aa76e3b1837b312f7ff8d97b1 Mon Sep 17 00:00:00 2001 From: Nina Berg Date: Mon, 7 Apr 2025 14:35:58 -0400 Subject: [PATCH 2/3] add changeset and tests Signed-off-by: Nina Berg --- .changeset/thin-trams-work.md | 5 ++ .../proxy-backend/src/service/router.test.ts | 47 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 .changeset/thin-trams-work.md diff --git a/.changeset/thin-trams-work.md b/.changeset/thin-trams-work.md new file mode 100644 index 0000000000..ddc31631d1 --- /dev/null +++ b/.changeset/thin-trams-work.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-proxy-backend': patch +--- + +Fixed handling of proxied sse connections when the upstream server closes the connection diff --git a/plugins/proxy-backend/src/service/router.test.ts b/plugins/proxy-backend/src/service/router.test.ts index 66d6de2f28..7d9a3dadbc 100644 --- a/plugins/proxy-backend/src/service/router.test.ts +++ b/plugins/proxy-backend/src/service/router.test.ts @@ -479,6 +479,7 @@ describe('buildMiddleware', () => { pragma: 'value', 'set-cookie': ['value'], }, + on: jest.fn(), } as Partial; expect(config).toBeDefined(); @@ -522,6 +523,7 @@ describe('buildMiddleware', () => { 'set-cookie': [], 'x-auth-request-user': 'asd', }, + on: jest.fn(), } as Partial; expect(config).toBeDefined(); @@ -603,4 +605,49 @@ describe('buildMiddleware', () => { ), ).toThrow(/Proxy target is not a valid URL/); }); + + it('closes SSE connections when backend closes the connection', async () => { + buildMiddleware( + '/proxy', + logger, + '/test', + { + target: 'http://mocked', + }, + httpRouterService, + ); + + expect(createProxyMiddleware).toHaveBeenCalledTimes(1); + + const config = mockCreateProxyMiddleware.mock.calls[0][1] as Options; + + const testServerResponse = { + headers: {}, + on: jest.fn((event, callback) => { + if (event === 'close') { + callback(); + } + return testServerResponse; + }), + } as Partial; + + const testClientResponse = { + writableEnded: false, + end: jest.fn(), + } as Partial; + + expect(config).toBeDefined(); + expect(config.onProxyRes).toBeDefined(); + + config.onProxyRes!( + testServerResponse as http.IncomingMessage, + {} as Request, + testClientResponse as Response, + ); + expect(testServerResponse.on).toHaveBeenCalledWith( + 'close', + expect.any(Function), + ); + expect(testClientResponse.end).toHaveBeenCalled(); + }); }); From d903b9228430422c226f41bbd40a02b3b6ca8daa Mon Sep 17 00:00:00 2001 From: Nina Berg Date: Mon, 7 Apr 2025 14:47:52 -0400 Subject: [PATCH 3/3] capitalize SSE for vale Signed-off-by: Nina Berg --- .changeset/thin-trams-work.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/thin-trams-work.md b/.changeset/thin-trams-work.md index ddc31631d1..26accde189 100644 --- a/.changeset/thin-trams-work.md +++ b/.changeset/thin-trams-work.md @@ -2,4 +2,4 @@ '@backstage/plugin-proxy-backend': patch --- -Fixed handling of proxied sse connections when the upstream server closes the connection +Fixed handling of proxied SSE connections when the upstream server closes the connection