зеркало из https://github.com/Azure/ms-rest-js.git
Merge pull request #403 from joshgummersall/master
Add HTTP agent settings and policy
This commit is contained in:
Коммит
abc4f8f58e
|
@ -1,4 +1,8 @@
|
|||
# Changelog
|
||||
## 2.1.0 - 2020-10-08
|
||||
- Add support for custom http/https agent (PR [#403](https://github.com/Azure/ms-rest-js/pull/403))
|
||||
- Fix WebResource clone to include extra settings (Issue [#405](https://github.com/Azure/ms-rest-js/issue/403))
|
||||
|
||||
## 2.0.8 - 2020-07-23
|
||||
- [BugFix] - Fixed loading of proxyPolicy.browser.js in the HTML files.(PR [#397](https://github.com/Azure/ms-rest-js/pull/397))
|
||||
|
||||
|
@ -7,7 +11,7 @@
|
|||
- Replace public usage of `RequestPolicyOptions` to an interface `RequestPolicyOptionsLike` to avoid compatibility issues with private members.
|
||||
- Fix issue with null/undefined values in array and tabs/space delimiter arrays during sendOperationRequest. [PR #390](https://github.com/Azure/ms-rest-js/pull/390)
|
||||
- Fix in flattenResponse when expecting an array, checking for parsedBody to be an array before proceeding with flattening. (PR [#385](https://github.com/Azure/ms-rest-js/pull/385))
|
||||
|
||||
|
||||
## 2.0.6 - 2020-04-15
|
||||
- A new interface `WebResourceLike` was introduced to avoid a direct dependency on the class `WebResource` in public interfaces. `HttpHeadersLike` was also added to replace references to `HttpHeaders`. This change was added to improve compatibility between `@azure/core-http` and `@azure/ms-rest-nodeauth`.
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ export { generateClientRequestIdPolicy } from "./policies/generateClientRequestI
|
|||
export { exponentialRetryPolicy } from "./policies/exponentialRetryPolicy";
|
||||
export { systemErrorRetryPolicy } from "./policies/systemErrorRetryPolicy";
|
||||
export { throttlingRetryPolicy } from "./policies/throttlingRetryPolicy";
|
||||
export { agentPolicy } from "./policies/agentPolicy";
|
||||
export { getDefaultProxySettings, proxyPolicy } from "./policies/proxyPolicy";
|
||||
export { redirectPolicy } from "./policies/redirectPolicy";
|
||||
export { signingPolicy } from "./policies/signingPolicy";
|
||||
|
|
|
@ -46,7 +46,14 @@ export class NodeFetchHttpClient extends FetchHttpClient {
|
|||
httpRequest.headers.set("Cookie", cookieString);
|
||||
}
|
||||
|
||||
if (httpRequest.proxySettings) {
|
||||
if (httpRequest.agentSettings) {
|
||||
const {http: httpAgent, https: httpsAgent} = httpRequest.agentSettings;
|
||||
if (httpsAgent && httpRequest.url.startsWith("https")) {
|
||||
requestInit.agent = httpsAgent;
|
||||
} else if (httpAgent) {
|
||||
requestInit.agent = httpAgent;
|
||||
}
|
||||
} else if (httpRequest.proxySettings) {
|
||||
const tunnel: ProxyAgent = createProxyAgent(httpRequest.url, httpRequest.proxySettings, httpRequest.headers);
|
||||
requestInit.agent = tunnel.agent;
|
||||
}
|
||||
|
|
|
@ -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, RequestPolicyOptionsLike } from "./requestPolicy";
|
||||
import { HttpOperationResponse } from "../httpOperationResponse";
|
||||
import { WebResourceLike } from "../webResource";
|
||||
|
||||
const agentNotSupportedInBrowser = new Error("AgentPolicy is not supported in browser environment");
|
||||
|
||||
export function agentPolicy(_agentSettings?: AgentSettings): RequestPolicyFactory {
|
||||
return {
|
||||
create: (_nextPolicy: RequestPolicy, _options: RequestPolicyOptionsLike) => {
|
||||
throw agentNotSupportedInBrowser;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export class AgentPolicy extends BaseRequestPolicy {
|
||||
constructor(nextPolicy: RequestPolicy, options: RequestPolicyOptionsLike) {
|
||||
super(nextPolicy, options);
|
||||
throw agentNotSupportedInBrowser;
|
||||
}
|
||||
|
||||
public sendRequest(_request: WebResourceLike): 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, RequestPolicyOptionsLike } from "./requestPolicy";
|
||||
import { HttpOperationResponse } from "../httpOperationResponse";
|
||||
import { WebResourceLike } from "../webResource";
|
||||
|
||||
export function agentPolicy(agentSettings?: AgentSettings): RequestPolicyFactory {
|
||||
return {
|
||||
create: (nextPolicy: RequestPolicy, options: RequestPolicyOptionsLike) => {
|
||||
return new AgentPolicy(nextPolicy, options, agentSettings!);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export class AgentPolicy extends BaseRequestPolicy {
|
||||
agentSettings: AgentSettings;
|
||||
|
||||
constructor(nextPolicy: RequestPolicy, options: RequestPolicyOptionsLike, agentSettings: AgentSettings) {
|
||||
super(nextPolicy, options);
|
||||
this.agentSettings = agentSettings;
|
||||
}
|
||||
|
||||
public sendRequest(request: WebResourceLike): Promise<HttpOperationResponse> {
|
||||
if (!request.agentSettings) {
|
||||
request.agentSettings = this.agentSettings;
|
||||
}
|
||||
return this._nextPolicy.sendRequest(request);
|
||||
}
|
||||
}
|
|
@ -26,8 +26,10 @@ import { stringifyXML } from "./util/xml";
|
|||
import { RequestOptionsBase, RequestPrepareOptions, WebResourceLike, isWebResourceLike, WebResource } from "./webResource";
|
||||
import { OperationResponse } from "./operationResponse";
|
||||
import { ServiceCallback } from "./util/utils";
|
||||
import { agentPolicy } from "./policies/agentPolicy";
|
||||
import { proxyPolicy, getDefaultProxySettings } from "./policies/proxyPolicy";
|
||||
import { throttlingRetryPolicy } from "./policies/throttlingRetryPolicy";
|
||||
import { Agent } from "http";
|
||||
|
||||
|
||||
/**
|
||||
|
@ -40,6 +42,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 +109,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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -434,6 +448,10 @@ function createDefaultRequestPolicyFactories(credentials: ServiceClientCredentia
|
|||
factories.push(proxyPolicy(proxySettings));
|
||||
}
|
||||
|
||||
if (options.agentSettings) {
|
||||
factories.push(agentPolicy(options.agentSettings));
|
||||
}
|
||||
|
||||
return factories;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ export const Constants = {
|
|||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
msRestVersion: "2.0.8",
|
||||
msRestVersion: "2.1.0",
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
@ -94,6 +94,10 @@ export interface WebResourceLike {
|
|||
* Proxy configuration.
|
||||
*/
|
||||
proxySettings?: ProxySettings;
|
||||
/**
|
||||
* HTTP(S) agent configuration.
|
||||
*/
|
||||
agentSettings?: AgentSettings;
|
||||
/**
|
||||
* If the connection should be reused.
|
||||
*/
|
||||
|
@ -182,6 +186,7 @@ export class WebResource {
|
|||
timeout: number;
|
||||
proxySettings?: ProxySettings;
|
||||
keepAlive?: boolean;
|
||||
agentSettings?: AgentSettings;
|
||||
|
||||
abortSignal?: AbortSignalLike;
|
||||
|
||||
|
@ -204,7 +209,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 || "";
|
||||
|
@ -220,6 +226,7 @@ export class WebResource {
|
|||
this.onDownloadProgress = onDownloadProgress;
|
||||
this.proxySettings = proxySettings;
|
||||
this.keepAlive = keepAlive;
|
||||
this.agentSettings = agentSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -427,7 +434,10 @@ export class WebResource {
|
|||
this.abortSignal,
|
||||
this.timeout,
|
||||
this.onUploadProgress,
|
||||
this.onDownloadProgress);
|
||||
this.onDownloadProgress,
|
||||
this.proxySettings,
|
||||
this.keepAlive,
|
||||
this.agentSettings);
|
||||
|
||||
if (this.formData) {
|
||||
result.formData = this.formData;
|
||||
|
|
|
@ -14,6 +14,10 @@ export class XhrHttpClient implements HttpClient {
|
|||
public sendRequest(request: WebResourceLike): 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");
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"email": "azsdkteam@microsoft.com",
|
||||
"url": "https://github.com/Azure/ms-rest-js"
|
||||
},
|
||||
"version": "2.0.8",
|
||||
"version": "2.1.0",
|
||||
"description": "Isomorphic client Runtime for Typescript/node.js/browser javascript client libraries generated using AutoRest",
|
||||
"tags": [
|
||||
"isomorphic",
|
||||
|
@ -42,6 +42,7 @@
|
|||
],
|
||||
"browser": {
|
||||
"./es/lib/policies/msRestUserAgentPolicy.js": "./es/lib/policies/msRestUserAgentPolicy.browser.js",
|
||||
"./es/lib/policies/agentPolicy.js": "./es/lib/policies/agentPolicy.browser.js",
|
||||
"./es/lib/policies/proxyPolicy.js": "./es/lib/policies/proxyPolicy.browser.js",
|
||||
"./es/lib/util/base64.js": "./es/lib/util/base64.browser.js",
|
||||
"./es/lib/util/xml.js": "./es/lib/util/xml.browser.js",
|
||||
|
|
|
@ -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, WebResourceLike } 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: (_: WebResourceLike) =>
|
||||
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: {
|
||||
|
|
Загрузка…
Ссылка в новой задаче