Port HTTP agent ServiceClientOption to 1.x

Ports functionality to 1.x from:
https://github.com/Azure/ms-rest-js/pull/403/files
This commit is contained in:
Josh Gummersall 2020-10-02 12:13:29 -07:00
Родитель 808ceee6a0
Коммит 00513a6484
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: AF311748D532A661
12 изменённых файлов: 216 добавлений и 11 удалений

Просмотреть файл

@ -154,16 +154,35 @@ export class AxiosHttpClient implements HttpClient {
proxy: false
};
if (httpRequest.proxySettings) {
if (httpRequest.agentSettings) {
const {http: httpAgent, https: httpsAgent} = httpRequest.agentSettings;
if (httpsAgent) {
config.httpsAgent = httpsAgent;
}
if (httpAgent) {
config.httpAgent = httpAgent;
}
} else if (httpRequest.proxySettings) {
const agent = createProxyAgent(httpRequest.url, httpRequest.proxySettings, httpRequest.headers);
if (agent.isHttps) {
config.httpsAgent = agent.agent;
} else {
config.httpAgent = agent.agent;
}
} else if (httpRequest.keepAlive) {
config.httpAgent = keepaliveAgents.http;
config.httpsAgent = keepaliveAgents.https;
}
if (httpRequest.keepAlive === true) {
if (config.httpAgent) {
config.httpAgent.keepAlive = true;
} else {
config.httpAgent = keepaliveAgents.http;
}
if (config.httpsAgent) {
config.httpsAgent.keepAlive = true;
} else {
config.httpsAgent = keepaliveAgents.https;
}
}
res = await axiosInstance.request(config);

Просмотреть файл

@ -0,0 +1,28 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { AgentSettings } from "../serviceClient";
import { BaseRequestPolicy, RequestPolicy, RequestPolicyFactory, RequestPolicyOptions } from "./requestPolicy";
import { HttpOperationResponse } from "../httpOperationResponse";
import { WebResource } from "../webResource";
const agentNotSupportedInBrowser = new Error("AgentPolicy is not supported in browser environment");
export function agentPolicy(_agentSettings?: AgentSettings): RequestPolicyFactory {
return {
create: (_nextPolicy: RequestPolicy, _options: RequestPolicyOptions) => {
throw agentNotSupportedInBrowser;
}
};
}
export class AgentPolicy extends BaseRequestPolicy {
constructor(nextPolicy: RequestPolicy, options: RequestPolicyOptions) {
super(nextPolicy, options);
throw agentNotSupportedInBrowser;
}
public sendRequest(_request: WebResource): Promise<HttpOperationResponse> {
throw agentNotSupportedInBrowser;
}
}

Просмотреть файл

@ -0,0 +1,31 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { AgentSettings } from "../serviceClient";
import { BaseRequestPolicy, RequestPolicy, RequestPolicyFactory, RequestPolicyOptions } from "./requestPolicy";
import { HttpOperationResponse } from "../httpOperationResponse";
import { WebResource } from "../webResource";
export function agentPolicy(agentSettings?: AgentSettings): RequestPolicyFactory {
return {
create: (nextPolicy: RequestPolicy, options: RequestPolicyOptions) => {
return new AgentPolicy(nextPolicy, options, agentSettings!);
}
};
}
export class AgentPolicy extends BaseRequestPolicy {
agentSettings: AgentSettings;
constructor(nextPolicy: RequestPolicy, options: RequestPolicyOptions, agentSettings: AgentSettings) {
super(nextPolicy, options);
this.agentSettings = agentSettings;
}
public sendRequest(request: WebResource): Promise<HttpOperationResponse> {
if (!request.agentSettings) {
request.agentSettings = this.agentSettings;
}
return this._nextPolicy.sendRequest(request);
}
}

Просмотреть файл

@ -28,6 +28,7 @@ import { OperationResponse } from "./operationResponse";
import { ServiceCallback } from "./util/utils";
import { proxyPolicy, getDefaultProxySettings } from "./policies/proxyPolicy";
import { throttlingRetryPolicy } from "./policies/throttlingRetryPolicy";
import { Agent } from "http";
/**
@ -40,6 +41,14 @@ export interface ProxySettings {
password?: string;
}
/**
* HTTP and HTTPS agents (Node.js only)
*/
export interface AgentSettings {
http: Agent;
https: Agent;
}
/**
* Options to be provided while creating the client.
*/
@ -99,6 +108,10 @@ export interface ServiceClientOptions {
* Proxy settings which will be used for every HTTP request (Node.js only).
*/
proxySettings?: ProxySettings;
/**
* HTTP and HTTPS agents which will be used for every HTTP request (Node.js only).
*/
agentSettings?: AgentSettings;
}
/**

Просмотреть файл

@ -7,7 +7,7 @@ export const Constants = {
* @const
* @type {string}
*/
msRestVersion: "1.8.16",
msRestVersion: "1.8.17",
/**
* Specifies HTTP.

Просмотреть файл

@ -7,7 +7,7 @@ import { Mapper, Serializer } from "./serializer";
import { generateUuid } from "./util/utils";
import { HttpOperationResponse } from "./httpOperationResponse";
import { OperationResponse } from "./operationResponse";
import { ProxySettings } from "./serviceClient";
import { AgentSettings, ProxySettings } from "./serviceClient";
export type HttpMethods = "GET" | "PUT" | "POST" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS" | "TRACE";
export type HttpRequestBody = Blob | string | ArrayBuffer | ArrayBufferView | (() => NodeJS.ReadableStream);
@ -67,6 +67,7 @@ export class WebResource {
timeout: number;
proxySettings?: ProxySettings;
keepAlive?: boolean;
agentSettings?: AgentSettings;
abortSignal?: AbortSignalLike;
@ -89,7 +90,8 @@ export class WebResource {
onUploadProgress?: (progress: TransferProgressEvent) => void,
onDownloadProgress?: (progress: TransferProgressEvent) => void,
proxySettings?: ProxySettings,
keepAlive?: boolean) {
keepAlive?: boolean,
agentSettings?: AgentSettings) {
this.streamResponseBody = streamResponseBody;
this.url = url || "";
@ -105,6 +107,7 @@ export class WebResource {
this.onDownloadProgress = onDownloadProgress;
this.proxySettings = proxySettings;
this.keepAlive = keepAlive;
this.agentSettings = agentSettings;
}
/**

Просмотреть файл

@ -14,6 +14,10 @@ export class XhrHttpClient implements HttpClient {
public sendRequest(request: WebResource): Promise<HttpOperationResponse> {
const xhr = new XMLHttpRequest();
if (request.agentSettings) {
throw new Error("HTTP agent settings not supported in browser environment");
}
if (request.proxySettings) {
throw new Error("HTTP proxy is not supported in browser environment");
}

2
package-lock.json сгенерированный
Просмотреть файл

@ -1,6 +1,6 @@
{
"name": "@azure/ms-rest-js",
"version": "1.8.15",
"version": "1.8.17",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

Просмотреть файл

@ -5,7 +5,7 @@
"email": "azsdkteam@microsoft.com",
"url": "https://github.com/Azure/ms-rest-js"
},
"version": "1.8.16",
"version": "1.8.17",
"description": "Isomorphic client Runtime for Typescript/node.js/browser javascript client libraries generated using AutoRest",
"tags": [
"isomorphic",
@ -44,7 +44,9 @@
"./es/lib/policies/msRestUserAgentPolicy.js": "./es/lib/policies/msRestUserAgentPolicy.browser.js",
"./es/lib/util/base64.js": "./es/lib/util/base64.browser.js",
"./es/lib/util/xml.js": "./es/lib/util/xml.browser.js",
"./es/lib/defaultHttpClient.js": "./es/lib/defaultHttpClient.browser.js"
"./es/lib/defaultHttpClient.js": "./es/lib/defaultHttpClient.browser.js",
"./es/lib/policies/agentPolicy.js": "./es/lib/policies/agentPolicy.browser.js",
"./es/lib/policies/proxyPolicy.js": "./es/lib/policies/proxyPolicy.browser.js"
},
"license": "MIT",
"dependencies": {

Просмотреть файл

@ -0,0 +1,95 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import "chai/register-should";
import { AgentSettings } from "../../lib/serviceClient";
import { RequestPolicyOptions } from "../../lib/policies/requestPolicy";
import { WebResource } from "../../lib/webResource";
import { HttpHeaders } from "../../lib/httpHeaders";
import { agentPolicy, AgentPolicy } from "../../lib/policies/agentPolicy";
import { nodeDescribe, browserDescribe } from "../msAssert";
describe("AgentPolicy", function () {
const emptyRequestPolicy = {
sendRequest: (_: WebResource) =>
Promise.resolve({
request: new WebResource(),
status: 404,
headers: new HttpHeaders(undefined),
}),
};
const emptyPolicyOptions = new RequestPolicyOptions();
nodeDescribe("for Node.js", function () {
const http = require("http");
const https = require("https");
const agentSettings: AgentSettings = {
http: new http.Agent(),
https: new https.Agent(),
};
it("factory passes correct agent settings", function () {
const factory = agentPolicy(agentSettings);
const policy = factory.create(
emptyRequestPolicy,
emptyPolicyOptions
) as AgentPolicy;
policy.agentSettings.should.be.deep.equal(agentSettings);
});
it("sets correct agent settings through constructor", function () {
const policy = new AgentPolicy(
emptyRequestPolicy,
emptyPolicyOptions,
agentSettings
);
policy.agentSettings.should.be.deep.equal(agentSettings);
});
it("should assign agent settings to the web request", async function () {
const policy = new AgentPolicy(
emptyRequestPolicy,
emptyPolicyOptions,
agentSettings
);
const request = new WebResource();
await policy.sendRequest(request);
request.agentSettings!.should.be.deep.equal(agentSettings);
});
it("should not override agent settings to the web request", async function () {
const policy = new AgentPolicy(
emptyRequestPolicy,
emptyPolicyOptions,
agentSettings
);
const request = new WebResource();
const requestSpecificAgentSettings = {
http: new http.Agent({keepAlive: true}),
https: new http.Agent({keepAlive: true}),
};
request.agentSettings = requestSpecificAgentSettings;
await policy.sendRequest(request);
request.agentSettings!.should.be.deep.equal(requestSpecificAgentSettings);
});
});
browserDescribe("for browser", () => {
it("should throw an Error while constructing object", () => {
const agentSettings = {} as AgentSettings;
const construct = () =>
new AgentPolicy(emptyRequestPolicy, emptyPolicyOptions, agentSettings);
construct.should.throw();
});
});
});

Просмотреть файл

@ -1,9 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { AgentSettings } from "../lib/serviceClient";
import { WebResource } from "../lib/webResource";
import { assert } from "chai";
import { parseHeaders, XhrHttpClient } from "../lib/xhrHttpClient";
import { WebResource } from "../lib/webResource";
describe("XhrHttpClient", function() {
it("parses headers", function() {
@ -38,4 +39,12 @@ describe("XhrHttpClient", function() {
const client = new XhrHttpClient();
assert.throws(() => { client.sendRequest(request); }, Error);
});
it("throws when agent settings are passed", function() {
const request = new WebResource();
request.agentSettings = {} as AgentSettings;
const client = new XhrHttpClient();
assert.throws(() => { client.sendRequest(request); }, Error);
});
});

Просмотреть файл

@ -31,6 +31,7 @@ const config: webpack.Configuration = {
new webpack.NormalModuleReplacementPlugin(/(\.).+util\/xml/, path.resolve(__dirname, "./lib/util/xml.browser.ts")),
new webpack.NormalModuleReplacementPlugin(/(\.).+defaultHttpClient/, path.resolve(__dirname, "./lib/defaultHttpClient.browser.ts")),
new webpack.NormalModuleReplacementPlugin(/(\.).+msRestUserAgentPolicy/, path.resolve(__dirname, "./lib/policies/msRestUserAgentPolicy.browser.ts")),
new webpack.NormalModuleReplacementPlugin(/(\.).+agentPolicy/, path.resolve(__dirname, "./lib/policies/agentPolicy.browser.ts")),
new webpack.NormalModuleReplacementPlugin(/(\.).+proxyPolicy/, path.resolve(__dirname, "./lib/policies/proxyPolicy.browser.ts"))
],
module: {