提交 bb8e79c8 编写于 作者: J Johannes Rieken 提交者: GitHub

Merge pull request #16211 from Microsoft/joh/xhr

Use XmlHttpRequest when making requests from a renderer
......@@ -31,11 +31,19 @@ export interface IRequestOptions {
}
export interface IRequestContext {
req: http.ClientRequest;
res: http.ClientResponse;
// req: http.ClientRequest;
// res: http.ClientResponse;
res: {
headers: { [n: string]: string };
statusCode?: number;
};
stream: Stream;
}
export interface IRequestFunction {
(options: IRequestOptions): TPromise<IRequestContext>;
}
export function request(options: IRequestOptions): TPromise<IRequestContext> {
let req: http.ClientRequest;
......@@ -71,7 +79,7 @@ export function request(options: IRequestOptions): TPromise<IRequestContext> {
stream = stream.pipe(createGunzip());
}
c({ req, res, stream });
c({ res, stream });
}
});
......@@ -144,4 +152,4 @@ export function asJson<T>(context: IRequestContext): TPromise<T> {
context.stream.on('end', () => c(JSON.parse(buffer.join(''))));
context.stream.on('error', e);
});
}
\ No newline at end of file
}
/*---------------------------------------------------------------------------------------------
* 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 { IRequestOptions, IRequestContext, IRequestFunction } from 'vs/base/node/request';
import { Readable } from 'stream';
import { RequestService as NodeRequestService } from 'vs/platform/request/node/requestService';
/**
* This service exposes the `request` API, while using the global
* or configured proxy settings.
*/
export class RequestService extends NodeRequestService {
request(options: IRequestOptions): TPromise<IRequestContext> {
return super.request(options, xhrRequest);
}
}
class ArryBufferStream extends Readable {
private _buffer: Buffer;
private _offset: number;
private _length: number;
constructor(arraybuffer: ArrayBuffer) {
super();
this._buffer = new Buffer(new Uint8Array(arraybuffer));
this._offset = 0;
this._length = this._buffer.length;
}
_read(size: number) {
if (this._offset < this._length) {
this.push(this._buffer.slice(this._offset, (this._offset + size)));
this._offset += size;
} else {
this.push(null);
}
}
}
export const xhrRequest: IRequestFunction = (options: IRequestOptions): TPromise<IRequestContext> => {
const xhr = new XMLHttpRequest();
return new TPromise<IRequestContext>((resolve, reject) => {
xhr.open(options.type, options.url, true, options.user, options.password);
setRequestHeaders(xhr, options);
xhr.responseType = 'arraybuffer';
xhr.onerror = reject;
xhr.onload = (e) => {
resolve({
res: {
statusCode: xhr.status,
headers: getResponseHeaders(xhr)
},
stream: new ArryBufferStream(xhr.response)
});
};
xhr.send(options.data);
return null;
}, () => {
// cancel
xhr.abort();
});
};
function setRequestHeaders(xhr: XMLHttpRequest, options: IRequestOptions): void {
if (options.headers) {
for (let k in options.headers) {
try {
xhr.setRequestHeader(k, options.headers[k]);
} catch (e) {
console.warn(e);
}
}
}
}
function getResponseHeaders(xhr: XMLHttpRequest): { [name: string]: string } {
const headers: { [name: string]: string } = Object.create(null);
for (const line of xhr.getAllResponseHeaders().split(/\r\n|\n|\r/g)) {
if (line) {
const idx = line.indexOf(':');
headers[line.substr(0, idx).trim().toLowerCase()] = line.substr(idx + 1).trim();
}
}
return headers;
}
......@@ -7,7 +7,7 @@
import { TPromise } from 'vs/base/common/winjs.base';
import { IDisposable } from 'vs/base/common/lifecycle';
import { assign } from 'vs/base/common/objects';
import { IRequestOptions, IRequestContext, request } from 'vs/base/node/request';
import { IRequestOptions, IRequestContext, IRequestFunction, request } from 'vs/base/node/request';
import { getProxyAgent } from 'vs/base/node/proxy';
import { IRequestService, IHTTPConfiguration } from 'vs/platform/request/node/request';
import { IConfigurationService, IConfigurationServiceEvent } from 'vs/platform/configuration/common/configuration';
......@@ -42,7 +42,7 @@ export class RequestService implements IRequestService {
this.authorization = config.http && config.http.proxyAuthorization;
}
request(options: IRequestOptions): TPromise<IRequestContext> {
request(options: IRequestOptions, requestFn: IRequestFunction = request): TPromise<IRequestContext> {
const { proxyUrl, strictSSL } = this;
options.agent = options.agent || getProxyAgent(options.url, { proxyUrl, strictSSL });
......@@ -52,6 +52,6 @@ export class RequestService implements IRequestService {
options.headers = assign(options.headers || {}, { 'Proxy-Authorization': this.authorization });
}
return request(options);
return requestFn(options);
}
}
......@@ -37,7 +37,7 @@ import { WindowsChannelClient } from 'vs/platform/windows/common/windowsIpc';
import { WindowService } from 'vs/platform/windows/electron-browser/windowService';
import { MessageService } from 'vs/workbench/services/message/electron-browser/messageService';
import { IRequestService } from 'vs/platform/request/node/request';
import { RequestService } from 'vs/platform/request/node/requestService';
import { RequestService } from 'vs/platform/request/electron-browser/requestService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { SearchService } from 'vs/workbench/services/search/node/searchService';
import { LifecycleService } from 'vs/workbench/services/lifecycle/electron-browser/lifecycleService';
......@@ -560,4 +560,4 @@ export class WorkbenchShell {
// Container
$(this.container).empty();
}
}
\ No newline at end of file
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册