feat(plugin-proxy-backend): revive request bodies
in order to support proxying requests with bodies that have previously been consumed in a middleware, the proxy config can now specify `reviveRequestBody: true` in order to propagate the previously consumed body to the proxied request. Signed-off-by: Dan Hoizner <dan.hoizner@gmail.com>
This commit is contained in:
@@ -18,11 +18,16 @@ import { getVoidLogger, SingleHostDiscovery } from '@backstage/backend-common';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { Request, Response } from 'express';
|
||||
import * as http from 'http';
|
||||
import { createProxyMiddleware, Options } from 'http-proxy-middleware';
|
||||
import {
|
||||
createProxyMiddleware,
|
||||
fixRequestBody,
|
||||
Options,
|
||||
} from 'http-proxy-middleware';
|
||||
import { buildMiddleware, createRouter } from './router';
|
||||
|
||||
jest.mock('http-proxy-middleware', () => ({
|
||||
createProxyMiddleware: jest.fn(() => () => undefined),
|
||||
fixRequestBody: jest.fn(),
|
||||
}));
|
||||
|
||||
const mockCreateProxyMiddleware = createProxyMiddleware as jest.MockedFunction<
|
||||
@@ -389,6 +394,41 @@ describe('buildMiddleware', () => {
|
||||
expect(Object.keys(testClientResponse.headers!)).toEqual(['set-cookie']);
|
||||
});
|
||||
|
||||
it('revives request body when configured', async () => {
|
||||
buildMiddleware('/proxy', logger, '/test', {
|
||||
target: 'http://mocked',
|
||||
reviveRequestBody: true,
|
||||
});
|
||||
|
||||
expect(createProxyMiddleware).toHaveBeenCalledTimes(1);
|
||||
|
||||
const config = mockCreateProxyMiddleware.mock.calls[0][1] as Options;
|
||||
|
||||
expect(config).toBeDefined();
|
||||
expect(config.onProxyReq).toBeDefined();
|
||||
|
||||
config.onProxyReq!(
|
||||
{} as http.ClientRequest,
|
||||
{} as Request,
|
||||
{} as Response,
|
||||
{},
|
||||
);
|
||||
expect(fixRequestBody).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('does not revive request body when not configured', async () => {
|
||||
buildMiddleware('/proxy', logger, '/test', {
|
||||
target: 'http://mocked',
|
||||
});
|
||||
|
||||
expect(createProxyMiddleware).toHaveBeenCalledTimes(1);
|
||||
|
||||
const config = mockCreateProxyMiddleware.mock.calls[0][1] as Options;
|
||||
|
||||
expect(config).toBeDefined();
|
||||
expect(config.onProxyReq).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('rejects malformed target URLs', async () => {
|
||||
expect(() =>
|
||||
buildMiddleware('/proxy', logger, '/test', 'backstage.io'),
|
||||
|
||||
@@ -19,6 +19,7 @@ import express from 'express';
|
||||
import Router from 'express-promise-router';
|
||||
import {
|
||||
createProxyMiddleware,
|
||||
fixRequestBody,
|
||||
Options,
|
||||
RequestHandler,
|
||||
} from 'http-proxy-middleware';
|
||||
@@ -58,6 +59,7 @@ export interface RouterOptions {
|
||||
export interface ProxyConfig extends Options {
|
||||
allowedMethods?: string[];
|
||||
allowedHeaders?: string[];
|
||||
reviveRequestBody?: boolean;
|
||||
}
|
||||
|
||||
// Creates a proxy middleware, possibly with defaults added on top of the
|
||||
@@ -175,6 +177,10 @@ export function buildMiddleware(
|
||||
});
|
||||
};
|
||||
|
||||
if (fullConfig.reviveRequestBody) {
|
||||
fullConfig.onProxyReq = fixRequestBody;
|
||||
}
|
||||
|
||||
return createProxyMiddleware(filter, fullConfig);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user