Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions sdk/core/core-http/lib/credentials/apiKeyCredentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ export class ApiKeyCredentials implements ServiceClientCredentials {
*/
constructor(options: ApiKeyCredentialOptions) {
if (!options || (options && !options.inHeader && !options.inQuery)) {
throw new Error(`options cannot be null or undefined. Either "inHeader" or "inQuery" property of the options object needs to be provided.`);
throw new Error(
`options cannot be null or undefined. Either "inHeader" or "inQuery" property of the options object needs to be provided.`
);
}
this.inHeader = options.inHeader;
this.inQuery = options.inQuery;
Expand All @@ -53,7 +55,9 @@ export class ApiKeyCredentials implements ServiceClientCredentials {
*/
signRequest(webResource: WebResource): Promise<WebResource> {
if (!webResource) {
return Promise.reject(new Error(`webResource cannot be null or undefined and must be of type "object".`));
return Promise.reject(
new Error(`webResource cannot be null or undefined and must be of type "object".`)
);
}

if (this.inHeader) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ export class BasicAuthenticationCredentials implements ServiceClientCredentials
* @param {string} password Password.
* @param {string} [authorizationScheme] The authorization scheme.
*/
constructor(userName: string, password: string, authorizationScheme: string = DEFAULT_AUTHORIZATION_SCHEME) {
constructor(
userName: string,
password: string,
authorizationScheme: string = DEFAULT_AUTHORIZATION_SCHEME
) {
if (userName === null || userName === undefined || typeof userName.valueOf() !== "string") {
throw new Error("userName cannot be null or undefined and must be of type string.");
}
Expand Down
52 changes: 39 additions & 13 deletions sdk/core/core-http/lib/fetchHttpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,28 @@ class ReportTransform extends Transform {
callback(undefined, chunk);
}

constructor(private progressCallback: ((progress: TransferProgressEvent) => void)) {
constructor(private progressCallback: (progress: TransferProgressEvent) => void) {
super();
}
}

export abstract class FetchHttpClient implements HttpClient {
async sendRequest(httpRequest: WebResource): Promise<HttpOperationResponse> {
if (!httpRequest && typeof httpRequest !== "object") {
throw new Error("'httpRequest' (WebResource) cannot be null or undefined and must be of type object.");
throw new Error(
"'httpRequest' (WebResource) cannot be null or undefined and must be of type object."
);
}

const abortController = new AbortController();
if (httpRequest.abortSignal) {
if (httpRequest.abortSignal.aborted) {
throw new RestError("The request was aborted", RestError.REQUEST_ABORTED_ERROR, undefined, httpRequest);
throw new RestError(
"The request was aborted",
RestError.REQUEST_ABORTED_ERROR,
undefined,
httpRequest
);
}

httpRequest.abortSignal.addEventListener("abort", (event: Event) => {
Expand All @@ -60,7 +67,7 @@ export abstract class FetchHttpClient implements HttpClient {
const formData: any = httpRequest.formData;
const requestForm = new FormData();
const appendFormValue = (key: string, value: any) => {
// value function probably returns a stream so we can provide a fresh stream on each retry
// value function probably returns a stream so we can provide a fresh stream on each retry
if (typeof value === "function") {
value = value();
}
Expand All @@ -86,7 +93,10 @@ export abstract class FetchHttpClient implements HttpClient {
const contentType = httpRequest.headers.get("Content-Type");
if (contentType && contentType.indexOf("multipart/form-data") !== -1) {
if (typeof requestForm.getBoundary === "function") {
httpRequest.headers.set("Content-Type", `multipart/form-data; boundary=${requestForm.getBoundary()}`);
httpRequest.headers.set(
"Content-Type",
`multipart/form-data; boundary=${requestForm.getBoundary()}`
);
} else {
// browser will automatically apply a suitable content-type header
httpRequest.headers.remove("Content-Type");
Expand All @@ -95,8 +105,10 @@ export abstract class FetchHttpClient implements HttpClient {
}

let body = httpRequest.body
? (typeof httpRequest.body === "function" ? httpRequest.body() : httpRequest.body)
: undefined;
? typeof httpRequest.body === "function"
? httpRequest.body()
: httpRequest.body
: undefined;
if (httpRequest.onUploadProgress && httpRequest.body) {
const onUploadProgress = httpRequest.onUploadProgress;
const uploadReportStream = new ReportTransform(onUploadProgress);
Expand All @@ -109,7 +121,9 @@ export abstract class FetchHttpClient implements HttpClient {
body = uploadReportStream;
}

const platformSpecificRequestInit: Partial<RequestInit> = await this.prepareRequest(httpRequest);
const platformSpecificRequestInit: Partial<RequestInit> = await this.prepareRequest(
httpRequest
);

const requestInit: RequestInit = {
body: body,
Expand All @@ -127,12 +141,14 @@ export abstract class FetchHttpClient implements HttpClient {
headers: headers,
request: httpRequest,
status: response.status,
readableStreamBody: httpRequest.streamResponseBody ? (response.body as unknown) as NodeJS.ReadableStream : undefined,
bodyAsText: !httpRequest.streamResponseBody ? await response.text() : undefined,
readableStreamBody: httpRequest.streamResponseBody
? ((response.body as unknown) as NodeJS.ReadableStream)
: undefined,
bodyAsText: !httpRequest.streamResponseBody ? await response.text() : undefined
};

const onDownloadProgress = httpRequest.onDownloadProgress;
if (onDownloadProgress) {
if (onDownloadProgress) {
const responseBody: ReadableStream<Uint8Array> | undefined = response.body || undefined;

if (isReadableStream(responseBody)) {
Expand All @@ -154,9 +170,19 @@ export abstract class FetchHttpClient implements HttpClient {
} catch (error) {
const fetchError: FetchError = error;
if (fetchError.code === "ENOTFOUND") {
throw new RestError(fetchError.message, RestError.REQUEST_SEND_ERROR, undefined, httpRequest);
throw new RestError(
fetchError.message,
RestError.REQUEST_SEND_ERROR,
undefined,
httpRequest
);
} else if (fetchError.type === "aborted") {
throw new RestError("The request was aborted", RestError.REQUEST_ABORTED_ERROR, undefined, httpRequest);
throw new RestError(
"The request was aborted",
RestError.REQUEST_ABORTED_ERROR,
undefined,
httpRequest
);
}

throw fetchError;
Expand Down
3 changes: 1 addition & 2 deletions sdk/core/core-http/lib/httpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ import { RequestPolicy } from "./policies/requestPolicy";
/**
* An interface that can send HttpRequests and receive promised HttpResponses.
*/
export interface HttpClient extends RequestPolicy {
}
export interface HttpClient extends RequestPolicy {}
5 changes: 4 additions & 1 deletion sdk/core/core-http/lib/httpHeaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ export class HttpHeaders {
* @param headerValue The value of the header to set.
*/
public set(headerName: string, headerValue: string | number): void {
this._headersMap[getHeaderKey(headerName)] = { name: headerName, value: headerValue.toString() };
this._headersMap[getHeaderKey(headerName)] = {
name: headerName,
value: headerValue.toString()
};
}

/**
Expand Down
2 changes: 1 addition & 1 deletion sdk/core/core-http/lib/httpOperationResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ declare global {
* Stub declaration of the browser-only Blob type.
* Full type information can be obtained by including "lib": ["dom"] in tsconfig.json.
*/
interface Blob { }
interface Blob {}
}

/**
Expand Down
21 changes: 10 additions & 11 deletions sdk/core/core-http/lib/httpPipelineLogger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ export class ConsoleHttpPipelineLogger implements HttpPipelineLogger {
* Create a new ConsoleHttpPipelineLogger.
* @param minimumLogLevel The log level threshold for what logs will be logged.
*/
constructor(public minimumLogLevel: HttpPipelineLogLevel) {
}
constructor(public minimumLogLevel: HttpPipelineLogLevel) {}

/**
* Log the provided message.
Expand All @@ -40,17 +39,17 @@ export class ConsoleHttpPipelineLogger implements HttpPipelineLogger {
log(logLevel: HttpPipelineLogLevel, message: string): void {
const logMessage = `${HttpPipelineLogLevel[logLevel]}: ${message}`;
switch (logLevel) {
case HttpPipelineLogLevel.ERROR:
console.error(logMessage);
break;
case HttpPipelineLogLevel.ERROR:
console.error(logMessage);
break;

case HttpPipelineLogLevel.WARNING:
console.warn(logMessage);
break;
case HttpPipelineLogLevel.WARNING:
console.warn(logMessage);
break;

case HttpPipelineLogLevel.INFO:
console.log(logMessage);
break;
case HttpPipelineLogLevel.INFO:
console.log(logMessage);
break;
}
}
}
16 changes: 11 additions & 5 deletions sdk/core/core-http/lib/nodeFetchHttpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ if (typeof globalWithFetch.fetch !== "function") {
globalWithFetch.fetch = fetch;
}


export class NodeFetchHttpClient extends FetchHttpClient {
private readonly cookieJar = new tough.CookieJar(undefined, { looseMode: true });

Expand All @@ -47,7 +46,11 @@ export class NodeFetchHttpClient extends FetchHttpClient {
}

if (httpRequest.proxySettings) {
const tunnel: ProxyAgent = createProxyAgent(httpRequest.url, httpRequest.proxySettings, httpRequest.headers);
const tunnel: ProxyAgent = createProxyAgent(
httpRequest.url,
httpRequest.proxySettings,
httpRequest.headers
);
requestInit.agent = tunnel.agent;
}

Expand All @@ -56,7 +59,9 @@ export class NodeFetchHttpClient extends FetchHttpClient {
requestInit.agent.keepAlive = true;
} else {
const options: http.AgentOptions | https.AgentOptions = { keepAlive: true };
const agent = httpRequest.url.startsWith("https") ? new https.Agent(options) : new http.Agent(options);
const agent = httpRequest.url.startsWith("https")
? new https.Agent(options)
: new http.Agent(options);
requestInit.agent = agent;
}
}
Expand All @@ -73,13 +78,14 @@ export class NodeFetchHttpClient extends FetchHttpClient {
setCookieHeader,
operationResponse.request.url,
{ ignoreError: true },
err => {
(err) => {
if (err) {
reject(err);
} else {
resolve();
}
});
}
);
});
}
}
Expand Down
5 changes: 4 additions & 1 deletion sdk/core/core-http/lib/operationParameter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ export function getPathStringFromParameter(parameter: OperationParameter): strin
return getPathStringFromParameterPath(parameter.parameterPath, parameter.mapper);
}

export function getPathStringFromParameterPath(parameterPath: ParameterPath, mapper: Mapper): string {
export function getPathStringFromParameterPath(
parameterPath: ParameterPath,
mapper: Mapper
): string {
let result: string;
if (typeof parameterPath === "string") {
result = parameterPath;
Expand Down
11 changes: 9 additions & 2 deletions sdk/core/core-http/lib/operationSpec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { OperationParameter, OperationQueryParameter, OperationURLParameter } from "./operationParameter";
import {
OperationParameter,
OperationQueryParameter,
OperationURLParameter
} from "./operationParameter";
import { OperationResponse } from "./operationResponse";
import { MapperType, Serializer } from "./serializer";
import { HttpMethods } from "./webResource";
Expand Down Expand Up @@ -82,7 +86,10 @@ export function isStreamOperation(operationSpec: OperationSpec): boolean {
let result = false;
for (const statusCode in operationSpec.responses) {
const operationResponse: OperationResponse = operationSpec.responses[statusCode];
if (operationResponse.bodyMapper && operationResponse.bodyMapper.type.name === MapperType.Stream) {
if (
operationResponse.bodyMapper &&
operationResponse.bodyMapper.type.name === MapperType.Stream
) {
result = true;
break;
}
Expand Down
33 changes: 21 additions & 12 deletions sdk/core/core-http/lib/policies/bearerTokenAuthenticationPolicy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@
// Licensed under the MIT License.

import { TokenCredential, GetTokenOptions } from "@azure/core-auth";
import { BaseRequestPolicy, RequestPolicy, RequestPolicyOptions, RequestPolicyFactory } from "../policies/requestPolicy";
import {
BaseRequestPolicy,
RequestPolicy,
RequestPolicyOptions,
RequestPolicyFactory
} from "../policies/requestPolicy";
import { Constants } from "../util/constants";
import { HttpOperationResponse } from "../httpOperationResponse";
import { HttpHeaders, } from "../httpHeaders";
import { HttpHeaders } from "../httpHeaders";
import { WebResource } from "../webResource";
import { AccessTokenCache, ExpiringAccessTokenCache } from "../credentials/accessTokenCache";

Expand All @@ -15,11 +20,20 @@ import { AccessTokenCache, ExpiringAccessTokenCache } from "../credentials/acces
* @param credential The TokenCredential implementation that can supply the bearer token.
* @param scopes The scopes for which the bearer token applies.
*/
export function bearerTokenAuthenticationPolicy(credential: TokenCredential, scopes: string | string[]): RequestPolicyFactory {
export function bearerTokenAuthenticationPolicy(
credential: TokenCredential,
scopes: string | string[]
): RequestPolicyFactory {
const tokenCache: AccessTokenCache = new ExpiringAccessTokenCache();
return {
create: (nextPolicy: RequestPolicy, options: RequestPolicyOptions) => {
return new BearerTokenAuthenticationPolicy(nextPolicy, options, credential, scopes, tokenCache);
return new BearerTokenAuthenticationPolicy(
nextPolicy,
options,
credential,
scopes,
tokenCache
);
}
};
}
Expand Down Expand Up @@ -55,24 +69,19 @@ export class BearerTokenAuthenticationPolicy extends BaseRequestPolicy {
* Applies the Bearer token to the request through the Authorization header.
* @param webResource
*/
public async sendRequest(
webResource: WebResource
): Promise<HttpOperationResponse> {
public async sendRequest(webResource: WebResource): Promise<HttpOperationResponse> {
if (!webResource.headers) webResource.headers = new HttpHeaders();
const token = await this.getToken({
abortSignal: webResource.abortSignal
});
webResource.headers.set(
Constants.HeaderConstants.AUTHORIZATION,
`Bearer ${token}`
);
webResource.headers.set(Constants.HeaderConstants.AUTHORIZATION, `Bearer ${token}`);
return this._nextPolicy.sendRequest(webResource);
}

private async getToken(options: GetTokenOptions): Promise<string | undefined> {
let accessToken = this.tokenCache.getCachedToken();
if (accessToken === undefined) {
accessToken = await this.credential.getToken(this.scopes, options) || undefined;
accessToken = (await this.credential.getToken(this.scopes, options)) || undefined;
this.tokenCache.setCachedToken(accessToken);
}

Expand Down
Loading