Skip to content

Commit eaf969c

Browse files
fix(amazonq): migrate process.env proxy setting handling to proxyUtil.ts
fix(amazonq): migrate process.env proxy setting handling to proxyUtil.ts
2 parents f1dc9b8 + 696e143 commit eaf969c

File tree

4 files changed

+75
-96
lines changed

4 files changed

+75
-96
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Bug Fix",
3+
"description": "Added automatic system certificate detection and VSCode proxy settings support"
4+
}

packages/amazonq/src/extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ export async function activateAmazonQCommon(context: vscode.ExtensionContext, is
122122
}
123123

124124
// Configure proxy settings early
125-
ProxyUtil.configureProxyForLanguageServer()
125+
await ProxyUtil.configureProxyForLanguageServer()
126126

127127
// This contains every lsp agnostic things (auth, security scan, code scan)
128128
await activateCodeWhisperer(extContext as ExtContext)

packages/core/src/shared/lsp/utils/platform.ts

Lines changed: 2 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,10 @@
44
*/
55

66
import { ToolkitError } from '../../errors'
7-
import { Logger, getLogger } from '../../logger/logger'
7+
import { Logger } from '../../logger/logger'
88
import { ChildProcess } from '../../utilities/processUtils'
99
import { waitUntil } from '../../utilities/timeoutUtils'
1010
import { isDebugInstance } from '../../vscode/env'
11-
import { tmpdir } from 'os'
12-
import { join } from 'path'
13-
import * as nodefs from 'fs' // eslint-disable-line no-restricted-imports
14-
import * as vscode from 'vscode'
1511

1612
export function getNodeExecutableName(): string {
1713
return process.platform === 'win32' ? 'node.exe' : 'node'
@@ -85,67 +81,18 @@ export async function validateNodeExe(nodePath: string[], lsp: string, args: str
8581
}
8682
}
8783

