Skip to content

Commit 5be69f3

Browse files
committed
use uuid for marketplace queries
related to microsoft#17108 microsoft#26484
1 parent a7f070e commit 5be69f3

6 files changed

Lines changed: 50 additions & 55 deletions

File tree

src/vs/code/electron-main/window.ts

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { ILogService } from 'vs/platform/log/common/log';
1818
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
1919
import { parseArgs } from 'vs/platform/environment/node/argv';
2020
import product from 'vs/platform/node/product';
21-
import { getCommonHTTPHeaders } from 'vs/platform/environment/node/http';
21+
import pkg from 'vs/platform/node/package';
2222
import { IWindowSettings, MenuBarVisibility, IWindowConfiguration, ReadyState } from 'vs/platform/windows/common/windows';
2323
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
2424
import { KeyboardLayoutMonitor } from 'vs/code/electron-main/keyboard';
@@ -299,20 +299,15 @@ export class CodeWindow implements ICodeWindow {
299299
}
300300

301301
private registerListeners(): void {
302+
const urls = ['https://marketplace.visualstudio.com/*', 'https://*.vsassets.io/*'];
303+
const headers = {
304+
'X-Market-Client-Id': `VSCode ${pkg.version}`,
305+
'User-Agent': `VSCode ${pkg.version}`,
306+
'X-Market-User-Id': this.environmentService.machineUUID
307+
};
302308

303-
// Set common HTTP headers
304-
// TODO@joao: hook this up to some initialization routine this causes a race between setting the headers and doing
305-
// a request that needs them. chances are low
306-
getCommonHTTPHeaders().done(headers => {
307-
if (!this._win) {
308-
return;
309-
}
310-
311-
const urls = ['https://marketplace.visualstudio.com/*', 'https://*.vsassets.io/*'];
312-
313-
this._win.webContents.session.webRequest.onBeforeSendHeaders({ urls }, (details, cb) => {
314-
cb({ cancel: false, requestHeaders: objects.assign(details.requestHeaders, headers) });
315-
});
309+
this._win.webContents.session.webRequest.onBeforeSendHeaders({ urls }, (details, cb) => {
310+
cb({ cancel: false, requestHeaders: objects.assign(details.requestHeaders, headers) });
316311
});
317312

318313
// Prevent loading of svgs

src/vs/platform/environment/common/environment.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export interface IEnvironmentService {
6060
appSettingsHome: string;
6161
appSettingsPath: string;
6262
appKeybindingsPath: string;
63+
machineUUID: string;
6364

6465
backupHome: string;
6566
backupWorkspacesPath: string;

src/vs/platform/environment/node/environmentService.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import * as crypto from 'crypto';
88
import * as paths from 'vs/base/node/paths';
99
import * as os from 'os';
1010
import * as path from 'path';
11+
import * as fs from 'fs';
1112
import URI from 'vs/base/common/uri';
13+
import { generateUuid } from 'vs/base/common/uuid';
1214
import { memoize } from 'vs/base/common/decorators';
1315
import pkg from 'vs/platform/node/package';
1416
import product from 'vs/platform/node/product';
@@ -139,7 +141,23 @@ export class EnvironmentService implements IEnvironmentService {
139141
@memoize
140142
get nodeCachedDataDir(): string { return this.isBuilt ? path.join(this.userDataPath, 'CachedData', product.commit) : undefined; }
141143

142-
constructor(private _args: ParsedArgs, private _execPath: string) { }
144+
readonly machineUUID: string;
145+
146+
constructor(private _args: ParsedArgs, private _execPath: string) {
147+
const machineIdPath = path.join(this.userDataPath, 'machineid');
148+
149+
try {
150+
this.machineUUID = fs.readFileSync(machineIdPath, 'utf8');
151+
} catch (err) {
152+
this.machineUUID = generateUuid();
153+
154+
try {
155+
fs.writeFileSync(machineIdPath, this.machineUUID);
156+
} catch (err) {
157+
console.warn('Could not store machine ID');
158+
}
159+
}
160+
}
143161
}
144162

145163
export function parseExtensionHostPort(args: ParsedArgs, isBuild: boolean): { port: number; break: boolean; debugId: string } {

src/vs/platform/environment/node/http.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

src/vs/platform/extensionManagement/common/extensionManagement.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,6 @@ export enum StatisticType {
203203
export interface IExtensionGalleryService {
204204
_serviceBrand: any;
205205
isEnabled(): boolean;
206-
getRequestHeaders(): TPromise<{ [key: string]: string; }>;
207206
query(options?: IQueryOptions): TPromise<IPager<IGalleryExtension>>;
208207
download(extension: IGalleryExtension): TPromise<string>;
209208
reportStatistic(publisher: string, name: string, version: string, type: StatisticType): TPromise<void>;

src/vs/platform/extensionManagement/node/extensionGalleryService.ts

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
2121
import pkg from 'vs/platform/node/package';
2222
import product from 'vs/platform/node/product';
2323
import { isVersionValid } from 'vs/platform/extensions/node/extensionValidator';
24-
import { getCommonHTTPHeaders } from 'vs/platform/environment/node/http';
24+
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
2525

2626
interface IRawGalleryExtensionFile {
2727
assetType: string;
@@ -276,16 +276,21 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
276276

277277
private extensionsGalleryUrl: string;
278278

279-
private readonly commonHTTPHeaders: TPromise<{ [key: string]: string; }>;
279+
private readonly commonHTTPHeaders: { [key: string]: string; };
280280

281281
constructor(
282282
@IRequestService private requestService: IRequestService,
283+
@IEnvironmentService private environmentService: IEnvironmentService,
283284
@ITelemetryService private telemetryService: ITelemetryService,
284285
@IConfigurationService private configurationService: IConfigurationService
285286
) {
286287
const config = product.extensionsGallery;
287288
this.extensionsGalleryUrl = config && config.serviceUrl;
288-
this.commonHTTPHeaders = getCommonHTTPHeaders();
289+
this.commonHTTPHeaders = {
290+
'X-Market-Client-Id': `VSCode ${pkg.version}`,
291+
'User-Agent': `VSCode ${pkg.version}`,
292+
'X-Market-User-Id': this.environmentService.machineUUID
293+
};
289294
}
290295

291296
private api(path = ''): string {
@@ -296,10 +301,6 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
296301
return !!this.extensionsGalleryUrl;
297302
}
298303

299-
getRequestHeaders(): TPromise<{ [key: string]: string; }> {
300-
return this.commonHTTPHeaders;
301-
}
302-
303304
query(options: IQueryOptions = {}): TPromise<IPager<IGalleryExtension>> {
304305
if (!this.isEnabled()) {
305306
return TPromise.wrapError<IPager<IGalleryExtension>>(new Error('No extension gallery service configured.'));
@@ -541,26 +542,23 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
541542

542543
private getAsset(asset: IGalleryExtensionAsset, options: IRequestOptions = {}): TPromise<IRequestContext> {
543544
const baseOptions = { type: 'GET' };
545+
const headers = assign({}, this.commonHTTPHeaders, options.headers || {});
546+
options = assign({}, options, baseOptions, { headers });
544547

545-
return this.commonHTTPHeaders.then(headers => {
546-
headers = assign({}, headers, options.headers || {});
547-
options = assign({}, options, baseOptions, { headers });
548+
const firstOptions = assign({}, options, { url: asset.uri });
548549

549-
const firstOptions = assign({}, options, { url: asset.uri });
550+
return this.requestService.request(firstOptions)
551+
.then(context => context.res.statusCode === 200 ? context : TPromise.wrapError<IRequestContext>(new Error('expected 200')))
552+
.then(null, err => {
553+
this.telemetryService.publicLog('galleryService:requestError', { cdn: true, message: getErrorMessage(err) });
554+
this.telemetryService.publicLog('galleryService:cdnFallback', { url: asset.uri });
550555

551-
return this.requestService.request(firstOptions)
552-
.then(context => context.res.statusCode === 200 ? context : TPromise.wrapError<IRequestContext>(new Error('expected 200')))
553-
.then(null, err => {
554-
this.telemetryService.publicLog('galleryService:requestError', { cdn: true, message: getErrorMessage(err) });
555-
this.telemetryService.publicLog('galleryService:cdnFallback', { url: asset.uri });
556-
557-
const fallbackOptions = assign({}, options, { url: asset.fallbackUri });
558-
return this.requestService.request(fallbackOptions).then(null, err => {
559-
this.telemetryService.publicLog('galleryService:requestError', { cdn: false, message: getErrorMessage(err) });
560-
return TPromise.wrapError<IRequestContext>(err);
561-
});
556+
const fallbackOptions = assign({}, options, { url: asset.fallbackUri });
557+
return this.requestService.request(fallbackOptions).then(null, err => {
558+
this.telemetryService.publicLog('galleryService:requestError', { cdn: false, message: getErrorMessage(err) });
559+
return TPromise.wrapError<IRequestContext>(err);
562560
});
563-
});
561+
});
564562
}
565563

566564
private getLastValidExtensionVersion(extension: IRawGalleryExtension, versions: IRawGalleryExtensionVersion[]): TPromise<IRawGalleryExtensionVersion> {

0 commit comments

Comments
 (0)