Avoid setting (#237890)

This commit is contained in:
Christof Marti
2025-01-21 09:36:36 +01:00
parent 57e5f4bba7
commit 735640be5a
2 changed files with 78 additions and 36 deletions

View File

@@ -5,12 +5,12 @@
import * as https from 'https';
import 'mocha';
import { assertNoRpc, delay } from '../utils';
import { assertNoRpc } from '../utils';
import { pki } from 'node-forge';
import { AddressInfo } from 'net';
import { resetCaches } from '@vscode/proxy-agent';
import * as vscode from 'vscode';
import { middleware, Straightforward } from 'straightforward';
import { Straightforward, Middleware, RequestContext, ConnectContext, isRequest, isConnect } from 'straightforward';
import assert from 'assert';
(vscode.env.uiKind === vscode.UIKind.Web ? suite.skip : suite)('vscode API - network proxy support', () => {
@@ -85,7 +85,8 @@ import assert from 'assert';
const sf = new Straightforward();
let authEnabled = false;
const auth = middleware.auth({ user, pass });
const authOpts: AuthOpts = { user, pass };
const auth = middlewareAuth(authOpts);
sf.onConnect.use(async (context, next) => {
if (authEnabled) {
return auth(context, next);
@@ -132,27 +133,17 @@ import assert from 'assert';
.on('error', reject);
});
for (let i = 0; i < 3; i++) {
await vscode.workspace.getConfiguration().update('integration-test.http.proxyAuth', `${user}:${pass}`, vscode.ConfigurationTarget.Global);
await delay(1000); // Wait for the configuration change to propagate.
try {
await new Promise<void>((resolve, reject) => {
https.get(url, res => {
if (res.statusCode === 204) {
resolve();
} else {
reject(new Error(`Unexpected status code (expected 204): ${res.statusCode}`));
}
})
.on('error', reject);
});
break; // Exit the loop if the request is successful
} catch (err) {
if (i === 2) {
throw err; // Rethrow the error if it's the last attempt
authOpts.realm = Buffer.from(JSON.stringify({ username: user, password: pass })).toString('base64');
await new Promise<void>((resolve, reject) => {
https.get(url, res => {
if (res.statusCode === 204) {
resolve();
} else {
reject(new Error(`Unexpected status code (expected 204): ${res.statusCode}`));
}
}
}
})
.on('error', reject);
});
} finally {
sf.close();
const change = waitForConfigChange('http.proxy');
@@ -219,3 +210,61 @@ import assert from 'assert';
});
}
});
// Added 'realm'. From MIT licensed https://github.com/berstend/straightforward/blob/84a4cb88024cffce37a05870da7d9d0aba7dcca8/src/middleware/auth.ts
export interface AuthOpts {
realm?: string;
user?: string;
pass?: string;
dynamic?: boolean;
}
export interface RequestAdditionsAuth {
locals: { proxyUser: string; proxyPass: string };
}
/**
* Authenticate an incoming proxy request
* Supports static `user` and `pass` or `dynamic`,
* in which case `ctx.req.locals` will be populated with `proxyUser` and `proxyPass`
* This middleware supports both onRequest and onConnect
*/
export const middlewareAuth =
(opts: AuthOpts): Middleware<
RequestContext<RequestAdditionsAuth> | ConnectContext<RequestAdditionsAuth>
> =>
async (ctx, next) => {
const { realm, user, pass, dynamic } = opts;
const sendAuthRequired = () => {
const realmStr = realm ? ` realm="${realm}"` : '';
if (isRequest(ctx)) {
ctx.res.writeHead(407, { 'Proxy-Authenticate': `Basic${realmStr}` });
ctx.res.end();
} else if (isConnect(ctx)) {
ctx.clientSocket.end(
'HTTP/1.1 407\r\n' + `Proxy-Authenticate: basic${realmStr}\r\n` + '\r\n'
);
}
};
const proxyAuth = ctx.req.headers['proxy-authorization'];
if (!proxyAuth) {
return sendAuthRequired();
}
const [proxyUser, proxyPass] = Buffer.from(
proxyAuth.replace('Basic ', ''),
'base64'
)
.toString()
.split(':');
if (!dynamic && !!(!!user && !!pass)) {
if (user !== proxyUser || pass !== proxyPass) {
return sendAuthRequired();
}
}
ctx.req.locals.proxyUser = proxyUser;
ctx.req.locals.proxyPass = proxyPass;
return next();
};