88-
/**
89-
* Gets proxy settings and certificates from VS Code
90-
*/
91-
export async function getVSCodeSettings(): Promise<{ proxyUrl?: string; certificatePath?: string }> {
92-
const result: { proxyUrl?: string; certificatePath?: string } = {}
93-
const logger = getLogger('amazonqLsp')
94-
95-
try {
96-
// Get proxy settings from VS Code configuration
97-
const httpConfig = vscode.workspace.getConfiguration('http')
98-
const proxy = httpConfig.get<string>('proxy')
99-
if (proxy) {
100-
result.proxyUrl = proxy
101-
logger.info(`Using proxy from VS Code settings: ${proxy}`)
102-
}
103-
} catch (err) {
104-
logger.error(`Failed to get VS Code settings: ${err}`)
105-
return result
106-
}
107-
try {
108-
const tls = await import('tls')
109-
// @ts-ignore Get system certificates
110-
const systemCerts = tls.getCACertificates('system')
111-
// @ts-ignore Get any existing extra certificates
112-
const extraCerts = tls.getCACertificates('extra')
113-
const allCerts = [...systemCerts, ...extraCerts]
114-
if (allCerts && allCerts.length > 0) {
115-
logger.info(`Found ${allCerts.length} certificates in system's trust store`)
116-
117-
const tempDir = join(tmpdir(), 'aws-toolkit-vscode')
118-
if (!nodefs.existsSync(tempDir)) {
119-
nodefs.mkdirSync(tempDir, { recursive: true })
120-
}
121-
122-
const certPath = join(tempDir, 'vscode-ca-certs.pem')
123-
const certContent = allCerts.join('\n')
124-
125-
nodefs.writeFileSync(certPath, certContent)
126-
result.certificatePath = certPath
127-
logger.info(`Created certificate file at: ${certPath}`)
128-
}
129-
} catch (err) {
130-
logger.error(`Failed to extract certificates: ${err}`)
131-
}
132-
return result
133-
}
134-
13584
export function createServerOptions({
13685
encryptionKey,
13786
executable,
13887
serverModule,
13988
execArgv,
14089
warnThresholds,
141-
env,
14290
}: {
14391
encryptionKey: Buffer
14492
executable: string[]
14593
serverModule: string
14694
execArgv: string[]
14795
warnThresholds?: { cpu?: number; memory?: number }
148-
env?: Record<string, string>
14996
}) {
15097
return async () => {
15198
const bin = executable[0]
@@ -154,43 +101,7 @@ export function createServerOptions({
154101
args.unshift('--inspect=6080')
155102
}
156103

157-
// Merge environment variables
158-
const processEnv = { ...process.env }
159-
if (env) {
160-
Object.assign(processEnv, env)
161-
}
162-
163-
// Get settings from VS Code
164-
const settings = await getVSCodeSettings()
165-
const logger = getLogger('amazonqLsp')
166-
167-
// Add proxy settings to the Node.js process
168-
if (settings.proxyUrl) {
169-
processEnv.HTTPS_PROXY = settings.proxyUrl
170-
}
171-
172-
// Add certificate path if available
173-
if (settings.certificatePath) {
174-
processEnv.NODE_EXTRA_CA_CERTS = settings.certificatePath
175-
logger.info(`Using certificate file: ${settings.certificatePath}`)
176-
}
177-
178-
// Get SSL verification settings
179-
const httpConfig = vscode.workspace.getConfiguration('http')
180-
const strictSSL = httpConfig.get<boolean>('proxyStrictSSL', true)
181-
182-
// Handle SSL certificate verification
183-
if (!strictSSL) {
184-
processEnv.NODE_TLS_REJECT_UNAUTHORIZED = '0'
185-
logger.info('SSL verification disabled via VS Code settings')
186-
}
187-
188-
const lspProcess = new ChildProcess(bin, args, {
189-
warnThresholds,
190-
spawnOptions: {
191-
env: processEnv,
192-
},
193-
})
104+
const lspProcess = new ChildProcess(bin, args, { warnThresholds })
194105

195106
// this is a long running process, awaiting it will never resolve
196107
void lspProcess.run()

packages/core/src/shared/utilities/proxyUtil.ts

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,14 @@
55

66
import vscode from 'vscode'
77
import { getLogger } from '../logger/logger'
8+
import { tmpdir } from 'os'
9+
import { join } from 'path'
10+
import * as nodefs from 'fs' // eslint-disable-line no-restricted-imports
811

912
interface ProxyConfig {
1013
proxyUrl: string | undefined
14+
noProxy: string | undefined
15+
proxyStrictSSL: boolean | true
1116
certificateAuthority: string | undefined
1217
}
1318

@@ -23,11 +28,11 @@ export class ProxyUtil {
2328
* See documentation here for setting the environement variables which are inherited by Flare LS process:
2429
* https://github.com/aws/language-server-runtimes/blob/main/runtimes/docs/proxy.md
2530
*/
26-
public static configureProxyForLanguageServer(): void {
31+
public static async configureProxyForLanguageServer(): Promise<void> {
2732
try {
2833
const proxyConfig = this.getProxyConfiguration()
2934

30-
this.setProxyEnvironmentVariables(proxyConfig)
35+
await this.setProxyEnvironmentVariables(proxyConfig)
3136
} catch (err) {
3237
this.logger.error(`Failed to configure proxy: ${err}`)
3338
}
@@ -41,21 +46,30 @@ export class ProxyUtil {
4146
const proxyUrl = httpConfig.get<string>('proxy')
4247
this.logger.debug(`Proxy URL Setting in VSCode Settings: ${proxyUrl}`)
4348

49+
const noProxy = httpConfig.get<string>('noProxy')
50+
if (noProxy) {
51+
this.logger.info(`Using noProxy from VS Code settings: ${noProxy}`)
52+
}
53+
54+
const proxyStrictSSL = httpConfig.get<boolean>('proxyStrictSSL', true)
55+
4456
const amazonQConfig = vscode.workspace.getConfiguration('amazonQ')
4557
const proxySettings = amazonQConfig.get<{
4658
certificateAuthority?: string
4759
}>('proxy', {})
4860

4961
return {
5062
proxyUrl,
63+
noProxy,
64+
proxyStrictSSL,
5165
certificateAuthority: proxySettings.certificateAuthority,
5266
}
5367
}
5468

5569
/**
5670
* Sets environment variables based on proxy configuration
5771
*/
58-
private static setProxyEnvironmentVariables(config: ProxyConfig): void {
72+
private static async setProxyEnvironmentVariables(config: ProxyConfig): Promise<void> {
5973
const proxyUrl = config.proxyUrl
6074
// Set proxy environment variables
6175
if (proxyUrl) {
@@ -64,11 +78,61 @@ export class ProxyUtil {
6478
this.logger.debug(`Set proxy environment variables: ${proxyUrl}`)
6579
}
6680

67-
// Set certificate bundle environment variables if configured
81+
// set NO_PROXY vals
82+
const noProxy = config.noProxy
83+
if (noProxy) {
84+
process.env.NO_PROXY = noProxy
85+
this.logger.debug(`Set NO_PROXY environment variable: ${noProxy}`)
86+
}
87+
88+
const strictSSL = config.proxyStrictSSL
89+
// Handle SSL certificate verification
90+
if (!strictSSL) {
91+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
92+
this.logger.info('SSL verification disabled via VS Code settings')
93+
return // No need to set CA certs when SSL verification is disabled
94+
}
95+
96+
// Set certificate bundle environment variables if user configured
6897
if (config.certificateAuthority) {
6998
process.env.NODE_EXTRA_CA_CERTS = config.certificateAuthority
7099
process.env.AWS_CA_BUNDLE = config.certificateAuthority
71100
this.logger.debug(`Set certificate bundle path: ${config.certificateAuthority}`)
101+
} else {
102+
// Fallback to system certificates if no custom CA is configured
103+
await this.setSystemCertificates()
104+
}
105+
}
106+
107+
/**
108+
* Sets system certificates as fallback when no custom CA is configured
109+
*/
110+
private static async setSystemCertificates(): Promise<void> {
111+
try {
112+
const tls = await import('tls')
113+
// @ts-ignore Get system certificates
114+
const systemCerts = tls.getCACertificates('system')
115+
// @ts-ignore Get any existing extra certificates
116+
const extraCerts = tls.getCACertificates('extra')
117+
const allCerts = [...systemCerts, ...extraCerts]
118+
if (allCerts && allCerts.length > 0) {
119+
this.logger.debug(`Found ${allCerts.length} certificates in system's trust store`)
120+
121+
const tempDir = join(tmpdir(), 'aws-toolkit-vscode')
122+
if (!nodefs.existsSync(tempDir)) {
123+
nodefs.mkdirSync(tempDir, { recursive: true })
124+
}
125+
126+
const certPath = join(tempDir, 'vscode-ca-certs.pem')
127+
const certContent = allCerts.join('\n')
128+
129+
nodefs.writeFileSync(certPath, certContent)
130+
process.env.NODE_EXTRA_CA_CERTS = certPath
131+
process.env.AWS_CA_BUNDLE = certPath
132+
this.logger.debug(`Set system certificate bundle path: ${certPath}`)
133+
}
134+
} catch (err) {
135+
this.logger.error(`Failed to extract system certificates: ${err}`)
72136
}
73137
}
74138
}

0 commit comments

Comments
 (0)