提交 73627ac0 编写于 作者: J Joao Moreno

simplify request service

上级 da7d4513
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import { assign } from 'vs/base/common/objects';
import { IXHRResponse } from 'vs/base/common/http';
import { request, IRequestOptions } from 'vs/base/node/request';
import { getProxyAgent } from 'vs/base/node/proxy';
import { createGunzip } from 'zlib';
import { Stream } from 'stream';
export interface IXHROptions extends IRequestOptions {
responseType?: string;
followRedirects: number;
}
let proxyUrl: string = null;
let strictSSL: boolean = true;
export function configure(_proxyUrl: string, _strictSSL: boolean): void {
proxyUrl = _proxyUrl;
strictSSL = _strictSSL;
}
export function xhr(options: IXHROptions): TPromise<IXHRResponse> {
const agent = getProxyAgent(options.url, { proxyUrl, strictSSL });
options = assign({}, options);
options = assign(options, { agent, strictSSL });
return request(options).then(result => new TPromise<IXHRResponse>((c, e, p) => {
const res = result.res;
let stream: Stream = res;
if (res.headers['content-encoding'] === 'gzip') {
stream = stream.pipe(createGunzip());
}
const data: string[] = [];
stream.on('data', c => data.push(c));
stream.on('end', () => {
const status = res.statusCode;
if (options.followRedirects > 0 && (status >= 300 && status <= 303 || status === 307)) {
let location = res.headers['location'];
if (location) {
let newOptions = {
type: options.type, url: location, user: options.user, password: options.password, responseType: options.responseType, headers: options.headers,
timeout: options.timeout, followRedirects: options.followRedirects - 1, data: options.data
};
xhr(newOptions).done(c, e, p);
return;
}
}
const response: IXHRResponse = {
responseText: data.join(''),
status,
getResponseHeader: header => res.headers[header],
readyState: 4
};
if ((status >= 200 && status < 300) || status === 1223) {
c(response);
} else {
e(response);
}
});
}, err => {
let message: string;
if (agent) {
message = 'Unable to to connect to ' + options.url + ' through a proxy . Error: ' + err.message;
} else {
message = 'Unable to to connect to ' + options.url + '. Error: ' + err.message;
}
return TPromise.wrapError<IXHRResponse>({
responseText: message,
status: 404
});
}));
}
......@@ -5,66 +5,49 @@
'use strict';
import {TPromise, Promise, xhr} from 'vs/base/common/winjs.base';
import http = require('vs/base/common/http');
import {IConfigurationRegistry, Extensions} from 'vs/platform/configuration/common/configurationRegistry';
import { TPromise, Promise, xhr } from 'vs/base/common/winjs.base';
import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry';
import strings = require('vs/base/common/strings');
import nls = require('vs/nls');
import lifecycle = require('vs/base/common/lifecycle');
import timer = require('vs/base/common/timer');
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import platform = require('vs/platform/platform');
import async = require('vs/base/common/async');
import {IConfigurationService} from 'vs/platform/configuration/common/configuration';
import {BaseRequestService} from 'vs/platform/request/common/baseRequestService';
import rawHttpService = require('vs/workbench/services/request/node/rawHttpService');
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
interface IRawHttpService {
xhr(options: http.IXHROptions): TPromise<http.IXHRResponse>;
configure(proxy: string, strictSSL: boolean): void;
}
interface IXHRFunction {
(options: http.IXHROptions): TPromise<http.IXHRResponse>;
}
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { BaseRequestService } from 'vs/platform/request/common/baseRequestService';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { assign } from 'vs/base/common/objects';
import { IXHROptions, IXHRResponse } from 'vs/base/common/http';
import { request } from 'vs/base/node/request';
import { getProxyAgent } from 'vs/base/node/proxy';
import { createGunzip } from 'zlib';
import { Stream } from 'stream';
export class RequestService extends BaseRequestService {
private callOnDispose: Function[];
private disposables: IDisposable[];
private proxyUrl: string = null;
private strictSSL: boolean = true;
constructor(
contextService: IWorkspaceContextService,
private configurationService: IConfigurationService,
configurationService: IConfigurationService,
telemetryService?: ITelemetryService
) {
super(contextService, telemetryService);
this.callOnDispose = [];
this.disposables = [];
// proxy setting updating
this.callOnDispose.push(configurationService.onDidUpdateConfiguration(e => {
this.rawHttpServicePromise.then((rawHttpService) => {
rawHttpService.configure(e.config.http && e.config.http.proxy, e.config.http.proxyStrictSSL);
});
}).dispose);
}
private _rawHttpServicePromise: TPromise<IRawHttpService>;
private get rawHttpServicePromise(): TPromise<IRawHttpService> {
if (!this._rawHttpServicePromise) {
const configuration = this.configurationService.getConfiguration<any>();
rawHttpService.configure(configuration.http && configuration.http.proxy, configuration.http.proxyStrictSSL);
return TPromise.as(rawHttpService);
}
const configuration = configurationService.getConfiguration<any>();
this.proxyUrl = configuration.http && configuration.http.proxy;
this.strictSSL = configuration.http && configuration.http.proxyStrictSSL;
return this._rawHttpServicePromise;
this.disposables.push(configurationService.onDidUpdateConfiguration(e => {
const configuration = e.config;
this.proxyUrl = configuration.http && configuration.http.proxy;
this.strictSSL = configuration.http && configuration.http.proxyStrictSSL;
}));
}
public dispose(): void {
lifecycle.cAll(this.callOnDispose);
}
public makeRequest(options: http.IXHROptions): TPromise<http.IXHRResponse> {
makeRequest(options: IXHROptions): TPromise<IXHRResponse> {
let url = options.url;
if (!url) {
throw new Error('IRequestService.makeRequest: Url is required.');
......@@ -84,20 +67,68 @@ export class RequestService extends BaseRequestService {
return super.makeRequest(options);
}
/**
* Make a cross origin request using NodeJS.
* Note: This method is also called from workers.
*/
protected makeCrossOriginRequest(options: http.IXHROptions): TPromise<http.IXHRResponse> {
let timerVar: timer.ITimerEvent = timer.nullEvent;
return this.rawHttpServicePromise.then((rawHttpService: IRawHttpService) => {
return async.always(rawHttpService.xhr(options), ((xhr: http.IXHRResponse) => {
if (timerVar.data) {
timerVar.data.status = xhr.status;
protected makeCrossOriginRequest(options: IXHROptions): TPromise<IXHRResponse> {
const { proxyUrl, strictSSL } = this;
const agent = getProxyAgent(options.url, { proxyUrl, strictSSL });
options = assign({}, options);
options = assign(options, { agent, strictSSL });
return request(options).then(result => new TPromise<IXHRResponse>((c, e, p) => {
const res = result.res;
let stream: Stream = res;
if (res.headers['content-encoding'] === 'gzip') {
stream = stream.pipe(createGunzip());
}
const data: string[] = [];
stream.on('data', c => data.push(c));
stream.on('end', () => {
const status = res.statusCode;
if (options.followRedirects > 0 && (status >= 300 && status <= 303 || status === 307)) {
let location = res.headers['location'];
if (location) {
let newOptions = {
type: options.type, url: location, user: options.user, password: options.password, responseType: options.responseType, headers: options.headers,
timeout: options.timeout, followRedirects: options.followRedirects - 1, data: options.data
};
xhr(newOptions).done(c, e, p);
return;
}
}
const response: IXHRResponse = {
responseText: data.join(''),
status,
getResponseHeader: header => res.headers[header],
readyState: 4
};
if ((status >= 200 && status < 300) || status === 1223) {
c(response);
} else {
e(response);
}
timerVar.stop();
}));
});
});
}, err => {
let message: string;
if (agent) {
message = 'Unable to to connect to ' + options.url + ' through a proxy . Error: ' + err.message;
} else {
message = 'Unable to to connect to ' + options.url + '. Error: ' + err.message;
}
return TPromise.wrapError<IXHRResponse>({
responseText: message,
status: 404
});
}));
}
dispose(): void {
this.disposables = dispose(this.disposables);
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册