Merge pull request #19952 from luchillo17/fix/BCKSTG-287-k8sproxy-web-socket-fails-on-
fix: Handle Proxy WS upgrade manually for WS handshakes
This commit is contained in:
@@ -18,7 +18,7 @@ import { Logger } from 'winston';
|
||||
import type { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common';
|
||||
import { PermissionEvaluator } from '@backstage/plugin-permission-common';
|
||||
import { PluginEndpointDiscovery } from '@backstage/backend-common';
|
||||
import type { RequestHandler } from 'express';
|
||||
import { RequestHandler } from 'http-proxy-middleware';
|
||||
import { TokenCredential } from '@azure/identity';
|
||||
|
||||
// @public (undocumented)
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
"@jest-mock/express": "^2.0.1",
|
||||
"@kubernetes/client-node": "0.18.1",
|
||||
"@types/express": "^4.17.6",
|
||||
"@types/http-proxy-middleware": "^0.19.3",
|
||||
"@types/luxon": "^3.0.0",
|
||||
"compression": "^1.7.4",
|
||||
"cors": "^2.8.5",
|
||||
@@ -88,8 +89,6 @@
|
||||
"@backstage/backend-test-utils": "workspace:^",
|
||||
"@backstage/cli": "workspace:^",
|
||||
"@types/aws4": "^1.5.1",
|
||||
"@types/http-proxy-middleware": "^0.19.3",
|
||||
"cross-fetch": "^3.1.5",
|
||||
"mock-fs": "^5.2.0",
|
||||
"msw": "^1.0.0",
|
||||
"supertest": "^6.1.3",
|
||||
|
||||
@@ -46,7 +46,6 @@ import {
|
||||
HEADER_KUBERNETES_CLUSTER,
|
||||
KubernetesProxy,
|
||||
} from './KubernetesProxy';
|
||||
import fetch from 'cross-fetch';
|
||||
|
||||
import type { Request } from 'express';
|
||||
|
||||
@@ -757,7 +756,6 @@ describe('KubernetesProxy', () => {
|
||||
|
||||
const wsProxyAddress = `ws://127.0.0.1:${proxyPort}${proxyPath}${wsPath}`;
|
||||
const wsAddress = `ws://localhost:${wsPort}${wsPath}`;
|
||||
console.log('Ports: ', wsProxyAddress, wsAddress);
|
||||
|
||||
// Let this request through so it reaches the express router above
|
||||
worker.use(
|
||||
@@ -769,10 +767,6 @@ describe('KubernetesProxy', () => {
|
||||
),
|
||||
);
|
||||
|
||||
// Prepopulate the proxy so the WebSocket upgrade can happen, result doesn't actually matter
|
||||
const result = await fetch(wsProxyAddress.replace('ws', 'http'));
|
||||
expect(result.ok).toBeFalsy();
|
||||
|
||||
const webSocket = new WebSocket(wsProxyAddress);
|
||||
|
||||
const connectMessagePromise = eventPromiseFactory(webSocket, 'message');
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
ErrorResponseBody,
|
||||
ForwardedError,
|
||||
@@ -24,16 +23,18 @@ import {
|
||||
import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node';
|
||||
import { kubernetesProxyPermission } from '@backstage/plugin-kubernetes-common';
|
||||
import {
|
||||
PermissionEvaluator,
|
||||
AuthorizeResult,
|
||||
PermissionEvaluator,
|
||||
} from '@backstage/plugin-permission-common';
|
||||
import { bufferFromFileOrString } from '@kubernetes/client-node';
|
||||
import type { Request, RequestHandler } from 'express';
|
||||
import { createProxyMiddleware } from 'http-proxy-middleware';
|
||||
import { createProxyMiddleware, RequestHandler } from 'http-proxy-middleware';
|
||||
import { Logger } from 'winston';
|
||||
|
||||
import { AuthenticationStrategy } from '../auth';
|
||||
import { ClusterDetails, KubernetesClustersSupplier } from '../types/types';
|
||||
|
||||
import type { Request } from 'express';
|
||||
|
||||
export const APPLICATION_JSON: string = 'application/json';
|
||||
|
||||
/**
|
||||
@@ -121,7 +122,17 @@ export class KubernetesProxy {
|
||||
}
|
||||
|
||||
const middleware = await this.getMiddleware(req);
|
||||
middleware(req, res, next);
|
||||
|
||||
// If req is an upgrade handshake, use middleware upgrade instead of http request handler https://github.com/chimurai/http-proxy-middleware#external-websocket-upgrade
|
||||
if (
|
||||
req.header('connection')?.toLowerCase() === 'upgrade' &&
|
||||
req.header('upgrade')?.toLowerCase() === 'websocket'
|
||||
) {
|
||||
// Missing the `head`, since it's optional we pass undefined to avoid type issues
|
||||
middleware.upgrade!(req, req.socket, undefined);
|
||||
} else {
|
||||
middleware(req, res, next);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user